BackgroundManager.java revision b70539172cdeb5672ed7128f69383d1fc1458ccb
117993c442c26161f684d6c0c6867a746f3148548Craig Stout/* 217993c442c26161f684d6c0c6867a746f3148548Craig Stout * Copyright (C) 2014 The Android Open Source Project 317993c442c26161f684d6c0c6867a746f3148548Craig Stout * 417993c442c26161f684d6c0c6867a746f3148548Craig Stout * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 517993c442c26161f684d6c0c6867a746f3148548Craig Stout * in compliance with the License. You may obtain a copy of the License at 617993c442c26161f684d6c0c6867a746f3148548Craig Stout * 717993c442c26161f684d6c0c6867a746f3148548Craig Stout * http://www.apache.org/licenses/LICENSE-2.0 817993c442c26161f684d6c0c6867a746f3148548Craig Stout * 917993c442c26161f684d6c0c6867a746f3148548Craig Stout * Unless required by applicable law or agreed to in writing, software distributed under the License 1017993c442c26161f684d6c0c6867a746f3148548Craig Stout * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 1117993c442c26161f684d6c0c6867a746f3148548Craig Stout * or implied. See the License for the specific language governing permissions and limitations under 1217993c442c26161f684d6c0c6867a746f3148548Craig Stout * the License. 1317993c442c26161f684d6c0c6867a746f3148548Craig Stout */ 1417993c442c26161f684d6c0c6867a746f3148548Craig Stoutpackage android.support.v17.leanback.app; 1517993c442c26161f684d6c0c6867a746f3148548Craig Stout 1617993c442c26161f684d6c0c6867a746f3148548Craig Stoutimport android.support.v17.leanback.R; 1717993c442c26161f684d6c0c6867a746f3148548Craig Stoutimport android.animation.ObjectAnimator; 1817993c442c26161f684d6c0c6867a746f3148548Craig Stoutimport android.app.Activity; 1917993c442c26161f684d6c0c6867a746f3148548Craig Stoutimport android.content.Context; 2017993c442c26161f684d6c0c6867a746f3148548Craig Stoutimport android.content.res.TypedArray; 2117993c442c26161f684d6c0c6867a746f3148548Craig Stoutimport android.graphics.Bitmap; 2217993c442c26161f684d6c0c6867a746f3148548Craig Stoutimport android.graphics.Color; 2317993c442c26161f684d6c0c6867a746f3148548Craig Stoutimport android.graphics.Matrix; 2417993c442c26161f684d6c0c6867a746f3148548Craig Stoutimport android.graphics.drawable.BitmapDrawable; 2517993c442c26161f684d6c0c6867a746f3148548Craig Stoutimport android.graphics.drawable.ColorDrawable; 2617993c442c26161f684d6c0c6867a746f3148548Craig Stoutimport android.graphics.drawable.Drawable; 2717993c442c26161f684d6c0c6867a746f3148548Craig Stoutimport android.graphics.drawable.LayerDrawable; 2817993c442c26161f684d6c0c6867a746f3148548Craig Stoutimport android.os.Handler; 2917993c442c26161f684d6c0c6867a746f3148548Craig Stoutimport android.util.Log; 3017993c442c26161f684d6c0c6867a746f3148548Craig Stoutimport android.view.Gravity; 3117993c442c26161f684d6c0c6867a746f3148548Craig Stoutimport android.view.LayoutInflater; 3217993c442c26161f684d6c0c6867a746f3148548Craig Stoutimport android.view.View; 3317993c442c26161f684d6c0c6867a746f3148548Craig Stoutimport android.view.ViewGroup; 3417993c442c26161f684d6c0c6867a746f3148548Craig Stoutimport android.view.Window; 3517993c442c26161f684d6c0c6867a746f3148548Craig Stoutimport android.view.WindowManager; 3617993c442c26161f684d6c0c6867a746f3148548Craig Stoutimport android.view.animation.LinearInterpolator; 3717993c442c26161f684d6c0c6867a746f3148548Craig Stout 3817993c442c26161f684d6c0c6867a746f3148548Craig Stout/** 3917993c442c26161f684d6c0c6867a746f3148548Craig Stout * Supports background continuity between multiple activities. 4017993c442c26161f684d6c0c6867a746f3148548Craig Stout * 411c33346ba79177e64fe33da70ee73547d7bb15f7Craig Stout * An activity should instantiate a BackgroundManager and {@link #attach} 4217993c442c26161f684d6c0c6867a746f3148548Craig Stout * to the activity's window. When the activity is started, the background is 4317993c442c26161f684d6c0c6867a746f3148548Craig Stout * initialized to the current background values stored in a continuity service. 4417993c442c26161f684d6c0c6867a746f3148548Craig Stout * The background continuity service is updated as the background is updated. 4517993c442c26161f684d6c0c6867a746f3148548Craig Stout * 4617993c442c26161f684d6c0c6867a746f3148548Craig Stout * At some point, for example when stopped, the activity may release its background 4717993c442c26161f684d6c0c6867a746f3148548Craig Stout * state. The background may then be resumed, again from the continuity service. 4817993c442c26161f684d6c0c6867a746f3148548Craig Stout * 4917993c442c26161f684d6c0c6867a746f3148548Craig Stout * When the last activity is destroyed, the background state is reset. 5017993c442c26161f684d6c0c6867a746f3148548Craig Stout * 5117993c442c26161f684d6c0c6867a746f3148548Craig Stout * Backgrounds consist of several layers, from back to front: 5217993c442c26161f684d6c0c6867a746f3148548Craig Stout * - the background drawable of the theme 5317993c442c26161f684d6c0c6867a746f3148548Craig Stout * - a solid color (set via setColor) 5417993c442c26161f684d6c0c6867a746f3148548Craig Stout * - two drawables, previous and current (set via setBitmap or setDrawable), 5517993c442c26161f684d6c0c6867a746f3148548Craig Stout * which may be in transition 5617993c442c26161f684d6c0c6867a746f3148548Craig Stout * 5717993c442c26161f684d6c0c6867a746f3148548Craig Stout * BackgroundManager holds references to potentially large bitmap drawables. 581c33346ba79177e64fe33da70ee73547d7bb15f7Craig Stout * Call {@link #release} to release these references when the activity is not 5917993c442c26161f684d6c0c6867a746f3148548Craig Stout * visible. 6017993c442c26161f684d6c0c6867a746f3148548Craig Stout * 6117993c442c26161f684d6c0c6867a746f3148548Craig Stout * TODO: support for multiple app processes requires a proper android service 6217993c442c26161f684d6c0c6867a746f3148548Craig Stout * instead of the shared memory "service" implemented here. Such a service could 6317993c442c26161f684d6c0c6867a746f3148548Craig Stout * support continuity between fragments of different applications if desired. 6417993c442c26161f684d6c0c6867a746f3148548Craig Stout */ 6517993c442c26161f684d6c0c6867a746f3148548Craig Stoutpublic final class BackgroundManager { 6617993c442c26161f684d6c0c6867a746f3148548Craig Stout private static final String TAG = "BackgroundManager"; 6717993c442c26161f684d6c0c6867a746f3148548Craig Stout private static final boolean DEBUG = false; 6817993c442c26161f684d6c0c6867a746f3148548Craig Stout 6917993c442c26161f684d6c0c6867a746f3148548Craig Stout private static final int FULL_ALPHA = 255; 7017993c442c26161f684d6c0c6867a746f3148548Craig Stout private static final int DIM_ALPHA_ON_SOLID = (int) (0.8f * FULL_ALPHA); 7117993c442c26161f684d6c0c6867a746f3148548Craig Stout private static final int CHANGE_BG_DELAY_MS = 500; 7217993c442c26161f684d6c0c6867a746f3148548Craig Stout private static final int FADE_DURATION_QUICK = 200; 7317993c442c26161f684d6c0c6867a746f3148548Craig Stout private static final int FADE_DURATION_SLOW = 1000; 7417993c442c26161f684d6c0c6867a746f3148548Craig Stout 7517993c442c26161f684d6c0c6867a746f3148548Craig Stout /** 7617993c442c26161f684d6c0c6867a746f3148548Craig Stout * Using a separate window for backgrounds can improve graphics performance by 7717993c442c26161f684d6c0c6867a746f3148548Craig Stout * leveraging hardware display layers. 7817993c442c26161f684d6c0c6867a746f3148548Craig Stout * TODO: support a leanback configuration option. 7917993c442c26161f684d6c0c6867a746f3148548Craig Stout */ 8017993c442c26161f684d6c0c6867a746f3148548Craig Stout private static final boolean USE_SEPARATE_WINDOW = false; 8117993c442c26161f684d6c0c6867a746f3148548Craig Stout 8217993c442c26161f684d6c0c6867a746f3148548Craig Stout /** 8317993c442c26161f684d6c0c6867a746f3148548Craig Stout * If true, bitmaps will be scaled to the exact display size. 8417993c442c26161f684d6c0c6867a746f3148548Craig Stout * Small bitmaps will be scaled up, using more memory but improving display quality. 8517993c442c26161f684d6c0c6867a746f3148548Craig Stout * Large bitmaps will be scaled down to use less memory. 8617993c442c26161f684d6c0c6867a746f3148548Craig Stout * Introduces an allocation overhead. 8717993c442c26161f684d6c0c6867a746f3148548Craig Stout * TODO: support a leanback configuration option. 8817993c442c26161f684d6c0c6867a746f3148548Craig Stout */ 8917993c442c26161f684d6c0c6867a746f3148548Craig Stout private static final boolean SCALE_BITMAPS_TO_FIT = true; 9017993c442c26161f684d6c0c6867a746f3148548Craig Stout 9117993c442c26161f684d6c0c6867a746f3148548Craig Stout private static final String WINDOW_NAME = "BackgroundManager"; 9217993c442c26161f684d6c0c6867a746f3148548Craig Stout 9317993c442c26161f684d6c0c6867a746f3148548Craig Stout private Context mContext; 9417993c442c26161f684d6c0c6867a746f3148548Craig Stout private Handler mHandler; 9517993c442c26161f684d6c0c6867a746f3148548Craig Stout private Window mWindow; 9617993c442c26161f684d6c0c6867a746f3148548Craig Stout private WindowManager mWindowManager; 9717993c442c26161f684d6c0c6867a746f3148548Craig Stout private View mBgView; 9817993c442c26161f684d6c0c6867a746f3148548Craig Stout private BackgroundContinuityService mService; 9917993c442c26161f684d6c0c6867a746f3148548Craig Stout private int mThemeDrawableResourceId; 10017993c442c26161f684d6c0c6867a746f3148548Craig Stout 10117993c442c26161f684d6c0c6867a746f3148548Craig Stout private int mHeightPx; 10217993c442c26161f684d6c0c6867a746f3148548Craig Stout private int mWidthPx; 10317993c442c26161f684d6c0c6867a746f3148548Craig Stout private Drawable mBackgroundDrawable; 10417993c442c26161f684d6c0c6867a746f3148548Craig Stout private int mBackgroundColor; 10517993c442c26161f684d6c0c6867a746f3148548Craig Stout private boolean mAttached; 10617993c442c26161f684d6c0c6867a746f3148548Craig Stout 10717993c442c26161f684d6c0c6867a746f3148548Craig Stout private class DrawableWrapper { 10817993c442c26161f684d6c0c6867a746f3148548Craig Stout protected int mAlpha; 10917993c442c26161f684d6c0c6867a746f3148548Craig Stout protected Drawable mDrawable; 11017993c442c26161f684d6c0c6867a746f3148548Craig Stout protected ObjectAnimator mAnimator; 11117993c442c26161f684d6c0c6867a746f3148548Craig Stout protected boolean mAnimationPending; 11217993c442c26161f684d6c0c6867a746f3148548Craig Stout 11317993c442c26161f684d6c0c6867a746f3148548Craig Stout public DrawableWrapper(Drawable drawable) { 11417993c442c26161f684d6c0c6867a746f3148548Craig Stout mDrawable = drawable; 11517993c442c26161f684d6c0c6867a746f3148548Craig Stout setAlpha(FULL_ALPHA); 11617993c442c26161f684d6c0c6867a746f3148548Craig Stout } 11717993c442c26161f684d6c0c6867a746f3148548Craig Stout 11817993c442c26161f684d6c0c6867a746f3148548Craig Stout public Drawable getDrawable() { 11917993c442c26161f684d6c0c6867a746f3148548Craig Stout return mDrawable; 12017993c442c26161f684d6c0c6867a746f3148548Craig Stout } 12117993c442c26161f684d6c0c6867a746f3148548Craig Stout public void setAlpha(int alpha) { 12217993c442c26161f684d6c0c6867a746f3148548Craig Stout mAlpha = alpha; 12317993c442c26161f684d6c0c6867a746f3148548Craig Stout mDrawable.setAlpha(alpha); 12417993c442c26161f684d6c0c6867a746f3148548Craig Stout } 12517993c442c26161f684d6c0c6867a746f3148548Craig Stout public int getAlpha() { 12617993c442c26161f684d6c0c6867a746f3148548Craig Stout return mAlpha; 12717993c442c26161f684d6c0c6867a746f3148548Craig Stout } 12817993c442c26161f684d6c0c6867a746f3148548Craig Stout public void setColor(int color) { 12917993c442c26161f684d6c0c6867a746f3148548Craig Stout ((ColorDrawable) mDrawable).setColor(color); 13017993c442c26161f684d6c0c6867a746f3148548Craig Stout } 13117993c442c26161f684d6c0c6867a746f3148548Craig Stout public void fadeIn(int durationMs, int delayMs) { 13217993c442c26161f684d6c0c6867a746f3148548Craig Stout fade(durationMs, delayMs, FULL_ALPHA); 13317993c442c26161f684d6c0c6867a746f3148548Craig Stout } 13417993c442c26161f684d6c0c6867a746f3148548Craig Stout public void fadeOut(int durationMs) { 13517993c442c26161f684d6c0c6867a746f3148548Craig Stout fade(durationMs, 0, 0); 13617993c442c26161f684d6c0c6867a746f3148548Craig Stout } 13717993c442c26161f684d6c0c6867a746f3148548Craig Stout public void fade(int durationMs, int delayMs, int alpha) { 13817993c442c26161f684d6c0c6867a746f3148548Craig Stout if (mAnimator != null && mAnimator.isStarted()) { 13917993c442c26161f684d6c0c6867a746f3148548Craig Stout mAnimator.cancel(); 14017993c442c26161f684d6c0c6867a746f3148548Craig Stout } 14117993c442c26161f684d6c0c6867a746f3148548Craig Stout mAnimator = ObjectAnimator.ofInt(this, "alpha", alpha); 14217993c442c26161f684d6c0c6867a746f3148548Craig Stout mAnimator.setInterpolator(new LinearInterpolator()); 14317993c442c26161f684d6c0c6867a746f3148548Craig Stout mAnimator.setDuration(durationMs); 14417993c442c26161f684d6c0c6867a746f3148548Craig Stout mAnimator.setStartDelay(delayMs); 14517993c442c26161f684d6c0c6867a746f3148548Craig Stout mAnimationPending = true; 14617993c442c26161f684d6c0c6867a746f3148548Craig Stout } 14717993c442c26161f684d6c0c6867a746f3148548Craig Stout public boolean isAnimationPending() { 14817993c442c26161f684d6c0c6867a746f3148548Craig Stout return mAnimationPending; 14917993c442c26161f684d6c0c6867a746f3148548Craig Stout } 15017993c442c26161f684d6c0c6867a746f3148548Craig Stout public boolean isAnimationStarted() { 15117993c442c26161f684d6c0c6867a746f3148548Craig Stout return mAnimator != null && mAnimator.isStarted(); 15217993c442c26161f684d6c0c6867a746f3148548Craig Stout } 15317993c442c26161f684d6c0c6867a746f3148548Craig Stout public void startAnimation() { 15417993c442c26161f684d6c0c6867a746f3148548Craig Stout mAnimator.start(); 15517993c442c26161f684d6c0c6867a746f3148548Craig Stout mAnimationPending = false; 15617993c442c26161f684d6c0c6867a746f3148548Craig Stout } 15717993c442c26161f684d6c0c6867a746f3148548Craig Stout } 15817993c442c26161f684d6c0c6867a746f3148548Craig Stout 15917993c442c26161f684d6c0c6867a746f3148548Craig Stout private LayerDrawable mLayerDrawable; 16017993c442c26161f684d6c0c6867a746f3148548Craig Stout private DrawableWrapper mLayerWrapper; 16117993c442c26161f684d6c0c6867a746f3148548Craig Stout private DrawableWrapper mImageInWrapper; 16217993c442c26161f684d6c0c6867a746f3148548Craig Stout private DrawableWrapper mImageOutWrapper; 16317993c442c26161f684d6c0c6867a746f3148548Craig Stout private DrawableWrapper mColorWrapper; 16417993c442c26161f684d6c0c6867a746f3148548Craig Stout private DrawableWrapper mDimWrapper; 16517993c442c26161f684d6c0c6867a746f3148548Craig Stout 16617993c442c26161f684d6c0c6867a746f3148548Craig Stout private Drawable mThemeDrawable; 16717993c442c26161f684d6c0c6867a746f3148548Craig Stout private ChangeBackgroundRunnable mChangeRunnable; 16817993c442c26161f684d6c0c6867a746f3148548Craig Stout 16917993c442c26161f684d6c0c6867a746f3148548Craig Stout /** 17017993c442c26161f684d6c0c6867a746f3148548Craig Stout * Shared memory continuity service. 17117993c442c26161f684d6c0c6867a746f3148548Craig Stout */ 17217993c442c26161f684d6c0c6867a746f3148548Craig Stout private static class BackgroundContinuityService { 17317993c442c26161f684d6c0c6867a746f3148548Craig Stout private static final String TAG = "BackgroundContinuityService"; 17417993c442c26161f684d6c0c6867a746f3148548Craig Stout private static boolean DEBUG = BackgroundManager.DEBUG; 17517993c442c26161f684d6c0c6867a746f3148548Craig Stout 17617993c442c26161f684d6c0c6867a746f3148548Craig Stout private static BackgroundContinuityService sService = new BackgroundContinuityService(); 17717993c442c26161f684d6c0c6867a746f3148548Craig Stout 17817993c442c26161f684d6c0c6867a746f3148548Craig Stout private int mColor; 17917993c442c26161f684d6c0c6867a746f3148548Craig Stout private Drawable mDrawable; 18017993c442c26161f684d6c0c6867a746f3148548Craig Stout private int mCount; 18117993c442c26161f684d6c0c6867a746f3148548Craig Stout 18217993c442c26161f684d6c0c6867a746f3148548Craig Stout private BackgroundContinuityService() { 18317993c442c26161f684d6c0c6867a746f3148548Craig Stout reset(); 18417993c442c26161f684d6c0c6867a746f3148548Craig Stout } 18517993c442c26161f684d6c0c6867a746f3148548Craig Stout 18617993c442c26161f684d6c0c6867a746f3148548Craig Stout private void reset() { 18717993c442c26161f684d6c0c6867a746f3148548Craig Stout mColor = Color.TRANSPARENT; 18817993c442c26161f684d6c0c6867a746f3148548Craig Stout mDrawable = null; 18917993c442c26161f684d6c0c6867a746f3148548Craig Stout } 19017993c442c26161f684d6c0c6867a746f3148548Craig Stout 19117993c442c26161f684d6c0c6867a746f3148548Craig Stout public static BackgroundContinuityService getInstance() { 19217993c442c26161f684d6c0c6867a746f3148548Craig Stout final int count = sService.mCount++; 19317993c442c26161f684d6c0c6867a746f3148548Craig Stout if (DEBUG) Log.v(TAG, "Returning instance with new count " + count); 19417993c442c26161f684d6c0c6867a746f3148548Craig Stout return sService; 19517993c442c26161f684d6c0c6867a746f3148548Craig Stout } 19617993c442c26161f684d6c0c6867a746f3148548Craig Stout 19717993c442c26161f684d6c0c6867a746f3148548Craig Stout public void unref() { 19817993c442c26161f684d6c0c6867a746f3148548Craig Stout if (mCount <= 0) throw new IllegalStateException("Can't unref, count " + mCount); 19917993c442c26161f684d6c0c6867a746f3148548Craig Stout if (--mCount == 0) { 20017993c442c26161f684d6c0c6867a746f3148548Craig Stout if (DEBUG) Log.v(TAG, "mCount is zero, resetting"); 20117993c442c26161f684d6c0c6867a746f3148548Craig Stout reset(); 20217993c442c26161f684d6c0c6867a746f3148548Craig Stout } 20317993c442c26161f684d6c0c6867a746f3148548Craig Stout } 20417993c442c26161f684d6c0c6867a746f3148548Craig Stout public int getColor() { 20517993c442c26161f684d6c0c6867a746f3148548Craig Stout return mColor; 20617993c442c26161f684d6c0c6867a746f3148548Craig Stout } 20717993c442c26161f684d6c0c6867a746f3148548Craig Stout public Drawable getDrawable() { 20817993c442c26161f684d6c0c6867a746f3148548Craig Stout return mDrawable; 20917993c442c26161f684d6c0c6867a746f3148548Craig Stout } 21017993c442c26161f684d6c0c6867a746f3148548Craig Stout public void setColor(int color) { 21117993c442c26161f684d6c0c6867a746f3148548Craig Stout mColor = color; 21217993c442c26161f684d6c0c6867a746f3148548Craig Stout } 21317993c442c26161f684d6c0c6867a746f3148548Craig Stout public void setDrawable(Drawable drawable) { 21417993c442c26161f684d6c0c6867a746f3148548Craig Stout mDrawable = drawable; 21517993c442c26161f684d6c0c6867a746f3148548Craig Stout } 21617993c442c26161f684d6c0c6867a746f3148548Craig Stout } 21717993c442c26161f684d6c0c6867a746f3148548Craig Stout 21817993c442c26161f684d6c0c6867a746f3148548Craig Stout private Drawable getThemeDrawable() { 21917993c442c26161f684d6c0c6867a746f3148548Craig Stout Drawable drawable = null; 22017993c442c26161f684d6c0c6867a746f3148548Craig Stout if (mThemeDrawableResourceId != -1) { 22117993c442c26161f684d6c0c6867a746f3148548Craig Stout drawable = mContext.getResources().getDrawable(mThemeDrawableResourceId); 22217993c442c26161f684d6c0c6867a746f3148548Craig Stout } 22317993c442c26161f684d6c0c6867a746f3148548Craig Stout if (drawable == null) { 22417993c442c26161f684d6c0c6867a746f3148548Craig Stout drawable = createEmptyDrawable(); 22517993c442c26161f684d6c0c6867a746f3148548Craig Stout } 22617993c442c26161f684d6c0c6867a746f3148548Craig Stout return drawable; 22717993c442c26161f684d6c0c6867a746f3148548Craig Stout } 22817993c442c26161f684d6c0c6867a746f3148548Craig Stout 22917993c442c26161f684d6c0c6867a746f3148548Craig Stout /** 23017993c442c26161f684d6c0c6867a746f3148548Craig Stout * Construct a background manager instance. 23117993c442c26161f684d6c0c6867a746f3148548Craig Stout * Initial background set from continuity service. 23217993c442c26161f684d6c0c6867a746f3148548Craig Stout */ 23317993c442c26161f684d6c0c6867a746f3148548Craig Stout public BackgroundManager(Activity activity) { 23417993c442c26161f684d6c0c6867a746f3148548Craig Stout mContext = activity; 23517993c442c26161f684d6c0c6867a746f3148548Craig Stout mService = BackgroundContinuityService.getInstance(); 23617993c442c26161f684d6c0c6867a746f3148548Craig Stout mHeightPx = mContext.getResources().getDisplayMetrics().heightPixels; 23717993c442c26161f684d6c0c6867a746f3148548Craig Stout mWidthPx = mContext.getResources().getDisplayMetrics().widthPixels; 23817993c442c26161f684d6c0c6867a746f3148548Craig Stout mHandler = new Handler(); 23917993c442c26161f684d6c0c6867a746f3148548Craig Stout 24017993c442c26161f684d6c0c6867a746f3148548Craig Stout TypedArray ta = activity.getTheme().obtainStyledAttributes(new int[] { 24117993c442c26161f684d6c0c6867a746f3148548Craig Stout android.R.attr.windowBackground }); 24217993c442c26161f684d6c0c6867a746f3148548Craig Stout mThemeDrawableResourceId = ta.getResourceId(0, -1); 24317993c442c26161f684d6c0c6867a746f3148548Craig Stout if (mThemeDrawableResourceId < 0) { 24417993c442c26161f684d6c0c6867a746f3148548Craig Stout if (DEBUG) Log.v(TAG, "BackgroundManager no window background resource!"); 24517993c442c26161f684d6c0c6867a746f3148548Craig Stout } 24617993c442c26161f684d6c0c6867a746f3148548Craig Stout ta.recycle(); 24717993c442c26161f684d6c0c6867a746f3148548Craig Stout 24817993c442c26161f684d6c0c6867a746f3148548Craig Stout createFragment(activity); 24917993c442c26161f684d6c0c6867a746f3148548Craig Stout 25017993c442c26161f684d6c0c6867a746f3148548Craig Stout syncWithService(); 25117993c442c26161f684d6c0c6867a746f3148548Craig Stout } 25217993c442c26161f684d6c0c6867a746f3148548Craig Stout 25317993c442c26161f684d6c0c6867a746f3148548Craig Stout private void createFragment(Activity activity) { 25417993c442c26161f684d6c0c6867a746f3148548Craig Stout // Use a fragment to ensure the background manager gets detached properly. 255b70539172cdeb5672ed7128f69383d1fc1458ccbDake Gu BackgroundFragment fragment = (BackgroundFragment) activity.getFragmentManager() 256b70539172cdeb5672ed7128f69383d1fc1458ccbDake Gu .findFragmentByTag(TAG); 257b70539172cdeb5672ed7128f69383d1fc1458ccbDake Gu if (fragment == null) { 258b70539172cdeb5672ed7128f69383d1fc1458ccbDake Gu fragment = new BackgroundFragment(); 259b70539172cdeb5672ed7128f69383d1fc1458ccbDake Gu activity.getFragmentManager().beginTransaction().add(fragment, TAG).commit(); 260b70539172cdeb5672ed7128f69383d1fc1458ccbDake Gu } 26117993c442c26161f684d6c0c6867a746f3148548Craig Stout fragment.setBackgroundManager(this); 26217993c442c26161f684d6c0c6867a746f3148548Craig Stout } 26317993c442c26161f684d6c0c6867a746f3148548Craig Stout 26417993c442c26161f684d6c0c6867a746f3148548Craig Stout /** 26517993c442c26161f684d6c0c6867a746f3148548Craig Stout * Updates state from continuity service. 26617993c442c26161f684d6c0c6867a746f3148548Craig Stout * Typically called when an activity resumes after having done a release. 26717993c442c26161f684d6c0c6867a746f3148548Craig Stout */ 26817993c442c26161f684d6c0c6867a746f3148548Craig Stout public void resume() { 26917993c442c26161f684d6c0c6867a746f3148548Craig Stout syncWithService(); 27017993c442c26161f684d6c0c6867a746f3148548Craig Stout updateImmediate(); 27117993c442c26161f684d6c0c6867a746f3148548Craig Stout } 27217993c442c26161f684d6c0c6867a746f3148548Craig Stout 27317993c442c26161f684d6c0c6867a746f3148548Craig Stout private void syncWithService() { 27417993c442c26161f684d6c0c6867a746f3148548Craig Stout int color = mService.getColor(); 27517993c442c26161f684d6c0c6867a746f3148548Craig Stout Drawable drawable = mService.getDrawable(); 27617993c442c26161f684d6c0c6867a746f3148548Craig Stout 27717993c442c26161f684d6c0c6867a746f3148548Craig Stout if (DEBUG) Log.v(TAG, "syncWithService color " + Integer.toHexString(color) 27817993c442c26161f684d6c0c6867a746f3148548Craig Stout + " drawable " + drawable); 27917993c442c26161f684d6c0c6867a746f3148548Craig Stout 28017993c442c26161f684d6c0c6867a746f3148548Craig Stout if (drawable != null) { 28117993c442c26161f684d6c0c6867a746f3148548Craig Stout drawable = drawable.getConstantState().newDrawable(mContext.getResources()).mutate(); 28217993c442c26161f684d6c0c6867a746f3148548Craig Stout } 28317993c442c26161f684d6c0c6867a746f3148548Craig Stout 28417993c442c26161f684d6c0c6867a746f3148548Craig Stout mBackgroundColor = color; 28517993c442c26161f684d6c0c6867a746f3148548Craig Stout mBackgroundDrawable = drawable; 28617993c442c26161f684d6c0c6867a746f3148548Craig Stout } 28717993c442c26161f684d6c0c6867a746f3148548Craig Stout 28817993c442c26161f684d6c0c6867a746f3148548Craig Stout private void lazyInit() { 28917993c442c26161f684d6c0c6867a746f3148548Craig Stout if (mLayerDrawable != null) { 29017993c442c26161f684d6c0c6867a746f3148548Craig Stout return; 29117993c442c26161f684d6c0c6867a746f3148548Craig Stout } 29217993c442c26161f684d6c0c6867a746f3148548Craig Stout 29317993c442c26161f684d6c0c6867a746f3148548Craig Stout mLayerDrawable = (LayerDrawable) mContext.getResources().getDrawable( 29417993c442c26161f684d6c0c6867a746f3148548Craig Stout R.drawable.lb_background); 29517993c442c26161f684d6c0c6867a746f3148548Craig Stout mBgView.setBackground(mLayerDrawable); 29617993c442c26161f684d6c0c6867a746f3148548Craig Stout 29717993c442c26161f684d6c0c6867a746f3148548Craig Stout mLayerDrawable.setDrawableByLayerId(R.id.background_imageout, createEmptyDrawable()); 29817993c442c26161f684d6c0c6867a746f3148548Craig Stout 29917993c442c26161f684d6c0c6867a746f3148548Craig Stout mDimWrapper = new DrawableWrapper( 30017993c442c26161f684d6c0c6867a746f3148548Craig Stout mLayerDrawable.findDrawableByLayerId(R.id.background_dim)); 30117993c442c26161f684d6c0c6867a746f3148548Craig Stout 30217993c442c26161f684d6c0c6867a746f3148548Craig Stout mLayerWrapper = new DrawableWrapper(mLayerDrawable); 30317993c442c26161f684d6c0c6867a746f3148548Craig Stout 30417993c442c26161f684d6c0c6867a746f3148548Craig Stout mColorWrapper = new DrawableWrapper( 30517993c442c26161f684d6c0c6867a746f3148548Craig Stout mLayerDrawable.findDrawableByLayerId(R.id.background_color)); 30617993c442c26161f684d6c0c6867a746f3148548Craig Stout } 30717993c442c26161f684d6c0c6867a746f3148548Craig Stout 30817993c442c26161f684d6c0c6867a746f3148548Craig Stout /** 30917993c442c26161f684d6c0c6867a746f3148548Craig Stout * Make the background visible on the given window. 31017993c442c26161f684d6c0c6867a746f3148548Craig Stout */ 31117993c442c26161f684d6c0c6867a746f3148548Craig Stout public void attach(Window window) { 31217993c442c26161f684d6c0c6867a746f3148548Craig Stout if (USE_SEPARATE_WINDOW) { 31317993c442c26161f684d6c0c6867a746f3148548Craig Stout attachBehindWindow(window); 31417993c442c26161f684d6c0c6867a746f3148548Craig Stout } else { 31517993c442c26161f684d6c0c6867a746f3148548Craig Stout attachToView(window.getDecorView()); 31617993c442c26161f684d6c0c6867a746f3148548Craig Stout } 31717993c442c26161f684d6c0c6867a746f3148548Craig Stout } 31817993c442c26161f684d6c0c6867a746f3148548Craig Stout 31917993c442c26161f684d6c0c6867a746f3148548Craig Stout private void attachBehindWindow(Window window) { 32017993c442c26161f684d6c0c6867a746f3148548Craig Stout if (DEBUG) Log.v(TAG, "attachBehindWindow " + window); 32117993c442c26161f684d6c0c6867a746f3148548Craig Stout mWindow = window; 32217993c442c26161f684d6c0c6867a746f3148548Craig Stout mWindowManager = window.getWindowManager(); 32317993c442c26161f684d6c0c6867a746f3148548Craig Stout 32417993c442c26161f684d6c0c6867a746f3148548Craig Stout WindowManager.LayoutParams params = new WindowManager.LayoutParams( 32517993c442c26161f684d6c0c6867a746f3148548Craig Stout // Media window sits behind the main application window 32617993c442c26161f684d6c0c6867a746f3148548Craig Stout WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA, 32717993c442c26161f684d6c0c6867a746f3148548Craig Stout // Avoid default to software format RGBA 32817993c442c26161f684d6c0c6867a746f3148548Craig Stout WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, 32917993c442c26161f684d6c0c6867a746f3148548Craig Stout android.graphics.PixelFormat.TRANSLUCENT); 33017993c442c26161f684d6c0c6867a746f3148548Craig Stout params.setTitle(WINDOW_NAME); 33117993c442c26161f684d6c0c6867a746f3148548Craig Stout params.width = ViewGroup.LayoutParams.MATCH_PARENT; 33217993c442c26161f684d6c0c6867a746f3148548Craig Stout params.height = ViewGroup.LayoutParams.MATCH_PARENT; 33317993c442c26161f684d6c0c6867a746f3148548Craig Stout 33417993c442c26161f684d6c0c6867a746f3148548Craig Stout View backgroundView = LayoutInflater.from(mContext).inflate( 33517993c442c26161f684d6c0c6867a746f3148548Craig Stout R.layout.lb_background_window, null); 33617993c442c26161f684d6c0c6867a746f3148548Craig Stout mWindowManager.addView(backgroundView, params); 33717993c442c26161f684d6c0c6867a746f3148548Craig Stout 33817993c442c26161f684d6c0c6867a746f3148548Craig Stout attachToView(backgroundView); 33917993c442c26161f684d6c0c6867a746f3148548Craig Stout } 34017993c442c26161f684d6c0c6867a746f3148548Craig Stout 34117993c442c26161f684d6c0c6867a746f3148548Craig Stout private void attachToView(View sceneRoot) { 34217993c442c26161f684d6c0c6867a746f3148548Craig Stout mBgView = sceneRoot; 34317993c442c26161f684d6c0c6867a746f3148548Craig Stout mAttached = true; 34417993c442c26161f684d6c0c6867a746f3148548Craig Stout updateImmediate(); 34517993c442c26161f684d6c0c6867a746f3148548Craig Stout } 34617993c442c26161f684d6c0c6867a746f3148548Craig Stout 34717993c442c26161f684d6c0c6867a746f3148548Craig Stout /** 34817993c442c26161f684d6c0c6867a746f3148548Craig Stout * Releases references to drawables and puts the background manager into 34917993c442c26161f684d6c0c6867a746f3148548Craig Stout * detached state. 35017993c442c26161f684d6c0c6867a746f3148548Craig Stout * Called when the associated activity is destroyed. 35117993c442c26161f684d6c0c6867a746f3148548Craig Stout * @hide 35217993c442c26161f684d6c0c6867a746f3148548Craig Stout */ 35317993c442c26161f684d6c0c6867a746f3148548Craig Stout void detach() { 35417993c442c26161f684d6c0c6867a746f3148548Craig Stout if (DEBUG) Log.v(TAG, "detach"); 35517993c442c26161f684d6c0c6867a746f3148548Craig Stout release(); 35617993c442c26161f684d6c0c6867a746f3148548Craig Stout 35717993c442c26161f684d6c0c6867a746f3148548Craig Stout if (mWindowManager != null && mBgView != null) { 35817993c442c26161f684d6c0c6867a746f3148548Craig Stout mWindowManager.removeViewImmediate(mBgView); 35917993c442c26161f684d6c0c6867a746f3148548Craig Stout } 36017993c442c26161f684d6c0c6867a746f3148548Craig Stout 36117993c442c26161f684d6c0c6867a746f3148548Craig Stout mWindowManager = null; 36217993c442c26161f684d6c0c6867a746f3148548Craig Stout mWindow = null; 36317993c442c26161f684d6c0c6867a746f3148548Craig Stout mBgView = null; 36417993c442c26161f684d6c0c6867a746f3148548Craig Stout mAttached = false; 36517993c442c26161f684d6c0c6867a746f3148548Craig Stout 36617993c442c26161f684d6c0c6867a746f3148548Craig Stout if (mService != null) { 36717993c442c26161f684d6c0c6867a746f3148548Craig Stout mService.unref(); 36817993c442c26161f684d6c0c6867a746f3148548Craig Stout mService = null; 36917993c442c26161f684d6c0c6867a746f3148548Craig Stout } 37017993c442c26161f684d6c0c6867a746f3148548Craig Stout } 37117993c442c26161f684d6c0c6867a746f3148548Craig Stout 37217993c442c26161f684d6c0c6867a746f3148548Craig Stout /** 37317993c442c26161f684d6c0c6867a746f3148548Craig Stout * Releases references to drawables. 37417993c442c26161f684d6c0c6867a746f3148548Craig Stout * May be called to reduce memory overhead when not visible. 37517993c442c26161f684d6c0c6867a746f3148548Craig Stout */ 37617993c442c26161f684d6c0c6867a746f3148548Craig Stout public void release() { 37717993c442c26161f684d6c0c6867a746f3148548Craig Stout if (DEBUG) Log.v(TAG, "release"); 37817993c442c26161f684d6c0c6867a746f3148548Craig Stout mLayerDrawable = null; 37917993c442c26161f684d6c0c6867a746f3148548Craig Stout mLayerWrapper = null; 38017993c442c26161f684d6c0c6867a746f3148548Craig Stout mImageInWrapper = null; 38117993c442c26161f684d6c0c6867a746f3148548Craig Stout mImageOutWrapper = null; 38217993c442c26161f684d6c0c6867a746f3148548Craig Stout mColorWrapper = null; 38317993c442c26161f684d6c0c6867a746f3148548Craig Stout mDimWrapper = null; 38417993c442c26161f684d6c0c6867a746f3148548Craig Stout mThemeDrawable = null; 38517993c442c26161f684d6c0c6867a746f3148548Craig Stout if (mChangeRunnable != null) { 38617993c442c26161f684d6c0c6867a746f3148548Craig Stout mChangeRunnable.cancel(); 38717993c442c26161f684d6c0c6867a746f3148548Craig Stout mChangeRunnable = null; 38817993c442c26161f684d6c0c6867a746f3148548Craig Stout } 38917993c442c26161f684d6c0c6867a746f3148548Craig Stout releaseBackgroundBitmap(); 39017993c442c26161f684d6c0c6867a746f3148548Craig Stout } 39117993c442c26161f684d6c0c6867a746f3148548Craig Stout 39217993c442c26161f684d6c0c6867a746f3148548Craig Stout private void releaseBackgroundBitmap() { 39317993c442c26161f684d6c0c6867a746f3148548Craig Stout mBackgroundDrawable = null; 39417993c442c26161f684d6c0c6867a746f3148548Craig Stout } 39517993c442c26161f684d6c0c6867a746f3148548Craig Stout 39617993c442c26161f684d6c0c6867a746f3148548Craig Stout private void updateImmediate() { 39717993c442c26161f684d6c0c6867a746f3148548Craig Stout lazyInit(); 39817993c442c26161f684d6c0c6867a746f3148548Craig Stout 39917993c442c26161f684d6c0c6867a746f3148548Craig Stout mColorWrapper.setColor(mBackgroundColor); 40017993c442c26161f684d6c0c6867a746f3148548Craig Stout if (mDimWrapper != null) { 40117993c442c26161f684d6c0c6867a746f3148548Craig Stout mDimWrapper.setAlpha(mBackgroundColor == Color.TRANSPARENT ? 0 : DIM_ALPHA_ON_SOLID); 40217993c442c26161f684d6c0c6867a746f3148548Craig Stout } 40317993c442c26161f684d6c0c6867a746f3148548Craig Stout showWallpaper(mBackgroundColor == Color.TRANSPARENT); 40417993c442c26161f684d6c0c6867a746f3148548Craig Stout 40517993c442c26161f684d6c0c6867a746f3148548Craig Stout mThemeDrawable = getThemeDrawable(); 40617993c442c26161f684d6c0c6867a746f3148548Craig Stout mLayerDrawable.setDrawableByLayerId(R.id.background_theme, mThemeDrawable); 40717993c442c26161f684d6c0c6867a746f3148548Craig Stout 40817993c442c26161f684d6c0c6867a746f3148548Craig Stout if (mBackgroundDrawable == null) { 40917993c442c26161f684d6c0c6867a746f3148548Craig Stout mLayerDrawable.setDrawableByLayerId(R.id.background_imagein, createEmptyDrawable()); 41017993c442c26161f684d6c0c6867a746f3148548Craig Stout } else { 41117993c442c26161f684d6c0c6867a746f3148548Craig Stout if (DEBUG) Log.v(TAG, "Background drawable is available"); 41217993c442c26161f684d6c0c6867a746f3148548Craig Stout mImageInWrapper = new DrawableWrapper(mBackgroundDrawable); 41317993c442c26161f684d6c0c6867a746f3148548Craig Stout mLayerDrawable.setDrawableByLayerId(R.id.background_imagein, mBackgroundDrawable); 41417993c442c26161f684d6c0c6867a746f3148548Craig Stout if (mDimWrapper != null) { 41517993c442c26161f684d6c0c6867a746f3148548Craig Stout mDimWrapper.setAlpha(FULL_ALPHA); 41617993c442c26161f684d6c0c6867a746f3148548Craig Stout } 41717993c442c26161f684d6c0c6867a746f3148548Craig Stout } 41817993c442c26161f684d6c0c6867a746f3148548Craig Stout } 41917993c442c26161f684d6c0c6867a746f3148548Craig Stout 42017993c442c26161f684d6c0c6867a746f3148548Craig Stout /** 42117993c442c26161f684d6c0c6867a746f3148548Craig Stout * Sets the given color into the background. 42217993c442c26161f684d6c0c6867a746f3148548Craig Stout * Timing is undefined. 42317993c442c26161f684d6c0c6867a746f3148548Craig Stout */ 42417993c442c26161f684d6c0c6867a746f3148548Craig Stout public void setColor(int color) { 42517993c442c26161f684d6c0c6867a746f3148548Craig Stout if (DEBUG) Log.v(TAG, "setColor " + Integer.toHexString(color)); 42617993c442c26161f684d6c0c6867a746f3148548Craig Stout 42717993c442c26161f684d6c0c6867a746f3148548Craig Stout mBackgroundColor = color; 42817993c442c26161f684d6c0c6867a746f3148548Craig Stout mService.setColor(mBackgroundColor); 42917993c442c26161f684d6c0c6867a746f3148548Craig Stout 43017993c442c26161f684d6c0c6867a746f3148548Craig Stout if (mColorWrapper != null) { 43117993c442c26161f684d6c0c6867a746f3148548Craig Stout mColorWrapper.setColor(mBackgroundColor); 43217993c442c26161f684d6c0c6867a746f3148548Craig Stout } 43317993c442c26161f684d6c0c6867a746f3148548Craig Stout } 43417993c442c26161f684d6c0c6867a746f3148548Craig Stout 43517993c442c26161f684d6c0c6867a746f3148548Craig Stout /** 43617993c442c26161f684d6c0c6867a746f3148548Craig Stout * Set the given drawable into the background. 43717993c442c26161f684d6c0c6867a746f3148548Craig Stout * Timing is undefined. 43817993c442c26161f684d6c0c6867a746f3148548Craig Stout */ 43917993c442c26161f684d6c0c6867a746f3148548Craig Stout public void setDrawable(Drawable drawable) { 44017993c442c26161f684d6c0c6867a746f3148548Craig Stout if (DEBUG) Log.v(TAG, "setBackgroundDrawable " + drawable); 44117993c442c26161f684d6c0c6867a746f3148548Craig Stout setDrawableInternal(drawable); 44217993c442c26161f684d6c0c6867a746f3148548Craig Stout } 44317993c442c26161f684d6c0c6867a746f3148548Craig Stout 44417993c442c26161f684d6c0c6867a746f3148548Craig Stout private void setDrawableInternal(Drawable drawable) { 44517993c442c26161f684d6c0c6867a746f3148548Craig Stout if (!mAttached) throw new IllegalStateException("Must attach before setting background drawable"); 44617993c442c26161f684d6c0c6867a746f3148548Craig Stout 44717993c442c26161f684d6c0c6867a746f3148548Craig Stout if (mChangeRunnable != null) { 44817993c442c26161f684d6c0c6867a746f3148548Craig Stout mChangeRunnable.cancel(); 44917993c442c26161f684d6c0c6867a746f3148548Craig Stout } 45017993c442c26161f684d6c0c6867a746f3148548Craig Stout mChangeRunnable = new ChangeBackgroundRunnable(drawable); 45117993c442c26161f684d6c0c6867a746f3148548Craig Stout 45217993c442c26161f684d6c0c6867a746f3148548Craig Stout mHandler.postDelayed(mChangeRunnable, CHANGE_BG_DELAY_MS); 45317993c442c26161f684d6c0c6867a746f3148548Craig Stout } 45417993c442c26161f684d6c0c6867a746f3148548Craig Stout 45517993c442c26161f684d6c0c6867a746f3148548Craig Stout /** 45617993c442c26161f684d6c0c6867a746f3148548Craig Stout * Set the given bitmap into the background. 45717993c442c26161f684d6c0c6867a746f3148548Craig Stout * Timing is undefined. 45817993c442c26161f684d6c0c6867a746f3148548Craig Stout */ 45917993c442c26161f684d6c0c6867a746f3148548Craig Stout public void setBitmap(Bitmap bitmap) { 46017993c442c26161f684d6c0c6867a746f3148548Craig Stout if (DEBUG) Log.v(TAG, "setBitmap " + bitmap); 46117993c442c26161f684d6c0c6867a746f3148548Craig Stout 46217993c442c26161f684d6c0c6867a746f3148548Craig Stout if (bitmap.getWidth() <= 0 || bitmap.getHeight() <= 0) { 46317993c442c26161f684d6c0c6867a746f3148548Craig Stout if (DEBUG) Log.v(TAG, "invalid bitmap width or height"); 46417993c442c26161f684d6c0c6867a746f3148548Craig Stout return; 46517993c442c26161f684d6c0c6867a746f3148548Craig Stout } 46617993c442c26161f684d6c0c6867a746f3148548Craig Stout 46717993c442c26161f684d6c0c6867a746f3148548Craig Stout if (mBackgroundDrawable instanceof BitmapDrawable && 46817993c442c26161f684d6c0c6867a746f3148548Craig Stout ((BitmapDrawable) mBackgroundDrawable).getBitmap() == bitmap) { 46917993c442c26161f684d6c0c6867a746f3148548Craig Stout if (DEBUG) Log.v(TAG, "same bitmap detected"); 47017993c442c26161f684d6c0c6867a746f3148548Craig Stout mService.setDrawable(mBackgroundDrawable); 47117993c442c26161f684d6c0c6867a746f3148548Craig Stout return; 47217993c442c26161f684d6c0c6867a746f3148548Craig Stout } 47317993c442c26161f684d6c0c6867a746f3148548Craig Stout 47417993c442c26161f684d6c0c6867a746f3148548Craig Stout if (SCALE_BITMAPS_TO_FIT && bitmap.getWidth() != mWidthPx) { 47517993c442c26161f684d6c0c6867a746f3148548Craig Stout // Scale proportionately to fit width. 47617993c442c26161f684d6c0c6867a746f3148548Craig Stout final float scale = (float) mWidthPx / (float) bitmap.getWidth(); 47717993c442c26161f684d6c0c6867a746f3148548Craig Stout final int height = (int) (mHeightPx / scale); 47817993c442c26161f684d6c0c6867a746f3148548Craig Stout 47917993c442c26161f684d6c0c6867a746f3148548Craig Stout Matrix matrix = new Matrix(); 48017993c442c26161f684d6c0c6867a746f3148548Craig Stout matrix.postScale(scale, scale); 48117993c442c26161f684d6c0c6867a746f3148548Craig Stout 48217993c442c26161f684d6c0c6867a746f3148548Craig Stout bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), height, matrix, true); 48317993c442c26161f684d6c0c6867a746f3148548Craig Stout if (DEBUG) Log.v(TAG, "resized image to " + bitmap.getWidth() + "x" + bitmap.getHeight() + " from height " + height); 48417993c442c26161f684d6c0c6867a746f3148548Craig Stout } 48517993c442c26161f684d6c0c6867a746f3148548Craig Stout 48617993c442c26161f684d6c0c6867a746f3148548Craig Stout BitmapDrawable bitmapDrawable = new BitmapDrawable(mContext.getResources(), bitmap); 48717993c442c26161f684d6c0c6867a746f3148548Craig Stout bitmapDrawable.setGravity(Gravity.CLIP_HORIZONTAL); 48817993c442c26161f684d6c0c6867a746f3148548Craig Stout 48917993c442c26161f684d6c0c6867a746f3148548Craig Stout setDrawableInternal(bitmapDrawable); 49017993c442c26161f684d6c0c6867a746f3148548Craig Stout } 49117993c442c26161f684d6c0c6867a746f3148548Craig Stout 49217993c442c26161f684d6c0c6867a746f3148548Craig Stout private void applyBackgroundChanges() { 49317993c442c26161f684d6c0c6867a746f3148548Craig Stout if (!mAttached || mLayerWrapper == null) { 49417993c442c26161f684d6c0c6867a746f3148548Craig Stout return; 49517993c442c26161f684d6c0c6867a746f3148548Craig Stout } 49617993c442c26161f684d6c0c6867a746f3148548Craig Stout 49717993c442c26161f684d6c0c6867a746f3148548Craig Stout if (DEBUG) Log.v(TAG, "applyBackgroundChanges drawable " + mBackgroundDrawable); 49817993c442c26161f684d6c0c6867a746f3148548Craig Stout 49917993c442c26161f684d6c0c6867a746f3148548Craig Stout int dimAlpha = 0; 50017993c442c26161f684d6c0c6867a746f3148548Craig Stout 50117993c442c26161f684d6c0c6867a746f3148548Craig Stout if (mImageOutWrapper != null && mImageOutWrapper.isAnimationPending()) { 50217993c442c26161f684d6c0c6867a746f3148548Craig Stout if (DEBUG) Log.v(TAG, "mImageOutWrapper animation starting"); 50317993c442c26161f684d6c0c6867a746f3148548Craig Stout mImageOutWrapper.startAnimation(); 50417993c442c26161f684d6c0c6867a746f3148548Craig Stout mImageOutWrapper = null; 50517993c442c26161f684d6c0c6867a746f3148548Craig Stout dimAlpha = DIM_ALPHA_ON_SOLID; 50617993c442c26161f684d6c0c6867a746f3148548Craig Stout } 50717993c442c26161f684d6c0c6867a746f3148548Craig Stout 50817993c442c26161f684d6c0c6867a746f3148548Craig Stout if (mImageInWrapper == null && mBackgroundDrawable != null) { 50917993c442c26161f684d6c0c6867a746f3148548Craig Stout if (DEBUG) Log.v(TAG, "creating new imagein drawable"); 51017993c442c26161f684d6c0c6867a746f3148548Craig Stout mImageInWrapper = new DrawableWrapper(mBackgroundDrawable); 51117993c442c26161f684d6c0c6867a746f3148548Craig Stout mLayerDrawable.setDrawableByLayerId(R.id.background_imagein, mBackgroundDrawable); 51217993c442c26161f684d6c0c6867a746f3148548Craig Stout if (mLayerWrapper.isAnimationStarted()) { 51317993c442c26161f684d6c0c6867a746f3148548Craig Stout mImageInWrapper.setAlpha(mLayerWrapper.getAlpha()); 51417993c442c26161f684d6c0c6867a746f3148548Craig Stout } else { 51517993c442c26161f684d6c0c6867a746f3148548Craig Stout if (DEBUG) Log.v(TAG, "mImageInWrapper animation starting"); 51617993c442c26161f684d6c0c6867a746f3148548Craig Stout mImageInWrapper.setAlpha(0); 51717993c442c26161f684d6c0c6867a746f3148548Craig Stout mImageInWrapper.fadeIn(FADE_DURATION_SLOW, 0); 51817993c442c26161f684d6c0c6867a746f3148548Craig Stout mImageInWrapper.startAnimation(); 51917993c442c26161f684d6c0c6867a746f3148548Craig Stout dimAlpha = FULL_ALPHA; 52017993c442c26161f684d6c0c6867a746f3148548Craig Stout } 52117993c442c26161f684d6c0c6867a746f3148548Craig Stout } 52217993c442c26161f684d6c0c6867a746f3148548Craig Stout 52317993c442c26161f684d6c0c6867a746f3148548Craig Stout if (mDimWrapper != null && dimAlpha != 0) { 52417993c442c26161f684d6c0c6867a746f3148548Craig Stout if (DEBUG) Log.v(TAG, "dimwrapper animation starting to " + dimAlpha); 52517993c442c26161f684d6c0c6867a746f3148548Craig Stout mDimWrapper.fade(FADE_DURATION_SLOW, 0, dimAlpha); 52617993c442c26161f684d6c0c6867a746f3148548Craig Stout mDimWrapper.startAnimation(); 52717993c442c26161f684d6c0c6867a746f3148548Craig Stout } 52817993c442c26161f684d6c0c6867a746f3148548Craig Stout } 52917993c442c26161f684d6c0c6867a746f3148548Craig Stout 53017993c442c26161f684d6c0c6867a746f3148548Craig Stout /** 53117993c442c26161f684d6c0c6867a746f3148548Craig Stout * Returns the color currently in use by the background. 53217993c442c26161f684d6c0c6867a746f3148548Craig Stout */ 53317993c442c26161f684d6c0c6867a746f3148548Craig Stout public final int getColor() { 53417993c442c26161f684d6c0c6867a746f3148548Craig Stout return mBackgroundColor; 53517993c442c26161f684d6c0c6867a746f3148548Craig Stout } 53617993c442c26161f684d6c0c6867a746f3148548Craig Stout 53717993c442c26161f684d6c0c6867a746f3148548Craig Stout /** 53817993c442c26161f684d6c0c6867a746f3148548Craig Stout * Returns the {@link Drawable} currently in use by the background. 53917993c442c26161f684d6c0c6867a746f3148548Craig Stout */ 54017993c442c26161f684d6c0c6867a746f3148548Craig Stout public Drawable getDrawable() { 54117993c442c26161f684d6c0c6867a746f3148548Craig Stout return mBackgroundDrawable; 54217993c442c26161f684d6c0c6867a746f3148548Craig Stout } 54317993c442c26161f684d6c0c6867a746f3148548Craig Stout 54417993c442c26161f684d6c0c6867a746f3148548Craig Stout /** 54517993c442c26161f684d6c0c6867a746f3148548Craig Stout * Task which changes the background. 54617993c442c26161f684d6c0c6867a746f3148548Craig Stout */ 54717993c442c26161f684d6c0c6867a746f3148548Craig Stout class ChangeBackgroundRunnable implements Runnable { 54817993c442c26161f684d6c0c6867a746f3148548Craig Stout private Drawable mDrawable; 54917993c442c26161f684d6c0c6867a746f3148548Craig Stout private boolean mCancel; 55017993c442c26161f684d6c0c6867a746f3148548Craig Stout 55117993c442c26161f684d6c0c6867a746f3148548Craig Stout ChangeBackgroundRunnable(Drawable drawable) { 55217993c442c26161f684d6c0c6867a746f3148548Craig Stout mDrawable = drawable; 55317993c442c26161f684d6c0c6867a746f3148548Craig Stout } 55417993c442c26161f684d6c0c6867a746f3148548Craig Stout 55517993c442c26161f684d6c0c6867a746f3148548Craig Stout public void cancel() { 55617993c442c26161f684d6c0c6867a746f3148548Craig Stout mCancel = true; 55717993c442c26161f684d6c0c6867a746f3148548Craig Stout } 55817993c442c26161f684d6c0c6867a746f3148548Craig Stout 55917993c442c26161f684d6c0c6867a746f3148548Craig Stout @Override 56017993c442c26161f684d6c0c6867a746f3148548Craig Stout public void run() { 56117993c442c26161f684d6c0c6867a746f3148548Craig Stout if (!mCancel) { 56217993c442c26161f684d6c0c6867a746f3148548Craig Stout runTask(); 56317993c442c26161f684d6c0c6867a746f3148548Craig Stout } 56417993c442c26161f684d6c0c6867a746f3148548Craig Stout } 56517993c442c26161f684d6c0c6867a746f3148548Craig Stout 56617993c442c26161f684d6c0c6867a746f3148548Craig Stout private void runTask() { 56717993c442c26161f684d6c0c6867a746f3148548Craig Stout boolean newBackground = false; 56817993c442c26161f684d6c0c6867a746f3148548Craig Stout lazyInit(); 56917993c442c26161f684d6c0c6867a746f3148548Craig Stout 57017993c442c26161f684d6c0c6867a746f3148548Craig Stout if (mDrawable != mBackgroundDrawable) { 57117993c442c26161f684d6c0c6867a746f3148548Craig Stout newBackground = true; 57217993c442c26161f684d6c0c6867a746f3148548Craig Stout releaseBackgroundBitmap(); 57317993c442c26161f684d6c0c6867a746f3148548Craig Stout 57417993c442c26161f684d6c0c6867a746f3148548Craig Stout if (mImageInWrapper != null) { 57517993c442c26161f684d6c0c6867a746f3148548Craig Stout mImageOutWrapper = new DrawableWrapper(mImageInWrapper.getDrawable()); 57617993c442c26161f684d6c0c6867a746f3148548Craig Stout mImageOutWrapper.setAlpha(mImageInWrapper.getAlpha()); 57717993c442c26161f684d6c0c6867a746f3148548Craig Stout mImageOutWrapper.fadeOut(FADE_DURATION_QUICK); 57817993c442c26161f684d6c0c6867a746f3148548Craig Stout 57917993c442c26161f684d6c0c6867a746f3148548Craig Stout // Order is important! Setting a drawable "removes" the 58017993c442c26161f684d6c0c6867a746f3148548Craig Stout // previous one from the view 58117993c442c26161f684d6c0c6867a746f3148548Craig Stout mLayerDrawable.setDrawableByLayerId(R.id.background_imagein, createEmptyDrawable()); 58217993c442c26161f684d6c0c6867a746f3148548Craig Stout mLayerDrawable.setDrawableByLayerId(R.id.background_imageout, 58317993c442c26161f684d6c0c6867a746f3148548Craig Stout mImageOutWrapper.getDrawable()); 58417993c442c26161f684d6c0c6867a746f3148548Craig Stout mImageInWrapper.setAlpha(0); 58517993c442c26161f684d6c0c6867a746f3148548Craig Stout mImageInWrapper = null; 58617993c442c26161f684d6c0c6867a746f3148548Craig Stout } 58717993c442c26161f684d6c0c6867a746f3148548Craig Stout 58817993c442c26161f684d6c0c6867a746f3148548Craig Stout mBackgroundDrawable = mDrawable; 58917993c442c26161f684d6c0c6867a746f3148548Craig Stout mService.setDrawable(mBackgroundDrawable); 59017993c442c26161f684d6c0c6867a746f3148548Craig Stout } 59117993c442c26161f684d6c0c6867a746f3148548Craig Stout 59217993c442c26161f684d6c0c6867a746f3148548Craig Stout if (newBackground) { 59317993c442c26161f684d6c0c6867a746f3148548Craig Stout applyBackgroundChanges(); 59417993c442c26161f684d6c0c6867a746f3148548Craig Stout } 59517993c442c26161f684d6c0c6867a746f3148548Craig Stout } 59617993c442c26161f684d6c0c6867a746f3148548Craig Stout } 59717993c442c26161f684d6c0c6867a746f3148548Craig Stout 59817993c442c26161f684d6c0c6867a746f3148548Craig Stout private Drawable createEmptyDrawable() { 59917993c442c26161f684d6c0c6867a746f3148548Craig Stout Bitmap bitmap = null; 60017993c442c26161f684d6c0c6867a746f3148548Craig Stout return new BitmapDrawable(mContext.getResources(), bitmap); 60117993c442c26161f684d6c0c6867a746f3148548Craig Stout } 60217993c442c26161f684d6c0c6867a746f3148548Craig Stout 60317993c442c26161f684d6c0c6867a746f3148548Craig Stout private void showWallpaper(boolean show) { 60417993c442c26161f684d6c0c6867a746f3148548Craig Stout if (mWindow == null) { 60517993c442c26161f684d6c0c6867a746f3148548Craig Stout return; 60617993c442c26161f684d6c0c6867a746f3148548Craig Stout } 60717993c442c26161f684d6c0c6867a746f3148548Craig Stout 60817993c442c26161f684d6c0c6867a746f3148548Craig Stout WindowManager.LayoutParams layoutParams = mWindow.getAttributes(); 60917993c442c26161f684d6c0c6867a746f3148548Craig Stout if (show) { 61017993c442c26161f684d6c0c6867a746f3148548Craig Stout if ((layoutParams.flags & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) { 61117993c442c26161f684d6c0c6867a746f3148548Craig Stout return; 61217993c442c26161f684d6c0c6867a746f3148548Craig Stout } 61317993c442c26161f684d6c0c6867a746f3148548Craig Stout if (DEBUG) Log.v(TAG, "showing wallpaper"); 61417993c442c26161f684d6c0c6867a746f3148548Craig Stout layoutParams.flags |= WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER; 61517993c442c26161f684d6c0c6867a746f3148548Craig Stout } else { 61617993c442c26161f684d6c0c6867a746f3148548Craig Stout if ((layoutParams.flags & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) == 0) { 61717993c442c26161f684d6c0c6867a746f3148548Craig Stout return; 61817993c442c26161f684d6c0c6867a746f3148548Craig Stout } 61917993c442c26161f684d6c0c6867a746f3148548Craig Stout if (DEBUG) Log.v(TAG, "hiding wallpaper"); 62017993c442c26161f684d6c0c6867a746f3148548Craig Stout layoutParams.flags &= ~WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER; 62117993c442c26161f684d6c0c6867a746f3148548Craig Stout } 62217993c442c26161f684d6c0c6867a746f3148548Craig Stout 62317993c442c26161f684d6c0c6867a746f3148548Craig Stout mWindow.setAttributes(layoutParams); 62417993c442c26161f684d6c0c6867a746f3148548Craig Stout } 62517993c442c26161f684d6c0c6867a746f3148548Craig Stout} 626