diff --git a/res/layout/preference_animated_image.xml b/res/layout/preference_animated_image.xml index 305b03630e1..e7d9b52518a 100644 --- a/res/layout/preference_animated_image.xml +++ b/res/layout/preference_animated_image.xml @@ -24,9 +24,10 @@ diff --git a/res/values/strings.xml b/res/values/strings.xml index 6897c656dea..9bc9b5e26be 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -4945,7 +4945,7 @@ Use accessibility button to open - Hold volume key to open + Hold volume keys to open Triple tap screen to open @@ -4953,19 +4953,19 @@ Use new accessibility gesture - To turn this feature on or off, tap the accessibility button %s on the bottom of your screen.\n\nTo switch between features, touch & hold the accessibility button. + To use this feature, tap the accessibility button %s on the bottom of your screen.\n\nTo switch between features, touch & hold the accessibility button. - To turn this feature on or off, press & hold both volume keys. + To use this feature, press & hold both volume keys. To start and stop magnification, triple-tap anywhere on your screen. - To turn this feature on or off, swipe up from the bottom of the screen with 2 fingers.\n\nTo switch between features, swipe up with 2 fingers and hold. + To use this feature, swipe up from the bottom of the screen with 2 fingers.\n\nTo switch between features, swipe up with 2 fingers and hold. - To turn this feature on or off, swipe up from the bottom of the screen with 3 fingers.\n\nTo switch between features, swipe up with 3 fingers and hold. + To use this feature, swipe up from the bottom of the screen with 3 fingers.\n\nTo switch between features, swipe up with 3 fingers and hold. - To turn an accessibility feature on or off, swipe up from the bottom of the screen with 2 fingers.\n\nTo switch between features, swipe up with 2 fingers and hold. + To use an accessibility feature, swipe up from the bottom of the screen with 2 fingers.\n\nTo switch between features, swipe up with 2 fingers and hold. - To turn an accessibility feature on or off, swipe up from the bottom of the screen with 3 fingers.\n\nTo switch between features, swipe up with 3 fingers and hold. + To use an accessibility feature, swipe up from the bottom of the screen with 3 fingers.\n\nTo switch between features, swipe up with 3 fingers and hold. Got it @@ -7312,6 +7312,9 @@ Send & receive when mobile data is off + + com.android.cellbroadcastreceiver + @@ -7485,6 +7488,14 @@ Bluetooth, NFC Bluetooth + + Bluetooth, Android Auto, driving mode, NFC + Bluetooth, Android Auto, driving mode + + Bluetooth, Android Auto, NFC + + Bluetooth, Android Auto Unavailable because NFC is off diff --git a/res/xml/app_and_notification.xml b/res/xml/app_and_notification.xml index f75bd8629ae..b49918024a3 100644 --- a/res/xml/app_and_notification.xml +++ b/res/xml/app_and_notification.xml @@ -82,7 +82,7 @@ settings:useAdminDisabledSummary="true"> diff --git a/src/com/android/settings/accessibility/AnimatedImagePreference.java b/src/com/android/settings/accessibility/AnimatedImagePreference.java index 61e439f6ca5..2ca13f33fe2 100644 --- a/src/com/android/settings/accessibility/AnimatedImagePreference.java +++ b/src/com/android/settings/accessibility/AnimatedImagePreference.java @@ -60,7 +60,7 @@ public class AnimatedImagePreference extends Preference { } if (mMaxHeight > -1) { - imageView.setMaxWidth(mMaxHeight); + imageView.setMaxHeight(mMaxHeight); } } diff --git a/src/com/android/settings/applications/appinfo/AppInstallerInfoPreferenceController.java b/src/com/android/settings/applications/appinfo/AppInstallerInfoPreferenceController.java index bf8567684ec..2e119537a2c 100644 --- a/src/com/android/settings/applications/appinfo/AppInstallerInfoPreferenceController.java +++ b/src/com/android/settings/applications/appinfo/AppInstallerInfoPreferenceController.java @@ -42,6 +42,11 @@ public class AppInstallerInfoPreferenceController extends AppInfoPreferenceContr if (UserManager.get(mContext).isManagedProfile()) { return DISABLED_FOR_USER; } + + if (AppUtils.isMainlineModule(mContext, mPackageName)) { + return DISABLED_FOR_USER; + } + return mInstallerLabel != null ? AVAILABLE : DISABLED_FOR_USER; } diff --git a/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceController.java b/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceController.java index 26c3e345558..2855f0ab16a 100644 --- a/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceController.java +++ b/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceController.java @@ -15,7 +15,10 @@ */ package com.android.settings.connecteddevice; +import static com.android.settingslib.drawer.TileUtils.IA_SETTINGS_ACTION; + import android.content.Context; +import android.content.Intent; import android.provider.Settings; import androidx.annotation.VisibleForTesting; @@ -31,6 +34,7 @@ public class AdvancedConnectedDeviceController extends BasePreferenceController private static final String DRIVING_MODE_SETTINGS_ENABLED = "gearhead:driving_mode_settings_enabled"; + private static final String GEARHEAD_PACKAGE = "com.google.android.projection.gearhead"; public AdvancedConnectedDeviceController(Context context, String preferenceKey) { super(context, preferenceKey); @@ -55,7 +59,7 @@ public class AdvancedConnectedDeviceController extends BasePreferenceController new NfcPreferenceController(context, NfcPreferenceController.KEY_TOGGLE_NFC); return getConnectedDevicesSummaryResourceId(nfcPreferenceController, - isDrivingModeAvailable(context)); + isDrivingModeAvailable(context), isAndroidAutoSettingAvailable(context)); } @VisibleForTesting @@ -64,26 +68,57 @@ public class AdvancedConnectedDeviceController extends BasePreferenceController getInt(context.getContentResolver(), DRIVING_MODE_SETTINGS_ENABLED, 0) == 1; } + @VisibleForTesting + static boolean isAndroidAutoSettingAvailable(Context context) { + final Intent intent = new Intent(IA_SETTINGS_ACTION); + intent.setPackage(GEARHEAD_PACKAGE); + return intent.resolveActivity(context.getPackageManager()) != null; + } + @VisibleForTesting static int getConnectedDevicesSummaryResourceId(NfcPreferenceController - nfcPreferenceController, boolean isDrivingModeAvailable) { + nfcPreferenceController, + boolean isDrivingModeAvailable, + boolean isAndroidAutoAvailable) { final int resId; - if (nfcPreferenceController.isAvailable()) { - if (isDrivingModeAvailable) { - // NFC available, driving mode available - resId = R.string.connected_devices_dashboard_summary; + if (isAndroidAutoAvailable) { + if (nfcPreferenceController.isAvailable()) { + if (isDrivingModeAvailable) { + // NFC available, driving mode available + resId = R.string.connected_devices_dashboard_android_auto_summary; + } else { + // NFC available, driving mode not available + resId = + R.string.connected_devices_dashboard_android_auto_no_driving_mode_summary; + } } else { - // NFC available, driving mode not available - resId = R.string.connected_devices_dashboard_no_driving_mode_summary; + if (isDrivingModeAvailable) { + // NFC not available, driving mode available + resId = R.string.connected_devices_dashboard_android_auto_no_nfc_summary; + } else { + // NFC not available, driving mode not available + resId = + R.string.connected_devices_dashboard_android_auto_no_nfc_no_driving_mode; + } } } else { - if (isDrivingModeAvailable) { - // NFC not available, driving mode available - resId = R.string.connected_devices_dashboard_no_nfc_summary; + if (nfcPreferenceController.isAvailable()) { + if (isDrivingModeAvailable) { + // NFC available, driving mode available + resId = R.string.connected_devices_dashboard_summary; + } else { + // NFC available, driving mode not available + resId = R.string.connected_devices_dashboard_no_driving_mode_summary; + } } else { - // NFC not available, driving mode not available - resId = R.string.connected_devices_dashboard_no_driving_mode_no_nfc_summary; + if (isDrivingModeAvailable) { + // NFC not available, driving mode available + resId = R.string.connected_devices_dashboard_no_nfc_summary; + } else { + // NFC not available, driving mode not available + resId = R.string.connected_devices_dashboard_no_driving_mode_no_nfc_summary; + } } } diff --git a/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogController.java b/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogController.java index f9aef2cd41e..fc6811a81a9 100644 --- a/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogController.java +++ b/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogController.java @@ -61,9 +61,11 @@ import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.core.lifecycle.LifecycleObserver; import com.android.settingslib.core.lifecycle.events.OnPause; import com.android.settingslib.core.lifecycle.events.OnResume; +import com.android.settingslib.utils.ThreadUtils; import java.util.List; import java.util.Map; +import java.util.concurrent.atomic.AtomicReference; public class SimStatusDialogController implements LifecycleObserver, OnResume, OnPause { @@ -218,7 +220,7 @@ public class SimStatusDialogController implements LifecycleObserver, OnResume, O } public void initialize() { - updateEid(); + requestForUpdateEid(); if (mSubscriptionInfo == null) { return; @@ -560,25 +562,33 @@ public class SimStatusDialogController implements LifecycleObserver, OnResume, O } } - private void updateEid() { + @VisibleForTesting + void requestForUpdateEid() { + ThreadUtils.postOnBackgroundThread(() -> { + final AtomicReference eid = getEid(mSlotIndex); + ThreadUtils.postOnMainThread(() -> updateEid(eid)); + }); + } + + @VisibleForTesting + AtomicReference getEid(int slotIndex) { boolean shouldHaveEid = false; String eid = null; - if (mTelephonyManager.getActiveModemCount() > MAX_PHONE_COUNT_SINGLE_SIM) { // Get EID per-SIM in multi-SIM mode - Map mapping = mTelephonyManager.getLogicalToPhysicalSlotMapping(); - int pSlotId = mapping.getOrDefault(mSlotIndex, + final Map mapping = mTelephonyManager + .getLogicalToPhysicalSlotMapping(); + final int pSlotId = mapping.getOrDefault(slotIndex, SubscriptionManager.INVALID_SIM_SLOT_INDEX); if (pSlotId != SubscriptionManager.INVALID_SIM_SLOT_INDEX) { - List infos = mTelephonyManager.getUiccCardsInfo(); + final List infos = mTelephonyManager.getUiccCardsInfo(); for (UiccCardInfo info : infos) { if (info.getSlotIndex() == pSlotId) { if (info.isEuicc()) { shouldHaveEid = true; eid = info.getEid(); - if (TextUtils.isEmpty(eid)) { eid = mEuiccManager.createForCardId(info.getCardId()).getEid(); } @@ -592,12 +602,19 @@ public class SimStatusDialogController implements LifecycleObserver, OnResume, O shouldHaveEid = true; eid = mEuiccManager.getEid(); } + if ((!shouldHaveEid) && (eid == null)) { + return null; + } + return new AtomicReference(eid); + } - if (!shouldHaveEid) { + @VisibleForTesting + void updateEid(AtomicReference eid) { + if (eid == null) { mDialog.removeSettingFromScreen(EID_INFO_LABEL_ID); mDialog.removeSettingFromScreen(EID_INFO_VALUE_ID); - } else if (!TextUtils.isEmpty(eid)) { - mDialog.setText(EID_INFO_VALUE_ID, eid); + } else if (eid.get() != null) { + mDialog.setText(EID_INFO_VALUE_ID, eid.get()); } } diff --git a/src/com/android/settings/gestures/PowerMenuPrivacyPreferenceController.java b/src/com/android/settings/gestures/PowerMenuPrivacyPreferenceController.java index 29c6176a4f8..ec88ddc01cf 100644 --- a/src/com/android/settings/gestures/PowerMenuPrivacyPreferenceController.java +++ b/src/com/android/settings/gestures/PowerMenuPrivacyPreferenceController.java @@ -86,7 +86,7 @@ public class PowerMenuPrivacyPreferenceController extends TogglePreferenceContro final ContentResolver resolver = mContext.getContentResolver(); boolean cardsAvailable = Settings.Secure.getInt(resolver, CARDS_AVAILABLE_KEY, 0) != 0; boolean cardsEnabled = Settings.Secure.getInt(resolver, CARDS_ENABLED_KEY, 0) != 0; - boolean controlsEnabled = Settings.Secure.getInt(resolver, CONTROLS_ENABLED_KEY, 0) != 0; + boolean controlsEnabled = Settings.Secure.getInt(resolver, CONTROLS_ENABLED_KEY, 1) != 0; return (cardsAvailable && cardsEnabled) || controlsEnabled; } diff --git a/src/com/android/settings/network/ActiveSubsciptionsListener.java b/src/com/android/settings/network/ActiveSubsciptionsListener.java index 3d150258418..26f644145b2 100644 --- a/src/com/android/settings/network/ActiveSubsciptionsListener.java +++ b/src/com/android/settings/network/ActiveSubsciptionsListener.java @@ -62,6 +62,7 @@ public abstract class ActiveSubsciptionsListener private BroadcastReceiver mSubscriptionChangeReceiver; private static final int MAX_SUBSCRIPTION_UNKNOWN = -1; + private final int mTargetSubscriptionId; private AtomicInteger mMaxActiveSubscriptionInfos; private List mCachedActiveSubscriptionInfo; @@ -73,9 +74,21 @@ public abstract class ActiveSubsciptionsListener * @param context {@code Context} of this listener */ public ActiveSubsciptionsListener(Looper looper, Context context) { + this(looper, context, SubscriptionManager.INVALID_SUBSCRIPTION_ID); + } + + /** + * Constructor + * + * @param looper {@code Looper} of this listener + * @param context {@code Context} of this listener + * @param subscriptionId for subscription on this listener + */ + public ActiveSubsciptionsListener(Looper looper, Context context, int subscriptionId) { super(looper); mLooper = looper; mContext = context; + mTargetSubscriptionId = subscriptionId; mCacheState = new AtomicInteger(STATE_NOT_LISTENING); mMaxActiveSubscriptionInfos = new AtomicInteger(MAX_SUBSCRIPTION_UNKNOWN); @@ -108,6 +121,12 @@ public abstract class ActiveSubsciptionsListener if (!clearCachedSubId(subId)) { return; } + if (SubscriptionManager.isValidSubscriptionId(mTargetSubscriptionId)) { + if (SubscriptionManager.isValidSubscriptionId(subId) + && (mTargetSubscriptionId != subId)) { + return; + } + } } onSubscriptionsChanged(); } diff --git a/src/com/android/settings/network/telephony/AbstractMobileNetworkSettings.java b/src/com/android/settings/network/telephony/AbstractMobileNetworkSettings.java index e92cdfcd9d1..aa84cc14acd 100644 --- a/src/com/android/settings/network/telephony/AbstractMobileNetworkSettings.java +++ b/src/com/android/settings/network/telephony/AbstractMobileNetworkSettings.java @@ -16,7 +16,9 @@ package com.android.settings.network.telephony; +import android.os.SystemClock; import android.text.TextUtils; +import android.util.Log; import androidx.preference.Preference; import androidx.preference.PreferenceScreen; @@ -34,6 +36,7 @@ abstract class AbstractMobileNetworkSettings extends RestrictedDashboardFragment private List mHiddenControllerList = new ArrayList(); + private boolean mIsRedrawRequired; /** * @param restrictionKey The restriction key to check before pin protecting @@ -52,6 +55,15 @@ abstract class AbstractMobileNetworkSettings extends RestrictedDashboardFragment return result; } + Preference searchForPreference(PreferenceScreen screen, + AbstractPreferenceController controller) { + final String key = controller.getPreferenceKey(); + if (TextUtils.isEmpty(key)) { + return null; + } + return screen.findPreference(key); + } + TelephonyStatusControlSession setTelephonyAvailabilityStatus( Collection listOfPrefControllers) { return (new TelephonyStatusControlSession.Builder(listOfPrefControllers)) @@ -78,26 +90,60 @@ abstract class AbstractMobileNetworkSettings extends RestrictedDashboardFragment protected void updatePreferenceStates() { mHiddenControllerList.clear(); + if (mIsRedrawRequired) { + redrawPreferenceControllers(); + return; + } + final PreferenceScreen screen = getPreferenceScreen(); - getPreferenceControllersAsList().forEach(controller -> { - final String key = controller.getPreferenceKey(); - if (TextUtils.isEmpty(key)) { - return; - } - final Preference preference = screen.findPreference(key); - if (preference == null) { - return; - } - if (!isPreferenceExpanded(preference)) { - mHiddenControllerList.add(controller); - return; - } - if (!controller.isAvailable()) { - return; - } - controller.updateState(preference); - }); + getPreferenceControllersAsList().forEach(controller -> + updateVisiblePreferenceControllers(screen, controller)); } + private void updateVisiblePreferenceControllers(PreferenceScreen screen, + AbstractPreferenceController controller) { + final Preference preference = searchForPreference(screen, controller); + if (preference == null) { + return; + } + if (!isPreferenceExpanded(preference)) { + mHiddenControllerList.add(controller); + return; + } + if (!controller.isAvailable()) { + return; + } + controller.updateState(preference); + } + + void redrawPreferenceControllers() { + mHiddenControllerList.clear(); + + if (!isResumed()) { + mIsRedrawRequired = true; + return; + } + mIsRedrawRequired = false; + + final long startTime = SystemClock.elapsedRealtime(); + + final List controllers = + getPreferenceControllersAsList(); + final TelephonyStatusControlSession session = + setTelephonyAvailabilityStatus(controllers); + + + final PreferenceScreen screen = getPreferenceScreen(); + controllers.forEach(controller -> { + controller.displayPreference(screen); + updateVisiblePreferenceControllers(screen, controller); + }); + + final long endTime = SystemClock.elapsedRealtime(); + + Log.d(LOG_TAG, "redraw fragment: +" + (endTime - startTime) + "ms"); + + session.close(); + } } diff --git a/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceController.java b/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceController.java index d5a192a5456..6917549cb25 100644 --- a/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceController.java +++ b/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceController.java @@ -413,10 +413,10 @@ public class EnabledNetworkModePreferenceController extends TelephonyManagerConstants.NETWORK_MODE_LTE_GSM_WCDMA); if (is5gEntryDisplayed()) { setSummary(mShow4gForLTE - ? R.string.network_4G_pure : R.string.network_lte_pure); + ? R.string.network_4G_pure : R.string.network_lte_pure); } else { setSummary(mShow4gForLTE - ? R.string.network_4G : R.string.network_lte); + ? R.string.network_4G : R.string.network_lte); } } else { setSelectedEntry( @@ -461,8 +461,8 @@ public class EnabledNetworkModePreferenceController extends case TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA: case TelephonyManagerConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA: if (MobileNetworkUtils.isTdscdmaSupported(mContext, mSubId)) { - setSelectedEntry( - TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA); + setSelectedEntry(TelephonyManagerConstants + .NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA); setSummary(is5gEntryDisplayed() ? R.string.network_lte_pure : R.string.network_lte); } else { @@ -498,8 +498,8 @@ public class EnabledNetworkModePreferenceController extends case TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA_WCDMA: case TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA_GSM_WCDMA: case TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA: - setSelectedEntry( - TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA); + setSelectedEntry(TelephonyManagerConstants + .NETWORK_MODE_NR_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA); setSummary(mContext.getString(R.string.network_5G) + mContext.getString(R.string.network_recommended)); break; @@ -553,7 +553,8 @@ public class EnabledNetworkModePreferenceController extends case TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA: return TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA_GSM_WCDMA; case TelephonyManagerConstants.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA: - return TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA; + return TelephonyManagerConstants + .NETWORK_MODE_NR_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA; default: return networkType; // not LTE } @@ -654,7 +655,7 @@ public class EnabledNetworkModePreferenceController extends } private String[] getEntryValues() { - Integer intArr[] = mEntriesValue.toArray(new Integer[0]); + final Integer [] intArr = mEntriesValue.toArray(new Integer[0]); return Arrays.stream(intArr) .map(String::valueOf) .toArray(String[]::new); diff --git a/src/com/android/settings/network/telephony/MobileNetworkActivity.java b/src/com/android/settings/network/telephony/MobileNetworkActivity.java index fd7ab97cf85..7f7dc3a192c 100644 --- a/src/com/android/settings/network/telephony/MobileNetworkActivity.java +++ b/src/com/android/settings/network/telephony/MobileNetworkActivity.java @@ -126,12 +126,13 @@ public class MobileNetworkActivity extends SettingsBaseActivity : SUB_ID_NULL); final SubscriptionInfo subscription = getSubscription(); - updateTitleAndNavigation(subscription); maybeShowContactDiscoveryDialog(subscription); // Since onChanged() will take place immediately when addActiveSubscriptionsListener(), // perform registration after mCurSubscriptionId been configured. registerActiveSubscriptionsListener(); + + updateSubscriptions(subscription); } @VisibleForTesting diff --git a/src/com/android/settings/network/telephony/MobileNetworkSettings.java b/src/com/android/settings/network/telephony/MobileNetworkSettings.java index d84d15409f0..49f7981c28b 100644 --- a/src/com/android/settings/network/telephony/MobileNetworkSettings.java +++ b/src/com/android/settings/network/telephony/MobileNetworkSettings.java @@ -37,6 +37,7 @@ import androidx.preference.Preference; import com.android.settings.R; import com.android.settings.datausage.BillingCyclePreferenceController; import com.android.settings.datausage.DataUsageSummaryPreferenceController; +import com.android.settings.network.ActiveSubsciptionsListener; import com.android.settings.network.telephony.cdma.CdmaSubscriptionPreferenceController; import com.android.settings.network.telephony.cdma.CdmaSystemSelectPreferenceController; import com.android.settings.network.telephony.gsm.AutoSelectPreferenceController; @@ -44,6 +45,7 @@ import com.android.settings.network.telephony.gsm.OpenNetworkSelectPagePreferenc import com.android.settings.search.BaseSearchIndexProvider; import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.search.SearchIndexable; +import com.android.settingslib.utils.ThreadUtils; import java.util.Arrays; import java.util.List; @@ -70,6 +72,10 @@ public class MobileNetworkSettings extends AbstractMobileNetworkSettings { private UserManager mUserManager; private String mClickedPrefKey; + private ActiveSubsciptionsListener mActiveSubsciptionsListener; + private boolean mActiveSubsciptionsListenerStarting; + private int mActiveSubsciptionsListenerCount; + public MobileNetworkSettings() { super(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS); } @@ -197,6 +203,38 @@ public class MobileNetworkSettings extends AbstractMobileNetworkSettings { onRestoreInstance(icicle); } + @Override + public void onResume() { + super.onResume(); + if (mActiveSubsciptionsListener == null) { + mActiveSubsciptionsListenerStarting = true; + mActiveSubsciptionsListener = new ActiveSubsciptionsListener( + getContext().getMainLooper(), getContext(), mSubId) { + public void onChanged() { + onSubscriptionDetailChanged(); + } + }; + mActiveSubsciptionsListenerStarting = false; + } + mActiveSubsciptionsListener.start(); + } + + private void onSubscriptionDetailChanged() { + if (mActiveSubsciptionsListenerStarting) { + Log.d(LOG_TAG, "Callback during onResume()"); + return; + } + mActiveSubsciptionsListenerCount++; + if (mActiveSubsciptionsListenerCount != 1) { + return; + } + + ThreadUtils.postOnMainThread(() -> { + mActiveSubsciptionsListenerCount = 0; + redrawPreferenceControllers(); + }); + } + @VisibleForTesting void onRestoreInstance(Bundle icicle) { if (icicle != null) { diff --git a/src/com/android/settings/notification/EmergencyBroadcastPreferenceController.java b/src/com/android/settings/notification/EmergencyBroadcastPreferenceController.java index 7add167ab8e..de7e7801ac2 100644 --- a/src/com/android/settings/notification/EmergencyBroadcastPreferenceController.java +++ b/src/com/android/settings/notification/EmergencyBroadcastPreferenceController.java @@ -24,6 +24,7 @@ import android.os.UserManager; import androidx.annotation.VisibleForTesting; import androidx.preference.Preference; +import com.android.internal.telephony.CellBroadcastUtils; import com.android.settings.accounts.AccountRestrictionHelper; import com.android.settings.core.PreferenceControllerMixin; import com.android.settingslib.RestrictedPreference; @@ -88,7 +89,9 @@ public class EmergencyBroadcastPreferenceController extends AbstractPreferenceCo com.android.internal.R.bool.config_cellBroadcastAppLinks); if (enabled) { try { - if (mPm.getApplicationEnabledSetting("com.android.cellbroadcastreceiver") + String packageName = CellBroadcastUtils + .getDefaultCellBroadcastReceiverPackageName(mContext); + if (packageName == null || mPm.getApplicationEnabledSetting(packageName) == PackageManager.COMPONENT_ENABLED_STATE_DISABLED) { enabled = false; // CMAS app disabled } diff --git a/src/com/android/settings/notification/RemoteVolumeGroupController.java b/src/com/android/settings/notification/RemoteVolumeGroupController.java index a0b10579f2b..4b045e289b0 100644 --- a/src/com/android/settings/notification/RemoteVolumeGroupController.java +++ b/src/com/android/settings/notification/RemoteVolumeGroupController.java @@ -23,8 +23,6 @@ import android.text.TextUtils; import android.util.Log; import androidx.annotation.VisibleForTesting; -import androidx.lifecycle.LifecycleObserver; -import androidx.lifecycle.OnLifecycleEvent; import androidx.preference.Preference; import androidx.preference.PreferenceCategory; import androidx.preference.PreferenceScreen; @@ -32,7 +30,8 @@ import androidx.preference.PreferenceScreen; import com.android.settings.R; import com.android.settings.Utils; import com.android.settings.core.BasePreferenceController; -import com.android.settingslib.core.lifecycle.Lifecycle; +import com.android.settingslib.core.lifecycle.LifecycleObserver; +import com.android.settingslib.core.lifecycle.events.OnDestroy; import com.android.settingslib.media.LocalMediaManager; import com.android.settingslib.media.MediaDevice; import com.android.settingslib.media.MediaOutputSliceConstants; @@ -46,7 +45,8 @@ import java.util.List; * {@link com.android.settings.notification.RemoteVolumeSeekBarPreference} **/ public class RemoteVolumeGroupController extends BasePreferenceController implements - Preference.OnPreferenceChangeListener, LifecycleObserver, LocalMediaManager.DeviceCallback { + Preference.OnPreferenceChangeListener, LifecycleObserver, OnDestroy, + LocalMediaManager.DeviceCallback { private static final String KEY_REMOTE_VOLUME_GROUP = "remote_media_group"; private static final String TAG = "RemoteVolumePrefCtr"; @@ -93,11 +93,7 @@ public class RemoteVolumeGroupController extends BasePreferenceController implem } } - /** - * onDestroy() - * {@link androidx.lifecycle.OnLifecycleEvent} - **/ - @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) + @Override public void onDestroy() { mLocalMediaManager.unregisterCallback(this); mLocalMediaManager.stopScan(); diff --git a/src/com/android/settings/notification/SoundSettings.java b/src/com/android/settings/notification/SoundSettings.java index 746a2df8ab2..9e7f3ed5489 100644 --- a/src/com/android/settings/notification/SoundSettings.java +++ b/src/com/android/settings/notification/SoundSettings.java @@ -190,7 +190,6 @@ public class SoundSettings extends DashboardFragment implements OnActivityResult controller.setCallback(mVolumeCallback); getSettingsLifecycle().addObserver(controller); } - getSettingsLifecycle().addObserver(use(RemoteVolumeGroupController.class)); } // === Volumes === diff --git a/src/com/android/settings/wifi/p2p/WifiP2pPeer.java b/src/com/android/settings/wifi/p2p/WifiP2pPeer.java index cea7200e10a..00cb36b2670 100644 --- a/src/com/android/settings/wifi/p2p/WifiP2pPeer.java +++ b/src/com/android/settings/wifi/p2p/WifiP2pPeer.java @@ -22,6 +22,7 @@ import android.net.wifi.p2p.WifiP2pDevice; import android.text.TextUtils; import android.widget.ImageView; +import androidx.annotation.VisibleForTesting; import androidx.preference.Preference; import androidx.preference.PreferenceViewHolder; @@ -29,19 +30,21 @@ import com.android.settings.R; public class WifiP2pPeer extends Preference { + private static final int FIXED_RSSI = 60; private static final int[] STATE_SECURED = {R.attr.state_encrypted}; public WifiP2pDevice device; - private final int mRssi; + @VisibleForTesting final int mRssi; private ImageView mSignal; - private static final int SIGNAL_LEVELS = 4; + @VisibleForTesting + static final int SIGNAL_LEVELS = 4; public WifiP2pPeer(Context context, WifiP2pDevice dev) { super(context); device = dev; setWidgetLayoutResource(R.layout.preference_widget_wifi_signal); - mRssi = 60; //TODO: fix + mRssi = FIXED_RSSI; //TODO: fix if (TextUtils.isEmpty(device.deviceName)) { setTitle(device.deviceAddress); } else { diff --git a/src/com/android/settings/wifi/p2p/WifiP2pPreferenceController.java b/src/com/android/settings/wifi/p2p/WifiP2pPreferenceController.java index 86cce1ef1c8..96044100647 100644 --- a/src/com/android/settings/wifi/p2p/WifiP2pPreferenceController.java +++ b/src/com/android/settings/wifi/p2p/WifiP2pPreferenceController.java @@ -52,7 +52,8 @@ public class WifiP2pPreferenceController extends AbstractPreferenceController }; private final IntentFilter mFilter = new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION); private final LocationManager mLocationManager; - private final BroadcastReceiver mLocationReceiver = new BroadcastReceiver() { + @VisibleForTesting + final BroadcastReceiver mLocationReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (mWifiDirectPref != null) { diff --git a/src/com/android/settings/wifi/p2p/WifiP2pSettings.java b/src/com/android/settings/wifi/p2p/WifiP2pSettings.java index 07bee3bc30a..9578c802ab0 100644 --- a/src/com/android/settings/wifi/p2p/WifiP2pSettings.java +++ b/src/com/android/settings/wifi/p2p/WifiP2pSettings.java @@ -91,16 +91,16 @@ public class WifiP2pSettings extends DashboardFragment @VisibleForTesting boolean mLastGroupFormed = false; private boolean mIsIgnoreInitConnectionInfoCallback = false; - private P2pPeerCategoryPreferenceController mPeerCategoryController; - private P2pPersistentCategoryPreferenceController mPersistentCategoryController; - private P2pThisDevicePreferenceController mThisDevicePreferenceController; + @VisibleForTesting P2pPeerCategoryPreferenceController mPeerCategoryController; + @VisibleForTesting P2pPersistentCategoryPreferenceController mPersistentCategoryController; + @VisibleForTesting P2pThisDevicePreferenceController mThisDevicePreferenceController; @VisibleForTesting static final int DIALOG_DISCONNECT = 1; @VisibleForTesting static final int DIALOG_CANCEL_CONNECT = 2; @VisibleForTesting static final int DIALOG_RENAME = 3; @VisibleForTesting static final int DIALOG_DELETE_GROUP = 4; - private static final String SAVE_DIALOG_PEER = "PEER_STATE"; + @VisibleForTesting static final String SAVE_DIALOG_PEER = "PEER_STATE"; @VisibleForTesting static final String SAVE_DEVICE_NAME = "DEV_NAME"; @VisibleForTesting static final String SAVE_SELECTED_GROUP = "GROUP_NAME"; diff --git a/tests/robotests/src/com/android/settings/applications/appinfo/AppInstallerInfoPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/appinfo/AppInstallerInfoPreferenceControllerTest.java index 1f85477c02e..00bd5f80724 100644 --- a/tests/robotests/src/com/android/settings/applications/appinfo/AppInstallerInfoPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/applications/appinfo/AppInstallerInfoPreferenceControllerTest.java @@ -32,6 +32,7 @@ import android.content.Context; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; +import android.content.pm.ModuleInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; @@ -148,4 +149,16 @@ public class AppInstallerInfoPreferenceControllerTest { verify(mPreference, never()).setEnabled(false); verify(mPreference).setIntent(any(Intent.class)); } + + @Test + public void getAvailabilityStatus_isMainlineModule_shouldReturnDisabled() + throws PackageManager.NameNotFoundException { + when(mUserManager.isManagedProfile()).thenReturn(false); + when(mAppInfo.loadLabel(mPackageManager)).thenReturn("Label"); + mController.setPackageName("Package"); + when(mPackageManager.getModuleInfo("Package", 0 /* flags */)).thenReturn(new ModuleInfo()); + + assertThat(mController.getAvailabilityStatus()).isEqualTo( + BasePreferenceController.DISABLED_FOR_USER); + } } diff --git a/tests/robotests/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceControllerTest.java index 08f937b2788..974a52b519d 100644 --- a/tests/robotests/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceControllerTest.java +++ b/tests/robotests/src/com/android/settings/connecteddevice/AdvancedConnectedDeviceControllerTest.java @@ -23,9 +23,15 @@ import static org.mockito.Mockito.spy; import android.content.ContentResolver; import android.content.Context; +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.content.pm.ApplicationInfo; +import android.content.pm.ResolveInfo; import android.nfc.NfcAdapter; import android.provider.Settings; +import androidx.test.core.content.pm.ApplicationInfoBuilder; + import com.android.settings.R; import com.android.settings.nfc.NfcPreferenceController; @@ -38,6 +44,7 @@ import org.robolectric.RuntimeEnvironment; import org.robolectric.Shadows; import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowNfcAdapter; +import org.robolectric.shadows.ShadowPackageManager; import org.robolectric.util.ReflectionHelpers; @RunWith(RobolectricTestRunner.class) @@ -47,11 +54,13 @@ public class AdvancedConnectedDeviceControllerTest { private static final String KEY = "test_key"; private static final String DRIVING_MODE_SETTINGS_ENABLED = "gearhead:driving_mode_settings_enabled"; + private static final String ANDROID_AUTO_PACKAGE = "com.google.android.projection.gearhead"; private Context mContext; private NfcPreferenceController mNfcController; private ShadowNfcAdapter mShadowNfcAdapter; private ContentResolver mContentResolver; + private ShadowPackageManager mShadowPackageManager; @Before public void setUp() { @@ -62,6 +71,7 @@ public class AdvancedConnectedDeviceControllerTest { mNfcController = new NfcPreferenceController(mContext, NfcPreferenceController.KEY_TOGGLE_NFC); mShadowNfcAdapter = Shadows.shadowOf(NfcAdapter.getNfcAdapter(mContext)); + mShadowPackageManager = Shadows.shadowOf(mContext.getPackageManager()); } @Test @@ -76,14 +86,41 @@ public class AdvancedConnectedDeviceControllerTest { public void isDrivingModeAvailable_returnTrue() { Settings.System.putInt(mContentResolver, DRIVING_MODE_SETTINGS_ENABLED, 1); - assertThat(AdvancedConnectedDeviceController.isDrivingModeAvailable(mContext)).isTrue(); + assertThat( + AdvancedConnectedDeviceController.isDrivingModeAvailable(mContext)).isTrue(); } @Test public void isDrivingModeAvailable_returnFalse() { Settings.System.putInt(mContentResolver, DRIVING_MODE_SETTINGS_ENABLED, 0); - assertThat(AdvancedConnectedDeviceController.isDrivingModeAvailable(mContext)).isFalse(); + assertThat( + AdvancedConnectedDeviceController.isDrivingModeAvailable(mContext)).isFalse(); + } + + @Test + public void isAndroidAutoSettingAvailable_returnTrue() { + final ApplicationInfo appInfo = + ApplicationInfoBuilder.newBuilder().setPackageName(ANDROID_AUTO_PACKAGE).build(); + final ActivityInfo activityInfo = new ActivityInfo(); + activityInfo.packageName = ANDROID_AUTO_PACKAGE; + activityInfo.name = ANDROID_AUTO_PACKAGE; + activityInfo.applicationInfo = appInfo; + final ResolveInfo resolveInfo = new ResolveInfo(); + resolveInfo.activityInfo = activityInfo; + mShadowPackageManager.addResolveInfoForIntent( + buildAndroidAutoSettingsIntent(), + resolveInfo); + + assertThat( + AdvancedConnectedDeviceController.isAndroidAutoSettingAvailable(mContext)).isTrue(); + } + + @Test + public void isAndroidAutoSettingAvailable_returnFalse() { + // No ResolveInfo for Android Auto, expect false. + assertThat( + AdvancedConnectedDeviceController.isAndroidAutoSettingAvailable(mContext)).isFalse(); } @Test @@ -91,7 +128,7 @@ public class AdvancedConnectedDeviceControllerTest { // NFC available, driving mode available mShadowNfcAdapter.setEnabled(true); assertThat(AdvancedConnectedDeviceController - .getConnectedDevicesSummaryResourceId(mNfcController, true)) + .getConnectedDevicesSummaryResourceId(mNfcController, true, false)) .isEqualTo(R.string.connected_devices_dashboard_summary); } @@ -100,7 +137,7 @@ public class AdvancedConnectedDeviceControllerTest { // NFC is available, driving mode not available mShadowNfcAdapter.setEnabled(true); assertThat(AdvancedConnectedDeviceController - .getConnectedDevicesSummaryResourceId(mNfcController, false)) + .getConnectedDevicesSummaryResourceId(mNfcController, false, false)) .isEqualTo(R.string.connected_devices_dashboard_no_driving_mode_summary); } @@ -109,7 +146,7 @@ public class AdvancedConnectedDeviceControllerTest { // NFC not available, driving mode available ReflectionHelpers.setField(mNfcController, "mNfcAdapter", null); assertThat(AdvancedConnectedDeviceController - .getConnectedDevicesSummaryResourceId(mNfcController, true)) + .getConnectedDevicesSummaryResourceId(mNfcController, true, false)) .isEqualTo(R.string.connected_devices_dashboard_no_nfc_summary); } @@ -118,7 +155,52 @@ public class AdvancedConnectedDeviceControllerTest { // NFC not available, driving mode not available ReflectionHelpers.setField(mNfcController, "mNfcAdapter", null); assertThat(AdvancedConnectedDeviceController - .getConnectedDevicesSummaryResourceId(mNfcController, false)) + .getConnectedDevicesSummaryResourceId(mNfcController, false, false)) .isEqualTo(R.string.connected_devices_dashboard_no_driving_mode_no_nfc_summary); } + + @Test + public void getConnectedDevicesSummaryResourceId_Auto_NFC_DrivingMode_Available() { + // NFC available, driving mode available + mShadowNfcAdapter.setEnabled(true); + assertThat(AdvancedConnectedDeviceController + .getConnectedDevicesSummaryResourceId(mNfcController, true, true)) + .isEqualTo(R.string.connected_devices_dashboard_android_auto_summary); + } + + @Test + public void getConnectedDevicesSummaryResourceId_Auto_NFC_Available() { + // NFC is available, driving mode not available + mShadowNfcAdapter.setEnabled(true); + assertThat(AdvancedConnectedDeviceController + .getConnectedDevicesSummaryResourceId(mNfcController, false, true)) + .isEqualTo( + R.string.connected_devices_dashboard_android_auto_no_driving_mode_summary); + } + + @Test + public void getConnectedDevicesSummaryResourceId_Auto_DrivingMode_Available() { + // NFC not available, driving mode available + ReflectionHelpers.setField(mNfcController, "mNfcAdapter", null); + assertThat(AdvancedConnectedDeviceController + .getConnectedDevicesSummaryResourceId(mNfcController, true, true)) + .isEqualTo(R.string.connected_devices_dashboard_android_auto_no_nfc_summary); + } + + @Test + public void getConnectedDevicesSummaryResourceId_Auto_Available() { + // NFC not available, driving mode not available + ReflectionHelpers.setField(mNfcController, "mNfcAdapter", null); + assertThat(AdvancedConnectedDeviceController + .getConnectedDevicesSummaryResourceId(mNfcController, false, true)) + .isEqualTo( + R.string.connected_devices_dashboard_android_auto_no_nfc_no_driving_mode); + } + + private Intent buildAndroidAutoSettingsIntent() { + final Intent intent = new Intent("com.android.settings.action.IA_SETTINGS"); + intent.setPackage(ANDROID_AUTO_PACKAGE); + return intent; + } } + diff --git a/tests/robotests/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogControllerTest.java index 395c8a47219..bbab2592707 100644 --- a/tests/robotests/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogControllerTest.java +++ b/tests/robotests/src/com/android/settings/deviceinfo/simstatus/SimStatusDialogControllerTest.java @@ -38,6 +38,7 @@ import static com.android.settings.deviceinfo.simstatus.SimStatusDialogControlle import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; @@ -452,6 +453,8 @@ public class SimStatusDialogControllerTest { when(mEuiccManager.isEnabled()).thenReturn(true); when(mEuiccManager.getEid()).thenReturn(null); + doNothing().when(mController).requestForUpdateEid(); + mController.updateEid(mController.getEid(0)); mController.initialize(); // Keep 'Not available' if neither the card nor the associated manager can provide EID. @@ -489,7 +492,10 @@ public class SimStatusDialogControllerTest { when(mEuiccManager.isEnabled()).thenReturn(true); when(mEuiccManager.getEid()).thenReturn(TEST_EID_FROM_MANAGER); + when(mEuiccManager.createForCardId(0)).thenReturn(mEuiccManager); + doNothing().when(mController).requestForUpdateEid(); + mController.updateEid(mController.getEid(0)); mController.initialize(); // Set EID retrieved from the card. @@ -531,6 +537,8 @@ public class SimStatusDialogControllerTest { new RuntimeException("Unexpected card ID was specified")); when(mEuiccManager.createForCardId(1)).thenReturn(mEuiccManager); + doNothing().when(mController).requestForUpdateEid(); + mController.updateEid(mController.getEid(0)); mController.initialize(); // Set EID retrieved from the manager associated with the card which cannot provide EID. @@ -569,6 +577,8 @@ public class SimStatusDialogControllerTest { when(mEuiccManager.isEnabled()).thenReturn(true); when(mEuiccManager.getEid()).thenReturn(TEST_EID_FROM_MANAGER); + doNothing().when(mController).requestForUpdateEid(); + mController.updateEid(mController.getEid(0)); mController.initialize(); // Remove EID if the card is not eUICC. @@ -599,6 +609,8 @@ public class SimStatusDialogControllerTest { when(mEuiccManager.isEnabled()).thenReturn(true); when(mEuiccManager.getEid()).thenReturn(null); + doNothing().when(mController).requestForUpdateEid(); + mController.updateEid(mController.getEid(0)); mController.initialize(); // Keep 'Not available' if the default eUICC manager cannot provide EID in Single SIM mode. @@ -630,6 +642,8 @@ public class SimStatusDialogControllerTest { when(mEuiccManager.createForCardId(anyInt())).thenThrow( new RuntimeException("EID shall be retrieved from the default eUICC manager")); + doNothing().when(mController).requestForUpdateEid(); + mController.updateEid(mController.getEid(0)); mController.initialize(); // Set EID retrieved from the default eUICC manager in Single SIM mode. @@ -661,6 +675,8 @@ public class SimStatusDialogControllerTest { when(mEuiccManager.createForCardId(anyInt())).thenThrow( new RuntimeException("EID shall be retrieved from the default eUICC manager")); + doNothing().when(mController).requestForUpdateEid(); + mController.updateEid(mController.getEid(0)); mController.initialize(); // Set EID retrieved from the default eUICC manager in Single SIM mode. @@ -690,6 +706,8 @@ public class SimStatusDialogControllerTest { when(mEuiccManager.isEnabled()).thenReturn(false); when(mEuiccManager.getEid()).thenReturn(null); + doNothing().when(mController).requestForUpdateEid(); + mController.updateEid(mController.getEid(0)); mController.initialize(); // Remove EID if the default eUICC manager indicates that eSIM is not enabled. diff --git a/tests/robotests/src/com/android/settings/gestures/PowerMenuPrivacyPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/PowerMenuPrivacyPreferenceControllerTest.java index 7891d2f9427..32048a157d8 100644 --- a/tests/robotests/src/com/android/settings/gestures/PowerMenuPrivacyPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/gestures/PowerMenuPrivacyPreferenceControllerTest.java @@ -202,4 +202,14 @@ public class PowerMenuPrivacyPreferenceControllerTest { assertThat(mController.getAvailabilityStatus()).isEqualTo( BasePreferenceController.DISABLED_DEPENDENT_SETTING); } + + @Test + public void getAvailabilityStatus_controlsDeletedSecure_retursAvailable() { + when(mLockPatternUtils.isSecure(anyInt())).thenReturn(true); + + Settings.Secure.putString(mContentResolver, CONTROLS_ENABLED_KEY, null); + + assertThat(mController.getAvailabilityStatus()).isEqualTo( + BasePreferenceController.AVAILABLE); + } } diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUserManager.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUserManager.java index 673c0fe2689..1d4f2019fb8 100644 --- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUserManager.java +++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUserManager.java @@ -45,7 +45,6 @@ public class ShadowUserManager extends org.robolectric.shadows.ShadowUserManager private static boolean sIsSupportsMultipleUsers; private final List mBaseRestrictions = new ArrayList<>(); - private final List mUserRestrictions = new ArrayList<>(); private final List mGuestRestrictions = new ArrayList<>(); private final Map> mRestrictionSources = new HashMap<>(); private final List mUserProfileInfos = new ArrayList<>(); @@ -95,16 +94,6 @@ public class ShadowUserManager extends org.robolectric.shadows.ShadowUserManager mBaseRestrictions.add(restriction); } - @Implementation - protected boolean hasUserRestriction(@UserManager.UserRestrictionKey String restrictionKey, - UserHandle userHandle) { - return mUserRestrictions.contains(restrictionKey); - } - - public void addUserRestriction(String restriction) { - mUserRestrictions.add(restriction); - } - @Implementation protected Bundle getDefaultGuestRestrictions() { Bundle bundle = new Bundle(); diff --git a/tests/robotests/src/com/android/settings/users/UserDetailsSettingsTest.java b/tests/robotests/src/com/android/settings/users/UserDetailsSettingsTest.java index c51b2fc67d8..6c5478262aa 100644 --- a/tests/robotests/src/com/android/settings/users/UserDetailsSettingsTest.java +++ b/tests/robotests/src/com/android/settings/users/UserDetailsSettingsTest.java @@ -297,7 +297,8 @@ public class UserDetailsSettingsTest { public void initialize_userHasCallRestriction_shouldSetPhoneSwitchUnChecked() { setupSelectedUser(); mUserManager.setIsAdminUser(true); - mUserManager.addUserRestriction(UserManager.DISALLOW_OUTGOING_CALLS); + mUserManager.setUserRestriction(mUserInfo.getUserHandle(), + UserManager.DISALLOW_OUTGOING_CALLS, true); mFragment.initialize(mActivity, mArguments); diff --git a/tests/robotests/src/com/android/settings/users/UserSettingsTest.java b/tests/robotests/src/com/android/settings/users/UserSettingsTest.java index d2a18403773..3104c3c2749 100644 --- a/tests/robotests/src/com/android/settings/users/UserSettingsTest.java +++ b/tests/robotests/src/com/android/settings/users/UserSettingsTest.java @@ -277,6 +277,7 @@ public class UserSettingsTest { @Test public void updateUserList_canNotAddMoreUsers_shouldDisableAddUserWithSummary() { + mUserCapabilities.mCanAddUser = true; doReturn(false).when(mUserManager).canAddMoreUsers(); doReturn(false).when(mAddUserPreference).isEnabled(); doReturn(SWITCHABILITY_STATUS_OK).when(mUserManager).getUserSwitchability(); diff --git a/tests/robotests/src/com/android/settings/wifi/WifiConfigController2Test.java b/tests/robotests/src/com/android/settings/wifi/WifiConfigController2Test.java index c9bc3465467..e588799d6a4 100644 --- a/tests/robotests/src/com/android/settings/wifi/WifiConfigController2Test.java +++ b/tests/robotests/src/com/android/settings/wifi/WifiConfigController2Test.java @@ -83,6 +83,12 @@ public class WifiConfigController2Test { // Valid PSK pass phrase private static final String GOOD_PSK = "abcdefghijklmnopqrstuvwxyz"; private static final String GOOD_SSID = "abc"; + private static final String VALID_HEX_PSK = + "123456789012345678901234567890123456789012345678901234567890abcd"; + private static final String INVALID_HEX_PSK = + "123456789012345678901234567890123456789012345678901234567890ghij"; + private static final String NUMBER_AND_CHARACTER_KEY = "123456abcd"; + private static final String PARTIAL_NUMBER_AND_CHARACTER_KEY = "123456abc?"; private static final int DHCP = 0; @Before @@ -518,16 +524,7 @@ public class WifiConfigController2Test { @Test public void selectEapMethod_savedWifiEntry_shouldGetCorrectPosition() { - when(mWifiEntry.isSaved()).thenReturn(true); - when(mWifiEntry.getSecurity()).thenReturn(WifiEntry.SECURITY_EAP); - final WifiConfiguration mockWifiConfig = mock(WifiConfiguration.class); - when(mockWifiConfig.getIpConfiguration()).thenReturn(mock(IpConfiguration.class)); - final WifiEnterpriseConfig mockWifiEnterpriseConfig = mock(WifiEnterpriseConfig.class); - when(mockWifiEnterpriseConfig.getEapMethod()).thenReturn(Eap.PEAP); - mockWifiConfig.enterpriseConfig = mockWifiEnterpriseConfig; - when(mWifiEntry.getWifiConfiguration()).thenReturn(mockWifiConfig); - mController = new TestWifiConfigController2(mConfigUiBase, mView, mWifiEntry, - WifiConfigUiBase2.MODE_MODIFY); + setUpModifyingSavedPeapConfigController(); final Spinner eapMethodSpinner = mView.findViewById(R.id.method); final Spinner phase2Spinner = mView.findViewById(R.id.phase2); WifiConfiguration wifiConfiguration; @@ -568,4 +565,199 @@ public class WifiConfigController2Test { assertThat(advButton.getContentDescription()).isEqualTo( mContext.getString(R.string.wifi_advanced_toggle_description)); } + + @Test + public void getWepConfig_withNumberAndCharacterKey_shouldContainTheSameKey() { + final TextView password = mView.findViewById(R.id.password); + password.setText(NUMBER_AND_CHARACTER_KEY); + mController.mWifiEntrySecurity = WifiEntry.SECURITY_WEP; + + WifiConfiguration wifiConfiguration = mController.getConfig(); + + assertThat(wifiConfiguration.wepKeys[0]).isEqualTo(NUMBER_AND_CHARACTER_KEY); + } + + @Test + public void getWepConfig_withPartialNumberAndCharacterKey_shouldContainDifferentKey() { + final TextView password = mView.findViewById(R.id.password); + password.setText(PARTIAL_NUMBER_AND_CHARACTER_KEY); + mController.mWifiEntrySecurity = WifiEntry.SECURITY_WEP; + + WifiConfiguration wifiConfiguration = mController.getConfig(); + + assertThat(wifiConfiguration.wepKeys[0]).isNotEqualTo(PARTIAL_NUMBER_AND_CHARACTER_KEY); + } + + @Test + public void getPskConfig_withValidHexKey_shouldContainTheSameKey() { + final TextView password = mView.findViewById(R.id.password); + password.setText(VALID_HEX_PSK); + mController.mWifiEntrySecurity = WifiEntry.SECURITY_PSK; + + WifiConfiguration wifiConfiguration = mController.getConfig(); + + assertThat(wifiConfiguration.preSharedKey).isEqualTo(VALID_HEX_PSK); + } + + @Test + public void getPskConfig_withInvalidHexKey_shouldContainDifferentKey() { + final TextView password = mView.findViewById(R.id.password); + password.setText(INVALID_HEX_PSK); + mController.mWifiEntrySecurity = WifiEntry.SECURITY_PSK; + + WifiConfiguration wifiConfiguration = mController.getConfig(); + + assertThat(wifiConfiguration.preSharedKey).isNotEqualTo(INVALID_HEX_PSK); + } + + @Test + public void getEapConfig_withPhase2Gtc_shouldContainGtcMethod() { + setUpModifyingSavedPeapConfigController(); + + // Test EAP method PEAP + final Spinner eapMethodSpinner = mView.findViewById(R.id.method); + eapMethodSpinner.setSelection(Eap.PEAP); + + // Test phase2 GTC + final Spinner phase2Spinner = mView.findViewById(R.id.phase2); + phase2Spinner.setSelection(WifiConfigController2.WIFI_PEAP_PHASE2_GTC); + + WifiConfiguration wifiConfiguration = mController.getConfig(); + + assertThat(wifiConfiguration.enterpriseConfig.getPhase2Method()).isEqualTo(Phase2.GTC); + } + + @Test + public void getEapConfig_withPhase2Sim_shouldContainSimMethod() { + setUpModifyingSavedPeapConfigController(); + + // Test EAP method PEAP + final Spinner eapMethodSpinner = mView.findViewById(R.id.method); + eapMethodSpinner.setSelection(Eap.PEAP); + + // Test phase2 SIM + final Spinner phase2Spinner = mView.findViewById(R.id.phase2); + phase2Spinner.setSelection(WifiConfigController2.WIFI_PEAP_PHASE2_SIM); + + WifiConfiguration wifiConfiguration = mController.getConfig(); + + assertThat(wifiConfiguration.enterpriseConfig.getPhase2Method()).isEqualTo(Phase2.SIM); + } + + @Test + public void getEapConfig_withPhase2Aka_shouldContainAkaMethod() { + setUpModifyingSavedPeapConfigController(); + + // Test EAP method PEAP + final Spinner eapMethodSpinner = mView.findViewById(R.id.method); + eapMethodSpinner.setSelection(Eap.PEAP); + + // Test phase2 AKA + final Spinner phase2Spinner = mView.findViewById(R.id.phase2); + phase2Spinner.setSelection(WifiConfigController2.WIFI_PEAP_PHASE2_AKA); + + WifiConfiguration wifiConfiguration = mController.getConfig(); + + assertThat(wifiConfiguration.enterpriseConfig.getPhase2Method()).isEqualTo(Phase2.AKA); + } + + @Test + public void getEapConfig_withPhase2AkaPrime_shouldContainAkaPrimeMethod() { + setUpModifyingSavedPeapConfigController(); + + // Test EAP method PEAP + final Spinner eapMethodSpinner = mView.findViewById(R.id.method); + eapMethodSpinner.setSelection(Eap.PEAP); + + // Test phase2 AKA PRIME + final Spinner phase2Spinner = mView.findViewById(R.id.phase2); + phase2Spinner.setSelection(WifiConfigController2.WIFI_PEAP_PHASE2_AKA_PRIME); + + WifiConfiguration wifiConfiguration = mController.getConfig(); + + assertThat(wifiConfiguration.enterpriseConfig.getPhase2Method()).isEqualTo( + Phase2.AKA_PRIME); + } + + + @Test + public void getEapConfig_withPeapPhase2Unknown_shouldContainNoneMethod() { + setUpModifyingSavedPeapConfigController(); + + // Test EAP method PEAP + final Spinner eapMethodSpinner = mView.findViewById(R.id.method); + eapMethodSpinner.setSelection(Eap.PEAP); + + // Test phase2 Unknown + final Spinner phase2Spinner = mView.findViewById(R.id.phase2); + phase2Spinner.setSelection(-1); + + WifiConfiguration wifiConfiguration = mController.getConfig(); + + assertThat(wifiConfiguration.enterpriseConfig.getPhase2Method()).isEqualTo(Phase2.NONE); + } + + @Test + public void getEapConfig_withTTLSPhase2Pap_shouldContainPapMethod() { + setUpModifyingSavedPeapConfigController(); + + // Test EAP method TTLS + final Spinner eapMethodSpinner = mView.findViewById(R.id.method); + eapMethodSpinner.setSelection(Eap.TTLS); + + // Test phase2 PAP + final Spinner phase2Spinner = mView.findViewById(R.id.phase2); + phase2Spinner.setSelection(WifiConfigController2.WIFI_TTLS_PHASE2_PAP); + + WifiConfiguration wifiConfiguration = mController.getConfig(); + + assertThat(wifiConfiguration.enterpriseConfig.getPhase2Method()).isEqualTo(Phase2.PAP); + } + + @Test + public void getEapConfig_withTTLSPhase2Mschap_shouldContainMschapMethod() { + setUpModifyingSavedPeapConfigController(); + + // Test EAP method TTLS + final Spinner eapMethodSpinner = mView.findViewById(R.id.method); + eapMethodSpinner.setSelection(Eap.TTLS); + + // Test phase2 MSCHAP + final Spinner phase2Spinner = mView.findViewById(R.id.phase2); + phase2Spinner.setSelection(WifiConfigController2.WIFI_TTLS_PHASE2_MSCHAP); + + WifiConfiguration wifiConfiguration = mController.getConfig(); + + assertThat(wifiConfiguration.enterpriseConfig.getPhase2Method()).isEqualTo(Phase2.MSCHAP); + } + + @Test + public void getEapConfig_withTTLSPhase2Gtc_shouldContainGtcMethod() { + setUpModifyingSavedPeapConfigController(); + + // Test EAP method TTLS + final Spinner eapMethodSpinner = mView.findViewById(R.id.method); + eapMethodSpinner.setSelection(Eap.TTLS); + + // Test phase2 GTC + final Spinner phase2Spinner = mView.findViewById(R.id.phase2); + phase2Spinner.setSelection(WifiConfigController2.WIFI_TTLS_PHASE2_GTC); + + WifiConfiguration wifiConfiguration = mController.getConfig(); + + assertThat(wifiConfiguration.enterpriseConfig.getPhase2Method()).isEqualTo(Phase2.GTC); + } + + private void setUpModifyingSavedPeapConfigController() { + when(mWifiEntry.isSaved()).thenReturn(true); + when(mWifiEntry.getSecurity()).thenReturn(WifiEntry.SECURITY_EAP); + final WifiConfiguration mockWifiConfig = mock(WifiConfiguration.class); + when(mockWifiConfig.getIpConfiguration()).thenReturn(mock(IpConfiguration.class)); + final WifiEnterpriseConfig mockWifiEnterpriseConfig = mock(WifiEnterpriseConfig.class); + when(mockWifiEnterpriseConfig.getEapMethod()).thenReturn(Eap.PEAP); + mockWifiConfig.enterpriseConfig = mockWifiEnterpriseConfig; + when(mWifiEntry.getWifiConfiguration()).thenReturn(mockWifiConfig); + mController = new TestWifiConfigController2(mConfigUiBase, mView, mWifiEntry, + WifiConfigUiBase2.MODE_MODIFY); + } } diff --git a/tests/robotests/src/com/android/settings/wifi/p2p/WifiP2PPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/p2p/WifiP2PPreferenceControllerTest.java index ec8d16802d2..973168904c4 100644 --- a/tests/robotests/src/com/android/settings/wifi/p2p/WifiP2PPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/wifi/p2p/WifiP2PPreferenceControllerTest.java @@ -39,7 +39,6 @@ import androidx.lifecycle.LifecycleOwner; import androidx.preference.Preference; import androidx.preference.PreferenceScreen; -import com.android.settings.dashboard.DashboardFragment; import com.android.settingslib.core.lifecycle.Lifecycle; import org.junit.Before; @@ -132,4 +131,17 @@ public class WifiP2PPreferenceControllerTest { mController.displayPreference(mScreen); verify(mWifiDirectPreference, times(2)).setEnabled(false); } + + @Test + public void updateState_withLocationDisabled_preferenceShouldBeDisable() { + when(mWifiManager.isWifiEnabled()).thenReturn(true); + when(mLocationManager.isLocationEnabled()).thenReturn(true); + Intent dummyIntent = new Intent(); + mController.displayPreference(mScreen); + verify(mWifiDirectPreference).setEnabled(true); + + when(mLocationManager.isLocationEnabled()).thenReturn(false); + mController.mLocationReceiver.onReceive(mContext, dummyIntent); + verify(mWifiDirectPreference).setEnabled(false); + } } diff --git a/tests/robotests/src/com/android/settings/wifi/p2p/WifiP2pPeerTest.java b/tests/robotests/src/com/android/settings/wifi/p2p/WifiP2pPeerTest.java new file mode 100644 index 00000000000..c3ae0690ba0 --- /dev/null +++ b/tests/robotests/src/com/android/settings/wifi/p2p/WifiP2pPeerTest.java @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.wifi.p2p; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.mock; + +import android.content.Context; +import android.net.wifi.WifiManager; +import android.net.wifi.p2p.WifiP2pDevice; + +import androidx.preference.Preference; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; + +@RunWith(RobolectricTestRunner.class) +public class WifiP2pPeerTest { + + private static final String DEVICE_NAME = "fakeName"; + private static final String OTHER_NAME = "otherName"; + private static final String MAC_ADDRESS = "00:11:22:33:44:55"; + + private Context mContext; + private WifiP2pPeer mPreference; + + @Mock + private WifiP2pDevice mWifiP2pDevice; + @Mock + private WifiP2pPeer mOtherWifiP2pPeer; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mContext = RuntimeEnvironment.application; + } + + @Test + public void compareTo_withSameDeviceName_shouldBeZero() { + setupOneOtherP2pPeer(DEVICE_NAME, null /* address */); + mWifiP2pDevice.deviceName = DEVICE_NAME; + mPreference = new WifiP2pPeer(mContext, mWifiP2pDevice); + + assertThat(mPreference.compareTo(mOtherWifiP2pPeer)).isEqualTo(0); + } + + @Test + public void compareTo_withDifferentDeviceName_shouldNotZero() { + setupOneOtherP2pPeer(DEVICE_NAME, null /* address */); + mWifiP2pDevice.deviceName = OTHER_NAME; + mPreference = new WifiP2pPeer(mContext, mWifiP2pDevice); + + assertThat(mPreference.compareTo(mOtherWifiP2pPeer)).isNotEqualTo(0); + } + + @Test + public void compareTo_withSameDeviceAddress_shouldBeZero() { + setupOneOtherP2pPeer(null /* name */, MAC_ADDRESS); + mWifiP2pDevice.deviceAddress = MAC_ADDRESS; + mPreference = new WifiP2pPeer(mContext, mWifiP2pDevice); + + assertThat(mPreference.compareTo(mOtherWifiP2pPeer)).isEqualTo(0); + } + + @Test + public void compareTo_withLowerDeviceStatus_shouldBeOne() { + setupOneOtherP2pPeer(DEVICE_NAME, null /* address */); + mWifiP2pDevice.status = WifiP2pDevice.FAILED; + mPreference = new WifiP2pPeer(mContext, mWifiP2pDevice); + + assertThat(mPreference.compareTo(mOtherWifiP2pPeer)).isEqualTo(1); + } + + @Test + public void compareTo_withNotPeerParameter_shouldBeOne() { + final Preference fakePreference = mock(Preference.class); + setupOneOtherP2pPeer(DEVICE_NAME, null /* address */); + mPreference = new WifiP2pPeer(mContext, mWifiP2pDevice); + + assertThat(mPreference.compareTo(fakePreference)).isEqualTo(1); + } + + @Test + public void signalLevel_afterNewPreference_shouldBeExpected() { + mPreference = new WifiP2pPeer(mContext, mWifiP2pDevice); + + final int expectSignalLevel = WifiManager.calculateSignalLevel(mPreference.mRssi, + WifiP2pPeer.SIGNAL_LEVELS); + + assertThat(mPreference.getLevel()).isEqualTo(expectSignalLevel); + } + + private void setupOneOtherP2pPeer(String name, String address) { + final WifiP2pDevice wifiP2pDevice = mock(WifiP2pDevice.class); + wifiP2pDevice.status = WifiP2pDevice.CONNECTED; + wifiP2pDevice.deviceAddress = address; + wifiP2pDevice.deviceName = name; + mOtherWifiP2pPeer.device = wifiP2pDevice; + } +} diff --git a/tests/robotests/src/com/android/settings/wifi/p2p/WifiP2pSettingsTest.java b/tests/robotests/src/com/android/settings/wifi/p2p/WifiP2pSettingsTest.java index d212ddb6e3c..81615f231b4 100644 --- a/tests/robotests/src/com/android/settings/wifi/p2p/WifiP2pSettingsTest.java +++ b/tests/robotests/src/com/android/settings/wifi/p2p/WifiP2pSettingsTest.java @@ -21,6 +21,7 @@ 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.mock; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -33,6 +34,7 @@ import android.net.NetworkInfo; import android.net.wifi.p2p.WifiP2pDevice; import android.net.wifi.p2p.WifiP2pDeviceList; import android.net.wifi.p2p.WifiP2pGroup; +import android.net.wifi.p2p.WifiP2pGroupList; import android.net.wifi.p2p.WifiP2pInfo; import android.net.wifi.p2p.WifiP2pManager; import android.os.Bundle; @@ -360,6 +362,161 @@ public class WifiP2pSettingsTest { assertThat(mFragment.getDialogMetricsCategory(-1 /* dialogId */)).isEqualTo(0); } + @Test + public void onSaveInstanceState_withWiFiPeer_shouldGetP2pDeviceType() { + setupOneP2pPeer(WifiP2pDevice.CONNECTED); + mFragment.onPreferenceTreeClick(mWifiP2pPeer); + final Bundle outBundle = new Bundle(); + + mFragment.onSaveInstanceState(outBundle); + + final Object object = outBundle.getParcelable(WifiP2pSettings.SAVE_DIALOG_PEER); + assertThat(object instanceof WifiP2pDevice).isTrue(); + } + + @Test + public void onSaveInstanceState_withDeviceNameText_shouldSaveName() { + final String fakeDeviceName = "fakeName"; + final Bundle createBundle = new Bundle(); + createBundle.putString(WifiP2pSettings.SAVE_DEVICE_NAME, fakeDeviceName); + mFragment.onActivityCreated(createBundle); + final Bundle outBundle = new Bundle(); + final Dialog dialog = mFragment.onCreateDialog(WifiP2pSettings.DIALOG_RENAME); + + mFragment.onSaveInstanceState(outBundle); + + final String string = outBundle.getString(WifiP2pSettings.SAVE_DEVICE_NAME); + assertThat(string).isEqualTo(fakeDeviceName); + } + + @Test + public void onSaveInstanceState_withSelectedGroup_shouldSaveGroupName() { + final String fakeGroupName = "fakeGroupName"; + final WifiP2pPersistentGroup wifiP2pPersistentGroup = spy( + new WifiP2pPersistentGroup(mContext, + mWifiP2pGroup)); + doReturn(fakeGroupName).when(wifiP2pPersistentGroup).getGroupName(); + mFragment.mSelectedGroup = wifiP2pPersistentGroup; + final Bundle outBundle = new Bundle(); + + mFragment.onSaveInstanceState(outBundle); + + assertThat(outBundle.getString(WifiP2pSettings.SAVE_SELECTED_GROUP)).isEqualTo( + fakeGroupName); + } + + @Test + public void persistentController_withOneGroup_shouldBeAvailable() { + final String fakeGroupName = new String("fakeGroupName"); + doReturn(fakeGroupName).when(mWifiP2pGroup).getNetworkName(); + final List groupList = new ArrayList<>(); + groupList.add(mWifiP2pGroup); + final WifiP2pGroupList wifiP2pGroupList = mock(WifiP2pGroupList.class); + doReturn(groupList).when(wifiP2pGroupList).getGroupList(); + final Bundle bundle = new Bundle(); + bundle.putString(WifiP2pSettings.SAVE_SELECTED_GROUP, fakeGroupName); + mFragment.onActivityCreated(bundle); + + mFragment.onPersistentGroupInfoAvailable(wifiP2pGroupList); + + assertThat(mFragment.mPersistentCategoryController.isAvailable()).isTrue(); + } + + @Test + public void persistentController_withNoGroup_shouldBeUnavailable() { + final WifiP2pGroupList wifiP2pGroupList = mock(WifiP2pGroupList.class); + final List groupList = new ArrayList<>(); + doReturn(groupList).when(wifiP2pGroupList).getGroupList(); + + mFragment.onPersistentGroupInfoAvailable(wifiP2pGroupList); + + assertThat(mFragment.mPersistentCategoryController.isAvailable()).isFalse(); + } + + @Test + public void peersCategoryController_withOnePeerDevice_shouldBeAvailable() { + final WifiP2pDevice wifiP2pDevice = mock(WifiP2pDevice.class); + final ArrayList deviceList = new ArrayList<>(); + deviceList.add(wifiP2pDevice); + final WifiP2pDeviceList peers = mock(WifiP2pDeviceList.class); + doReturn(deviceList).when(peers).getDeviceList(); + + mFragment.onPeersAvailable(peers); + + assertThat(mFragment.mPeerCategoryController.isAvailable()).isTrue(); + } + + @Test + public void peersCategoryController_withNoPeerDevice_shouldBeUnavailable() { + final ArrayList deviceList = new ArrayList<>(); + final WifiP2pDeviceList peers = mock(WifiP2pDeviceList.class); + doReturn(deviceList).when(peers).getDeviceList(); + + mFragment.onPeersAvailable(peers); + + assertThat(mFragment.mPeerCategoryController.isAvailable()).isFalse(); + } + + @Test + public void thisDeviceController_onDeviceInfoAvailable_shouldUpdateDeviceName() { + final WifiP2pDevice wifiP2pDevice = mock(WifiP2pDevice.class); + final P2pThisDevicePreferenceController thisDevicePreferenceController = mock( + P2pThisDevicePreferenceController.class); + mFragment.mThisDevicePreferenceController = thisDevicePreferenceController; + + mFragment.onDeviceInfoAvailable(wifiP2pDevice); + + verify(thisDevicePreferenceController, times(1)).updateDeviceName(any()); + } + + @Test + public void p2pThisDeviceChange_shouldRequestDeviceInfoAgain() { + final Intent intent = new Intent(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION); + + mFragment.mReceiver.onReceive(mContext, intent); + + verify(mWifiP2pManager, times(2)).requestDeviceInfo(any(), any()); + } + + @Test + public void p2pPersistentGroupChange_shouldRequestGroupInfo() { + final Intent intent = new Intent(WifiP2pManager.ACTION_WIFI_P2P_PERSISTENT_GROUPS_CHANGED); + + mFragment.mReceiver.onReceive(mContext, intent); + + verify(mWifiP2pManager, times(1)).requestPersistentGroupInfo(any(), any()); + } + + @Test + public void onActivityCreate_withNullP2pManager_shouldGetP2pManagerAgain() { + mFragment.mWifiP2pManager = null; + + mFragment.onActivityCreated(new Bundle()); + + assertThat(mFragment.mWifiP2pManager).isNotNull(); + } + + @Test + public void onActivityCreate_withNullChannel_shouldSetP2pManagerNull() { + doReturn(null).when(mWifiP2pManager).initialize(any(), any(), any()); + + mFragment.onActivityCreated(new Bundle()); + + assertThat(mFragment.mWifiP2pManager).isNull(); + } + + @Test + public void clickNegativeButton_whenDeleteGroupDialogShow_shouldSetGroupNull() { + final WifiP2pPersistentGroup wifiP2pPersistentGroup = new WifiP2pPersistentGroup(mContext, + mWifiP2pGroup); + mFragment.mSelectedGroup = wifiP2pPersistentGroup; + final Dialog dialog = mFragment.onCreateDialog(WifiP2pSettings.DIALOG_DELETE_GROUP); + + mFragment.mDeleteGroupListener.onClick(dialog, DialogInterface.BUTTON_NEGATIVE); + + assertThat(mFragment.mSelectedGroup).isNull(); + } + private void setupOneP2pPeer(int status) { final WifiP2pDevice wifiP2pDevice = mock(WifiP2pDevice.class); wifiP2pDevice.status = status;