Hide "Open by default" entirely for browser apps

Browsers are explicitly treated outside the web link infrastructure, so
we shouldn't offer "Open by default" section.

Fixes: 129162570
Test: robotests
Change-Id: Ie63d5fbfb32eaed4bba8a80158b6bb19bb45b380
This commit is contained in:
Yi-Ling Chuang
2019-09-13 09:55:38 -07:00
parent 68cc44bb77
commit 4ff357addc
4 changed files with 64 additions and 39 deletions

View File

@@ -20,11 +20,8 @@ import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATIO
import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER; import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
import android.app.settings.SettingsEnums; import android.app.settings.SettingsEnums;
import android.content.Intent;
import android.content.pm.ApplicationInfo; import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.os.UserHandle; import android.os.UserHandle;
import android.util.ArraySet; import android.util.ArraySet;
@@ -37,8 +34,7 @@ import androidx.preference.Preference;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.Utils; import com.android.settings.Utils;
import com.android.settings.core.SubSettingLauncher; import com.android.settings.core.SubSettingLauncher;
import com.android.settingslib.applications.AppUtils;
import java.util.List;
public class AppLaunchSettings extends AppInfoWithHeader implements OnClickListener, public class AppLaunchSettings extends AppInfoWithHeader implements OnClickListener,
Preference.OnPreferenceChangeListener { Preference.OnPreferenceChangeListener {
@@ -49,15 +45,6 @@ public class AppLaunchSettings extends AppInfoWithHeader implements OnClickListe
private static final String FRAGMENT_OPEN_SUPPORTED_LINKS = private static final String FRAGMENT_OPEN_SUPPORTED_LINKS =
"com.android.settings.applications.OpenSupportedLinks"; "com.android.settings.applications.OpenSupportedLinks";
private static final Intent sBrowserIntent;
static {
sBrowserIntent = new Intent()
.setAction(Intent.ACTION_VIEW)
.addCategory(Intent.CATEGORY_BROWSABLE)
.setData(Uri.parse("http:"));
}
private PackageManager mPm; private PackageManager mPm;
private boolean mIsBrowser; private boolean mIsBrowser;
@@ -90,7 +77,7 @@ public class AppLaunchSettings extends AppInfoWithHeader implements OnClickListe
mPm = getActivity().getPackageManager(); mPm = getActivity().getPackageManager();
mIsBrowser = isBrowserApp(mPackageName); mIsBrowser = AppUtils.isBrowserApp(this.getContext(), mPackageName, UserHandle.myUserId());
mHasDomainUrls = mHasDomainUrls =
(mAppEntry.info.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0; (mAppEntry.info.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0;
@@ -108,22 +95,6 @@ public class AppLaunchSettings extends AppInfoWithHeader implements OnClickListe
} }
} }
// An app is a "browser" if it has an activity resolution that wound up
// marked with the 'handleAllWebDataURI' flag.
private boolean isBrowserApp(String packageName) {
sBrowserIntent.setPackage(packageName);
List<ResolveInfo> list = mPm.queryIntentActivitiesAsUser(sBrowserIntent,
PackageManager.MATCH_ALL, UserHandle.myUserId());
final int count = list.size();
for (int i = 0; i < count; i++) {
ResolveInfo info = list.get(i);
if (info.activityInfo != null && info.handleAllWebDataURI) {
return true;
}
}
return false;
}
private int linkStateToResourceId(int state) { private int linkStateToResourceId(int state) {
switch (state) { switch (state) {
case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS: case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS:

View File

@@ -150,7 +150,11 @@ public class AppInfoDashboardFragment extends DashboardFragment
installer.setParentFragment(this); installer.setParentFragment(this);
use(AppInstallerPreferenceCategoryController.class).setChildren(Arrays.asList(installer)); use(AppInstallerPreferenceCategoryController.class).setChildren(Arrays.asList(installer));
use(AppNotificationPreferenceController.class).setParentFragment(this); use(AppNotificationPreferenceController.class).setParentFragment(this);
use(AppOpenByDefaultPreferenceController.class).setParentFragment(this);
use(AppOpenByDefaultPreferenceController.class)
.setPackageName(packageName)
.setParentFragment(this);
use(AppPermissionPreferenceController.class).setParentFragment(this); use(AppPermissionPreferenceController.class).setParentFragment(this);
use(AppPermissionPreferenceController.class).setPackageName(packageName); use(AppPermissionPreferenceController.class).setPackageName(packageName);
use(AppSettingPreferenceController.class) use(AppSettingPreferenceController.class)

View File

@@ -22,6 +22,7 @@ import android.content.pm.PackageInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.hardware.usb.IUsbManager; import android.hardware.usb.IUsbManager;
import android.os.ServiceManager; import android.os.ServiceManager;
import android.os.UserHandle;
import androidx.preference.Preference; import androidx.preference.Preference;
import androidx.preference.PreferenceScreen; import androidx.preference.PreferenceScreen;
@@ -35,6 +36,7 @@ public class AppOpenByDefaultPreferenceController extends AppInfoPreferenceContr
private IUsbManager mUsbManager; private IUsbManager mUsbManager;
private PackageManager mPackageManager; private PackageManager mPackageManager;
private String mPackageName;
public AppOpenByDefaultPreferenceController(Context context, String key) { public AppOpenByDefaultPreferenceController(Context context, String key) {
super(context, key); super(context, key);
@@ -42,6 +44,12 @@ public class AppOpenByDefaultPreferenceController extends AppInfoPreferenceContr
mPackageManager = context.getPackageManager(); mPackageManager = context.getPackageManager();
} }
/** Set a package name for this controller. */
public AppOpenByDefaultPreferenceController setPackageName(String packageName) {
mPackageName = packageName;
return this;
}
@Override @Override
public void displayPreference(PreferenceScreen screen) { public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen); super.displayPreference(screen);
@@ -57,7 +65,9 @@ public class AppOpenByDefaultPreferenceController extends AppInfoPreferenceContr
@Override @Override
public void updateState(Preference preference) { public void updateState(Preference preference) {
final PackageInfo packageInfo = mParent.getPackageInfo(); final PackageInfo packageInfo = mParent.getPackageInfo();
if (packageInfo != null && !AppUtils.isInstant(packageInfo.applicationInfo)) { if (packageInfo != null && !AppUtils.isInstant(packageInfo.applicationInfo)
&& !AppUtils.isBrowserApp(mContext, packageInfo.packageName,
UserHandle.myUserId())) {
preference.setVisible(true); preference.setVisible(true);
preference.setSummary(AppUtils.getLaunchByDefaultSummary(mParent.getAppEntry(), preference.setSummary(AppUtils.getLaunchByDefaultSummary(mParent.getAppEntry(),
mUsbManager, mPackageManager, mContext)); mUsbManager, mPackageManager, mContext));
@@ -70,5 +80,4 @@ public class AppOpenByDefaultPreferenceController extends AppInfoPreferenceContr
protected Class<? extends SettingsPreferenceFragment> getDetailFragmentClass() { protected Class<? extends SettingsPreferenceFragment> getDetailFragmentClass() {
return AppLaunchSettings.class; return AppLaunchSettings.class;
} }
} }

View File

@@ -19,6 +19,7 @@ package com.android.settings.applications.appinfo;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never; import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy; import static org.mockito.Mockito.spy;
@@ -26,8 +27,12 @@ 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.pm.ActivityInfo;
import android.content.pm.ApplicationInfo; import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo; import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import androidx.preference.Preference; import androidx.preference.Preference;
import androidx.preference.PreferenceScreen; import androidx.preference.PreferenceScreen;
@@ -37,6 +42,8 @@ import com.android.settingslib.applications.AppUtils;
import com.android.settingslib.applications.ApplicationsState.AppEntry; import com.android.settingslib.applications.ApplicationsState.AppEntry;
import com.android.settingslib.applications.instantapps.InstantAppDataProvider; import com.android.settingslib.applications.instantapps.InstantAppDataProvider;
import com.google.common.collect.ImmutableList;
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;
@@ -46,6 +53,8 @@ import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment; import org.robolectric.RuntimeEnvironment;
import org.robolectric.util.ReflectionHelpers; import org.robolectric.util.ReflectionHelpers;
import java.util.List;
@RunWith(RobolectricTestRunner.class) @RunWith(RobolectricTestRunner.class)
public class AppOpenByDefaultPreferenceControllerTest { public class AppOpenByDefaultPreferenceControllerTest {
@@ -55,6 +64,8 @@ public class AppOpenByDefaultPreferenceControllerTest {
private PreferenceScreen mScreen; private PreferenceScreen mScreen;
@Mock @Mock
private Preference mPreference; private Preference mPreference;
@Mock
private PackageManager mPackageManager;
private Context mContext; private Context mContext;
private AppOpenByDefaultPreferenceController mController; private AppOpenByDefaultPreferenceController mController;
@@ -62,10 +73,11 @@ public class AppOpenByDefaultPreferenceControllerTest {
@Before @Before
public void setUp() { public void setUp() {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application.getApplicationContext(); mContext = spy(RuntimeEnvironment.application.getApplicationContext());
mController = spy(new AppOpenByDefaultPreferenceController(mContext, "preferred_app")); mController = spy(new AppOpenByDefaultPreferenceController(mContext, "preferred_app"));
mController.setParentFragment(mFragment); mController.setParentFragment(mFragment);
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference); when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
when(mContext.getPackageManager()).thenReturn(mPackageManager);
} }
@Test @Test
@@ -146,13 +158,42 @@ public class AppOpenByDefaultPreferenceControllerTest {
} }
@Test @Test
public void updateState_notInstantApp_shouldShowPreferenceAndSetSummary() { public void updateState_isBrowserApp_shouldNotShowPreference() {
when(mFragment.getPackageInfo()).thenReturn(new PackageInfo()); final PackageInfo packageInfo = new PackageInfo();
packageInfo.packageName = "com.package.test.browser";
when(mFragment.getPackageInfo()).thenReturn(packageInfo);
ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider",
(InstantAppDataProvider) (i -> false));
final ResolveInfo resolveInfo = new ResolveInfo();
resolveInfo.activityInfo = new ActivityInfo();
resolveInfo.handleAllWebDataURI = true;
final List<ResolveInfo> resolveInfos = ImmutableList.of(resolveInfo);
when(mPackageManager
.queryIntentActivitiesAsUser(any(Intent.class), anyInt(), anyInt()))
.thenReturn(resolveInfos);
mController.updateState(mPreference);
verify(mPreference).setVisible(false);
}
@Test
public void updateState_notBrowserApp_notInstantApp_shouldShowPreferenceAndSetSummary() {
final PackageInfo packageInfo = new PackageInfo();
packageInfo.packageName = "com.package.test.browser";
when(mFragment.getPackageInfo()).thenReturn(packageInfo);
ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider",
(InstantAppDataProvider) (i -> false));
final ResolveInfo resolveInfo = new ResolveInfo();
resolveInfo.activityInfo = new ActivityInfo();
resolveInfo.handleAllWebDataURI = false;
final List<ResolveInfo> resolveInfos = ImmutableList.of(resolveInfo);
when(mPackageManager
.queryIntentActivitiesAsUser(any(Intent.class), anyInt(), anyInt()))
.thenReturn(resolveInfos);
final AppEntry appEntry = mock(AppEntry.class); final AppEntry appEntry = mock(AppEntry.class);
appEntry.info = new ApplicationInfo(); appEntry.info = new ApplicationInfo();
when(mFragment.getAppEntry()).thenReturn(appEntry); when(mFragment.getAppEntry()).thenReturn(appEntry);
ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider",
(InstantAppDataProvider) (i -> false));
mController.updateState(mPreference); mController.updateState(mPreference);