Merge "Apply new slice attributes to customize layout"
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 84b12dc..70dce8f 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -443,7 +443,7 @@
android:exported="true"
android:permission="android.permission.TETHER_PRIVILEGED" />
- <activity android:name="network.TetherProvisioningActivity"
+ <activity android:name=".network.TetherProvisioningActivity"
android:exported="true"
android:permission="android.permission.TETHER_PRIVILEGED"
android:excludeFromRecents="true"
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 7bd9950..281389d 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1433,13 +1433,13 @@
<string name="unlock_change_lock_password_title">Change unlock password</string>
<!-- Footer preference text in the screen lock type picker to indicate which app is requesting a new screen lock and that it requests for a strong PIN or password [CHAR LIMIT=NONE] -->
- <string name="unlock_footer_high_complexity_requested"><xliff:g id="app_name" example="Gmail">%1$s</xliff:g> requests a strong PIN or password.</string>
+ <string name="unlock_footer_high_complexity_requested"><xliff:g id="app_name" example="Gmail">%1$s</xliff:g> recommends a strong PIN or password and may not work as expected without one</string>
<!-- Footer preference text in the screen lock type picker to indicate which app is requesting a new screen lock and that it requests for a medium strength PIN or password [CHAR LIMIT=NONE] -->
- <string name="unlock_footer_medium_complexity_requested"><xliff:g id="app_name" example="Gmail">%1$s</xliff:g> requests a new PIN or password.</string>
+ <string name="unlock_footer_medium_complexity_requested"><xliff:g id="app_name" example="Gmail">%1$s</xliff:g> recommends a new PIN or password and may not work as expected without one</string>
<!-- Footer preference text in the screen lock type picker to indicate which app is requesting a new screen lock and it requests for any screen lock [CHAR LIMIT=NONE] -->
- <string name="unlock_footer_low_complexity_requested"><xliff:g id="app_name" example="Gmail">%1$s</xliff:g> requests a new pattern, PIN or password.</string>
+ <string name="unlock_footer_low_complexity_requested"><xliff:g id="app_name" example="Gmail">%1$s</xliff:g> recommends a new pattern, PIN, or password and may not work as expected without one</string>
<!-- Footer preference text in the screen lock type picker to indicate which app is requesting a new screen lock [CHAR LIMIT=NONE] -->
- <string name="unlock_footer_none_complexity_requested"><xliff:g id="app_name" example="Gmail">%1$s</xliff:g> requests a new screen lock.</string>
+ <string name="unlock_footer_none_complexity_requested"><xliff:g id="app_name" example="Gmail">%1$s</xliff:g> recommends a new screen lock</string>
<!-- Message shown on the lock screen when the user incorrectly enters their lock and it counts towards the max attempts before their data on the device is wiped. [CHAR LIMIT=NONE] -->
diff --git a/src/com/android/settings/MasterClear.java b/src/com/android/settings/MasterClear.java
index 8dad57f..58bc58c 100644
--- a/src/com/android/settings/MasterClear.java
+++ b/src/com/android/settings/MasterClear.java
@@ -65,10 +65,10 @@
import com.android.settings.password.ConfirmLockPattern;
import com.android.settingslib.RestrictedLockUtilsInternal;
-import com.google.android.setupcompat.TemplateLayout;
import com.google.android.setupcompat.template.FooterBarMixin;
import com.google.android.setupcompat.template.FooterButton;
import com.google.android.setupcompat.template.FooterButton.ButtonType;
+import com.google.android.setupdesign.GlifLayout;
import java.util.List;
@@ -416,7 +416,7 @@
return;
}
- final TemplateLayout layout = mContentView.findViewById(R.id.setup_wizard_layout);
+ final GlifLayout layout = mContentView.findViewById(R.id.setup_wizard_layout);
final FooterBarMixin mixin = layout.getMixin(FooterBarMixin.class);
mixin.setPrimaryButton(
new FooterButton.Builder(getActivity())
diff --git a/src/com/android/settings/MasterClearConfirm.java b/src/com/android/settings/MasterClearConfirm.java
index c25f2af..618dd2c 100644
--- a/src/com/android/settings/MasterClearConfirm.java
+++ b/src/com/android/settings/MasterClearConfirm.java
@@ -44,10 +44,10 @@
import com.android.settings.enterprise.ActionDisabledByAdminDialogHelper;
import com.android.settingslib.RestrictedLockUtilsInternal;
-import com.google.android.setupcompat.TemplateLayout;
import com.google.android.setupcompat.template.FooterBarMixin;
import com.google.android.setupcompat.template.FooterButton;
import com.google.android.setupcompat.template.FooterButton.ButtonType;
+import com.google.android.setupdesign.GlifLayout;
/**
* Confirm and execute a reset of the device to a clean "just out of the box"
@@ -152,7 +152,7 @@
* Configure the UI for the final confirmation interaction
*/
private void establishFinalConfirmationState() {
- final TemplateLayout layout = mContentView.findViewById(R.id.setup_wizard_layout);
+ final GlifLayout layout = mContentView.findViewById(R.id.setup_wizard_layout);
final FooterBarMixin mixin = layout.getMixin(FooterBarMixin.class);
mixin.setPrimaryButton(
diff --git a/src/com/android/settings/accessibility/AccessibilityHearingAidPreferenceController.java b/src/com/android/settings/accessibility/AccessibilityHearingAidPreferenceController.java
index 617a9bb..1881ca7 100644
--- a/src/com/android/settings/accessibility/AccessibilityHearingAidPreferenceController.java
+++ b/src/com/android/settings/accessibility/AccessibilityHearingAidPreferenceController.java
@@ -148,7 +148,8 @@
mFragmentManager = fragmentManager;
}
- private CachedBluetoothDevice getConnectedHearingAidDevice() {
+ @VisibleForTesting
+ CachedBluetoothDevice getConnectedHearingAidDevice() {
if (!mHearingAidProfileSupported) {
return null;
}
@@ -158,9 +159,11 @@
final List<BluetoothDevice> deviceList = mLocalBluetoothManager.getProfileManager()
.getHearingAidProfile().getConnectedDevices();
final Iterator it = deviceList.iterator();
- if (it.hasNext()) {
+ while (it.hasNext()) {
BluetoothDevice obj = (BluetoothDevice)it.next();
- return mLocalBluetoothManager.getCachedDeviceManager().findDevice(obj);
+ if (!mLocalBluetoothManager.getCachedDeviceManager().isSubDevice(obj)) {
+ return mLocalBluetoothManager.getCachedDeviceManager().findDevice(obj);
+ }
}
return null;
}
diff --git a/src/com/android/settings/biometrics/face/FaceSettings.java b/src/com/android/settings/biometrics/face/FaceSettings.java
index 4e2c711..490580d 100644
--- a/src/com/android/settings/biometrics/face/FaceSettings.java
+++ b/src/com/android/settings/biometrics/face/FaceSettings.java
@@ -58,7 +58,9 @@
private FaceSettingsAttentionPreferenceController mAttentionController;
private final FaceSettingsRemoveButtonPreferenceController.Listener mRemovalListener = () -> {
- getActivity().finish();
+ if (getActivity() != null) {
+ getActivity().finish();
+ }
};
public static boolean isAvailable(Context context) {
diff --git a/src/com/android/settings/network/SubscriptionUtil.java b/src/com/android/settings/network/SubscriptionUtil.java
index 237e08a..224fc41 100644
--- a/src/com/android/settings/network/SubscriptionUtil.java
+++ b/src/com/android/settings/network/SubscriptionUtil.java
@@ -38,7 +38,7 @@
if (sResultsForTesting != null) {
return sResultsForTesting;
}
- List<SubscriptionInfo> subscriptions = manager.getAvailableSubscriptionInfoList();
+ List<SubscriptionInfo> subscriptions = manager.getSelectableSubscriptionInfoList();
if (subscriptions == null) {
subscriptions = new ArrayList<>();
}
diff --git a/src/com/android/settings/network/telephony/MobileNetworkActivity.java b/src/com/android/settings/network/telephony/MobileNetworkActivity.java
index 821b1e1..3c0940d 100644
--- a/src/com/android/settings/network/telephony/MobileNetworkActivity.java
+++ b/src/com/android/settings/network/telephony/MobileNetworkActivity.java
@@ -160,7 +160,7 @@
final int subId = intent.getIntExtra(Settings.EXTRA_SUB_ID, SUB_ID_NULL);
if (subId != SUB_ID_NULL) {
for (SubscriptionInfo subscription :
- mSubscriptionManager.getAvailableSubscriptionInfoList()) {
+ mSubscriptionManager.getSelectableSubscriptionInfoList()) {
if (subscription.getSubscriptionId() == subId) {
return subscription;
}
diff --git a/src/com/android/settings/wifi/calling/WifiCallingSettingsForSub.java b/src/com/android/settings/wifi/calling/WifiCallingSettingsForSub.java
index 40cc0dc..9ed2035 100644
--- a/src/com/android/settings/wifi/calling/WifiCallingSettingsForSub.java
+++ b/src/com/android/settings/wifi/calling/WifiCallingSettingsForSub.java
@@ -29,6 +29,7 @@
import android.telephony.PhoneStateListener;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
+import android.telephony.ims.ProvisioningManager;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
@@ -44,7 +45,9 @@
import androidx.preference.PreferenceScreen;
import com.android.ims.ImsConfig;
+import com.android.ims.ImsException;
import com.android.ims.ImsManager;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.Phone;
import com.android.settings.R;
import com.android.settings.SettingsActivity;
@@ -152,6 +155,19 @@
}
};
+ private final ProvisioningManager.Callback mProvisioningCallback =
+ new ProvisioningManager.Callback() {
+ @Override
+ public void onProvisioningIntChanged(int item, int value) {
+ if (item == ImsConfig.ConfigConstants.VOICE_OVER_WIFI_SETTING_ENABLED
+ || item == ImsConfig.ConfigConstants.VLT_SETTING_ENABLED) {
+ // The provisioning policy might have changed. Update the body to make sure
+ // this change takes effect if needed.
+ updateBody();
+ }
+ }
+ };
+
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
@@ -221,6 +237,11 @@
return 0;
}
+ @VisibleForTesting
+ ImsManager getImsManager() {
+ return ImsManager.getInstance(getActivity(), SubscriptionManager.getPhoneId(mSubId));
+ }
+
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -236,8 +257,7 @@
FRAGMENT_BUNDLE_SUBID, SubscriptionManager.INVALID_SUBSCRIPTION_ID);
}
- mImsManager = ImsManager.getInstance(
- getActivity(), SubscriptionManager.getPhoneId(mSubId));
+ mImsManager = getImsManager();
mTelephonyManager = ((TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE))
.createForSubscriptionId(mSubId);
@@ -277,6 +297,13 @@
}
private void updateBody() {
+ if (!mImsManager.isWfcProvisionedOnDevice()) {
+ // This screen is not allowed to be shown due to provisioning policy and should
+ // therefore be closed.
+ finish();
+ return;
+ }
+
CarrierConfigManager configManager = (CarrierConfigManager)
getSystemService(Context.CARRIER_CONFIG_SERVICE);
boolean isWifiOnlySupported = true;
@@ -336,6 +363,14 @@
if (intent.getBooleanExtra(Phone.EXTRA_KEY_ALERT_SHOW, false)) {
showAlert(intent);
}
+
+ // Register callback for provisioning changes.
+ try {
+ mImsManager.getConfigInterface().addConfigCallback(mProvisioningCallback);
+ } catch (ImsException e) {
+ Log.w(TAG, "onResume: Unable to register callback for provisioning changes.");
+ }
+
}
@Override
@@ -354,6 +389,15 @@
}
context.unregisterReceiver(mIntentReceiver);
+
+ // Remove callback for provisioning changes.
+ try {
+ mImsManager.getConfigInterface().removeConfigCallback(
+ mProvisioningCallback.getBinder());
+ } catch (ImsException e) {
+ Log.w(TAG, "onPause: Unable to remove callback for provisioning changes");
+ }
+
}
/**
diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilityHearingAidPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilityHearingAidPreferenceControllerTest.java
index 951f203..3f4e82d 100644
--- a/tests/robotests/src/com/android/settings/accessibility/AccessibilityHearingAidPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilityHearingAidPreferenceControllerTest.java
@@ -181,6 +181,15 @@
verify(mContext, never()).unregisterReceiver(any());
}
+ @Test
+ public void getConnectedHearingAidDevice_doNotReturnSubDevice() {
+ when(mHearingAidProfile.getConnectedDevices()).thenReturn(generateHearingAidDeviceList());
+ when(mLocalBluetoothManager.getCachedDeviceManager().isSubDevice(mBluetoothDevice))
+ .thenReturn(true);
+
+ assertThat(mPreferenceController.getConnectedHearingAidDevice()).isNull();
+ }
+
private void setupBluetoothEnvironment() {
ShadowBluetoothUtils.sLocalBluetoothManager = mLocalBluetoothManager;
mLocalBluetoothManager = Utils.getLocalBtManager(mContext);
diff --git a/tests/robotests/src/com/android/settings/network/SubscriptionUtilTest.java b/tests/robotests/src/com/android/settings/network/SubscriptionUtilTest.java
index e0334b1..dbc122a 100644
--- a/tests/robotests/src/com/android/settings/network/SubscriptionUtilTest.java
+++ b/tests/robotests/src/com/android/settings/network/SubscriptionUtilTest.java
@@ -47,7 +47,7 @@
@Test
public void getAvailableSubscriptions_nullInfoFromSubscriptionManager_nonNullResult() {
- when(mManager.getAvailableSubscriptionInfoList()).thenReturn(null);
+ when(mManager.getSelectableSubscriptionInfoList()).thenReturn(null);
final List<SubscriptionInfo> subs = SubscriptionUtil.getAvailableSubscriptions(mManager);
assertThat(subs).isNotNull();
assertThat(subs).isEmpty();
@@ -57,7 +57,7 @@
public void getAvailableSubscriptions_oneSubscription_oneResult() {
final SubscriptionInfo info = mock(SubscriptionInfo.class);
when(info.getMncString()).thenReturn("fake1234");
- when(mManager.getAvailableSubscriptionInfoList()).thenReturn(Arrays.asList(info));
+ when(mManager.getSelectableSubscriptionInfoList()).thenReturn(Arrays.asList(info));
final List<SubscriptionInfo> subs = SubscriptionUtil.getAvailableSubscriptions(mManager);
assertThat(subs).isNotNull();
assertThat(subs).hasSize(1);
@@ -69,7 +69,7 @@
final SubscriptionInfo info2 = mock(SubscriptionInfo.class);
when(info1.getMncString()).thenReturn("fake1234");
when(info2.getMncString()).thenReturn("fake5678");
- when(mManager.getAvailableSubscriptionInfoList()).thenReturn(Arrays.asList(info1, info2));
+ when(mManager.getSelectableSubscriptionInfoList()).thenReturn(Arrays.asList(info1, info2));
final List<SubscriptionInfo> subs = SubscriptionUtil.getAvailableSubscriptions(mManager);
assertThat(subs).isNotNull();
assertThat(subs).hasSize(2);
@@ -82,7 +82,7 @@
final SubscriptionInfo info3 = mock(SubscriptionInfo.class);
when(info1.getSubscriptionId()).thenReturn(1);
when(info1.getMncString()).thenReturn("fake1234");
- when(mManager.getAvailableSubscriptionInfoList()).thenReturn(
+ when(mManager.getSelectableSubscriptionInfoList()).thenReturn(
new ArrayList<>(Arrays.asList(info1, info2, info3)));
final List<SubscriptionInfo> subs = SubscriptionUtil.getAvailableSubscriptions(mManager);
assertThat(subs).isNotNull();
@@ -100,7 +100,7 @@
when(info1.getMncString()).thenReturn("fake1234");
when(info4.getSubscriptionId()).thenReturn(4);
when(info4.getMncString()).thenReturn("fake5678");
- when(mManager.getAvailableSubscriptionInfoList()).thenReturn(new ArrayList<>(
+ when(mManager.getSelectableSubscriptionInfoList()).thenReturn(new ArrayList<>(
Arrays.asList(info1, info2, info3, info4)));
final List<SubscriptionInfo> subs = SubscriptionUtil.getAvailableSubscriptions(mManager);
assertThat(subs).isNotNull();
diff --git a/tests/robotests/src/com/android/settings/network/telephony/MobileNetworkActivityTest.java b/tests/robotests/src/com/android/settings/network/telephony/MobileNetworkActivityTest.java
index 447931e..3b5cdf9 100644
--- a/tests/robotests/src/com/android/settings/network/telephony/MobileNetworkActivityTest.java
+++ b/tests/robotests/src/com/android/settings/network/telephony/MobileNetworkActivityTest.java
@@ -148,7 +148,7 @@
doReturn(intent).when(mMobileNetworkActivity).getIntent();
mSubscriptionInfos.add(mSubscriptionInfo);
mSubscriptionInfos.add(mSubscriptionInfo2);
- doReturn(mSubscriptionInfos).when(mSubscriptionManager).getAvailableSubscriptionInfoList();
+ doReturn(mSubscriptionInfos).when(mSubscriptionManager).getSelectableSubscriptionInfoList();
doReturn(true).when(mSubscriptionManager).isActiveSubscriptionId(CURRENT_SUB_ID);
assertThat(mMobileNetworkActivity.getSubscriptionId()).isEqualTo(CURRENT_SUB_ID);
diff --git a/tests/robotests/src/com/android/settings/wifi/calling/WifiCallingSettingsForSubTest.java b/tests/robotests/src/com/android/settings/wifi/calling/WifiCallingSettingsForSubTest.java
index b194d73..98795a7 100644
--- a/tests/robotests/src/com/android/settings/wifi/calling/WifiCallingSettingsForSubTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/calling/WifiCallingSettingsForSubTest.java
@@ -18,15 +18,140 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+import android.telephony.TelephonyManager;
+import android.telephony.ims.ProvisioningManager;
+import android.view.View;
+import android.widget.TextView;
+
+import androidx.preference.ListPreference;
+import androidx.preference.PreferenceScreen;
+
+import com.android.ims.ImsConfig;
+import com.android.ims.ImsException;
+import com.android.ims.ImsManager;
+import com.android.settings.R;
+import com.android.settings.SettingsActivity;
+import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settings.widget.SwitchBar;
+import com.android.settings.widget.ToggleSwitch;
+
+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;
+import org.robolectric.util.ReflectionHelpers;
@RunWith(RobolectricTestRunner.class)
public class WifiCallingSettingsForSubTest {
+ private TestFragment mFragment;
+ private Context mContext;
+ private TextView mEmptyView;
+
+ @Mock private ImsManager mImsManager;
+ @Mock private TelephonyManager mTelephonyManager;
+ @Mock private PreferenceScreen mPreferenceScreen;
+ @Mock private SettingsActivity mActivity;
+ @Mock private SwitchBar mSwitchBar;
+ @Mock private ToggleSwitch mToggleSwitch;
+ @Mock private View mView;
+ @Mock private ImsConfig mImsConfig;
+
+ @Before
+ public void setUp() throws NoSuchFieldException, ImsException {
+ MockitoAnnotations.initMocks(this);
+
+ mContext = RuntimeEnvironment.application;
+ doReturn(mContext.getTheme()).when(mActivity).getTheme();
+
+ mFragment = spy(new TestFragment());
+ doReturn(mActivity).when(mFragment).getActivity();
+ doReturn(mContext).when(mFragment).getContext();
+ doReturn(mock(Intent.class)).when(mActivity).getIntent();
+ doReturn(mContext.getResources()).when(mFragment).getResources();
+ doReturn(mPreferenceScreen).when(mFragment).getPreferenceScreen();
+ doReturn(mTelephonyManager).when(mTelephonyManager).createForSubscriptionId(anyInt());
+ final Bundle bundle = new Bundle();
+ when(mFragment.getArguments()).thenReturn(bundle);
+ doNothing().when(mFragment).addPreferencesFromResource(anyInt());
+ doReturn(mock(ListPreference.class)).when(mFragment).findPreference(any());
+ doNothing().when(mFragment).finish();
+ doReturn(mView).when(mFragment).getView();
+
+ mEmptyView = new TextView(mContext);
+ doReturn(mEmptyView).when(mView).findViewById(android.R.id.empty);
+
+ ReflectionHelpers.setField(mSwitchBar, "mSwitch", mToggleSwitch);
+ doReturn(mSwitchBar).when(mView).findViewById(R.id.switch_bar);
+
+ doReturn(mImsManager).when(mFragment).getImsManager();
+ doReturn(mImsConfig).when(mImsManager).getConfigInterface();
+ doReturn(true).when(mImsManager).isWfcProvisionedOnDevice();
+
+ mFragment.onAttach(mContext);
+ mFragment.onCreate(null);
+ mFragment.onActivityCreated(null);
+ }
@Test
public void getHelpResource_shouldReturn0() {
- assertThat(new WifiCallingSettingsForSub().getHelpResource()).isEqualTo(0);
+ assertThat(mFragment.getHelpResource()).isEqualTo(0);
+ }
+
+ @Test
+ public void onResume_provisioningAllowed_shouldNotFinish() throws ImsException {
+ // Call onResume while provisioning is allowed.
+ mFragment.onResume();
+
+ // Verify that finish() is not called.
+ verify(mFragment, never()).finish();
+ }
+
+ @Test
+ public void onResume_provisioningDisallowed_shouldFinish() {
+ // Call onResume while provisioning is disallowed.
+ doReturn(false).when(mImsManager).isWfcProvisionedOnDevice();
+ mFragment.onResume();
+
+ // Verify that finish() is called
+ verify(mFragment).finish();
+ }
+
+ @Test
+ public void onResumeOnPause_provisioningCallbackRegistration() throws ImsException {
+ // Verify that provisioning callback is registered after call to onResume().
+ mFragment.onResume();
+ verify(mImsConfig).addConfigCallback(any(ProvisioningManager.Callback.class));
+
+ // Verify that provisioning callback is unregistered after call to onPause.
+ mFragment.onPause();
+ verify(mImsConfig).removeConfigCallback(any());
+ }
+
+ protected class TestFragment extends WifiCallingSettingsForSub {
+ @Override
+ protected Object getSystemService(final String name) {
+ if (Context.TELEPHONY_SERVICE.equals(name)) {
+ return mTelephonyManager;
+ }
+ return null;
+ }
}
}