Snap for 5499134 from 0014cd721e to qt-release
Change-Id: Id3cc81df305988d3fa4190ad64acb6bedf1c872f
This commit is contained in:
@@ -14,33 +14,68 @@
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<LinearLayout
|
||||
<RelativeLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="horizontal"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingEnd="16dp"
|
||||
android:paddingStart="16dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/title"/>
|
||||
|
||||
<Space
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"/>
|
||||
android:layout_height="wrap_content"
|
||||
style="?attr/face_layout_theme">
|
||||
|
||||
<!-- Top divider -->
|
||||
<View
|
||||
android:layout_width="1dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="?android:attr/listDivider" />
|
||||
|
||||
<!-- Title -->
|
||||
<com.google.android.setupdesign.view.RichTextView
|
||||
style="@style/SudDescription.Glif"
|
||||
android:id="@+id/title"
|
||||
android:paddingHorizontal="8dp"
|
||||
android:paddingTop="8dp"
|
||||
android:gravity="start"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_toLeftOf="@+id/toggle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<!-- Subtitle -->
|
||||
<TextView
|
||||
android:id="@+id/subtitle"
|
||||
android:paddingHorizontal="8dp"
|
||||
android:paddingBottom="8dp"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_toLeftOf="@+id/toggle"
|
||||
android:layout_below="@+id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/security_settings_face_enroll_introduction_accessibility_expanded"/>
|
||||
|
||||
<!-- Vertical divider -->
|
||||
<View
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_alignTop="@+id/toggle"
|
||||
android:layout_alignBottom="@+id/toggle"
|
||||
android:layout_toStartOf="@+id/toggle"
|
||||
android:layout_width="1dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?android:attr/listDivider" />
|
||||
|
||||
<!-- Toggle -->
|
||||
<Switch
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/toggle"
|
||||
android:layout_centerVertical="true"
|
||||
android:checked="true"/>
|
||||
|
||||
</LinearLayout>
|
||||
<!-- Bottom divider -->
|
||||
<View
|
||||
android:layout_below="@+id/subtitle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="?android:attr/listDivider" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
@@ -77,6 +77,7 @@
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<Button
|
||||
android:id="@+id/accessibility_button"
|
||||
style="@style/SudGlifButton.Secondary"
|
||||
@@ -89,7 +90,7 @@
|
||||
android:id="@+id/toggle_diversity"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="invisible"
|
||||
android:visibility="gone"
|
||||
FaceEnrollAccessibilitySwitch:messageText="@string/security_settings_face_enroll_introduction_accessibility_diversity"/>
|
||||
|
||||
</FrameLayout>
|
||||
@@ -101,7 +102,7 @@
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:layout_marginTop="24dp">
|
||||
android:paddingTop="24dp">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
|
||||
@@ -890,6 +890,8 @@
|
||||
<string name="security_settings_face_preference_title">Face authentication</string>
|
||||
<!-- Button shown which shows accessibility toggles for face enrollment when clicked. [CHAR LIMIT=32] -->
|
||||
<string name="security_settings_face_enroll_introduction_accessibility">Use accessibility setup</string>
|
||||
<!-- Additional details shown when the accessibility toggle is expanded. [CHAR LIMIT=NONE]-->
|
||||
<string name="security_settings_face_enroll_introduction_accessibility_expanded"></string>
|
||||
<!-- Message shown for a toggle which when enabled, allows the user to enroll using a simpler flow for accessibility [CHAR LIMIT=NONE] -->
|
||||
<string name="security_settings_face_enroll_introduction_accessibility_diversity"></string>
|
||||
<!-- Message shown for a toggle which when enabled, allows the user to enroll using a simpler flow for accessibility [CHAR LIMIT=NONE] -->
|
||||
@@ -2203,10 +2205,10 @@
|
||||
<string name="wifi_dpp_wifi_password">Wi\u2011Fi password: <xliff:g id="password" example="my password">%1$s</xliff:g></string>
|
||||
<!-- Hint for Wi-Fi hotspot password [CHAR LIMIT=50] -->
|
||||
<string name="wifi_dpp_hotspot_password">Hotspot password: <xliff:g id="password" example="my password">%1$s</xliff:g></string>
|
||||
<!-- Label for "Connect to this network using a QR code" [CHAR LIMIT=50] -->
|
||||
<!-- Label for "Use a QR code to add a device to this network" [CHAR LIMIT=50] -->
|
||||
<string name="wifi_dpp_add_device">Add device</string>
|
||||
<!-- Hint for "Add device" [CHAR LIMIT=NONE] -->
|
||||
<string name="wifi_dpp_connect_network_using_qr_code">Connect to this network using a QR code</string>
|
||||
<string name="wifi_dpp_connect_network_using_qr_code">Use a QR code to add a device to this network</string>
|
||||
<!-- Label for the try again button [CHAR LIMIT=20]-->
|
||||
<string name="retry">Retry</string>
|
||||
<!-- Label for the check box to share a network with other users on the same device -->
|
||||
@@ -7652,19 +7654,19 @@
|
||||
<string name="zen_mode_sound_summary_on">On</string>
|
||||
|
||||
<!-- Do not disturb: Summary for zen mode duration setting indicating user will be prompted to set dnd duration whenever dnd is manually toggled on [CHAR LIMIT=NONE]-->
|
||||
<string name="zen_mode_duration_summary_always_prompt">Ask every time (unless turned on automatically)</string>
|
||||
<string name="zen_mode_duration_summary_always_prompt">Ask every time</string>
|
||||
|
||||
<!-- Do not disturb: Summary for zen mode duration setting indicating how long dnd will last when dnd is manually toggled on [CHAR LIMIT=NONE] -->
|
||||
<string name="zen_mode_duration_summary_forever">Until you turn off (unless turned on automatically)</string>
|
||||
<string name="zen_mode_duration_summary_forever">Until you turn off</string>
|
||||
|
||||
<!-- Do not disturb: Summary for zen mode duration setting indicating how long dnd will last when dnd is manually toggled on [CHAR LIMIT=NONE] -->
|
||||
<plurals name="zen_mode_duration_summary_time_hours">
|
||||
<item quantity="one">1 hour (unless turned on automatically)</item>
|
||||
<item quantity="other"><xliff:g id="num_hours" example="3">%d</xliff:g> hours (unless turned on automatically)</item>
|
||||
<item quantity="one">1 hour</item>
|
||||
<item quantity="other"><xliff:g id="num_hours" example="3">%d</xliff:g> hours</item>
|
||||
</plurals>
|
||||
|
||||
<!-- Do not disturb: Summary for zen mode duration setting indicating how long dnd will last when toggled on -->
|
||||
<string name="zen_mode_duration_summary_time_minutes"><xliff:g id="num_minutes" example="5">%d</xliff:g> minutes (unless turned on automatically)</string>
|
||||
<string name="zen_mode_duration_summary_time_minutes"><xliff:g id="num_minutes" example="5">%d</xliff:g> minutes</string>
|
||||
|
||||
<!-- Summary for the Sound Do not Disturb option when at least one automatic rules is enabled. [CHAR LIMIT=NONE]-->
|
||||
<plurals name="zen_mode_sound_summary_summary_off_info">
|
||||
|
||||
@@ -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<Bundle>() {
|
||||
@Override
|
||||
public void run(AccountManagerFuture<Bundle> 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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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<ContextualCard> {
|
||||
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<ContextualCard> {
|
||||
}
|
||||
|
||||
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<ContextualCard> {
|
||||
}
|
||||
return returnSlice[0];
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
boolean isSliceToggleable(Slice slice) {
|
||||
final SliceMetadata metadata = SliceMetadata.from(mContext, slice);
|
||||
final List<SliceAction> toggles = metadata.getToggles();
|
||||
|
||||
return !toggles.isEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ public class MobileNetworkListController extends AbstractPreferenceController im
|
||||
mPreferences = new ArrayMap<>();
|
||||
|
||||
final List<SubscriptionInfo> subscriptions = SubscriptionUtil.getAvailableSubscriptions(
|
||||
mSubscriptionManager);
|
||||
mContext);
|
||||
for (SubscriptionInfo info : subscriptions) {
|
||||
final int subId = info.getSubscriptionId();
|
||||
Preference pref = existingPreferences.remove(subId);
|
||||
|
||||
@@ -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<SubscriptionInfo> 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<SubscriptionInfo> 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;
|
||||
});
|
||||
|
||||
@@ -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<SubscriptionInfo> sAvailableResultsForTesting;
|
||||
private static List<SubscriptionInfo> sActiveResultsForTesting;
|
||||
|
||||
@@ -44,21 +52,56 @@ public class SubscriptionUtil {
|
||||
if (sActiveResultsForTesting != null) {
|
||||
return sActiveResultsForTesting;
|
||||
}
|
||||
List<SubscriptionInfo> subscriptions = manager.getActiveSubscriptionInfoList(true);
|
||||
final List<SubscriptionInfo> subscriptions = manager.getActiveSubscriptionInfoList(true);
|
||||
if (subscriptions == null) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
return subscriptions;
|
||||
}
|
||||
|
||||
public static List<SubscriptionInfo> getAvailableSubscriptions(SubscriptionManager manager) {
|
||||
private static boolean isInactiveInsertedPSim(UiccSlotInfo slotInfo) {
|
||||
return !slotInfo.getIsEuicc() && !slotInfo.getIsActive() &&
|
||||
slotInfo.getCardStateInfo() == CARD_STATE_INFO_PRESENT;
|
||||
}
|
||||
|
||||
public static List<SubscriptionInfo> getAvailableSubscriptions(Context context) {
|
||||
if (sAvailableResultsForTesting != null) {
|
||||
return sAvailableResultsForTesting;
|
||||
}
|
||||
List<SubscriptionInfo> subscriptions = manager.getSelectableSubscriptionInfoList();
|
||||
if (subscriptions == null) {
|
||||
subscriptions = new ArrayList<>();
|
||||
final SubscriptionManager subMgr = context.getSystemService(SubscriptionManager.class);
|
||||
final TelephonyManager telMgr = context.getSystemService(TelephonyManager.class);
|
||||
|
||||
List<SubscriptionInfo> subscriptions =
|
||||
new ArrayList<>(emptyIfNull(subMgr.getSelectableSubscriptionInfoList()));
|
||||
|
||||
// Look for inactive but present physical SIMs that are missing from the selectable list.
|
||||
final List<UiccSlotInfo> 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.
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -94,8 +94,9 @@ public class MobileNetworkSwitchController extends BasePreferenceController impl
|
||||
return;
|
||||
}
|
||||
final List<SubscriptionInfo> 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;
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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<AccessPoint> 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<AccessPoint> implement
|
||||
protected void onSliceUnpinned() {
|
||||
mWifiTracker.onStop();
|
||||
unregisterCaptivePortalNetworkCallback();
|
||||
clearClickedWifi();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -146,6 +150,19 @@ public class WifiScanWorker extends SliceBackgroundWorker<AccessPoint> 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<AccessPoint> 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<AccessPoint> 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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
|
||||
|
||||
88
tests/robotests/res/values/overlayable_icons_test.xml
Normal file
88
tests/robotests/res/values/overlayable_icons_test.xml
Normal file
@@ -0,0 +1,88 @@
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<resources>
|
||||
<!-- overlayable_icons references all of the drawables in this package
|
||||
that are being overlayed by resource overlays. If you remove/rename
|
||||
any of these resources, you must also change the resource overlay icons.-->
|
||||
<array name="overlayable_icons">
|
||||
<item>@drawable/drag_handle</item>
|
||||
<item>@drawable/ic_add_24dp</item>
|
||||
<item>@drawable/ic_airplanemode_active</item>
|
||||
<item>@drawable/ic_android</item>
|
||||
<item>@drawable/ic_apps</item>
|
||||
<item>@drawable/ic_arrow_back</item>
|
||||
<item>@drawable/ic_battery_charging_full</item>
|
||||
<item>@drawable/ic_battery_saver_accent_24dp</item>
|
||||
<item>@drawable/ic_battery_status_bad_24dp</item>
|
||||
<item>@drawable/ic_battery_status_good_24dp</item>
|
||||
<item>@drawable/ic_battery_status_maybe_24dp</item>
|
||||
<item>@drawable/ic_call_24dp</item>
|
||||
<item>@drawable/ic_cancel</item>
|
||||
<item>@drawable/ic_cast_24dp</item>
|
||||
<item>@drawable/ic_cellular_off</item>
|
||||
<item>@drawable/ic_content_copy_grey600_24dp</item>
|
||||
<item>@drawable/ic_data_saver</item>
|
||||
<item>@drawable/ic_delete</item>
|
||||
<item>@drawable/ic_delete_accent</item>
|
||||
<item>@drawable/ic_devices_other</item>
|
||||
<item>@drawable/ic_devices_other_opaque_black</item>
|
||||
<item>@drawable/ic_do_not_disturb_on_24dp</item>
|
||||
<item>@drawable/ic_eject_24dp</item>
|
||||
<item>@drawable/ic_expand_less</item>
|
||||
<item>@drawable/ic_expand_more_inverse</item>
|
||||
<item>@drawable/ic_folder_vd_theme_24</item>
|
||||
<item>@drawable/ic_friction_lock_closed</item>
|
||||
<item>@drawable/ic_gray_scale_24dp</item>
|
||||
<item>@drawable/ic_headset_24dp</item>
|
||||
<item>@drawable/ic_help</item>
|
||||
<item>@drawable/ic_homepage_search</item>
|
||||
<item>@drawable/ic_local_movies</item>
|
||||
<item>@drawable/ic_local_phone_24_lib</item>
|
||||
<item>@drawable/ic_lock</item>
|
||||
<item>@drawable/ic_media_stream</item>
|
||||
<item>@drawable/ic_media_stream_off</item>
|
||||
<item>@drawable/ic_network_cell</item>
|
||||
<item>@drawable/ic_notifications</item>
|
||||
<item>@drawable/ic_notifications_off_24dp</item>
|
||||
<item>@drawable/ic_phone_info</item>
|
||||
<item>@drawable/ic_photo_library</item>
|
||||
<item>@drawable/ic_settings_accessibility</item>
|
||||
<item>@drawable/ic_settings_accounts</item>
|
||||
<item>@drawable/ic_settings_battery_white</item>
|
||||
<item>@drawable/ic_settings_data_usage</item>
|
||||
<item>@drawable/ic_settings_date_time</item>
|
||||
<item>@drawable/ic_settings_delete</item>
|
||||
<item>@drawable/ic_settings_display_white</item>
|
||||
<item>@drawable/ic_settings_home</item>
|
||||
<item>@drawable/ic_settings_location</item>
|
||||
<item>@drawable/ic_settings_night_display</item>
|
||||
<item>@drawable/ic_settings_open</item>
|
||||
<item>@drawable/ic_settings_print</item>
|
||||
<item>@drawable/ic_settings_privacy</item>
|
||||
<item>@drawable/ic_settings_security_white</item>
|
||||
<item>@drawable/ic_settings_sim</item>
|
||||
<item>@drawable/ic_settings_system_dashboard_white</item>
|
||||
<item>@drawable/ic_settings_wireless</item>
|
||||
<item>@drawable/ic_settings_wireless_white</item>
|
||||
<item>@drawable/ic_storage_white</item>
|
||||
<item>@drawable/ic_suggestion_night_display</item>
|
||||
<item>@drawable/ic_videogame_vd_theme_24</item>
|
||||
<item>@drawable/ic_volume_ringer_vibrate</item>
|
||||
<item>@drawable/ic_volume_up_24dp</item>
|
||||
<item>@drawable/ic_vpn_key</item>
|
||||
<item>@drawable/ic_wifi_tethering</item>
|
||||
</array>
|
||||
</resources>
|
||||
@@ -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<AccountManagerCallback<Bundle>> callbackCaptor = ArgumentCaptor.forClass(
|
||||
AccountManagerCallback.class);
|
||||
verify(mAccountManager).removeAccountAsUser(eq(account), nullable(Activity.class),
|
||||
callbackCaptor.capture(), nullable(Handler.class), eq(userHandle));
|
||||
|
||||
AccountManagerCallback<Bundle> callback = callbackCaptor.getValue();
|
||||
assertThat(callback).isNotNull();
|
||||
AccountManagerFuture<Bundle> 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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<ContextualCard> 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<ContextualCard> getContextualCardList() {
|
||||
final List<ContextualCard> cards = new ArrayList<>();
|
||||
cards.add(new ContextualCard.Builder()
|
||||
|
||||
@@ -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<ContextualCard> mOldCards;
|
||||
private List<ContextualCard> 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();
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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<Intent> 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
|
||||
|
||||
@@ -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<SubscriptionInfo> subs = SubscriptionUtil.getAvailableSubscriptions(mManager);
|
||||
when(mSubMgr.getSelectableSubscriptionInfoList()).thenReturn(null);
|
||||
final List<SubscriptionInfo> 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<SubscriptionInfo> subs = SubscriptionUtil.getAvailableSubscriptions(mManager);
|
||||
when(mSubMgr.getSelectableSubscriptionInfoList()).thenReturn(Arrays.asList(info));
|
||||
final List<SubscriptionInfo> 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<SubscriptionInfo> subs = SubscriptionUtil.getAvailableSubscriptions(mManager);
|
||||
when(mSubMgr.getSelectableSubscriptionInfoList()).thenReturn(Arrays.asList(info1, info2));
|
||||
final List<SubscriptionInfo> 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<SubscriptionInfo> subs = SubscriptionUtil.getAvailableSubscriptions(mManager);
|
||||
final List<SubscriptionInfo> 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<SubscriptionInfo> subs = SubscriptionUtil.getAvailableSubscriptions(mManager);
|
||||
final List<SubscriptionInfo> 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<SubscriptionInfo> 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<SubscriptionInfo> 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<SubscriptionInfo> subs = SubscriptionUtil.getActiveSubscriptions(mManager);
|
||||
when(mSubMgr.getActiveSubscriptionInfoList(anyBoolean())).thenReturn(null);
|
||||
final List<SubscriptionInfo> 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<SubscriptionInfo> subs = SubscriptionUtil.getActiveSubscriptions(mManager);
|
||||
when(mSubMgr.getActiveSubscriptionInfoList(anyBoolean())).thenReturn(Arrays.asList(info));
|
||||
final List<SubscriptionInfo> 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<SubscriptionInfo> subs = SubscriptionUtil.getActiveSubscriptions(mManager);
|
||||
final List<SubscriptionInfo> subs = SubscriptionUtil.getActiveSubscriptions(mSubMgr);
|
||||
assertThat(subs).isNotNull();
|
||||
assertThat(subs).hasSize(2);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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<FakeSettingsPanelActivity> 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,
|
||||
|
||||
@@ -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
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<MediaController> 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<Uri> 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<Uri> 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();
|
||||
|
||||
@@ -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<WifiManager.ActionListener> 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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user