blob: bd16c966de84a6ed48430a5cd584435038cea3fe [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
Jason Monk697b82a2017-04-19 18:41:06 -040019import android.app.ActivityManager;
Jason Monk324b8862017-02-16 17:19:12 -050020import android.app.ActivityManager.StackId;
21import android.app.ActivityManager.StackInfo;
Jason Monk697b82a2017-04-19 18:41:06 -040022import android.app.AlarmManager;
John Spurlock604a5ee2015-06-01 12:27:22 -040023import android.app.AlarmManager.AlarmClockInfo;
Jason Monk697b82a2017-04-19 18:41:06 -040024import android.app.AppGlobals;
25import android.app.Notification;
Jason Monk324b8862017-02-16 17:19:12 -050026import android.app.Notification.Action;
Jason Monk697b82a2017-04-19 18:41:06 -040027import android.app.NotificationManager;
28import android.app.PendingIntent;
29import android.app.SynchronousUserSwitchObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030import android.content.BroadcastReceiver;
Jason Monk697b82a2017-04-19 18:41:06 -040031import android.content.ComponentName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080032import android.content.Context;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080033import android.content.Intent;
34import android.content.IntentFilter;
Jason Monk324b8862017-02-16 17:19:12 -050035import android.content.pm.ApplicationInfo;
36import android.content.pm.IPackageManager;
37import android.content.pm.PackageManager;
Kenny Guy3094d4a2015-04-01 19:14:10 +010038import android.content.pm.UserInfo;
Jason Monk324b8862017-02-16 17:19:12 -050039import android.graphics.drawable.Icon;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080040import android.media.AudioManager;
Jason Monk324b8862017-02-16 17:19:12 -050041import android.net.Uri;
42import android.os.Bundle;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080043import android.os.Handler;
Kenny Guy3094d4a2015-04-01 19:14:10 +010044import android.os.RemoteException;
Adrian Roosc42a1e12014-07-07 23:35:53 +020045import android.os.UserHandle;
Kenny Guy3094d4a2015-04-01 19:14:10 +010046import android.os.UserManager;
Jason Monk324b8862017-02-16 17:19:12 -050047import android.provider.Settings;
John Spurlockae641c92014-06-30 18:11:40 -040048import android.provider.Settings.Global;
Jason Monk324b8862017-02-16 17:19:12 -050049import android.service.notification.StatusBarNotification;
Tyler Gunnef9f6f92014-09-12 22:16:17 -070050import android.telecom.TelecomManager;
Jason Monk324b8862017-02-16 17:19:12 -050051import android.util.ArraySet;
John Spurlockcd686b52013-06-05 10:13:46 -040052import android.util.Log;
Jason Monk324b8862017-02-16 17:19:12 -050053import android.util.Pair;
Jason Monk324b8862017-02-16 17:19:12 -050054import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
Wink Savillea639b312012-07-10 12:37:54 -070055import com.android.internal.telephony.IccCardConstants;
Wink Saville04e71b32009-04-02 11:00:54 -070056import com.android.internal.telephony.TelephonyIntents;
Jason Monk9c7844c2017-01-18 15:21:53 -050057import com.android.systemui.Dependency;
Jason Monkf85fc962017-04-19 17:13:41 -040058import com.android.systemui.DockedStackExistsListener;
Joe Onorato798ac4c2010-05-27 16:39:00 -040059import com.android.systemui.R;
Jason Monkaa573e92017-01-27 17:00:29 -050060import com.android.systemui.SysUiServiceProvider;
John Spurlock3c4076a2015-02-24 12:12:25 -050061import com.android.systemui.qs.tiles.DndTile;
Jason Monk3e189872016-01-12 09:10:34 -050062import com.android.systemui.qs.tiles.RotationLockTile;
Jason Monk324b8862017-02-16 17:19:12 -050063import com.android.systemui.recents.misc.SystemServicesProxy;
64import com.android.systemui.recents.misc.SystemServicesProxy.TaskStackListener;
Jason Monkaa573e92017-01-27 17:00:29 -050065import com.android.systemui.statusbar.CommandQueue;
66import com.android.systemui.statusbar.CommandQueue.Callbacks;
Jason Monk70364362015-08-06 16:32:18 -040067import com.android.systemui.statusbar.policy.BluetoothController;
68import com.android.systemui.statusbar.policy.BluetoothController.Callback;
John Spurlock96fe98d2014-08-27 09:36:02 -040069import com.android.systemui.statusbar.policy.CastController;
70import com.android.systemui.statusbar.policy.CastController.CastDevice;
Jason Monkf23aa992016-01-22 16:45:21 -050071import com.android.systemui.statusbar.policy.DataSaverController;
Jason Monkaa573e92017-01-27 17:00:29 -050072import com.android.systemui.statusbar.policy.DataSaverController.Listener;
73import com.android.systemui.statusbar.policy.DeviceProvisionedController;
74import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
Jason Monk952d5d82014-10-27 15:28:22 -040075import com.android.systemui.statusbar.policy.HotspotController;
Jason Monkaa573e92017-01-27 17:00:29 -050076import com.android.systemui.statusbar.policy.KeyguardMonitor;
Jason Monk359bb742017-04-13 10:40:40 -040077import com.android.systemui.statusbar.policy.LocationController;
78import com.android.systemui.statusbar.policy.LocationController.LocationChangeCallback;
Juan Flores2ff37202015-04-30 13:44:23 +020079import com.android.systemui.statusbar.policy.NextAlarmController;
Jason Monk3e189872016-01-12 09:10:34 -050080import com.android.systemui.statusbar.policy.RotationLockController;
Jason Monkaa573e92017-01-27 17:00:29 -050081import com.android.systemui.statusbar.policy.RotationLockController.RotationLockControllerCallback;
Adrian Roos88b11932015-07-22 14:59:48 -070082import com.android.systemui.statusbar.policy.UserInfoController;
Jason Monkaa573e92017-01-27 17:00:29 -050083import com.android.systemui.statusbar.policy.ZenModeController;
Jason Monk324b8862017-02-16 17:19:12 -050084import com.android.systemui.util.NotificationChannels;
85
Jason Monk697b82a2017-04-19 18:41:06 -040086import java.util.List;
87
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080088/**
89 * This class contains all of the policy about which icons are installed in the status
Joe Onorato798ac4c2010-05-27 16:39:00 -040090 * bar at boot time. It goes through the normal API for icons, even though it probably
91 * strictly doesn't need to.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080092 */
Jason Monkaa573e92017-01-27 17:00:29 -050093public class PhoneStatusBarPolicy implements Callback, Callbacks,
Jason Monk359bb742017-04-13 10:40:40 -040094 RotationLockControllerCallback, Listener, LocationChangeCallback,
Jason Monkaa573e92017-01-27 17:00:29 -050095 ZenModeController.Callback, DeviceProvisionedListener, KeyguardMonitor.Callback {
Joe Onoratofd52b182010-11-10 18:00:52 -080096 private static final String TAG = "PhoneStatusBarPolicy";
John Spurlocka37e9c82014-07-08 09:40:31 -040097 private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
Robert Greenwaltd7085fc2010-09-08 15:24:47 -070098
Jason Monk359bb742017-04-13 10:40:40 -040099 public static final int LOCATION_STATUS_ICON_ID = R.drawable.stat_sys_location;
Jason Monk697b82a2017-04-19 18:41:06 -0400100 public static final int NUM_TASKS_FOR_INSTANT_APP_INFO = 5;
Jason Monk359bb742017-04-13 10:40:40 -0400101
Jason Monk3e189872016-01-12 09:10:34 -0500102 private final String mSlotCast;
103 private final String mSlotHotspot;
104 private final String mSlotBluetooth;
105 private final String mSlotTty;
106 private final String mSlotZen;
107 private final String mSlotVolume;
108 private final String mSlotAlarmClock;
109 private final String mSlotManagedProfile;
110 private final String mSlotRotate;
111 private final String mSlotHeadset;
Jason Monkf23aa992016-01-22 16:45:21 -0500112 private final String mSlotDataSaver;
Jason Monk359bb742017-04-13 10:40:40 -0400113 private final String mSlotLocation;
John Spurlocka37e9c82014-07-08 09:40:31 -0400114
Dianne Hackborn4840e142009-03-24 22:40:29 -0700115 private final Context mContext;
Joe Onorato10523b4d2010-10-25 10:42:46 -0700116 private final Handler mHandler = new Handler();
John Spurlock96fe98d2014-08-27 09:36:02 -0400117 private final CastController mCast;
Jason Monk952d5d82014-10-27 15:28:22 -0400118 private final HotspotController mHotspot;
Juan Flores2ff37202015-04-30 13:44:23 +0200119 private final NextAlarmController mNextAlarm;
John Spurlock15782262015-05-29 15:35:53 -0400120 private final AlarmManager mAlarmManager;
Adrian Roos88b11932015-07-22 14:59:48 -0700121 private final UserInfoController mUserInfoController;
Rubin Xu1205fb12015-11-04 17:45:03 +0000122 private final UserManager mUserManager;
Jason Monk07473ce2016-01-05 14:59:19 -0500123 private final StatusBarIconController mIconController;
Jason Monk3e189872016-01-12 09:10:34 -0500124 private final RotationLockController mRotationLockController;
Jason Monkf23aa992016-01-22 16:45:21 -0500125 private final DataSaverController mDataSaver;
Jason Monkaa573e92017-01-27 17:00:29 -0500126 private final ZenModeController mZenController;
127 private final DeviceProvisionedController mProvisionedController;
128 private final KeyguardMonitor mKeyguardMonitor;
Jason Monk359bb742017-04-13 10:40:40 -0400129 private final LocationController mLocationController;
Jason Monk324b8862017-02-16 17:19:12 -0500130 private final ArraySet<Pair<String, Integer>> mCurrentNotifs = new ArraySet<>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800131
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800132 // Assume it's all good unless we hear otherwise. We don't always seem
133 // to get broadcasts that it *is* there.
Wink Savillea639b312012-07-10 12:37:54 -0700134 IccCardConstants.State mSimState = IccCardConstants.State.READY;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800135
John Spurlocka37e9c82014-07-08 09:40:31 -0400136 private boolean mZenVisible;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800137 private boolean mVolumeVisible;
John Spurlock604a5ee2015-06-01 12:27:22 -0400138 private boolean mCurrentUserSetup;
Jason Monkf85fc962017-04-19 17:13:41 -0400139 private boolean mDockedStackExists;
Wink Saville04e71b32009-04-02 11:00:54 -0700140
Rubin Xu1205fb12015-11-04 17:45:03 +0000141 private boolean mManagedProfileIconVisible = false;
142 private boolean mManagedProfileInQuietMode = false;
Kenny Guy3094d4a2015-04-01 19:14:10 +0100143
Jason Monk70364362015-08-06 16:32:18 -0400144 private BluetoothController mBluetooth;
Wink Savillee9b06d72009-05-18 21:47:50 -0700145
Jason Monk9c7844c2017-01-18 15:21:53 -0500146 public PhoneStatusBarPolicy(Context context, StatusBarIconController iconController) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800147 mContext = context;
Jason Monk07473ce2016-01-05 14:59:19 -0500148 mIconController = iconController;
Jason Monk9c7844c2017-01-18 15:21:53 -0500149 mCast = Dependency.get(CastController.class);
150 mHotspot = Dependency.get(HotspotController.class);
151 mBluetooth = Dependency.get(BluetoothController.class);
Jason Monk9c7844c2017-01-18 15:21:53 -0500152 mNextAlarm = Dependency.get(NextAlarmController.class);
John Spurlock15782262015-05-29 15:35:53 -0400153 mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Jason Monk9c7844c2017-01-18 15:21:53 -0500154 mUserInfoController = Dependency.get(UserInfoController.class);
Rubin Xu1205fb12015-11-04 17:45:03 +0000155 mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
Jason Monk9c7844c2017-01-18 15:21:53 -0500156 mRotationLockController = Dependency.get(RotationLockController.class);
157 mDataSaver = Dependency.get(DataSaverController.class);
Jason Monkaa573e92017-01-27 17:00:29 -0500158 mZenController = Dependency.get(ZenModeController.class);
159 mProvisionedController = Dependency.get(DeviceProvisionedController.class);
160 mKeyguardMonitor = Dependency.get(KeyguardMonitor.class);
Jason Monk359bb742017-04-13 10:40:40 -0400161 mLocationController = Dependency.get(LocationController.class);
Jason Monk3e189872016-01-12 09:10:34 -0500162
163 mSlotCast = context.getString(com.android.internal.R.string.status_bar_cast);
164 mSlotHotspot = context.getString(com.android.internal.R.string.status_bar_hotspot);
165 mSlotBluetooth = context.getString(com.android.internal.R.string.status_bar_bluetooth);
166 mSlotTty = context.getString(com.android.internal.R.string.status_bar_tty);
167 mSlotZen = context.getString(com.android.internal.R.string.status_bar_zen);
168 mSlotVolume = context.getString(com.android.internal.R.string.status_bar_volume);
169 mSlotAlarmClock = context.getString(com.android.internal.R.string.status_bar_alarm_clock);
170 mSlotManagedProfile = context.getString(
171 com.android.internal.R.string.status_bar_managed_profile);
172 mSlotRotate = context.getString(com.android.internal.R.string.status_bar_rotate);
173 mSlotHeadset = context.getString(com.android.internal.R.string.status_bar_headset);
Jason Monkf23aa992016-01-22 16:45:21 -0500174 mSlotDataSaver = context.getString(com.android.internal.R.string.status_bar_data_saver);
Jason Monk359bb742017-04-13 10:40:40 -0400175 mSlotLocation = context.getString(com.android.internal.R.string.status_bar_location);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800176
Daniel Sandlere3b7a2d2011-10-27 16:16:15 -0400177 // listen for broadcasts
178 IntentFilter filter = new IntentFilter();
Daniel Sandlere3b7a2d2011-10-27 16:16:15 -0400179 filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
John Spurlockbcc10872014-11-28 15:29:21 -0500180 filter.addAction(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION);
Jason Monk3e189872016-01-12 09:10:34 -0500181 filter.addAction(AudioManager.ACTION_HEADSET_PLUG);
Daniel Sandlere3b7a2d2011-10-27 16:16:15 -0400182 filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700183 filter.addAction(TelecomManager.ACTION_CURRENT_TTY_MODE_CHANGED);
Rubin Xue95057a2016-04-01 16:49:25 +0100184 filter.addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE);
185 filter.addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE);
Nicolas Prevot6c7b8742016-04-13 10:28:58 +0100186 filter.addAction(Intent.ACTION_MANAGED_PROFILE_REMOVED);
Daniel Sandlere3b7a2d2011-10-27 16:16:15 -0400187 mContext.registerReceiver(mIntentReceiver, filter, null, mHandler);
188
Kenny Guy3094d4a2015-04-01 19:14:10 +0100189 // listen for user / profile change.
190 try {
Sudheer Shankadc589ac2016-11-10 15:30:17 -0800191 ActivityManager.getService().registerUserSwitchObserver(mUserSwitchListener, TAG);
Kenny Guy3094d4a2015-04-01 19:14:10 +0100192 } catch (RemoteException e) {
193 // Ignore
194 }
195
Wink Saville04e71b32009-04-02 11:00:54 -0700196 // TTY status
Jason Monk324b8862017-02-16 17:19:12 -0500197 mIconController.setIcon(mSlotTty, R.drawable.stat_sys_tty_mode, null);
Jason Monk3e189872016-01-12 09:10:34 -0500198 mIconController.setIconVisibility(mSlotTty, false);
Wink Saville04e71b32009-04-02 11:00:54 -0700199
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800200 // bluetooth status
Jorim Jaggi2d75f9f2014-10-08 17:10:58 -0700201 updateBluetooth();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800202
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800203 // Alarm clock
Jason Monk3e189872016-01-12 09:10:34 -0500204 mIconController.setIcon(mSlotAlarmClock, R.drawable.stat_sys_alarm, null);
205 mIconController.setIconVisibility(mSlotAlarmClock, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800206
John Spurlocka37e9c82014-07-08 09:40:31 -0400207 // zen
Jason Monk3e189872016-01-12 09:10:34 -0500208 mIconController.setIcon(mSlotZen, R.drawable.stat_sys_zen_important, null);
209 mIconController.setIconVisibility(mSlotZen, false);
John Spurlocka37e9c82014-07-08 09:40:31 -0400210
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800211 // volume
Jason Monk3e189872016-01-12 09:10:34 -0500212 mIconController.setIcon(mSlotVolume, R.drawable.stat_sys_ringer_vibrate, null);
213 mIconController.setIconVisibility(mSlotVolume, false);
John Spurlocka37e9c82014-07-08 09:40:31 -0400214 updateVolumeZen();
John Spurlock96fe98d2014-08-27 09:36:02 -0400215
216 // cast
Jason Monk3e189872016-01-12 09:10:34 -0500217 mIconController.setIcon(mSlotCast, R.drawable.stat_sys_cast, null);
218 mIconController.setIconVisibility(mSlotCast, false);
Jason Monk952d5d82014-10-27 15:28:22 -0400219
220 // hotspot
Jason Monk3e189872016-01-12 09:10:34 -0500221 mIconController.setIcon(mSlotHotspot, R.drawable.stat_sys_hotspot,
Jason Monk08187a42015-06-09 14:33:51 -0400222 mContext.getString(R.string.accessibility_status_bar_hotspot));
Jason Monk3e189872016-01-12 09:10:34 -0500223 mIconController.setIconVisibility(mSlotHotspot, mHotspot.isHotspotEnabled());
Kenny Guy3094d4a2015-04-01 19:14:10 +0100224
225 // managed profile
Jason Monk3e189872016-01-12 09:10:34 -0500226 mIconController.setIcon(mSlotManagedProfile, R.drawable.stat_sys_managed_profile_status,
Adrian Roos1b5eb972015-06-11 18:22:52 -0700227 mContext.getString(R.string.accessibility_managed_profile));
Jason Monk3e189872016-01-12 09:10:34 -0500228 mIconController.setIconVisibility(mSlotManagedProfile, mManagedProfileIconVisible);
Jason Monkf23aa992016-01-22 16:45:21 -0500229
230 // data saver
231 mIconController.setIcon(mSlotDataSaver, R.drawable.stat_sys_data_saver,
232 context.getString(R.string.accessibility_data_saver_on));
233 mIconController.setIconVisibility(mSlotDataSaver, false);
Jason Monkaa573e92017-01-27 17:00:29 -0500234
235 mRotationLockController.addCallback(this);
236 mBluetooth.addCallback(this);
237 mProvisionedController.addCallback(this);
238 mZenController.addCallback(this);
239 mCast.addCallback(mCastCallback);
240 mHotspot.addCallback(mHotspotCallback);
241 mNextAlarm.addCallback(mNextAlarmCallback);
Jason Monk88529052016-11-04 13:29:58 -0400242 mDataSaver.addCallback(this);
Jason Monkaa573e92017-01-27 17:00:29 -0500243 mKeyguardMonitor.addCallback(this);
Jason Monk359bb742017-04-13 10:40:40 -0400244 mLocationController.addCallback(this);
Jason Monkaa573e92017-01-27 17:00:29 -0500245
246 SysUiServiceProvider.getComponent(mContext, CommandQueue.class).addCallbacks(this);
Jason Monk324b8862017-02-16 17:19:12 -0500247 SystemServicesProxy.getInstance(mContext).registerTaskStackListener(mTaskListener);
248
249 // Clear out all old notifications on startup (only present in the case where sysui dies)
250 NotificationManager noMan = mContext.getSystemService(NotificationManager.class);
251 for (StatusBarNotification notification : noMan.getActiveNotifications()) {
252 if (notification.getId() == SystemMessage.NOTE_INSTANT_APPS) {
253 noMan.cancel(notification.getTag(), notification.getId());
254 }
255 }
Jason Monkf85fc962017-04-19 17:13:41 -0400256 DockedStackExistsListener.register(exists -> {
257 mDockedStackExists = exists;
258 updateForegroundInstantApps();
259 });
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800260 }
261
Jason Monkaa573e92017-01-27 17:00:29 -0500262 public void destroy() {
263 mRotationLockController.removeCallback(this);
264 mBluetooth.removeCallback(this);
265 mProvisionedController.removeCallback(this);
266 mZenController.removeCallback(this);
267 mCast.removeCallback(mCastCallback);
268 mHotspot.removeCallback(mHotspotCallback);
269 mNextAlarm.removeCallback(mNextAlarmCallback);
270 mDataSaver.removeCallback(this);
271 mKeyguardMonitor.removeCallback(this);
Jason Monk359bb742017-04-13 10:40:40 -0400272 mLocationController.removeCallback(this);
Jason Monkaa573e92017-01-27 17:00:29 -0500273 SysUiServiceProvider.getComponent(mContext, CommandQueue.class).removeCallbacks(this);
274 mContext.unregisterReceiver(mIntentReceiver);
Jason Monk324b8862017-02-16 17:19:12 -0500275
276 NotificationManager noMan = mContext.getSystemService(NotificationManager.class);
277 mCurrentNotifs.forEach(v -> noMan.cancelAsUser(v.first, SystemMessage.NOTE_INSTANT_APPS,
278 new UserHandle(v.second)));
Nicolas Prevot1dbbe7d2016-05-17 12:52:54 +0100279 }
280
Jason Monkaa573e92017-01-27 17:00:29 -0500281 @Override
282 public void onZenChanged(int zen) {
John Spurlocka37e9c82014-07-08 09:40:31 -0400283 updateVolumeZen();
John Spurlockba2c6a02014-05-19 09:44:06 -0400284 }
285
Jason Monk359bb742017-04-13 10:40:40 -0400286 @Override
287 public void onLocationActiveChanged(boolean active) {
288 updateLocation();
289 }
290
291 // Updates the status view based on the current state of location requests.
292 private void updateLocation() {
293 if (mLocationController.isLocationActive()) {
294 mIconController.setIcon(mSlotLocation, LOCATION_STATUS_ICON_ID,
295 mContext.getString(R.string.accessibility_location_active));
296 } else {
297 mIconController.removeIcon(mSlotLocation);
298 }
299 }
300
Adrian Roosc42a1e12014-07-07 23:35:53 +0200301 private void updateAlarm() {
John Spurlock604a5ee2015-06-01 12:27:22 -0400302 final AlarmClockInfo alarm = mAlarmManager.getNextAlarmClock(UserHandle.USER_CURRENT);
303 final boolean hasAlarm = alarm != null && alarm.getTriggerTime() > 0;
Jason Monk20c0eb42017-03-02 17:35:49 -0500304 int zen = mZenController.getZen();
305 final boolean zenNone = zen == Global.ZEN_MODE_NO_INTERRUPTIONS;
Jason Monk3e189872016-01-12 09:10:34 -0500306 mIconController.setIcon(mSlotAlarmClock, zenNone ? R.drawable.stat_sys_alarm_dim
Jason Monk07473ce2016-01-05 14:59:19 -0500307 : R.drawable.stat_sys_alarm, null);
Jason Monk3e189872016-01-12 09:10:34 -0500308 mIconController.setIconVisibility(mSlotAlarmClock, mCurrentUserSetup && hasAlarm);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800309 }
310
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800311 private final void updateSimState(Intent intent) {
Wink Savillea639b312012-07-10 12:37:54 -0700312 String stateExtra = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE);
313 if (IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {
314 mSimState = IccCardConstants.State.ABSENT;
Jason Monk07473ce2016-01-05 14:59:19 -0500315 } else if (IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR.equals(stateExtra)) {
Rakesh Pallerlaf099a5f2013-02-06 11:44:23 +0530316 mSimState = IccCardConstants.State.CARD_IO_ERROR;
Junda Liua2f6a672016-05-24 10:07:40 -0700317 } else if (IccCardConstants.INTENT_VALUE_ICC_CARD_RESTRICTED.equals(stateExtra)) {
318 mSimState = IccCardConstants.State.CARD_RESTRICTED;
Jason Monk07473ce2016-01-05 14:59:19 -0500319 } else if (IccCardConstants.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
Wink Savillea639b312012-07-10 12:37:54 -0700320 mSimState = IccCardConstants.State.READY;
Jason Monk07473ce2016-01-05 14:59:19 -0500321 } else if (IccCardConstants.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) {
Wink Savillea639b312012-07-10 12:37:54 -0700322 final String lockedReason =
323 intent.getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
324 if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) {
325 mSimState = IccCardConstants.State.PIN_REQUIRED;
Jason Monk07473ce2016-01-05 14:59:19 -0500326 } else if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) {
Wink Savillea639b312012-07-10 12:37:54 -0700327 mSimState = IccCardConstants.State.PUK_REQUIRED;
Jason Monk07473ce2016-01-05 14:59:19 -0500328 } else {
Wink Savillea639b312012-07-10 12:37:54 -0700329 mSimState = IccCardConstants.State.NETWORK_LOCKED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800330 }
331 } else {
Wink Savillea639b312012-07-10 12:37:54 -0700332 mSimState = IccCardConstants.State.UNKNOWN;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800333 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800334 }
335
John Spurlockbcc10872014-11-28 15:29:21 -0500336 private final void updateVolumeZen() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800337 AudioManager audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
John Spurlocka37e9c82014-07-08 09:40:31 -0400338
339 boolean zenVisible = false;
340 int zenIconId = 0;
341 String zenDescription = null;
342
343 boolean volumeVisible = false;
344 int volumeIconId = 0;
345 String volumeDescription = null;
Jason Monk20c0eb42017-03-02 17:35:49 -0500346 int zen = mZenController.getZen();
John Spurlocka37e9c82014-07-08 09:40:31 -0400347
John Spurlockf88d8082015-03-25 18:09:51 -0400348 if (DndTile.isVisible(mContext) || DndTile.isCombinedIcon(mContext)) {
Jason Monk20c0eb42017-03-02 17:35:49 -0500349 zenVisible = zen != Global.ZEN_MODE_OFF;
350 zenIconId = zen == Global.ZEN_MODE_NO_INTERRUPTIONS
John Spurlock4ec8b602015-05-11 17:46:28 -0400351 ? R.drawable.stat_sys_dnd_total_silence : R.drawable.stat_sys_dnd;
John Spurlock3c4076a2015-02-24 12:12:25 -0500352 zenDescription = mContext.getString(R.string.quick_settings_dnd_label);
Jason Monk20c0eb42017-03-02 17:35:49 -0500353 } else if (zen == Global.ZEN_MODE_NO_INTERRUPTIONS) {
John Spurlocka37e9c82014-07-08 09:40:31 -0400354 zenVisible = true;
355 zenIconId = R.drawable.stat_sys_zen_none;
John Spurlockd9c75db2015-04-28 11:19:13 -0400356 zenDescription = mContext.getString(R.string.interruption_level_none);
Jason Monk20c0eb42017-03-02 17:35:49 -0500357 } else if (zen == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) {
John Spurlocka37e9c82014-07-08 09:40:31 -0400358 zenVisible = true;
359 zenIconId = R.drawable.stat_sys_zen_important;
John Spurlockd9c75db2015-04-28 11:19:13 -0400360 zenDescription = mContext.getString(R.string.interruption_level_priority);
Svetoslav Ganov6179ea32011-06-28 01:12:41 -0700361 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800362
John Spurlockd9c75db2015-04-28 11:19:13 -0400363 if (DndTile.isVisible(mContext) && !DndTile.isCombinedIcon(mContext)
John Spurlocka48d7792015-03-03 17:35:57 -0500364 && audioManager.getRingerModeInternal() == AudioManager.RINGER_MODE_SILENT) {
365 volumeVisible = true;
366 volumeIconId = R.drawable.stat_sys_ringer_silent;
367 volumeDescription = mContext.getString(R.string.accessibility_ringer_silent);
Jason Monk20c0eb42017-03-02 17:35:49 -0500368 } else if (zen != Global.ZEN_MODE_NO_INTERRUPTIONS && zen != Global.ZEN_MODE_ALARMS &&
John Spurlock661f2cf2014-11-17 10:29:10 -0500369 audioManager.getRingerModeInternal() == AudioManager.RINGER_MODE_VIBRATE) {
John Spurlocka37e9c82014-07-08 09:40:31 -0400370 volumeVisible = true;
371 volumeIconId = R.drawable.stat_sys_ringer_vibrate;
372 volumeDescription = mContext.getString(R.string.accessibility_ringer_vibrate);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800373 }
John Spurlocka37e9c82014-07-08 09:40:31 -0400374
375 if (zenVisible) {
Jason Monk3e189872016-01-12 09:10:34 -0500376 mIconController.setIcon(mSlotZen, zenIconId, zenDescription);
John Spurlocka37e9c82014-07-08 09:40:31 -0400377 }
378 if (zenVisible != mZenVisible) {
Jason Monk3e189872016-01-12 09:10:34 -0500379 mIconController.setIconVisibility(mSlotZen, zenVisible);
John Spurlocka37e9c82014-07-08 09:40:31 -0400380 mZenVisible = zenVisible;
381 }
382
383 if (volumeVisible) {
Jason Monk3e189872016-01-12 09:10:34 -0500384 mIconController.setIcon(mSlotVolume, volumeIconId, volumeDescription);
John Spurlocka37e9c82014-07-08 09:40:31 -0400385 }
386 if (volumeVisible != mVolumeVisible) {
Jason Monk3e189872016-01-12 09:10:34 -0500387 mIconController.setIconVisibility(mSlotVolume, volumeVisible);
John Spurlocka37e9c82014-07-08 09:40:31 -0400388 mVolumeVisible = volumeVisible;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800389 }
John Spurlock15782262015-05-29 15:35:53 -0400390 updateAlarm();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800391 }
392
Jason Monk70364362015-08-06 16:32:18 -0400393 @Override
394 public void onBluetoothDevicesChanged() {
395 updateBluetooth();
396 }
397
398 @Override
399 public void onBluetoothStateChange(boolean enabled) {
400 updateBluetooth();
401 }
402
Jorim Jaggi2d75f9f2014-10-08 17:10:58 -0700403 private final void updateBluetooth() {
Joe Onorato798ac4c2010-05-27 16:39:00 -0400404 int iconId = R.drawable.stat_sys_data_bluetooth;
Jorim Jaggi2d75f9f2014-10-08 17:10:58 -0700405 String contentDescription =
Jason Monk1aa32822015-07-14 16:10:32 -0400406 mContext.getString(R.string.accessibility_quick_settings_bluetooth_on);
Jason Monk70364362015-08-06 16:32:18 -0400407 boolean bluetoothEnabled = false;
408 if (mBluetooth != null) {
409 bluetoothEnabled = mBluetooth.isBluetoothEnabled();
410 if (mBluetooth.isBluetoothConnected()) {
Jaikumar Ganeshd9bb6882010-09-27 17:05:24 -0700411 iconId = R.drawable.stat_sys_data_bluetooth_connected;
Svetoslav Ganov6179ea32011-06-28 01:12:41 -0700412 contentDescription = mContext.getString(R.string.accessibility_bluetooth_connected);
Jaikumar Ganesh084c6652009-12-07 10:58:18 -0800413 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800414 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700415
Jason Monk3e189872016-01-12 09:10:34 -0500416 mIconController.setIcon(mSlotBluetooth, iconId, contentDescription);
417 mIconController.setIconVisibility(mSlotBluetooth, bluetoothEnabled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800418 }
419
Wink Savillee9b06d72009-05-18 21:47:50 -0700420 private final void updateTTY(Intent intent) {
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700421 int currentTtyMode = intent.getIntExtra(TelecomManager.EXTRA_CURRENT_TTY_MODE,
422 TelecomManager.TTY_MODE_OFF);
423 boolean enabled = currentTtyMode != TelecomManager.TTY_MODE_OFF;
Wink Saville04e71b32009-04-02 11:00:54 -0700424
John Spurlocka37e9c82014-07-08 09:40:31 -0400425 if (DEBUG) Log.v(TAG, "updateTTY: enabled: " + enabled);
Wink Saville04e71b32009-04-02 11:00:54 -0700426
427 if (enabled) {
428 // TTY is on
John Spurlocka37e9c82014-07-08 09:40:31 -0400429 if (DEBUG) Log.v(TAG, "updateTTY: set TTY on");
Jason Monk3e189872016-01-12 09:10:34 -0500430 mIconController.setIcon(mSlotTty, R.drawable.stat_sys_tty_mode,
Svetoslav Ganov6179ea32011-06-28 01:12:41 -0700431 mContext.getString(R.string.accessibility_tty_enabled));
Jason Monk3e189872016-01-12 09:10:34 -0500432 mIconController.setIconVisibility(mSlotTty, true);
Wink Saville04e71b32009-04-02 11:00:54 -0700433 } else {
434 // TTY is off
John Spurlocka37e9c82014-07-08 09:40:31 -0400435 if (DEBUG) Log.v(TAG, "updateTTY: set TTY off");
Jason Monk3e189872016-01-12 09:10:34 -0500436 mIconController.setIconVisibility(mSlotTty, false);
Wink Saville04e71b32009-04-02 11:00:54 -0700437 }
438 }
John Spurlock96fe98d2014-08-27 09:36:02 -0400439
440 private void updateCast() {
441 boolean isCasting = false;
442 for (CastDevice device : mCast.getCastDevices()) {
443 if (device.state == CastDevice.STATE_CONNECTING
444 || device.state == CastDevice.STATE_CONNECTED) {
445 isCasting = true;
446 break;
447 }
448 }
449 if (DEBUG) Log.v(TAG, "updateCast: isCasting: " + isCasting);
Dan Sandler8fd25bf2015-10-20 16:01:27 -0700450 mHandler.removeCallbacks(mRemoveCastIconRunnable);
John Spurlock96fe98d2014-08-27 09:36:02 -0400451 if (isCasting) {
Jason Monk3e189872016-01-12 09:10:34 -0500452 mIconController.setIcon(mSlotCast, R.drawable.stat_sys_cast,
John Spurlock96fe98d2014-08-27 09:36:02 -0400453 mContext.getString(R.string.accessibility_casting));
Jason Monk3e189872016-01-12 09:10:34 -0500454 mIconController.setIconVisibility(mSlotCast, true);
Dan Sandler8fd25bf2015-10-20 16:01:27 -0700455 } else {
456 // don't turn off the screen-record icon for a few seconds, just to make sure the user
457 // has seen it
458 if (DEBUG) Log.v(TAG, "updateCast: hiding icon in 3 sec...");
459 mHandler.postDelayed(mRemoveCastIconRunnable, 3000);
John Spurlock96fe98d2014-08-27 09:36:02 -0400460 }
John Spurlock96fe98d2014-08-27 09:36:02 -0400461 }
462
Rubin Xu1205fb12015-11-04 17:45:03 +0000463 private void updateQuietState() {
464 mManagedProfileInQuietMode = false;
465 int currentUserId = ActivityManager.getCurrentUser();
466 for (UserInfo ui : mUserManager.getEnabledProfiles(currentUserId)) {
467 if (ui.isManagedProfile() && ui.isQuietModeEnabled()) {
468 mManagedProfileInQuietMode = true;
469 return;
470 }
471 }
472 }
473
Kenny Guy3094d4a2015-04-01 19:14:10 +0100474 private void updateManagedProfile() {
Tony Makec319ab2017-03-28 18:50:01 +0100475 try {
476 final boolean showIcon;
477 final int userId = ActivityManager.getService().getLastResumedActivityUserId();
478 if (mUserManager.isManagedProfile(userId) && !mKeyguardMonitor.isShowing()) {
479 showIcon = true;
480 mIconController.setIcon(mSlotManagedProfile,
481 R.drawable.stat_sys_managed_profile_status,
482 mContext.getString(R.string.accessibility_managed_profile));
483 } else if (mManagedProfileInQuietMode) {
484 showIcon = true;
485 mIconController.setIcon(mSlotManagedProfile,
486 R.drawable.stat_sys_managed_profile_status_off,
487 mContext.getString(R.string.accessibility_managed_profile));
488 } else {
489 showIcon = false;
490 }
491 if (mManagedProfileIconVisible != showIcon) {
492 mIconController.setIconVisibility(mSlotManagedProfile, showIcon);
493 mManagedProfileIconVisible = showIcon;
494 }
495 } catch (RemoteException ex) {
496 Log.w(TAG, "updateManagedProfile: ", ex);
497 // ignore
Kenny Guy3094d4a2015-04-01 19:14:10 +0100498 }
499 }
500
Jason Monk324b8862017-02-16 17:19:12 -0500501 private void updateForegroundInstantApps() {
502 NotificationManager noMan = mContext.getSystemService(NotificationManager.class);
503 ArraySet<Pair<String, Integer>> notifs = new ArraySet<>(mCurrentNotifs);
504 IPackageManager pm = AppGlobals.getPackageManager();
505 mCurrentNotifs.clear();
506 try {
Jason Monkf85fc962017-04-19 17:13:41 -0400507 ArraySet<Integer> stacksToCheck = new ArraySet<>();
Jason Monk324b8862017-02-16 17:19:12 -0500508 int[] STACKS_TO_CHECK = new int[]{
509 StackId.FULLSCREEN_WORKSPACE_STACK_ID,
510 StackId.DOCKED_STACK_ID,
511 };
Jason Monkf85fc962017-04-19 17:13:41 -0400512 int focusedId = ActivityManager.getService().getFocusedStackId();
513 if (focusedId == StackId.FULLSCREEN_WORKSPACE_STACK_ID
514 || focusedId == StackId.FULLSCREEN_WORKSPACE_STACK_ID) {
515 checkStack(StackId.FULLSCREEN_WORKSPACE_STACK_ID, notifs, noMan, pm);
516 }
517 if (mDockedStackExists) {
518 checkStack(StackId.DOCKED_STACK_ID, notifs, noMan, pm);
Jason Monk324b8862017-02-16 17:19:12 -0500519 }
520 } catch (RemoteException e) {
521 e.rethrowFromSystemServer();
522 }
523 // Cancel all the leftover notifications that don't have a foreground process anymore.
524 notifs.forEach(v -> noMan.cancelAsUser(v.first, SystemMessage.NOTE_INSTANT_APPS,
525 new UserHandle(v.second)));
526 }
527
Jason Monkf85fc962017-04-19 17:13:41 -0400528 private void checkStack(int stackId, ArraySet<Pair<String, Integer>> notifs,
529 NotificationManager noMan, IPackageManager pm) {
530 try {
531 StackInfo info = ActivityManager.getService().getStackInfo(stackId);
532 if (info == null || info.topActivity == null) return;
533 String pkg = info.topActivity.getPackageName();
534 if (!hasNotif(notifs, pkg, info.userId)) {
535 // TODO: Optimize by not always needing to get application info.
536 // Maybe cache non-ephemeral packages?
537 ApplicationInfo appInfo = pm.getApplicationInfo(pkg,
538 PackageManager.MATCH_UNINSTALLED_PACKAGES, info.userId);
539 if (appInfo.isInstantApp()) {
Jason Monk697b82a2017-04-19 18:41:06 -0400540 postEphemeralNotif(pkg, info.userId, appInfo, noMan, info.taskIds[info.taskIds.length - 1]);
Jason Monkf85fc962017-04-19 17:13:41 -0400541 }
542 }
543 } catch (RemoteException e) {
544 e.rethrowFromSystemServer();
545 }
546 }
547
Jason Monk324b8862017-02-16 17:19:12 -0500548 private void postEphemeralNotif(String pkg, int userId, ApplicationInfo appInfo,
Jason Monk697b82a2017-04-19 18:41:06 -0400549 NotificationManager noMan, int taskId) {
Jason Monk324b8862017-02-16 17:19:12 -0500550 final Bundle extras = new Bundle();
551 extras.putString(Notification.EXTRA_SUBSTITUTE_APP_NAME,
552 mContext.getString(R.string.instant_apps));
553 mCurrentNotifs.add(new Pair<>(pkg, userId));
554 String message = mContext.getString(R.string.instant_apps_message);
555 PendingIntent appInfoAction = PendingIntent.getActivity(mContext, 0,
556 new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
557 .setData(Uri.fromParts("package", pkg, null)), 0);
Jason Monk324b8862017-02-16 17:19:12 -0500558 Action action = new Notification.Action.Builder(null, mContext.getString(R.string.app_info),
559 appInfoAction).build();
560
Jason Monk697b82a2017-04-19 18:41:06 -0400561 Intent browserIntent = getTaskIntent(taskId, userId);
562 Notification.Builder builder = new Notification.Builder(mContext, NotificationChannels.GENERAL);
563 if (browserIntent != null) {
564 PendingIntent pendingIntent = PendingIntent.getActivity(mContext,
565 0 /* requestCode */, browserIntent, 0 /* flags */);
566 browserIntent.setComponent(null);
567 browserIntent.addFlags(Intent.FLAG_IGNORE_EPHEMERAL);
568 browserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
569
570 ComponentName aiaComponent = null;
571 try {
572 aiaComponent = AppGlobals.getPackageManager().getInstantAppInstallerComponent();
573 } catch (RemoteException e) {
574 e.rethrowFromSystemServer();
575 }
576 Intent goToWebIntent = new Intent()
577 .setComponent(aiaComponent)
578 .setAction(Intent.ACTION_VIEW)
579 .addCategory(Intent.CATEGORY_BROWSABLE)
580 .putExtra(Intent.EXTRA_PACKAGE_NAME, appInfo.packageName)
581 .putExtra(Intent.EXTRA_VERSION_CODE, appInfo.versionCode)
582 .putExtra(Intent.EXTRA_EPHEMERAL_FAILURE, pendingIntent);
583
584 PendingIntent webPendingIntent = PendingIntent.getActivity(mContext, 0, goToWebIntent, 0);
585 Action webAction = new Notification.Action.Builder(null, mContext.getString(R.string.go_to_web),
586 webPendingIntent).build();
587 builder.addAction(webAction);
588 }
589
590 noMan.notifyAsUser(pkg, SystemMessage.NOTE_INSTANT_APPS, builder
Jason Monk324b8862017-02-16 17:19:12 -0500591 .addExtras(extras)
592 .addAction(action)
593 .setContentIntent(appInfoAction)
594 .setColor(mContext.getColor(R.color.instant_apps_color))
595 .setContentTitle(appInfo.loadLabel(mContext.getPackageManager()))
596 .setLargeIcon(Icon.createWithResource(pkg, appInfo.icon))
597 .setSmallIcon(Icon.createWithResource(mContext.getPackageName(),
598 R.drawable.instant_icon))
599 .setContentText(message)
600 .setOngoing(true)
601 .build(),
602 new UserHandle(userId));
603 }
604
Jason Monk697b82a2017-04-19 18:41:06 -0400605 private Intent getTaskIntent(int taskId, int userId) {
606 List<ActivityManager.RecentTaskInfo> tasks = mContext.getSystemService(ActivityManager.class)
607 .getRecentTasksForUser(NUM_TASKS_FOR_INSTANT_APP_INFO, 0, userId);
608 for (int i = 0; i < tasks.size(); i++) {
609 if (tasks.get(i).id == taskId) {
610 return tasks.get(i).baseIntent;
611 }
612 }
613 return null;
614 }
615
Jason Monk324b8862017-02-16 17:19:12 -0500616 private boolean hasNotif(ArraySet<Pair<String, Integer>> notifs, String pkg, int userId) {
617 Pair<String, Integer> key = new Pair<>(pkg, userId);
618 if (notifs.remove(key)) {
619 mCurrentNotifs.add(key);
620 return true;
621 }
622 return false;
623 }
624
Fyodor Kupolov6005b3f2015-11-23 17:41:50 -0800625 private final SynchronousUserSwitchObserver mUserSwitchListener =
626 new SynchronousUserSwitchObserver() {
Kenny Guy3094d4a2015-04-01 19:14:10 +0100627 @Override
Fyodor Kupolov6005b3f2015-11-23 17:41:50 -0800628 public void onUserSwitching(int newUserId) throws RemoteException {
Tony Makec319ab2017-03-28 18:50:01 +0100629 mHandler.post(() -> mUserInfoController.reloadUserInfo());
Kenny Guy3094d4a2015-04-01 19:14:10 +0100630 }
631
632 @Override
633 public void onUserSwitchComplete(int newUserId) throws RemoteException {
Tony Makec319ab2017-03-28 18:50:01 +0100634 mHandler.post(() -> {
635 updateAlarm();
636 updateQuietState();
637 updateManagedProfile();
638 updateForegroundInstantApps();
Toni Barzice97f9232016-04-27 18:10:58 -0700639 });
Kenny Guy3094d4a2015-04-01 19:14:10 +0100640 }
641 };
642
Jason Monk952d5d82014-10-27 15:28:22 -0400643 private final HotspotController.Callback mHotspotCallback = new HotspotController.Callback() {
644 @Override
645 public void onHotspotChanged(boolean enabled) {
Jason Monk3e189872016-01-12 09:10:34 -0500646 mIconController.setIconVisibility(mSlotHotspot, enabled);
Jason Monk952d5d82014-10-27 15:28:22 -0400647 }
648 };
649
John Spurlock96fe98d2014-08-27 09:36:02 -0400650 private final CastController.Callback mCastCallback = new CastController.Callback() {
651 @Override
652 public void onCastDevicesChanged() {
653 updateCast();
654 }
655 };
Kenny Guy3094d4a2015-04-01 19:14:10 +0100656
Juan Flores2ff37202015-04-30 13:44:23 +0200657 private final NextAlarmController.NextAlarmChangeCallback mNextAlarmCallback =
658 new NextAlarmController.NextAlarmChangeCallback() {
Jason Monk324b8862017-02-16 17:19:12 -0500659 @Override
660 public void onNextAlarmChanged(AlarmManager.AlarmClockInfo nextAlarm) {
661 updateAlarm();
662 }
663 };
Juan Flores2ff37202015-04-30 13:44:23 +0200664
Jason Monkaa573e92017-01-27 17:00:29 -0500665 @Override
666 public void appTransitionStarting(long startTime, long duration, boolean forced) {
Kenny Guy3094d4a2015-04-01 19:14:10 +0100667 updateManagedProfile();
Jason Monk324b8862017-02-16 17:19:12 -0500668 updateForegroundInstantApps();
Kenny Guy3094d4a2015-04-01 19:14:10 +0100669 }
670
Jason Monkaa573e92017-01-27 17:00:29 -0500671 @Override
672 public void onKeyguardShowingChanged() {
Kenny Guy3094d4a2015-04-01 19:14:10 +0100673 updateManagedProfile();
Jason Monk324b8862017-02-16 17:19:12 -0500674 updateForegroundInstantApps();
Kenny Guy3094d4a2015-04-01 19:14:10 +0100675 }
John Spurlock604a5ee2015-06-01 12:27:22 -0400676
Jason Monkaa573e92017-01-27 17:00:29 -0500677 @Override
678 public void onUserSetupChanged() {
679 boolean userSetup = mProvisionedController.isUserSetup(
680 mProvisionedController.getCurrentUser());
John Spurlock604a5ee2015-06-01 12:27:22 -0400681 if (mCurrentUserSetup == userSetup) return;
682 mCurrentUserSetup = userSetup;
683 updateAlarm();
Rubin Xu1205fb12015-11-04 17:45:03 +0000684 updateQuietState();
John Spurlock604a5ee2015-06-01 12:27:22 -0400685 }
Jason Monk3e189872016-01-12 09:10:34 -0500686
687 @Override
Jason Monk324b8862017-02-16 17:19:12 -0500688 public void preloadRecentApps() {
689 updateForegroundInstantApps();
690 }
691
692 @Override
Jason Monk3e189872016-01-12 09:10:34 -0500693 public void onRotationLockStateChanged(boolean rotationLocked, boolean affordanceVisible) {
694 boolean portrait = RotationLockTile.isCurrentOrientationLockPortrait(
695 mRotationLockController, mContext);
696 if (rotationLocked) {
697 if (portrait) {
698 mIconController.setIcon(mSlotRotate, R.drawable.stat_sys_rotate_portrait,
699 mContext.getString(R.string.accessibility_rotation_lock_on_portrait));
700 } else {
701 mIconController.setIcon(mSlotRotate, R.drawable.stat_sys_rotate_landscape,
702 mContext.getString(R.string.accessibility_rotation_lock_on_landscape));
703 }
Jason Monk8816dff2016-02-09 21:50:36 -0500704 mIconController.setIconVisibility(mSlotRotate, true);
Jason Monk3e189872016-01-12 09:10:34 -0500705 } else {
Jason Monk8816dff2016-02-09 21:50:36 -0500706 mIconController.setIconVisibility(mSlotRotate, false);
Jason Monk3e189872016-01-12 09:10:34 -0500707 }
708 }
709
710 private void updateHeadsetPlug(Intent intent) {
711 boolean connected = intent.getIntExtra("state", 0) != 0;
712 boolean hasMic = intent.getIntExtra("microphone", 0) != 0;
713 if (connected) {
714 String contentDescription = mContext.getString(hasMic
715 ? R.string.accessibility_status_bar_headset
716 : R.string.accessibility_status_bar_headphones);
717 mIconController.setIcon(mSlotHeadset, hasMic ? R.drawable.ic_headset_mic
718 : R.drawable.ic_headset, contentDescription);
719 mIconController.setIconVisibility(mSlotHeadset, true);
720 } else {
721 mIconController.setIconVisibility(mSlotHeadset, false);
722 }
723 }
724
Jason Monkf23aa992016-01-22 16:45:21 -0500725 @Override
726 public void onDataSaverChanged(boolean isDataSaving) {
727 mIconController.setIconVisibility(mSlotDataSaver, isDataSaving);
728 }
729
Jason Monk324b8862017-02-16 17:19:12 -0500730 private final TaskStackListener mTaskListener = new TaskStackListener() {
731 @Override
732 public void onTaskStackChanged() {
733 // Listen for changes to stacks and then check which instant apps are foreground.
734 updateForegroundInstantApps();
735 }
736 };
737
Jason Monk3e189872016-01-12 09:10:34 -0500738 private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
739 @Override
740 public void onReceive(Context context, Intent intent) {
741 String action = intent.getAction();
Julia Reynolds4e6024b2016-04-26 16:12:26 -0400742 if (action.equals(AudioManager.RINGER_MODE_CHANGED_ACTION) ||
Jason Monk3e189872016-01-12 09:10:34 -0500743 action.equals(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION)) {
744 updateVolumeZen();
745 } else if (action.equals(TelephonyIntents.ACTION_SIM_STATE_CHANGED)) {
746 updateSimState(intent);
747 } else if (action.equals(TelecomManager.ACTION_CURRENT_TTY_MODE_CHANGED)) {
748 updateTTY(intent);
Rubin Xue95057a2016-04-01 16:49:25 +0100749 } else if (action.equals(Intent.ACTION_MANAGED_PROFILE_AVAILABLE) ||
Nicolas Prevot6c7b8742016-04-13 10:28:58 +0100750 action.equals(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE) ||
751 action.equals(Intent.ACTION_MANAGED_PROFILE_REMOVED)) {
Jason Monk3e189872016-01-12 09:10:34 -0500752 updateQuietState();
753 updateManagedProfile();
754 } else if (action.equals(AudioManager.ACTION_HEADSET_PLUG)) {
755 updateHeadsetPlug(intent);
756 }
757 }
758 };
759
760 private Runnable mRemoveCastIconRunnable = new Runnable() {
761 @Override
762 public void run() {
763 if (DEBUG) Log.v(TAG, "updateCast: hiding icon NOW");
764 mIconController.setIconVisibility(mSlotCast, false);
765 }
766 };
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800767}