1 /*
2  * Copyright (C) 2021 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.picker;
17 
18 import android.app.WallpaperColors;
19 import android.content.Context;
20 import android.util.Log;
21 import android.view.SurfaceView;
22 import android.view.View;
23 import android.view.Window;
24 
25 import androidx.annotation.Nullable;
26 import androidx.fragment.app.FragmentActivity;
27 
28 import com.android.customization.model.color.ColorUtils;
29 import com.android.wallpaper.module.InjectorProvider;
30 
31 import com.google.android.material.color.MaterialColors;
32 
33 /** Interface to help Fragment to preview wallpaper color theme. */
34 public interface WallpaperColorThemePreview {
35 
36     String TAG = "WallpaperColorThemePreview";
37 
38     /** */
getActivity()39     FragmentActivity getActivity();
40 
41     /**
42      * Updates the color of status bar and navigation bar with the background color attribute
43      * extracted from {@code context}.
44      */
updateSystemBarColor(Context context)45     default void updateSystemBarColor(Context context) {
46         int colorPrimary = MaterialColors.getColor(context, android.R.attr.colorPrimary,
47                 "android.R.attr.colorPrimary is not set in the current theme");
48         Window window = getActivity().getWindow();
49         window.setStatusBarColor(colorPrimary);
50         window.setNavigationBarColor(colorPrimary);
51     }
52 
53     /** Updates the background color for the given {@code fragmentView}. */
updateBackgroundColor(Context context, View fragmentView)54     default void updateBackgroundColor(Context context, View fragmentView) {
55         int colorPrimary = MaterialColors.getColor(context, android.R.attr.colorPrimary,
56                 "android.R.attr.colorPrimary is not set in the current theme");
57         fragmentView.setBackgroundColor(colorPrimary);
58     }
59 
60     /** Returns {@code true} if the fragment theme should apply the wallpaper colors. */
shouldApplyWallpaperColors()61     default boolean shouldApplyWallpaperColors() {
62         FragmentActivity fragmentActivity = getActivity();
63         if (fragmentActivity == null || fragmentActivity.isFinishing()) {
64             Log.w(TAG, "shouldApplyWallpaperColors: activity is null or finishing");
65             return false;
66         }
67 
68         if (!ColorUtils.isMonetEnabled(fragmentActivity)) {
69             Log.w(TAG, "Monet is not enabled");
70             return false;
71         }
72         // If user selects a preset color, we should never apply the color extracted from the
73         // wallpaper preview.
74         Context appContext = fragmentActivity.getApplicationContext();
75         return !InjectorProvider.getInjector().isCurrentSelectedColorPreset(appContext);
76     }
77 
78     /**
79      * If needed, re-request a workspace preview from Launcher based on the updated WallpaperColors
80      * (which can be {@code null} to use the default color scheme.
81      */
updateWorkspacePreview(SurfaceView workspaceSurface, WorkspaceSurfaceHolderCallback callback, @Nullable WallpaperColors colors)82     default void updateWorkspacePreview(SurfaceView workspaceSurface,
83             WorkspaceSurfaceHolderCallback callback, @Nullable WallpaperColors colors) {
84         updateWorkspacePreview(workspaceSurface, callback, colors, false);
85     }
86 
87     /**
88      * If needed, re-request a workspace preview from Launcher based on the updated WallpaperColors
89      * (which can be {@code null} to use the default color scheme and the flag of whether to hide
90      * workspace QSB.
91      */
updateWorkspacePreview( SurfaceView workspaceSurface, WorkspaceSurfaceHolderCallback callback, @Nullable WallpaperColors colors, boolean hideBottomRow)92     default void updateWorkspacePreview(
93             SurfaceView workspaceSurface,
94             WorkspaceSurfaceHolderCallback callback,
95             @Nullable WallpaperColors colors,
96             boolean hideBottomRow) {
97         if (!shouldApplyWallpaperColors()) {
98             return;
99         }
100         // Adjust surface visibility to trigger a surfaceCreated event in the callback
101         int previousVisibility = workspaceSurface.getVisibility();
102         workspaceSurface.setVisibility(View.GONE);
103         if (callback != null) {
104             callback.cleanUp();
105             callback.setHideBottomRow(hideBottomRow);
106             callback.setWallpaperColors(colors);
107             callback.maybeRenderPreview();
108             workspaceSurface.setUseAlpha();
109             workspaceSurface.setAlpha(0);
110             callback.setListener(() -> {
111                 // Move one pixel to trigger a surface update, otherwise it won't pick up the
112                 // proper scale
113                 workspaceSurface.setTop(-1);
114                 workspaceSurface.animate().alpha(1f).setDuration(300).start();
115             });
116         }
117         workspaceSurface.setVisibility(previousVisibility);
118     }
119 }
120