summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/ActivityOptions.java25
-rw-r--r--core/java/android/view/IWindowManager.aidl2
-rw-r--r--core/java/android/view/WindowManagerPolicy.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java16
-rwxr-xr-xservices/core/java/com/android/server/am/ActivityRecord.java3
-rw-r--r--services/core/java/com/android/server/am/ActivityStack.java2
-rw-r--r--services/core/java/com/android/server/policy/PhoneWindowManager.java8
-rw-r--r--services/core/java/com/android/server/wm/AppWindowToken.java1
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java3
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java8
-rw-r--r--tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java2
-rw-r--r--tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java3
13 files changed, 82 insertions, 9 deletions
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index ccc37d72e846..d9a46903ee38 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -193,6 +193,7 @@ public class ActivityOptions {
= "android:activity.exitCoordinatorIndex";
private static final String KEY_USAGE_TIME_REPORT = "android:activity.usageTimeReport";
+ private static final String KEY_ROTATION_ANIMATION_HINT = "android:activity.rotationAnimationHint";
/** @hide */
public static final int ANIM_NONE = 0;
@@ -244,6 +245,7 @@ public class ActivityOptions {
private int mDockCreateMode = DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
private boolean mTaskOverlay;
private AppTransitionAnimationSpec mAnimSpecs[];
+ private int mRotationAnimationHint = -1;
/**
* Create an ActivityOptions specifying a custom animation to run when
@@ -863,6 +865,7 @@ public class ActivityOptions {
mAnimationFinishedListener = IRemoteCallback.Stub.asInterface(
opts.getBinder(KEY_ANIMATION_FINISHED_LISTENER));
}
+ mRotationAnimationHint = opts.getInt(KEY_ROTATION_ANIMATION_HINT);
}
/**
@@ -1216,6 +1219,7 @@ public class ActivityOptions {
if (mAnimationFinishedListener != null) {
b.putBinder(KEY_ANIMATION_FINISHED_LISTENER, mAnimationFinishedListener.asBinder());
}
+ b.putInt(KEY_ROTATION_ANIMATION_HINT, mRotationAnimationHint);
return b;
}
@@ -1262,6 +1266,27 @@ public class ActivityOptions {
return null;
}
+ /**
+ * Returns the rotation animation set by {@link setRotationAnimationHint} or -1
+ * if unspecified.
+ * @hide
+ */
+ public int getRotationAnimationHint() {
+ return mRotationAnimationHint;
+ }
+
+
+ /**
+ * Set a rotation animation to be used if launching the activity
+ * triggers an orientation change, or -1 to clear. See
+ * {@link android.view.WindowManager.LayoutParams} for rotation
+ * animation values.
+ * @hide
+ */
+ public void setRotationAnimationHint(int hint) {
+ mRotationAnimationHint = hint;
+ }
+
/** @hide */
@Override
public String toString() {
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 72126d0329a3..e3ff54d40316 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -112,7 +112,7 @@ interface IWindowManager
int requestedOrientation, boolean fullscreen, boolean showWhenLocked, int userId,
int configChanges, boolean voiceInteraction, boolean launchTaskBehind,
in Rect taskBounds, in Configuration configuration, int taskResizeMode,
- boolean alwaysFocusable, boolean homeTask, int targetSdkVersion);
+ boolean alwaysFocusable, boolean homeTask, int targetSdkVersion, int rotationAnimationHint);
/**
*
* @param token The token we are adding to the input task Id.
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index a8afaf20a1c5..9a8c8a86499a 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -416,6 +416,8 @@ public interface WindowManagerPolicy {
* screen with other application windows.
*/
public boolean isInMultiWindowMode();
+
+ public int getRotationAnimationHint();
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index 772c76642b9e..a98601a33300 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -18,6 +18,7 @@ package com.android.systemui.statusbar.phone;
import android.app.ActivityManager;
import android.app.ActivityManagerNative;
+import android.app.ActivityOptions;
import android.app.admin.DevicePolicyManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
@@ -44,6 +45,7 @@ import android.util.Log;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
+import android.view.WindowManager;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.FrameLayout;
import android.widget.TextView;
@@ -448,12 +450,24 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
@Override
public void run() {
int result = ActivityManager.START_CANCELED;
+
+ // Normally an activity will set it's requested rotation
+ // animation on its window. However when launching an activity
+ // causes the orientation to change this is too late. In these cases
+ // the default animation is used. This doesn't look good for
+ // the camera (as it rotates the camera contents out of sync
+ // with physical reality). So, we ask the WindowManager to
+ // force the crossfade animation if an orientation change
+ // happens to occur during the launch.
+ ActivityOptions o = ActivityOptions.makeBasic();
+ o.setRotationAnimationHint(
+ WindowManager.LayoutParams.ROTATION_ANIMATION_CROSSFADE);
try {
result = ActivityManagerNative.getDefault().startActivityAsUser(
null, getContext().getBasePackageName(),
intent,
intent.resolveTypeIfNeeded(getContext().getContentResolver()),
- null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, null,
+ null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, o.toBundle(),
UserHandle.CURRENT.getIdentifier());
} catch (RemoteException e) {
Log.w(TAG, "Unable to start camera activity", e);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 4de769db61c6..fcb1da0033bb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -22,6 +22,7 @@ import android.animation.AnimatorListenerAdapter;
import android.annotation.NonNull;
import android.app.ActivityManager;
import android.app.ActivityManagerNative;
+import android.app.ActivityOptions;
import android.app.IActivityManager;
import android.app.Notification;
import android.app.PendingIntent;
@@ -3322,13 +3323,26 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
intent.setFlags(
Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
int result = ActivityManager.START_CANCELED;
+ ActivityOptions options = new ActivityOptions(getActivityOptions());
+ if (intent == KeyguardBottomAreaView.INSECURE_CAMERA_INTENT) {
+ // Normally an activity will set it's requested rotation
+ // animation on its window. However when launching an activity
+ // causes the orientation to change this is too late. In these cases
+ // the default animation is used. This doesn't look good for
+ // the camera (as it rotates the camera contents out of sync
+ // with physical reality). So, we ask the WindowManager to
+ // force the crossfade animation if an orientation change
+ // happens to occur during the launch.
+ options.setRotationAnimationHint(
+ WindowManager.LayoutParams.ROTATION_ANIMATION_CROSSFADE);
+ }
try {
result = ActivityManagerNative.getDefault().startActivityAsUser(
null, mContext.getBasePackageName(),
intent,
intent.resolveTypeIfNeeded(mContext.getContentResolver()),
null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null,
- getActivityOptions(), UserHandle.CURRENT.getIdentifier());
+ options.toBundle(), UserHandle.CURRENT.getIdentifier());
} catch (RemoteException e) {
Log.w(TAG, "Unable to start activity", e);
}
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 50b6c0c7502f..6e40cfff5411 100755
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -221,6 +221,8 @@ final class ActivityRecord {
boolean pendingVoiceInteractionStart; // Waiting for activity-invoked voice session
IVoiceInteractionSession voiceSession; // Voice interaction session for this activity
+ int mRotationAnimationHint;
+
private static String startingWindowStateToString(int state) {
switch (state) {
case STARTING_WINDOW_NOT_SHOWN:
@@ -635,6 +637,7 @@ final class ActivityRecord {
if (options != null) {
pendingOptions = options;
mLaunchTaskBehind = pendingOptions.getLaunchTaskBehind();
+ mRotationAnimationHint = pendingOptions.getRotationAnimationHint();
PendingIntent usageReport = pendingOptions.getUsageTimeReport();
if (usageReport != null) {
appTimeTracker = new AppTimeTracker(usageReport);
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 6d229466ebf9..fc649a1ea140 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -5199,7 +5199,7 @@ final class ActivityStack {
(r.info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0, r.userId, r.info.configChanges,
task.voiceSession != null, r.mLaunchTaskBehind, bounds, task.mOverrideConfig,
task.mResizeMode, r.isAlwaysFocusable(), task.isHomeTask(),
- r.appInfo.targetSdkVersion);
+ r.appInfo.targetSdkVersion, r.mRotationAnimationHint);
r.taskConfigOverride = task.mOverrideConfig;
}
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 22521b916ba8..0e732271403b 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -2874,8 +2874,12 @@ public class PhoneWindowManager implements WindowManagerPolicy {
+ mTopFullscreenOpaqueWindowState + " rotationAnimation="
+ (mTopFullscreenOpaqueWindowState == null ?
"0" : mTopFullscreenOpaqueWindowState.getAttrs().rotationAnimation));
- if (mTopFullscreenOpaqueWindowState != null && mTopIsFullscreen) {
- switch (mTopFullscreenOpaqueWindowState.getAttrs().rotationAnimation) {
+ if (mTopFullscreenOpaqueWindowState != null) {
+ int animationHint = mTopFullscreenOpaqueWindowState.getRotationAnimationHint();
+ if (animationHint < 0 && mTopIsFullscreen) {
+ animationHint = mTopFullscreenOpaqueWindowState.getAttrs().rotationAnimation;
+ }
+ switch (animationHint) {
case ROTATION_ANIMATION_CROSSFADE:
anim[0] = R.anim.rotation_animation_xfade_exit;
anim[1] = R.anim.rotation_animation_enter;
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index edcc32e5b587..776a1753aa72 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -132,6 +132,7 @@ class AppWindowToken extends WindowToken {
boolean mAlwaysFocusable;
boolean mAppStopped;
+ int mRotationAnimationHint;
int mPendingRelaunchCount;
ArrayDeque<Rect> mFrozenBounds = new ArrayDeque<>();
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index b8accf547686..59ddab08c4c8 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -3429,7 +3429,7 @@ public class WindowManagerService extends IWindowManager.Stub
int requestedOrientation, boolean fullscreen, boolean showForAllUsers, int userId,
int configChanges, boolean voiceInteraction, boolean launchTaskBehind,
Rect taskBounds, Configuration config, int taskResizeMode, boolean alwaysFocusable,
- boolean homeTask, int targetSdkVersion) {
+ boolean homeTask, int targetSdkVersion, int rotationAnimationHint) {
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
"addAppToken()")) {
throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
@@ -3467,6 +3467,7 @@ public class WindowManagerService extends IWindowManager.Stub
atoken.mAlwaysFocusable = alwaysFocusable;
if (DEBUG_TOKEN_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "addAppToken: " + atoken
+ " to stack=" + stackId + " task=" + taskId + " at " + addPos);
+ atoken.mRotationAnimationHint = rotationAnimationHint;
Task task = mTaskIdToTask.get(taskId);
if (task == null) {
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 99fec7bdb791..1ac3d44c7a45 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -2908,4 +2908,12 @@ final class WindowState implements WindowManagerPolicy.WindowState {
boolean shouldBeReplacedWithChildren() {
return isChildWindow() || mAttrs.type == TYPE_APPLICATION;
}
+
+ public int getRotationAnimationHint() {
+ if (mAppToken != null) {
+ return mAppToken.mRotationAnimationHint;
+ } else {
+ return -1;
+ }
+ }
}
diff --git a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
index a726a15f7cc2..063dd8631565 100644
--- a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
+++ b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
@@ -93,7 +93,7 @@ public class WindowManagerPermissionTests extends TestCase {
try {
mWm.addAppToken(0, null, 0, 0, 0, false, false, 0, 0, false, false, null,
- Configuration.EMPTY, 0, false, false, 0);
+ Configuration.EMPTY, 0, false, false, 0, -1);
fail("IWindowManager.addAppToken did not throw SecurityException as"
+ " expected");
} catch (SecurityException e) {
diff --git a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
index 04a59bcfb5ae..4e4da8bb3f08 100644
--- a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
+++ b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
@@ -78,7 +78,8 @@ public class IWindowManagerImpl implements IWindowManager {
@Override
public void addAppToken(int arg0, IApplicationToken arg1, int arg2, int arg3, int arg4,
boolean arg5, boolean arg6, int arg7, int arg8, boolean arg9, boolean arg10,
- Rect arg11, Configuration arg12, int arg13, boolean arg14, boolean arg15, int arg16)
+ Rect arg11, Configuration arg12, int arg13, boolean arg14, boolean arg15, int arg16,
+ int arg17)
throws RemoteException {
// TODO Auto-generated method stub
}