diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 41b4d05a35f..06237381fab 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -191,6 +191,7 @@ + + + + + android:value="com.android.settings.network.NetworkProviderSettings"/> + android:value="@string/menu_key_network"/> + android:value="true"/> @@ -330,9 +335,11 @@ android:icon="@drawable/ic_homepage_network" android:exported="true"> + android:value="com.android.settings.network.NetworkProviderSettings"/> + android:value="@string/menu_key_network"/> + - - + + - - - - - - + + + android:value="com.android.settings.network.NetworkProviderSettings"/> + android:value="@string/menu_key_network"/> + android:value="true"/> Show device controls Access controls when locked + + Show double-line clock when available + + Double-line clock diff --git a/res/xml/security_lockscreen_settings.xml b/res/xml/security_lockscreen_settings.xml index 82cb8609114..19a1a4cbba2 100644 --- a/res/xml/security_lockscreen_settings.xml +++ b/res/xml/security_lockscreen_settings.xml @@ -56,6 +56,12 @@ android:title="@string/lockscreen_privacy_controls_setting_toggle" android:summary="@string/lockscreen_privacy_controls_summary" settings:controller="com.android.settings.display.ControlsPrivacyPreferenceController" /> + + { final int scrollViewHeight = scrollView.getHeight(); - if (scrollViewHeight > 0) { + if (scrollViewHeight > 0 && scrollViewHeight != mLastScrollViewHeight) { + mLastScrollViewHeight = scrollViewHeight; scrollView.post(() -> { // Here is no need to show the scrolling animation. So disabled first and // then enabled it after scrolling finished. diff --git a/src/com/android/settings/datausage/BillingCycleSettings.java b/src/com/android/settings/datausage/BillingCycleSettings.java index 8c433a061a6..57931c1b36b 100644 --- a/src/com/android/settings/datausage/BillingCycleSettings.java +++ b/src/com/android/settings/datausage/BillingCycleSettings.java @@ -271,12 +271,14 @@ public class BillingCycleSettings extends DataUsageBaseFragment implements mView = dialogInflater.inflate(R.layout.data_usage_bytes_editor, null, false); setupPicker((EditText) mView.findViewById(R.id.bytes), (Spinner) mView.findViewById(R.id.size_spinner)); - return new AlertDialog.Builder(context) + Dialog dialog = new AlertDialog.Builder(context) .setTitle(isLimit ? R.string.data_usage_limit_editor_title : R.string.data_usage_warning_editor_title) .setView(mView) .setPositiveButton(R.string.data_usage_cycle_editor_positive, this) .create(); + dialog.setCanceledOnTouchOutside(false); + return dialog; } private void setupPicker(EditText bytesPicker, Spinner type) { @@ -402,10 +404,12 @@ public class BillingCycleSettings extends DataUsageBaseFragment implements mCycleDayPicker.setValue(cycleDay); mCycleDayPicker.setWrapSelectorWheel(true); - return builder.setTitle(R.string.data_usage_cycle_editor_title) + Dialog dialog = builder.setTitle(R.string.data_usage_cycle_editor_title) .setView(view) .setPositiveButton(R.string.data_usage_cycle_editor_positive, this) .create(); + dialog.setCanceledOnTouchOutside(false); + return dialog; } @Override @@ -466,12 +470,14 @@ public class BillingCycleSettings extends DataUsageBaseFragment implements public Dialog onCreateDialog(Bundle savedInstanceState) { final Context context = getActivity(); - return new AlertDialog.Builder(context) + Dialog dialog = new AlertDialog.Builder(context) .setTitle(R.string.data_usage_limit_dialog_title) .setMessage(R.string.data_usage_limit_dialog_mobile) .setPositiveButton(android.R.string.ok, this) .setNegativeButton(android.R.string.cancel, null) .create(); + dialog.setCanceledOnTouchOutside(false); + return dialog; } @Override diff --git a/src/com/android/settings/display/LockscreenClockPreferenceController.java b/src/com/android/settings/display/LockscreenClockPreferenceController.java new file mode 100644 index 00000000000..70ae55eaf91 --- /dev/null +++ b/src/com/android/settings/display/LockscreenClockPreferenceController.java @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2021 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.display; + +import android.content.Context; +import android.provider.Settings; + +import androidx.preference.Preference; + +import com.android.settings.R; +import com.android.settings.core.TogglePreferenceController; + +/** + * Preference to enable/disable the large double-line clock on lockscreen + */ +public class LockscreenClockPreferenceController extends TogglePreferenceController { + + private static final String SETTING_KEY = Settings.Secure.LOCKSCREEN_USE_DOUBLE_LINE_CLOCK; + + public LockscreenClockPreferenceController(Context context, String preferenceKey) { + super(context, preferenceKey); + } + + @Override + public boolean isChecked() { + return Settings.Secure.getInt(mContext.getContentResolver(), SETTING_KEY, 1) != 0; + } + + @Override + public boolean setChecked(boolean isChecked) { + return Settings.Secure.putInt(mContext.getContentResolver(), SETTING_KEY, + isChecked ? 1 : 0); + } + + @Override + public CharSequence getSummary() { + return mContext.getText(R.string.lockscreen_double_line_clock_summary); + } + + @Override + public int getAvailabilityStatus() { + return AVAILABLE; + } + + @Override + public void updateState(Preference preference) { + super.updateState(preference); + preference.setEnabled(true); + refreshSummary(preference); + } + + @Override + public int getSliceHighlightMenuRes() { + return R.string.menu_key_display; + } +} diff --git a/src/com/android/settings/network/telephony/NetworkSelectSettings.java b/src/com/android/settings/network/telephony/NetworkSelectSettings.java index 813cc745680..c1c0f8f0dbd 100644 --- a/src/com/android/settings/network/telephony/NetworkSelectSettings.java +++ b/src/com/android/settings/network/telephony/NetworkSelectSettings.java @@ -50,6 +50,7 @@ import com.android.settingslib.utils.ThreadUtils; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Optional; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -326,12 +327,19 @@ public class NetworkSelectSettings extends DashboardFragment { CellInfoUtil.getCellIdentityMccMnc(cellInfo.getCellIdentity())); Class className = cellInfo.getClass(); - if (aggregatedList.stream().anyMatch( + Optional itemInTheList = aggregatedList.stream().filter( item -> { String itemPlmn = CellInfoUtil.getNetworkTitle(item.getCellIdentity(), CellInfoUtil.getCellIdentityMccMnc(item.getCellIdentity())); return itemPlmn.equals(plmn) && item.getClass().equals(className); - })) { + }) + .findFirst(); + if (itemInTheList.isPresent()) { + if (cellInfo.isRegistered() && !itemInTheList.get().isRegistered()) { + // Adding the registered cellinfo item into list. If there are two registered + // cellinfo items, then select first one from source list. + aggregatedList.set(aggregatedList.indexOf(itemInTheList.get()), cellInfo); + } continue; } aggregatedList.add(cellInfo); diff --git a/src/com/android/settings/network/telephony/NrAdvancedCallingPreferenceController.java b/src/com/android/settings/network/telephony/NrAdvancedCallingPreferenceController.java index 7615fe339bc..b585ecec6a4 100644 --- a/src/com/android/settings/network/telephony/NrAdvancedCallingPreferenceController.java +++ b/src/com/android/settings/network/telephony/NrAdvancedCallingPreferenceController.java @@ -46,6 +46,7 @@ public class NrAdvancedCallingPreferenceController extends TelephonyTogglePrefer Preference mPreference; private TelephonyManager mTelephonyManager; private PhoneCallStateTelephonyCallback mTelephonyCallback; + private boolean mIsVonrEnabledFromCarrierConfig = false; private boolean mIsVonrVisibleFromCarrierConfig = false; private boolean mIsNrEnableFromCarrierConfig = false; private boolean mHas5gCapability = false; @@ -83,6 +84,9 @@ public class NrAdvancedCallingPreferenceController extends TelephonyTogglePrefer if (carrierConfig == null) { return this; } + mIsVonrEnabledFromCarrierConfig = carrierConfig.getBoolean( + CarrierConfigManager.KEY_VONR_ENABLED_BOOL); + mIsVonrVisibleFromCarrierConfig = carrierConfig.getBoolean( CarrierConfigManager.KEY_VONR_SETTING_VISIBILITY_BOOL); @@ -92,6 +96,7 @@ public class NrAdvancedCallingPreferenceController extends TelephonyTogglePrefer Log.d(TAG, "mHas5gCapability: " + mHas5gCapability + ",mIsNrEnabledFromCarrierConfig: " + mIsNrEnableFromCarrierConfig + + ",mIsVonrEnabledFromCarrierConfig: " + mIsVonrEnabledFromCarrierConfig + ",mIsVonrVisibleFromCarrierConfig: " + mIsVonrVisibleFromCarrierConfig); return this; } @@ -100,7 +105,10 @@ public class NrAdvancedCallingPreferenceController extends TelephonyTogglePrefer public int getAvailabilityStatus(int subId) { init(subId); - if (mHas5gCapability && mIsNrEnableFromCarrierConfig && mIsVonrVisibleFromCarrierConfig) { + if (mHas5gCapability + && mIsNrEnableFromCarrierConfig + && mIsVonrEnabledFromCarrierConfig + && mIsVonrVisibleFromCarrierConfig) { return AVAILABLE; } return CONDITIONALLY_UNAVAILABLE; diff --git a/src/com/android/settings/password/PasswordUtils.java b/src/com/android/settings/password/PasswordUtils.java index 5b75033f0f2..e8e309c40ec 100644 --- a/src/com/android/settings/password/PasswordUtils.java +++ b/src/com/android/settings/password/PasswordUtils.java @@ -79,18 +79,20 @@ public final class PasswordUtils extends com.android.settingslib.Utils { } /** Crashes the calling application and provides it with {@code message}. */ - public static void crashCallingApplication(IBinder activityToken, String message) { + public static void crashCallingApplication(IBinder activityToken, String message, + int exceptionTypeId) { IActivityManager am = ActivityManager.getService(); try { int uid = am.getLaunchedFromUid(activityToken); int userId = UserHandle.getUserId(uid); - am.crashApplication( + am.crashApplicationWithType( uid, /* initialPid= */ -1, getCallingAppPackageName(activityToken), userId, message, - false); + false, + exceptionTypeId); } catch (RemoteException e) { Log.v(TAG, "Could not talk to activity manager.", e); } diff --git a/src/com/android/settings/password/SetNewPasswordActivity.java b/src/com/android/settings/password/SetNewPasswordActivity.java index 22825872128..fc664eccde1 100644 --- a/src/com/android/settings/password/SetNewPasswordActivity.java +++ b/src/com/android/settings/password/SetNewPasswordActivity.java @@ -29,6 +29,7 @@ import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_I import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_REQUESTED_MIN_COMPLEXITY; import android.app.Activity; +import android.app.RemoteServiceException.MissingRequestPasswordComplexityPermissionException; import android.app.admin.DevicePolicyManager; import android.app.admin.DevicePolicyManager.PasswordComplexity; import android.app.admin.PasswordMetrics; @@ -101,7 +102,8 @@ public class SetNewPasswordActivity extends Activity implements SetNewPasswordCo PasswordUtils.crashCallingApplication(activityToken, "Must have permission " + REQUEST_PASSWORD_COMPLEXITY + " to use extra " - + EXTRA_PASSWORD_COMPLEXITY); + + EXTRA_PASSWORD_COMPLEXITY, + MissingRequestPasswordComplexityPermissionException.TYPE_ID); finish(); return; } diff --git a/src/com/android/settings/password/SetupChooseLockGeneric.java b/src/com/android/settings/password/SetupChooseLockGeneric.java index 3261b81083b..968af3232f8 100644 --- a/src/com/android/settings/password/SetupChooseLockGeneric.java +++ b/src/com/android/settings/password/SetupChooseLockGeneric.java @@ -21,6 +21,7 @@ import static android.app.admin.DevicePolicyManager.EXTRA_PASSWORD_COMPLEXITY; import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_REQUESTED_MIN_COMPLEXITY; +import android.app.RemoteServiceException.MissingRequestPasswordComplexityPermissionException; import android.content.Context; import android.content.Intent; import android.os.Bundle; @@ -79,7 +80,8 @@ public class SetupChooseLockGeneric extends ChooseLockGeneric { if (!hasPermission) { PasswordUtils.crashCallingApplication(activityToken, "Must have permission " + REQUEST_PASSWORD_COMPLEXITY - + " to use extra " + EXTRA_PASSWORD_COMPLEXITY); + + " to use extra " + EXTRA_PASSWORD_COMPLEXITY, + MissingRequestPasswordComplexityPermissionException.TYPE_ID); finish(); return; } diff --git a/tests/robotests/src/com/android/settings/display/LockscreenClockPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/LockscreenClockPreferenceControllerTest.java new file mode 100644 index 00000000000..94f2dc66555 --- /dev/null +++ b/tests/robotests/src/com/android/settings/display/LockscreenClockPreferenceControllerTest.java @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2021 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.display; + +import static com.google.common.truth.Truth.assertThat; + +import android.content.ContentResolver; +import android.content.Context; +import android.provider.Settings; + +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 LockscreenClockPreferenceControllerTest { + + private static final String TEST_KEY = "test_key"; + private static final String SETTING_KEY = Settings.Secure.LOCKSCREEN_USE_DOUBLE_LINE_CLOCK; + + private Context mContext; + private ContentResolver mContentResolver; + private LockscreenClockPreferenceController mController; + + @Mock + private Preference mPreference; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mContext = RuntimeEnvironment.application; + mContentResolver = mContext.getContentResolver(); + mController = new LockscreenClockPreferenceController(mContext, TEST_KEY); + } + + @Test + public void isChecked_SettingIs1_returnTrue() { + Settings.Secure.putInt(mContentResolver, SETTING_KEY, 1); + + assertThat(mController.isChecked()).isTrue(); + } + + @Test + public void isChecked_SettingIs0_returnFalse() { + Settings.Secure.putInt(mContentResolver, SETTING_KEY, 0); + + assertThat(mController.isChecked()).isFalse(); + } + + @Test + public void isChecked_SettingIsNotSet_returnTrue() { + Settings.Secure.putString(mContentResolver, SETTING_KEY, null); + + assertThat(mController.isChecked()).isTrue(); + } + + @Test + public void setChecked_true_SettingIsNot0() { + mController.setChecked(true); + + assertThat(Settings.Secure.getInt(mContentResolver, SETTING_KEY, 0)).isNotEqualTo(0); + } + + @Test + public void setChecked_false_SettingIs0() { + mController.setChecked(false); + + assertThat(Settings.Secure.getInt(mContentResolver, SETTING_KEY, 0)).isEqualTo(0); + } +} diff --git a/tests/unit/src/com/android/settings/network/telephony/NetworkSelectSettingsTest.java b/tests/unit/src/com/android/settings/network/telephony/NetworkSelectSettingsTest.java index 47e3ad903d6..02b8706843a 100644 --- a/tests/unit/src/com/android/settings/network/telephony/NetworkSelectSettingsTest.java +++ b/tests/unit/src/com/android/settings/network/telephony/NetworkSelectSettingsTest.java @@ -166,6 +166,19 @@ public class NetworkSelectSettingsTest { assertThat(mNetworkSelectSettings.doAggregation(testList)).isEqualTo(expected); } + @Test + public void doAggregation_hasDuplicateItemsDiffMccMncCase3_removeSamePlmnRatItem() { + List testList = Arrays.asList( + createLteCellInfo(false, 123, "123", "232", "CarrierA"), + createLteCellInfo(false, 124, "123", "233", "CarrierA"), + createLteCellInfo(true, 125, "123", "234", "CarrierA"), + createGsmCellInfo(false, 126, "456", "232", "CarrierA")); + List expected = Arrays.asList( + createLteCellInfo(true, 125, "123", "234", "CarrierA"), + createGsmCellInfo(false, 126, "456", "232", "CarrierA")); + assertThat(mNetworkSelectSettings.doAggregation(testList)).isEqualTo(expected); + } + private CellInfoLte createLteCellInfo(boolean registered, int cellId, String mcc, String mnc, String plmnName) { CellIdentityLte cil = new CellIdentityLte( diff --git a/tests/unit/src/com/android/settings/network/telephony/NrAdvancedCallingPreferenceControllerTest.java b/tests/unit/src/com/android/settings/network/telephony/NrAdvancedCallingPreferenceControllerTest.java index 9eb67df96ca..fac777232f0 100644 --- a/tests/unit/src/com/android/settings/network/telephony/NrAdvancedCallingPreferenceControllerTest.java +++ b/tests/unit/src/com/android/settings/network/telephony/NrAdvancedCallingPreferenceControllerTest.java @@ -80,7 +80,8 @@ public class NrAdvancedCallingPreferenceControllerTest { mTelephonyManager).setVoNrEnabled(anyBoolean()); mCarrierConfig = new PersistableBundle(); doReturn(mCarrierConfig).when(mCarrierConfigManager).getConfigForSubId(SUB_ID); - mCarrierConfig.putBoolean(CarrierConfigManager.KEY_VONR_SETTING_VISIBILITY_BOOL, false); + mCarrierConfig.putBoolean(CarrierConfigManager.KEY_VONR_ENABLED_BOOL, false); + mCarrierConfig.putBoolean(CarrierConfigManager.KEY_VONR_SETTING_VISIBILITY_BOOL, true); mCarrierConfig.putIntArray(CarrierConfigManager.KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY, new int[]{1, 2}); @@ -92,7 +93,8 @@ public class NrAdvancedCallingPreferenceControllerTest { } @Test - public void getAvailabilityStatus_vonrDisabled_returnUnavailable() { + public void getAvailabilityStatus_vonrEnabledAndVisibleDisable_returnUnavailable() { + mCarrierConfig.putBoolean(CarrierConfigManager.KEY_VONR_ENABLED_BOOL, true); mCarrierConfig.putBoolean(CarrierConfigManager.KEY_VONR_SETTING_VISIBILITY_BOOL, false); mController.init(SUB_ID); @@ -102,7 +104,30 @@ public class NrAdvancedCallingPreferenceControllerTest { } @Test - public void getAvailabilityStatus_vonrEnabled_returnAvailable() { + public void getAvailabilityStatus_vonrDisabledAndVisibleDisable_returnUnavailable() { + mCarrierConfig.putBoolean(CarrierConfigManager.KEY_VONR_ENABLED_BOOL, false); + mCarrierConfig.putBoolean(CarrierConfigManager.KEY_VONR_SETTING_VISIBILITY_BOOL, false); + + mController.init(SUB_ID); + + assertThat(mController.getAvailabilityStatus()).isEqualTo( + BasePreferenceController.CONDITIONALLY_UNAVAILABLE); + } + + @Test + public void getAvailabilityStatus_vonrDisabledAndVisibleEnable_returnUnavailable() { + mCarrierConfig.putBoolean(CarrierConfigManager.KEY_VONR_ENABLED_BOOL, false); + mCarrierConfig.putBoolean(CarrierConfigManager.KEY_VONR_SETTING_VISIBILITY_BOOL, true); + + mController.init(SUB_ID); + + assertThat(mController.getAvailabilityStatus()).isEqualTo( + BasePreferenceController.CONDITIONALLY_UNAVAILABLE); + } + + @Test + public void getAvailabilityStatus_vonrEnabledAndVisibleEnable_returnAvailable() { + mCarrierConfig.putBoolean(CarrierConfigManager.KEY_VONR_ENABLED_BOOL, true); mCarrierConfig.putBoolean(CarrierConfigManager.KEY_VONR_SETTING_VISIBILITY_BOOL, true); mController.init(SUB_ID);