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

Commit fec7d6ec authored by Chris Li's avatar Chris Li Committed by Android (Google) Code Review
Browse files

Merge "Add onErrorCallback for TaskFragmentOrganizer" into sc-v2-dev

parents 8b03c849 ccff5a6a
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