14c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn/*
24c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn * Copyright (C) 2009 The Android Open Source Project
34c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn *
44c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License");
54c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn * you may not use this file except in compliance with the License.
64c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn * You may obtain a copy of the License at
74c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn *
84c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn *      http://www.apache.org/licenses/LICENSE-2.0
94c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn *
104c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn * Unless required by applicable law or agreed to in writing, software
114c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS,
124c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn * See the License for the specific language governing permissions and
144c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn * limitations under the License.
154c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn */
164c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn
178cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackbornpackage android.app;
188cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn
198cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackbornimport android.content.Context;
208cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackbornimport android.content.Intent;
218cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackbornimport android.content.res.Resources;
228cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackbornimport android.graphics.Bitmap;
238cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackbornimport android.graphics.BitmapFactory;
24284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackbornimport android.graphics.Canvas;
2519382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackbornimport android.graphics.ColorFilter;
26284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackbornimport android.graphics.Paint;
2719382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackbornimport android.graphics.PixelFormat;
2824572375323dee79e3b456af07640ca194fd40bfJeff Brownimport android.graphics.PorterDuff;
2924572375323dee79e3b456af07640ca194fd40bfJeff Brownimport android.graphics.PorterDuffXfermode;
30284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackbornimport android.graphics.Rect;
318cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackbornimport android.graphics.drawable.BitmapDrawable;
328cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackbornimport android.graphics.drawable.Drawable;
33284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackbornimport android.os.Bundle;
348cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackbornimport android.os.Handler;
358cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackbornimport android.os.IBinder;
36840c3a2b7e29cd75c13418a90cce5e311415c843Dianne Hackbornimport android.os.Looper;
37840c3a2b7e29cd75c13418a90cce5e311415c843Dianne Hackbornimport android.os.Message;
388cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackbornimport android.os.ParcelFileDescriptor;
398cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackbornimport android.os.RemoteException;
408cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackbornimport android.os.ServiceManager;
41284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackbornimport android.util.DisplayMetrics;
427341d7a104b47996445d069a695e155a07184606Dianne Hackbornimport android.util.Log;
436dd005b48138708762bfade0081d031a2a4a3822Dianne Hackbornimport android.view.ViewRootImpl;
448cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn
458cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackbornimport java.io.FileOutputStream;
468cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackbornimport java.io.IOException;
478cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackbornimport java.io.InputStream;
488cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn
498b2e000c43f5a93209be269a0b9e08943fad8d3cScott Main/**
508b2e000c43f5a93209be269a0b9e08943fad8d3cScott Main * Provides access to the system wallpaper. With WallpaperManager, you can
518b2e000c43f5a93209be269a0b9e08943fad8d3cScott Main * get the current wallpaper, get the desired dimensions for the wallpaper, set
528b2e000c43f5a93209be269a0b9e08943fad8d3cScott Main * the wallpaper, and more. Get an instance of WallpaperManager with
538b2e000c43f5a93209be269a0b9e08943fad8d3cScott Main * {@link #getInstance(android.content.Context) getInstance()}.
548b2e000c43f5a93209be269a0b9e08943fad8d3cScott Main */
558cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackbornpublic class WallpaperManager {
568cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn    private static String TAG = "WallpaperManager";
578cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn    private static boolean DEBUG = false;
58bf6956b1d95442e9d9c483894d578fe6b7044cbbMarco Nelissen    private float mWallpaperXStep = -1;
59bf6956b1d95442e9d9c483894d578fe6b7044cbbMarco Nelissen    private float mWallpaperYStep = -1;
608cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn
614c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    /**
624c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn     * Launch an activity for the user to pick the current global live
634c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn     * wallpaper.
644c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn     */
654c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    public static final String ACTION_LIVE_WALLPAPER_CHOOSER
664c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            = "android.service.wallpaper.LIVE_WALLPAPER_CHOOSER";
675a242ec2cf54e1bda69c2451304181ef1bc3e872Adam Cohen
685a242ec2cf54e1bda69c2451304181ef1bc3e872Adam Cohen    /**
695a242ec2cf54e1bda69c2451304181ef1bc3e872Adam Cohen     * Manifest entry for activities that respond to {@link Intent#ACTION_SET_WALLPAPER}
705a242ec2cf54e1bda69c2451304181ef1bc3e872Adam Cohen     * which allows them to provide a custom large icon associated with this action.
715a242ec2cf54e1bda69c2451304181ef1bc3e872Adam Cohen     */
725a242ec2cf54e1bda69c2451304181ef1bc3e872Adam Cohen    public static final String WALLPAPER_PREVIEW_META_DATA = "android.wallpaper.preview";
735a242ec2cf54e1bda69c2451304181ef1bc3e872Adam Cohen
7423ef7b4836d66d31430fedee2aac36275bb30d4bDianne Hackborn    /**
7523ef7b4836d66d31430fedee2aac36275bb30d4bDianne Hackborn     * Command for {@link #sendWallpaperCommand}: reported by the wallpaper
7623ef7b4836d66d31430fedee2aac36275bb30d4bDianne Hackborn     * host when the user taps on an empty area (not performing an action
7723ef7b4836d66d31430fedee2aac36275bb30d4bDianne Hackborn     * in the host).  The x and y arguments are the location of the tap in
7823ef7b4836d66d31430fedee2aac36275bb30d4bDianne Hackborn     * screen coordinates.
7923ef7b4836d66d31430fedee2aac36275bb30d4bDianne Hackborn     */
8023ef7b4836d66d31430fedee2aac36275bb30d4bDianne Hackborn    public static final String COMMAND_TAP = "android.wallpaper.tap";
8123ef7b4836d66d31430fedee2aac36275bb30d4bDianne Hackborn
8223ef7b4836d66d31430fedee2aac36275bb30d4bDianne Hackborn    /**
8323ef7b4836d66d31430fedee2aac36275bb30d4bDianne Hackborn     * Command for {@link #sendWallpaperCommand}: reported by the wallpaper
849f3bdfe3eb04723efa07a2d0e6a7709da1191fa5Jeff Brown     * host when the user releases a secondary pointer on an empty area
859f3bdfe3eb04723efa07a2d0e6a7709da1191fa5Jeff Brown     * (not performing an action in the host).  The x and y arguments are
869f3bdfe3eb04723efa07a2d0e6a7709da1191fa5Jeff Brown     * the location of the secondary tap in screen coordinates.
879f3bdfe3eb04723efa07a2d0e6a7709da1191fa5Jeff Brown     */
889f3bdfe3eb04723efa07a2d0e6a7709da1191fa5Jeff Brown    public static final String COMMAND_SECONDARY_TAP = "android.wallpaper.secondaryTap";
899f3bdfe3eb04723efa07a2d0e6a7709da1191fa5Jeff Brown
909f3bdfe3eb04723efa07a2d0e6a7709da1191fa5Jeff Brown    /**
919f3bdfe3eb04723efa07a2d0e6a7709da1191fa5Jeff Brown     * Command for {@link #sendWallpaperCommand}: reported by the wallpaper
9223ef7b4836d66d31430fedee2aac36275bb30d4bDianne Hackborn     * host when the user drops an object into an area of the host.  The x
9323ef7b4836d66d31430fedee2aac36275bb30d4bDianne Hackborn     * and y arguments are the location of the drop.
9423ef7b4836d66d31430fedee2aac36275bb30d4bDianne Hackborn     */
9523ef7b4836d66d31430fedee2aac36275bb30d4bDianne Hackborn    public static final String COMMAND_DROP = "android.home.drop";
9623ef7b4836d66d31430fedee2aac36275bb30d4bDianne Hackborn
978cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn    private final Context mContext;
988cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn
9919382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn    /**
10019382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn     * Special drawable that draws a wallpaper as fast as possible.  Assumes
10119382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn     * no scaling or placement off (0,0) of the wallpaper (this should be done
10219382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn     * at the time the bitmap is loaded).
10319382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn     */
10419382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn    static class FastBitmapDrawable extends Drawable {
10519382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        private final Bitmap mBitmap;
10619382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        private final int mWidth;
10719382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        private final int mHeight;
10819382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        private int mDrawLeft;
10919382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        private int mDrawTop;
110407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy        private final Paint mPaint;
11119382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn
11219382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        private FastBitmapDrawable(Bitmap bitmap) {
11319382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn            mBitmap = bitmap;
11419382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn            mWidth = bitmap.getWidth();
11519382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn            mHeight = bitmap.getHeight();
116407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy
11719382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn            setBounds(0, 0, mWidth, mHeight);
118407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy
119407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy            mPaint = new Paint();
120407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy            mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
12119382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        }
12219382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn
12319382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        @Override
12419382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        public void draw(Canvas canvas) {
125407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy            canvas.drawBitmap(mBitmap, mDrawLeft, mDrawTop, mPaint);
12619382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        }
12719382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn
12819382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        @Override
12919382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        public int getOpacity() {
13019382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn            return PixelFormat.OPAQUE;
13119382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        }
13219382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn
13319382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        @Override
13419382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        public void setBounds(int left, int top, int right, int bottom) {
13519382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn            mDrawLeft = left + (right-left - mWidth) / 2;
13619382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn            mDrawTop = top + (bottom-top - mHeight) / 2;
13719382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        }
13819382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn
13919382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        @Override
14019382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        public void setAlpha(int alpha) {
141407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy            throw new UnsupportedOperationException("Not supported with this drawable");
14219382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        }
14319382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn
14419382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        @Override
14519382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        public void setColorFilter(ColorFilter cf) {
146407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy            throw new UnsupportedOperationException("Not supported with this drawable");
14719382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        }
14819382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn
14919382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        @Override
15019382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        public void setDither(boolean dither) {
151407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy            throw new UnsupportedOperationException("Not supported with this drawable");
15219382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        }
15319382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn
15419382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        @Override
15519382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        public void setFilterBitmap(boolean filter) {
156407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy            throw new UnsupportedOperationException("Not supported with this drawable");
15719382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        }
15819382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn
15919382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        @Override
16019382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        public int getIntrinsicWidth() {
16119382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn            return mWidth;
16219382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        }
16319382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn
16419382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        @Override
16519382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        public int getIntrinsicHeight() {
16619382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn            return mHeight;
16719382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        }
16819382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn
16919382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        @Override
17019382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        public int getMinimumWidth() {
17119382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn            return mWidth;
17219382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        }
17319382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn
17419382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        @Override
17519382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        public int getMinimumHeight() {
17619382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn            return mHeight;
17719382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        }
17819382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn    }
17919382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn
1808cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn    static class Globals extends IWallpaperManagerCallback.Stub {
1818cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn        private IWallpaperManager mService;
182284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn        private Bitmap mWallpaper;
18319382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        private Bitmap mDefaultWallpaper;
1848cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn
185840c3a2b7e29cd75c13418a90cce5e311415c843Dianne Hackborn        private static final int MSG_CLEAR_WALLPAPER = 1;
186840c3a2b7e29cd75c13418a90cce5e311415c843Dianne Hackborn
1875e802fbb895a0ff4d9be1a72390f51c134a5ba0fDianne Hackborn        private final Handler mHandler;
188840c3a2b7e29cd75c13418a90cce5e311415c843Dianne Hackborn
1895e802fbb895a0ff4d9be1a72390f51c134a5ba0fDianne Hackborn        Globals(Looper looper) {
1908cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn            IBinder b = ServiceManager.getService(Context.WALLPAPER_SERVICE);
1918cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn            mService = IWallpaperManager.Stub.asInterface(b);
19285644d78894b66fa2903fb012b5122185767d1c5Dianne Hackborn            mHandler = new Handler(looper) {
1935e802fbb895a0ff4d9be1a72390f51c134a5ba0fDianne Hackborn                @Override
1945e802fbb895a0ff4d9be1a72390f51c134a5ba0fDianne Hackborn                public void handleMessage(Message msg) {
1955e802fbb895a0ff4d9be1a72390f51c134a5ba0fDianne Hackborn                    switch (msg.what) {
1965e802fbb895a0ff4d9be1a72390f51c134a5ba0fDianne Hackborn                        case MSG_CLEAR_WALLPAPER:
1975e802fbb895a0ff4d9be1a72390f51c134a5ba0fDianne Hackborn                            synchronized (this) {
1985e802fbb895a0ff4d9be1a72390f51c134a5ba0fDianne Hackborn                                mWallpaper = null;
19919382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn                                mDefaultWallpaper = null;
2005e802fbb895a0ff4d9be1a72390f51c134a5ba0fDianne Hackborn                            }
2015e802fbb895a0ff4d9be1a72390f51c134a5ba0fDianne Hackborn                            break;
2025e802fbb895a0ff4d9be1a72390f51c134a5ba0fDianne Hackborn                    }
2035e802fbb895a0ff4d9be1a72390f51c134a5ba0fDianne Hackborn                }
2045e802fbb895a0ff4d9be1a72390f51c134a5ba0fDianne Hackborn            };
2058cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn        }
2068cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn
2078cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn        public void onWallpaperChanged() {
2088cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn            /* The wallpaper has changed but we shouldn't eagerly load the
2098cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn             * wallpaper as that would be inefficient. Reset the cached wallpaper
2108cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn             * to null so if the user requests the wallpaper again then we'll
2118cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn             * fetch it.
2128cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn             */
213840c3a2b7e29cd75c13418a90cce5e311415c843Dianne Hackborn            mHandler.sendEmptyMessage(MSG_CLEAR_WALLPAPER);
2148cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn        }
215041a0baba7f075ab3aba9c075dd75695a51617e4Adam Cohen
216041a0baba7f075ab3aba9c075dd75695a51617e4Adam Cohen        public Handler getHandler() {
217041a0baba7f075ab3aba9c075dd75695a51617e4Adam Cohen            return mHandler;
218041a0baba7f075ab3aba9c075dd75695a51617e4Adam Cohen        }
219041a0baba7f075ab3aba9c075dd75695a51617e4Adam Cohen
22019382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        public Bitmap peekWallpaperBitmap(Context context, boolean returnDefault) {
2218cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn            synchronized (this) {
2228cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn                if (mWallpaper != null) {
2238cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn                    return mWallpaper;
2248cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn                }
22519382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn                if (mDefaultWallpaper != null) {
22619382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn                    return mDefaultWallpaper;
22719382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn                }
228c9dbbe28f7879bd377114587ed1f40235a2d37caDianne Hackborn                mWallpaper = null;
229c9dbbe28f7879bd377114587ed1f40235a2d37caDianne Hackborn                try {
230407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy                    mWallpaper = getCurrentWallpaperLocked();
231c9dbbe28f7879bd377114587ed1f40235a2d37caDianne Hackborn                } catch (OutOfMemoryError e) {
232c9dbbe28f7879bd377114587ed1f40235a2d37caDianne Hackborn                    Log.w(TAG, "No memory load current wallpaper", e);
233c9dbbe28f7879bd377114587ed1f40235a2d37caDianne Hackborn                }
234ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn                if (returnDefault) {
235ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn                    if (mWallpaper == null) {
236ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn                        mDefaultWallpaper = getDefaultWallpaperLocked(context);
237ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn                        return mDefaultWallpaper;
238ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn                    } else {
239ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn                        mDefaultWallpaper = null;
240ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn                    }
24119382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn                }
2428cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn                return mWallpaper;
2438cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn            }
2448cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn        }
245ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn
246ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn        public void forgetLoadedWallpaper() {
247ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn            synchronized (this) {
248ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn                mWallpaper = null;
249ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn                mDefaultWallpaper = null;
250ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn            }
251ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn        }
252ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn
253407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy        private Bitmap getCurrentWallpaperLocked() {
2548cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn            try {
255284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn                Bundle params = new Bundle();
256284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn                ParcelFileDescriptor fd = mService.getWallpaper(this, params);
2578cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn                if (fd != null) {
258284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn                    int width = params.getInt("width", 0);
259284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn                    int height = params.getInt("height", 0);
26024572375323dee79e3b456af07640ca194fd40bfJeff Brown
26124572375323dee79e3b456af07640ca194fd40bfJeff Brown                    try {
26224572375323dee79e3b456af07640ca194fd40bfJeff Brown                        BitmapFactory.Options options = new BitmapFactory.Options();
26324572375323dee79e3b456af07640ca194fd40bfJeff Brown                        Bitmap bm = BitmapFactory.decodeFileDescriptor(
26424572375323dee79e3b456af07640ca194fd40bfJeff Brown                                fd.getFileDescriptor(), null, options);
265407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy                        return generateBitmap(bm, width, height);
26624572375323dee79e3b456af07640ca194fd40bfJeff Brown                    } catch (OutOfMemoryError e) {
26724572375323dee79e3b456af07640ca194fd40bfJeff Brown                        Log.w(TAG, "Can't decode file", e);
26824572375323dee79e3b456af07640ca194fd40bfJeff Brown                    } finally {
269284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn                        try {
270284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn                            fd.close();
271284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn                        } catch (IOException e) {
272407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy                            // Ignore
273284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn                        }
274284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn                    }
27519382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn                }
27619382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn            } catch (RemoteException e) {
277407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy                // Ignore
27819382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn            }
27919382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn            return null;
28019382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        }
28119382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn
28219382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        private Bitmap getDefaultWallpaperLocked(Context context) {
28319382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn            try {
28419382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn                InputStream is = context.getResources().openRawResource(
28519382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn                        com.android.internal.R.drawable.default_wallpaper);
28619382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn                if (is != null) {
28719382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn                    int width = mService.getWidthHint();
28819382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn                    int height = mService.getHeightHint();
28924572375323dee79e3b456af07640ca194fd40bfJeff Brown
29024572375323dee79e3b456af07640ca194fd40bfJeff Brown                    try {
29124572375323dee79e3b456af07640ca194fd40bfJeff Brown                        BitmapFactory.Options options = new BitmapFactory.Options();
29224572375323dee79e3b456af07640ca194fd40bfJeff Brown                        Bitmap bm = BitmapFactory.decodeStream(is, null, options);
293407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy                        return generateBitmap(bm, width, height);
29424572375323dee79e3b456af07640ca194fd40bfJeff Brown                    } catch (OutOfMemoryError e) {
29524572375323dee79e3b456af07640ca194fd40bfJeff Brown                        Log.w(TAG, "Can't decode stream", e);
29624572375323dee79e3b456af07640ca194fd40bfJeff Brown                    } finally {
29719382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn                        try {
29819382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn                            is.close();
29919382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn                        } catch (IOException e) {
300407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy                            // Ignore
301284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn                        }
302c9dbbe28f7879bd377114587ed1f40235a2d37caDianne Hackborn                    }
3038cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn                }
3048cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn            } catch (RemoteException e) {
305407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy                // Ignore
3068cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn            }
3078cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn            return null;
3088cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn        }
3098cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn    }
3108cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn
311407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    private static final Object sSync = new Object[0];
3128cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn    private static Globals sGlobals;
3138cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn
314840c3a2b7e29cd75c13418a90cce5e311415c843Dianne Hackborn    static void initGlobals(Looper looper) {
315407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy        synchronized (sSync) {
3168cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn            if (sGlobals == null) {
3175e802fbb895a0ff4d9be1a72390f51c134a5ba0fDianne Hackborn                sGlobals = new Globals(looper);
3188cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn            }
3198cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn        }
3208cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn    }
3218cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn
3228cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn    /*package*/ WallpaperManager(Context context, Handler handler) {
3238cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn        mContext = context;
324840c3a2b7e29cd75c13418a90cce5e311415c843Dianne Hackborn        initGlobals(context.getMainLooper());
3258cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn    }
3268cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn
3278cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn    /**
3284c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn     * Retrieve a WallpaperManager associated with the given Context.
3294c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn     */
3304c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    public static WallpaperManager getInstance(Context context) {
3314c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        return (WallpaperManager)context.getSystemService(
3324c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                Context.WALLPAPER_SERVICE);
3334c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    }
3344c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn
3354c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    /** @hide */
3364c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    public IWallpaperManager getIWallpaperManager() {
337840c3a2b7e29cd75c13418a90cce5e311415c843Dianne Hackborn        return sGlobals.mService;
3384c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    }
3394c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn
3404c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    /**
3418b2e000c43f5a93209be269a0b9e08943fad8d3cScott Main     * Retrieve the current system wallpaper; if
3428cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     * no wallpaper is set, the system default wallpaper is returned.
3438b2e000c43f5a93209be269a0b9e08943fad8d3cScott Main     * This is returned as an
3448b2e000c43f5a93209be269a0b9e08943fad8d3cScott Main     * abstract Drawable that you can install in a View to display whatever
3458b2e000c43f5a93209be269a0b9e08943fad8d3cScott Main     * wallpaper the user has currently set.
3468cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     *
3478cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     * @return Returns a Drawable object that will draw the wallpaper.
3488cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     */
3494c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    public Drawable getDrawable() {
35019382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, true);
35119382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        if (bm != null) {
35219382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn            Drawable dr = new BitmapDrawable(mContext.getResources(), bm);
35319382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn            dr.setDither(false);
35419382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn            return dr;
35519382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        }
35619382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        return null;
3578cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn    }
3588cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn
3598cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn    /**
3608b2e000c43f5a93209be269a0b9e08943fad8d3cScott Main     * Retrieve the current system wallpaper; if there is no wallpaper set,
3618b2e000c43f5a93209be269a0b9e08943fad8d3cScott Main     * a null pointer is returned. This is returned as an
3628cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     * abstract Drawable that you can install in a View to display whatever
3638b2e000c43f5a93209be269a0b9e08943fad8d3cScott Main     * wallpaper the user has currently set.
3648cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     *
3658cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     * @return Returns a Drawable object that will draw the wallpaper or a
3668cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     * null pointer if these is none.
3678cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     */
3684c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    public Drawable peekDrawable() {
36919382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, false);
37019382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        if (bm != null) {
37119382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn            Drawable dr = new BitmapDrawable(mContext.getResources(), bm);
37219382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn            dr.setDither(false);
37319382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn            return dr;
37419382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        }
37519382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        return null;
37619382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn    }
37719382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn
37819382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn    /**
3798b2e000c43f5a93209be269a0b9e08943fad8d3cScott Main     * Like {@link #getDrawable()}, but the returned Drawable has a number
3808b2e000c43f5a93209be269a0b9e08943fad8d3cScott Main     * of limitations to reduce its overhead as much as possible. It will
3818b2e000c43f5a93209be269a0b9e08943fad8d3cScott Main     * never scale the wallpaper (only centering it if the requested bounds
3828b2e000c43f5a93209be269a0b9e08943fad8d3cScott Main     * do match the bitmap bounds, which should not be typical), doesn't
3838b2e000c43f5a93209be269a0b9e08943fad8d3cScott Main     * allow setting an alpha, color filter, or other attributes, etc.  The
3848b2e000c43f5a93209be269a0b9e08943fad8d3cScott Main     * bounds of the returned drawable will be initialized to the same bounds
3858b2e000c43f5a93209be269a0b9e08943fad8d3cScott Main     * as the wallpaper, so normally you will not need to touch it.  The
3868b2e000c43f5a93209be269a0b9e08943fad8d3cScott Main     * drawable also assumes that it will be used in a context running in
3878b2e000c43f5a93209be269a0b9e08943fad8d3cScott Main     * the same density as the screen (not in density compatibility mode).
38819382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn     *
38919382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn     * @return Returns a Drawable object that will draw the wallpaper.
39019382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn     */
39119382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn    public Drawable getFastDrawable() {
39219382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, true);
39319382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        if (bm != null) {
394407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy            return new FastBitmapDrawable(bm);
39519382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        }
39619382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        return null;
39719382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn    }
39819382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn
39919382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn    /**
4008b2e000c43f5a93209be269a0b9e08943fad8d3cScott Main     * Like {@link #getFastDrawable()}, but if there is no wallpaper set,
4018b2e000c43f5a93209be269a0b9e08943fad8d3cScott Main     * a null pointer is returned.
40219382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn     *
40319382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn     * @return Returns an optimized Drawable object that will draw the
40419382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn     * wallpaper or a null pointer if these is none.
40519382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn     */
40619382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn    public Drawable peekFastDrawable() {
40719382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, false);
40819382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        if (bm != null) {
409407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy            return new FastBitmapDrawable(bm);
41019382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        }
41119382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        return null;
4128cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn    }
4138cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn
4148cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn    /**
415407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy     * Like {@link #getDrawable()} but returns a Bitmap.
416407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy     *
417407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy     * @hide
418407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy     */
419407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    public Bitmap getBitmap() {
420407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy        return sGlobals.peekWallpaperBitmap(mContext, true);
421407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    }
422407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy
423407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    /**
424ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn     * Remove all internal references to the last loaded wallpaper.  Useful
425ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn     * for apps that want to reduce memory usage when they only temporarily
426ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn     * need to have the wallpaper.  After calling, the next request for the
427ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn     * wallpaper will require reloading it again from disk.
428ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn     */
429ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn    public void forgetLoadedWallpaper() {
430ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn        sGlobals.forgetLoadedWallpaper();
431ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn    }
432ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn
433ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn    /**
434eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn     * If the current wallpaper is a live wallpaper component, return the
435eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn     * information about that wallpaper.  Otherwise, if it is a static image,
436eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn     * simply return null.
437eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn     */
438eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn    public WallpaperInfo getWallpaperInfo() {
439eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn        try {
440eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn            return sGlobals.mService.getWallpaperInfo();
441eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn        } catch (RemoteException e) {
442eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn            return null;
443eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn        }
444eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn    }
445eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn
446eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn    /**
4478cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     * Change the current system wallpaper to the bitmap in the given resource.
4488cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     * The resource is opened as a raw data stream and copied into the
4498cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     * wallpaper; it must be a valid PNG or JPEG image.  On success, the intent
4508cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     * {@link Intent#ACTION_WALLPAPER_CHANGED} is broadcast.
4518cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     *
4528cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     * @param resid The bitmap to save.
4538cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     *
4548cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     * @throws IOException If an error occurs reverting to the default
4558cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     * wallpaper.
4568cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     */
4574c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    public void setResource(int resid) throws IOException {
4588cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn        try {
4598cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn            Resources resources = mContext.getResources();
4608cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn            /* Set the wallpaper to the default values */
461840c3a2b7e29cd75c13418a90cce5e311415c843Dianne Hackborn            ParcelFileDescriptor fd = sGlobals.mService.setWallpaper(
4628cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn                    "res:" + resources.getResourceName(resid));
4638cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn            if (fd != null) {
4648cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn                FileOutputStream fos = null;
4658cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn                try {
4668cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn                    fos = new ParcelFileDescriptor.AutoCloseOutputStream(fd);
4678cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn                    setWallpaper(resources.openRawResource(resid), fos);
4688cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn                } finally {
4698cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn                    if (fos != null) {
4708cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn                        fos.close();
4718cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn                    }
4728cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn                }
4738cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn            }
4748cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn        } catch (RemoteException e) {
475407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy            // Ignore
4768cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn        }
4778cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn    }
4788cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn
4798cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn    /**
4808cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     * Change the current system wallpaper to a bitmap.  The given bitmap is
4818cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     * converted to a PNG and stored as the wallpaper.  On success, the intent
4828cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     * {@link Intent#ACTION_WALLPAPER_CHANGED} is broadcast.
4838cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     *
4848cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     * @param bitmap The bitmap to save.
4858cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     *
4868cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     * @throws IOException If an error occurs reverting to the default
4878cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     * wallpaper.
4888cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     */
4894c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    public void setBitmap(Bitmap bitmap) throws IOException {
4908cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn        try {
491840c3a2b7e29cd75c13418a90cce5e311415c843Dianne Hackborn            ParcelFileDescriptor fd = sGlobals.mService.setWallpaper(null);
4928cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn            if (fd == null) {
4938cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn                return;
4948cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn            }
4958cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn            FileOutputStream fos = null;
4968cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn            try {
4978cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn                fos = new ParcelFileDescriptor.AutoCloseOutputStream(fd);
4988cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn                bitmap.compress(Bitmap.CompressFormat.PNG, 90, fos);
4998cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn            } finally {
5008cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn                if (fos != null) {
5018cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn                    fos.close();
5028cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn                }
5038cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn            }
5048cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn        } catch (RemoteException e) {
505407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy            // Ignore
5068cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn        }
5078cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn    }
5088cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn
5098cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn    /**
5108cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     * Change the current system wallpaper to a specific byte stream.  The
5118cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     * give InputStream is copied into persistent storage and will now be
5128cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     * used as the wallpaper.  Currently it must be either a JPEG or PNG
5138cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     * image.  On success, the intent {@link Intent#ACTION_WALLPAPER_CHANGED}
5148cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     * is broadcast.
5158cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     *
5168cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     * @param data A stream containing the raw data to install as a wallpaper.
5178cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     *
5188cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     * @throws IOException If an error occurs reverting to the default
5198cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     * wallpaper.
5208cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     */
5214c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    public void setStream(InputStream data) throws IOException {
5228cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn        try {
523840c3a2b7e29cd75c13418a90cce5e311415c843Dianne Hackborn            ParcelFileDescriptor fd = sGlobals.mService.setWallpaper(null);
5248cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn            if (fd == null) {
5258cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn                return;
5268cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn            }
5278cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn            FileOutputStream fos = null;
5288cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn            try {
5298cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn                fos = new ParcelFileDescriptor.AutoCloseOutputStream(fd);
5308cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn                setWallpaper(data, fos);
5318cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn            } finally {
5328cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn                if (fos != null) {
5338cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn                    fos.close();
5348cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn                }
5358cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn            }
5368cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn        } catch (RemoteException e) {
537407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy            // Ignore
5388cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn        }
5398cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn    }
5408cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn
5418cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn    private void setWallpaper(InputStream data, FileOutputStream fos)
5428cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn            throws IOException {
5438cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn        byte[] buffer = new byte[32768];
5448cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn        int amt;
5458cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn        while ((amt=data.read(buffer)) > 0) {
5468cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn            fos.write(buffer, 0, amt);
5478cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn        }
5488cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn    }
5498cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn
5508cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn    /**
5518cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     * Returns the desired minimum width for the wallpaper. Callers of
5524c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn     * {@link #setBitmap(android.graphics.Bitmap)} or
5534c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn     * {@link #setStream(java.io.InputStream)} should check this value
5548cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     * beforehand to make sure the supplied wallpaper respects the desired
5558cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     * minimum width.
5568cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     *
5578cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     * If the returned value is <= 0, the caller should use the width of
5588cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     * the default display instead.
5598cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     *
5608cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     * @return The desired minimum width for the wallpaper. This value should
5618cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     * be honored by applications that set the wallpaper but it is not
5628cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     * mandatory.
5638cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     */
5648cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn    public int getDesiredMinimumWidth() {
5658cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn        try {
566840c3a2b7e29cd75c13418a90cce5e311415c843Dianne Hackborn            return sGlobals.mService.getWidthHint();
5678cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn        } catch (RemoteException e) {
5688cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn            // Shouldn't happen!
5698cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn            return 0;
5708cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn        }
5718cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn    }
5728cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn
5738cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn    /**
5748cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     * Returns the desired minimum height for the wallpaper. Callers of
5754c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn     * {@link #setBitmap(android.graphics.Bitmap)} or
5764c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn     * {@link #setStream(java.io.InputStream)} should check this value
5778cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     * beforehand to make sure the supplied wallpaper respects the desired
5788cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     * minimum height.
5798cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     *
5808cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     * If the returned value is <= 0, the caller should use the height of
5818cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     * the default display instead.
5828cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     *
5838cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     * @return The desired minimum height for the wallpaper. This value should
5848cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     * be honored by applications that set the wallpaper but it is not
5858cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     * mandatory.
5868cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     */
5878cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn    public int getDesiredMinimumHeight() {
5888cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn        try {
589840c3a2b7e29cd75c13418a90cce5e311415c843Dianne Hackborn            return sGlobals.mService.getHeightHint();
5908cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn        } catch (RemoteException e) {
5918cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn            // Shouldn't happen!
5928cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn            return 0;
5938cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn        }
5948cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn    }
5958cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn
5968cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn    /**
5978cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     * For use only by the current home application, to specify the size of
5988cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     * wallpaper it would like to use.  This allows such applications to have
5998cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     * a virtual wallpaper that is larger than the physical screen, matching
6008cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     * the size of their workspace.
6018cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     * @param minimumWidth Desired minimum width
6028cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     * @param minimumHeight Desired minimum height
6038cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     */
6044c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    public void suggestDesiredDimensions(int minimumWidth, int minimumHeight) {
6058cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn        try {
606840c3a2b7e29cd75c13418a90cce5e311415c843Dianne Hackborn            sGlobals.mService.setDimensionHints(minimumWidth, minimumHeight);
6078cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn        } catch (RemoteException e) {
608407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy            // Ignore
6098cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn        }
6108cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn    }
611041a0baba7f075ab3aba9c075dd75695a51617e4Adam Cohen
6128cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn    /**
613c8a0a75e1c61d1ab24bd46a8243041c107e738acDianne Hackborn     * Set the position of the current wallpaper within any larger space, when
614c8a0a75e1c61d1ab24bd46a8243041c107e738acDianne Hackborn     * that wallpaper is visible behind the given window.  The X and Y offsets
615c8a0a75e1c61d1ab24bd46a8243041c107e738acDianne Hackborn     * are floating point numbers ranging from 0 to 1, representing where the
616c8a0a75e1c61d1ab24bd46a8243041c107e738acDianne Hackborn     * wallpaper should be positioned within the screen space.  These only
617c8a0a75e1c61d1ab24bd46a8243041c107e738acDianne Hackborn     * make sense when the wallpaper is larger than the screen.
618c8a0a75e1c61d1ab24bd46a8243041c107e738acDianne Hackborn     *
619c8a0a75e1c61d1ab24bd46a8243041c107e738acDianne Hackborn     * @param windowToken The window who these offsets should be associated
6208b2e000c43f5a93209be269a0b9e08943fad8d3cScott Main     * with, as returned by {@link android.view.View#getWindowToken()
621c8a0a75e1c61d1ab24bd46a8243041c107e738acDianne Hackborn     * View.getWindowToken()}.
622bf6956b1d95442e9d9c483894d578fe6b7044cbbMarco Nelissen     * @param xOffset The offset along the X dimension, from 0 to 1.
623c8a0a75e1c61d1ab24bd46a8243041c107e738acDianne Hackborn     * @param yOffset The offset along the Y dimension, from 0 to 1.
624c8a0a75e1c61d1ab24bd46a8243041c107e738acDianne Hackborn     */
625c8a0a75e1c61d1ab24bd46a8243041c107e738acDianne Hackborn    public void setWallpaperOffsets(IBinder windowToken, float xOffset, float yOffset) {
626041a0baba7f075ab3aba9c075dd75695a51617e4Adam Cohen        final IBinder fWindowToken = windowToken;
627041a0baba7f075ab3aba9c075dd75695a51617e4Adam Cohen        final float fXOffset = xOffset;
628041a0baba7f075ab3aba9c075dd75695a51617e4Adam Cohen        final float fYOffset = yOffset;
629041a0baba7f075ab3aba9c075dd75695a51617e4Adam Cohen        sGlobals.getHandler().post(new Runnable() {
630041a0baba7f075ab3aba9c075dd75695a51617e4Adam Cohen            public void run() {
631041a0baba7f075ab3aba9c075dd75695a51617e4Adam Cohen                try {
632041a0baba7f075ab3aba9c075dd75695a51617e4Adam Cohen                    //Log.v(TAG, "Sending new wallpaper offsets from app...");
633041a0baba7f075ab3aba9c075dd75695a51617e4Adam Cohen                    ViewRootImpl.getWindowSession(mContext.getMainLooper()).setWallpaperPosition(
634041a0baba7f075ab3aba9c075dd75695a51617e4Adam Cohen                            fWindowToken, fXOffset, fYOffset, mWallpaperXStep, mWallpaperYStep);
635041a0baba7f075ab3aba9c075dd75695a51617e4Adam Cohen                    //Log.v(TAG, "...app returning after sending offsets!");
636041a0baba7f075ab3aba9c075dd75695a51617e4Adam Cohen                } catch (RemoteException e) {
637041a0baba7f075ab3aba9c075dd75695a51617e4Adam Cohen                    // Ignore.
6388e2e5722242c2b5cc02d433105c668f47ab84785Adam Cohen                } catch (IllegalArgumentException e) {
6398e2e5722242c2b5cc02d433105c668f47ab84785Adam Cohen                    // Since this is being posted, it's possible that this windowToken is no longer
6408e2e5722242c2b5cc02d433105c668f47ab84785Adam Cohen                    // valid, for example, if setWallpaperOffsets is called just before rotation.
641041a0baba7f075ab3aba9c075dd75695a51617e4Adam Cohen                }
642041a0baba7f075ab3aba9c075dd75695a51617e4Adam Cohen            }
643041a0baba7f075ab3aba9c075dd75695a51617e4Adam Cohen        });
6447580493b014a2c7ea883cd291255798dc72ebbffDianne Hackborn    }
645041a0baba7f075ab3aba9c075dd75695a51617e4Adam Cohen
6467580493b014a2c7ea883cd291255798dc72ebbffDianne Hackborn    /**
647bf6956b1d95442e9d9c483894d578fe6b7044cbbMarco Nelissen     * For applications that use multiple virtual screens showing a wallpaper,
648bf6956b1d95442e9d9c483894d578fe6b7044cbbMarco Nelissen     * specify the step size between virtual screens. For example, if the
64923ef7b4836d66d31430fedee2aac36275bb30d4bDianne Hackborn     * launcher has 3 virtual screens, it would specify an xStep of 0.5,
650bf6956b1d95442e9d9c483894d578fe6b7044cbbMarco Nelissen     * since the X offset for those screens are 0.0, 0.5 and 1.0
651bf6956b1d95442e9d9c483894d578fe6b7044cbbMarco Nelissen     * @param xStep The X offset delta from one screen to the next one
652bf6956b1d95442e9d9c483894d578fe6b7044cbbMarco Nelissen     * @param yStep The Y offset delta from one screen to the next one
653bf6956b1d95442e9d9c483894d578fe6b7044cbbMarco Nelissen     */
654bf6956b1d95442e9d9c483894d578fe6b7044cbbMarco Nelissen    public void setWallpaperOffsetSteps(float xStep, float yStep) {
655bf6956b1d95442e9d9c483894d578fe6b7044cbbMarco Nelissen        mWallpaperXStep = xStep;
656bf6956b1d95442e9d9c483894d578fe6b7044cbbMarco Nelissen        mWallpaperYStep = yStep;
657bf6956b1d95442e9d9c483894d578fe6b7044cbbMarco Nelissen    }
658bf6956b1d95442e9d9c483894d578fe6b7044cbbMarco Nelissen
659bf6956b1d95442e9d9c483894d578fe6b7044cbbMarco Nelissen    /**
6607580493b014a2c7ea883cd291255798dc72ebbffDianne Hackborn     * Send an arbitrary command to the current active wallpaper.
6617580493b014a2c7ea883cd291255798dc72ebbffDianne Hackborn     *
6627580493b014a2c7ea883cd291255798dc72ebbffDianne Hackborn     * @param windowToken The window who these offsets should be associated
6637580493b014a2c7ea883cd291255798dc72ebbffDianne Hackborn     * with, as returned by {@link android.view.View#getWindowToken()
6647580493b014a2c7ea883cd291255798dc72ebbffDianne Hackborn     * View.getWindowToken()}.
6657580493b014a2c7ea883cd291255798dc72ebbffDianne Hackborn     * @param action Name of the command to perform.  This must be a scoped
6667580493b014a2c7ea883cd291255798dc72ebbffDianne Hackborn     * name to avoid collisions, such as "com.mycompany.wallpaper.DOIT".
6677580493b014a2c7ea883cd291255798dc72ebbffDianne Hackborn     * @param x Arbitrary integer argument based on command.
6687580493b014a2c7ea883cd291255798dc72ebbffDianne Hackborn     * @param y Arbitrary integer argument based on command.
6697580493b014a2c7ea883cd291255798dc72ebbffDianne Hackborn     * @param z Arbitrary integer argument based on command.
6707580493b014a2c7ea883cd291255798dc72ebbffDianne Hackborn     * @param extras Optional additional information for the command, or null.
6717580493b014a2c7ea883cd291255798dc72ebbffDianne Hackborn     */
6727580493b014a2c7ea883cd291255798dc72ebbffDianne Hackborn    public void sendWallpaperCommand(IBinder windowToken, String action,
6737580493b014a2c7ea883cd291255798dc72ebbffDianne Hackborn            int x, int y, int z, Bundle extras) {
6747580493b014a2c7ea883cd291255798dc72ebbffDianne Hackborn        try {
6757580493b014a2c7ea883cd291255798dc72ebbffDianne Hackborn            //Log.v(TAG, "Sending new wallpaper offsets from app...");
6766dd005b48138708762bfade0081d031a2a4a3822Dianne Hackborn            ViewRootImpl.getWindowSession(mContext.getMainLooper()).sendWallpaperCommand(
6777580493b014a2c7ea883cd291255798dc72ebbffDianne Hackborn                    windowToken, action, x, y, z, extras, false);
6787580493b014a2c7ea883cd291255798dc72ebbffDianne Hackborn            //Log.v(TAG, "...app returning after sending offsets!");
679c8a0a75e1c61d1ab24bd46a8243041c107e738acDianne Hackborn        } catch (RemoteException e) {
680c8a0a75e1c61d1ab24bd46a8243041c107e738acDianne Hackborn            // Ignore.
681c8a0a75e1c61d1ab24bd46a8243041c107e738acDianne Hackborn        }
682c8a0a75e1c61d1ab24bd46a8243041c107e738acDianne Hackborn    }
683c8a0a75e1c61d1ab24bd46a8243041c107e738acDianne Hackborn
684c8a0a75e1c61d1ab24bd46a8243041c107e738acDianne Hackborn    /**
68572c82ab9923025a91bbabb32e56bfea27bfd083bDianne Hackborn     * Clear the offsets previously associated with this window through
68672c82ab9923025a91bbabb32e56bfea27bfd083bDianne Hackborn     * {@link #setWallpaperOffsets(IBinder, float, float)}.  This reverts
68772c82ab9923025a91bbabb32e56bfea27bfd083bDianne Hackborn     * the window to its default state, where it does not cause the wallpaper
68872c82ab9923025a91bbabb32e56bfea27bfd083bDianne Hackborn     * to scroll from whatever its last offsets were.
68972c82ab9923025a91bbabb32e56bfea27bfd083bDianne Hackborn     *
69072c82ab9923025a91bbabb32e56bfea27bfd083bDianne Hackborn     * @param windowToken The window who these offsets should be associated
6918b2e000c43f5a93209be269a0b9e08943fad8d3cScott Main     * with, as returned by {@link android.view.View#getWindowToken()
69272c82ab9923025a91bbabb32e56bfea27bfd083bDianne Hackborn     * View.getWindowToken()}.
69372c82ab9923025a91bbabb32e56bfea27bfd083bDianne Hackborn     */
69472c82ab9923025a91bbabb32e56bfea27bfd083bDianne Hackborn    public void clearWallpaperOffsets(IBinder windowToken) {
69572c82ab9923025a91bbabb32e56bfea27bfd083bDianne Hackborn        try {
6966dd005b48138708762bfade0081d031a2a4a3822Dianne Hackborn            ViewRootImpl.getWindowSession(mContext.getMainLooper()).setWallpaperPosition(
697bf6956b1d95442e9d9c483894d578fe6b7044cbbMarco Nelissen                    windowToken, -1, -1, -1, -1);
69872c82ab9923025a91bbabb32e56bfea27bfd083bDianne Hackborn        } catch (RemoteException e) {
69972c82ab9923025a91bbabb32e56bfea27bfd083bDianne Hackborn            // Ignore.
70072c82ab9923025a91bbabb32e56bfea27bfd083bDianne Hackborn        }
70172c82ab9923025a91bbabb32e56bfea27bfd083bDianne Hackborn    }
70272c82ab9923025a91bbabb32e56bfea27bfd083bDianne Hackborn
70372c82ab9923025a91bbabb32e56bfea27bfd083bDianne Hackborn    /**
7048cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     * Remove any currently set wallpaper, reverting to the system's default
7058cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     * wallpaper. On success, the intent {@link Intent#ACTION_WALLPAPER_CHANGED}
7068cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     * is broadcast.
7078cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     *
7088cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     * @throws IOException If an error occurs reverting to the default
7098cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     * wallpaper.
7108cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn     */
7118cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn    public void clear() throws IOException {
7124c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        setResource(com.android.internal.R.drawable.default_wallpaper);
7138cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn    }
71419382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn
715407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    static Bitmap generateBitmap(Bitmap bm, int width, int height) {
71619382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        if (bm == null) {
71724572375323dee79e3b456af07640ca194fd40bfJeff Brown            return null;
71819382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        }
71924572375323dee79e3b456af07640ca194fd40bfJeff Brown
72019382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        bm.setDensity(DisplayMetrics.DENSITY_DEVICE);
72124572375323dee79e3b456af07640ca194fd40bfJeff Brown
722038b737c7561e6a92edcd6267f1299d2602f1920Jeff Brown        if (width <= 0 || height <= 0
723038b737c7561e6a92edcd6267f1299d2602f1920Jeff Brown                || (bm.getWidth() == width && bm.getHeight() == height)) {
72424572375323dee79e3b456af07640ca194fd40bfJeff Brown            return bm;
72524572375323dee79e3b456af07640ca194fd40bfJeff Brown        }
72624572375323dee79e3b456af07640ca194fd40bfJeff Brown
72719382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        // This is the final bitmap we want to return.
72824572375323dee79e3b456af07640ca194fd40bfJeff Brown        try {
72924572375323dee79e3b456af07640ca194fd40bfJeff Brown            Bitmap newbm = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
73024572375323dee79e3b456af07640ca194fd40bfJeff Brown            newbm.setDensity(DisplayMetrics.DENSITY_DEVICE);
73124572375323dee79e3b456af07640ca194fd40bfJeff Brown
73224572375323dee79e3b456af07640ca194fd40bfJeff Brown            Canvas c = new Canvas(newbm);
73324572375323dee79e3b456af07640ca194fd40bfJeff Brown            Rect targetRect = new Rect();
73424572375323dee79e3b456af07640ca194fd40bfJeff Brown            targetRect.right = bm.getWidth();
73524572375323dee79e3b456af07640ca194fd40bfJeff Brown            targetRect.bottom = bm.getHeight();
73624572375323dee79e3b456af07640ca194fd40bfJeff Brown
73724572375323dee79e3b456af07640ca194fd40bfJeff Brown            int deltaw = width - targetRect.right;
73824572375323dee79e3b456af07640ca194fd40bfJeff Brown            int deltah = height - targetRect.bottom;
73924572375323dee79e3b456af07640ca194fd40bfJeff Brown
74024572375323dee79e3b456af07640ca194fd40bfJeff Brown            if (deltaw > 0 || deltah > 0) {
74124572375323dee79e3b456af07640ca194fd40bfJeff Brown                // We need to scale up so it covers the entire area.
742407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy                float scale;
74324572375323dee79e3b456af07640ca194fd40bfJeff Brown                if (deltaw > deltah) {
74424572375323dee79e3b456af07640ca194fd40bfJeff Brown                    scale = width / (float)targetRect.right;
74524572375323dee79e3b456af07640ca194fd40bfJeff Brown                } else {
74624572375323dee79e3b456af07640ca194fd40bfJeff Brown                    scale = height / (float)targetRect.bottom;
74724572375323dee79e3b456af07640ca194fd40bfJeff Brown                }
74824572375323dee79e3b456af07640ca194fd40bfJeff Brown                targetRect.right = (int)(targetRect.right*scale);
74924572375323dee79e3b456af07640ca194fd40bfJeff Brown                targetRect.bottom = (int)(targetRect.bottom*scale);
75024572375323dee79e3b456af07640ca194fd40bfJeff Brown                deltaw = width - targetRect.right;
75124572375323dee79e3b456af07640ca194fd40bfJeff Brown                deltah = height - targetRect.bottom;
75219382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn            }
75324572375323dee79e3b456af07640ca194fd40bfJeff Brown
75424572375323dee79e3b456af07640ca194fd40bfJeff Brown            targetRect.offset(deltaw/2, deltah/2);
75524572375323dee79e3b456af07640ca194fd40bfJeff Brown
75624572375323dee79e3b456af07640ca194fd40bfJeff Brown            Paint paint = new Paint();
75724572375323dee79e3b456af07640ca194fd40bfJeff Brown            paint.setFilterBitmap(true);
75824572375323dee79e3b456af07640ca194fd40bfJeff Brown            paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
75924572375323dee79e3b456af07640ca194fd40bfJeff Brown            c.drawBitmap(bm, null, targetRect, paint);
76024572375323dee79e3b456af07640ca194fd40bfJeff Brown
76124572375323dee79e3b456af07640ca194fd40bfJeff Brown            bm.recycle();
762ba39839444532af0ed3766f736582413f6d7a40bDianne Hackborn            c.setBitmap(null);
76324572375323dee79e3b456af07640ca194fd40bfJeff Brown            return newbm;
76424572375323dee79e3b456af07640ca194fd40bfJeff Brown        } catch (OutOfMemoryError e) {
76524572375323dee79e3b456af07640ca194fd40bfJeff Brown            Log.w(TAG, "Can't generate default bitmap", e);
76624572375323dee79e3b456af07640ca194fd40bfJeff Brown            return bm;
76719382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn        }
76819382ac1a4e4e7c23a1346d299368763f149de9cDianne Hackborn    }
7698cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn}
770