1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.example.wallpapertest; 18 19 import android.service.wallpaper.WallpaperService; 20 import android.graphics.Canvas; 21 import android.graphics.Rect; 22 import android.graphics.Paint; 23 import android.graphics.Color; 24 import android.graphics.RectF; 25 import android.text.TextPaint; 26 import android.view.SurfaceHolder; 27 import android.content.res.XmlResourceParser; 28 29 import android.os.Handler; 30 import android.util.Log; 31 32 import android.view.WindowInsets; 33 34 public class TestWallpaper extends WallpaperService { 35 private static final String LOG_TAG = "PolarClock"; 36 37 private final Handler mHandler = new Handler(); 38 39 @Override onCreate()40 public void onCreate() { 41 super.onCreate(); 42 } 43 44 @Override onDestroy()45 public void onDestroy() { 46 super.onDestroy(); 47 } 48 onCreateEngine()49 public Engine onCreateEngine() { 50 return new ClockEngine(); 51 } 52 53 class ClockEngine extends Engine { 54 private static final int OUTER_COLOR = 0xffff0000; 55 private static final int INNER_COLOR = 0xff000080; 56 private static final int STABLE_COLOR = 0xa000ff00; 57 private static final int TEXT_COLOR = 0xa0ffffff; 58 59 private final Paint.FontMetrics mTextMetrics = new Paint.FontMetrics(); 60 61 private int mPadding; 62 63 private final Rect mMainInsets = new Rect(); 64 private final Rect mStableInsets = new Rect(); 65 private boolean mRound = false; 66 67 private int mDesiredWidth; 68 private int mDesiredHeight; 69 70 private float mOffsetX; 71 private float mOffsetY; 72 private float mOffsetXStep; 73 private float mOffsetYStep; 74 private int mOffsetXPixels; 75 private int mOffsetYPixels; 76 77 private final Paint mFillPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 78 private final Paint mStrokePaint = new Paint(Paint.ANTI_ALIAS_FLAG); 79 private final TextPaint mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG); 80 81 private final Runnable mDrawClock = new Runnable() { 82 public void run() { 83 drawFrame(); 84 } 85 }; 86 private boolean mVisible; 87 ClockEngine()88 ClockEngine() { 89 } 90 91 @Override onCreate(SurfaceHolder surfaceHolder)92 public void onCreate(SurfaceHolder surfaceHolder) { 93 super.onCreate(surfaceHolder); 94 95 mDesiredWidth = getDesiredMinimumWidth(); 96 mDesiredHeight = getDesiredMinimumHeight(); 97 98 Paint paint = mFillPaint; 99 paint.setStyle(Paint.Style.FILL); 100 101 paint = mStrokePaint; 102 paint.setStrokeWidth(3); 103 paint.setStrokeCap(Paint.Cap.ROUND); 104 paint.setStyle(Paint.Style.STROKE); 105 106 TextPaint tpaint = mTextPaint; 107 tpaint.density = getResources().getDisplayMetrics().density; 108 tpaint.setCompatibilityScaling(getResources().getCompatibilityInfo().applicationScale); 109 tpaint.setColor(TEXT_COLOR); 110 tpaint.setTextSize(18 * getResources().getDisplayMetrics().scaledDensity); 111 tpaint.setShadowLayer(4 * getResources().getDisplayMetrics().density, 0, 0, 0xff000000); 112 113 mTextPaint.getFontMetrics(mTextMetrics); 114 115 mPadding = (int)(16 * getResources().getDisplayMetrics().density); 116 117 if (isPreview()) { 118 mOffsetX = 0.5f; 119 mOffsetY = 0.5f; 120 } 121 } 122 123 @Override onDestroy()124 public void onDestroy() { 125 super.onDestroy(); 126 mHandler.removeCallbacks(mDrawClock); 127 } 128 129 @Override onVisibilityChanged(boolean visible)130 public void onVisibilityChanged(boolean visible) { 131 mVisible = visible; 132 if (!visible) { 133 mHandler.removeCallbacks(mDrawClock); 134 } 135 drawFrame(); 136 } 137 138 @Override onSurfaceChanged(SurfaceHolder holder, int format, int width, int height)139 public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) { 140 super.onSurfaceChanged(holder, format, width, height); 141 drawFrame(); 142 } 143 144 @Override onSurfaceCreated(SurfaceHolder holder)145 public void onSurfaceCreated(SurfaceHolder holder) { 146 super.onSurfaceCreated(holder); 147 148 // Simulate some slowness, so we can test the loading process in the live wallpaper 149 // picker. 150 try { 151 Thread.sleep(1000); 152 } catch (InterruptedException e) { 153 e.printStackTrace(); 154 } 155 } 156 157 @Override onSurfaceDestroyed(SurfaceHolder holder)158 public void onSurfaceDestroyed(SurfaceHolder holder) { 159 super.onSurfaceDestroyed(holder); 160 mVisible = false; 161 mHandler.removeCallbacks(mDrawClock); 162 } 163 164 @Override onApplyWindowInsets(WindowInsets insets)165 public void onApplyWindowInsets(WindowInsets insets) { 166 super.onApplyWindowInsets(insets); 167 mMainInsets.set(insets.getSystemWindowInsetLeft(), insets.getSystemWindowInsetTop(), 168 insets.getSystemWindowInsetRight(), insets.getSystemWindowInsetBottom()); 169 mStableInsets.set(insets.getStableInsetLeft(), insets.getStableInsetTop(), 170 insets.getStableInsetRight(), insets.getStableInsetBottom()); 171 mRound = insets.isRound(); 172 drawFrame(); 173 } 174 175 @Override onDesiredSizeChanged(int desiredWidth, int desiredHeight)176 public void onDesiredSizeChanged(int desiredWidth, int desiredHeight) { 177 super.onDesiredSizeChanged(desiredWidth, desiredHeight); 178 mDesiredWidth = desiredWidth; 179 mDesiredHeight = desiredHeight; 180 drawFrame(); 181 } 182 183 @Override onOffsetsChanged(float xOffset, float yOffset, float xStep, float yStep, int xPixels, int yPixels)184 public void onOffsetsChanged(float xOffset, float yOffset, 185 float xStep, float yStep, int xPixels, int yPixels) { 186 super.onOffsetsChanged(xOffset, yOffset, xStep, yStep, xPixels, yPixels); 187 188 if (isPreview()) return; 189 190 mOffsetX = xOffset; 191 mOffsetY = yOffset; 192 mOffsetXStep = xStep; 193 mOffsetYStep = yStep; 194 mOffsetXPixels = xPixels; 195 mOffsetYPixels = yPixels; 196 197 drawFrame(); 198 } 199 drawFrame()200 void drawFrame() { 201 final SurfaceHolder holder = getSurfaceHolder(); 202 final Rect frame = holder.getSurfaceFrame(); 203 final int width = frame.width(); 204 final int height = frame.height(); 205 206 Canvas c = null; 207 try { 208 c = holder.lockCanvas(); 209 if (c != null) { 210 final Paint paint = mFillPaint; 211 212 paint.setColor(OUTER_COLOR); 213 c.drawRect(0, 0, width, height, paint); 214 215 paint.setColor(INNER_COLOR); 216 c.drawRect(0+mMainInsets.left, 0+mMainInsets.top, 217 width-mMainInsets.right, height-mMainInsets.bottom, paint); 218 219 mStrokePaint.setColor(STABLE_COLOR); 220 c.drawRect(0 + mStableInsets.left, 0 + mStableInsets.top, 221 width - mStableInsets.right, height - mStableInsets.bottom, 222 mStrokePaint); 223 224 final int ascdesc = (int)(-mTextMetrics.ascent + mTextMetrics.descent); 225 final int linegap = (int)(-mTextMetrics.ascent + mTextMetrics.descent 226 + mTextMetrics.leading); 227 228 int x = mStableInsets.left + mPadding; 229 int y = height - mStableInsets.bottom - mPadding - ascdesc; 230 c.drawText("Surface Size: " + width + " x " + height, 231 x, y, mTextPaint); 232 y -= linegap; 233 c.drawText("Desired Size: " + mDesiredWidth + " x " + mDesiredHeight, 234 x, y, mTextPaint); 235 y -= linegap; 236 c.drawText("Cur Offset Raw: " + mOffsetX + ", " + mOffsetY, 237 x, y, mTextPaint); 238 y -= linegap; 239 c.drawText("Cur Offset Step: " + mOffsetXStep + ", " + mOffsetYStep, 240 x, y, mTextPaint); 241 y -= linegap; 242 c.drawText("Cur Offset Pixels: " + mOffsetXPixels + ", " + mOffsetYPixels, 243 x, y, mTextPaint); 244 y -= linegap; 245 c.drawText("Stable Insets: (" + mStableInsets.left + ", " + mStableInsets.top 246 + ") - (" + mStableInsets.right + ", " + mStableInsets.bottom + ")", 247 x, y, mTextPaint); 248 y -= linegap; 249 c.drawText("System Insets: (" + mMainInsets.left + ", " + mMainInsets.top 250 + ") - (" + mMainInsets.right + ", " + mMainInsets.bottom + ")", 251 x, y, mTextPaint); 252 253 } 254 } finally { 255 if (c != null) holder.unlockCanvasAndPost(c); 256 } 257 } 258 } 259 } 260