diff --git a/res/layout/adb_qrcode_scanner_fragment.xml b/res/layout/adb_qrcode_scanner_fragment.xml index 975256d18aa..f37c9a6ff4c 100644 --- a/res/layout/adb_qrcode_scanner_fragment.xml +++ b/res/layout/adb_qrcode_scanner_fragment.xml @@ -99,10 +99,12 @@ android:layout_height="wrap_content"/> + android:text="@string/adb_wireless_verifying_qrcode_text" + android:accessibilityLiveRegion="polite"/> diff --git a/res/layout/notification_history_log_row.xml b/res/layout/notification_history_log_row.xml index d2d7cd60e6e..b1357e9cc9e 100644 --- a/res/layout/notification_history_log_row.xml +++ b/res/layout/notification_history_log_row.xml @@ -16,6 +16,7 @@ - - - - - - - - + android:layout_height="@*android:dimen/status_bar_icon_size" + android:gravity="center_vertical"> + android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Notification.Title" + android:layout_toStartOf="@id/alerted_icon" + android:textAlignment="viewStart"/> + + + + + diff --git a/res/layout/notification_sbn_log_row.xml b/res/layout/notification_sbn_log_row.xml index 3eb6796ed3f..3b731ac4f8f 100644 --- a/res/layout/notification_sbn_log_row.xml +++ b/res/layout/notification_sbn_log_row.xml @@ -16,44 +16,44 @@ - + android:minHeight="@*android:dimen/status_bar_icon_size" + android:paddingBottom="6dp"> @@ -66,7 +66,6 @@ android:paddingTop="1dp" android:scaleType="fitCenter" android:visibility="gone" - android:layout_toEndOf="@id/pkgname" android:tint="?android:attr/textColorSecondary" android:src="@drawable/ic_notifications_alert" /> @@ -87,8 +86,7 @@ android:id="@+id/timestamp" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:paddingTop="13dp" - android:paddingBottom="13dp" + android:minHeight="@*android:dimen/status_bar_icon_size" android:layout_alignBottom="@android:id/widget_frame" android:layout_alignParentEnd="true" android:layout_alignTop="@android:id/widget_frame" @@ -98,13 +96,12 @@ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Notification" android:textAlignment="viewEnd" /> - + diff --git a/res/values/strings.xml b/res/values/strings.xml index 8a642ac1fa9..f913b7abe64 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -3017,6 +3017,10 @@ Incorrect SIM PIN code, you have %d remaining attempt before you must contact your carrier to unlock your device. Incorrect SIM PIN code, you have %d remaining attempts. + + + Incorrect SIM PIN code, you have 1 remaining attempt before you must contact your carrier to unlock your device. SIM PIN operation failed! @@ -4941,17 +4945,11 @@ Tap accessibility button - Tap the accessibility button %s at the bottom of your screen + Tap the accessibility button %s at the bottom of your screen.\n\nTo switch between features, touch & hold the accessibility button. - Swipe up from the bottom of the screen with 2 fingers + Swipe up from the bottom of the screen with 2 fingers.\n\nTo switch between features, swipe up with 2 fingers and hold. - Swipe up from the bottom of the screen with 3 fingers - - Tap the accessibility button %s at the bottom of your screen.\n\nTo switch between features, touch & hold the accessibility button. - - Swipe up from the bottom of the screen with 2 fingers.\n\nTo switch between features, swipe up with 2 fingers and hold. - - Swipe up from the bottom of the screen with 3 fingers.\n\nTo switch between features, swipe up with 3 fingers and hold. + Swipe up from the bottom of the screen with 3 fingers.\n\nTo switch between features, swipe up with 3 fingers and hold. Hold volume keys @@ -5144,30 +5142,20 @@ Blue-yellow - - - Extremely short delay (%1$s second) - Extremely short delay (%1$s seconds) - - - - Very short delay (%1$s second) - Very short delay (%1$s seconds) - - Short delay (%1$s second) - Short delay (%1$s seconds) + Short (%1$s second) + Short (%1$s seconds) + + + + Medium (%1$s second) + Medium (%1$s seconds) - Long delay (%1$s second) - Long delay (%1$s seconds) - - - - Very long delay (%1$s second) - Very long delay (%1$s seconds) + Long (%1$s second) + Long (%1$s seconds) @@ -7187,6 +7175,8 @@ + + @@ -10667,7 +10657,7 @@ Go back, Home, and switch apps with buttons at the bottom of your screen. - system navigation, 2 button navigation, 3 button navigation, gesture navigation + system navigation, 2 button navigation, 3 button navigation, gesture navigation, swipe Not supported by your default home app, %s diff --git a/res/xml/development_settings.xml b/res/xml/development_settings.xml index c134763d82a..def0075ed7b 100644 --- a/res/xml/development_settings.xml +++ b/res/xml/development_settings.xml @@ -577,6 +577,11 @@ android:title="@string/show_notification_channel_warnings" android:summary="@string/show_notification_channel_warnings_summary" /> + + + settings:controller="com.android.settings.gestures.SystemNavigationPreferenceController" + settings:keywords="@string/keywords_system_navigation" /> 0) { + } else if (attemptsRemaining == 1) { + displayMessage = mRes.getString(R.string.wrong_pin_code_one, attemptsRemaining); + } else if (attemptsRemaining > 1) { displayMessage = mRes .getQuantityString(R.plurals.wrong_pin_code, attemptsRemaining, attemptsRemaining); diff --git a/src/com/android/settings/accessibility/CaptionAppearanceFragment.java b/src/com/android/settings/accessibility/CaptionAppearanceFragment.java index 394f50ab787..6c2b593c471 100644 --- a/src/com/android/settings/accessibility/CaptionAppearanceFragment.java +++ b/src/com/android/settings/accessibility/CaptionAppearanceFragment.java @@ -105,7 +105,7 @@ public class CaptionAppearanceFragment extends SettingsPreferenceFragment @Override public int getMetricsCategory() { - return SettingsEnums.ACCESSIBILITY_CAPTION_PROPERTIES; + return SettingsEnums.ACCESSIBILITY_CAPTION_APPEARANCE; } @Override diff --git a/src/com/android/settings/accessibility/CaptionMoreOptionsFragment.java b/src/com/android/settings/accessibility/CaptionMoreOptionsFragment.java index 8e5c003189b..d3fd407436a 100644 --- a/src/com/android/settings/accessibility/CaptionMoreOptionsFragment.java +++ b/src/com/android/settings/accessibility/CaptionMoreOptionsFragment.java @@ -44,7 +44,7 @@ public class CaptionMoreOptionsFragment extends SettingsPreferenceFragment @Override public int getMetricsCategory() { - return SettingsEnums.ACCESSIBILITY_CAPTION_PROPERTIES; + return SettingsEnums.ACCESSIBILITY_CAPTION_MORE_OPTIONS; } @Override diff --git a/src/com/android/settings/accessibility/ToggleAutoclickPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleAutoclickPreferenceFragment.java index 5e09b2a78c1..6624457ad98 100644 --- a/src/com/android/settings/accessibility/ToggleAutoclickPreferenceFragment.java +++ b/src/com/android/settings/accessibility/ToggleAutoclickPreferenceFragment.java @@ -64,12 +64,10 @@ public class ToggleAutoclickPreferenceFragment extends DashboardFragment * Resource ids from which autoclick preference summaries should be derived. The strings have * placeholder for integer delay value. */ - private static final int[] mAutoclickPreferenceSummaries = { - R.plurals.accessibilty_autoclick_preference_subtitle_extremely_short_delay, - R.plurals.accessibilty_autoclick_preference_subtitle_very_short_delay, + private static final int[] AUTOCLICK_PREFERENCE_SUMMARIES = { R.plurals.accessibilty_autoclick_preference_subtitle_short_delay, - R.plurals.accessibilty_autoclick_preference_subtitle_long_delay, - R.plurals.accessibilty_autoclick_preference_subtitle_very_long_delay + R.plurals.accessibilty_autoclick_preference_subtitle_medium_delay, + R.plurals.accessibilty_autoclick_preference_subtitle_long_delay }; /** @@ -86,7 +84,7 @@ public class ToggleAutoclickPreferenceFragment extends DashboardFragment // Only show integer when delay time is 1. final String decimalFormat = (delaySecond == 1) ? "%.0f" : "%.1f"; - return resources.getQuantityString(mAutoclickPreferenceSummaries[summaryIndex], + return resources.getQuantityString(AUTOCLICK_PREFERENCE_SUMMARIES[summaryIndex], quantity, String.format(decimalFormat, delaySecond)); } @@ -98,10 +96,10 @@ public class ToggleAutoclickPreferenceFragment extends DashboardFragment return 0; } if (delay >= MAX_AUTOCLICK_DELAY_MS) { - return mAutoclickPreferenceSummaries.length - 1; + return AUTOCLICK_PREFERENCE_SUMMARIES.length - 1; } int delayRange = MAX_AUTOCLICK_DELAY_MS - MIN_AUTOCLICK_DELAY_MS; - int rangeSize = (delayRange) / (mAutoclickPreferenceSummaries.length - 1); + int rangeSize = (delayRange) / (AUTOCLICK_PREFERENCE_SUMMARIES.length - 1); return (delay - MIN_AUTOCLICK_DELAY_MS) / rangeSize; } diff --git a/src/com/android/settings/accessibility/ToggleColorInversionPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleColorInversionPreferenceFragment.java index c0ad2ac235a..833c9f181ea 100644 --- a/src/com/android/settings/accessibility/ToggleColorInversionPreferenceFragment.java +++ b/src/com/android/settings/accessibility/ToggleColorInversionPreferenceFragment.java @@ -113,6 +113,11 @@ public class ToggleColorInversionPreferenceFragment extends ToggleFeaturePrefere super.onPause(); } + @Override + public int getHelpResource() { + return R.string.help_url_color_inversion; + } + @Override public void onSettingsClicked(ShortcutPreference preference) { super.onSettingsClicked(preference); diff --git a/src/com/android/settings/applications/RecentAppsPreferenceController.java b/src/com/android/settings/applications/RecentAppsPreferenceController.java index 28a88a200f1..69a68ef9e7e 100644 --- a/src/com/android/settings/applications/RecentAppsPreferenceController.java +++ b/src/com/android/settings/applications/RecentAppsPreferenceController.java @@ -17,7 +17,6 @@ package com.android.settings.applications; import android.app.Application; -import android.app.settings.SettingsEnums; import android.app.usage.UsageStats; import android.content.Context; import android.icu.text.RelativeDateTimeFormatter; @@ -98,12 +97,12 @@ public class RecentAppsPreferenceController extends BasePreferenceController .setHeaderTitleRes(R.string.recent_app_category_title) .setHeaderDetailsClickListener((View v) -> { mMetricsFeatureProvider.logClickedPreference(mRecentAppsPreference, - SettingsEnums.SETTINGS_APP_NOTIF_CATEGORY); + getMetricsCategory()); new SubSettingLauncher(mContext) .setDestination(ManageApplications.class.getName()) .setArguments(null /* arguments */) .setTitleRes(R.string.application_info_label) - .setSourceMetricsCategory(SettingsEnums.SETTINGS_APP_NOTIF_CATEGORY) + .setSourceMetricsCategory(getMetricsCategory()) .launch(); }); } @@ -166,11 +165,10 @@ public class RecentAppsPreferenceController extends BasePreferenceController RelativeDateTimeFormatter.Style.SHORT)) .setOnClickListener(v -> { mMetricsFeatureProvider.logClickedPreference(mRecentAppsPreference, - SettingsEnums.SETTINGS_APP_NOTIF_CATEGORY); + getMetricsCategory()); AppInfoBase.startAppInfoFragment(AppInfoDashboardFragment.class, R.string.application_info_label, pkgName, appEntry.info.uid, - mHost, 1001 /*RequestCode*/, - SettingsEnums.SETTINGS_APP_NOTIF_CATEGORY); + mHost, 1001 /*RequestCode*/, getMetricsCategory()); }) .build(); } diff --git a/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminListPreferenceController.java b/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminListPreferenceController.java index b5ccd73fef7..d8ec8489cd4 100644 --- a/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminListPreferenceController.java +++ b/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminListPreferenceController.java @@ -46,7 +46,6 @@ import androidx.preference.PreferenceScreen; import androidx.preference.SwitchPreference; import com.android.settings.core.BasePreferenceController; -import com.android.settings.dashboard.DashboardFragment; import com.android.settings.overlay.FeatureFactory; import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.android.settingslib.core.lifecycle.LifecycleObserver; @@ -202,8 +201,7 @@ public class DeviceAdminListPreferenceController extends BasePreferenceControlle pref.setSummary(item.getDescription()); pref.setEnabled(item.isEnabled()); pref.setOnPreferenceClickListener(preference -> { - mMetricsFeatureProvider.logClickedPreference(preference, - preference.getExtras().getInt(DashboardFragment.CATEGORY)); + mMetricsFeatureProvider.logClickedPreference(preference, getMetricsCategory()); final UserHandle user = item.getUser(); mContext.startActivityAsUser(item.getLaunchIntent(mContext), user); return true; diff --git a/src/com/android/settings/core/BasePreferenceController.java b/src/com/android/settings/core/BasePreferenceController.java index 1985a998d85..c90fe48bc9c 100644 --- a/src/com/android/settings/core/BasePreferenceController.java +++ b/src/com/android/settings/core/BasePreferenceController.java @@ -124,6 +124,7 @@ public abstract class BasePreferenceController extends AbstractPreferenceControl private boolean mIsForWork; @Nullable private UserHandle mWorkProfileUser; + private int mMetricsCategory; /** * Instantiate a controller as specified controller type and user-defined key. @@ -398,11 +399,27 @@ public abstract class BasePreferenceController extends AbstractPreferenceControl * This won't block UI thread however has similar side effect. Please use it if you * want to avoid janky animation(i.e. new preference is added in the middle of page). * - * This music be used in {@link BasePreferenceController} + * This must be used in {@link BasePreferenceController} */ public interface UiBlocker { } + /** + * Set the metrics category of the parent fragment. + * + * Called by DashboardFragment#onAttach + */ + public void setMetricsCategory(int metricsCategory) { + mMetricsCategory = metricsCategory; + } + + /** + * @return the metrics category of the parent fragment. + */ + protected int getMetricsCategory() { + return mMetricsCategory; + } + /** * @return Non-{@code null} {@link UserHandle} when a work profile is enabled. * Otherwise {@code null}. diff --git a/src/com/android/settings/core/TogglePreferenceController.java b/src/com/android/settings/core/TogglePreferenceController.java index 7abe6e09fca..5a2a8b70e5a 100644 --- a/src/com/android/settings/core/TogglePreferenceController.java +++ b/src/com/android/settings/core/TogglePreferenceController.java @@ -18,8 +18,10 @@ import android.content.Context; import androidx.preference.Preference; import androidx.preference.TwoStatePreference; +import com.android.settings.overlay.FeatureFactory; import com.android.settings.slices.SliceData; import com.android.settings.widget.MasterSwitchPreference; +import com.android.settings.widget.TwoStateButtonPreference; /** * Abstract class that consolidates logic for updating toggle controllers. @@ -54,6 +56,8 @@ public abstract class TogglePreferenceController extends BasePreferenceControlle ((TwoStatePreference) preference).setChecked(isChecked()); } else if (preference instanceof MasterSwitchPreference) { ((MasterSwitchPreference) preference).setChecked(isChecked()); + } else if (preference instanceof TwoStateButtonPreference) { + ((TwoStateButtonPreference) preference).setChecked(isChecked()); } else { refreshSummary(preference); } @@ -61,6 +65,12 @@ public abstract class TogglePreferenceController extends BasePreferenceControlle @Override public final boolean onPreferenceChange(Preference preference, Object newValue) { + // TwoStatePreference is a regular preference and can be handled by DashboardFragment + if (preference instanceof MasterSwitchPreference + || preference instanceof TwoStateButtonPreference) { + FeatureFactory.getFactory(mContext).getMetricsFeatureProvider() + .logClickedPreference(preference, getMetricsCategory()); + } return setChecked((boolean) newValue); } diff --git a/src/com/android/settings/dashboard/DashboardFragment.java b/src/com/android/settings/dashboard/DashboardFragment.java index d1211953d68..c70d8419974 100644 --- a/src/com/android/settings/dashboard/DashboardFragment.java +++ b/src/com/android/settings/dashboard/DashboardFragment.java @@ -113,6 +113,14 @@ public abstract class DashboardFragment extends SettingsPreferenceFragment } }); + // Set metrics category for BasePreferenceController. + final int metricCategory = getMetricsCategory(); + mControllers.forEach(controller -> { + if (controller instanceof BasePreferenceController) { + ((BasePreferenceController) controller).setMetricsCategory(metricCategory); + } + }); + mPlaceholderPreferenceController = new DashboardTilePlaceholderPreferenceController(context); mControllers.add(mPlaceholderPreferenceController); diff --git a/src/com/android/settings/development/AdbQrcodeScannerFragment.java b/src/com/android/settings/development/AdbQrcodeScannerFragment.java index 066cf156030..7a30443bca4 100644 --- a/src/com/android/settings/development/AdbQrcodeScannerFragment.java +++ b/src/com/android/settings/development/AdbQrcodeScannerFragment.java @@ -73,6 +73,7 @@ public class AdbQrcodeScannerFragment extends WifiDppQrCodeBaseFragment implemen private QrDecorateView mDecorateView; private View mQrCameraView; private View mVerifyingView; + private TextView mVerifyingTextView; private TextView mErrorMessage; /** QR code data scanned by camera */ @@ -168,6 +169,7 @@ public class AdbQrcodeScannerFragment extends WifiDppQrCodeBaseFragment implemen mQrCameraView = view.findViewById(R.id.camera_layout); mVerifyingView = view.findViewById(R.id.verifying_layout); + mVerifyingTextView = view.findViewById(R.id.verifying_textview); setHeaderTitle(R.string.wifi_dpp_scan_qr_code); mSummary.setText(R.string.adb_wireless_qrcode_pairing_description); @@ -207,6 +209,15 @@ public class AdbQrcodeScannerFragment extends WifiDppQrCodeBaseFragment implemen super.onAttach(context); } + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + getActivity().getActionBar().hide(); + // setTitle for TalkBack + getActivity().setTitle(R.string.wifi_dpp_scan_qr_code); + } + @Override public int getMetricsCategory() { return 0; @@ -264,6 +275,8 @@ public class AdbQrcodeScannerFragment extends WifiDppQrCodeBaseFragment implemen mDecorateView.setFocused(true); mQrCameraView.setVisibility(View.GONE); mVerifyingView.setVisibility(View.VISIBLE); + AdbQrCode.triggerVibrationForQrCodeRecognition(getContext()); + mVerifyingTextView.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED); try { mAdbManager.enablePairingByQrCode(mAdbConfig.getSsid(), mAdbConfig.getPreSharedKey()); diff --git a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java index ef58c8a84a7..66b93e17b46 100644 --- a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java +++ b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java @@ -501,6 +501,7 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra controllers.add(new ShowFirstCrashDialogPreferenceController(context)); controllers.add(new AppsNotRespondingPreferenceController(context)); controllers.add(new NotificationChannelWarningsPreferenceController(context)); + controllers.add(new EnforceConversationShortcutsPreferenceController(context)); controllers.add(new AllowAppsOnExternalPreferenceController(context)); controllers.add(new ResizableActivityPreferenceController(context)); controllers.add(new FreeformWindowsPreferenceController(context)); diff --git a/src/com/android/settings/development/EnforceConversationShortcutsPreferenceController.java b/src/com/android/settings/development/EnforceConversationShortcutsPreferenceController.java new file mode 100644 index 00000000000..dd4cdcae837 --- /dev/null +++ b/src/com/android/settings/development/EnforceConversationShortcutsPreferenceController.java @@ -0,0 +1,68 @@ +/* + * 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.development; + +import android.content.Context; +import android.os.Build; +import android.provider.Settings; + +import androidx.annotation.VisibleForTesting; +import androidx.preference.Preference; +import androidx.preference.SwitchPreference; + +import com.android.settings.core.PreferenceControllerMixin; +import com.android.settingslib.development.DeveloperOptionsPreferenceController; + +public class EnforceConversationShortcutsPreferenceController extends + DeveloperOptionsPreferenceController implements Preference.OnPreferenceChangeListener, + PreferenceControllerMixin { + + private static final String KEY = + "enforce_shortcuts_for_conversations"; + + @VisibleForTesting + final static int SETTING_VALUE_ON = 1; + @VisibleForTesting + final static int SETTING_VALUE_OFF = 0; + + final static int DEFAULT_VALUE = SETTING_VALUE_OFF; + + public EnforceConversationShortcutsPreferenceController(Context context) { + super(context); + } + + @Override + public String getPreferenceKey() { + return KEY; + } + + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + final boolean isEnabled = (Boolean) newValue; + Settings.Global.putInt(mContext.getContentResolver(), + Settings.Global.REQUIRE_SHORTCUTS_FOR_CONVERSATIONS, + isEnabled ? SETTING_VALUE_ON : SETTING_VALUE_OFF); + return true; + } + + @Override + public void updateState(Preference preference) { + final int mode = Settings.Global.getInt(mContext.getContentResolver(), + Settings.Global.REQUIRE_SHORTCUTS_FOR_CONVERSATIONS, DEFAULT_VALUE); + ((SwitchPreference) mPreference).setChecked(mode != SETTING_VALUE_OFF); + } +} diff --git a/src/com/android/settings/display/DarkUIPreferenceController.java b/src/com/android/settings/display/DarkUIPreferenceController.java index c2da56aaa8f..98d9a69ea7c 100644 --- a/src/com/android/settings/display/DarkUIPreferenceController.java +++ b/src/com/android/settings/display/DarkUIPreferenceController.java @@ -17,7 +17,6 @@ package com.android.settings.display; import android.app.UiModeManager; -import android.app.settings.SettingsEnums; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -33,8 +32,6 @@ import androidx.preference.PreferenceScreen; import com.android.settings.R; import com.android.settings.core.TogglePreferenceController; -import com.android.settings.overlay.FeatureFactory; -import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.android.settingslib.core.lifecycle.LifecycleObserver; import com.android.settingslib.core.lifecycle.events.OnStart; import com.android.settingslib.core.lifecycle.events.OnStop; @@ -49,7 +46,6 @@ public class DarkUIPreferenceController extends TogglePreferenceController imple @VisibleForTesting Preference mPreference; - private final MetricsFeatureProvider mMetricsFeatureProvider; private UiModeManager mUiModeManager; private PowerManager mPowerManager; private Context mContext; @@ -68,7 +64,6 @@ public class DarkUIPreferenceController extends TogglePreferenceController imple mContext = context; mUiModeManager = context.getSystemService(UiModeManager.class); mPowerManager = context.getSystemService(PowerManager.class); - mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider(); } @Override @@ -91,7 +86,6 @@ public class DarkUIPreferenceController extends TogglePreferenceController imple @Override public boolean setChecked(boolean isChecked) { - mMetricsFeatureProvider.logClickedPreference(mPreference, SettingsEnums.DISPLAY); final boolean dialogSeen = Settings.Secure.getInt(mContext.getContentResolver(), Settings.Secure.DARK_MODE_DIALOG_SEEN, 0) == DIALOG_SEEN; diff --git a/src/com/android/settings/display/NightDisplayActivationPreferenceController.java b/src/com/android/settings/display/NightDisplayActivationPreferenceController.java index f68df503908..4b1e295445d 100644 --- a/src/com/android/settings/display/NightDisplayActivationPreferenceController.java +++ b/src/com/android/settings/display/NightDisplayActivationPreferenceController.java @@ -16,7 +16,6 @@ package com.android.settings.display; -import android.app.settings.SettingsEnums; import android.content.Context; import android.hardware.display.ColorDisplayManager; import android.text.TextUtils; @@ -50,8 +49,7 @@ public class NightDisplayActivationPreferenceController extends TogglePreference @Override public void onClick(View v) { mButtonTriggered = true; - mMetricsFeatureProvider.logClickedPreference(mPreference, - SettingsEnums.NIGHT_DISPLAY_SETTINGS); + mMetricsFeatureProvider.logClickedPreference(mPreference, getMetricsCategory()); mColorDisplayManager.setNightDisplayActivated( !mColorDisplayManager.isNightDisplayActivated()); updateStateInternal(); diff --git a/src/com/android/settings/display/darkmode/DarkModeActivationPreferenceController.java b/src/com/android/settings/display/darkmode/DarkModeActivationPreferenceController.java index 622f2e2cf45..74b029fc3b0 100644 --- a/src/com/android/settings/display/darkmode/DarkModeActivationPreferenceController.java +++ b/src/com/android/settings/display/darkmode/DarkModeActivationPreferenceController.java @@ -16,7 +16,6 @@ package com.android.settings.display.darkmode; import android.app.UiModeManager; -import android.app.settings.SettingsEnums; import android.content.Context; import android.content.res.Configuration; import android.os.PowerManager; @@ -136,8 +135,7 @@ public class DarkModeActivationPreferenceController extends BasePreferenceContro private final View.OnClickListener mListener = new View.OnClickListener() { @Override public void onClick(View v) { - mMetricsFeatureProvider.logClickedPreference(mPreference, - SettingsEnums.DARK_UI_SETTINGS); + mMetricsFeatureProvider.logClickedPreference(mPreference, getMetricsCategory()); final boolean active = (mContext.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_YES) != 0; mUiModeManager.setNightModeActivated(!active); diff --git a/src/com/android/settings/fuelgauge/batterysaver/BatterySaverButtonPreferenceController.java b/src/com/android/settings/fuelgauge/batterysaver/BatterySaverButtonPreferenceController.java index fff6523a395..a089abc8c25 100644 --- a/src/com/android/settings/fuelgauge/batterysaver/BatterySaverButtonPreferenceController.java +++ b/src/com/android/settings/fuelgauge/batterysaver/BatterySaverButtonPreferenceController.java @@ -16,21 +16,17 @@ package com.android.settings.fuelgauge.batterysaver; -import android.app.settings.SettingsEnums; import android.content.ContentResolver; import android.content.Context; import android.net.Uri; import android.os.PowerManager; import android.provider.SettingsSlicesContract; -import androidx.preference.Preference; import androidx.preference.PreferenceScreen; import com.android.settings.core.TogglePreferenceController; import com.android.settings.fuelgauge.BatterySaverReceiver; -import com.android.settings.overlay.FeatureFactory; import com.android.settings.widget.TwoStateButtonPreference; -import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.android.settingslib.core.lifecycle.LifecycleObserver; import com.android.settingslib.core.lifecycle.events.OnStart; import com.android.settingslib.core.lifecycle.events.OnStop; @@ -45,13 +41,11 @@ public class BatterySaverButtonPreferenceController extends private final BatterySaverReceiver mBatterySaverReceiver; private final PowerManager mPowerManager; - private final MetricsFeatureProvider mMetricsFeatureProvider; private TwoStateButtonPreference mPreference; public BatterySaverButtonPreferenceController(Context context, String key) { super(context, key); - mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider(); mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE); mBatterySaverReceiver = new BatterySaverReceiver(context); mBatterySaverReceiver.setBatterySaverListener(this); @@ -100,21 +94,11 @@ public class BatterySaverButtonPreferenceController extends @Override public boolean setChecked(boolean stateOn) { - mMetricsFeatureProvider.logClickedPreference(mPreference, - SettingsEnums.FUELGAUGE_BATTERY_SAVER); // This screen already shows a warning, so we don't need another warning. return BatterySaverUtils.setPowerSaveMode(mContext, stateOn, false /* needFirstTimeWarning */); } - @Override - public void updateState(Preference preference) { - super.updateState(preference); - if (mPreference != null) { - mPreference.setChecked(isChecked()); - } - } - @Override public void onPowerSaveModeChanged() { final boolean isChecked = isChecked(); diff --git a/src/com/android/settings/network/telephony/TelephonyConstants.java b/src/com/android/settings/network/telephony/TelephonyConstants.java index 2a2613cc497..78a177edccc 100644 --- a/src/com/android/settings/network/telephony/TelephonyConstants.java +++ b/src/com/android/settings/network/telephony/TelephonyConstants.java @@ -16,7 +16,6 @@ package com.android.settings.network.telephony; - import android.telephony.TelephonyManager; /** @@ -210,6 +209,12 @@ public class TelephonyConstants { * Copied from {@link android.telephony.RadioAccessFamily} */ public static class RadioAccessFamily { + /** + * TODO: get rid of RAF definition in RadioAccessFamily and + * use {@link TelephonyManager.NetworkTypeBitMask} + * TODO: public definition {@link TelephonyManager.NetworkTypeBitMask} is long. + * TODO: Convert from int * to long everywhere including HAL definitions. + */ // 2G public static final int RAF_UNKNOWN = (int) TelephonyManager.NETWORK_TYPE_BITMASK_UNKNOWN; public static final int RAF_GSM = (int) TelephonyManager.NETWORK_TYPE_BITMASK_GSM; @@ -245,9 +250,7 @@ public class TelephonyConstants { public static final int WCDMA = HS | RAF_UMTS; // 4G public static final int LTE = RAF_LTE | RAF_LTE_CA; - // 5G public static final int NR = RAF_NR; - } } diff --git a/src/com/android/settings/notification/history/NotificationSbnViewHolder.java b/src/com/android/settings/notification/history/NotificationSbnViewHolder.java index 27b4b73d09c..dabf3f3dd46 100644 --- a/src/com/android/settings/notification/history/NotificationSbnViewHolder.java +++ b/src/com/android/settings/notification/history/NotificationSbnViewHolder.java @@ -17,6 +17,7 @@ package com.android.settings.notification.history; import android.app.PendingIntent; +import android.content.ActivityNotFoundException; import android.content.Intent; import android.graphics.drawable.Drawable; import android.os.UserHandle; @@ -91,10 +92,14 @@ public class NotificationSbnViewHolder extends RecyclerView.ViewHolder { Slog.e(TAG, "Could not launch", e); } } else { - Intent appIntent = new Intent(Intent.ACTION_MAIN) - .setPackage(pkg); + Intent appIntent = itemView.getContext().getPackageManager() + .getLaunchIntentForPackage(pkg); appIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - itemView.getContext().startActivityAsUser(appIntent, UserHandle.of(userId)); + try { + itemView.getContext().startActivityAsUser(appIntent, UserHandle.of(userId)); + } catch (ActivityNotFoundException e) { + Slog.e(TAG, "no launch activity", e); + } } }); ViewCompat.setAccessibilityDelegate(itemView, new AccessibilityDelegateCompat() { diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java index bba90016bb2..581f202b170 100644 --- a/src/com/android/settings/wifi/WifiSettings.java +++ b/src/com/android/settings/wifi/WifiSettings.java @@ -1304,9 +1304,7 @@ public class WifiSettings extends RestrictedSettingsFragment final List keys = super.getNonIndexableKeys(context); final WifiManager wifiManager = context.getSystemService(WifiManager.class); - final List accessPoints = WifiSavedConfigUtils.getAllConfigs( - context, wifiManager); - if (accessPoints == null || accessPoints.size() <= 0) { + if (WifiSavedConfigUtils.getAllConfigsCount(context, wifiManager) == 0) { keys.add(PREF_KEY_SAVED_NETWORKS); } diff --git a/src/com/android/settings/wifi/WifiSettings2.java b/src/com/android/settings/wifi/WifiSettings2.java index 1098c013cdc..e791df83a29 100644 --- a/src/com/android/settings/wifi/WifiSettings2.java +++ b/src/com/android/settings/wifi/WifiSettings2.java @@ -76,6 +76,7 @@ import com.android.settingslib.RestrictedLockUtilsInternal; import com.android.settingslib.search.Indexable; import com.android.settingslib.search.SearchIndexable; import com.android.settingslib.wifi.LongPressWifiEntryPreference; +import com.android.settingslib.wifi.WifiSavedConfigUtils; import com.android.wifitrackerlib.WifiEntry; import com.android.wifitrackerlib.WifiEntry.ConnectCallback; import com.android.wifitrackerlib.WifiPickerTracker; @@ -1027,7 +1028,22 @@ public class WifiSettings2 extends RestrictedSettingsFragment }; public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = - new BaseSearchIndexProvider(R.xml.wifi_settings2); + new BaseSearchIndexProvider(R.xml.wifi_settings2) { + @Override + public List getNonIndexableKeys(Context context) { + final List keys = super.getNonIndexableKeys(context); + + final WifiManager wifiManager = context.getSystemService(WifiManager.class); + if (WifiSavedConfigUtils.getAllConfigsCount(context, wifiManager) == 0) { + keys.add(PREF_KEY_SAVED_NETWORKS); + } + + if (!DataUsageUtils.hasWifiRadio(context)) { + keys.add(PREF_KEY_DATA_USAGE); + } + return keys; + } + }; private class WifiEntryConnectCallback implements ConnectCallback { final WifiEntry mConnectWifiEntry; diff --git a/src/com/android/settings/wifi/dpp/AdbQrCode.java b/src/com/android/settings/wifi/dpp/AdbQrCode.java index fb63e0a5384..65577874e20 100644 --- a/src/com/android/settings/wifi/dpp/AdbQrCode.java +++ b/src/com/android/settings/wifi/dpp/AdbQrCode.java @@ -15,6 +15,7 @@ */ package com.android.settings.wifi.dpp; +import android.content.Context; import android.text.TextUtils; /** @@ -53,4 +54,13 @@ public class AdbQrCode extends WifiQrCode { public WifiNetworkConfig getAdbNetworkConfig() { return mAdbConfig; } + + /** + * Triggers a vibration to notify of a valid QR code. + * + * @param context The context to use + */ + public static void triggerVibrationForQrCodeRecognition(Context context) { + WifiDppUtils.triggerVibrationForQrCodeRecognition(context); + } } diff --git a/tests/robotests/src/com/android/settings/AllInOneTetherSettingsTest.java b/tests/robotests/src/com/android/settings/AllInOneTetherSettingsTest.java index 55486d26a15..f966e3c5e75 100644 --- a/tests/robotests/src/com/android/settings/AllInOneTetherSettingsTest.java +++ b/tests/robotests/src/com/android/settings/AllInOneTetherSettingsTest.java @@ -16,6 +16,9 @@ package com.android.settings; +import static com.android.settings.AllInOneTetherSettings.EXPANDED_CHILD_COUNT_DEFAULT; +import static com.android.settings.AllInOneTetherSettings.EXPANDED_CHILD_COUNT_WITHOUT_WIFI_CONFIG; +import static com.android.settings.AllInOneTetherSettings.EXPANDED_CHILD_COUNT_WITH_SECURITY_NON; import static com.android.settings.network.TetherEnabler.BLUETOOTH_TETHER_KEY; import static com.android.settings.network.TetherEnabler.USB_TETHER_KEY; import static com.android.settings.network.TetherEnabler.WIFI_TETHER_DISABLE_KEY; @@ -29,6 +32,7 @@ import static org.mockito.Mockito.when; import android.content.Context; import android.net.ConnectivityManager; +import android.net.wifi.SoftApConfiguration; import android.os.UserHandle; import android.os.UserManager; import android.util.FeatureFlagUtils; @@ -36,6 +40,7 @@ import android.util.FeatureFlagUtils; import com.android.settings.core.FeatureFlags; import com.android.settings.testutils.shadow.ShadowWifiManager; import com.android.settings.wifi.tether.WifiTetherAutoOffPreferenceController; +import com.android.settings.wifi.tether.WifiTetherSecurityPreferenceController; import com.android.settingslib.core.lifecycle.Lifecycle; import org.junit.Before; @@ -65,6 +70,8 @@ public class AllInOneTetherSettingsTest { private ConnectivityManager mConnectivityManager; @Mock private UserManager mUserManager; + @Mock + private WifiTetherSecurityPreferenceController mSecurityPreferenceController; @Before public void setUp() { @@ -82,6 +89,8 @@ public class AllInOneTetherSettingsTest { mAllInOneTetherSettings = new AllInOneTetherSettings(); ReflectionHelpers.setField(mAllInOneTetherSettings, "mLifecycle", mock(Lifecycle.class)); + ReflectionHelpers.setField(mAllInOneTetherSettings, "mSecurityPreferenceController", + mSecurityPreferenceController); } @Test @@ -157,6 +166,32 @@ public class AllInOneTetherSettingsTest { .isEqualTo(1); } + @Test + public void getInitialExpandedChildCount_shouldShowWifiConfigWithSecurity() { + ReflectionHelpers.setField(mAllInOneTetherSettings, "mWifiTethering", true); + when(mSecurityPreferenceController.getSecurityType()) + .thenReturn(SoftApConfiguration.SECURITY_TYPE_WPA2_PSK); + assertThat(mAllInOneTetherSettings.getInitialExpandedChildCount()) + .isEqualTo(EXPANDED_CHILD_COUNT_DEFAULT); + } + + @Test + public void getInitialExpandedChildCount_shouldShowWifiConfigWithoutSecurity() { + ReflectionHelpers.setField(mAllInOneTetherSettings, "mWifiTethering", true); + when(mSecurityPreferenceController.getSecurityType()) + .thenReturn(SoftApConfiguration.SECURITY_TYPE_OPEN); + assertThat(mAllInOneTetherSettings.getInitialExpandedChildCount()) + .isEqualTo(EXPANDED_CHILD_COUNT_WITH_SECURITY_NON); + } + + @Test + public void getInitialExpandedChildCount_shouldNotShowWifiConfig() { + ReflectionHelpers.setField(mAllInOneTetherSettings, "mWifiTethering", false); + ReflectionHelpers.setField(mAllInOneTetherSettings, "mBluetoothTethering", true); + assertThat(mAllInOneTetherSettings.getInitialExpandedChildCount()) + .isEqualTo(EXPANDED_CHILD_COUNT_WITHOUT_WIFI_CONFIG); + } + private void setupIsTetherAvailable(boolean returnValue) { when(mConnectivityManager.isTetheringSupported()).thenReturn(true); diff --git a/tests/robotests/src/com/android/settings/core/BasePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/core/BasePreferenceControllerTest.java index fc18f6008ad..0707c2cabc3 100644 --- a/tests/robotests/src/com/android/settings/core/BasePreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/core/BasePreferenceControllerTest.java @@ -28,6 +28,7 @@ import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import android.app.settings.SettingsEnums; import android.content.Context; import androidx.preference.Preference; @@ -205,6 +206,15 @@ public class BasePreferenceControllerTest { assertThat(keys).isEmpty(); } + @Test + public void getMetricsCategory_metricsCategoryIsSet_shouldReturnTheSameCategory() { + mPreferenceController.setMetricsCategory(SettingsEnums.DISPLAY); + + final int category = mPreferenceController.getMetricsCategory(); + + assertThat(category).isEqualTo(SettingsEnums.DISPLAY); + } + private class FakeBasePreferenceController extends BasePreferenceController { private int mAvailable; diff --git a/tests/robotests/src/com/android/settings/development/EnforceConversationShortcutsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/EnforceConversationShortcutsPreferenceControllerTest.java new file mode 100644 index 00000000000..cbd775f103a --- /dev/null +++ b/tests/robotests/src/com/android/settings/development/EnforceConversationShortcutsPreferenceControllerTest.java @@ -0,0 +1,103 @@ +/* + * 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.development; + +import static com.android.settings.development.EnforceConversationShortcutsPreferenceController.SETTING_VALUE_OFF; +import static com.android.settings.development.EnforceConversationShortcutsPreferenceController.SETTING_VALUE_ON; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.content.Context; +import android.provider.Settings; + +import androidx.preference.PreferenceScreen; +import androidx.preference.SwitchPreference; + +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 EnforceConversationShortcutsPreferenceControllerTest { + + @Mock + private SwitchPreference mPreference; + @Mock + private PreferenceScreen mScreen; + + private Context mContext; + private EnforceConversationShortcutsPreferenceController mController; + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + mContext = RuntimeEnvironment.application; + mController = new EnforceConversationShortcutsPreferenceController(mContext); + when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference); + mController.displayPreference(mScreen); + } + + @Test + public void onPreferenceChange_settingEnabled() { + mController.onPreferenceChange(mPreference, true /* new value */); + + final int mode = Settings.Global.getInt(mContext.getContentResolver(), + Settings.Global.REQUIRE_SHORTCUTS_FOR_CONVERSATIONS, -1 /* default */); + + assertThat(mode).isEqualTo(SETTING_VALUE_ON); + } + + @Test + public void onPreferenceChange_settingDisabled() { + mController.onPreferenceChange(mPreference, false /* new value */); + + final int mode = Settings.Global.getInt(mContext.getContentResolver(), + Settings.Global.REQUIRE_SHORTCUTS_FOR_CONVERSATIONS, -1 /* default */); + + assertThat(mode).isEqualTo(SETTING_VALUE_OFF); + } + + @Test + public void updateState_settingEnabled_preferenceShouldBeChecked() { + Settings.Global.putInt(mContext.getContentResolver(), + Settings.Global.REQUIRE_SHORTCUTS_FOR_CONVERSATIONS, + SETTING_VALUE_ON); + + mController.updateState(mPreference); + + verify(mPreference).setChecked(true); + } + + @Test + public void updateState_settingDisabled_preferenceShouldNotBeChecked() { + Settings.Global.putInt(mContext.getContentResolver(), + Settings.Global.REQUIRE_SHORTCUTS_FOR_CONVERSATIONS, SETTING_VALUE_OFF); + + mController.updateState(mPreference); + + verify(mPreference).setChecked(false); + } +}