The intent will have the following extra values:
+ *
+ * - {@link #EXTRA_DOCK_STATE} - the current dock
+ * state, which depends on the state of the car mode.
+ * - {@link #EXTRA_PHYSICAL_DOCK_STATE} - the physical dock
+ * state.
+ * - {@link #EXTRA_CAR_MODE_ENABLED} - a boolean indicating the
+ * state of the car mode.
+ *
+ * This is intended for monitoring the current dock state.
* To launch an activity from a dock state change, use {@link #CATEGORY_CAR_DOCK}
* or {@link #CATEGORY_DESK_DOCK} instead.
*/
@@ -2153,6 +2160,16 @@ public class Intent implements Parcelable, Cloneable {
*/
public static final int EXTRA_DOCK_STATE_CAR = 2;
+ /**
+ * Used as an int extra field in {@link android.content.Intent#ACTION_DOCK_EVENT}
+ * intents to request the physical dock state. Possible values are
+ * {@link android.content.Intent#EXTRA_DOCK_STATE_UNDOCKED},
+ * {@link android.content.Intent#EXTRA_DOCK_STATE_DESK}, or
+ * {@link android.content.Intent#EXTRA_DOCK_STATE_CAR}.
+ */
+ public static final String EXTRA_PHYSICAL_DOCK_STATE =
+ "android.intent.extra.PHYSICAL_DOCK_STATE";
+
/**
* Used as an boolean extra field in {@link android.content.Intent#ACTION_DOCK_EVENT}
* intents to indicate that the car mode is enabled or not.
diff --git a/core/java/com/android/internal/app/DisableCarModeActivity.java b/core/java/com/android/internal/app/DisableCarModeActivity.java
new file mode 100644
index 0000000000000..95dc1f9d014b3
--- /dev/null
+++ b/core/java/com/android/internal/app/DisableCarModeActivity.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.app;
+
+import android.app.Activity;
+import android.app.IUiModeManager;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.util.Log;
+
+public class DisableCarModeActivity extends Activity {
+ private static final String TAG = "DisableCarModeActivity";
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ try {
+ IUiModeManager uiModeManager = IUiModeManager.Stub.asInterface(
+ ServiceManager.getService("uimode"));
+ uiModeManager.disableCarMode();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to disable car mode", e);
+ }
+ finish();
+ }
+
+}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index a27d28f6138ac..333db05a10f4b 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1252,6 +1252,10 @@
+
+
We\'ve encountered a problem turning off Tethering. Please try again.
+
+
+ Car mode enabled
+ Select to disable car mode.
+
diff --git a/services/java/com/android/server/DockObserver.java b/services/java/com/android/server/DockObserver.java
index b566fb7eb8a58..4791718aad9d8 100644
--- a/services/java/com/android/server/DockObserver.java
+++ b/services/java/com/android/server/DockObserver.java
@@ -22,8 +22,10 @@ import android.app.AlarmManager;
import android.app.IActivityManager;
import android.app.IUiModeManager;
import android.app.KeyguardManager;
-import android.app.StatusBarManager;
+import android.app.Notification;
+import android.app.NotificationManager;
import android.app.PendingIntent;
+import android.app.StatusBarManager;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.ActivityNotFoundException;
@@ -55,6 +57,8 @@ import android.text.format.DateUtils;
import android.text.format.Time;
import android.util.Log;
+import com.android.internal.R;
+import com.android.internal.app.DisableCarModeActivity;
import com.android.internal.widget.LockPatternUtils;
import java.io.FileNotFoundException;
@@ -101,6 +105,7 @@ class DockObserver extends UEventObserver {
private final Context mContext;
private PowerManagerService mPowerManager;
+ private NotificationManager mNotificationManager;
private KeyguardManager.KeyguardLock mKeyguardLock;
private boolean mKeyguardDisabled;
@@ -125,7 +130,8 @@ class DockObserver extends UEventObserver {
// Launch a dock activity
String category;
- if (mCarModeEnabled || mDockState == Intent.EXTRA_DOCK_STATE_CAR) {
+ if (mCarModeEnabled) {
+ // Only launch car home when car mode is enabled.
category = Intent.CATEGORY_CAR_DOCK;
} else if (mDockState == Intent.EXTRA_DOCK_STATE_DESK) {
category = Intent.CATEGORY_DESK_DOCK;
@@ -332,9 +338,13 @@ class DockObserver extends UEventObserver {
if (mCarModeEnabled && mDockState != Intent.EXTRA_DOCK_STATE_CAR) {
// Pretend to be in DOCK_STATE_CAR.
intent.putExtra(Intent.EXTRA_DOCK_STATE, Intent.EXTRA_DOCK_STATE_CAR);
+ } else if (!mCarModeEnabled && mDockState == Intent.EXTRA_DOCK_STATE_CAR) {
+ // Pretend to be in DOCK_STATE_UNDOCKED.
+ intent.putExtra(Intent.EXTRA_DOCK_STATE, Intent.EXTRA_DOCK_STATE_UNDOCKED);
} else {
intent.putExtra(Intent.EXTRA_DOCK_STATE, mDockState);
}
+ intent.putExtra(Intent.EXTRA_PHYSICAL_DOCK_STATE, mDockState);
intent.putExtra(Intent.EXTRA_CAR_MODE_ENABLED, mCarModeEnabled);
// Check if this is Bluetooth Dock
@@ -462,6 +472,52 @@ class DockObserver extends UEventObserver {
}
};
+ private void adjustStatusBarCarMode() {
+ if (mStatusBarManager == null) {
+ mStatusBarManager = (StatusBarManager) mContext.getSystemService(Context.STATUS_BAR_SERVICE);
+ }
+
+ // Fear not: StatusBarService manages a list of requests to disable
+ // features of the status bar; these are ORed together to form the
+ // active disabled list. So if (for example) the device is locked and
+ // the status bar should be totally disabled, the calls below will
+ // have no effect until the device is unlocked.
+ if (mStatusBarManager != null) {
+ long ident = Binder.clearCallingIdentity();
+ mStatusBarManager.disable(mCarModeEnabled
+ ? StatusBarManager.DISABLE_NOTIFICATION_TICKER
+ : StatusBarManager.DISABLE_NONE);
+ Binder.restoreCallingIdentity(ident);
+ }
+
+ if (mNotificationManager == null) {
+ mNotificationManager = (NotificationManager)
+ mContext.getSystemService(Context.NOTIFICATION_SERVICE);
+ }
+
+ if (mNotificationManager != null) {
+ long ident = Binder.clearCallingIdentity();
+ if (mCarModeEnabled) {
+ Intent carModeOffIntent = new Intent(mContext, DisableCarModeActivity.class);
+
+ Notification n = new Notification();
+ n.icon = R.drawable.stat_notify_car_mode;
+ n.defaults = Notification.DEFAULT_LIGHTS;
+ n.flags = Notification.FLAG_ONGOING_EVENT;
+ n.when = 0;
+ n.setLatestEventInfo(
+ mContext,
+ mContext.getString(R.string.car_mode_disable_notification_title),
+ mContext.getString(R.string.car_mode_disable_notification_message),
+ PendingIntent.getActivity(mContext, 0, carModeOffIntent, 0));
+ mNotificationManager.notify(0, n);
+ } else {
+ mNotificationManager.cancel(0);
+ }
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
private void setCarMode(boolean enabled) throws RemoteException {
mCarModeEnabled = enabled;
if (enabled) {
@@ -475,23 +531,7 @@ class DockObserver extends UEventObserver {
setMode(Configuration.UI_MODE_TYPE_NORMAL,
Configuration.UI_MODE_NIGHT_UNDEFINED);
}
-
- if (mStatusBarManager == null) {
- mStatusBarManager = (StatusBarManager) mContext.getSystemService(Context.STATUS_BAR_SERVICE);
- }
-
- // Fear not: StatusBarService manages a list of requests to disable
- // features of the status bar; these are ORed together to form the
- // active disabled list. So if (for example) the device is locked and
- // the status bar should be totally disabled, the calls below will
- // have no effect until the device is unlocked.
- if (mStatusBarManager != null) {
- long ident = Binder.clearCallingIdentity();
- mStatusBarManager.disable(enabled
- ? StatusBarManager.DISABLE_NOTIFICATION_TICKER
- : StatusBarManager.DISABLE_NONE);
- Binder.restoreCallingIdentity(ident);
- }
+ adjustStatusBarCarMode();
}
private void setMode(int modeType, int modeNight) throws RemoteException {