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 package com.android.car.dialer;
17 
18 import com.android.car.dialer.telecom.TelecomUtils;
19 
20 import android.content.ContentResolver;
21 import android.graphics.Bitmap;
22 import android.os.AsyncTask;
23 import android.widget.ImageView;
24 
25 import java.lang.ref.WeakReference;
26 
27 /**
28  * AsyncTask for handling getting contact photo from number.
29  */
30 public class BitmapWorkerTask extends AsyncTask<Void, Void, Bitmap> {
31     private final WeakReference<ImageView> imageViewReference;
32     private final WeakReference<ContentResolver> contentResolverReference;
33     private final String mNumber;
34     private final BitmapRunnable mRunnable;
35 
BitmapWorkerTask( ContentResolver contentResolver, ImageView imageView, String number, BitmapRunnable runnable)36     public BitmapWorkerTask(
37             ContentResolver contentResolver, ImageView imageView,
38             String number, BitmapRunnable runnable) {
39         imageViewReference = new WeakReference<>(imageView);
40         contentResolverReference = new WeakReference<>(contentResolver);
41         mNumber = number;
42         mRunnable = runnable;
43     }
44 
45     @Override
doInBackground(Void... voids)46     protected Bitmap doInBackground(Void... voids) {
47         final ContentResolver contentResolver = contentResolverReference.get();
48         if (contentResolver != null) {
49             return TelecomUtils.getContactPhotoFromNumber(contentResolver, mNumber);
50         }
51         return null;
52     }
53 
54     @Override
onPostExecute(Bitmap bitmap)55     protected void onPostExecute(Bitmap bitmap) {
56         if (isCancelled()) {
57             return;
58         }
59 
60         final ImageView imageView = imageViewReference.get();
61         if (imageView != null) {
62             final BitmapWorkerTask bitmapWorkerTask = (BitmapWorkerTask) imageView.getTag();
63             if (this == bitmapWorkerTask) {
64                 mRunnable.setBitmap(bitmap);
65                 mRunnable.setImageView(imageView);
66                 mRunnable.setNumber(mNumber);
67                 mRunnable.run();
68             }
69         }
70     }
71 
loadBitmap( ContentResolver contentResolver, ImageView imageView, String number, BitmapRunnable runnable)72     public static void loadBitmap(
73             ContentResolver contentResolver, ImageView imageView,
74             String number, BitmapRunnable runnable) {
75         if (cancelPotentialWork(number, imageView)) {
76             final BitmapWorkerTask task =
77                     new BitmapWorkerTask(contentResolver, imageView, number, runnable);
78             imageView.setTag(task);
79             imageView.setImageResource(0);
80             task.execute();
81         }
82     }
83 
cancelPotentialWork(String number, ImageView imageView)84     private static boolean cancelPotentialWork(String number, ImageView imageView) {
85         final BitmapWorkerTask bitmapWorkerTask = (BitmapWorkerTask) imageView.getTag();
86         if (bitmapWorkerTask != null) {
87             if (bitmapWorkerTask.mNumber != number) {
88                 bitmapWorkerTask.cancel(true);
89             } else {
90                 // The same work is already in progress
91                 return false;
92             }
93         }
94 
95         return true;
96     }
97 
98     /**
99      * Generate interface for handling logic after getting bitmap.
100      */
101     public static abstract class BitmapRunnable implements Runnable {
102         protected String mNumber;
103         protected Bitmap mBitmap;
104         protected ImageView mImageView;
105 
setBitmap(Bitmap bitmap)106         public void setBitmap(Bitmap bitmap) {
107             mBitmap = bitmap;
108         }
109 
setImageView(ImageView imageView)110         public void setImageView(ImageView imageView) {
111             mImageView = imageView;
112         }
113 
setNumber(String number)114         public void setNumber(String number) {
115             mNumber = number;
116         }
117     }
118 }
119