• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009 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.android.internal.service.wallpaper;
18 
19 import android.app.WallpaperManager;
20 import android.graphics.Canvas;
21 import android.graphics.Rect;
22 import android.graphics.Region.Op;
23 import android.graphics.drawable.Drawable;
24 import android.os.HandlerThread;
25 import android.os.Process;
26 import android.service.wallpaper.WallpaperService;
27 import android.util.Log;
28 import android.view.MotionEvent;
29 import android.view.SurfaceHolder;
30 import android.content.Context;
31 import android.content.IntentFilter;
32 import android.content.Intent;
33 import android.content.BroadcastReceiver;
34 
35 /**
36  * Default built-in wallpaper that simply shows a static image.
37  */
38 public class ImageWallpaper extends WallpaperService {
39     WallpaperManager mWallpaperManager;
40     private HandlerThread mThread;
41 
42     @Override
onCreate()43     public void onCreate() {
44         super.onCreate();
45         mWallpaperManager = (WallpaperManager) getSystemService(WALLPAPER_SERVICE);
46         mThread = new HandlerThread("Wallpaper", Process.THREAD_PRIORITY_FOREGROUND);
47         mThread.start();
48         setCallbackLooper(mThread.getLooper());
49     }
50 
onCreateEngine()51     public Engine onCreateEngine() {
52         return new DrawableEngine();
53     }
54 
55     @Override
onDestroy()56     public void onDestroy() {
57         super.onDestroy();
58         mThread.quit();
59     }
60 
61     class DrawableEngine extends Engine {
62         private final Object mLock = new Object();
63         private WallpaperObserver mReceiver;
64         Drawable mBackground;
65         float mXOffset;
66         float mYOffset;
67 
68         class WallpaperObserver extends BroadcastReceiver {
onReceive(Context context, Intent intent)69             public void onReceive(Context context, Intent intent) {
70                 updateWallpaper();
71                 drawFrame();
72                 // Assume we are the only one using the wallpaper in this
73                 // process, and force a GC now to release the old wallpaper.
74                 System.gc();
75             }
76         }
77 
78         @Override
onCreate(SurfaceHolder surfaceHolder)79         public void onCreate(SurfaceHolder surfaceHolder) {
80             super.onCreate(surfaceHolder);
81             IntentFilter filter = new IntentFilter(Intent.ACTION_WALLPAPER_CHANGED);
82             mReceiver = new WallpaperObserver();
83             registerReceiver(mReceiver, filter);
84             updateWallpaper();
85             surfaceHolder.setSizeFromLayout();
86         }
87 
88         @Override
onDestroy()89         public void onDestroy() {
90             super.onDestroy();
91             unregisterReceiver(mReceiver);
92         }
93 
94         @Override
onVisibilityChanged(boolean visible)95         public void onVisibilityChanged(boolean visible) {
96             drawFrame();
97         }
98 
99         @Override
onTouchEvent(MotionEvent event)100         public void onTouchEvent(MotionEvent event) {
101             super.onTouchEvent(event);
102         }
103 
104         @Override
onOffsetsChanged(float xOffset, float yOffset, float xOffsetStep, float yOffsetStep, int xPixels, int yPixels)105         public void onOffsetsChanged(float xOffset, float yOffset,
106                 float xOffsetStep, float yOffsetStep,
107                 int xPixels, int yPixels) {
108             mXOffset = xOffset;
109             mYOffset = yOffset;
110             drawFrame();
111         }
112 
113         @Override
onSurfaceChanged(SurfaceHolder holder, int format, int width, int height)114         public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
115             super.onSurfaceChanged(holder, format, width, height);
116             drawFrame();
117         }
118 
119         @Override
onSurfaceCreated(SurfaceHolder holder)120         public void onSurfaceCreated(SurfaceHolder holder) {
121             super.onSurfaceCreated(holder);
122         }
123 
124         @Override
onSurfaceDestroyed(SurfaceHolder holder)125         public void onSurfaceDestroyed(SurfaceHolder holder) {
126             super.onSurfaceDestroyed(holder);
127         }
128 
drawFrame()129         void drawFrame() {
130             SurfaceHolder sh = getSurfaceHolder();
131             Canvas c = sh.lockCanvas();
132             if (c != null) {
133                 final Rect frame = sh.getSurfaceFrame();
134                 synchronized (mLock) {
135                     final Drawable background = mBackground;
136                     final int dw = frame.width();
137                     final int dh = frame.height();
138                     final int bw = background != null ? background.getIntrinsicWidth() : 0;
139                     final int bh = background != null ? background.getIntrinsicHeight() : 0;
140                     final int availw = dw-bw;
141                     final int availh = dh-bh;
142                     int xPixels = availw < 0 ? (int)(availw*mXOffset+.5f) : (availw/2);
143                     int yPixels = availh < 0 ? (int)(availh*mYOffset+.5f) : (availh/2);
144 
145                     c.translate(xPixels, yPixels);
146                     if (availw<0 || availh<0) {
147                         c.save(Canvas.CLIP_SAVE_FLAG);
148                         c.clipRect(0, 0, bw, bh, Op.DIFFERENCE);
149                         c.drawColor(0xff000000);
150                         c.restore();
151                     }
152                     if (background != null) {
153                         background.draw(c);
154                     }
155                 }
156                 sh.unlockCanvasAndPost(c);
157             }
158         }
159 
160         void updateWallpaper() {
161             synchronized (mLock) {
162                 try {
163                     mBackground = mWallpaperManager.getFastDrawable();
164                 } catch (RuntimeException e) {
165                     Log.w("ImageWallpaper", "Unable to load wallpaper!", e);
166                 }
167             }
168         }
169     }
170 }
171