1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License 15 */ 16 17 package com.example.android.leanback; 18 19 import android.app.Activity; 20 import android.graphics.Bitmap; 21 import android.graphics.drawable.BitmapDrawable; 22 import android.graphics.drawable.Drawable; 23 import android.os.AsyncTask; 24 import android.os.Handler; 25 import android.support.v17.leanback.app.BackgroundManager; 26 import android.support.v4.content.ContextCompat; 27 import android.util.Log; 28 29 public class BackgroundHelper { 30 31 private static final String TAG = "BackgroundHelper"; 32 private static final boolean DEBUG = false; 33 private static final boolean ENABLED = true; 34 35 // Background delay serves to avoid kicking off expensive bitmap loading 36 // in case multiple backgrounds are set in quick succession. 37 private static final int SET_BACKGROUND_DELAY_MS = 100; 38 39 static class Request { 40 Object mImageToken; 41 Activity mActivity; 42 Bitmap mResult; 43 Request(Activity activity, Object imageToken)44 Request(Activity activity, Object imageToken) { 45 mActivity = activity; 46 mImageToken = imageToken; 47 } 48 } 49 BackgroundHelper()50 public BackgroundHelper() { 51 if (DEBUG && !ENABLED) Log.v(TAG, "BackgroundHelper: disabled"); 52 } 53 54 class LoadBackgroundRunnable implements Runnable { 55 Request mRequest; 56 LoadBackgroundRunnable(Activity activity, Object imageToken)57 LoadBackgroundRunnable(Activity activity, Object imageToken) { 58 mRequest = new Request(activity, imageToken); 59 } 60 61 @Override run()62 public void run() { 63 if (mTask != null) { 64 if (DEBUG) Log.v(TAG, "Cancelling task"); 65 mTask.cancel(true); 66 } 67 if (DEBUG) Log.v(TAG, "Executing task"); 68 mTask = new LoadBitmapTask(); 69 mTask.execute(mRequest); 70 mRunnable = null; 71 } 72 }; 73 74 class LoadBitmapTask extends AsyncTask<Request, Object, Request> { 75 @Override doInBackground(Request... params)76 protected Request doInBackground(Request... params) { 77 boolean cancelled = isCancelled(); 78 if (DEBUG) Log.v(TAG, "doInBackground cancelled " + cancelled); 79 Request request = params[0]; 80 if (!cancelled) { 81 request.mResult = loadBitmap(request.mActivity, request.mImageToken); 82 } 83 return request; 84 } 85 86 @Override onPostExecute(Request request)87 protected void onPostExecute(Request request) { 88 if (DEBUG) Log.v(TAG, "onPostExecute"); 89 applyBackground(request.mActivity, request.mResult); 90 if (mTask == this) { 91 mTask = null; 92 } 93 } 94 95 @Override onCancelled(Request request)96 protected void onCancelled(Request request) { 97 if (DEBUG) Log.v(TAG, "onCancelled"); 98 } 99 loadBitmap(Activity activity, Object imageToken)100 private Bitmap loadBitmap(Activity activity, Object imageToken) { 101 if (imageToken instanceof Integer) { 102 final int resourceId = (Integer) imageToken; 103 if (DEBUG) Log.v(TAG, "load resourceId " + resourceId); 104 Drawable drawable = ContextCompat.getDrawable(activity, resourceId); 105 if (drawable instanceof BitmapDrawable) { 106 return ((BitmapDrawable) drawable).getBitmap(); 107 } 108 } 109 return null; 110 } 111 applyBackground(Activity activity, Bitmap bitmap)112 private void applyBackground(Activity activity, Bitmap bitmap) { 113 BackgroundManager backgroundManager = BackgroundManager.getInstance(activity); 114 if (backgroundManager == null || !backgroundManager.isAttached()) { 115 return; 116 } 117 backgroundManager.setBitmap(bitmap); 118 } 119 } 120 121 private LoadBackgroundRunnable mRunnable; 122 private LoadBitmapTask mTask; 123 124 // Allocate a dedicated handler because there may be no view available 125 // when setBackground is invoked. 126 private Handler mHandler = new Handler(); 127 setBackground(Activity activity, Object imageToken)128 public void setBackground(Activity activity, Object imageToken) { 129 if (!ENABLED) { 130 return; 131 } 132 if (mRunnable != null) { 133 mHandler.removeCallbacks(mRunnable); 134 } 135 mRunnable = new LoadBackgroundRunnable(activity, imageToken); 136 mHandler.postDelayed(mRunnable, SET_BACKGROUND_DELAY_MS); 137 } 138 attach(Activity activity)139 static public void attach(Activity activity) { 140 if (!ENABLED) { 141 return; 142 } 143 if (DEBUG) Log.v(TAG, "attach to activity " + activity); 144 BackgroundManager.getInstance(activity).attach(activity.getWindow()); 145 } 146 release(Activity activity)147 static public void release(Activity activity) { 148 if (!ENABLED) { 149 return; 150 } 151 if (DEBUG) Log.v(TAG, "release from activity " + activity); 152 BackgroundManager.getInstance(activity).release(); 153 } 154 } 155