BackgroundManager.java revision 2590c39739945451f80dcf8667709b93293fc8bc
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 1660c3b420827d0520509387f1abe3e3d8168e2279Dake Guimport java.lang.ref.WeakReference; 1760c3b420827d0520509387f1abe3e3d8168e2279Dake Gu 18d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stoutimport android.graphics.PixelFormat; 1917993c442c26161f684d6c0c6867a746f3148548Craig Stoutimport android.support.v17.leanback.R; 203d9d8cbaa9086f3ca2f486233fa3051e614a99edCraig Stoutimport android.animation.Animator; 217e22f555da71f49a32420965817c760522b95963Craig Stoutimport android.animation.ValueAnimator; 2217993c442c26161f684d6c0c6867a746f3148548Craig Stoutimport android.app.Activity; 2317993c442c26161f684d6c0c6867a746f3148548Craig Stoutimport android.content.Context; 247f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stoutimport android.content.res.Resources; 2517993c442c26161f684d6c0c6867a746f3148548Craig Stoutimport android.content.res.TypedArray; 2617993c442c26161f684d6c0c6867a746f3148548Craig Stoutimport android.graphics.Bitmap; 277f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stoutimport android.graphics.Canvas; 2817993c442c26161f684d6c0c6867a746f3148548Craig Stoutimport android.graphics.Color; 297f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stoutimport android.graphics.ColorFilter; 3017993c442c26161f684d6c0c6867a746f3148548Craig Stoutimport android.graphics.Matrix; 317f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stoutimport android.graphics.Paint; 3217993c442c26161f684d6c0c6867a746f3148548Craig Stoutimport android.graphics.drawable.ColorDrawable; 3317993c442c26161f684d6c0c6867a746f3148548Craig Stoutimport android.graphics.drawable.Drawable; 3417993c442c26161f684d6c0c6867a746f3148548Craig Stoutimport android.graphics.drawable.LayerDrawable; 3517993c442c26161f684d6c0c6867a746f3148548Craig Stoutimport android.os.Handler; 362590c39739945451f80dcf8667709b93293fc8bcCraig Stoutimport android.support.v17.leanback.widget.BackgroundHelper; 370f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stoutimport android.support.v4.view.animation.FastOutLinearInInterpolator; 3817993c442c26161f684d6c0c6867a746f3148548Craig Stoutimport android.util.Log; 3917993c442c26161f684d6c0c6867a746f3148548Craig Stoutimport android.view.LayoutInflater; 4017993c442c26161f684d6c0c6867a746f3148548Craig Stoutimport android.view.View; 4117993c442c26161f684d6c0c6867a746f3148548Craig Stoutimport android.view.ViewGroup; 4217993c442c26161f684d6c0c6867a746f3148548Craig Stoutimport android.view.Window; 4317993c442c26161f684d6c0c6867a746f3148548Craig Stoutimport android.view.WindowManager; 447e22f555da71f49a32420965817c760522b95963Craig Stoutimport android.view.animation.Interpolator; 450f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stoutimport android.view.animation.AnimationUtils; 46fa9f41f8f5408b6e3931f1ab81f586a47cc2d975Dake Guimport android.support.v4.app.FragmentActivity; 4760c3b420827d0520509387f1abe3e3d8168e2279Dake Guimport android.support.v4.content.ContextCompat; 4817993c442c26161f684d6c0c6867a746f3148548Craig Stout 4917993c442c26161f684d6c0c6867a746f3148548Craig Stout/** 50146a2a07c0e9750c2bdd5bd434197c2f46fea662Tim Kilbourn * Supports background image continuity between multiple Activities. 5117993c442c26161f684d6c0c6867a746f3148548Craig Stout * 52146a2a07c0e9750c2bdd5bd434197c2f46fea662Tim Kilbourn * <p>An Activity should instantiate a BackgroundManager and {@link #attach} 53146a2a07c0e9750c2bdd5bd434197c2f46fea662Tim Kilbourn * to the Activity's window. When the Activity is started, the background is 5417993c442c26161f684d6c0c6867a746f3148548Craig Stout * initialized to the current background values stored in a continuity service. 5517993c442c26161f684d6c0c6867a746f3148548Craig Stout * The background continuity service is updated as the background is updated. 5617993c442c26161f684d6c0c6867a746f3148548Craig Stout * 57146a2a07c0e9750c2bdd5bd434197c2f46fea662Tim Kilbourn * <p>At some point, for example when it is stopped, the Activity may release 58146a2a07c0e9750c2bdd5bd434197c2f46fea662Tim Kilbourn * its background state. 592e2e91a93f6d03108a73e7b4a05d289589957a0eCraig Stout * 60146a2a07c0e9750c2bdd5bd434197c2f46fea662Tim Kilbourn * <p>When an Activity is resumed, if the BackgroundManager has not been 61146a2a07c0e9750c2bdd5bd434197c2f46fea662Tim Kilbourn * released, the continuity service is updated from the BackgroundManager state. 62146a2a07c0e9750c2bdd5bd434197c2f46fea662Tim Kilbourn * If the BackgroundManager was released, the BackgroundManager inherits the 63146a2a07c0e9750c2bdd5bd434197c2f46fea662Tim Kilbourn * current state from the continuity service. 6417993c442c26161f684d6c0c6867a746f3148548Craig Stout * 65146a2a07c0e9750c2bdd5bd434197c2f46fea662Tim Kilbourn * <p>When the last Activity is destroyed, the background state is reset. 6617993c442c26161f684d6c0c6867a746f3148548Craig Stout * 67146a2a07c0e9750c2bdd5bd434197c2f46fea662Tim Kilbourn * <p>Backgrounds consist of several layers, from back to front: 68146a2a07c0e9750c2bdd5bd434197c2f46fea662Tim Kilbourn * <ul> 69146a2a07c0e9750c2bdd5bd434197c2f46fea662Tim Kilbourn * <li>the background Drawable of the theme</li> 70146a2a07c0e9750c2bdd5bd434197c2f46fea662Tim Kilbourn * <li>a solid color (set via {@link #setColor})</li> 71146a2a07c0e9750c2bdd5bd434197c2f46fea662Tim Kilbourn * <li>two Drawables, previous and current (set via {@link #setBitmap} or 72146a2a07c0e9750c2bdd5bd434197c2f46fea662Tim Kilbourn * {@link #setDrawable}), which may be in transition</li> 73146a2a07c0e9750c2bdd5bd434197c2f46fea662Tim Kilbourn * </ul> 7417993c442c26161f684d6c0c6867a746f3148548Craig Stout * 75146a2a07c0e9750c2bdd5bd434197c2f46fea662Tim Kilbourn * <p>BackgroundManager holds references to potentially large bitmap Drawables. 76146a2a07c0e9750c2bdd5bd434197c2f46fea662Tim Kilbourn * Call {@link #release} to release these references when the Activity is not 7717993c442c26161f684d6c0c6867a746f3148548Craig Stout * visible. 7817993c442c26161f684d6c0c6867a746f3148548Craig Stout */ 79146a2a07c0e9750c2bdd5bd434197c2f46fea662Tim Kilbourn// TODO: support for multiple app processes requires a proper android service 80146a2a07c0e9750c2bdd5bd434197c2f46fea662Tim Kilbourn// instead of the shared memory "service" implemented here. Such a service could 81146a2a07c0e9750c2bdd5bd434197c2f46fea662Tim Kilbourn// support continuity between fragments of different applications if desired. 8217993c442c26161f684d6c0c6867a746f3148548Craig Stoutpublic final class BackgroundManager { 8317993c442c26161f684d6c0c6867a746f3148548Craig Stout private static final String TAG = "BackgroundManager"; 8417993c442c26161f684d6c0c6867a746f3148548Craig Stout private static final boolean DEBUG = false; 8517993c442c26161f684d6c0c6867a746f3148548Craig Stout 8617993c442c26161f684d6c0c6867a746f3148548Craig Stout private static final int FULL_ALPHA = 255; 8717993c442c26161f684d6c0c6867a746f3148548Craig Stout private static final int DIM_ALPHA_ON_SOLID = (int) (0.8f * FULL_ALPHA); 8817993c442c26161f684d6c0c6867a746f3148548Craig Stout private static final int CHANGE_BG_DELAY_MS = 500; 893d9d8cbaa9086f3ca2f486233fa3051e614a99edCraig Stout private static final int FADE_DURATION = 500; 9017993c442c26161f684d6c0c6867a746f3148548Craig Stout 9117993c442c26161f684d6c0c6867a746f3148548Craig Stout /** 9217993c442c26161f684d6c0c6867a746f3148548Craig Stout * Using a separate window for backgrounds can improve graphics performance by 9317993c442c26161f684d6c0c6867a746f3148548Craig Stout * leveraging hardware display layers. 9417993c442c26161f684d6c0c6867a746f3148548Craig Stout * TODO: support a leanback configuration option. 9517993c442c26161f684d6c0c6867a746f3148548Craig Stout */ 9617993c442c26161f684d6c0c6867a746f3148548Craig Stout private static final boolean USE_SEPARATE_WINDOW = false; 9717993c442c26161f684d6c0c6867a746f3148548Craig Stout 9817993c442c26161f684d6c0c6867a746f3148548Craig Stout private static final String WINDOW_NAME = "BackgroundManager"; 997f0ed3452a3378c851217cd300950ba2e03f2649Dake Gu private static final String FRAGMENT_TAG = BackgroundManager.class.getCanonicalName(); 10017993c442c26161f684d6c0c6867a746f3148548Craig Stout 10117993c442c26161f684d6c0c6867a746f3148548Craig Stout private Context mContext; 10217993c442c26161f684d6c0c6867a746f3148548Craig Stout private Handler mHandler; 10317993c442c26161f684d6c0c6867a746f3148548Craig Stout private Window mWindow; 10417993c442c26161f684d6c0c6867a746f3148548Craig Stout private WindowManager mWindowManager; 10517993c442c26161f684d6c0c6867a746f3148548Craig Stout private View mBgView; 10617993c442c26161f684d6c0c6867a746f3148548Craig Stout private BackgroundContinuityService mService; 10717993c442c26161f684d6c0c6867a746f3148548Craig Stout private int mThemeDrawableResourceId; 10817993c442c26161f684d6c0c6867a746f3148548Craig Stout 10917993c442c26161f684d6c0c6867a746f3148548Craig Stout private int mHeightPx; 11017993c442c26161f684d6c0c6867a746f3148548Craig Stout private int mWidthPx; 11117993c442c26161f684d6c0c6867a746f3148548Craig Stout private Drawable mBackgroundDrawable; 11217993c442c26161f684d6c0c6867a746f3148548Craig Stout private int mBackgroundColor; 11317993c442c26161f684d6c0c6867a746f3148548Craig Stout private boolean mAttached; 1140f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout private long mLastSetTime; 1150f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout 1160f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout private final Interpolator mAccelerateInterpolator; 1170f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout private final Interpolator mDecelerateInterpolator; 1180f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout private final ValueAnimator mAnimator; 1190f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout private final ValueAnimator mDimAnimator; 12017993c442c26161f684d6c0c6867a746f3148548Craig Stout 1217f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout private static class BitmapDrawable extends Drawable { 1227f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout 1233d9d8cbaa9086f3ca2f486233fa3051e614a99edCraig Stout static class ConstantState extends Drawable.ConstantState { 1243d9d8cbaa9086f3ca2f486233fa3051e614a99edCraig Stout Bitmap mBitmap; 1253d9d8cbaa9086f3ca2f486233fa3051e614a99edCraig Stout Matrix mMatrix; 1263d9d8cbaa9086f3ca2f486233fa3051e614a99edCraig Stout Paint mPaint; 1273d9d8cbaa9086f3ca2f486233fa3051e614a99edCraig Stout 1283d9d8cbaa9086f3ca2f486233fa3051e614a99edCraig Stout @Override 1293d9d8cbaa9086f3ca2f486233fa3051e614a99edCraig Stout public Drawable newDrawable() { 1303d9d8cbaa9086f3ca2f486233fa3051e614a99edCraig Stout return new BitmapDrawable(null, mBitmap, mMatrix); 1313d9d8cbaa9086f3ca2f486233fa3051e614a99edCraig Stout } 1323d9d8cbaa9086f3ca2f486233fa3051e614a99edCraig Stout 1333d9d8cbaa9086f3ca2f486233fa3051e614a99edCraig Stout @Override 1343d9d8cbaa9086f3ca2f486233fa3051e614a99edCraig Stout public int getChangingConfigurations() { 1353d9d8cbaa9086f3ca2f486233fa3051e614a99edCraig Stout return 0; 1363d9d8cbaa9086f3ca2f486233fa3051e614a99edCraig Stout } 1373d9d8cbaa9086f3ca2f486233fa3051e614a99edCraig Stout } 1383d9d8cbaa9086f3ca2f486233fa3051e614a99edCraig Stout 1393d9d8cbaa9086f3ca2f486233fa3051e614a99edCraig Stout private ConstantState mState = new ConstantState(); 1407f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout 1417f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout BitmapDrawable(Resources resources, Bitmap bitmap) { 1427f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout this(resources, bitmap, null); 1437f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout } 1447f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout 1457f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout BitmapDrawable(Resources resources, Bitmap bitmap, Matrix matrix) { 1463d9d8cbaa9086f3ca2f486233fa3051e614a99edCraig Stout mState.mBitmap = bitmap; 1473d9d8cbaa9086f3ca2f486233fa3051e614a99edCraig Stout mState.mMatrix = matrix != null ? matrix : new Matrix(); 1483d9d8cbaa9086f3ca2f486233fa3051e614a99edCraig Stout mState.mPaint = new Paint(); 1493d9d8cbaa9086f3ca2f486233fa3051e614a99edCraig Stout mState.mPaint.setFilterBitmap(true); 1507f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout } 1517f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout 1527f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout Bitmap getBitmap() { 1533d9d8cbaa9086f3ca2f486233fa3051e614a99edCraig Stout return mState.mBitmap; 1547f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout } 1557f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout 1567f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout @Override 1577f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout public void draw(Canvas canvas) { 1583d9d8cbaa9086f3ca2f486233fa3051e614a99edCraig Stout if (mState.mBitmap == null) { 1597f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout return; 1607f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout } 1613d9d8cbaa9086f3ca2f486233fa3051e614a99edCraig Stout canvas.drawBitmap(mState.mBitmap, mState.mMatrix, mState.mPaint); 1627f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout } 1637f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout 1647f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout @Override 1657f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout public int getOpacity() { 166d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout return android.graphics.PixelFormat.TRANSLUCENT; 1677f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout } 1687f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout 1697f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout @Override 1707f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout public void setAlpha(int alpha) { 1713d9d8cbaa9086f3ca2f486233fa3051e614a99edCraig Stout if (mState.mPaint.getAlpha() != alpha) { 1723d9d8cbaa9086f3ca2f486233fa3051e614a99edCraig Stout mState.mPaint.setAlpha(alpha); 1737f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout invalidateSelf(); 1747f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout } 1757f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout } 1767f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout 1777f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout @Override 1787f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout public void setColorFilter(ColorFilter cf) { 1797f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout // Abstract in Drawable, not implemented 1807f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout } 1813d9d8cbaa9086f3ca2f486233fa3051e614a99edCraig Stout 1823d9d8cbaa9086f3ca2f486233fa3051e614a99edCraig Stout @Override 1833d9d8cbaa9086f3ca2f486233fa3051e614a99edCraig Stout public ConstantState getConstantState() { 1843d9d8cbaa9086f3ca2f486233fa3051e614a99edCraig Stout return mState; 1853d9d8cbaa9086f3ca2f486233fa3051e614a99edCraig Stout } 1867f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout } 1877f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout 1887f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout private static class DrawableWrapper { 189d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout private int mAlpha = FULL_ALPHA; 190d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout private Drawable mDrawable; 1917e22f555da71f49a32420965817c760522b95963Craig Stout 19217993c442c26161f684d6c0c6867a746f3148548Craig Stout public DrawableWrapper(Drawable drawable) { 19317993c442c26161f684d6c0c6867a746f3148548Craig Stout mDrawable = drawable; 194d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout updateAlpha(); 195d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout } 196d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout public DrawableWrapper(DrawableWrapper wrapper, Drawable drawable) { 197d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout mDrawable = drawable; 198d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout mAlpha = wrapper.getAlpha(); 199d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout updateAlpha(); 20017993c442c26161f684d6c0c6867a746f3148548Craig Stout } 20117993c442c26161f684d6c0c6867a746f3148548Craig Stout public Drawable getDrawable() { 20217993c442c26161f684d6c0c6867a746f3148548Craig Stout return mDrawable; 20317993c442c26161f684d6c0c6867a746f3148548Craig Stout } 20417993c442c26161f684d6c0c6867a746f3148548Craig Stout public void setAlpha(int alpha) { 20517993c442c26161f684d6c0c6867a746f3148548Craig Stout mAlpha = alpha; 206d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout updateAlpha(); 20717993c442c26161f684d6c0c6867a746f3148548Craig Stout } 20817993c442c26161f684d6c0c6867a746f3148548Craig Stout public int getAlpha() { 20917993c442c26161f684d6c0c6867a746f3148548Craig Stout return mAlpha; 21017993c442c26161f684d6c0c6867a746f3148548Craig Stout } 211d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout private void updateAlpha() { 212d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout mDrawable.setAlpha(mAlpha); 213d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout } 21417993c442c26161f684d6c0c6867a746f3148548Craig Stout public void setColor(int color) { 21517993c442c26161f684d6c0c6867a746f3148548Craig Stout ((ColorDrawable) mDrawable).setColor(color); 21617993c442c26161f684d6c0c6867a746f3148548Craig Stout } 21717993c442c26161f684d6c0c6867a746f3148548Craig Stout } 21817993c442c26161f684d6c0c6867a746f3148548Craig Stout 219d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout private static class TranslucentLayerDrawable extends LayerDrawable { 220d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout private DrawableWrapper[] mWrapper; 221d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout private Paint mPaint = new Paint(); 222d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout 223d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout public static TranslucentLayerDrawable create(LayerDrawable layerDrawable) { 224d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout int numChildren = layerDrawable.getNumberOfLayers(); 225d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout Drawable[] drawables = new Drawable[numChildren]; 226d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout for (int i = 0; i < numChildren; i++) { 227d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout drawables[i] = layerDrawable.getDrawable(i); 228d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout } 229d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout TranslucentLayerDrawable result = new TranslucentLayerDrawable(drawables); 230d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout for (int i = 0; i < numChildren; i++) { 231d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout result.setId(i, layerDrawable.getId(i)); 232d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout } 233d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout return result; 234d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout } 235d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout 236d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout public TranslucentLayerDrawable(Drawable[] drawables) { 237d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout super(drawables); 238d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout int count = drawables.length; 239d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout mWrapper = new DrawableWrapper[count]; 240d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout for (int i = 0; i < count; i++) { 241d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout mWrapper[i] = new DrawableWrapper(drawables[i]); 242d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout } 243d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout } 244d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout 245d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout @Override 246d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout public void setAlpha(int alpha) { 247d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout if (mPaint.getAlpha() != alpha) { 248d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout mPaint.setAlpha(alpha); 249d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout invalidateSelf(); 250d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout } 251d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout } 252d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout 2532590c39739945451f80dcf8667709b93293fc8bcCraig Stout // Queried by system transitions 2542590c39739945451f80dcf8667709b93293fc8bcCraig Stout public int getAlpha() { 2552590c39739945451f80dcf8667709b93293fc8bcCraig Stout return mPaint.getAlpha(); 2562590c39739945451f80dcf8667709b93293fc8bcCraig Stout } 2572590c39739945451f80dcf8667709b93293fc8bcCraig Stout 258d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout @Override 259d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout public Drawable mutate() { 260d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout Drawable drawable = super.mutate(); 261d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout int count = getNumberOfLayers(); 262d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout for (int i = 0; i < count; i++) { 263d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout if (mWrapper[i] != null) { 264d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout mWrapper[i] = new DrawableWrapper(mWrapper[i], getDrawable(i)); 265d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout } 266d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout } 267d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout return drawable; 268d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout } 269d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout 270d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout @Override 271d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout public int getOpacity() { 272d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout return PixelFormat.TRANSLUCENT; 273d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout } 274d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout 275d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout @Override 276d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout public boolean setDrawableByLayerId(int id, Drawable drawable) { 277d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout return updateDrawable(id, drawable) != null; 278d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout } 279d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout 280d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout public DrawableWrapper updateDrawable(int id, Drawable drawable) { 281d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout super.setDrawableByLayerId(id, drawable); 282d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout for (int i = 0; i < getNumberOfLayers(); i++) { 283d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout if (getId(i) == id) { 284d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout mWrapper[i] = new DrawableWrapper(drawable); 285d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout return mWrapper[i]; 286d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout } 287d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout } 288d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout return null; 289d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout } 290d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout 291d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout public void clearDrawable(int id, Context context) { 292d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout for (int i = 0; i < getNumberOfLayers(); i++) { 293d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout if (getId(i) == id) { 294d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout mWrapper[i] = null; 295d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout super.setDrawableByLayerId(id, createEmptyDrawable(context)); 296d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout break; 297d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout } 298d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout } 299d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout } 300d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout 301d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout public DrawableWrapper findWrapperById(int id) { 302d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout for (int i = 0; i < getNumberOfLayers(); i++) { 303d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout if (getId(i) == id) { 304d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout return mWrapper[i]; 305d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout } 306d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout } 307d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout return null; 308d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout } 309d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout 310d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout @Override 311d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout public void draw(Canvas canvas) { 312d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout if (mPaint.getAlpha() < FULL_ALPHA) { 313d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout canvas.saveLayer(0, 0, canvas.getWidth(), canvas.getHeight(), 314d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout mPaint, Canvas.ALL_SAVE_FLAG); 315d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout } 316d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout super.draw(canvas); 317d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout if (mPaint.getAlpha() < FULL_ALPHA) { 318d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout canvas.restore(); 319d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout } 320d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout } 321d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout } 322d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout 323d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout private TranslucentLayerDrawable mLayerDrawable; 3240f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout private Drawable mDimDrawable; 32517993c442c26161f684d6c0c6867a746f3148548Craig Stout private ChangeBackgroundRunnable mChangeRunnable; 32617993c442c26161f684d6c0c6867a746f3148548Craig Stout 3270f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout private final Animator.AnimatorListener mAnimationListener = new Animator.AnimatorListener() { 3280f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout @Override 3290f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout public void onAnimationStart(Animator animation) { 3300f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout } 3310f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout @Override 3320f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout public void onAnimationRepeat(Animator animation) { 3330f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout } 3340f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout @Override 3350f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout public void onAnimationEnd(Animator animation) { 3362590c39739945451f80dcf8667709b93293fc8bcCraig Stout // imageInWrapper should be full alpha, but imageOutWrapper may not be 0 alpha 3372590c39739945451f80dcf8667709b93293fc8bcCraig Stout DrawableWrapper imageOutWrapper = getImageOutWrapper(); 3382590c39739945451f80dcf8667709b93293fc8bcCraig Stout if (imageOutWrapper != null) { 3392590c39739945451f80dcf8667709b93293fc8bcCraig Stout imageOutWrapper.setAlpha(0); 340d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout } 3410f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout if (mChangeRunnable != null) { 3420f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout long delayMs = getRunnableDelay(); 3430f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout if (DEBUG) Log.v(TAG, "animation ended, found change runnable delayMs " + delayMs); 3440f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout mHandler.postDelayed(mChangeRunnable, delayMs); 3450f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout } 3460f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout } 3470f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout @Override 3480f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout public void onAnimationCancel(Animator animation) { 3490f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout } 3500f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout }; 3510f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout 3520f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout private final ValueAnimator.AnimatorUpdateListener mAnimationUpdateListener = 3530f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout new ValueAnimator.AnimatorUpdateListener() { 3540f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout @Override 3550f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout public void onAnimationUpdate(ValueAnimator animation) { 3560f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout int fadeInAlpha = (Integer) animation.getAnimatedValue(); 3572590c39739945451f80dcf8667709b93293fc8bcCraig Stout DrawableWrapper imageInWrapper = getImageInWrapper(); 3582590c39739945451f80dcf8667709b93293fc8bcCraig Stout if (imageInWrapper != null) { 3592590c39739945451f80dcf8667709b93293fc8bcCraig Stout imageInWrapper.setAlpha(fadeInAlpha); 3602590c39739945451f80dcf8667709b93293fc8bcCraig Stout } else { 3612590c39739945451f80dcf8667709b93293fc8bcCraig Stout DrawableWrapper imageOutWrapper = getImageOutWrapper(); 3622590c39739945451f80dcf8667709b93293fc8bcCraig Stout if (imageOutWrapper != null) { 3632590c39739945451f80dcf8667709b93293fc8bcCraig Stout imageOutWrapper.setAlpha(255 - fadeInAlpha); 3642590c39739945451f80dcf8667709b93293fc8bcCraig Stout } 3650f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout } 3660f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout } 3670f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout }; 3680f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout 3690f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout private final ValueAnimator.AnimatorUpdateListener mDimUpdateListener = 3700f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout new ValueAnimator.AnimatorUpdateListener() { 3710f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout @Override 3720f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout public void onAnimationUpdate(ValueAnimator animation) { 3732590c39739945451f80dcf8667709b93293fc8bcCraig Stout DrawableWrapper dimWrapper = getDimWrapper(); 3742590c39739945451f80dcf8667709b93293fc8bcCraig Stout if (dimWrapper != null) { 3752590c39739945451f80dcf8667709b93293fc8bcCraig Stout dimWrapper.setAlpha((Integer) animation.getAnimatedValue()); 3760f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout } 3770f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout } 3780f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout }; 3790f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout 38017993c442c26161f684d6c0c6867a746f3148548Craig Stout /** 38117993c442c26161f684d6c0c6867a746f3148548Craig Stout * Shared memory continuity service. 38217993c442c26161f684d6c0c6867a746f3148548Craig Stout */ 38317993c442c26161f684d6c0c6867a746f3148548Craig Stout private static class BackgroundContinuityService { 38417993c442c26161f684d6c0c6867a746f3148548Craig Stout private static final String TAG = "BackgroundContinuityService"; 38517993c442c26161f684d6c0c6867a746f3148548Craig Stout private static boolean DEBUG = BackgroundManager.DEBUG; 38617993c442c26161f684d6c0c6867a746f3148548Craig Stout 38717993c442c26161f684d6c0c6867a746f3148548Craig Stout private static BackgroundContinuityService sService = new BackgroundContinuityService(); 38817993c442c26161f684d6c0c6867a746f3148548Craig Stout 38917993c442c26161f684d6c0c6867a746f3148548Craig Stout private int mColor; 39017993c442c26161f684d6c0c6867a746f3148548Craig Stout private Drawable mDrawable; 39117993c442c26161f684d6c0c6867a746f3148548Craig Stout private int mCount; 39217993c442c26161f684d6c0c6867a746f3148548Craig Stout 39360c3b420827d0520509387f1abe3e3d8168e2279Dake Gu /** Single cache of theme drawable */ 39460c3b420827d0520509387f1abe3e3d8168e2279Dake Gu private int mLastThemeDrawableId; 39560c3b420827d0520509387f1abe3e3d8168e2279Dake Gu private WeakReference<Drawable> mLastThemeDrawable; 39660c3b420827d0520509387f1abe3e3d8168e2279Dake Gu 39717993c442c26161f684d6c0c6867a746f3148548Craig Stout private BackgroundContinuityService() { 39817993c442c26161f684d6c0c6867a746f3148548Craig Stout reset(); 39917993c442c26161f684d6c0c6867a746f3148548Craig Stout } 40017993c442c26161f684d6c0c6867a746f3148548Craig Stout 40117993c442c26161f684d6c0c6867a746f3148548Craig Stout private void reset() { 40217993c442c26161f684d6c0c6867a746f3148548Craig Stout mColor = Color.TRANSPARENT; 40317993c442c26161f684d6c0c6867a746f3148548Craig Stout mDrawable = null; 40417993c442c26161f684d6c0c6867a746f3148548Craig Stout } 40517993c442c26161f684d6c0c6867a746f3148548Craig Stout 40617993c442c26161f684d6c0c6867a746f3148548Craig Stout public static BackgroundContinuityService getInstance() { 40717993c442c26161f684d6c0c6867a746f3148548Craig Stout final int count = sService.mCount++; 40817993c442c26161f684d6c0c6867a746f3148548Craig Stout if (DEBUG) Log.v(TAG, "Returning instance with new count " + count); 40917993c442c26161f684d6c0c6867a746f3148548Craig Stout return sService; 41017993c442c26161f684d6c0c6867a746f3148548Craig Stout } 41117993c442c26161f684d6c0c6867a746f3148548Craig Stout 41217993c442c26161f684d6c0c6867a746f3148548Craig Stout public void unref() { 41317993c442c26161f684d6c0c6867a746f3148548Craig Stout if (mCount <= 0) throw new IllegalStateException("Can't unref, count " + mCount); 41417993c442c26161f684d6c0c6867a746f3148548Craig Stout if (--mCount == 0) { 41517993c442c26161f684d6c0c6867a746f3148548Craig Stout if (DEBUG) Log.v(TAG, "mCount is zero, resetting"); 41617993c442c26161f684d6c0c6867a746f3148548Craig Stout reset(); 41717993c442c26161f684d6c0c6867a746f3148548Craig Stout } 41817993c442c26161f684d6c0c6867a746f3148548Craig Stout } 41917993c442c26161f684d6c0c6867a746f3148548Craig Stout public int getColor() { 42017993c442c26161f684d6c0c6867a746f3148548Craig Stout return mColor; 42117993c442c26161f684d6c0c6867a746f3148548Craig Stout } 42217993c442c26161f684d6c0c6867a746f3148548Craig Stout public Drawable getDrawable() { 42317993c442c26161f684d6c0c6867a746f3148548Craig Stout return mDrawable; 42417993c442c26161f684d6c0c6867a746f3148548Craig Stout } 42517993c442c26161f684d6c0c6867a746f3148548Craig Stout public void setColor(int color) { 42617993c442c26161f684d6c0c6867a746f3148548Craig Stout mColor = color; 42717993c442c26161f684d6c0c6867a746f3148548Craig Stout } 42817993c442c26161f684d6c0c6867a746f3148548Craig Stout public void setDrawable(Drawable drawable) { 42917993c442c26161f684d6c0c6867a746f3148548Craig Stout mDrawable = drawable; 43017993c442c26161f684d6c0c6867a746f3148548Craig Stout } 43160c3b420827d0520509387f1abe3e3d8168e2279Dake Gu public Drawable getThemeDrawable(Context context, int themeDrawableId) { 43260c3b420827d0520509387f1abe3e3d8168e2279Dake Gu Drawable drawable = null; 43360c3b420827d0520509387f1abe3e3d8168e2279Dake Gu if (mLastThemeDrawable != null && mLastThemeDrawableId == themeDrawableId) { 43460c3b420827d0520509387f1abe3e3d8168e2279Dake Gu drawable = mLastThemeDrawable.get(); 43560c3b420827d0520509387f1abe3e3d8168e2279Dake Gu } 43660c3b420827d0520509387f1abe3e3d8168e2279Dake Gu if (drawable == null) { 43760c3b420827d0520509387f1abe3e3d8168e2279Dake Gu drawable = ContextCompat.getDrawable(context, themeDrawableId); 43860c3b420827d0520509387f1abe3e3d8168e2279Dake Gu mLastThemeDrawable = new WeakReference<Drawable>(drawable); 43960c3b420827d0520509387f1abe3e3d8168e2279Dake Gu mLastThemeDrawableId = themeDrawableId; 44060c3b420827d0520509387f1abe3e3d8168e2279Dake Gu } 44160c3b420827d0520509387f1abe3e3d8168e2279Dake Gu return drawable.getConstantState().newDrawable(context.getResources()).mutate(); 44260c3b420827d0520509387f1abe3e3d8168e2279Dake Gu } 44317993c442c26161f684d6c0c6867a746f3148548Craig Stout } 44417993c442c26161f684d6c0c6867a746f3148548Craig Stout 44517993c442c26161f684d6c0c6867a746f3148548Craig Stout private Drawable getThemeDrawable() { 44617993c442c26161f684d6c0c6867a746f3148548Craig Stout Drawable drawable = null; 44717993c442c26161f684d6c0c6867a746f3148548Craig Stout if (mThemeDrawableResourceId != -1) { 44860c3b420827d0520509387f1abe3e3d8168e2279Dake Gu drawable = mService.getThemeDrawable(mContext, mThemeDrawableResourceId); 44917993c442c26161f684d6c0c6867a746f3148548Craig Stout } 45017993c442c26161f684d6c0c6867a746f3148548Craig Stout if (drawable == null) { 451d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout drawable = createEmptyDrawable(mContext); 45217993c442c26161f684d6c0c6867a746f3148548Craig Stout } 45317993c442c26161f684d6c0c6867a746f3148548Craig Stout return drawable; 45417993c442c26161f684d6c0c6867a746f3148548Craig Stout } 45517993c442c26161f684d6c0c6867a746f3148548Craig Stout 45617993c442c26161f684d6c0c6867a746f3148548Craig Stout /** 457146a2a07c0e9750c2bdd5bd434197c2f46fea662Tim Kilbourn * Get the BackgroundManager associated with the Activity. 4587f0ed3452a3378c851217cd300950ba2e03f2649Dake Gu * <p> 459146a2a07c0e9750c2bdd5bd434197c2f46fea662Tim Kilbourn * The BackgroundManager will be created on-demand for each individual 460146a2a07c0e9750c2bdd5bd434197c2f46fea662Tim Kilbourn * Activity. Subsequent calls will return the same BackgroundManager created 461146a2a07c0e9750c2bdd5bd434197c2f46fea662Tim Kilbourn * for this Activity. 4627f0ed3452a3378c851217cd300950ba2e03f2649Dake Gu */ 4637f0ed3452a3378c851217cd300950ba2e03f2649Dake Gu public static BackgroundManager getInstance(Activity activity) { 464fa9f41f8f5408b6e3931f1ab81f586a47cc2d975Dake Gu if (activity instanceof FragmentActivity) { 465fa9f41f8f5408b6e3931f1ab81f586a47cc2d975Dake Gu return getSupportInstance((FragmentActivity) activity); 466fa9f41f8f5408b6e3931f1ab81f586a47cc2d975Dake Gu } 4677f0ed3452a3378c851217cd300950ba2e03f2649Dake Gu BackgroundFragment fragment = (BackgroundFragment) activity.getFragmentManager() 4687f0ed3452a3378c851217cd300950ba2e03f2649Dake Gu .findFragmentByTag(FRAGMENT_TAG); 4697f0ed3452a3378c851217cd300950ba2e03f2649Dake Gu if (fragment != null) { 4707f0ed3452a3378c851217cd300950ba2e03f2649Dake Gu BackgroundManager manager = fragment.getBackgroundManager(); 4717f0ed3452a3378c851217cd300950ba2e03f2649Dake Gu if (manager != null) { 4727f0ed3452a3378c851217cd300950ba2e03f2649Dake Gu return manager; 4737f0ed3452a3378c851217cd300950ba2e03f2649Dake Gu } 4747f0ed3452a3378c851217cd300950ba2e03f2649Dake Gu // manager is null: this is a fragment restored by FragmentManager, 4757f0ed3452a3378c851217cd300950ba2e03f2649Dake Gu // fall through to create a BackgroundManager attach to it. 4767f0ed3452a3378c851217cd300950ba2e03f2649Dake Gu } 477fa9f41f8f5408b6e3931f1ab81f586a47cc2d975Dake Gu return new BackgroundManager(activity, false); 478fa9f41f8f5408b6e3931f1ab81f586a47cc2d975Dake Gu } 479fa9f41f8f5408b6e3931f1ab81f586a47cc2d975Dake Gu 480fa9f41f8f5408b6e3931f1ab81f586a47cc2d975Dake Gu private static BackgroundManager getSupportInstance(FragmentActivity activity) { 481fa9f41f8f5408b6e3931f1ab81f586a47cc2d975Dake Gu BackgroundSupportFragment fragment = (BackgroundSupportFragment) activity 482fa9f41f8f5408b6e3931f1ab81f586a47cc2d975Dake Gu .getSupportFragmentManager().findFragmentByTag(FRAGMENT_TAG); 483fa9f41f8f5408b6e3931f1ab81f586a47cc2d975Dake Gu if (fragment != null) { 484fa9f41f8f5408b6e3931f1ab81f586a47cc2d975Dake Gu BackgroundManager manager = fragment.getBackgroundManager(); 485fa9f41f8f5408b6e3931f1ab81f586a47cc2d975Dake Gu if (manager != null) { 486fa9f41f8f5408b6e3931f1ab81f586a47cc2d975Dake Gu return manager; 487fa9f41f8f5408b6e3931f1ab81f586a47cc2d975Dake Gu } 488fa9f41f8f5408b6e3931f1ab81f586a47cc2d975Dake Gu // manager is null: this is a fragment restored by FragmentManager, 489fa9f41f8f5408b6e3931f1ab81f586a47cc2d975Dake Gu // fall through to create a BackgroundManager attach to it. 490fa9f41f8f5408b6e3931f1ab81f586a47cc2d975Dake Gu } 491fa9f41f8f5408b6e3931f1ab81f586a47cc2d975Dake Gu return new BackgroundManager(activity, true); 4927f0ed3452a3378c851217cd300950ba2e03f2649Dake Gu } 4937f0ed3452a3378c851217cd300950ba2e03f2649Dake Gu 494fa9f41f8f5408b6e3931f1ab81f586a47cc2d975Dake Gu private BackgroundManager(Activity activity, boolean isSupportFragmentActivity) { 49517993c442c26161f684d6c0c6867a746f3148548Craig Stout mContext = activity; 49617993c442c26161f684d6c0c6867a746f3148548Craig Stout mService = BackgroundContinuityService.getInstance(); 49717993c442c26161f684d6c0c6867a746f3148548Craig Stout mHeightPx = mContext.getResources().getDisplayMetrics().heightPixels; 49817993c442c26161f684d6c0c6867a746f3148548Craig Stout mWidthPx = mContext.getResources().getDisplayMetrics().widthPixels; 49917993c442c26161f684d6c0c6867a746f3148548Craig Stout mHandler = new Handler(); 50017993c442c26161f684d6c0c6867a746f3148548Craig Stout 5010f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout Interpolator defaultInterpolator = new FastOutLinearInInterpolator(); 5020f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout mAccelerateInterpolator = AnimationUtils.loadInterpolator(mContext, 5030f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout android.R.anim.accelerate_interpolator); 5040f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout mDecelerateInterpolator = AnimationUtils.loadInterpolator(mContext, 5050f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout android.R.anim.decelerate_interpolator); 5060f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout 5070f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout mAnimator = ValueAnimator.ofInt(0, FULL_ALPHA); 5080f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout mAnimator.addListener(mAnimationListener); 5090f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout mAnimator.addUpdateListener(mAnimationUpdateListener); 5100f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout mAnimator.setInterpolator(defaultInterpolator); 5110f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout 5120f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout mDimAnimator = new ValueAnimator(); 5130f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout mDimAnimator.addUpdateListener(mDimUpdateListener); 5140f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout 51517993c442c26161f684d6c0c6867a746f3148548Craig Stout TypedArray ta = activity.getTheme().obtainStyledAttributes(new int[] { 51617993c442c26161f684d6c0c6867a746f3148548Craig Stout android.R.attr.windowBackground }); 51717993c442c26161f684d6c0c6867a746f3148548Craig Stout mThemeDrawableResourceId = ta.getResourceId(0, -1); 51817993c442c26161f684d6c0c6867a746f3148548Craig Stout if (mThemeDrawableResourceId < 0) { 51917993c442c26161f684d6c0c6867a746f3148548Craig Stout if (DEBUG) Log.v(TAG, "BackgroundManager no window background resource!"); 52017993c442c26161f684d6c0c6867a746f3148548Craig Stout } 52117993c442c26161f684d6c0c6867a746f3148548Craig Stout ta.recycle(); 52217993c442c26161f684d6c0c6867a746f3148548Craig Stout 523fa9f41f8f5408b6e3931f1ab81f586a47cc2d975Dake Gu if (isSupportFragmentActivity) { 524fa9f41f8f5408b6e3931f1ab81f586a47cc2d975Dake Gu createSupportFragment((FragmentActivity) activity); 525fa9f41f8f5408b6e3931f1ab81f586a47cc2d975Dake Gu } else { 526fa9f41f8f5408b6e3931f1ab81f586a47cc2d975Dake Gu createFragment(activity); 527fa9f41f8f5408b6e3931f1ab81f586a47cc2d975Dake Gu } 52817993c442c26161f684d6c0c6867a746f3148548Craig Stout } 52917993c442c26161f684d6c0c6867a746f3148548Craig Stout 53017993c442c26161f684d6c0c6867a746f3148548Craig Stout private void createFragment(Activity activity) { 53117993c442c26161f684d6c0c6867a746f3148548Craig Stout // Use a fragment to ensure the background manager gets detached properly. 532b70539172cdeb5672ed7128f69383d1fc1458ccbDake Gu BackgroundFragment fragment = (BackgroundFragment) activity.getFragmentManager() 5337f0ed3452a3378c851217cd300950ba2e03f2649Dake Gu .findFragmentByTag(FRAGMENT_TAG); 534b70539172cdeb5672ed7128f69383d1fc1458ccbDake Gu if (fragment == null) { 535b70539172cdeb5672ed7128f69383d1fc1458ccbDake Gu fragment = new BackgroundFragment(); 5367f0ed3452a3378c851217cd300950ba2e03f2649Dake Gu activity.getFragmentManager().beginTransaction().add(fragment, FRAGMENT_TAG).commit(); 5377f0ed3452a3378c851217cd300950ba2e03f2649Dake Gu } else { 5387f0ed3452a3378c851217cd300950ba2e03f2649Dake Gu if (fragment.getBackgroundManager() != null) { 5397f0ed3452a3378c851217cd300950ba2e03f2649Dake Gu throw new IllegalStateException("Created duplicated BackgroundManager for same " + 5407f0ed3452a3378c851217cd300950ba2e03f2649Dake Gu "activity, please use getInstance() instead"); 5417f0ed3452a3378c851217cd300950ba2e03f2649Dake Gu } 542b70539172cdeb5672ed7128f69383d1fc1458ccbDake Gu } 54317993c442c26161f684d6c0c6867a746f3148548Craig Stout fragment.setBackgroundManager(this); 54417993c442c26161f684d6c0c6867a746f3148548Craig Stout } 54517993c442c26161f684d6c0c6867a746f3148548Craig Stout 546fa9f41f8f5408b6e3931f1ab81f586a47cc2d975Dake Gu private void createSupportFragment(FragmentActivity activity) { 547fa9f41f8f5408b6e3931f1ab81f586a47cc2d975Dake Gu // Use a fragment to ensure the background manager gets detached properly. 548fa9f41f8f5408b6e3931f1ab81f586a47cc2d975Dake Gu BackgroundSupportFragment fragment = (BackgroundSupportFragment) activity 549fa9f41f8f5408b6e3931f1ab81f586a47cc2d975Dake Gu .getSupportFragmentManager().findFragmentByTag(FRAGMENT_TAG); 550fa9f41f8f5408b6e3931f1ab81f586a47cc2d975Dake Gu if (fragment == null) { 551fa9f41f8f5408b6e3931f1ab81f586a47cc2d975Dake Gu fragment = new BackgroundSupportFragment(); 552fa9f41f8f5408b6e3931f1ab81f586a47cc2d975Dake Gu activity.getSupportFragmentManager().beginTransaction().add(fragment, FRAGMENT_TAG) 553fa9f41f8f5408b6e3931f1ab81f586a47cc2d975Dake Gu .commit(); 554fa9f41f8f5408b6e3931f1ab81f586a47cc2d975Dake Gu } else { 555fa9f41f8f5408b6e3931f1ab81f586a47cc2d975Dake Gu if (fragment.getBackgroundManager() != null) { 556fa9f41f8f5408b6e3931f1ab81f586a47cc2d975Dake Gu throw new IllegalStateException("Created duplicated BackgroundManager for same " + 557fa9f41f8f5408b6e3931f1ab81f586a47cc2d975Dake Gu "activity, please use getInstance() instead"); 558fa9f41f8f5408b6e3931f1ab81f586a47cc2d975Dake Gu } 559fa9f41f8f5408b6e3931f1ab81f586a47cc2d975Dake Gu } 560fa9f41f8f5408b6e3931f1ab81f586a47cc2d975Dake Gu fragment.setBackgroundManager(this); 561fa9f41f8f5408b6e3931f1ab81f586a47cc2d975Dake Gu } 562fa9f41f8f5408b6e3931f1ab81f586a47cc2d975Dake Gu 5632590c39739945451f80dcf8667709b93293fc8bcCraig Stout private DrawableWrapper getImageInWrapper() { 5642590c39739945451f80dcf8667709b93293fc8bcCraig Stout return mLayerDrawable == null ? null : 5652590c39739945451f80dcf8667709b93293fc8bcCraig Stout mLayerDrawable.findWrapperById(R.id.background_imagein); 5662590c39739945451f80dcf8667709b93293fc8bcCraig Stout } 5672590c39739945451f80dcf8667709b93293fc8bcCraig Stout 5682590c39739945451f80dcf8667709b93293fc8bcCraig Stout private DrawableWrapper getImageOutWrapper() { 5692590c39739945451f80dcf8667709b93293fc8bcCraig Stout return mLayerDrawable == null ? null : 5702590c39739945451f80dcf8667709b93293fc8bcCraig Stout mLayerDrawable.findWrapperById(R.id.background_imageout); 5712590c39739945451f80dcf8667709b93293fc8bcCraig Stout } 5722590c39739945451f80dcf8667709b93293fc8bcCraig Stout 5732590c39739945451f80dcf8667709b93293fc8bcCraig Stout private DrawableWrapper getDimWrapper() { 5742590c39739945451f80dcf8667709b93293fc8bcCraig Stout return mLayerDrawable == null ? null : 5752590c39739945451f80dcf8667709b93293fc8bcCraig Stout mLayerDrawable.findWrapperById(R.id.background_dim); 5762590c39739945451f80dcf8667709b93293fc8bcCraig Stout } 5772590c39739945451f80dcf8667709b93293fc8bcCraig Stout 5782590c39739945451f80dcf8667709b93293fc8bcCraig Stout private DrawableWrapper getColorWrapper() { 5792590c39739945451f80dcf8667709b93293fc8bcCraig Stout return mLayerDrawable == null ? null : 5802590c39739945451f80dcf8667709b93293fc8bcCraig Stout mLayerDrawable.findWrapperById(R.id.background_color); 5812590c39739945451f80dcf8667709b93293fc8bcCraig Stout } 5822590c39739945451f80dcf8667709b93293fc8bcCraig Stout 58317993c442c26161f684d6c0c6867a746f3148548Craig Stout /** 584146a2a07c0e9750c2bdd5bd434197c2f46fea662Tim Kilbourn * Synchronizes state when the owning Activity is resumed. 58517993c442c26161f684d6c0c6867a746f3148548Craig Stout */ 5862e2e91a93f6d03108a73e7b4a05d289589957a0eCraig Stout void onActivityResume() { 5872e2e91a93f6d03108a73e7b4a05d289589957a0eCraig Stout if (mService == null) { 5882e2e91a93f6d03108a73e7b4a05d289589957a0eCraig Stout return; 5892e2e91a93f6d03108a73e7b4a05d289589957a0eCraig Stout } 5902e2e91a93f6d03108a73e7b4a05d289589957a0eCraig Stout if (mLayerDrawable == null) { 5913d9d8cbaa9086f3ca2f486233fa3051e614a99edCraig Stout if (DEBUG) Log.v(TAG, "onActivityResume " + this + 5923d9d8cbaa9086f3ca2f486233fa3051e614a99edCraig Stout " released state, syncing with service"); 5932e2e91a93f6d03108a73e7b4a05d289589957a0eCraig Stout syncWithService(); 5942e2e91a93f6d03108a73e7b4a05d289589957a0eCraig Stout } else { 5953d9d8cbaa9086f3ca2f486233fa3051e614a99edCraig Stout if (DEBUG) Log.v(TAG, "onActivityResume " + this + " updating service color " 5962e2e91a93f6d03108a73e7b4a05d289589957a0eCraig Stout + mBackgroundColor + " drawable " + mBackgroundDrawable); 5972e2e91a93f6d03108a73e7b4a05d289589957a0eCraig Stout mService.setColor(mBackgroundColor); 5982e2e91a93f6d03108a73e7b4a05d289589957a0eCraig Stout mService.setDrawable(mBackgroundDrawable); 5992e2e91a93f6d03108a73e7b4a05d289589957a0eCraig Stout } 60017993c442c26161f684d6c0c6867a746f3148548Craig Stout } 60117993c442c26161f684d6c0c6867a746f3148548Craig Stout 60217993c442c26161f684d6c0c6867a746f3148548Craig Stout private void syncWithService() { 60317993c442c26161f684d6c0c6867a746f3148548Craig Stout int color = mService.getColor(); 60417993c442c26161f684d6c0c6867a746f3148548Craig Stout Drawable drawable = mService.getDrawable(); 60517993c442c26161f684d6c0c6867a746f3148548Craig Stout 60617993c442c26161f684d6c0c6867a746f3148548Craig Stout if (DEBUG) Log.v(TAG, "syncWithService color " + Integer.toHexString(color) 60717993c442c26161f684d6c0c6867a746f3148548Craig Stout + " drawable " + drawable); 60817993c442c26161f684d6c0c6867a746f3148548Craig Stout 60917993c442c26161f684d6c0c6867a746f3148548Craig Stout mBackgroundColor = color; 6103d9d8cbaa9086f3ca2f486233fa3051e614a99edCraig Stout mBackgroundDrawable = drawable == null ? null : 6113d9d8cbaa9086f3ca2f486233fa3051e614a99edCraig Stout drawable.getConstantState().newDrawable().mutate(); 6122e2e91a93f6d03108a73e7b4a05d289589957a0eCraig Stout 6132e2e91a93f6d03108a73e7b4a05d289589957a0eCraig Stout updateImmediate(); 61417993c442c26161f684d6c0c6867a746f3148548Craig Stout } 61517993c442c26161f684d6c0c6867a746f3148548Craig Stout 61617993c442c26161f684d6c0c6867a746f3148548Craig Stout private void lazyInit() { 61717993c442c26161f684d6c0c6867a746f3148548Craig Stout if (mLayerDrawable != null) { 61817993c442c26161f684d6c0c6867a746f3148548Craig Stout return; 61917993c442c26161f684d6c0c6867a746f3148548Craig Stout } 62017993c442c26161f684d6c0c6867a746f3148548Craig Stout 621d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout LayerDrawable layerDrawable = (LayerDrawable) 622d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout ContextCompat.getDrawable(mContext, R.drawable.lb_background).mutate(); 623d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout mLayerDrawable = TranslucentLayerDrawable.create(layerDrawable); 6242590c39739945451f80dcf8667709b93293fc8bcCraig Stout BackgroundHelper.setBackgroundPreservingAlpha(mBgView, mLayerDrawable); 62517993c442c26161f684d6c0c6867a746f3148548Craig Stout 626d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout mLayerDrawable.clearDrawable(R.id.background_imageout, mContext); 627d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout mLayerDrawable.updateDrawable(R.id.background_theme, getThemeDrawable()); 628c149abce7f8a46f7c54211b5f97c5cd9ee729357Dake Gu 6290f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout updateDimWrapper(); 6300f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout } 6310f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout 6320f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout private void updateDimWrapper() { 6330f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout if (mDimDrawable == null) { 6340f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout mDimDrawable = getDefaultDimLayer(); 6350f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout } 636d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout Drawable dimDrawable = mDimDrawable.getConstantState().newDrawable( 637d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout mContext.getResources()).mutate(); 6382590c39739945451f80dcf8667709b93293fc8bcCraig Stout if (mLayerDrawable != null) { 6392590c39739945451f80dcf8667709b93293fc8bcCraig Stout mLayerDrawable.updateDrawable(R.id.background_dim, dimDrawable); 6402590c39739945451f80dcf8667709b93293fc8bcCraig Stout } 64117993c442c26161f684d6c0c6867a746f3148548Craig Stout } 64217993c442c26161f684d6c0c6867a746f3148548Craig Stout 64317993c442c26161f684d6c0c6867a746f3148548Craig Stout /** 6440f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout * Make the background visible on the given Window. The background manager must be attached 6450f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout * when the background is set. 64617993c442c26161f684d6c0c6867a746f3148548Craig Stout */ 64717993c442c26161f684d6c0c6867a746f3148548Craig Stout public void attach(Window window) { 64817993c442c26161f684d6c0c6867a746f3148548Craig Stout if (USE_SEPARATE_WINDOW) { 64917993c442c26161f684d6c0c6867a746f3148548Craig Stout attachBehindWindow(window); 65017993c442c26161f684d6c0c6867a746f3148548Craig Stout } else { 65117993c442c26161f684d6c0c6867a746f3148548Craig Stout attachToView(window.getDecorView()); 65217993c442c26161f684d6c0c6867a746f3148548Craig Stout } 65317993c442c26161f684d6c0c6867a746f3148548Craig Stout } 65417993c442c26161f684d6c0c6867a746f3148548Craig Stout 65517993c442c26161f684d6c0c6867a746f3148548Craig Stout private void attachBehindWindow(Window window) { 65617993c442c26161f684d6c0c6867a746f3148548Craig Stout if (DEBUG) Log.v(TAG, "attachBehindWindow " + window); 65717993c442c26161f684d6c0c6867a746f3148548Craig Stout mWindow = window; 65817993c442c26161f684d6c0c6867a746f3148548Craig Stout mWindowManager = window.getWindowManager(); 65917993c442c26161f684d6c0c6867a746f3148548Craig Stout 66017993c442c26161f684d6c0c6867a746f3148548Craig Stout WindowManager.LayoutParams params = new WindowManager.LayoutParams( 66117993c442c26161f684d6c0c6867a746f3148548Craig Stout // Media window sits behind the main application window 66217993c442c26161f684d6c0c6867a746f3148548Craig Stout WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA, 66317993c442c26161f684d6c0c6867a746f3148548Craig Stout // Avoid default to software format RGBA 66417993c442c26161f684d6c0c6867a746f3148548Craig Stout WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, 66517993c442c26161f684d6c0c6867a746f3148548Craig Stout android.graphics.PixelFormat.TRANSLUCENT); 66617993c442c26161f684d6c0c6867a746f3148548Craig Stout params.setTitle(WINDOW_NAME); 66717993c442c26161f684d6c0c6867a746f3148548Craig Stout params.width = ViewGroup.LayoutParams.MATCH_PARENT; 66817993c442c26161f684d6c0c6867a746f3148548Craig Stout params.height = ViewGroup.LayoutParams.MATCH_PARENT; 66917993c442c26161f684d6c0c6867a746f3148548Craig Stout 67017993c442c26161f684d6c0c6867a746f3148548Craig Stout View backgroundView = LayoutInflater.from(mContext).inflate( 67117993c442c26161f684d6c0c6867a746f3148548Craig Stout R.layout.lb_background_window, null); 67217993c442c26161f684d6c0c6867a746f3148548Craig Stout mWindowManager.addView(backgroundView, params); 67317993c442c26161f684d6c0c6867a746f3148548Craig Stout 67417993c442c26161f684d6c0c6867a746f3148548Craig Stout attachToView(backgroundView); 67517993c442c26161f684d6c0c6867a746f3148548Craig Stout } 67617993c442c26161f684d6c0c6867a746f3148548Craig Stout 67717993c442c26161f684d6c0c6867a746f3148548Craig Stout private void attachToView(View sceneRoot) { 67817993c442c26161f684d6c0c6867a746f3148548Craig Stout mBgView = sceneRoot; 67917993c442c26161f684d6c0c6867a746f3148548Craig Stout mAttached = true; 6802e2e91a93f6d03108a73e7b4a05d289589957a0eCraig Stout syncWithService(); 68117993c442c26161f684d6c0c6867a746f3148548Craig Stout } 68217993c442c26161f684d6c0c6867a746f3148548Craig Stout 68317993c442c26161f684d6c0c6867a746f3148548Craig Stout /** 6840f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout * Returns true if the background manager is currently attached; false otherwise. 6850f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout */ 6860f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout public boolean isAttached() { 6870f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout return mAttached; 6880f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout } 6890f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout 6900f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout /** 691146a2a07c0e9750c2bdd5bd434197c2f46fea662Tim Kilbourn * Release references to Drawables and put the BackgroundManager into the 692146a2a07c0e9750c2bdd5bd434197c2f46fea662Tim Kilbourn * detached state. Called when the associated Activity is destroyed. 69317993c442c26161f684d6c0c6867a746f3148548Craig Stout * @hide 69417993c442c26161f684d6c0c6867a746f3148548Craig Stout */ 69517993c442c26161f684d6c0c6867a746f3148548Craig Stout void detach() { 6963d9d8cbaa9086f3ca2f486233fa3051e614a99edCraig Stout if (DEBUG) Log.v(TAG, "detach " + this); 69717993c442c26161f684d6c0c6867a746f3148548Craig Stout release(); 69817993c442c26161f684d6c0c6867a746f3148548Craig Stout 69917993c442c26161f684d6c0c6867a746f3148548Craig Stout if (mWindowManager != null && mBgView != null) { 70017993c442c26161f684d6c0c6867a746f3148548Craig Stout mWindowManager.removeViewImmediate(mBgView); 70117993c442c26161f684d6c0c6867a746f3148548Craig Stout } 70217993c442c26161f684d6c0c6867a746f3148548Craig Stout 70317993c442c26161f684d6c0c6867a746f3148548Craig Stout mWindowManager = null; 70417993c442c26161f684d6c0c6867a746f3148548Craig Stout mWindow = null; 70517993c442c26161f684d6c0c6867a746f3148548Craig Stout mBgView = null; 70617993c442c26161f684d6c0c6867a746f3148548Craig Stout mAttached = false; 70717993c442c26161f684d6c0c6867a746f3148548Craig Stout 70817993c442c26161f684d6c0c6867a746f3148548Craig Stout if (mService != null) { 70917993c442c26161f684d6c0c6867a746f3148548Craig Stout mService.unref(); 71017993c442c26161f684d6c0c6867a746f3148548Craig Stout mService = null; 71117993c442c26161f684d6c0c6867a746f3148548Craig Stout } 71217993c442c26161f684d6c0c6867a746f3148548Craig Stout } 71317993c442c26161f684d6c0c6867a746f3148548Craig Stout 71417993c442c26161f684d6c0c6867a746f3148548Craig Stout /** 715146a2a07c0e9750c2bdd5bd434197c2f46fea662Tim Kilbourn * Release references to Drawables. Typically called to reduce memory 716146a2a07c0e9750c2bdd5bd434197c2f46fea662Tim Kilbourn * overhead when not visible. 7172e2e91a93f6d03108a73e7b4a05d289589957a0eCraig Stout * <p> 718146a2a07c0e9750c2bdd5bd434197c2f46fea662Tim Kilbourn * When an Activity is resumed, if the BackgroundManager has not been 719146a2a07c0e9750c2bdd5bd434197c2f46fea662Tim Kilbourn * released, the continuity service is updated from the BackgroundManager 720146a2a07c0e9750c2bdd5bd434197c2f46fea662Tim Kilbourn * state. If the BackgroundManager was released, the BackgroundManager 721146a2a07c0e9750c2bdd5bd434197c2f46fea662Tim Kilbourn * inherits the current state from the continuity service. 72217993c442c26161f684d6c0c6867a746f3148548Craig Stout */ 72317993c442c26161f684d6c0c6867a746f3148548Craig Stout public void release() { 7243d9d8cbaa9086f3ca2f486233fa3051e614a99edCraig Stout if (DEBUG) Log.v(TAG, "release " + this); 7252e2e91a93f6d03108a73e7b4a05d289589957a0eCraig Stout if (mLayerDrawable != null) { 726d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout mLayerDrawable.clearDrawable(R.id.background_imagein, mContext); 727d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout mLayerDrawable.clearDrawable(R.id.background_imageout, mContext); 728d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout mLayerDrawable.clearDrawable(R.id.background_theme, mContext); 7292e2e91a93f6d03108a73e7b4a05d289589957a0eCraig Stout mLayerDrawable = null; 7302e2e91a93f6d03108a73e7b4a05d289589957a0eCraig Stout } 73117993c442c26161f684d6c0c6867a746f3148548Craig Stout if (mChangeRunnable != null) { 7320f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout mHandler.removeCallbacks(mChangeRunnable); 73317993c442c26161f684d6c0c6867a746f3148548Craig Stout mChangeRunnable = null; 73417993c442c26161f684d6c0c6867a746f3148548Craig Stout } 73517993c442c26161f684d6c0c6867a746f3148548Craig Stout releaseBackgroundBitmap(); 73617993c442c26161f684d6c0c6867a746f3148548Craig Stout } 73717993c442c26161f684d6c0c6867a746f3148548Craig Stout 73817993c442c26161f684d6c0c6867a746f3148548Craig Stout private void releaseBackgroundBitmap() { 73917993c442c26161f684d6c0c6867a746f3148548Craig Stout mBackgroundDrawable = null; 74017993c442c26161f684d6c0c6867a746f3148548Craig Stout } 74117993c442c26161f684d6c0c6867a746f3148548Craig Stout 7420f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout /** 7430f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout * Sets the drawable used as a dim layer. 7440f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout */ 7450f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout public void setDimLayer(Drawable drawable) { 7460f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout mDimDrawable = drawable; 7470f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout updateDimWrapper(); 7480f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout } 7490f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout 7500f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout /** 7510f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout * Returns the drawable used as a dim layer. 7520f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout */ 7530f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout public Drawable getDimLayer() { 7540f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout return mDimDrawable; 7550f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout } 7560f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout 7570f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout /** 7580f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout * Returns the default drawable used as a dim layer. 7590f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout */ 7600f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout public Drawable getDefaultDimLayer() { 7610f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout return ContextCompat.getDrawable(mContext, R.color.lb_background_protection); 7620f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout } 7630f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout 76417993c442c26161f684d6c0c6867a746f3148548Craig Stout private void updateImmediate() { 76517993c442c26161f684d6c0c6867a746f3148548Craig Stout lazyInit(); 76617993c442c26161f684d6c0c6867a746f3148548Craig Stout 7672590c39739945451f80dcf8667709b93293fc8bcCraig Stout DrawableWrapper colorWrapper = getColorWrapper(); 7682590c39739945451f80dcf8667709b93293fc8bcCraig Stout if (colorWrapper != null) { 7692590c39739945451f80dcf8667709b93293fc8bcCraig Stout colorWrapper.setColor(mBackgroundColor); 7702590c39739945451f80dcf8667709b93293fc8bcCraig Stout } 7712590c39739945451f80dcf8667709b93293fc8bcCraig Stout DrawableWrapper dimWrapper = getDimWrapper(); 7722590c39739945451f80dcf8667709b93293fc8bcCraig Stout if (dimWrapper != null) { 7732590c39739945451f80dcf8667709b93293fc8bcCraig Stout dimWrapper.setAlpha(mBackgroundColor == Color.TRANSPARENT ? 0 : DIM_ALPHA_ON_SOLID); 77417993c442c26161f684d6c0c6867a746f3148548Craig Stout } 77517993c442c26161f684d6c0c6867a746f3148548Craig Stout showWallpaper(mBackgroundColor == Color.TRANSPARENT); 77617993c442c26161f684d6c0c6867a746f3148548Craig Stout 77717993c442c26161f684d6c0c6867a746f3148548Craig Stout if (mBackgroundDrawable == null) { 778d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout mLayerDrawable.clearDrawable(R.id.background_imagein, mContext); 77917993c442c26161f684d6c0c6867a746f3148548Craig Stout } else { 78017993c442c26161f684d6c0c6867a746f3148548Craig Stout if (DEBUG) Log.v(TAG, "Background drawable is available"); 7812590c39739945451f80dcf8667709b93293fc8bcCraig Stout mLayerDrawable.updateDrawable( 782d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout R.id.background_imagein, mBackgroundDrawable); 7832590c39739945451f80dcf8667709b93293fc8bcCraig Stout if (dimWrapper != null) { 7842590c39739945451f80dcf8667709b93293fc8bcCraig Stout dimWrapper.setAlpha(FULL_ALPHA); 78517993c442c26161f684d6c0c6867a746f3148548Craig Stout } 78617993c442c26161f684d6c0c6867a746f3148548Craig Stout } 78717993c442c26161f684d6c0c6867a746f3148548Craig Stout } 78817993c442c26161f684d6c0c6867a746f3148548Craig Stout 78917993c442c26161f684d6c0c6867a746f3148548Craig Stout /** 790146a2a07c0e9750c2bdd5bd434197c2f46fea662Tim Kilbourn * Set the background to the given color. The timing for when this becomes 791146a2a07c0e9750c2bdd5bd434197c2f46fea662Tim Kilbourn * visible in the app is undefined and may take place after a small delay. 79217993c442c26161f684d6c0c6867a746f3148548Craig Stout */ 79317993c442c26161f684d6c0c6867a746f3148548Craig Stout public void setColor(int color) { 79417993c442c26161f684d6c0c6867a746f3148548Craig Stout if (DEBUG) Log.v(TAG, "setColor " + Integer.toHexString(color)); 79517993c442c26161f684d6c0c6867a746f3148548Craig Stout 79617993c442c26161f684d6c0c6867a746f3148548Craig Stout mBackgroundColor = color; 79717993c442c26161f684d6c0c6867a746f3148548Craig Stout mService.setColor(mBackgroundColor); 79817993c442c26161f684d6c0c6867a746f3148548Craig Stout 7992590c39739945451f80dcf8667709b93293fc8bcCraig Stout DrawableWrapper colorWrapper = getColorWrapper(); 8002590c39739945451f80dcf8667709b93293fc8bcCraig Stout if (colorWrapper != null) { 8012590c39739945451f80dcf8667709b93293fc8bcCraig Stout colorWrapper.setColor(mBackgroundColor); 80217993c442c26161f684d6c0c6867a746f3148548Craig Stout } 80317993c442c26161f684d6c0c6867a746f3148548Craig Stout } 80417993c442c26161f684d6c0c6867a746f3148548Craig Stout 80517993c442c26161f684d6c0c6867a746f3148548Craig Stout /** 8065a8a7c929e07e3a3d17b2e5466785d271eee7657Jose Lima * Set the given drawable into the background. The provided Drawable will be 8075a8a7c929e07e3a3d17b2e5466785d271eee7657Jose Lima * used unmodified as the background, without any scaling or cropping 8085a8a7c929e07e3a3d17b2e5466785d271eee7657Jose Lima * applied to it. The timing for when this becomes visible in the app is 8095a8a7c929e07e3a3d17b2e5466785d271eee7657Jose Lima * undefined and may take place after a small delay. 81017993c442c26161f684d6c0c6867a746f3148548Craig Stout */ 81117993c442c26161f684d6c0c6867a746f3148548Craig Stout public void setDrawable(Drawable drawable) { 81217993c442c26161f684d6c0c6867a746f3148548Craig Stout if (DEBUG) Log.v(TAG, "setBackgroundDrawable " + drawable); 81317993c442c26161f684d6c0c6867a746f3148548Craig Stout setDrawableInternal(drawable); 81417993c442c26161f684d6c0c6867a746f3148548Craig Stout } 81517993c442c26161f684d6c0c6867a746f3148548Craig Stout 81617993c442c26161f684d6c0c6867a746f3148548Craig Stout private void setDrawableInternal(Drawable drawable) { 8175a8a7c929e07e3a3d17b2e5466785d271eee7657Jose Lima if (!mAttached) { 8185a8a7c929e07e3a3d17b2e5466785d271eee7657Jose Lima throw new IllegalStateException("Must attach before setting background drawable"); 8195a8a7c929e07e3a3d17b2e5466785d271eee7657Jose Lima } 8200f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout long delayMs = getRunnableDelay(); 8210f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout mLastSetTime = System.currentTimeMillis(); 82217993c442c26161f684d6c0c6867a746f3148548Craig Stout 82317993c442c26161f684d6c0c6867a746f3148548Craig Stout if (mChangeRunnable != null) { 824d6019d141130ae4811b78e37286faf93d5944fd9Craig Stout if (sameDrawable(drawable, mChangeRunnable.mDrawable)) { 8250f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout if (DEBUG) Log.v(TAG, "new drawable same as pending"); 826d6019d141130ae4811b78e37286faf93d5944fd9Craig Stout return; 827d6019d141130ae4811b78e37286faf93d5944fd9Craig Stout } 8280f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout mHandler.removeCallbacks(mChangeRunnable); 82917993c442c26161f684d6c0c6867a746f3148548Craig Stout } 830d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout 831d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout if (mLayerDrawable == null) { 832d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout if (DEBUG) Log.v(TAG, "setDrawableInternal while in released state"); 833d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout mBackgroundDrawable = drawable; 834d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout updateImmediate(); 835d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout return; 836d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout } 837d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout 83817993c442c26161f684d6c0c6867a746f3148548Craig Stout mChangeRunnable = new ChangeBackgroundRunnable(drawable); 83917993c442c26161f684d6c0c6867a746f3148548Craig Stout 8400f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout if (mAnimator.isStarted()) { 8413d9d8cbaa9086f3ca2f486233fa3051e614a99edCraig Stout if (DEBUG) Log.v(TAG, "animation in progress"); 8423d9d8cbaa9086f3ca2f486233fa3051e614a99edCraig Stout } else { 8430f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout if (DEBUG) Log.v(TAG, "posting runnable delayMs " + delayMs); 8440f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout mHandler.postDelayed(mChangeRunnable, delayMs); 8453d9d8cbaa9086f3ca2f486233fa3051e614a99edCraig Stout } 84617993c442c26161f684d6c0c6867a746f3148548Craig Stout } 84717993c442c26161f684d6c0c6867a746f3148548Craig Stout 8480f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout private long getRunnableDelay() { 8490f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout return Math.max(0, mLastSetTime + CHANGE_BG_DELAY_MS - System.currentTimeMillis()); 8500f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout } 8510f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout 85217993c442c26161f684d6c0c6867a746f3148548Craig Stout /** 8535a8a7c929e07e3a3d17b2e5466785d271eee7657Jose Lima * Set the given bitmap into the background. When using setBitmap to set the 8545a8a7c929e07e3a3d17b2e5466785d271eee7657Jose Lima * background, the provided bitmap will be scaled and cropped to correctly 8555a8a7c929e07e3a3d17b2e5466785d271eee7657Jose Lima * fit within the dimensions of the view. The timing for when this becomes 856146a2a07c0e9750c2bdd5bd434197c2f46fea662Tim Kilbourn * visible in the app is undefined and may take place after a small delay. 85717993c442c26161f684d6c0c6867a746f3148548Craig Stout */ 85817993c442c26161f684d6c0c6867a746f3148548Craig Stout public void setBitmap(Bitmap bitmap) { 8595a8a7c929e07e3a3d17b2e5466785d271eee7657Jose Lima if (DEBUG) { 8605a8a7c929e07e3a3d17b2e5466785d271eee7657Jose Lima Log.v(TAG, "setBitmap " + bitmap); 8615a8a7c929e07e3a3d17b2e5466785d271eee7657Jose Lima } 8625a8a7c929e07e3a3d17b2e5466785d271eee7657Jose Lima 8635a8a7c929e07e3a3d17b2e5466785d271eee7657Jose Lima if (bitmap == null) { 8645a8a7c929e07e3a3d17b2e5466785d271eee7657Jose Lima setDrawableInternal(null); 8655a8a7c929e07e3a3d17b2e5466785d271eee7657Jose Lima return; 8665a8a7c929e07e3a3d17b2e5466785d271eee7657Jose Lima } 86717993c442c26161f684d6c0c6867a746f3148548Craig Stout 86817993c442c26161f684d6c0c6867a746f3148548Craig Stout if (bitmap.getWidth() <= 0 || bitmap.getHeight() <= 0) { 8695a8a7c929e07e3a3d17b2e5466785d271eee7657Jose Lima if (DEBUG) { 8705a8a7c929e07e3a3d17b2e5466785d271eee7657Jose Lima Log.v(TAG, "invalid bitmap width or height"); 8715a8a7c929e07e3a3d17b2e5466785d271eee7657Jose Lima } 87217993c442c26161f684d6c0c6867a746f3148548Craig Stout return; 87317993c442c26161f684d6c0c6867a746f3148548Craig Stout } 87417993c442c26161f684d6c0c6867a746f3148548Craig Stout 8757f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout Matrix matrix = null; 87617993c442c26161f684d6c0c6867a746f3148548Craig Stout 8777f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout if ((bitmap.getWidth() != mWidthPx || bitmap.getHeight() != mHeightPx)) { 8785a8a7c929e07e3a3d17b2e5466785d271eee7657Jose Lima int dwidth = bitmap.getWidth(); 8795a8a7c929e07e3a3d17b2e5466785d271eee7657Jose Lima int dheight = bitmap.getHeight(); 8805a8a7c929e07e3a3d17b2e5466785d271eee7657Jose Lima float scale; 8815a8a7c929e07e3a3d17b2e5466785d271eee7657Jose Lima 8827f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout // Scale proportionately to fit width and height. 8835a8a7c929e07e3a3d17b2e5466785d271eee7657Jose Lima if (dwidth * mHeightPx > mWidthPx * dheight) { 8845a8a7c929e07e3a3d17b2e5466785d271eee7657Jose Lima scale = (float) mHeightPx / (float) dheight; 8855a8a7c929e07e3a3d17b2e5466785d271eee7657Jose Lima } else { 8865a8a7c929e07e3a3d17b2e5466785d271eee7657Jose Lima scale = (float) mWidthPx / (float) dwidth; 8875a8a7c929e07e3a3d17b2e5466785d271eee7657Jose Lima } 8885a8a7c929e07e3a3d17b2e5466785d271eee7657Jose Lima 8895a8a7c929e07e3a3d17b2e5466785d271eee7657Jose Lima int subX = Math.min((int) (mWidthPx / scale), dwidth); 8907f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout int dx = Math.max(0, (dwidth - subX) / 2); 8915a8a7c929e07e3a3d17b2e5466785d271eee7657Jose Lima 8927f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout matrix = new Matrix(); 8937f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout matrix.setScale(scale, scale); 8947f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout matrix.preTranslate(-dx, 0); 8957f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout 8967f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout if (DEBUG) Log.v(TAG, "original image size " + bitmap.getWidth() + "x" + bitmap.getHeight() + 8977f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout " scale " + scale + " dx " + dx); 89817993c442c26161f684d6c0c6867a746f3148548Craig Stout } 89917993c442c26161f684d6c0c6867a746f3148548Craig Stout 9007f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout BitmapDrawable bitmapDrawable = new BitmapDrawable(mContext.getResources(), bitmap, matrix); 90117993c442c26161f684d6c0c6867a746f3148548Craig Stout 90217993c442c26161f684d6c0c6867a746f3148548Craig Stout setDrawableInternal(bitmapDrawable); 90317993c442c26161f684d6c0c6867a746f3148548Craig Stout } 90417993c442c26161f684d6c0c6867a746f3148548Craig Stout 90517993c442c26161f684d6c0c6867a746f3148548Craig Stout private void applyBackgroundChanges() { 906d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout if (!mAttached) { 90717993c442c26161f684d6c0c6867a746f3148548Craig Stout return; 90817993c442c26161f684d6c0c6867a746f3148548Craig Stout } 90917993c442c26161f684d6c0c6867a746f3148548Craig Stout 91017993c442c26161f684d6c0c6867a746f3148548Craig Stout if (DEBUG) Log.v(TAG, "applyBackgroundChanges drawable " + mBackgroundDrawable); 91117993c442c26161f684d6c0c6867a746f3148548Craig Stout 9120f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout int dimAlpha = -1; 91317993c442c26161f684d6c0c6867a746f3148548Craig Stout 9142590c39739945451f80dcf8667709b93293fc8bcCraig Stout if (getImageOutWrapper() != null) { 9150f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout dimAlpha = mBackgroundColor == Color.TRANSPARENT ? 0 : DIM_ALPHA_ON_SOLID; 91617993c442c26161f684d6c0c6867a746f3148548Craig Stout } 91717993c442c26161f684d6c0c6867a746f3148548Craig Stout 9182590c39739945451f80dcf8667709b93293fc8bcCraig Stout DrawableWrapper imageInWrapper = getImageInWrapper(); 9192590c39739945451f80dcf8667709b93293fc8bcCraig Stout if (imageInWrapper == null && mBackgroundDrawable != null) { 92017993c442c26161f684d6c0c6867a746f3148548Craig Stout if (DEBUG) Log.v(TAG, "creating new imagein drawable"); 9212590c39739945451f80dcf8667709b93293fc8bcCraig Stout imageInWrapper = mLayerDrawable.updateDrawable( 922d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout R.id.background_imagein, mBackgroundDrawable); 9232590c39739945451f80dcf8667709b93293fc8bcCraig Stout if (DEBUG) Log.v(TAG, "imageInWrapper animation starting"); 9242590c39739945451f80dcf8667709b93293fc8bcCraig Stout imageInWrapper.setAlpha(0); 9252e2e91a93f6d03108a73e7b4a05d289589957a0eCraig Stout dimAlpha = FULL_ALPHA; 92617993c442c26161f684d6c0c6867a746f3148548Craig Stout } 92717993c442c26161f684d6c0c6867a746f3148548Craig Stout 9280f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout mAnimator.setDuration(FADE_DURATION); 9290f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout mAnimator.start(); 9300f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout 9312590c39739945451f80dcf8667709b93293fc8bcCraig Stout DrawableWrapper dimWrapper = getDimWrapper(); 9322590c39739945451f80dcf8667709b93293fc8bcCraig Stout if (dimWrapper != null && dimAlpha >= 0) { 93317993c442c26161f684d6c0c6867a746f3148548Craig Stout if (DEBUG) Log.v(TAG, "dimwrapper animation starting to " + dimAlpha); 9340f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout mDimAnimator.cancel(); 9352590c39739945451f80dcf8667709b93293fc8bcCraig Stout mDimAnimator.setIntValues(dimWrapper.getAlpha(), dimAlpha); 9360f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout mDimAnimator.setDuration(FADE_DURATION); 9370f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout mDimAnimator.setInterpolator( 9380f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout dimAlpha == FULL_ALPHA ? mDecelerateInterpolator : mAccelerateInterpolator); 9390f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout mDimAnimator.start(); 94017993c442c26161f684d6c0c6867a746f3148548Craig Stout } 94117993c442c26161f684d6c0c6867a746f3148548Craig Stout } 94217993c442c26161f684d6c0c6867a746f3148548Craig Stout 94317993c442c26161f684d6c0c6867a746f3148548Craig Stout /** 944146a2a07c0e9750c2bdd5bd434197c2f46fea662Tim Kilbourn * Returns the current background color. 94517993c442c26161f684d6c0c6867a746f3148548Craig Stout */ 94617993c442c26161f684d6c0c6867a746f3148548Craig Stout public final int getColor() { 94717993c442c26161f684d6c0c6867a746f3148548Craig Stout return mBackgroundColor; 94817993c442c26161f684d6c0c6867a746f3148548Craig Stout } 94917993c442c26161f684d6c0c6867a746f3148548Craig Stout 95017993c442c26161f684d6c0c6867a746f3148548Craig Stout /** 951146a2a07c0e9750c2bdd5bd434197c2f46fea662Tim Kilbourn * Returns the current background {@link Drawable}. 95217993c442c26161f684d6c0c6867a746f3148548Craig Stout */ 95317993c442c26161f684d6c0c6867a746f3148548Craig Stout public Drawable getDrawable() { 95417993c442c26161f684d6c0c6867a746f3148548Craig Stout return mBackgroundDrawable; 95517993c442c26161f684d6c0c6867a746f3148548Craig Stout } 95617993c442c26161f684d6c0c6867a746f3148548Craig Stout 9577f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout private boolean sameDrawable(Drawable first, Drawable second) { 9587f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout if (first == null || second == null) { 9597f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout return false; 9607f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout } 9617f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout if (first == second) { 9627f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout return true; 9637f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout } 9647f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout if (first instanceof BitmapDrawable && second instanceof BitmapDrawable) { 9657f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout if (((BitmapDrawable) first).getBitmap().sameAs(((BitmapDrawable) second).getBitmap())) { 9667f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout return true; 9677f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout } 9687f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout } 9697f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout return false; 9707f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout } 9717f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout 97217993c442c26161f684d6c0c6867a746f3148548Craig Stout /** 97317993c442c26161f684d6c0c6867a746f3148548Craig Stout * Task which changes the background. 97417993c442c26161f684d6c0c6867a746f3148548Craig Stout */ 97517993c442c26161f684d6c0c6867a746f3148548Craig Stout class ChangeBackgroundRunnable implements Runnable { 97617993c442c26161f684d6c0c6867a746f3148548Craig Stout private Drawable mDrawable; 97717993c442c26161f684d6c0c6867a746f3148548Craig Stout 97817993c442c26161f684d6c0c6867a746f3148548Craig Stout ChangeBackgroundRunnable(Drawable drawable) { 97917993c442c26161f684d6c0c6867a746f3148548Craig Stout mDrawable = drawable; 98017993c442c26161f684d6c0c6867a746f3148548Craig Stout } 98117993c442c26161f684d6c0c6867a746f3148548Craig Stout 98217993c442c26161f684d6c0c6867a746f3148548Craig Stout @Override 98317993c442c26161f684d6c0c6867a746f3148548Craig Stout public void run() { 9840f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout runTask(); 9850f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout mChangeRunnable = null; 98617993c442c26161f684d6c0c6867a746f3148548Craig Stout } 98717993c442c26161f684d6c0c6867a746f3148548Craig Stout 98817993c442c26161f684d6c0c6867a746f3148548Craig Stout private void runTask() { 989d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout if (mLayerDrawable == null) { 990d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout if (DEBUG) Log.v(TAG, "runTask while released - should not happen"); 991d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout return; 992d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout } 99317993c442c26161f684d6c0c6867a746f3148548Craig Stout 9947f85292289f235c50740c3180fdbcb4bb2bf9703Craig Stout if (sameDrawable(mDrawable, mBackgroundDrawable)) { 9950f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout if (DEBUG) Log.v(TAG, "new drawable same as current"); 9962e2e91a93f6d03108a73e7b4a05d289589957a0eCraig Stout return; 99717993c442c26161f684d6c0c6867a746f3148548Craig Stout } 99817993c442c26161f684d6c0c6867a746f3148548Craig Stout 9992e2e91a93f6d03108a73e7b4a05d289589957a0eCraig Stout releaseBackgroundBitmap(); 10002e2e91a93f6d03108a73e7b4a05d289589957a0eCraig Stout 10012590c39739945451f80dcf8667709b93293fc8bcCraig Stout DrawableWrapper imageInWrapper = getImageInWrapper(); 10022590c39739945451f80dcf8667709b93293fc8bcCraig Stout if (imageInWrapper != null) { 10030f82bdd768ca56c4d14fa96afe8ff0355360148bCraig Stout if (DEBUG) Log.v(TAG, "moving image in to image out"); 10042e2e91a93f6d03108a73e7b4a05d289589957a0eCraig Stout // Order is important! Setting a drawable "removes" the 10052e2e91a93f6d03108a73e7b4a05d289589957a0eCraig Stout // previous one from the view 1006d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout mLayerDrawable.clearDrawable(R.id.background_imagein, mContext); 10072590c39739945451f80dcf8667709b93293fc8bcCraig Stout mLayerDrawable.updateDrawable(R.id.background_imageout, 10082590c39739945451f80dcf8667709b93293fc8bcCraig Stout imageInWrapper.getDrawable()); 100917993c442c26161f684d6c0c6867a746f3148548Craig Stout } 10102e2e91a93f6d03108a73e7b4a05d289589957a0eCraig Stout 10112e2e91a93f6d03108a73e7b4a05d289589957a0eCraig Stout mBackgroundDrawable = mDrawable; 10122e2e91a93f6d03108a73e7b4a05d289589957a0eCraig Stout mService.setDrawable(mBackgroundDrawable); 10132e2e91a93f6d03108a73e7b4a05d289589957a0eCraig Stout 10142e2e91a93f6d03108a73e7b4a05d289589957a0eCraig Stout applyBackgroundChanges(); 101517993c442c26161f684d6c0c6867a746f3148548Craig Stout } 101617993c442c26161f684d6c0c6867a746f3148548Craig Stout } 101717993c442c26161f684d6c0c6867a746f3148548Craig Stout 1018d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout private static Drawable createEmptyDrawable(Context context) { 101917993c442c26161f684d6c0c6867a746f3148548Craig Stout Bitmap bitmap = null; 1020d6c1bec6bd003158e79da4c945ee57f915336e12Craig Stout return new BitmapDrawable(context.getResources(), bitmap); 102117993c442c26161f684d6c0c6867a746f3148548Craig Stout } 102217993c442c26161f684d6c0c6867a746f3148548Craig Stout 102317993c442c26161f684d6c0c6867a746f3148548Craig Stout private void showWallpaper(boolean show) { 102417993c442c26161f684d6c0c6867a746f3148548Craig Stout if (mWindow == null) { 102517993c442c26161f684d6c0c6867a746f3148548Craig Stout return; 102617993c442c26161f684d6c0c6867a746f3148548Craig Stout } 102717993c442c26161f684d6c0c6867a746f3148548Craig Stout 102817993c442c26161f684d6c0c6867a746f3148548Craig Stout WindowManager.LayoutParams layoutParams = mWindow.getAttributes(); 102917993c442c26161f684d6c0c6867a746f3148548Craig Stout if (show) { 103017993c442c26161f684d6c0c6867a746f3148548Craig Stout if ((layoutParams.flags & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) { 103117993c442c26161f684d6c0c6867a746f3148548Craig Stout return; 103217993c442c26161f684d6c0c6867a746f3148548Craig Stout } 103317993c442c26161f684d6c0c6867a746f3148548Craig Stout if (DEBUG) Log.v(TAG, "showing wallpaper"); 103417993c442c26161f684d6c0c6867a746f3148548Craig Stout layoutParams.flags |= WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER; 103517993c442c26161f684d6c0c6867a746f3148548Craig Stout } else { 103617993c442c26161f684d6c0c6867a746f3148548Craig Stout if ((layoutParams.flags & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) == 0) { 103717993c442c26161f684d6c0c6867a746f3148548Craig Stout return; 103817993c442c26161f684d6c0c6867a746f3148548Craig Stout } 103917993c442c26161f684d6c0c6867a746f3148548Craig Stout if (DEBUG) Log.v(TAG, "hiding wallpaper"); 104017993c442c26161f684d6c0c6867a746f3148548Craig Stout layoutParams.flags &= ~WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER; 104117993c442c26161f684d6c0c6867a746f3148548Craig Stout } 104217993c442c26161f684d6c0c6867a746f3148548Craig Stout 104317993c442c26161f684d6c0c6867a746f3148548Craig Stout mWindow.setAttributes(layoutParams); 104417993c442c26161f684d6c0c6867a746f3148548Craig Stout } 104517993c442c26161f684d6c0c6867a746f3148548Craig Stout} 1046