diff options
17 files changed, 273 insertions, 77 deletions
diff --git a/Android.mk b/Android.mk index a0187165cb52..a1d91c363b0b 100644 --- a/Android.mk +++ b/Android.mk @@ -231,6 +231,7 @@ LOCAL_SRC_FILES += \ core/java/android/view/IWindowId.aidl \ core/java/android/view/IWindowManager.aidl \ core/java/android/view/IWindowSession.aidl \ + core/java/android/view/IWindowSessionCallback.aidl \ core/java/android/speech/IRecognitionListener.aidl \ core/java/android/speech/IRecognitionService.aidl \ core/java/android/speech/tts/ITextToSpeechCallback.aidl \ diff --git a/api/current.txt b/api/current.txt index 8d6b906dd00a..eb63f90e0d37 100644 --- a/api/current.txt +++ b/api/current.txt @@ -21323,12 +21323,14 @@ package android.os { public final class PowerManager { method public void goToSleep(long); method public boolean isInteractive(); + method public boolean isPowerSaveMode(); method public deprecated boolean isScreenOn(); method public android.os.PowerManager.WakeLock newWakeLock(int, java.lang.String); method public void reboot(java.lang.String); method public void userActivity(long, boolean); method public void wakeUp(long); field public static final int ACQUIRE_CAUSES_WAKEUP = 268435456; // 0x10000000 + field public static final java.lang.String ACTION_POWER_SAVE_MODE_CHANGED = "android.os.action.POWER_SAVE_MODE_CHANGED"; field public static final deprecated int FULL_WAKE_LOCK = 26; // 0x1a field public static final int ON_AFTER_RELEASE = 536870912; // 0x20000000 field public static final int PARTIAL_WAKE_LOCK = 1; // 0x1 diff --git a/core/java/android/os/IPowerManager.aidl b/core/java/android/os/IPowerManager.aidl index 61194e96c7f1..658180b21342 100644 --- a/core/java/android/os/IPowerManager.aidl +++ b/core/java/android/os/IPowerManager.aidl @@ -41,6 +41,7 @@ interface IPowerManager void goToSleep(long time, int reason, int flags); void nap(long time); boolean isInteractive(); + boolean isPowerSaveMode(); void reboot(boolean confirm, String reason, boolean wait); void shutdown(boolean confirm, boolean wait); diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java index d5177e808e12..92e80a5afd1a 100644 --- a/core/java/android/os/PowerManager.java +++ b/core/java/android/os/PowerManager.java @@ -16,6 +16,7 @@ package android.os; +import android.annotation.SdkConstant; import android.content.Context; import android.util.Log; @@ -685,6 +686,30 @@ public final class PowerManager { } /** + * Returns true if the device is currently in power save mode. When in this mode, + * applications should reduce their functionality in order to conserve battery as + * much as possible. You can monitor for changes to this state with + * {@link #ACTION_POWER_SAVE_MODE_CHANGED}. + * + * @return Returns true if currently in low power mode, else false. + */ + public boolean isPowerSaveMode() { + try { + return mService.isPowerSaveMode(); + } catch (RemoteException e) { + return false; + } + } + + /** + * Intent that is broadcast when the state of {@link #isPowerSaveMode()} changes. + * This broadcast is only sent to registered receivers. + */ + @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String ACTION_POWER_SAVE_MODE_CHANGED + = "android.os.action.POWER_SAVE_MODE_CHANGED"; + + /** * A wake lock is a mechanism to indicate that your application needs * to have the device stay on. * <p> diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl index a52ccdfef13e..ae59bbc636ff 100644 --- a/core/java/android/view/IWindowManager.aidl +++ b/core/java/android/view/IWindowManager.aidl @@ -30,6 +30,7 @@ import android.view.IApplicationToken; import android.view.IOnKeyguardExitResult; import android.view.IRotationWatcher; import android.view.IWindowSession; +import android.view.IWindowSessionCallback; import android.view.KeyEvent; import android.view.InputEvent; import android.view.MagnificationSpec; @@ -56,7 +57,7 @@ interface IWindowManager boolean stopViewServer(); // Transaction #2 boolean isViewServerRunning(); // Transaction #3 - IWindowSession openSession(in IInputMethodClient client, + IWindowSession openSession(in IWindowSessionCallback callback, in IInputMethodClient client, in IInputContext inputContext); boolean inputMethodClientHasFocus(IInputMethodClient client); @@ -130,6 +131,8 @@ interface IWindowManager void setAnimationScale(int which, float scale); void setAnimationScales(in float[] scales); + float getCurrentAnimatorScale(); + // For testing void setInTouchMode(boolean showFocus); diff --git a/core/java/android/view/IWindowSessionCallback.aidl b/core/java/android/view/IWindowSessionCallback.aidl new file mode 100644 index 000000000000..88931ce000a5 --- /dev/null +++ b/core/java/android/view/IWindowSessionCallback.aidl @@ -0,0 +1,27 @@ +/* +** Copyright 2014, 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 android.view; + +/** + * Callback to active sessions of the window manager + * + * {@hide} + */ +oneway interface IWindowSessionCallback +{ + void onAnimatorScaleChanged(float scale); +} diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java index b4779f4d91d6..0ebf2e18f184 100644 --- a/core/java/android/view/WindowManagerGlobal.java +++ b/core/java/android/view/WindowManagerGlobal.java @@ -147,9 +147,14 @@ public final class WindowManagerGlobal { InputMethodManager imm = InputMethodManager.getInstance(); IWindowManager windowManager = getWindowManagerService(); sWindowSession = windowManager.openSession( + new IWindowSessionCallback.Stub() { + @Override + public void onAnimatorScaleChanged(float scale) { + ValueAnimator.setDurationScale(scale); + } + }, imm.getClient(), imm.getInputContext()); - float animatorScale = windowManager.getAnimationScale(2); - ValueAnimator.setDurationScale(animatorScale); + ValueAnimator.setDurationScale(windowManager.getCurrentAnimatorScale()); } catch (RemoteException e) { Log.e(TAG, "Failed to open window session", e); } diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index d844818cb506..f57c3a0d8365 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -74,6 +74,8 @@ <protected-broadcast android:name="android.intent.action.USER_FOREGROUND" /> <protected-broadcast android:name="android.intent.action.USER_SWITCHED" /> + <protected-broadcast android:name="android.os.action.POWER_SAVE_MODE_CHANGED" /> + <protected-broadcast android:name="android.app.action.ENTER_CAR_MODE" /> <protected-broadcast android:name="android.app.action.EXIT_CAR_MODE" /> <protected-broadcast android:name="android.app.action.ENTER_DESK_MODE" /> diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java index cb5946afacaa..fe5c2ef3ad06 100644 --- a/services/core/java/com/android/server/BatteryService.java +++ b/services/core/java/com/android/server/BatteryService.java @@ -128,6 +128,8 @@ public final class BatteryService extends Binder { private int mPlugType; private int mLastPlugType = -1; // Extra state so we can detect first run + private boolean mBatteryLevelLow; + private long mDischargeStartTime; private int mDischargeStartLevel; @@ -222,14 +224,30 @@ public final class BatteryService extends Binder { } /** - * Returns true if battery level is below the first warning threshold. + * Returns whether we currently consider the battery level to be low. */ - public boolean isBatteryLow() { + public boolean getBatteryLevelLow() { synchronized (mLock) { - return mBatteryProps.batteryPresent && mBatteryProps.batteryLevel <= mLowBatteryWarningLevel; + return mBatteryLevelLow; } } + public boolean isBatteryLowLocked() { + final boolean plugged = mPlugType != BATTERY_PLUGGED_NONE; + final boolean oldPlugged = mLastPlugType != BATTERY_PLUGGED_NONE; + + /* The ACTION_BATTERY_LOW broadcast is sent in these situations: + * - is just un-plugged (previously was plugged) and battery level is + * less than or equal to WARNING, or + * - is not plugged and battery level falls to WARNING boundary + * (becomes <= mLowBatteryWarningLevel). + */ + return !plugged + && mBatteryProps.batteryStatus != BatteryManager.BATTERY_STATUS_UNKNOWN + && mBatteryProps.batteryLevel <= mLowBatteryWarningLevel + && (oldPlugged || mLastBatteryLevel > mLowBatteryWarningLevel); + } + /** * Returns a non-zero value if an unsupported charger is attached. */ @@ -382,19 +400,7 @@ public final class BatteryService extends Binder { logOutlier = true; } - final boolean plugged = mPlugType != BATTERY_PLUGGED_NONE; - final boolean oldPlugged = mLastPlugType != BATTERY_PLUGGED_NONE; - - /* The ACTION_BATTERY_LOW broadcast is sent in these situations: - * - is just un-plugged (previously was plugged) and battery level is - * less than or equal to WARNING, or - * - is not plugged and battery level falls to WARNING boundary - * (becomes <= mLowBatteryWarningLevel). - */ - final boolean sendBatteryLow = !plugged - && mBatteryProps.batteryStatus != BatteryManager.BATTERY_STATUS_UNKNOWN - && mBatteryProps.batteryLevel <= mLowBatteryWarningLevel - && (oldPlugged || mLastBatteryLevel > mLowBatteryWarningLevel); + mBatteryLevelLow = isBatteryLowLocked(); sendIntentLocked(); @@ -422,7 +428,7 @@ public final class BatteryService extends Binder { }); } - if (sendBatteryLow) { + if (mBatteryLevelLow) { mSentLowBatteryBroadcast = true; mHandler.post(new Runnable() { @Override diff --git a/services/core/java/com/android/server/VibratorService.java b/services/core/java/com/android/server/VibratorService.java index 06dd3edb3015..fdaf55e4f9a4 100644 --- a/services/core/java/com/android/server/VibratorService.java +++ b/services/core/java/com/android/server/VibratorService.java @@ -28,6 +28,7 @@ import android.os.BatteryStats; import android.os.Handler; import android.os.IVibratorService; import android.os.PowerManager; +import android.os.PowerManagerInternal; import android.os.Process; import android.os.RemoteException; import android.os.IBinder; @@ -64,6 +65,7 @@ public class VibratorService extends IVibratorService.Stub private final PowerManager.WakeLock mWakeLock; private final IAppOpsService mAppOpsService; private final IBatteryStats mBatteryStatsService; + private PowerManagerInternal mPowerManagerInternal; private InputManager mIm; volatile VibrateThread mThread; @@ -169,14 +171,19 @@ public class VibratorService extends IVibratorService.Stub mIm = (InputManager)mContext.getSystemService(Context.INPUT_SERVICE); mSettingObserver = new SettingsObserver(mH); + mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class); + mPowerManagerInternal.registerLowPowerModeObserver( + new PowerManagerInternal.LowPowerModeListener() { + @Override + public void onLowPowerModeChanged(boolean enabled) { + updateInputDeviceVibrators(); + } + }); + mContext.getContentResolver().registerContentObserver( Settings.System.getUriFor(Settings.System.VIBRATE_INPUT_DEVICES), true, mSettingObserver, UserHandle.USER_ALL); - mContext.getContentResolver().registerContentObserver( - Settings.Global.getUriFor(Settings.Global.LOW_POWER_MODE), false, - mSettingObserver, UserHandle.USER_ALL); - mContext.registerReceiver(new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { @@ -448,8 +455,7 @@ public class VibratorService extends IVibratorService.Stub } catch (SettingNotFoundException snfe) { } - mLowPowerMode = Settings.Global.getInt(mContext.getContentResolver(), - Settings.Global.LOW_POWER_MODE, 0) != 0; + mLowPowerMode = mPowerManagerInternal.getLowPowerModeEnabled(); if (mVibrateInputDevicesSetting) { if (!mInputDeviceListenerRegistered) { diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java index aca17bff6a96..d8671d9535e7 100644 --- a/services/core/java/com/android/server/power/PowerManagerService.java +++ b/services/core/java/com/android/server/power/PowerManagerService.java @@ -406,6 +406,12 @@ public final class PowerManagerService extends com.android.server.SystemService // If true, the device is in low power mode. private boolean mLowPowerModeEnabled; + // Current state of the low power mode setting. + private boolean mLowPowerModeSetting; + + // True if the battery level is currently considered low. + private boolean mBatteryLevelLow; + private final ArrayList<PowerManagerInternal.LowPowerModeListener> mLowPowerModeListeners = new ArrayList<PowerManagerInternal.LowPowerModeListener>(); @@ -502,6 +508,7 @@ public final class PowerManagerService extends com.android.server.SystemService // Register for broadcasts from other components of the system. IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_BATTERY_CHANGED); + filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); mContext.registerReceiver(new BatteryReceiver(), filter, null, mHandler); filter = new IntentFilter(); @@ -638,7 +645,18 @@ public final class PowerManagerService extends com.android.server.SystemService final boolean lowPowerModeEnabled = Settings.Global.getInt(resolver, Settings.Global.LOW_POWER_MODE, 0) != 0; - if (lowPowerModeEnabled != mLowPowerModeEnabled) { + if (lowPowerModeEnabled != mLowPowerModeSetting) { + mLowPowerModeSetting = lowPowerModeEnabled; + updateLowPowerModeLocked(); + } + + mDirty |= DIRTY_SETTINGS; + } + + void updateLowPowerModeLocked() { + final boolean lowPowerModeEnabled = mLowPowerModeSetting || mBatteryLevelLow; + if (mLowPowerModeEnabled != lowPowerModeEnabled) { + mLowPowerModeEnabled = lowPowerModeEnabled; powerHintInternal(POWER_HINT_LOW_POWER_MODE, lowPowerModeEnabled ? 1 : 0); mLowPowerModeEnabled = lowPowerModeEnabled; BackgroundThread.getHandler().post(new Runnable() { @@ -652,11 +670,12 @@ public final class PowerManagerService extends com.android.server.SystemService for (int i=0; i<listeners.size(); i++) { listeners.get(i).onLowPowerModeChanged(lowPowerModeEnabled); } + Intent intent = new Intent(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED); + intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); + mContext.sendBroadcast(intent); } }); } - - mDirty |= DIRTY_SETTINGS; } private void handleSettingsChangedLocked() { @@ -1137,9 +1156,11 @@ public final class PowerManagerService extends com.android.server.SystemService if ((dirty & DIRTY_BATTERY_STATE) != 0) { final boolean wasPowered = mIsPowered; final int oldPlugType = mPlugType; + final boolean oldLevelLow = mBatteryLevelLow; mIsPowered = mBatteryService.isPowered(BatteryManager.BATTERY_PLUGGED_ANY); mPlugType = mBatteryService.getPlugType(); mBatteryLevel = mBatteryService.getBatteryLevel(); + mBatteryLevelLow = mBatteryService.getBatteryLevelLow(); if (DEBUG_SPEW) { Slog.d(TAG, "updateIsPoweredLocked: wasPowered=" + wasPowered @@ -1175,6 +1196,10 @@ public final class PowerManagerService extends com.android.server.SystemService mNotifier.onWirelessChargingStarted(); } } + + if (oldLevelLow != mBatteryLevelLow) { + updateLowPowerModeLocked(); + } } } @@ -1896,6 +1921,12 @@ public final class PowerManagerService extends com.android.server.SystemService } } + private boolean isLowPowerModeInternal() { + synchronized (mLock) { + return mLowPowerModeEnabled; + } + } + private void handleBatteryStateChangedLocked() { mDirty |= DIRTY_BATTERY_STATE; updatePowerStateLocked(); @@ -2764,6 +2795,16 @@ public final class PowerManagerService extends com.android.server.SystemService } } + @Override // Binder call + public boolean isPowerSaveMode() { + final long ident = Binder.clearCallingIdentity(); + try { + return isLowPowerModeInternal(); + } finally { + Binder.restoreCallingIdentity(ident); + } + } + /** * Reboots the device. * diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java index 35b7f99d8813..cfd09e5c8e17 100644 --- a/services/core/java/com/android/server/wm/AccessibilityController.java +++ b/services/core/java/com/android/server/wm/AccessibilityController.java @@ -541,7 +541,7 @@ final class AccessibilityController { if (isMagnifyingLocked()) { setMagnifiedRegionBorderShownLocked(false, false); final long delay = (long) (mLongAnimationDuration - * mWindowManagerService.mWindowAnimationScale); + * mWindowManagerService.getWindowAnimationScaleLocked()); Message message = mHandler.obtainMessage( MyHandler.MESSAGE_SHOW_MAGNIFIED_REGION_BOUNDS_IF_NEEDED); mHandler.sendMessageDelayed(message, delay); diff --git a/services/core/java/com/android/server/wm/AppWindowAnimator.java b/services/core/java/com/android/server/wm/AppWindowAnimator.java index 7fe895b57a90..63ae98e444a5 100644 --- a/services/core/java/com/android/server/wm/AppWindowAnimator.java +++ b/services/core/java/com/android/server/wm/AppWindowAnimator.java @@ -87,7 +87,7 @@ public class AppWindowAnimator { anim.initialize(width, height, width, height); } anim.restrictDuration(WindowManagerService.MAX_ANIMATION_DURATION); - anim.scaleCurrentDuration(mService.mTransitionAnimationScale); + anim.scaleCurrentDuration(mService.getTransitionAnimationScaleLocked()); int zorder = anim.getZAdjustment(); int adj = 0; if (zorder == Animation.ZORDER_TOP) { @@ -227,7 +227,8 @@ public class AppWindowAnimator { if (!animating) { if (WindowManagerService.DEBUG_ANIM) Slog.v( TAG, "Starting animation in " + mAppToken + - " @ " + currentTime + " scale=" + mService.mTransitionAnimationScale + " @ " + currentTime + " scale=" + + mService.getTransitionAnimationScaleLocked() + " allDrawn=" + mAppToken.allDrawn + " animating=" + animating); animation.setStartTime(currentTime); animating = true; diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java index ca9076f51496..3200b54f5c5d 100644 --- a/services/core/java/com/android/server/wm/Session.java +++ b/services/core/java/com/android/server/wm/Session.java @@ -17,6 +17,7 @@ package com.android.server.wm; import android.view.IWindowId; +import android.view.IWindowSessionCallback; import com.android.internal.view.IInputContext; import com.android.internal.view.IInputMethodClient; import com.android.internal.view.IInputMethodManager; @@ -54,6 +55,7 @@ import java.io.PrintWriter; final class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { final WindowManagerService mService; + final IWindowSessionCallback mCallback; final IInputMethodClient mClient; final IInputContext mInputContext; final int mUid; @@ -62,14 +64,17 @@ final class Session extends IWindowSession.Stub SurfaceSession mSurfaceSession; int mNumWindow = 0; boolean mClientDead = false; + float mLastReportedAnimatorScale; - public Session(WindowManagerService service, IInputMethodClient client, - IInputContext inputContext) { + public Session(WindowManagerService service, IWindowSessionCallback callback, + IInputMethodClient client, IInputContext inputContext) { mService = service; + mCallback = callback; mClient = client; mInputContext = inputContext; mUid = Binder.getCallingUid(); mPid = Binder.getCallingPid(); + mLastReportedAnimatorScale = service.getCurrentAnimatorScale(); StringBuilder sb = new StringBuilder(); sb.append("Session{"); sb.append(Integer.toHexString(System.identityHashCode(this))); @@ -464,6 +469,9 @@ final class Session extends IWindowSession.Stub if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i( WindowManagerService.TAG, " NEW SURFACE SESSION " + mSurfaceSession); mService.mSessions.add(this); + if (mLastReportedAnimatorScale != mService.getCurrentAnimatorScale()) { + mService.dispatchNewAnimatorScaleLocked(this); + } } mNumWindow++; } diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index da584d8ef59a..1db8b55196b6 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -24,6 +24,7 @@ import android.util.ArraySet; import android.util.TimeUtils; import android.view.IWindowId; +import android.view.IWindowSessionCallback; import android.view.WindowContentFrameStats; import com.android.internal.app.IBatteryStats; import com.android.internal.policy.PolicyManager; @@ -339,7 +340,7 @@ public class WindowManagerService extends IWindowManager.Stub /** * All currently active sessions with clients. */ - final HashSet<Session> mSessions = new HashSet<Session>(); + final ArraySet<Session> mSessions = new ArraySet<Session>(); /** * Mapping from an IWindow IBinder to the server's Window object. @@ -562,9 +563,10 @@ public class WindowManagerService extends IWindowManager.Stub PowerManager mPowerManager; PowerManagerInternal mPowerManagerInternal; - float mWindowAnimationScale = 1.0f; - float mTransitionAnimationScale = 1.0f; - float mAnimatorDurationScale = 1.0f; + float mWindowAnimationScaleSetting = 1.0f; + float mTransitionAnimationScaleSetting = 1.0f; + float mAnimatorDurationScaleSetting = 1.0f; + boolean mAnimationsDisabled = false; final InputManagerService mInputManager; final DisplayManagerInternal mDisplayManagerInternal; @@ -780,6 +782,19 @@ public class WindowManagerService extends IWindowManager.Stub mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE); mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class); mPowerManagerInternal.setPolicy(mPolicy); // TODO: register as local service instead + mPowerManagerInternal.registerLowPowerModeObserver( + new PowerManagerInternal.LowPowerModeListener() { + @Override + public void onLowPowerModeChanged(boolean enabled) { + synchronized (mWindowMap) { + if (mAnimationsDisabled != enabled) { + mAnimationsDisabled = enabled; + dispatchNewAnimatorScaleLocked(null); + } + } + } + }); + mAnimationsDisabled = mPowerManagerInternal.getLowPowerModeEnabled(); mScreenFrozenLock = mPowerManager.newWakeLock( PowerManager.PARTIAL_WAKE_LOCK, "SCREEN_FROZEN"); mScreenFrozenLock.setReferenceCounted(false); @@ -799,12 +814,12 @@ public class WindowManagerService extends IWindowManager.Stub ); // Get persisted window scale setting - mWindowAnimationScale = Settings.Global.getFloat(context.getContentResolver(), - Settings.Global.WINDOW_ANIMATION_SCALE, mWindowAnimationScale); - mTransitionAnimationScale = Settings.Global.getFloat(context.getContentResolver(), - Settings.Global.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale); + mWindowAnimationScaleSetting = Settings.Global.getFloat(context.getContentResolver(), + Settings.Global.WINDOW_ANIMATION_SCALE, mWindowAnimationScaleSetting); + mTransitionAnimationScaleSetting = Settings.Global.getFloat(context.getContentResolver(), + Settings.Global.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScaleSetting); setAnimatorDurationScale(Settings.Global.getFloat(context.getContentResolver(), - Settings.Global.ANIMATOR_DURATION_SCALE, mAnimatorDurationScale)); + Settings.Global.ANIMATOR_DURATION_SCALE, mAnimatorDurationScaleSetting)); // Track changes to DevicePolicyManager state so we can enable/disable keyguard. IntentFilter filter = new IntentFilter(); @@ -5188,9 +5203,9 @@ public class WindowManagerService extends IWindowManager.Stub scale = fixScale(scale); switch (which) { - case 0: mWindowAnimationScale = scale; break; - case 1: mTransitionAnimationScale = scale; break; - case 2: mAnimatorDurationScale = scale; break; + case 0: mWindowAnimationScaleSetting = scale; break; + case 1: mTransitionAnimationScaleSetting = scale; break; + case 2: mAnimatorDurationScaleSetting = scale; break; } // Persist setting @@ -5206,13 +5221,14 @@ public class WindowManagerService extends IWindowManager.Stub if (scales != null) { if (scales.length >= 1) { - mWindowAnimationScale = fixScale(scales[0]); + mWindowAnimationScaleSetting = fixScale(scales[0]); } if (scales.length >= 2) { - mTransitionAnimationScale = fixScale(scales[1]); + mTransitionAnimationScaleSetting = fixScale(scales[1]); } if (scales.length >= 3) { - setAnimatorDurationScale(fixScale(scales[2])); + mAnimatorDurationScaleSetting = fixScale(scales[2]); + dispatchNewAnimatorScaleLocked(null); } } @@ -5221,24 +5237,43 @@ public class WindowManagerService extends IWindowManager.Stub } private void setAnimatorDurationScale(float scale) { - mAnimatorDurationScale = scale; + mAnimatorDurationScaleSetting = scale; ValueAnimator.setDurationScale(scale); } + public float getWindowAnimationScaleLocked() { + return mAnimationsDisabled ? 0 : mWindowAnimationScaleSetting; + } + + public float getTransitionAnimationScaleLocked() { + return mAnimationsDisabled ? 0 : mTransitionAnimationScaleSetting; + } + @Override public float getAnimationScale(int which) { switch (which) { - case 0: return mWindowAnimationScale; - case 1: return mTransitionAnimationScale; - case 2: return mAnimatorDurationScale; + case 0: return mWindowAnimationScaleSetting; + case 1: return mTransitionAnimationScaleSetting; + case 2: return mAnimatorDurationScaleSetting; } return 0; } @Override public float[] getAnimationScales() { - return new float[] { mWindowAnimationScale, mTransitionAnimationScale, - mAnimatorDurationScale }; + return new float[] { mWindowAnimationScaleSetting, mTransitionAnimationScaleSetting, + mAnimatorDurationScaleSetting }; + } + + @Override + public float getCurrentAnimatorScale() { + synchronized(mWindowMap) { + return mAnimationsDisabled ? 0 : mAnimatorDurationScaleSetting; + } + } + + void dispatchNewAnimatorScaleLocked(Session session) { + mH.obtainMessage(H.NEW_ANIMATOR_SCALE, session).sendToTarget(); } @Override @@ -6094,7 +6129,7 @@ public class WindowManagerService extends IWindowManager.Stub && screenRotationAnimation.hasScreenshot()) { if (screenRotationAnimation.setRotationInTransaction( rotation, mFxSession, - MAX_ANIMATION_DURATION, mTransitionAnimationScale, + MAX_ANIMATION_DURATION, getTransitionAnimationScaleLocked(), displayInfo.logicalWidth, displayInfo.logicalHeight)) { scheduleAnimationLocked(); } @@ -7179,6 +7214,8 @@ public class WindowManagerService extends IWindowManager.Stub public static final int SHOW_DISPLAY_MASK = 33; public static final int ALL_WINDOWS_DRAWN = 34; + public static final int NEW_ANIMATOR_SCALE = 35; + @Override public void handleMessage(Message msg) { if (DEBUG_WINDOW_TRACE) { @@ -7429,11 +7466,12 @@ public class WindowManagerService extends IWindowManager.Stub case PERSIST_ANIMATION_SCALE: { Settings.Global.putFloat(mContext.getContentResolver(), - Settings.Global.WINDOW_ANIMATION_SCALE, mWindowAnimationScale); + Settings.Global.WINDOW_ANIMATION_SCALE, mWindowAnimationScaleSetting); Settings.Global.putFloat(mContext.getContentResolver(), - Settings.Global.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale); + Settings.Global.TRANSITION_ANIMATION_SCALE, + mTransitionAnimationScaleSetting); Settings.Global.putFloat(mContext.getContentResolver(), - Settings.Global.ANIMATOR_DURATION_SCALE, mAnimatorDurationScale); + Settings.Global.ANIMATOR_DURATION_SCALE, mAnimatorDurationScaleSetting); break; } @@ -7636,6 +7674,33 @@ public class WindowManagerService extends IWindowManager.Stub } } } + case NEW_ANIMATOR_SCALE: { + float scale = getCurrentAnimatorScale(); + ValueAnimator.setDurationScale(scale); + Session session = (Session)msg.obj; + if (session != null) { + try { + session.mCallback.onAnimatorScaleChanged(scale); + } catch (RemoteException e) { + } + } else { + ArrayList<IWindowSessionCallback> callbacks + = new ArrayList<IWindowSessionCallback>(); + synchronized (mWindowMap) { + for (int i=0; i<mSessions.size(); i++) { + callbacks.add(mSessions.valueAt(i).mCallback); + } + + } + for (int i=0; i<callbacks.size(); i++) { + try { + callbacks.get(i).onAnimatorScaleChanged(scale); + } catch (RemoteException e) { + } + } + } + } + break; } if (DEBUG_WINDOW_TRACE) { Slog.v(TAG, "handleMessage: exit"); @@ -7648,11 +7713,11 @@ public class WindowManagerService extends IWindowManager.Stub // ------------------------------------------------------------- @Override - public IWindowSession openSession(IInputMethodClient client, + public IWindowSession openSession(IWindowSessionCallback callback, IInputMethodClient client, IInputContext inputContext) { if (client == null) throw new IllegalArgumentException("null client"); if (inputContext == null) throw new IllegalArgumentException("null inputContext"); - Session session = new Session(this, client, inputContext); + Session session = new Session(this, callback, client, inputContext); return session; } @@ -8762,7 +8827,7 @@ public class WindowManagerService extends IWindowManager.Stub displayInfo.appWidth, displayInfo.appHeight, transit); appAnimator.thumbnailAnimation = anim; anim.restrictDuration(MAX_ANIMATION_DURATION); - anim.scaleCurrentDuration(mTransitionAnimationScale); + anim.scaleCurrentDuration(getTransitionAnimationScaleLocked()); Point p = new Point(); mAppTransition.getStartingPoint(p); appAnimator.thumbnailX = p.x; @@ -10070,7 +10135,7 @@ public class WindowManagerService extends IWindowManager.Stub mExitAnimId = mEnterAnimId = 0; } if (screenRotationAnimation.dismiss(mFxSession, MAX_ANIMATION_DURATION, - mTransitionAnimationScale, displayInfo.logicalWidth, + getTransitionAnimationScaleLocked(), displayInfo.logicalWidth, displayInfo.logicalHeight, mExitAnimId, mEnterAnimId)) { scheduleAnimationLocked(); } else { @@ -10405,13 +10470,10 @@ public class WindowManagerService extends IWindowManager.Stub void dumpSessionsLocked(PrintWriter pw, boolean dumpAll) { pw.println("WINDOW MANAGER SESSIONS (dumpsys window sessions)"); - if (mSessions.size() > 0) { - Iterator<Session> it = mSessions.iterator(); - while (it.hasNext()) { - Session s = it.next(); - pw.print(" Session "); pw.print(s); pw.println(':'); - s.dump(pw, " "); - } + for (int i=0; i<mSessions.size(); i++) { + Session s = mSessions.valueAt(i); + pw.print(" Session "); pw.print(s); pw.println(':'); + s.dump(pw, " "); } } @@ -10615,9 +10677,10 @@ public class WindowManagerService extends IWindowManager.Stub pw.print(" mLastWindowForcedOrientation="); pw.print(mLastWindowForcedOrientation); pw.print(" mForcedAppOrientation="); pw.println(mForcedAppOrientation); pw.print(" mDeferredRotationPauseCount="); pw.println(mDeferredRotationPauseCount); - pw.print(" mWindowAnimationScale="); pw.print(mWindowAnimationScale); - pw.print(" mTransitionWindowAnimationScale="); pw.print(mTransitionAnimationScale); - pw.print(" mAnimatorDurationScale="); pw.println(mAnimatorDurationScale); + pw.print(" Animation settings: disabled="); pw.print(mAnimationsDisabled); + pw.print(" window="); pw.print(mWindowAnimationScaleSetting); + pw.print(" transition="); pw.print(mTransitionAnimationScaleSetting); + pw.print(" animator="); pw.println(mAnimatorDurationScaleSetting); pw.print(" mTraversalScheduled="); pw.println(mTraversalScheduled); pw.print(" mStartingIconInTransition="); pw.print(mStartingIconInTransition); pw.print(" mSkipAppTransitionAnimation="); pw.println(mSkipAppTransitionAnimation); diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java index e257ebc90b48..bda10de01df0 100644 --- a/services/core/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java @@ -207,7 +207,7 @@ class WindowStateAnimator { mLocalAnimating = false; mAnimation = anim; mAnimation.restrictDuration(WindowManagerService.MAX_ANIMATION_DURATION); - mAnimation.scaleCurrentDuration(mService.mWindowAnimationScale); + mAnimation.scaleCurrentDuration(mService.getWindowAnimationScaleLocked()); // Start out animation gone if window is gone, or visible if window is visible. mTransformation.clear(); mTransformation.setAlpha(mLastHidden ? 0 : 1); @@ -283,7 +283,7 @@ class WindowStateAnimator { " @ " + currentTime + ": ww=" + mWin.mFrame.width() + " wh=" + mWin.mFrame.height() + " dw=" + mAnimDw + " dh=" + mAnimDh + - " scale=" + mService.mWindowAnimationScale); + " scale=" + mService.getWindowAnimationScaleLocked()); mAnimation.initialize(mWin.mFrame.width(), mWin.mFrame.height(), mAnimDw, mAnimDh); final DisplayInfo displayInfo = displayContent.getDisplayInfo(); diff --git a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java index cfe8e1580851..2f40003cc784 100644 --- a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java +++ b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java @@ -195,8 +195,8 @@ public class IWindowManagerImpl implements IWindowManager { } @Override - public IWindowSession openSession(IInputMethodClient arg0, IInputContext arg1) - throws RemoteException { + public IWindowSession openSession(IWindowSessionCallback argn1, IInputMethodClient arg0, + IInputContext arg1) throws RemoteException { // TODO Auto-generated method stub return null; } @@ -276,6 +276,11 @@ public class IWindowManagerImpl implements IWindowManager { } @Override + public float getCurrentAnimatorScale() throws RemoteException { + return 0; + } + + @Override public void setAppGroupId(IBinder arg0, int arg1) throws RemoteException { // TODO Auto-generated method stub |