Merge "Send IActivityClientController to client when launching activity"

This commit is contained in:
Riddle Hsu
2020-12-10 15:15:41 +00:00
committed by Android (Google) Code Review
8 changed files with 201 additions and 32 deletions

View File

@@ -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();
}
}
};
}
}

View File

@@ -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;
}
}

View File

@@ -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));
}

View File

@@ -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);
}
}
}

View File

@@ -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);

View File

@@ -29,6 +29,7 @@ import android.app.IApplicationThread;
import android.app.IInstrumentationWatcher;
import android.app.IUiAutomationConnection;
import android.app.ProfilerInfo;
import android.app.servertransaction.TestUtils.LaunchActivityItemBuilder;
import android.content.AutofillOptions;
import android.content.ComponentName;
import android.content.ContentCaptureOptions;
@@ -195,11 +196,14 @@ public class TransactionParcelTests {
FixedRotationAdjustments fixedRotationAdjustments = new FixedRotationAdjustments(
Surface.ROTATION_90, 1920, 1080, DisplayCutout.NO_CUTOUT);
LaunchActivityItem item = LaunchActivityItem.obtain(intent, ident, activityInfo,
config(), overrideConfig, compat, referrer, null /* voiceInteractor */,
procState, bundle, persistableBundle, resultInfoList(), referrerIntentList(),
true /* isForward */, null /* profilerInfo */, new Binder(),
fixedRotationAdjustments);
LaunchActivityItem item = 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(new Binder())
.setFixedRotationAdjustments(fixedRotationAdjustments).build();
writeAndPrepareForReading(item);
// Read from parcel and assert

View File

@@ -88,6 +88,7 @@ import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
import android.app.ActivityOptions;
import android.app.AppOpsManager;
import android.app.IActivityClientController;
import android.app.ProfilerInfo;
import android.app.ResultInfo;
import android.app.WaitResult;
@@ -795,6 +796,11 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
+ " old=" + r.app + " new=" + proc);
}
// Send the controller to client if the process is the first time to launch activity.
// So the client can save binder transactions of getting the controller from activity
// task manager service.
final IActivityClientController activityClientController =
proc.hasEverLaunchedActivity() ? null : mService.mActivityClientController;
r.launchCount++;
r.lastLaunchTime = SystemClock.uptimeMillis();
proc.setLastActivityLaunchTime(r.lastLaunchTime);
@@ -863,7 +869,8 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
r.getSavedState(), r.getPersistentSavedState(), results, newIntents,
dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
r.assistToken, r.createFixedRotationAdjustmentsIfNeeded()));
r.assistToken, activityClientController,
r.createFixedRotationAdjustmentsIfNeeded()));
// Set desired final state.
final ActivityLifecycleItem lifecycleItem;

View File

@@ -463,6 +463,10 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
return mUsingWrapper;
}
boolean hasEverLaunchedActivity() {
return mLastActivityLaunchTime > 0;
}
void setLastActivityLaunchTime(long launchTime) {
if (launchTime <= mLastActivityLaunchTime) {
if (launchTime < mLastActivityLaunchTime) {