Fix incorrect default browser summary.
- move the logic to retrieve browser candidates with unique package name from default browser picker to the controller, so that both uses the same logic to get the candidate list. When there is only 1 package that can handle the web but it has multiple resolved activities, it should be considered as the only app, and hence be set as default. Change-Id: I945bcef3f7de586b19f65ceada3abf7addb0b26e Fixes: 109882811 Test: make RunSettingsRoboTests
This commit is contained in:
@@ -17,11 +17,9 @@
|
|||||||
package com.android.settings.applications.defaultapps;
|
package com.android.settings.applications.defaultapps;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.pm.ComponentInfo;
|
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.ResolveInfo;
|
import android.content.pm.ResolveInfo;
|
||||||
|
|
||||||
import android.util.ArraySet;
|
|
||||||
import com.android.internal.logging.nano.MetricsProto;
|
import com.android.internal.logging.nano.MetricsProto;
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
|
|
||||||
@@ -29,7 +27,6 @@ import com.android.settingslib.applications.DefaultAppInfo;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fragment for choosing default browser.
|
* Fragment for choosing default browser.
|
||||||
@@ -61,24 +58,13 @@ public class DefaultBrowserPicker extends DefaultAppPickerFragment {
|
|||||||
final List<DefaultAppInfo> candidates = new ArrayList<>();
|
final List<DefaultAppInfo> candidates = new ArrayList<>();
|
||||||
final Context context = getContext();
|
final Context context = getContext();
|
||||||
// Resolve that intent and check that the handleAllWebDataURI boolean is set
|
// Resolve that intent and check that the handleAllWebDataURI boolean is set
|
||||||
final List<ResolveInfo> list = mPm.queryIntentActivitiesAsUser(
|
final List<ResolveInfo> list =
|
||||||
DefaultBrowserPreferenceController.BROWSE_PROBE, PackageManager.MATCH_ALL, mUserId);
|
DefaultBrowserPreferenceController.getCandidates(mPm, mUserId);
|
||||||
|
|
||||||
final int count = list.size();
|
for (ResolveInfo info : list) {
|
||||||
final Set<String> addedPackages = new ArraySet<>();
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
ResolveInfo info = list.get(i);
|
|
||||||
if (info.activityInfo == null || !info.handleAllWebDataURI) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
final String packageName = info.activityInfo.packageName;
|
|
||||||
if (addedPackages.contains(packageName)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
candidates.add(new DefaultAppInfo(context, mPm,
|
candidates.add(new DefaultAppInfo(context, mPm,
|
||||||
mPm.getApplicationInfoAsUser(packageName, 0, mUserId)));
|
mPm.getApplicationInfoAsUser(info.activityInfo.packageName, 0, mUserId)));
|
||||||
addedPackages.add(packageName);
|
|
||||||
} catch (PackageManager.NameNotFoundException e) {
|
} catch (PackageManager.NameNotFoundException e) {
|
||||||
// Skip unknown packages.
|
// Skip unknown packages.
|
||||||
}
|
}
|
||||||
|
@@ -26,12 +26,15 @@ import android.graphics.drawable.Drawable;
|
|||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import androidx.preference.Preference;
|
import androidx.preference.Preference;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
import android.util.ArraySet;
|
||||||
import android.util.IconDrawableFactory;
|
import android.util.IconDrawableFactory;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.android.settingslib.applications.DefaultAppInfo;
|
import com.android.settingslib.applications.DefaultAppInfo;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
public class DefaultBrowserPreferenceController extends DefaultAppPreferenceController {
|
public class DefaultBrowserPreferenceController extends DefaultAppPreferenceController {
|
||||||
|
|
||||||
@@ -48,7 +51,7 @@ public class DefaultBrowserPreferenceController extends DefaultAppPreferenceCont
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAvailable() {
|
public boolean isAvailable() {
|
||||||
final List<ResolveInfo> candidates = getCandidates();
|
final List<ResolveInfo> candidates = getCandidates(mPackageManager, mUserId);
|
||||||
return candidates != null && !candidates.isEmpty();
|
return candidates != null && !candidates.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,14 +106,31 @@ public class DefaultBrowserPreferenceController extends DefaultAppPreferenceCont
|
|||||||
return getOnlyAppIcon();
|
return getOnlyAppIcon();
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<ResolveInfo> getCandidates() {
|
static List<ResolveInfo> getCandidates(PackageManager packageManager, int userId) {
|
||||||
return mPackageManager.queryIntentActivitiesAsUser(BROWSE_PROBE, PackageManager.MATCH_ALL,
|
final List<ResolveInfo> candidates = new ArrayList<>();
|
||||||
mUserId);
|
// Resolve that intent and check that the handleAllWebDataURI boolean is set
|
||||||
|
final List<ResolveInfo> list = packageManager.queryIntentActivitiesAsUser(
|
||||||
|
BROWSE_PROBE, PackageManager.MATCH_ALL, userId);
|
||||||
|
if (list != null) {
|
||||||
|
final Set<String> addedPackages = new ArraySet<>();
|
||||||
|
for (ResolveInfo info : list) {
|
||||||
|
if (info.activityInfo == null || !info.handleAllWebDataURI) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
final String packageName = info.activityInfo.packageName;
|
||||||
|
if (addedPackages.contains(packageName)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
candidates.add(info);
|
||||||
|
addedPackages.add(packageName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return candidates;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getOnlyAppLabel() {
|
private String getOnlyAppLabel() {
|
||||||
// Resolve that intent and check that the handleAllWebDataURI boolean is set
|
// Resolve that intent and check that the handleAllWebDataURI boolean is set
|
||||||
final List<ResolveInfo> list = getCandidates();
|
final List<ResolveInfo> list = getCandidates(mPackageManager, mUserId);
|
||||||
if (list != null && list.size() == 1) {
|
if (list != null && list.size() == 1) {
|
||||||
final ResolveInfo info = list.get(0);
|
final ResolveInfo info = list.get(0);
|
||||||
final String label = info.loadLabel(mPackageManager).toString();
|
final String label = info.loadLabel(mPackageManager).toString();
|
||||||
@@ -123,7 +143,7 @@ public class DefaultBrowserPreferenceController extends DefaultAppPreferenceCont
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Drawable getOnlyAppIcon() {
|
private Drawable getOnlyAppIcon() {
|
||||||
final List<ResolveInfo> list = getCandidates();
|
final List<ResolveInfo> list = getCandidates(mPackageManager, mUserId);
|
||||||
if (list != null && list.size() == 1) {
|
if (list != null && list.size() == 1) {
|
||||||
final ResolveInfo info = list.get(0);
|
final ResolveInfo info = list.get(0);
|
||||||
final ComponentInfo cn = info.getComponentInfo();
|
final ComponentInfo cn = info.getComponentInfo();
|
||||||
|
@@ -16,8 +16,6 @@
|
|||||||
|
|
||||||
package com.android.settings.applications.defaultapps;
|
package com.android.settings.applications.defaultapps;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
|
||||||
import static org.mockito.Matchers.any;
|
|
||||||
import static org.mockito.Matchers.anyInt;
|
import static org.mockito.Matchers.anyInt;
|
||||||
import static org.mockito.Matchers.eq;
|
import static org.mockito.Matchers.eq;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
@@ -25,20 +23,11 @@ import static org.mockito.Mockito.when;
|
|||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Context;
|
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.PackageManager;
|
||||||
import android.content.pm.PackageManager.NameNotFoundException;
|
|
||||||
import android.content.pm.ResolveInfo;
|
|
||||||
import android.os.UserManager;
|
import android.os.UserManager;
|
||||||
|
|
||||||
import com.android.settings.testutils.FakeFeatureFactory;
|
import com.android.settings.testutils.FakeFeatureFactory;
|
||||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||||
import com.android.settingslib.applications.DefaultAppInfo;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@@ -85,39 +74,4 @@ public class DefaultBrowserPickerTest {
|
|||||||
mPicker.getDefaultKey();
|
mPicker.getDefaultKey();
|
||||||
verify(mPackageManager).getDefaultBrowserPackageNameAsUser(anyInt());
|
verify(mPackageManager).getDefaultBrowserPackageNameAsUser(anyInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void getCandidates_shouldNotIncludeDuplicatePackageName() throws NameNotFoundException {
|
|
||||||
final List<ResolveInfo> resolveInfos = new ArrayList<>();
|
|
||||||
final String PACKAGE_ONE = "com.first.package";
|
|
||||||
final String PACKAGE_TWO = "com.second.package";
|
|
||||||
resolveInfos.add(createResolveInfo(PACKAGE_ONE));
|
|
||||||
resolveInfos.add(createResolveInfo(PACKAGE_TWO));
|
|
||||||
resolveInfos.add(createResolveInfo(PACKAGE_ONE));
|
|
||||||
resolveInfos.add(createResolveInfo(PACKAGE_TWO));
|
|
||||||
when(mPackageManager.queryIntentActivitiesAsUser(any(Intent.class), anyInt(), anyInt()))
|
|
||||||
.thenReturn(resolveInfos);
|
|
||||||
when(mPackageManager.getApplicationInfoAsUser(eq(PACKAGE_ONE), anyInt(), anyInt()))
|
|
||||||
.thenReturn(createApplicationInfo(PACKAGE_ONE));
|
|
||||||
when(mPackageManager.getApplicationInfoAsUser(eq(PACKAGE_TWO), anyInt(), anyInt()))
|
|
||||||
.thenReturn(createApplicationInfo(PACKAGE_TWO));
|
|
||||||
|
|
||||||
final List<DefaultAppInfo> defaultBrowserInfo = mPicker.getCandidates();
|
|
||||||
|
|
||||||
assertThat(defaultBrowserInfo.size()).isEqualTo(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
private ResolveInfo createResolveInfo(String packageName) {
|
|
||||||
final ResolveInfo info = new ResolveInfo();
|
|
||||||
info.handleAllWebDataURI = true;
|
|
||||||
info.activityInfo = new ActivityInfo();
|
|
||||||
info.activityInfo.packageName = packageName;
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ApplicationInfo createApplicationInfo(String packageName) {
|
|
||||||
final ApplicationInfo info = new ApplicationInfo();
|
|
||||||
info.packageName = packageName;
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -17,15 +17,21 @@
|
|||||||
package com.android.settings.applications.defaultapps;
|
package com.android.settings.applications.defaultapps;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
import static org.mockito.Matchers.any;
|
import static org.mockito.Matchers.any;
|
||||||
import static org.mockito.Matchers.anyInt;
|
import static org.mockito.Matchers.anyInt;
|
||||||
|
import static org.mockito.Mockito.doReturn;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.spy;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.pm.ActivityInfo;
|
||||||
|
import android.content.pm.ApplicationInfo;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
|
import android.content.pm.PackageManager.NameNotFoundException;
|
||||||
import android.content.pm.ResolveInfo;
|
import android.content.pm.ResolveInfo;
|
||||||
import android.os.UserManager;
|
import android.os.UserManager;
|
||||||
import androidx.preference.Preference;
|
import androidx.preference.Preference;
|
||||||
@@ -33,6 +39,8 @@ import androidx.preference.Preference;
|
|||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
@@ -73,8 +81,11 @@ public class DefaultBrowserPreferenceControllerTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void isAvailable_hasBrowser_shouldReturnTrue() {
|
public void isAvailable_hasBrowser_shouldReturnTrue() {
|
||||||
|
final ResolveInfo info = new ResolveInfo();
|
||||||
|
info.activityInfo = new ActivityInfo();
|
||||||
|
info.handleAllWebDataURI = true;
|
||||||
when(mPackageManager.queryIntentActivitiesAsUser(any(Intent.class), anyInt(), anyInt()))
|
when(mPackageManager.queryIntentActivitiesAsUser(any(Intent.class), anyInt(), anyInt()))
|
||||||
.thenReturn(Collections.singletonList(new ResolveInfo()));
|
.thenReturn(Collections.singletonList(info));
|
||||||
assertThat(mController.isAvailable()).isTrue();
|
assertThat(mController.isAvailable()).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,6 +99,28 @@ public class DefaultBrowserPreferenceControllerTest {
|
|||||||
verify(pref).setSummary(R.string.app_list_preference_none);
|
verify(pref).setSummary(R.string.app_list_preference_none);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getDefaultAppLabel_hasAppWithMultipleResolvedInfo_shouldReturnLabel()
|
||||||
|
throws NameNotFoundException {
|
||||||
|
DefaultBrowserPreferenceController spyController = spy(mController);
|
||||||
|
doReturn(null).when(spyController).getDefaultAppIcon();
|
||||||
|
final List<ResolveInfo> resolveInfos = new ArrayList<>();
|
||||||
|
final CharSequence PACKAGE_NAME = "com.test.package";
|
||||||
|
final ResolveInfo info1 = spy(createResolveInfo(PACKAGE_NAME.toString()));
|
||||||
|
when(info1.loadLabel(mPackageManager)).thenReturn(PACKAGE_NAME);
|
||||||
|
resolveInfos.add(info1);
|
||||||
|
resolveInfos.add(createResolveInfo(PACKAGE_NAME.toString()));
|
||||||
|
when(mPackageManager.getDefaultBrowserPackageNameAsUser(anyInt())).thenReturn(null);
|
||||||
|
when(mPackageManager.queryIntentActivitiesAsUser(any(Intent.class), anyInt(), anyInt()))
|
||||||
|
.thenReturn(resolveInfos);
|
||||||
|
when(mPackageManager.getApplicationInfoAsUser(
|
||||||
|
eq(PACKAGE_NAME.toString()), anyInt(), anyInt()))
|
||||||
|
.thenReturn(createApplicationInfo(PACKAGE_NAME.toString()));
|
||||||
|
final Preference pref = mock(Preference.class);
|
||||||
|
|
||||||
|
assertThat(spyController.getDefaultAppLabel()).isEqualTo(PACKAGE_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getDefaultApp_shouldGetDefaultBrowserPackage() {
|
public void getDefaultApp_shouldGetDefaultBrowserPackage() {
|
||||||
mController.getDefaultAppInfo();
|
mController.getDefaultAppInfo();
|
||||||
@@ -103,4 +136,40 @@ public class DefaultBrowserPreferenceControllerTest {
|
|||||||
|
|
||||||
assertThat(mController.isBrowserDefault("pkg", 0)).isTrue();
|
assertThat(mController.isBrowserDefault("pkg", 0)).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getCandidates_shouldNotIncludeDuplicatePackageName() throws NameNotFoundException {
|
||||||
|
final List<ResolveInfo> resolveInfos = new ArrayList<>();
|
||||||
|
final String PACKAGE_ONE = "com.first.package";
|
||||||
|
final String PACKAGE_TWO = "com.second.package";
|
||||||
|
resolveInfos.add(createResolveInfo(PACKAGE_ONE));
|
||||||
|
resolveInfos.add(createResolveInfo(PACKAGE_TWO));
|
||||||
|
resolveInfos.add(createResolveInfo(PACKAGE_ONE));
|
||||||
|
resolveInfos.add(createResolveInfo(PACKAGE_TWO));
|
||||||
|
when(mPackageManager.queryIntentActivitiesAsUser(any(Intent.class), anyInt(), anyInt()))
|
||||||
|
.thenReturn(resolveInfos);
|
||||||
|
when(mPackageManager.getApplicationInfoAsUser(eq(PACKAGE_ONE), anyInt(), anyInt()))
|
||||||
|
.thenReturn(createApplicationInfo(PACKAGE_ONE));
|
||||||
|
when(mPackageManager.getApplicationInfoAsUser(eq(PACKAGE_TWO), anyInt(), anyInt()))
|
||||||
|
.thenReturn(createApplicationInfo(PACKAGE_TWO));
|
||||||
|
|
||||||
|
final List<ResolveInfo> defaultBrowserInfo =
|
||||||
|
mController.getCandidates(mPackageManager, 0 /* userId */);
|
||||||
|
|
||||||
|
assertThat(defaultBrowserInfo.size()).isEqualTo(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ResolveInfo createResolveInfo(String packageName) {
|
||||||
|
final ResolveInfo info = new ResolveInfo();
|
||||||
|
info.handleAllWebDataURI = true;
|
||||||
|
info.activityInfo = new ActivityInfo();
|
||||||
|
info.activityInfo.packageName = packageName;
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ApplicationInfo createApplicationInfo(String packageName) {
|
||||||
|
final ApplicationInfo info = new ApplicationInfo();
|
||||||
|
info.packageName = packageName;
|
||||||
|
return info;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user