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