am 3ed9f2f9
: Merge "Adding bounce animation for affiliated tasks. (Bug 16656169)" into lmp-mr1-dev
* commit '3ed9f2f903a8e6c38ca9f2ce3819ac063281a020': Adding bounce animation for affiliated tasks. (Bug 16656169)
This commit is contained in:
@ -2279,6 +2279,20 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
|
||||
return true;
|
||||
}
|
||||
|
||||
case START_IN_PLACE_ANIMATION_TRANSACTION: {
|
||||
data.enforceInterface(IActivityManager.descriptor);
|
||||
final Bundle bundle;
|
||||
if (data.readInt() == 0) {
|
||||
bundle = null;
|
||||
} else {
|
||||
bundle = data.readBundle();
|
||||
}
|
||||
final ActivityOptions options = bundle == null ? null : new ActivityOptions(bundle);
|
||||
startInPlaceAnimationOnFrontMostApplication(options);
|
||||
reply.writeNoException();
|
||||
return true;
|
||||
}
|
||||
|
||||
case REQUEST_VISIBLE_BEHIND_TRANSACTION: {
|
||||
data.enforceInterface(IActivityManager.descriptor);
|
||||
IBinder token = data.readStrongBinder();
|
||||
@ -5297,6 +5311,24 @@ class ActivityManagerProxy implements IActivityManager
|
||||
return icon;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions options)
|
||||
throws RemoteException {
|
||||
Parcel data = Parcel.obtain();
|
||||
Parcel reply = Parcel.obtain();
|
||||
data.writeInterfaceToken(IActivityManager.descriptor);
|
||||
if (options == null) {
|
||||
data.writeInt(0);
|
||||
} else {
|
||||
data.writeInt(1);
|
||||
data.writeBundle(options.toBundle());
|
||||
}
|
||||
mRemote.transact(START_IN_PLACE_ANIMATION_TRANSACTION, data, reply, IBinder.FLAG_ONEWAY);
|
||||
reply.readException();
|
||||
data.recycle();
|
||||
reply.recycle();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean requestVisibleBehind(IBinder token, boolean visible) throws RemoteException {
|
||||
Parcel data = Parcel.obtain();
|
||||
|
@ -62,6 +62,12 @@ public class ActivityOptions {
|
||||
*/
|
||||
public static final String KEY_ANIM_EXIT_RES_ID = "android:animExitRes";
|
||||
|
||||
/**
|
||||
* Custom in-place animation resource ID.
|
||||
* @hide
|
||||
*/
|
||||
public static final String KEY_ANIM_IN_PLACE_RES_ID = "android:animInPlaceRes";
|
||||
|
||||
/**
|
||||
* Bitmap for thumbnail animation.
|
||||
* @hide
|
||||
@ -132,11 +138,14 @@ public class ActivityOptions {
|
||||
public static final int ANIM_THUMBNAIL_ASPECT_SCALE_UP = 8;
|
||||
/** @hide */
|
||||
public static final int ANIM_THUMBNAIL_ASPECT_SCALE_DOWN = 9;
|
||||
/** @hide */
|
||||
public static final int ANIM_CUSTOM_IN_PLACE = 10;
|
||||
|
||||
private String mPackageName;
|
||||
private int mAnimationType = ANIM_NONE;
|
||||
private int mCustomEnterResId;
|
||||
private int mCustomExitResId;
|
||||
private int mCustomInPlaceResId;
|
||||
private Bitmap mThumbnail;
|
||||
private int mStartX;
|
||||
private int mStartY;
|
||||
@ -198,6 +207,30 @@ public class ActivityOptions {
|
||||
return opts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an ActivityOptions specifying a custom animation to run in place on an existing
|
||||
* activity.
|
||||
*
|
||||
* @param context Who is defining this. This is the application that the
|
||||
* animation resources will be loaded from.
|
||||
* @param animId A resource ID of the animation resource to use for
|
||||
* the incoming activity.
|
||||
* @return Returns a new ActivityOptions object that you can use to
|
||||
* supply these options as the options Bundle when running an in-place animation.
|
||||
* @hide
|
||||
*/
|
||||
public static ActivityOptions makeCustomInPlaceAnimation(Context context, int animId) {
|
||||
if (animId == 0) {
|
||||
throw new RuntimeException("You must specify a valid animation.");
|
||||
}
|
||||
|
||||
ActivityOptions opts = new ActivityOptions();
|
||||
opts.mPackageName = context.getPackageName();
|
||||
opts.mAnimationType = ANIM_CUSTOM_IN_PLACE;
|
||||
opts.mCustomInPlaceResId = animId;
|
||||
return opts;
|
||||
}
|
||||
|
||||
private void setOnAnimationStartedListener(Handler handler,
|
||||
OnAnimationStartedListener listener) {
|
||||
if (listener != null) {
|
||||
@ -540,6 +573,10 @@ public class ActivityOptions {
|
||||
opts.getBinder(KEY_ANIM_START_LISTENER));
|
||||
break;
|
||||
|
||||
case ANIM_CUSTOM_IN_PLACE:
|
||||
mCustomInPlaceResId = opts.getInt(KEY_ANIM_IN_PLACE_RES_ID, 0);
|
||||
break;
|
||||
|
||||
case ANIM_SCALE_UP:
|
||||
mStartX = opts.getInt(KEY_ANIM_START_X, 0);
|
||||
mStartY = opts.getInt(KEY_ANIM_START_Y, 0);
|
||||
@ -591,6 +628,11 @@ public class ActivityOptions {
|
||||
return mCustomExitResId;
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public int getCustomInPlaceResId() {
|
||||
return mCustomInPlaceResId;
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public Bitmap getThumbnail() {
|
||||
return mThumbnail;
|
||||
@ -689,6 +731,9 @@ public class ActivityOptions {
|
||||
}
|
||||
mAnimationStartedListener = otherOptions.mAnimationStartedListener;
|
||||
break;
|
||||
case ANIM_CUSTOM_IN_PLACE:
|
||||
mCustomInPlaceResId = otherOptions.mCustomInPlaceResId;
|
||||
break;
|
||||
case ANIM_SCALE_UP:
|
||||
mStartX = otherOptions.mStartX;
|
||||
mStartY = otherOptions.mStartY;
|
||||
@ -756,6 +801,9 @@ public class ActivityOptions {
|
||||
b.putBinder(KEY_ANIM_START_LISTENER, mAnimationStartedListener
|
||||
!= null ? mAnimationStartedListener.asBinder() : null);
|
||||
break;
|
||||
case ANIM_CUSTOM_IN_PLACE:
|
||||
b.putInt(KEY_ANIM_IN_PLACE_RES_ID, mCustomInPlaceResId);
|
||||
break;
|
||||
case ANIM_SCALE_UP:
|
||||
b.putInt(KEY_ANIM_START_X, mStartX);
|
||||
b.putInt(KEY_ANIM_START_Y, mStartY);
|
||||
|
@ -456,6 +456,9 @@ public interface IActivityManager extends IInterface {
|
||||
throws RemoteException;
|
||||
public Bitmap getTaskDescriptionIcon(String filename) throws RemoteException;
|
||||
|
||||
public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
|
||||
throws RemoteException;
|
||||
|
||||
public boolean requestVisibleBehind(IBinder token, boolean visible) throws RemoteException;
|
||||
public boolean isBackgroundVisibleBehind(IBinder token) throws RemoteException;
|
||||
public void backgroundResourcesReleased(IBinder token) throws RemoteException;
|
||||
@ -781,4 +784,5 @@ public interface IActivityManager extends IInterface {
|
||||
int BOOT_ANIMATION_COMPLETE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+237;
|
||||
int GET_TASK_DESCRIPTION_ICON_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+238;
|
||||
int LAUNCH_ASSIST_INTENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+239;
|
||||
int START_IN_PLACE_ANIMATION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+240;
|
||||
}
|
||||
|
@ -96,6 +96,7 @@ interface IWindowManager
|
||||
void overridePendingAppTransitionAspectScaledThumb(in Bitmap srcThumb, int startX,
|
||||
int startY, int targetWidth, int targetHeight, IRemoteCallback startedCallback,
|
||||
boolean scaleUp);
|
||||
void overridePendingAppTransitionInPlace(String packageName, int anim);
|
||||
void executeAppTransition();
|
||||
void setAppStartingWindow(IBinder token, String pkg, int theme,
|
||||
in CompatibilityInfo compatInfo, CharSequence nonLocalizedLabel, int labelRes,
|
||||
|
@ -22,38 +22,27 @@
|
||||
|
||||
<alpha android:fromAlpha="1.0" android:toAlpha="0.6"
|
||||
android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
|
||||
android:interpolator="@interpolator/accelerate_cubic"
|
||||
android:duration="133"/>
|
||||
android:interpolator="@interpolator/linear_out_slow_in"
|
||||
android:duration="417"/>
|
||||
|
||||
<translate android:fromYDelta="0" android:toYDelta="10%"
|
||||
android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
|
||||
android:interpolator="@interpolator/accelerate_cubic"
|
||||
android:duration="350"/>
|
||||
|
||||
<scale android:fromXScale="1.0" android:toXScale="0.9"
|
||||
android:fromYScale="1.0" android:toYScale="0.9"
|
||||
<scale android:fromXScale="1.0" android:toXScale="0.918"
|
||||
android:fromYScale="1.0" android:toYScale="0.918"
|
||||
android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
|
||||
android:pivotX="50%p" android:pivotY="50%p"
|
||||
android:interpolator="@interpolator/fast_out_slow_in"
|
||||
android:duration="350" />
|
||||
android:interpolator="@interpolator/launch_task_behind_source_scale_1"
|
||||
android:duration="417" />
|
||||
|
||||
<alpha android:fromAlpha="1.0" android:toAlpha="1.6666666666"
|
||||
android:fillEnabled="true" android:fillBefore="false" android:fillAfter="true"
|
||||
android:interpolator="@interpolator/decelerate_cubic"
|
||||
android:startOffset="433"
|
||||
android:duration="133"/>
|
||||
android:interpolator="@interpolator/linear"
|
||||
android:startOffset="500"
|
||||
android:duration="167"/>
|
||||
|
||||
<translate android:fromYDelta="0%" android:toYDelta="-8.8888888888%"
|
||||
android:fillEnabled="true" android:fillBefore="false" android:fillAfter="true"
|
||||
android:interpolator="@interpolator/decelerate_cubic"
|
||||
android:startOffset="433"
|
||||
android:duration="350"/>
|
||||
|
||||
<scale android:fromXScale="1.0" android:toXScale="1.1111111111"
|
||||
android:fromYScale="1.0" android:toYScale="1.1111111111"
|
||||
<scale android:fromXScale="1.0" android:toXScale="1.08932461873638"
|
||||
android:fromYScale="1.0" android:toYScale="1.08932461873638"
|
||||
android:fillEnabled="true" android:fillBefore="false" android:fillAfter="true"
|
||||
android:pivotX="50%p" android:pivotY="50%p"
|
||||
android:interpolator="@interpolator/decelerate_cubic"
|
||||
android:startOffset="433"
|
||||
android:duration="350" />
|
||||
android:interpolator="@interpolator/launch_task_behind_source_scale_2"
|
||||
android:startOffset="500"
|
||||
android:duration="317" />
|
||||
</set>
|
@ -20,15 +20,15 @@
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:background="#ff000000" android:shareInterpolator="false" android:zAdjustment="top">
|
||||
|
||||
<translate android:fromYDelta="110%" android:toYDelta="66%"
|
||||
<translate android:fromYDelta="110%" android:toYDelta="70%"
|
||||
android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
|
||||
android:interpolator="@interpolator/decelerate_quint"
|
||||
android:interpolator="@interpolator/launch_task_behind_target_ydelta"
|
||||
android:startOffset="50"
|
||||
android:duration="300" />
|
||||
android:duration="333" />
|
||||
|
||||
<translate android:fromYDelta="0%" android:toYDelta="167%"
|
||||
<translate android:fromYDelta="0%" android:toYDelta="50%"
|
||||
android:fillEnabled="true" android:fillBefore="false" android:fillAfter="true"
|
||||
android:interpolator="@interpolator/accelerate_quint"
|
||||
android:startOffset="433"
|
||||
android:duration="300" />
|
||||
</set>
|
||||
android:interpolator="@interpolator/fast_out_linear_in"
|
||||
android:startOffset="467"
|
||||
android:duration="317" />
|
||||
</set>
|
||||
|
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
** 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.
|
||||
*/
|
||||
-->
|
||||
|
||||
<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:pathData="M 0,0 c 0.541795,0 0.2,1 1,1" />
|
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
** 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.
|
||||
*/
|
||||
-->
|
||||
|
||||
<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:pathData="M 0,0 c 0.220434,0 0.833333,1 1,1" />
|
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
** 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.
|
||||
*/
|
||||
-->
|
||||
|
||||
<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:pathData="M 0,0 c 0.3,0 0,1 1,1" />
|
@ -1811,6 +1811,7 @@
|
||||
<java-symbol type="anim" name="lock_screen_behind_enter_wallpaper" />
|
||||
<java-symbol type="anim" name="lock_screen_behind_enter_fade_in" />
|
||||
<java-symbol type="anim" name="lock_screen_wallpaper_exit" />
|
||||
<java-symbol type="anim" name="launch_task_behind_source" />
|
||||
|
||||
<java-symbol type="bool" name="config_alwaysUseCdmaRssi" />
|
||||
<java-symbol type="dimen" name="status_bar_icon_size" />
|
||||
|
@ -20,40 +20,30 @@
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:background="#ff000000" android:shareInterpolator="false" android:zAdjustment="normal">
|
||||
|
||||
<alpha android:fromAlpha="1.0" android:toAlpha="0.6"
|
||||
|
||||
<translate android:fromYDelta="0" android:toYDelta="2%"
|
||||
android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
|
||||
android:interpolator="@android:interpolator/accelerate_cubic"
|
||||
android:interpolator="@android:interpolator/fast_out_slow_in"
|
||||
android:duration="133"/>
|
||||
|
||||
<translate android:fromYDelta="0" android:toYDelta="10%"
|
||||
android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
|
||||
android:interpolator="@android:interpolator/accelerate_cubic"
|
||||
android:duration="350"/>
|
||||
|
||||
<scale android:fromXScale="1.0" android:toXScale="0.9"
|
||||
android:fromYScale="1.0" android:toYScale="0.9"
|
||||
<scale android:fromXScale="1.0" android:toXScale="0.98"
|
||||
android:fromYScale="1.0" android:toYScale="0.98"
|
||||
android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
|
||||
android:pivotX="50%p" android:pivotY="50%p"
|
||||
android:interpolator="@android:interpolator/fast_out_slow_in"
|
||||
android:duration="350" />
|
||||
android:duration="133" />
|
||||
|
||||
<alpha android:fromAlpha="1.0" android:toAlpha="1.6666666666"
|
||||
android:fillEnabled="true" android:fillBefore="false" android:fillAfter="true"
|
||||
android:interpolator="@android:interpolator/decelerate_cubic"
|
||||
android:startOffset="350"
|
||||
android:duration="133"/>
|
||||
<translate android:fromYDelta="0" android:toYDelta="-2%"
|
||||
android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
|
||||
android:interpolator="@interpolator/recents_launch_prev_affiliated_task_bounce_ydelta"
|
||||
android:startOffset="133"
|
||||
android:duration="217"/>
|
||||
|
||||
<translate android:fromYDelta="0%" android:toYDelta="-8.8888888888%"
|
||||
android:fillEnabled="true" android:fillBefore="false" android:fillAfter="true"
|
||||
android:interpolator="@android:interpolator/decelerate_cubic"
|
||||
android:startOffset="350"
|
||||
android:duration="350"/>
|
||||
|
||||
<scale android:fromXScale="1.0" android:toXScale="1.1111111111"
|
||||
android:fromYScale="1.0" android:toYScale="1.1111111111"
|
||||
<scale android:fromXScale="1.0" android:toXScale="1.02040816326531"
|
||||
android:fromYScale="1.0" android:toYScale="1.02040816326531"
|
||||
android:fillEnabled="true" android:fillBefore="false" android:fillAfter="true"
|
||||
android:pivotX="50%p" android:pivotY="50%p"
|
||||
android:interpolator="@android:interpolator/decelerate_cubic"
|
||||
android:startOffset="350"
|
||||
android:duration="350" />
|
||||
android:interpolator="@interpolator/recents_launch_next_affiliated_task_bounce_scale"
|
||||
android:startOffset="133"
|
||||
android:duration="217" />
|
||||
</set>
|
@ -22,12 +22,12 @@
|
||||
|
||||
<translate android:fromYDelta="0%" android:toYDelta="10%"
|
||||
android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
|
||||
android:interpolator="@android:interpolator/decelerate_quint"
|
||||
android:duration="300" />
|
||||
android:interpolator="@android:interpolator/fast_out_slow_in"
|
||||
android:duration="133" />
|
||||
|
||||
<translate android:fromYDelta="10%" android:toYDelta="0%"
|
||||
<translate android:fromYDelta="0%" android:toYDelta="-10%"
|
||||
android:fillEnabled="true" android:fillBefore="false" android:fillAfter="true"
|
||||
android:interpolator="@android:interpolator/accelerate_quint"
|
||||
android:startOffset="300"
|
||||
android:duration="300" />
|
||||
android:interpolator="@interpolator/recents_launch_prev_affiliated_task_bounce_ydelta"
|
||||
android:startOffset="133"
|
||||
android:duration="217" />
|
||||
</set>
|
@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
** 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.
|
||||
*/
|
||||
-->
|
||||
<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:pathData="M 0,0 c 0.8,0 0.2,1 1,1" />
|
@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
** 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.
|
||||
*/
|
||||
-->
|
||||
<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:pathData="M 0,0 c 0.6,0 0.2,1 1,1" />
|
@ -16,13 +16,11 @@
|
||||
|
||||
package com.android.systemui.recents;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.ActivityOptions;
|
||||
import android.appwidget.AppWidgetHost;
|
||||
import android.appwidget.AppWidgetProviderInfo;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
@ -31,7 +29,6 @@ import android.content.res.Resources;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Handler;
|
||||
import android.os.UserHandle;
|
||||
import android.util.Pair;
|
||||
import android.view.LayoutInflater;
|
||||
@ -207,6 +204,7 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta
|
||||
Task toTask = null;
|
||||
ActivityOptions launchOpts = null;
|
||||
int taskCount = tasks.size();
|
||||
int numAffiliatedTasks = 0;
|
||||
for (int i = 0; i < taskCount; i++) {
|
||||
Task task = tasks.get(i);
|
||||
if (task.key.id == runningTask.id) {
|
||||
@ -226,16 +224,23 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta
|
||||
if (toTaskKey != null) {
|
||||
toTask = stack.findTaskWithId(toTaskKey.id);
|
||||
}
|
||||
numAffiliatedTasks = group.getTaskCount();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Return early if there is no next task
|
||||
if (toTask == null) {
|
||||
if (showNextTask) {
|
||||
// XXX: Show the next-task bounce animation
|
||||
} else {
|
||||
// XXX: Show the prev-task bounce animation
|
||||
if (numAffiliatedTasks > 1) {
|
||||
if (showNextTask) {
|
||||
mSystemServicesProxy.startInPlaceAnimationOnFrontMostApplication(
|
||||
ActivityOptions.makeCustomInPlaceAnimation(mContext,
|
||||
R.anim.recents_launch_next_affiliated_task_bounce));
|
||||
} else {
|
||||
mSystemServicesProxy.startInPlaceAnimationOnFrontMostApplication(
|
||||
ActivityOptions.makeCustomInPlaceAnimation(mContext,
|
||||
R.anim.recents_launch_prev_affiliated_task_bounce));
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -48,12 +48,14 @@ import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
import android.view.Display;
|
||||
import android.view.DisplayInfo;
|
||||
import android.view.IWindowManager;
|
||||
import android.view.SurfaceControl;
|
||||
import android.view.WindowManager;
|
||||
import android.view.accessibility.AccessibilityManager;
|
||||
@ -429,6 +431,7 @@ public class SystemServicesProxy {
|
||||
opts.putInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY,
|
||||
AppWidgetProviderInfo.WIDGET_CATEGORY_SEARCHBOX);
|
||||
if (!mAwm.bindAppWidgetIdIfAllowed(searchWidgetId, searchWidgetInfo.provider, opts)) {
|
||||
host.deleteAppWidgetId(searchWidgetId);
|
||||
return null;
|
||||
}
|
||||
return new Pair<Integer, AppWidgetProviderInfo>(searchWidgetId, searchWidgetInfo);
|
||||
@ -532,4 +535,15 @@ public class SystemServicesProxy {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Starts an in-place animation on the front most application windows. */
|
||||
public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts) {
|
||||
if (mIam == null) return;
|
||||
|
||||
try {
|
||||
mIam.startInPlaceAnimationOnFrontMostApplication(opts);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8298,6 +8298,20 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
return mTaskPersister.getTaskDescriptionIcon(filename);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
|
||||
throws RemoteException {
|
||||
if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
|
||||
opts.getCustomInPlaceResId() == 0) {
|
||||
throw new IllegalArgumentException("Expected in-place ActivityOption " +
|
||||
"with valid animation");
|
||||
}
|
||||
mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
|
||||
mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
|
||||
opts.getCustomInPlaceResId());
|
||||
mWindowManager.executeAppTransition();
|
||||
}
|
||||
|
||||
private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
|
||||
mRecentTasks.remove(tr);
|
||||
tr.removedFromRecents(mTaskPersister);
|
||||
|
@ -109,6 +109,8 @@ public class AppTransition implements Dump {
|
||||
/** A window in a new task is being opened behind an existing one in another activity's task.
|
||||
* The new window will show briefly and then be gone. */
|
||||
public static final int TRANSIT_TASK_OPEN_BEHIND = 16;
|
||||
/** A window in a task is being animated in-place. */
|
||||
public static final int TRANSIT_TASK_IN_PLACE = 17;
|
||||
|
||||
/** Fraction of animation at which the recents thumbnail stays completely transparent */
|
||||
private static final float RECENTS_THUMBNAIL_FADEIN_FRACTION = 0.7f;
|
||||
@ -131,6 +133,7 @@ public class AppTransition implements Dump {
|
||||
private static final int NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN = 4;
|
||||
private static final int NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP = 5;
|
||||
private static final int NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN = 6;
|
||||
private static final int NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE = 7;
|
||||
private int mNextAppTransitionType = NEXT_TRANSIT_TYPE_NONE;
|
||||
|
||||
// These are the possible states for the enter/exit activities during a thumbnail transition
|
||||
@ -146,6 +149,7 @@ public class AppTransition implements Dump {
|
||||
private IRemoteCallback mNextAppTransitionCallback;
|
||||
private int mNextAppTransitionEnter;
|
||||
private int mNextAppTransitionExit;
|
||||
private int mNextAppTransitionInPlace;
|
||||
private int mNextAppTransitionStartX;
|
||||
private int mNextAppTransitionStartY;
|
||||
private int mNextAppTransitionStartWidth;
|
||||
@ -835,6 +839,12 @@ public class AppTransition implements Dump {
|
||||
+ " anim=" + a + " nextAppTransition=ANIM_CUSTOM"
|
||||
+ " transit=" + transit + " isEntrance=" + enter
|
||||
+ " Callers=" + Debug.getCallers(3));
|
||||
} else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE) {
|
||||
a = loadAnimationRes(mNextAppTransitionPackage, mNextAppTransitionInPlace);
|
||||
if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
|
||||
"applyAnimation:"
|
||||
+ " anim=" + a + " nextAppTransition=ANIM_CUSTOM_IN_PLACE"
|
||||
+ " transit=" + transit + " Callers=" + Debug.getCallers(3));
|
||||
} else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_SCALE_UP) {
|
||||
a = createScaleUpAnimationLocked(transit, enter, appWidth, appHeight);
|
||||
if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
|
||||
@ -1013,6 +1023,16 @@ public class AppTransition implements Dump {
|
||||
}
|
||||
}
|
||||
|
||||
void overrideInPlaceAppTransition(String packageName, int anim) {
|
||||
if (isTransitionSet()) {
|
||||
mNextAppTransitionType = NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE;
|
||||
mNextAppTransitionPackage = packageName;
|
||||
mNextAppTransitionInPlace = anim;
|
||||
} else {
|
||||
postAnimationCallback();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "mNextAppTransition=0x" + Integer.toHexString(mNextAppTransition);
|
||||
@ -1092,6 +1112,8 @@ public class AppTransition implements Dump {
|
||||
return "NEXT_TRANSIT_TYPE_NONE";
|
||||
case NEXT_TRANSIT_TYPE_CUSTOM:
|
||||
return "NEXT_TRANSIT_TYPE_CUSTOM";
|
||||
case NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE:
|
||||
return "NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE";
|
||||
case NEXT_TRANSIT_TYPE_SCALE_UP:
|
||||
return "NEXT_TRANSIT_TYPE_SCALE_UP";
|
||||
case NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP:
|
||||
@ -1123,6 +1145,12 @@ public class AppTransition implements Dump {
|
||||
pw.print(" mNextAppTransitionExit=0x");
|
||||
pw.println(Integer.toHexString(mNextAppTransitionExit));
|
||||
break;
|
||||
case NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE:
|
||||
pw.print(" mNextAppTransitionPackage=");
|
||||
pw.println(mNextAppTransitionPackage);
|
||||
pw.print(" mNextAppTransitionInPlace=0x");
|
||||
pw.print(Integer.toHexString(mNextAppTransitionInPlace));
|
||||
break;
|
||||
case NEXT_TRANSIT_TYPE_SCALE_UP:
|
||||
pw.print(" mNextAppTransitionStartX="); pw.print(mNextAppTransitionStartX);
|
||||
pw.print(" mNextAppTransitionStartY=");
|
||||
|
@ -4123,6 +4123,13 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void overridePendingAppTransitionInPlace(String packageName, int anim) {
|
||||
synchronized(mWindowMap) {
|
||||
mAppTransition.overrideInPlaceAppTransition(packageName, anim);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeAppTransition() {
|
||||
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
|
||||
@ -4535,6 +4542,15 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
return delayed;
|
||||
}
|
||||
|
||||
void updateTokenInPlaceLocked(AppWindowToken wtoken, int transit) {
|
||||
if (transit != AppTransition.TRANSIT_UNSET) {
|
||||
if (wtoken.mAppAnimator.animation == AppWindowAnimator.sDummyAnimation) {
|
||||
wtoken.mAppAnimator.animation = null;
|
||||
}
|
||||
applyAnimationLocked(wtoken, null, transit, false, false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAppVisibility(IBinder token, boolean visible) {
|
||||
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
|
||||
@ -9125,6 +9141,29 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
int topOpeningLayer = 0;
|
||||
int topClosingLayer = 0;
|
||||
|
||||
// Process all applications animating in place
|
||||
if (transit == AppTransition.TRANSIT_TASK_IN_PLACE) {
|
||||
// Find the focused window
|
||||
final WindowState win =
|
||||
findFocusedWindowLocked(getDefaultDisplayContentLocked());
|
||||
if (win != null) {
|
||||
final AppWindowToken wtoken = win.mAppToken;
|
||||
final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
|
||||
if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now animating app in place " + wtoken);
|
||||
appAnimator.clearThumbnail();
|
||||
appAnimator.animation = null;
|
||||
updateTokenInPlaceLocked(wtoken, transit);
|
||||
wtoken.updateReportedVisibilityLocked();
|
||||
|
||||
appAnimator.mAllAppWinAnimators.clear();
|
||||
final int N = wtoken.allAppWindows.size();
|
||||
for (int j = 0; j < N; j++) {
|
||||
appAnimator.mAllAppWinAnimators.add(wtoken.allAppWindows.get(j).mWinAnimator);
|
||||
}
|
||||
mAnimator.mAnimating |= appAnimator.showAllWindowsLocked();
|
||||
}
|
||||
}
|
||||
|
||||
NN = mOpeningApps.size();
|
||||
for (i=0; i<NN; i++) {
|
||||
AppWindowToken wtoken = mOpeningApps.valueAt(i);
|
||||
|
@ -227,6 +227,11 @@ public class IWindowManagerImpl implements IWindowManager {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public void overridePendingAppTransitionInPlace(String packageName, int anim) {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pauseKeyDispatching(IBinder arg0) throws RemoteException {
|
||||
// TODO Auto-generated method stub
|
||||
|
Reference in New Issue
Block a user