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