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

Commit ea203cdb authored by Louis Chang's avatar Louis Chang
Browse files

Avoid making post state to RESUMED for a PAUSING activity

Make sure the client post execution lifecycle state to RESUMED
only if the activity was RESUMED while delivering new intent.

Bug: 135715788
Test: making skype calls
Test: atest ActivityThreadTest

Change-Id: I1e3054e1d1611aecf6ddf6d482abf2cb3ebdf9a4
parent 5924e5ee
Loading
Loading
Loading
Loading
+11 −4
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package android.app.servertransaction;

import static android.app.servertransaction.ActivityLifecycleItem.ON_RESUME;
import static android.app.servertransaction.ActivityLifecycleItem.UNDEFINED;

import android.annotation.UnsupportedAppUsage;
import android.app.ClientTransactionHandler;
@@ -38,10 +39,11 @@ public class NewIntentItem extends ClientTransactionItem {

    @UnsupportedAppUsage
    private List<ReferrerIntent> mIntents;
    private boolean mResume;

    @Override
    public int getPostExecutionState() {
        return ON_RESUME;
        return mResume ? ON_RESUME : UNDEFINED;
    }

    @Override
@@ -58,12 +60,13 @@ public class NewIntentItem extends ClientTransactionItem {
    private NewIntentItem() {}

    /** Obtain an instance initialized with provided params. */
    public static NewIntentItem obtain(List<ReferrerIntent> intents) {
    public static NewIntentItem obtain(List<ReferrerIntent> intents, boolean resume) {
        NewIntentItem instance = ObjectPool.obtain(NewIntentItem.class);
        if (instance == null) {
            instance = new NewIntentItem();
        }
        instance.mIntents = intents;
        instance.mResume = resume;

        return instance;
    }
@@ -71,6 +74,7 @@ public class NewIntentItem extends ClientTransactionItem {
    @Override
    public void recycle() {
        mIntents = null;
        mResume = false;
        ObjectPool.recycle(this);
    }

@@ -80,11 +84,13 @@ public class NewIntentItem extends ClientTransactionItem {
    /** Write to Parcel. */
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeBoolean(mResume);
        dest.writeTypedList(mIntents, flags);
    }

    /** Read from Parcel. */
    private NewIntentItem(Parcel in) {
        mResume = in.readBoolean();
        mIntents = in.createTypedArrayList(ReferrerIntent.CREATOR);
    }

@@ -108,18 +114,19 @@ public class NewIntentItem extends ClientTransactionItem {
            return false;
        }
        final NewIntentItem other = (NewIntentItem) o;
        return Objects.equals(mIntents, other.mIntents);
        return mResume == other.mResume && Objects.equals(mIntents, other.mIntents);
    }

    @Override
    public int hashCode() {
        int result = 17;
        result = 31 * result + (mResume ? 1 : 0);
        result = 31 * result + mIntents.hashCode();
        return result;
    }

    @Override
    public String toString() {
        return "NewIntentItem{intents=" + mIntents + "}";
        return "NewIntentItem{intents=" + mIntents + ",resume=" + mResume + "}";
    }
}
+35 −0
Original line number Diff line number Diff line
@@ -19,6 +19,8 @@ package android.app.activity;
import static android.content.Intent.ACTION_EDIT;
import static android.content.Intent.ACTION_VIEW;

import static com.google.common.truth.Truth.assertThat;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNull;
@@ -31,6 +33,7 @@ import android.app.servertransaction.ActivityConfigurationChangeItem;
import android.app.servertransaction.ActivityRelaunchItem;
import android.app.servertransaction.ClientTransaction;
import android.app.servertransaction.ClientTransactionItem;
import android.app.servertransaction.NewIntentItem;
import android.app.servertransaction.ResumeActivityItem;
import android.app.servertransaction.StopActivityItem;
import android.content.Intent;
@@ -45,9 +48,13 @@ import androidx.test.filters.MediumTest;
import androidx.test.rule.ActivityTestRule;
import androidx.test.runner.AndroidJUnit4;

import com.android.internal.content.ReferrerIntent;

import org.junit.Test;
import org.junit.runner.RunWith;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;

/**
@@ -307,6 +314,24 @@ public class ActivityThreadTest {
        assertEquals(400, activity.mConfig.smallestScreenWidthDp);
    }

    @Test
    public void testResumeAfterNewIntent() {
        final Activity activity = mActivityTestRule.launchActivity(new Intent());
        final ActivityThread activityThread = activity.getActivityThread();
        final ArrayList<ReferrerIntent> rIntents = new ArrayList<>();
        rIntents.add(new ReferrerIntent(new Intent(), "android.app.activity"));

        InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
            activityThread.executeTransaction(newNewIntentTransaction(activity, rIntents, false));
        });
        assertThat(activity.isResumed()).isFalse();

        InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
            activityThread.executeTransaction(newNewIntentTransaction(activity, rIntents, true));
        });
        assertThat(activity.isResumed()).isTrue();
    }

    /**
     * Calls {@link ActivityThread#handleActivityConfigurationChanged(IBinder, Configuration, int)}
     * to try to push activity configuration to the activity for the given sequence number.
@@ -386,6 +411,16 @@ public class ActivityThreadTest {
        return transaction;
    }

    private static ClientTransaction newNewIntentTransaction(Activity activity,
            List<ReferrerIntent> intents, boolean resume) {
        final NewIntentItem item = NewIntentItem.obtain(intents, resume);

        final ClientTransaction transaction = newTransaction(activity);
        transaction.addCallback(item);

        return transaction;
    }

    private static ClientTransaction newTransaction(Activity activity) {
        final IApplicationThread appThread = activity.getActivityThread().getApplicationThread();
        return ClientTransaction.obtain(appThread, activity.getActivityToken());
+3 −3
Original line number Diff line number Diff line
@@ -214,15 +214,15 @@ public class ObjectPoolTests {

    @Test
    public void testRecycleNewIntentItem() {
        NewIntentItem emptyItem = NewIntentItem.obtain(null);
        NewIntentItem item = NewIntentItem.obtain(referrerIntentList());
        NewIntentItem emptyItem = NewIntentItem.obtain(null, false);
        NewIntentItem item = NewIntentItem.obtain(referrerIntentList(), false);
        assertNotSame(item, emptyItem);
        assertFalse(item.equals(emptyItem));

        item.recycle();
        assertEquals(item, emptyItem);

        NewIntentItem item2 = NewIntentItem.obtain(referrerIntentList());
        NewIntentItem item2 = NewIntentItem.obtain(referrerIntentList(), false);
        assertSame(item, item2);
        assertFalse(item2.equals(emptyItem));
    }
+1 −1
Original line number Diff line number Diff line
@@ -128,7 +128,7 @@ public class TransactionParcelTests {
    @Test
    public void testNewIntent() {
        // Write to parcel
        NewIntentItem item = NewIntentItem.obtain(referrerIntentList());
        NewIntentItem item = NewIntentItem.obtain(referrerIntentList(), false);
        writeAndPrepareForReading(item);

        // Read from parcel and assert
+4 −1
Original line number Diff line number Diff line
@@ -1616,8 +1616,11 @@ final class ActivityRecord extends ConfigurationContainer {
            try {
                ArrayList<ReferrerIntent> ar = new ArrayList<>(1);
                ar.add(rintent);
                // Making sure the client state is RESUMED after transaction completed and doing
                // so only if activity is currently RESUMED. Otherwise, client may have extra
                // life-cycle calls to RESUMED (and PAUSED later).
                mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
                        NewIntentItem.obtain(ar));
                        NewIntentItem.obtain(ar, mState == RESUMED));
                unsent = false;
            } catch (RemoteException e) {
                Slog.w(TAG, "Exception thrown sending new intent to " + this, e);
Loading