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 149 @Override onSurfaceDestroyed(SurfaceHolder holder)150 public void onSurfaceDestroyed(SurfaceHolder holder) { 151 super.onSurfaceDestroyed(holder); 152 mVisible = false; 153 mHandler.removeCallbacks(mDrawClock); 154 } 155 156 @Override onApplyWindowInsets(WindowInsets insets)157 public void onApplyWindowInsets(WindowInsets insets) { 158 super.onApplyWindowInsets(insets); 159 mMainInsets.set(insets.getSystemWindowInsetLeft(), insets.getSystemWindowInsetTop(), 160 insets.getSystemWindowInsetRight(), insets.getSystemWindowInsetBottom()); 161 mStableInsets.set(insets.getStableInsetLeft(), insets.getStableInsetTop(), 162 insets.getStableInsetRight(), insets.getStableInsetBottom()); 163 mRound = insets.isRound(); 164 drawFrame(); 165 } 166 167 @Override onDesiredSizeChanged(int desiredWidth, int desiredHeight)168 public void onDesiredSizeChanged(int desiredWidth, int desiredHeight) { 169 super.onDesiredSizeChanged(desiredWidth, desiredHeight); 170 mDesiredWidth = desiredWidth; 171 mDesiredHeight = desiredHeight; 172 drawFrame(); 173 } 174 175 @Override onOffsetsChanged(float xOffset, float yOffset, float xStep, float yStep, int xPixels, int yPixels)176 public void onOffsetsChanged(float xOffset, float yOffset, 177 float xStep, float yStep, int xPixels, int yPixels) { 178 super.onOffsetsChanged(xOffset, yOffset, xStep, yStep, xPixels, yPixels); 179 180 if (isPreview()) return; 181 182 mOffsetX = xOffset; 183 mOffsetY = yOffset; 184 mOffsetXStep = xStep; 185 mOffsetYStep = yStep; 186 mOffsetXPixels = xPixels; 187 mOffsetYPixels = yPixels; 188 189 drawFrame(); 190 } 191 drawFrame()192 void drawFrame() { 193 final SurfaceHolder holder = getSurfaceHolder(); 194 final Rect frame = holder.getSurfaceFrame(); 195 final int width = frame.width(); 196 final int height = frame.height(); 197 198 Canvas c = null; 199 try { 200 c = holder.lockCanvas(); 201 if (c != null) { 202 final Paint paint = mFillPaint; 203 204 paint.setColor(OUTER_COLOR); 205 c.drawRect(0, 0, width, height, paint); 206 207 paint.setColor(INNER_COLOR); 208 c.drawRect(0+mMainInsets.left, 0+mMainInsets.top, 209 width-mMainInsets.right, height-mMainInsets.bottom, paint); 210 211 mStrokePaint.setColor(STABLE_COLOR); 212 c.drawRect(0 + mStableInsets.left, 0 + mStableInsets.top, 213 width - mStableInsets.right, height - mStableInsets.bottom, 214 mStrokePaint); 215 216 final int ascdesc = (int)(-mTextMetrics.ascent + mTextMetrics.descent); 217 final int linegap = (int)(-mTextMetrics.ascent + mTextMetrics.descent 218 + mTextMetrics.leading); 219 220 int x = mStableInsets.left + mPadding; 221 int y = height - mStableInsets.bottom - mPadding - ascdesc; 222 c.drawText("Surface Size: " + width + " x " + height, 223 x, y, mTextPaint); 224 y -= linegap; 225 c.drawText("Desired Size: " + mDesiredWidth + " x " + mDesiredHeight, 226 x, y, mTextPaint); 227 y -= linegap; 228 c.drawText("Cur Offset Raw: " + mOffsetX + ", " + mOffsetY, 229 x, y, mTextPaint); 230 y -= linegap; 231 c.drawText("Cur Offset Step: " + mOffsetXStep + ", " + mOffsetYStep, 232 x, y, mTextPaint); 233 y -= linegap; 234 c.drawText("Cur Offset Pixels: " + mOffsetXPixels + ", " + mOffsetYPixels, 235 x, y, mTextPaint); 236 y -= linegap; 237 c.drawText("Stable Insets: (" + mStableInsets.left + ", " + mStableInsets.top 238 + ") - (" + mStableInsets.right + ", " + mStableInsets.bottom + ")", 239 x, y, mTextPaint); 240 y -= linegap; 241 c.drawText("System Insets: (" + mMainInsets.left + ", " + mMainInsets.top 242 + ") - (" + mMainInsets.right + ", " + mMainInsets.bottom + ")", 243 x, y, mTextPaint); 244 245 } 246 } finally { 247 if (c != null) holder.unlockCanvasAndPost(c); 248 } 249 } 250 } 251 } 252