PageRenderTime 184ms CodeModel.GetById 33ms RepoModel.GetById 0ms app.codeStats 0ms

/services/java/com/android/server/UiModeManagerService.java

https://bitbucket.org/ProuDroid/frameworks_base
Java | 683 lines | 544 code | 84 blank | 55 comment | 124 complexity | 468ee2122cc9aa2e5775ada6890ea14b MD5 | raw file
  1. /*
  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. package com.android.server;
  17. import android.app.Activity;
  18. import android.app.ActivityManager;
  19. import android.app.ActivityManagerNative;
  20. import android.app.IUiModeManager;
  21. import android.app.Notification;
  22. import android.app.NotificationManager;
  23. import android.app.PendingIntent;
  24. import android.app.StatusBarManager;
  25. import android.app.UiModeManager;
  26. import android.content.BroadcastReceiver;
  27. import android.content.ContentResolver;
  28. import android.content.Context;
  29. import android.content.Intent;
  30. import android.content.IntentFilter;
  31. import android.content.pm.PackageManager;
  32. import android.content.res.Configuration;
  33. import android.database.ContentObserver;
  34. import android.os.BatteryManager;
  35. import android.os.Binder;
  36. import android.os.Handler;
  37. import android.os.PowerManager;
  38. import android.os.RemoteException;
  39. import android.os.ServiceManager;
  40. import android.os.UserHandle;
  41. import android.provider.Settings;
  42. import android.service.dreams.Sandman;
  43. import android.util.Slog;
  44. import java.io.FileDescriptor;
  45. import java.io.PrintWriter;
  46. import com.android.internal.R;
  47. import com.android.internal.app.DisableCarModeActivity;
  48. import com.android.server.TwilightService.TwilightState;
  49. import com.android.internal.app.ThemeUtils;
  50. final class UiModeManagerService extends IUiModeManager.Stub {
  51. private static final String TAG = UiModeManager.class.getSimpleName();
  52. private static final boolean LOG = false;
  53. // Enable launching of applications when entering the dock.
  54. private static final boolean ENABLE_LAUNCH_CAR_DOCK_APP = true;
  55. private static final boolean ENABLE_LAUNCH_DESK_DOCK_APP = true;
  56. private final Context mContext;
  57. private final TwilightService mTwilightService;
  58. private final Handler mHandler = new Handler();
  59. private Context mUiContext;
  60. final Object mLock = new Object();
  61. private int mDockState = Intent.EXTRA_DOCK_STATE_UNDOCKED;
  62. private int mLastBroadcastState = Intent.EXTRA_DOCK_STATE_UNDOCKED;
  63. private int mNightMode = UiModeManager.MODE_NIGHT_NO;
  64. private boolean mCarModeEnabled = false;
  65. private boolean mCharging = false;
  66. private int mDefaultUiModeType;
  67. private boolean mCarModeKeepsScreenOn;
  68. private boolean mDeskModeKeepsScreenOn;
  69. private boolean mTelevision;
  70. private boolean mComputedNightMode;
  71. private int mCurUiMode = 0;
  72. private int mSetUiMode = 0;
  73. private boolean mInitialVarSet;
  74. private boolean mHoldingConfiguration = false;
  75. private Configuration mConfiguration = new Configuration();
  76. private boolean mSystemReady;
  77. private NotificationManager mNotificationManager;
  78. private StatusBarManager mStatusBarManager;
  79. private PowerManager mPowerManager;
  80. private PowerManager.WakeLock mWakeLock;
  81. static Intent buildHomeIntent(String category) {
  82. Intent intent = new Intent(Intent.ACTION_MAIN);
  83. intent.addCategory(category);
  84. intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
  85. | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
  86. return intent;
  87. }
  88. // The broadcast receiver which receives the result of the ordered broadcast sent when
  89. // the dock state changes. The original ordered broadcast is sent with an initial result
  90. // code of RESULT_OK. If any of the registered broadcast receivers changes this value, e.g.,
  91. // to RESULT_CANCELED, then the intent to start a dock app will not be sent.
  92. private final BroadcastReceiver mResultReceiver = new BroadcastReceiver() {
  93. @Override
  94. public void onReceive(Context context, Intent intent) {
  95. if (getResultCode() != Activity.RESULT_OK) {
  96. if (LOG) {
  97. Slog.v(TAG, "Handling broadcast result for action " + intent.getAction()
  98. + ": canceled: " + getResultCode());
  99. }
  100. return;
  101. }
  102. final int enableFlags = intent.getIntExtra("enableFlags", 0);
  103. final int disableFlags = intent.getIntExtra("disableFlags", 0);
  104. synchronized (mLock) {
  105. updateAfterBroadcastLocked(intent.getAction(), enableFlags, disableFlags);
  106. }
  107. }
  108. };
  109. private final BroadcastReceiver mDockModeReceiver = new BroadcastReceiver() {
  110. @Override
  111. public void onReceive(Context context, Intent intent) {
  112. int state = intent.getIntExtra(Intent.EXTRA_DOCK_STATE,
  113. Intent.EXTRA_DOCK_STATE_UNDOCKED);
  114. updateDockState(state);
  115. }
  116. };
  117. private final BroadcastReceiver mBatteryReceiver = new BroadcastReceiver() {
  118. @Override
  119. public void onReceive(Context context, Intent intent) {
  120. mCharging = (intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0) != 0);
  121. synchronized (mLock) {
  122. if (mSystemReady) {
  123. updateLocked(0, 0);
  124. }
  125. }
  126. }
  127. };
  128. private final BroadcastReceiver mThemeChangeReceiver = new BroadcastReceiver() {
  129. @Override
  130. public void onReceive(Context context, Intent intent) {
  131. mUiContext = null;
  132. }
  133. };
  134. private final TwilightService.TwilightListener mTwilightListener =
  135. new TwilightService.TwilightListener() {
  136. @Override
  137. public void onTwilightStateChanged() {
  138. updateTwilight();
  139. }
  140. };
  141. private final class SettingsObserver extends ContentObserver {
  142. SettingsObserver(Handler handler) {
  143. super(handler);
  144. }
  145. void observe() {
  146. ContentResolver resolver = mContext.getContentResolver();
  147. resolver.registerContentObserver(Settings.Secure.getUriFor(
  148. Settings.Secure.UI_INVERTED_MODE),
  149. false, this);
  150. }
  151. @Override
  152. public void onChange(boolean selfChange) {
  153. updateUiMode();
  154. mUiContext = null;
  155. updateLocked(0, 0);
  156. forceUiModeChangeForNonObservingMethods();
  157. }
  158. }
  159. public UiModeManagerService(Context context, TwilightService twilight) {
  160. mInitialVarSet = true;
  161. mContext = context;
  162. mTwilightService = twilight;
  163. ServiceManager.addService(Context.UI_MODE_SERVICE, this);
  164. mContext.registerReceiver(mDockModeReceiver,
  165. new IntentFilter(Intent.ACTION_DOCK_EVENT));
  166. mContext.registerReceiver(mBatteryReceiver,
  167. new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
  168. ThemeUtils.registerThemeChangeReceiver(mContext, mThemeChangeReceiver);
  169. mTwilightService.registerListener(mTwilightListener, mHandler);
  170. // Register settings observer and set initial preferences
  171. SettingsObserver settingsObserver = new SettingsObserver(new Handler());
  172. settingsObserver.observe();
  173. mPowerManager = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
  174. mWakeLock = mPowerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, TAG);
  175. mConfiguration.setToDefaults();
  176. updateUiMode();
  177. mCarModeKeepsScreenOn = (mContext.getResources().getInteger(
  178. com.android.internal.R.integer.config_carDockKeepsScreenOn) == 1);
  179. mDeskModeKeepsScreenOn = (mContext.getResources().getInteger(
  180. com.android.internal.R.integer.config_deskDockKeepsScreenOn) == 1);
  181. mTelevision = mContext.getPackageManager().hasSystemFeature(
  182. PackageManager.FEATURE_TELEVISION);
  183. mNightMode = Settings.Secure.getInt(mContext.getContentResolver(),
  184. Settings.Secure.UI_NIGHT_MODE, UiModeManager.MODE_NIGHT_AUTO);
  185. }
  186. private void updateUiMode() {
  187. if (Settings.Secure.getInt(mContext.getContentResolver(),
  188. Settings.Secure.UI_INVERTED_MODE, 0) == 1) {
  189. mDefaultUiModeType = mContext.getResources().getInteger(
  190. com.android.internal.R.integer.config_alternativeUiModeType);
  191. } else {
  192. mDefaultUiModeType = mContext.getResources().getInteger(
  193. com.android.internal.R.integer.config_defaultUiModeType);
  194. }
  195. if (mInitialVarSet && mDefaultUiModeType != Configuration.UI_MODE_TYPE_NORMAL) {
  196. mUiContext = null;
  197. updateLocked(0, 0);
  198. forceUiModeChangeForNonObservingMethods();
  199. }
  200. mInitialVarSet = false;
  201. }
  202. @Override // Binder call
  203. public void disableCarMode(int flags) {
  204. final long ident = Binder.clearCallingIdentity();
  205. try {
  206. synchronized (mLock) {
  207. setCarModeLocked(false);
  208. if (mSystemReady) {
  209. updateLocked(0, flags);
  210. }
  211. }
  212. } finally {
  213. Binder.restoreCallingIdentity(ident);
  214. }
  215. }
  216. @Override // Binder call
  217. public void enableCarMode(int flags) {
  218. final long ident = Binder.clearCallingIdentity();
  219. try {
  220. synchronized (mLock) {
  221. setCarModeLocked(true);
  222. if (mSystemReady) {
  223. updateLocked(flags, 0);
  224. }
  225. }
  226. } finally {
  227. Binder.restoreCallingIdentity(ident);
  228. }
  229. }
  230. @Override // Binder call
  231. public int getCurrentModeType() {
  232. final long ident = Binder.clearCallingIdentity();
  233. try {
  234. synchronized (mLock) {
  235. return mCurUiMode & Configuration.UI_MODE_TYPE_MASK;
  236. }
  237. } finally {
  238. Binder.restoreCallingIdentity(ident);
  239. }
  240. }
  241. @Override // Binder call
  242. public void setNightMode(int mode) {
  243. switch (mode) {
  244. case UiModeManager.MODE_NIGHT_NO:
  245. case UiModeManager.MODE_NIGHT_YES:
  246. case UiModeManager.MODE_NIGHT_AUTO:
  247. break;
  248. default:
  249. throw new IllegalArgumentException("Unknown mode: " + mode);
  250. }
  251. final long ident = Binder.clearCallingIdentity();
  252. try {
  253. synchronized (mLock) {
  254. if (isDoingNightModeLocked() && mNightMode != mode) {
  255. Settings.Secure.putInt(mContext.getContentResolver(),
  256. Settings.Secure.UI_NIGHT_MODE, mode);
  257. mNightMode = mode;
  258. updateLocked(0, 0);
  259. }
  260. }
  261. } finally {
  262. Binder.restoreCallingIdentity(ident);
  263. }
  264. }
  265. @Override // Binder call
  266. public int getNightMode() {
  267. synchronized (mLock) {
  268. return mNightMode;
  269. }
  270. }
  271. void systemReady() {
  272. synchronized (mLock) {
  273. mSystemReady = true;
  274. mCarModeEnabled = mDockState == Intent.EXTRA_DOCK_STATE_CAR;
  275. updateComputedNightModeLocked();
  276. updateLocked(0, 0);
  277. }
  278. }
  279. private boolean isDoingNightModeLocked() {
  280. return mCarModeEnabled || mDockState != Intent.EXTRA_DOCK_STATE_UNDOCKED;
  281. }
  282. private void setCarModeLocked(boolean enabled) {
  283. if (mCarModeEnabled != enabled) {
  284. mCarModeEnabled = enabled;
  285. }
  286. }
  287. private void updateDockState(int newState) {
  288. synchronized (mLock) {
  289. if (newState != mDockState) {
  290. mDockState = newState;
  291. setCarModeLocked(mDockState == Intent.EXTRA_DOCK_STATE_CAR);
  292. if (mSystemReady) {
  293. updateLocked(UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME, 0);
  294. }
  295. }
  296. }
  297. }
  298. private static boolean isDeskDockState(int state) {
  299. switch (state) {
  300. case Intent.EXTRA_DOCK_STATE_DESK:
  301. case Intent.EXTRA_DOCK_STATE_LE_DESK:
  302. case Intent.EXTRA_DOCK_STATE_HE_DESK:
  303. return true;
  304. default:
  305. return false;
  306. }
  307. }
  308. private void forceUiModeChangeForNonObservingMethods() {
  309. final boolean toggleUiMode = Settings.Secure.getInt(
  310. mContext.getContentResolver(),
  311. Settings.Secure.UI_MODE_IS_TOGGLED, 0) == 1;
  312. Settings.Secure.putInt(mContext.getContentResolver(),
  313. Settings.Secure.UI_MODE_IS_TOGGLED,
  314. toggleUiMode ? 0 : 1);
  315. }
  316. private void updateConfigurationLocked() {
  317. int uiMode = mTelevision ? Configuration.UI_MODE_TYPE_TELEVISION : mDefaultUiModeType;
  318. if (mCarModeEnabled) {
  319. uiMode = Configuration.UI_MODE_TYPE_CAR;
  320. } else if (isDeskDockState(mDockState)) {
  321. uiMode = Configuration.UI_MODE_TYPE_DESK;
  322. }
  323. if (mCarModeEnabled) {
  324. if (mNightMode == UiModeManager.MODE_NIGHT_AUTO) {
  325. updateComputedNightModeLocked();
  326. uiMode |= mComputedNightMode ? Configuration.UI_MODE_NIGHT_YES
  327. : Configuration.UI_MODE_NIGHT_NO;
  328. } else {
  329. uiMode |= mNightMode << 4;
  330. }
  331. } else {
  332. // Disabling the car mode clears the night mode.
  333. uiMode = (uiMode & ~Configuration.UI_MODE_NIGHT_MASK) | Configuration.UI_MODE_NIGHT_NO;
  334. }
  335. if (LOG) {
  336. Slog.d(TAG,
  337. "updateConfigurationLocked: mDockState=" + mDockState
  338. + "; mCarMode=" + mCarModeEnabled
  339. + "; mNightMode=" + mNightMode
  340. + "; uiMode=" + uiMode);
  341. }
  342. mCurUiMode = uiMode;
  343. if (!mHoldingConfiguration) {
  344. mConfiguration.uiMode = uiMode;
  345. }
  346. }
  347. private void sendConfigurationLocked() {
  348. if (mSetUiMode != mConfiguration.uiMode) {
  349. mSetUiMode = mConfiguration.uiMode;
  350. try {
  351. ActivityManagerNative.getDefault().updateConfiguration(mConfiguration);
  352. } catch (RemoteException e) {
  353. Slog.w(TAG, "Failure communicating with activity manager", e);
  354. }
  355. }
  356. }
  357. private void updateLocked(int enableFlags, int disableFlags) {
  358. String action = null;
  359. String oldAction = null;
  360. if (mLastBroadcastState == Intent.EXTRA_DOCK_STATE_CAR) {
  361. adjustStatusBarCarModeLocked();
  362. oldAction = UiModeManager.ACTION_EXIT_CAR_MODE;
  363. } else if (isDeskDockState(mLastBroadcastState)) {
  364. oldAction = UiModeManager.ACTION_EXIT_DESK_MODE;
  365. }
  366. if (mCarModeEnabled) {
  367. if (mLastBroadcastState != Intent.EXTRA_DOCK_STATE_CAR) {
  368. adjustStatusBarCarModeLocked();
  369. if (oldAction != null) {
  370. mContext.sendBroadcastAsUser(new Intent(oldAction), UserHandle.ALL);
  371. }
  372. mLastBroadcastState = Intent.EXTRA_DOCK_STATE_CAR;
  373. action = UiModeManager.ACTION_ENTER_CAR_MODE;
  374. }
  375. } else if (isDeskDockState(mDockState)) {
  376. if (!isDeskDockState(mLastBroadcastState)) {
  377. if (oldAction != null) {
  378. mContext.sendBroadcastAsUser(new Intent(oldAction), UserHandle.ALL);
  379. }
  380. mLastBroadcastState = mDockState;
  381. action = UiModeManager.ACTION_ENTER_DESK_MODE;
  382. }
  383. } else {
  384. mLastBroadcastState = Intent.EXTRA_DOCK_STATE_UNDOCKED;
  385. action = oldAction;
  386. }
  387. if (action != null) {
  388. if (LOG) {
  389. Slog.v(TAG, String.format(
  390. "updateLocked: preparing broadcast: action=%s enable=0x%08x disable=0x%08x",
  391. action, enableFlags, disableFlags));
  392. }
  393. // Send the ordered broadcast; the result receiver will receive after all
  394. // broadcasts have been sent. If any broadcast receiver changes the result
  395. // code from the initial value of RESULT_OK, then the result receiver will
  396. // not launch the corresponding dock application. This gives apps a chance
  397. // to override the behavior and stay in their app even when the device is
  398. // placed into a dock.
  399. Intent intent = new Intent(action);
  400. intent.putExtra("enableFlags", enableFlags);
  401. intent.putExtra("disableFlags", disableFlags);
  402. mContext.sendOrderedBroadcastAsUser(intent, UserHandle.CURRENT, null,
  403. mResultReceiver, null, Activity.RESULT_OK, null, null);
  404. // Attempting to make this transition a little more clean, we are going
  405. // to hold off on doing a configuration change until we have finished
  406. // the broadcast and started the home activity.
  407. mHoldingConfiguration = true;
  408. updateConfigurationLocked();
  409. } else {
  410. String category = null;
  411. if (mCarModeEnabled) {
  412. if (ENABLE_LAUNCH_CAR_DOCK_APP
  413. && (enableFlags & UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME) != 0) {
  414. category = Intent.CATEGORY_CAR_DOCK;
  415. }
  416. } else if (isDeskDockState(mDockState)) {
  417. if (ENABLE_LAUNCH_DESK_DOCK_APP
  418. && (enableFlags & UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME) != 0) {
  419. category = Intent.CATEGORY_DESK_DOCK;
  420. }
  421. } else {
  422. if ((disableFlags & UiModeManager.DISABLE_CAR_MODE_GO_HOME) != 0) {
  423. category = Intent.CATEGORY_HOME;
  424. }
  425. }
  426. if (LOG) {
  427. Slog.v(TAG, "updateLocked: null action, mDockState="
  428. + mDockState +", category=" + category);
  429. }
  430. sendConfigurationAndStartDreamOrDockAppLocked(category);
  431. }
  432. // keep screen on when charging and in car mode
  433. boolean keepScreenOn = mCharging &&
  434. ((mCarModeEnabled && mCarModeKeepsScreenOn) ||
  435. (mCurUiMode == Configuration.UI_MODE_TYPE_DESK && mDeskModeKeepsScreenOn));
  436. if (keepScreenOn != mWakeLock.isHeld()) {
  437. if (keepScreenOn) {
  438. mWakeLock.acquire();
  439. } else {
  440. mWakeLock.release();
  441. }
  442. }
  443. }
  444. private void updateAfterBroadcastLocked(String action, int enableFlags, int disableFlags) {
  445. // Launch a dock activity
  446. String category = null;
  447. if (UiModeManager.ACTION_ENTER_CAR_MODE.equals(action)) {
  448. // Only launch car home when car mode is enabled and the caller
  449. // has asked us to switch to it.
  450. if (ENABLE_LAUNCH_CAR_DOCK_APP
  451. && (enableFlags & UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME) != 0) {
  452. category = Intent.CATEGORY_CAR_DOCK;
  453. }
  454. } else if (UiModeManager.ACTION_ENTER_DESK_MODE.equals(action)) {
  455. // Only launch car home when desk mode is enabled and the caller
  456. // has asked us to switch to it. Currently re-using the car
  457. // mode flag since we don't have a formal API for "desk mode".
  458. if (ENABLE_LAUNCH_DESK_DOCK_APP
  459. && (enableFlags & UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME) != 0) {
  460. category = Intent.CATEGORY_DESK_DOCK;
  461. }
  462. } else {
  463. // Launch the standard home app if requested.
  464. if ((disableFlags & UiModeManager.DISABLE_CAR_MODE_GO_HOME) != 0) {
  465. category = Intent.CATEGORY_HOME;
  466. }
  467. }
  468. if (LOG) {
  469. Slog.v(TAG, String.format(
  470. "Handling broadcast result for action %s: enable=0x%08x, disable=0x%08x, "
  471. + "category=%s",
  472. action, enableFlags, disableFlags, category));
  473. }
  474. sendConfigurationAndStartDreamOrDockAppLocked(category);
  475. }
  476. private void sendConfigurationAndStartDreamOrDockAppLocked(String category) {
  477. // Update the configuration but don't send it yet.
  478. mHoldingConfiguration = false;
  479. updateConfigurationLocked();
  480. // Start the dock app, if there is one.
  481. boolean dockAppStarted = false;
  482. if (category != null) {
  483. // Now we are going to be careful about switching the
  484. // configuration and starting the activity -- we need to
  485. // do this in a specific order under control of the
  486. // activity manager, to do it cleanly. So compute the
  487. // new config, but don't set it yet, and let the
  488. // activity manager take care of both the start and config
  489. // change.
  490. Intent homeIntent = buildHomeIntent(category);
  491. if (Sandman.shouldStartDockApp(mContext, homeIntent)) {
  492. try {
  493. int result = ActivityManagerNative.getDefault().startActivityWithConfig(
  494. null, homeIntent, null, null, null, 0, 0,
  495. mConfiguration, null, UserHandle.USER_CURRENT);
  496. if (result >= ActivityManager.START_SUCCESS) {
  497. dockAppStarted = true;
  498. } else if (result != ActivityManager.START_INTENT_NOT_RESOLVED) {
  499. Slog.e(TAG, "Could not start dock app: " + homeIntent
  500. + ", startActivityWithConfig result " + result);
  501. }
  502. } catch (RemoteException ex) {
  503. Slog.e(TAG, "Could not start dock app: " + homeIntent, ex);
  504. }
  505. }
  506. }
  507. // Send the new configuration.
  508. sendConfigurationLocked();
  509. // If we did not start a dock app, then start dreaming if supported.
  510. if (category != null && !dockAppStarted) {
  511. Sandman.startDreamWhenDockedIfAppropriate(mContext);
  512. }
  513. }
  514. private void adjustStatusBarCarModeLocked() {
  515. if (mStatusBarManager == null) {
  516. mStatusBarManager = (StatusBarManager)
  517. mContext.getSystemService(Context.STATUS_BAR_SERVICE);
  518. }
  519. // Fear not: StatusBarManagerService manages a list of requests to disable
  520. // features of the status bar; these are ORed together to form the
  521. // active disabled list. So if (for example) the device is locked and
  522. // the status bar should be totally disabled, the calls below will
  523. // have no effect until the device is unlocked.
  524. if (mStatusBarManager != null) {
  525. mStatusBarManager.disable(mCarModeEnabled
  526. ? StatusBarManager.DISABLE_NOTIFICATION_TICKER
  527. : StatusBarManager.DISABLE_NONE);
  528. }
  529. if (mNotificationManager == null) {
  530. mNotificationManager = (NotificationManager)
  531. mContext.getSystemService(Context.NOTIFICATION_SERVICE);
  532. }
  533. if (mNotificationManager != null) {
  534. if (mCarModeEnabled) {
  535. Intent carModeOffIntent = new Intent(mContext, DisableCarModeActivity.class);
  536. Notification n = new Notification();
  537. n.icon = R.drawable.stat_notify_car_mode;
  538. n.defaults = Notification.DEFAULT_LIGHTS;
  539. n.flags = Notification.FLAG_ONGOING_EVENT;
  540. n.when = 0;
  541. n.setLatestEventInfo(
  542. getUiContext(),
  543. mContext.getString(R.string.car_mode_disable_notification_title),
  544. mContext.getString(R.string.car_mode_disable_notification_message),
  545. PendingIntent.getActivityAsUser(mContext, 0, carModeOffIntent, 0,
  546. null, UserHandle.CURRENT));
  547. mNotificationManager.notifyAsUser(null,
  548. R.string.car_mode_disable_notification_title, n, UserHandle.ALL);
  549. } else {
  550. mNotificationManager.cancelAsUser(null,
  551. R.string.car_mode_disable_notification_title, UserHandle.ALL);
  552. }
  553. }
  554. }
  555. private void updateTwilight() {
  556. synchronized (mLock) {
  557. if (isDoingNightModeLocked() && mNightMode == UiModeManager.MODE_NIGHT_AUTO) {
  558. updateComputedNightModeLocked();
  559. updateLocked(0, 0);
  560. }
  561. }
  562. }
  563. private void updateComputedNightModeLocked() {
  564. TwilightState state = mTwilightService.getCurrentState();
  565. if (state != null) {
  566. mComputedNightMode = state.isNight();
  567. }
  568. }
  569. private Context getUiContext() {
  570. if (mUiContext == null) {
  571. mUiContext = ThemeUtils.createUiContext(mContext);
  572. }
  573. return mUiContext != null ? mUiContext : mContext;
  574. }
  575. @Override
  576. protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
  577. if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
  578. != PackageManager.PERMISSION_GRANTED) {
  579. pw.println("Permission Denial: can't dump uimode service from from pid="
  580. + Binder.getCallingPid()
  581. + ", uid=" + Binder.getCallingUid());
  582. return;
  583. }
  584. synchronized (mLock) {
  585. pw.println("Current UI Mode Service state:");
  586. pw.print(" mDockState="); pw.print(mDockState);
  587. pw.print(" mLastBroadcastState="); pw.println(mLastBroadcastState);
  588. pw.print(" mNightMode="); pw.print(mNightMode);
  589. pw.print(" mCarModeEnabled="); pw.print(mCarModeEnabled);
  590. pw.print(" mComputedNightMode="); pw.println(mComputedNightMode);
  591. pw.print(" mCurUiMode=0x"); pw.print(Integer.toHexString(mCurUiMode));
  592. pw.print(" mSetUiMode=0x"); pw.println(Integer.toHexString(mSetUiMode));
  593. pw.print(" mHoldingConfiguration="); pw.print(mHoldingConfiguration);
  594. pw.print(" mSystemReady="); pw.println(mSystemReady);
  595. pw.print(" mTwilightService.getCurrentState()=");
  596. pw.println(mTwilightService.getCurrentState());
  597. }
  598. }
  599. }