diff --git a/res/layout/face_enroll_accessibility_toggle.xml b/res/layout/face_enroll_accessibility_toggle.xml
index 4dda2a76920..d37175be31f 100644
--- a/res/layout/face_enroll_accessibility_toggle.xml
+++ b/res/layout/face_enroll_accessibility_toggle.xml
@@ -14,33 +14,68 @@
limitations under the License.
-->
-
-
-
-
-
+ android:layout_height="wrap_content"
+ style="?attr/face_layout_theme">
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
diff --git a/res/layout/face_enroll_introduction.xml b/res/layout/face_enroll_introduction.xml
index 5107bd8b48d..3115bb4ca2f 100644
--- a/res/layout/face_enroll_introduction.xml
+++ b/res/layout/face_enroll_introduction.xml
@@ -77,6 +77,7 @@
+
@@ -101,7 +102,7 @@
android:orientation="horizontal"
android:paddingStart="16dp"
android:paddingEnd="16dp"
- android:layout_marginTop="24dp">
+ android:paddingTop="24dp">
Face authentication
Use accessibility setup
+
+
@@ -2203,10 +2205,10 @@
Wi\u2011Fi password: %1$s
Hotspot password: %1$s
-
+
Add device
- Connect to this network using a QR code
+ Use a QR code to add a device to this network
Retry
@@ -7652,19 +7654,19 @@
On
- Ask every time (unless turned on automatically)
+ Ask every time
- Until you turn off (unless turned on automatically)
+ Until you turn off
- - 1 hour (unless turned on automatically)
- - %d hours (unless turned on automatically)
+ - 1 hour
+ - %d hours
- %d minutes (unless turned on automatically)
+ %d minutes
diff --git a/src/com/android/settings/accounts/RemoveAccountPreferenceController.java b/src/com/android/settings/accounts/RemoveAccountPreferenceController.java
index 938606b19d2..1bc30d03130 100644
--- a/src/com/android/settings/accounts/RemoveAccountPreferenceController.java
+++ b/src/com/android/settings/accounts/RemoveAccountPreferenceController.java
@@ -17,8 +17,6 @@ package com.android.settings.accounts;
import android.accounts.Account;
import android.accounts.AccountManager;
-import android.accounts.AccountManagerCallback;
-import android.accounts.AccountManagerFuture;
import android.accounts.AuthenticatorException;
import android.accounts.OperationCanceledException;
import android.app.Activity;
@@ -30,6 +28,7 @@ import android.content.Intent;
import android.os.Bundle;
import android.os.UserHandle;
import android.os.UserManager;
+import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
@@ -153,28 +152,27 @@ public class RemoveAccountPreferenceController extends AbstractPreferenceControl
public void onClick(DialogInterface dialog, int which) {
Activity activity = getTargetFragment().getActivity();
AccountManager.get(activity).removeAccountAsUser(mAccount, activity,
- new AccountManagerCallback() {
- @Override
- public void run(AccountManagerFuture future) {
- boolean failed = true;
- try {
- if (future.getResult()
- .getBoolean(AccountManager.KEY_BOOLEAN_RESULT)) {
- failed = false;
- }
- } catch (OperationCanceledException e) {
- // handled below
- } catch (IOException e) {
- // handled below
- } catch (AuthenticatorException e) {
- // handled below
- }
- final Activity activity = getTargetFragment().getActivity();
- if (failed && activity != null && !activity.isFinishing()) {
- RemoveAccountFailureDialog.show(getTargetFragment());
- } else {
- activity.finish();
+ future -> {
+ final Activity targetActivity = getTargetFragment().getActivity();
+ if (targetActivity == null || targetActivity.isFinishing()) {
+ Log.w(TAG, "Activity is no longer alive, skipping results");
+ return;
+ }
+ boolean failed = true;
+ try {
+ if (future.getResult()
+ .getBoolean(AccountManager.KEY_BOOLEAN_RESULT)) {
+ failed = false;
}
+ } catch (OperationCanceledException
+ | IOException
+ | AuthenticatorException e) {
+ // handled below
+ }
+ if (failed) {
+ RemoveAccountFailureDialog.show(getTargetFragment());
+ } else {
+ targetActivity.finish();
}
}, null, mUserHandle);
}
diff --git a/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java b/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java
index d923e55fa4d..6887d51e598 100644
--- a/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java
+++ b/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java
@@ -72,12 +72,10 @@ public class FaceEnrollIntroduction extends BiometricEnrollIntroduction {
mFaceManager = Utils.getFaceManagerOrNull(this);
final Button accessibilityButton = findViewById(R.id.accessibility_button);
- final View footerView = findViewById(R.id.footer_layout);
accessibilityButton.setOnClickListener(view -> {
mSwitchDiversity.setChecked(true);
accessibilityButton.setVisibility(View.GONE);
mSwitchDiversity.setVisibility(View.VISIBLE);
- footerView.setVisibility(View.GONE);
});
mSwitchDiversity = findViewById(R.id.toggle_diversity);
diff --git a/src/com/android/settings/development/SystemServerHeapDumpPreferenceController.java b/src/com/android/settings/development/SystemServerHeapDumpPreferenceController.java
index 599162e13f4..e6701ce248c 100644
--- a/src/com/android/settings/development/SystemServerHeapDumpPreferenceController.java
+++ b/src/com/android/settings/development/SystemServerHeapDumpPreferenceController.java
@@ -20,6 +20,7 @@ import android.app.ActivityManager;
import android.content.Context;
import android.os.Build;
import android.os.Handler;
+import android.os.Looper;
import android.os.RemoteException;
import android.os.UserManager;
import android.util.Log;
@@ -47,7 +48,7 @@ public class SystemServerHeapDumpPreferenceController extends DeveloperOptionsPr
super(context);
mUserManager = context.getSystemService(UserManager.class);
- mHandler = new Handler();
+ mHandler = new Handler(Looper.getMainLooper());
}
@Override
diff --git a/src/com/android/settings/gestures/SystemNavigationPreferenceController.java b/src/com/android/settings/gestures/SystemNavigationPreferenceController.java
index 5f58fcfa559..f2c8252be39 100644
--- a/src/com/android/settings/gestures/SystemNavigationPreferenceController.java
+++ b/src/com/android/settings/gestures/SystemNavigationPreferenceController.java
@@ -139,12 +139,11 @@ public abstract class SystemNavigationPreferenceController extends GesturePrefer
* Enables the specified overlay package.
*/
static void setNavBarInteractionMode(IOverlayManager overlayManager, String overlayPackage) {
- setOverlayEnabled(overlayManager, NAV_BAR_MODE_3BUTTON_OVERLAY,
- overlayPackage == NAV_BAR_MODE_3BUTTON_OVERLAY);
- setOverlayEnabled(overlayManager, NAV_BAR_MODE_2BUTTON_OVERLAY,
- overlayPackage == NAV_BAR_MODE_2BUTTON_OVERLAY);
- setOverlayEnabled(overlayManager, NAV_BAR_MODE_GESTURAL_OVERLAY,
- overlayPackage == NAV_BAR_MODE_GESTURAL_OVERLAY);
+ try {
+ overlayManager.setEnabledExclusiveInCategory(overlayPackage, USER_CURRENT);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
}
static boolean isSwipeUpEnabled(Context context) {
@@ -159,12 +158,4 @@ public abstract class SystemNavigationPreferenceController extends GesturePrefer
return NAV_BAR_MODE_GESTURAL == context.getResources().getInteger(
com.android.internal.R.integer.config_navBarInteractionMode);
}
-
- static void setOverlayEnabled(IOverlayManager overlayManager, String pkg, boolean enabled) {
- try {
- overlayManager.setEnabled(pkg, enabled, USER_CURRENT);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
}
diff --git a/src/com/android/settings/homepage/contextualcards/ContextualCard.java b/src/com/android/settings/homepage/contextualcards/ContextualCard.java
index ede12fb00c1..ccfb22d3e17 100644
--- a/src/com/android/settings/homepage/contextualcards/ContextualCard.java
+++ b/src/com/android/settings/homepage/contextualcards/ContextualCard.java
@@ -72,6 +72,7 @@ public class ContextualCard {
@LayoutRes
private final int mViewType;
private final boolean mIsPendingDismiss;
+ private final boolean mHasInlineAction;
public String getName() {
return mName;
@@ -161,6 +162,10 @@ public class ContextualCard {
return mIsPendingDismiss;
}
+ public boolean hasInlineAction() {
+ return mHasInlineAction;
+ }
+
public Builder mutate() {
return mBuilder;
}
@@ -187,6 +192,7 @@ public class ContextualCard {
mIsLargeCard = builder.mIsLargeCard;
mViewType = builder.mViewType;
mIsPendingDismiss = builder.mIsPendingDismiss;
+ mHasInlineAction = builder.mHasInlineAction;
}
ContextualCard(Cursor c) {
@@ -234,6 +240,8 @@ public class ContextualCard {
mBuilder.setViewType(mViewType);
mIsPendingDismiss = false;
mBuilder.setIsPendingDismiss(mIsPendingDismiss);
+ mHasInlineAction = false;
+ mBuilder.setHasInlineAction(mHasInlineAction);
}
@Override
@@ -286,6 +294,7 @@ public class ContextualCard {
@LayoutRes
private int mViewType;
private boolean mIsPendingDismiss;
+ private boolean mHasInlineAction;
public Builder setName(String name) {
mName = name;
@@ -387,6 +396,11 @@ public class ContextualCard {
return this;
}
+ public Builder setHasInlineAction(boolean hasInlineAction) {
+ mHasInlineAction = hasInlineAction;
+ return this;
+ }
+
public ContextualCard build() {
return new ContextualCard(this);
}
diff --git a/src/com/android/settings/homepage/contextualcards/ContextualCardsDiffCallback.java b/src/com/android/settings/homepage/contextualcards/ContextualCardsDiffCallback.java
index d1623cd8ef4..58d6a4197c0 100644
--- a/src/com/android/settings/homepage/contextualcards/ContextualCardsDiffCallback.java
+++ b/src/com/android/settings/homepage/contextualcards/ContextualCardsDiffCallback.java
@@ -20,7 +20,6 @@ import androidx.recyclerview.widget.DiffUtil;
import java.util.List;
-//TODO(b/117816826): add test cases for DiffUtil.
/**
* A DiffCallback to calculate the difference between old and new {@link ContextualCard} List.
*/
@@ -53,6 +52,11 @@ public class ContextualCardsDiffCallback extends DiffUtil.Callback {
@Override
public boolean areContentsTheSame(int oldCardPosition, int newCardPosition) {
+ // Slices with toggles needs to be updated continuously, which means their contents may
+ // change. So here we assume the content will always be different to force view rebinding.
+ if (mNewCards.get(newCardPosition).hasInlineAction()) {
+ return false;
+ }
return mOldCards.get(oldCardPosition).equals(mNewCards.get(newCardPosition));
}
}
\ No newline at end of file
diff --git a/src/com/android/settings/homepage/contextualcards/EligibleCardChecker.java b/src/com/android/settings/homepage/contextualcards/EligibleCardChecker.java
index 811aaa2fa13..8558ee79566 100644
--- a/src/com/android/settings/homepage/contextualcards/EligibleCardChecker.java
+++ b/src/com/android/settings/homepage/contextualcards/EligibleCardChecker.java
@@ -26,11 +26,14 @@ import android.util.Log;
import androidx.annotation.VisibleForTesting;
import androidx.slice.Slice;
+import androidx.slice.SliceMetadata;
import androidx.slice.SliceViewManager;
+import androidx.slice.core.SliceAction;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
+import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -41,7 +44,9 @@ public class EligibleCardChecker implements Callable {
private static final long LATCH_TIMEOUT_MS = 200;
private final Context mContext;
- private final ContextualCard mCard;
+
+ @VisibleForTesting
+ ContextualCard mCard;
EligibleCardChecker(Context context, ContextualCard card) {
mContext = context;
@@ -93,6 +98,11 @@ public class EligibleCardChecker implements Callable {
}
final Slice slice = bindSlice(uri);
+
+ if (isSliceToggleable(slice)) {
+ mCard = card.mutate().setHasInlineAction(true).build();
+ }
+
if (slice == null || slice.hasHint(HINT_ERROR)) {
Log.w(TAG, "Failed to bind slice, not eligible for display " + uri);
return false;
@@ -133,4 +143,12 @@ public class EligibleCardChecker implements Callable {
}
return returnSlice[0];
}
+
+ @VisibleForTesting
+ boolean isSliceToggleable(Slice slice) {
+ final SliceMetadata metadata = SliceMetadata.from(mContext, slice);
+ final List toggles = metadata.getToggles();
+
+ return !toggles.isEmpty();
+ }
}
diff --git a/src/com/android/settings/network/MobileNetworkListController.java b/src/com/android/settings/network/MobileNetworkListController.java
index a2e4116fd8b..d0e14ce2168 100644
--- a/src/com/android/settings/network/MobileNetworkListController.java
+++ b/src/com/android/settings/network/MobileNetworkListController.java
@@ -98,7 +98,7 @@ public class MobileNetworkListController extends AbstractPreferenceController im
mPreferences = new ArrayMap<>();
final List subscriptions = SubscriptionUtil.getAvailableSubscriptions(
- mSubscriptionManager);
+ mContext);
for (SubscriptionInfo info : subscriptions) {
final int subId = info.getSubscriptionId();
Preference pref = existingPreferences.remove(subId);
diff --git a/src/com/android/settings/network/MobileNetworkSummaryController.java b/src/com/android/settings/network/MobileNetworkSummaryController.java
index ae115ebb727..9498c4e61e0 100644
--- a/src/com/android/settings/network/MobileNetworkSummaryController.java
+++ b/src/com/android/settings/network/MobileNetworkSummaryController.java
@@ -22,6 +22,7 @@ import static androidx.lifecycle.Lifecycle.Event.ON_RESUME;
import android.content.Context;
import android.content.Intent;
import android.os.UserManager;
+import android.provider.Settings;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.euicc.EuiccManager;
@@ -99,7 +100,7 @@ public class MobileNetworkSummaryController extends AbstractPreferenceController
@Override
public CharSequence getSummary() {
final List subs = SubscriptionUtil.getAvailableSubscriptions(
- mSubscriptionManager);
+ mContext);
if (subs.isEmpty()) {
if (MobileNetworkUtils.showEuiccSettings(mContext)) {
return mContext.getResources().getString(
@@ -132,7 +133,7 @@ public class MobileNetworkSummaryController extends AbstractPreferenceController
mPreference.setEnabled(!mChangeListener.isAirplaneModeOn());
final List subs = SubscriptionUtil.getAvailableSubscriptions(
- mSubscriptionManager);
+ mContext);
if (subs.isEmpty()) {
if (MobileNetworkUtils.showEuiccSettings(mContext)) {
@@ -154,6 +155,7 @@ public class MobileNetworkSummaryController extends AbstractPreferenceController
if (subs.size() == 1) {
mPreference.setOnPreferenceClickListener((Preference pref) -> {
final Intent intent = new Intent(mContext, MobileNetworkActivity.class);
+ intent.putExtra(Settings.EXTRA_SUB_ID, subs.get(0).getSubscriptionId());
mContext.startActivity(intent);
return true;
});
diff --git a/src/com/android/settings/network/SubscriptionUtil.java b/src/com/android/settings/network/SubscriptionUtil.java
index 5f1becaf54d..86655d4ff38 100644
--- a/src/com/android/settings/network/SubscriptionUtil.java
+++ b/src/com/android/settings/network/SubscriptionUtil.java
@@ -16,8 +16,15 @@
package com.android.settings.network;
+import static android.telephony.UiccSlotInfo.CARD_STATE_INFO_PRESENT;
+
+import static com.android.internal.util.CollectionUtils.emptyIfNull;
+
+import android.content.Context;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+import android.telephony.UiccSlotInfo;
import android.text.TextUtils;
import androidx.annotation.VisibleForTesting;
@@ -27,6 +34,7 @@ import java.util.Iterator;
import java.util.List;
public class SubscriptionUtil {
+ private static final String TAG = "SubscriptionUtil";
private static List sAvailableResultsForTesting;
private static List sActiveResultsForTesting;
@@ -44,21 +52,56 @@ public class SubscriptionUtil {
if (sActiveResultsForTesting != null) {
return sActiveResultsForTesting;
}
- List subscriptions = manager.getActiveSubscriptionInfoList(true);
+ final List subscriptions = manager.getActiveSubscriptionInfoList(true);
if (subscriptions == null) {
return new ArrayList<>();
}
return subscriptions;
}
- public static List getAvailableSubscriptions(SubscriptionManager manager) {
+ private static boolean isInactiveInsertedPSim(UiccSlotInfo slotInfo) {
+ return !slotInfo.getIsEuicc() && !slotInfo.getIsActive() &&
+ slotInfo.getCardStateInfo() == CARD_STATE_INFO_PRESENT;
+ }
+
+ public static List getAvailableSubscriptions(Context context) {
if (sAvailableResultsForTesting != null) {
return sAvailableResultsForTesting;
}
- List subscriptions = manager.getSelectableSubscriptionInfoList();
- if (subscriptions == null) {
- subscriptions = new ArrayList<>();
+ final SubscriptionManager subMgr = context.getSystemService(SubscriptionManager.class);
+ final TelephonyManager telMgr = context.getSystemService(TelephonyManager.class);
+
+ List subscriptions =
+ new ArrayList<>(emptyIfNull(subMgr.getSelectableSubscriptionInfoList()));
+
+ // Look for inactive but present physical SIMs that are missing from the selectable list.
+ final List missing = new ArrayList<>();
+ UiccSlotInfo[] slotsInfo = telMgr.getUiccSlotsInfo();
+ for (int i = 0; slotsInfo != null && i < slotsInfo.length; i++) {
+ final UiccSlotInfo slotInfo = slotsInfo[i];
+ if (isInactiveInsertedPSim(slotInfo)) {
+ final int index = slotInfo.getLogicalSlotIdx();
+ final String cardId = slotInfo.getCardId();
+
+ final boolean found = subscriptions.stream().anyMatch(info ->
+ index == info.getSimSlotIndex() && cardId.equals(info.getCardString()));
+ if (!found) {
+ missing.add(slotInfo);
+ }
+ }
}
+ if (!missing.isEmpty()) {
+ for (SubscriptionInfo info : subMgr.getAllSubscriptionInfoList()) {
+ for (UiccSlotInfo slotInfo : missing) {
+ if (info.getSimSlotIndex() == slotInfo.getLogicalSlotIdx() &&
+ info.getCardString().equals(slotInfo.getCardId())) {
+ subscriptions.add(info);
+ break;
+ }
+ }
+ }
+ }
+
// With some carriers such as Google Fi which provide a sort of virtual service that spans
// across multiple underlying networks, we end up with subscription entries for the
// underlying networks that need to be hidden from the user in the UI.
diff --git a/src/com/android/settings/network/telephony/MobileNetworkActivity.java b/src/com/android/settings/network/telephony/MobileNetworkActivity.java
index 47eb66be400..b8ed31f94b8 100644
--- a/src/com/android/settings/network/telephony/MobileNetworkActivity.java
+++ b/src/com/android/settings/network/telephony/MobileNetworkActivity.java
@@ -40,6 +40,7 @@ import com.android.settings.R;
import com.android.settings.core.FeatureFlags;
import com.android.settings.core.SettingsBaseActivity;
import com.android.settings.development.featureflags.FeatureFlagPersistent;
+import com.android.settings.network.SubscriptionUtil;
import com.google.android.material.bottomnavigation.BottomNavigationView;
@@ -165,7 +166,7 @@ public class MobileNetworkActivity extends SettingsBaseActivity {
final int subId = intent.getIntExtra(Settings.EXTRA_SUB_ID, SUB_ID_NULL);
if (subId != SUB_ID_NULL) {
for (SubscriptionInfo subscription :
- mSubscriptionManager.getSelectableSubscriptionInfoList()) {
+ SubscriptionUtil.getAvailableSubscriptions(this)) {
if (subscription.getSubscriptionId() == subId) {
return subscription;
}
diff --git a/src/com/android/settings/network/telephony/MobileNetworkSwitchController.java b/src/com/android/settings/network/telephony/MobileNetworkSwitchController.java
index fd296ecc86e..2037adce4b5 100644
--- a/src/com/android/settings/network/telephony/MobileNetworkSwitchController.java
+++ b/src/com/android/settings/network/telephony/MobileNetworkSwitchController.java
@@ -94,8 +94,9 @@ public class MobileNetworkSwitchController extends BasePreferenceController impl
return;
}
final List subs = SubscriptionUtil.getAvailableSubscriptions(
- mSubscriptionManager);
- if (mSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID || subs.size() < 2) {
+ mContext);
+ if (mSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID ||
+ mSubscriptionManager.isSubscriptionEnabled(mSubId) && subs.size() < 2) {
mSwitchBar.hide();
return;
}
diff --git a/src/com/android/settings/notification/ConfigureNotificationSettings.java b/src/com/android/settings/notification/ConfigureNotificationSettings.java
index 73f6e0618e7..d9d2b9be182 100644
--- a/src/com/android/settings/notification/ConfigureNotificationSettings.java
+++ b/src/com/android/settings/notification/ConfigureNotificationSettings.java
@@ -16,6 +16,8 @@
package com.android.settings.notification;
+import static com.android.settings.SettingsActivity.EXTRA_FRAGMENT_ARG_KEY;
+
import android.app.Activity;
import android.app.Application;
import android.app.settings.SettingsEnums;
@@ -24,10 +26,13 @@ import android.content.Intent;
import android.os.Bundle;
import android.os.UserHandle;
import android.provider.SearchIndexableResource;
+import android.text.TextUtils;
import androidx.annotation.VisibleForTesting;
import androidx.fragment.app.Fragment;
import androidx.preference.Preference;
+import androidx.preference.PreferenceCategory;
+import androidx.preference.PreferenceScreen;
import com.android.settings.R;
import com.android.settings.RingtonePreference;
@@ -62,10 +67,11 @@ public class ConfigureNotificationSettings extends DashboardFragment implements
static final String KEY_NOTIFICATION_ASSISTANT = "notification_assistant";
private static final String KEY_NOTI_DEFAULT_RINGTONE = "notification_default_ringtone";
-
- private RingtonePreference mRequestPreference;
private static final int REQUEST_CODE = 200;
private static final String SELECTED_PREFERENCE_KEY = "selected_preference";
+ private static final String KEY_ADVANCED_CATEGORY = "configure_notifications_advanced";
+
+ private RingtonePreference mRequestPreference;
@Override
public int getMetricsCategory() {
@@ -118,6 +124,27 @@ public class ConfigureNotificationSettings extends DashboardFragment implements
return controllers;
}
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ final PreferenceScreen screen = getPreferenceScreen();
+ final Bundle arguments = getArguments();
+
+ if (screen == null) {
+ return;
+ }
+ if (arguments != null) {
+ final String highlightKey = arguments.getString(EXTRA_FRAGMENT_ARG_KEY);
+ if (!TextUtils.isEmpty(highlightKey)) {
+ final PreferenceCategory advancedCategory =
+ screen.findPreference(KEY_ADVANCED_CATEGORY);
+ // Has highlight row - expand everything
+ advancedCategory.setInitialExpandedChildrenCount(Integer.MAX_VALUE);
+ scrollToPreference(advancedCategory);
+ }
+ }
+ }
+
@Override
public boolean onPreferenceTreeClick(Preference preference) {
if (preference instanceof RingtonePreference) {
diff --git a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
index ae96ed31930..f98dc589579 100644
--- a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
+++ b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
@@ -146,7 +146,8 @@ public class WifiDetailPreferenceController extends AbstractPreferenceController
private static final long TIMEOUT = Duration.ofSeconds(10).toMillis();
// Be static to avoid too much object not be reset.
- private static CountDownTimer mTimer;
+ @VisibleForTesting
+ static CountDownTimer mTimer;
private AccessPoint mAccessPoint;
private final ConnectivityManager mConnectivityManager;
@@ -256,20 +257,15 @@ public class WifiDetailPreferenceController extends AbstractPreferenceController
@Override
public void onLost(Network network) {
- final boolean lostCurrentNetwork = network.equals(mNetwork);
- if (lostCurrentNetwork) {
- // Should update as disconnect but not exit. Except for ephemeral network which
- // should not show on saved network list.
- if (!mIsEphemeral) {
- return;
- }
-
+ // Ephemeral network not a saved network, leave detail page once disconnected
+ if (mIsEphemeral && network.equals(mNetwork)) {
exitActivity();
}
}
};
- private final WifiTracker.WifiListener mWifiListener = new WifiTracker.WifiListener() {
+ @VisibleForTesting
+ final WifiTracker.WifiListener mWifiListener = new WifiTracker.WifiListener() {
/** Called when the state of Wifi has changed. */
public void onWifiStateChanged(int state) {
Log.d(TAG, "onWifiStateChanged(" + state + ")");
@@ -284,16 +280,7 @@ public class WifiDetailPreferenceController extends AbstractPreferenceController
/** Called when the connection state of wifi has changed. */
public void onConnectedChanged() {
- updateAccessPointFromScannedList();
- if (mConnected != mAccessPoint.isActive()) {
- Log.d(TAG, "Connection state changed!");
- mConnected = mAccessPoint.isActive();
- if (mAccessPoint.isActive()) {
- updateConnectingState(STATE_CONNECTED);
- } else {
- updateConnectingState(STATE_DISCONNECTED);
- }
- }
+ refreshPage();
}
/**
@@ -516,42 +503,41 @@ public class WifiDetailPreferenceController extends AbstractPreferenceController
refreshMacAddress();
}
- private boolean updateAccessPoint() {
+ @VisibleForTesting
+ boolean updateAccessPoint() {
boolean changed = false;
- if (mWifiTracker != null) {
- // remember mIsOutOfRange as old before updated
- boolean oldState = mIsOutOfRange;
- updateAccessPointFromScannedList();
- // refresh UI if signal level changed for disconnect network.
- changed = mRssiSignalLevel != mAccessPoint.getLevel();
- changed |= oldState != mIsOutOfRange;
- }
+ // remember mIsOutOfRange as old before updated
+ boolean oldState = mIsOutOfRange;
+ updateAccessPointFromScannedList();
if (mAccessPoint.isActive()) {
- // Sometimes {@link WifiManager#getCurrentNetwork()} return null after connected,
- // refresh it if needed.
- if (mNetwork == null) {
- updateNetworkInfo();
- }
+ updateNetworkInfo();
mNetworkInfo = mConnectivityManager.getNetworkInfo(mNetwork);
mWifiInfo = mWifiManager.getConnectionInfo();
if (mNetwork == null || mNetworkInfo == null || mWifiInfo == null) {
- // Once connected, can't get mNetworkInfo immediately, return false and wait for
- // next time to update UI.
+ // Once connected, can't get mNetwork immediately, return false and wait for
+ // next time to update UI. also reset {@code mIsOutOfRange}
+ mIsOutOfRange = oldState;
return false;
}
-
changed |= mAccessPoint.update(mWifiConfig, mWifiInfo, mNetworkInfo);
- // If feature for saved network not enabled, always return true.
- return mWifiTracker == null || changed;
+ }
+
+ // signal level changed
+ changed |= mRssiSignalLevel != mAccessPoint.getLevel();
+ // In/Out of range changed
+ changed |= oldState != mIsOutOfRange;
+ // connect state changed
+ if (mConnected != mAccessPoint.isActive()) {
+ mConnected = mAccessPoint.isActive();
+ changed = true;
+ updateConnectingState(mAccessPoint.isActive() ? STATE_CONNECTED : STATE_DISCONNECTED);
}
return changed;
}
private void updateAccessPointFromScannedList() {
- if (mWifiTracker == null) return;
-
mIsOutOfRange = true;
for (AccessPoint ap : mWifiTracker.getAccessPoints()) {
@@ -899,13 +885,19 @@ public class WifiDetailPreferenceController extends AbstractPreferenceController
/**
* Show QR code to share the network represented by this preference.
*/
- public void launchWifiDppConfiguratorActivity() {
+ private void launchWifiDppConfiguratorActivity() {
final Intent intent = WifiDppUtils.getConfiguratorQrCodeGeneratorIntentOrNull(mContext,
mWifiManager, mAccessPoint);
if (intent == null) {
Log.e(TAG, "Launch Wi-Fi DPP QR code generator with a wrong Wi-Fi network!");
} else {
+ mMetricsFeatureProvider.action(SettingsEnums.PAGE_UNKNOWN,
+ SettingsEnums.ACTION_SETTINGS_SHARE_WIFI_QR_CODE,
+ SettingsEnums.SETTINGS_WIFI_DPP_CONFIGURATOR,
+ /* key */ null,
+ /* value */ Integer.MIN_VALUE);
+
mContext.startActivity(intent);
}
}
@@ -967,7 +959,8 @@ public class WifiDetailPreferenceController extends AbstractPreferenceController
return FeatureFlagUtils.isEnabled(context, FeatureFlags.WIFI_DETAILS_DATAUSAGE_HEADER);
}
- private void connectNetwork() {
+ @VisibleForTesting
+ void connectNetwork() {
final Activity activity = mFragment.getActivity();
// error handling, connected/saved network should have mWifiConfig.
if (mWifiConfig == null) {
@@ -1045,7 +1038,6 @@ public class WifiDetailPreferenceController extends AbstractPreferenceController
mAccessPoint.getTitle()),
Toast.LENGTH_SHORT).show();
- updateNetworkInfo();
refreshPage();
} else if (state == STATE_NOT_IN_RANGE) {
Log.d(TAG, "AP not in range");
@@ -1084,7 +1076,11 @@ public class WifiDetailPreferenceController extends AbstractPreferenceController
.setButton3Enabled(false);
break;
case STATE_CONNECTED:
- mButtonsPref.setButton3Visible(false);
+ // init button state and set as invisible
+ mButtonsPref.setButton3Text(R.string.wifi_connect)
+ .setButton3Icon(R.drawable.ic_settings_wireless)
+ .setButton3Enabled(true)
+ .setButton3Visible(false);
break;
case STATE_DISCONNECTED:
case STATE_NOT_IN_RANGE:
diff --git a/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java b/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java
index d0322b7f4c8..0cd7f09c2ff 100644
--- a/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java
+++ b/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java
@@ -193,6 +193,13 @@ public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment impl
return;
}
+ mMetricsFeatureProvider.action(
+ mMetricsFeatureProvider.getAttribution(getActivity()),
+ SettingsEnums.ACTION_SETTINGS_ENROLL_WIFI_QR_CODE,
+ SettingsEnums.SETTINGS_WIFI_DPP_ENROLLEE,
+ /* key */ null,
+ /* value */ Integer.MIN_VALUE);
+
notifyUserForQrCodeRecognition();
break;
diff --git a/src/com/android/settings/wifi/slice/ConnectToWifiHandler.java b/src/com/android/settings/wifi/slice/ConnectToWifiHandler.java
index ee158202095..f1b0b6f4902 100644
--- a/src/com/android/settings/wifi/slice/ConnectToWifiHandler.java
+++ b/src/com/android/settings/wifi/slice/ConnectToWifiHandler.java
@@ -43,17 +43,21 @@ public class ConnectToWifiHandler extends Activity {
WifiDialogActivity.KEY_ACCESS_POINT_STATE);
if (network != null) {
+ WifiScanWorker.clearClickedWifi();
final ConnectivityManager cm = getSystemService(ConnectivityManager.class);
// start captive portal app to sign in to network
cm.startCaptivePortalApp(network);
} else if (accessPointState != null) {
connect(new AccessPoint(this, accessPointState));
}
+
finish();
}
@VisibleForTesting
void connect(AccessPoint accessPoint) {
+ WifiScanWorker.saveClickedWifi(accessPoint);
+
final WifiConnectListener connectListener = new WifiConnectListener(this);
switch (WifiUtils.getConnectingType(accessPoint)) {
case WifiUtils.CONNECT_TYPE_OSU_PROVISION:
diff --git a/src/com/android/settings/wifi/slice/WifiScanWorker.java b/src/com/android/settings/wifi/slice/WifiScanWorker.java
index b8462287568..e43844336fd 100644
--- a/src/com/android/settings/wifi/slice/WifiScanWorker.java
+++ b/src/com/android/settings/wifi/slice/WifiScanWorker.java
@@ -20,6 +20,7 @@ import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
import static com.android.settings.wifi.slice.WifiSlice.DEFAULT_EXPANDED_ROW_COUNT;
import android.content.Context;
+import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.ConnectivityManager.NetworkCallback;
import android.net.Network;
@@ -27,9 +28,12 @@ import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.net.NetworkRequest;
import android.net.Uri;
+import android.net.wifi.WifiInfo;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
+import android.os.UserHandle;
+import android.text.TextUtils;
import android.util.Log;
import androidx.annotation.VisibleForTesting;
@@ -55,22 +59,21 @@ public class WifiScanWorker extends SliceBackgroundWorker implement
CaptivePortalNetworkCallback mCaptivePortalNetworkCallback;
private final Context mContext;
+ private final ConnectivityManager mConnectivityManager;
+ private final WifiTracker mWifiTracker;
- private WifiTracker mWifiTracker;
- private ConnectivityManager mConnectivityManager;
+ private static String sClickedWifiSsid;
public WifiScanWorker(Context context, Uri uri) {
super(context, uri);
mContext = context;
mConnectivityManager = context.getSystemService(ConnectivityManager.class);
+ mWifiTracker = new WifiTracker(mContext, this /* wifiListener */,
+ true /* includeSaved */, true /* includeScans */);
}
@Override
protected void onSlicePinned() {
- if (mWifiTracker == null) {
- mWifiTracker = new WifiTracker(mContext, this /* wifiListener */,
- true /* includeSaved */, true /* includeScans */);
- }
mWifiTracker.onStart();
onAccessPointsChanged();
}
@@ -79,6 +82,7 @@ public class WifiScanWorker extends SliceBackgroundWorker implement
protected void onSliceUnpinned() {
mWifiTracker.onStop();
unregisterCaptivePortalNetworkCallback();
+ clearClickedWifi();
}
@Override
@@ -146,6 +150,19 @@ public class WifiScanWorker extends SliceBackgroundWorker implement
return null;
}
+ static void saveClickedWifi(AccessPoint accessPoint) {
+ sClickedWifiSsid = accessPoint.getSsidStr();
+ }
+
+ static void clearClickedWifi() {
+ sClickedWifiSsid = null;
+ }
+
+ static boolean isWifiClicked(WifiInfo info) {
+ final String ssid = WifiInfo.removeDoubleQuotes(info.getSSID());
+ return !TextUtils.isEmpty(ssid) && TextUtils.equals(ssid, sClickedWifiSsid);
+ }
+
public void registerCaptivePortalNetworkCallback(Network wifiNetwork) {
if (wifiNetwork == null) {
return;
@@ -191,7 +208,7 @@ public class WifiScanWorker extends SliceBackgroundWorker implement
@Override
public void onCapabilitiesChanged(Network network,
NetworkCapabilities networkCapabilities) {
- if (!mNetwork.equals(network)) {
+ if (!isSameNetwork(network)) {
return;
}
@@ -202,6 +219,19 @@ public class WifiScanWorker extends SliceBackgroundWorker implement
mIsCaptivePortal = isCaptivePortal;
notifySliceChange();
+
+ // Automatically start captive portal
+ if (mIsCaptivePortal) {
+ if (!isWifiClicked(mWifiTracker.getManager().getConnectionInfo())) {
+ return;
+ }
+
+ final Intent intent = new Intent(mContext, ConnectToWifiHandler.class)
+ .putExtra(ConnectivityManager.EXTRA_NETWORK, network)
+ .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ // Starting activity in the system process needs to specify a user
+ mContext.startActivityAsUser(intent, UserHandle.CURRENT);
+ }
}
/**
diff --git a/src/com/android/settings/wifi/tether/WifiTetherSSIDPreferenceController.java b/src/com/android/settings/wifi/tether/WifiTetherSSIDPreferenceController.java
index b7ddcae8985..1197db436cd 100644
--- a/src/com/android/settings/wifi/tether/WifiTetherSSIDPreferenceController.java
+++ b/src/com/android/settings/wifi/tether/WifiTetherSSIDPreferenceController.java
@@ -16,6 +16,7 @@
package com.android.settings.wifi.tether;
+import android.app.settings.SettingsEnums;
import android.content.Context;
import android.content.Intent;
import android.net.wifi.WifiConfiguration;
@@ -27,9 +28,12 @@ import androidx.preference.EditTextPreference;
import androidx.preference.Preference;
import com.android.settings.R;
+import com.android.settings.overlay.FeatureFactory;
import com.android.settings.widget.ValidatedEditTextPreference;
import com.android.settings.wifi.dpp.WifiDppUtils;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
+
public class WifiTetherSSIDPreferenceController extends WifiTetherBasePreferenceController
implements ValidatedEditTextPreference.Validator {
@@ -41,10 +45,14 @@ public class WifiTetherSSIDPreferenceController extends WifiTetherBasePreference
private String mSSID;
private WifiDeviceNameTextValidator mWifiDeviceNameTextValidator;
+ private final MetricsFeatureProvider mMetricsFeatureProvider;
+
public WifiTetherSSIDPreferenceController(Context context,
OnTetherConfigUpdateListener listener) {
super(context, listener);
+
mWifiDeviceNameTextValidator = new WifiDeviceNameTextValidator();
+ mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
}
@Override
@@ -104,7 +112,15 @@ public class WifiTetherSSIDPreferenceController extends WifiTetherBasePreference
}
private void shareHotspotNetwork(Intent intent) {
- WifiDppUtils.showLockScreen(mContext, () -> mContext.startActivity(intent));
+ WifiDppUtils.showLockScreen(mContext, () -> {
+ mMetricsFeatureProvider.action(SettingsEnums.PAGE_UNKNOWN,
+ SettingsEnums.ACTION_SETTINGS_SHARE_WIFI_HOTSPOT_QR_CODE,
+ SettingsEnums.SETTINGS_WIFI_DPP_CONFIGURATOR,
+ /* key */ null,
+ /* value */ Integer.MIN_VALUE);
+
+ mContext.startActivity(intent);
+ });
}
@VisibleForTesting
diff --git a/tests/robotests/res/values/overlayable_icons_test.xml b/tests/robotests/res/values/overlayable_icons_test.xml
new file mode 100644
index 00000000000..575f798bdbd
--- /dev/null
+++ b/tests/robotests/res/values/overlayable_icons_test.xml
@@ -0,0 +1,88 @@
+
+
+
+
+ - @drawable/drag_handle
+ - @drawable/ic_add_24dp
+ - @drawable/ic_airplanemode_active
+ - @drawable/ic_android
+ - @drawable/ic_apps
+ - @drawable/ic_arrow_back
+ - @drawable/ic_battery_charging_full
+ - @drawable/ic_battery_saver_accent_24dp
+ - @drawable/ic_battery_status_bad_24dp
+ - @drawable/ic_battery_status_good_24dp
+ - @drawable/ic_battery_status_maybe_24dp
+ - @drawable/ic_call_24dp
+ - @drawable/ic_cancel
+ - @drawable/ic_cast_24dp
+ - @drawable/ic_cellular_off
+ - @drawable/ic_content_copy_grey600_24dp
+ - @drawable/ic_data_saver
+ - @drawable/ic_delete
+ - @drawable/ic_delete_accent
+ - @drawable/ic_devices_other
+ - @drawable/ic_devices_other_opaque_black
+ - @drawable/ic_do_not_disturb_on_24dp
+ - @drawable/ic_eject_24dp
+ - @drawable/ic_expand_less
+ - @drawable/ic_expand_more_inverse
+ - @drawable/ic_folder_vd_theme_24
+ - @drawable/ic_friction_lock_closed
+ - @drawable/ic_gray_scale_24dp
+ - @drawable/ic_headset_24dp
+ - @drawable/ic_help
+ - @drawable/ic_homepage_search
+ - @drawable/ic_local_movies
+ - @drawable/ic_local_phone_24_lib
+ - @drawable/ic_lock
+ - @drawable/ic_media_stream
+ - @drawable/ic_media_stream_off
+ - @drawable/ic_network_cell
+ - @drawable/ic_notifications
+ - @drawable/ic_notifications_off_24dp
+ - @drawable/ic_phone_info
+ - @drawable/ic_photo_library
+ - @drawable/ic_settings_accessibility
+ - @drawable/ic_settings_accounts
+ - @drawable/ic_settings_battery_white
+ - @drawable/ic_settings_data_usage
+ - @drawable/ic_settings_date_time
+ - @drawable/ic_settings_delete
+ - @drawable/ic_settings_display_white
+ - @drawable/ic_settings_home
+ - @drawable/ic_settings_location
+ - @drawable/ic_settings_night_display
+ - @drawable/ic_settings_open
+ - @drawable/ic_settings_print
+ - @drawable/ic_settings_privacy
+ - @drawable/ic_settings_security_white
+ - @drawable/ic_settings_sim
+ - @drawable/ic_settings_system_dashboard_white
+ - @drawable/ic_settings_wireless
+ - @drawable/ic_settings_wireless_white
+ - @drawable/ic_storage_white
+ - @drawable/ic_suggestion_night_display
+ - @drawable/ic_videogame_vd_theme_24
+ - @drawable/ic_volume_ringer_vibrate
+ - @drawable/ic_volume_up_24dp
+ - @drawable/ic_vpn_key
+ - @drawable/ic_wifi_tethering
+
+
diff --git a/tests/robotests/src/com/android/settings/accounts/RemoveAccountPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accounts/RemoveAccountPreferenceControllerTest.java
index cf4cb7cf34b..d98d30aff6b 100644
--- a/tests/robotests/src/com/android/settings/accounts/RemoveAccountPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accounts/RemoveAccountPreferenceControllerTest.java
@@ -144,7 +144,7 @@ public class RemoveAccountPreferenceControllerTest {
}
@Test
- public void onClick_shouldNotStartConfirmDialogWhenModifyAccountsIsDisallowed() {
+ public void onClick_modifyAccountsIsDisallowed_shouldNotStartConfirmDialog() {
when(mFragment.isAdded()).thenReturn(true);
final int userId = UserHandle.myUserId();
@@ -195,7 +195,41 @@ public class RemoveAccountPreferenceControllerTest {
Bundle resultBundle = new Bundle();
resultBundle.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, true);
when(future.getResult()).thenReturn(resultBundle);
+
callback.run(future);
verify(activity).finish();
}
+
+ @Test
+ @Config(shadows = {ShadowAccountManager.class, ShadowContentResolver.class})
+ public void confirmRemove_activityGone_shouldSilentlyRemoveAccount()
+ throws AuthenticatorException, OperationCanceledException, IOException {
+ final Account account = new Account("Account11", "com.acct1");
+ final UserHandle userHandle = new UserHandle(10);
+ final FragmentActivity activity = mock(FragmentActivity.class);
+ when(mFragment.isAdded()).thenReturn(true);
+ when(activity.getSystemService(Context.ACCOUNT_SERVICE)).thenReturn(mAccountManager);
+ when(mFragment.getActivity()).thenReturn(activity).thenReturn(null);
+
+ final RemoveAccountPreferenceController.ConfirmRemoveAccountDialog dialog =
+ RemoveAccountPreferenceController.ConfirmRemoveAccountDialog.show(
+ mFragment, account, userHandle);
+ dialog.onCreate(new Bundle());
+ dialog.onClick(null, 0);
+
+ ArgumentCaptor> callbackCaptor = ArgumentCaptor.forClass(
+ AccountManagerCallback.class);
+ verify(mAccountManager).removeAccountAsUser(eq(account), nullable(Activity.class),
+ callbackCaptor.capture(), nullable(Handler.class), eq(userHandle));
+
+ AccountManagerCallback callback = callbackCaptor.getValue();
+ assertThat(callback).isNotNull();
+ AccountManagerFuture future = mock(AccountManagerFuture.class);
+ Bundle resultBundle = new Bundle();
+ resultBundle.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, true);
+ when(future.getResult()).thenReturn(resultBundle);
+
+ callback.run(future);
+ verify(activity, never()).finish();
+ }
}
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardLoaderTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardLoaderTest.java
index f025ee8bb1c..c2a3aa9cc9e 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardLoaderTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardLoaderTest.java
@@ -16,8 +16,6 @@
package com.android.settings.homepage.contextualcards;
-import static android.app.slice.Slice.HINT_ERROR;
-
import static com.android.settings.homepage.contextualcards.ContextualCardLoader.DEFAULT_CARD_COUNT;
import static com.google.common.truth.Truth.assertThat;
@@ -34,8 +32,6 @@ import android.app.settings.SettingsEnums;
import android.content.Context;
import android.net.Uri;
-import androidx.slice.Slice;
-
import com.android.settings.R;
import com.android.settings.slices.CustomSliceRegistry;
import com.android.settings.testutils.FakeFeatureFactory;
@@ -53,73 +49,17 @@ import java.util.stream.Collectors;
@RunWith(RobolectricTestRunner.class)
public class ContextualCardLoaderTest {
- private static final String TEST_SLICE_URI = "content://test/test";
-
private Context mContext;
private ContextualCardLoader mContextualCardLoader;
- private EligibleCardChecker mEligibleCardChecker;
private FakeFeatureFactory mFakeFeatureFactory;
@Before
public void setUp() {
mContext = RuntimeEnvironment.application;
mContextualCardLoader = spy(new ContextualCardLoader(mContext));
- mEligibleCardChecker =
- spy(new EligibleCardChecker(mContext, getContextualCard(TEST_SLICE_URI)));
mFakeFeatureFactory = FakeFeatureFactory.setupForTest();
}
- @Test
- public void isCardEligibleToDisplay_customCard_returnTrue() {
- final ContextualCard customCard = new ContextualCard.Builder()
- .setName("custom_card")
- .setCardType(ContextualCard.CardType.DEFAULT)
- .setTitleText("custom_title")
- .setSummaryText("custom_summary")
- .build();
-
- assertThat(mEligibleCardChecker.isCardEligibleToDisplay(customCard)).isTrue();
- }
-
- @Test
- public void isCardEligibleToDisplay_invalidScheme_returnFalse() {
- final String sliceUri = "contet://com.android.settings.slices/action/flashlight";
-
- assertThat(mEligibleCardChecker.isCardEligibleToDisplay(getContextualCard(sliceUri)))
- .isFalse();
- }
-
- @Test
- public void isCardEligibleToDisplay_invalidRankingScore_returnFalse() {
- final ContextualCard card = new ContextualCard.Builder()
- .setName("test_card")
- .setCardType(ContextualCard.CardType.SLICE)
- .setSliceUri(CustomSliceRegistry.FLASHLIGHT_SLICE_URI)
- .setRankingScore(-1)
- .build();
-
- assertThat(mEligibleCardChecker.isCardEligibleToDisplay(card))
- .isFalse();
- }
-
- @Test
- public void isCardEligibleToDisplay_nullSlice_returnFalse() {
- doReturn(null).when(mEligibleCardChecker).bindSlice(Uri.parse(TEST_SLICE_URI));
-
- assertThat(mEligibleCardChecker.isCardEligibleToDisplay(getContextualCard(TEST_SLICE_URI)))
- .isFalse();
- }
-
- @Test
- public void isCardEligibleToDisplay_errorSlice_returnFalse() {
- final Slice slice = new Slice.Builder(Uri.parse(TEST_SLICE_URI))
- .addHints(HINT_ERROR).build();
- doReturn(slice).when(mEligibleCardChecker).bindSlice(Uri.parse(TEST_SLICE_URI));
-
- assertThat(mEligibleCardChecker.isCardEligibleToDisplay(getContextualCard(TEST_SLICE_URI)))
- .isFalse();
- }
-
@Test
public void getDisplayableCards_twoEligibleCards_shouldShowAll() {
final List cards = getContextualCardList().stream().limit(2)
@@ -201,15 +141,6 @@ public class ContextualCardLoaderTest {
eq(SettingsEnums.ACTION_CONTEXTUAL_CARD_SHOW), any(String.class));
}
- private ContextualCard getContextualCard(String sliceUri) {
- return new ContextualCard.Builder()
- .setName("test_card")
- .setRankingScore(0.5)
- .setCardType(ContextualCard.CardType.SLICE)
- .setSliceUri(Uri.parse(sliceUri))
- .build();
- }
-
private List getContextualCardList() {
final List cards = new ArrayList<>();
cards.add(new ContextualCard.Builder()
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardsDiffCallbackTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardsDiffCallbackTest.java
new file mode 100644
index 00000000000..eb95f716b5c
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardsDiffCallbackTest.java
@@ -0,0 +1,95 @@
+/*
+ * 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.homepage.contextualcards;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.net.Uri;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@RunWith(RobolectricTestRunner.class)
+public class ContextualCardsDiffCallbackTest {
+
+ private static final Uri TEST_SLICE_URI = Uri.parse("content://test/test");
+
+ private ContextualCardsDiffCallback mDiffCallback;
+ private List mOldCards;
+ private List mNewCards;
+
+ @Before
+ public void setUp() {
+ mOldCards = new ArrayList<>();
+ mNewCards = new ArrayList<>();
+ mOldCards.add(getContextualCard("test1"));
+ mNewCards.add(getContextualCard("test1"));
+ mNewCards.add(getContextualCard("test2"));
+ mDiffCallback = new ContextualCardsDiffCallback(mOldCards, mNewCards);
+ }
+
+ @Test
+ public void getOldListSize_oneCard_returnOne() {
+ assertThat(mDiffCallback.getOldListSize()).isEqualTo(1);
+ }
+
+ @Test
+ public void getNewListSize_twoCards_returnTwo() {
+ assertThat(mDiffCallback.getNewListSize()).isEqualTo(2);
+ }
+
+ @Test
+ public void areItemsTheSame_sameItems_returnTrue() {
+ assertThat(mDiffCallback.areItemsTheSame(0, 0)).isTrue();
+ }
+
+ @Test
+ public void areItemsTheSame_differentItems_returnFalse() {
+ mOldCards.add(getContextualCard("test3"));
+
+ assertThat(mDiffCallback.areItemsTheSame(1, 1)).isFalse();
+ }
+
+ @Test
+ public void areContentsTheSame_sameContents_returnTrue() {
+ assertThat(mDiffCallback.areContentsTheSame(0, 0)).isTrue();
+ }
+
+ @Test
+ public void areContentsTheSame_sliceWithToggle_returnFalse() {
+ final ContextualCard card = getContextualCard("test1").mutate()
+ .setHasInlineAction(true).build();
+ mNewCards.add(0, card);
+
+ assertThat(mDiffCallback.areContentsTheSame(0, 0)).isFalse();
+ }
+
+ private ContextualCard getContextualCard(String name) {
+ return new ContextualCard.Builder()
+ .setName(name)
+ .setRankingScore(0.5)
+ .setCardType(ContextualCard.CardType.SLICE)
+ .setSliceUri(TEST_SLICE_URI)
+ .build();
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/EligibleCardCheckerTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/EligibleCardCheckerTest.java
new file mode 100644
index 00000000000..7b70dadfa23
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/EligibleCardCheckerTest.java
@@ -0,0 +1,157 @@
+/*
+ * 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.homepage.contextualcards;
+
+import static android.app.slice.Slice.HINT_ERROR;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+
+import android.content.Context;
+import android.net.Uri;
+
+import androidx.slice.Slice;
+import androidx.slice.SliceProvider;
+import androidx.slice.widget.SliceLiveData;
+
+import com.android.settings.homepage.contextualcards.deviceinfo.EmergencyInfoSlice;
+import com.android.settings.slices.CustomSliceRegistry;
+import com.android.settings.wifi.slice.ContextualWifiSlice;
+
+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 EligibleCardCheckerTest {
+
+ private static final Uri TEST_SLICE_URI = Uri.parse("content://test/test");
+
+ private Context mContext;
+ private EligibleCardChecker mEligibleCardChecker;
+
+ @Before
+ public void setUp() {
+ mContext = RuntimeEnvironment.application;
+ mEligibleCardChecker =
+ spy(new EligibleCardChecker(mContext, getContextualCard(TEST_SLICE_URI)));
+ SliceProvider.setSpecs(SliceLiveData.SUPPORTED_SPECS);
+ }
+
+ @Test
+ public void isSliceToggleable_cardWithToggle_returnTrue() {
+ final ContextualWifiSlice wifiSlice = new ContextualWifiSlice(mContext);
+ final Slice slice = wifiSlice.getSlice();
+
+ assertThat(mEligibleCardChecker.isSliceToggleable(slice)).isTrue();
+ }
+
+ @Test
+ public void isSliceToggleable_cardWithoutToggle_returnFalse() {
+ final EmergencyInfoSlice emergencyInfoSlice = new EmergencyInfoSlice(mContext);
+ final Slice slice = emergencyInfoSlice.getSlice();
+
+ assertThat(mEligibleCardChecker.isSliceToggleable(slice)).isFalse();
+ }
+
+ @Test
+ public void isCardEligibleToDisplay_toggleSlice_hasInlineActionShouldBeTrue() {
+ final ContextualWifiSlice wifiSlice = new ContextualWifiSlice(mContext);
+ final Slice slice = wifiSlice.getSlice();
+ doReturn(slice).when(mEligibleCardChecker).bindSlice(any(Uri.class));
+
+ mEligibleCardChecker.isCardEligibleToDisplay(getContextualCard(TEST_SLICE_URI));
+
+ assertThat(mEligibleCardChecker.mCard.hasInlineAction()).isTrue();
+ }
+
+ @Test
+ public void isCardEligibleToDisplay_notToggleSlice_hasInlineActionShouldBeFalse() {
+ final EmergencyInfoSlice emergencyInfoSlice = new EmergencyInfoSlice(mContext);
+ final Slice slice = emergencyInfoSlice.getSlice();
+ doReturn(slice).when(mEligibleCardChecker).bindSlice(any(Uri.class));
+
+ mEligibleCardChecker.isCardEligibleToDisplay(getContextualCard(TEST_SLICE_URI));
+
+ assertThat(mEligibleCardChecker.mCard.hasInlineAction()).isFalse();
+ }
+
+ @Test
+ public void isCardEligibleToDisplay_customCard_returnTrue() {
+ final ContextualCard customCard = new ContextualCard.Builder()
+ .setName("custom_card")
+ .setCardType(ContextualCard.CardType.DEFAULT)
+ .setTitleText("custom_title")
+ .setSummaryText("custom_summary")
+ .build();
+
+ assertThat(mEligibleCardChecker.isCardEligibleToDisplay(customCard)).isTrue();
+ }
+
+ @Test
+ public void isCardEligibleToDisplay_invalidScheme_returnFalse() {
+ final Uri sliceUri = Uri.parse("contet://com.android.settings.slices/action/flashlight");
+
+ assertThat(mEligibleCardChecker.isCardEligibleToDisplay(getContextualCard(sliceUri)))
+ .isFalse();
+ }
+
+ @Test
+ public void isCardEligibleToDisplay_invalidRankingScore_returnFalse() {
+ final ContextualCard card = new ContextualCard.Builder()
+ .setName("test_card")
+ .setCardType(ContextualCard.CardType.SLICE)
+ .setSliceUri(CustomSliceRegistry.FLASHLIGHT_SLICE_URI)
+ .setRankingScore(-1)
+ .build();
+
+ assertThat(mEligibleCardChecker.isCardEligibleToDisplay(card))
+ .isFalse();
+ }
+
+ @Test
+ public void isCardEligibleToDisplay_nullSlice_returnFalse() {
+ doReturn(null).when(mEligibleCardChecker).bindSlice(any(Uri.class));
+
+ assertThat(mEligibleCardChecker.isCardEligibleToDisplay(getContextualCard(TEST_SLICE_URI)))
+ .isFalse();
+ }
+
+ @Test
+ public void isCardEligibleToDisplay_errorSlice_returnFalse() {
+ final Slice slice = new Slice.Builder(TEST_SLICE_URI)
+ .addHints(HINT_ERROR).build();
+ doReturn(slice).when(mEligibleCardChecker).bindSlice(any(Uri.class));
+
+ assertThat(mEligibleCardChecker.isCardEligibleToDisplay(getContextualCard(TEST_SLICE_URI)))
+ .isFalse();
+ }
+
+ private ContextualCard getContextualCard(Uri sliceUri) {
+ return new ContextualCard.Builder()
+ .setName("test_card")
+ .setRankingScore(0.5)
+ .setCardType(ContextualCard.CardType.SLICE)
+ .setSliceUri(sliceUri)
+ .build();
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/network/MobileNetworkSummaryControllerTest.java b/tests/robotests/src/com/android/settings/network/MobileNetworkSummaryControllerTest.java
index b8ba63c752c..a6238505756 100644
--- a/tests/robotests/src/com/android/settings/network/MobileNetworkSummaryControllerTest.java
+++ b/tests/robotests/src/com/android/settings/network/MobileNetworkSummaryControllerTest.java
@@ -34,6 +34,7 @@ import android.net.ConnectivityManager;
import android.os.UserManager;
import android.provider.Settings;
import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.telephony.euicc.EuiccManager;
import android.text.TextUtils;
@@ -151,8 +152,11 @@ public class MobileNetworkSummaryControllerTest {
mPreference.getOnPreferenceClickListener().onPreferenceClick(mPreference);
final ArgumentCaptor intentCaptor = ArgumentCaptor.forClass(Intent.class);
verify(mContext).startActivity(intentCaptor.capture());
- assertThat(intentCaptor.getValue().getComponent().getClassName()).isEqualTo(
+ Intent intent = intentCaptor.getValue();
+ assertThat(intent.getComponent().getClassName()).isEqualTo(
MobileNetworkActivity.class.getName());
+ assertThat(intent.getIntExtra(Settings.EXTRA_SUB_ID,
+ SubscriptionManager.INVALID_SUBSCRIPTION_ID)).isEqualTo(sub1.getSubscriptionId());
}
@Test
diff --git a/tests/robotests/src/com/android/settings/network/SubscriptionUtilTest.java b/tests/robotests/src/com/android/settings/network/SubscriptionUtilTest.java
index c074466b789..28a390d5a98 100644
--- a/tests/robotests/src/com/android/settings/network/SubscriptionUtilTest.java
+++ b/tests/robotests/src/com/android/settings/network/SubscriptionUtilTest.java
@@ -16,14 +16,21 @@
package com.android.settings.network;
+import static android.telephony.UiccSlotInfo.CARD_STATE_INFO_ABSENT;
+import static android.telephony.UiccSlotInfo.CARD_STATE_INFO_PRESENT;
+
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
+import android.content.Context;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+import android.telephony.UiccSlotInfo;
import org.junit.Before;
import org.junit.Test;
@@ -39,17 +46,25 @@ import java.util.List;
@RunWith(RobolectricTestRunner.class)
public class SubscriptionUtilTest {
@Mock
- private SubscriptionManager mManager;
+ private Context mContext;
+ @Mock
+ private SubscriptionManager mSubMgr;
+ @Mock
+ private TelephonyManager mTelMgr;
+
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
+ doReturn(mSubMgr).when(mContext).getSystemService(SubscriptionManager.class);
+ doReturn(mTelMgr).when(mContext).getSystemService(TelephonyManager.class);
+ when(mTelMgr.getUiccSlotsInfo()).thenReturn(null);
}
@Test
public void getAvailableSubscriptions_nullInfoFromSubscriptionManager_nonNullResult() {
- when(mManager.getSelectableSubscriptionInfoList()).thenReturn(null);
- final List subs = SubscriptionUtil.getAvailableSubscriptions(mManager);
+ when(mSubMgr.getSelectableSubscriptionInfoList()).thenReturn(null);
+ final List subs = SubscriptionUtil.getAvailableSubscriptions(mContext);
assertThat(subs).isNotNull();
assertThat(subs).isEmpty();
}
@@ -58,8 +73,8 @@ public class SubscriptionUtilTest {
public void getAvailableSubscriptions_oneSubscription_oneResult() {
final SubscriptionInfo info = mock(SubscriptionInfo.class);
when(info.getMncString()).thenReturn("fake1234");
- when(mManager.getSelectableSubscriptionInfoList()).thenReturn(Arrays.asList(info));
- final List subs = SubscriptionUtil.getAvailableSubscriptions(mManager);
+ when(mSubMgr.getSelectableSubscriptionInfoList()).thenReturn(Arrays.asList(info));
+ final List subs = SubscriptionUtil.getAvailableSubscriptions(mContext);
assertThat(subs).isNotNull();
assertThat(subs).hasSize(1);
}
@@ -70,8 +85,8 @@ public class SubscriptionUtilTest {
final SubscriptionInfo info2 = mock(SubscriptionInfo.class);
when(info1.getMncString()).thenReturn("fake1234");
when(info2.getMncString()).thenReturn("fake5678");
- when(mManager.getSelectableSubscriptionInfoList()).thenReturn(Arrays.asList(info1, info2));
- final List subs = SubscriptionUtil.getAvailableSubscriptions(mManager);
+ when(mSubMgr.getSelectableSubscriptionInfoList()).thenReturn(Arrays.asList(info1, info2));
+ final List subs = SubscriptionUtil.getAvailableSubscriptions(mContext);
assertThat(subs).isNotNull();
assertThat(subs).hasSize(2);
}
@@ -83,9 +98,9 @@ public class SubscriptionUtilTest {
final SubscriptionInfo info3 = mock(SubscriptionInfo.class);
when(info1.getSubscriptionId()).thenReturn(1);
when(info1.getMncString()).thenReturn("fake1234");
- when(mManager.getSelectableSubscriptionInfoList()).thenReturn(
+ when(mSubMgr.getSelectableSubscriptionInfoList()).thenReturn(
new ArrayList<>(Arrays.asList(info1, info2, info3)));
- final List subs = SubscriptionUtil.getAvailableSubscriptions(mManager);
+ final List subs = SubscriptionUtil.getAvailableSubscriptions(mContext);
assertThat(subs).isNotNull();
assertThat(subs).hasSize(1);
assertThat(subs.get(0).getSubscriptionId()).isEqualTo(1);
@@ -101,19 +116,96 @@ public class SubscriptionUtilTest {
when(info1.getMncString()).thenReturn("fake1234");
when(info4.getSubscriptionId()).thenReturn(4);
when(info4.getMncString()).thenReturn("fake5678");
- when(mManager.getSelectableSubscriptionInfoList()).thenReturn(new ArrayList<>(
+ when(mSubMgr.getSelectableSubscriptionInfoList()).thenReturn(new ArrayList<>(
Arrays.asList(info1, info2, info3, info4)));
- final List subs = SubscriptionUtil.getAvailableSubscriptions(mManager);
+ final List subs = SubscriptionUtil.getAvailableSubscriptions(mContext);
assertThat(subs).isNotNull();
assertThat(subs).hasSize(2);
assertThat(subs.get(0).getSubscriptionId()).isEqualTo(1);
assertThat(subs.get(1).getSubscriptionId()).isEqualTo(4);
}
+ @Test
+ public void getAvailableSubscriptions_oneSelectableOneDisabledPSim_twoResults() {
+ final SubscriptionInfo info1 = mock(SubscriptionInfo.class);
+ final SubscriptionInfo info2 = mock(SubscriptionInfo.class);
+
+ when(info1.getSubscriptionId()).thenReturn(111);
+ when(info1.getMncString()).thenReturn("fake111");
+ when(info1.getSimSlotIndex()).thenReturn(-1);
+ when(info1.getCardString()).thenReturn("info1_cardid");
+
+ when(info2.getSubscriptionId()).thenReturn(222);
+ when(info2.getMncString()).thenReturn("fake222");
+ when(info2.getSimSlotIndex()).thenReturn(0);
+ when(info2.getCardString()).thenReturn("info2_cardid");
+
+ when(mSubMgr.getSelectableSubscriptionInfoList()).thenReturn(Arrays.asList(info1));
+ when(mSubMgr.getAllSubscriptionInfoList()).thenReturn(Arrays.asList(info1, info2));
+
+ final UiccSlotInfo info2slot = mock(UiccSlotInfo.class);
+ when(info2slot.getCardStateInfo()).thenReturn(CARD_STATE_INFO_PRESENT);
+ when(info2slot.getLogicalSlotIdx()).thenReturn(0);
+ when(info2slot.getCardId()).thenReturn("info2_cardid");
+
+ final UiccSlotInfo[] slotInfos = {info2slot};
+ when(mTelMgr.getUiccSlotsInfo()).thenReturn(slotInfos);
+
+ final List subs = SubscriptionUtil.getAvailableSubscriptions(mContext);
+ assertThat(subs).hasSize(2);
+ assertThat(subs.get(0).getSubscriptionId()).isEqualTo(111);
+ assertThat(subs.get(1).getSubscriptionId()).isEqualTo(222);
+ }
+
+
+ @Test
+ public void getAvailableSubscriptions_oneSelectableTwoDisabledPSimsOneAbsent_twoResults() {
+ final SubscriptionInfo info1 = mock(SubscriptionInfo.class);
+ final SubscriptionInfo info2 = mock(SubscriptionInfo.class);
+ final SubscriptionInfo info3 = mock(SubscriptionInfo.class);
+
+ when(info1.getSubscriptionId()).thenReturn(111);
+ when(info1.getMncString()).thenReturn("fake111");
+ when(info1.getSimSlotIndex()).thenReturn(-1);
+ when(info1.getCardString()).thenReturn("info1_cardid");
+
+ when(info2.getSubscriptionId()).thenReturn(222);
+ when(info2.getMncString()).thenReturn("fake222");
+ when(info2.getSimSlotIndex()).thenReturn(-1);
+ when(info2.getCardString()).thenReturn("info2_cardid");
+
+ when(info3.getSubscriptionId()).thenReturn(333);
+ when(info3.getMncString()).thenReturn("fake333");
+ when(info3.getSimSlotIndex()).thenReturn(0);
+ when(info3.getCardString()).thenReturn("info3_cardid");
+
+ when(mSubMgr.getSelectableSubscriptionInfoList()).thenReturn(Arrays.asList(info1));
+ when(mSubMgr.getAllSubscriptionInfoList()).thenReturn(Arrays.asList(info1, info2, info3));
+
+ final UiccSlotInfo info2slot = mock(UiccSlotInfo.class);
+ final UiccSlotInfo info3slot = mock(UiccSlotInfo.class);
+
+ when(info2slot.getLogicalSlotIdx()).thenReturn(-1);
+ when(info2slot.getCardStateInfo()).thenReturn(CARD_STATE_INFO_ABSENT);
+ when(info2slot.getCardId()).thenReturn("info2_cardid");
+
+ when(info3slot.getLogicalSlotIdx()).thenReturn(0);
+ when(info3slot.getCardStateInfo()).thenReturn(CARD_STATE_INFO_PRESENT);
+ when(info3slot.getCardId()).thenReturn("info3_cardid");
+
+ final UiccSlotInfo[] slotInfos = {info2slot, info3slot};
+ when(mTelMgr.getUiccSlotsInfo()).thenReturn(slotInfos);
+
+ final List subs = SubscriptionUtil.getAvailableSubscriptions(mContext);
+ assertThat(subs).hasSize(2);
+ assertThat(subs.get(0).getSubscriptionId()).isEqualTo(111);
+ assertThat(subs.get(1).getSubscriptionId()).isEqualTo(333);
+ }
+
@Test
public void getActiveSubscriptions_nullInfoFromSubscriptionManager_nonNullResult() {
- when(mManager.getActiveSubscriptionInfoList(anyBoolean())).thenReturn(null);
- final List subs = SubscriptionUtil.getActiveSubscriptions(mManager);
+ when(mSubMgr.getActiveSubscriptionInfoList(anyBoolean())).thenReturn(null);
+ final List subs = SubscriptionUtil.getActiveSubscriptions(mSubMgr);
assertThat(subs).isNotNull();
assertThat(subs).isEmpty();
}
@@ -121,8 +213,8 @@ public class SubscriptionUtilTest {
@Test
public void getActiveSubscriptions_oneSubscription_oneResult() {
final SubscriptionInfo info = mock(SubscriptionInfo.class);
- when(mManager.getActiveSubscriptionInfoList(anyBoolean())).thenReturn(Arrays.asList(info));
- final List subs = SubscriptionUtil.getActiveSubscriptions(mManager);
+ when(mSubMgr.getActiveSubscriptionInfoList(anyBoolean())).thenReturn(Arrays.asList(info));
+ final List subs = SubscriptionUtil.getActiveSubscriptions(mSubMgr);
assertThat(subs).isNotNull();
assertThat(subs).hasSize(1);
}
@@ -131,9 +223,9 @@ public class SubscriptionUtilTest {
public void getActiveSubscriptions_twoSubscriptions_twoResults() {
final SubscriptionInfo info1 = mock(SubscriptionInfo.class);
final SubscriptionInfo info2 = mock(SubscriptionInfo.class);
- when(mManager.getActiveSubscriptionInfoList(anyBoolean())).thenReturn(
+ when(mSubMgr.getActiveSubscriptionInfoList(anyBoolean())).thenReturn(
Arrays.asList(info1, info2));
- final List subs = SubscriptionUtil.getActiveSubscriptions(mManager);
+ final List subs = SubscriptionUtil.getActiveSubscriptions(mSubMgr);
assertThat(subs).isNotNull();
assertThat(subs).hasSize(2);
}
diff --git a/tests/robotests/src/com/android/settings/network/telephony/MobileNetworkActivityTest.java b/tests/robotests/src/com/android/settings/network/telephony/MobileNetworkActivityTest.java
index 68f8c912972..f38f2a2bb0c 100644
--- a/tests/robotests/src/com/android/settings/network/telephony/MobileNetworkActivityTest.java
+++ b/tests/robotests/src/com/android/settings/network/telephony/MobileNetworkActivityTest.java
@@ -33,15 +33,18 @@ import android.os.Bundle;
import android.provider.Settings;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
import android.view.Menu;
import android.view.View;
import com.android.internal.telephony.TelephonyIntents;
import com.android.internal.view.menu.ContextMenuBuilder;
import com.android.settings.R;
+import com.android.settings.network.SubscriptionUtil;
import com.google.android.material.bottomnavigation.BottomNavigationView;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -52,6 +55,7 @@ import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import androidx.fragment.app.Fragment;
@@ -73,6 +77,8 @@ public class MobileNetworkActivityTest {
@Mock
private SubscriptionManager mSubscriptionManager;
@Mock
+ private TelephonyManager mTelephonyManager;
+ @Mock
private SubscriptionInfo mSubscriptionInfo;
@Mock
private SubscriptionInfo mSubscriptionInfo2;
@@ -99,6 +105,8 @@ public class MobileNetworkActivityTest {
doReturn(mSubscriptionManager).when(mMobileNetworkActivity).getSystemService(
SubscriptionManager.class);
+ doReturn(mTelephonyManager).when(mMobileNetworkActivity).getSystemService(
+ TelephonyManager.class);
doReturn(mBottomNavigationView).when(mMobileNetworkActivity).findViewById(R.id.bottom_nav);
doReturn(mFragmentManager).when(mMobileNetworkActivity).getSupportFragmentManager();
doReturn(mFragmentTransaction).when(mFragmentManager).beginTransaction();
@@ -108,6 +116,11 @@ public class MobileNetworkActivityTest {
MOBILE_SETTINGS_TAG + CURRENT_SUB_ID);
}
+ @After
+ public void tearDown() {
+ SubscriptionUtil.setAvailableSubscriptionsForTesting(null);
+ }
+
@Test
public void updateBottomNavigationView_oneSubscription_shouldBeGone() {
mSubscriptionInfos.add(mSubscriptionInfo);
@@ -169,7 +182,7 @@ public class MobileNetworkActivityTest {
doReturn(intent).when(mMobileNetworkActivity).getIntent();
mSubscriptionInfos.add(mSubscriptionInfo);
mSubscriptionInfos.add(mSubscriptionInfo2);
- doReturn(mSubscriptionInfos).when(mSubscriptionManager).getSelectableSubscriptionInfoList();
+ SubscriptionUtil.setAvailableSubscriptionsForTesting(mSubscriptionInfos);
doReturn(true).when(mSubscriptionManager).isActiveSubscriptionId(CURRENT_SUB_ID);
assertThat(mMobileNetworkActivity.getSubscriptionId()).isEqualTo(CURRENT_SUB_ID);
diff --git a/tests/robotests/src/com/android/settings/network/telephony/MobileNetworkSwitchControllerTest.java b/tests/robotests/src/com/android/settings/network/telephony/MobileNetworkSwitchControllerTest.java
index 6d85826ade4..a10227f5924 100644
--- a/tests/robotests/src/com/android/settings/network/telephony/MobileNetworkSwitchControllerTest.java
+++ b/tests/robotests/src/com/android/settings/network/telephony/MobileNetworkSwitchControllerTest.java
@@ -20,6 +20,7 @@ import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
@@ -99,12 +100,21 @@ public class MobileNetworkSwitchControllerTest {
}
@Test
- public void displayPreference_onlyOneSubscription_switchBarHidden() {
+ public void displayPreference_oneEnabledSubscription_switchBarHidden() {
+ doReturn(true).when(mSubscriptionManager).isSubscriptionEnabled(mSubId);
SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(mSubscription));
mController.displayPreference(mScreen);
assertThat(mSwitchBar.isShowing()).isFalse();
}
+ @Test
+ public void displayPreference_oneDisabledSubscription_switchBarNotHidden() {
+ doReturn(false).when(mSubscriptionManager).isSubscriptionEnabled(mSubId);
+ SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(mSubscription));
+ mController.displayPreference(mScreen);
+ assertThat(mSwitchBar.isShowing()).isTrue();
+ }
+
@Test
public void displayPreference_subscriptionEnabled_switchIsOn() {
when(mSubscriptionManager.isSubscriptionEnabled(mSubId)).thenReturn(true);
diff --git a/tests/robotests/src/com/android/settings/panel/PanelFragmentTest.java b/tests/robotests/src/com/android/settings/panel/PanelFragmentTest.java
index 793b44d5ba2..44dc3bcfcee 100644
--- a/tests/robotests/src/com/android/settings/panel/PanelFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/panel/PanelFragmentTest.java
@@ -36,20 +36,19 @@ import com.android.settings.R;
import com.android.settings.testutils.FakeFeatureFactory;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
-import org.robolectric.android.controller.ActivityController;
@RunWith(RobolectricTestRunner.class)
public class PanelFragmentTest {
private Context mContext;
private PanelFragment mPanelFragment;
+ private FakeSettingsPanelActivity mActivity;
private FakeFeatureFactory mFakeFeatureFactory;
private PanelFeatureProvider mPanelFeatureProvider;
private FakePanelContent mFakePanelContent;
@@ -66,16 +65,12 @@ public class PanelFragmentTest {
mFakePanelContent = new FakePanelContent();
doReturn(mFakePanelContent).when(mPanelFeatureProvider).getPanel(any(), any(), any());
- ActivityController activityController =
- Robolectric.buildActivity(FakeSettingsPanelActivity.class);
- activityController.setup();
+ mActivity = spy(Robolectric.buildActivity(FakeSettingsPanelActivity.class).setup().get());
mPanelFragment =
spy((PanelFragment)
- activityController
- .get()
- .getSupportFragmentManager()
- .findFragmentById(R.id.main_content));
+ mActivity.getSupportFragmentManager().findFragmentById(R.id.main_content));
+ doReturn(mActivity).when(mPanelFragment).getActivity();
final Bundle bundle = new Bundle();
bundle.putString(SettingsPanelActivity.KEY_PANEL_TYPE_ARGUMENT, FAKE_EXTRA);
@@ -106,23 +101,23 @@ public class PanelFragmentTest {
}
@Test
- @Ignore("b/130896218")
public void onDestroy_logCloseEvent() {
- mPanelFragment.onDestroy();
+ mPanelFragment.onDestroyView();
verify(mFakeFeatureFactory.metricsFeatureProvider).action(
0,
- SettingsEnums.PAGE_VISIBLE,
+ SettingsEnums.PAGE_HIDE,
mFakePanelContent.getMetricsCategory(),
- any(String.class),
- 0); }
+ PanelLoggingContract.PanelClosedKeys.KEY_OTHERS,
+ 0);
+ }
@Test
- @Ignore("b/130896218")
public void panelSeeMoreClick_logsCloseEvent() {
final View.OnClickListener listener = mPanelFragment.getSeeMoreListener();
-
listener.onClick(null);
+ verify(mActivity).finish();
+ mPanelFragment.onDestroyView();
verify(mFakeFeatureFactory.metricsFeatureProvider).action(
0,
SettingsEnums.PAGE_HIDE,
@@ -133,12 +128,12 @@ public class PanelFragmentTest {
}
@Test
- @Ignore("b/130896218")
public void panelDoneClick_logsCloseEvent() {
final View.OnClickListener listener = mPanelFragment.getCloseListener();
-
listener.onClick(null);
+ verify(mActivity).finish();
+ mPanelFragment.onDestroyView();
verify(mFakeFeatureFactory.metricsFeatureProvider).action(
0,
SettingsEnums.PAGE_HIDE,
diff --git a/tests/robotests/src/com/android/settings/panel/SettingsPanelActivityTest.java b/tests/robotests/src/com/android/settings/panel/SettingsPanelActivityTest.java
index 4ca6395400a..8ad21569401 100644
--- a/tests/robotests/src/com/android/settings/panel/SettingsPanelActivityTest.java
+++ b/tests/robotests/src/com/android/settings/panel/SettingsPanelActivityTest.java
@@ -35,7 +35,6 @@ import android.view.MotionEvent;
import com.android.settings.testutils.FakeFeatureFactory;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
@@ -52,8 +51,8 @@ public class SettingsPanelActivityTest {
@Before
public void setUp() {
mFakeFeatureFactory = FakeFeatureFactory.setupForTest();
- mSettingsPanelActivity = Robolectric.buildActivity(FakeSettingsPanelActivity.class)
- .create().get();
+ mSettingsPanelActivity = spy(
+ Robolectric.buildActivity(FakeSettingsPanelActivity.class).create().get());
mPanelFeatureProvider = spy(new PanelFeatureProviderImpl());
mFakeFeatureFactory.panelFeatureProvider = mPanelFeatureProvider;
mFakePanelContent = new FakePanelContent();
@@ -88,21 +87,4 @@ public class SettingsPanelActivityTest {
assertThat(activity.mBundle.getString(KEY_PANEL_TYPE_ARGUMENT))
.isEqualTo("com.android.settings.panel.action.MEDIA_OUTPUT");
}
-
- @Test
- @Ignore("b/130896218")
- public void onTouchEvent_outsideAction_logsPanelClosed() {
- final MotionEvent event = mock(MotionEvent.class);
- when(event.getAction()).thenReturn(MotionEvent.ACTION_OUTSIDE);
-
- mSettingsPanelActivity.onTouchEvent(event);
-
- verify(mFakeFeatureFactory.metricsFeatureProvider).action(
- 0,
- SettingsEnums.PAGE_HIDE,
- SettingsEnums.TESTING,
- PanelLoggingContract.PanelClosedKeys.KEY_OTHERS,
- 0
- );
- }
}
diff --git a/tests/robotests/src/com/android/settings/panel/VolumePanelTest.java b/tests/robotests/src/com/android/settings/panel/VolumePanelTest.java
index 154428de679..8dd04ce82c5 100644
--- a/tests/robotests/src/com/android/settings/panel/VolumePanelTest.java
+++ b/tests/robotests/src/com/android/settings/panel/VolumePanelTest.java
@@ -18,32 +18,71 @@ package com.android.settings.panel;
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.media.session.ISessionController;
+import android.media.session.MediaController;
+import android.media.session.MediaSession;
+import android.media.session.MediaSessionManager;
import android.net.Uri;
+import com.android.settings.notification.RemoteVolumePreferenceController;
import com.android.settings.slices.CustomSliceRegistry;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.Answers;
+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 VolumePanelTest {
+ @Mock
+ private MediaSessionManager mMediaSessionManager;
+ @Mock
+ private MediaController mMediaController;
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private ISessionController mStub;
+
+
private VolumePanel mPanel;
+ private Context mContext;
+
@Before
public void setUp() {
- mPanel = VolumePanel.create(RuntimeEnvironment.application);
+ MockitoAnnotations.initMocks(this);
+
+ mContext = spy(RuntimeEnvironment.application);
+
+ when(mContext.getApplicationContext()).thenReturn(mContext);
+ when(mContext.getSystemService(MediaSessionManager.class)).thenReturn(mMediaSessionManager);
+
+ mPanel = VolumePanel.create(mContext);
}
@Test
- @Ignore("b/130896218")
- public void getSlices_containsNecessarySlices() {
+ public void getSlices_hasActiveRemoteToken_containsRemoteMediaUri() {
+ List activeSessions = new ArrayList<>();
+ MediaSession.Token token = new MediaSession.Token(mStub);
+ activeSessions.add(mMediaController);
+
+ when(mMediaSessionManager.getActiveSessions(null)).thenReturn(
+ activeSessions);
+ when(mMediaController.getPlaybackInfo()).thenReturn(new MediaController.PlaybackInfo(
+ MediaController.PlaybackInfo.PLAYBACK_TYPE_REMOTE, 0, 10, 5, null));
+ when(mMediaController.getSessionToken()).thenReturn(new MediaSession.Token(mStub));
+ when(RemoteVolumePreferenceController.getActiveRemoteToken(mContext)).thenReturn(token);
+
final List uris = mPanel.getSlices();
assertThat(uris).containsExactly(
@@ -55,6 +94,22 @@ public class VolumePanelTest {
CustomSliceRegistry.VOLUME_ALARM_URI);
}
+ @Test
+ public void getSlices_doesNotHaveActiveRemoteToken_doesNotcontainRemoteMediaUri() {
+ final List uris = mPanel.getSlices();
+
+ when(RemoteVolumePreferenceController.getActiveRemoteToken(mContext))
+ .thenReturn(null);
+
+ assertThat(uris).doesNotContain(CustomSliceRegistry.VOLUME_REMOTE_MEDIA_URI);
+ assertThat(uris).containsExactly(
+ CustomSliceRegistry.VOLUME_CALL_URI,
+ CustomSliceRegistry.VOLUME_MEDIA_URI,
+ CustomSliceRegistry.MEDIA_OUTPUT_INDICATOR_SLICE_URI,
+ CustomSliceRegistry.VOLUME_RINGER_URI,
+ CustomSliceRegistry.VOLUME_ALARM_URI);
+ }
+
@Test
public void getSeeMoreIntent_notNull() {
assertThat(mPanel.getSeeMoreIntent()).isNotNull();
diff --git a/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java
index 906c55c39f2..d4ce481e005 100644
--- a/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java
@@ -35,6 +35,7 @@ import static org.mockito.Mockito.when;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.res.Resources;
import android.content.pm.PackageManager;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
@@ -83,7 +84,6 @@ import com.android.settingslib.wifi.WifiTracker;
import com.android.settingslib.wifi.WifiTrackerFactory;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Answers;
@@ -96,6 +96,7 @@ import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowToast;
import java.net.Inet4Address;
import java.net.InetAddress;
@@ -106,7 +107,6 @@ import java.util.stream.Collectors;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = {ShadowDevicePolicyManager.class, ShadowEntityHeaderController.class})
-@Ignore("b/130896210")
public class WifiDetailPreferenceControllerTest {
private static final int LEVEL = 1;
@@ -118,6 +118,7 @@ public class WifiDetailPreferenceControllerTest {
private static final String RANDOMIZED_MAC_ADDRESS = "RANDOMIZED_MAC_ADDRESS";
private static final String FACTORY_MAC_ADDRESS = "FACTORY_MAC_ADDRESS";
private static final String SECURITY = "None";
+ private static final String FQDN = "fqdn";
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private PreferenceScreen mockScreen;
@@ -299,7 +300,7 @@ public class WifiDetailPreferenceControllerTest {
list.add(mockAccessPoint);
when(mockWifiTracker.getAccessPoints()).thenReturn(list);
WifiTrackerFactory.setTestingWifiTracker(mockWifiTracker);
- when(mockAccessPoint.matches(any(WifiConfiguration.class))).thenReturn(true);
+ when(mockAccessPoint.matches(any(AccessPoint.class))).thenReturn(true);
when(mockAccessPoint.isReachable()).thenReturn(true);
mController = newWifiDetailPreferenceController();
@@ -311,7 +312,7 @@ public class WifiDetailPreferenceControllerTest {
list.add(mockAccessPoint);
when(mockWifiTracker.getAccessPoints()).thenReturn(list);
WifiTrackerFactory.setTestingWifiTracker(mockWifiTracker);
- when(mockAccessPoint.matches(any(WifiConfiguration.class))).thenReturn(true);
+ when(mockAccessPoint.matches(any(AccessPoint.class))).thenReturn(true);
when(mockAccessPoint.isReachable()).thenReturn(true);
mController = newWifiDetailPreferenceController();
@@ -323,7 +324,7 @@ public class WifiDetailPreferenceControllerTest {
list.add(mockAccessPoint);
when(mockWifiTracker.getAccessPoints()).thenReturn(list);
WifiTrackerFactory.setTestingWifiTracker(mockWifiTracker);
- when(mockAccessPoint.matches(any(WifiConfiguration.class))).thenReturn(false);
+ when(mockAccessPoint.matches(any(AccessPoint.class))).thenReturn(false);
when(mockAccessPoint.isReachable()).thenReturn(false);
mController = newWifiDetailPreferenceController();
@@ -1114,12 +1115,13 @@ public class WifiDetailPreferenceControllerTest {
FeatureFlagPersistent.setEnabled(mContext, FeatureFlags.NETWORK_INTERNET_V2, false);
mockWifiConfig.networkId = 5;
- when(mockWifiConfig.isPasspoint()).thenReturn(true);
+ when(mockAccessPoint.isPasspoint()).thenReturn(true);
+ when(mockAccessPoint.getPasspointFqdn()).thenReturn(FQDN);
mController.displayPreference(mockScreen);
mForgetClickListener.getValue().onClick(null);
- verify(mockWifiManager).removePasspointConfiguration(mockWifiConfig.FQDN);
+ verify(mockWifiManager).removePasspointConfiguration(FQDN);
verify(mockMetricsFeatureProvider)
.action(mockActivity, MetricsProto.MetricsEvent.ACTION_WIFI_FORGET);
}
@@ -1130,13 +1132,14 @@ public class WifiDetailPreferenceControllerTest {
final WifiDetailPreferenceController spyController = spy(mController);
mockWifiConfig.networkId = 5;
- when(mockWifiConfig.isPasspoint()).thenReturn(true);
+ when(mockAccessPoint.isPasspoint()).thenReturn(true);
+ when(mockAccessPoint.getPasspointFqdn()).thenReturn(FQDN);
spyController.displayPreference(mockScreen);
FeatureFlagPersistent.setEnabled(mContext, FeatureFlags.NETWORK_INTERNET_V2, true);
mForgetClickListener.getValue().onClick(null);
- verify(mockWifiManager, times(0)).removePasspointConfiguration(mockWifiConfig.FQDN);
+ verify(mockWifiManager, times(0)).removePasspointConfiguration(FQDN);
verify(mockMetricsFeatureProvider, times(0))
.action(mockActivity, MetricsProto.MetricsEvent.ACTION_WIFI_FORGET);
verify(spyController).showConfirmForgetDialog();
@@ -1309,6 +1312,406 @@ public class WifiDetailPreferenceControllerTest {
verify(mockButtonsPref).setButton2Visible(false);
}
+ @Test
+ public void testConnectButton_shouldInvisibleForConnectNetwork() {
+ setUpForConnectedNetwork();
+
+ displayAndResume();
+
+ verify(mockButtonsPref, times(1)).setButton3Visible(false);
+ }
+
+ @Test
+ public void testConnectButton_shouldVisibleForDisconnectNetwork() {
+ setUpForDisconnectedNetwork();
+
+ displayAndResume();
+
+ verify(mockButtonsPref, times(1)).setButton3Visible(true);
+ verify(mockButtonsPref, times(1)).setButton3Text(R.string.wifi_connect);
+ }
+
+ private void setUpForToast() {
+ Resources res = mContext.getResources();
+ when(mockActivity.getResources()).thenReturn(res);
+ }
+
+ @Test
+ public void testConnectButton_clickConnect_displayAsSuccess() {
+ setUpForDisconnectedNetwork();
+ when(mockWifiManager.isWifiEnabled()).thenReturn(true);
+ InOrder inOrder = inOrder(mockButtonsPref);
+ String label = "title";
+ when(mockAccessPoint.getTitle()).thenReturn(label);
+ setUpForToast();
+
+ displayAndResume();
+
+ // check connect button exist
+ verifyConnectBtnSetUpAsVisible(inOrder);
+
+ // click connect button
+ mController.connectNetwork();
+
+ // check display button as connecting
+ verify(mockWifiManager, times(1)).connect(anyInt(), any(WifiManager.ActionListener.class));
+ verifyConnectBtnSetUpAsConnecting(inOrder);
+
+ // update as connected
+ when(mockAccessPoint.isActive()).thenReturn(true);
+ mController.updateAccessPoint();
+
+ // check connect button invisible, be init as default state and toast success message
+ verifyConnectBtnBeInitAsDefault(inOrder);
+ inOrder.verify(mockButtonsPref, times(1)).setButton3Visible(false);
+ assertThat(ShadowToast.getTextOfLatestToast()).isEqualTo(
+ mContext.getString(R.string.wifi_connected_to_message, label));
+ }
+
+ @Test
+ public void testConnectButton_clickConnectButFailed_displayFailMessage() {
+ setUpForDisconnectedNetwork();
+ ArgumentCaptor connectListenerCaptor =
+ ArgumentCaptor.forClass(WifiManager.ActionListener.class);
+ when(mockWifiManager.isWifiEnabled()).thenReturn(true);
+ InOrder inOrder = inOrder(mockButtonsPref);
+ setUpForToast();
+
+ displayAndResume();
+
+ // check connect button exist
+ verifyConnectBtnSetUpAsVisible(inOrder);
+
+ // click connect button
+ mController.connectNetwork();
+
+ // check display button as connecting
+ verify(mockWifiManager, times(1)).connect(anyInt(), connectListenerCaptor.capture());
+ verifyConnectBtnSetUpAsConnecting(inOrder);
+
+ // update as failed
+ connectListenerCaptor.getValue().onFailure(-1);
+
+ // check connect button visible, be init as default and toast failed message
+ verifyConnectBtnBeInitAsDefault(inOrder);
+ inOrder.verify(mockButtonsPref, times(1)).setButton3Visible(true);
+ assertThat(ShadowToast.getTextOfLatestToast()).isEqualTo(
+ mContext.getString(R.string.wifi_failed_connect_message));
+ }
+
+ private void verifyConnectBtnSetUpAsVisible(InOrder inOrder) {
+ inOrder.verify(mockButtonsPref, times(1)).setButton3Text(R.string.wifi_connect);
+ inOrder.verify(mockButtonsPref, times(1)).setButton3Icon(R.drawable.ic_settings_wireless);
+ inOrder.verify(mockButtonsPref, times(1)).setButton3Visible(true);
+ }
+
+ private void verifyConnectBtnSetUpAsConnecting(InOrder inOrder) {
+ inOrder.verify(mockButtonsPref, times(1)).setButton3Text(R.string.wifi_connecting);
+ inOrder.verify(mockButtonsPref, times(1)).setButton3Enabled(false);
+ }
+
+ private void verifyConnectBtnBeInitAsDefault(InOrder inOrder) {
+ inOrder.verify(mockButtonsPref, times(1)).setButton3Text(R.string.wifi_connect);
+ inOrder.verify(mockButtonsPref, times(1)).setButton3Icon(R.drawable.ic_settings_wireless);
+ inOrder.verify(mockButtonsPref, times(1)).setButton3Enabled(true);
+ }
+
+ @Test
+ public void testConnectButton_clickConnectButTimeout_displayFailMessage() {
+ setUpForDisconnectedNetwork();
+ when(mockWifiManager.isWifiEnabled()).thenReturn(true);
+ InOrder inOrder = inOrder(mockButtonsPref);
+ setUpForToast();
+
+ displayAndResume();
+
+ // check connect button exist
+ verifyConnectBtnSetUpAsVisible(inOrder);
+
+ // click connect button
+ mController.connectNetwork();
+
+ // check display button as connecting
+ verify(mockWifiManager, times(1)).connect(anyInt(), any(WifiManager.ActionListener.class));
+ verifyConnectBtnSetUpAsConnecting(inOrder);
+
+ // update as failed
+ mController.mTimer.onFinish();
+
+ // check connect button visible, be init as default and toast failed message
+ verifyConnectBtnBeInitAsDefault(inOrder);
+ inOrder.verify(mockButtonsPref, times(1)).setButton3Visible(true);
+ assertThat(ShadowToast.getTextOfLatestToast()).isEqualTo(
+ mContext.getString(R.string.wifi_failed_connect_message));
+ }
+
+ @Test
+ public void testConnectButton_clickConnectButTimeout_displayNotInRangeMessage() {
+ setUpForNotInRangeNetwork();
+ when(mockWifiManager.isWifiEnabled()).thenReturn(true);
+ InOrder inOrder = inOrder(mockButtonsPref);
+ setUpForToast();
+
+ displayAndResume();
+
+ // check connect button exist
+ verifyConnectBtnSetUpAsVisible(inOrder);
+
+ // click connect button
+ mController.connectNetwork();
+
+ // check display button as connecting
+ verify(mockWifiManager, times(1)).connect(anyInt(), any(WifiManager.ActionListener.class));
+ verifyConnectBtnSetUpAsConnecting(inOrder);
+
+ // update as failed
+ mController.mTimer.onFinish();
+
+ // check connect button visible, be init as default and toast failed message
+ verifyConnectBtnBeInitAsDefault(inOrder);
+ inOrder.verify(mockButtonsPref, times(1)).setButton3Visible(true);
+ assertThat(ShadowToast.getTextOfLatestToast()).isEqualTo(
+ mContext.getString(R.string.wifi_not_in_range_message));
+ }
+
+ @Test
+ public void testConnectButton_clickConnectWhenWiFiDisabled_displaySuccessMessage() {
+ setUpForDisconnectedNetwork();
+ when(mockWifiManager.isWifiEnabled()).thenReturn(false); // wifi disabled
+ InOrder inOrder = inOrder(mockButtonsPref);
+ String label = "title";
+ when(mockAccessPoint.getTitle()).thenReturn(label);
+ setUpForToast();
+
+ displayAndResume();
+
+ // check connect button exist
+ verifyConnectBtnSetUpAsVisible(inOrder);
+
+ // click connect button
+ mController.connectNetwork();
+
+ // check turn on Wi-Fi, display button as connecting and toast turn on Wi-Fi message
+ verify(mockWifiManager, times(1)).setWifiEnabled(true);
+ verifyConnectBtnSetUpAsConnecting(inOrder);
+ assertThat(ShadowToast.getTextOfLatestToast()).isEqualTo(
+ mContext.getString(R.string.wifi_turned_on_message));
+
+ // notify Wi-Fi enabled
+ mController.mWifiListener.onWifiStateChanged(WifiManager.WIFI_STATE_ENABLED);
+
+ // check had connect network and icon display as expected
+ verify(mockWifiManager, times(1)).connect(anyInt(), any(WifiManager.ActionListener.class));
+ verifyConnectBtnSetUpAsConnecting(inOrder);
+
+ // update as connected
+ when(mockAccessPoint.isActive()).thenReturn(true);
+ mController.updateAccessPoint();
+
+ // check connect button invisible, be init as default state and toast success message
+ verifyConnectBtnBeInitAsDefault(inOrder);
+ inOrder.verify(mockButtonsPref, times(1)).setButton3Visible(false);
+ assertThat(ShadowToast.getTextOfLatestToast()).isEqualTo(
+ mContext.getString(R.string.wifi_connected_to_message, label));
+ }
+
+ @Test
+ public void testConnectButton_clickConnectWhenWiFiDisabled_failedToConnectWiFi() {
+ setUpForDisconnectedNetwork();
+ when(mockWifiManager.isWifiEnabled()).thenReturn(false); // wifi disabled
+ InOrder inOrder = inOrder(mockButtonsPref);
+ setUpForToast();
+
+ displayAndResume();
+
+ // check connect button exist
+ verifyConnectBtnSetUpAsVisible(inOrder);
+
+ // click connect button
+ mController.connectNetwork();
+
+ // check turn on Wi-Fi, display button as connecting and toast turn on Wi-Fi message
+ verify(mockWifiManager, times(1)).setWifiEnabled(true);
+ verifyConnectBtnSetUpAsConnecting(inOrder);
+ assertThat(ShadowToast.getTextOfLatestToast()).isEqualTo(
+ mContext.getString(R.string.wifi_turned_on_message));
+
+ // notify Wi-Fi enabled
+ mController.mWifiListener.onWifiStateChanged(WifiManager.WIFI_STATE_ENABLED);
+
+ // check had connect network and icon display as expected
+ verify(mockWifiManager, times(1)).connect(anyInt(), any(WifiManager.ActionListener.class));
+ verifyConnectBtnSetUpAsConnecting(inOrder);
+
+ // update as failed
+ mController.mTimer.onFinish();
+
+ // check connect button visible, be init as default and toast failed message
+ verifyConnectBtnBeInitAsDefault(inOrder);
+ inOrder.verify(mockButtonsPref, times(1)).setButton3Visible(true);
+ assertThat(ShadowToast.getTextOfLatestToast()).isEqualTo(
+ mContext.getString(R.string.wifi_failed_connect_message));
+ }
+
+ @Test
+ public void
+ testConnectButton_clickConnectWhenWiFiDisabled_failedToConnectWifiBecauseNotInRange() {
+ setUpForNotInRangeNetwork();
+ when(mockWifiManager.isWifiEnabled()).thenReturn(false); // wifi disabled
+ InOrder inOrder = inOrder(mockButtonsPref);
+ setUpForToast();
+
+ displayAndResume();
+
+ // check connect button exist
+ verifyConnectBtnSetUpAsVisible(inOrder);
+
+ // click connect button
+ mController.connectNetwork();
+
+ // check turn on Wi-Fi, display button as connecting and toast turn on Wi-Fi message
+ verify(mockWifiManager, times(1)).setWifiEnabled(true);
+ verifyConnectBtnSetUpAsConnecting(inOrder);
+ assertThat(ShadowToast.getTextOfLatestToast()).isEqualTo(
+ mContext.getString(R.string.wifi_turned_on_message));
+
+ // notify Wi-Fi enabled
+ mController.mWifiListener.onWifiStateChanged(WifiManager.WIFI_STATE_ENABLED);
+
+ // check had connect network and icon display as expected
+ verify(mockWifiManager, times(1)).connect(anyInt(), any(WifiManager.ActionListener.class));
+ verifyConnectBtnSetUpAsConnecting(inOrder);
+
+ // update as failed
+ mController.mTimer.onFinish();
+
+ // check connect button visible, be init as default and toast failed message
+ verifyConnectBtnBeInitAsDefault(inOrder);
+ inOrder.verify(mockButtonsPref, times(1)).setButton3Visible(true);
+ assertThat(ShadowToast.getTextOfLatestToast()).isEqualTo(
+ mContext.getString(R.string.wifi_not_in_range_message));
+ }
+
+ @Test
+ public void testConnectButton_clickConnectWhenWiFiDisabled_failedToEnableWifi() {
+ setUpForDisconnectedNetwork();
+ when(mockWifiManager.isWifiEnabled()).thenReturn(false); // wifi disabled
+ InOrder inOrder = inOrder(mockButtonsPref);
+ setUpForToast();
+
+ displayAndResume();
+
+ // check connect button exist
+ verifyConnectBtnSetUpAsVisible(inOrder);
+
+ // click connect button
+ mController.connectNetwork();
+
+ // check turn on Wi-Fi, display button as connecting and toast turn on Wi-Fi message
+ verify(mockWifiManager, times(1)).setWifiEnabled(true);
+ verifyConnectBtnSetUpAsConnecting(inOrder);
+ assertThat(ShadowToast.getTextOfLatestToast()).isEqualTo(
+ mContext.getString(R.string.wifi_turned_on_message));
+
+ // notify turn on Wi-Fi failed
+ mController.mTimer.onFinish();
+
+ // check connect button visible, be init as default and toast failed message
+ verifyConnectBtnBeInitAsDefault(inOrder);
+ inOrder.verify(mockButtonsPref, times(1)).setButton3Visible(true);
+ assertThat(ShadowToast.getTextOfLatestToast()).isEqualTo(
+ mContext.getString(R.string.wifi_failed_connect_message));
+ }
+
+ @Test
+ public void updateAccessPoint_returnFalseForNothingChanged() {
+ setUpForDisconnectedNetwork();
+
+ displayAndResume();
+ boolean changed = mController.updateAccessPoint();
+
+ assertThat(changed).isFalse();
+ }
+
+ @Test
+ public void updateAccessPoint_returnTrueForSignalLevelChanged() {
+ setUpForDisconnectedNetwork();
+
+ displayAndResume();
+
+ // Level changed
+ when(mockAccessPoint.getLevel()).thenReturn(LEVEL + 1);
+ boolean changed = mController.updateAccessPoint();
+
+ assertThat(changed).isTrue();
+ }
+
+ @Test
+ public void updateAccessPoint_returnTrueForChangeAsNotInRange() {
+ setUpForDisconnectedNetwork();
+
+ displayAndResume();
+
+ // change as not in range
+ when(mockAccessPoint.matches(any(AccessPoint.class))).thenReturn(false);
+ boolean changed = mController.updateAccessPoint();
+
+ assertThat(changed).isTrue();
+ }
+
+ @Test
+ public void updateAccessPoint_returnTrueForChangeAsInRange() {
+ setUpForNotInRangeNetwork();
+
+ displayAndResume();
+
+ // change as in range
+ when(mockAccessPoint.matches(any(AccessPoint.class))).thenReturn(true);
+ boolean changed = mController.updateAccessPoint();
+
+ assertThat(changed).isTrue();
+ }
+
+ @Test
+ public void updateAccessPoint_returnTrueForChangeAsConnected() {
+ setUpForDisconnectedNetwork();
+
+ displayAndResume();
+
+ // change as connected
+ when(mockAccessPoint.isActive()).thenReturn(true);
+ boolean changed = mController.updateAccessPoint();
+
+ assertThat(changed).isTrue();
+ }
+
+ @Test
+ public void updateAccessPoint_returnTrueForChangeAsDisconnected() {
+ setUpForConnectedNetwork();
+
+ displayAndResume();
+
+ // change as disconnected
+ when(mockAccessPoint.isActive()).thenReturn(false);
+ boolean changed = mController.updateAccessPoint();
+
+ assertThat(changed).isTrue();
+ }
+
+ @Test
+ public void updateAccessPoint_returnTrueForAccessPointUpdated() {
+ setUpForConnectedNetwork();
+
+ displayAndResume();
+
+ // change as disconnected
+ when(mockAccessPoint.update(mockWifiConfig, mockWifiInfo, mockNetworkInfo))
+ .thenReturn(true);
+ boolean changed = mController.updateAccessPoint();
+
+ assertThat(changed).isTrue();
+ }
+
@Test
public void testRefreshRssiViews_shouldNotUpdateIfLevelIsSameForConnectedNetwork() {
setUpForConnectedNetwork();
diff --git a/tests/robotests/src/com/android/settings/wifi/slice/ConnectToWifiHandlerTest.java b/tests/robotests/src/com/android/settings/wifi/slice/ConnectToWifiHandlerTest.java
index b18102d226d..cea8365190e 100644
--- a/tests/robotests/src/com/android/settings/wifi/slice/ConnectToWifiHandlerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/slice/ConnectToWifiHandlerTest.java
@@ -27,7 +27,6 @@ import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiConfiguration.NetworkSelectionStatus;
import android.net.wifi.WifiManager;
-import com.android.settings.testutils.shadow.ShadowConnectivityManager;
import com.android.settings.testutils.shadow.ShadowWifiManager;
import com.android.settingslib.wifi.AccessPoint;
@@ -41,13 +40,10 @@ import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
@RunWith(RobolectricTestRunner.class)
-@Config(shadows = {
- ShadowConnectivityManager.class,
- ShadowWifiManager.class,
-})
+@Config(shadows = ShadowWifiManager.class)
public class ConnectToWifiHandlerTest {
- private static final String AP1_SSID = "\"ap1\"";
+ private static final String AP_SSID = "\"ap\"";
private ConnectToWifiHandler mHandler;
private WifiConfiguration mWifiConfig;
@Mock
@@ -59,7 +55,7 @@ public class ConnectToWifiHandlerTest {
mHandler = Robolectric.setupActivity(ConnectToWifiHandler.class);
mWifiConfig = new WifiConfiguration();
- mWifiConfig.SSID = AP1_SSID;
+ mWifiConfig.SSID = AP_SSID;
doReturn(mWifiConfig).when(mAccessPoint).getConfig();
}
@@ -70,7 +66,7 @@ public class ConnectToWifiHandlerTest {
mHandler.connect(mAccessPoint);
- assertThat(ShadowWifiManager.get().savedWifiConfig.SSID).isEqualTo(AP1_SSID);
+ assertThat(ShadowWifiManager.get().savedWifiConfig.SSID).isEqualTo(AP_SSID);
}
@Test
@@ -91,7 +87,7 @@ public class ConnectToWifiHandlerTest {
mHandler.connect(mAccessPoint);
- assertThat(ShadowWifiManager.get().savedWifiConfig.SSID).isEqualTo(AP1_SSID);
+ assertThat(ShadowWifiManager.get().savedWifiConfig.SSID).isEqualTo(AP_SSID);
}
@Test
@@ -104,7 +100,7 @@ public class ConnectToWifiHandlerTest {
mHandler.connect(mAccessPoint);
- assertThat(ShadowWifiManager.get().savedWifiConfig.SSID).isEqualTo(AP1_SSID);
+ assertThat(ShadowWifiManager.get().savedWifiConfig.SSID).isEqualTo(AP_SSID);
}
@Test
diff --git a/tests/robotests/src/com/android/settings/wifi/slice/WifiScanWorkerTest.java b/tests/robotests/src/com/android/settings/wifi/slice/WifiScanWorkerTest.java
index 30e289b0550..19d3e4002ec 100644
--- a/tests/robotests/src/com/android/settings/wifi/slice/WifiScanWorkerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/slice/WifiScanWorkerTest.java
@@ -20,36 +20,54 @@ import static com.android.settings.slices.CustomSliceRegistry.WIFI_SLICE_URI;
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import android.content.ContentResolver;
import android.content.Context;
+import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkInfo;
import android.net.NetworkInfo.State;
+import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
+import android.net.wifi.WifiSsid;
import android.os.Bundle;
+import android.os.UserHandle;
import androidx.slice.SliceProvider;
import androidx.slice.widget.SliceLiveData;
+import com.android.settings.testutils.shadow.ShadowWifiManager;
import com.android.settingslib.wifi.AccessPoint;
+import com.android.settingslib.wifi.WifiTracker;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
@RunWith(RobolectricTestRunner.class)
+@Config(shadows = {
+ ShadowWifiManager.class,
+ WifiScanWorkerTest.ShadowWifiTracker.class,
+})
public class WifiScanWorkerTest {
private static final String AP_NAME = "ap";
@@ -59,6 +77,7 @@ public class WifiScanWorkerTest {
private WifiManager mWifiManager;
private ConnectivityManager mConnectivityManager;
private WifiScanWorker mWifiScanWorker;
+ private ConnectToWifiHandler mConnectToWifiHandler;
@Before
public void setUp() {
@@ -73,6 +92,12 @@ public class WifiScanWorkerTest {
mConnectivityManager = mContext.getSystemService(ConnectivityManager.class);
mWifiScanWorker = new WifiScanWorker(mContext, WIFI_SLICE_URI);
+ mConnectToWifiHandler = Robolectric.setupActivity(ConnectToWifiHandler.class);
+ }
+
+ @After
+ public void tearDown() {
+ mWifiScanWorker.clearClickedWifi();
}
@Test
@@ -131,4 +156,82 @@ public class WifiScanWorkerTest {
verify(mResolver).notifyChange(WIFI_SLICE_URI, null);
}
+
+ private AccessPoint createAccessPoint(String ssid) {
+ final AccessPoint accessPoint = mock(AccessPoint.class);
+ doReturn(ssid).when(accessPoint).getSsidStr();
+ return accessPoint;
+ }
+
+ private void setConnectionInfoSSID(String ssid) {
+ final WifiInfo wifiInfo = new WifiInfo();
+ wifiInfo.setSSID(WifiSsid.createFromAsciiEncoded(ssid));
+ ShadowWifiManager.get().setConnectionInfo(wifiInfo);
+ }
+
+ @Test
+ public void NetworkCallback_onCapabilitiesChanged_isClickedWifi_shouldStartActivity() {
+ final AccessPoint accessPoint = createAccessPoint("ap1");
+ setConnectionInfoSSID("ap1");
+ final Network network = mConnectivityManager.getActiveNetwork();
+ mWifiScanWorker.registerCaptivePortalNetworkCallback(network);
+
+ mConnectToWifiHandler.connect(accessPoint);
+ mWifiScanWorker.mCaptivePortalNetworkCallback.onCapabilitiesChanged(network,
+ WifiSliceTest.makeCaptivePortalNetworkCapabilities());
+
+ verify(mContext).startActivityAsUser(any(Intent.class), eq(UserHandle.CURRENT));
+ }
+
+ @Test
+ public void NetworkCallback_onCapabilitiesChanged_isNotClickedWifi_shouldNotStartActivity() {
+ final AccessPoint accessPoint = createAccessPoint("ap1");
+ setConnectionInfoSSID("ap2");
+ final Network network = mConnectivityManager.getActiveNetwork();
+ mWifiScanWorker.registerCaptivePortalNetworkCallback(network);
+
+ mConnectToWifiHandler.connect(accessPoint);
+ mWifiScanWorker.mCaptivePortalNetworkCallback.onCapabilitiesChanged(network,
+ WifiSliceTest.makeCaptivePortalNetworkCapabilities());
+
+ verify(mContext, never()).startActivityAsUser(any(Intent.class), eq(UserHandle.CURRENT));
+ }
+
+ @Test
+ public void NetworkCallback_onCapabilitiesChanged_neverClickWifi_shouldNotStartActivity() {
+ setConnectionInfoSSID("ap1");
+ final Network network = mConnectivityManager.getActiveNetwork();
+ mWifiScanWorker.registerCaptivePortalNetworkCallback(network);
+
+ mWifiScanWorker.mCaptivePortalNetworkCallback.onCapabilitiesChanged(network,
+ WifiSliceTest.makeCaptivePortalNetworkCapabilities());
+
+ verify(mContext, never()).startActivityAsUser(any(Intent.class), eq(UserHandle.CURRENT));
+ }
+
+ @Test
+ public void NetworkCallback_onCapabilitiesChanged_sliceIsUnpinned_shouldNotStartActivity() {
+ final AccessPoint accessPoint = createAccessPoint("ap1");
+ setConnectionInfoSSID("ap1");
+ final Network network = mConnectivityManager.getActiveNetwork();
+ mWifiScanWorker.registerCaptivePortalNetworkCallback(network);
+ final WifiScanWorker.CaptivePortalNetworkCallback callback =
+ mWifiScanWorker.mCaptivePortalNetworkCallback;
+
+ mWifiScanWorker.onSlicePinned();
+ mConnectToWifiHandler.connect(accessPoint);
+ mWifiScanWorker.onSliceUnpinned();
+ callback.onCapabilitiesChanged(network,
+ WifiSliceTest.makeCaptivePortalNetworkCapabilities());
+
+ verify(mContext, never()).startActivityAsUser(any(Intent.class), eq(UserHandle.CURRENT));
+ }
+
+ @Implements(WifiTracker.class)
+ public static class ShadowWifiTracker {
+ @Implementation
+ public void onStart() {
+ // do nothing
+ }
+ }
}