am 17de1532: Merge "Fix issue #2581524: Car home icon should always go to car home" into froyo

Merge commit '17de1532a950f7ee961debab93a7977292b7f1f3' into froyo-plus-aosp

* commit '17de1532a950f7ee961debab93a7977292b7f1f3':
  Fix issue #2581524: Car home icon should always go to car home
diff --git a/api/current.xml b/api/current.xml
index 37736e3..61666ad 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -25428,6 +25428,17 @@
  visibility="public"
 >
 </field>
+<field name="ENABLE_CAR_MODE_GO_CAR_HOME"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="MODE_NIGHT_AUTO"
  type="int"
  transient="false"
@@ -89029,7 +89040,7 @@
 <method name="getMobileRxBytes"
  return="long"
  abstract="false"
- native="false"
+ native="true"
  synchronized="false"
  static="true"
  final="false"
@@ -89040,7 +89051,7 @@
 <method name="getMobileRxPackets"
  return="long"
  abstract="false"
- native="false"
+ native="true"
  synchronized="false"
  static="true"
  final="false"
@@ -89051,7 +89062,7 @@
 <method name="getMobileTxBytes"
  return="long"
  abstract="false"
- native="false"
+ native="true"
  synchronized="false"
  static="true"
  final="false"
@@ -89062,7 +89073,7 @@
 <method name="getMobileTxPackets"
  return="long"
  abstract="false"
- native="false"
+ native="true"
  synchronized="false"
  static="true"
  final="false"
@@ -89073,7 +89084,7 @@
 <method name="getTotalRxBytes"
  return="long"
  abstract="false"
- native="false"
+ native="true"
  synchronized="false"
  static="true"
  final="false"
@@ -89084,7 +89095,7 @@
 <method name="getTotalRxPackets"
  return="long"
  abstract="false"
- native="false"
+ native="true"
  synchronized="false"
  static="true"
  final="false"
@@ -89095,7 +89106,7 @@
 <method name="getTotalTxBytes"
  return="long"
  abstract="false"
- native="false"
+ native="true"
  synchronized="false"
  static="true"
  final="false"
@@ -89106,7 +89117,7 @@
 <method name="getTotalTxPackets"
  return="long"
  abstract="false"
- native="false"
+ native="true"
  synchronized="false"
  static="true"
  final="false"
@@ -89117,7 +89128,7 @@
 <method name="getUidRxBytes"
  return="long"
  abstract="false"
- native="false"
+ native="true"
  synchronized="false"
  static="true"
  final="false"
@@ -89130,7 +89141,7 @@
 <method name="getUidTxBytes"
  return="long"
  abstract="false"
- native="false"
+ native="true"
  synchronized="false"
  static="true"
  final="false"
diff --git a/core/java/android/app/IUiModeManager.aidl b/core/java/android/app/IUiModeManager.aidl
index 7b668d2..7e9873e 100644
--- a/core/java/android/app/IUiModeManager.aidl
+++ b/core/java/android/app/IUiModeManager.aidl
@@ -25,7 +25,7 @@
      * Enables the car mode. Only the system can do this.
      * @hide
      */
-    void enableCarMode();
+    void enableCarMode(int flags);
 
     /**
      * Disables the car mode.
diff --git a/core/java/android/app/UiModeManager.java b/core/java/android/app/UiModeManager.java
index a76dfb1..95451d6 100644
--- a/core/java/android/app/UiModeManager.java
+++ b/core/java/android/app/UiModeManager.java
@@ -116,13 +116,13 @@
     }
 
     /**
-     * Flag for use with {@link #disableCarMode(int)}: go to the normal
-     * home activity as part of the disable.  Disabling this way ensures
-     * a clean transition between the current activity (in car mode) and
-     * the original home activity (which was typically last running without
-     * being in car mode).
+     * Flag for use with {@link #enableCarMode(int)}: go to the car
+     * home activity as part of the enable.  Enabling this way ensures
+     * a clean transition between the current activity (in non-car-mode) and
+     * the car home activity that will serve as home while in car mode.  This
+     * will switch to the car home activity even if we are already in car mode.
      */
