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

Commit 8d2b58b2 authored by Riddle Hsu's avatar Riddle Hsu
Browse files

Send IActivityClientController to client when launching activity

This reduces 2 binder transactions when launching activity:
- Get IActivityTaskManager from ServiceManager
- Get IActivityClientController from IActivityTaskManager

Bug: 174800802
Bug: 174041144
Test: "am start -n ${activity_name} -W -S -P /data/local/tmp/test.trace"
      There should not have ActivityTaskManager#getService and
      IActivityTaskManager#getActivityClientController from any
      methods of ActivityClient.

Change-Id: I5ebf8d0764205f338ef53bbb8dfd8b5d0b7f9811
parent d6cd319f
Loading
Loading
Loading
Loading
+25 −4
Original line number Diff line number Diff line
@@ -451,8 +451,20 @@ public class ActivityClient {
        return sInstance.get();
    }

    /**
     * If system server has passed the controller interface, store it so the subsequent access can
     * speed up.
     */
    public static IActivityClientController setActivityClientController(
            IActivityClientController activityClientController) {
        // No lock because it is no harm to encounter race condition. The thread safe Singleton#get
        // will take over that case.
        return INTERFACE_SINGLETON.mKnownInstance = activityClientController;
    }

    private static IActivityClientController getActivityClientController() {
        return sActivityClientController.get();
        final IActivityClientController controller = INTERFACE_SINGLETON.mKnownInstance;
        return controller != null ? controller : INTERFACE_SINGLETON.get();
    }

    private static final Singleton<ActivityClient> sInstance = new Singleton<ActivityClient>() {
@@ -462,8 +474,17 @@ public class ActivityClient {
        }
    };

    private static final Singleton<IActivityClientController> sActivityClientController =
            new Singleton<IActivityClientController>() {
    private static final ActivityClientControllerSingleton INTERFACE_SINGLETON =
            new ActivityClientControllerSingleton();

    private static class ActivityClientControllerSingleton
            extends Singleton<IActivityClientController> {
        /**
         * A quick look up to reduce potential extra binder transactions. E.g. getting activity
         * task manager from service manager and controller from activity task manager.
         */
        IActivityClientController mKnownInstance;

        @Override
        protected IActivityClientController create() {
            try {
@@ -472,5 +493,5 @@ public class ActivityClient {
                throw e.rethrowFromSystemServer();
            }
        }
    };
    }
}
+19 −3
Original line number Diff line number Diff line
@@ -20,8 +20,10 @@ import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityClient;
import android.app.ActivityThread.ActivityClientRecord;
import android.app.ClientTransactionHandler;
import android.app.IActivityClientController;
import android.app.ProfilerInfo;
import android.app.ResultInfo;
import android.compat.annotation.UnsupportedAppUsage;
@@ -67,6 +69,11 @@ public class LaunchActivityItem extends ClientTransactionItem {
    private boolean mIsForward;
    private ProfilerInfo mProfilerInfo;
    private IBinder mAssistToken;
    /**
     * It is only non-null if the process is the first time to launch activity. It is only an
     * optimization for quick look up of the interface so the field is ignored for comparison.
     */
    private IActivityClientController mActivityClientController;
    private FixedRotationAdjustments mFixedRotationAdjustments;

    @Override
@@ -74,6 +81,9 @@ public class LaunchActivityItem extends ClientTransactionItem {
        client.countLaunchingActivities(1);
        client.updateProcessState(mProcState, false);
        client.updatePendingConfiguration(mCurConfig);
        if (mActivityClientController != null) {
            ActivityClient.setActivityClientController(mActivityClientController);
        }
    }

    @Override
@@ -105,14 +115,16 @@ public class LaunchActivityItem extends ClientTransactionItem {
            String referrer, IVoiceInteractor voiceInteractor, int procState, Bundle state,
            PersistableBundle persistentState, List<ResultInfo> pendingResults,
            List<ReferrerIntent> pendingNewIntents, boolean isForward, ProfilerInfo profilerInfo,
            IBinder assistToken, FixedRotationAdjustments fixedRotationAdjustments) {
            IBinder assistToken, IActivityClientController activityClientController,
            FixedRotationAdjustments fixedRotationAdjustments) {
        LaunchActivityItem instance = ObjectPool.obtain(LaunchActivityItem.class);
        if (instance == null) {
            instance = new LaunchActivityItem();
        }
        setValues(instance, intent, ident, info, curConfig, overrideConfig, compatInfo, referrer,
                voiceInteractor, procState, state, persistentState, pendingResults,
                pendingNewIntents, isForward, profilerInfo, assistToken, fixedRotationAdjustments);
                pendingNewIntents, isForward, profilerInfo, assistToken, activityClientController,
                fixedRotationAdjustments);

        return instance;
    }
