diff --git a/AndroidManifest.xml b/AndroidManifest.xml index eae5eaac7e7..7094d8ef485 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -1382,7 +1382,7 @@ + android:value="com.android.settings.applications.specialaccess.deviceadmin.DeviceAdminSettings" /> @@ -1391,10 +1391,10 @@ android:exported="true" android:targetActivity="Settings$DeviceAdminSettingsActivity"> + android:value="com.android.settings.applications.specialaccess.deviceadmin.DeviceAdminSettings" /> - @@ -1405,7 +1405,7 @@ + android:targetActivity=".applications.specialaccess.deviceadmin.DeviceAdminAdd"> diff --git a/res/xml/security_dashboard_settings.xml b/res/xml/security_dashboard_settings.xml index 789932f8a43..af15c082ae2 100644 --- a/res/xml/security_dashboard_settings.xml +++ b/res/xml/security_dashboard_settings.xml @@ -112,7 +112,7 @@ android:key="manage_device_admin" android:title="@string/manage_device_admin" android:summary="@string/summary_placeholder" - android:fragment="com.android.settings.DeviceAdminSettings" /> + android:fragment="com.android.settings.applications.specialaccess.deviceadmin.DeviceAdminSettings" /> + android:fragment="com.android.settings.applications.specialaccess.deviceadmin.DeviceAdminSettings" + settings:controller="com.android.settings.applications.specialaccess.deviceadmin.DeviceAdministratorsController" /> mParent.showDialogInner(mParent.DLG_CLEAR_INSTANT_APP, 0)); + clearDataButton.setOnClickListener(v -> showDialog()); + } + + private void showDialog() { + final DialogFragment newFragment = + InstantAppButtonDialogFragment.newInstance(mPackageName); + newFragment.setTargetFragment(mParent, 0); + newFragment.show(mParent.getFragmentManager(), KEY_INSTANT_APP_BUTTONS); } private String getDefaultLaunchUri() { diff --git a/src/com/android/settings/DeviceAdminAdd.java b/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminAdd.java similarity index 99% rename from src/com/android/settings/DeviceAdminAdd.java rename to src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminAdd.java index 0ad882df9a2..787b1442d70 100644 --- a/src/com/android/settings/DeviceAdminAdd.java +++ b/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminAdd.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.settings; +package com.android.settings.applications.specialaccess.deviceadmin; import android.app.Activity; import android.app.ActivityManager; @@ -59,6 +59,8 @@ import android.widget.ImageView; import android.widget.TextView; import com.android.internal.logging.nano.MetricsProto; +import com.android.settings.EventLogTags; +import com.android.settings.R; import com.android.settings.overlay.FeatureFactory; import com.android.settings.users.UserDialogs; import com.android.settingslib.RestrictedLockUtils; diff --git a/src/com/android/settings/DeviceAdminSettings.java b/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminSettings.java similarity index 99% rename from src/com/android/settings/DeviceAdminSettings.java rename to src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminSettings.java index bb53018dfd6..6e0f60c9d65 100644 --- a/src/com/android/settings/DeviceAdminSettings.java +++ b/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminSettings.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.settings; +package com.android.settings.applications.specialaccess.deviceadmin; import android.app.Activity; import android.app.AppGlobals; @@ -49,6 +49,8 @@ import android.widget.Switch; import android.widget.TextView; import com.android.internal.logging.nano.MetricsProto; +import com.android.settings.R; +import com.android.settings.Utils; import com.android.settings.overlay.FeatureFactory; import com.android.settingslib.core.instrumentation.Instrumentable; import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin; diff --git a/src/com/android/settings/applications/specialaccess/DeviceAdministratorsController.java b/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdministratorsController.java similarity index 94% rename from src/com/android/settings/applications/specialaccess/DeviceAdministratorsController.java rename to src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdministratorsController.java index bdb99ef113a..5b05b866ab5 100644 --- a/src/com/android/settings/applications/specialaccess/DeviceAdministratorsController.java +++ b/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdministratorsController.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.settings.applications.specialaccess; +package com.android.settings.applications.specialaccess.deviceadmin; import android.content.Context; diff --git a/src/com/android/settings/core/gateway/SettingsGateway.java b/src/com/android/settings/core/gateway/SettingsGateway.java index a050628d31e..fbe7399662d 100644 --- a/src/com/android/settings/core/gateway/SettingsGateway.java +++ b/src/com/android/settings/core/gateway/SettingsGateway.java @@ -17,7 +17,7 @@ package com.android.settings.core.gateway; import com.android.settings.DateTimeSettings; -import com.android.settings.DeviceAdminSettings; +import com.android.settings.applications.specialaccess.deviceadmin.DeviceAdminSettings; import com.android.settings.DisplaySettings; import com.android.settings.IccLockSettings; import com.android.settings.MasterClear; diff --git a/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelper.java b/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelper.java index 026b79f0fd9..4f299401531 100644 --- a/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelper.java +++ b/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelper.java @@ -34,7 +34,7 @@ import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; -import com.android.settings.DeviceAdminAdd; +import com.android.settings.applications.specialaccess.deviceadmin.DeviceAdminAdd; import com.android.settings.R; import com.android.settings.Settings; import com.android.settings.Utils; diff --git a/tests/robotests/src/com/android/settings/applications/appinfo/InstantAppButtonDialogFragmentTest.java b/tests/robotests/src/com/android/settings/applications/appinfo/InstantAppButtonDialogFragmentTest.java new file mode 100644 index 00000000000..c353b1b6006 --- /dev/null +++ b/tests/robotests/src/com/android/settings/applications/appinfo/InstantAppButtonDialogFragmentTest.java @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2018 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.settings.applications.appinfo; + +import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyInt; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.robolectric.Shadows.shadowOf; + +import android.app.AlertDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.pm.PackageManager; +import com.android.settings.R; +import com.android.settings.testutils.SettingsRobolectricTestRunner; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.shadows.ShadowAlertDialog; +import org.robolectric.shadows.ShadowDialog; +import org.robolectric.util.FragmentTestUtil; + +@RunWith(SettingsRobolectricTestRunner.class) +public class InstantAppButtonDialogFragmentTest { + + private static final String TEST_PACKAGE = "testPackage"; + + private InstantAppButtonDialogFragment mFragment; + private Context mContext; + + @Before + public void setUp() { + mContext = spy(RuntimeEnvironment.application); + mFragment = spy(InstantAppButtonDialogFragment.newInstance(TEST_PACKAGE)); + doReturn(mContext).when(mFragment).getContext(); + } + + @Test + public void onClick_shouldDeleteApp() { + final PackageManager packageManager = mock(PackageManager.class); + when(mContext.getPackageManager()).thenReturn(packageManager); + FragmentTestUtil.startFragment(mFragment); + + mFragment.onClick(null /* dialog */, 0 /* which */); + + verify(packageManager) + .deletePackageAsUser(eq(TEST_PACKAGE), any(), anyInt(), anyInt()); + } + + @Test + public void onCreateDialog_clearAppDialog_shouldShowClearAppDataConfirmation() { + FragmentTestUtil.startFragment(mFragment); + + final AlertDialog dialog = (AlertDialog) ShadowDialog.getLatestDialog(); + assertThat(dialog).isNotNull(); + final ShadowAlertDialog shadowDialog = shadowOf(dialog); + + assertThat(shadowDialog.getMessage()).isEqualTo( + mContext.getString(R.string.clear_instant_app_confirmation)); + assertThat(shadowDialog.getTitle()).isEqualTo( + mContext.getString(R.string.clear_instant_app_data)); + assertThat(dialog.getButton(DialogInterface.BUTTON_POSITIVE).getText()).isEqualTo( + mContext.getString(R.string.clear_instant_app_data)); + assertThat(dialog.getButton(DialogInterface.BUTTON_NEGATIVE).getText()).isEqualTo( + mContext.getString(R.string.cancel)); + } +} diff --git a/tests/robotests/src/com/android/settings/applications/appinfo/InstantAppButtonsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/appinfo/InstantAppButtonsPreferenceControllerTest.java index 425b9f0ff19..32cafeb86c2 100644 --- a/tests/robotests/src/com/android/settings/applications/appinfo/InstantAppButtonsPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/applications/appinfo/InstantAppButtonsPreferenceControllerTest.java @@ -27,9 +27,10 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.app.FragmentManager; +import android.app.FragmentTransaction; import android.content.ComponentName; import android.content.Context; -import android.content.DialogInterface; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; @@ -287,13 +288,16 @@ public class InstantAppButtonsPreferenceControllerTest { } @Test - public void onClick_shouldDeleteApp() { - PackageManager packageManager = mock(PackageManager.class); - ReflectionHelpers.setField(mController, "mPackageManager", packageManager); + public void clickClearAppButton_shouldLaunchInstantAppButtonDialogFragment() { + final FragmentManager fragmentManager = mock(FragmentManager.class); + final FragmentTransaction fragmentTransaction = mock(FragmentTransaction.class); + when(mFragment.getFragmentManager()).thenReturn(fragmentManager); + when(fragmentManager.beginTransaction()).thenReturn(fragmentTransaction); + mController.displayPreference(mScreen); - mController.onClick(mock(DialogInterface.class), DialogInterface.BUTTON_POSITIVE); + mClearAppButton.callOnClick(); - verify(packageManager) - .deletePackageAsUser(eq(TEST_AIA_PACKAGE_NAME), any(), anyInt(),anyInt()); + verify(fragmentTransaction).add(any(InstantAppButtonDialogFragment.class), + eq("instant_app_buttons")); } } diff --git a/tests/robotests/src/com/android/settings/DeviceAdminAddTest.java b/tests/robotests/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminAddTest.java similarity index 95% rename from tests/robotests/src/com/android/settings/DeviceAdminAddTest.java rename to tests/robotests/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminAddTest.java index 1a4ce89fbcd..b2965c464d3 100644 --- a/tests/robotests/src/com/android/settings/DeviceAdminAddTest.java +++ b/tests/robotests/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminAddTest.java @@ -11,10 +11,10 @@ * 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 + * limitations under the License. */ -package com.android.settings; +package com.android.settings.applications.specialaccess.deviceadmin; import static org.mockito.Matchers.any; import static org.mockito.Matchers.eq; diff --git a/tests/robotests/src/com/android/settings/applications/specialaccess/DeviceAdministratorsControllerTest.java b/tests/robotests/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdministratorsControllerTest.java similarity index 96% rename from tests/robotests/src/com/android/settings/applications/specialaccess/DeviceAdministratorsControllerTest.java rename to tests/robotests/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdministratorsControllerTest.java index efa784683f3..6e3ff2c857e 100644 --- a/tests/robotests/src/com/android/settings/applications/specialaccess/DeviceAdministratorsControllerTest.java +++ b/tests/robotests/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdministratorsControllerTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.settings.applications.specialaccess; +package com.android.settings.applications.specialaccess.deviceadmin; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.spy; diff --git a/tests/robotests/src/com/android/settings/development/MockLocationAppPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/MockLocationAppPreferenceControllerTest.java index 24d46dd74d7..a8f534129c2 100644 --- a/tests/robotests/src/com/android/settings/development/MockLocationAppPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/development/MockLocationAppPreferenceControllerTest.java @@ -1,6 +1,7 @@ package com.android.settings.development; -import static com.android.settings.development.DevelopmentOptionsActivityRequestCodes.REQUEST_MOCK_LOCATION_APP; +import static com.android.settings.development.DevelopmentOptionsActivityRequestCodes + .REQUEST_MOCK_LOCATION_APP; import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; @@ -16,8 +17,6 @@ import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; -import androidx.preference.Preference; -import androidx.preference.PreferenceScreen; import com.android.settings.R; import com.android.settings.testutils.SettingsRobolectricTestRunner; @@ -32,6 +31,9 @@ import org.robolectric.util.ReflectionHelpers; import java.util.Collections; +import androidx.preference.Preference; +import androidx.preference.PreferenceScreen; + @RunWith(SettingsRobolectricTestRunner.class) public class MockLocationAppPreferenceControllerTest { @@ -45,10 +47,7 @@ public class MockLocationAppPreferenceControllerTest { private Preference mPreference; @Mock private PreferenceScreen mScreen; - @Mock - private AppOpsManager.PackageOps mPackageOps; - @Mock - private AppOpsManager.OpEntry mOpEntry; + @Mock private ApplicationInfo mApplicationInfo; @@ -69,11 +68,12 @@ public class MockLocationAppPreferenceControllerTest { @Test public void updateState_foobarAppSelected_shouldSetSummaryToFoobar() { final String appName = "foobar"; + + final AppOpsManager.PackageOps packageOps = + new AppOpsManager.PackageOps(appName, 0, + Collections.singletonList(createOpEntry(AppOpsManager.MODE_ALLOWED))); when(mAppOpsManager.getPackagesForOps(any())).thenReturn( - Collections.singletonList(mPackageOps)); - when(mPackageOps.getOps()).thenReturn(Collections.singletonList(mOpEntry)); - when(mOpEntry.getMode()).thenReturn(AppOpsManager.MODE_ALLOWED); - when(mPackageOps.getPackageName()).thenReturn(appName); + Collections.singletonList(packageOps)); mController.updateState(mPreference); @@ -96,16 +96,16 @@ public class MockLocationAppPreferenceControllerTest { final String newAppName = "bar"; final Intent intent = new Intent(); intent.setAction(newAppName); + final AppOpsManager.PackageOps packageOps = new AppOpsManager.PackageOps(prevAppName, 0, + Collections.singletonList(createOpEntry(AppOpsManager.MODE_ALLOWED))); + when(mAppOpsManager.getPackagesForOps(any())) - .thenReturn(Collections.singletonList(mPackageOps)); - when(mPackageOps.getOps()).thenReturn(Collections.singletonList(mOpEntry)); - when(mOpEntry.getMode()).thenReturn(AppOpsManager.MODE_ALLOWED); - when(mPackageOps.getPackageName()).thenReturn(prevAppName); + .thenReturn(Collections.singletonList(packageOps)); when(mPackageManager.getApplicationInfo(anyString(), eq(PackageManager.MATCH_DISABLED_COMPONENTS))).thenReturn(mApplicationInfo); final boolean handled = - mController.onActivityResult(REQUEST_MOCK_LOCATION_APP, Activity.RESULT_OK, intent); + mController.onActivityResult(REQUEST_MOCK_LOCATION_APP, Activity.RESULT_OK, intent); assertThat(handled).isTrue(); verify(mAppOpsManager).setMode(anyInt(), anyInt(), eq(newAppName), @@ -139,4 +139,9 @@ public class MockLocationAppPreferenceControllerTest { assertThat(mController.handlePreferenceTreeClick(mPreference)).isFalse(); } + + private AppOpsManager.OpEntry createOpEntry(int opMode) { + return new AppOpsManager.OpEntry(0, opMode, 0l /* time */, 0 /* rejectTime */, + 0 /* duration */, 0 /* proxyUid */, null /* proxyPackage */); + } } diff --git a/tests/robotests/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelperTest.java b/tests/robotests/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelperTest.java index ccd66e86bfc..8914b53daa1 100644 --- a/tests/robotests/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelperTest.java +++ b/tests/robotests/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelperTest.java @@ -32,7 +32,7 @@ import android.view.ViewGroup; import android.widget.FrameLayout; import android.widget.TextView; -import com.android.settings.DeviceAdminAdd; +import com.android.settings.applications.specialaccess.deviceadmin.DeviceAdminAdd; import com.android.settings.R; import com.android.settings.Settings; import com.android.settings.testutils.CustomActivity; diff --git a/tests/robotests/src/com/android/settings/fuelgauge/RestrictAppPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/RestrictAppPreferenceControllerTest.java index c6f885cc5bf..81cf6526347 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/RestrictAppPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/RestrictAppPreferenceControllerTest.java @@ -18,9 +18,7 @@ package com.android.settings.fuelgauge; import static com.android.settings.SettingsActivity.EXTRA_SHOW_FRAGMENT; import static com.android.settings.SettingsActivity.EXTRA_SHOW_FRAGMENT_TITLE_RESID; - import static com.google.common.truth.Truth.assertThat; - import static org.mockito.Matchers.any; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; @@ -31,10 +29,8 @@ import android.content.Context; import android.content.Intent; import android.os.UserHandle; import android.os.UserManager; -import androidx.preference.Preference; import com.android.settings.R; -import com.android.settings.SettingsActivity; import com.android.settings.core.InstrumentedPreferenceFragment; import com.android.settings.fuelgauge.batterytip.AppInfo; @@ -50,6 +46,8 @@ import org.robolectric.RuntimeEnvironment; import java.util.ArrayList; import java.util.List; +import androidx.preference.Preference; + @RunWith(RobolectricTestRunner.class) public class RestrictAppPreferenceControllerTest { private static final int ALLOWED_UID = 111; @@ -61,15 +59,13 @@ public class RestrictAppPreferenceControllerTest { @Mock private AppOpsManager mAppOpsManager; @Mock - private AppOpsManager.PackageOps mRestrictedPackageOps; - @Mock - private AppOpsManager.PackageOps mAllowedPackageOps; - @Mock - private AppOpsManager.PackageOps mOtherUserPackageOps; - @Mock private InstrumentedPreferenceFragment mFragment; @Mock private UserManager mUserManager; + + private AppOpsManager.PackageOps mRestrictedPackageOps; + private AppOpsManager.PackageOps mAllowedPackageOps; + private AppOpsManager.PackageOps mOtherUserPackageOps; private List mPackageOpsList; private RestrictAppPreferenceController mRestrictAppPreferenceController; private Preference mPreference; @@ -87,15 +83,12 @@ public class RestrictAppPreferenceControllerTest { AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, AppOpsManager.MODE_IGNORED, 0, 0, 0, 0, ""); final List restrictedOps = new ArrayList<>(); restrictedOps.add(restrictedOpEntry); - doReturn(ALLOWED_UID).when(mAllowedPackageOps).getUid(); - doReturn(ALLOWED_PACKAGE_NAME).when(mAllowedPackageOps).getPackageName(); - doReturn(allowOps).when(mAllowedPackageOps).getOps(); - doReturn(RESTRICTED_UID).when(mRestrictedPackageOps).getUid(); - doReturn(RESTRICTED_PACKAGE_NAME).when(mRestrictedPackageOps).getPackageName(); - doReturn(restrictedOps).when(mRestrictedPackageOps).getOps(); - doReturn(OTHER_USER_UID).when(mOtherUserPackageOps).getUid(); - doReturn(RESTRICTED_PACKAGE_NAME).when(mOtherUserPackageOps).getPackageName(); - doReturn(restrictedOps).when(mOtherUserPackageOps).getOps(); + mAllowedPackageOps = new AppOpsManager.PackageOps( + ALLOWED_PACKAGE_NAME, ALLOWED_UID, allowOps); + mRestrictedPackageOps = new AppOpsManager.PackageOps( + RESTRICTED_PACKAGE_NAME, RESTRICTED_UID, restrictedOps); + mOtherUserPackageOps = new AppOpsManager.PackageOps( + RESTRICTED_PACKAGE_NAME, OTHER_USER_UID, restrictedOps); mContext = spy(RuntimeEnvironment.application); doReturn(mAppOpsManager).when(mContext).getSystemService(Context.APP_OPS_SERVICE);