blob: ba4ff585fed77f95db35cbb9084d45ce860cdce1 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2008 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
Joe Onoratofd52b182010-11-10 18:00:52 -080017package com.android.systemui.statusbar.phone;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080018
Wale Ogunwale68278562017-09-23 17:13:55 -070019import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
20import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
21import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
22import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
23
Jason Monk697b82a2017-04-19 18:41:06 -040024import android.app.ActivityManager;
Jason Monk324b8862017-02-16 17:19:12 -050025import android.app.ActivityManager.StackInfo;
Jason Monk697b82a2017-04-19 18:41:06 -040026import android.app.AlarmManager;
John Spurlock604a5ee2015-06-01 12:27:22 -040027import android.app.AlarmManager.AlarmClockInfo;
Jason Monk697b82a2017-04-19 18:41:06 -040028import android.app.AppGlobals;
29import android.app.Notification;
Jason Monk324b8862017-02-16 17:19:12 -050030import android.app.Notification.Action;
Jason Monk697b82a2017-04-19 18:41:06 -040031import android.app.NotificationManager;
32import android.app.PendingIntent;
33import android.app.SynchronousUserSwitchObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080034import android.content.BroadcastReceiver;
Jason Monk697b82a2017-04-19 18:41:06 -040035import android.content.ComponentName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080036import android.content.Context;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080037import android.content.Intent;
38import android.content.IntentFilter;
Jason Monk324b8862017-02-16 17:19:12 -050039import android.content.pm.ApplicationInfo;
40import android.content.pm.IPackageManager;
41import android.content.pm.PackageManager;
Kenny Guy3094d4a2015-04-01 19:14:10 +010042import android.content.pm.UserInfo;
Jason Monk324b8862017-02-16 17:19:12 -050043import android.graphics.drawable.Icon;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044import android.media.AudioManager;
Jason Monk324b8862017-02-16 17:19:12 -050045import android.net.Uri;
46import android.os.Bundle;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080047import android.os.Handler;
Kenny Guy3094d4a2015-04-01 19:14:10 +010048import android.os.RemoteException;
Adrian Roosc42a1e12014-07-07 23:35:53 +020049import android.os.UserHandle;
Kenny Guy3094d4a2015-04-01 19:14:10 +010050import android.os.UserManager;
Jason Monk324b8862017-02-16 17:19:12 -050051import android.provider.Settings;
John Spurlockae641c92014-06-30 18:11:40 -040052import android.provider.Settings.Global;
Jason Monk324b8862017-02-16 17:19:12 -050053import android.service.notification.StatusBarNotification;
Tyler Gunnef9f6f92014-09-12 22:16:17 -070054import android.telecom.TelecomManager;
Jason Monk324b8862017-02-16 17:19:12 -050055import android.util.ArraySet;
John Spurlockcd686b52013-06-05 10:13:46 -040056import android.util.Log;
Jason Monk324b8862017-02-16 17:19:12 -050057import android.util.Pair;
Jason Monk324b8862017-02-16 17:19:12 -050058import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
Wink Savillea639b312012-07-10 12:37:54 -070059import com.android.internal.telephony.IccCardConstants;
Wink Saville04e71b32009-04-02 11:00:54 -070060import com.android.internal.telephony.TelephonyIntents;
Jason Monk9c7844c2017-01-18 15:21:53 -050061import com.android.systemui.Dependency;
Jason Monkf85fc962017-04-19 17:13:41 -040062import com.android.systemui.DockedStackExistsListener;
Joe Onorato798ac4c2010-05-27 16:39:00 -040063import com.android.systemui.R;
Jason Monkaa573e92017-01-27 17:00:29 -050064import com.android.systemui.SysUiServiceProvider;
Jorim Jaggifabc7432017-05-15 02:40:05 +020065import com.android.systemui.UiOffloadThread;
John Spurlock3c4076a2015-02-24 12:12:25 -050066import com.android.systemui.qs.tiles.DndTile;
Jason Monk3e189872016-01-12 09:10:34 -050067import com.android.systemui.qs.tiles.RotationLockTile;
Winson Chungaa357452017-10-31 11:35:30 -070068import com.android.systemui.recents.misc.SysUiTaskStackChangeListener;
Jason Monk324b8862017-02-16 17:19:12 -050069import com.android.systemui.recents.misc.SystemServicesProxy;
Jason Monkaa573e92017-01-27 17:00:29 -050070import com.android.systemui.statusbar.CommandQueue;
71import com.android.systemui.statusbar.CommandQueue.Callbacks;
Jason Monk70364362015-08-06 16:32:18 -040072import com.android.systemui.statusbar.policy.BluetoothController;
73import com.android.systemui.statusbar.policy.BluetoothController.Callback;
John Spurlock96fe98d2014-08-27 09:36:02 -040074import com.android.systemui.statusbar.policy.CastController;
75import com.android.systemui.statusbar.policy.CastController.CastDevice;
Jason Monkf23aa992016-01-22 16:45:21 -050076import com.android.systemui.statusbar.policy.DataSaverController;
Jason Monkaa573e92017-01-27 17:00:29 -050077import com.android.systemui.statusbar.policy.DataSaverController.Listener;
78import com.android.systemui.statusbar.policy.DeviceProvisionedController;
79import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
Jason Monk952d5d82014-10-27 15:28:22 -040080import com.android.systemui.statusbar.policy.HotspotController;
Jason Monkaa573e92017-01-27 17:00:29 -050081import com.android.systemui.statusbar.policy.KeyguardMonitor;
Jason Monk359bb742017-04-13 10:40:40 -040082import com.android.systemui.statusbar.policy.LocationController;
83import com.android.systemui.statusbar.policy.LocationController.LocationChangeCallback;
Juan Flores2ff37202015-04-30 13:44:23 +020084import com.android.systemui.statusbar.policy.NextAlarmController;
Jason Monk3e189872016-01-12 09:10:34 -050085import com.android.systemui.statusbar.policy.RotationLockController;
Jason Monkaa573e92017-01-27 17:00:29 -050086import com.android.systemui.statusbar.policy.RotationLockController.RotationLockControllerCallback;
Adrian Roos88b11932015-07-22 14:59:48 -070087import com.android.systemui.statusbar.policy.UserInfoController;
Jason Monkaa573e92017-01-27 17:00:29 -050088import com.android.systemui.statusbar.policy.ZenModeController;
Jason Monk324b8862017-02-16 17:19:12 -050089import com.android.systemui.util.NotificationChannels;
90
Jason Monk697b82a2017-04-19 18:41:06 -040091import java.util.List;
92
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080093/**
94 * This class contains all of the policy about which icons are installed in the status
Joe Onorato798ac4c2010-05-27 16:39:00 -040095 * bar at boot time. It goes through the normal API for icons, even though it probably
96 * strictly doesn't need to.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080097 */
Jason Monkaa573e92017-01-27 17:00:29 -050098public class PhoneStatusBarPolicy implements Callback, Callbacks,
Jason Monk359bb742017-04-13 10:40:40 -040099 RotationLockControllerCallback, Listener, LocationChangeCallback,
Jason Monkaa573e92017-01-27 17:00:29 -0500100 ZenModeController.Callback, DeviceProvisionedListener, KeyguardMonitor.Callback {
Joe Onoratofd52b182010-11-10 18:00:52 -0800101 private static final String TAG = "PhoneStatusBarPolicy";
John Spurlocka37e9c82014-07-08 09:40:31 -0400102 private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
Robert Greenwaltd7085fc2010-09-08 15:24:47 -0700103
Jason Monk359bb742017-04-13 10:40:40 -0400104 public static final int LOCATION_STATUS_ICON_ID = R.drawable.stat_sys_location;
Jason Monk697b82a2017-04-19 18:41:06 -0400105 public static final int NUM_TASKS_FOR_INSTANT_APP_INFO = 5;
Jason Monk359bb742017-04-13 10:40:40 -0400106
Jason Monk3e189872016-01-12 09:10:34 -0500107 private final String mSlotCast;
108 private final String mSlotHotspot;
109 private final String mSlotBluetooth;
110 private final String mSlotTty;
111 private final String mSlotZen;
112 private final String mSlotVolume;
113 private final String mSlotAlarmClock;
114 private final String mSlotManagedProfile;
115 private final String mSlotRotate;
116 private final String mSlotHeadset;
Jason Monkf23aa992016-01-22 16:45:21 -0500117 private final String mSlotDataSaver;
Jason Monk359bb742017-04-13 10:40:40 -0400118 private final String mSlotLocation;
John Spurlocka37e9c82014-07-08 09:40:31 -0400119
Dianne Hackborn4840e142009-03-24 22:40:29 -0700120 private final Context mContext;
Joe Onorato10523b4d2010-10-25 10:42:46 -0700121 private final Handler mHandler = new Handler();
John Spurlock96fe98d2014-08-27 09:36:02 -0400122 private final CastController mCast;
Jason Monk952d5d82014-10-27 15:28:22 -0400123 private final HotspotController mHotspot;
Juan Flores2ff37202015-04-30 13:44:23 +0200124 private final NextAlarmController mNextAlarm;
John Spurlock15782262015-05-29 15:35:53 -0400125 private final AlarmManager mAlarmManager;
Adrian Roos88b11932015-07-22 14:59:48 -0700126 private final UserInfoController mUserInfoController;
Rubin Xu1205fb12015-11-04 17:45:03 +0000127 private final UserManager mUserManager;
Jason Monk07473ce2016-01-05 14:59:19 -0500128 private final StatusBarIconController mIconController;
Jason Monk3e189872016-01-12 09:10:34 -0500129 private final RotationLockController mRotationLockController;
Jason Monkf23aa992016-01-22 16:45:21 -0500130 private final DataSaverController mDataSaver;
Jason Monkaa573e92017-01-27 17:00:29 -0500131 private final ZenModeController mZenController;
132 private final DeviceProvisionedController mProvisionedController;
133 private final KeyguardMonitor mKeyguardMonitor;
Jason Monk359bb742017-04-13 10:40:40 -0400134 private final LocationController mLocationController;
Jason Monk324b8862017-02-16 17:19:12 -0500135 private final ArraySet<Pair<String, Integer>> mCurrentNotifs = new ArraySet<>();
Jorim Jaggifabc7432017-05-15 02:40:05 +0200136 private final UiOffloadThread mUiOffloadThread = Dependency.get(UiOffloadThread.class);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800137
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800138 // Assume it's all good unless we hear otherwise. We don't always seem
139 // to get broadcasts that it *is* there.
Wink Savillea639b312012-07-10 12:37:54 -0700140 IccCardConstants.State mSimState = IccCardConstants.State.READY;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800141
John Spurlocka37e9c82014-07-08 09:40:31 -0400142 private boolean mZenVisible;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800143 private boolean mVolumeVisible;
John Spurlock604a5ee2015-06-01 12:27:22 -0400144 private boolean mCurrentUserSetup;
Jason Monkf85fc962017-04-19 17:13:41 -0400145 private boolean mDockedStackExists;
Wink Saville04e71b32009-04-02 11:00:54 -0700146
Rubin Xu1205fb12015-11-04 17:45:03 +0000147 private boolean mManagedProfileIconVisible = false;
148 private boolean mManagedProfileInQuietMode = false;
Kenny Guy3094d4a2015-04-01 19:14:10 +0100149
Jason Monk70364362015-08-06 16:32:18 -0400150 private BluetoothController mBluetooth;
Wink Savillee9b06d72009-05-18 21:47:50 -0700151
Jason Monk9c7844c2017-01-18 15:21:53 -0500152 public PhoneStatusBarPolicy(Context context, StatusBarIconController iconController) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800153 mContext = context;
Jason Monk07473ce2016-01-05 14:59:19 -0500154 mIconController = iconController;
Jason Monk9c7844c2017-01-18 15:21:53 -0500155 mCast = Dependency.get(CastController.class);
156 mHotspot = Dependency.get(HotspotController.class);
157 mBluetooth = Dependency.get(BluetoothController.class);
Jason Monk9c7844c2017-01-18 15:21:53 -0500158 mNextAlarm = Dependency.get(NextAlarmController.class);
John Spurlock15782262015-05-29 15:35:53 -0400159 mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Jason Monk9c7844c2017-01-18 15:21:53 -0500160 mUserInfoController = Dependency.get(UserInfoController.class);
Rubin Xu1205fb12015-11-04 17:45:03 +0000161 mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
Jason Monk9c7844c2017-01-18 15:21:53 -0500162 mRotationLockController = Dependency.get(RotationLockController.class);
163 mDataSaver = Dependency.get(DataSaverController.class);
Jason Monkaa573e92017-01-27 17:00:29 -0500164 mZenController = Dependency.get(ZenModeController.class);
165 mProvisionedController = Dependency.get(DeviceProvisionedController.class);
166 mKeyguardMonitor = Dependency.get(KeyguardMonitor.class);
Jason Monk359bb742017-04-13 10:40:40 -0400167 mLocationController = Dependency.get(LocationController.class);
Jason Monk3e189872016-01-12 09:10:34 -0500168
169 mSlotCast = context.getString(com.android.internal.R.string.status_bar_cast);
170 mSlotHotspot = context.getString(com.android.internal.R.string.status_bar_hotspot);
171 mSlotBluetooth = context.getString(com.android.internal.R.string.status_bar_bluetooth);
172 mSlotTty = context.getString(com.android.internal.R.string.status_bar_tty);
173 mSlotZen = context.getString(com.android.internal.R.string.status_bar_zen);
174 mSlotVolume = context.getString(com.android.internal.R.string.status_bar_volume);
175 mSlotAlarmClock = context.getString(com.android.internal.R.string.status_bar_alarm_clock);
176 mSlotManagedProfile = context.getString(
177 com.android.internal.R.string.status_bar_managed_profile);
178 mSlotRotate = context.getString(com.android.internal.R.string.status_bar_rotate);
179 mSlotHeadset = context.getString(com.android.internal.R.string.status_bar_headset);
Jason Monkf23aa992016-01-22 16:45:21 -0500180 mSlotDataSaver = context.getString(com.android.internal.R.string.status_bar_data_saver);
Jason Monk359bb742017-04-13 10:40:40 -0400181 mSlotLocation = context.getString(com.android.internal.R.string.status_bar_location);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800182
Daniel Sandlere3b7a2d2011-10-27 16:16:15 -0400183 // listen for broadcasts
184 IntentFilter filter = new IntentFilter();
Daniel Sandlere3b7a2d2011-10-27 16:16:15 -0400185 filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
John Spurlockbcc10872014-11-28 15:29:21 -0500186 filter.addAction(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION);
Jason Monk3e189872016-01-12 09:10:34 -0500187 filter.addAction(AudioManager.ACTION_HEADSET_PLUG);
Daniel Sandlere3b7a2d2011-10-27 16:16:15 -0400188 filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700189 filter.addAction(TelecomManager.ACTION_CURRENT_TTY_MODE_CHANGED);
Rubin Xue95057a2016-04-01 16:49:25 +0100190 filter.addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE);
191 filter.addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE);
Nicolas Prevot6c7b8742016-04-13 10:28:58 +0100192 filter.addAction(Intent.ACTION_MANAGED_PROFILE_REMOVED);
Daniel Sandlere3b7a2d2011-10-27 16:16:15 -0400193 mContext.registerReceiver(mIntentReceiver, filter, null, mHandler);
194
Kenny Guy3094d4a2015-04-01 19:14:10 +0100195 // listen for user / profile change.
196 try {
Sudheer Shankadc589ac2016-11-10 15:30:17 -0800197 ActivityManager.getService().registerUserSwitchObserver(mUserSwitchListener, TAG);
Kenny Guy3094d4a2015-04-01 19:14:10 +0100198 } catch (RemoteException e) {
199 // Ignore
200 }
201
Wink Saville04e71b32009-04-02 11:00:54 -0700202 // TTY status
Hall Liu108ca202017-07-24 15:19:04 -0700203 updateTTY();
Wink Saville04e71b32009-04-02 11:00:54 -0700204
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800205 // bluetooth status
Jorim Jaggi2d75f9f2014-10-08 17:10:58 -0700206 updateBluetooth();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800207
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800208 // Alarm clock
Jason Monk3e189872016-01-12 09:10:34 -0500209 mIconController.setIcon(mSlotAlarmClock, R.drawable.stat_sys_alarm, null);
210 mIconController.setIconVisibility(mSlotAlarmClock, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800211
John Spurlocka37e9c82014-07-08 09:40:31 -0400212 // zen
Jason Monk3e189872016-01-12 09:10:34 -0500213 mIconController.setIcon(mSlotZen, R.drawable.stat_sys_zen_important, null);
214 mIconController.setIconVisibility(mSlotZen, false);
John Spurlocka37e9c82014-07-08 09:40:31 -0400215
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800216 // volume
Jason Monk3e189872016-01-12 09:10:34 -0500217 mIconController.setIcon(mSlotVolume, R.drawable.stat_sys_ringer_vibrate, null);
218 mIconController.setIconVisibility(mSlotVolume, false);
John Spurlocka37e9c82014-07-08 09:40:31 -0400219 updateVolumeZen();
John Spurlock96fe98d2014-08-27 09:36:02 -0400220
221 // cast
Jason Monk3e189872016-01-12 09:10:34 -0500222 mIconController.setIcon(mSlotCast, R.drawable.stat_sys_cast, null);
223 mIconController.setIconVisibility(mSlotCast, false);
Jason Monk952d5d82014-10-27 15:28:22 -0400224
225 // hotspot
Jason Monk3e189872016-01-12 09:10:34 -0500226 mIconController.setIcon(mSlotHotspot, R.drawable.stat_sys_hotspot,
Jason Monk08187a42015-06-09 14:33:51 -0400227 mContext.getString(R.string.accessibility_status_bar_hotspot));
Jason Monk3e189872016-01-12 09:10:34 -0500228 mIconController.setIconVisibility(mSlotHotspot, mHotspot.isHotspotEnabled());
Kenny Guy3094d4a2015-04-01 19:14:10 +0100229
230 // managed profile
Jason Monk3e189872016-01-12 09:10:34 -0500231 mIconController.setIcon(mSlotManagedProfile, R.drawable.stat_sys_managed_profile_status,
Adrian Roos1b5eb972015-06-11 18:22:52 -0700232 mContext.getString(R.string.accessibility_managed_profile));
Jason Monk3e189872016-01-12 09:10:34 -0500233 mIconController.setIconVisibility(mSlotManagedProfile, mManagedProfileIconVisible);
Jason Monkf23aa992016-01-22 16:45:21 -0500234
235 // data saver
236 mIconController.setIcon(mSlotDataSaver, R.drawable.stat_sys_data_saver,
237 context.getString(R.string.accessibility_data_saver_on));
238 mIconController.setIconVisibility(mSlotDataSaver, false);
Jason Monkaa573e92017-01-27 17:00:29 -0500239
240 mRotationLockController.addCallback(this);
241 mBluetooth.addCallback(this);
242 mProvisionedController.addCallback(this);
243 mZenController.addCallback(this);
244 mCast.addCallback(mCastCallback);
245 mHotspot.addCallback(mHotspotCallback);
246 mNextAlarm.addCallback(mNextAlarmCallback);
Jason Monk88529052016-11-04 13:29:58 -0400247 mDataSaver.addCallback(this);
Jason Monkaa573e92017-01-27 17:00:29 -0500248 mKeyguardMonitor.addCallback(this);
Jason Monk359bb742017-04-13 10:40:40 -0400249 mLocationController.addCallback(this);
Jason Monkaa573e92017-01-27 17:00:29 -0500250
251 SysUiServiceProvider.getComponent(mContext, CommandQueue.class).addCallbacks(this);
Jason Monk324b8862017-02-16 17:19:12 -0500252 SystemServicesProxy.getInstance(mContext).registerTaskStackListener(mTaskListener);
253
254 // Clear out all old notifications on startup (only present in the case where sysui dies)
255 NotificationManager noMan = mContext.getSystemService(NotificationManager.class);
256 for (StatusBarNotification notification : noMan.getActiveNotifications()) {
257 if (notification.getId() == SystemMessage.NOTE_INSTANT_APPS) {
258 noMan.cancel(notification.getTag(), notification.getId());
259 }
260 }
Jason Monkf85fc962017-04-19 17:13:41 -0400261 DockedStackExistsListener.register(exists -> {
262 mDockedStackExists = exists;
263 updateForegroundInstantApps();
264 });
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800265 }
266
Jason Monkaa573e92017-01-27 17:00:29 -0500267 public void destroy() {
268 mRotationLockController.removeCallback(this);
269 mBluetooth.removeCallback(this);
270 mProvisionedController.removeCallback(this);
271 mZenController.removeCallback(this);
272 mCast.removeCallback(mCastCallback);
273 mHotspot.removeCallback(mHotspotCallback);
274 mNextAlarm.removeCallback(mNextAlarmCallback);
275 mDataSaver.removeCallback(this);
276 mKeyguardMonitor.removeCallback(this);
Jason Monk359bb742017-04-13 10:40:40 -0400277 mLocationController.removeCallback(this);
Jason Monkaa573e92017-01-27 17:00:29 -0500278 SysUiServiceProvider.getComponent(mContext, CommandQueue.class).removeCallbacks(this);
279 mContext.unregisterReceiver(mIntentReceiver);
Jason Monk324b8862017-02-16 17:19:12 -0500280
281 NotificationManager noMan = mContext.getSystemService(NotificationManager.class);
282 mCurrentNotifs.forEach(v -> noMan.cancelAsUser(v.first, SystemMessage.NOTE_INSTANT_APPS,
283 new UserHandle(v.second)));
Nicolas Prevot1dbbe7d2016-05-17 12:52:54 +0100284 }
285
Jason Monkaa573e92017-01-27 17:00:29 -0500286 @Override
287 public void onZenChanged(int zen) {
John Spurlocka37e9c82014-07-08 09:40:31 -0400288 updateVolumeZen();
John Spurlockba2c6a02014-05-19 09:44:06 -0400289 }
290
Jason Monk359bb742017-04-13 10:40:40 -0400291 @Override
292 public void onLocationActiveChanged(boolean active) {
293 updateLocation();
294 }
295
296 // Updates the status view based on the current state of location requests.
297 private void updateLocation() {
298 if (mLocationController.isLocationActive()) {
299 mIconController.setIcon(mSlotLocation, LOCATION_STATUS_ICON_ID,
300 mContext.getString(R.string.accessibility_location_active));
301 } else {
302 mIconController.removeIcon(mSlotLocation);
303 }
304 }
305
Adrian Roosc42a1e12014-07-07 23:35:53 +0200306 private void updateAlarm() {
John Spurlock604a5ee2015-06-01 12:27:22 -0400307 final AlarmClockInfo alarm = mAlarmManager.getNextAlarmClock(UserHandle.USER_CURRENT);
308 final boolean hasAlarm = alarm != null && alarm.getTriggerTime() > 0;
Jason Monk20c0eb42017-03-02 17:35:49 -0500309 int zen = mZenController.getZen();
310 final boolean zenNone = zen == Global.ZEN_MODE_NO_INTERRUPTIONS;
Jason Monk3e189872016-01-12 09:10:34 -0500311 mIconController.setIcon(mSlotAlarmClock, zenNone ? R.drawable.stat_sys_alarm_dim
Jason Monk07473ce2016-01-05 14:59:19 -0500312 : R.drawable.stat_sys_alarm, null);
Jason Monk3e189872016-01-12 09:10:34 -0500313 mIconController.setIconVisibility(mSlotAlarmClock, mCurrentUserSetup && hasAlarm);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800314 }
315
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800316 private final void updateSimState(Intent intent) {
Wink Savillea639b312012-07-10 12:37:54 -0700317 String stateExtra = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE);
318 if (IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {
319 mSimState = IccCardConstants.State.ABSENT;
Jason Monk07473ce2016-01-05 14:59:19 -0500320 } else if (IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR.equals(stateExtra)) {
Rakesh Pallerlaf099a5f2013-02-06 11:44:23 +0530321 mSimState = IccCardConstants.State.CARD_IO_ERROR;
Junda Liua2f6a672016-05-24 10:07:40 -0700322 } else if (IccCardConstants.INTENT_VALUE_ICC_CARD_RESTRICTED.equals(stateExtra)) {
323 mSimState = IccCardConstants.State.CARD_RESTRICTED;
Jason Monk07473ce2016-01-05 14:59:19 -0500324 } else if (IccCardConstants.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
Wink Savillea639b312012-07-10 12:37:54 -0700325 mSimState = IccCardConstants.State.READY;
Jason Monk07473ce2016-01-05 14:59:19 -0500326 } else if (IccCardConstants.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) {
Wink Savillea639b312012-07-10 12:37:54 -0700327 final String lockedReason =
328 intent.getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
329 if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) {
330 mSimState = IccCardConstants.State.PIN_REQUIRED;
Jason Monk07473ce2016-01-05 14:59:19 -0500331 } else if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) {
Wink Savillea639b312012-07-10 12:37:54 -0700332 mSimState = IccCardConstants.State.PUK_REQUIRED;
Jason Monk07473ce2016-01-05 14:59:19 -0500333 } else {
Wink Savillea639b312012-07-10 12:37:54 -0700334 mSimState = IccCardConstants.State.NETWORK_LOCKED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800335 }
336 } else {
Wink Savillea639b312012-07-10 12:37:54 -0700337 mSimState = IccCardConstants.State.UNKNOWN;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800338 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800339 }
340
John Spurlockbcc10872014-11-28 15:29:21 -0500341 private final void updateVolumeZen() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800342 AudioManager audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
John Spurlocka37e9c82014-07-08 09:40:31 -0400343
344 boolean zenVisible = false;
345 int zenIconId = 0;
346 String zenDescription = null;
347
348 boolean volumeVisible = false;
349 int volumeIconId = 0;
350 String volumeDescription = null;
Jason Monk20c0eb42017-03-02 17:35:49 -0500351 int zen = mZenController.getZen();
John Spurlocka37e9c82014-07-08 09:40:31 -0400352
John Spurlockf88d8082015-03-25 18:09:51 -0400353 if (DndTile.isVisible(mContext) || DndTile.isCombinedIcon(mContext)) {
Jason Monk20c0eb42017-03-02 17:35:49 -0500354 zenVisible = zen != Global.ZEN_MODE_OFF;
355 zenIconId = zen == Global.ZEN_MODE_NO_INTERRUPTIONS
John Spurlock4ec8b602015-05-11 17:46:28 -0400356 ? R.drawable.stat_sys_dnd_total_silence : R.drawable.stat_sys_dnd;
John Spurlock3c4076a2015-02-24 12:12:25 -0500357 zenDescription = mContext.getString(R.string.quick_settings_dnd_label);
Jason Monk20c0eb42017-03-02 17:35:49 -0500358 } else if (zen == Global.ZEN_MODE_NO_INTERRUPTIONS) {
John Spurlocka37e9c82014-07-08 09:40:31 -0400359 zenVisible = true;
360 zenIconId = R.drawable.stat_sys_zen_none;
John Spurlockd9c75db2015-04-28 11:19:13 -0400361 zenDescription = mContext.getString(R.string.interruption_level_none);
Jason Monk20c0eb42017-03-02 17:35:49 -0500362 } else if (zen == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) {
John Spurlocka37e9c82014-07-08 09:40:31 -0400363 zenVisible = true;
364 zenIconId = R.drawable.stat_sys_zen_important;
John Spurlockd9c75db2015-04-28 11:19:13 -0400365 zenDescription = mContext.getString(R.string.interruption_level_priority);
Svetoslav Ganov6179ea32011-06-28 01:12:41 -0700366 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800367
John Spurlockd9c75db2015-04-28 11:19:13 -0400368 if (DndTile.isVisible(mContext) && !DndTile.isCombinedIcon(mContext)
John Spurlocka48d7792015-03-03 17:35:57 -0500369 && audioManager.getRingerModeInternal() == AudioManager.RINGER_MODE_SILENT) {
370 volumeVisible = true;
371 volumeIconId = R.drawable.stat_sys_ringer_silent;
372 volumeDescription = mContext.getString(R.string.accessibility_ringer_silent);
Jason Monk20c0eb42017-03-02 17:35:49 -0500373 } else if (zen != Global.ZEN_MODE_NO_INTERRUPTIONS && zen != Global.ZEN_MODE_ALARMS &&
John Spurlock661f2cf2014-11-17 10:29:10 -0500374 audioManager.getRingerModeInternal() == AudioManager.RINGER_MODE_VIBRATE) {
John Spurlocka37e9c82014-07-08 09:40:31 -0400375 volumeVisible = true;
376 volumeIconId = R.drawable.stat_sys_ringer_vibrate;
377 volumeDescription = mContext.getString(R.string.accessibility_ringer_vibrate);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800378 }
John Spurlocka37e9c82014-07-08 09:40:31 -0400379
380 if (zenVisible) {
Jason Monk3e189872016-01-12 09:10:34 -0500381 mIconController.setIcon(mSlotZen, zenIconId, zenDescription);
John Spurlocka37e9c82014-07-08 09:40:31 -0400382 }
383 if (zenVisible != mZenVisible) {
Jason Monk3e189872016-01-12 09:10:34 -0500384 mIconController.setIconVisibility(mSlotZen, zenVisible);
John Spurlocka37e9c82014-07-08 09:40:31 -0400385 mZenVisible = zenVisible;
386 }
387
388 if (volumeVisible) {
Jason Monk3e189872016-01-12 09:10:34 -0500389 mIconController.setIcon(mSlotVolume, volumeIconId, volumeDescription);
John Spurlocka37e9c82014-07-08 09:40:31 -0400390 }
391 if (volumeVisible != mVolumeVisible) {
Jason Monk3e189872016-01-12 09:10:34 -0500392 mIconController.setIconVisibility(mSlotVolume, volumeVisible);
John Spurlocka37e9c82014-07-08 09:40:31 -0400393 mVolumeVisible = volumeVisible;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800394 }
John Spurlock15782262015-05-29 15:35:53 -0400395 updateAlarm();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800396 }
397
Jason Monk70364362015-08-06 16:32:18 -0400398 @Override
399 public void onBluetoothDevicesChanged() {
400 updateBluetooth();
401 }
402
403 @Override
404 public void onBluetoothStateChange(boolean enabled) {
405 updateBluetooth();
406 }
407
Jorim Jaggi2d75f9f2014-10-08 17:10:58 -0700408 private final void updateBluetooth() {
Joe Onorato798ac4c2010-05-27 16:39:00 -0400409 int iconId = R.drawable.stat_sys_data_bluetooth;
Jorim Jaggi2d75f9f2014-10-08 17:10:58 -0700410 String contentDescription =
Jason Monk1aa32822015-07-14 16:10:32 -0400411 mContext.getString(R.string.accessibility_quick_settings_bluetooth_on);
Jason Monk70364362015-08-06 16:32:18 -0400412 boolean bluetoothEnabled = false;
413 if (mBluetooth != null) {
414 bluetoothEnabled = mBluetooth.isBluetoothEnabled();
415 if (mBluetooth.isBluetoothConnected()) {
Jaikumar Ganeshd9bb6882010-09-27 17:05:24 -0700416 iconId = R.drawable.stat_sys_data_bluetooth_connected;
Svetoslav Ganov6179ea32011-06-28 01:12:41 -0700417 contentDescription = mContext.getString(R.string.accessibility_bluetooth_connected);
Jaikumar Ganesh084c6652009-12-07 10:58:18 -0800418 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800419 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700420
Jason Monk3e189872016-01-12 09:10:34 -0500421 mIconController.setIcon(mSlotBluetooth, iconId, contentDescription);
422 mIconController.setIconVisibility(mSlotBluetooth, bluetoothEnabled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800423 }
424
Hall Liu108ca202017-07-24 15:19:04 -0700425 private final void updateTTY() {
426 TelecomManager telecomManager =
427 (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
428 if (telecomManager == null) {
429 updateTTY(TelecomManager.TTY_MODE_OFF);
430 } else {
431 updateTTY(telecomManager.getCurrentTtyMode());
432 }
433 }
434
435 private final void updateTTY(int currentTtyMode) {
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700436 boolean enabled = currentTtyMode != TelecomManager.TTY_MODE_OFF;
Wink Saville04e71b32009-04-02 11:00:54 -0700437
John Spurlocka37e9c82014-07-08 09:40:31 -0400438 if (DEBUG) Log.v(TAG, "updateTTY: enabled: " + enabled);
Wink Saville04e71b32009-04-02 11:00:54 -0700439
440 if (enabled) {
441 // TTY is on
John Spurlocka37e9c82014-07-08 09:40:31 -0400442 if (DEBUG) Log.v(TAG, "updateTTY: set TTY on");
Jason Monk3e189872016-01-12 09:10:34 -0500443 mIconController.setIcon(mSlotTty, R.drawable.stat_sys_tty_mode,
Svetoslav Ganov6179ea32011-06-28 01:12:41 -0700444 mContext.getString(R.string.accessibility_tty_enabled));
Jason Monk3e189872016-01-12 09:10:34 -0500445 mIconController.setIconVisibility(mSlotTty, true);
Wink Saville04e71b32009-04-02 11:00:54 -0700446 } else {
447 // TTY is off
John Spurlocka37e9c82014-07-08 09:40:31 -0400448 if (DEBUG) Log.v(TAG, "updateTTY: set TTY off");
Jason Monk3e189872016-01-12 09:10:34 -0500449 mIconController.setIconVisibility(mSlotTty, false);
Wink Saville04e71b32009-04-02 11:00:54 -0700450 }
451 }
John Spurlock96fe98d2014-08-27 09:36:02 -0400452
453 private void updateCast() {
454 boolean isCasting = false;
455 for (CastDevice device : mCast.getCastDevices()) {
456 if (device.state == CastDevice.STATE_CONNECTING
457 || device.state == CastDevice.STATE_CONNECTED) {
458 isCasting = true;
459 break;
460 }
461 }
462 if (DEBUG) Log.v(TAG, "updateCast: isCasting: " + isCasting);
Dan Sandler8fd25bf2015-10-20 16:01:27 -0700463 mHandler.removeCallbacks(mRemoveCastIconRunnable);
John Spurlock96fe98d2014-08-27 09:36:02 -0400464 if (isCasting) {
Jason Monk3e189872016-01-12 09:10:34 -0500465 mIconController.setIcon(mSlotCast, R.drawable.stat_sys_cast,
John Spurlock96fe98d2014-08-27 09:36:02 -0400466 mContext.getString(R.string.accessibility_casting));
Jason Monk3e189872016-01-12 09:10:34 -0500467 mIconController.setIconVisibility(mSlotCast, true);
Dan Sandler8fd25bf2015-10-20 16:01:27 -0700468 } else {
469 // don't turn off the screen-record icon for a few seconds, just to make sure the user
470 // has seen it
471 if (DEBUG) Log.v(TAG, "updateCast: hiding icon in 3 sec...");
472 mHandler.postDelayed(mRemoveCastIconRunnable, 3000);
John Spurlock96fe98d2014-08-27 09:36:02 -0400473 }
John Spurlock96fe98d2014-08-27 09:36:02 -0400474 }
475
Rubin Xu1205fb12015-11-04 17:45:03 +0000476 private void updateQuietState() {
477 mManagedProfileInQuietMode = false;
478 int currentUserId = ActivityManager.getCurrentUser();
479 for (UserInfo ui : mUserManager.getEnabledProfiles(currentUserId)) {
480 if (ui.isManagedProfile() && ui.isQuietModeEnabled()) {
481 mManagedProfileInQuietMode = true;
482 return;
483 }
484 }
485 }
486
Kenny Guy3094d4a2015-04-01 19:14:10 +0100487 private void updateManagedProfile() {
Jorim Jaggifabc7432017-05-15 02:40:05 +0200488 // getLastResumedActivityUserId needds to acquire the AM lock, which may be contended in
489 // some cases. Since it doesn't really matter here whether it's updated in this frame
490 // or in the next one, we call this method from our UI offload thread.
491 mUiOffloadThread.submit(() -> {
492 final int userId;
493 try {
494 userId = ActivityManager.getService().getLastResumedActivityUserId();
495 boolean isManagedProfile = mUserManager.isManagedProfile(userId);
496 mHandler.post(() -> {
497 final boolean showIcon;
Pavel Grafov410d8082017-06-29 18:42:32 +0100498 if (isManagedProfile &&
499 (!mKeyguardMonitor.isShowing() || mKeyguardMonitor.isOccluded())) {
Jorim Jaggifabc7432017-05-15 02:40:05 +0200500 showIcon = true;
501 mIconController.setIcon(mSlotManagedProfile,
502 R.drawable.stat_sys_managed_profile_status,
503 mContext.getString(R.string.accessibility_managed_profile));
504 } else if (mManagedProfileInQuietMode) {
505 showIcon = true;
506 mIconController.setIcon(mSlotManagedProfile,
507 R.drawable.stat_sys_managed_profile_status_off,
508 mContext.getString(R.string.accessibility_managed_profile));
509 } else {
510 showIcon = false;
511 }
512 if (mManagedProfileIconVisible != showIcon) {
513 mIconController.setIconVisibility(mSlotManagedProfile, showIcon);
514 mManagedProfileIconVisible = showIcon;
515 }
516 });
517 } catch (RemoteException e) {
518 Log.w(TAG, "updateManagedProfile: ", e);
Tony Makec319ab2017-03-28 18:50:01 +0100519 }
Jorim Jaggifabc7432017-05-15 02:40:05 +0200520 });
Kenny Guy3094d4a2015-04-01 19:14:10 +0100521 }
522
Jason Monk324b8862017-02-16 17:19:12 -0500523 private void updateForegroundInstantApps() {
524 NotificationManager noMan = mContext.getSystemService(NotificationManager.class);
525 ArraySet<Pair<String, Integer>> notifs = new ArraySet<>(mCurrentNotifs);
526 IPackageManager pm = AppGlobals.getPackageManager();
527 mCurrentNotifs.clear();
Jorim Jaggifabc7432017-05-15 02:40:05 +0200528 mUiOffloadThread.submit(() -> {
529 try {
Wale Ogunwale68278562017-09-23 17:13:55 -0700530 final StackInfo focusedStack = ActivityManager.getService().getFocusedStackInfo();
531 if (focusedStack != null) {
532 final int windowingMode =
533 focusedStack.configuration.windowConfiguration.getWindowingMode();
534 if (windowingMode == WINDOWING_MODE_FULLSCREEN
535 || windowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY) {
536 checkStack(focusedStack, notifs, noMan, pm);
537 }
Jorim Jaggifabc7432017-05-15 02:40:05 +0200538 }
539 if (mDockedStackExists) {
Wale Ogunwale68278562017-09-23 17:13:55 -0700540 checkStack(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_UNDEFINED,
541 notifs, noMan, pm);
Jorim Jaggifabc7432017-05-15 02:40:05 +0200542 }
543 } catch (RemoteException e) {
544 e.rethrowFromSystemServer();
Jason Monkf85fc962017-04-19 17:13:41 -0400545 }
Jorim Jaggifabc7432017-05-15 02:40:05 +0200546 // Cancel all the leftover notifications that don't have a foreground process anymore.
547 notifs.forEach(v -> noMan.cancelAsUser(v.first, SystemMessage.NOTE_INSTANT_APPS,
548 new UserHandle(v.second)));
549 });
Jason Monk324b8862017-02-16 17:19:12 -0500550 }
551
Wale Ogunwale68278562017-09-23 17:13:55 -0700552 private void checkStack(int windowingMode, int activityType,
553 ArraySet<Pair<String, Integer>> notifs, NotificationManager noMan, IPackageManager pm) {
554 try {
555 final StackInfo info =
556 ActivityManager.getService().getStackInfo(windowingMode, activityType);
557 checkStack(info, notifs, noMan, pm);
558 } catch (RemoteException e) {
559 e.rethrowFromSystemServer();
560 }
561 }
562 private void checkStack(StackInfo info, ArraySet<Pair<String, Integer>> notifs,
Jason Monkf85fc962017-04-19 17:13:41 -0400563 NotificationManager noMan, IPackageManager pm) {
564 try {
Jason Monkf85fc962017-04-19 17:13:41 -0400565 if (info == null || info.topActivity == null) return;
566 String pkg = info.topActivity.getPackageName();
567 if (!hasNotif(notifs, pkg, info.userId)) {
568 // TODO: Optimize by not always needing to get application info.
569 // Maybe cache non-ephemeral packages?
570 ApplicationInfo appInfo = pm.getApplicationInfo(pkg,
571 PackageManager.MATCH_UNINSTALLED_PACKAGES, info.userId);
572 if (appInfo.isInstantApp()) {
Jason Monk697b82a2017-04-19 18:41:06 -0400573 postEphemeralNotif(pkg, info.userId, appInfo, noMan, info.taskIds[info.taskIds.length - 1]);
Jason Monkf85fc962017-04-19 17:13:41 -0400574 }
575 }
576 } catch (RemoteException e) {
577 e.rethrowFromSystemServer();
578 }
579 }
580
Jason Monk324b8862017-02-16 17:19:12 -0500581 private void postEphemeralNotif(String pkg, int userId, ApplicationInfo appInfo,
Jason Monk697b82a2017-04-19 18:41:06 -0400582 NotificationManager noMan, int taskId) {
Jason Monk324b8862017-02-16 17:19:12 -0500583 final Bundle extras = new Bundle();
584 extras.putString(Notification.EXTRA_SUBSTITUTE_APP_NAME,
585 mContext.getString(R.string.instant_apps));
586 mCurrentNotifs.add(new Pair<>(pkg, userId));
587 String message = mContext.getString(R.string.instant_apps_message);
588 PendingIntent appInfoAction = PendingIntent.getActivity(mContext, 0,
589 new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
590 .setData(Uri.fromParts("package", pkg, null)), 0);
Jason Monk324b8862017-02-16 17:19:12 -0500591 Action action = new Notification.Action.Builder(null, mContext.getString(R.string.app_info),
592 appInfoAction).build();
593
Jason Monk697b82a2017-04-19 18:41:06 -0400594 Intent browserIntent = getTaskIntent(taskId, userId);
595 Notification.Builder builder = new Notification.Builder(mContext, NotificationChannels.GENERAL);
596 if (browserIntent != null) {
Jesse Evansa2024a22017-04-20 14:44:49 -0700597 // Make sure that this doesn't resolve back to an instant app
598 browserIntent.setComponent(null)
599 .setPackage(null)
600 .addFlags(Intent.FLAG_IGNORE_EPHEMERAL)
601 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
602
Jason Monk697b82a2017-04-19 18:41:06 -0400603 PendingIntent pendingIntent = PendingIntent.getActivity(mContext,
604 0 /* requestCode */, browserIntent, 0 /* flags */);
Jason Monk697b82a2017-04-19 18:41:06 -0400605 ComponentName aiaComponent = null;
606 try {
607 aiaComponent = AppGlobals.getPackageManager().getInstantAppInstallerComponent();
608 } catch (RemoteException e) {
609 e.rethrowFromSystemServer();
610 }
611 Intent goToWebIntent = new Intent()
612 .setComponent(aiaComponent)
613 .setAction(Intent.ACTION_VIEW)
614 .addCategory(Intent.CATEGORY_BROWSABLE)
Jason Monk83c00512017-05-08 11:23:14 -0400615 .addCategory("unique:" + System.currentTimeMillis())
Jason Monk697b82a2017-04-19 18:41:06 -0400616 .putExtra(Intent.EXTRA_PACKAGE_NAME, appInfo.packageName)
617 .putExtra(Intent.EXTRA_VERSION_CODE, appInfo.versionCode)
618 .putExtra(Intent.EXTRA_EPHEMERAL_FAILURE, pendingIntent);
619
620 PendingIntent webPendingIntent = PendingIntent.getActivity(mContext, 0, goToWebIntent, 0);
621 Action webAction = new Notification.Action.Builder(null, mContext.getString(R.string.go_to_web),
622 webPendingIntent).build();
623 builder.addAction(webAction);
624 }
625
626 noMan.notifyAsUser(pkg, SystemMessage.NOTE_INSTANT_APPS, builder
Jason Monk324b8862017-02-16 17:19:12 -0500627 .addExtras(extras)
628 .addAction(action)
629 .setContentIntent(appInfoAction)
630 .setColor(mContext.getColor(R.color.instant_apps_color))
631 .setContentTitle(appInfo.loadLabel(mContext.getPackageManager()))
632 .setLargeIcon(Icon.createWithResource(pkg, appInfo.icon))
633 .setSmallIcon(Icon.createWithResource(mContext.getPackageName(),
634 R.drawable.instant_icon))
635 .setContentText(message)
636 .setOngoing(true)
637 .build(),
638 new UserHandle(userId));
639 }
640
Jason Monk697b82a2017-04-19 18:41:06 -0400641 private Intent getTaskIntent(int taskId, int userId) {
Winson Chung5fa39752017-10-04 14:50:15 -0700642 try {
643 final List<ActivityManager.RecentTaskInfo> tasks =
644 ActivityManager.getService().getRecentTasks(
645 NUM_TASKS_FOR_INSTANT_APP_INFO, 0, userId).getList();
646 for (int i = 0; i < tasks.size(); i++) {
647 if (tasks.get(i).id == taskId) {
648 return tasks.get(i).baseIntent;
649 }
Jason Monk697b82a2017-04-19 18:41:06 -0400650 }
Winson Chung5fa39752017-10-04 14:50:15 -0700651 } catch (RemoteException e) {
652 // Fall through
Jason Monk697b82a2017-04-19 18:41:06 -0400653 }
654 return null;
655 }
656
Jason Monk324b8862017-02-16 17:19:12 -0500657 private boolean hasNotif(ArraySet<Pair<String, Integer>> notifs, String pkg, int userId) {
658 Pair<String, Integer> key = new Pair<>(pkg, userId);
659 if (notifs.remove(key)) {
660 mCurrentNotifs.add(key);
661 return true;
662 }
663 return false;
664 }
665
Fyodor Kupolov6005b3f2015-11-23 17:41:50 -0800666 private final SynchronousUserSwitchObserver mUserSwitchListener =
667 new SynchronousUserSwitchObserver() {
Kenny Guy3094d4a2015-04-01 19:14:10 +0100668 @Override
Fyodor Kupolov6005b3f2015-11-23 17:41:50 -0800669 public void onUserSwitching(int newUserId) throws RemoteException {
Tony Makec319ab2017-03-28 18:50:01 +0100670 mHandler.post(() -> mUserInfoController.reloadUserInfo());
Kenny Guy3094d4a2015-04-01 19:14:10 +0100671 }
672
673 @Override
674 public void onUserSwitchComplete(int newUserId) throws RemoteException {
Tony Makec319ab2017-03-28 18:50:01 +0100675 mHandler.post(() -> {
676 updateAlarm();
677 updateQuietState();
678 updateManagedProfile();
679 updateForegroundInstantApps();
Toni Barzice97f9232016-04-27 18:10:58 -0700680 });
Kenny Guy3094d4a2015-04-01 19:14:10 +0100681 }
682 };
683
Jason Monk952d5d82014-10-27 15:28:22 -0400684 private final HotspotController.Callback mHotspotCallback = new HotspotController.Callback() {
685 @Override
686 public void onHotspotChanged(boolean enabled) {
Jason Monk3e189872016-01-12 09:10:34 -0500687 mIconController.setIconVisibility(mSlotHotspot, enabled);
Jason Monk952d5d82014-10-27 15:28:22 -0400688 }
689 };
690
John Spurlock96fe98d2014-08-27 09:36:02 -0400691 private final CastController.Callback mCastCallback = new CastController.Callback() {
692 @Override
693 public void onCastDevicesChanged() {
694 updateCast();
695 }
696 };
Kenny Guy3094d4a2015-04-01 19:14:10 +0100697
Juan Flores2ff37202015-04-30 13:44:23 +0200698 private final NextAlarmController.NextAlarmChangeCallback mNextAlarmCallback =
699 new NextAlarmController.NextAlarmChangeCallback() {
Jason Monk324b8862017-02-16 17:19:12 -0500700 @Override
701 public void onNextAlarmChanged(AlarmManager.AlarmClockInfo nextAlarm) {
702 updateAlarm();
703 }
704 };
Juan Flores2ff37202015-04-30 13:44:23 +0200705
Jason Monkaa573e92017-01-27 17:00:29 -0500706 @Override
707 public void appTransitionStarting(long startTime, long duration, boolean forced) {
Kenny Guy3094d4a2015-04-01 19:14:10 +0100708 updateManagedProfile();
Jason Monk324b8862017-02-16 17:19:12 -0500709 updateForegroundInstantApps();
Kenny Guy3094d4a2015-04-01 19:14:10 +0100710 }
711
Jason Monkaa573e92017-01-27 17:00:29 -0500712 @Override
713 public void onKeyguardShowingChanged() {
Kenny Guy3094d4a2015-04-01 19:14:10 +0100714 updateManagedProfile();
Jason Monk324b8862017-02-16 17:19:12 -0500715 updateForegroundInstantApps();
Kenny Guy3094d4a2015-04-01 19:14:10 +0100716 }
John Spurlock604a5ee2015-06-01 12:27:22 -0400717
Jason Monkaa573e92017-01-27 17:00:29 -0500718 @Override
719 public void onUserSetupChanged() {
720 boolean userSetup = mProvisionedController.isUserSetup(
721 mProvisionedController.getCurrentUser());
John Spurlock604a5ee2015-06-01 12:27:22 -0400722 if (mCurrentUserSetup == userSetup) return;
723 mCurrentUserSetup = userSetup;
724 updateAlarm();
Rubin Xu1205fb12015-11-04 17:45:03 +0000725 updateQuietState();
John Spurlock604a5ee2015-06-01 12:27:22 -0400726 }
Jason Monk3e189872016-01-12 09:10:34 -0500727
728 @Override
Jason Monk324b8862017-02-16 17:19:12 -0500729 public void preloadRecentApps() {
730 updateForegroundInstantApps();
731 }
732
733 @Override
Jason Monk3e189872016-01-12 09:10:34 -0500734 public void onRotationLockStateChanged(boolean rotationLocked, boolean affordanceVisible) {
735 boolean portrait = RotationLockTile.isCurrentOrientationLockPortrait(
736 mRotationLockController, mContext);
737 if (rotationLocked) {
738 if (portrait) {
739 mIconController.setIcon(mSlotRotate, R.drawable.stat_sys_rotate_portrait,
740 mContext.getString(R.string.accessibility_rotation_lock_on_portrait));
741 } else {
742 mIconController.setIcon(mSlotRotate, R.drawable.stat_sys_rotate_landscape,
743 mContext.getString(R.string.accessibility_rotation_lock_on_landscape));
744 }
Jason Monk8816dff2016-02-09 21:50:36 -0500745 mIconController.setIconVisibility(mSlotRotate, true);
Jason Monk3e189872016-01-12 09:10:34 -0500746 } else {
Jason Monk8816dff2016-02-09 21:50:36 -0500747 mIconController.setIconVisibility(mSlotRotate, false);
Jason Monk3e189872016-01-12 09:10:34 -0500748 }
749 }
750
751 private void updateHeadsetPlug(Intent intent) {
752 boolean connected = intent.getIntExtra("state", 0) != 0;
753 boolean hasMic = intent.getIntExtra("microphone", 0) != 0;
754 if (connected) {
755 String contentDescription = mContext.getString(hasMic
756 ? R.string.accessibility_status_bar_headset
757 : R.string.accessibility_status_bar_headphones);
758 mIconController.setIcon(mSlotHeadset, hasMic ? R.drawable.ic_headset_mic
759 : R.drawable.ic_headset, contentDescription);
760 mIconController.setIconVisibility(mSlotHeadset, true);
761 } else {
762 mIconController.setIconVisibility(mSlotHeadset, false);
763 }
764 }
765
Jason Monkf23aa992016-01-22 16:45:21 -0500766 @Override
767 public void onDataSaverChanged(boolean isDataSaving) {
768 mIconController.setIconVisibility(mSlotDataSaver, isDataSaving);
769 }
770
Winson Chungaa357452017-10-31 11:35:30 -0700771 private final SysUiTaskStackChangeListener mTaskListener = new SysUiTaskStackChangeListener() {
Jason Monk324b8862017-02-16 17:19:12 -0500772 @Override
773 public void onTaskStackChanged() {
774 // Listen for changes to stacks and then check which instant apps are foreground.
775 updateForegroundInstantApps();
776 }
777 };
778
Jason Monk3e189872016-01-12 09:10:34 -0500779 private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
780 @Override
781 public void onReceive(Context context, Intent intent) {
782 String action = intent.getAction();
Julia Reynolds4e6024b2016-04-26 16:12:26 -0400783 if (action.equals(AudioManager.RINGER_MODE_CHANGED_ACTION) ||
Jason Monk3e189872016-01-12 09:10:34 -0500784 action.equals(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION)) {
785 updateVolumeZen();
786 } else if (action.equals(TelephonyIntents.ACTION_SIM_STATE_CHANGED)) {
787 updateSimState(intent);
788 } else if (action.equals(TelecomManager.ACTION_CURRENT_TTY_MODE_CHANGED)) {
Hall Liu108ca202017-07-24 15:19:04 -0700789 updateTTY(intent.getIntExtra(TelecomManager.EXTRA_CURRENT_TTY_MODE,
790 TelecomManager.TTY_MODE_OFF));
Rubin Xue95057a2016-04-01 16:49:25 +0100791 } else if (action.equals(Intent.ACTION_MANAGED_PROFILE_AVAILABLE) ||
Nicolas Prevot6c7b8742016-04-13 10:28:58 +0100792 action.equals(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE) ||
793 action.equals(Intent.ACTION_MANAGED_PROFILE_REMOVED)) {
Jason Monk3e189872016-01-12 09:10:34 -0500794 updateQuietState();
795 updateManagedProfile();
796 } else if (action.equals(AudioManager.ACTION_HEADSET_PLUG)) {
797 updateHeadsetPlug(intent);
798 }
799 }
800 };
801
802 private Runnable mRemoveCastIconRunnable = new Runnable() {
803 @Override
804 public void run() {
805 if (DEBUG) Log.v(TAG, "updateCast: hiding icon NOW");
806 mIconController.setIconVisibility(mSlotCast, false);
807 }
808 };
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800809}