@@ -120,7 +132,7 @@ public class LaunchActivityItem extends ClientTransactionItem {
    @Override
    public void recycle() {
        setValues(this, null, 0, null, null, null, null, null, null, 0, null, null, null, null,
                false, null, null, null);
                false, null, null, null, null);
        ObjectPool.recycle(this);
    }

@@ -146,6 +158,7 @@ public class LaunchActivityItem extends ClientTransactionItem {
        dest.writeBoolean(mIsForward);
        dest.writeTypedObject(mProfilerInfo, flags);
        dest.writeStrongBinder(mAssistToken);
        dest.writeStrongInterface(mActivityClientController);
        dest.writeTypedObject(mFixedRotationAdjustments, flags);
    }

@@ -162,6 +175,7 @@ public class LaunchActivityItem extends ClientTransactionItem {
                in.createTypedArrayList(ReferrerIntent.CREATOR), in.readBoolean(),
                in.readTypedObject(ProfilerInfo.CREATOR),
                in.readStrongBinder(),
                IActivityClientController.Stub.asInterface(in.readStrongBinder()),
                in.readTypedObject(FixedRotationAdjustments.CREATOR));
    }

@@ -266,6 +280,7 @@ public class LaunchActivityItem extends ClientTransactionItem {
            int procState, Bundle state, PersistableBundle persistentState,
            List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
            boolean isForward, ProfilerInfo profilerInfo, IBinder assistToken,
            IActivityClientController activityClientController,
            FixedRotationAdjustments fixedRotationAdjustments) {
        instance.mIntent = intent;
        instance.mIdent = ident;
@@ -283,6 +298,7 @@ public class LaunchActivityItem extends ClientTransactionItem {
        instance.mIsForward = isForward;
        instance.mProfilerInfo = profilerInfo;
        instance.mAssistToken = assistToken;
        instance.mActivityClientController = activityClientController;
        instance.mFixedRotationAdjustments = fixedRotationAdjustments;
    }
}
+13 −12
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertSame;

import android.app.servertransaction.TestUtils.LaunchActivityItemBuilder;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
@@ -43,6 +44,8 @@ import androidx.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.util.function.Supplier;

/**
 * Tests for {@link ObjectPool}.
 *
@@ -144,24 +147,22 @@ public class ObjectPoolTests {
        persistableBundle.putInt("k", 4);
        IBinder assistToken = new Binder();

        LaunchActivityItem emptyItem = LaunchActivityItem.obtain(null, 0, null, null, null, null,
                null, null, 0, null, null, null, null, false, null, null, null);
        LaunchActivityItem item = LaunchActivityItem.obtain(intent, ident, activityInfo,
                config(), overrideConfig, compat, referrer, null /* voiceInteractor */,
                procState, bundle, persistableBundle, resultInfoList(), referrerIntentList(),
                true /* isForward */, null /* profilerInfo */, assistToken,
                null /* fixedRotationAdjustments */);
        Supplier<LaunchActivityItem> itemSupplier = () -> new LaunchActivityItemBuilder()
                .setIntent(intent).setIdent(ident).setInfo(activityInfo).setCurConfig(config())
                .setOverrideConfig(overrideConfig).setCompatInfo(compat).setReferrer(referrer)
                .setProcState(procState).setState(bundle).setPersistentState(persistableBundle)
                .setPendingResults(resultInfoList()).setPendingNewIntents(referrerIntentList())
                .setIsForward(true).setAssistToken(assistToken).build();

        LaunchActivityItem emptyItem = new LaunchActivityItemBuilder().build();
        LaunchActivityItem item = itemSupplier.get();
        assertNotSame(item, emptyItem);
        assertFalse(item.equals(emptyItem));

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

        LaunchActivityItem item2 = LaunchActivityItem.obtain(intent, ident, activityInfo,
                config(), overrideConfig, compat, referrer, null /* voiceInteractor */,
                procState, bundle, persistableBundle, resultInfoList(), referrerIntentList(),
                true /* isForward */, null /* profilerInfo */, assistToken,
                null /* fixedRotationAdjustments */);
        LaunchActivityItem item2 = itemSupplier.get();
        assertSame(item, item2);
        assertFalse(item2.equals(emptyItem));
    }
+121 −0
Original line number Diff line number Diff line
@@ -18,11 +18,19 @@ package android.app.servertransaction;

import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;

import android.app.ProfilerInfo;
import android.app.ResultInfo;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
import android.os.Bundle;
import android.os.IBinder;
import android.os.PersistableBundle;
import android.util.MergedConfiguration;
import android.view.DisplayAdjustments.FixedRotationAdjustments;

import com.android.internal.app.IVoiceInteractor;
import com.android.internal.content.ReferrerIntent;

