From f176175f24a11da9ab100b79b56979bf109b7447 Mon Sep 17 00:00:00 2001 From: Doris Ling Date: Thu, 14 Jun 2018 14:58:52 -0700 Subject: [PATCH 1/4] Move clear instant app dialog logic out of AppInfoDashboardFragment. - refactor AppInfoDashboardFragment and move the clear instant app dialog handling into instant app button controller. - move the dialog fragment to be a stand-alone class instead of inner class. Change-Id: I51c045938f3fd1db73b4b9f7e0311a51df599a29 Fixes: 110102457 Test: make RunSettingsRoboTests --- .../appinfo/AppInfoDashboardFragment.java | 53 +---------- .../appinfo/ButtonActionDialogFragment.java | 15 ++++ .../InstantAppButtonDialogFragment.java | 80 +++++++++++++++++ ...InstantAppButtonsPreferenceController.java | 42 +++------ .../InstantAppButtonDialogFragmentTest.java | 87 +++++++++++++++++++ ...antAppButtonsPreferenceControllerTest.java | 18 ++-- 6 files changed, 206 insertions(+), 89 deletions(-) create mode 100644 src/com/android/settings/applications/appinfo/InstantAppButtonDialogFragment.java create mode 100644 tests/robotests/src/com/android/settings/applications/appinfo/InstantAppButtonDialogFragmentTest.java diff --git a/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java b/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java index 7107ff754aa..44982252e2a 100755 --- a/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java +++ b/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java @@ -19,9 +19,6 @@ package com.android.settings.applications.appinfo; import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; import android.app.Activity; -import android.app.AlertDialog; -import android.app.Dialog; -import android.app.DialogFragment; import android.app.admin.DevicePolicyManager; import android.content.BroadcastReceiver; import android.content.Context; @@ -95,10 +92,6 @@ public class AppInfoDashboardFragment extends DashboardFragment static final int LOADER_STORAGE = 3; static final int LOADER_BATTERY = 4; - // Dialog identifiers used in showDialog - private static final int DLG_BASE = 0; - static final int DLG_CLEAR_INSTANT_APP = DLG_BASE + 1; - public static final String ARG_PACKAGE_NAME = "package"; public static final String ARG_PACKAGE_UID = "uid"; @@ -419,7 +412,9 @@ public class AppInfoDashboardFragment extends DashboardFragment for (Callback callback : mCallbacks) { callback.refreshUi(); } - mAppButtonsPreferenceController.refreshUi(); + if (mAppButtonsPreferenceController.isAvailable()) { + mAppButtonsPreferenceController.refreshUi(); + } if (!mInitialized) { // First time init: are we displaying an uninstalled app? @@ -447,11 +442,6 @@ public class AppInfoDashboardFragment extends DashboardFragment return true; } - @VisibleForTesting - AlertDialog createDialog(int id, int errorCode) { - return mInstantAppButtonPreferenceController.createDialog(id); - } - private void uninstallPkg(String packageName, boolean allUsers, boolean andDisable) { stopListeningToPackageRemove(); // Create new intent to launch Uninstaller activity @@ -561,12 +551,6 @@ public class AppInfoDashboardFragment extends DashboardFragment mFinishing = true; } - void showDialogInner(int id, int moveErrorCode) { - final DialogFragment newFragment = MyAlertDialogFragment.newInstance(id, moveErrorCode); - newFragment.setTargetFragment(this, 0); - newFragment.show(getFragmentManager(), "dialog " + id); - } - @Override public void onRunningStateChanged(boolean running) { // No op. @@ -604,37 +588,6 @@ public class AppInfoDashboardFragment extends DashboardFragment } } - public static class MyAlertDialogFragment extends InstrumentedDialogFragment { - - private static final String ARG_ID = "id"; - - @Override - public int getMetricsCategory() { - return MetricsEvent.DIALOG_APP_INFO_ACTION; - } - - @Override - public Dialog onCreateDialog(Bundle savedInstanceState) { - final int id = getArguments().getInt(ARG_ID); - final int errorCode = getArguments().getInt("moveError"); - final Dialog dialog = - ((AppInfoDashboardFragment) getTargetFragment()).createDialog(id, errorCode); - if (dialog == null) { - throw new IllegalArgumentException("unknown id " + id); - } - return dialog; - } - - public static MyAlertDialogFragment newInstance(int id, int errorCode) { - final MyAlertDialogFragment dialogFragment = new MyAlertDialogFragment(); - final Bundle args = new Bundle(); - args.putInt(ARG_ID, id); - args.putInt("moveError", errorCode); - dialogFragment.setArguments(args); - return dialogFragment; - } - } - @VisibleForTesting void startListeningToPackageRemove() { if (mListeningToPackageRemove) { diff --git a/src/com/android/settings/applications/appinfo/ButtonActionDialogFragment.java b/src/com/android/settings/applications/appinfo/ButtonActionDialogFragment.java index a3f1bab78c5..7198a54ef88 100644 --- a/src/com/android/settings/applications/appinfo/ButtonActionDialogFragment.java +++ b/src/com/android/settings/applications/appinfo/ButtonActionDialogFragment.java @@ -1,3 +1,18 @@ +/* + * 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 android.app.AlertDialog; diff --git a/src/com/android/settings/applications/appinfo/InstantAppButtonDialogFragment.java b/src/com/android/settings/applications/appinfo/InstantAppButtonDialogFragment.java new file mode 100644 index 00000000000..d010918cbeb --- /dev/null +++ b/src/com/android/settings/applications/appinfo/InstantAppButtonDialogFragment.java @@ -0,0 +1,80 @@ +/* + * 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 android.app.AlertDialog; +import android.app.Dialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.pm.PackageManager; +import android.os.Bundle; +import android.os.UserHandle; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; +import com.android.settings.R; +import com.android.settings.core.instrumentation.InstrumentedDialogFragment; +import com.android.settings.overlay.FeatureFactory; + +/** + * Fragment to show the dialog for clearing the instant app. + */ +public class InstantAppButtonDialogFragment extends InstrumentedDialogFragment implements + DialogInterface.OnClickListener { + + private static final String ARG_PACKAGE_NAME = "packageName"; + + private String mPackageName; + + public static InstantAppButtonDialogFragment newInstance(String packageName) { + final InstantAppButtonDialogFragment dialogFragment = new InstantAppButtonDialogFragment(); + final Bundle args = new Bundle(1); + args.putString(ARG_PACKAGE_NAME, packageName); + dialogFragment.setArguments(args); + return dialogFragment; + } + + @Override + public int getMetricsCategory() { + return MetricsEvent.DIALOG_APP_INFO_ACTION; + } + + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + final Bundle arguments = getArguments(); + mPackageName = arguments.getString(ARG_PACKAGE_NAME); + return createDialog(); + } + + @Override + public void onClick(DialogInterface dialog, int which) { + final Context context = getContext(); + final PackageManager packageManager = context.getPackageManager(); + FeatureFactory.getFactory(context).getMetricsFeatureProvider() + .action(context, MetricsEvent.ACTION_SETTINGS_CLEAR_INSTANT_APP, mPackageName); + packageManager.deletePackageAsUser(mPackageName, null, 0, UserHandle.myUserId()); + } + + private AlertDialog createDialog() { + AlertDialog confirmDialog = new AlertDialog.Builder(getContext()) + .setPositiveButton(R.string.clear_instant_app_data, this) + .setNegativeButton(R.string.cancel, null) + .setTitle(R.string.clear_instant_app_data) + .setMessage(R.string.clear_instant_app_confirmation) + .create(); + return confirmDialog; + } + +} + diff --git a/src/com/android/settings/applications/appinfo/InstantAppButtonsPreferenceController.java b/src/com/android/settings/applications/appinfo/InstantAppButtonsPreferenceController.java index 4d1dfd9589b..8498669e348 100644 --- a/src/com/android/settings/applications/appinfo/InstantAppButtonsPreferenceController.java +++ b/src/com/android/settings/applications/appinfo/InstantAppButtonsPreferenceController.java @@ -16,15 +16,13 @@ package com.android.settings.applications.appinfo; -import android.app.AlertDialog; +import android.app.DialogFragment; import android.content.Context; -import android.content.DialogInterface; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.net.Uri; import android.os.Bundle; -import android.os.UserHandle; import androidx.preference.PreferenceScreen; import android.text.TextUtils; @@ -34,12 +32,10 @@ import android.view.MenuItem; import android.view.View; import android.widget.Button; -import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settings.R; import com.android.settings.applications.AppStoreUtil; import com.android.settings.applications.LayoutPreference; import com.android.settings.core.BasePreferenceController; -import com.android.settings.overlay.FeatureFactory; import com.android.settingslib.applications.AppUtils; import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.core.lifecycle.LifecycleObserver; @@ -50,15 +46,13 @@ import com.android.settingslib.core.lifecycle.events.OnPrepareOptionsMenu; import java.util.List; public class InstantAppButtonsPreferenceController extends BasePreferenceController implements - LifecycleObserver, OnCreateOptionsMenu, OnPrepareOptionsMenu, OnOptionsItemSelected, - DialogInterface.OnClickListener { + LifecycleObserver, OnCreateOptionsMenu, OnPrepareOptionsMenu, OnOptionsItemSelected { private static final String KEY_INSTANT_APP_BUTTONS = "instant_app_buttons"; private static final String META_DATA_DEFAULT_URI = "default-url"; private final AppInfoDashboardFragment mParent; private final String mPackageName; - private final PackageManager mPackageManager; private String mLaunchUri; private LayoutPreference mPreference; private MenuItem mInstallMenu; @@ -68,7 +62,6 @@ public class InstantAppButtonsPreferenceController extends BasePreferenceControl super(context, KEY_INSTANT_APP_BUTTONS); mParent = parent; mPackageName = packageName; - mPackageManager = context.getPackageManager(); mLaunchUri = getDefaultLaunchUri(); if (lifecycle != null) { lifecycle.addObserver(this); @@ -118,27 +111,6 @@ public class InstantAppButtonsPreferenceController extends BasePreferenceControl } } - @Override - public void onClick(DialogInterface dialog, int which) { - FeatureFactory.getFactory(mContext).getMetricsFeatureProvider() - .action(mContext, MetricsEvent.ACTION_SETTINGS_CLEAR_INSTANT_APP, mPackageName); - mPackageManager.deletePackageAsUser( - mPackageName, null, 0, UserHandle.myUserId()); - } - - AlertDialog createDialog(int id) { - if (id == AppInfoDashboardFragment.DLG_CLEAR_INSTANT_APP) { - AlertDialog confirmDialog = new AlertDialog.Builder(mContext) - .setPositiveButton(R.string.clear_instant_app_data, this) - .setNegativeButton(R.string.cancel, null) - .setTitle(R.string.clear_instant_app_data) - .setMessage(mContext.getString(R.string.clear_instant_app_confirmation)) - .create(); - return confirmDialog; - } - return null; - } - private void initButtons(View view) { final Button installButton = view.findViewById(R.id.install); final Button clearDataButton = view.findViewById(R.id.clear_data); @@ -160,8 +132,14 @@ public class InstantAppButtonsPreferenceController extends BasePreferenceControl installButton.setEnabled(false); } } - clearDataButton.setOnClickListener( - v -> 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/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")); } } From ca6d86c5ab02fef5640c093f44d2094b9e0d24a8 Mon Sep 17 00:00:00 2001 From: Fan Zhang Date: Thu, 14 Jun 2018 12:52:06 -0700 Subject: [PATCH 2/4] Move device admin viewer/adder to specialaccess package. Bug: 110207366 Test: robo Change-Id: I51552dcc5ec6525040cfde17087b7f3f6b21b581 --- AndroidManifest.xml | 8 ++++---- res/xml/security_dashboard_settings.xml | 2 +- res/xml/special_access.xml | 4 ++-- .../appinfo/AppButtonsPreferenceController.java | 2 +- .../specialaccess/deviceadmin}/DeviceAdminAdd.java | 4 +++- .../specialaccess/deviceadmin}/DeviceAdminSettings.java | 4 +++- .../{ => deviceadmin}/DeviceAdministratorsController.java | 2 +- .../android/settings/core/gateway/SettingsGateway.java | 2 +- .../enterprise/ActionDisabledByAdminDialogHelper.java | 2 +- .../specialaccess/deviceadmin}/DeviceAdminAddTest.java | 4 ++-- .../DeviceAdministratorsControllerTest.java | 2 +- .../enterprise/ActionDisabledByAdminDialogHelperTest.java | 2 +- 12 files changed, 21 insertions(+), 17 deletions(-) rename src/com/android/settings/{ => applications/specialaccess/deviceadmin}/DeviceAdminAdd.java (99%) rename src/com/android/settings/{ => applications/specialaccess/deviceadmin}/DeviceAdminSettings.java (99%) rename src/com/android/settings/applications/specialaccess/{ => deviceadmin}/DeviceAdministratorsController.java (94%) rename tests/robotests/src/com/android/settings/{ => applications/specialaccess/deviceadmin}/DeviceAdminAddTest.java (95%) rename tests/robotests/src/com/android/settings/applications/specialaccess/{ => deviceadmin}/DeviceAdministratorsControllerTest.java (96%) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 4fa39649718..8bd2581b4af 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" /> Date: Fri, 15 Jun 2018 10:24:32 -0700 Subject: [PATCH 3/4] Disable two test files They are broken in master because of change in framework. First disable them to unblock the master. Bug: 110263693 Test: RunSettingsRoboTests Change-Id: I487129c905b070a5a968fd2b677218909e1afda4 --- .../development/MockLocationAppPreferenceControllerTest.java | 2 ++ .../settings/fuelgauge/RestrictAppPreferenceControllerTest.java | 2 ++ 2 files changed, 4 insertions(+) diff --git a/tests/robotests/src/com/android/settings/development/MockLocationAppPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/MockLocationAppPreferenceControllerTest.java index 24d46dd74d7..e247485f082 100644 --- a/tests/robotests/src/com/android/settings/development/MockLocationAppPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/development/MockLocationAppPreferenceControllerTest.java @@ -23,6 +23,7 @@ import com.android.settings.R; import com.android.settings.testutils.SettingsRobolectricTestRunner; import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; @@ -33,6 +34,7 @@ import org.robolectric.util.ReflectionHelpers; import java.util.Collections; @RunWith(SettingsRobolectricTestRunner.class) +@Ignore public class MockLocationAppPreferenceControllerTest { @Mock diff --git a/tests/robotests/src/com/android/settings/fuelgauge/RestrictAppPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/RestrictAppPreferenceControllerTest.java index c6f885cc5bf..a377c16439b 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/RestrictAppPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/RestrictAppPreferenceControllerTest.java @@ -39,6 +39,7 @@ import com.android.settings.core.InstrumentedPreferenceFragment; import com.android.settings.fuelgauge.batterytip.AppInfo; import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; @@ -51,6 +52,7 @@ import java.util.ArrayList; import java.util.List; @RunWith(RobolectricTestRunner.class) +@Ignore public class RestrictAppPreferenceControllerTest { private static final int ALLOWED_UID = 111; private static final String ALLOWED_PACKAGE_NAME = "com.android.allowed.package"; From 50c8cdbf7ea01cea705a61d5389e722b368ba3b8 Mon Sep 17 00:00:00 2001 From: Fan Zhang Date: Fri, 15 Jun 2018 10:33:46 -0700 Subject: [PATCH 4/4] Fix robotest Change-Id: Id6e9c82121873b68e6806d6c80634d592606f479 Fixes: 110263693 Test: robotest --- ...ckLocationAppPreferenceControllerTest.java | 39 ++++++++++--------- .../RestrictAppPreferenceControllerTest.java | 33 ++++++---------- 2 files changed, 33 insertions(+), 39 deletions(-) diff --git a/tests/robotests/src/com/android/settings/development/MockLocationAppPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/MockLocationAppPreferenceControllerTest.java index e247485f082..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,14 +17,11 @@ 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; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; @@ -33,8 +31,10 @@ import org.robolectric.util.ReflectionHelpers; import java.util.Collections; +import androidx.preference.Preference; +import androidx.preference.PreferenceScreen; + @RunWith(SettingsRobolectricTestRunner.class) -@Ignore public class MockLocationAppPreferenceControllerTest { @Mock @@ -47,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; @@ -71,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); @@ -98,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), @@ -141,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/fuelgauge/RestrictAppPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/RestrictAppPreferenceControllerTest.java index a377c16439b..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,15 +29,12 @@ 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; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; @@ -51,8 +46,9 @@ import org.robolectric.RuntimeEnvironment; import java.util.ArrayList; import java.util.List; +import androidx.preference.Preference; + @RunWith(RobolectricTestRunner.class) -@Ignore public class RestrictAppPreferenceControllerTest { private static final int ALLOWED_UID = 111; private static final String ALLOWED_PACKAGE_NAME = "com.android.allowed.package"; @@ -63,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; @@ -89,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);