blob: 06d35a36e3c409507a4be7d37b58b7d91d38a400 [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
Dave Mankoff3c6aaab2020-01-10 17:50:34 -050019import android.annotation.Nullable;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070020import android.app.ActivityTaskManager;
Jason Monk697b82a2017-04-19 18:41:06 -040021import android.app.AlarmManager;
John Spurlock604a5ee2015-06-01 12:27:22 -040022import android.app.AlarmManager.AlarmClockInfo;
Dave Mankoff3c6aaab2020-01-10 17:50:34 -050023import android.app.IActivityManager;
Jason Monk697b82a2017-04-19 18:41:06 -040024import android.app.SynchronousUserSwitchObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080025import android.content.BroadcastReceiver;
26import android.content.Context;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080027import android.content.Intent;
28import android.content.IntentFilter;
Dave Mankoff3c6aaab2020-01-10 17:50:34 -050029import android.content.SharedPreferences;
30import android.content.res.Resources;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031import android.media.AudioManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080032import android.os.Handler;
Kenny Guy3094d4a2015-04-01 19:14:10 +010033import android.os.RemoteException;
Adrian Roosc42a1e12014-07-07 23:35:53 +020034import android.os.UserHandle;
Kenny Guy3094d4a2015-04-01 19:14:10 +010035import android.os.UserManager;
John Spurlockae641c92014-06-30 18:11:40 -040036import android.provider.Settings.Global;
Beverlyb9826dd2018-04-12 15:02:45 -040037import android.service.notification.ZenModeConfig;
Tyler Gunnef9f6f92014-09-12 22:16:17 -070038import android.telecom.TelecomManager;
Evan Lairdbee3eb82018-05-16 15:58:49 -040039import android.text.format.DateFormat;
John Spurlockcd686b52013-06-05 10:13:46 -040040import android.util.Log;
Beth Thibodeaua5af2402020-06-15 23:16:09 -040041import android.view.View;
Beverlyff2df9b2018-10-10 16:54:10 -040042
Fabian Kozynskib6a20372020-04-01 09:36:43 -040043import androidx.lifecycle.Observer;
44
Joe Onorato798ac4c2010-05-27 16:39:00 -040045import com.android.systemui.R;
Fabian Kozynski5ca7a512019-10-16 19:56:11 +000046import com.android.systemui.broadcast.BroadcastDispatcher;
Dave Mankoff3c6aaab2020-01-10 17:50:34 -050047import com.android.systemui.dagger.qualifiers.DisplayId;
48import com.android.systemui.dagger.qualifiers.Main;
Dave Mankoffc7cf9fc2019-12-19 15:43:20 -050049import com.android.systemui.dagger.qualifiers.UiBackground;
John Spurlock3c4076a2015-02-24 12:12:25 -050050import com.android.systemui.qs.tiles.DndTile;
Jason Monk3e189872016-01-12 09:10:34 -050051import com.android.systemui.qs.tiles.RotationLockTile;
Beth Thibodeau8bfbf1f2020-02-13 13:55:37 -050052import com.android.systemui.screenrecord.RecordingController;
Jason Monkaa573e92017-01-27 17:00:29 -050053import com.android.systemui.statusbar.CommandQueue;
Jason Monk70364362015-08-06 16:32:18 -040054import com.android.systemui.statusbar.policy.BluetoothController;
John Spurlock96fe98d2014-08-27 09:36:02 -040055import com.android.systemui.statusbar.policy.CastController;
56import com.android.systemui.statusbar.policy.CastController.CastDevice;
Jason Monkf23aa992016-01-22 16:45:21 -050057import com.android.systemui.statusbar.policy.DataSaverController;
Jason Monkaa573e92017-01-27 17:00:29 -050058import com.android.systemui.statusbar.policy.DataSaverController.Listener;
59import com.android.systemui.statusbar.policy.DeviceProvisionedController;
60import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
Jason Monk952d5d82014-10-27 15:28:22 -040061import com.android.systemui.statusbar.policy.HotspotController;
Lucas Dupinc8f16e82019-09-17 18:24:50 -040062import com.android.systemui.statusbar.policy.KeyguardStateController;
Jason Monk359bb742017-04-13 10:40:40 -040063import com.android.systemui.statusbar.policy.LocationController;
Juan Flores2ff37202015-04-30 13:44:23 +020064import com.android.systemui.statusbar.policy.NextAlarmController;
Jason Monk3e189872016-01-12 09:10:34 -050065import com.android.systemui.statusbar.policy.RotationLockController;
Jason Monkaa573e92017-01-27 17:00:29 -050066import com.android.systemui.statusbar.policy.RotationLockController.RotationLockControllerCallback;
Michael Groovera51ea812019-03-19 18:56:36 -070067import com.android.systemui.statusbar.policy.SensorPrivacyController;
Adrian Roos88b11932015-07-22 14:59:48 -070068import com.android.systemui.statusbar.policy.UserInfoController;
Jason Monkaa573e92017-01-27 17:00:29 -050069import com.android.systemui.statusbar.policy.ZenModeController;
Fabian Kozynskib6a20372020-04-01 09:36:43 -040070import com.android.systemui.util.RingerModeTracker;
Dave Mankoff3c6aaab2020-01-10 17:50:34 -050071import com.android.systemui.util.time.DateFormatUtil;
Jason Monk324b8862017-02-16 17:19:12 -050072
Evan Lairdbee3eb82018-05-16 15:58:49 -040073import java.util.Locale;
Dave Mankoffc7cf9fc2019-12-19 15:43:20 -050074import java.util.concurrent.Executor;
Jason Monk697b82a2017-04-19 18:41:06 -040075
Dave Mankoff3c6aaab2020-01-10 17:50:34 -050076import javax.inject.Inject;
77
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080078/**
yoshiki iguchi69d65852019-02-13 18:07:41 +090079 * This class contains all of the policy about which icons are installed in the status bar at boot
80 * time. It goes through the normal API for icons, even though it probably strictly doesn't need to.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080081 */
yoshiki iguchi69d65852019-02-13 18:07:41 +090082public class PhoneStatusBarPolicy
83 implements BluetoothController.Callback,
Lucas Dupin68857da02020-05-27 23:41:50 +000084 CommandQueue.Callbacks,
85 RotationLockControllerCallback,
86 Listener,
87 ZenModeController.Callback,
88 DeviceProvisionedListener,
89 KeyguardStateController.Callback,
90 LocationController.LocationChangeCallback,
91 RecordingController.RecordingStateChangeCallback {
Joe Onoratofd52b182010-11-10 18:00:52 -080092 private static final String TAG = "PhoneStatusBarPolicy";
John Spurlocka37e9c82014-07-08 09:40:31 -040093 private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
Robert Greenwaltd7085fc2010-09-08 15:24:47 -070094
Dave Mankoff3c6aaab2020-01-10 17:50:34 -050095 static final int LOCATION_STATUS_ICON_ID =
Fabian Kozynski228e3102019-11-25 11:04:34 -050096 com.android.internal.R.drawable.perm_group_location;
Jason Monk359bb742017-04-13 10:40:40 -040097
Jason Monk3e189872016-01-12 09:10:34 -050098 private final String mSlotCast;
99 private final String mSlotHotspot;
100 private final String mSlotBluetooth;
101 private final String mSlotTty;
102 private final String mSlotZen;
103 private final String mSlotVolume;
104 private final String mSlotAlarmClock;
105 private final String mSlotManagedProfile;
106 private final String mSlotRotate;
107 private final String mSlotHeadset;
Jason Monkf23aa992016-01-22 16:45:21 -0500108 private final String mSlotDataSaver;
Jason Monk359bb742017-04-13 10:40:40 -0400109 private final String mSlotLocation;
Michael Groovera51ea812019-03-19 18:56:36 -0700110 private final String mSlotSensorsOff;
Beth Thibodeau8bfbf1f2020-02-13 13:55:37 -0500111 private final String mSlotScreenRecord;
Dave Mankoff3c6aaab2020-01-10 17:50:34 -0500112 private final int mDisplayId;
113 private final SharedPreferences mSharedPreferences;
114 private final DateFormatUtil mDateFormatUtil;
115 private final TelecomManager mTelecomManager;
John Spurlocka37e9c82014-07-08 09:40:31 -0400116
Joe Onorato10523b4d2010-10-25 10:42:46 -0700117 private final Handler mHandler = new Handler();
John Spurlock96fe98d2014-08-27 09:36:02 -0400118 private final CastController mCast;
Jason Monk952d5d82014-10-27 15:28:22 -0400119 private final HotspotController mHotspot;
Evan Lairdbee3eb82018-05-16 15:58:49 -0400120 private final NextAlarmController mNextAlarmController;
John Spurlock15782262015-05-29 15:35:53 -0400121 private final AlarmManager mAlarmManager;
Adrian Roos88b11932015-07-22 14:59:48 -0700122 private final UserInfoController mUserInfoController;
Dave Mankoff3c6aaab2020-01-10 17:50:34 -0500123 private final IActivityManager mIActivityManager;
Rubin Xu1205fb12015-11-04 17:45:03 +0000124 private final UserManager mUserManager;
Jason Monk07473ce2016-01-05 14:59:19 -0500125 private final StatusBarIconController mIconController;
Dave Mankoff3c6aaab2020-01-10 17:50:34 -0500126 private final CommandQueue mCommandQueue;
127 private final BroadcastDispatcher mBroadcastDispatcher;
128 private final Resources mResources;
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;
Lucas Dupinc8f16e82019-09-17 18:24:50 -0400133 private final KeyguardStateController mKeyguardStateController;
Jason Monk359bb742017-04-13 10:40:40 -0400134 private final LocationController mLocationController;
Dave Mankoffc7cf9fc2019-12-19 15:43:20 -0500135 private final Executor mUiBgExecutor;
Michael Groovera51ea812019-03-19 18:56:36 -0700136 private final SensorPrivacyController mSensorPrivacyController;
Beth Thibodeau8bfbf1f2020-02-13 13:55:37 -0500137 private final RecordingController mRecordingController;
Fabian Kozynskib6a20372020-04-01 09:36:43 -0400138 private final RingerModeTracker mRingerModeTracker;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800139
John Spurlocka37e9c82014-07-08 09:40:31 -0400140 private boolean mZenVisible;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800141 private boolean mVolumeVisible;
John Spurlock604a5ee2015-06-01 12:27:22 -0400142 private boolean mCurrentUserSetup;
Wink Saville04e71b32009-04-02 11:00:54 -0700143
Rubin Xu1205fb12015-11-04 17:45:03 +0000144 private boolean mManagedProfileIconVisible = false;
Kenny Guy3094d4a2015-04-01 19:14:10 +0100145
Jason Monk70364362015-08-06 16:32:18 -0400146 private BluetoothController mBluetooth;
Evan Lairdbee3eb82018-05-16 15:58:49 -0400147 private AlarmManager.AlarmClockInfo mNextAlarm;
Wink Savillee9b06d72009-05-18 21:47:50 -0700148
Dave Mankoff3c6aaab2020-01-10 17:50:34 -0500149 @Inject
150 public PhoneStatusBarPolicy(StatusBarIconController iconController,
Dave Mankoffc7cf9fc2019-12-19 15:43:20 -0500151 CommandQueue commandQueue, BroadcastDispatcher broadcastDispatcher,
Dave Mankoff3c6aaab2020-01-10 17:50:34 -0500152 @UiBackground Executor uiBgExecutor, @Main Resources resources,
153 CastController castController, HotspotController hotspotController,
154 BluetoothController bluetoothController, NextAlarmController nextAlarmController,
155 UserInfoController userInfoController, RotationLockController rotationLockController,
156 DataSaverController dataSaverController, ZenModeController zenModeController,
157 DeviceProvisionedController deviceProvisionedController,
158 KeyguardStateController keyguardStateController,
159 LocationController locationController,
160 SensorPrivacyController sensorPrivacyController, IActivityManager iActivityManager,
Fabian Kozynskib6a20372020-04-01 09:36:43 -0400161 AlarmManager alarmManager, UserManager userManager,
Dave Mankoff3c6aaab2020-01-10 17:50:34 -0500162 RecordingController recordingController,
163 @Nullable TelecomManager telecomManager, @DisplayId int displayId,
Fabian Kozynskib6a20372020-04-01 09:36:43 -0400164 @Main SharedPreferences sharedPreferences, DateFormatUtil dateFormatUtil,
165 RingerModeTracker ringerModeTracker) {
Jason Monk07473ce2016-01-05 14:59:19 -0500166 mIconController = iconController;
Dave Mankoff3c6aaab2020-01-10 17:50:34 -0500167 mCommandQueue = commandQueue;
168 mBroadcastDispatcher = broadcastDispatcher;
169 mResources = resources;
170 mCast = castController;
171 mHotspot = hotspotController;
172 mBluetooth = bluetoothController;
173 mNextAlarmController = nextAlarmController;
174 mAlarmManager = alarmManager;
175 mUserInfoController = userInfoController;
176 mIActivityManager = iActivityManager;
177 mUserManager = userManager;
178 mRotationLockController = rotationLockController;
179 mDataSaver = dataSaverController;
180 mZenController = zenModeController;
181 mProvisionedController = deviceProvisionedController;
182 mKeyguardStateController = keyguardStateController;
183 mLocationController = locationController;
184 mSensorPrivacyController = sensorPrivacyController;
185 mRecordingController = recordingController;
Dave Mankoffc7cf9fc2019-12-19 15:43:20 -0500186 mUiBgExecutor = uiBgExecutor;
Dave Mankoff3c6aaab2020-01-10 17:50:34 -0500187 mTelecomManager = telecomManager;
Fabian Kozynskib6a20372020-04-01 09:36:43 -0400188 mRingerModeTracker = ringerModeTracker;
Jason Monk3e189872016-01-12 09:10:34 -0500189
Dave Mankoff3c6aaab2020-01-10 17:50:34 -0500190 mSlotCast = resources.getString(com.android.internal.R.string.status_bar_cast);
191 mSlotHotspot = resources.getString(com.android.internal.R.string.status_bar_hotspot);
192 mSlotBluetooth = resources.getString(com.android.internal.R.string.status_bar_bluetooth);
193 mSlotTty = resources.getString(com.android.internal.R.string.status_bar_tty);
194 mSlotZen = resources.getString(com.android.internal.R.string.status_bar_zen);
195 mSlotVolume = resources.getString(com.android.internal.R.string.status_bar_volume);
196 mSlotAlarmClock = resources.getString(com.android.internal.R.string.status_bar_alarm_clock);
197 mSlotManagedProfile = resources.getString(
Jason Monk3e189872016-01-12 09:10:34 -0500198 com.android.internal.R.string.status_bar_managed_profile);
Dave Mankoff3c6aaab2020-01-10 17:50:34 -0500199 mSlotRotate = resources.getString(com.android.internal.R.string.status_bar_rotate);
200 mSlotHeadset = resources.getString(com.android.internal.R.string.status_bar_headset);
201 mSlotDataSaver = resources.getString(com.android.internal.R.string.status_bar_data_saver);
202 mSlotLocation = resources.getString(com.android.internal.R.string.status_bar_location);
203 mSlotSensorsOff = resources.getString(com.android.internal.R.string.status_bar_sensors_off);
204 mSlotScreenRecord = resources.getString(
Beth Thibodeau8bfbf1f2020-02-13 13:55:37 -0500205 com.android.internal.R.string.status_bar_screen_record);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800206
Dave Mankoff3c6aaab2020-01-10 17:50:34 -0500207 mDisplayId = displayId;
208 mSharedPreferences = sharedPreferences;
209 mDateFormatUtil = dateFormatUtil;
210 }
211
212 /** Initialize the object after construction. */
213 public void init() {
Daniel Sandlere3b7a2d2011-10-27 16:16:15 -0400214 // listen for broadcasts
215 IntentFilter filter = new IntentFilter();
Fabian Kozynskib6a20372020-04-01 09:36:43 -0400216
Jason Monk3e189872016-01-12 09:10:34 -0500217 filter.addAction(AudioManager.ACTION_HEADSET_PLUG);
Daniel Bright350f7f92020-01-22 14:24:11 -0800218 filter.addAction(Intent.ACTION_SIM_STATE_CHANGED);
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700219 filter.addAction(TelecomManager.ACTION_CURRENT_TTY_MODE_CHANGED);
Rubin Xue95057a2016-04-01 16:49:25 +0100220 filter.addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE);
221 filter.addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE);
Nicolas Prevot6c7b8742016-04-13 10:28:58 +0100222 filter.addAction(Intent.ACTION_MANAGED_PROFILE_REMOVED);
Dave Mankoff3c6aaab2020-01-10 17:50:34 -0500223 mBroadcastDispatcher.registerReceiverWithHandler(mIntentReceiver, filter, mHandler);
Fabian Kozynskib6a20372020-04-01 09:36:43 -0400224 Observer<Integer> observer = ringer -> mHandler.post(this::updateVolumeZen);
225
226 mRingerModeTracker.getRingerMode().observeForever(observer);
227 mRingerModeTracker.getRingerModeInternal().observeForever(observer);
Daniel Sandlere3b7a2d2011-10-27 16:16:15 -0400228
Kenny Guy3094d4a2015-04-01 19:14:10 +0100229 // listen for user / profile change.
230 try {
Dave Mankoff3c6aaab2020-01-10 17:50:34 -0500231 mIActivityManager.registerUserSwitchObserver(mUserSwitchListener, TAG);
Kenny Guy3094d4a2015-04-01 19:14:10 +0100232 } catch (RemoteException e) {
233 // Ignore
234 }
235
Wink Saville04e71b32009-04-02 11:00:54 -0700236 // TTY status
Hall Liu108ca202017-07-24 15:19:04 -0700237 updateTTY();
Wink Saville04e71b32009-04-02 11:00:54 -0700238
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800239 // bluetooth status
Jorim Jaggi2d75f9f2014-10-08 17:10:58 -0700240 updateBluetooth();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800241
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800242 // Alarm clock
Jason Monk3e189872016-01-12 09:10:34 -0500243 mIconController.setIcon(mSlotAlarmClock, R.drawable.stat_sys_alarm, null);
244 mIconController.setIconVisibility(mSlotAlarmClock, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800245
John Spurlocka37e9c82014-07-08 09:40:31 -0400246 // zen
Amin Shaikh833bb0f2019-03-28 14:03:48 -0400247 mIconController.setIcon(mSlotZen, R.drawable.stat_sys_dnd, null);
Jason Monk3e189872016-01-12 09:10:34 -0500248 mIconController.setIconVisibility(mSlotZen, false);
John Spurlocka37e9c82014-07-08 09:40:31 -0400249
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800250 // volume
Jason Monk3e189872016-01-12 09:10:34 -0500251 mIconController.setIcon(mSlotVolume, R.drawable.stat_sys_ringer_vibrate, null);
252 mIconController.setIconVisibility(mSlotVolume, false);
John Spurlocka37e9c82014-07-08 09:40:31 -0400253 updateVolumeZen();
John Spurlock96fe98d2014-08-27 09:36:02 -0400254
255 // cast
Jason Monk3e189872016-01-12 09:10:34 -0500256 mIconController.setIcon(mSlotCast, R.drawable.stat_sys_cast, null);
257 mIconController.setIconVisibility(mSlotCast, false);
Jason Monk952d5d82014-10-27 15:28:22 -0400258
259 // hotspot
Jason Monk3e189872016-01-12 09:10:34 -0500260 mIconController.setIcon(mSlotHotspot, R.drawable.stat_sys_hotspot,
Dave Mankoff3c6aaab2020-01-10 17:50:34 -0500261 mResources.getString(R.string.accessibility_status_bar_hotspot));
Jason Monk3e189872016-01-12 09:10:34 -0500262 mIconController.setIconVisibility(mSlotHotspot, mHotspot.isHotspotEnabled());
Kenny Guy3094d4a2015-04-01 19:14:10 +0100263
264 // managed profile
Jason Monk3e189872016-01-12 09:10:34 -0500265 mIconController.setIcon(mSlotManagedProfile, R.drawable.stat_sys_managed_profile_status,
Dave Mankoff3c6aaab2020-01-10 17:50:34 -0500266 mResources.getString(R.string.accessibility_managed_profile));
Jason Monk3e189872016-01-12 09:10:34 -0500267 mIconController.setIconVisibility(mSlotManagedProfile, mManagedProfileIconVisible);
Jason Monkf23aa992016-01-22 16:45:21 -0500268
269 // data saver
270 mIconController.setIcon(mSlotDataSaver, R.drawable.stat_sys_data_saver,
Dave Mankoff3c6aaab2020-01-10 17:50:34 -0500271 mResources.getString(R.string.accessibility_data_saver_on));
Jason Monkf23aa992016-01-22 16:45:21 -0500272 mIconController.setIconVisibility(mSlotDataSaver, false);
Jason Monkaa573e92017-01-27 17:00:29 -0500273
Fabian Kozynskied5dfd92018-12-20 15:00:48 -0500274 mIconController.setIcon(mSlotLocation, LOCATION_STATUS_ICON_ID,
Dave Mankoff3c6aaab2020-01-10 17:50:34 -0500275 mResources.getString(R.string.accessibility_location_active));
Fabian Kozynskied5dfd92018-12-20 15:00:48 -0500276 mIconController.setIconVisibility(mSlotLocation, false);
Evan Lairdcf1a1032018-11-14 13:46:08 -0500277
Michael Groovera51ea812019-03-19 18:56:36 -0700278 // sensors off
Michael Groover1ddabcc2019-04-19 18:35:24 -0700279 mIconController.setIcon(mSlotSensorsOff, R.drawable.stat_sys_sensors_off,
Dave Mankoff3c6aaab2020-01-10 17:50:34 -0500280 mResources.getString(R.string.accessibility_sensors_off_active));
Michael Groovera51ea812019-03-19 18:56:36 -0700281 mIconController.setIconVisibility(mSlotSensorsOff,
282 mSensorPrivacyController.isSensorPrivacyEnabled());
283
Beth Thibodeau8bfbf1f2020-02-13 13:55:37 -0500284 // screen record
285 mIconController.setIcon(mSlotScreenRecord, R.drawable.stat_sys_screen_record, null);
286 mIconController.setIconVisibility(mSlotScreenRecord, false);
287
Jason Monkaa573e92017-01-27 17:00:29 -0500288 mRotationLockController.addCallback(this);
289 mBluetooth.addCallback(this);
290 mProvisionedController.addCallback(this);
291 mZenController.addCallback(this);
292 mCast.addCallback(mCastCallback);
293 mHotspot.addCallback(mHotspotCallback);
Evan Lairdbee3eb82018-05-16 15:58:49 -0400294 mNextAlarmController.addCallback(mNextAlarmCallback);
Jason Monk88529052016-11-04 13:29:58 -0400295 mDataSaver.addCallback(this);
Lucas Dupinc8f16e82019-09-17 18:24:50 -0400296 mKeyguardStateController.addCallback(this);
Michael Groovera51ea812019-03-19 18:56:36 -0700297 mSensorPrivacyController.addCallback(mSensorPrivacyListener);
Fabian Kozynski16b26992019-05-06 10:18:41 -0400298 mLocationController.addCallback(this);
Beth Thibodeau8bfbf1f2020-02-13 13:55:37 -0500299 mRecordingController.addCallback(this);
Jason Monkaa573e92017-01-27 17:00:29 -0500300
Dave Mankoff3c6aaab2020-01-10 17:50:34 -0500301 mCommandQueue.addCallback(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800302 }
303
Jason Monkaa573e92017-01-27 17:00:29 -0500304 @Override
305 public void onZenChanged(int zen) {
John Spurlocka37e9c82014-07-08 09:40:31 -0400306 updateVolumeZen();
John Spurlockba2c6a02014-05-19 09:44:06 -0400307 }
308
Jason Monk359bb742017-04-13 10:40:40 -0400309 @Override
Beverlyb9826dd2018-04-12 15:02:45 -0400310 public void onConfigChanged(ZenModeConfig config) {
311 updateVolumeZen();
312 }
313
Adrian Roosc42a1e12014-07-07 23:35:53 +0200314 private void updateAlarm() {
John Spurlock604a5ee2015-06-01 12:27:22 -0400315 final AlarmClockInfo alarm = mAlarmManager.getNextAlarmClock(UserHandle.USER_CURRENT);
316 final boolean hasAlarm = alarm != null && alarm.getTriggerTime() > 0;
Jason Monk20c0eb42017-03-02 17:35:49 -0500317 int zen = mZenController.getZen();
318 final boolean zenNone = zen == Global.ZEN_MODE_NO_INTERRUPTIONS;
Jason Monk3e189872016-01-12 09:10:34 -0500319 mIconController.setIcon(mSlotAlarmClock, zenNone ? R.drawable.stat_sys_alarm_dim
Evan Lairdbee3eb82018-05-16 15:58:49 -0400320 : R.drawable.stat_sys_alarm, buildAlarmContentDescription());
Jason Monk3e189872016-01-12 09:10:34 -0500321 mIconController.setIconVisibility(mSlotAlarmClock, mCurrentUserSetup && hasAlarm);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800322 }
323
Evan Lairdbee3eb82018-05-16 15:58:49 -0400324 private String buildAlarmContentDescription() {
325 if (mNextAlarm == null) {
Dave Mankoff3c6aaab2020-01-10 17:50:34 -0500326 return mResources.getString(R.string.status_bar_alarm);
Evan Lairdbee3eb82018-05-16 15:58:49 -0400327 }
Evan Lairdbee3eb82018-05-16 15:58:49 -0400328
Dave Mankoff3c6aaab2020-01-10 17:50:34 -0500329 String skeleton = mDateFormatUtil.is24HourFormat() ? "EHm" : "Ehma";
Evan Lairdbee3eb82018-05-16 15:58:49 -0400330 String pattern = DateFormat.getBestDateTimePattern(Locale.getDefault(), skeleton);
Dave Mankoff3c6aaab2020-01-10 17:50:34 -0500331 String dateString = DateFormat.format(pattern, mNextAlarm.getTriggerTime()).toString();
Evan Lairdbee3eb82018-05-16 15:58:49 -0400332
Dave Mankoff3c6aaab2020-01-10 17:50:34 -0500333 return mResources.getString(R.string.accessibility_quick_settings_alarm, dateString);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800334 }
335
John Spurlockbcc10872014-11-28 15:29:21 -0500336 private final void updateVolumeZen() {
John Spurlocka37e9c82014-07-08 09:40:31 -0400337 boolean zenVisible = false;
338 int zenIconId = 0;
339 String zenDescription = null;
340
341 boolean volumeVisible = false;
342 int volumeIconId = 0;
343 String volumeDescription = null;
Jason Monk20c0eb42017-03-02 17:35:49 -0500344 int zen = mZenController.getZen();
John Spurlocka37e9c82014-07-08 09:40:31 -0400345
Dave Mankoff3c6aaab2020-01-10 17:50:34 -0500346 if (DndTile.isVisible(mSharedPreferences) || DndTile.isCombinedIcon(mSharedPreferences)) {
Jason Monk20c0eb42017-03-02 17:35:49 -0500347 zenVisible = zen != Global.ZEN_MODE_OFF;
Evan Lairda9adbd52018-05-16 11:32:08 -0400348 zenIconId = R.drawable.stat_sys_dnd;
Dave Mankoff3c6aaab2020-01-10 17:50:34 -0500349 zenDescription = mResources.getString(R.string.quick_settings_dnd_label);
Jason Monk20c0eb42017-03-02 17:35:49 -0500350 } else if (zen == Global.ZEN_MODE_NO_INTERRUPTIONS) {
John Spurlocka37e9c82014-07-08 09:40:31 -0400351 zenVisible = true;
Amin Shaikh833bb0f2019-03-28 14:03:48 -0400352 zenIconId = R.drawable.stat_sys_dnd;
Dave Mankoff3c6aaab2020-01-10 17:50:34 -0500353 zenDescription = mResources.getString(R.string.interruption_level_none);
Jason Monk20c0eb42017-03-02 17:35:49 -0500354 } else if (zen == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) {
John Spurlocka37e9c82014-07-08 09:40:31 -0400355 zenVisible = true;
Amin Shaikh833bb0f2019-03-28 14:03:48 -0400356 zenIconId = R.drawable.stat_sys_dnd;
Dave Mankoff3c6aaab2020-01-10 17:50:34 -0500357 zenDescription = mResources.getString(R.string.interruption_level_priority);
Svetoslav Ganov6179ea32011-06-28 01:12:41 -0700358 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800359
Beverlyff2df9b2018-10-10 16:54:10 -0400360 if (!ZenModeConfig.isZenOverridingRinger(zen, mZenController.getConsolidatedPolicy())) {
Fabian Kozynskib6a20372020-04-01 09:36:43 -0400361 final Integer ringerModeInternal =
362 mRingerModeTracker.getRingerModeInternal().getValue();
363 if (ringerModeInternal != null) {
364 if (ringerModeInternal == AudioManager.RINGER_MODE_VIBRATE) {
365 volumeVisible = true;
366 volumeIconId = R.drawable.stat_sys_ringer_vibrate;
367 volumeDescription = mResources.getString(R.string.accessibility_ringer_vibrate);
368 } else if (ringerModeInternal == AudioManager.RINGER_MODE_SILENT) {
369 volumeVisible = true;
370 volumeIconId = R.drawable.stat_sys_ringer_silent;
371 volumeDescription = mResources.getString(R.string.accessibility_ringer_silent);
372 }
Beverlyb9826dd2018-04-12 15:02:45 -0400373 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800374 }
John Spurlocka37e9c82014-07-08 09:40:31 -0400375
376 if (zenVisible) {
Jason Monk3e189872016-01-12 09:10:34 -0500377 mIconController.setIcon(mSlotZen, zenIconId, zenDescription);
John Spurlocka37e9c82014-07-08 09:40:31 -0400378 }
379 if (zenVisible != mZenVisible) {
Jason Monk3e189872016-01-12 09:10:34 -0500380 mIconController.setIconVisibility(mSlotZen, zenVisible);
John Spurlocka37e9c82014-07-08 09:40:31 -0400381 mZenVisible = zenVisible;
382 }
383
384 if (volumeVisible) {
Jason Monk3e189872016-01-12 09:10:34 -0500385 mIconController.setIcon(mSlotVolume, volumeIconId, volumeDescription);
John Spurlocka37e9c82014-07-08 09:40:31 -0400386 }
387 if (volumeVisible != mVolumeVisible) {
Jason Monk3e189872016-01-12 09:10:34 -0500388 mIconController.setIconVisibility(mSlotVolume, volumeVisible);
John Spurlocka37e9c82014-07-08 09:40:31 -0400389 mVolumeVisible = volumeVisible;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800390 }
John Spurlock15782262015-05-29 15:35:53 -0400391 updateAlarm();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800392 }
393
Jason Monk70364362015-08-06 16:32:18 -0400394 @Override
395 public void onBluetoothDevicesChanged() {
396 updateBluetooth();
397 }
398
399 @Override
400 public void onBluetoothStateChange(boolean enabled) {
401 updateBluetooth();
402 }
403
Jorim Jaggi2d75f9f2014-10-08 17:10:58 -0700404 private final void updateBluetooth() {
Amin Shaikhad29e932019-03-08 11:26:12 -0500405 int iconId = R.drawable.stat_sys_data_bluetooth_connected;
Jorim Jaggi2d75f9f2014-10-08 17:10:58 -0700406 String contentDescription =
Dave Mankoff3c6aaab2020-01-10 17:50:34 -0500407 mResources.getString(R.string.accessibility_quick_settings_bluetooth_on);
Evan Laird3cdf47e2018-01-29 16:01:41 -0500408 boolean bluetoothVisible = false;
Jason Monk70364362015-08-06 16:32:18 -0400409 if (mBluetooth != null) {
Ugo Yu40f08802019-11-19 09:56:40 +0800410 if (mBluetooth.isBluetoothConnected()
411 && (mBluetooth.isBluetoothAudioActive()
412 || !mBluetooth.isBluetoothAudioProfileOnly())) {
Dave Mankoff3c6aaab2020-01-10 17:50:34 -0500413 contentDescription = mResources.getString(
Ugo Yu40f08802019-11-19 09:56:40 +0800414 R.string.accessibility_bluetooth_connected);
Evan Laird3cdf47e2018-01-29 16:01:41 -0500415 bluetoothVisible = mBluetooth.isBluetoothEnabled();
Jaikumar Ganesh084c6652009-12-07 10:58:18 -0800416 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800417 }
Wink Savillee9b06d72009-05-18 21:47:50 -0700418
Jason Monk3e189872016-01-12 09:10:34 -0500419 mIconController.setIcon(mSlotBluetooth, iconId, contentDescription);
Evan Laird3cdf47e2018-01-29 16:01:41 -0500420 mIconController.setIconVisibility(mSlotBluetooth, bluetoothVisible);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800421 }
422
Hall Liu108ca202017-07-24 15:19:04 -0700423 private final void updateTTY() {
Dave Mankoff3c6aaab2020-01-10 17:50:34 -0500424 if (mTelecomManager == null) {
Hall Liu108ca202017-07-24 15:19:04 -0700425 updateTTY(TelecomManager.TTY_MODE_OFF);
426 } else {
Dave Mankoff3c6aaab2020-01-10 17:50:34 -0500427 updateTTY(mTelecomManager.getCurrentTtyMode());
Hall Liu108ca202017-07-24 15:19:04 -0700428 }
429 }
430
431 private final void updateTTY(int currentTtyMode) {
Tyler Gunnef9f6f92014-09-12 22:16:17 -0700432 boolean enabled = currentTtyMode != TelecomManager.TTY_MODE_OFF;
Wink Saville04e71b32009-04-02 11:00:54 -0700433
John Spurlocka37e9c82014-07-08 09:40:31 -0400434 if (DEBUG) Log.v(TAG, "updateTTY: enabled: " + enabled);
Wink Saville04e71b32009-04-02 11:00:54 -0700435
436 if (enabled) {
437 // TTY is on
John Spurlocka37e9c82014-07-08 09:40:31 -0400438 if (DEBUG) Log.v(TAG, "updateTTY: set TTY on");
Jason Monk3e189872016-01-12 09:10:34 -0500439 mIconController.setIcon(mSlotTty, R.drawable.stat_sys_tty_mode,
Dave Mankoff3c6aaab2020-01-10 17:50:34 -0500440 mResources.getString(R.string.accessibility_tty_enabled));
Jason Monk3e189872016-01-12 09:10:34 -0500441 mIconController.setIconVisibility(mSlotTty, true);
Wink Saville04e71b32009-04-02 11:00:54 -0700442 } else {
443 // TTY is off
John Spurlocka37e9c82014-07-08 09:40:31 -0400444 if (DEBUG) Log.v(TAG, "updateTTY: set TTY off");
Jason Monk3e189872016-01-12 09:10:34 -0500445 mIconController.setIconVisibility(mSlotTty, false);
Wink Saville04e71b32009-04-02 11:00:54 -0700446 }
447 }
John Spurlock96fe98d2014-08-27 09:36:02 -0400448
449 private void updateCast() {
450 boolean isCasting = false;
451 for (CastDevice device : mCast.getCastDevices()) {
452 if (device.state == CastDevice.STATE_CONNECTING
453 || device.state == CastDevice.STATE_CONNECTED) {
454 isCasting = true;
455 break;
456 }
457 }
458 if (DEBUG) Log.v(TAG, "updateCast: isCasting: " + isCasting);
Dan Sandler8fd25bf2015-10-20 16:01:27 -0700459 mHandler.removeCallbacks(mRemoveCastIconRunnable);
Beth Thibodeau8bfbf1f2020-02-13 13:55:37 -0500460 if (isCasting && !mRecordingController.isRecording()) { // screen record has its own icon
Jason Monk3e189872016-01-12 09:10:34 -0500461 mIconController.setIcon(mSlotCast, R.drawable.stat_sys_cast,
Dave Mankoff3c6aaab2020-01-10 17:50:34 -0500462 mResources.getString(R.string.accessibility_casting));
Jason Monk3e189872016-01-12 09:10:34 -0500463 mIconController.setIconVisibility(mSlotCast, true);
Dan Sandler8fd25bf2015-10-20 16:01:27 -0700464 } else {
465 // don't turn off the screen-record icon for a few seconds, just to make sure the user
466 // has seen it
467 if (DEBUG) Log.v(TAG, "updateCast: hiding icon in 3 sec...");
468 mHandler.postDelayed(mRemoveCastIconRunnable, 3000);
John Spurlock96fe98d2014-08-27 09:36:02 -0400469 }
John Spurlock96fe98d2014-08-27 09:36:02 -0400470 }
471
Kenny Guy3094d4a2015-04-01 19:14:10 +0100472 private void updateManagedProfile() {
Jorim Jaggifabc7432017-05-15 02:40:05 +0200473 // getLastResumedActivityUserId needds to acquire the AM lock, which may be contended in
474 // some cases. Since it doesn't really matter here whether it's updated in this frame
475 // or in the next one, we call this method from our UI offload thread.
Dave Mankoffc7cf9fc2019-12-19 15:43:20 -0500476 mUiBgExecutor.execute(() -> {
Jorim Jaggifabc7432017-05-15 02:40:05 +0200477 final int userId;
478 try {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700479 userId = ActivityTaskManager.getService().getLastResumedActivityUserId();
Jorim Jaggifabc7432017-05-15 02:40:05 +0200480 boolean isManagedProfile = mUserManager.isManagedProfile(userId);
481 mHandler.post(() -> {
482 final boolean showIcon;
Lucas Dupinc8f16e82019-09-17 18:24:50 -0400483 if (isManagedProfile && (!mKeyguardStateController.isShowing()
484 || mKeyguardStateController.isOccluded())) {
Jorim Jaggifabc7432017-05-15 02:40:05 +0200485 showIcon = true;
486 mIconController.setIcon(mSlotManagedProfile,
487 R.drawable.stat_sys_managed_profile_status,
Dave Mankoff3c6aaab2020-01-10 17:50:34 -0500488 mResources.getString(R.string.accessibility_managed_profile));
Jorim Jaggifabc7432017-05-15 02:40:05 +0200489 } else {
490 showIcon = false;
491 }
492 if (mManagedProfileIconVisible != showIcon) {
493 mIconController.setIconVisibility(mSlotManagedProfile, showIcon);
494 mManagedProfileIconVisible = showIcon;
495 }
496 });
497 } catch (RemoteException e) {
498 Log.w(TAG, "updateManagedProfile: ", e);
Tony Makec319ab2017-03-28 18:50:01 +0100499 }
Jorim Jaggifabc7432017-05-15 02:40:05 +0200500 });
Kenny Guy3094d4a2015-04-01 19:14:10 +0100501 }
502
Fyodor Kupolov6005b3f2015-11-23 17:41:50 -0800503 private final SynchronousUserSwitchObserver mUserSwitchListener =
504 new SynchronousUserSwitchObserver() {
Kenny Guy3094d4a2015-04-01 19:14:10 +0100505 @Override
Fyodor Kupolov6005b3f2015-11-23 17:41:50 -0800506 public void onUserSwitching(int newUserId) throws RemoteException {
Tony Makec319ab2017-03-28 18:50:01 +0100507 mHandler.post(() -> mUserInfoController.reloadUserInfo());
Kenny Guy3094d4a2015-04-01 19:14:10 +0100508 }
509
510 @Override
511 public void onUserSwitchComplete(int newUserId) throws RemoteException {
Tony Makec319ab2017-03-28 18:50:01 +0100512 mHandler.post(() -> {
513 updateAlarm();
Tony Makec319ab2017-03-28 18:50:01 +0100514 updateManagedProfile();
Toni Barzice97f9232016-04-27 18:10:58 -0700515 });
Kenny Guy3094d4a2015-04-01 19:14:10 +0100516 }
517 };
518
Jason Monk952d5d82014-10-27 15:28:22 -0400519 private final HotspotController.Callback mHotspotCallback = new HotspotController.Callback() {
520 @Override
Rohan Shahe4071122018-01-22 15:16:09 -0800521 public void onHotspotChanged(boolean enabled, int numDevices) {
Jason Monk3e189872016-01-12 09:10:34 -0500522 mIconController.setIconVisibility(mSlotHotspot, enabled);
Jason Monk952d5d82014-10-27 15:28:22 -0400523 }
524 };
525
John Spurlock96fe98d2014-08-27 09:36:02 -0400526 private final CastController.Callback mCastCallback = new CastController.Callback() {
527 @Override
528 public void onCastDevicesChanged() {
529 updateCast();
530 }
531 };
Kenny Guy3094d4a2015-04-01 19:14:10 +0100532
Juan Flores2ff37202015-04-30 13:44:23 +0200533 private final NextAlarmController.NextAlarmChangeCallback mNextAlarmCallback =
534 new NextAlarmController.NextAlarmChangeCallback() {
Jason Monk324b8862017-02-16 17:19:12 -0500535 @Override
536 public void onNextAlarmChanged(AlarmManager.AlarmClockInfo nextAlarm) {
Evan Lairdbee3eb82018-05-16 15:58:49 -0400537 mNextAlarm = nextAlarm;
Jason Monk324b8862017-02-16 17:19:12 -0500538 updateAlarm();
539 }
540 };
Juan Flores2ff37202015-04-30 13:44:23 +0200541
Michael Groovera51ea812019-03-19 18:56:36 -0700542 private final SensorPrivacyController.OnSensorPrivacyChangedListener mSensorPrivacyListener =
543 new SensorPrivacyController.OnSensorPrivacyChangedListener() {
544 @Override
545 public void onSensorPrivacyChanged(boolean enabled) {
546 mHandler.post(() -> {
547 mIconController.setIconVisibility(mSlotSensorsOff, enabled);
548 });
549 }
550 };
551
Jason Monkaa573e92017-01-27 17:00:29 -0500552 @Override
Charles Chenf3d295c2018-11-30 18:15:21 +0800553 public void appTransitionStarting(int displayId, long startTime, long duration,
554 boolean forced) {
Dave Mankoff3c6aaab2020-01-10 17:50:34 -0500555 if (mDisplayId == displayId) {
Charles Chenf3d295c2018-11-30 18:15:21 +0800556 updateManagedProfile();
Charles Chenf3d295c2018-11-30 18:15:21 +0800557 }
Kenny Guy3094d4a2015-04-01 19:14:10 +0100558 }
559
Jason Monkaa573e92017-01-27 17:00:29 -0500560 @Override
561 public void onKeyguardShowingChanged() {
Kenny Guy3094d4a2015-04-01 19:14:10 +0100562 updateManagedProfile();
563 }
John Spurlock604a5ee2015-06-01 12:27:22 -0400564
Jason Monkaa573e92017-01-27 17:00:29 -0500565 @Override
566 public void onUserSetupChanged() {
567 boolean userSetup = mProvisionedController.isUserSetup(
568 mProvisionedController.getCurrentUser());
John Spurlock604a5ee2015-06-01 12:27:22 -0400569 if (mCurrentUserSetup == userSetup) return;
570 mCurrentUserSetup = userSetup;
571 updateAlarm();
572 }
Jason Monk3e189872016-01-12 09:10:34 -0500573
574 @Override
575 public void onRotationLockStateChanged(boolean rotationLocked, boolean affordanceVisible) {
576 boolean portrait = RotationLockTile.isCurrentOrientationLockPortrait(
Dave Mankoff3c6aaab2020-01-10 17:50:34 -0500577 mRotationLockController, mResources);
Jason Monk3e189872016-01-12 09:10:34 -0500578 if (rotationLocked) {
579 if (portrait) {
580 mIconController.setIcon(mSlotRotate, R.drawable.stat_sys_rotate_portrait,
Dave Mankoff3c6aaab2020-01-10 17:50:34 -0500581 mResources.getString(R.string.accessibility_rotation_lock_on_portrait));
Jason Monk3e189872016-01-12 09:10:34 -0500582 } else {
583 mIconController.setIcon(mSlotRotate, R.drawable.stat_sys_rotate_landscape,
Dave Mankoff3c6aaab2020-01-10 17:50:34 -0500584 mResources.getString(R.string.accessibility_rotation_lock_on_landscape));
Jason Monk3e189872016-01-12 09:10:34 -0500585 }
Jason Monk8816dff2016-02-09 21:50:36 -0500586 mIconController.setIconVisibility(mSlotRotate, true);
Jason Monk3e189872016-01-12 09:10:34 -0500587 } else {
Jason Monk8816dff2016-02-09 21:50:36 -0500588 mIconController.setIconVisibility(mSlotRotate, false);
Jason Monk3e189872016-01-12 09:10:34 -0500589 }
590 }
591
592 private void updateHeadsetPlug(Intent intent) {
593 boolean connected = intent.getIntExtra("state", 0) != 0;
594 boolean hasMic = intent.getIntExtra("microphone", 0) != 0;
595 if (connected) {
Dave Mankoff3c6aaab2020-01-10 17:50:34 -0500596 String contentDescription = mResources.getString(hasMic
Jason Monk3e189872016-01-12 09:10:34 -0500597 ? R.string.accessibility_status_bar_headset
598 : R.string.accessibility_status_bar_headphones);
Amin Shaikhad29e932019-03-08 11:26:12 -0500599 mIconController.setIcon(mSlotHeadset, hasMic ? R.drawable.stat_sys_headset_mic
600 : R.drawable.stat_sys_headset, contentDescription);
Jason Monk3e189872016-01-12 09:10:34 -0500601 mIconController.setIconVisibility(mSlotHeadset, true);
602 } else {
603 mIconController.setIconVisibility(mSlotHeadset, false);
604 }
605 }
606
Jason Monkf23aa992016-01-22 16:45:21 -0500607 @Override
608 public void onDataSaverChanged(boolean isDataSaving) {
609 mIconController.setIconVisibility(mSlotDataSaver, isDataSaving);
610 }
611
Fabian Kozynski16b26992019-05-06 10:18:41 -0400612 @Override
613 public void onLocationActiveChanged(boolean active) {
Fabian Kozynski228e3102019-11-25 11:04:34 -0500614 updateLocation();
Fabian Kozynski16b26992019-05-06 10:18:41 -0400615 }
616
617 // Updates the status view based on the current state of location requests.
618 private void updateLocation() {
619 if (mLocationController.isLocationActive()) {
620 mIconController.setIconVisibility(mSlotLocation, true);
621 } else {
622 mIconController.setIconVisibility(mSlotLocation, false);
623 }
624 }
625
Jason Monk3e189872016-01-12 09:10:34 -0500626 private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
627 @Override
628 public void onReceive(Context context, Intent intent) {
629 String action = intent.getAction();
Lucas Dupin5e0f0d22018-02-26 13:32:16 -0800630 switch (action) {
Daniel Bright350f7f92020-01-22 14:24:11 -0800631 case Intent.ACTION_SIM_STATE_CHANGED:
Lucas Dupin5e0f0d22018-02-26 13:32:16 -0800632 // Avoid rebroadcast because SysUI is direct boot aware.
Meng Wang0e8d91a2020-01-17 14:58:01 -0800633 if (intent.getBooleanExtra(Intent.EXTRA_REBROADCAST_ON_UNLOCK, false)) {
Lucas Dupin5e0f0d22018-02-26 13:32:16 -0800634 break;
635 }
Lucas Dupin5e0f0d22018-02-26 13:32:16 -0800636 break;
637 case TelecomManager.ACTION_CURRENT_TTY_MODE_CHANGED:
638 updateTTY(intent.getIntExtra(TelecomManager.EXTRA_CURRENT_TTY_MODE,
639 TelecomManager.TTY_MODE_OFF));
640 break;
641 case Intent.ACTION_MANAGED_PROFILE_AVAILABLE:
642 case Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE:
643 case Intent.ACTION_MANAGED_PROFILE_REMOVED:
644 updateManagedProfile();
645 break;
646 case AudioManager.ACTION_HEADSET_PLUG:
647 updateHeadsetPlug(intent);
648 break;
Jason Monk3e189872016-01-12 09:10:34 -0500649 }
650 }
651 };
652
653 private Runnable mRemoveCastIconRunnable = new Runnable() {
654 @Override
655 public void run() {
656 if (DEBUG) Log.v(TAG, "updateCast: hiding icon NOW");
657 mIconController.setIconVisibility(mSlotCast, false);
658 }
659 };
Beth Thibodeau8bfbf1f2020-02-13 13:55:37 -0500660
661 // Screen Recording
662 @Override
663 public void onCountdown(long millisUntilFinished) {
664 if (DEBUG) Log.d(TAG, "screenrecord: countdown " + millisUntilFinished);
665 int countdown = (int) Math.floorDiv(millisUntilFinished + 500, 1000);
666 int resourceId = R.drawable.stat_sys_screen_record;
Beth Thibodeau47811b42020-04-22 01:22:39 -0400667 String description = Integer.toString(countdown);
Beth Thibodeau8bfbf1f2020-02-13 13:55:37 -0500668 switch (countdown) {
669 case 1:
670 resourceId = R.drawable.stat_sys_screen_record_1;
671 break;
672 case 2:
673 resourceId = R.drawable.stat_sys_screen_record_2;
674 break;
675 case 3:
676 resourceId = R.drawable.stat_sys_screen_record_3;
677 break;
678 }
Beth Thibodeau47811b42020-04-22 01:22:39 -0400679 mIconController.setIcon(mSlotScreenRecord, resourceId, description);
Beth Thibodeau8bfbf1f2020-02-13 13:55:37 -0500680 mIconController.setIconVisibility(mSlotScreenRecord, true);
Beth Thibodeaua5af2402020-06-15 23:16:09 -0400681 // Set as assertive so talkback will announce the countdown
682 mIconController.setIconAccessibilityLiveRegion(mSlotScreenRecord,
683 View.ACCESSIBILITY_LIVE_REGION_ASSERTIVE);
Beth Thibodeau8bfbf1f2020-02-13 13:55:37 -0500684 }
685
686 @Override
Beth Thibodeau58772782020-02-18 20:55:38 -0500687 public void onCountdownEnd() {
688 if (DEBUG) Log.d(TAG, "screenrecord: hiding icon during countdown");
689 mHandler.post(() -> mIconController.setIconVisibility(mSlotScreenRecord, false));
Beth Thibodeaua5af2402020-06-15 23:16:09 -0400690 // Reset talkback priority
691 mIconController.setIconAccessibilityLiveRegion(mSlotScreenRecord,
692 View.ACCESSIBILITY_LIVE_REGION_NONE);
Beth Thibodeau58772782020-02-18 20:55:38 -0500693 }
694
695 @Override
Beth Thibodeau8bfbf1f2020-02-13 13:55:37 -0500696 public void onRecordingStart() {
697 if (DEBUG) Log.d(TAG, "screenrecord: showing icon");
698 mIconController.setIcon(mSlotScreenRecord,
Beth Thibodeau47811b42020-04-22 01:22:39 -0400699 R.drawable.stat_sys_screen_record,
700 mResources.getString(R.string.screenrecord_ongoing_screen_only));
Beth Thibodeau8bfbf1f2020-02-13 13:55:37 -0500701 mIconController.setIconVisibility(mSlotScreenRecord, true);
702 }
703
704 @Override
705 public void onRecordingEnd() {
Beth Thibodeau58772782020-02-18 20:55:38 -0500706 // Ensure this is on the main thread
Beth Thibodeau8bfbf1f2020-02-13 13:55:37 -0500707 if (DEBUG) Log.d(TAG, "screenrecord: hiding icon");
708 mHandler.post(() -> mIconController.setIconVisibility(mSlotScreenRecord, false));
709 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800710}