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.Handler; 23 import android.os.RemoteException; 24 import android.os.Trace; 25 import android.os.UserHandle; 26 import android.util.Log; 27 import android.view.Display; 28 import android.view.IWallpaperVisibilityListener; 29 import android.view.IWindowManager; 30 import android.view.WindowManagerGlobal; 31 32 import com.android.internal.annotations.VisibleForTesting; 33 import com.android.internal.colorextraction.ColorExtractor; 34 import com.android.internal.colorextraction.types.ExtractionType; 35 import com.android.internal.colorextraction.types.Tonal; 36 import com.android.keyguard.KeyguardUpdateMonitor; 37 import com.android.systemui.Dumpable; 38 39 import java.io.FileDescriptor; 40 import java.io.PrintWriter; 41 import java.util.Arrays; 42 43 /** 44 * ColorExtractor aware of wallpaper visibility 45 */ 46 public class SysuiColorExtractor extends ColorExtractor implements Dumpable { 47 private static final String TAG = "SysuiColorExtractor"; 48 private boolean mWallpaperVisible; 49 private boolean mMediaBackdropVisible; 50 // Colors to return when the wallpaper isn't visible 51 private final GradientColors mWpHiddenColors; 52 SysuiColorExtractor(Context context)53 public SysuiColorExtractor(Context context) { 54 this(context, new Tonal(context), true); 55 } 56 57 @VisibleForTesting SysuiColorExtractor(Context context, ExtractionType type, boolean registerVisibility)58 public SysuiColorExtractor(Context context, ExtractionType type, boolean registerVisibility) { 59 super(context, type); 60 mWpHiddenColors = new GradientColors(); 61 62 WallpaperColors systemColors = getWallpaperColors(WallpaperManager.FLAG_SYSTEM); 63 updateDefaultGradients(systemColors); 64 65 if (registerVisibility) { 66 try { 67 IWindowManager windowManagerService = WindowManagerGlobal.getWindowManagerService(); 68 Handler handler = Handler.getMain(); 69 boolean visible = windowManagerService.registerWallpaperVisibilityListener( 70 new IWallpaperVisibilityListener.Stub() { 71 @Override 72 public void onWallpaperVisibilityChanged(boolean newVisibility, 73 int displayId) throws RemoteException { 74 handler.post(() -> setWallpaperVisible(newVisibility)); 75 } 76 }, Display.DEFAULT_DISPLAY); 77 setWallpaperVisible(visible); 78 } catch (RemoteException e) { 79 Log.w(TAG, "Can't listen to wallpaper visibility changes", e); 80 } 81 } 82 83 WallpaperManager wallpaperManager = context.getSystemService(WallpaperManager.class); 84 if (wallpaperManager != null) { 85 // Listen to all users instead of only the current one. 86 wallpaperManager.removeOnColorsChangedListener(this); 87 wallpaperManager.addOnColorsChangedListener(this, null /* handler */, 88 UserHandle.USER_ALL); 89 } 90 } 91 updateDefaultGradients(WallpaperColors colors)92 private void updateDefaultGradients(WallpaperColors colors) { 93 Tonal.applyFallback(colors, mWpHiddenColors); 94 } 95 96 @Override onColorsChanged(WallpaperColors colors, int which, int userId)97 public void onColorsChanged(WallpaperColors colors, int which, int userId) { 98 if (userId != KeyguardUpdateMonitor.getCurrentUser()) { 99 // Colors do not belong to current user, ignoring. 100 return; 101 } 102 103 super.onColorsChanged(colors, which); 104 105 if ((which & WallpaperManager.FLAG_SYSTEM) != 0) { 106 updateDefaultGradients(colors); 107 } 108 } 109 110 @VisibleForTesting getFallbackColors()111 GradientColors getFallbackColors() { 112 return mWpHiddenColors; 113 } 114 115 /** 116 * Get TYPE_NORMAL colors when wallpaper is visible, or fallback otherwise. 117 * 118 * @param which FLAG_LOCK or FLAG_SYSTEM 119 * @return colors 120 */ 121 @Override getColors(int which)122 public GradientColors getColors(int which) { 123 return getColors(which, TYPE_DARK); 124 } 125 126 /** 127 * Wallpaper colors when the wallpaper is visible, fallback otherwise. 128 * 129 * @param which FLAG_LOCK or FLAG_SYSTEM 130 * @param type TYPE_NORMAL, TYPE_DARK or TYPE_EXTRA_DARK 131 * @return colors 132 */ 133 @Override getColors(int which, int type)134 public GradientColors getColors(int which, int type) { 135 return getColors(which, type, false /* ignoreVisibility */); 136 } 137 138 /** 139 * Get TYPE_NORMAL colors, possibly ignoring wallpaper visibility. 140 * 141 * @param which FLAG_LOCK or FLAG_SYSTEM 142 * @param ignoreWallpaperVisibility whether you want fallback colors or not if the wallpaper 143 * isn't visible 144 * @return 145 */ getColors(int which, boolean ignoreWallpaperVisibility)146 public GradientColors getColors(int which, boolean ignoreWallpaperVisibility) { 147 return getColors(which, TYPE_NORMAL, ignoreWallpaperVisibility); 148 } 149 150 /** 151 * 152 * @param which FLAG_LOCK or FLAG_SYSTEM 153 * @param type TYPE_NORMAL, TYPE_DARK or TYPE_EXTRA_DARK 154 * @param ignoreWallpaperVisibility true if true wallpaper colors should be returning 155 * if it's visible or not 156 * @return colors 157 */ getColors(int which, int type, boolean ignoreWallpaperVisibility)158 public GradientColors getColors(int which, int type, boolean ignoreWallpaperVisibility) { 159 // mWallpaperVisible only handles the "system wallpaper" and will be always set to false 160 // if we have different lock and system wallpapers. 161 if (which == WallpaperManager.FLAG_SYSTEM) { 162 if (mWallpaperVisible || ignoreWallpaperVisibility) { 163 return super.getColors(which, type); 164 } else { 165 return mWpHiddenColors; 166 } 167 } else { 168 if (mMediaBackdropVisible) { 169 return mWpHiddenColors; 170 } else { 171 return super.getColors(which, type); 172 } 173 } 174 } 175 176 @VisibleForTesting setWallpaperVisible(boolean visible)177 void setWallpaperVisible(boolean visible) { 178 if (mWallpaperVisible != visible) { 179 mWallpaperVisible = visible; 180 triggerColorsChanged(WallpaperManager.FLAG_SYSTEM); 181 } 182 } 183 setMediaBackdropVisible(boolean visible)184 public void setMediaBackdropVisible(boolean visible) { 185 if (mMediaBackdropVisible != visible) { 186 mMediaBackdropVisible = visible; 187 triggerColorsChanged(WallpaperManager.FLAG_LOCK); 188 } 189 } 190 191 @Override dump(FileDescriptor fd, PrintWriter pw, String[] args)192 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 193 pw.println("SysuiColorExtractor:"); 194 195 pw.println(" Current wallpaper colors:"); 196 pw.println(" system: " + mSystemColors); 197 pw.println(" lock: " + mLockColors); 198 199 GradientColors[] system = mGradientColors.get(WallpaperManager.FLAG_SYSTEM); 200 GradientColors[] lock = mGradientColors.get(WallpaperManager.FLAG_LOCK); 201 pw.println(" Gradients:"); 202 pw.println(" system: " + Arrays.toString(system)); 203 pw.println(" lock: " + Arrays.toString(lock)); 204 pw.println(" Default scrim: " + mWpHiddenColors); 205 206 } 207 } 208