-    public static final int DISABLE_CAR_MODE_GO_HOME = 0x0001;
+    public static final int ENABLE_CAR_MODE_GO_CAR_HOME = 0x0001;
     
     /**
      * Force device into car mode, like it had been placed in the car dock.
@@ -133,7 +133,7 @@
     public void enableCarMode(int flags) {
         if (mService != null) {
             try {
-                mService.enableCarMode();
+                mService.enableCarMode(flags);
             } catch (RemoteException e) {
                 Log.e(TAG, "disableCarMode: RemoteException", e);
             }
@@ -141,6 +141,15 @@
     }
 
     /**
+     * Flag for use with {@link #disableCarMode(int)}: go to the normal
+     * home activity as part of the disable.  Disabling this way ensures
+     * a clean transition between the current activity (in car mode) and
+     * the original home activity (which was typically last running without
+     * being in car mode).
+     */
+    public static final int DISABLE_CAR_MODE_GO_HOME = 0x0001;
+    
+    /**
      * Turn off special mode if currently in car mode.
      * @param flags May be 0 or {@link #DISABLE_CAR_MODE_GO_HOME}.
      */
diff --git a/services/java/com/android/server/UiModeManagerService.java b/services/java/com/android/server/UiModeManagerService.java
index d6a42f6..3606629 100644
--- a/services/java/com/android/server/UiModeManagerService.java
+++ b/services/java/com/android/server/UiModeManagerService.java
@@ -25,6 +25,7 @@
 import android.app.PendingIntent;
 import android.app.StatusBarManager;
 import android.app.UiModeManager;
+import android.content.ActivityNotFoundException;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -103,6 +104,14 @@
     private StatusBarManager mStatusBarManager;
     private final PowerManager.WakeLock mWakeLock;
 
+    static Intent buildHomeIntent(String category) {
+        Intent intent = new Intent(Intent.ACTION_MAIN);
+        intent.addCategory(category);
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+                | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
+        return intent;
+    }
+    
     // The broadcast receiver which receives the result of the ordered broadcast sent when
     // the dock state changes. The original ordered broadcast is sent with an initial result
     // code of RESULT_OK. If any of the registered broadcast receivers changes this value, e.g.,
@@ -114,24 +123,36 @@
                 return;
             }
 
+            final int  enableFlags = intent.getIntExtra("enableFlags", 0);
+            final int  disableFlags = intent.getIntExtra("disableFlags", 0);
+            
             synchronized (mLock) {
                 // Launch a dock activity
-                String category;
+                String category = null;
                 if (UiModeManager.ACTION_ENTER_CAR_MODE.equals(intent.getAction())) {
-                    // Only launch car home when car mode is enabled.
-                    category = Intent.CATEGORY_CAR_DOCK;
+                    // Only launch car home when car mode is enabled and the caller
+                    // has asked us to switch to it.
+                    if ((enableFlags&UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME) != 0) {
+                        category = Intent.CATEGORY_CAR_DOCK;
+                    }
                 } else if (UiModeManager.ACTION_ENTER_DESK_MODE.equals(intent.getAction())) {
-                    category = Intent.CATEGORY_DESK_DOCK;
+                    // Only launch car home when desk mode is enabled and the caller
+                    // has asked us to switch to it.  Currently re-using the car
+                    // mode flag since we don't have a formal API for "desk mode".
+                    if ((enableFlags&UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME) != 0) {
+                        category = Intent.CATEGORY_DESK_DOCK;
+                    }
                 } else {
-                    category = null;
+                    // Launch the standard home app if requested.
+                    if ((disableFlags&UiModeManager.DISABLE_CAR_MODE_GO_HOME) != 0) {
+                        category = Intent.CATEGORY_HOME;
+                    }
                 }
+                
                 if (category != null) {
                     // This is the new activity that will serve as home while
                     // we are in care mode.
-                    intent = new Intent(Intent.ACTION_MAIN);
-                    intent.addCategory(category);
-                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
-                            | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
+                    Intent homeIntent = buildHomeIntent(category);
                     
                     // Now we are going to be careful about switching the
                     // configuration and starting the activity -- we need to
@@ -148,7 +169,7 @@
                     }
                     try {
                         ActivityManagerNative.getDefault().startActivityWithConfig(
-                                null, intent, null, null, 0, null, null, 0, false, false,
+                                null, homeIntent, null, null, 0, null, null, 0, false, false,
                                 newConfig);
                         mHoldingConfiguration = false;
                     } catch (RemoteException e) {
@@ -188,7 +209,7 @@
             mCharging = (intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0) != 0);
             synchronized (mLock) {
                 if (mSystemReady) {
-                    updateLocked(0);
+                    updateLocked(0, 0);
                 }
             }
         }
@@ -302,16 +323,16 @@
         synchronized (mLock) {
             setCarModeLocked(false);
             if (mSystemReady) {
-                updateLocked(flags);
+                updateLocked(0, flags);
             }
         }
     }
 
