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