Govinda Wasserman | a2c88760 | 2019-05-08 08:02:47 -0400 | [diff] [blame] | 1 | /* |
Govinda Wasserman | c7495cd | 2019-05-20 14:43:28 -0400 | [diff] [blame] | 2 | * Copyright (C) 2019 The Android Open Source Project |
Govinda Wasserman | a2c88760 | 2019-05-08 08:02:47 -0400 | [diff] [blame] | 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.assist; |
| 18 | |
Govinda Wasserman | a2c88760 | 2019-05-08 08:02:47 -0400 | [diff] [blame] | 19 | import android.app.ActivityManager; |
| 20 | import android.app.KeyguardManager; |
| 21 | import android.content.BroadcastReceiver; |
| 22 | import android.content.ComponentName; |
| 23 | import android.content.Context; |
| 24 | import android.content.Intent; |
| 25 | import android.content.IntentFilter; |
Govinda Wasserman | 8c78dee | 2019-06-13 09:58:22 -0400 | [diff] [blame] | 26 | import android.content.pm.ResolveInfo; |
Govinda Wasserman | a2c88760 | 2019-05-08 08:02:47 -0400 | [diff] [blame] | 27 | |
| 28 | import androidx.annotation.Nullable; |
| 29 | |
| 30 | import com.android.systemui.Dependency; |
| 31 | import com.android.systemui.SysUiServiceProvider; |
| 32 | import com.android.systemui.plugins.statusbar.StatusBarStateController; |
| 33 | import com.android.systemui.shared.system.ActivityManagerWrapper; |
| 34 | import com.android.systemui.shared.system.PackageManagerWrapper; |
| 35 | import com.android.systemui.shared.system.TaskStackChangeListener; |
| 36 | import com.android.systemui.statusbar.StatusBarState; |
| 37 | import com.android.systemui.statusbar.phone.StatusBar; |
| 38 | |
| 39 | import java.util.ArrayList; |
Govinda Wasserman | 8c78dee | 2019-06-13 09:58:22 -0400 | [diff] [blame] | 40 | import java.util.List; |
Govinda Wasserman | a2c88760 | 2019-05-08 08:02:47 -0400 | [diff] [blame] | 41 | |
| 42 | /** Class to monitor and report the state of the phone. */ |
| 43 | final class PhoneStateMonitor { |
| 44 | |
| 45 | private static final int PHONE_STATE_AOD1 = 1; |
| 46 | private static final int PHONE_STATE_AOD2 = 2; |
| 47 | private static final int PHONE_STATE_BOUNCER = 3; |
| 48 | private static final int PHONE_STATE_UNLOCKED_LOCKSCREEN = 4; |
| 49 | private static final int PHONE_STATE_HOME = 5; |
| 50 | private static final int PHONE_STATE_OVERVIEW = 6; |
| 51 | private static final int PHONE_STATE_ALL_APPS = 7; |
| 52 | private static final int PHONE_STATE_APP_DEFAULT = 8; |
| 53 | private static final int PHONE_STATE_APP_IMMERSIVE = 9; |
| 54 | private static final int PHONE_STATE_APP_FULLSCREEN = 10; |
| 55 | |
Govinda Wasserman | 8c78dee | 2019-06-13 09:58:22 -0400 | [diff] [blame] | 56 | private static final String[] DEFAULT_HOME_CHANGE_ACTIONS = new String[] { |
| 57 | PackageManagerWrapper.ACTION_PREFERRED_ACTIVITY_CHANGED, |
| 58 | Intent.ACTION_BOOT_COMPLETED, |
| 59 | Intent.ACTION_PACKAGE_ADDED, |
| 60 | Intent.ACTION_PACKAGE_CHANGED, |
| 61 | Intent.ACTION_PACKAGE_REMOVED |
| 62 | }; |
| 63 | |
Govinda Wasserman | a2c88760 | 2019-05-08 08:02:47 -0400 | [diff] [blame] | 64 | private final Context mContext; |
| 65 | private final StatusBarStateController mStatusBarStateController; |
| 66 | |
| 67 | private boolean mLauncherShowing; |
| 68 | @Nullable private ComponentName mDefaultHome; |
| 69 | |
| 70 | PhoneStateMonitor(Context context) { |
| 71 | mContext = context; |
| 72 | mStatusBarStateController = Dependency.get(StatusBarStateController.class); |
| 73 | |
| 74 | ActivityManagerWrapper activityManagerWrapper = ActivityManagerWrapper.getInstance(); |
Govinda Wasserman | 8c78dee | 2019-06-13 09:58:22 -0400 | [diff] [blame] | 75 | mDefaultHome = getCurrentDefaultHome(); |
| 76 | IntentFilter intentFilter = new IntentFilter(); |
| 77 | for (String action : DEFAULT_HOME_CHANGE_ACTIONS) { |
| 78 | intentFilter.addAction(action); |
| 79 | } |
Govinda Wasserman | a2c88760 | 2019-05-08 08:02:47 -0400 | [diff] [blame] | 80 | mContext.registerReceiver(new BroadcastReceiver() { |
| 81 | @Override |
| 82 | public void onReceive(Context context, Intent intent) { |
Govinda Wasserman | 8c78dee | 2019-06-13 09:58:22 -0400 | [diff] [blame] | 83 | mDefaultHome = getCurrentDefaultHome(); |
Govinda Wasserman | a2c88760 | 2019-05-08 08:02:47 -0400 | [diff] [blame] | 84 | } |
Govinda Wasserman | 8c78dee | 2019-06-13 09:58:22 -0400 | [diff] [blame] | 85 | }, intentFilter); |
Govinda Wasserman | a2c88760 | 2019-05-08 08:02:47 -0400 | [diff] [blame] | 86 | mLauncherShowing = isLauncherShowing(activityManagerWrapper.getRunningTask()); |
| 87 | activityManagerWrapper.registerTaskStackListener(new TaskStackChangeListener() { |
| 88 | @Override |
| 89 | public void onTaskMovedToFront(ActivityManager.RunningTaskInfo taskInfo) { |
| 90 | mLauncherShowing = isLauncherShowing(taskInfo); |
| 91 | } |
| 92 | }); |
| 93 | } |
| 94 | |
| 95 | int getPhoneState() { |
| 96 | int phoneState; |
| 97 | if (isShadeFullscreen()) { |
| 98 | phoneState = getPhoneLockscreenState(); |
| 99 | } else if (mLauncherShowing) { |
| 100 | phoneState = getPhoneLauncherState(); |
| 101 | } else { |
| 102 | phoneState = getPhoneAppState(); |
| 103 | } |
| 104 | return phoneState; |
| 105 | } |
| 106 | |
Govinda Wasserman | 8c78dee | 2019-06-13 09:58:22 -0400 | [diff] [blame] | 107 | @Nullable |
| 108 | private static ComponentName getCurrentDefaultHome() { |
| 109 | List<ResolveInfo> homeActivities = new ArrayList<>(); |
| 110 | ComponentName defaultHome = |
| 111 | PackageManagerWrapper.getInstance().getHomeActivities(homeActivities); |
| 112 | if (defaultHome != null) { |
| 113 | return defaultHome; |
| 114 | } |
| 115 | |
| 116 | int topPriority = Integer.MIN_VALUE; |
| 117 | ComponentName topComponent = null; |
| 118 | for (ResolveInfo resolveInfo : homeActivities) { |
| 119 | if (resolveInfo.priority > topPriority) { |
| 120 | topComponent = resolveInfo.activityInfo.getComponentName(); |
| 121 | topPriority = resolveInfo.priority; |
| 122 | } else if (resolveInfo.priority == topPriority) { |
| 123 | topComponent = null; |
| 124 | } |
| 125 | } |
| 126 | return topComponent; |
| 127 | } |
| 128 | |
Govinda Wasserman | a2c88760 | 2019-05-08 08:02:47 -0400 | [diff] [blame] | 129 | private int getPhoneLockscreenState() { |
| 130 | if (isDozing()) { |
| 131 | return PHONE_STATE_AOD1; |
| 132 | } else if (isBouncerShowing()) { |
| 133 | return PHONE_STATE_BOUNCER; |
| 134 | } else if (isKeyguardLocked()) { |
| 135 | return PHONE_STATE_AOD2; |
| 136 | } else { |
| 137 | return PHONE_STATE_UNLOCKED_LOCKSCREEN; |
| 138 | } |
| 139 | } |
| 140 | |
| 141 | private int getPhoneLauncherState() { |
| 142 | if (isLauncherInOverview()) { |
| 143 | return PHONE_STATE_OVERVIEW; |
| 144 | } else if (isLauncherInAllApps()) { |
| 145 | return PHONE_STATE_ALL_APPS; |
| 146 | } else { |
| 147 | return PHONE_STATE_HOME; |
| 148 | } |
| 149 | } |
| 150 | |
| 151 | private int getPhoneAppState() { |
| 152 | if (isAppImmersive()) { |
| 153 | return PHONE_STATE_APP_IMMERSIVE; |
| 154 | } else if (isAppFullscreen()) { |
| 155 | return PHONE_STATE_APP_FULLSCREEN; |
| 156 | } else { |
| 157 | return PHONE_STATE_APP_DEFAULT; |
| 158 | } |
| 159 | } |
| 160 | |
| 161 | private boolean isShadeFullscreen() { |
| 162 | int statusBarState = mStatusBarStateController.getState(); |
| 163 | return statusBarState == StatusBarState.KEYGUARD |
| 164 | || statusBarState == StatusBarState.SHADE_LOCKED; |
| 165 | } |
| 166 | |
| 167 | private boolean isDozing() { |
| 168 | return mStatusBarStateController.isDozing(); |
| 169 | } |
| 170 | |
| 171 | private boolean isLauncherShowing(ActivityManager.RunningTaskInfo runningTaskInfo) { |
James O'Leary | 35cb43b | 2019-05-20 23:21:54 -0400 | [diff] [blame] | 172 | if (runningTaskInfo == null) { |
| 173 | return false; |
| 174 | } else { |
| 175 | return runningTaskInfo.topActivity.equals(mDefaultHome); |
| 176 | } |
Govinda Wasserman | a2c88760 | 2019-05-08 08:02:47 -0400 | [diff] [blame] | 177 | } |
| 178 | |
| 179 | private boolean isAppImmersive() { |
| 180 | return SysUiServiceProvider.getComponent(mContext, StatusBar.class).inImmersiveMode(); |
| 181 | } |
| 182 | |
| 183 | private boolean isAppFullscreen() { |
| 184 | return SysUiServiceProvider.getComponent(mContext, StatusBar.class).inFullscreenMode(); |
| 185 | } |
| 186 | |
| 187 | private boolean isBouncerShowing() { |
| 188 | StatusBar statusBar = SysUiServiceProvider.getComponent(mContext, StatusBar.class); |
| 189 | return statusBar != null && statusBar.isBouncerShowing(); |
| 190 | } |
| 191 | |
| 192 | private boolean isKeyguardLocked() { |
| 193 | // TODO: Move binder call off of critical path |
| 194 | KeyguardManager keyguardManager = mContext.getSystemService(KeyguardManager.class); |
| 195 | return keyguardManager != null && keyguardManager.isKeyguardLocked(); |
| 196 | } |
| 197 | |
| 198 | private boolean isLauncherInOverview() { |
| 199 | // TODO |
| 200 | return false; |
| 201 | } |
| 202 | |
| 203 | private boolean isLauncherInAllApps() { |
| 204 | // TODO |
| 205 | return false; |
| 206 | } |
| 207 | } |