Merge "Only perform autolaunch if list has completely rebuilt" into rvc-dev

This commit is contained in:
TreeHugger Robot
2020-04-28 13:59:33 +00:00
committed by Android (Google) Code Review
7 changed files with 101 additions and 22 deletions

View File

@@ -301,7 +301,7 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter {
private boolean rebuildTab(ResolverListAdapter activeListAdapter, boolean doPostProcessing) {
if (shouldShowNoCrossProfileIntentsEmptyState(activeListAdapter)) {
activeListAdapter.postListReadyRunnable(doPostProcessing);
activeListAdapter.postListReadyRunnable(doPostProcessing, /* rebuildCompleted */ true);
return false;
}
return activeListAdapter.rebuildList(doPostProcessing);

View File

@@ -2404,10 +2404,9 @@ public class ChooserActivity extends ResolverActivity implements
public ChooserGridAdapter createChooserGridAdapter(Context context,
List<Intent> payloadIntents, Intent[] initialIntents, List<ResolveInfo> rList,
boolean filterLastUsed, boolean useLayoutForBrowsables, UserHandle userHandle) {
ChooserListAdapter chooserListAdapter = new ChooserListAdapter(context, payloadIntents,
initialIntents, rList,
filterLastUsed, createListController(userHandle), useLayoutForBrowsables,
this, this);
ChooserListAdapter chooserListAdapter = createChooserListAdapter(context, payloadIntents,
initialIntents, rList, filterLastUsed,
useLayoutForBrowsables, createListController(userHandle));
AppPredictor.Callback appPredictorCallback = createAppPredictorCallback(chooserListAdapter);
AppPredictor appPredictor = setupAppPredictorForUser(userHandle, appPredictorCallback);
chooserListAdapter.setAppPredictor(appPredictor);
@@ -2415,6 +2414,16 @@ public class ChooserActivity extends ResolverActivity implements
return new ChooserGridAdapter(chooserListAdapter);
}
@VisibleForTesting
public ChooserListAdapter createChooserListAdapter(Context context,
List<Intent> payloadIntents, Intent[] initialIntents, List<ResolveInfo> rList,
boolean filterLastUsed, boolean useLayoutForBrowsables,
ResolverListController resolverListController) {
return new ChooserListAdapter(context, payloadIntents, initialIntents, rList,
filterLastUsed, resolverListController, useLayoutForBrowsables,
this, this, context.getPackageManager());
}
@VisibleForTesting
protected ResolverListController createListController(UserHandle userHandle) {
AppPredictor appPredictor = getAppPredictorForShareActivitiesIfEnabled(userHandle);

View File

@@ -88,7 +88,7 @@ public class ChooserListAdapter extends ResolverListAdapter {
private final int mMaxShortcutTargetsPerApp;
private final ChooserListCommunicator mChooserListCommunicator;
private final SelectableTargetInfo.SelectableTargetInfoCommunicator
mSelectableTargetInfoComunicator;
mSelectableTargetInfoCommunicator;
private int mNumShortcutResults = 0;
@@ -117,7 +117,8 @@ public class ChooserListAdapter extends ResolverListAdapter {
boolean filterLastUsed, ResolverListController resolverListController,
boolean useLayoutForBrowsables,
ChooserListCommunicator chooserListCommunicator,
SelectableTargetInfo.SelectableTargetInfoCommunicator selectableTargetInfoComunicator) {
SelectableTargetInfo.SelectableTargetInfoCommunicator selectableTargetInfoCommunicator,
PackageManager packageManager) {
// Don't send the initial intents through the shared ResolverActivity path,
// we want to separate them into a different section.
super(context, payloadIntents, null, rList, filterLastUsed,
@@ -128,10 +129,9 @@ public class ChooserListAdapter extends ResolverListAdapter {
mMaxShortcutTargetsPerApp =
context.getResources().getInteger(R.integer.config_maxShortcutTargetsPerApp);
mChooserListCommunicator = chooserListCommunicator;
mSelectableTargetInfoComunicator = selectableTargetInfoComunicator;
mSelectableTargetInfoCommunicator = selectableTargetInfoCommunicator;
if (initialIntents != null) {
final PackageManager pm = context.getPackageManager();
for (int i = 0; i < initialIntents.length; i++) {
final Intent ii = initialIntents[i];
if (ii == null) {
@@ -147,7 +147,7 @@ public class ChooserListAdapter extends ResolverListAdapter {
final ComponentName cn = ii.getComponent();
if (cn != null) {
try {
ai = pm.getActivityInfo(ii.getComponent(), 0);
ai = packageManager.getActivityInfo(ii.getComponent(), 0);
ri = new ResolveInfo();
ri.activityInfo = ai;
} catch (PackageManager.NameNotFoundException ignored) {
@@ -155,7 +155,7 @@ public class ChooserListAdapter extends ResolverListAdapter {
}
}
if (ai == null) {
ri = pm.resolveActivity(ii, PackageManager.MATCH_DEFAULT_ONLY);
ri = packageManager.resolveActivity(ii, PackageManager.MATCH_DEFAULT_ONLY);
ai = ri != null ? ri.activityInfo : null;
}
if (ai == null) {
@@ -455,7 +455,7 @@ public class ChooserListAdapter extends ResolverListAdapter {
UserHandle userHandle = getUserHandle();
Context contextAsUser = mContext.createContextAsUser(userHandle, 0 /* flags */);
boolean isInserted = insertServiceTarget(new SelectableTargetInfo(contextAsUser,
origTarget, target, targetScore, mSelectableTargetInfoComunicator,
origTarget, target, targetScore, mSelectableTargetInfoCommunicator,
(isShortcutResult ? directShareToShortcutInfos.get(target) : null)));
if (isInserted && isShortcutResult) {
@@ -507,7 +507,7 @@ public class ChooserListAdapter extends ResolverListAdapter {
.map(target ->
new SelectableTargetInfo(
contextAsUser, origTarget, target, target.getScore(),
mSelectableTargetInfoComunicator,
mSelectableTargetInfoCommunicator,
(isShortcutResult ? directShareToShortcutInfos.get(target)
: null))
)

View File

@@ -1026,7 +1026,8 @@ public class ResolverActivity extends Activity implements
}
@Override // ResolverListCommunicator
public final void onPostListReady(ResolverListAdapter listAdapter, boolean doPostProcessing) {
public final void onPostListReady(ResolverListAdapter listAdapter, boolean doPostProcessing,
boolean rebuildCompleted) {
if (isAutolaunching()) {
return;
}
@@ -1041,7 +1042,7 @@ public class ResolverActivity extends Activity implements
}
// showEmptyResolverListEmptyState can mark the tab as loaded,
// which is a precondition for auto launching
if (maybeAutolaunchActivity()) {
if (rebuildCompleted && maybeAutolaunchActivity()) {
return;
}
if (doPostProcessing) {

View File

@@ -282,7 +282,7 @@ public class ResolverListAdapter extends BaseAdapter {
}
setPlaceholderCount(placeholderCount);
createSortingTask(doPostProcessing).execute(currentResolveList);
postListReadyRunnable(doPostProcessing);
postListReadyRunnable(doPostProcessing, /* rebuildCompleted */ false);
return false;
} else {
processSortedList(currentResolveList, doPostProcessing);
@@ -370,7 +370,7 @@ public class ResolverListAdapter extends BaseAdapter {
}
mResolverListCommunicator.sendVoiceChoicesIfNeeded();
postListReadyRunnable(doPostProcessing);
postListReadyRunnable(doPostProcessing, /* rebuildCompleted */ true);
mIsTabLoaded = true;
}
@@ -380,14 +380,15 @@ public class ResolverListAdapter extends BaseAdapter {
* handler thread to update after the current task is finished.
* @param doPostProcessing Whether to update the UI and load additional direct share targets
* after the list has been rebuilt
* @param rebuildCompleted Whether the list has been completely rebuilt
*/
void postListReadyRunnable(boolean doPostProcessing) {
void postListReadyRunnable(boolean doPostProcessing, boolean rebuildCompleted) {
if (mPostListReadyRunnable == null) {
mPostListReadyRunnable = new Runnable() {
@Override
public void run() {
mResolverListCommunicator.onPostListReady(ResolverListAdapter.this,
doPostProcessing);
doPostProcessing, rebuildCompleted);
mPostListReadyRunnable = null;
}
};
@@ -649,7 +650,8 @@ public class ResolverListAdapter extends BaseAdapter {
Intent getReplacementIntent(ActivityInfo activityInfo, Intent defIntent);
void onPostListReady(ResolverListAdapter listAdapter, boolean updateUi);
void onPostListReady(ResolverListAdapter listAdapter, boolean updateUi,
boolean rebuildCompleted);
void sendVoiceChoicesIfNeeded();

View File

@@ -34,6 +34,7 @@ import static com.android.internal.app.ChooserListAdapter.SHORTCUT_TARGET_SCORE_
import static com.android.internal.app.ChooserWrapperActivity.sOverrides;
import static com.android.internal.app.MatcherUtils.first;
import static junit.framework.Assert.assertNull;
import static junit.framework.Assert.assertTrue;
import static org.hamcrest.CoreMatchers.is;
@@ -41,6 +42,8 @@ import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.mock;
@@ -55,6 +58,8 @@ import android.content.ClipboardManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ShortcutInfo;
@@ -302,7 +307,7 @@ public class ChooserActivityTest {
waitForIdle();
UsageStatsManager usm = activity.getUsageStatsManager();
verify(sOverrides.resolverListController, times(1))
.topK(Mockito.any(List.class), Mockito.anyInt());
.topK(any(List.class), anyInt());
assertThat(activity.getIsSelected(), is(false));
sOverrides.onSafelyStartCallback = targetInfo -> {
return true;
@@ -312,7 +317,7 @@ public class ChooserActivityTest {
.perform(click());
waitForIdle();
verify(sOverrides.resolverListController, times(1))
.updateChooserCounts(Mockito.anyString(), Mockito.anyInt(), Mockito.anyString());
.updateChooserCounts(Mockito.anyString(), anyInt(), Mockito.anyString());
verify(sOverrides.resolverListController, times(1))
.updateModel(toChoose.activityInfo.getComponentName());
assertThat(activity.getIsSelected(), is(true));
@@ -1750,6 +1755,54 @@ public class ChooserActivityTest {
assertThat(chosen[0], is(personalResolvedComponentInfos.get(1).getResolveInfoAt(0)));
}
@Test
public void testOneInitialIntent_noAutolaunch() {
List<ResolvedComponentInfo> personalResolvedComponentInfos =
createResolvedComponentsForTest(1);
when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
Mockito.anyBoolean(),
Mockito.isA(List.class)))
.thenReturn(new ArrayList<>(personalResolvedComponentInfos));
Intent chooserIntent = createChooserIntent(new Intent[] {new Intent("action.fake")});
ResolveInfo[] chosen = new ResolveInfo[1];
sOverrides.onSafelyStartCallback = targetInfo -> {
chosen[0] = targetInfo.getResolveInfo();
return true;
};
sOverrides.packageManager = mock(PackageManager.class);
ResolveInfo ri = createFakeResolveInfo();
when(sOverrides.packageManager.resolveActivity(any(Intent.class), anyInt())).thenReturn(ri);
waitForIdle();
mActivityRule.launchActivity(chooserIntent);
waitForIdle();
assertNull(chosen[0]);
}
private Intent createChooserIntent(Intent[] initialIntents) {
Intent chooserIntent = new Intent();
chooserIntent.setAction(Intent.ACTION_CHOOSER);
chooserIntent.putExtra(Intent.EXTRA_TEXT, "testing intent sending");
chooserIntent.putExtra(Intent.EXTRA_TITLE, "some title");
chooserIntent.putExtra(Intent.EXTRA_INTENT, createSendTextIntent());
chooserIntent.setType("text/plain");
if (initialIntents != null) {
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, initialIntents);
}
return chooserIntent;
}
private ResolveInfo createFakeResolveInfo() {
ResolveInfo ri = new ResolveInfo();
ri.activityInfo = new ActivityInfo();
ri.activityInfo.name = "FakeActivityName";
ri.activityInfo.packageName = "fake.package.name";
ri.activityInfo.applicationInfo = new ApplicationInfo();
ri.activityInfo.applicationInfo.packageName = "fake.package.name";
return ri;
}
private Intent createSendTextIntent() {
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);

View File

@@ -58,6 +58,18 @@ public class ChooserWrapperActivity extends ChooserActivity {
return multiProfilePagerAdapter;
}
@Override
public ChooserListAdapter createChooserListAdapter(Context context, List<Intent> payloadIntents,
Intent[] initialIntents, List<ResolveInfo> rList, boolean filterLastUsed,
boolean useLayoutForBrowsables, ResolverListController resolverListController) {
PackageManager packageManager =
sOverrides.packageManager == null ? context.getPackageManager()
: sOverrides.packageManager;
return new ChooserListAdapter(context, payloadIntents, initialIntents, rList,
filterLastUsed, resolverListController, useLayoutForBrowsables,
this, this, packageManager);
}
ChooserListAdapter getAdapter() {
return mChooserMultiProfilePagerAdapter.getActiveListAdapter();
}
@@ -217,6 +229,7 @@ public class ChooserWrapperActivity extends ChooserActivity {
public boolean hasCrossProfileIntents;
public boolean isQuietModeEnabled;
public AbstractMultiProfilePagerAdapter.Injector multiPagerAdapterInjector;
public PackageManager packageManager;
public void reset() {
onSafelyStartCallback = null;
@@ -235,6 +248,7 @@ public class ChooserWrapperActivity extends ChooserActivity {
workProfileUserHandle = null;
hasCrossProfileIntents = true;
isQuietModeEnabled = false;
packageManager = null;
multiPagerAdapterInjector = new AbstractMultiProfilePagerAdapter.Injector() {
@Override
public boolean hasCrossProfileIntents(List<Intent> intents, int sourceUserId,