diff --git a/res/anim/confirm_credential_biometric_transition_enter.xml b/res/anim/confirm_credential_biometric_transition_enter.xml
deleted file mode 100644
index 56f35930b8e..00000000000
--- a/res/anim/confirm_credential_biometric_transition_enter.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/res/layout/advanced_bt_entity_sub.xml b/res/layout/advanced_bt_entity_sub.xml
index 17ef865a62f..0c9374fdc7c 100644
--- a/res/layout/advanced_bt_entity_sub.xml
+++ b/res/layout/advanced_bt_entity_sub.xml
@@ -47,22 +47,21 @@
+ android:layout_height="wrap_content"/>
+ android:layout_marginStart="4dp"/>
\ No newline at end of file
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 4ca9798a95d..79071ed3a05 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -408,6 +408,9 @@
7.8dp
13dp
+ 15.5dp
+ 27.5dp
+ -4dp
8dp
diff --git a/src/com/android/settings/MasterClear.java b/src/com/android/settings/MasterClear.java
index 8bb898abca2..57dfd1be809 100644
--- a/src/com/android/settings/MasterClear.java
+++ b/src/com/android/settings/MasterClear.java
@@ -344,6 +344,8 @@ public class MasterClear extends InstrumentedFragment implements OnGlobalLayoutL
noCancelMobilePlan.setVisibility(View.VISIBLE);
mEsimStorage.setChecked(true /* checked */);
}
+ } else {
+ mEsimStorage.setChecked(false /* checked */);
}
final UserManager um = (UserManager) getActivity().getSystemService(Context.USER_SERVICE);
diff --git a/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderController.java b/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderController.java
index bee93fb048d..47421923230 100644
--- a/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderController.java
+++ b/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderController.java
@@ -31,6 +31,7 @@ import android.provider.DeviceConfig;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
+import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
@@ -191,11 +192,9 @@ public class AdvancedBluetoothDetailsHeaderController extends BasePreferenceCont
context.getResources().getDimensionPixelSize(
R.dimen.advanced_bluetooth_battery_meter_height));
drawable.setBatteryLevel(level);
- final int attr = level > LOW_BATTERY_LEVEL || charging
- ? android.R.attr.colorControlNormal
- : android.R.attr.colorError;
drawable.setColorFilter(new PorterDuffColorFilter(
- com.android.settings.Utils.getColorAttrDefaultColor(context, attr),
+ com.android.settings.Utils.getColorAttrDefaultColor(context,
+ android.R.attr.colorControlNormal),
PorterDuff.Mode.SRC));
drawable.setCharging(charging);
@@ -218,12 +217,10 @@ public class AdvancedBluetoothDetailsHeaderController extends BasePreferenceCont
final boolean charging = BluetoothUtils.getBooleanMetaData(bluetoothDevice, chargeMetaKey);
if (batteryLevel != BluetoothUtils.META_INT_ERROR) {
linearLayout.setVisibility(View.VISIBLE);
- final ImageView imageView = linearLayout.findViewById(R.id.bt_battery_icon);
- imageView.setImageDrawable(createBtBatteryIcon(mContext, batteryLevel, charging));
- imageView.setVisibility(View.VISIBLE);
final TextView textView = linearLayout.findViewById(R.id.bt_battery_summary);
textView.setText(com.android.settings.Utils.formatPercentage(batteryLevel));
textView.setVisibility(View.VISIBLE);
+ showBatteryIcon(linearLayout, batteryLevel, charging);
} else {
// Hide it if it doesn't have battery information
linearLayout.setVisibility(View.GONE);
@@ -234,6 +231,28 @@ public class AdvancedBluetoothDetailsHeaderController extends BasePreferenceCont
textView.setVisibility(View.VISIBLE);
}
+ private void showBatteryIcon(LinearLayout linearLayout, int level, boolean charging) {
+ boolean enableLowBattery = level <= LOW_BATTERY_LEVEL && !charging;
+ final ImageView imageView = linearLayout.findViewById(R.id.bt_battery_icon);
+ if (enableLowBattery) {
+ imageView.setImageDrawable(mContext.getDrawable(R.drawable.ic_battery_alert_24dp));
+ LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
+ mContext.getResources().getDimensionPixelSize(
+ R.dimen.advanced_bluetooth_battery_width),
+ mContext.getResources().getDimensionPixelSize(
+ R.dimen.advanced_bluetooth_battery_height));
+ layoutParams.rightMargin = mContext.getResources().getDimensionPixelSize(
+ R.dimen.advanced_bluetooth_battery_right_margin);
+ imageView.setLayoutParams(layoutParams);
+ } else {
+ imageView.setImageDrawable(createBtBatteryIcon(mContext, level, charging));
+ LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
+ ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+ imageView.setLayoutParams(layoutParams);
+ }
+ imageView.setVisibility(View.VISIBLE);
+ }
+
private void updateDisconnectLayout() {
mLayoutPreference.findViewById(R.id.layout_left).setVisibility(View.GONE);
mLayoutPreference.findViewById(R.id.layout_right).setVisibility(View.GONE);
diff --git a/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceController.java b/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceController.java
index 5ae1fdeaf95..948eecaa5c2 100644
--- a/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceController.java
+++ b/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceController.java
@@ -466,6 +466,7 @@ public class EnabledNetworkModePreferenceController extends
}
break;
case TelephonyManagerConstants.NETWORK_MODE_NR_LTE_CDMA_EVDO:
+ case TelephonyManagerConstants.NETWORK_MODE_NR_LTE_GSM_WCDMA:
case TelephonyManagerConstants.NETWORK_MODE_NR_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA:
setSelectedEntry(networkMode);
setSummary(mContext.getString(R.string.network_5G)
diff --git a/src/com/android/settings/notification/app/ConversationListPreferenceController.java b/src/com/android/settings/notification/app/ConversationListPreferenceController.java
index 2dc52bf050d..4d424839415 100644
--- a/src/com/android/settings/notification/app/ConversationListPreferenceController.java
+++ b/src/com/android/settings/notification/app/ConversationListPreferenceController.java
@@ -70,6 +70,8 @@ public abstract class ConversationListPreferenceController extends AbstractPrefe
if (containerGroup.getPreferenceCount() == 0) {
containerGroup.setVisible(false);
+ } else {
+ containerGroup.setVisible(true);
}
}
diff --git a/src/com/android/settings/password/BiometricFragment.java b/src/com/android/settings/password/BiometricFragment.java
index 7e783227362..fc9e42e00fa 100644
--- a/src/com/android/settings/password/BiometricFragment.java
+++ b/src/com/android/settings/password/BiometricFragment.java
@@ -77,6 +77,13 @@ public class BiometricFragment extends InstrumentedFragment {
mClientCallback.onAuthenticationFailed();
});
}
+
+ @Override
+ public void onSystemEvent(int event) {
+ mClientExecutor.execute(() -> {
+ mClientCallback.onSystemEvent(event);
+ });
+ }
};
private final DialogInterface.OnClickListener mNegativeButtonListener =
@@ -121,10 +128,6 @@ public class BiometricFragment extends InstrumentedFragment {
}
}
- boolean isAuthenticating() {
- return mAuthenticating;
- }
-
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -144,7 +147,8 @@ public class BiometricFragment extends InstrumentedFragment {
.setConfirmationRequired(mBundle.getBoolean(
BiometricPrompt.KEY_REQUIRE_CONFIRMATION, true))
.setDisallowBiometricsIfPolicyExists(mBundle.getBoolean(
- BiometricPrompt.EXTRA_DISALLOW_BIOMETRICS_IF_POLICY_EXISTS, false));
+ BiometricPrompt.EXTRA_DISALLOW_BIOMETRICS_IF_POLICY_EXISTS, false))
+ .setReceiveSystemEvents(true);
mBiometricPrompt = builder.build();
mCancellationSignal = new CancellationSignal();
diff --git a/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java b/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java
index 220b64929ad..3c81eb8e0c3 100644
--- a/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java
+++ b/src/com/android/settings/password/ConfirmDeviceCredentialActivity.java
@@ -25,6 +25,7 @@ import android.app.admin.DevicePolicyManager;
import android.app.trust.TrustManager;
import android.content.Context;
import android.content.Intent;
+import android.graphics.Color;
import android.hardware.biometrics.BiometricConstants;
import android.hardware.biometrics.BiometricManager;
import android.hardware.biometrics.BiometricPrompt;
@@ -35,6 +36,7 @@ import android.os.Looper;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.Log;
+import android.view.WindowManager;
import androidx.annotation.NonNull;
import androidx.fragment.app.FragmentActivity;
@@ -142,6 +144,16 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity {
public void onAuthenticationFailed() {
mDevicePolicyManager.reportFailedBiometricAttempt(mUserId);
}
+
+ @Override
+ public void onSystemEvent(int event) {
+ Log.d(TAG, "SystemEvent: " + event);
+ switch (event) {
+ case BiometricConstants.BIOMETRIC_SYSTEM_EVENT_EARLY_USER_CANCEL:
+ finish();
+ break;
+ }
+ }
};
private String getStringForError(int errorCode) {
@@ -159,6 +171,9 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
+ getWindow().setStatusBarColor(Color.TRANSPARENT);
+
mBiometricManager = getSystemService(BiometricManager.class);
mDevicePolicyManager = getSystemService(DevicePolicyManager.class);
mUserManager = UserManager.get(this);
@@ -208,7 +223,7 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity {
getTitleFromCredentialType(credentialType, isManagedProfile));
}
if (mDetails == null) {
- bpBundle.putString(BiometricPrompt.KEY_DEVICE_CREDENTIAL_DESCRIPTION,
+ bpBundle.putString(BiometricPrompt.KEY_DEVICE_CREDENTIAL_SUBTITLE,
getDetailsFromCredentialType(credentialType, isManagedProfile));
}
@@ -379,14 +394,6 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity {
finish();
}
- @Override
- public void finish() {
- super.finish();
- // Finish without animation since the activity is just there so we can launch
- // BiometricPrompt.
- overridePendingTransition(R.anim.confirm_credential_biometric_transition_enter, 0);
- }
-
private boolean isInternalActivity() {
return this instanceof ConfirmDeviceCredentialActivity.InternalActivity;
}
diff --git a/src/com/android/settings/wifi/WifiConnectionPreferenceController.java b/src/com/android/settings/wifi/WifiConnectionPreferenceController.java
index 12a6d143656..742edd196dd 100644
--- a/src/com/android/settings/wifi/WifiConnectionPreferenceController.java
+++ b/src/com/android/settings/wifi/WifiConnectionPreferenceController.java
@@ -17,22 +17,32 @@
package com.android.settings.wifi;
import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.NetworkScoreManager;
+import android.net.wifi.WifiManager;
import android.os.Bundle;
-import android.util.FeatureFlagUtils;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.Process;
+import android.os.SimpleClock;
+import android.os.SystemClock;
+import androidx.annotation.VisibleForTesting;
import androidx.preference.PreferenceGroup;
import androidx.preference.PreferenceScreen;
import com.android.settings.R;
import com.android.settings.core.SubSettingLauncher;
-import com.android.settings.wifi.details.WifiNetworkDetailsFragment;
import com.android.settings.wifi.details2.WifiNetworkDetailsFragment2;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.lifecycle.Lifecycle;
-import com.android.settingslib.wifi.AccessPoint;
-import com.android.settingslib.wifi.AccessPointPreference;
-import com.android.settingslib.wifi.WifiTracker;
-import com.android.settingslib.wifi.WifiTrackerFactory;
+import com.android.settingslib.wifi.WifiEntryPreference;
+import com.android.wifitrackerlib.WifiEntry;
+import com.android.wifitrackerlib.WifiPickerTracker;
+
+import java.time.Clock;
+import java.time.ZoneOffset;
// TODO(b/151133650): Replace AbstractPreferenceController with BasePreferenceController.
/**
@@ -40,21 +50,28 @@ import com.android.settingslib.wifi.WifiTrackerFactory;
* controller class when there is a wifi connection present.
*/
public class WifiConnectionPreferenceController extends AbstractPreferenceController implements
- WifiTracker.WifiListener {
+ WifiPickerTracker.WifiPickerTrackerCallback {
private static final String TAG = "WifiConnPrefCtrl";
private static final String KEY = "active_wifi_connection";
+ // Max age of tracked WifiEntries.
+ private static final long MAX_SCAN_AGE_MILLIS = 15_000;
+ // Interval between initiating WifiPickerTracker scans.
+ private static final long SCAN_INTERVAL_MILLIS = 10_000;
+
private UpdateListener mUpdateListener;
private Context mPrefContext;
private String mPreferenceGroupKey;
private PreferenceGroup mPreferenceGroup;
- private WifiTracker mWifiTracker;
- private AccessPointPreference mPreference;
- private AccessPointPreference.UserBadgeCache mBadgeCache;
+ @VisibleForTesting
+ public WifiPickerTracker mWifiPickerTracker;
+ private WifiEntryPreference mPreference;
private int order;
private int mMetricsCategory;
+ // Worker thread used for WifiPickerTracker work.
+ private HandlerThread mWorkerThread;
/**
* Used to notify a parent controller that this controller has changed in availability, or has
@@ -82,16 +99,34 @@ public class WifiConnectionPreferenceController extends AbstractPreferenceContro
super(context);
mUpdateListener = updateListener;
mPreferenceGroupKey = preferenceGroupKey;
- mWifiTracker = WifiTrackerFactory.create(context, this, lifecycle, true /* includeSaved */,
- true /* includeScans */);
this.order = order;
mMetricsCategory = metricsCategory;
- mBadgeCache = new AccessPointPreference.UserBadgeCache(context.getPackageManager());
+
+ mWorkerThread = new HandlerThread(
+ TAG + "{" + Integer.toHexString(System.identityHashCode(this)) + "}",
+ Process.THREAD_PRIORITY_BACKGROUND);
+ mWorkerThread.start();
+ final Clock elapsedRealtimeClock = new SimpleClock(ZoneOffset.UTC) {
+ @Override
+ public long millis() {
+ return SystemClock.elapsedRealtime();
+ }
+ };
+ mWifiPickerTracker = new WifiPickerTracker(lifecycle, context,
+ context.getSystemService(WifiManager.class),
+ context.getSystemService(ConnectivityManager.class),
+ context.getSystemService(NetworkScoreManager.class),
+ new Handler(Looper.getMainLooper()),
+ mWorkerThread.getThreadHandler(),
+ elapsedRealtimeClock,
+ MAX_SCAN_AGE_MILLIS,
+ SCAN_INTERVAL_MILLIS,
+ this);
}
@Override
public boolean isAvailable() {
- return mWifiTracker.isConnected() && getCurrentAccessPoint() != null;
+ return mWifiPickerTracker.getConnectedWifiEntry() != null;
}
@Override
@@ -107,88 +142,69 @@ public class WifiConnectionPreferenceController extends AbstractPreferenceContro
update();
}
- private AccessPoint getCurrentAccessPoint() {
- for (AccessPoint accessPoint : mWifiTracker.getAccessPoints()) {
- if (accessPoint.isActive()) {
- return accessPoint;
- }
- }
- return null;
- }
-
- private void updatePreference(AccessPoint accessPoint) {
+ private void updatePreference(WifiEntry wifiEntry) {
if (mPreference != null) {
mPreferenceGroup.removePreference(mPreference);
mPreference = null;
}
- if (accessPoint == null) {
+ if (wifiEntry == null || mPrefContext == null) {
return;
}
- if (mPrefContext != null) {
- mPreference = new AccessPointPreference(accessPoint, mPrefContext, mBadgeCache,
- R.drawable.ic_wifi_signal_0, false /* forSavedNetworks */);
- mPreference.setKey(KEY);
- mPreference.refresh();
- mPreference.setOrder(order);
- if (FeatureFlagUtils.isEnabled(mPrefContext, FeatureFlagUtils.SETTINGS_WIFITRACKER2)) {
- mPreference.setOnPreferenceClickListener(pref -> {
- Bundle args = new Bundle();
- mPreference.getAccessPoint().saveWifiState(args);
- new SubSettingLauncher(mPrefContext)
- .setTitleRes(R.string.pref_title_network_details)
- .setDestination(WifiNetworkDetailsFragment2.class.getName())
- .setArguments(args)
- .setSourceMetricsCategory(mMetricsCategory)
- .launch();
- return true;
- });
- } else {
- mPreference.setOnPreferenceClickListener(pref -> {
- Bundle args = new Bundle();
- mPreference.getAccessPoint().saveWifiState(args);
- new SubSettingLauncher(mPrefContext)
- .setTitleRes(R.string.pref_title_network_details)
- .setDestination(WifiNetworkDetailsFragment.class.getName())
- .setArguments(args)
- .setSourceMetricsCategory(mMetricsCategory)
- .launch();
- return true;
- });
- }
- mPreferenceGroup.addPreference(mPreference);
- }
+ mPreference = new WifiEntryPreference(mPrefContext, wifiEntry);
+ mPreference.setKey(KEY);
+ mPreference.refresh();
+ mPreference.setOrder(order);
+ mPreference.setOnPreferenceClickListener(pref -> {
+ final Bundle args = new Bundle();
+ args.putString(WifiNetworkDetailsFragment2.KEY_CHOSEN_WIFIENTRY_KEY,
+ wifiEntry.getKey());
+ new SubSettingLauncher(mPrefContext)
+ .setTitleRes(R.string.pref_title_network_details)
+ .setDestination(WifiNetworkDetailsFragment2.class.getName())
+ .setArguments(args)
+ .setSourceMetricsCategory(mMetricsCategory)
+ .launch();
+ return true;
+ });
+ mPreferenceGroup.addPreference(mPreference);
}
private void update() {
- AccessPoint connectedAccessPoint = null;
- if (mWifiTracker.isConnected()) {
- connectedAccessPoint = getCurrentAccessPoint();
- }
- if (connectedAccessPoint == null) {
+ final WifiEntry connectedWifiEntry = mWifiPickerTracker.getConnectedWifiEntry();
+ if (connectedWifiEntry == null) {
updatePreference(null);
} else {
- if (mPreference == null || !mPreference.getAccessPoint().equals(connectedAccessPoint)) {
- updatePreference(connectedAccessPoint);
- } else if (mPreference != null) {
- mPreference.refresh();
- }
+ if (mPreference == null || !mPreference.getWifiEntry().equals(connectedWifiEntry)) {
+ updatePreference(connectedWifiEntry);
+ } else if (mPreference != null) {
+ mPreference.refresh();
+ }
}
mUpdateListener.onChildrenUpdated();
}
+ /** Called when the state of Wifi has changed. */
@Override
- public void onWifiStateChanged(int state) {
+ public void onWifiStateChanged() {
+ update();
+ }
+
+ /**
+ * Update the results when data changes.
+ */
+ @Override
+ public void onWifiEntriesChanged() {
update();
}
@Override
- public void onConnectedChanged() {
- update();
+ public void onNumSavedSubscriptionsChanged() {
+ // Do nothing.
}
@Override
- public void onAccessPointsChanged() {
- update();
+ public void onNumSavedNetworksChanged() {
+ // Do nothing.
}
}
diff --git a/tests/perftests/AndroidTest.xml b/tests/perftests/AndroidTest.xml
new file mode 100644
index 00000000000..a2af24a1c1f
--- /dev/null
+++ b/tests/perftests/AndroidTest.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/robotests/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderControllerTest.java b/tests/robotests/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderControllerTest.java
index 80ab42c58a1..5097938f2ee 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderControllerTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderControllerTest.java
@@ -21,6 +21,7 @@ import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import static org.robolectric.Shadows.shadowOf;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
@@ -58,6 +59,7 @@ public class AdvancedBluetoothDetailsHeaderControllerTest {
private static final int BATTERY_LEVEL_MAIN = 30;
private static final int BATTERY_LEVEL_LEFT = 25;
private static final int BATTERY_LEVEL_RIGHT = 45;
+ private static final int LOW_BATTERY_LEVEL = 5;
private static final String ICON_URI = "content://test.provider/icon.png";
private static final String MAC_ADDRESS = "04:52:C7:0B:D8:3C";
@@ -115,6 +117,7 @@ public class AdvancedBluetoothDetailsHeaderControllerTest {
when(mBluetoothDevice.getMetadata(
BluetoothDevice.METADATA_UNTETHERED_CASE_BATTERY)).thenReturn(
String.valueOf(BATTERY_LEVEL_MAIN).getBytes());
+
when(mCachedDevice.isConnected()).thenReturn(true);
mController.refresh();
@@ -143,6 +146,36 @@ public class AdvancedBluetoothDetailsHeaderControllerTest {
assertThat(layout.findViewById(R.id.header_icon).getVisibility()).isEqualTo(View.VISIBLE);
}
+ @Test
+ public void refresh_withLowBatteryAndUncharged_showAlertIcon() {
+ when(mBluetoothDevice.getMetadata(
+ BluetoothDevice.METADATA_UNTETHERED_LEFT_BATTERY)).thenReturn(
+ String.valueOf(LOW_BATTERY_LEVEL).getBytes());
+ when(mBluetoothDevice.getMetadata(
+ BluetoothDevice.METADATA_UNTETHERED_RIGHT_BATTERY)).thenReturn(
+ String.valueOf(LOW_BATTERY_LEVEL).getBytes());
+ when(mBluetoothDevice.getMetadata(
+ BluetoothDevice.METADATA_UNTETHERED_CASE_BATTERY)).thenReturn(
+ String.valueOf(BATTERY_LEVEL_MAIN).getBytes());
+ when(mBluetoothDevice.getMetadata(
+ BluetoothDevice.METADATA_UNTETHERED_LEFT_CHARGING)).thenReturn(
+ String.valueOf(false).getBytes());
+ when(mBluetoothDevice.getMetadata(
+ BluetoothDevice.METADATA_UNTETHERED_RIGHT_CHARGING)).thenReturn(
+ String.valueOf(true).getBytes());
+ when(mBluetoothDevice.getMetadata(
+ BluetoothDevice.METADATA_UNTETHERED_CASE_CHARGING)).thenReturn(
+ String.valueOf(false).getBytes());
+ when(mCachedDevice.isConnected()).thenReturn(true);
+
+ mController.refresh();
+
+ assertBatteryIcon(mLayoutPreference.findViewById(R.id.layout_left),
+ R.drawable.ic_battery_alert_24dp);
+ assertBatteryIcon(mLayoutPreference.findViewById(R.id.layout_right), /* resId= */-1);
+ assertBatteryIcon(mLayoutPreference.findViewById(R.id.layout_middle), /* resId= */ -1);
+ }
+
@Test
public void getAvailabilityStatus_untetheredHeadsetWithConfigOn_returnAvailable() {
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SETTINGS_UI,
@@ -256,4 +289,10 @@ public class AdvancedBluetoothDetailsHeaderControllerTest {
com.android.settings.Utils.formatPercentage(batteryLevel));
}
+ private void assertBatteryIcon(LinearLayout linearLayout, int resId) {
+ final ImageView imageView = linearLayout.findViewById(R.id.bt_battery_icon);
+ assertThat(shadowOf(imageView.getDrawable()).getCreatedFromResId())
+ .isEqualTo(resId);
+ }
+
}
diff --git a/tests/robotests/src/com/android/settings/network/WifiConnectionPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/WifiConnectionPreferenceControllerTest.java
index 703731858c3..ea957c3e762 100644
--- a/tests/robotests/src/com/android/settings/network/WifiConnectionPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/network/WifiConnectionPreferenceControllerTest.java
@@ -29,12 +29,15 @@ import static org.mockito.Mockito.when;
import android.content.Context;
+import androidx.lifecycle.LifecycleOwner;
+import androidx.preference.PreferenceCategory;
+import androidx.preference.PreferenceScreen;
+
import com.android.settings.wifi.WifiConnectionPreferenceController;
import com.android.settingslib.core.lifecycle.Lifecycle;
-import com.android.settingslib.wifi.AccessPoint;
-import com.android.settingslib.wifi.AccessPointPreference;
-import com.android.settingslib.wifi.WifiTracker;
-import com.android.settingslib.wifi.WifiTrackerFactory;
+import com.android.settingslib.wifi.WifiEntryPreference;
+import com.android.wifitrackerlib.WifiEntry;
+import com.android.wifitrackerlib.WifiPickerTracker;
import org.junit.Before;
import org.junit.Test;
@@ -45,19 +48,12 @@ import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
-import java.util.ArrayList;
-import java.util.Arrays;
-
-import androidx.lifecycle.LifecycleOwner;
-import androidx.preference.PreferenceCategory;
-import androidx.preference.PreferenceScreen;
-
@RunWith(RobolectricTestRunner.class)
public class WifiConnectionPreferenceControllerTest {
private static final String KEY = "wifi_connection";
@Mock
- WifiTracker mWifiTracker;
+ WifiPickerTracker mWifiPickerTracker;
@Mock
PreferenceScreen mScreen;
@Mock
@@ -74,7 +70,6 @@ public class WifiConnectionPreferenceControllerTest {
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = spy(RuntimeEnvironment.application);
- WifiTrackerFactory.setTestingWifiTracker(mWifiTracker);
mLifecycleOwner = () -> mLifecycle;
mLifecycle = new Lifecycle(mLifecycleOwner);
when(mScreen.findPreference(eq(KEY))).thenReturn(mPreferenceCategory);
@@ -83,49 +78,51 @@ public class WifiConnectionPreferenceControllerTest {
mController = new WifiConnectionPreferenceController(mContext, mLifecycle, mUpdateListener,
KEY, 0, 0);
+ mController.mWifiPickerTracker = mWifiPickerTracker;
}
@Test
- public void isAvailable_noWiFiConnection_availableIsFalse() {
- when(mWifiTracker.isConnected()).thenReturn(false);
+ public void isAvailable_noConnectedWifiEntry_availableIsFalse() {
+ when(mWifiPickerTracker.getConnectedWifiEntry()).thenReturn(null);
+
assertThat(mController.isAvailable()).isFalse();
}
@Test
- public void displayPreference_noWiFiConnection_noPreferenceAdded() {
- when(mWifiTracker.isConnected()).thenReturn(false);
- when(mWifiTracker.getAccessPoints()).thenReturn(new ArrayList<>());
+ public void displayPreference_noConnectedWifiEntry_noPreferenceAdded() {
+ when(mWifiPickerTracker.getConnectedWifiEntry()).thenReturn(null);
+
mController.displayPreference(mScreen);
+
verify(mPreferenceCategory, never()).addPreference(any());
}
@Test
- public void displayPreference_hasWiFiConnection_preferenceAdded() {
- when(mWifiTracker.isConnected()).thenReturn(true);
- final AccessPoint accessPoint = mock(AccessPoint.class);
- when(accessPoint.isActive()).thenReturn(true);
- when(mWifiTracker.getAccessPoints()).thenReturn(Arrays.asList(accessPoint));
+ public void displayPreference_hasConnectedWifiEntry_preferenceAdded() {
+ final WifiEntry wifiEntry = mock(WifiEntry.class);
+ when(mWifiPickerTracker.getConnectedWifiEntry()).thenReturn(wifiEntry);
+
mController.displayPreference(mScreen);
- verify(mPreferenceCategory).addPreference(any(AccessPointPreference.class));
+ verify(mPreferenceCategory).addPreference(any(WifiEntryPreference.class));
}
@Test
public void onConnectedChanged_wifiBecameDisconnected_preferenceRemoved() {
- when(mWifiTracker.isConnected()).thenReturn(true);
- final AccessPoint accessPoint = mock(AccessPoint.class);
+ final WifiEntry wifiEntry = mock(WifiEntry.class);
+ when(mWifiPickerTracker.getConnectedWifiEntry()).thenReturn(wifiEntry);
- when(accessPoint.isActive()).thenReturn(true);
- when(mWifiTracker.getAccessPoints()).thenReturn(Arrays.asList(accessPoint));
mController.displayPreference(mScreen);
- final ArgumentCaptor captor = ArgumentCaptor.forClass(
- AccessPointPreference.class);
+ final ArgumentCaptor captor = ArgumentCaptor.forClass(
+ WifiEntryPreference.class);
verify(mPreferenceCategory).addPreference(captor.capture());
- final AccessPointPreference pref = captor.getValue();
+ final WifiEntryPreference pref = captor.getValue();
- when(mWifiTracker.isConnected()).thenReturn(false);
- when(mWifiTracker.getAccessPoints()).thenReturn(new ArrayList<>());
+ // Become disconnected.
+ when(mWifiPickerTracker.getConnectedWifiEntry()).thenReturn(null);
final int onUpdatedCountBefore = mOnChildUpdatedCount;
- mController.onConnectedChanged();
+
+ mController.onWifiStateChanged();
+
verify(mPreferenceCategory).removePreference(pref);
assertThat(mOnChildUpdatedCount).isEqualTo(onUpdatedCountBefore + 1);
}
@@ -133,28 +130,24 @@ public class WifiConnectionPreferenceControllerTest {
@Test
public void onAccessPointsChanged_wifiBecameConnectedToDifferentAP_preferenceReplaced() {
- when(mWifiTracker.isConnected()).thenReturn(true);
- final AccessPoint accessPoint1 = mock(AccessPoint.class);
-
- when(accessPoint1.isActive()).thenReturn(true);
- when(mWifiTracker.getAccessPoints()).thenReturn(Arrays.asList(accessPoint1));
+ final WifiEntry wifiEntry1 = mock(WifiEntry.class);
+ when(wifiEntry1.getKey()).thenReturn("KEY_1");
+ when(mWifiPickerTracker.getConnectedWifiEntry()).thenReturn(wifiEntry1);
mController.displayPreference(mScreen);
- final ArgumentCaptor captor = ArgumentCaptor.forClass(
- AccessPointPreference.class);
+ final ArgumentCaptor captor = ArgumentCaptor.forClass(
+ WifiEntryPreference.class);
-
- final AccessPoint accessPoint2 = mock(AccessPoint.class);
- when(accessPoint1.isActive()).thenReturn(false);
- when(accessPoint2.isActive()).thenReturn(true);
- when(mWifiTracker.getAccessPoints()).thenReturn(Arrays.asList(accessPoint1, accessPoint2));
+ final WifiEntry wifiEntry2 = mock(WifiEntry.class);
+ when(wifiEntry1.getKey()).thenReturn("KEY_2");
+ when(mWifiPickerTracker.getConnectedWifiEntry()).thenReturn(wifiEntry2);
final int onUpdatedCountBefore = mOnChildUpdatedCount;
- mController.onAccessPointsChanged();
+ mController.onWifiEntriesChanged();
verify(mPreferenceCategory, times(2)).addPreference(captor.capture());
- final AccessPointPreference pref1 = captor.getAllValues().get(0);
- final AccessPointPreference pref2 = captor.getAllValues().get(1);
- assertThat(pref1.getAccessPoint()).isEqualTo(accessPoint1);
- assertThat(pref2.getAccessPoint()).isEqualTo(accessPoint2);
+ final WifiEntryPreference pref1 = captor.getAllValues().get(0);
+ final WifiEntryPreference pref2 = captor.getAllValues().get(1);
+ assertThat(pref1.getWifiEntry()).isEqualTo(wifiEntry1);
+ assertThat(pref2.getWifiEntry()).isEqualTo(wifiEntry2);
verify(mPreferenceCategory).removePreference(eq(pref1));
assertThat(mOnChildUpdatedCount).isEqualTo(onUpdatedCountBefore + 1);
}
diff --git a/tests/robotests/src/com/android/settings/notification/app/ConversationListPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/app/ConversationListPreferenceControllerTest.java
index 6cc20d78acd..dc82adbd028 100644
--- a/tests/robotests/src/com/android/settings/notification/app/ConversationListPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/app/ConversationListPreferenceControllerTest.java
@@ -21,6 +21,7 @@ import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -34,6 +35,8 @@ import android.provider.Settings;
import android.service.notification.ConversationChannelWrapper;
import androidx.preference.PreferenceCategory;
+import androidx.preference.PreferenceManager;
+import androidx.preference.PreferenceScreen;
import com.android.settings.applications.AppInfoBase;
import com.android.settings.notification.NotificationBackend;
@@ -85,7 +88,10 @@ public class ConversationListPreferenceControllerTest {
@Test
public void testPopulateList_validConversations() {
- PreferenceCategory outerContainer = mock(PreferenceCategory.class);
+ final PreferenceManager preferenceManager = new PreferenceManager(mContext);
+ PreferenceScreen ps = preferenceManager.createPreferenceScreen(mContext);
+ PreferenceCategory outerContainer = spy(new PreferenceCategory(mContext));
+ ps.addPreference(outerContainer);
ConversationChannelWrapper ccw = new ConversationChannelWrapper();
ccw.setNotificationChannel(mock(NotificationChannel.class));
diff --git a/tests/robotests/src/com/android/settings/notification/zen/ZenModeEventRuleSettingsTest.java b/tests/robotests/src/com/android/settings/notification/zen/ZenModeEventRuleSettingsTest.java
index 0c49850f5b6..8ebac3097e0 100644
--- a/tests/robotests/src/com/android/settings/notification/zen/ZenModeEventRuleSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/notification/zen/ZenModeEventRuleSettingsTest.java
@@ -19,6 +19,7 @@ package com.android.settings.notification.zen;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -28,11 +29,11 @@ import android.app.NotificationManager;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
+import android.os.Looper;
import androidx.fragment.app.FragmentActivity;
import com.android.settings.R;
-import com.android.settings.notification.zen.ZenModeEventRuleSettings;
import org.junit.Before;
import org.junit.Test;
@@ -40,7 +41,6 @@ import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.shadows.ShadowApplication;
import org.robolectric.shadows.ShadowToast;
@@ -68,7 +68,7 @@ public class ZenModeEventRuleSettingsTest {
ShadowApplication shadowApplication = ShadowApplication.getInstance();
shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNotificationManager);
- mContext = RuntimeEnvironment.application;
+ mContext = application;
mFragment = spy(new TestFragment());
mFragment.onAttach(application);
@@ -81,6 +81,7 @@ public class ZenModeEventRuleSettingsTest {
when(mActivity.getTheme()).thenReturn(res.newTheme());
when(mActivity.getIntent()).thenReturn(mIntent);
when(mActivity.getResources()).thenReturn(res);
+ when(mActivity.getMainLooper()).thenReturn(mock(Looper.class));
when(mFragment.getContext()).thenReturn(mContext);
}
diff --git a/tests/robotests/src/com/android/settings/notification/zen/ZenModeScheduleRuleSettingsTest.java b/tests/robotests/src/com/android/settings/notification/zen/ZenModeScheduleRuleSettingsTest.java
index a556dbfaa88..ff96d687902 100644
--- a/tests/robotests/src/com/android/settings/notification/zen/ZenModeScheduleRuleSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/notification/zen/ZenModeScheduleRuleSettingsTest.java
@@ -19,6 +19,7 @@ package com.android.settings.notification.zen;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -28,11 +29,11 @@ import android.app.NotificationManager;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
+import android.os.Looper;
import androidx.fragment.app.FragmentActivity;
import com.android.settings.R;
-import com.android.settings.notification.zen.ZenModeScheduleRuleSettings;
import org.junit.Before;
import org.junit.Test;
@@ -40,7 +41,6 @@ import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.shadows.ShadowApplication;
import org.robolectric.shadows.ShadowToast;
@@ -65,7 +65,7 @@ public class ZenModeScheduleRuleSettingsTest {
ShadowApplication shadowApplication = ShadowApplication.getInstance();
shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNotificationManager);
- mContext = RuntimeEnvironment.application;
+ mContext = application;
mFragment = spy(new TestFragment());
mFragment.onAttach(application);
@@ -78,6 +78,7 @@ public class ZenModeScheduleRuleSettingsTest {
when(mActivity.getTheme()).thenReturn(res.newTheme());
when(mActivity.getIntent()).thenReturn(mIntent);
when(mActivity.getResources()).thenReturn(res);
+ when(mActivity.getMainLooper()).thenReturn(mock(Looper.class));
when(mFragment.getContext()).thenReturn(mContext);
}
diff --git a/tests/robotests/src/com/android/settings/wifi/details2/WifiMeteredPreferenceController2Test.java b/tests/robotests/src/com/android/settings/wifi/details2/WifiMeteredPreferenceController2Test.java
index 9c31d4481b8..c63fa60437b 100644
--- a/tests/robotests/src/com/android/settings/wifi/details2/WifiMeteredPreferenceController2Test.java
+++ b/tests/robotests/src/com/android/settings/wifi/details2/WifiMeteredPreferenceController2Test.java
@@ -31,6 +31,7 @@ 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;
@@ -50,6 +51,7 @@ public class WifiMeteredPreferenceController2Test {
@Before
public void setUp() {
+ MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application;
mPreferenceController = spy(