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