Snap for 5499134 from 0014cd721e to qt-release

Change-Id: Id3cc81df305988d3fa4190ad64acb6bedf1c872f
This commit is contained in:
android-build-team Robot
2019-04-24 03:06:19 +00:00
36 changed files with 1433 additions and 286 deletions

View File

@@ -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>

View File

@@ -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"

View File

@@ -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">

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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

View File

@@ -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();
}
}
}

View File

@@ -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);
}

View File

@@ -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));
}
}

View File

@@ -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();
}
}

View File

@@ -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);

View File

@@ -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;
});

View File

@@ -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.

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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) {

View File

@@ -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:

View File

@@ -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;

View File

@@ -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:

View File

@@ -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);
}
}
/**

View File

@@ -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

View 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>

View File

@@ -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();
}
}

View File

@@ -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()

View File

@@ -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();
}
}

View File

@@ -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();
}
}

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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);

View File

@@ -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,

View File

@@ -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
);
}
}

View File

@@ -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();

View File

@@ -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();

View File

@@ -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

View File

@@ -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
}
}
}