Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8078d8c8 authored by Dianne Hackborn's avatar Dianne Hackborn
Browse files

Add new thumbnail animation.

Use it for recent tasks switching.

Not perfect yet by far, but something.

Also fix issue #6186758: Twitter crashes after tapping on a tweet on JRM75D

Change-Id: I49bf6c94aafde875ac652dedaf96d6c08cc9e7d2
parent 3c4da3ca
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -2744,6 +2744,7 @@ package android.app {
    method public static boolean isUserAMonkey();
    method public void killBackgroundProcesses(java.lang.String);
    method public void moveTaskToFront(int, int);
    method public void moveTaskToFront(int, int, android.os.Bundle);
    method public deprecated void restartPackage(java.lang.String);
    field public static final int MOVE_TASK_NO_USER_ACTION = 2; // 0x2
    field public static final int MOVE_TASK_WITH_HOME = 1; // 0x1
@@ -2867,9 +2868,14 @@ package android.app {
  public class ActivityOptions {
    method public void join(android.app.ActivityOptions);
    method public static android.app.ActivityOptions makeCustomAnimation(android.content.Context, int, int);
    method public static android.app.ActivityOptions makeThumbnailScaleUpAnimation(android.view.View, android.graphics.Bitmap, int, int, android.app.ActivityOptions.OnAnimationStartedListener);
    method public android.os.Bundle toBundle();
  }
  public static abstract interface ActivityOptions.OnAnimationStartedListener {
    method public abstract void onAnimationStarted();
  }
  public class AlarmManager {
    method public void cancel(android.app.PendingIntent);
    method public void set(int, long, android.app.PendingIntent);
+1 −1
Original line number Diff line number Diff line
@@ -3639,7 +3639,7 @@ public class Activity extends ContextThemeWrapper
     */
    public void startActivityFromChild(Activity child, Intent intent,
            int requestCode) {
        startActivityFromChild(child, intent, requestCode);
        startActivityFromChild(child, intent, requestCode, null);
    }

    /**
+19 −2
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Point;
import android.os.Binder;
import android.os.Bundle;
import android.os.Debug;
import android.os.Handler;
import android.os.Parcel;
@@ -815,6 +816,19 @@ public class ActivityManager {
     */
    public static final int MOVE_TASK_NO_USER_ACTION = 0x00000002;

    /**
     * Equivalent to calling {@link #moveTaskToFront(int, int, Bundle)}
     * with a null options argument.
     *
     * @param taskId The identifier of the task to be moved, as found in
     * {@link RunningTaskInfo} or {@link RecentTaskInfo}.
     * @param flags Additional operational flags, 0 or more of
     * {@link #MOVE_TASK_WITH_HOME}.
     */
    public void moveTaskToFront(int taskId, int flags) {
        moveTaskToFront(taskId, flags, null);
    }

    /**
     * Ask that the task associated with a given task ID be moved to the
     * front of the stack, so it is now visible to the user.  Requires that
@@ -825,10 +839,13 @@ public class ActivityManager {
     * {@link RunningTaskInfo} or {@link RecentTaskInfo}.
     * @param flags Additional operational flags, 0 or more of
     * {@link #MOVE_TASK_WITH_HOME}.
     * @param options Additional options for the operation, either null or
     * as per {@link Context#startActivity(Intent, android.os.Bundle)
     * Context.startActivity(Intent, Bundle)}.
     */
    public void moveTaskToFront(int taskId, int flags) {
    public void moveTaskToFront(int taskId, int flags, Bundle options) {
        try {
            ActivityManagerNative.getDefault().moveTaskToFront(taskId, flags);
            ActivityManagerNative.getDefault().moveTaskToFront(taskId, flags, options);
        } catch (RemoteException e) {
            // System dead, we will be dead too soon!
        }
+10 −2
Original line number Diff line number Diff line
@@ -510,7 +510,9 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
            data.enforceInterface(IActivityManager.descriptor);
            int task = data.readInt();
            int fl = data.readInt();
            moveTaskToFront(task, fl);
            Bundle options = data.readInt() != 0
                    ? Bundle.CREATOR.createFromParcel(data) : null;
            moveTaskToFront(task, fl, options);
            reply.writeNoException();
            return true;
        }
@@ -2134,13 +2136,19 @@ class ActivityManagerProxy implements IActivityManager
        reply.recycle();
        return list;
    }
    public void moveTaskToFront(int task, int flags) throws RemoteException
    public void moveTaskToFront(int task, int flags, Bundle options) throws RemoteException
    {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
        data.writeInt(task);
        data.writeInt(flags);
        if (options != null) {
            data.writeInt(1);
            options.writeToParcel(data, 0);
        } else {
            data.writeInt(0);
        }
        mRemote.transact(MOVE_TASK_TO_FRONT_TRANSACTION, data, reply, 0);
        reply.readException();
        data.recycle();
+181 −13
Original line number Diff line number Diff line
@@ -17,7 +17,13 @@
package android.app;

import android.content.Context;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.Handler;
import android.os.IRemoteCallback;
import android.os.Message;
import android.os.RemoteException;
import android.view.View;

/**
 * Helper class for building an options Bundle that can be used with
@@ -31,6 +37,12 @@ public class ActivityOptions {
     */
    public static final String KEY_PACKAGE_NAME = "android:packageName";

    /**
     * Type of animation that arguments specify.
     * @hide
     */
    public static final String KEY_ANIM_TYPE = "android:animType";

    /**
     * Custom enter animation resource ID.
     * @hide
@@ -43,10 +55,45 @@ public class ActivityOptions {
     */
    public static final String KEY_ANIM_EXIT_RES_ID = "android:animExitRes";

    /**
     * Bitmap for thumbnail animation.
     * @hide
     */
    public static final String KEY_ANIM_THUMBNAIL = "android:animThumbnail";

    /**
     * Start X position of thumbnail animation.
     * @hide
     */
    public static final String KEY_ANIM_START_X = "android:animStartX";

    /**
     * Start Y position of thumbnail animation.
     * @hide
     */
    public static final String KEY_ANIM_START_Y = "android:animStartY";

    /**
     * Callback for when animation is started.
     * @hide
     */
    public static final String KEY_ANIM_START_LISTENER = "android:animStartListener";

    /** @hide */
    public static final int ANIM_NONE = 0;
    /** @hide */
    public static final int ANIM_CUSTOM = 1;
    /** @hide */
    public static final int ANIM_THUMBNAIL = 2;

    private String mPackageName;
    private boolean mIsCustomAnimation;
    private int mAnimationType = ANIM_NONE;
    private int mCustomEnterResId;
    private int mCustomExitResId;
    private Bitmap mThumbnail;
    private int mStartX;
    private int mStartY;
    private IRemoteCallback mAnimationStartedListener;

    /**
     * Create an ActivityOptions specifying a custom animation to run when
@@ -65,22 +112,79 @@ public class ActivityOptions {
            int enterResId, int exitResId) {
        ActivityOptions opts = new ActivityOptions();
        opts.mPackageName = context.getPackageName();
        opts.mIsCustomAnimation = true;
        opts.mAnimationType = ANIM_CUSTOM;
        opts.mCustomEnterResId = enterResId;
        opts.mCustomExitResId = exitResId;
        return opts;
    }

    /**
     * Callback for use with {@link ActivityOptions#makeThumbnailScaleUpAnimation}
     * to find out when the given animation has started running.
     */
    public interface OnAnimationStartedListener {
        void onAnimationStarted();
    }

    /**
     * Create an ActivityOptions specifying an animation where a thumbnail
     * is scaled from a given position to the new activity window that is
     * being started.
     *
     * @param source The View that this thumbnail is animating from.  This
     * defines the coordinate space for <var>startX</var> and <var>startY</var>.
     * @param thumbnail The bitmap that will be shown as the initial thumbnail
     * of the animation.
     * @param startX The x starting location of the bitmap, in screen coordiantes.
     * @param startY The y starting location of the bitmap, in screen coordinates.
     * @param listener Optional OnAnimationStartedListener to find out when the
     * requested animation has started running.  If for some reason the animation
     * is not executed, the callback will happen immediately.
     * @return Returns a new ActivityOptions object that you can use to
     * supply these options as the options Bundle when starting an activity.
     */
    public static ActivityOptions makeThumbnailScaleUpAnimation(View source,
            Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener) {
        ActivityOptions opts = new ActivityOptions();
        opts.mPackageName = source.getContext().getPackageName();
        opts.mAnimationType = ANIM_THUMBNAIL;
        opts.mThumbnail = thumbnail;
        int[] pts = new int[2];
        source.getLocationOnScreen(pts);
        opts.mStartX = pts[0] + startX;
        opts.mStartY = pts[1] + startY;
        if (listener != null) {
            final Handler h = source.getHandler();
            final OnAnimationStartedListener finalListener = listener;
            opts.mAnimationStartedListener = new IRemoteCallback.Stub() {
                @Override public void sendResult(Bundle data) throws RemoteException {
                    h.post(new Runnable() {
                        @Override public void run() {
                            finalListener.onAnimationStarted();
                        }
                    });
                }
            };
        }
        return opts;
    }

    private ActivityOptions() {
    }

    /** @hide */
    public ActivityOptions(Bundle opts) {
        mPackageName = opts.getString(KEY_PACKAGE_NAME);
        if (opts.containsKey(KEY_ANIM_ENTER_RES_ID)) {
            mIsCustomAnimation = true;
        mAnimationType = opts.getInt(KEY_ANIM_TYPE);
        if (mAnimationType == ANIM_CUSTOM) {
            mCustomEnterResId = opts.getInt(KEY_ANIM_ENTER_RES_ID, 0);
            mCustomExitResId = opts.getInt(KEY_ANIM_EXIT_RES_ID, 0);
        } else if (mAnimationType == ANIM_THUMBNAIL) {
            mThumbnail = (Bitmap)opts.getParcelable(KEY_ANIM_THUMBNAIL);
            mStartX = opts.getInt(KEY_ANIM_START_X, 0);
            mStartY = opts.getInt(KEY_ANIM_START_Y, 0);
            mAnimationStartedListener = IRemoteCallback.Stub.asInterface(
                    opts.getIBinder(KEY_ANIM_START_LISTENER));
        }
    }

@@ -90,8 +194,8 @@ public class ActivityOptions {
    }

    /** @hide */
    public boolean isCustomAnimation() {
        return mIsCustomAnimation;
    public int getAnimationType() {
        return mAnimationType;
    }

    /** @hide */
@@ -104,6 +208,43 @@ public class ActivityOptions {
        return mCustomExitResId;
    }

    /** @hide */
    public Bitmap getThumbnail() {
        return mThumbnail;
    }

    /** @hide */
    public int getStartX() {
        return mStartX;
    }

    /** @hide */
    public int getStartY() {
        return mStartY;
    }

    /** @hide */
    public IRemoteCallback getOnAnimationStartListener() {
        return mAnimationStartedListener;
    }

    /** @hide */
    public void abort() {
        if (mAnimationStartedListener != null) {
            try {
                mAnimationStartedListener.sendResult(null);
            } catch (RemoteException e) {
            }
        }
    }

    /** @hide */
    public static void abort(Bundle options) {
        if (options != null) {
            (new ActivityOptions(options)).abort();
        }
    }

    /**
     * Join the values in <var>otherOptions</var> in to this one.  Any values
     * defined in <var>otherOptions</var> replace those in the base options.
@@ -112,10 +253,27 @@ public class ActivityOptions {
        if (otherOptions.mPackageName != null) {
            mPackageName = otherOptions.mPackageName;
        }
        if (otherOptions.mIsCustomAnimation) {
            mIsCustomAnimation = true;
        switch (otherOptions.mAnimationType) {
            case ANIM_CUSTOM:
                mAnimationType = otherOptions.mAnimationType;
                mCustomEnterResId = otherOptions.mCustomEnterResId;
                mCustomExitResId = otherOptions.mCustomExitResId;
                mThumbnail = null;
                mAnimationStartedListener = null;
                break;
            case ANIM_THUMBNAIL:
                mAnimationType = otherOptions.mAnimationType;
                mThumbnail = otherOptions.mThumbnail;
                mStartX = otherOptions.mStartX;
                mStartY = otherOptions.mStartY;
                if (otherOptions.mAnimationStartedListener != null) {
                    try {
                        otherOptions.mAnimationStartedListener.sendResult(null);
                    } catch (RemoteException e) {
                    }
                }
                mAnimationStartedListener = otherOptions.mAnimationStartedListener;
                break;
        }
    }

@@ -132,9 +290,19 @@ public class ActivityOptions {
        if (mPackageName != null) {
            b.putString(KEY_PACKAGE_NAME, mPackageName);
        }
        if (mIsCustomAnimation) {
        switch (mAnimationType) {
            case ANIM_CUSTOM:
                b.putInt(KEY_ANIM_TYPE, mAnimationType);
                b.putInt(KEY_ANIM_ENTER_RES_ID, mCustomEnterResId);
                b.putInt(KEY_ANIM_EXIT_RES_ID, mCustomExitResId);
                break;
            case ANIM_THUMBNAIL:
                b.putInt(KEY_ANIM_TYPE, mAnimationType);
                b.putParcelable(KEY_ANIM_THUMBNAIL, mThumbnail);
                b.putInt(KEY_ANIM_START_X, mStartX);
                b.putInt(KEY_ANIM_START_Y, mStartY);
                b.putIBinder(KEY_ANIM_START_LISTENER, mAnimationStartedListener
                        != null ? mAnimationStartedListener.asBinder() : null);
        }
        return b;
    }
Loading