PageRenderTime 75ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 1ms

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

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