Selim Cinek | 6f0a62a | 2019-04-09 18:40:12 -0700 | [diff] [blame] | 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; |
Selim Cinek | 5454a0d | 2019-07-30 17:14:50 -0700 | [diff] [blame] | 23 | import com.android.systemui.plugins.statusbar.StatusBarStateController; |
Selim Cinek | 6f0a62a | 2019-04-09 18:40:12 -0700 | [diff] [blame] | 24 | import com.android.systemui.statusbar.NotificationLockscreenUserManager; |
Selim Cinek | 5454a0d | 2019-07-30 17:14:50 -0700 | [diff] [blame] | 25 | import com.android.systemui.statusbar.StatusBarState; |
| 26 | import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; |
Selim Cinek | 6f0a62a | 2019-04-09 18:40:12 -0700 | [diff] [blame] | 27 | import com.android.systemui.statusbar.phone.UnlockMethodCache; |
Selim Cinek | 10a5729 | 2019-07-31 20:00:26 -0700 | [diff] [blame] | 28 | import com.android.systemui.statusbar.policy.KeyguardMonitor; |
Selim Cinek | 6f0a62a | 2019-04-09 18:40:12 -0700 | [diff] [blame] | 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; |
Selim Cinek | 5454a0d | 2019-07-30 17:14:50 -0700 | [diff] [blame] | 41 | private final StatusBarStateController mStateController; |
Selim Cinek | 10a5729 | 2019-07-31 20:00:26 -0700 | [diff] [blame] | 42 | private final KeyguardMonitor mKeyguardMonitor; |
Selim Cinek | 6f0a62a | 2019-04-09 18:40:12 -0700 | [diff] [blame] | 43 | private ArraySet<Listener> mListeners = new ArraySet<>(); |
| 44 | |
| 45 | private boolean mLastDynamicUnlocked; |
| 46 | private boolean mCacheInvalid; |
Selim Cinek | 5454a0d | 2019-07-30 17:14:50 -0700 | [diff] [blame] | 47 | private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager; |
Selim Cinek | 6f0a62a | 2019-04-09 18:40:12 -0700 | [diff] [blame] | 48 | |
| 49 | @Inject |
| 50 | DynamicPrivacyController(Context context, |
Selim Cinek | 10a5729 | 2019-07-31 20:00:26 -0700 | [diff] [blame] | 51 | KeyguardMonitor keyguardMonitor, |
Selim Cinek | 5454a0d | 2019-07-30 17:14:50 -0700 | [diff] [blame] | 52 | NotificationLockscreenUserManager notificationLockscreenUserManager, |
| 53 | StatusBarStateController stateController) { |
Selim Cinek | 10a5729 | 2019-07-31 20:00:26 -0700 | [diff] [blame] | 54 | this(notificationLockscreenUserManager, keyguardMonitor, |
| 55 | UnlockMethodCache.getInstance(context), |
Selim Cinek | 5454a0d | 2019-07-30 17:14:50 -0700 | [diff] [blame] | 56 | stateController); |
Selim Cinek | 6f0a62a | 2019-04-09 18:40:12 -0700 | [diff] [blame] | 57 | } |
| 58 | |
| 59 | @VisibleForTesting |
| 60 | DynamicPrivacyController(NotificationLockscreenUserManager notificationLockscreenUserManager, |
Selim Cinek | 10a5729 | 2019-07-31 20:00:26 -0700 | [diff] [blame] | 61 | KeyguardMonitor keyguardMonitor, |
Selim Cinek | 5454a0d | 2019-07-30 17:14:50 -0700 | [diff] [blame] | 62 | UnlockMethodCache unlockMethodCache, |
| 63 | StatusBarStateController stateController) { |
Selim Cinek | 6f0a62a | 2019-04-09 18:40:12 -0700 | [diff] [blame] | 64 | mLockscreenUserManager = notificationLockscreenUserManager; |
Selim Cinek | 5454a0d | 2019-07-30 17:14:50 -0700 | [diff] [blame] | 65 | mStateController = stateController; |
Selim Cinek | 6f0a62a | 2019-04-09 18:40:12 -0700 | [diff] [blame] | 66 | mUnlockMethodCache = unlockMethodCache; |
Selim Cinek | 10a5729 | 2019-07-31 20:00:26 -0700 | [diff] [blame] | 67 | mKeyguardMonitor = keyguardMonitor; |
Selim Cinek | 6f0a62a | 2019-04-09 18:40:12 -0700 | [diff] [blame] | 68 | mUnlockMethodCache.addListener(this); |
| 69 | mLastDynamicUnlocked = isDynamicallyUnlocked(); |
| 70 | } |
| 71 | |
| 72 | @Override |
| 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 | |
| 89 | private boolean isDynamicPrivacyEnabled() { |
| 90 | return !mLockscreenUserManager.shouldHideNotifications( |
| 91 | mLockscreenUserManager.getCurrentUserId()); |
| 92 | } |
| 93 | |
| 94 | public boolean isDynamicallyUnlocked() { |
Selim Cinek | 10a5729 | 2019-07-31 20:00:26 -0700 | [diff] [blame] | 95 | return (mUnlockMethodCache.canSkipBouncer() || mKeyguardMonitor.isKeyguardGoingAway() |
| 96 | || mKeyguardMonitor.isKeyguardFadingAway()) |
| 97 | && isDynamicPrivacyEnabled(); |
Selim Cinek | 6f0a62a | 2019-04-09 18:40:12 -0700 | [diff] [blame] | 98 | } |
| 99 | |
| 100 | public void addListener(Listener listener) { |
| 101 | mListeners.add(listener); |
| 102 | } |
| 103 | |
Selim Cinek | 5454a0d | 2019-07-30 17:14:50 -0700 | [diff] [blame] | 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 | */ |
| 108 | public boolean isInLockedDownShade() { |
| 109 | if (!mStatusBarKeyguardViewManager.isShowing() |
Lucas Dupin | e36d8d8 | 2019-08-16 17:01:28 -0700 | [diff] [blame] | 110 | || !mUnlockMethodCache.isMethodSecure()) { |
Selim Cinek | 5454a0d | 2019-07-30 17:14:50 -0700 | [diff] [blame] | 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 | |
| 123 | public void setStatusBarKeyguardViewManager( |
| 124 | StatusBarKeyguardViewManager statusBarKeyguardViewManager) { |
| 125 | mStatusBarKeyguardViewManager = statusBarKeyguardViewManager; |
| 126 | } |
| 127 | |
Selim Cinek | 6f0a62a | 2019-04-09 18:40:12 -0700 | [diff] [blame] | 128 | public interface Listener { |
| 129 | void onDynamicPrivacyChanged(); |
| 130 | } |
| 131 | } |