PageRenderTime 59ms CodeModel.GetById 29ms RepoModel.GetById 1ms app.codeStats 0ms

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

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