am 0bac8bcb: Merge "Animations for user switching." into jb-mr1-dev

* commit '0bac8bcbcc281afc041f621a156fd21549d686e1':
  Animations for user switching.
This commit is contained in:
Dianne Hackborn
2012-09-10 21:06:38 -07:00
committed by Android Git Automerger
16 changed files with 2010 additions and 1830 deletions

View File

@@ -107,6 +107,9 @@ interface IWindowManager
IBinder freezeThisOneIfNeeded);
void setNewConfiguration(in Configuration config);
void startFreezingScreen(int exitAnim, int enterAnim);
void stopFreezingScreen();
// these require DISABLE_KEYGUARD permission
void disableKeyguard(IBinder token, String tag);
void reenableKeyguard(IBinder token);

View File

@@ -22,7 +22,7 @@ import android.util.AttributeSet;
/**
* An animation that controls the rotation of an object. This rotation takes
* place int the X-Y plane. You can specify the point to use for the center of
* place in the X-Y plane. You can specify the point to use for the center of
* the rotation, where (0,0) is the top left point. If not specified, (0,0) is
* the default rotation point.
*

View File

@@ -1265,6 +1265,13 @@
android:description="@string/permdesc_manageAppTokens"
android:protectionLevel="signature" />
<!-- @hide Allows the application to temporarily freeze the screen for a
full-screen transition. -->
<permission android:name="android.permission.FREEZE_SCREEN"
android:label="@string/permlab_freezeScreen"
android:description="@string/permdesc_freezeScreen"
android:protectionLevel="signature" />
<!-- Allows an application to inject user events (keys, touch, trackball)
into the event stream and deliver them to ANY window. Without this
permission, you can only deliver events to windows in your own process.

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/* Copyright 20012, 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.
*/
-->
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="100%p" android:toXDelta="0"
android:duration="500"
android:interpolator="@interpolator/decelerate_quad" />
<alpha android:fromAlpha="0.0" android:toAlpha="1.0"
android:duration="500"
android:interpolator="@interpolator/decelerate_quad" />
</set>

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/* Copyright 20012, 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.
*/
-->
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="0" android:toXDelta="-100%p"
android:duration="500"
android:interpolator="@interpolator/decelerate_quad" />
<alpha android:fromAlpha="1.0" android:toAlpha="0.0"
android:duration="500"
android:interpolator="@interpolator/decelerate_quad" />
</set>

File diff suppressed because it is too large Load Diff

View File

@@ -780,6 +780,12 @@
create and manage their own tokens, bypassing their normal
Z-ordering. Should never be needed for normal apps.</string>
<!-- [CHAR LIMIT=NONE] Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_freezeScreen">freeze screen</string>
<!-- [CHAR LIMIT=NONE] Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_freezeScreen">Allows the application to temporarily freeze
the screen for a full-screen transition.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_injectEvents">press keys and control buttons</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->

File diff suppressed because it is too large Load Diff

View File

@@ -13876,6 +13876,9 @@ public final class ActivityManagerService extends ActivityManagerNative
return true;
}
mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
R.anim.screen_user_enter);
// If the user we are switching to is not currently started, then
// we need to start it now.
if (mStartedUsers.get(userId) == null) {
@@ -13889,6 +13892,8 @@ public final class ActivityManagerService extends ActivityManagerNative
boolean haveActivities = mMainStack.switchUser(userId);
if (!haveActivities) {
startHomeActivityLocked(userId, mStartedUsers.get(userId));
} else {
mMainStack.addStartingUserLocked(mStartedUsers.get(userId));
}
}
@@ -13919,6 +13924,7 @@ public final class ActivityManagerService extends ActivityManagerNative
android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
false, false, MY_PID, Process.SYSTEM_UID, userId);
}
mWindowManager.stopFreezingScreen();
}
}

View File

