Merge "Cross profile apps animation part 2"
This commit is contained in:
committed by
Android (Google) Code Review
commit
bb454e993c
41
core/res/res/anim/cross_profile_apps_thumbnail_enter.xml
Normal file
41
core/res/res/anim/cross_profile_apps_thumbnail_enter.xml
Normal file
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
** Copyright 2018, 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.
|
||||
*/
|
||||
-->
|
||||
<!-- This should be kept in sync with task_open_enter.xml -->
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shareInterpolator="false" android:zAdjustment="top">
|
||||
|
||||
<alpha android:fromAlpha="0" android:toAlpha="1.0"
|
||||
android:startOffset="300"
|
||||
android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
|
||||
android:interpolator="@interpolator/decelerate_quart"
|
||||
android:duration="167"/>
|
||||
|
||||
<translate android:fromYDelta="110%" android:toYDelta="0"
|
||||
android:startOffset="300"
|
||||
android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
|
||||
android:interpolator="@interpolator/decelerate_quint"
|
||||
android:duration="417"/>
|
||||
|
||||
<!-- To keep the thumbnail around longer -->
|
||||
<alpha android:fromAlpha="1.0" android:toAlpha="0"
|
||||
android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
|
||||
android:interpolator="@interpolator/decelerate_quint"
|
||||
android:startOffset="717"
|
||||
android:duration="200"/>
|
||||
</set>
|
||||
@@ -16,7 +16,7 @@
|
||||
** limitations under the License.
|
||||
*/
|
||||
-->
|
||||
|
||||
<!-- This should in sync with task_open_enter_cross_profile_apps.xml -->
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shareInterpolator="false" android:zAdjustment="top">
|
||||
|
||||
|
||||
41
core/res/res/anim/task_open_enter_cross_profile_apps.xml
Normal file
41
core/res/res/anim/task_open_enter_cross_profile_apps.xml
Normal file
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
** Copyright 2018, 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.
|
||||
*/
|
||||
-->
|
||||
<!-- This should in sync with task_open_enter.xml -->
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shareInterpolator="false" android:zAdjustment="top">
|
||||
|
||||
<alpha android:fromAlpha="0" android:toAlpha="1.0"
|
||||
android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
|
||||
android:interpolator="@interpolator/decelerate_quart"
|
||||
android:startOffset="300"
|
||||
android:duration="167"/>
|
||||
|
||||
<translate android:fromYDelta="110%" android:toYDelta="0"
|
||||
android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
|
||||
android:interpolator="@interpolator/decelerate_quint"
|
||||
android:startOffset="300"
|
||||
android:duration="417"/>
|
||||
|
||||
<!-- To keep the transition around longer for the thumbnail, should be kept in sync with
|
||||
cross_profile_apps_thumbmail.xml -->
|
||||
<alpha android:fromAlpha="1.0" android:toAlpha="1.0"
|
||||
android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
|
||||
android:startOffset="717"
|
||||
android:duration="200"/>
|
||||
</set>
|
||||
@@ -631,4 +631,8 @@
|
||||
|
||||
<!-- Default dialog corner radius -->
|
||||
<dimen name="dialog_corner_radius">2dp</dimen>
|
||||
|
||||
<!-- Size of thumbnail used in the cross profile apps animation -->
|
||||
<dimen name="cross_profile_apps_thumbnail_size">72dp</dimen>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -1578,8 +1578,10 @@
|
||||
<java-symbol type="anim" name="voice_activity_close_enter" />
|
||||
<java-symbol type="anim" name="voice_activity_open_exit" />
|
||||
<java-symbol type="anim" name="voice_activity_open_enter" />
|
||||
<java-symbol type="anim" name="activity_open_exit" />
|
||||
<java-symbol type="anim" name="activity_open_enter" />
|
||||
<java-symbol type="anim" name="task_open_exit" />
|
||||
<java-symbol type="anim" name="task_open_enter" />
|
||||
<java-symbol type="anim" name="cross_profile_apps_thumbnail_enter" />
|
||||
<java-symbol type="anim" name="task_open_enter_cross_profile_apps" />
|
||||
|
||||
<java-symbol type="array" name="config_autoRotationTiltTolerance" />
|
||||
<java-symbol type="array" name="config_keyboardTapVibePattern" />
|
||||
@@ -1726,6 +1728,7 @@
|
||||
<java-symbol type="style" name="Theme.ExpandedMenu" />
|
||||
<java-symbol type="string" name="forward_intent_to_owner" />
|
||||
<java-symbol type="string" name="forward_intent_to_work" />
|
||||
<java-symbol type="dimen" name="cross_profile_apps_thumbnail_size" />
|
||||
|
||||
<!-- From services -->
|
||||
<java-symbol type="anim" name="screen_rotate_0_enter" />
|
||||
|
||||
@@ -49,14 +49,17 @@ import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_NONE;
|
||||
import static com.android.server.wm.proto.AppTransitionProto.APP_TRANSITION_STATE;
|
||||
import static com.android.server.wm.proto.AppTransitionProto.LAST_USED_APP_TRANSITION;
|
||||
|
||||
import android.annotation.DrawableRes;
|
||||
import android.annotation.Nullable;
|
||||
import android.app.ActivityManager;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.GraphicBuffer;
|
||||
import android.graphics.Path;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Binder;
|
||||
import android.os.Debug;
|
||||
import android.os.IBinder;
|
||||
@@ -70,7 +73,10 @@ import android.util.Slog;
|
||||
import android.util.SparseArray;
|
||||
import android.util.proto.ProtoOutputStream;
|
||||
import android.view.AppTransitionAnimationSpec;
|
||||
import android.view.DisplayListCanvas;
|
||||
import android.view.IAppTransitionAnimationSpecsFuture;
|
||||
import android.view.RenderNode;
|
||||
import android.view.ThreadedRenderer;
|
||||
import android.view.WindowManager;
|
||||
import android.view.animation.AlphaAnimation;
|
||||
import android.view.animation.Animation;
|
||||
@@ -391,6 +397,11 @@ public class AppTransition implements Dump {
|
||||
mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN;
|
||||
}
|
||||
|
||||
|
||||
boolean isNextAppTransitionOpenCrossProfileApps() {
|
||||
return mNextAppTransitionType == NEXT_TRANSIT_TYPE_OPEN_CROSS_PROFILE_APPS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if and only if we are currently fetching app transition specs from the future
|
||||
* passed into {@link #overridePendingAppTransitionMultiThumbFuture}
|
||||
@@ -977,6 +988,43 @@ public class AppTransition implements Dump {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an overlay with a background color and a thumbnail for the cross profile apps
|
||||
* animation.
|
||||
*/
|
||||
GraphicBuffer createCrossProfileAppsThumbnail(
|
||||
@DrawableRes int thumbnailDrawableRes, Rect frame) {
|
||||
final int width = frame.width();
|
||||
final int height = frame.height();
|
||||
|
||||
final RenderNode node = RenderNode.create("CrossProfileAppsThumbnail", null);
|
||||
node.setLeftTopRightBottom(0, 0, width, height);
|
||||
node.setClipToBounds(false);
|
||||
|
||||
final DisplayListCanvas canvas = node.start(width, height);
|
||||
canvas.drawColor(Color.argb(0.6f, 0, 0, 0));
|
||||
final int thumbnailSize = mService.mContext.getResources().getDimensionPixelSize(
|
||||
com.android.internal.R.dimen.cross_profile_apps_thumbnail_size);
|
||||
final Drawable drawable = mService.mContext.getDrawable(thumbnailDrawableRes);
|
||||
drawable.setBounds(
|
||||
(width - thumbnailSize) / 2,
|
||||
(height - thumbnailSize) / 2,
|
||||
(width + thumbnailSize) / 2,
|
||||
(height + thumbnailSize) / 2);
|
||||
drawable.draw(canvas);
|
||||
node.end(canvas);
|
||||
|
||||
return ThreadedRenderer.createHardwareBitmap(node, width, height)
|
||||
.createGraphicBufferHandle();
|
||||
}
|
||||
|
||||
Animation createCrossProfileAppsThumbnailAnimationLocked(Rect appRect) {
|
||||
final Animation animation = loadAnimationRes(
|
||||
"android", com.android.internal.R.anim.cross_profile_apps_thumbnail_enter);
|
||||
return prepareThumbnailAnimationWithDuration(animation, appRect.width(),
|
||||
appRect.height(), 0, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* This animation runs for the thumbnail that gets cross faded with the enter/exit activity
|
||||
* when a thumbnail is specified with the pending animation override.
|
||||
@@ -1624,9 +1672,10 @@ public class AppTransition implements Dump {
|
||||
&& (transit == TRANSIT_ACTIVITY_OPEN
|
||||
|| transit == TRANSIT_TASK_OPEN
|
||||
|| transit == TRANSIT_TASK_TO_FRONT)) {
|
||||
|
||||
a = loadAnimationRes("android", enter
|
||||
? com.android.internal.R.anim.activity_open_enter
|
||||
: com.android.internal.R.anim.activity_open_exit);
|
||||
? com.android.internal.R.anim.task_open_enter_cross_profile_apps
|
||||
: com.android.internal.R.anim.task_open_exit);
|
||||
Slog.v(TAG,
|
||||
"applyAnimation NEXT_TRANSIT_TYPE_OPEN_CROSS_PROFILE_APPS:"
|
||||
+ " anim=" + a + " transit=" + appTransitionToString(transit)
|
||||
@@ -2007,6 +2056,8 @@ public class AppTransition implements Dump {
|
||||
return "NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP";
|
||||
case NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN:
|
||||
return "NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN";
|
||||
case NEXT_TRANSIT_TYPE_OPEN_CROSS_PROFILE_APPS:
|
||||
return "NEXT_TRANSIT_TYPE_OPEN_CROSS_PROFILE_APPS";
|
||||
default:
|
||||
return "unknown type=" + mNextAppTransitionType;
|
||||
}
|
||||
|
||||
@@ -85,10 +85,14 @@ class AppWindowThumbnail implements Animatable {
|
||||
}
|
||||
|
||||
void startAnimation(Transaction t, Animation anim) {
|
||||
startAnimation(t, anim, null /* position */);
|
||||
}
|
||||
|
||||
void startAnimation(Transaction t, Animation anim, Point position) {
|
||||
anim.restrictDuration(MAX_ANIMATION_DURATION);
|
||||
anim.scaleCurrentDuration(mAppToken.mService.getTransitionAnimationScaleLocked());
|
||||
mSurfaceAnimator.startAnimation(t, new LocalAnimationAdapter(
|
||||
new WindowAnimationSpec(anim, null /* position */,
|
||||
new WindowAnimationSpec(anim, position,
|
||||
mAppToken.mService.mAppTransition.canSkipFirstFrame()),
|
||||
mAppToken.mService.mSurfaceAnimationRunner), false /* hidden */);
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package com.android.server.wm;
|
||||
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
|
||||
import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION;
|
||||
@@ -31,6 +30,7 @@ import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
|
||||
|
||||
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
|
||||
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
|
||||
import static com.android.server.wm.AppTransition.TRANSIT_UNSET;
|
||||
@@ -56,7 +56,6 @@ import static com.android.server.wm.proto.AppWindowTokenProto.WINDOW_TOKEN;
|
||||
|
||||
import android.annotation.CallSuper;
|
||||
import android.app.Activity;
|
||||
import android.app.WindowConfiguration.WindowingMode;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.GraphicBuffer;
|
||||
import android.graphics.Point;
|
||||
@@ -69,13 +68,14 @@ import android.os.Trace;
|
||||
import android.util.Slog;
|
||||
import android.util.proto.ProtoOutputStream;
|
||||
import android.view.DisplayInfo;
|
||||
import android.view.SurfaceControl.Transaction;
|
||||
import android.view.animation.Animation;
|
||||
import android.view.IApplicationToken;
|
||||
import android.view.SurfaceControl;
|
||||
import android.view.SurfaceControl.Transaction;
|
||||
import android.view.WindowManager;
|
||||
import android.view.WindowManager.LayoutParams;
|
||||
import android.view.animation.Animation;
|
||||
|
||||
import com.android.internal.R;
|
||||
import com.android.internal.util.ToBooleanFunction;
|
||||
import com.android.server.input.InputApplicationHandle;
|
||||
import com.android.server.policy.WindowManagerPolicy.StartingSurface;
|
||||
@@ -1775,6 +1775,37 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree
|
||||
mThumbnail.startAnimation(getPendingTransaction(), loadThumbnailAnimation(thumbnailHeader));
|
||||
}
|
||||
|
||||
/**
|
||||
* Attaches a surface with a thumbnail for the
|
||||
* {@link android.app.ActivityOptions#ANIM_OPEN_CROSS_PROFILE_APPS} animation.
|
||||
*/
|
||||
void attachCrossProfileAppsThumbnailAnimation() {
|
||||
if (!isReallyAnimating()) {
|
||||
return;
|
||||
}
|
||||
clearThumbnail();
|
||||
|
||||
final WindowState win = findMainWindow();
|
||||
if (win == null) {
|
||||
return;
|
||||
}
|
||||
final Rect frame = win.mFrame;
|
||||
final int thumbnailDrawableRes = getTask().mUserId == mService.mCurrentUserId
|
||||
? R.drawable.ic_account_circle
|
||||
: R.drawable.ic_corp_badge_no_background;
|
||||
final GraphicBuffer thumbnail =
|
||||
mService.mAppTransition
|
||||
.createCrossProfileAppsThumbnail(thumbnailDrawableRes, frame);
|
||||
if (thumbnail == null) {
|
||||
return;
|
||||
}
|
||||
mThumbnail = new AppWindowThumbnail(getPendingTransaction(), this, thumbnail);
|
||||
final Animation animation =
|
||||
mService.mAppTransition.createCrossProfileAppsThumbnailAnimationLocked(win.mFrame);
|
||||
mThumbnail.startAnimation(getPendingTransaction(), animation, new Point(frame.left,
|
||||
frame.top));
|
||||
}
|
||||
|
||||
private Animation loadThumbnailAnimation(GraphicBuffer thumbnailHeader) {
|
||||
final DisplayInfo displayInfo = mDisplayContent.getDisplayInfo();
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
|
||||
import static android.app.ActivityManagerInternal.APP_TRANSITION_SNAPSHOT;
|
||||
import static android.app.ActivityManagerInternal.APP_TRANSITION_SPLASH_SCREEN;
|
||||
import static android.app.ActivityManagerInternal.APP_TRANSITION_WINDOWS_DRAWN;
|
||||
|
||||
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG;
|
||||
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
|
||||
import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_CLOSE;
|
||||
@@ -43,28 +44,19 @@ import static com.android.server.wm.AppTransition.isKeyguardGoingAwayTransit;
|
||||
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG;
|
||||
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
|
||||
import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
|
||||
import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
|
||||
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
|
||||
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
|
||||
import static com.android.server.wm.WindowManagerService.H.NOTIFY_APP_TRANSITION_STARTING;
|
||||
import static com.android.server.wm.WindowManagerService.H.REPORT_WINDOWS_CHANGE;
|
||||
import static com.android.server.wm.WindowManagerService.LAYOUT_REPEAT_THRESHOLD;
|
||||
import static com.android.server.wm.WindowManagerService.MAX_ANIMATION_DURATION;
|
||||
import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_PLACING_SURFACES;
|
||||
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.GraphicBuffer;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Binder;
|
||||
import android.os.Debug;
|
||||
import android.os.Trace;
|
||||
import android.util.ArraySet;
|
||||
import android.util.Slog;
|
||||
import android.util.SparseIntArray;
|
||||
import android.view.Display;
|
||||
import android.view.DisplayInfo;
|
||||
import android.view.Surface;
|
||||
import android.view.SurfaceControl;
|
||||
import android.view.WindowManager.LayoutParams;
|
||||
import android.view.animation.Animation;
|
||||
@@ -414,7 +406,6 @@ class WindowSurfacePlacer {
|
||||
}
|
||||
wtoken.updateReportedVisibilityLocked();
|
||||
wtoken.waitingToShow = false;
|
||||
|
||||
if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
|
||||
">>> OPEN TRANSACTION handleAppTransitionReadyLocked()");
|
||||
mService.openSurfaceTransaction();
|
||||
@@ -435,6 +426,8 @@ class WindowSurfacePlacer {
|
||||
}
|
||||
if (mService.mAppTransition.isNextAppTransitionThumbnailUp()) {
|
||||
wtoken.attachThumbnailAnimation();
|
||||
} else if (mService.mAppTransition.isNextAppTransitionOpenCrossProfileApps()) {
|
||||
wtoken.attachCrossProfileAppsThumbnailAnimation();
|
||||
}
|
||||
}
|
||||
return topOpeningApp;
|
||||
|
||||
Reference in New Issue
Block a user