Merge "Keystore 2.0: Update credential settings to use public Keystore API." am: 7086917968 am: 08bea2183d am: a409521a64 am: 4e10002367
Original change: https://android-review.googlesource.com/c/platform/packages/apps/Settings/+/1569700
MUST ONLY BE SUBMITTED BY AUTOMERGER
Change-Id: I2e1974eb69cbdfb0e5323e594ff01e82b69168c2
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 86d7992..5ba05c3 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -81,6 +81,7 @@
<uses-permission android:name="android.permission.OEM_UNLOCK_STATE" />
<uses-permission android:name="android.permission.MANAGE_USER_OEM_UNLOCK_STATE" />
<uses-permission android:name="android.permission.OVERRIDE_WIFI_CONFIG" />
+ <uses-permission android:name="android.permission.RESTART_WIFI_SUBSYSTEM" />
<uses-permission android:name="android.permission.MANAGE_FINGERPRINT" />
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
<uses-permission android:name="android.permission.USE_BIOMETRIC_INTERNAL" />
diff --git a/res/values-mcc234/strings.xml b/res/values-mcc234/strings.xml
new file mode 100644
index 0000000..f7d0d33
--- /dev/null
+++ b/res/values-mcc234/strings.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 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.
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="cell_broadcast_settings">Emergency alerts</string>
+</resources>
\ No newline at end of file
diff --git a/res/values-nl/arrays.xml b/res/values-nl/arrays.xml
index 54b7224..627fa59 100644
--- a/res/values-nl/arrays.xml
+++ b/res/values-nl/arrays.xml
@@ -273,7 +273,7 @@
<item msgid="5099026183238335900">"monitorlocatie"</item>
<item msgid="2297727967385895059">"locatie met hoog energieverbruik controleren"</item>
<item msgid="8700593962030471569">"gebruiksstatistieken ophalen"</item>
- <item msgid="4140820386622184831">"microfoon dempen/dempen opheffen"</item>
+ <item msgid="4140820386622184831">"microfoon uit-/aanzetten"</item>
<item msgid="317746827951691657">"toast weergeven"</item>
<item msgid="5679422988212309779">"media projecteren"</item>
<item msgid="6454031639780101439">"VPN activeren"</item>
@@ -340,7 +340,7 @@
<item msgid="8482874682804856549">"Locatie"</item>
<item msgid="5186169827582545242">"Locatie"</item>
<item msgid="6122293931012635638">"Gebruiksstatistieken ophalen"</item>
- <item msgid="2526677383312751932">"Microfoon dempen/dempen opheffen"</item>
+ <item msgid="2526677383312751932">"Microfoon uit-/aanzetten"</item>
<item msgid="4000577305179914546">"Toast weergeven"</item>
<item msgid="8660207174515570558">"Media projecteren"</item>
<item msgid="3904996949561946108">"VPN activeren"</item>
diff --git a/src/com/android/settings/deviceinfo/BuildNumberPreferenceController.java b/src/com/android/settings/deviceinfo/BuildNumberPreferenceController.java
index c09ea02..3653baf 100644
--- a/src/com/android/settings/deviceinfo/BuildNumberPreferenceController.java
+++ b/src/com/android/settings/deviceinfo/BuildNumberPreferenceController.java
@@ -17,6 +17,7 @@
package com.android.settings.deviceinfo;
import android.app.Activity;
+import android.app.ActivityManager;
import android.app.settings.SettingsEnums;
import android.content.ComponentName;
import android.content.Context;
@@ -29,6 +30,7 @@
import android.text.TextUtils;
import android.widget.Toast;
+import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -112,7 +114,7 @@
if (!TextUtils.equals(preference.getKey(), getPreferenceKey())) {
return false;
}
- if (Utils.isMonkeyRunning()) {
+ if (isUserAMonkey()) {
return false;
}
// Don't enable developer options for secondary non-demo users.
@@ -245,4 +247,9 @@
Toast.LENGTH_LONG);
mDevHitToast.show();
}
+
+ @VisibleForTesting
+ protected boolean isUserAMonkey() {
+ return ActivityManager.isUserAMonkey();
+ }
}
diff --git a/src/com/android/settings/deviceinfo/TopLevelStoragePreferenceController.java b/src/com/android/settings/deviceinfo/TopLevelStoragePreferenceController.java
index dcc581c..89d349f 100644
--- a/src/com/android/settings/deviceinfo/TopLevelStoragePreferenceController.java
+++ b/src/com/android/settings/deviceinfo/TopLevelStoragePreferenceController.java
@@ -21,6 +21,7 @@
import android.text.format.Formatter;
import android.util.FeatureFlagUtils;
+import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
import com.android.settings.R;
@@ -31,6 +32,7 @@
import com.android.settingslib.utils.ThreadUtils;
import java.text.NumberFormat;
+import java.util.concurrent.Future;
public class TopLevelStoragePreferenceController extends BasePreferenceController {
@@ -59,10 +61,15 @@
return;
}
- ThreadUtils.postOnBackgroundThread(() -> {
+ refreshSummaryThread(preference);
+ }
+
+ @VisibleForTesting
+ protected Future refreshSummaryThread(Preference preference) {
+ return ThreadUtils.postOnBackgroundThread(() -> {
final NumberFormat percentageFormat = NumberFormat.getPercentInstance();
final PrivateStorageInfo info = PrivateStorageInfo.getPrivateStorageInfo(
- mStorageManagerVolumeProvider);
+ getStorageManagerVolumeProvider());
final double privateUsedBytes = info.totalBytes - info.freeBytes;
ThreadUtils.postOnMainThread(() -> {
@@ -72,4 +79,10 @@
});
});
}
+
+
+ @VisibleForTesting
+ protected StorageManagerVolumeProvider getStorageManagerVolumeProvider() {
+ return mStorageManagerVolumeProvider;
+ }
}
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/BrandedAccountPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/BrandedAccountPreferenceControllerTest.java
deleted file mode 100644
index 87dcb33..0000000
--- a/tests/robotests/src/com/android/settings/deviceinfo/BrandedAccountPreferenceControllerTest.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * 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.deviceinfo;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.when;
-
-import android.accounts.Account;
-import android.content.Context;
-
-import com.android.settings.testutils.FakeFeatureFactory;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-
-@RunWith(RobolectricTestRunner.class)
-public class BrandedAccountPreferenceControllerTest {
-
- private Context mContext;
- private FakeFeatureFactory fakeFeatureFactory;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
- mContext = RuntimeEnvironment.application;
- fakeFeatureFactory = FakeFeatureFactory.setupForTest();
-
- }
-
- @Test
- public void isAvailable_configOn_noAccount_off() {
- final BrandedAccountPreferenceController controller =
- new BrandedAccountPreferenceController(mContext, "test_key");
- assertThat(controller.isAvailable()).isFalse();
- }
-
- @Test
- public void isAvailable_accountIsAvailable_on() {
- when(fakeFeatureFactory.mAccountFeatureProvider.getAccounts(any(Context.class)))
- .thenReturn(new Account[]{new Account("fake@account.foo", "fake.reallyfake")});
-
- final BrandedAccountPreferenceController controller =
- new BrandedAccountPreferenceController(mContext, "test_key");
-
- assertThat(controller.isAvailable()).isTrue();
- }
-
- @Test
- @Config(qualifiers = "mcc999")
- public void isAvailable_configOff_hasAccount_off() {
- when(fakeFeatureFactory.mAccountFeatureProvider.getAccounts(any(Context.class)))
- .thenReturn(new Account[]{new Account("fake@account.foo", "fake.reallyfake")});
-
- final BrandedAccountPreferenceController controller =
- new BrandedAccountPreferenceController(mContext, "test_key");
-
- assertThat(controller.isAvailable()).isFalse();
- }
-}
diff --git a/tests/unit/src/com/android/settings/deviceinfo/BrandedAccountPreferenceControllerTest.java b/tests/unit/src/com/android/settings/deviceinfo/BrandedAccountPreferenceControllerTest.java
new file mode 100644
index 0000000..6e78d05
--- /dev/null
+++ b/tests/unit/src/com/android/settings/deviceinfo/BrandedAccountPreferenceControllerTest.java
@@ -0,0 +1,99 @@
+/*
+ * 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.deviceinfo;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.accounts.Account;
+import android.content.Context;
+import android.content.res.Resources;
+
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settings.testutils.ResourcesUtils;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@RunWith(AndroidJUnit4.class)
+public class BrandedAccountPreferenceControllerTest {
+
+ @Mock
+ private Resources mResources;
+ private Context mContext;
+ private FakeFeatureFactory mFakeFeatureFactory;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mContext = spy(ApplicationProvider.getApplicationContext());
+ when(mContext.getResources()).thenReturn(mResources);
+ mFakeFeatureFactory = FakeFeatureFactory.setupForTest();
+
+ }
+
+ @Test
+ public void isAvailable_configOn_noAccount_off() {
+ final int boolId = ResourcesUtils.getResourcesId(
+ ApplicationProvider.getApplicationContext(), "bool",
+ "config_show_branded_account_in_device_info");
+ when(mResources.getBoolean(boolId)).thenReturn(true);
+
+ final BrandedAccountPreferenceController controller =
+ new BrandedAccountPreferenceController(mContext, "test_key");
+ assertThat(controller.isAvailable()).isFalse();
+ }
+
+ @Test
+ public void isAvailable_accountIsAvailable_on() {
+ final int boolId = ResourcesUtils.getResourcesId(
+ ApplicationProvider.getApplicationContext(), "bool",
+ "config_show_branded_account_in_device_info");
+ when(mResources.getBoolean(boolId)).thenReturn(true);
+ when(mFakeFeatureFactory.mAccountFeatureProvider.getAccounts(any(Context.class)))
+ .thenReturn(new Account[]{new Account("fake@account.foo", "fake.reallyfake")});
+
+ final BrandedAccountPreferenceController controller =
+ new BrandedAccountPreferenceController(mContext, "test_key");
+
+ assertThat(controller.isAvailable()).isTrue();
+ }
+
+ @Test
+ public void isAvailable_configOff_hasAccount_off() {
+ final int boolId = ResourcesUtils.getResourcesId(
+ ApplicationProvider.getApplicationContext(), "bool",
+ "config_show_branded_account_in_device_info");
+ when(mResources.getBoolean(boolId)).thenReturn(false);
+ when(mFakeFeatureFactory.mAccountFeatureProvider.getAccounts(any(Context.class)))
+ .thenReturn(new Account[]{new Account("fake@account.foo", "fake.reallyfake")});
+
+ final BrandedAccountPreferenceController controller =
+ new BrandedAccountPreferenceController(mContext, "test_key");
+
+ assertThat(controller.isAvailable()).isFalse();
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/BuildNumberPreferenceControllerTest.java b/tests/unit/src/com/android/settings/deviceinfo/BuildNumberPreferenceControllerTest.java
similarity index 71%
rename from tests/robotests/src/com/android/settings/deviceinfo/BuildNumberPreferenceControllerTest.java
rename to tests/unit/src/com/android/settings/deviceinfo/BuildNumberPreferenceControllerTest.java
index 80a3a11..8c75449 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/BuildNumberPreferenceControllerTest.java
+++ b/tests/unit/src/com/android/settings/deviceinfo/BuildNumberPreferenceControllerTest.java
@@ -22,52 +22,51 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
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 android.app.Activity;
+import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
-import android.content.pm.UserInfo;
-import android.os.Process;
-import android.os.UserHandle;
+import android.os.Looper;
import android.os.UserManager;
import android.provider.Settings;
import androidx.lifecycle.LifecycleOwner;
import androidx.preference.Preference;
+import androidx.test.annotation.UiThreadTest;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.core.InstrumentedPreferenceFragment;
import com.android.settings.testutils.FakeFeatureFactory;
-import com.android.settings.testutils.shadow.ShadowUtils;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.development.DevelopmentSettingsEnabler;
-import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Answers;
+import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.Shadows;
-import org.robolectric.annotation.Config;
-import org.robolectric.shadows.ShadowUserManager;
-@RunWith(RobolectricTestRunner.class)
-@Config(shadows = ShadowUtils.class)
+@RunWith(AndroidJUnit4.class)
public class BuildNumberPreferenceControllerTest {
private static final String KEY_BUILD_NUMBER = "build_number";
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private InstrumentedPreferenceFragment mFragment;
- private ShadowUserManager mShadowUserManager;
-
private Context mContext;
+ private UserManager mUserManager;
+ private ClipboardManager mClipboardManager;
private LifecycleOwner mLifecycleOwner;
private Lifecycle mLifecycle;
private FakeFeatureFactory mFactory;
@@ -75,15 +74,23 @@
private BuildNumberPreferenceController mController;
@Before
+ @UiThreadTest
public void setUp() {
+ if (Looper.myLooper() == null) {
+ Looper.prepare();
+ }
MockitoAnnotations.initMocks(this);
- mContext = RuntimeEnvironment.application;
- mShadowUserManager = Shadows.shadowOf(
- RuntimeEnvironment.application.getSystemService(UserManager.class));
+
+ mContext = spy(ApplicationProvider.getApplicationContext());
+ mUserManager = (UserManager) spy(mContext.getSystemService(Context.USER_SERVICE));
+ doReturn(mUserManager).when(mContext).getSystemService(Context.USER_SERVICE);
+ mClipboardManager = (ClipboardManager) spy(mContext.getSystemService(CLIPBOARD_SERVICE));
+ doReturn(mClipboardManager).when(mContext).getSystemService(CLIPBOARD_SERVICE);
+
mFactory = FakeFeatureFactory.setupForTest();
mLifecycleOwner = () -> mLifecycle;
mLifecycle = new Lifecycle(mLifecycleOwner);
- mController = new BuildNumberPreferenceController(mContext, KEY_BUILD_NUMBER);
+ mController = spy(new BuildNumberPreferenceController(mContext, KEY_BUILD_NUMBER));
mController.setHost(mFragment);
mPreference = new Preference(mContext);
@@ -93,11 +100,6 @@
Settings.Global.DEVICE_PROVISIONED, 1);
}
- @After
- public void tearDown() {
- ShadowUtils.reset();
- }
-
@Test
public void handlePrefTreeClick_onlyHandleBuildNumberPref() {
assertThat(mController.handlePreferenceTreeClick(mock(Preference.class))).isFalse();
@@ -105,32 +107,32 @@
@Test
public void handlePrefTreeClick_notAdminUser_notDemoUser_doNothing() {
- mShadowUserManager.setIsAdminUser(false);
- mShadowUserManager.setIsDemoUser(false);
+ when(mUserManager.isAdminUser()).thenReturn(false);
+ when(mUserManager.isDemoUser()).thenReturn(false);
assertThat(mController.handlePreferenceTreeClick(mPreference)).isFalse();
}
@Test
public void handlePrefTreeClick_isAdminUser_notDemoUser_handleBuildNumberPref() {
- mShadowUserManager.setIsAdminUser(true);
- mShadowUserManager.setIsDemoUser(false);
+ when(mUserManager.isAdminUser()).thenReturn(true);
+ when(mUserManager.isDemoUser()).thenReturn(false);
assertThat(mController.handlePreferenceTreeClick(mPreference)).isTrue();
}
@Test
public void handlePrefTreeClick_notAdminUser_isDemoUser_handleBuildNumberPref() {
- mShadowUserManager.setIsAdminUser(false);
- mShadowUserManager.addUser(UserHandle.myUserId(), "test", UserInfo.FLAG_DEMO);
+ when(mUserManager.isAdminUser()).thenReturn(false);
+ when(mUserManager.isDemoUser()).thenReturn(true);
assertThat(mController.handlePreferenceTreeClick(mPreference)).isTrue();
}
@Test
public void handlePrefTreeClick_deviceNotProvisioned_doNothing() {
- mShadowUserManager.setIsAdminUser(true);
- mShadowUserManager.setIsDemoUser(false);
+ when(mUserManager.isAdminUser()).thenReturn(true);
+ when(mUserManager.isDemoUser()).thenReturn(false);
Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.DEVICE_PROVISIONED,
0);
@@ -143,17 +145,16 @@
@Test
public void handlePrefTreeClick_isMonkeyRun_doNothing() {
- ShadowUtils.setIsUserAMonkey(true);
+ when(mController.isUserAMonkey()).thenReturn(true);
assertThat(mController.handlePreferenceTreeClick(mPreference)).isFalse();
}
@Test
public void handlePrefTreeClick_userHasRestriction_doNothing() {
- mShadowUserManager.setIsAdminUser(true);
- mShadowUserManager.setIsDemoUser(false);
-
- mShadowUserManager.setUserRestriction(Process.myUserHandle(),
- UserManager.DISALLOW_DEBUGGING_FEATURES, true);
+ when(mUserManager.isAdminUser()).thenReturn(true);
+ when(mUserManager.isDemoUser()).thenReturn(false);
+ when(mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES))
+ .thenReturn(true);
assertThat(mController.handlePreferenceTreeClick(mPreference)).isFalse();
verify(mFactory.metricsFeatureProvider).action(
@@ -184,8 +185,9 @@
}
@Test
+ @UiThreadTest
public void onActivityResult_confirmPasswordRequestCompleted_enableDevPref() {
- mShadowUserManager.setIsAdminUser(true);
+ when(mUserManager.isAdminUser()).thenReturn(true);
final boolean activityResultHandled = mController.onActivityResult(
BuildNumberPreferenceController.REQUEST_CONFIRM_PASSWORD_FOR_DEV_PREF,
@@ -197,12 +199,14 @@
}
@Test
+ @UiThreadTest
public void copy_shouldCopyBuildNumberToClipboard() {
+ ArgumentCaptor<ClipData> captor = ArgumentCaptor.forClass(ClipData.class);
+ doNothing().when(mClipboardManager).setPrimaryClip(captor.capture());
+
mController.copy();
- final ClipboardManager clipboard = (ClipboardManager) mContext.getSystemService(
- CLIPBOARD_SERVICE);
- final CharSequence data = clipboard.getPrimaryClip().getItemAt(0).getText();
- assertThat(data.toString()).isEqualTo(mController.getSummary());
+ final ClipData data = captor.getValue();
+ assertThat(data.getItemAt(0).getText().toString()).isEqualTo(mController.getSummary());
}
}
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/PrivateVolumeOptionMenuControllerTest.java b/tests/unit/src/com/android/settings/deviceinfo/PrivateVolumeOptionMenuControllerTest.java
similarity index 76%
rename from tests/robotests/src/com/android/settings/deviceinfo/PrivateVolumeOptionMenuControllerTest.java
rename to tests/unit/src/com/android/settings/deviceinfo/PrivateVolumeOptionMenuControllerTest.java
index ed7f16b..e3affef 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/PrivateVolumeOptionMenuControllerTest.java
+++ b/tests/unit/src/com/android/settings/deviceinfo/PrivateVolumeOptionMenuControllerTest.java
@@ -18,30 +18,35 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.storage.VolumeInfo;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
-import com.android.settings.R;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import com.android.settings.testutils.ResourcesUtils;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Answers;
+import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.shadows.ShadowApplication;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class PrivateVolumeOptionMenuControllerTest {
@Mock
@@ -57,11 +62,13 @@
@Mock
private VolumeInfo mPrimaryInfo;
+ private Context mContext;
private PrivateVolumeOptionMenuController mController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
+ mContext = spy(ApplicationProvider.getApplicationContext());
when(mVolumeInfo.getType()).thenReturn(VolumeInfo.TYPE_PRIVATE);
when(mVolumeInfo.isMountedWritable()).thenReturn(true);
@@ -69,15 +76,15 @@
when(mMenu.findItem(anyInt())).thenReturn(mMigrateMenuItem);
when(mMigrateMenuItem.getItemId()).thenReturn(100);
- mController = new PrivateVolumeOptionMenuController(
- Robolectric.setupActivity(Activity.class), mPrimaryInfo, mPm);
+ mController = new PrivateVolumeOptionMenuController(mContext, mPrimaryInfo, mPm);
}
@Test
public void testMigrateDataMenuItemIsAdded() {
mController.onCreateOptionsMenu(mMenu, mMenuInflater);
- verify(mMenu).add(Menu.NONE, 100, Menu.NONE, R.string.storage_menu_migrate);
+ verify(mMenu).add(Menu.NONE, 100, Menu.NONE, ResourcesUtils.getResourcesId(
+ mContext, "string", "storage_menu_migrate"));
}
@Test
@@ -115,14 +122,18 @@
@Test
public void testMigrateDataGoesToMigrateWizard() {
when(mPm.getPrimaryStorageCurrentVolume()).thenReturn(mVolumeInfo);
+ doNothing().when(mContext).startActivity(any(Intent.class));
mController.onCreateOptionsMenu(mMenu, mMenuInflater);
mController.onPrepareOptionsMenu(mMenu);
assertThat(mController.onOptionsItemSelected(mMigrateMenuItem)).isTrue();
- ShadowApplication shadowApplication = ShadowApplication.getInstance();
- assertThat(shadowApplication).isNotNull();
- assertThat(shadowApplication.getNextStartedActivity().getComponent().getClassName())
+
+ final ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(
+ Intent.class);
+ verify(mContext).startActivity(intentCaptor.capture());
+ final Intent startedIntent = intentCaptor.getValue();
+ assertThat(startedIntent.getComponent().getClassName())
.isEqualTo(StorageWizardMigrateConfirm.class.getName());
}
}
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/TopLevelStoragePreferenceControllerTest.java b/tests/unit/src/com/android/settings/deviceinfo/TopLevelStoragePreferenceControllerTest.java
similarity index 68%
rename from tests/robotests/src/com/android/settings/deviceinfo/TopLevelStoragePreferenceControllerTest.java
rename to tests/unit/src/com/android/settings/deviceinfo/TopLevelStoragePreferenceControllerTest.java
index 7e6be9b..d4157b8 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/TopLevelStoragePreferenceControllerTest.java
+++ b/tests/unit/src/com/android/settings/deviceinfo/TopLevelStoragePreferenceControllerTest.java
@@ -18,9 +18,11 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import android.app.usage.StorageStatsManager;
@@ -31,9 +33,11 @@
import android.util.FeatureFlagUtils;
import androidx.preference.Preference;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
-import com.android.settings.R;
import com.android.settings.core.FeatureFlags;
+import com.android.settings.testutils.ResourcesUtils;
import com.android.settingslib.deviceinfo.StorageManagerVolumeProvider;
import org.junit.Before;
@@ -41,14 +45,14 @@
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.util.ReflectionHelpers;
import java.util.ArrayList;
import java.util.List;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class TopLevelStoragePreferenceControllerTest {
@Mock
@@ -62,12 +66,12 @@
public void setUp() {
MockitoAnnotations.initMocks(this);
- mContext = RuntimeEnvironment.application;
+ mContext = ApplicationProvider.getApplicationContext();
mVolumes = new ArrayList<>();
mVolumes.add(mock(VolumeInfo.class, RETURNS_DEEP_STUBS));
when(mStorageManagerVolumeProvider.getVolumes()).thenReturn(mVolumes);
- mController = new TopLevelStoragePreferenceController(mContext, "test_key");
+ mController = spy(new TopLevelStoragePreferenceController(mContext, "test_key"));
FeatureFlagUtils.setEnabled(mContext, FeatureFlags.SILKY_HOME, false);
}
@@ -82,16 +86,27 @@
when(mStorageManagerVolumeProvider
.getFreeBytes(nullable(StorageStatsManager.class), nullable(VolumeInfo.class)))
.thenReturn(0L);
- ReflectionHelpers.setField(mController,
- "mStorageManagerVolumeProvider", mStorageManagerVolumeProvider);
+ when(mController.getStorageManagerVolumeProvider())
+ .thenReturn(mStorageManagerVolumeProvider);
final String percentage = NumberFormat.getPercentInstance().format(1);
- final String freeSpace = Formatter.formatFileSize(RuntimeEnvironment.application, 0);
+ final String freeSpace = Formatter.formatFileSize(mContext, 0);
final Preference preference = new Preference(mContext);
- mController.updateState(preference);
+ // Wait for asynchronous thread to finish, otherwise test will flake.
+ Future thread = mController.refreshSummaryThread(preference);
+ try {
+ thread.get();
+ } catch (ExecutionException | InterruptedException e) {
+ e.printStackTrace();
+ fail("Exception during automatic selection");
+ }
- assertThat(preference.getSummary()).isEqualTo(
- mContext.getString(R.string.storage_summary, percentage, freeSpace));
+
+ // Sleep for 5 seconds because a function is executed on the main thread from within
+ // the background thread.
+ TimeUnit.SECONDS.sleep(5);
+ assertThat(preference.getSummary()).isEqualTo(ResourcesUtils.getResourcesString(
+ mContext, "storage_summary", percentage, freeSpace));
}
@Test
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/hardwareinfo/HardwareInfoPreferenceControllerTest.java b/tests/unit/src/com/android/settings/deviceinfo/hardwareinfo/HardwareInfoPreferenceControllerTest.java
similarity index 70%
rename from tests/robotests/src/com/android/settings/deviceinfo/hardwareinfo/HardwareInfoPreferenceControllerTest.java
rename to tests/unit/src/com/android/settings/deviceinfo/hardwareinfo/HardwareInfoPreferenceControllerTest.java
index c7c7669..7262615 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/hardwareinfo/HardwareInfoPreferenceControllerTest.java
+++ b/tests/unit/src/com/android/settings/deviceinfo/hardwareinfo/HardwareInfoPreferenceControllerTest.java
@@ -17,41 +17,53 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
import android.content.Context;
+import android.content.res.Resources;
import android.os.Build;
+import android.os.Looper;
import androidx.preference.Preference;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.deviceinfo.HardwareInfoPreferenceController;
+import com.android.settings.testutils.ResourcesUtils;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class HardwareInfoPreferenceControllerTest {
- private final String KEY = "device_model";
+ private static final String KEY = "device_model";
private Preference mPreference;
private PreferenceScreen mPreferenceScreen;
private Context mContext;
+ @Mock
+ private Resources mResources;
private HardwareInfoPreferenceController mController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- mContext = RuntimeEnvironment.application;
+ mContext = spy(ApplicationProvider.getApplicationContext());
+ when(mContext.getResources()).thenReturn(mResources);
mController = new HardwareInfoPreferenceController(mContext, KEY);
mPreference = new Preference(mContext);
mPreference.setKey(KEY);
+ if (Looper.myLooper() == null) {
+ Looper.prepare();
+ }
final PreferenceManager preferenceManager = new PreferenceManager(mContext);
mPreferenceScreen = preferenceManager.createPreferenceScreen(mContext);
mPreferenceScreen.addPreference(mPreference);
@@ -59,13 +71,20 @@
@Test
public void isAvailable_returnTrueIfVisible() {
+ final int boolId = ResourcesUtils.getResourcesId(
+ ApplicationProvider.getApplicationContext(), "bool", "config_show_device_model");
+
+ when(mResources.getBoolean(boolId)).thenReturn(true);
assertThat(mController.getAvailabilityStatus()).isEqualTo(
BasePreferenceController.AVAILABLE);
}
@Test
- @Config(qualifiers = "mcc999")
public void isAvailable_returnFalseIfNotVisible() {
+ final int boolId = ResourcesUtils.getResourcesId(
+ ApplicationProvider.getApplicationContext(), "bool", "config_show_device_model");
+
+ when(mResources.getBoolean(boolId)).thenReturn(false);
assertThat(mController.getAvailabilityStatus()).isEqualTo(
BasePreferenceController.UNSUPPORTED_ON_DEVICE);
}