@@ -48,6 +48,7 @@ class ScreenRotationAnimation {
BlackFrame mExitingBlackFrame;
BlackFrame mEnteringBlackFrame;
int mWidth, mHeight;
int mExitAnimId, mEnterAnimId;
int mOriginalRotation;
int mOriginalWidth, mOriginalHeight;
@@ -188,9 +189,12 @@ class ScreenRotationAnimation {
}
public ScreenRotationAnimation(Context context, Display display, SurfaceSession session,
boolean inTransaction, int originalWidth, int originalHeight, int originalRotation) {
boolean inTransaction, int originalWidth, int originalHeight, int originalRotation,
int exitAnim, int enterAnim) {
mContext = context;
mDisplay = display;
mExitAnimId = exitAnim;
mEnterAnimId = enterAnim;
// Screenshot does NOT include rotation!
if (originalRotation == Surface.ROTATION_90
@@ -375,58 +379,68 @@ class ScreenRotationAnimation {
+ finalWidth + " finalHeight=" + finalHeight
+ " origWidth=" + mOriginalWidth + " origHeight=" + mOriginalHeight);
switch (delta) {
case Surface.ROTATION_0:
mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
com.android.internal.R.anim.screen_rotate_0_exit);
mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
com.android.internal.R.anim.screen_rotate_0_enter);
if (USE_CUSTOM_BLACK_FRAME) {
mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
com.android.internal.R.anim.screen_rotate_0_frame);
}
break;
case Surface.ROTATION_90:
mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
com.android.internal.R.anim.screen_rotate_plus_90_exit);
mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
com.android.internal.R.anim.screen_rotate_plus_90_enter);
if (USE_CUSTOM_BLACK_FRAME) {
mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
com.android.internal.R.anim.screen_rotate_plus_90_frame);
}
break;
case Surface.ROTATION_180:
mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
com.android.internal.R.anim.screen_rotate_180_exit);
mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
com.android.internal.R.anim.screen_rotate_180_enter);
mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
com.android.internal.R.anim.screen_rotate_180_frame);
break;
case Surface.ROTATION_270:
mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
com.android.internal.R.anim.screen_rotate_minus_90_exit);
mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
com.android.internal.R.anim.screen_rotate_minus_90_enter);
if (USE_CUSTOM_BLACK_FRAME) {
mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
com.android.internal.R.anim.screen_rotate_minus_90_frame);
}
break;
final boolean customAnim;
if (mExitAnimId != 0 && mEnterAnimId != 0) {
customAnim = true;
mRotateExitAnimation = AnimationUtils.loadAnimation(mContext, mExitAnimId);
mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext, mEnterAnimId);
} else {
customAnim = false;
switch (delta) {
case Surface.ROTATION_0:
mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
com.android.internal.R.anim.screen_rotate_0_exit);
mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
com.android.internal.R.anim.screen_rotate_0_enter);
if (USE_CUSTOM_BLACK_FRAME) {
mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
com.android.internal.R.anim.screen_rotate_0_frame);
}
break;
case Surface.ROTATION_90:
mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
com.android.internal.R.anim.screen_rotate_plus_90_exit);
mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
com.android.internal.R.anim.screen_rotate_plus_90_enter);
if (USE_CUSTOM_BLACK_FRAME) {
mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
com.android.internal.R.anim.screen_rotate_plus_90_frame);
}
break;
case Surface.ROTATION_180:
mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
com.android.internal.R.anim.screen_rotate_180_exit);
mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
com.android.internal.R.anim.screen_rotate_180_enter);
if (USE_CUSTOM_BLACK_FRAME) {
mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
com.android.internal.R.anim.screen_rotate_180_frame);
}
break;
case Surface.ROTATION_270:
mRotateExitAnimation = AnimationUtils.loadAnimation(mContext,
com.android.internal.R.anim.screen_rotate_minus_90_exit);
mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext,
com.android.internal.R.anim.screen_rotate_minus_90_enter);
if (USE_CUSTOM_BLACK_FRAME) {
mRotateFrameAnimation = AnimationUtils.loadAnimation(mContext,
com.android.internal.R.anim.screen_rotate_minus_90_frame);
}
break;
}
}
// Compute partial steps between original and final sizes. These
// are used for the dimensions of the exiting and entering elements,
// so they are never stretched too significantly.
final int halfWidth = (finalWidth + mOriginalWidth) / 2;
final int halfHeight = (finalHeight + mOriginalHeight) / 2;
// Initialize the animations. This is a hack, redefining what "parent"
// means to allow supplying the last and next size. In this definition
// "%p" is the original (let's call it "previous") size, and "%" is the
// screen's current/new size.
if (TWO_PHASE_ANIMATION && firstStart) {
// Compute partial steps between original and final sizes. These
// are used for the dimensions of the exiting and entering elements,
// so they are never stretched too significantly.
final int halfWidth = (finalWidth + mOriginalWidth) / 2;
final int halfHeight = (finalHeight + mOriginalHeight) / 2;
if (DEBUG_STATE) Slog.v(TAG, "Initializing start and finish animations");
mStartEnterAnimation.initialize(finalWidth, finalHeight,
halfWidth, halfHeight);
@@ -510,7 +524,7 @@ class ScreenRotationAnimation {
}
}
if (mExitingBlackFrame == null) {
if (!customAnim && mExitingBlackFrame == null) {
if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
WindowManagerService.TAG,
">>> OPEN TRANSACTION ScreenRotationAnimation.startAnimation");
@@ -540,7 +554,7 @@ class ScreenRotationAnimation {
}
}
if (false && mEnteringBlackFrame == null) {
if (customAnim && mEnteringBlackFrame == null) {
if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
WindowManagerService.TAG,
">>> OPEN TRANSACTION ScreenRotationAnimation.startAnimation");

View File

@@ -461,6 +461,7 @@ public class WindowManagerService extends IWindowManager.Stub
boolean mDisplayFrozen = false;
boolean mWaitingForConfig = false;
boolean mWindowsFreezingScreen = false;
boolean mClientFreezingScreen = false;
int mAppsFreezingScreen = 0;
int mLastWindowForcedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
@@ -3915,7 +3916,7 @@ public class WindowManagerService extends IWindowManager.Stub
if (currentConfig.diff(mTempConfiguration) != 0) {
mWaitingForConfig = true;
getDefaultDisplayContent().layoutNeeded = true;
startFreezingDisplayLocked(false);
startFreezingDisplayLocked(false, 0, 0);
config = new Configuration(mTempConfiguration);
}
}
@@ -4644,7 +4645,7 @@ public class WindowManagerService extends IWindowManager.Stub
wtoken.mAppAnimator.freezingScreen = true;
mAppsFreezingScreen++;
if (mAppsFreezingScreen == 1) {
startFreezingDisplayLocked(false);
startFreezingDisplayLocked(false, 0, 0);
mH.removeMessages(H.APP_FREEZE_TIMEOUT);
mH.sendMessageDelayed(mH.obtainMessage(H.APP_FREEZE_TIMEOUT),
5000);
@@ -5153,6 +5154,49 @@ public class WindowManagerService extends IWindowManager.Stub
// Misc IWindowSession methods
// -------------------------------------------------------------
@Override
public void startFreezingScreen(int exitAnim, int enterAnim) {
if (!checkCallingPermission(android.Manifest.permission.FREEZE_SCREEN,
"startFreezingScreen()")) {
throw new SecurityException("Requires FREEZE_SCREEN permission");
}
synchronized(mWindowMap) {
if (!mClientFreezingScreen) {
mClientFreezingScreen = true;
final long origId = Binder.clearCallingIdentity();
try {
startFreezingDisplayLocked(false, exitAnim, enterAnim);
mH.removeMessages(H.CLIENT_FREEZE_TIMEOUT);
mH.sendMessageDelayed(mH.obtainMessage(H.CLIENT_FREEZE_TIMEOUT),
5000);
} finally {
Binder.restoreCallingIdentity(origId);
}
}
}
}
@Override
public void stopFreezingScreen() {
if (!checkCallingPermission(android.Manifest.permission.FREEZE_SCREEN,
"stopFreezingScreen()")) {
throw new SecurityException("Requires FREEZE_SCREEN permission");
}
synchronized(mWindowMap) {
if (mClientFreezingScreen) {
mClientFreezingScreen = false;
final long origId = Binder.clearCallingIdentity();
try {
stopFreezingDisplayLocked();
} finally {
Binder.restoreCallingIdentity(origId);
}
}
}
}
@Override
public void disableKeyguard(IBinder token, String tag) {
if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
@@ -5947,7 +5991,7 @@ public class WindowManagerService extends IWindowManager.Stub
mH.sendMessageDelayed(mH.obtainMessage(H.WINDOW_FREEZE_TIMEOUT), 2000);
mWaitingForConfig = true;
getDefaultDisplayContent().layoutNeeded = true;
startFreezingDisplayLocked(inTransaction);
startFreezingDisplayLocked(inTransaction, 0, 0);
// We need to update our screen size information to match the new
// rotation. Note that this is redundant with the later call to
@@ -7207,6 +7251,8 @@ public class WindowManagerService extends IWindowManager.Stub
public static final int DO_DISPLAY_REMOVED = 32;
public static final int DO_DISPLAY_CHANGED = 33;
public static final int CLIENT_FREEZE_TIMEOUT = 34;
public static final int ANIMATOR_WHAT_OFFSET = 100000;
public static final int SET_TRANSPARENT_REGION = ANIMATOR_WHAT_OFFSET + 1;
public static final int CLEAR_PENDING_ACTIONS = ANIMATOR_WHAT_OFFSET + 2;
@@ -7533,6 +7579,16 @@ public class WindowManagerService extends IWindowManager.Stub
break;
}
case CLIENT_FREEZE_TIMEOUT: {
synchronized (mWindowMap) {
if (mClientFreezingScreen) {
mClientFreezingScreen = false;
stopFreezingDisplayLocked();
}
}
break;
}
case SEND_NEW_CONFIGURATION: {
removeMessages(SEND_NEW_CONFIGURATION);
sendNewConfiguration();
@@ -7949,7 +8005,7 @@ public class WindowManagerService extends IWindowManager.Stub
if (configChanged) {
mWaitingForConfig = true;
startFreezingDisplayLocked(false);
startFreezingDisplayLocked(false, 0, 0);
mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
}
@@ -9859,7 +9915,8 @@ public class WindowManagerService extends IWindowManager.Stub
return result;
}
private void startFreezingDisplayLocked(boolean inTransaction) {
private void startFreezingDisplayLocked(boolean inTransaction,
int exitAnim, int enterAnim) {
if (mDisplayFrozen) {
return;
}
@@ -9901,7 +9958,8 @@ public class WindowManagerService extends IWindowManager.Stub
final DisplayInfo displayInfo = displayContent.getDisplayInfo();
mAnimator.mScreenRotationAnimation = new ScreenRotationAnimation(mContext,
display, mFxSession, inTransaction, displayInfo.logicalWidth,
displayInfo.logicalHeight, display.getRotation());
displayInfo.logicalHeight, display.getRotation(),
exitAnim, enterAnim);
}
}
@@ -9910,16 +9968,19 @@ public class WindowManagerService extends IWindowManager.Stub
return;
}
if (mWaitingForConfig || mAppsFreezingScreen > 0 || mWindowsFreezingScreen) {
if (mWaitingForConfig || mAppsFreezingScreen > 0 || mWindowsFreezingScreen
|| mClientFreezingScreen) {
if (DEBUG_ORIENTATION) Slog.d(TAG,
"stopFreezingDisplayLocked: Returning mWaitingForConfig=" + mWaitingForConfig
+ ", mAppsFreezingScreen=" + mAppsFreezingScreen
+ ", mWindowsFreezingScreen=" + mWindowsFreezingScreen);
+ ", mWindowsFreezingScreen=" + mWindowsFreezingScreen
+ ", mClientFreezingScreen=" + mClientFreezingScreen);
return;
}
mDisplayFrozen = false;
mH.removeMessages(H.APP_FREEZE_TIMEOUT);
mH.removeMessages(H.CLIENT_FREEZE_TIMEOUT);
if (PROFILE_ORIENTATION) {
Debug.stopMethodTracing();
}
@@ -10440,9 +10501,10 @@ public class WindowManagerService extends IWindowManager.Stub
}
pw.print(" mTransactionSequence="); pw.println(mTransactionSequence);
pw.print(" mDisplayFrozen="); pw.print(mDisplayFrozen);
pw.print(" mWindowsFreezingScreen="); pw.print(mWindowsFreezingScreen);
pw.print(" mAppsFreezingScreen="); pw.print(mAppsFreezingScreen);
pw.print(" mWaitingForConfig="); pw.println(mWaitingForConfig);
pw.print(" windows="); pw.print(mWindowsFreezingScreen);
pw.print(" client="); pw.print(mClientFreezingScreen);
pw.print(" apps="); pw.print(mAppsFreezingScreen);
pw.print(" waitingForConfig="); pw.println(mWaitingForConfig);
pw.print(" mRotation="); pw.print(mRotation);
pw.print(" mAltOrientation="); pw.println(mAltOrientation);
pw.print(" mLastWindowForcedOrientation="); pw.print(mLastWindowForcedOrientation);

View File

@@ -106,6 +106,16 @@ public class BridgeWindowManager implements IWindowManager {
}
@Override
public void startFreezingScreen(int exitAnim, int enterAnim) {
// TODO Auto-generated method stub
}
@Override
public void stopFreezingScreen() {
// TODO Auto-generated method stub
}
@Override
public void disableKeyguard(IBinder arg0, String arg1) throws RemoteException {
// TODO Auto-generated method stub