Add ResolverActivity testing
Still very basic, but will be adding as we find more issues pop up. Test: Ran the tests Change-Id: Ib9863509d140ff425ce446ecc876f53494d4fd0e
This commit is contained in:
@@ -749,10 +749,7 @@ public class ResolverActivity extends Activity {
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
AppGlobals.getPackageManager().setLastChosenActivity(intent,
|
||||
intent.resolveType(getContentResolver()),
|
||||
PackageManager.MATCH_DEFAULT_ONLY,
|
||||
filter, bestMatch, intent.getComponent());
|
||||
mAdapter.mResolverListController.setLastChosen(intent, filter, bestMatch);
|
||||
} catch (RemoteException re) {
|
||||
Log.d(TAG, "Error calling setLastChosenActivity\n" + re);
|
||||
}
|
||||
@@ -1312,10 +1309,7 @@ public class ResolverActivity extends Activity {
|
||||
protected boolean rebuildList() {
|
||||
List<ResolvedComponentInfo> currentResolveList = null;
|
||||
try {
|
||||
final Intent primaryIntent = getTargetIntent();
|
||||
mLastChosen = AppGlobals.getPackageManager().getLastChosenActivity(
|
||||
primaryIntent, primaryIntent.resolveTypeIfNeeded(getContentResolver()),
|
||||
PackageManager.MATCH_DEFAULT_ONLY);
|
||||
mLastChosen = mResolverListController.getLastChosen();
|
||||
} catch (RemoteException re) {
|
||||
Log.d(TAG, "Error calling getLastChosenActivity\n" + re);
|
||||
}
|
||||
|
||||
@@ -19,13 +19,16 @@ package com.android.internal.app;
|
||||
|
||||
import android.annotation.WorkerThread;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.AppGlobals;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
|
||||
@@ -65,6 +68,22 @@ public class ResolverListController {
|
||||
mReferrerPackage = referrerPackage;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
ResolveInfo getLastChosen() throws RemoteException {
|
||||
return AppGlobals.getPackageManager().getLastChosenActivity(
|
||||
mTargetIntent, mTargetIntent.resolveTypeIfNeeded(mContext.getContentResolver()),
|
||||
PackageManager.MATCH_DEFAULT_ONLY);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setLastChosen(Intent intent, IntentFilter filter, int match)
|
||||
throws RemoteException {
|
||||
AppGlobals.getPackageManager().setLastChosenActivity(intent,
|
||||
intent.resolveType(mContext.getContentResolver()),
|
||||
PackageManager.MATCH_DEFAULT_ONLY,
|
||||
filter, match, intent.getComponent());
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public List<ResolverActivity.ResolvedComponentInfo> getResolversForIntent(
|
||||
boolean shouldGetResolvedFilter,
|
||||
|
||||
@@ -1168,6 +1168,7 @@
|
||||
<activity android:name="android.app.EmptyActivity">
|
||||
</activity>
|
||||
<activity android:name="com.android.internal.app.ChooserWrapperActivity"/>
|
||||
<activity android:name="com.android.internal.app.ResolverWrapperActivity"/>
|
||||
|
||||
<receiver android:name="android.app.activity.AbortReceiver">
|
||||
<intent-filter android:priority="1">
|
||||
|
||||
@@ -222,7 +222,7 @@ public class ChooserActivityTest {
|
||||
private List<ResolvedComponentInfo> createResolvedComponentsForTest(int numberOfResults) {
|
||||
List<ResolvedComponentInfo> infoList = new ArrayList<>(numberOfResults);
|
||||
for (int i = 0; i < numberOfResults; i++) {
|
||||
infoList.add(ChooserDataProvider.createResolvedComponentInfo(i));
|
||||
infoList.add(ResolverDataProvider.createResolvedComponentInfo(i));
|
||||
}
|
||||
return infoList;
|
||||
}
|
||||
|
||||
@@ -24,11 +24,10 @@ import java.util.function.Function;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
|
||||
/**
|
||||
* Simple wrapper around chooser activity to be able to initiate it under test
|
||||
*/
|
||||
public class ChooserWrapperActivity extends ChooserActivity {
|
||||
/*
|
||||
* Simple wrapper around chooser activity to be able to initiate it under test
|
||||
*/
|
||||
static final OverrideData sOverrides = new OverrideData();
|
||||
private UsageStatsManager mUsm;
|
||||
|
||||
@@ -94,4 +93,4 @@ public class ChooserWrapperActivity extends ChooserActivity {
|
||||
resolverListController = mock(ResolverListController.class);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.internal.app;
|
||||
|
||||
import com.android.internal.R;
|
||||
import com.android.internal.app.ResolverActivity.ResolvedComponentInfo;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import android.app.usage.UsageStats;
|
||||
import android.app.usage.UsageStatsManager;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.os.UserHandle;
|
||||
import android.support.test.InstrumentationRegistry;
|
||||
import android.support.test.rule.ActivityTestRule;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static android.os.SystemClock.sleep;
|
||||
import static android.support.test.espresso.Espresso.onView;
|
||||
import static android.support.test.espresso.action.ViewActions.click;
|
||||
import static android.support.test.espresso.assertion.ViewAssertions.matches;
|
||||
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
|
||||
import static android.support.test.espresso.matcher.ViewMatchers.withId;
|
||||
import static android.support.test.espresso.matcher.ViewMatchers.withText;
|
||||
import static com.android.internal.app.ResolverWrapperActivity.sOverrides;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.CoreMatchers.not;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* Resolver activity instrumentation tests
|
||||
*/
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class ResolverActivityTest {
|
||||
@Rule
|
||||
public ActivityTestRule<ResolverWrapperActivity> mActivityRule =
|
||||
new ActivityTestRule<>(ResolverWrapperActivity.class, false,
|
||||
false);
|
||||
|
||||
@Before
|
||||
public void cleanOverrideData() {
|
||||
sOverrides.reset();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void twoOptionsAndUserSelectsOne() throws InterruptedException {
|
||||
Intent sendIntent = createSendImageIntent();
|
||||
List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
|
||||
|
||||
when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
|
||||
Mockito.anyBoolean(),
|
||||
Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
|
||||
|
||||
final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent);
|
||||
waitForIdle();
|
||||
|
||||
assertThat(activity.getAdapter().getCount(), is(2));
|
||||
|
||||
ResolveInfo[] chosen = new ResolveInfo[1];
|
||||
sOverrides.onSafelyStartCallback = targetInfo -> {
|
||||
chosen[0] = targetInfo.getResolveInfo();
|
||||
return true;
|
||||
};
|
||||
|
||||
ResolveInfo toChoose = resolvedComponentInfos.get(0).getResolveInfoAt(0);
|
||||
onView(withText(toChoose.activityInfo.name))
|
||||
.perform(click());
|
||||
onView(withId(R.id.button_once))
|
||||
.perform(click());
|
||||
waitForIdle();
|
||||
assertThat(chosen[0], is(toChoose));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hasLastChosenActivity() throws Exception {
|
||||
Intent sendIntent = createSendImageIntent();
|
||||
List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
|
||||
|
||||
when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
|
||||
Mockito.anyBoolean(),
|
||||
Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
|
||||
when(sOverrides.resolverListController.getLastChosen())
|
||||
.thenReturn(resolvedComponentInfos.get(0).getResolveInfoAt(0));
|
||||
|
||||
final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent);
|
||||
waitForIdle();
|
||||
|
||||
// The other entry is filtered to the last used slot
|
||||
assertThat(activity.getAdapter().getCount(), is(1));
|
||||
|
||||
ResolveInfo[] chosen = new ResolveInfo[1];
|
||||
sOverrides.onSafelyStartCallback = targetInfo -> {
|
||||
chosen[0] = targetInfo.getResolveInfo();
|
||||
return true;
|
||||
};
|
||||
|
||||
ResolveInfo toChoose = resolvedComponentInfos.get(0).getResolveInfoAt(0);
|
||||
onView(withId(R.id.title)).perform(click());
|
||||
onView(withId(R.id.button_once))
|
||||
.perform(click());
|
||||
waitForIdle();
|
||||
assertThat(chosen[0], is(toChoose));
|
||||
}
|
||||
|
||||
private Intent createSendImageIntent() {
|
||||
Intent sendIntent = new Intent();
|
||||
sendIntent.setAction(Intent.ACTION_SEND);
|
||||
sendIntent.putExtra(Intent.EXTRA_TEXT, "testing intent sending");
|
||||
sendIntent.setType("image/jpeg");
|
||||
return sendIntent;
|
||||
}
|
||||
|
||||
private List<ResolvedComponentInfo> createResolvedComponentsForTest(int numberOfResults) {
|
||||
List<ResolvedComponentInfo> infoList = new ArrayList<>(numberOfResults);
|
||||
for (int i = 0; i < numberOfResults; i++) {
|
||||
infoList.add(ResolverDataProvider.createResolvedComponentInfo(i));
|
||||
}
|
||||
return infoList;
|
||||
}
|
||||
|
||||
private void waitForIdle() {
|
||||
InstrumentationRegistry.getInstrumentation().waitForIdleSync();
|
||||
}
|
||||
}
|
||||
@@ -22,16 +22,15 @@ import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.os.UserHandle;
|
||||
import android.service.chooser.ChooserTarget;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* Utility class used by chooser tests to create mock data
|
||||
* Utility class used by resolver tests to create mock data
|
||||
*/
|
||||
class ChooserDataProvider {
|
||||
class ResolverDataProvider {
|
||||
|
||||
static ResolverActivity.ResolvedComponentInfo createResolvedComponentInfo(int i) {
|
||||
return new ResolverActivity.ResolvedComponentInfo(createComponentName(i),
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.internal.app;
|
||||
|
||||
import android.app.usage.UsageStatsManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.RemoteException;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
|
||||
/*
|
||||
* Simple wrapper around chooser activity to be able to initiate it under test
|
||||
*/
|
||||
public class ResolverWrapperActivity extends ResolverActivity {
|
||||
static final OverrideData sOverrides = new OverrideData();
|
||||
private UsageStatsManager mUsm;
|
||||
|
||||
ResolveListAdapter getAdapter() {
|
||||
return mAdapter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVoiceInteraction() {
|
||||
if (sOverrides.isVoiceInteraction != null) {
|
||||
return sOverrides.isVoiceInteraction;
|
||||
}
|
||||
return super.isVoiceInteraction();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void safelyStartActivity(TargetInfo cti) {
|
||||
if (sOverrides.onSafelyStartCallback != null &&
|
||||
sOverrides.onSafelyStartCallback.apply(cti)) {
|
||||
return;
|
||||
}
|
||||
super.safelyStartActivity(cti);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResolverListController createListController() {
|
||||
return sOverrides.resolverListController;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PackageManager getPackageManager() {
|
||||
if (sOverrides.createPackageManager != null) {
|
||||
return sOverrides.createPackageManager.apply(super.getPackageManager());
|
||||
}
|
||||
return super.getPackageManager();
|
||||
}
|
||||
|
||||
/**
|
||||
* We cannot directly mock the activity created since instrumentation creates it.
|
||||
* <p>
|
||||
* Instead, we use static instances of this object to modify behavior.
|
||||
*/
|
||||
static class OverrideData {
|
||||
@SuppressWarnings("Since15")
|
||||
public Function<PackageManager, PackageManager> createPackageManager;
|
||||
public Function<TargetInfo, Boolean> onSafelyStartCallback;
|
||||
public ResolverListController resolverListController;
|
||||
public Boolean isVoiceInteraction;
|
||||
|
||||
public void reset() {
|
||||
onSafelyStartCallback = null;
|
||||
isVoiceInteraction = null;
|
||||
createPackageManager = null;
|
||||
resolverListController = mock(ResolverListController.class);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user