1 /*
2  * Copyright (C) 2020 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.widget;
17 
18 import android.app.WallpaperColors;
19 import android.content.Context;
20 import android.graphics.Bitmap;
21 import android.graphics.Point;
22 import android.util.Log;
23 import android.util.LruCache;
24 import android.view.Display;
25 import android.view.WindowManager;
26 
27 import androidx.annotation.NonNull;
28 import androidx.annotation.Nullable;
29 
30 import com.android.wallpaper.asset.Asset;
31 import com.android.wallpaper.asset.BitmapCachingAsset;
32 import com.android.wallpaper.util.ScreenSizeCalculator;
33 
34 /** A class to load the {@link WallpaperColors} from wallpaper {@link Asset}. */
35 public class WallpaperColorsLoader {
36     private static final String TAG = "WallpaperColorsLoader";
37 
38     /** Callback of loading a {@link WallpaperColors}. */
39     public interface Callback {
40         /** Gets called when a {@link WallpaperColors} is loaded. */
onLoaded(@ullable WallpaperColors colors)41         void onLoaded(@Nullable WallpaperColors colors);
42     }
43 
44     // The max size should be at least 2 for storing home and lockscreen wallpaper if they are
45     // different.
46     private static LruCache<Asset, WallpaperColors> sCache = new LruCache<>(/* maxSize= */ 6);
47 
48     /** Gets the {@link WallpaperColors} from the wallpaper {@link Asset}. */
getWallpaperColors(Context context, @NonNull Asset asset, @NonNull Callback callback)49     public static void getWallpaperColors(Context context, @NonNull Asset asset,
50                                           @NonNull Callback callback) {
51         WallpaperColors cached = sCache.get(asset);
52         if (cached != null) {
53             callback.onLoaded(cached);
54             return;
55         }
56 
57         Display display = context.getSystemService(WindowManager.class).getDefaultDisplay();
58         Point screen = ScreenSizeCalculator.getInstance().getScreenSize(display);
59         new BitmapCachingAsset(context, asset).decodeBitmap(screen.y / 2, screen.x / 2, bitmap -> {
60             if (bitmap != null) {
61                 boolean shouldRecycle = false;
62                 if (bitmap.getConfig() == Bitmap.Config.HARDWARE) {
63                     bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, false);
64                     shouldRecycle = true;
65                 }
66                 WallpaperColors colors = WallpaperColors.fromBitmap(bitmap);
67                 sCache.put(asset, colors);
68                 callback.onLoaded(colors);
69                 if (shouldRecycle) {
70                     bitmap.recycle();
71                 }
72             } else {
73                 Log.i(TAG, "Can't get wallpaper colors from a null bitmap, uses null color.");
74                 callback.onLoaded(null);
75             }
76         });
77     }
78 }
79