From a46f0248c4e0826af95c9a56a0821fd81da51e9c Mon Sep 17 00:00:00 2001 From: wilsonshih Date: Thu, 18 Apr 2019 17:25:28 +0800 Subject: [PATCH] Provide a sample of multi-display wallpaper. Some key events to build a wallpaper which can support multiple display. - The rendering or event handler of each engine must be independent. - Set supportsMultipleDisplays attribute to true. - Use Engine#getDisplayContext to load resource if needed. Bug: 129696884 Test: launch wallpaper and check on multi display. Change-Id: I3c60caba921e0af3d5f681ed318a543328e3375a --- samples/MultiDisplay/AndroidManifest.xml | 17 ++ .../res/drawable-nodpi/res_image.png | Bin 0 -> 3464 bytes .../res/drawable-sw320dp/res_image.png | Bin 0 -> 4294 bytes .../res/drawable-sw480dp/res_image.png | Bin 0 -> 4459 bytes .../res/drawable-sw640dp/res_image.png | Bin 0 -> 4467 bytes .../res/drawable-sw960dp/res_image.png | Bin 0 -> 5140 bytes samples/MultiDisplay/res/values/strings.xml | 1 + samples/MultiDisplay/res/xml/wallpaper.xml | 21 ++ .../wallpaper/SampleWallpaper.java | 271 ++++++++++++++++++ 9 files changed, 310 insertions(+) create mode 100644 samples/MultiDisplay/res/drawable-nodpi/res_image.png create mode 100644 samples/MultiDisplay/res/drawable-sw320dp/res_image.png create mode 100644 samples/MultiDisplay/res/drawable-sw480dp/res_image.png create mode 100644 samples/MultiDisplay/res/drawable-sw640dp/res_image.png create mode 100644 samples/MultiDisplay/res/drawable-sw960dp/res_image.png create mode 100644 samples/MultiDisplay/res/xml/wallpaper.xml create mode 100644 samples/MultiDisplay/src/com/example/android/multidisplay/wallpaper/SampleWallpaper.java diff --git a/samples/MultiDisplay/AndroidManifest.xml b/samples/MultiDisplay/AndroidManifest.xml index 8468377ee..81aa43b9a 100644 --- a/samples/MultiDisplay/AndroidManifest.xml +++ b/samples/MultiDisplay/AndroidManifest.xml @@ -18,6 +18,8 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/MultiDisplay/res/drawable-nodpi/res_image.png b/samples/MultiDisplay/res/drawable-nodpi/res_image.png new file mode 100644 index 0000000000000000000000000000000000000000..14b569d5899c367576aa381cf60884df23ea831b GIT binary patch literal 3464 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 literal 0 HcmV?d00001 diff --git a/samples/MultiDisplay/res/drawable-sw480dp/res_image.png b/samples/MultiDisplay/res/drawable-sw480dp/res_image.png new file mode 100644 index 0000000000000000000000000000000000000000..87af2ec334bf28a2468f172fb2cf1f025ca91179 GIT binary patch literal 4459 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 literal 0 HcmV?d00001 diff --git a/samples/MultiDisplay/res/drawable-sw640dp/res_image.png b/samples/MultiDisplay/res/drawable-sw640dp/res_image.png new file mode 100644 index 0000000000000000000000000000000000000000..ea57d9662894ea0dc85e6edca3d290886da6cfcd GIT binary patch literal 4467 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 literal 0 HcmV?d00001 diff --git a/samples/MultiDisplay/res/values/strings.xml b/samples/MultiDisplay/res/values/strings.xml index 96eb9f56b..53996f75e 100644 --- a/samples/MultiDisplay/res/values/strings.xml +++ b/samples/MultiDisplay/res/values/strings.xml @@ -23,4 +23,5 @@ Add app shortcut Set wallpaper Request launch in new instance + Sample multidisplay wallpaper diff --git a/samples/MultiDisplay/res/xml/wallpaper.xml b/samples/MultiDisplay/res/xml/wallpaper.xml new file mode 100644 index 000000000..748fcf7ee --- /dev/null +++ b/samples/MultiDisplay/res/xml/wallpaper.xml @@ -0,0 +1,21 @@ + + + diff --git a/samples/MultiDisplay/src/com/example/android/multidisplay/wallpaper/SampleWallpaper.java b/samples/MultiDisplay/src/com/example/android/multidisplay/wallpaper/SampleWallpaper.java new file mode 100644 index 000000000..7bf883bbc --- /dev/null +++ b/samples/MultiDisplay/src/com/example/android/multidisplay/wallpaper/SampleWallpaper.java @@ -0,0 +1,271 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.android.multidisplay.wallpaper; + + +import android.app.WallpaperColors; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.Point; +import android.graphics.Rect; +import android.graphics.drawable.ColorDrawable; +import android.hardware.display.DisplayManager; +import android.hardware.display.DisplayManager.DisplayListener; +import android.os.Handler; +import android.service.wallpaper.WallpaperService; +import android.util.DisplayMetrics; +import android.view.Display; +import android.view.MotionEvent; +import android.view.SurfaceHolder; +import android.view.WindowManager; +import java.util.Random; +import com.example.android.multidisplay.R; + +public class SampleWallpaper extends WallpaperService { + + @Override + public Engine onCreateEngine() { + return new MySampleEngine(); + } + + private class MySampleEngine extends Engine { + private boolean mVisible = false; + private DisplayMetrics mDisplayMetrics; + private Display mDisplay; + private Paint mPaint = new Paint(); + + private final Handler mHandler = new Handler(); + private final Runnable mDrawRunner = this::draw; + + private String mShowingText; + private final Rect mTextBounds = new Rect(); + + private Bitmap mTipImage; + + private final Point mCircleShift = new Point(); + private final Point mCirclePosition = new Point(); + private float mCircleRadioShift; + private final float MaxCircleRadioShift = 6f; + private boolean mRadioRevert = false; + + private int mBackgroundColor = Color.BLACK; + private int mPaintColor = Color.WHITE; + + private boolean mCircleDirectionX = false; + private boolean mCircleDirectionY = false; + + @Override + public void onCreate(SurfaceHolder surfaceHolder) { + initDisplay(); + updateDisplay(); + initPaint(); + genNewShift(); + genNewColor(); + mHandler.post(mDrawRunner); + } + + @Override + public void onDestroy() { + final DisplayManager dm = getSystemService(DisplayManager.class); + if (dm != null) { + dm.unregisterDisplayListener(mDisplayListener); + } + } + + @Override + public WallpaperColors onComputeColors() { + super.onComputeColors(); + ColorDrawable drawable = new ColorDrawable(mBackgroundColor); + drawable.setBounds(0, 0, mDisplayMetrics.widthPixels, mDisplayMetrics.widthPixels); + return WallpaperColors.fromDrawable(drawable); + } + + @Override + public void onVisibilityChanged(boolean visible) { + mVisible = visible; + if (visible) { + mHandler.post(mDrawRunner); + } else { + mHandler.removeCallbacks(mDrawRunner); + } + } + + @Override + public void onTouchEvent(MotionEvent event) { + if (event.getAction() == MotionEvent.ACTION_DOWN) { + mCirclePosition.x = (int) event.getX(); + mCirclePosition.y = (int) event.getY(); + invertCircleDirectionIfNeeded(); + } + super.onTouchEvent(event); + } + + @Override + public void onSurfaceDestroyed(SurfaceHolder holder) { + super.onSurfaceDestroyed(holder); + mVisible = false; + mHandler.removeCallbacks(mDrawRunner); + } + + private void draw() { + SurfaceHolder holder = getSurfaceHolder(); + Canvas canvas = null; + float centerX = (float) mDisplayMetrics.widthPixels/2; + float centerY = (float) mDisplayMetrics.heightPixels/2; + + updateShift(); + invertCircleDirectionIfNeeded(); + + try { + canvas = holder.lockCanvas(); + if (canvas != null) { + canvas.drawColor(mBackgroundColor); + if (mTipImage != null) { + canvas.drawBitmap(mTipImage, 0, 0, mPaint); + } + canvas.drawText(mShowingText, centerX - mTextBounds.exactCenterX(), + centerY - mTextBounds.exactCenterY(), mPaint); + + canvas.drawCircle(mCirclePosition.x, mCirclePosition.y, + 20.0f + mCircleRadioShift, mPaint); + } + } finally { + if (canvas != null) + holder.unlockCanvasAndPost(canvas); + } + mHandler.removeCallbacks(mDrawRunner); + if (mVisible) { + mHandler.postDelayed(mDrawRunner, 40); + } + } + + private void invertCircleDirectionIfNeeded() { + boolean invertX = mCirclePosition.x < 0 + || mCirclePosition.x > mDisplayMetrics.widthPixels; + boolean invertY = mCirclePosition.y < 0 + || mCirclePosition.y > mDisplayMetrics.heightPixels; + + if (!invertX && !invertY) return; + + if (invertX) { + mCircleDirectionX = mCirclePosition.x < 0; + } + if (invertY) { + mCircleDirectionY = mCirclePosition.y < 0; + } + + genNewShift(); + genNewColor(); + } + + private void updateShift() { + mCirclePosition.x = mCircleDirectionX + ? mCirclePosition.x + mCircleShift.x + : mCirclePosition.x - mCircleShift.x; + mCirclePosition.y = mCircleDirectionY + ? mCirclePosition.y + mCircleShift.y + : mCirclePosition.y - mCircleShift.y; + + mCircleRadioShift = mRadioRevert ? mCircleRadioShift + 1f : mCircleRadioShift - 1f; + if (Math.abs(mCircleRadioShift) > MaxCircleRadioShift) { + mRadioRevert = !mRadioRevert; + } + } + + private void genNewShift() { + Random random = new Random(); + mCircleShift.x = Math.abs(random.nextInt(5)); + mCircleShift.y = Math.abs(5 - mCircleShift.x); + } + + private void genNewColor() { + final Random random = new Random(); + int br = random.nextInt(256); + int bg = random.nextInt(256); + int bb = random.nextInt(256); + + // Keep some contrast... + int pg = Math.abs(bg - 128); + int pr = Math.abs(br - 128); + int pb = Math.abs(bb - 128); + mBackgroundColor = Color.argb(255, br, bg, bb); + mPaintColor = Color.argb(255, pr, pg, pb); + mPaint.setColor(mPaintColor); + } + + private void initDisplay() { + // If we want to get display, use getDisplayContext().getSystemService so the + // WindowManager is created for this context. + final WindowManager wm = getDisplayContext().getSystemService(WindowManager.class); + if (wm != null) { + mDisplay = wm.getDefaultDisplay(); + } + final DisplayManager dm = getSystemService(DisplayManager.class); + if (dm != null) { + dm.registerDisplayListener(mDisplayListener, null); + } + } + + private void updateDisplay() { + // Use getDisplayContext() to get the context for current display. + mDisplayMetrics = getDisplayContext().getResources().getDisplayMetrics(); + mCirclePosition.x = mDisplayMetrics.widthPixels/2; + mCirclePosition.y = mDisplayMetrics.heightPixels/2 + 60; + + mShowingText = "densityDpi= " + mDisplayMetrics.densityDpi; + if (mTipImage != null) { + mTipImage.recycle(); + mTipImage = null; + } + mTipImage = BitmapFactory + .decodeResource(getDisplayContext().getResources(), R.drawable.res_image); + mPaint.getTextBounds(mShowingText, 0, mShowingText.length(), mTextBounds); + } + + public MySampleEngine() { + + } + + private void initPaint() { + mPaint.setAntiAlias(true); + mPaint.setStrokeWidth(1f); + mPaint.setTextSize(50f); + } + + // Use DisplayListener to know display changed. + private final DisplayListener mDisplayListener = new DisplayListener() { + @Override + public void onDisplayChanged(int displayId) { + if (mDisplay.getDisplayId() == displayId) { + updateDisplay(); + } + } + + @Override + public void onDisplayRemoved(int displayId) { + // handle here or wait onDestroy + } + + @Override + public void onDisplayAdded(int displayId) { + } + }; + } +}