-    public void enableCarMode() {
+    public void enableCarMode(int flags) {
         synchronized (mLock) {
             setCarModeLocked(true);
             if (mSystemReady) {
-                updateLocked(0);
+                updateLocked(flags, 0);
             }
         }
     }
@@ -342,7 +363,7 @@
                         Settings.Secure.UI_NIGHT_MODE, mode);
                 Binder.restoreCallingIdentity(ident);
                 mNightMode = mode;
-                updateLocked(0);
+                updateLocked(0, 0);
             }
         }
     }
@@ -355,7 +376,7 @@
         synchronized (mLock) {
             mSystemReady = true;
             mCarModeEnabled = mDockState == Intent.EXTRA_DOCK_STATE_CAR;
-            updateLocked(0);
+            updateLocked(0, 0);
             mHandler.sendEmptyMessage(MSG_ENABLE_LOCATION_UPDATES);
         }
     }
@@ -376,7 +397,7 @@
                 mDockState = newState;
                 setCarModeLocked(mDockState == Intent.EXTRA_DOCK_STATE_CAR);
                 if (mSystemReady) {
-                    updateLocked(0);
+                    updateLocked(UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME, 0);
                 }
             }
         }
@@ -426,7 +447,7 @@
         }
     }
 
-    final void updateLocked(int flags) {
+    final void updateLocked(int enableFlags, int disableFlags) {
         long ident = Binder.clearCallingIdentity();
 
         try {
@@ -469,34 +490,39 @@
                 // not launch the corresponding dock application. This gives apps a chance
                 // to override the behavior and stay in their app even when the device is
                 // placed into a dock.
-                mContext.sendOrderedBroadcast(new Intent(action), null,
+                Intent intent = new Intent(action);
+                intent.putExtra("enableFlags", enableFlags);
+                intent.putExtra("disableFlags", disableFlags);
+                mContext.sendOrderedBroadcast(intent, null,
                         mResultReceiver, null, Activity.RESULT_OK, null, null);
                 // Attempting to make this transition a little more clean, we are going
                 // to hold off on doing a configuration change until we have finished
-                // the broacast and started the home activity.
+                // the broadcast and started the home activity.
                 mHoldingConfiguration = true;
+            } else {
+                Intent homeIntent = null;
+                if (mCarModeEnabled) {
+                    if ((enableFlags&UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME) != 0) {
+                        homeIntent = buildHomeIntent(Intent.CATEGORY_CAR_DOCK);
+                    }
+                } else if (mDockState == Intent.EXTRA_DOCK_STATE_DESK) {
+                    if ((enableFlags&UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME) != 0) {
+                        homeIntent = buildHomeIntent(Intent.CATEGORY_DESK_DOCK);
+                    }
+                } else {
+                    if ((disableFlags&UiModeManager.DISABLE_CAR_MODE_GO_HOME) != 0) {
+                        homeIntent = buildHomeIntent(Intent.CATEGORY_HOME);
+                    }
+                }
+                if (homeIntent != null) {
+                    try {
+                        mContext.startActivity(homeIntent);
+                    } catch (ActivityNotFoundException e) {
+                    }
+                }
             }
 
-            if (oldAction != null && (flags&UiModeManager.DISABLE_CAR_MODE_GO_HOME) != 0) {
-                // We are exiting the special mode, and have been asked to return
-                // to the main home screen while doing so.  To keep this clean, we
-                // have the activity manager switch the configuration for us at the
-                // same time as the switch.
-                try {
-                    Intent intent = new Intent(Intent.ACTION_MAIN);
-                    intent.addCategory(Intent.CATEGORY_HOME);
-                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-                    mHoldingConfiguration = false;
-                    updateConfigurationLocked(false);
-                    ActivityManagerNative.getDefault().startActivityWithConfig(
-                            null, intent, null, null, 0, null, null, 0, false, false,
-                            mConfiguration);
-                } catch (RemoteException e) {
-                    Slog.w(TAG, e.getCause());
-                }
-            } else {
-                updateConfigurationLocked(true);
-            }
+            updateConfigurationLocked(true);
 
             // keep screen on when charging and in car mode
             boolean keepScreenOn = mCharging &&
@@ -569,7 +595,7 @@
                         if (isDoingNightMode() && mLocation != null
                                 && mNightMode == UiModeManager.MODE_NIGHT_AUTO) {
                             updateTwilightLocked();
-                            updateLocked(0);
+                            updateLocked(0, 0);
                         }
                     }
                     break;
@@ -597,7 +623,7 @@
                             if (isDoingNightMode() && mLocation != null
                                     && mNightMode == UiModeManager.MODE_NIGHT_AUTO) {
                                 updateTwilightLocked();
-                                updateLocked(0);
+                                updateLocked(0, 0);
                             }
                         }
                     }