• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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.wallpaper.asset;
17 
18 import android.app.Activity;
19 import android.app.WallpaperManager;
20 import android.content.Context;
21 import android.graphics.Bitmap;
22 import android.graphics.Point;
23 import android.graphics.Rect;
24 import android.graphics.drawable.BitmapDrawable;
25 import android.graphics.drawable.Drawable;
26 import android.os.AsyncTask;
27 
28 /**
29  * Asset implementation which represents the currently-set wallpaper on API 16 through 23 devices.
30  */
31 public class CurrentWallpaperAssetV16 extends Asset {
32 
33     private static final boolean FILTER_SCALED_BITMAP = true;
34 
35     private Context mApplicationContext;
36 
CurrentWallpaperAssetV16(Context context)37     public CurrentWallpaperAssetV16(Context context) {
38         mApplicationContext = context.getApplicationContext();
39     }
40 
41     @Override
decodeBitmapRegion(Rect rect, int targetWidth, int targetHeight, BitmapReceiver receiver)42     public void decodeBitmapRegion(Rect rect, int targetWidth, int targetHeight,
43                                    BitmapReceiver receiver) {
44         receiver.onBitmapDecoded(null);
45     }
46 
47     @Override
decodeBitmap(int targetWidth, int targetHeight, BitmapReceiver receiver)48     public void decodeBitmap(int targetWidth, int targetHeight,
49                              BitmapReceiver receiver) {
50         DecodeBitmapAsyncTask task = new DecodeBitmapAsyncTask(receiver, targetWidth, targetHeight);
51         task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
52     }
53 
54     @Override
supportsTiling()55     public boolean supportsTiling() {
56         return false;
57     }
58 
59     @Override
decodeRawDimensions(Activity unused, DimensionsReceiver receiver)60     public void decodeRawDimensions(Activity unused, DimensionsReceiver receiver) {
61         DecodeDimensionsAsyncTask task = new DecodeDimensionsAsyncTask(receiver);
62         task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
63     }
64 
getCurrentWallpaperDrawable()65     private Drawable getCurrentWallpaperDrawable() {
66         WallpaperManager wallpaperManager = WallpaperManager.getInstance(mApplicationContext);
67         Drawable drawable;
68         try {
69             drawable = wallpaperManager.getDrawable();
70         } catch (java.lang.SecurityException e) {
71             // Work around Samsung bug where SecurityException is thrown if device is still using its
72             // default wallpaper.
73             drawable = wallpaperManager.getBuiltInDrawable();
74         }
75         return drawable;
76     }
77 
78     /**
79      * Decodes and then post-decode scales down the currently-set wallpaper bitmap.
80      */
81     private class DecodeBitmapAsyncTask extends AsyncTask<Void, Void, Bitmap> {
82 
83         private BitmapReceiver mReceiver;
84         private int mTargetWidth;
85         private int mTargetHeight;
86 
DecodeBitmapAsyncTask(BitmapReceiver receiver, int width, int height)87         public DecodeBitmapAsyncTask(BitmapReceiver receiver, int width, int height) {
88             mReceiver = receiver;
89             mTargetWidth = width;
90             mTargetHeight = height;
91         }
92 
93         @Override
doInBackground(Void... unused)94         protected Bitmap doInBackground(Void... unused) {
95             Drawable wallpaperDrawable = getCurrentWallpaperDrawable();
96             Bitmap bitmap = ((BitmapDrawable) wallpaperDrawable).getBitmap();
97 
98             // The final bitmap may be constrained by only one of height and width, so find the maximum
99             // downscaling factor without having the final result bitmap's height or width dip below the
100             // provided target height or width.
101             float maxDownscaleFactor = Math.min((float) bitmap.getWidth() / mTargetWidth,
102                     (float) bitmap.getHeight() / mTargetHeight);
103 
104             // Scale down full bitmap to save memory consumption post-decoding, while maintaining the
105             // source bitmap's aspect ratio.
106             int resultWidth = Math.round(bitmap.getWidth() / maxDownscaleFactor);
107             int resultHeight = Math.round(bitmap.getHeight() / maxDownscaleFactor);
108             return Bitmap.createScaledBitmap(bitmap, resultWidth, resultHeight, FILTER_SCALED_BITMAP);
109         }
110 
111         @Override
onPostExecute(Bitmap bitmap)112         protected void onPostExecute(Bitmap bitmap) {
113             mReceiver.onBitmapDecoded(bitmap);
114         }
115     }
116 
117     /**
118      * Decodes the raw dimensions of the currently-set wallpaper.
119      */
120     private class DecodeDimensionsAsyncTask extends AsyncTask<Void, Void, Point> {
121 
122         private DimensionsReceiver mReceiver;
123 
DecodeDimensionsAsyncTask(DimensionsReceiver receiver)124         public DecodeDimensionsAsyncTask(DimensionsReceiver receiver) {
125             mReceiver = receiver;
126         }
127 
128         @Override
doInBackground(Void... unused)129         protected Point doInBackground(Void... unused) {
130             Drawable wallpaperDrawable = getCurrentWallpaperDrawable();
131             return new Point(
132                     wallpaperDrawable.getIntrinsicWidth(), wallpaperDrawable.getIntrinsicHeight());
133         }
134 
135         @Override
onPostExecute(Point dimensions)136         protected void onPostExecute(Point dimensions) {
137             mReceiver.onDimensionsDecoded(dimensions);
138         }
139     }
140 }
141