Merge "Adjust UI of face and fingerprint enroll intro pages" into sc-dev am: 588c13555d am: 7bc93a4d5c
Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Settings/+/15175824
Change-Id: I21924526a85c7d9dae60f5267d1bfd0affd9cac1
diff --git a/Android.bp b/Android.bp
index bb9db22..24fc7e8 100644
--- a/Android.bp
+++ b/Android.bp
@@ -73,6 +73,7 @@
"android.hardware.dumpstate-V1.0-java",
"android.hardware.dumpstate-V1.1-java",
"lottie",
+ "WifiTrackerLib",
],
libs: [
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 60dbb24..d40acb0 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -82,6 +82,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-night/themes.xml b/res/values-night/themes.xml
index b61a98d..946cd91 100644
--- a/res/values-night/themes.xml
+++ b/res/values-night/themes.xml
@@ -28,10 +28,6 @@
<style name="Theme.SubSettings" parent="Theme.SubSettings.Base"/>
- <style name="ThemeOverlay.SwitchBar.Settings" parent="ThemeOverlay.SwitchBar.Settings.Base">
- <item name="android:textColorPrimaryInverse">@android:color/black</item>
- </style>
-
<style name="Theme.AlertDialog.Base" parent="@style/Theme.AppCompat.DayNight.Dialog.Alert">
<item name="colorAccent">@*android:color/accent_device_default_dark</item>
<item name="android:colorError">@color/settings_dialog_colorError</item>
diff --git a/src/com/android/settings/development/tare/OWNERS b/src/com/android/settings/development/tare/OWNERS
new file mode 100644
index 0000000..46d25c8
--- /dev/null
+++ b/src/com/android/settings/development/tare/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 330055
+
+include platform/frameworks/base:/apex/jobscheduler/service/java/com/android/server/tare/OWNERS
\ No newline at end of file
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/PhoneNumberPreferenceController.java b/src/com/android/settings/deviceinfo/PhoneNumberPreferenceController.java
index abf58d8..292196e 100644
--- a/src/com/android/settings/deviceinfo/PhoneNumberPreferenceController.java
+++ b/src/com/android/settings/deviceinfo/PhoneNumberPreferenceController.java
@@ -133,7 +133,7 @@
}
@VisibleForTesting
- SubscriptionInfo getSubscriptionInfo(int simSlot) {
+ protected SubscriptionInfo getSubscriptionInfo(int simSlot) {
final List<SubscriptionInfo> subscriptionInfoList =
mSubscriptionManager.getActiveSubscriptionInfoList();
if (subscriptionInfoList != null) {
@@ -147,7 +147,7 @@
}
@VisibleForTesting
- CharSequence getFormattedPhoneNumber(SubscriptionInfo subscriptionInfo) {
+ protected CharSequence getFormattedPhoneNumber(SubscriptionInfo subscriptionInfo) {
final String phoneNumber = DeviceInfoUtils.getBidiFormattedPhoneNumber(mContext,
subscriptionInfo);
return TextUtils.isEmpty(phoneNumber) ? mContext.getString(R.string.device_info_default)
@@ -155,7 +155,7 @@
}
@VisibleForTesting
- Preference createNewPreference(Context context) {
+ protected Preference createNewPreference(Context context) {
return new Preference(context);
}
}
diff --git a/src/com/android/settings/network/NetworkProviderSettings.java b/src/com/android/settings/network/NetworkProviderSettings.java
index f6e7917..12497ed 100644
--- a/src/com/android/settings/network/NetworkProviderSettings.java
+++ b/src/com/android/settings/network/NetworkProviderSettings.java
@@ -66,6 +66,7 @@
import com.android.settings.wifi.AddWifiNetworkPreference;
import com.android.settings.wifi.ConfigureWifiEntryFragment;
import com.android.settings.wifi.ConnectedWifiEntryPreference;
+import com.android.settings.wifi.LongPressWifiEntryPreference;
import com.android.settings.wifi.WifiConfigUiBase2;
import com.android.settings.wifi.WifiConnectListener;
import com.android.settings.wifi.WifiDialog2;
@@ -80,7 +81,6 @@
import com.android.settingslib.search.SearchIndexable;
import com.android.settingslib.utils.ThreadUtils;
import com.android.settingslib.widget.LayoutPreference;
-import com.android.settingslib.wifi.LongPressWifiEntryPreference;
import com.android.settingslib.wifi.WifiSavedConfigUtils;
import com.android.wifitrackerlib.WifiEntry;
import com.android.wifitrackerlib.WifiEntry.ConnectCallback;
diff --git a/src/com/android/settings/network/PrivateDnsModeDialogPreference.java b/src/com/android/settings/network/PrivateDnsModeDialogPreference.java
index 1c3fc76..442af38 100644
--- a/src/com/android/settings/network/PrivateDnsModeDialogPreference.java
+++ b/src/com/android/settings/network/PrivateDnsModeDialogPreference.java
@@ -189,6 +189,8 @@
if (linkInfo.isActionable()) {
helpTextView.setText(AnnotationSpan.linkify(
context.getText(R.string.private_dns_help_message), linkInfo));
+ } else {
+ helpTextView.setText("");
}
}
diff --git a/src/com/android/settings/network/telephony/CellInfoUtil.java b/src/com/android/settings/network/telephony/CellInfoUtil.java
index d7d2b18..63ef159 100644
--- a/src/com/android/settings/network/telephony/CellInfoUtil.java
+++ b/src/com/android/settings/network/telephony/CellInfoUtil.java
@@ -145,6 +145,8 @@
final CellIdentity cid = getCellIdentity(cellInfo);
String mcc = null;
String mnc = null;
+ CharSequence alphaLong = null;
+ CharSequence alphaShort = null;
if (cid != null) {
if (cid instanceof CellIdentityGsm) {
mcc = ((CellIdentityGsm) cid).getMccString();
@@ -162,10 +164,13 @@
mcc = ((CellIdentityNr) cid).getMccString();
mnc = ((CellIdentityNr) cid).getMncString();
}
+
+ alphaLong = cid.getOperatorAlphaLong();
+ alphaShort = cid.getOperatorAlphaShort();
}
return String.format(
"{CellType = %s, isRegistered = %b, mcc = %s, mnc = %s, alphaL = %s, alphaS = %s}",
cellType, cellInfo.isRegistered(), mcc, mnc,
- cid.getOperatorAlphaLong(), cid.getOperatorAlphaShort());
+ alphaLong, alphaShort);
}
}
diff --git a/src/com/android/settings/network/telephony/MobileNetworkActivity.java b/src/com/android/settings/network/telephony/MobileNetworkActivity.java
index 20b37c1..f2be37f 100644
--- a/src/com/android/settings/network/telephony/MobileNetworkActivity.java
+++ b/src/com/android/settings/network/telephony/MobileNetworkActivity.java
@@ -36,6 +36,7 @@
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
+import androidx.lifecycle.Lifecycle;
import com.android.internal.util.CollectionUtils;
import com.android.settings.R;
@@ -68,6 +69,7 @@
// Set initial value to true allows subscription information fragment to be re-created when
// Activity re-create occur.
private boolean mFragmentForceReload = true;
+ private boolean mPendingSubscriptionChange = false;
@Override
protected void onNewIntent(Intent intent) {
@@ -155,6 +157,10 @@
* Implementation of ProxySubscriptionManager.OnActiveSubscriptionChangedListener
*/
public void onChanged() {
+ if (!getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED)) {
+ mPendingSubscriptionChange = true;
+ return;
+ }
SubscriptionInfo info = getSubscription();
int oldSubIndex = mCurSubscriptionId;
updateSubscriptions(info, null);
@@ -180,6 +186,10 @@
super.onStart();
// updateSubscriptions doesn't need to be called, onChanged will always be called after we
// register a listener.
+ if (mPendingSubscriptionChange) {
+ mPendingSubscriptionChange = false;
+ onChanged();
+ }
}
@Override
diff --git a/src/com/android/settings/network/telephony/NetworkOperatorPreference.java b/src/com/android/settings/network/telephony/NetworkOperatorPreference.java
index 3a7dc31..397bf36 100644
--- a/src/com/android/settings/network/telephony/NetworkOperatorPreference.java
+++ b/src/com/android/settings/network/telephony/NetworkOperatorPreference.java
@@ -36,6 +36,7 @@
import android.telephony.CellSignalStrength;
import android.util.Log;
+import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
import com.android.internal.telephony.OperatorInfo;
@@ -89,7 +90,8 @@
updateCell(cellinfo, CellInfoUtil.getCellIdentity(cellinfo));
}
- private void updateCell(CellInfo cellinfo, CellIdentity cellId) {
+ @VisibleForTesting
+ protected void updateCell(CellInfo cellinfo, CellIdentity cellId) {
mCellInfo = cellinfo;
mCellId = cellId;
refresh();
diff --git a/src/com/android/settings/network/telephony/NetworkSelectSettings.java b/src/com/android/settings/network/telephony/NetworkSelectSettings.java
index 6f315be..76b6cbd 100644
--- a/src/com/android/settings/network/telephony/NetworkSelectSettings.java
+++ b/src/com/android/settings/network/telephony/NetworkSelectSettings.java
@@ -36,6 +36,7 @@
import android.util.Log;
import android.view.View;
+import androidx.annotation.Keep;
import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
import androidx.preference.PreferenceCategory;
@@ -56,6 +57,7 @@
/**
* "Choose network" settings UI for the Settings app.
*/
+@Keep
public class NetworkSelectSettings extends DashboardFragment {
private static final String TAG = "NetworkSelectSettings";
@@ -67,8 +69,7 @@
private static final String PREF_KEY_NETWORK_OPERATORS = "network_operators_preference";
- @VisibleForTesting
- PreferenceCategory mPreferenceCategory;
+ private PreferenceCategory mPreferenceCategory;
@VisibleForTesting
NetworkOperatorPreference mSelectedPreference;
private View mProgressHeader;
@@ -76,8 +77,7 @@
@VisibleForTesting
List<CellInfo> mCellInfoList;
private int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
- @VisibleForTesting
- TelephonyManager mTelephonyManager;
+ private TelephonyManager mTelephonyManager;
private List<String> mForbiddenPlmns;
private boolean mShow4GForLTE = false;
private NetworkScanHelper mNetworkScanHelper;
@@ -93,28 +93,74 @@
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
+ onCreateInitialization();
+ }
- mUseNewApi = getContext().getResources().getBoolean(
- com.android.internal.R.bool.config_enableNewAutoSelectNetworkUI);
+ @Keep
+ @VisibleForTesting
+ protected void onCreateInitialization() {
+ mUseNewApi = enableNewAutoSelectNetworkUI(getContext());
mSubId = getArguments().getInt(Settings.EXTRA_SUB_ID);
- mPreferenceCategory = findPreference(PREF_KEY_NETWORK_OPERATORS);
+ mPreferenceCategory = getPreferenceCategory(PREF_KEY_NETWORK_OPERATORS);
mStatusMessagePreference = new Preference(getContext());
mStatusMessagePreference.setSelectable(false);
mSelectedPreference = null;
- mTelephonyManager = getContext().getSystemService(TelephonyManager.class)
- .createForSubscriptionId(mSubId);
+ mTelephonyManager = getTelephonyManager(getContext(), mSubId);
mNetworkScanHelper = new NetworkScanHelper(
mTelephonyManager, mCallback, mNetworkScanExecutor);
- PersistableBundle bundle = ((CarrierConfigManager) getContext().getSystemService(
- Context.CARRIER_CONFIG_SERVICE)).getConfigForSubId(mSubId);
+ PersistableBundle bundle = getCarrierConfigManager(getContext())
+ .getConfigForSubId(mSubId);
if (bundle != null) {
mShow4GForLTE = bundle.getBoolean(
CarrierConfigManager.KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL);
}
- mMetricsFeatureProvider = FeatureFactory
- .getFactory(getContext()).getMetricsFeatureProvider();
+ mMetricsFeatureProvider = getMetricsFeatureProvider(getContext());
+ }
+
+ @Keep
+ @VisibleForTesting
+ protected boolean enableNewAutoSelectNetworkUI(Context context) {
+ return context.getResources().getBoolean(
+ com.android.internal.R.bool.config_enableNewAutoSelectNetworkUI);
+ }
+
+ @Keep
+ @VisibleForTesting
+ protected PreferenceCategory getPreferenceCategory(String preferenceKey) {
+ return findPreference(preferenceKey);
+ }
+
+ @Keep
+ @VisibleForTesting
+ protected TelephonyManager getTelephonyManager(Context context, int subscriptionId) {
+ return context.getSystemService(TelephonyManager.class)
+ .createForSubscriptionId(subscriptionId);
+ }
+
+ @Keep
+ @VisibleForTesting
+ protected CarrierConfigManager getCarrierConfigManager(Context context) {
+ return context.getSystemService(CarrierConfigManager.class);
+ }
+
+ @Keep
+ @VisibleForTesting
+ protected MetricsFeatureProvider getMetricsFeatureProvider(Context context) {
+ return FeatureFactory.getFactory(context).getMetricsFeatureProvider();
+ }
+
+ @Keep
+ @VisibleForTesting
+ protected boolean isPreferenceScreenEnabled() {
+ return getPreferenceScreen().isEnabled();
+ }
+
+ @Keep
+ @VisibleForTesting
+ protected void enablePreferenceScreen(boolean enable) {
+ getPreferenceScreen().setEnabled(enable);
}
@Override
@@ -146,8 +192,9 @@
/**
* Update forbidden PLMNs from the USIM App
*/
+ @Keep
@VisibleForTesting
- void updateForbiddenPlmns() {
+ protected void updateForbiddenPlmns() {
final String[] forbiddenPlmns = mTelephonyManager.getForbiddenPlmns();
mForbiddenPlmns = forbiddenPlmns != null
? Arrays.asList(forbiddenPlmns)
@@ -182,7 +229,7 @@
setProgressBarVisible(true);
// Disable the screen until network is manually set
- getPreferenceScreen().setEnabled(false);
+ enablePreferenceScreen(false);
mRequestIdManualNetworkSelect = getNewRequestId();
mWaitingForNumberOfScanResults = MIN_NUMBER_OF_SCAN_REQUIRED;
@@ -222,7 +269,7 @@
final boolean isSucceed = (boolean) msg.obj;
stopNetworkQuery();
setProgressBarVisible(false);
- getPreferenceScreen().setEnabled(true);
+ enablePreferenceScreen(true);
if (mSelectedPreference != null) {
mSelectedPreference.setSummary(isSucceed
@@ -233,38 +280,7 @@
}
break;
case EVENT_NETWORK_SCAN_RESULTS:
- final List<CellInfo> results = (List<CellInfo>) msg.obj;
- if (mRequestIdManualNetworkScan < mRequestIdManualNetworkSelect) {
- Log.d(TAG, "CellInfoList (drop): "
- + CellInfoUtil.cellInfoListToString(new ArrayList<>(results)));
- break;
- }
- mWaitingForNumberOfScanResults--;
- if ((mWaitingForNumberOfScanResults <= 0) && (!isResumed())) {
- stopNetworkQuery();
- }
-
- mCellInfoList = new ArrayList<>(results);
- Log.d(TAG, "CellInfoList: " + CellInfoUtil.cellInfoListToString(mCellInfoList));
- if (mCellInfoList != null && mCellInfoList.size() != 0) {
- final NetworkOperatorPreference connectedPref =
- updateAllPreferenceCategory();
- if (connectedPref != null) {
- // update selected preference instance into connected preference
- if (mSelectedPreference != null) {
- mSelectedPreference = connectedPref;
- }
- } else if (!getPreferenceScreen().isEnabled()) {
- if (connectedPref == null) {
- mSelectedPreference.setSummary(R.string.network_connecting);
- }
- }
- getPreferenceScreen().setEnabled(true);
- } else if (getPreferenceScreen().isEnabled()) {
- addMessagePreference(R.string.empty_networks_list);
- // keep showing progress bar, it will be stopped when error or completed
- setProgressBarVisible(true);
- }
+ scanResultHandler((List<CellInfo>) msg.obj);
break;
case EVENT_NETWORK_SCAN_ERROR:
@@ -277,9 +293,9 @@
if (mRequestIdManualNetworkScan < mRequestIdManualNetworkSelect) {
break;
}
- if (!getPreferenceScreen().isEnabled()) {
+ if (!isPreferenceScreenEnabled()) {
clearPreferenceSummary();
- getPreferenceScreen().setEnabled(true);
+ enablePreferenceScreen(true);
} else {
addMessagePreference(R.string.network_query_error);
}
@@ -295,9 +311,9 @@
if (mRequestIdManualNetworkScan < mRequestIdManualNetworkSelect) {
break;
}
- if (!getPreferenceScreen().isEnabled()) {
+ if (!isPreferenceScreenEnabled()) {
clearPreferenceSummary();
- getPreferenceScreen().setEnabled(true);
+ enablePreferenceScreen(true);
} else if (mCellInfoList == null) {
// In case the scan timeout before getting any results
addMessagePreference(R.string.empty_networks_list);
@@ -327,13 +343,55 @@
}
};
+ @Keep
+ @VisibleForTesting
+ protected void scanResultHandler(List<CellInfo> results) {
+ if (mRequestIdManualNetworkScan < mRequestIdManualNetworkSelect) {
+ Log.d(TAG, "CellInfoList (drop): "
+ + CellInfoUtil.cellInfoListToString(new ArrayList<>(results)));
+ return;
+ }
+ mWaitingForNumberOfScanResults--;
+ if ((mWaitingForNumberOfScanResults <= 0) && (!isResumed())) {
+ stopNetworkQuery();
+ }
+
+ mCellInfoList = new ArrayList<>(results);
+ Log.d(TAG, "CellInfoList: " + CellInfoUtil.cellInfoListToString(mCellInfoList));
+ if (mCellInfoList != null && mCellInfoList.size() != 0) {
+ final NetworkOperatorPreference connectedPref =
+ updateAllPreferenceCategory();
+ if (connectedPref != null) {
+ // update selected preference instance into connected preference
+ if (mSelectedPreference != null) {
+ mSelectedPreference = connectedPref;
+ }
+ } else if (!isPreferenceScreenEnabled()) {
+ if (connectedPref == null) {
+ mSelectedPreference.setSummary(R.string.network_connecting);
+ }
+ }
+ enablePreferenceScreen(true);
+ } else if (isPreferenceScreenEnabled()) {
+ addMessagePreference(R.string.empty_networks_list);
+ // keep showing progress bar, it will be stopped when error or completed
+ setProgressBarVisible(true);
+ }
+ }
+
+ @Keep
+ @VisibleForTesting
+ protected NetworkOperatorPreference createNetworkOperatorPreference(CellInfo cellInfo) {
+ return new NetworkOperatorPreference(getPrefContext(),
+ cellInfo, mForbiddenPlmns, mShow4GForLTE);
+ }
+
/**
* Update the content of network operators list.
*
* @return preference which shows connected
*/
- @VisibleForTesting
- NetworkOperatorPreference updateAllPreferenceCategory() {
+ private NetworkOperatorPreference updateAllPreferenceCategory() {
int numberOfPreferences = mPreferenceCategory.getPreferenceCount();
// remove unused preferences
@@ -361,8 +419,7 @@
}
if (pref == null) {
// add new preference
- pref = new NetworkOperatorPreference(getPrefContext(),
- cellInfo, mForbiddenPlmns, mShow4GForLTE);
+ pref = createNetworkOperatorPreference(cellInfo);
pref.setOrder(index);
mPreferenceCategory.addPreference(pref);
}
diff --git a/src/com/android/settings/users/UserSettings.java b/src/com/android/settings/users/UserSettings.java
index ee23fc3..23cdaf9 100644
--- a/src/com/android/settings/users/UserSettings.java
+++ b/src/com/android/settings/users/UserSettings.java
@@ -809,51 +809,62 @@
mUserCreatingDialog = new UserCreatingDialog(getActivity());
mUserCreatingDialog.show();
- ThreadUtils.postOnBackgroundThread(new Runnable() {
- @Override
- public void run() {
- UserInfo user;
- String username;
+ ThreadUtils.postOnBackgroundThread(new AddUserNowImpl(userType, mAddingUserName));
+ }
- synchronized (mUserLock) {
- username = mAddingUserName;
- }
+ @VisibleForTesting
+ class AddUserNowImpl implements Runnable{
+ int mUserType;
+ String mImplAddUserName;
- // Could take a few seconds
- if (userType == USER_TYPE_USER) {
- user = mUserManager.createUser(username, 0);
- } else {
- user = mUserManager.createRestrictedProfile(username);
- }
+ AddUserNowImpl(final int userType, final String addUserName) {
+ mUserType = userType;
+ mImplAddUserName = addUserName;
+ }
- synchronized (mUserLock) {
- if (user == null) {
- mAddingUser = false;
- mPendingUserIcon = null;
- mPendingUserName = null;
- ThreadUtils.postOnMainThread(() -> onUserCreationFailed());
- return;
- }
+ @Override
+ public void run() {
+ UserInfo user;
+ String username;
- Drawable newUserIcon = mPendingUserIcon;
- if (newUserIcon == null) {
- newUserIcon = UserIcons.getDefaultUserIcon(getResources(), user.id, false);
- }
- mUserManager.setUserIcon(user.id, UserIcons.convertToBitmap(newUserIcon));
+ synchronized (mUserLock) {
+ username = mImplAddUserName;
+ }
- if (userType == USER_TYPE_USER) {
- mHandler.sendEmptyMessage(MESSAGE_UPDATE_LIST);
- }
+ // Could take a few seconds
+ if (mUserType == USER_TYPE_USER) {
+ user = mUserManager.createUser(username, 0);
+ } else {
+ user = mUserManager.createRestrictedProfile(username);
+ }
- mHandler.sendMessage(mHandler.obtainMessage(
- MESSAGE_USER_CREATED, user.id, user.serialNumber));
-
+ synchronized (mUserLock) {
+ if (user == null) {
+ mAddingUser = false;
mPendingUserIcon = null;
mPendingUserName = null;
+ ThreadUtils.postOnMainThread(() -> onUserCreationFailed());
+ return;
}
+
+ Drawable newUserIcon = mPendingUserIcon;
+ if (newUserIcon == null) {
+ newUserIcon = UserIcons.getDefaultUserIcon(getResources(), user.id, false);
+ }
+ mUserManager.setUserIcon(user.id, UserIcons.convertToBitmap(newUserIcon));
+
+ if (mUserType == USER_TYPE_USER) {
+ mHandler.sendEmptyMessage(MESSAGE_UPDATE_LIST);
+ }
+
+ mHandler.sendMessage(mHandler.obtainMessage(
+ MESSAGE_USER_CREATED, user.id, user.serialNumber));
+
+ mPendingUserIcon = null;
+ mPendingUserName = null;
}
- });
- }
+ }
+ };
/**
* Erase the current user (guest) and switch to another user.
diff --git a/src/com/android/settings/wifi/ConnectedWifiEntryPreference.java b/src/com/android/settings/wifi/ConnectedWifiEntryPreference.java
index afba0d8..1c069246 100644
--- a/src/com/android/settings/wifi/ConnectedWifiEntryPreference.java
+++ b/src/com/android/settings/wifi/ConnectedWifiEntryPreference.java
@@ -22,7 +22,6 @@
import androidx.preference.PreferenceViewHolder;
import com.android.settingslib.R;
-import com.android.settingslib.wifi.LongPressWifiEntryPreference;
import com.android.wifitrackerlib.WifiEntry;
/**
diff --git a/src/com/android/settings/wifi/LongPressWifiEntryPreference.java b/src/com/android/settings/wifi/LongPressWifiEntryPreference.java
new file mode 100644
index 0000000..bee92cf
--- /dev/null
+++ b/src/com/android/settings/wifi/LongPressWifiEntryPreference.java
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+package com.android.settings.wifi;
+
+import android.content.Context;
+
+import androidx.fragment.app.Fragment;
+import androidx.preference.PreferenceViewHolder;
+
+import com.android.wifitrackerlib.WifiEntry;
+
+/**
+ * WifiEntryPreference that can be long pressed.
+ */
+public class LongPressWifiEntryPreference extends WifiEntryPreference {
+
+ private final Fragment mFragment;
+
+ public LongPressWifiEntryPreference(Context context, WifiEntry wifiEntry, Fragment fragment) {
+ super(context, wifiEntry);
+ mFragment = fragment;
+ }
+
+ @Override
+ public void onBindViewHolder(final PreferenceViewHolder view) {
+ super.onBindViewHolder(view);
+ if (mFragment != null) {
+ view.itemView.setOnCreateContextMenuListener(mFragment);
+ view.itemView.setTag(this);
+ view.itemView.setLongClickable(true);
+ }
+ }
+}
diff --git a/src/com/android/settings/wifi/WifiConnectionPreferenceController.java b/src/com/android/settings/wifi/WifiConnectionPreferenceController.java
index 3b2669c..47eb587 100644
--- a/src/com/android/settings/wifi/WifiConnectionPreferenceController.java
+++ b/src/com/android/settings/wifi/WifiConnectionPreferenceController.java
@@ -37,7 +37,6 @@
import com.android.settings.wifi.details2.WifiNetworkDetailsFragment2;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.lifecycle.Lifecycle;
-import com.android.settingslib.wifi.WifiEntryPreference;
import com.android.wifitrackerlib.WifiEntry;
import com.android.wifitrackerlib.WifiPickerTracker;
diff --git a/src/com/android/settings/wifi/WifiDialog2.java b/src/com/android/settings/wifi/WifiDialog2.java
index dc546f3..52f3e74 100644
--- a/src/com/android/settings/wifi/WifiDialog2.java
+++ b/src/com/android/settings/wifi/WifiDialog2.java
@@ -21,6 +21,9 @@
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.View;
+import android.view.Window;
+import android.view.WindowInsets;
+import android.view.WindowManager;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.TextView;
@@ -108,6 +111,8 @@
@Override
protected void onCreate(Bundle savedInstanceState) {
+ setWindowsOverlay();
+
mView = getLayoutInflater().inflate(R.layout.wifi_dialog, /* root */ null);
setView(mView);
mController = new WifiConfigController2(this, mView, mWifiEntry, mMode);
@@ -126,6 +131,16 @@
}
}
+ private void setWindowsOverlay() {
+ final Window window = getWindow();
+ final WindowManager.LayoutParams lp = window.getAttributes();
+ window.setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
+ lp.setFitInsetsTypes(WindowInsets.Type.statusBars() | WindowInsets.Type.navigationBars());
+ lp.setFitInsetsSides(WindowInsets.Side.all());
+ lp.setFitInsetsIgnoringVisibility(true);
+ window.setAttributes(lp);
+ }
+
@Override
protected void onStart() {
final ImageButton ssidScannerButton = findViewById(R.id.ssid_scanner_button);
diff --git a/src/com/android/settings/wifi/WifiEntryPreference.java b/src/com/android/settings/wifi/WifiEntryPreference.java
new file mode 100644
index 0000000..3dfeada
--- /dev/null
+++ b/src/com/android/settings/wifi/WifiEntryPreference.java
@@ -0,0 +1,315 @@
+/*
+ * 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.
+ */
+package com.android.settings.wifi;
+
+import android.annotation.Nullable;
+import android.content.Context;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.StateListDrawable;
+import android.text.TextUtils;
+import android.view.View;
+import android.widget.ImageButton;
+import android.widget.ImageView;
+
+import androidx.annotation.DrawableRes;
+import androidx.annotation.NonNull;
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceViewHolder;
+
+import com.android.settingslib.R;
+import com.android.settingslib.Utils;
+import com.android.settingslib.wifi.WifiUtils;
+import com.android.wifitrackerlib.WifiEntry;
+
+/**
+ * Preference to display a WifiEntry in a wifi picker.
+ */
+public class WifiEntryPreference extends Preference implements WifiEntry.WifiEntryCallback,
+ View.OnClickListener {
+
+ private static final int[] STATE_SECURED = {
+ R.attr.state_encrypted
+ };
+
+ private static final int[] FRICTION_ATTRS = {
+ R.attr.wifi_friction
+ };
+
+ // These values must be kept within [WifiEntry.WIFI_LEVEL_MIN, WifiEntry.WIFI_LEVEL_MAX]
+ private static final int[] WIFI_CONNECTION_STRENGTH = {
+ R.string.accessibility_no_wifi,
+ R.string.accessibility_wifi_one_bar,
+ R.string.accessibility_wifi_two_bars,
+ R.string.accessibility_wifi_three_bars,
+ R.string.accessibility_wifi_signal_full
+ };
+
+ // StateListDrawable to display secured lock / metered "$" icon
+ @Nullable private final StateListDrawable mFrictionSld;
+ private final IconInjector mIconInjector;
+ private WifiEntry mWifiEntry;
+ private int mLevel = -1;
+ private boolean mShowX; // Shows the Wi-Fi signl icon of Pie+x when it's true.
+ private CharSequence mContentDescription;
+ private OnButtonClickListener mOnButtonClickListener;
+
+ public WifiEntryPreference(@NonNull Context context, @NonNull WifiEntry wifiEntry) {
+ this(context, wifiEntry, new IconInjector(context));
+ }
+
+ @VisibleForTesting
+ WifiEntryPreference(@NonNull Context context, @NonNull WifiEntry wifiEntry,
+ @NonNull IconInjector iconInjector) {
+ super(context);
+
+ setLayoutResource(R.layout.preference_access_point);
+ setWidgetLayoutResource(R.layout.access_point_friction_widget);
+ mFrictionSld = getFrictionStateListDrawable();
+ mWifiEntry = wifiEntry;
+ mWifiEntry.setListener(this);
+ mIconInjector = iconInjector;
+ refresh();
+ }
+
+ public WifiEntry getWifiEntry() {
+ return mWifiEntry;
+ }
+
+ @Override
+ public void onBindViewHolder(final PreferenceViewHolder view) {
+ super.onBindViewHolder(view);
+ final Drawable drawable = getIcon();
+ if (drawable != null) {
+ drawable.setLevel(mLevel);
+ }
+
+ view.itemView.setContentDescription(mContentDescription);
+
+ // Turn off divider
+ view.findViewById(R.id.two_target_divider).setVisibility(View.INVISIBLE);
+
+ // Enable the icon button when the help string in this WifiEntry is not null.
+ final ImageButton imageButton = (ImageButton) view.findViewById(R.id.icon_button);
+ final ImageView frictionImageView = (ImageView) view.findViewById(
+ R.id.friction_icon);
+ if (mWifiEntry.getHelpUriString() != null
+ && mWifiEntry.getConnectedState() == WifiEntry.CONNECTED_STATE_DISCONNECTED) {
+ final Drawable drawablehelp = getDrawable(R.drawable.ic_help);
+ drawablehelp.setTintList(
+ Utils.getColorAttr(getContext(), android.R.attr.colorControlNormal));
+ ((ImageView) imageButton).setImageDrawable(drawablehelp);
+ imageButton.setVisibility(View.VISIBLE);
+ imageButton.setOnClickListener(this);
+ imageButton.setContentDescription(
+ getContext().getText(R.string.help_label));
+
+ if (frictionImageView != null) {
+ frictionImageView.setVisibility(View.GONE);
+ }
+ } else {
+ imageButton.setVisibility(View.GONE);
+
+ if (frictionImageView != null) {
+ frictionImageView.setVisibility(View.VISIBLE);
+ bindFrictionImage(frictionImageView);
+ }
+ }
+ }
+
+ /**
+ * Updates the title and summary; may indirectly call notifyChanged().
+ */
+ public void refresh() {
+ setTitle(mWifiEntry.getTitle());
+ final int level = mWifiEntry.getLevel();
+ final boolean showX = mWifiEntry.shouldShowXLevelIcon();
+ if (level != mLevel || showX != mShowX) {
+ mLevel = level;
+ mShowX = showX;
+ updateIcon(mShowX, mLevel);
+ notifyChanged();
+ }
+
+ setSummary(mWifiEntry.getSummary(false /* concise */));
+ mContentDescription = buildContentDescription();
+ }
+
+ /**
+ * Indicates the state of the WifiEntry has changed and clients may retrieve updates through
+ * the WifiEntry getter methods.
+ */
+ public void onUpdated() {
+ // TODO(b/70983952): Fill this method in
+ refresh();
+ }
+
+ /**
+ * Result of the connect request indicated by the WifiEntry.CONNECT_STATUS constants.
+ */
+ public void onConnectResult(int status) {
+ // TODO(b/70983952): Fill this method in
+ }
+
+ /**
+ * Result of the disconnect request indicated by the WifiEntry.DISCONNECT_STATUS constants.
+ */
+ public void onDisconnectResult(int status) {
+ // TODO(b/70983952): Fill this method in
+ }
+
+ /**
+ * Result of the forget request indicated by the WifiEntry.FORGET_STATUS constants.
+ */
+ public void onForgetResult(int status) {
+ // TODO(b/70983952): Fill this method in
+ }
+
+ /**
+ * Result of the sign-in request indecated by the WifiEntry.SIGNIN_STATUS constants
+ */
+ public void onSignInResult(int status) {
+ // TODO(b/70983952): Fill this method in
+ }
+
+ protected int getIconColorAttr() {
+ final boolean accent = (mWifiEntry.hasInternetAccess()
+ && mWifiEntry.getConnectedState() == WifiEntry.CONNECTED_STATE_CONNECTED);
+ return accent ? android.R.attr.colorAccent : android.R.attr.colorControlNormal;
+ }
+
+ private void updateIcon(boolean showX, int level) {
+ if (level == -1) {
+ setIcon(null);
+ return;
+ }
+
+ final Drawable drawable = mIconInjector.getIcon(showX, level);
+ if (drawable != null) {
+ drawable.setTint(Utils.getColorAttrDefaultColor(getContext(), getIconColorAttr()));
+ setIcon(drawable);
+ } else {
+ setIcon(null);
+ }
+ }
+
+ @Nullable
+ private StateListDrawable getFrictionStateListDrawable() {
+ TypedArray frictionSld;
+ try {
+ frictionSld = getContext().getTheme().obtainStyledAttributes(FRICTION_ATTRS);
+ } catch (Resources.NotFoundException e) {
+ // Fallback for platforms that do not need friction icon resources.
+ frictionSld = null;
+ }
+ return frictionSld != null ? (StateListDrawable) frictionSld.getDrawable(0) : null;
+ }
+
+ /**
+ * Binds the friction icon drawable using a StateListDrawable.
+ *
+ * <p>Friction icons will be rebound when notifyChange() is called, and therefore
+ * do not need to be managed in refresh()</p>.
+ */
+ private void bindFrictionImage(ImageView frictionImageView) {
+ if (frictionImageView == null || mFrictionSld == null) {
+ return;
+ }
+ if ((mWifiEntry.getSecurity() != WifiEntry.SECURITY_NONE)
+ && (mWifiEntry.getSecurity() != WifiEntry.SECURITY_OWE)) {
+ mFrictionSld.setState(STATE_SECURED);
+ }
+ frictionImageView.setImageDrawable(mFrictionSld.getCurrent());
+ }
+
+ /**
+ * Helper method to generate content description string.
+ */
+ @VisibleForTesting
+ CharSequence buildContentDescription() {
+ final Context context = getContext();
+
+ CharSequence contentDescription = getTitle();
+ final CharSequence summary = getSummary();
+ if (!TextUtils.isEmpty(summary)) {
+ contentDescription = TextUtils.concat(contentDescription, ",", summary);
+ }
+ int level = mWifiEntry.getLevel();
+ if (level >= 0 && level < WIFI_CONNECTION_STRENGTH.length) {
+ contentDescription = TextUtils.concat(contentDescription, ",",
+ context.getString(WIFI_CONNECTION_STRENGTH[level]));
+ }
+ return TextUtils.concat(contentDescription, ",",
+ mWifiEntry.getSecurity() == WifiEntry.SECURITY_NONE
+ ? context.getString(R.string.accessibility_wifi_security_type_none)
+ : context.getString(R.string.accessibility_wifi_security_type_secured));
+ }
+
+
+ static class IconInjector {
+ private final Context mContext;
+
+ IconInjector(Context context) {
+ mContext = context;
+ }
+
+ public Drawable getIcon(boolean showX, int level) {
+ return mContext.getDrawable(WifiUtils.getInternetIconResource(level, showX));
+ }
+ }
+
+ /**
+ * Set listeners, who want to listen the button client event.
+ */
+ public void setOnButtonClickListener(OnButtonClickListener listener) {
+ mOnButtonClickListener = listener;
+ notifyChanged();
+ }
+
+ @Override
+ public void onClick(View view) {
+ if (view.getId() == R.id.icon_button) {
+ if (mOnButtonClickListener != null) {
+ mOnButtonClickListener.onButtonClick(this);
+ }
+ }
+ }
+
+ /**
+ * Callback to inform the caller that the icon button is clicked.
+ */
+ public interface OnButtonClickListener {
+
+ /**
+ * Register to listen the button click event.
+ */
+ void onButtonClick(WifiEntryPreference preference);
+ }
+
+ private Drawable getDrawable(@DrawableRes int iconResId) {
+ Drawable buttonIcon = null;
+
+ try {
+ buttonIcon = getContext().getDrawable(iconResId);
+ } catch (Resources.NotFoundException exception) {
+ // Do nothing
+ }
+ return buttonIcon;
+ }
+
+}
diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java
index 59f6504..0680b33 100644
--- a/src/com/android/settings/wifi/WifiSettings.java
+++ b/src/com/android/settings/wifi/WifiSettings.java
@@ -74,7 +74,6 @@
import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.search.Indexable;
import com.android.settingslib.search.SearchIndexable;
-import com.android.settingslib.wifi.LongPressWifiEntryPreference;
import com.android.settingslib.wifi.WifiSavedConfigUtils;
import com.android.wifitrackerlib.WifiEntry;
import com.android.wifitrackerlib.WifiEntry.ConnectCallback;
diff --git a/src/com/android/settings/wifi/calling/WifiCallingSettings.java b/src/com/android/settings/wifi/calling/WifiCallingSettings.java
index 86e7e8d..783ad3e 100644
--- a/src/com/android/settings/wifi/calling/WifiCallingSettings.java
+++ b/src/com/android/settings/wifi/calling/WifiCallingSettings.java
@@ -17,6 +17,7 @@
package com.android.settings.wifi.calling;
import android.app.settings.SettingsEnums;
+import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.provider.Settings;
@@ -29,12 +30,14 @@
import androidx.annotation.VisibleForTesting;
import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;
import com.android.internal.util.CollectionUtils;
import com.android.settings.R;
import com.android.settings.core.InstrumentedFragment;
+import com.android.settings.network.ActiveSubscriptionsListener;
import com.android.settings.network.SubscriptionUtil;
import com.android.settings.network.ims.WifiCallingQueryImsState;
import com.android.settings.search.actionbar.SearchMenuController;
@@ -42,6 +45,9 @@
import com.android.settings.widget.RtlCompatibleViewPager;
import com.android.settings.widget.SlidingTabLayout;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
/**
@@ -50,7 +56,10 @@
*/
public class WifiCallingSettings extends InstrumentedFragment implements HelpResourceProvider {
private static final String TAG = "WifiCallingSettings";
+ private int mConstructionSubId;
private List<SubscriptionInfo> mSil;
+ private ActiveSubscriptionsListener mSubscriptionChangeListener;
+ private static final int [] EMPTY_SUB_ID_LIST = new int[0];
//UI objects
private RtlCompatibleViewPager mViewPager;
@@ -95,16 +104,26 @@
return view;
}
+ private int getConstructionSubId(Bundle bundle) {
+ int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+
+ Intent intent = getActivity().getIntent();
+ if (intent != null) {
+ subId = intent.getIntExtra(Settings.EXTRA_SUB_ID,
+ SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+ }
+ if ((subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) && (bundle != null)) {
+ subId = bundle.getInt(Settings.EXTRA_SUB_ID,
+ SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+ }
+ return subId;
+ }
+
private void maybeSetViewForSubId() {
if (mSil == null) {
return;
}
- final Intent intent = getActivity().getIntent();
- if (intent == null) {
- return;
- }
- final int subId = intent.getIntExtra(Settings.EXTRA_SUB_ID,
- SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+ int subId = mConstructionSubId;
if (SubscriptionManager.isValidSubscriptionId(subId)) {
for (SubscriptionInfo subInfo : mSil) {
if (subId == subInfo.getSubscriptionId()) {
@@ -117,11 +136,15 @@
@Override
public void onCreate(Bundle icicle) {
+ mConstructionSubId = getConstructionSubId(icicle);
super.onCreate(icicle);
+ Log.d(TAG, "SubId=" + mConstructionSubId);
- // TODO: besides in onCreate, we should also update subList when SIM / Sub status
- // changes.
- updateSubList();
+ if (mConstructionSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+ // Only config Wfc if it's enabled by platform.
+ mSubscriptionChangeListener = getSubscriptionChangeListener(getContext());
+ }
+ mSil = updateSubList();
}
@Override
@@ -135,6 +158,26 @@
}
updateTitleForCurrentSub();
+
+ if (mSubscriptionChangeListener != null) {
+ mSubscriptionChangeListener.start();
+ }
+ }
+
+ @Override
+ public void onStop() {
+ if (mSubscriptionChangeListener != null) {
+ mSubscriptionChangeListener.stop();
+ }
+
+ super.onStop();
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ // keep subscription ID for recreation
+ outState.putInt(Settings.EXTRA_SUB_ID, mConstructionSubId);
}
@Override
@@ -160,11 +203,11 @@
@Override
public Fragment getItem(int position) {
- Log.d(TAG, "Adapter getItem " + position);
+ int subId = mSil.get(position).getSubscriptionId();
+ Log.d(TAG, "Adapter getItem " + position + " for subId=" + subId);
final Bundle args = new Bundle();
args.putBoolean(SearchMenuController.NEED_SEARCH_ICON_IN_ACTION_BAR, false);
- args.putInt(WifiCallingSettingsForSub.FRAGMENT_BUNDLE_SUBID,
- mSil.get(position).getSubscriptionId());
+ args.putInt(WifiCallingSettingsForSub.FRAGMENT_BUNDLE_SUBID, subId);
final WifiCallingSettingsForSub fragment = new WifiCallingSettingsForSub();
fragment.setArguments(args);
@@ -190,22 +233,27 @@
}
}
- private void updateSubList() {
- mSil = SubscriptionUtil.getActiveSubscriptions(
- getContext().getSystemService(SubscriptionManager.class));
+ @VisibleForTesting
+ protected List<SubscriptionInfo> getSelectableSubscriptions(Context context) {
+ return SubscriptionUtil.getSelectableSubscriptionInfoList(context);
+ }
- // Only config Wfc if it's enabled by platform.
- if (mSil == null) {
- return;
+ private List<SubscriptionInfo> updateSubList() {
+ List<SubscriptionInfo> subInfoList = getSelectableSubscriptions(getContext());
+
+ if (subInfoList == null) {
+ return Collections.emptyList();
}
- for (int i = 0; i < mSil.size(); ) {
- final SubscriptionInfo info = mSil.get(i);
- if (!queryImsState(info.getSubscriptionId()).isWifiCallingProvisioned()) {
- mSil.remove(i);
- } else {
- i++;
- }
+ List<SubscriptionInfo> selectedList = new ArrayList<SubscriptionInfo>();
+ for (SubscriptionInfo subInfo : subInfoList) {
+ int subId = subInfo.getSubscriptionId();
+ try {
+ if (queryImsState(subId).isWifiCallingProvisioned()) {
+ selectedList.add(subInfo);
+ }
+ } finally {}
}
+ return selectedList;
}
private void updateTitleForCurrentSub() {
@@ -218,7 +266,78 @@
}
@VisibleForTesting
- WifiCallingQueryImsState queryImsState(int subId) {
+ protected WifiCallingQueryImsState queryImsState(int subId) {
return new WifiCallingQueryImsState(getContext(), subId);
}
+
+ @VisibleForTesting
+ protected ActiveSubscriptionsListener getSubscriptionChangeListener(Context context) {
+ return new ActiveSubscriptionsListener(context.getMainLooper(), context) {
+ public void onChanged() {
+ onSubscriptionChange(context);
+ }
+ };
+ }
+
+ protected void onSubscriptionChange(Context context) {
+ if (mSubscriptionChangeListener == null) {
+ return;
+ }
+ int [] previousSubIdList = subscriptionIdList(mSil);
+ List<SubscriptionInfo> updateList = updateSubList();
+ int [] currentSubIdList = subscriptionIdList(updateList);
+
+ if (currentSubIdList.length > 0) {
+ // only keep fragment when any provisioned subscription is available
+ if (previousSubIdList.length == 0) {
+ // initial loading of list
+ mSil = updateList;
+ return;
+ }
+ if (previousSubIdList.length == currentSubIdList.length) {
+ // same number of subscriptions
+ if ( (!containsSubId(previousSubIdList, mConstructionSubId))
+ // original request not yet appears in list
+ || containsSubId(currentSubIdList, mConstructionSubId) )
+ // original request appears in list
+ {
+ mSil = updateList;
+ return;
+ }
+ }
+ }
+ Log.d(TAG, "Closed subId=" + mConstructionSubId
+ + " due to subscription change: " + Arrays.toString(previousSubIdList)
+ + " -> " + Arrays.toString(currentSubIdList));
+
+ // close this fragment when no provisioned subscriptions available
+ if (mSubscriptionChangeListener != null) {
+ mSubscriptionChangeListener.stop();
+ mSubscriptionChangeListener = null;
+ }
+
+ // close this fragment
+ finish();
+ }
+
+ protected void finish() {
+ FragmentActivity activity = getActivity();
+ if (activity == null) return;
+ if (getFragmentManager().getBackStackEntryCount() > 0) {
+ getFragmentManager().popBackStack();
+ } else {
+ activity.finish();
+ }
+ }
+
+ protected int [] subscriptionIdList(List<SubscriptionInfo> subInfoList) {
+ return (subInfoList == null) ? EMPTY_SUB_ID_LIST :
+ subInfoList.stream().mapToInt(subInfo -> (subInfo == null) ?
+ SubscriptionManager.INVALID_SUBSCRIPTION_ID : subInfo.getSubscriptionId())
+ .toArray();
+ }
+
+ protected boolean containsSubId(int [] subIdArray, int subIdLookUp) {
+ return Arrays.stream(subIdArray).anyMatch(subId -> (subId == subIdLookUp));
+ }
}
diff --git a/src/com/android/settings/wifi/dpp/WifiNetworkListFragment.java b/src/com/android/settings/wifi/dpp/WifiNetworkListFragment.java
index a017fac..61d2eb8 100644
--- a/src/com/android/settings/wifi/dpp/WifiNetworkListFragment.java
+++ b/src/com/android/settings/wifi/dpp/WifiNetworkListFragment.java
@@ -41,7 +41,7 @@
import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.core.SubSettingLauncher;
import com.android.settings.wifi.AddNetworkFragment;
-import com.android.settingslib.wifi.WifiEntryPreference;
+import com.android.settings.wifi.WifiEntryPreference;
import com.android.wifitrackerlib.SavedNetworkTracker;
import com.android.wifitrackerlib.WifiEntry;
diff --git a/src/com/android/settings/wifi/savedaccesspoints2/SavedAccessPointsPreferenceController2.java b/src/com/android/settings/wifi/savedaccesspoints2/SavedAccessPointsPreferenceController2.java
index 1d1c801..f0841f4 100644
--- a/src/com/android/settings/wifi/savedaccesspoints2/SavedAccessPointsPreferenceController2.java
+++ b/src/com/android/settings/wifi/savedaccesspoints2/SavedAccessPointsPreferenceController2.java
@@ -25,7 +25,7 @@
import androidx.preference.PreferenceScreen;
import com.android.settings.core.BasePreferenceController;
-import com.android.settingslib.wifi.WifiEntryPreference;
+import com.android.settings.wifi.WifiEntryPreference;
import com.android.wifitrackerlib.WifiEntry;
import java.util.ArrayList;
diff --git a/tests/componenttests/src/com/android/settings/display/darkmode/DarkThemeScheduleComponentTest.java b/tests/componenttests/src/com/android/settings/display/darkmode/DarkThemeScheduleComponentTest.java
new file mode 100644
index 0000000..e21f37e
--- /dev/null
+++ b/tests/componenttests/src/com/android/settings/display/darkmode/DarkThemeScheduleComponentTest.java
@@ -0,0 +1,144 @@
+/*
+ * 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.
+ */
+
+package com.android.settings.display.darkmode;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.app.Instrumentation;
+import android.app.TimePickerDialog;
+import android.app.UiModeManager;
+import android.content.Intent;
+import android.content.res.Configuration;
+import android.provider.Settings;
+import android.util.Log;
+
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentActivity;
+import androidx.test.core.app.ActivityScenario;
+import androidx.test.ext.junit.rules.ActivityScenarioRule;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.runner.lifecycle.Stage;
+
+import com.android.settings.testutils.CommonUtils;
+import com.android.settings.testutils.UiUtils;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.time.LocalTime;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class DarkThemeScheduleComponentTest {
+ private static final int DIALOG_START_TIME = 0;
+ private static final int DIALOG_END_TIME = 1;
+ /** The identifier for the positive button. */
+ private static final int BUTTON_POSITIVE = -1;
+ public final String TAG = this.getClass().getName();
+ private final Instrumentation mInstrumentation = InstrumentationRegistry.getInstrumentation();
+
+ @Rule
+ public ActivityScenarioRule<com.android.settings.Settings.DarkThemeSettingsActivity> rule =
+ new ActivityScenarioRule<>(
+ new Intent(
+ Settings.ACTION_DARK_THEME_SETTINGS).setFlags(
+ Intent.FLAG_ACTIVITY_NEW_TASK));
+ private UiModeManager mUiModeManager;
+
+ @Before
+ public void setUp() {
+ mUiModeManager = mInstrumentation.getTargetContext().getSystemService(UiModeManager.class);
+ if (mUiModeManager.getNightMode() != UiModeManager.MODE_NIGHT_NO) {
+ mUiModeManager.setNightMode(UiModeManager.MODE_NIGHT_NO);
+ }
+ }
+
+ private void test_step_for_custom_time(int startTimeDiff, int endTimeDiff) {
+
+ ActivityScenario scenario = rule.getScenario();
+ scenario.onActivity(activity -> {
+ mUiModeManager.setNightMode(UiModeManager.MODE_NIGHT_CUSTOM);
+ Fragment f =
+ ((FragmentActivity) activity).getSupportFragmentManager().getFragments().get(0);
+ DarkModeSettingsFragment fragment = (DarkModeSettingsFragment) f;
+
+ setCustomTime(fragment, DIALOG_START_TIME, LocalTime.now().plusMinutes(startTimeDiff));
+ setCustomTime(fragment, DIALOG_END_TIME, LocalTime.now().plusMinutes(endTimeDiff));
+
+ // The night mode need to reopen the screen to trigger UI change after mode change.
+ CommonUtils.reopenScreen();
+ });
+
+ // Relaunch the scenario to make sure UI apply new mode.
+ scenario.onActivity(activity -> {
+ Log.d(TAG, "Activity Recreated!");
+ UiUtils.waitForActivitiesInStage(2000, Stage.RESUMED);
+ });
+ }
+
+ @Test
+ public void test_dark_mode_in_custom_time() {
+ test_step_for_custom_time(-1, 11);
+ assertThat(checkNightMode(true)).isTrue();
+ }
+
+ @Test
+ public void test_dark_mode_after_custom_time() {
+ test_step_for_custom_time(-11, -1);
+ assertThat(checkNightMode(false)).isTrue();
+ }
+
+ @Test
+ public void test_dark_mode_before_custom_time() {
+ test_step_for_custom_time(2, 20);
+ assertThat(checkNightMode(false)).isTrue();
+ }
+
+ /**
+ * Sets custom time for night mode.
+ *
+ * @param fragment The DarkModeSettingsFragment.
+ * @param dialogId Dialog id for start time or end time.
+ * @param time The time to be set.
+ */
+ private void setCustomTime(DarkModeSettingsFragment fragment, int dialogId, LocalTime time) {
+ Log.d(TAG, "Start to set custom time " + (dialogId == DIALOG_START_TIME ? "StartTime"
+ : "EndTime") + " to " + time.getHour() + ":" + time.getMinute());
+ TimePickerDialog startTimeDialog = (TimePickerDialog) fragment.onCreateDialog(dialogId);
+ startTimeDialog.updateTime(time.getHour(), time.getMinute());
+ startTimeDialog.onClick(startTimeDialog, BUTTON_POSITIVE);
+ }
+
+ private boolean checkNightMode(boolean isNightMode) {
+ int mask = (isNightMode ? Configuration.UI_MODE_NIGHT_YES : Configuration.UI_MODE_NIGHT_NO);
+ int mode = mInstrumentation.getTargetContext().getResources().getConfiguration().uiMode;
+ return (mode & mask) != 0;
+ }
+
+ @After
+ public void tearDown() {
+ Log.d(TAG, "tearDown.");
+ if (mUiModeManager.getNightMode() != UiModeManager.MODE_NIGHT_NO) {
+ mUiModeManager.setNightMode(UiModeManager.MODE_NIGHT_NO);
+ }
+ }
+}
diff --git a/tests/componenttests/src/com/android/settings/homepage/HomepageComponentTest.java b/tests/componenttests/src/com/android/settings/homepage/HomepageComponentTest.java
new file mode 100644
index 0000000..cf64749
--- /dev/null
+++ b/tests/componenttests/src/com/android/settings/homepage/HomepageComponentTest.java
@@ -0,0 +1,137 @@
+/*
+ * 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.
+ */
+
+package com.android.settings.homepage;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assert_;
+
+import android.app.Instrumentation;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.provider.Settings;
+import android.util.Log;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.google.common.collect.ImmutableList;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.List;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class HomepageComponentTest {
+ public final String TAG = this.getClass().getSimpleName();
+
+ private final Instrumentation mInstrumentation = InstrumentationRegistry.getInstrumentation();
+
+ @Test
+ public void test_launch_all_settings_in_home()
+ throws ClassNotFoundException {
+
+ List<Intent> launchIntents = ImmutableList.of(
+
+ // Wifi
+ // Implemented in WifiSettings2ActivityTest
+
+ // Connected devices
+ new Intent(Settings.ACTION_BLUETOOTH_SETTINGS),
+
+ // Applications
+ new Intent(Settings.ACTION_AUTO_ROTATE_SETTINGS),
+
+ // Notifications
+ new Intent(Settings.ACTION_NOTIFICATION_SETTINGS),
+
+ // Display
+ new Intent(Settings.ACTION_DISPLAY_SETTINGS),
+
+ // Battery
+ // Implemented in fuelgauge.batterysaver
+
+ // Storage
+ new Intent(Settings.ACTION_INTERNAL_STORAGE_SETTINGS),
+
+ // Sound
+ new Intent(Settings.ACTION_SOUND_SETTINGS),
+
+ // Display
+ new Intent(Settings.ACTION_DISPLAY_SETTINGS),
+
+ // Wallpaper
+ new Intent(mInstrumentation.getTargetContext(), Class.forName(
+ "com.android.settings.wallpaper.WallpaperSuggestionActivity")),
+
+ // A11y
+ new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS),
+
+ // Security
+ new Intent(Settings.ACTION_SECURITY_SETTINGS),
+
+ // Privacy
+ new Intent(Settings.ACTION_PRIVACY_SETTINGS),
+
+ // Location
+ new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS),
+
+ // Emergency ? EmergencyDashboardFragment
+ // TODO: find out launch method
+
+ // Password & Account
+ new Intent(Settings.ACTION_SYNC_SETTINGS),
+
+ // Digital wellbeing
+ // Use IA link
+ new Intent().setComponent(
+ new ComponentName(
+ "com.google.android.apps.wellbeing",
+ "com.google.android.apps.wellbeing.settings"
+ + ".TopLevelSettingsActivity")),
+
+ // Google
+ // Use IA link
+ new Intent().setComponent(
+ new ComponentName(
+ "com.google.android.gms",
+ "com.google.android.gms.app.settings.GoogleSettingsIALink")),
+
+ // System ?
+ // TODO: find out launch method.
+
+ // About
+ new Intent(Settings.ACTION_DEVICE_INFO_SETTINGS)
+
+ );
+
+ for (Intent intent : launchIntents) {
+ Log.d(TAG, "Start to launch intent " + intent.getAction());
+ try {
+ mInstrumentation.getTargetContext()
+ .startActivity(intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
+ } catch (Exception e) {
+ Log.e(TAG, "Launch with exception. " + e.toString());
+ assert_().fail();
+ }
+ // Launch success without exception.
+ assertThat(Boolean.TRUE).isTrue();
+ }
+ }
+}
diff --git a/tests/componenttests/src/com/android/settings/network/AirplaneModePreferenceControllerComponentTest.java b/tests/componenttests/src/com/android/settings/network/AirplaneModePreferenceControllerComponentTest.java
new file mode 100644
index 0000000..27e67e5
--- /dev/null
+++ b/tests/componenttests/src/com/android/settings/network/AirplaneModePreferenceControllerComponentTest.java
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+package com.android.settings.network;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.app.Instrumentation;
+import android.provider.Settings;
+import android.provider.SettingsSlicesContract;
+import android.util.Log;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.settings.testutils.UiUtils;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class AirplaneModePreferenceControllerComponentTest {
+ // Airplane on off status
+ private static final int ON = 1;
+ private static final int OFF = 0;
+ public final String TAG = this.getClass().getName();
+ private final Instrumentation mInstrumentation = InstrumentationRegistry.getInstrumentation();
+ private boolean mOriginAirplaneModeIsOn;
+
+ @Before
+ public void setUp() {
+ // Make sure origin airplane mode is OFF.
+ mOriginAirplaneModeIsOn = is_airplane_mode_on();
+ if (mOriginAirplaneModeIsOn) {
+ Log.d(TAG, "Origin airplane mode is on, turn it off.");
+ Settings.Global.putInt(mInstrumentation.getTargetContext().getContentResolver(),
+ Settings.Global.AIRPLANE_MODE_ON, OFF);
+ }
+ }
+
+ /**
+ * Tests on/off airplane mode repeatedly.
+ * Previously, a bug describe that crash issue if user on off airplane mode repeatedly.
+ * This case try to switch on & off airplane mode for 10 times to check crash issue.
+ */
+ @Test
+ public void test_on_off_airplane_mode_multiple_times() {
+ AirplaneModePreferenceController controller =
+ new AirplaneModePreferenceController(mInstrumentation.getTargetContext(),
+ SettingsSlicesContract.KEY_AIRPLANE_MODE);
+
+ for (int i = 0; i < 10; ++i) {
+ Log.d(TAG, "Test #" + (i + 1));
+ controller.setChecked(true);
+ assertThat(UiUtils.waitUntilCondition(1000,
+ () -> is_airplane_mode_on())).isTrue();
+
+ controller.setChecked(false);
+ assertThat(UiUtils.waitUntilCondition(1000,
+ () -> !is_airplane_mode_on())).isTrue();
+ }
+
+ }
+
+ private boolean is_airplane_mode_on() {
+ return Settings.System.getInt(
+ mInstrumentation.getTargetContext().getContentResolver(),
+ Settings.Global.AIRPLANE_MODE_ON, OFF) != 0;
+ }
+
+ @After
+ public void tearDown() {
+ if (is_airplane_mode_on() != mOriginAirplaneModeIsOn) {
+ Settings.Global.putInt(mInstrumentation.getTargetContext().getContentResolver(),
+ Settings.Global.AIRPLANE_MODE_ON, (
+ mOriginAirplaneModeIsOn ? ON : OFF));
+ }
+ }
+}
diff --git a/tests/componenttests/src/com/android/settings/network/telephony/MobileDataPreferenceControllerComponentTest.java b/tests/componenttests/src/com/android/settings/network/telephony/MobileDataPreferenceControllerComponentTest.java
new file mode 100644
index 0000000..e35cd0c
--- /dev/null
+++ b/tests/componenttests/src/com/android/settings/network/telephony/MobileDataPreferenceControllerComponentTest.java
@@ -0,0 +1,148 @@
+/*
+ * 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.
+ */
+
+package com.android.settings.network.telephony;
+
+import static com.android.settings.testutils.CommonUtils.set_wifi_enabled;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.app.Instrumentation;
+import android.content.Context;
+import android.content.Intent;
+import android.net.wifi.WifiManager;
+import android.telephony.TelephonyManager;
+import android.util.Log;
+
+import androidx.fragment.app.FragmentActivity;
+import androidx.fragment.app.FragmentManager;
+import androidx.test.core.app.ActivityScenario;
+import androidx.test.ext.junit.rules.ActivityScenarioRule;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.settings.testutils.CommonUtils;
+import com.android.settings.testutils.UiUtils;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.concurrent.ExecutionException;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class MobileDataPreferenceControllerComponentTest {
+ public static final int TIMEOUT = 2000;
+ private static final int SUBSCRIPTION_ID = 2;
+ public final String TAG = this.getClass().getName();
+ private final Instrumentation mInstrumentation = InstrumentationRegistry.getInstrumentation();
+ private final WifiManager mWifiManager =
+ (WifiManager) mInstrumentation.getTargetContext().getSystemService(
+ Context.WIFI_SERVICE);
+ private final TelephonyManager mTelephonyManager =
+ (TelephonyManager) mInstrumentation.getTargetContext().getSystemService(
+ Context.TELEPHONY_SERVICE);
+
+ @Rule
+ public ActivityScenarioRule<com.android.settings.network.telephony.MobileNetworkActivity>
+ rule = new ActivityScenarioRule<>(
+ new Intent(android.provider.Settings.ACTION_DATA_ROAMING_SETTINGS)
+ .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
+ private boolean mOriginDataEnabled;
+ private boolean mOriginWifiEnabled;
+
+ @Before
+ public void setUp() {
+ mOriginWifiEnabled = mWifiManager.isWifiEnabled();
+ Log.d(TAG, "setup! mTelephonyManager = " + mTelephonyManager);
+ // Disable wifi
+ set_wifi_enabled(false);
+
+ // Enable mobile data
+ mOriginDataEnabled = mTelephonyManager.isDataEnabled();
+ if (!mOriginDataEnabled) {
+ mTelephonyManager.enableDataConnectivity();
+ }
+ }
+
+ /**
+ * Tests the mobile network is disabled.
+ * Precondition:
+ * Disabled wifi, and enabled mobile network.
+ * Steps:
+ * 1. Launch mobile data page.
+ * 2. Turn off mobile data from switch.
+ * [Check]
+ * - Mobile data is turned off via TelephonyManager.
+ * - Open socket connection https://www.google.net and check the connection failed.
+ */
+ @Test
+ public void test_disable_mobile_network() {
+ ActivityScenario scenario = rule.getScenario();
+ scenario.onActivity(activity -> {
+ try {
+ URL url = new URL("https://www.google.net");
+ MobileDataPreferenceController controller = new MobileDataPreferenceController(
+ mInstrumentation.getTargetContext(), "mobile_data");
+ FragmentManager manager = ((FragmentActivity) activity).getSupportFragmentManager();
+ controller.init(manager, SUBSCRIPTION_ID);
+ Log.d(TAG, "Start to click ");
+ controller.setChecked(false);
+ Log.d(TAG, "Set Checked, wait for fully close.");
+
+ // Assert the configuration is set.
+ assertThat(UiUtils.waitUntilCondition(10000,
+ () -> !mTelephonyManager.isDataEnabled())).isTrue();
+
+ // Assert the network is not connectable.
+ assertThat(UiUtils.waitUntilCondition(3000,
+ () -> {
+ try {
+ return CommonUtils.connectToURL(url);
+ } catch (ExecutionException e) {
+ e.printStackTrace();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ return false;
+ })).isFalse();
+ } catch (IOException e) {
+
+ }
+ });
+ }
+
+ @After
+ public void tearDown() {
+ // Restore wifi status wifi
+ set_wifi_enabled(mOriginWifiEnabled);
+
+ // Restore mobile data status
+ if (mOriginDataEnabled != mTelephonyManager.isDataEnabled()) {
+ if (mOriginDataEnabled) {
+ mTelephonyManager.enableDataConnectivity();
+ } else {
+ mTelephonyManager.disableDataConnectivity();
+ }
+ }
+ }
+}
diff --git a/tests/componenttests/src/com/android/settings/testutils/AdbUtils.java b/tests/componenttests/src/com/android/settings/testutils/AdbUtils.java
index 08eb47a..b6e3c52 100644
--- a/tests/componenttests/src/com/android/settings/testutils/AdbUtils.java
+++ b/tests/componenttests/src/com/android/settings/testutils/AdbUtils.java
@@ -17,46 +17,63 @@
package com.android.settings.testutils;
import android.os.ParcelFileDescriptor;
-import android.text.TextUtils;
-import android.util.Log;
import androidx.test.platform.app.InstrumentationRegistry;
import java.io.BufferedReader;
+import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
-import java.util.Optional;
+import java.util.stream.Collectors;
public class AdbUtils {
+ public static String getCallerClassName() {
+ StackTraceElement[] stElements = Thread.currentThread().getStackTrace();
+ for (int i = 1; i < stElements.length; i++) {
+ StackTraceElement ste = stElements[i];
+ if (!ste.getClassName().equals(new Object() {
+ }.getClass().getEnclosingClass().getName()) && ste.getClassName().indexOf(
+ "java.lang.Thread") != 0) {
+ return ste.getClassName();
+ }
+ }
+ return null;
+ }
+
public static boolean checkStringInAdbCommandOutput(String logTag, String command,
String prefix, String target, int timeoutInMillis) throws Exception {
long start = System.nanoTime();
+
//Sometimes the change do no reflect in adn output immediately, so need a wait and poll here
while (System.nanoTime() - start < (timeoutInMillis * 1000000)) {
- try (ParcelFileDescriptor.AutoCloseInputStream in =
- new ParcelFileDescriptor.AutoCloseInputStream(
- InstrumentationRegistry.getInstrumentation()
- .getUiAutomation()
- .executeShellCommand(command))) {
- try (BufferedReader br =
- new BufferedReader(
- new InputStreamReader(in, StandardCharsets.UTF_8))) {
- Optional<String> resultOptional = br.lines().filter(line -> {
- Log.d(logTag, line);
- return TextUtils.isEmpty(prefix) || line.contains(prefix);
- }).findFirst();
- String result = resultOptional.get();
- if (result.contains(target)) {
- return true;
- } else {
- Thread.sleep(100);
- }
- }
- } catch (Exception e) {
- throw e;
+ String result = shell(command);
+ if (result.contains(prefix == null ? "" : prefix)
+ && result.contains(target == null ? "" : target)) {
+ return true;
+ } else {
+ Thread.sleep(100);
}
}
return false;
}
+
+ public static String shell(String shellCommand) {
+ String returnValue = "";
+ try (ParcelFileDescriptor.AutoCloseInputStream in =
+ new ParcelFileDescriptor.AutoCloseInputStream(
+ InstrumentationRegistry.getInstrumentation()
+ .getUiAutomation()
+ .executeShellCommand(shellCommand))) {
+ try (BufferedReader br =
+ new BufferedReader(
+ new InputStreamReader(in, StandardCharsets.UTF_8))) {
+ returnValue = br.lines().collect(Collectors.joining());
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ return returnValue;
+ }
}
diff --git a/tests/componenttests/src/com/android/settings/testutils/CommonUtils.java b/tests/componenttests/src/com/android/settings/testutils/CommonUtils.java
index 02a83fc..dce377d 100644
--- a/tests/componenttests/src/com/android/settings/testutils/CommonUtils.java
+++ b/tests/componenttests/src/com/android/settings/testutils/CommonUtils.java
@@ -17,8 +17,14 @@
package com.android.settings.testutils;
import android.app.Activity;
+import android.app.Instrumentation;
+import android.content.Context;
import android.graphics.Bitmap;
+import android.net.wifi.WifiManager;
import android.os.Environment;
+import android.os.PowerManager;
+import android.os.StrictMode;
+import android.os.SystemClock;
import android.util.Log;
import android.view.View;
@@ -31,11 +37,20 @@
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
+import java.util.concurrent.ExecutionException;
import javax.net.ssl.HttpsURLConnection;
public class CommonUtils {
private static final String TAG = CommonUtils.class.getSimpleName();
+ private static final Instrumentation sInstrumentation =
+ InstrumentationRegistry.getInstrumentation();
+ private static final WifiManager sWifiManager =
+ (WifiManager) sInstrumentation.getTargetContext().getSystemService(
+ Context.WIFI_SERVICE);
+ private static final PowerManager sPowerManager =
+ (PowerManager) sInstrumentation.getTargetContext().getSystemService(
+ Context.POWER_SERVICE);
public static void takeScreenshot(Activity activity) {
long now = System.currentTimeMillis();
@@ -65,7 +80,9 @@
}
}
- public static boolean connectToURL(URL url) {
+ public static boolean connectToURL(URL url) throws ExecutionException, InterruptedException {
+ StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
+ StrictMode.setThreadPolicy(policy);
HttpURLConnection connection = null;
try {
connection = (HttpsURLConnection) url.openConnection();
@@ -81,17 +98,19 @@
while (null != (line = reader.readLine())) {
response.append(line);
}
+ Log.d(TAG, "Connection success! " + response.toString());
return true;
}
} catch (Exception e) {
- Log.d(TAG, e.getMessage());
+ Log.e(TAG, e.toString());
+ e.printStackTrace();
return false;
} finally {
if (null != connection) {
connection.disconnect();
}
}
-
+ Log.d(TAG, "End, return false.");
return false;
}
@@ -106,4 +125,42 @@
return InstrumentationRegistry.getInstrumentation().getTargetContext().getResources()
.getIdentifier(name, "id", Constants.SETTINGS_PACKAGE_NAME);
}
+
+ public static void reopenScreen() {
+ sPowerManager.goToSleep(SystemClock.uptimeMillis());
+ // According to local test, we need to sleep to wait it fully processed.
+ // 1000 ms is a good value to sleep, otherwise it might cause keyDispatchingTimedOut.
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ UiUtils.waitUntilCondition(1000, () -> !sPowerManager.isInteractive());
+ sPowerManager.wakeUp(SystemClock.uptimeMillis());
+ UiUtils.waitUntilCondition(1000, () -> sPowerManager.isInteractive());
+
+ // After power on screen, need to unlock and goto home page.
+ AdbUtils.shell("input keyevent KEYCODE_MENU");
+ }
+
+ /**
+ * Sets wifi status to given enable / disable via ADB command.
+ */
+ public static void set_wifi_enabled(boolean enable) {
+ final int timeoutMsec = 10000;
+ Log.d(TAG, "Set wifi status to " + enable);
+ if (sWifiManager.isWifiEnabled() != enable) {
+ AdbUtils.shell("svc wifi " + (enable ? "enable" : "disable"));
+ if (!UiUtils.waitUntilCondition(timeoutMsec,
+ () -> sWifiManager.isWifiEnabled() == enable)) {
+ Log.e(TAG, "Cannot set wifi to " + (enable ? "enabl" : "disable") + ", timeout "
+ + timeoutMsec + " (ms).");
+ Log.e(TAG, "See logcat for more information.");
+ }
+ Log.d(TAG, "After configuration wifi status = " + sWifiManager.isWifiEnabled());
+ } else {
+ Log.d(TAG, "Wifi is enable is already " + enable + ", no need to change.");
+ }
+
+ }
}
diff --git a/tests/componenttests/src/com/android/settings/testutils/UiUtils.java b/tests/componenttests/src/com/android/settings/testutils/UiUtils.java
index 481a7b2..d58dced 100644
--- a/tests/componenttests/src/com/android/settings/testutils/UiUtils.java
+++ b/tests/componenttests/src/com/android/settings/testutils/UiUtils.java
@@ -32,7 +32,7 @@
public class UiUtils {
private static final String TAG = "UI_UTILS";
- public static void waitUntilCondition(long timeoutInMillis, Supplier<Boolean> condition) {
+ public static boolean waitUntilCondition(long timeoutInMillis, Supplier<Boolean> condition) {
long start = System.nanoTime();
while (System.nanoTime() - start < (timeoutInMillis * 1000000)) {
try {
@@ -40,17 +40,14 @@
//findViewById when the view hierarchy is still rendering, it sometimes encounter
//null views that may exist few milliseconds before, and causes a NPE.
if (condition.get()) {
- return;
+ return true;
}
} catch (NullPointerException e) {
e.printStackTrace();
}
}
- if (System.nanoTime() - start >= (timeoutInMillis * 1000000)) {
- Log.w(TAG, "Condition not match and timeout for waiting " + timeoutInMillis + "(ms).");
- } else {
- Log.d(TAG, "Condition matched.");
- }
+ Log.w(TAG, "Condition not match and timeout for waiting " + timeoutInMillis + "(ms).");
+ return false;
}
public static boolean waitForActivitiesInStage(long timeoutInMillis, Stage stage) {
diff --git a/tests/componenttests/src/com/android/settings/users/UserSettingsComponentTest.java b/tests/componenttests/src/com/android/settings/users/UserSettingsComponentTest.java
new file mode 100644
index 0000000..b0735fb
--- /dev/null
+++ b/tests/componenttests/src/com/android/settings/users/UserSettingsComponentTest.java
@@ -0,0 +1,141 @@
+/*
+ * 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.
+ */
+
+package com.android.settings.users;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.app.Instrumentation;
+import android.content.Intent;
+import android.content.pm.UserInfo;
+import android.os.UserManager;
+import android.util.Log;
+
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentActivity;
+import androidx.test.core.app.ActivityScenario;
+import androidx.test.ext.junit.rules.ActivityScenarioRule;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.settings.Settings;
+import com.android.settings.testutils.AdbUtils;
+import com.android.settings.testutils.UiUtils;
+import com.android.settingslib.utils.ThreadUtils;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Random;
+import java.util.stream.Collectors;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class UserSettingsComponentTest {
+ public static final int TIMEOUT = 2000;
+ private static final int USER_TYPE_RESTRICTED_PROFILE = 2;
+ public final String TAG = this.getClass().getName();
+ private final Instrumentation mInstrumentation = InstrumentationRegistry.getInstrumentation();
+ private final ArrayList<Integer> mOriginUserIds = new ArrayList<>();
+ private final UserManager mUserManager =
+ (UserManager) mInstrumentation.getTargetContext().getSystemService("user");
+ @Rule
+ public ActivityScenarioRule<Settings.UserSettingsActivity>
+ rule = new ActivityScenarioRule<>(
+ new Intent(android.provider.Settings.ACTION_USER_SETTINGS)
+ .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
+
+ @Before
+ public void setUp() {
+ for (UserInfo info : mUserManager.getUsers()) {
+ mOriginUserIds.add(info.id);
+ }
+
+ // Enable multiple user switch.
+ if (!mUserManager.isUserSwitcherEnabled()) {
+ android.provider.Settings.Global.putInt(
+ mInstrumentation.getTargetContext().getContentResolver(),
+ android.provider.Settings.Global.USER_SWITCHER_ENABLED, 1);
+ }
+ }
+
+ @Test
+ public void test_new_user_on_multiple_setting_page() throws IOException {
+ String randomUserName = gendrate_random_name(10);
+ ActivityScenario scenario = rule.getScenario();
+ scenario.onActivity(activity -> {
+ Fragment f =
+ ((FragmentActivity) activity).getSupportFragmentManager().getFragments().get(0);
+ UserSettings us = (UserSettings) f;
+ Log.d(TAG, "Start to add user :" + randomUserName);
+ ThreadUtils.postOnBackgroundThread(
+ us.new AddUserNowImpl(USER_TYPE_RESTRICTED_PROFILE, randomUserName));
+ });
+
+ assertThat(
+ UiUtils.waitUntilCondition(5000, () -> mUserManager.getAliveUsers().stream().filter(
+ (user) -> user.name.equals(
+ randomUserName)).findFirst().isPresent())).isTrue();
+ }
+
+ @After
+ public void tearDown() {
+ int retryNumber = 5;
+ for (int i = 0; i < retryNumber; ++i) {
+ int currentUsersCount = mUserManager.getUserCount();
+ if (currentUsersCount == mOriginUserIds.size()) {
+ break;
+ } else if (i != 0) {
+ Log.d(TAG, "[tearDown] User not fully removed. Retry #" + (i = 1) + " of total "
+ + mOriginUserIds.size());
+ }
+
+ for (UserInfo info : mUserManager.getUsers()) {
+ if (mOriginUserIds.contains(info.id)) {
+ continue;
+ }
+ Log.d(TAG, "[tearDown] Clean up user {" + info.id + "}:" + info.name);
+ try {
+ AdbUtils.shell("pm remove-user " + info.id);
+ } catch (Exception e) {
+ Log.w(TAG, "[tearDown] Error occurs while removing user. " + e.toString());
+ }
+ }
+ }
+ }
+
+ private String gendrate_random_name(int length) {
+ String seed = "abcdefghijklmnopqrstuvwxyABCDEFGHIJKLMNOPQSTUVWXYZ";
+ Random r1 = new Random();
+ String result = "";
+ for (int i = 0; i < length; ++i) {
+ result = result + seed.charAt(r1.nextInt(seed.length() - 1));
+ }
+ if (mUserManager.getAliveUsers().stream().map(user -> user.name).collect(
+ Collectors.toList()).contains(result)) {
+ Log.d(TAG, "Name repeated! add padding 'rpt' in the end of name.");
+ result += "rpt";
+ }
+ return result;
+ }
+
+}
diff --git a/tests/robotests/src/com/android/settings/development/tare/OWNERS b/tests/robotests/src/com/android/settings/development/tare/OWNERS
new file mode 100644
index 0000000..46d25c8
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/development/tare/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 330055
+
+include platform/frameworks/base:/apex/jobscheduler/service/java/com/android/server/tare/OWNERS
\ No newline at end of file
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/robotests/src/com/android/settings/deviceinfo/hardwareinfo/HardwareRevisionPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/hardwareinfo/HardwareRevisionPreferenceControllerTest.java
deleted file mode 100644
index d705b64..0000000
--- a/tests/robotests/src/com/android/settings/deviceinfo/hardwareinfo/HardwareRevisionPreferenceControllerTest.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2019 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.hardwareinfo;
-
-import static android.content.Context.CLIPBOARD_SERVICE;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.content.ClipboardManager;
-import android.content.Context;
-import android.os.SystemProperties;
-
-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;
-
-@RunWith(RobolectricTestRunner.class)
-public class HardwareRevisionPreferenceControllerTest {
-
- private Context mContext;
- private HardwareRevisionPreferenceController mController;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
- mContext = RuntimeEnvironment.application;
- mController = new HardwareRevisionPreferenceController(mContext,
- "hardware_info_device_revision");
- }
-
- @Test
- public void copy_shouldCopyHardwareRevisionToClipboard() {
- final String fakeHardwareVer = "FakeVer1.0";
- SystemProperties.set("ro.boot.hardware.revision", fakeHardwareVer);
-
- mController.copy();
-
- final ClipboardManager clipboard = (ClipboardManager) mContext.getSystemService(
- CLIPBOARD_SERVICE);
- final CharSequence data = clipboard.getPrimaryClip().getItemAt(0).getText();
-
- assertThat(data.toString()).isEqualTo(fakeHardwareVer);
- }
-}
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/hardwareinfo/SerialNumberPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/hardwareinfo/SerialNumberPreferenceControllerTest.java
deleted file mode 100644
index 2106b54..0000000
--- a/tests/robotests/src/com/android/settings/deviceinfo/hardwareinfo/SerialNumberPreferenceControllerTest.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2019 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.hardwareinfo;
-
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.content.ClipData;
-import android.content.ClipboardManager;
-import android.content.Context;
-import android.os.Build;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-
-@RunWith(RobolectricTestRunner.class)
-public class SerialNumberPreferenceControllerTest {
-
- private Context mContext;
- private SerialNumberPreferenceController mController;
-
- @Before
- public void setUp() {
- mContext = RuntimeEnvironment.application;
- mController = new SerialNumberPreferenceController(mContext, "test");
- }
-
- @Test
- public void copy_shouldPutSerialNumberToClipBoard() {
- mController.copy();
-
- final ClipboardManager clipboardManager = mContext.getSystemService(ClipboardManager.class);
- final ClipData data = clipboardManager.getPrimaryClip();
-
- assertThat(data.getItemAt(0).getText().toString()).contains(Build.getSerial());
- }
-}
diff --git a/tests/robotests/src/com/android/settings/network/NetworkProviderSettingsTest.java b/tests/robotests/src/com/android/settings/network/NetworkProviderSettingsTest.java
index 47cd87c..7592c35 100644
--- a/tests/robotests/src/com/android/settings/network/NetworkProviderSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/network/NetworkProviderSettingsTest.java
@@ -64,10 +64,10 @@
import com.android.settings.testutils.shadow.ShadowFragment;
import com.android.settings.wifi.AddWifiNetworkPreference;
import com.android.settings.wifi.ConnectedWifiEntryPreference;
+import com.android.settings.wifi.LongPressWifiEntryPreference;
import com.android.settings.wifi.WifiConfigController2;
import com.android.settings.wifi.WifiDialog2;
import com.android.settingslib.widget.LayoutPreference;
-import com.android.settingslib.wifi.LongPressWifiEntryPreference;
import com.android.wifitrackerlib.WifiEntry;
import com.android.wifitrackerlib.WifiPickerTracker;
diff --git a/tests/robotests/src/com/android/settings/network/WifiConnectionPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/WifiConnectionPreferenceControllerTest.java
index ea957c3..038a292 100644
--- a/tests/robotests/src/com/android/settings/network/WifiConnectionPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/network/WifiConnectionPreferenceControllerTest.java
@@ -34,8 +34,8 @@
import androidx.preference.PreferenceScreen;
import com.android.settings.wifi.WifiConnectionPreferenceController;
+import com.android.settings.wifi.WifiEntryPreference;
import com.android.settingslib.core.lifecycle.Lifecycle;
-import com.android.settingslib.wifi.WifiEntryPreference;
import com.android.wifitrackerlib.WifiEntry;
import com.android.wifitrackerlib.WifiPickerTracker;
diff --git a/tests/robotests/src/com/android/settings/network/telephony/NetworkSelectSettingsTest.java b/tests/robotests/src/com/android/settings/network/telephony/NetworkSelectSettingsTest.java
deleted file mode 100644
index 6bee38f..0000000
--- a/tests/robotests/src/com/android/settings/network/telephony/NetworkSelectSettingsTest.java
+++ /dev/null
@@ -1,122 +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.network.telephony;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.telephony.CellIdentityLte;
-import android.telephony.CellIdentityWcdma;
-import android.telephony.CellInfoLte;
-import android.telephony.CellInfoWcdma;
-import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyManager;
-
-import androidx.preference.PreferenceCategory;
-import androidx.preference.PreferenceManager;
-
-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 java.util.Arrays;
-
-@RunWith(RobolectricTestRunner.class)
-public class NetworkSelectSettingsTest {
- private static final int SUB_ID = 2;
- private static final String CARRIER_NAME1 = "CarrierName1";
- private static final String CARRIER_NAME2 = "CarrierName2";
-
- @Mock
- private TelephonyManager mTelephonyManager;
- @Mock
- private SubscriptionManager mSubscriptionManager;
- @Mock
- private CellInfoWcdma mCellInfo1;
- @Mock
- private CellIdentityWcdma mCellId1;
- @Mock
- private CellInfoLte mCellInfo2;
- @Mock
- private CellIdentityLte mCellId2;
- @Mock
- private PreferenceManager mPreferenceManager;
- @Mock
- private SharedPreferences mSharedPreferences;
- private Context mContext;
-
- private PreferenceCategory mPreferenceCategory;
-
- private NetworkSelectSettings mNetworkSelectSettings;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
-
- mContext = spy(RuntimeEnvironment.application);
- when(mContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager);
- when(mContext.getSystemService(SubscriptionManager.class)).thenReturn(mSubscriptionManager);
- when(mTelephonyManager.createForSubscriptionId(SUB_ID)).thenReturn(mTelephonyManager);
-
- when(mCellInfo1.isRegistered()).thenReturn(true);
- when(mCellInfo1.getCellIdentity()).thenReturn(mCellId1);
- when(mCellId1.getOperatorAlphaLong()).thenReturn(CARRIER_NAME1);
- when(mCellInfo2.isRegistered()).thenReturn(false);
- when(mCellInfo2.getCellIdentity()).thenReturn(mCellId2);
- when(mCellId2.getOperatorAlphaLong()).thenReturn(CARRIER_NAME2);
-
- doReturn(mSharedPreferences).when(mPreferenceManager).getSharedPreferences();
- mPreferenceCategory = spy(new PreferenceCategory(mContext));
- doReturn(mPreferenceManager).when(mPreferenceCategory).getPreferenceManager();
-
- mNetworkSelectSettings = spy(new NetworkSelectSettings());
- doReturn(mContext).when(mNetworkSelectSettings).getContext();
- doReturn(mPreferenceManager).when(mNetworkSelectSettings).getPreferenceManager();
- doReturn(mContext).when(mPreferenceManager).getContext();
-
- mNetworkSelectSettings.mTelephonyManager = mTelephonyManager;
- mNetworkSelectSettings.mPreferenceCategory = mPreferenceCategory;
- mNetworkSelectSettings.mCellInfoList = Arrays.asList(mCellInfo1, mCellInfo2);
- }
-
- @Test
- public void updateAllPreferenceCategory_correctOrderingPreference() {
- mNetworkSelectSettings.updateAllPreferenceCategory();
-
- assertThat(mPreferenceCategory.getPreferenceCount()).isEqualTo(2);
- final NetworkOperatorPreference preference =
- (NetworkOperatorPreference) mPreferenceCategory.getPreference(1);
- assertThat(preference.getOperatorName()).isEqualTo(mCellId2.getOperatorAlphaLong());
- }
-
- @Test
- public void updateForbiddenPlmns_forbiddenPlmnsNull_shouldNotCrash() {
- when(mTelephonyManager.getForbiddenPlmns()).thenReturn(null);
-
- // Should not Crash
- mNetworkSelectSettings.updateForbiddenPlmns();
- }
-}
diff --git a/tests/robotests/src/com/android/settings/wifi/WifiEntryPreferenceTest.java b/tests/robotests/src/com/android/settings/wifi/WifiEntryPreferenceTest.java
new file mode 100644
index 0000000..ce1b46a
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/wifi/WifiEntryPreferenceTest.java
@@ -0,0 +1,255 @@
+/*
+ * 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.
+ */
+package com.android.settings.wifi;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.LinearLayout;
+
+import androidx.preference.PreferenceViewHolder;
+
+import com.android.settingslib.R;
+import com.android.wifitrackerlib.WifiEntry;
+
+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 java.util.ArrayList;
+import java.util.List;
+
+@RunWith(RobolectricTestRunner.class)
+public class WifiEntryPreferenceTest {
+
+ private Context mContext;
+
+ @Mock
+ private WifiEntry mMockWifiEntry;
+ @Mock
+ private WifiEntryPreference.IconInjector mMockIconInjector;
+
+ @Mock
+ private Drawable mMockDrawable0;
+ @Mock
+ private Drawable mMockDrawable1;
+ @Mock
+ private Drawable mMockDrawable2;
+ @Mock
+ private Drawable mMockDrawable3;
+ @Mock
+ private Drawable mMockDrawable4;
+
+ @Mock
+ private Drawable mMockShowXDrawable0;
+ @Mock
+ private Drawable mMockShowXDrawable1;
+ @Mock
+ private Drawable mMockShowXDrawable2;
+ @Mock
+ private Drawable mMockShowXDrawable3;
+ @Mock
+ private Drawable mMockShowXDrawable4;
+
+ private static final String MOCK_TITLE = "title";
+ private static final String MOCK_SUMMARY = "summary";
+ private static final String FAKE_URI_STRING = "fakeuri";
+
+ @Before
+ public void setUp() {
+ mContext = RuntimeEnvironment.application;
+
+ MockitoAnnotations.initMocks(this);
+
+ when(mMockWifiEntry.getTitle()).thenReturn(MOCK_TITLE);
+ when(mMockWifiEntry.getSummary(false /* concise */)).thenReturn(MOCK_SUMMARY);
+
+ when(mMockIconInjector.getIcon(false /* showX */, 0)).thenReturn(mMockDrawable0);
+ when(mMockIconInjector.getIcon(false /* showX */, 1)).thenReturn(mMockDrawable1);
+ when(mMockIconInjector.getIcon(false /* showX */, 2)).thenReturn(mMockDrawable2);
+ when(mMockIconInjector.getIcon(false /* showX */, 3)).thenReturn(mMockDrawable3);
+ when(mMockIconInjector.getIcon(false /* showX */, 4)).thenReturn(mMockDrawable4);
+
+ when(mMockIconInjector.getIcon(true /* showX */, 0))
+ .thenReturn(mMockShowXDrawable0);
+ when(mMockIconInjector.getIcon(true /* showX */, 1))
+ .thenReturn(mMockShowXDrawable1);
+ when(mMockIconInjector.getIcon(true /* showX */, 2))
+ .thenReturn(mMockShowXDrawable2);
+ when(mMockIconInjector.getIcon(true /* showX */, 3))
+ .thenReturn(mMockShowXDrawable3);
+ when(mMockIconInjector.getIcon(true /* showX */, 4))
+ .thenReturn(mMockShowXDrawable4);
+ }
+
+ @Test
+ public void constructor_shouldSetWifiEntryTitleAndSummary() {
+ final WifiEntryPreference pref =
+ new WifiEntryPreference(mContext, mMockWifiEntry, mMockIconInjector);
+
+ assertThat(pref.getTitle()).isEqualTo(MOCK_TITLE);
+ assertThat(pref.getSummary()).isEqualTo(MOCK_SUMMARY);
+ assertThat(false).isTrue();
+ }
+
+ @Test
+ public void constructor_shouldSetIcon() {
+ when(mMockWifiEntry.getLevel()).thenReturn(0);
+
+ final WifiEntryPreference pref =
+ new WifiEntryPreference(mContext, mMockWifiEntry, mMockIconInjector);
+
+ assertThat(pref.getIcon()).isEqualTo(mMockDrawable0);
+ }
+
+ @Test
+ public void titleChanged_refresh_shouldUpdateTitle() {
+ final WifiEntryPreference pref =
+ new WifiEntryPreference(mContext, mMockWifiEntry, mMockIconInjector);
+ final String updatedTitle = "updated title";
+ when(mMockWifiEntry.getTitle()).thenReturn(updatedTitle);
+
+ pref.refresh();
+
+ assertThat(pref.getTitle()).isEqualTo(updatedTitle);
+ }
+
+ @Test
+ public void summaryChanged_refresh_shouldUpdateSummary() {
+ final WifiEntryPreference pref =
+ new WifiEntryPreference(mContext, mMockWifiEntry, mMockIconInjector);
+ final String updatedSummary = "updated summary";
+ when(mMockWifiEntry.getSummary(false /* concise */)).thenReturn(updatedSummary);
+
+ pref.refresh();
+
+ assertThat(pref.getSummary()).isEqualTo(updatedSummary);
+ }
+
+ @Test
+ public void levelChanged_refresh_shouldUpdateLevelIcon() {
+ final List<Drawable> iconList = new ArrayList<>();
+ final WifiEntryPreference pref =
+ new WifiEntryPreference(mContext, mMockWifiEntry, mMockIconInjector);
+
+ when(mMockWifiEntry.getLevel()).thenReturn(0);
+ pref.refresh();
+ iconList.add(pref.getIcon());
+ when(mMockWifiEntry.getLevel()).thenReturn(1);
+ pref.refresh();
+ iconList.add(pref.getIcon());
+ when(mMockWifiEntry.getLevel()).thenReturn(2);
+ pref.refresh();
+ iconList.add(pref.getIcon());
+ when(mMockWifiEntry.getLevel()).thenReturn(3);
+ pref.refresh();
+ iconList.add(pref.getIcon());
+ when(mMockWifiEntry.getLevel()).thenReturn(4);
+ pref.refresh();
+ iconList.add(pref.getIcon());
+ when(mMockWifiEntry.getLevel()).thenReturn(-1);
+ pref.refresh();
+ iconList.add(pref.getIcon());
+
+ assertThat(iconList).containsExactly(mMockDrawable0, mMockDrawable1,
+ mMockDrawable2, mMockDrawable3, mMockDrawable4, null);
+ }
+
+ @Test
+ public void levelChanged_showXWifiRefresh_shouldUpdateLevelIcon() {
+ final List<Drawable> iconList = new ArrayList<>();
+ when(mMockWifiEntry.shouldShowXLevelIcon()).thenReturn(true);
+ final WifiEntryPreference pref =
+ new WifiEntryPreference(mContext, mMockWifiEntry, mMockIconInjector);
+
+ when(mMockWifiEntry.getLevel()).thenReturn(0);
+ pref.refresh();
+ iconList.add(pref.getIcon());
+ when(mMockWifiEntry.getLevel()).thenReturn(1);
+ pref.refresh();
+ iconList.add(pref.getIcon());
+ when(mMockWifiEntry.getLevel()).thenReturn(2);
+ pref.refresh();
+ iconList.add(pref.getIcon());
+ when(mMockWifiEntry.getLevel()).thenReturn(3);
+ pref.refresh();
+ iconList.add(pref.getIcon());
+ when(mMockWifiEntry.getLevel()).thenReturn(4);
+ pref.refresh();
+ iconList.add(pref.getIcon());
+ when(mMockWifiEntry.getLevel()).thenReturn(-1);
+ pref.refresh();
+ iconList.add(pref.getIcon());
+
+ assertThat(iconList).containsExactly(mMockShowXDrawable0, mMockShowXDrawable1,
+ mMockShowXDrawable2, mMockShowXDrawable3, mMockShowXDrawable4, null);
+ }
+
+ @Test
+ public void notNull_whenGetHelpUriString_shouldSetImageButtonVisible() {
+ when(mMockWifiEntry.getHelpUriString()).thenReturn(FAKE_URI_STRING);
+ final WifiEntryPreference pref =
+ new WifiEntryPreference(mContext, mMockWifiEntry, mMockIconInjector);
+ final LayoutInflater inflater = LayoutInflater.from(mContext);
+ final View view = inflater.inflate(pref.getLayoutResource(), new LinearLayout(mContext),
+ false);
+ final PreferenceViewHolder holder = PreferenceViewHolder.createInstanceForTests(view);
+
+ pref.onBindViewHolder(holder);
+
+ assertThat(view.findViewById(R.id.icon_button).getVisibility()).isEqualTo(View.VISIBLE);
+ }
+
+ @Test
+ public void helpButton_whenGetHelpUriStringNotNull_shouldSetCorrectContentDescription() {
+ when(mMockWifiEntry.getHelpUriString()).thenReturn(FAKE_URI_STRING);
+ final WifiEntryPreference pref =
+ new WifiEntryPreference(mContext, mMockWifiEntry, mMockIconInjector);
+ final LayoutInflater inflater = LayoutInflater.from(mContext);
+ final View view = inflater.inflate(pref.getLayoutResource(), new LinearLayout(mContext),
+ false);
+ final PreferenceViewHolder holder = PreferenceViewHolder.createInstanceForTests(view);
+
+ pref.onBindViewHolder(holder);
+
+ assertThat(view.findViewById(R.id.icon_button).getContentDescription()).isEqualTo(
+ mContext.getString(R.string.help_label));
+ }
+
+ @Test
+ public void subscriptionEntry_shouldSetImageButtonGone() {
+ when(mMockWifiEntry.isSubscription()).thenReturn(true);
+ final WifiEntryPreference pref =
+ new WifiEntryPreference(mContext, mMockWifiEntry, mMockIconInjector);
+ final LayoutInflater inflater = LayoutInflater.from(mContext);
+ final View view = inflater.inflate(pref.getLayoutResource(), new LinearLayout(mContext),
+ false);
+ final PreferenceViewHolder holder = PreferenceViewHolder.createInstanceForTests(view);
+
+ pref.onBindViewHolder(holder);
+
+ assertThat(view.findViewById(R.id.icon_button).getVisibility()).isEqualTo(View.GONE);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/wifi/WifiSettingsTest.java b/tests/robotests/src/com/android/settings/wifi/WifiSettingsTest.java
index 1f5abd3..c124c59 100644
--- a/tests/robotests/src/com/android/settings/wifi/WifiSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/WifiSettingsTest.java
@@ -57,7 +57,6 @@
import com.android.settings.datausage.DataUsagePreference;
import com.android.settings.testutils.shadow.ShadowDataUsageUtils;
import com.android.settings.testutils.shadow.ShadowFragment;
-import com.android.settingslib.wifi.LongPressWifiEntryPreference;
import com.android.wifitrackerlib.WifiEntry;
import com.android.wifitrackerlib.WifiPickerTracker;
diff --git a/tests/robotests/src/com/android/settings/wifi/dpp/WifiNetworkListFragmentTest.java b/tests/robotests/src/com/android/settings/wifi/dpp/WifiNetworkListFragmentTest.java
index 70f2b1a..e78f1c1 100644
--- a/tests/robotests/src/com/android/settings/wifi/dpp/WifiNetworkListFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/dpp/WifiNetworkListFragmentTest.java
@@ -36,7 +36,7 @@
import androidx.preference.PreferenceCategory;
import androidx.test.InstrumentationRegistry;
-import com.android.settingslib.wifi.WifiEntryPreference;
+import com.android.settings.wifi.WifiEntryPreference;
import com.android.wifitrackerlib.SavedNetworkTracker;
import com.android.wifitrackerlib.WifiEntry;
diff --git a/tests/robotests/src/com/android/settings/wifi/savedaccesspoints2/SavedAccessPointsPreferenceController2Test.java b/tests/robotests/src/com/android/settings/wifi/savedaccesspoints2/SavedAccessPointsPreferenceController2Test.java
index 7b7a3b1..0d10223 100644
--- a/tests/robotests/src/com/android/settings/wifi/savedaccesspoints2/SavedAccessPointsPreferenceController2Test.java
+++ b/tests/robotests/src/com/android/settings/wifi/savedaccesspoints2/SavedAccessPointsPreferenceController2Test.java
@@ -35,7 +35,7 @@
import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceScreen;
-import com.android.settingslib.wifi.WifiEntryPreference;
+import com.android.settings.wifi.WifiEntryPreference;
import com.android.wifitrackerlib.WifiEntry;
import org.junit.Before;
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/PhoneNumberPreferenceControllerTest.java b/tests/unit/src/com/android/settings/deviceinfo/PhoneNumberPreferenceControllerTest.java
similarity index 71%
rename from tests/robotests/src/com/android/settings/deviceinfo/PhoneNumberPreferenceControllerTest.java
rename to tests/unit/src/com/android/settings/deviceinfo/PhoneNumberPreferenceControllerTest.java
index 9bb2d3f..2a06ce9 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/PhoneNumberPreferenceControllerTest.java
+++ b/tests/unit/src/com/android/settings/deviceinfo/PhoneNumberPreferenceControllerTest.java
@@ -21,38 +21,43 @@
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
+import android.os.Looper;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import androidx.preference.Preference;
+import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;
+import androidx.test.annotation.UiThreadTest;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
-import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
+import com.android.settings.testutils.ResourcesUtils;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import java.util.ArrayList;
import java.util.List;
-@RunWith(RobolectricTestRunner.class)
+@RunWith(AndroidJUnit4.class)
public class PhoneNumberPreferenceControllerTest {
- @Mock
private Preference mPreference;
@Mock
private Preference mSecondPreference;
@@ -62,25 +67,34 @@
private SubscriptionInfo mSubscriptionInfo;
@Mock
private SubscriptionManager mSubscriptionManager;
- @Mock
private PreferenceScreen mScreen;
private Context mContext;
private PhoneNumberPreferenceController mController;
+ private ClipboardManager mClipboardManager;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
- mContext = spy(RuntimeEnvironment.application);
+ mContext = spy(ApplicationProvider.getApplicationContext());
+ mClipboardManager = (ClipboardManager) spy(mContext.getSystemService(CLIPBOARD_SERVICE));
+ doReturn(mClipboardManager).when(mContext).getSystemService(CLIPBOARD_SERVICE);
when(mContext.getSystemService(SubscriptionManager.class)).thenReturn(mSubscriptionManager);
when(mContext.getSystemService(TelephonyManager.class)).thenReturn(mTelephonyManager);
mController = spy(new PhoneNumberPreferenceController(mContext, "phone_number"));
- final String prefKey = mController.getPreferenceKey();
- when(mScreen.findPreference(prefKey)).thenReturn(mPreference);
- when(mScreen.getContext()).thenReturn(mContext);
+
+ if (Looper.myLooper() == null) {
+ Looper.prepare();
+ }
+ final PreferenceManager preferenceManager = new PreferenceManager(mContext);
+ mScreen = preferenceManager.createPreferenceScreen(mContext);
+ mPreference = spy(new Preference(mContext));
+ mPreference.setKey(mController.getPreferenceKey());
+ mPreference.setVisible(true);
+ mScreen.addPreference(mPreference);
+
doReturn(mSubscriptionInfo).when(mController).getSubscriptionInfo(anyInt());
doReturn(mSecondPreference).when(mController).createNewPreference(mContext);
- when(mPreference.isVisible()).thenReturn(true);
}
@Test
@@ -105,7 +119,7 @@
mController.displayPreference(mScreen);
- verify(mScreen).addPreference(mSecondPreference);
+ assertThat(mScreen.getPreferenceCount()).isEqualTo(2);
}
@Test
@@ -117,7 +131,7 @@
mController.updateState(mPreference);
- verify(mPreference).setTitle(mContext.getString(R.string.status_number));
+ verify(mPreference).setTitle(ResourcesUtils.getResourcesString(mContext, "status_number"));
verify(mPreference).setSummary(phoneNumber);
}
@@ -130,11 +144,11 @@
mController.updateState(mPreference);
- verify(mPreference).setTitle(
- mContext.getString(R.string.status_number_sim_slot, 1 /* sim slot */));
+ verify(mPreference).setTitle(ResourcesUtils.getResourcesString(
+ mContext, "status_number_sim_slot", 1 /* sim slot */));
verify(mPreference).setSummary(phoneNumber);
- verify(mSecondPreference).setTitle(
- mContext.getString(R.string.status_number_sim_slot, 2 /* sim slot */));
+ verify(mSecondPreference).setTitle(ResourcesUtils.getResourcesString(
+ mContext, "status_number_sim_slot", 2 /* sim slot */));
verify(mSecondPreference).setSummary(phoneNumber);
}
@@ -145,7 +159,8 @@
CharSequence primaryNumber = mController.getSummary();
assertThat(primaryNumber).isNotNull();
- assertThat(primaryNumber).isEqualTo(mContext.getString(R.string.device_info_default));
+ assertThat(primaryNumber).isEqualTo(ResourcesUtils.getResourcesString(
+ mContext, "device_info_default"));
}
@Test
@@ -155,22 +170,24 @@
CharSequence primaryNumber = mController.getSummary();
- assertThat(primaryNumber).isEqualTo(mContext.getString(R.string.device_info_default));
+ assertThat(primaryNumber).isEqualTo(ResourcesUtils.getResourcesString(
+ mContext, "device_info_default"));
}
@Test
+ @UiThreadTest
public void copy_shouldCopyPhoneNumberToClipboard() {
final List<SubscriptionInfo> list = new ArrayList<>();
list.add(mSubscriptionInfo);
when(mSubscriptionManager.getActiveSubscriptionInfoList()).thenReturn(list);
final String phoneNumber = "1111111111";
doReturn(phoneNumber).when(mController).getFormattedPhoneNumber(mSubscriptionInfo);
+ 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();
+ final CharSequence data = captor.getValue().getItemAt(0).getText();
assertThat(phoneNumber.contentEquals(data)).isTrue();
}
}
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/hardwareinfo/DeviceModelPreferenceControllerTest.java b/tests/unit/src/com/android/settings/deviceinfo/hardwareinfo/DeviceModelPreferenceControllerTest.java
similarity index 66%
rename from tests/robotests/src/com/android/settings/deviceinfo/hardwareinfo/DeviceModelPreferenceControllerTest.java
rename to tests/unit/src/com/android/settings/deviceinfo/hardwareinfo/DeviceModelPreferenceControllerTest.java
index 65e29b4..847919a 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/hardwareinfo/DeviceModelPreferenceControllerTest.java
+++ b/tests/unit/src/com/android/settings/deviceinfo/hardwareinfo/DeviceModelPreferenceControllerTest.java
@@ -18,41 +18,57 @@
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 androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.settings.core.BasePreferenceController;
+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 DeviceModelPreferenceControllerTest {
private Context mContext;
private DeviceModelPreferenceController mController;
+ @Mock
+ private Resources mResources;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- mContext = RuntimeEnvironment.application;
+ mContext = spy(ApplicationProvider.getApplicationContext());
+ when(mContext.getResources()).thenReturn(mResources);
mController = new DeviceModelPreferenceController(mContext, "test_key");
}
@Test
public void getAvailabilityStatus_configAllowed_available() {
+ 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 getAvailabilityStatus_configDisallowed_unavailable() {
+ 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);
}
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);
}
diff --git a/tests/unit/src/com/android/settings/deviceinfo/hardwareinfo/HardwareRevisionPreferenceControllerTest.java b/tests/unit/src/com/android/settings/deviceinfo/hardwareinfo/HardwareRevisionPreferenceControllerTest.java
new file mode 100644
index 0000000..fc1407f
--- /dev/null
+++ b/tests/unit/src/com/android/settings/deviceinfo/hardwareinfo/HardwareRevisionPreferenceControllerTest.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2019 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.hardwareinfo;
+
+import static android.content.Context.CLIPBOARD_SERVICE;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+
+import android.content.ClipData;
+import android.content.ClipboardManager;
+import android.content.Context;
+import android.os.Looper;
+import android.os.SystemProperties;
+
+import androidx.test.annotation.UiThreadTest;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+
+@RunWith(AndroidJUnit4.class)
+public class HardwareRevisionPreferenceControllerTest {
+
+ private Context mContext;
+ private HardwareRevisionPreferenceController mController;
+ private ClipboardManager mClipboardManager;
+
+ @Before
+ public void setUp() {
+ if (Looper.myLooper() == null) {
+ Looper.prepare();
+ }
+ mContext = spy(ApplicationProvider.getApplicationContext());
+ mClipboardManager = (ClipboardManager) spy(mContext.getSystemService(CLIPBOARD_SERVICE));
+ doReturn(mClipboardManager).when(mContext).getSystemService(CLIPBOARD_SERVICE);
+ mController = new HardwareRevisionPreferenceController(mContext,
+ "hardware_info_device_revision");
+ }
+
+ @Test
+ @UiThreadTest
+ public void copy_shouldCopyHardwareRevisionToClipboard() {
+ ArgumentCaptor<ClipData> captor = ArgumentCaptor.forClass(ClipData.class);
+ doNothing().when(mClipboardManager).setPrimaryClip(captor.capture());
+
+ mController.copy();
+
+ final ClipData data = captor.getValue();
+ final String hardwareVer = SystemProperties.get("ro.boot.hardware.revision");
+ assertThat(data.getItemAt(0).getText().toString()).isEqualTo(hardwareVer);
+ }
+}
diff --git a/tests/unit/src/com/android/settings/deviceinfo/hardwareinfo/SerialNumberPreferenceControllerTest.java b/tests/unit/src/com/android/settings/deviceinfo/hardwareinfo/SerialNumberPreferenceControllerTest.java
new file mode 100644
index 0000000..eaf97d4
--- /dev/null
+++ b/tests/unit/src/com/android/settings/deviceinfo/hardwareinfo/SerialNumberPreferenceControllerTest.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2019 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.hardwareinfo;
+
+import static android.content.Context.CLIPBOARD_SERVICE;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+
+import android.content.ClipData;
+import android.content.ClipboardManager;
+import android.content.Context;
+import android.os.Build;
+import android.os.Looper;
+
+import androidx.test.annotation.UiThreadTest;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+
+@RunWith(AndroidJUnit4.class)
+public class SerialNumberPreferenceControllerTest {
+
+ private Context mContext;
+ private SerialNumberPreferenceController mController;
+ private ClipboardManager mClipboardManager;
+
+ @Before
+ public void setUp() {
+ if (Looper.myLooper() == null) {
+ Looper.prepare();
+ }
+ mContext = spy(ApplicationProvider.getApplicationContext());
+ mClipboardManager = (ClipboardManager) spy(mContext.getSystemService(CLIPBOARD_SERVICE));
+ doReturn(mClipboardManager).when(mContext).getSystemService(CLIPBOARD_SERVICE);
+ mController = new SerialNumberPreferenceController(mContext, "test");
+ }
+
+ @Test
+ @UiThreadTest
+ public void copy_shouldPutSerialNumberToClipBoard() {
+ ArgumentCaptor<ClipData> captor = ArgumentCaptor.forClass(ClipData.class);
+ doNothing().when(mClipboardManager).setPrimaryClip(captor.capture());
+
+ mController.copy();
+
+ final ClipData data = captor.getValue();
+ assertThat(data.getItemAt(0).getText().toString()).contains(Build.getSerial());
+ }
+}
diff --git a/tests/unit/src/com/android/settings/network/telephony/NetworkSelectSettingsTest.java b/tests/unit/src/com/android/settings/network/telephony/NetworkSelectSettingsTest.java
new file mode 100644
index 0000000..8172e1a
--- /dev/null
+++ b/tests/unit/src/com/android/settings/network/telephony/NetworkSelectSettingsTest.java
@@ -0,0 +1,198 @@
+/*
+ * 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.
+ */
+package com.android.settings.network.telephony;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.os.Bundle;
+import android.os.PersistableBundle;
+import android.provider.Settings;
+import android.telephony.CarrierConfigManager;
+import android.telephony.CellIdentity;
+import android.telephony.CellInfo;
+import android.telephony.TelephonyManager;
+
+import androidx.preference.PreferenceCategory;
+import androidx.preference.PreferenceManager;
+import androidx.preference.PreferenceScreen;
+import androidx.test.annotation.UiThreadTest;
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.Arrays;
+
+public class NetworkSelectSettingsTest {
+ private static final int SUB_ID = 2;
+ private static final String CARRIER_NAME1 = "CarrierName1";
+ private static final String CARRIER_NAME2 = "CarrierName2";
+
+ @Mock
+ public Resources mResources;
+ @Mock
+ public TelephonyManager mTelephonyManager;
+ @Mock
+ public CarrierConfigManager mCarrierConfigManager;
+ @Mock
+ public MetricsFeatureProvider mMetricsFeatureProvider;
+ @Mock
+ public NetworkOperatorPreference mNetworkOperatorPreference1;
+ @Mock
+ public NetworkOperatorPreference mNetworkOperatorPreference2;
+ @Mock
+ private CellInfo mCellInfo1;
+ @Mock
+ private CellIdentity mCellId1;
+ @Mock
+ private CellInfo mCellInfo2;
+ @Mock
+ private CellIdentity mCellId2;
+
+ private PreferenceScreen mPreferenceScreen;
+ @Mock
+ public PreferenceManager mPreferenceManager;
+
+ public Context mContext;
+ public PreferenceCategory mPreferenceCategory;
+
+ private Bundle mInitArguments;
+ private TargetClass mNetworkSelectSettings;
+
+ @Before
+ @UiThreadTest
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+
+ mContext = spy(ApplicationProvider.getApplicationContext());
+ doReturn(mResources).when(mContext).getResources();
+ doReturn(mContext).when(mPreferenceManager).getContext();
+
+ mPreferenceCategory = spy(new PreferenceCategory(mContext));
+ doReturn(mPreferenceManager).when(mPreferenceCategory).getPreferenceManager();
+
+ doReturn(CARRIER_NAME1).when(mCellId1).getOperatorAlphaLong();
+ doReturn(CARRIER_NAME2).when(mCellId2).getOperatorAlphaLong();
+
+ mNetworkSelectSettings = spy(new TargetClass(this));
+
+ PersistableBundle config = new PersistableBundle();
+ config.putBoolean(CarrierConfigManager.KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL, true);
+ doReturn(config).when(mCarrierConfigManager).getConfigForSubId(SUB_ID);
+
+ doReturn(TelephonyManager.DATA_CONNECTED).when(mTelephonyManager).getDataState();
+ }
+
+ public class TargetClass extends NetworkSelectSettings {
+ private NetworkSelectSettingsTest mTestEnv;
+ private boolean mIsPreferenceScreenEnabled;
+
+ public TargetClass(NetworkSelectSettingsTest env) {
+ mTestEnv = env;
+
+ Bundle bundle = new Bundle();
+ bundle.putInt(Settings.EXTRA_SUB_ID, SUB_ID);
+ setArguments(bundle);
+ }
+
+ @Override
+ public Context getContext() {
+ return mTestEnv.mContext;
+ }
+
+ @Override
+ public PreferenceManager getPreferenceManager() {
+ return mTestEnv.mPreferenceManager;
+ }
+
+ @Override
+ protected PreferenceCategory getPreferenceCategory(String preferenceKey) {
+ return mTestEnv.mPreferenceCategory;
+ }
+
+ @Override
+ protected TelephonyManager getTelephonyManager(Context context, int subscriptionId) {
+ return mTestEnv.mTelephonyManager;
+ }
+
+ @Override
+ protected CarrierConfigManager getCarrierConfigManager(Context context) {
+ return mTestEnv.mCarrierConfigManager;
+ }
+
+ @Override
+ protected MetricsFeatureProvider getMetricsFeatureProvider(Context context) {
+ return mTestEnv.mMetricsFeatureProvider;
+ }
+
+ @Override
+ protected boolean isPreferenceScreenEnabled() {
+ return mIsPreferenceScreenEnabled;
+ }
+
+ @Override
+ protected void enablePreferenceScreen(boolean enable) {
+ mIsPreferenceScreenEnabled = enable;
+ }
+
+ @Override
+ protected NetworkOperatorPreference
+ createNetworkOperatorPreference(CellInfo cellInfo) {
+ NetworkOperatorPreference pref = super.createNetworkOperatorPreference(cellInfo);
+ if (cellInfo == mTestEnv.mCellInfo1) {
+ pref.updateCell(cellInfo, mTestEnv.mCellId1);
+ } else if (cellInfo == mTestEnv.mCellInfo2) {
+ pref.updateCell(cellInfo, mTestEnv.mCellId2);
+ }
+ return pref;
+ }
+ }
+
+ @Test
+ @UiThreadTest
+ public void updateAllPreferenceCategory_correctOrderingPreference() {
+ mNetworkSelectSettings.onCreateInitialization();
+ mNetworkSelectSettings.enablePreferenceScreen(true);
+ mNetworkSelectSettings.scanResultHandler(Arrays.asList(mCellInfo1, mCellInfo2));
+
+ assertThat(mPreferenceCategory.getPreferenceCount()).isEqualTo(2);
+ final NetworkOperatorPreference preference =
+ (NetworkOperatorPreference) mPreferenceCategory.getPreference(1);
+ assertThat(preference.getOperatorName()).isEqualTo(mCellId2.getOperatorAlphaLong());
+ }
+
+ @Test
+ @UiThreadTest
+ public void updateForbiddenPlmns_forbiddenPlmnsNull_shouldNotCrash() {
+ when(mTelephonyManager.getForbiddenPlmns()).thenReturn(null);
+
+ mNetworkSelectSettings.onCreateInitialization();
+ mNetworkSelectSettings.enablePreferenceScreen(true);
+
+ // Should not Crash
+ mNetworkSelectSettings.updateForbiddenPlmns();
+ }
+}
diff --git a/tests/unit/src/com/android/settings/vpn2/AppPreferenceTest.java b/tests/unit/src/com/android/settings/vpn2/AppPreferenceTest.java
new file mode 100644
index 0000000..1f618cc
--- /dev/null
+++ b/tests/unit/src/com/android/settings/vpn2/AppPreferenceTest.java
@@ -0,0 +1,81 @@
+/*
+ * 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.
+ */
+
+package com.android.settings.vpn2;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertFalse;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.Context;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.os.UserHandle;
+
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/** Unittest for AppPreference */
+@RunWith(AndroidJUnit4.class)
+public class AppPreferenceTest {
+ // Additional mocking of the underying classes is necsesary if another user id is used.
+ private static final int USER_ID = UserHandle.USER_NULL;
+ private static final String PACKAGE_NAME = "test_package";
+ private static final String DIFFERENT_PACKAGE_NAME = "not_test_package";
+
+ @Mock
+ private DevicePolicyManager mDevicePolicyManager;
+
+ private Context mContext;
+ private AppPreference mAppPreference;
+
+ @Before
+ public void setUp() throws NameNotFoundException {
+ MockitoAnnotations.initMocks(this);
+
+ mContext = spy(ApplicationProvider.getApplicationContext());
+ doReturn(mContext).when(mContext).createContextAsUser(any(), anyInt());
+ doReturn(mContext).when(mContext).createPackageContextAsUser(any(), anyInt(), any());
+ when(mContext.getSystemService(DevicePolicyManager.class)).thenReturn(mDevicePolicyManager);
+ }
+
+ @Test
+ public void getPackageName_returnsAccuratePackageName() {
+ doReturn(DIFFERENT_PACKAGE_NAME).when(mDevicePolicyManager).getAlwaysOnVpnPackage();
+
+ mAppPreference = spy(new AppPreference(mContext, USER_ID, PACKAGE_NAME));
+ assertThat(mAppPreference.getPackageName()).isEqualTo(PACKAGE_NAME);
+ }
+
+ @Test
+ public void disableIfConfiguredByAdmin_packageNameNotEqualsAlwaysOn_shouldEnable() {
+ doReturn(DIFFERENT_PACKAGE_NAME).when(mDevicePolicyManager).getAlwaysOnVpnPackage();
+
+ mAppPreference = spy(new AppPreference(mContext, USER_ID, PACKAGE_NAME));
+ assertFalse(mAppPreference.isDisabledByAdmin());
+ }
+}
diff --git a/tests/unit/src/com/android/settings/vpn2/LegacyVpnPreferenceTest.java b/tests/unit/src/com/android/settings/vpn2/LegacyVpnPreferenceTest.java
new file mode 100644
index 0000000..10077ad
--- /dev/null
+++ b/tests/unit/src/com/android/settings/vpn2/LegacyVpnPreferenceTest.java
@@ -0,0 +1,71 @@
+/*
+ * 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.
+ */
+
+package com.android.settings.vpn2;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.spy;
+
+import android.content.Context;
+import android.content.res.Resources.NotFoundException;
+
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import com.android.internal.net.VpnProfile;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/** Unittest for LegacyVpnPreference */
+@RunWith(AndroidJUnit4.class)
+public class LegacyVpnPreferenceTest {
+ private static final String PROFILE_KEY = "test_key";
+ private static final String PROFILE_NAME = "test_vpn_name";
+
+ private Context mContext;
+ private LegacyVpnPreference mLegacyVpnPreference;
+ private VpnProfile mVpnProfile;
+
+
+ @Before
+ public void setUp() {
+ mContext = spy(ApplicationProvider.getApplicationContext());
+ mVpnProfile = new VpnProfile(PROFILE_KEY);
+ mVpnProfile.name = PROFILE_NAME;
+ try {
+ // In Junit, loading the presference at first yields a Resources.NotFoundException
+ mLegacyVpnPreference = new LegacyVpnPreference(mContext);
+ } catch (NotFoundException exception) {
+ mLegacyVpnPreference = new LegacyVpnPreference(mContext);
+ }
+
+ }
+
+ @Test
+ public void setProfile_successfullyStoresProfile() {
+ mLegacyVpnPreference.setProfile(mVpnProfile);
+ assertThat(mLegacyVpnPreference.getProfile()).isEqualTo(mVpnProfile);
+ }
+
+ @Test
+ public void setProfile_updatesPreferenceTitle() {
+ mLegacyVpnPreference.setProfile(mVpnProfile);
+ assertThat(mLegacyVpnPreference.getTitle()).isEqualTo(PROFILE_NAME);
+ }
+}