import java.util.ArrayList;
@@ -81,4 +89,117 @@ class TestUtils {

        return referrerIntents;
    }

    static class LaunchActivityItemBuilder {
        private Intent mIntent;
        private int mIdent;
        private ActivityInfo mInfo;
        private Configuration mCurConfig;
        private Configuration mOverrideConfig;
        private CompatibilityInfo mCompatInfo;
        private String mReferrer;
        private IVoiceInteractor mVoiceInteractor;
        private int mProcState;
        private Bundle mState;
        private PersistableBundle mPersistentState;
        private List<ResultInfo> mPendingResults;
        private List<ReferrerIntent> mPendingNewIntents;
        private boolean mIsForward;
        private ProfilerInfo mProfilerInfo;
        private IBinder mAssistToken;
        private FixedRotationAdjustments mFixedRotationAdjustments;

        LaunchActivityItemBuilder setIntent(Intent intent) {
            mIntent = intent;
            return this;
        }

        LaunchActivityItemBuilder setIdent(int ident) {
            mIdent = ident;
            return this;
        }

        LaunchActivityItemBuilder setInfo(ActivityInfo info) {
            mInfo = info;
            return this;
        }

        LaunchActivityItemBuilder setCurConfig(Configuration curConfig) {
            mCurConfig = curConfig;
            return this;
        }

        LaunchActivityItemBuilder setOverrideConfig(Configuration overrideConfig) {
            mOverrideConfig = overrideConfig;
            return this;
        }

        LaunchActivityItemBuilder setCompatInfo(CompatibilityInfo compatInfo) {
            mCompatInfo = compatInfo;
            return this;
        }

        LaunchActivityItemBuilder setReferrer(String referrer) {
            mReferrer = referrer;
            return this;
        }

        LaunchActivityItemBuilder setVoiceInteractor(IVoiceInteractor voiceInteractor) {
            mVoiceInteractor = voiceInteractor;
            return this;
        }

        LaunchActivityItemBuilder setProcState(int procState) {
            mProcState = procState;
            return this;
        }

        LaunchActivityItemBuilder setState(Bundle state) {
            mState = state;
            return this;
        }

        LaunchActivityItemBuilder setPersistentState(PersistableBundle persistentState) {
            mPersistentState = persistentState;
            return this;
        }

        LaunchActivityItemBuilder setPendingResults(List<ResultInfo> pendingResults) {
            mPendingResults = pendingResults;
            return this;
        }

        LaunchActivityItemBuilder setPendingNewIntents(List<ReferrerIntent> pendingNewIntents) {
            mPendingNewIntents = pendingNewIntents;
            return this;
        }

        LaunchActivityItemBuilder setIsForward(boolean isForward) {
            mIsForward = isForward;
            return this;
        }

        LaunchActivityItemBuilder setProfilerInfo(ProfilerInfo profilerInfo) {
            mProfilerInfo = profilerInfo;
            return this;
        }

        LaunchActivityItemBuilder setAssistToken(IBinder assistToken) {
            mAssistToken = assistToken;
            return this;
        }

        LaunchActivityItemBuilder setFixedRotationAdjustments(FixedRotationAdjustments fra) {
            mFixedRotationAdjustments = fra;
            return this;
        }

        LaunchActivityItem build() {
            return LaunchActivityItem.obtain(mIntent, mIdent, mInfo,
                    mCurConfig, mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor,
                    mProcState, mState, mPersistentState, mPendingResults, mPendingNewIntents,
                    mIsForward, mProfilerInfo, mAssistToken, null /* activityClientController */,
                    mFixedRotationAdjustments);
        }
    }
}
+2 −7
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ import android.app.Activity;
import android.app.ActivityThread.ActivityClientRecord;
import android.app.ClientTransactionHandler;
import android.app.servertransaction.ActivityLifecycleItem.LifecycleState;
import android.app.servertransaction.TestUtils.LaunchActivityItemBuilder;
import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;
@@ -263,13 +264,7 @@ public class TransactionExecutorTests {
        // A previous queued launch transaction runs on main thread (execute).
        final ClientTransaction launchTransaction = ClientTransaction.obtain(null /* client */,
                token /* activityToken */);
        final LaunchActivityItem launchItem = spy(LaunchActivityItem.obtain(
                null /* intent */, 0 /* ident */, null /* info */, null /* curConfig */,
                null, /* overrideConfig */ null /* compatInfo */, null /* referrer */ ,
                null /* voiceInteractor */, 0 /* procState */, null /* state */,
                null /* persistentState */, null /* pendingResults */,
                null /* pendingNewIntents */, false /* isForward */, null /* profilerInfo */,
                null /* assistToken */, null /* fixedRotationAdjustments */));
        final LaunchActivityItem launchItem = spy(new LaunchActivityItemBuilder().build());
        launchTransaction.addCallback(launchItem);
        mExecutor.execute(launchTransaction);

Loading