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 
17 package com.android.systemui.colorextraction;
18 
19 import android.app.WallpaperColors;
20 import android.app.WallpaperManager;
21 import android.content.Context;
22 import android.os.UserHandle;
23 
24 import com.android.internal.annotations.VisibleForTesting;
25 import com.android.internal.colorextraction.ColorExtractor;
26 import com.android.internal.colorextraction.types.ExtractionType;
27 import com.android.internal.colorextraction.types.Tonal;
28 import com.android.systemui.Dumpable;
29 import com.android.systemui.dagger.SysUISingleton;
30 import com.android.systemui.dump.DumpManager;
31 import com.android.systemui.statusbar.policy.ConfigurationController;
32 import com.android.systemui.user.domain.interactor.SelectedUserInteractor;
33 
34 import dagger.Lazy;
35 
36 import java.io.PrintWriter;
37 import java.util.Arrays;
38 
39 import javax.inject.Inject;
40 
41 /**
42  * ColorExtractor aware of wallpaper visibility
43  */
44 @SysUISingleton
45 public class SysuiColorExtractor extends ColorExtractor implements Dumpable,
46         ConfigurationController.ConfigurationListener {
47     private static final String TAG = "SysuiColorExtractor";
48     private final Tonal mTonal;
49     private final GradientColors mNeutralColorsLock;
50     private Lazy<SelectedUserInteractor> mUserInteractor;
51 
52     @Inject
SysuiColorExtractor( Context context, ConfigurationController configurationController, DumpManager dumpManager, Lazy<SelectedUserInteractor> userInteractor)53     public SysuiColorExtractor(
54             Context context,
55             ConfigurationController configurationController,
56             DumpManager dumpManager,
57             Lazy<SelectedUserInteractor> userInteractor) {
58         this(
59                 context,
60                 new Tonal(context),
61                 configurationController,
62                 context.getSystemService(WallpaperManager.class),
63                 dumpManager,
64                 false /* immediately */,
65                 userInteractor);
66     }
67 
68     @VisibleForTesting
SysuiColorExtractor( Context context, ExtractionType type, ConfigurationController configurationController, WallpaperManager wallpaperManager, DumpManager dumpManager, boolean immediately, Lazy<SelectedUserInteractor> userInteractor)69     public SysuiColorExtractor(
70             Context context,
71             ExtractionType type,
72             ConfigurationController configurationController,
73             WallpaperManager wallpaperManager,
74             DumpManager dumpManager,
75             boolean immediately,
76             Lazy<SelectedUserInteractor> userInteractor) {
77         super(context, type, immediately, wallpaperManager);
78         mTonal = type instanceof Tonal ? (Tonal) type : new Tonal(context);
79         mNeutralColorsLock = new GradientColors();
80         configurationController.addCallback(this);
81         dumpManager.registerDumpable(getClass().getSimpleName(), this);
82         mUserInteractor = userInteractor;
83 
84         // Listen to all users instead of only the current one.
85         if (wallpaperManager.isWallpaperSupported()) {
86             wallpaperManager.removeOnColorsChangedListener(this);
87             wallpaperManager.addOnColorsChangedListener(this, null /* handler */,
88                     UserHandle.USER_ALL);
89         }
90     }
91 
92     @Override
extractWallpaperColors()93     protected void extractWallpaperColors() {
94         super.extractWallpaperColors();
95         // mTonal is final but this method will be invoked by the base class during its ctor.
96         if (mTonal == null || mNeutralColorsLock == null) {
97             return;
98         }
99         mTonal.applyFallback(mLockColors == null ? mSystemColors : mLockColors, mNeutralColorsLock);
100     }
101 
102     @Override
onColorsChanged(WallpaperColors colors, int which, int userId)103     public void onColorsChanged(WallpaperColors colors, int which, int userId) {
104         if (userId != mUserInteractor.get().getSelectedUserId()) {
105             // Colors do not belong to current user, ignoring.
106             return;
107         }
108         if ((which & WallpaperManager.FLAG_LOCK) != 0) {
109             mTonal.applyFallback(colors, mNeutralColorsLock);
110         }
111         super.onColorsChanged(colors, which);
112     }
113 
114     @Override
onUiModeChanged()115     public void onUiModeChanged() {
116         extractWallpaperColors();
117         triggerColorsChanged(WallpaperManager.FLAG_SYSTEM | WallpaperManager.FLAG_LOCK);
118     }
119 
120     /**
121      * Colors that should be using for scrims.
122      *
123      * They will be:
124      * - A light gray if the wallpaper is light
125      * - A dark gray if the wallpaper is very dark or we're in night mode.
126      * - Black otherwise
127      */
getNeutralColors()128     public GradientColors getNeutralColors() {
129         return mNeutralColorsLock;
130     }
131 
132     @Override
dump(PrintWriter pw, String[] args)133     public void dump(PrintWriter pw, String[] args) {
134         pw.println("SysuiColorExtractor:");
135 
136         pw.println("  Current wallpaper colors:");
137         pw.println("    system: " + mSystemColors);
138         pw.println("    lock: " + mLockColors);
139 
140         GradientColors[] system = mGradientColors.get(WallpaperManager.FLAG_SYSTEM);
141         GradientColors[] lock = mGradientColors.get(WallpaperManager.FLAG_LOCK);
142         pw.println("  Gradients:");
143         pw.println("    system: " + Arrays.toString(system));
144         pw.println("    lock: " + Arrays.toString(lock));
145         pw.println("  Neutral colors: " + mNeutralColorsLock);
146     }
147 }
148