1 /* 2 * Copyright (C) 2019 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.statusbar.notification; 18 19 import android.content.Context; 20 import android.util.ArraySet; 21 22 import com.android.internal.annotations.VisibleForTesting; 23 import com.android.systemui.plugins.statusbar.StatusBarStateController; 24 import com.android.systemui.statusbar.NotificationLockscreenUserManager; 25 import com.android.systemui.statusbar.StatusBarState; 26 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; 27 import com.android.systemui.statusbar.phone.UnlockMethodCache; 28 import com.android.systemui.statusbar.policy.KeyguardMonitor; 29 30 import javax.inject.Inject; 31 import javax.inject.Singleton; 32 33 /** 34 * A controller which dynamically controls the visibility of Notification content 35 */ 36 @Singleton 37 public class DynamicPrivacyController implements UnlockMethodCache.OnUnlockMethodChangedListener { 38 39 private final UnlockMethodCache mUnlockMethodCache; 40 private final NotificationLockscreenUserManager mLockscreenUserManager; 41 private final StatusBarStateController mStateController; 42 private final KeyguardMonitor mKeyguardMonitor; 43 private ArraySet<Listener> mListeners = new ArraySet<>(); 44 45 private boolean mLastDynamicUnlocked; 46 private boolean mCacheInvalid; 47 private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager; 48 49 @Inject DynamicPrivacyController(Context context, KeyguardMonitor keyguardMonitor, NotificationLockscreenUserManager notificationLockscreenUserManager, StatusBarStateController stateController)50 DynamicPrivacyController(Context context, 51 KeyguardMonitor keyguardMonitor, 52 NotificationLockscreenUserManager notificationLockscreenUserManager, 53 StatusBarStateController stateController) { 54 this(notificationLockscreenUserManager, keyguardMonitor, 55 UnlockMethodCache.getInstance(context), 56 stateController); 57 } 58 59 @VisibleForTesting DynamicPrivacyController(NotificationLockscreenUserManager notificationLockscreenUserManager, KeyguardMonitor keyguardMonitor, UnlockMethodCache unlockMethodCache, StatusBarStateController stateController)60 DynamicPrivacyController(NotificationLockscreenUserManager notificationLockscreenUserManager, 61 KeyguardMonitor keyguardMonitor, 62 UnlockMethodCache unlockMethodCache, 63 StatusBarStateController stateController) { 64 mLockscreenUserManager = notificationLockscreenUserManager; 65 mStateController = stateController; 66 mUnlockMethodCache = unlockMethodCache; 67 mKeyguardMonitor = keyguardMonitor; 68 mUnlockMethodCache.addListener(this); 69 mLastDynamicUnlocked = isDynamicallyUnlocked(); 70 } 71 72 @Override onUnlockMethodStateChanged()73 public void onUnlockMethodStateChanged() { 74 if (isDynamicPrivacyEnabled()) { 75 // We only want to notify our listeners if dynamic privacy is actually active 76 boolean dynamicallyUnlocked = isDynamicallyUnlocked(); 77 if (dynamicallyUnlocked != mLastDynamicUnlocked || mCacheInvalid) { 78 mLastDynamicUnlocked = dynamicallyUnlocked; 79 for (Listener listener : mListeners) { 80 listener.onDynamicPrivacyChanged(); 81 } 82 } 83 mCacheInvalid = false; 84 } else { 85 mCacheInvalid = true; 86 } 87 } 88 isDynamicPrivacyEnabled()89 private boolean isDynamicPrivacyEnabled() { 90 return !mLockscreenUserManager.shouldHideNotifications( 91 mLockscreenUserManager.getCurrentUserId()); 92 } 93 isDynamicallyUnlocked()94 public boolean isDynamicallyUnlocked() { 95 return (mUnlockMethodCache.canSkipBouncer() || mKeyguardMonitor.isKeyguardGoingAway() 96 || mKeyguardMonitor.isKeyguardFadingAway()) 97 && isDynamicPrivacyEnabled(); 98 } 99 addListener(Listener listener)100 public void addListener(Listener listener) { 101 mListeners.add(listener); 102 } 103 104 /** 105 * Is the notification shade currently in a locked down mode where it's fully showing but the 106 * contents aren't revealed yet? 107 */ isInLockedDownShade()108 public boolean isInLockedDownShade() { 109 if (!mStatusBarKeyguardViewManager.isShowing() 110 || !mUnlockMethodCache.isMethodSecure()) { 111 return false; 112 } 113 int state = mStateController.getState(); 114 if (state != StatusBarState.SHADE && state != StatusBarState.SHADE_LOCKED) { 115 return false; 116 } 117 if (!isDynamicPrivacyEnabled() || isDynamicallyUnlocked()) { 118 return false; 119 } 120 return true; 121 } 122 setStatusBarKeyguardViewManager( StatusBarKeyguardViewManager statusBarKeyguardViewManager)123 public void setStatusBarKeyguardViewManager( 124 StatusBarKeyguardViewManager statusBarKeyguardViewManager) { 125 mStatusBarKeyguardViewManager = statusBarKeyguardViewManager; 126 } 127 128 public interface Listener { onDynamicPrivacyChanged()129 void onDynamicPrivacyChanged(); 130 } 131 }