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