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

Commit 1be9657c authored by Charles Chen's avatar Charles Chen
Browse files

Using LaunchActivity when possible

... to prevent race

In [1], we store ActivityClientRecord earlier to make
ActivityClientRecord accessible in onCreate Lifcycle callback.
However, we still store the activity after Activity#onCreate.

This CL fixes the exception by obtaining ActivityClientRecord
from launch Activity list first to prevent race.

fixes: 196900007
Test: Try reproducible steps several times and didn't see
the error log.

[1]: 85986bf9

Change-Id: I7553c56cad474feb73fca73c72b5e6e833b46fbf
parent 6a458ebd
Loading
Loading
Loading
Loading
+16 −15
Original line number Diff line number Diff line
@@ -59,36 +59,37 @@ public abstract class ActivityTransactionItem extends ClientTransactionItem {
    }

    /**
     * Get the {@link ActivityClientRecord} instance that corresponds to the provided token.
     * Gets the {@link ActivityClientRecord} instance that corresponds to the provided token.
     * @param client Target client handler.
     * @param token Target activity token.
     * @param includeLaunching Indicate to also find the {@link ActivityClientRecord} in launching
     *                         activity list. It should be noted that there is no activity in
     * @param includeLaunching Indicate to find the {@link ActivityClientRecord} in launching
     *                         activity list.
     *                         <p>Note that there is no {@link android.app.Activity} instance in
     *                         {@link ActivityClientRecord} from the launching activity list.
     * @return The {@link ActivityClientRecord} instance that corresponds to the provided token.
     */
    @NonNull ActivityClientRecord getActivityClientRecord(
            @NonNull ClientTransactionHandler client, IBinder token, boolean includeLaunching) {
        ActivityClientRecord r = client.getActivityClient(token);
        if (r != null) {
            if (client.getActivity(token) == null) {
        ActivityClientRecord r = null;
        // Check launching Activity first to prevent race condition that activity instance has not
        // yet set to ActivityClientRecord.
        if (includeLaunching) {
            r = client.getLaunchingActivity(token);
        }
        // Then if we don't want to find launching Activity or the ActivityClientRecord doesn't
        // exist in launching Activity list. The ActivityClientRecord should have been initialized
        // and put in the Activity list.
        if (r == null) {
            r = client.getActivityClient(token);
            if (r != null && client.getActivity(token) == null) {
                throw new IllegalArgumentException("Activity must not be null to execute "
                        + "transaction item");
            }
            return r;
        }
        // The activity may not be launched yet. Fallback to check launching activity.
        if (includeLaunching) {
            r = client.getLaunchingActivity(token);
        }
        if (r == null) {
            throw new IllegalArgumentException("Activity client record must not be null to execute "
                    + "transaction item");
        }

        // We don't need to check the activity of launching activity client records because they
        // have not been launched yet.

        return r;
    }
}