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.