diff --git a/api/current.xml b/api/current.xml
index 03d8a3a50a1e9..bb15b043e5524 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -25508,6 +25508,8 @@
deprecated="not deprecated"
visibility="public"
>
+
+
+
+
+ android:interpolator="@anim/accelerate_decelerate_interpolator"
+ android:duration="@android:integer/config_mediumAnimTime"/>
-
-
diff --git a/services/java/com/android/server/UiModeManagerService.java b/services/java/com/android/server/UiModeManagerService.java
index 4e506e7eea9b8..a83af959be58c 100644
--- a/services/java/com/android/server/UiModeManagerService.java
+++ b/services/java/com/android/server/UiModeManagerService.java
@@ -144,6 +144,7 @@ class UiModeManagerService extends IUiModeManager.Stub {
// change.
Configuration newConfig = null;
if (mHoldingConfiguration) {
+ mHoldingConfiguration = false;
updateConfigurationLocked(false);
newConfig = mConfiguration;
}
@@ -151,7 +152,6 @@ class UiModeManagerService extends IUiModeManager.Stub {
ActivityManagerNative.getDefault().startActivityWithConfig(
null, intent, null, null, 0, null, null, 0, false, false,
newConfig);
- mContext.startActivity(intent);
mHoldingConfiguration = false;
} catch (RemoteException e) {
Slog.w(TAG, e.getCause());
@@ -190,7 +190,7 @@ class UiModeManagerService extends IUiModeManager.Stub {
mCharging = (intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0) != 0);
synchronized (mLock) {
if (mSystemReady) {
- updateLocked();
+ updateLocked(0);
}
}
}
@@ -300,11 +300,11 @@ class UiModeManagerService extends IUiModeManager.Stub {
Settings.Secure.UI_NIGHT_MODE, UiModeManager.MODE_NIGHT_AUTO);
}
- public void disableCarMode() {
+ public void disableCarMode(int flags) {
synchronized (mLock) {
setCarModeLocked(false);
if (mSystemReady) {
- updateLocked();
+ updateLocked(flags);
}
}
}
@@ -316,7 +316,7 @@ class UiModeManagerService extends IUiModeManager.Stub {
synchronized (mLock) {
setCarModeLocked(true);
if (mSystemReady) {
- updateLocked();
+ updateLocked(0);
}
}
}
@@ -347,7 +347,7 @@ class UiModeManagerService extends IUiModeManager.Stub {
Settings.Secure.UI_NIGHT_MODE, mode);
Binder.restoreCallingIdentity(ident);
mNightMode = mode;
- updateLocked();
+ updateLocked(0);
}
}
}
@@ -360,7 +360,7 @@ class UiModeManagerService extends IUiModeManager.Stub {
synchronized (mLock) {
mSystemReady = true;
mCarModeEnabled = mDockState == Intent.EXTRA_DOCK_STATE_CAR;
- updateLocked();
+ updateLocked(0);
mHandler.sendEmptyMessage(MSG_ENABLE_LOCATION_UPDATES);
}
}
@@ -381,7 +381,7 @@ class UiModeManagerService extends IUiModeManager.Stub {
mDockState = newState;
setCarModeLocked(mDockState == Intent.EXTRA_DOCK_STATE_CAR);
if (mSystemReady) {
- updateLocked();
+ updateLocked(0);
}
}
}
@@ -424,7 +424,7 @@ class UiModeManagerService extends IUiModeManager.Stub {
}
}
- final void updateLocked() {
+ final void updateLocked(int flags) {
long ident = Binder.clearCallingIdentity();
try {
@@ -475,7 +475,25 @@ class UiModeManagerService extends IUiModeManager.Stub {
mHoldingConfiguration = true;
}
- updateConfigurationLocked(true);
+ 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);
+ 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);
+ }
// keep screen on when charging and in car mode
boolean keepScreenOn = mCharging &&
@@ -548,7 +566,7 @@ class UiModeManagerService extends IUiModeManager.Stub {
if (isDoingNightMode() && mLocation != null
&& mNightMode == UiModeManager.MODE_NIGHT_AUTO) {
updateTwilightLocked();
- updateLocked();
+ updateLocked(0);
}
}
break;
@@ -576,7 +594,7 @@ class UiModeManagerService extends IUiModeManager.Stub {
if (isDoingNightMode() && mLocation != null
&& mNightMode == UiModeManager.MODE_NIGHT_AUTO) {
updateTwilightLocked();
- updateLocked();
+ updateLocked(0);
}
}
}
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index d1edc350ef72c..cd2d3e3ebcc31 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -69,7 +69,6 @@ import android.content.pm.PathPermission;
import android.content.pm.ProviderInfo;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
-import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.net.Uri;
@@ -782,6 +781,12 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
*/
int mConfigurationSeq = 0;
+ /**
+ * Set when we know we are going to be calling updateConfiguration()
+ * soon, so want to skip intermediate config checks.
+ */
+ boolean mConfigWillChange;
+
/**
* Hardware-reported OpenGLES version.
*/
@@ -3663,12 +3668,17 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
} else {
callingPid = callingUid = -1;
}
+
+ mConfigWillChange = config != null && mConfiguration.diff(config) != 0;
+
final long origId = Binder.clearCallingIdentity();
+
int res = startActivityLocked(caller, intent, resolvedType,
grantedUriPermissions, grantedMode, aInfo,
resultTo, resultWho, requestCode, callingPid, callingUid,
onlyIfNeeded, componentSpecified);
- if (config != null) {
+
+ if (config != null && mConfigWillChange) {
// If the caller also wants to switch to a new configuration,
// do so now. This allows a clean switch, as we are waiting
// for the current activity to pause (so we will not destroy
@@ -3677,6 +3687,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
"updateConfiguration()");
updateConfigurationLocked(config, null);
}
+
Binder.restoreCallingIdentity(origId);
if (outResult != null) {
@@ -9705,6 +9716,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
pw.println(" ");
pw.println(" mHomeProcess: " + mHomeProcess);
pw.println(" mConfiguration: " + mConfiguration);
+ pw.println(" mConfigWillChange: " + mConfigWillChange);
pw.println(" mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
|| mOrigWaitForDebugger) {
@@ -13452,6 +13464,12 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
*/
private final boolean ensureActivityConfigurationLocked(HistoryRecord r,
int globalChanges) {
+ if (!mConfigWillChange) {
+ if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
+ "Skipping config check (will change): " + r);
+ return true;
+ }
+
if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
"Ensuring correct configuration: " + r);
diff --git a/services/java/com/android/server/status/StatusBarView.java b/services/java/com/android/server/status/StatusBarView.java
index 2dd564e4517a9..5e1f57204cd68 100644
--- a/services/java/com/android/server/status/StatusBarView.java
+++ b/services/java/com/android/server/status/StatusBarView.java
@@ -17,9 +17,10 @@
package com.android.server.status;
import android.content.Context;
+import android.content.res.Configuration;
+import android.graphics.Canvas;
+import android.os.SystemClock;
import android.util.AttributeSet;
-import android.util.Slog;
-import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
@@ -31,6 +32,8 @@ import com.android.internal.R;
public class StatusBarView extends FrameLayout {
private static final String TAG = "StatusBarView";
+ static final int DIM_ANIM_TIME = 400;
+
StatusBarService mService;
boolean mTracking;
int mStartX, mStartY;
@@ -38,6 +41,10 @@ public class StatusBarView extends FrameLayout {
ViewGroup mStatusIcons;
View mDate;
FixedSizeDrawable mBackground;
+
+ boolean mNightMode = false;
+ int mStartAlpha = 0, mEndAlpha = 0;
+ long mEndTime = 0;
public StatusBarView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -60,7 +67,30 @@ public class StatusBarView extends FrameLayout {
super.onAttachedToWindow();
mService.onBarViewAttached();
}
+
+ @Override
+ protected void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+ boolean nightMode = (newConfig.uiMode & Configuration.UI_MODE_NIGHT_MASK)
+ == Configuration.UI_MODE_NIGHT_YES;
+ if (mNightMode != nightMode) {
+ mNightMode = nightMode;
+ mStartAlpha = getCurAlpha();
+ mEndAlpha = mNightMode ? 0x80 : 0x00;
+ mEndTime = SystemClock.uptimeMillis() + DIM_ANIM_TIME;
+ invalidate();
+ }
+ }
+ int getCurAlpha() {
+ long time = SystemClock.uptimeMillis();
+ if (time > mEndTime) {
+ return mEndAlpha;
+ }
+ return mEndAlpha
+ - (int)(((mEndAlpha-mStartAlpha) * (mEndTime-time) / DIM_ANIM_TIME));
+ }
+
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
@@ -97,6 +127,18 @@ public class StatusBarView extends FrameLayout {
mBackground.setFixedBounds(-mDate.getLeft(), -mDate.getTop(), (r-l), (b-t));
}
+ @Override
+ protected void dispatchDraw(Canvas canvas) {
+ super.dispatchDraw(canvas);
+ int alpha = getCurAlpha();
+ if (alpha != 0) {
+ canvas.drawARGB(alpha, 0, 0, 0);
+ }
+ if (alpha != mEndAlpha) {
+ invalidate();
+ }
+ }
+
/**
* Gets the left position of v in this view. Throws if v is not
* a child of this.