Loading src/com/android/settings/vpn2/AdvancedVpnFeatureProvider.java +5 −0 Original line number Diff line number Diff line Loading @@ -47,4 +47,9 @@ public interface AdvancedVpnFeatureProvider { * Returns {@code true} advanced vpn is removable. */ boolean isAdvancedVpnRemovable(); /** * Returns {@code true} if the disconnect dialog is enabled when advanced vpn is connected. */ boolean isDisconnectDialogEnabled(); } src/com/android/settings/vpn2/AdvancedVpnFeatureProviderImpl.java +5 −0 Original line number Diff line number Diff line Loading @@ -46,4 +46,9 @@ public class AdvancedVpnFeatureProviderImpl implements AdvancedVpnFeatureProvide public boolean isAdvancedVpnRemovable() { return true; } @Override public boolean isDisconnectDialogEnabled() { return true; } } src/com/android/settings/vpn2/VpnSettings.java +7 −5 Original line number Diff line number Diff line Loading @@ -366,7 +366,7 @@ public class VpnSettings extends RestrictedSettingsFragment implements public void setShownPreferences(final Collection<Preference> updates) { retainAllPreference(updates); final PreferenceGroup vpnGroup = getPreferenceScreen(); final PreferenceGroup vpnGroup = mPreferenceScreen; updatePreferenceGroup(vpnGroup, updates); // Show all new preferences on the screen Loading Loading @@ -448,14 +448,16 @@ public class VpnSettings extends RestrictedSettingsFragment implements } else if (preference instanceof AppPreference) { AppPreference pref = (AppPreference) preference; boolean connected = (pref.getState() == AppPreference.STATE_CONNECTED); String vpnPackageName = pref.getPackageName(); if (!connected) { if ((!connected) || (isAdvancedVpn(mFeatureProvider, vpnPackageName, getContext()) && !mFeatureProvider.isDisconnectDialogEnabled())) { try { UserHandle user = UserHandle.of(pref.getUserId()); Context userContext = getActivity().createPackageContextAsUser( getActivity().getPackageName(), 0 /* flags */, user); Context userContext = getContext().createPackageContextAsUser( getContext().getPackageName(), 0 /* flags */, user); PackageManager pm = userContext.getPackageManager(); Intent appIntent = pm.getLaunchIntentForPackage(pref.getPackageName()); Intent appIntent = pm.getLaunchIntentForPackage(vpnPackageName); if (appIntent != null) { userContext.startActivityAsUser(appIntent, user); return true; Loading tests/unit/src/com/android/settings/vpn2/VpnSettingsTest.java +106 −9 Original line number Diff line number Diff line Loading @@ -21,16 +21,21 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.AppOpsManager; import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.os.Looper; import android.os.UserHandle; import android.text.TextUtils; import android.util.ArraySet; import androidx.preference.Preference; Loading @@ -48,6 +53,7 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; Loading @@ -58,13 +64,18 @@ import java.util.Set; @RunWith(AndroidJUnit4.class) public class VpnSettingsTest { private static final String ADVANCED_VPN_GROUP_KEY = "advanced_vpn_group"; private static final int USER_ID_1 = UserHandle.USER_NULL; private static final String VPN_GROUP_KEY = "vpn_group"; private static final String ADVANCED_VPN_GROUP_TITLE = "advanced_vpn_group_title"; private static final String VPN_GROUP_TITLE = "vpn_group_title"; private static final String FAKE_PACKAGE_NAME = "com.fake.package.name"; private static final String ADVANCED_VPN_GROUP_PACKAGE_NAME = "com.advanced.package.name"; private static final int USER_ID_1 = UserHandle.USER_NULL; private static final String VPN_PACKAGE_NAME = "vpn.package.name"; private static final String VPN_LAUNCH_INTENT = "vpn.action"; private static final String ADVANCED_VPN_GROUP_KEY = "advanced_vpn_group"; private static final String ADVANCED_VPN_GROUP_TITLE = "advanced_vpn_group_title"; private static final String ADVANCED_VPN_PACKAGE_NAME = "advanced.vpn.package.name"; private static final String ADVANCED_VPN_LAUNCH_INTENT = "advanced.vpn.action"; private final Intent mVpnIntent = new Intent().setAction(VPN_LAUNCH_INTENT); private final Intent mAdvancedVpnIntent = new Intent().setAction(ADVANCED_VPN_LAUNCH_INTENT); @Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule(); Loading Loading @@ -108,7 +119,7 @@ public class VpnSettingsTest { when(mFakeFeatureFactory.mAdvancedVpnFeatureProvider.getVpnPreferenceGroupTitle(mContext)) .thenReturn(VPN_GROUP_TITLE); when(mFakeFeatureFactory.mAdvancedVpnFeatureProvider.getAdvancedVpnPackageName()) .thenReturn(ADVANCED_VPN_GROUP_PACKAGE_NAME); .thenReturn(ADVANCED_VPN_PACKAGE_NAME); when(mFakeFeatureFactory.mAdvancedVpnFeatureProvider.isAdvancedVpnSupported(any())) .thenReturn(true); when(mContext.getPackageManager()).thenReturn(mPackageManager); Loading @@ -122,7 +133,7 @@ public class VpnSettingsTest { public void setShownAdvancedPreferences_hasGeneralVpn_returnsVpnCountAs1() { Set<Preference> updates = new ArraySet<>(); AppPreference pref = spy(new AppPreference(mContext, USER_ID_1, FAKE_PACKAGE_NAME)); spy(new AppPreference(mContext, USER_ID_1, VPN_PACKAGE_NAME)); updates.add(pref); mVpnSettings.setShownAdvancedPreferences(updates); Loading @@ -136,7 +147,7 @@ public class VpnSettingsTest { public void setShownAdvancedPreferences_hasAdvancedVpn_returnsAdvancedVpnCountAs1() { Set<Preference> updates = new ArraySet<>(); AppPreference pref = spy(new AppPreference(mContext, USER_ID_1, ADVANCED_VPN_GROUP_PACKAGE_NAME)); spy(new AppPreference(mContext, USER_ID_1, ADVANCED_VPN_PACKAGE_NAME)); updates.add(pref); mVpnSettings.setShownAdvancedPreferences(updates); Loading Loading @@ -175,7 +186,7 @@ public class VpnSettingsTest { List<AppOpsManager.OpEntry> opEntries = new ArrayList<>(); List<AppOpsManager.PackageOps> apps = new ArrayList<>(); AppOpsManager.PackageOps packageOps = new AppOpsManager.PackageOps(FAKE_PACKAGE_NAME, uid, opEntries); new AppOpsManager.PackageOps(VPN_PACKAGE_NAME, uid, opEntries); apps.add(packageOps); when(mAppOpsManager.getPackagesForOps((int[]) any())).thenReturn(apps); when(mFakeFeatureFactory.mAdvancedVpnFeatureProvider.isAdvancedVpnSupported(any())) Loading @@ -185,4 +196,90 @@ public class VpnSettingsTest { mFakeFeatureFactory.getAdvancedVpnFeatureProvider(), mAppOpsManager)).isEmpty(); } @Test public void clickVpn_VpnConnected_doesNotStartVpnLaunchIntent() throws PackageManager.NameNotFoundException { Set<Preference> updates = new ArraySet<>(); AppPreference pref = spy(new AppPreference(mContext, USER_ID_1, VPN_PACKAGE_NAME)); pref.setState(AppPreference.STATE_CONNECTED); updates.add(pref); when(mContext.createPackageContextAsUser(any(), anyInt(), any())).thenReturn(mContext); when(mContext.getPackageManager()).thenReturn(mPackageManager); when(mPackageManager.getLaunchIntentForPackage(any())).thenReturn(mVpnIntent); ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class); doNothing().when(mContext).startActivityAsUser(captor.capture(), any()); mVpnSettings.setShownPreferences(updates); mVpnSettings.onPreferenceClick(pref); verify(mContext, never()).startActivityAsUser(any(), any()); } @Test public void clickVpn_VpnDisconnected_startsVpnLaunchIntent() throws PackageManager.NameNotFoundException { Set<Preference> updates = new ArraySet<>(); AppPreference pref = spy(new AppPreference(mContext, USER_ID_1, VPN_PACKAGE_NAME)); pref.setState(AppPreference.STATE_DISCONNECTED); updates.add(pref); when(mContext.createPackageContextAsUser(any(), anyInt(), any())).thenReturn(mContext); when(mContext.getPackageManager()).thenReturn(mPackageManager); when(mPackageManager.getLaunchIntentForPackage(any())).thenReturn(mVpnIntent); ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class); doNothing().when(mContext).startActivityAsUser(captor.capture(), any()); mVpnSettings.setShownPreferences(updates); mVpnSettings.onPreferenceClick(pref); verify(mContext).startActivityAsUser(captor.capture(), any()); assertThat(TextUtils.equals(captor.getValue().getAction(), VPN_LAUNCH_INTENT)).isTrue(); } @Test public void clickAdvancedVpn_VpnConnectedDisconnectDialogDisabled_startsAppLaunchIntent() throws PackageManager.NameNotFoundException { Set<Preference> updates = new ArraySet<>(); AppPreference pref = spy(new AppPreference(mContext, USER_ID_1, ADVANCED_VPN_PACKAGE_NAME)); pref.setState(AppPreference.STATE_CONNECTED); updates.add(pref); when(mFakeFeatureFactory.mAdvancedVpnFeatureProvider.isDisconnectDialogEnabled()) .thenReturn(false); when(mContext.createPackageContextAsUser(any(), anyInt(), any())).thenReturn(mContext); when(mContext.getPackageManager()).thenReturn(mPackageManager); when(mPackageManager.getLaunchIntentForPackage(any())).thenReturn(mAdvancedVpnIntent); ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class); doNothing().when(mContext).startActivityAsUser(captor.capture(), any()); mVpnSettings.setShownAdvancedPreferences(updates); mVpnSettings.onPreferenceClick(pref); verify(mContext).startActivityAsUser(captor.capture(), any()); assertThat(TextUtils.equals(captor.getValue().getAction(), ADVANCED_VPN_LAUNCH_INTENT)).isTrue(); } @Test public void clickAdvancedVpn_VpnConnectedDisconnectDialogEnabled_doesNotStartAppLaunchIntent() throws PackageManager.NameNotFoundException { Set<Preference> updates = new ArraySet<>(); AppPreference pref = spy(new AppPreference(mContext, USER_ID_1, ADVANCED_VPN_PACKAGE_NAME)); pref.setState(AppPreference.STATE_CONNECTED); updates.add(pref); when(mFakeFeatureFactory.mAdvancedVpnFeatureProvider.isDisconnectDialogEnabled()) .thenReturn(true); when(mContext.createPackageContextAsUser(any(), anyInt(), any())).thenReturn(mContext); when(mContext.getPackageManager()).thenReturn(mPackageManager); when(mPackageManager.getLaunchIntentForPackage(any())).thenReturn(mAdvancedVpnIntent); ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class); doNothing().when(mContext).startActivityAsUser(captor.capture(), any()); mVpnSettings.setShownAdvancedPreferences(updates); mVpnSettings.onPreferenceClick(pref); verify(mContext, never()).startActivityAsUser(any(), any()); } } Loading
src/com/android/settings/vpn2/AdvancedVpnFeatureProvider.java +5 −0 Original line number Diff line number Diff line Loading @@ -47,4 +47,9 @@ public interface AdvancedVpnFeatureProvider { * Returns {@code true} advanced vpn is removable. */ boolean isAdvancedVpnRemovable(); /** * Returns {@code true} if the disconnect dialog is enabled when advanced vpn is connected. */ boolean isDisconnectDialogEnabled(); }
src/com/android/settings/vpn2/AdvancedVpnFeatureProviderImpl.java +5 −0 Original line number Diff line number Diff line Loading @@ -46,4 +46,9 @@ public class AdvancedVpnFeatureProviderImpl implements AdvancedVpnFeatureProvide public boolean isAdvancedVpnRemovable() { return true; } @Override public boolean isDisconnectDialogEnabled() { return true; } }
src/com/android/settings/vpn2/VpnSettings.java +7 −5 Original line number Diff line number Diff line Loading @@ -366,7 +366,7 @@ public class VpnSettings extends RestrictedSettingsFragment implements public void setShownPreferences(final Collection<Preference> updates) { retainAllPreference(updates); final PreferenceGroup vpnGroup = getPreferenceScreen(); final PreferenceGroup vpnGroup = mPreferenceScreen; updatePreferenceGroup(vpnGroup, updates); // Show all new preferences on the screen Loading Loading @@ -448,14 +448,16 @@ public class VpnSettings extends RestrictedSettingsFragment implements } else if (preference instanceof AppPreference) { AppPreference pref = (AppPreference) preference; boolean connected = (pref.getState() == AppPreference.STATE_CONNECTED); String vpnPackageName = pref.getPackageName(); if (!connected) { if ((!connected) || (isAdvancedVpn(mFeatureProvider, vpnPackageName, getContext()) && !mFeatureProvider.isDisconnectDialogEnabled())) { try { UserHandle user = UserHandle.of(pref.getUserId()); Context userContext = getActivity().createPackageContextAsUser( getActivity().getPackageName(), 0 /* flags */, user); Context userContext = getContext().createPackageContextAsUser( getContext().getPackageName(), 0 /* flags */, user); PackageManager pm = userContext.getPackageManager(); Intent appIntent = pm.getLaunchIntentForPackage(pref.getPackageName()); Intent appIntent = pm.getLaunchIntentForPackage(vpnPackageName); if (appIntent != null) { userContext.startActivityAsUser(appIntent, user); return true; Loading
tests/unit/src/com/android/settings/vpn2/VpnSettingsTest.java +106 −9 Original line number Diff line number Diff line Loading @@ -21,16 +21,21 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.AppOpsManager; import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.os.Looper; import android.os.UserHandle; import android.text.TextUtils; import android.util.ArraySet; import androidx.preference.Preference; Loading @@ -48,6 +53,7 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; Loading @@ -58,13 +64,18 @@ import java.util.Set; @RunWith(AndroidJUnit4.class) public class VpnSettingsTest { private static final String ADVANCED_VPN_GROUP_KEY = "advanced_vpn_group"; private static final int USER_ID_1 = UserHandle.USER_NULL; private static final String VPN_GROUP_KEY = "vpn_group"; private static final String ADVANCED_VPN_GROUP_TITLE = "advanced_vpn_group_title"; private static final String VPN_GROUP_TITLE = "vpn_group_title"; private static final String FAKE_PACKAGE_NAME = "com.fake.package.name"; private static final String ADVANCED_VPN_GROUP_PACKAGE_NAME = "com.advanced.package.name"; private static final int USER_ID_1 = UserHandle.USER_NULL; private static final String VPN_PACKAGE_NAME = "vpn.package.name"; private static final String VPN_LAUNCH_INTENT = "vpn.action"; private static final String ADVANCED_VPN_GROUP_KEY = "advanced_vpn_group"; private static final String ADVANCED_VPN_GROUP_TITLE = "advanced_vpn_group_title"; private static final String ADVANCED_VPN_PACKAGE_NAME = "advanced.vpn.package.name"; private static final String ADVANCED_VPN_LAUNCH_INTENT = "advanced.vpn.action"; private final Intent mVpnIntent = new Intent().setAction(VPN_LAUNCH_INTENT); private final Intent mAdvancedVpnIntent = new Intent().setAction(ADVANCED_VPN_LAUNCH_INTENT); @Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule(); Loading Loading @@ -108,7 +119,7 @@ public class VpnSettingsTest { when(mFakeFeatureFactory.mAdvancedVpnFeatureProvider.getVpnPreferenceGroupTitle(mContext)) .thenReturn(VPN_GROUP_TITLE); when(mFakeFeatureFactory.mAdvancedVpnFeatureProvider.getAdvancedVpnPackageName()) .thenReturn(ADVANCED_VPN_GROUP_PACKAGE_NAME); .thenReturn(ADVANCED_VPN_PACKAGE_NAME); when(mFakeFeatureFactory.mAdvancedVpnFeatureProvider.isAdvancedVpnSupported(any())) .thenReturn(true); when(mContext.getPackageManager()).thenReturn(mPackageManager); Loading @@ -122,7 +133,7 @@ public class VpnSettingsTest { public void setShownAdvancedPreferences_hasGeneralVpn_returnsVpnCountAs1() { Set<Preference> updates = new ArraySet<>(); AppPreference pref = spy(new AppPreference(mContext, USER_ID_1, FAKE_PACKAGE_NAME)); spy(new AppPreference(mContext, USER_ID_1, VPN_PACKAGE_NAME)); updates.add(pref); mVpnSettings.setShownAdvancedPreferences(updates); Loading @@ -136,7 +147,7 @@ public class VpnSettingsTest { public void setShownAdvancedPreferences_hasAdvancedVpn_returnsAdvancedVpnCountAs1() { Set<Preference> updates = new ArraySet<>(); AppPreference pref = spy(new AppPreference(mContext, USER_ID_1, ADVANCED_VPN_GROUP_PACKAGE_NAME)); spy(new AppPreference(mContext, USER_ID_1, ADVANCED_VPN_PACKAGE_NAME)); updates.add(pref); mVpnSettings.setShownAdvancedPreferences(updates); Loading Loading @@ -175,7 +186,7 @@ public class VpnSettingsTest { List<AppOpsManager.OpEntry> opEntries = new ArrayList<>(); List<AppOpsManager.PackageOps> apps = new ArrayList<>(); AppOpsManager.PackageOps packageOps = new AppOpsManager.PackageOps(FAKE_PACKAGE_NAME, uid, opEntries); new AppOpsManager.PackageOps(VPN_PACKAGE_NAME, uid, opEntries); apps.add(packageOps); when(mAppOpsManager.getPackagesForOps((int[]) any())).thenReturn(apps); when(mFakeFeatureFactory.mAdvancedVpnFeatureProvider.isAdvancedVpnSupported(any())) Loading @@ -185,4 +196,90 @@ public class VpnSettingsTest { mFakeFeatureFactory.getAdvancedVpnFeatureProvider(), mAppOpsManager)).isEmpty(); } @Test public void clickVpn_VpnConnected_doesNotStartVpnLaunchIntent() throws PackageManager.NameNotFoundException { Set<Preference> updates = new ArraySet<>(); AppPreference pref = spy(new AppPreference(mContext, USER_ID_1, VPN_PACKAGE_NAME)); pref.setState(AppPreference.STATE_CONNECTED); updates.add(pref); when(mContext.createPackageContextAsUser(any(), anyInt(), any())).thenReturn(mContext); when(mContext.getPackageManager()).thenReturn(mPackageManager); when(mPackageManager.getLaunchIntentForPackage(any())).thenReturn(mVpnIntent); ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class); doNothing().when(mContext).startActivityAsUser(captor.capture(), any()); mVpnSettings.setShownPreferences(updates); mVpnSettings.onPreferenceClick(pref); verify(mContext, never()).startActivityAsUser(any(), any()); } @Test public void clickVpn_VpnDisconnected_startsVpnLaunchIntent() throws PackageManager.NameNotFoundException { Set<Preference> updates = new ArraySet<>(); AppPreference pref = spy(new AppPreference(mContext, USER_ID_1, VPN_PACKAGE_NAME)); pref.setState(AppPreference.STATE_DISCONNECTED); updates.add(pref); when(mContext.createPackageContextAsUser(any(), anyInt(), any())).thenReturn(mContext); when(mContext.getPackageManager()).thenReturn(mPackageManager); when(mPackageManager.getLaunchIntentForPackage(any())).thenReturn(mVpnIntent); ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class); doNothing().when(mContext).startActivityAsUser(captor.capture(), any()); mVpnSettings.setShownPreferences(updates); mVpnSettings.onPreferenceClick(pref); verify(mContext).startActivityAsUser(captor.capture(), any()); assertThat(TextUtils.equals(captor.getValue().getAction(), VPN_LAUNCH_INTENT)).isTrue(); } @Test public void clickAdvancedVpn_VpnConnectedDisconnectDialogDisabled_startsAppLaunchIntent() throws PackageManager.NameNotFoundException { Set<Preference> updates = new ArraySet<>(); AppPreference pref = spy(new AppPreference(mContext, USER_ID_1, ADVANCED_VPN_PACKAGE_NAME)); pref.setState(AppPreference.STATE_CONNECTED); updates.add(pref); when(mFakeFeatureFactory.mAdvancedVpnFeatureProvider.isDisconnectDialogEnabled()) .thenReturn(false); when(mContext.createPackageContextAsUser(any(), anyInt(), any())).thenReturn(mContext); when(mContext.getPackageManager()).thenReturn(mPackageManager); when(mPackageManager.getLaunchIntentForPackage(any())).thenReturn(mAdvancedVpnIntent); ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class); doNothing().when(mContext).startActivityAsUser(captor.capture(), any()); mVpnSettings.setShownAdvancedPreferences(updates); mVpnSettings.onPreferenceClick(pref); verify(mContext).startActivityAsUser(captor.capture(), any()); assertThat(TextUtils.equals(captor.getValue().getAction(), ADVANCED_VPN_LAUNCH_INTENT)).isTrue(); } @Test public void clickAdvancedVpn_VpnConnectedDisconnectDialogEnabled_doesNotStartAppLaunchIntent() throws PackageManager.NameNotFoundException { Set<Preference> updates = new ArraySet<>(); AppPreference pref = spy(new AppPreference(mContext, USER_ID_1, ADVANCED_VPN_PACKAGE_NAME)); pref.setState(AppPreference.STATE_CONNECTED); updates.add(pref); when(mFakeFeatureFactory.mAdvancedVpnFeatureProvider.isDisconnectDialogEnabled()) .thenReturn(true); when(mContext.createPackageContextAsUser(any(), anyInt(), any())).thenReturn(mContext); when(mContext.getPackageManager()).thenReturn(mPackageManager); when(mPackageManager.getLaunchIntentForPackage(any())).thenReturn(mAdvancedVpnIntent); ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class); doNothing().when(mContext).startActivityAsUser(captor.capture(), any()); mVpnSettings.setShownAdvancedPreferences(updates); mVpnSettings.onPreferenceClick(pref); verify(mContext, never()).startActivityAsUser(any(), any()); } }