Fix issue #2544466: Car Home brightness icon comes and goes while phone is in car dock in FRE83
There was a really dumb bug that was causing us to not always apply
the new configuration. As a result of fixing this, there were new
glithes in the transition between car and regular mode, so further
work here to fix that. And since I was actually working during the
night and seeing night mode, I noticed how obnoxiously bright the
status bar is compared to the car home at night, so it now nicely
dims itself when we switch to the night config. Oh and in doing
that I also found and fixed a bug in dispatching config changes to
a window (where they wouldn't get dispatched if the window didn't
resize).
FINALLY... tweak the wallpaper enter/exit animations a bit to
make them a little smoother.
Change-Id: I4e062093cbcfbc919307799a794846db2920216f
diff --git a/services/java/com/android/server/UiModeManagerService.java b/services/java/com/android/server/UiModeManagerService.java
index 4e506e7..a83af95 100644
--- a/services/java/com/android/server/UiModeManagerService.java
+++ b/services/java/com/android/server/UiModeManagerService.java
@@ -144,6 +144,7 @@
// change.
Configuration newConfig = null;
if (mHoldingConfiguration) {
+ mHoldingConfiguration = false;
updateConfigurationLocked(false);
newConfig = mConfiguration;
}
@@ -151,7 +152,6 @@
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 @@
mCharging = (intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0) != 0);
synchronized (mLock) {
if (mSystemReady) {
- updateLocked();
+ updateLocked(0);
}
}
}
@@ -300,11 +300,11 @@
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 @@
synchronized (mLock) {
setCarModeLocked(true);
if (mSystemReady) {
- updateLocked();
+ updateLocked(0);
}
}
}
@@ -347,7 +347,7 @@
Settings.Secure.UI_NIGHT_MODE, mode);
Binder.restoreCallingIdentity(ident);
mNightMode = mode;
- updateLocked();
+ updateLocked(0);
}
}
}
@@ -360,7 +360,7 @@
synchronized (mLock) {
mSystemReady = true;
mCarModeEnabled = mDockState == Intent.EXTRA_DOCK_STATE_CAR;
- updateLocked();
+ updateLocked(0);
mHandler.sendEmptyMessage(MSG_ENABLE_LOCATION_UPDATES);
}
}
@@ -381,7 +381,7 @@
mDockState = newState;
setCarModeLocked(mDockState == Intent.EXTRA_DOCK_STATE_CAR);
if (mSystemReady) {
- updateLocked();
+ updateLocked(0);
}
}
}
@@ -424,7 +424,7 @@
}
}
- final void updateLocked() {
+ final void updateLocked(int flags) {
long ident = Binder.clearCallingIdentity();
try {
@@ -475,7 +475,25 @@
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 @@
if (isDoingNightMode() && mLocation != null
&& mNightMode == UiModeManager.MODE_NIGHT_AUTO) {
updateTwilightLocked();
- updateLocked();
+ updateLocked(0);
}
}
break;
@@ -576,7 +594,7 @@
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 d1edc35..cd2d3e3 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.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;
@@ -783,6 +782,12 @@
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.
*/
final int GL_ES_VERSION;
@@ -3663,12 +3668,17 @@
} 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 @@
"updateConfiguration()");
updateConfigurationLocked(config, null);
}
+
Binder.restoreCallingIdentity(origId);
if (outResult != null) {
@@ -9705,6 +9716,7 @@
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 @@
*/
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 2dd564e..5e1f572 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 @@
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 @@
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 @@
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 @@
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.