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

Commit ccff5a6a authored by Chris Li's avatar Chris Li
Browse files

Add onErrorCallback for TaskFragmentOrganizer

When app wants to create activity through sidecar (for example,
startActivityToSide), we need a callback in case it failed to finish the
request.

Allow the caller to set a token for the WCT, which will be passed back
if there is any error, so that the caller can identify the error
callback.

Bug: 190433129
Test: N/A
Change-Id: Icffb7255e75465b90ed822559296f147a7e3418a
parent da14b09d
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package android.window;

import android.content.res.Configuration;
import android.os.Bundle;
import android.os.IBinder;
import android.window.TaskFragmentAppearedInfo;
import android.window.TaskFragmentInfo;
@@ -37,4 +38,15 @@ oneway interface ITaskFragmentOrganizer {
     * bounds.
     */
    void onTaskFragmentParentInfoChanged(in IBinder fragmentToken, in Configuration parentConfig);

    /**
     * Called when the {@link WindowContainerTransaction} created with
     * {@link WindowContainerTransaction#setErrorCallbackToken(IBinder)} failed on the server side.
     *
     * @param errorCallbackToken    Token set through {@link
     *                              WindowContainerTransaction#setErrorCallbackToken(IBinder)}
     * @param exceptionBundle   Bundle containing the exception. Should be created with
     *                          {@link TaskFragmentOrganizer#putExceptionInBundle}.
     */
    void onTaskFragmentError(in IBinder errorCallbackToken, in Bundle exceptionBundle);
}
+35 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package android.window;
import android.annotation.CallSuper;
import android.annotation.NonNull;
import android.content.res.Configuration;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;

@@ -30,6 +31,21 @@ import java.util.concurrent.Executor;
 */
public class TaskFragmentOrganizer extends WindowOrganizer {

    /**
     * Key to the exception in {@link Bundle} in {@link ITaskFragmentOrganizer#onTaskFragmentError}.
     */
    private static final String KEY_ERROR_CALLBACK_EXCEPTION = "fragment_exception";

    /**
     * Creates a {@link Bundle} with an exception that can be passed to
     * {@link ITaskFragmentOrganizer#onTaskFragmentError}.
     */
    public static Bundle putExceptionInBundle(@NonNull Throwable exception) {
        final Bundle exceptionBundle = new Bundle();
        exceptionBundle.putSerializable(KEY_ERROR_CALLBACK_EXCEPTION, exception);
        return exceptionBundle;
    }

    /**
     * Callbacks from WM Core are posted on this executor.
     */
@@ -93,6 +109,17 @@ public class TaskFragmentOrganizer extends WindowOrganizer {
    public void onTaskFragmentParentInfoChanged(
            @NonNull IBinder fragmentToken, @NonNull Configuration parentConfig) {}

    /**
     * Called when the {@link WindowContainerTransaction} created with
     * {@link WindowContainerTransaction#setErrorCallbackToken(IBinder)} failed on the server side.
     *
     * @param errorCallbackToken    token set in
     *                             {@link WindowContainerTransaction#setErrorCallbackToken(IBinder)}
     * @param exception             exception from the server side.
     */
    public void onTaskFragmentError(
            @NonNull IBinder errorCallbackToken, @NonNull Throwable exception) {}

    private final ITaskFragmentOrganizer mInterface = new ITaskFragmentOrganizer.Stub() {
        @Override
        public void onTaskFragmentAppeared(@NonNull TaskFragmentAppearedInfo taskFragmentInfo) {
@@ -119,6 +146,14 @@ public class TaskFragmentOrganizer extends WindowOrganizer {
                    () -> TaskFragmentOrganizer.this.onTaskFragmentParentInfoChanged(
                            fragmentToken, parentConfig));
        }

        @Override
        public void onTaskFragmentError(
                @NonNull IBinder errorCallbackToken, @NonNull Bundle exceptionBundle) {
            mExecutor.execute(() -> TaskFragmentOrganizer.this.onTaskFragmentError(
                    errorCallbackToken,
                    (Throwable) exceptionBundle.getSerializable(KEY_ERROR_CALLBACK_EXCEPTION)));
        }
    };

    private ITaskFragmentOrganizerController getController() {
+36 −1
Original line number Diff line number Diff line
@@ -49,11 +49,15 @@ public final class WindowContainerTransaction implements Parcelable {
    // Flat list because re-order operations are order-dependent
    private final ArrayList<HierarchyOp> mHierarchyOps = new ArrayList<>();

    @Nullable
    private IBinder mErrorCallbackToken;

    public WindowContainerTransaction() {}

    private WindowContainerTransaction(Parcel in) {
        in.readMap(mChanges, null /* loader */);
        in.readList(mHierarchyOps, null /* loader */);
        mErrorCallbackToken = in.readStrongBinder();
    }

    private Change getOrCreateChange(IBinder token) {
@@ -475,6 +479,23 @@ public final class WindowContainerTransaction implements Parcelable {
        return this;
    }

    /**
     * When this {@link WindowContainerTransaction} failed to finish on the server side, it will
     * trigger callback with this {@param errorCallbackToken}.
     * @param errorCallbackToken    client provided token that will be passed back as parameter in
     *                              the callback if there is an error on the server side.
     * @see ITaskFragmentOrganizer#onTaskFragmentError
     * @hide
     */
    @NonNull
    public WindowContainerTransaction setErrorCallbackToken(@NonNull IBinder errorCallbackToken) {
        if (mErrorCallbackToken != null) {
            throw new IllegalStateException("Can't set multiple error token for one transaction.");
        }
        mErrorCallbackToken = errorCallbackToken;
        return this;
    }

    /**
     * Merges another WCT into this one.
     * @param transfer When true, this will transfer everything from other potentially leaving
@@ -496,6 +517,13 @@ public final class WindowContainerTransaction implements Parcelable {
            mHierarchyOps.add(transfer ? other.mHierarchyOps.get(i)
                    : new HierarchyOp(other.mHierarchyOps.get(i)));
        }
        if (mErrorCallbackToken != null && other.mErrorCallbackToken != null && mErrorCallbackToken
                != other.mErrorCallbackToken) {
            throw new IllegalArgumentException("Can't merge two WCT with different error token");
        }
        mErrorCallbackToken = mErrorCallbackToken != null
                ? mErrorCallbackToken
                : other.mErrorCallbackToken;
    }

    /** @hide */
@@ -513,11 +541,17 @@ public final class WindowContainerTransaction implements Parcelable {
        return mHierarchyOps;
    }

    /** @hide */
    @Nullable
    public IBinder getErrorCallbackToken() {
        return mErrorCallbackToken;
    }

    @Override
    @NonNull
    public String toString() {
        return "WindowContainerTransaction { changes = " + mChanges + " hops = " + mHierarchyOps
                + " }";
                + " errorCallbackToken=" + mErrorCallbackToken + " }";
    }

    @Override
@@ -525,6 +559,7 @@ public final class WindowContainerTransaction implements Parcelable {
    public void writeToParcel(@NonNull Parcel dest, int flags) {
        dest.writeMap(mChanges);
        dest.writeList(mHierarchyOps);
        dest.writeStrongBinder(mErrorCallbackToken);
    }

    @Override