Snap for 4781697 from 8e060b42dd to qt-release
Change-Id: I42516df05f6a0e4b1f152bd44dc1e142200de816
This commit is contained in:
@@ -742,6 +742,28 @@
|
||||
android:value="true" />
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".notification.ZenSuggestionActivity"
|
||||
android:label="@string/zen_mode_settings_title"
|
||||
android:icon="@drawable/ic_zen"
|
||||
android:theme="@android:style/Theme.NoDisplay">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="com.android.settings.suggested.category.ZEN" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="com.android.settings.suggested.category.FIRST_IMPRESSION" />
|
||||
</intent-filter>
|
||||
|
||||
<meta-data android:name="com.android.settings.dismiss"
|
||||
android:value="0" />
|
||||
<meta-data android:name="com.android.settings.title"
|
||||
android:resource="@string/zen_suggestion_title" />
|
||||
<meta-data android:name="com.android.settings.summary"
|
||||
android:resource="@string/zen_suggestion_summary" />
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".notification.ZenOnboardingActivity"
|
||||
android:label="@string/zen_onboarding_dnd_visual_disturbances_header"
|
||||
@@ -755,7 +777,6 @@
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name="Settings$ZenModeAutomationSettingsActivity"
|
||||
android:label="@string/zen_mode_automation_settings_title"
|
||||
|
||||
@@ -14,13 +14,13 @@
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:viewportHeight="24.0"
|
||||
android:viewportWidth="24.0"
|
||||
android:height="24dp"
|
||||
android:width="24dp" >
|
||||
android:viewportHeight="24.0"
|
||||
android:viewportWidth="24.0"
|
||||
android:height="24dp"
|
||||
android:width="24dp" >
|
||||
|
||||
<path
|
||||
android:fillColor="#FFFFFFFF"
|
||||
android:pathData="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm4 11H8c-.55 0-1-.45-1-1s.45-1 1-1h8c.55 0 1 .45 1 1s-.45 1-1 1z" />
|
||||
android:fillColor="?android:attr/colorControlActivated"
|
||||
android:pathData="M 12 2 C 6.48 2 2 6.48 2 12 s 4.48 10 10 10 10 -4.48 10 -10 S 17.52 2 12 2 z m 4 11 H 8 c -.55 0 -1 -.45 -1 -1 s .45 -1 1 -1 h 8c.55 0 1 .45 1 1 s -.45 1 -1 1z" />
|
||||
|
||||
</vector>
|
||||
|
||||
@@ -402,11 +402,6 @@
|
||||
<!-- Summary for bluetooth item in connection detail page. (phone)-->
|
||||
<string name="bluetooth_pref_summary" product="default">Allow your phone to communicate with nearby Bluetooth devices</string>
|
||||
|
||||
<!-- Setting Checkbox title for disabling Bluetooth inband ringing in Development Settings -->
|
||||
<string name="bluetooth_disable_inband_ringing">Disable in-band ringing</string>
|
||||
<!-- Summary of checkbox for disabling Bluetooth inband ringing in Development Settings -->
|
||||
<string name="bluetooth_disable_inband_ringing_summary">Don’t play custom phone ringtones on Bluetooth headsets</string>
|
||||
|
||||
<!-- Title for Bluetooth device group with media capability group [CHAR LIMIT=none]-->
|
||||
<string name="connected_device_available_media_title">Available media devices</string>
|
||||
<!-- Title for Bluetooth device group with media capability group [CHAR LIMIT=none]-->
|
||||
@@ -1696,15 +1691,10 @@
|
||||
<!-- Bluetooth settings. Dock Setting Dialog - Remember setting and don't ask user again -->
|
||||
<string name="bluetooth_dock_settings_remember">Remember settings</string>
|
||||
|
||||
<!-- Bluetooth developer options. -->
|
||||
<!-- Bluetooth developer settings: Maximum number of connected audio devices -->
|
||||
<string name="bluetooth_max_connected_audio_devices_string">Maximum connected Bluetooth audio devices</string>
|
||||
<!-- Bluetooth developer settings: Maximum number of connected audio devices -->
|
||||
<string name="bluetooth_max_connected_audio_devices_dialog_title">Select maximum number of connected Bluetooth audio devices</string>
|
||||
<!-- Bluetooth developer settings: Checkbox title for disabling Bluetooth receiving AVDTP delay reports -->
|
||||
<string name="bluetooth_disable_avdtp_delay_reports">Disable Bluetooth AVDTP delay reports</string>
|
||||
<!-- Bluetooth developer settings: Summary of checkbox for disabling Bluetooth receiving AVDTP delay reports -->
|
||||
<string name="bluetooth_disable_avdtp_delay_reports_summary">Disallow receiving Bluetooth AVDTP delay reports</string>
|
||||
|
||||
<!-- Wifi Display settings. The title of the screen. [CHAR LIMIT=40] -->
|
||||
<string name="wifi_display_settings_title">Cast</string>
|
||||
@@ -2355,6 +2345,17 @@
|
||||
<!-- Message of private dns that provides a help link. [CHAR LIMIT=NONE] -->
|
||||
<string name="private_dns_help_message"><annotation id="url">Learn more</annotation> about Private DNS features</string>
|
||||
|
||||
<!-- Message to display when setting wifi calling are not editable [CHAR LIMIT=NONE] -->
|
||||
<string name="wifi_calling_pref_managed_by_carrier">Setting managed by carrier</string>
|
||||
<!-- Message to display when wifi calling needs activation [CHAR LIMIT=NONE] -->
|
||||
<string name="wifi_calling_settings_activation_instructions">Activate Wi\u2011Fi Calling</string>
|
||||
<!-- Message to display when wifi calling should be on [CHAR LIMIT=NONE] -->
|
||||
<string name="wifi_calling_turn_on">Turn on Wi\u2011Fi calling</string>
|
||||
<!-- Message to display when carrier does not support wifi calling or doesn't want the user
|
||||
to modify the settings [CHAR LIMIT=NONE] -->
|
||||
<string name="wifi_calling_not_supported">Wi\u2011Fi calling is not supported for %1$s</string>
|
||||
<!-- Carrier string to use in other messages -->
|
||||
<string name="carrier">Carrier</string>
|
||||
<!-- Sound and alerts settings -->
|
||||
<skip/>
|
||||
<string name="display_settings_title">Display</string>
|
||||
@@ -4922,6 +4923,8 @@
|
||||
<string name="background_activity_warning_dialog_title">Limit background activity?</string>
|
||||
<!-- TODO: Pending UX review. Text for the warning dialog to show to the user when limiting background activity for an app -->
|
||||
<string name="background_activity_warning_dialog_text">If you limit background activity for an app, it may misbehave</string>
|
||||
<!-- Dialog message when app can't been restricted because it is not optimized [CHAR_LIMIT=120] -->
|
||||
<string name="background_activity_disabled_dialog_text">Since this app is not set to optimize battery, you can\u2019t restrict it.\n\nTo restrict the app, first turn on battery optimization.</string>
|
||||
|
||||
<!-- Title for the screen usage in power use UI [CHAR_LIMIT=60] -->
|
||||
<string name="device_screen_usage">Screen usage since full charge</string>
|
||||
@@ -7930,6 +7933,9 @@
|
||||
<!-- [CHAR LIMIT=20] Zen mode settings: Calls option -->
|
||||
<string name="zen_mode_calls">Calls</string>
|
||||
|
||||
<!-- [CHAR LIMIT=40] Zen mode settings: Allow calls toggle title -->
|
||||
<string name="zen_mode_calls_title">Allow calls</string>
|
||||
|
||||
<!-- [CHAR LIMIT=20] Zen mode settings: Calls screen footer -->
|
||||
<string name="zen_mode_calls_footer">When Do Not Disturb is on, incoming calls are blocked. You can adjust settings to allow your friends, family, or other contacts to reach you.</string>
|
||||
|
||||
@@ -7945,6 +7951,9 @@
|
||||
<!-- [CHAR LIMIT=20] Zen mode settings: Messages option -->
|
||||
<string name="zen_mode_messages">Messages</string>
|
||||
|
||||
<!-- [CHAR LIMIT=40] Zen mode settings: Allow messages toggle title -->
|
||||
<string name="zen_mode_messages_title">Allow messages</string>
|
||||
|
||||
<!-- [CHAR LIMIT=50] Zen mode settings: All messages summary -->
|
||||
<string name="zen_mode_all_messages">Messages</string>
|
||||
|
||||
@@ -7984,9 +7993,15 @@
|
||||
<!-- [CHAR LIMIT=50] Zen mode settings: Reminders option -->
|
||||
<string name="zen_mode_reminders">Reminders</string>
|
||||
|
||||
<!-- [CHAR LIMIT=70] Zen mode settings: Allow reminders toggle title -->
|
||||
<string name="zen_mode_reminders_title">Allow reminders</string>
|
||||
|
||||
<!-- [CHAR LIMIT=50] Zen mode settings: Events option -->
|
||||
<string name="zen_mode_events">Events</string>
|
||||
|
||||
<!-- [CHAR LIMIT=70] Zen mode settings: Allow events toggle title -->
|
||||
<string name="zen_mode_events_title">Allow events</string>
|
||||
|
||||
<!-- [CHAR LIMIT=50] Zen mode settings: All callers summary -->
|
||||
<string name="zen_mode_all_callers">anyone</string>
|
||||
|
||||
@@ -7999,8 +8014,11 @@
|
||||
<!-- [CHAR LIMIT=50] Zen mode settings: Repeat callers option -->
|
||||
<string name="zen_mode_repeat_callers">Repeat callers</string>
|
||||
|
||||
<!-- [CHAR LIMIT=70] Zen mode settings: Allow repeat callers toggle title -->
|
||||
<string name="zen_mode_repeat_callers_title">Allow repeat callers</string>
|
||||
|
||||
<!-- [CHAR LIMIT=50] Zen mode settings: calls summary -->
|
||||
<string name="zen_mode_calls_summary_one">From <xliff:g id="caller type" example="contacts">%1$s</xliff:g> only</string>
|
||||
<string name="zen_mode_calls_summary_one">From <xliff:g id="caller type" example="contacts">%1$s</xliff:g></string>
|
||||
|
||||
<!-- [CHAR LIMIT=50] Zen mode settings: calls summary -->
|
||||
<string name="zen_mode_calls_summary_two">From <xliff:g id="caller type" example="starred contacts">%1$s</xliff:g> and <xliff:g id="callert tpye" example="repeat callers">%2$s</xliff:g></string>
|
||||
@@ -9882,6 +9900,12 @@
|
||||
<!-- Help URI, smart battery page [DO NOT TRANSLATE] -->
|
||||
<string name="help_uri_smart_battery_settings" translatable="false"></string>
|
||||
|
||||
<!-- Title label for dnd suggestion, which is displayed in Settings homepage [CHAR LIMIT=100] -->
|
||||
<string name="zen_suggestion_title">Update Do Not Disturb</string>
|
||||
|
||||
<!-- Summary label for dnd suggestion, which is displayed in Settings homepage [CHAR LIMIT=100] -->
|
||||
<string name="zen_suggestion_summary">Hide notifications to stay focused</string>
|
||||
|
||||
<!-- Title label for new device suggestion, which is displayed in Settings homepage [CHAR LIMIT=100] -->
|
||||
<string name="new_device_suggestion_title">What\'s new and exciting?</string>
|
||||
|
||||
|
||||
@@ -254,16 +254,6 @@
|
||||
android:title="@string/bluetooth_disable_absolute_volume"
|
||||
android:summary="@string/bluetooth_disable_absolute_volume_summary" />
|
||||
|
||||
<SwitchPreference
|
||||
android:key="bluetooth_disable_inband_ringing"
|
||||
android:title="@string/bluetooth_disable_inband_ringing"
|
||||
android:summary="@string/bluetooth_disable_inband_ringing_summary" />
|
||||
|
||||
<SwitchPreference
|
||||
android:key="bluetooth_disable_avdtp_delay_reports"
|
||||
android:title="@string/bluetooth_disable_avdtp_delay_reports"
|
||||
android:summary="@string/bluetooth_disable_avdtp_delay_reports_summary"/>
|
||||
|
||||
<ListPreference
|
||||
android:key="bluetooth_select_avrcp_version"
|
||||
android:title="@string/bluetooth_select_avrcp_version_string"
|
||||
|
||||
@@ -38,11 +38,12 @@
|
||||
|
||||
<!-- Model & hardware -->
|
||||
<Preference
|
||||
android:key="device_model"
|
||||
android:key="device_model_v1"
|
||||
android:order="21"
|
||||
android:title="@string/hardware_info"
|
||||
settings:keywords="@string/keywords_model_and_hardware"
|
||||
android:summary="@string/summary_placeholder" />
|
||||
android:summary="@string/summary_placeholder"
|
||||
settings:controller="com.android.settings.deviceinfo.DeviceModelPreferenceController" />
|
||||
|
||||
<!-- IMEI -->
|
||||
<Preference
|
||||
|
||||
@@ -87,7 +87,9 @@
|
||||
android:order="21"
|
||||
android:title="@string/hardware_info"
|
||||
settings:keywords="@string/keywords_model_and_hardware"
|
||||
android:summary="@string/summary_placeholder"/>
|
||||
android:summary="@string/summary_placeholder"
|
||||
settings:controller=
|
||||
"com.android.settings.deviceinfo.DeviceModelPreferenceController" />
|
||||
|
||||
<!-- IMEI -->
|
||||
<Preference
|
||||
|
||||
@@ -97,6 +97,7 @@
|
||||
android:order="15"
|
||||
android:dialogTitle="@string/select_private_dns_configuration_dialog_title"
|
||||
android:dialogLayout="@layout/private_dns_mode_dialog"
|
||||
android:positiveButtonText="@string/save" />
|
||||
android:positiveButtonText="@string/save"
|
||||
android:negativeButtonText="@android:string/cancel" />
|
||||
|
||||
</PreferenceScreen>
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
<PreferenceScreen
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:settings="http://schemas.android.com/apk/res-auto"
|
||||
android:key="tether_prefs_screen"
|
||||
android:title="@string/tether_settings_title_all">
|
||||
|
||||
<com.android.settings.widget.FixedLineSummaryPreference
|
||||
@@ -29,12 +30,14 @@
|
||||
<SwitchPreference
|
||||
android:key="usb_tether_settings"
|
||||
android:title="@string/usb_tethering_button_text"
|
||||
android:summary="@string/usb_tethering_subtext" />
|
||||
android:summary="@string/usb_tethering_subtext"
|
||||
settings:keywords="@string/keywords_hotspot_tethering" />
|
||||
|
||||
<SwitchPreference
|
||||
android:key="enable_bluetooth_tethering"
|
||||
android:title="@string/bluetooth_tether_checkbox_text"
|
||||
android:summary="@string/bluetooth_tethering_subtext" />
|
||||
android:summary="@string/bluetooth_tethering_subtext"
|
||||
settings:keywords="@string/keywords_hotspot_tethering" />
|
||||
|
||||
<Preference
|
||||
android:key="disabled_on_data_saver"
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
<PreferenceScreen
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:settings="http://schemas.android.com/apk/res-auto"
|
||||
android:key="wifi_tether_settings_screen"
|
||||
android:title="@string/wifi_hotspot_checkbox_text"
|
||||
settings:initialExpandedChildrenCount="2">
|
||||
|
||||
@@ -43,4 +44,4 @@
|
||||
android:dialogTitle="@string/wifi_hotspot_ap_band_title"
|
||||
android:negativeButtonText="@string/cancel"
|
||||
android:positiveButtonText="@string/apply"/>
|
||||
</PreferenceScreen>
|
||||
</PreferenceScreen>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<!-- Calls -->
|
||||
<ListPreference
|
||||
android:key="zen_mode_calls"
|
||||
android:title="@string/zen_mode_calls"
|
||||
android:title="@string/zen_mode_calls_title"
|
||||
android:entries="@array/zen_mode_contacts_entries"
|
||||
android:entryValues="@array/zen_mode_contacts_values"/>
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
<!-- Repeat callers -->
|
||||
<SwitchPreference
|
||||
android:key="zen_mode_repeat_callers"
|
||||
android:title="@string/zen_mode_repeat_callers" />
|
||||
android:title="@string/zen_mode_repeat_callers_title" />
|
||||
</PreferenceCategory>
|
||||
|
||||
<com.android.settingslib.widget.FooterPreference/>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<!-- Messages -->
|
||||
<ListPreference
|
||||
android:key="zen_mode_messages"
|
||||
android:title="@string/zen_mode_messages"
|
||||
android:title="@string/zen_mode_messages_title"
|
||||
android:entries="@array/zen_mode_contacts_entries"
|
||||
android:entryValues="@array/zen_mode_contacts_values"/>
|
||||
|
||||
@@ -37,12 +37,12 @@
|
||||
<!-- Reminders -->
|
||||
<SwitchPreference
|
||||
android:key="zen_mode_reminders"
|
||||
android:title="@string/zen_mode_reminders"/>
|
||||
android:title="@string/zen_mode_reminders_title"/>
|
||||
|
||||
<!-- Events -->
|
||||
<SwitchPreference
|
||||
android:key="zen_mode_events"
|
||||
android:title="@string/zen_mode_events"/>
|
||||
android:title="@string/zen_mode_events_title"/>
|
||||
</PreferenceCategory>
|
||||
|
||||
<com.android.settingslib.widget.FooterPreference />
|
||||
|
||||
@@ -34,27 +34,41 @@ import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.os.Handler;
|
||||
import android.os.UserManager;
|
||||
import androidx.preference.SwitchPreference;
|
||||
import android.provider.SearchIndexableResource;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.SwitchPreference;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.settings.datausage.DataSaverBackend;
|
||||
import com.android.settings.search.BaseSearchIndexProvider;
|
||||
import com.android.settings.search.Indexable;
|
||||
import com.android.settings.wifi.tether.WifiTetherPreferenceController;
|
||||
import com.android.settingslib.TetherUtil;
|
||||
import com.android.settingslib.search.SearchIndexable;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
/*
|
||||
* Displays preferences for Tethering.
|
||||
*/
|
||||
@SearchIndexable
|
||||
public class TetherSettings extends RestrictedSettingsFragment
|
||||
implements DataSaverBackend.Listener {
|
||||
|
||||
private static final String USB_TETHER_SETTINGS = "usb_tether_settings";
|
||||
private static final String ENABLE_BLUETOOTH_TETHERING = "enable_bluetooth_tethering";
|
||||
private static final String DATA_SAVER_FOOTER = "disabled_on_data_saver";
|
||||
@VisibleForTesting
|
||||
static final String KEY_TETHER_PREFS_SCREEN = "tether_prefs_screen";
|
||||
@VisibleForTesting
|
||||
static final String KEY_WIFI_TETHER = "wifi_tether";
|
||||
@VisibleForTesting
|
||||
static final String KEY_USB_TETHER_SETTINGS = "usb_tether_settings";
|
||||
@VisibleForTesting
|
||||
static final String KEY_ENABLE_BLUETOOTH_TETHERING = "enable_bluetooth_tethering";
|
||||
private static final String KEY_DATA_SAVER_FOOTER = "disabled_on_data_saver";
|
||||
|
||||
private static final String TAG = "TetheringSettings";
|
||||
|
||||
@@ -110,7 +124,7 @@ public class TetherSettings extends RestrictedSettingsFragment
|
||||
|
||||
mDataSaverBackend = new DataSaverBackend(getContext());
|
||||
mDataSaverEnabled = mDataSaverBackend.isDataSaverEnabled();
|
||||
mDataSaverFooter = findPreference(DATA_SAVER_FOOTER);
|
||||
mDataSaverFooter = findPreference(KEY_DATA_SAVER_FOOTER);
|
||||
|
||||
setIfOnlyAvailableForAdmins(true);
|
||||
if (isUiRestricted()) {
|
||||
@@ -126,8 +140,8 @@ public class TetherSettings extends RestrictedSettingsFragment
|
||||
BluetoothProfile.PAN);
|
||||
}
|
||||
|
||||
mUsbTether = (SwitchPreference) findPreference(USB_TETHER_SETTINGS);
|
||||
mBluetoothTether = (SwitchPreference) findPreference(ENABLE_BLUETOOTH_TETHERING);
|
||||
mUsbTether = (SwitchPreference) findPreference(KEY_USB_TETHER_SETTINGS);
|
||||
mBluetoothTether = (SwitchPreference) findPreference(KEY_ENABLE_BLUETOOTH_TETHERING);
|
||||
|
||||
mDataSaverBackend.addListener(this);
|
||||
|
||||
@@ -387,7 +401,6 @@ public class TetherSettings extends RestrictedSettingsFragment
|
||||
if (adapter.getState() == BluetoothAdapter.STATE_OFF) {
|
||||
mBluetoothEnableForTether = true;
|
||||
adapter.enable();
|
||||
mBluetoothTether.setSummary(R.string.bluetooth_turning_on);
|
||||
mBluetoothTether.setEnabled(false);
|
||||
return;
|
||||
}
|
||||
@@ -433,6 +446,42 @@ public class TetherSettings extends RestrictedSettingsFragment
|
||||
}
|
||||
};
|
||||
|
||||
public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
|
||||
new BaseSearchIndexProvider() {
|
||||
@Override
|
||||
public List<SearchIndexableResource> getXmlResourcesToIndex(
|
||||
Context context, boolean enabled) {
|
||||
final SearchIndexableResource sir = new SearchIndexableResource(context);
|
||||
sir.xmlResId = R.xml.tether_prefs;
|
||||
return Arrays.asList(sir);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getNonIndexableKeys(Context context) {
|
||||
final List<String> keys = super.getNonIndexableKeys(context);
|
||||
final ConnectivityManager cm =
|
||||
context.getSystemService(ConnectivityManager.class);
|
||||
|
||||
if (!TetherUtil.isTetherAvailable(context)) {
|
||||
keys.add(KEY_TETHER_PREFS_SCREEN);
|
||||
keys.add(KEY_WIFI_TETHER);
|
||||
}
|
||||
|
||||
final boolean usbAvailable =
|
||||
cm.getTetherableUsbRegexs().length != 0;
|
||||
if (!usbAvailable || Utils.isMonkeyRunning()) {
|
||||
keys.add(KEY_USB_TETHER_SETTINGS);
|
||||
}
|
||||
|
||||
final boolean bluetoothAvailable =
|
||||
cm.getTetherableBluetoothRegexs().length != 0;
|
||||
if (!bluetoothAvailable) {
|
||||
keys.add(KEY_ENABLE_BLUETOOTH_TETHERING);
|
||||
}
|
||||
return keys;
|
||||
}
|
||||
};
|
||||
|
||||
private static final class OnStartTetheringCallback extends
|
||||
ConnectivityManager.OnStartTetheringCallback {
|
||||
final WeakReference<TetherSettings> mTetherSettings;
|
||||
|
||||
@@ -21,6 +21,7 @@ import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.service.settings.suggestions.Suggestion;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import android.util.Log;
|
||||
@@ -32,6 +33,8 @@ import com.android.settings.Settings.NightDisplaySuggestionActivity;
|
||||
import com.android.settings.display.NightDisplayPreferenceController;
|
||||
import com.android.settings.fingerprint.FingerprintEnrollSuggestionActivity;
|
||||
import com.android.settings.fingerprint.FingerprintSuggestionActivity;
|
||||
import com.android.settings.notification.ZenOnboardingActivity;
|
||||
import com.android.settings.notification.ZenSuggestionActivity;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settings.password.ScreenLockSuggestionActivity;
|
||||
import com.android.settings.support.NewDeviceIntroSuggestionActivity;
|
||||
@@ -88,6 +91,8 @@ public class SuggestionFeatureProviderImpl implements SuggestionFeatureProvider
|
||||
return NightDisplayPreferenceController.isSuggestionComplete(context);
|
||||
} else if (className.equals(NewDeviceIntroSuggestionActivity.class.getName())) {
|
||||
return NewDeviceIntroSuggestionActivity.isSuggestionComplete(context);
|
||||
} else if (className.equals(ZenSuggestionActivity.class.getName())) {
|
||||
return ZenOnboardingActivity.isSuggestionComplete(context);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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.SystemProperties;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.preference.SwitchPreference;
|
||||
import androidx.preference.Preference;
|
||||
|
||||
import com.android.settings.core.PreferenceControllerMixin;
|
||||
import com.android.settingslib.development.DeveloperOptionsPreferenceController;
|
||||
|
||||
public class BluetoothDelayReportsPreferenceController extends DeveloperOptionsPreferenceController
|
||||
implements Preference.OnPreferenceChangeListener, PreferenceControllerMixin {
|
||||
|
||||
private static final String BLUETOOTH_DISABLE_AVDTP_DELAY_REPORT_KEY =
|
||||
"bluetooth_disable_avdtp_delay_reports";
|
||||
@VisibleForTesting
|
||||
static final String BLUETOOTH_DISABLE_AVDTP_DELAY_REPORTS_PROPERTY =
|
||||
"persist.bluetooth.disabledelayreports";
|
||||
|
||||
public BluetoothDelayReportsPreferenceController(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return BLUETOOTH_DISABLE_AVDTP_DELAY_REPORT_KEY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
final boolean isDisabled = (Boolean) newValue;
|
||||
SystemProperties.set(BLUETOOTH_DISABLE_AVDTP_DELAY_REPORTS_PROPERTY,
|
||||
isDisabled ? "true" : "false");
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
final boolean isDisabled = SystemProperties.getBoolean(
|
||||
BLUETOOTH_DISABLE_AVDTP_DELAY_REPORTS_PROPERTY, false /* default */);
|
||||
((SwitchPreference) mPreference).setChecked(isDisabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDeveloperOptionsSwitchDisabled() {
|
||||
super.onDeveloperOptionsSwitchDisabled();
|
||||
// the default setting for this preference is the disabled state
|
||||
((SwitchPreference) mPreference).setChecked(false);
|
||||
SystemProperties.set(BLUETOOTH_DISABLE_AVDTP_DELAY_REPORTS_PROPERTY, "false");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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.bluetooth.BluetoothHeadset;
|
||||
import android.content.Context;
|
||||
import android.os.SystemProperties;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.preference.SwitchPreference;
|
||||
import androidx.preference.Preference;
|
||||
|
||||
import com.android.settings.core.PreferenceControllerMixin;
|
||||
import com.android.settingslib.development.DeveloperOptionsPreferenceController;
|
||||
|
||||
public class BluetoothInbandRingingPreferenceController extends DeveloperOptionsPreferenceController
|
||||
implements Preference.OnPreferenceChangeListener, PreferenceControllerMixin {
|
||||
|
||||
private static final String BLUETOOTH_DISABLE_INBAND_RINGING_KEY =
|
||||
"bluetooth_disable_inband_ringing";
|
||||
@VisibleForTesting
|
||||
static final String BLUETOOTH_DISABLE_INBAND_RINGING_PROPERTY =
|
||||
"persist.bluetooth.disableinbandringing";
|
||||
|
||||
public BluetoothInbandRingingPreferenceController(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return isInbandRingingSupported();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return BLUETOOTH_DISABLE_INBAND_RINGING_KEY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
final boolean isChecked = (Boolean) newValue;
|
||||
SystemProperties.set(BLUETOOTH_DISABLE_INBAND_RINGING_PROPERTY,
|
||||
isChecked ? "true" : "false");
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
final boolean isEnabled = SystemProperties.getBoolean(
|
||||
BLUETOOTH_DISABLE_INBAND_RINGING_PROPERTY, false /* default */);
|
||||
((SwitchPreference) mPreference).setChecked(isEnabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDeveloperOptionsSwitchDisabled() {
|
||||
super.onDeveloperOptionsSwitchDisabled();
|
||||
((SwitchPreference) mPreference).setChecked(false);
|
||||
SystemProperties.set(BLUETOOTH_DISABLE_INBAND_RINGING_PROPERTY, "false");
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
boolean isInbandRingingSupported() {
|
||||
return BluetoothHeadset.isInbandRingingSupported(mContext);
|
||||
}
|
||||
}
|
||||
@@ -406,8 +406,6 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra
|
||||
controllers.add(new TetheringHardwareAccelPreferenceController(context));
|
||||
controllers.add(new BluetoothDeviceNoNamePreferenceController(context));
|
||||
controllers.add(new BluetoothAbsoluteVolumePreferenceController(context));
|
||||
controllers.add(new BluetoothInbandRingingPreferenceController(context));
|
||||
controllers.add(new BluetoothDelayReportsPreferenceController(context));
|
||||
controllers.add(new BluetoothAvrcpVersionPreferenceController(context));
|
||||
controllers.add(new BluetoothAudioCodecPreferenceController(context, lifecycle,
|
||||
bluetoothA2dpConfigStore));
|
||||
|
||||
@@ -21,7 +21,6 @@ import android.app.Fragment;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.provider.SearchIndexableResource;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import android.telephony.TelephonyManager;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
@@ -41,6 +40,8 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
@SearchIndexable
|
||||
public class DeviceInfoSettings extends DashboardFragment implements Indexable {
|
||||
|
||||
@@ -57,6 +58,7 @@ public class DeviceInfoSettings extends DashboardFragment implements Indexable {
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
use(FirmwareVersionPreferenceController.class).setHost(this /*parent*/);
|
||||
use(DeviceModelPreferenceController.class).setHost(this /* parent */);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -134,7 +136,6 @@ public class DeviceInfoSettings extends DashboardFragment implements Indexable {
|
||||
final List<AbstractPreferenceController> controllers = new ArrayList<>();
|
||||
controllers.add(new PhoneNumberPreferenceController(context));
|
||||
controllers.add(new SimStatusPreferenceController(context, fragment));
|
||||
controllers.add(new DeviceModelPreferenceController(context, fragment));
|
||||
controllers.add(new ImeiInfoPreferenceController(context, fragment));
|
||||
controllers.add(new IpAddressPreferenceController(context, lifecycle));
|
||||
controllers.add(new WifiMacAddressPreferenceController(context, lifecycle));
|
||||
|
||||
@@ -18,50 +18,54 @@ package com.android.settings.deviceinfo;
|
||||
import android.app.Fragment;
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.PreferenceControllerMixin;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settingslib.DeviceInfoUtils;
|
||||
import com.android.settingslib.core.AbstractPreferenceController;
|
||||
|
||||
public class DeviceModelPreferenceController extends AbstractPreferenceController implements
|
||||
PreferenceControllerMixin {
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.FutureTask;
|
||||
|
||||
private static final String KEY_DEVICE_MODEL = "device_model";
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
private final Fragment mHost;
|
||||
|
||||
public DeviceModelPreferenceController(Context context, Fragment host) {
|
||||
super(context);
|
||||
mHost = host;
|
||||
public class DeviceModelPreferenceController extends BasePreferenceController {
|
||||
|
||||
private static final String TAG = "DeviceModelPrefCtrl";
|
||||
|
||||
private Fragment mHost;
|
||||
|
||||
public DeviceModelPreferenceController(Context context, String key) {
|
||||
super(context, key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return mContext.getResources().getBoolean(R.bool.config_show_device_model);
|
||||
public void setHost(Fragment fragment) {
|
||||
mHost = fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
super.displayPreference(screen);
|
||||
final Preference pref = screen.findPreference(KEY_DEVICE_MODEL);
|
||||
if (pref != null) {
|
||||
pref.setSummary(mContext.getResources().getString(R.string.model_summary,
|
||||
getDeviceModel()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return KEY_DEVICE_MODEL;
|
||||
public int getAvailabilityStatus() {
|
||||
return mContext.getResources().getBoolean(R.bool.config_show_device_model)
|
||||
? AVAILABLE : UNSUPPORTED_ON_DEVICE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getSummary() {
|
||||
return mContext.getResources().getString(R.string.model_summary, getDeviceModel());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handlePreferenceTreeClick(Preference preference) {
|
||||
if (!TextUtils.equals(preference.getKey(), KEY_DEVICE_MODEL)) {
|
||||
if (!TextUtils.equals(preference.getKey(), getPreferenceKey())) {
|
||||
return false;
|
||||
}
|
||||
final HardwareInfoDialogFragment fragment = HardwareInfoDialogFragment.newInstance();
|
||||
@@ -70,6 +74,25 @@ public class DeviceModelPreferenceController extends AbstractPreferenceControlle
|
||||
}
|
||||
|
||||
public static String getDeviceModel() {
|
||||
return Build.MODEL + DeviceInfoUtils.getMsvSuffix();
|
||||
FutureTask<String> msvSuffixTask = new FutureTask<String>(new Callable<String>() {
|
||||
@Override
|
||||
public String call() {
|
||||
return DeviceInfoUtils.getMsvSuffix();
|
||||
}
|
||||
});
|
||||
|
||||
msvSuffixTask.run();
|
||||
try {
|
||||
// Wait for msv suffix value.
|
||||
final String msvSuffix = msvSuffixTask.get();
|
||||
return Build.MODEL + msvSuffix;
|
||||
} catch (ExecutionException e) {
|
||||
Log.e(TAG, "Execution error, so we only show model name");
|
||||
} catch (InterruptedException e) {
|
||||
Log.e(TAG, "Interruption error, so we only show model name");
|
||||
}
|
||||
// If we can't get an msv suffix value successfully,
|
||||
// it's better to return model name.
|
||||
return Build.MODEL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,6 +82,7 @@ public class MyDeviceInfoFragment extends DashboardFragment
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
use(FirmwareVersionPreferenceController.class).setHost(this /*parent*/);
|
||||
use(DeviceModelPreferenceController.class).setHost(this /* parent */);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -122,7 +123,6 @@ public class MyDeviceInfoFragment extends DashboardFragment
|
||||
}
|
||||
controllers.add(deviceNamePreferenceController);
|
||||
controllers.add(new SimStatusPreferenceController(context, fragment));
|
||||
controllers.add(new DeviceModelPreferenceController(context, fragment));
|
||||
controllers.add(new ImeiInfoPreferenceController(context, fragment));
|
||||
controllers.add(new IpAddressPreferenceController(context, lifecycle));
|
||||
controllers.add(new WifiMacAddressPreferenceController(context, lifecycle));
|
||||
|
||||
@@ -156,16 +156,18 @@ public class PrivateDnsModeDialogPreference extends CustomDialogPreference imple
|
||||
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
final Context context = getContext();
|
||||
if (mMode.equals(PRIVATE_DNS_MODE_PROVIDER_HOSTNAME)) {
|
||||
// Only clickable if hostname is valid, so we could save it safely
|
||||
Settings.Global.putString(context.getContentResolver(), HOSTNAME_KEY,
|
||||
mEditText.getText().toString());
|
||||
}
|
||||
if (which == DialogInterface.BUTTON_POSITIVE) {
|
||||
final Context context = getContext();
|
||||
if (mMode.equals(PRIVATE_DNS_MODE_PROVIDER_HOSTNAME)) {
|
||||
// Only clickable if hostname is valid, so we could save it safely
|
||||
Settings.Global.putString(context.getContentResolver(), HOSTNAME_KEY,
|
||||
mEditText.getText().toString());
|
||||
}
|
||||
|
||||
FeatureFactory.getFactory(context).getMetricsFeatureProvider().action(context,
|
||||
MetricsProto.MetricsEvent.ACTION_PRIVATE_DNS_MODE, mMode);
|
||||
Settings.Global.putString(context.getContentResolver(), MODE_KEY, mMode);
|
||||
FeatureFactory.getFactory(context).getMetricsFeatureProvider().action(context,
|
||||
MetricsProto.MetricsEvent.ACTION_PRIVATE_DNS_MODE, mMode);
|
||||
Settings.Global.putString(context.getContentResolver(), MODE_KEY, mMode);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -17,7 +17,6 @@ package com.android.settings.network;
|
||||
|
||||
import static android.os.UserManager.DISALLOW_CONFIG_TETHERING;
|
||||
import static com.android.settingslib.RestrictedLockUtils.checkIfRestrictionEnforced;
|
||||
import static com.android.settingslib.RestrictedLockUtils.hasBaseUserRestriction;
|
||||
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothPan;
|
||||
@@ -40,6 +39,7 @@ import androidx.preference.PreferenceScreen;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.TetherSettings;
|
||||
import com.android.settings.core.PreferenceControllerMixin;
|
||||
import com.android.settingslib.TetherUtil;
|
||||
import com.android.settingslib.core.AbstractPreferenceController;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
import com.android.settingslib.core.lifecycle.LifecycleObserver;
|
||||
@@ -112,11 +112,7 @@ public class TetherPreferenceController extends AbstractPreferenceController imp
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
final boolean isBlocked =
|
||||
(!mConnectivityManager.isTetheringSupported() && !mAdminDisallowedTetherConfig)
|
||||
|| hasBaseUserRestriction(mContext, DISALLOW_CONFIG_TETHERING,
|
||||
UserHandle.myUserId());
|
||||
return !isBlocked;
|
||||
return TetherUtil.isTetherAvailable(mContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -135,6 +135,9 @@ public class ZenModeBackend {
|
||||
}
|
||||
|
||||
protected void saveVisualEffectsPolicy(int category, boolean suppress) {
|
||||
Settings.Global.putInt(mContext.getContentResolver(),
|
||||
Settings.Global.ZEN_SETTINGS_UPDATED, 1);
|
||||
|
||||
int suppressedEffects = getNewSuppressedEffects(suppress, category);
|
||||
savePolicy(mPolicy.priorityCategories, mPolicy.priorityCallSenders,
|
||||
mPolicy.priorityMessageSenders, suppressedEffects);
|
||||
|
||||
@@ -16,22 +16,15 @@
|
||||
|
||||
package com.android.settings.notification;
|
||||
|
||||
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_ZEN_SHOW_CUSTOM;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.provider.SearchIndexableResource;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settings.search.BaseSearchIndexProvider;
|
||||
import com.android.settings.search.Indexable;
|
||||
import com.android.settingslib.core.AbstractPreferenceController;
|
||||
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
import com.android.settingslib.search.SearchIndexable;
|
||||
import com.android.settingslib.widget.FooterPreference;
|
||||
@@ -42,67 +35,21 @@ import java.util.List;
|
||||
@SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
|
||||
public class ZenModeRestrictNotificationsSettings extends ZenModeSettingsBase implements Indexable {
|
||||
|
||||
protected static final int APP_MENU_SHOW_CUSTOM = 1;
|
||||
protected boolean mShowMenuSelected;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle icicle) {
|
||||
super.onCreate(icicle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
menu.add(0, APP_MENU_SHOW_CUSTOM, 0, R.string.zen_mode_restrict_notifications_enable_custom)
|
||||
.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem menuItem) {
|
||||
if (menuItem.getItemId() == APP_MENU_SHOW_CUSTOM) {
|
||||
final FeatureFactory featureFactory = FeatureFactory.getFactory(mContext);
|
||||
MetricsFeatureProvider metrics = featureFactory.getMetricsFeatureProvider();
|
||||
|
||||
mShowMenuSelected = !mShowMenuSelected;
|
||||
|
||||
ZenModeVisEffectsCustomPreferenceController custom =
|
||||
use(ZenModeVisEffectsCustomPreferenceController.class);
|
||||
custom.setShownByMenu(mShowMenuSelected);
|
||||
custom.displayPreference(getPreferenceScreen());
|
||||
|
||||
if (mShowMenuSelected) {
|
||||
metrics.action(mContext, ACTION_ZEN_SHOW_CUSTOM, true);
|
||||
} else {
|
||||
metrics.action(mContext, ACTION_ZEN_SHOW_CUSTOM, false);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPrepareOptionsMenu(Menu menu) {
|
||||
if (mShowMenuSelected) {
|
||||
menu.findItem(APP_MENU_SHOW_CUSTOM)
|
||||
.setTitle(R.string.zen_mode_restrict_notifications_disable_custom);
|
||||
} else {
|
||||
menu.findItem(APP_MENU_SHOW_CUSTOM)
|
||||
.setTitle(R.string.zen_mode_restrict_notifications_enable_custom);
|
||||
}
|
||||
|
||||
if (mShowMenuSelected && use(ZenModeVisEffectsCustomPreferenceController.class)
|
||||
.areCustomOptionsSelected()) {
|
||||
menu.findItem(APP_MENU_SHOW_CUSTOM).setEnabled(false);
|
||||
} else {
|
||||
menu.findItem(APP_MENU_SHOW_CUSTOM).setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
|
||||
return buildPreferenceControllers(context, getLifecycle());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHelpResource() {
|
||||
return R.string.help_uri_interruptions;
|
||||
}
|
||||
|
||||
private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
|
||||
Lifecycle lifecycle) {
|
||||
List<AbstractPreferenceController> controllers = new ArrayList<>();
|
||||
|
||||
@@ -170,7 +170,7 @@ public class ZenModeSettings extends ZenModeSettingsBase {
|
||||
} else if (numCategories == 2) {
|
||||
return mContext.getString(R.string.join_two_items, enabledCategories.get(0),
|
||||
enabledCategories.get(1).toLowerCase());
|
||||
} else if (numCategories == 3) {
|
||||
} else if (numCategories == 3){
|
||||
final List<String> summaries = new ArrayList<>();
|
||||
summaries.add(enabledCategories.get(0));
|
||||
summaries.add(enabledCategories.get(1).toLowerCase());
|
||||
|
||||
@@ -30,7 +30,6 @@ import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
public class ZenModeVisEffectsCustomPreferenceController
|
||||
extends AbstractZenModePreferenceController {
|
||||
|
||||
protected boolean mShowMenuSelected;
|
||||
protected static final int INTERRUPTIVE_EFFECTS = Policy.SUPPRESSED_EFFECT_AMBIENT
|
||||
| Policy.SUPPRESSED_EFFECT_PEEK
|
||||
| Policy.SUPPRESSED_EFFECT_LIGHTS
|
||||
@@ -43,11 +42,7 @@ public class ZenModeVisEffectsCustomPreferenceController
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
if (mShowMenuSelected) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return areCustomOptionsSelected();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -67,10 +62,6 @@ public class ZenModeVisEffectsCustomPreferenceController
|
||||
});
|
||||
}
|
||||
|
||||
protected void setShownByMenu(boolean shown) {
|
||||
mShowMenuSelected = shown;
|
||||
}
|
||||
|
||||
protected boolean areCustomOptionsSelected() {
|
||||
boolean allEffectsSuppressed =
|
||||
Policy.areAllVisualEffectsSuppressed(mBackend.mPolicy.suppressedVisualEffects);
|
||||
|
||||
@@ -19,17 +19,34 @@ package com.android.settings.notification;
|
||||
import android.app.Activity;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.NotificationManager.Policy;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.provider.Settings;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import android.text.format.DateUtils;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
|
||||
import com.android.internal.logging.MetricsLogger;
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
public class ZenOnboardingActivity extends Activity {
|
||||
|
||||
private static final String TAG = "ZenOnboardingActivity";
|
||||
|
||||
@VisibleForTesting
|
||||
static final String PREF_KEY_SUGGESTION_FIRST_DISPLAY_TIME =
|
||||
"pref_zen_suggestion_first_display_time_ms";
|
||||
@VisibleForTesting
|
||||
static final String PREF_KEY_SUGGESTION_VIEWED = "pref_zen_suggestion_viewed";
|
||||
@VisibleForTesting
|
||||
static final long ALWAYS_SHOW_THRESHOLD = DateUtils.DAY_IN_MILLIS * 14;
|
||||
|
||||
private NotificationManager mNm;
|
||||
private MetricsLogger mMetrics;
|
||||
|
||||
@@ -39,6 +56,10 @@ public class ZenOnboardingActivity extends Activity {
|
||||
setNotificationManager(getSystemService(NotificationManager.class));
|
||||
setMetricsLogger(new MetricsLogger());
|
||||
|
||||
Context context = getApplicationContext();
|
||||
Settings.Global.putInt(context.getContentResolver(),
|
||||
Settings.Global.ZEN_SETTINGS_SUGGESTION_VIEWED, 1);
|
||||
|
||||
setupUI();
|
||||
}
|
||||
|
||||
@@ -61,20 +82,80 @@ public class ZenOnboardingActivity extends Activity {
|
||||
|
||||
public void close(View button) {
|
||||
mMetrics.action(MetricsEvent.ACTION_ZEN_ONBOARDING_KEEP_CURRENT_SETTINGS);
|
||||
|
||||
Settings.Global.putInt(getApplicationContext().getContentResolver(),
|
||||
Settings.Global.ZEN_SETTINGS_UPDATED, 1);
|
||||
|
||||
finishAndRemoveTask();
|
||||
}
|
||||
|
||||
public void save(View button) {
|
||||
mMetrics.action(MetricsEvent.ACTION_ZEN_ONBOARDING_OK);
|
||||
Policy policy = mNm.getNotificationPolicy();
|
||||
NotificationManager.Policy policy = mNm.getNotificationPolicy();
|
||||
|
||||
Policy newPolicy = new NotificationManager.Policy(
|
||||
NotificationManager.Policy newPolicy = new NotificationManager.Policy(
|
||||
Policy.PRIORITY_CATEGORY_REPEAT_CALLERS | policy.priorityCategories,
|
||||
Policy.PRIORITY_SENDERS_STARRED,
|
||||
policy.priorityMessageSenders,
|
||||
Policy.getAllSuppressedVisualEffects());
|
||||
NotificationManager.Policy.getAllSuppressedVisualEffects());
|
||||
mNm.setNotificationPolicy(newPolicy);
|
||||
|
||||
Settings.Global.putInt(getApplicationContext().getContentResolver(),
|
||||
Settings.Global.ZEN_SETTINGS_UPDATED, 1);
|
||||
|
||||
finishAndRemoveTask();
|
||||
}
|
||||
|
||||
public static boolean isSuggestionComplete(Context context) {
|
||||
if (wasZenUpdated(context)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (showSuggestion(context) || withinShowTimeThreshold(context)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean wasZenUpdated(Context context) {
|
||||
// ZEN_SETTINGS_UPDATED is true for:
|
||||
// - fresh P+ device
|
||||
// - if zen visual effects values were changed by the user in Settings
|
||||
return Settings.Global.getInt(context.getContentResolver(),
|
||||
Settings.Global.ZEN_SETTINGS_UPDATED, 0) != 0;
|
||||
}
|
||||
|
||||
private static boolean showSuggestion(Context context) {
|
||||
// SHOW_ZEN_SETTINGS_SUGGESTION is by default true, but false when:
|
||||
// - user manually turns on dnd
|
||||
|
||||
// SHOW_ZEN_SETTINGS_SUGGESTION is also true when:
|
||||
// - automatic rule has started DND and user has not seen the first use dialog
|
||||
return Settings.Global.getInt(context.getContentResolver(),
|
||||
Settings.Global.SHOW_ZEN_SETTINGS_SUGGESTION, 0) != 0;
|
||||
|
||||
}
|
||||
|
||||
private static boolean withinShowTimeThreshold(Context context) {
|
||||
final SuggestionFeatureProvider featureProvider = FeatureFactory.getFactory(context)
|
||||
.getSuggestionFeatureProvider(context);
|
||||
final SharedPreferences prefs = featureProvider.getSharedPrefs(context);
|
||||
final long currentTimeMs = System.currentTimeMillis();
|
||||
final long firstDisplayTimeMs;
|
||||
|
||||
if (!prefs.contains(PREF_KEY_SUGGESTION_FIRST_DISPLAY_TIME)) {
|
||||
firstDisplayTimeMs = currentTimeMs;
|
||||
prefs.edit().putLong(PREF_KEY_SUGGESTION_FIRST_DISPLAY_TIME, currentTimeMs).commit();
|
||||
} else {
|
||||
firstDisplayTimeMs = prefs.getLong(PREF_KEY_SUGGESTION_FIRST_DISPLAY_TIME, -1);
|
||||
}
|
||||
|
||||
final long showTimeMs = firstDisplayTimeMs + ALWAYS_SHOW_THRESHOLD;
|
||||
final boolean stillShow = currentTimeMs < showTimeMs;
|
||||
|
||||
Log.d(TAG, "still show zen suggestion based on time: " + stillShow + " showTimeMs="
|
||||
+ showTimeMs);
|
||||
return stillShow;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.android.settings.notification;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.provider.Settings;
|
||||
|
||||
public class ZenSuggestionActivity extends Activity {
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
// start up zen settings activity
|
||||
Intent settingsIntent = new Intent(Settings.ACTION_ZEN_MODE_SETTINGS);
|
||||
startActivity(settingsIntent);
|
||||
|
||||
// start up onboarding activity
|
||||
Intent onboardingActivity = new Intent(Settings.ZEN_MODE_ONBOARDING);
|
||||
startActivity(onboardingActivity);
|
||||
|
||||
finish();
|
||||
}
|
||||
}
|
||||
@@ -38,7 +38,6 @@ import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.os.storage.StorageManager;
|
||||
import android.security.KeyStore;
|
||||
import androidx.annotation.StringRes;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
@@ -97,7 +96,6 @@ public class ChooseLockGeneric extends SettingsActivity {
|
||||
public static class ChooseLockGenericFragment extends SettingsPreferenceFragment {
|
||||
|
||||
private static final String TAG = "ChooseLockGenericFragment";
|
||||
private static final int MIN_PASSWORD_LENGTH = 4;
|
||||
private static final String KEY_SKIP_FINGERPRINT = "unlock_skip_fingerprint";
|
||||
private static final String PASSWORD_CONFIRMED = "password_confirmed";
|
||||
private static final String WAITING_FOR_CONFIRMATION = "waiting_for_confirmation";
|
||||
@@ -136,7 +134,6 @@ public class ChooseLockGeneric extends SettingsActivity {
|
||||
|
||||
private ChooseLockSettingsHelper mChooseLockSettingsHelper;
|
||||
private DevicePolicyManager mDPM;
|
||||
private KeyStore mKeyStore;
|
||||
private boolean mHasChallenge = false;
|
||||
private long mChallenge;
|
||||
private boolean mPasswordConfirmed = false;
|
||||
@@ -168,7 +165,6 @@ public class ChooseLockGeneric extends SettingsActivity {
|
||||
String chooseLockAction = getActivity().getIntent().getAction();
|
||||
mFingerprintManager = Utils.getFingerprintManagerOrNull(getActivity());
|
||||
mDPM = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
|
||||
mKeyStore = KeyStore.getInstance();
|
||||
mChooseLockSettingsHelper = new ChooseLockSettingsHelper(this.getActivity());
|
||||
mLockPatternUtils = new LockPatternUtils(getActivity());
|
||||
mIsSetNewPassword = ACTION_SET_NEW_PARENT_PROFILE_PASSWORD.equals(chooseLockAction)
|
||||
@@ -585,11 +581,10 @@ public class ChooseLockGeneric extends SettingsActivity {
|
||||
return mManagedPasswordProvider.createIntent(false, password);
|
||||
}
|
||||
|
||||
protected Intent getLockPasswordIntent(int quality, int minLength, int maxLength) {
|
||||
protected Intent getLockPasswordIntent(int quality) {
|
||||
ChooseLockPassword.IntentBuilder builder =
|
||||
new ChooseLockPassword.IntentBuilder(getContext())
|
||||
.setPasswordQuality(quality)
|
||||
.setPasswordLengthRange(minLength, maxLength)
|
||||
.setForFingerprint(mForFingerprint)
|
||||
.setUserId(mUserId);
|
||||
if (mHasChallenge) {
|
||||
@@ -668,12 +663,7 @@ public class ChooseLockGeneric extends SettingsActivity {
|
||||
if (quality >= DevicePolicyManager.PASSWORD_QUALITY_MANAGED) {
|
||||
intent = getLockManagedPasswordIntent(mUserPassword);
|
||||
} else if (quality >= DevicePolicyManager.PASSWORD_QUALITY_NUMERIC) {
|
||||
int minLength = mDPM.getPasswordMinimumLength(null, mUserId);
|
||||
if (minLength < MIN_PASSWORD_LENGTH) {
|
||||
minLength = MIN_PASSWORD_LENGTH;
|
||||
}
|
||||
final int maxLength = mDPM.getPasswordMaximumLength(quality);
|
||||
intent = getLockPasswordIntent(quality, minLength, maxLength);
|
||||
intent = getLockPasswordIntent(quality);
|
||||
} else if (quality == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING) {
|
||||
intent = getLockPatternIntent();
|
||||
}
|
||||
|
||||
@@ -73,15 +73,6 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ChooseLockPassword extends SettingsActivity {
|
||||
public static final String PASSWORD_MIN_KEY = "lockscreen.password_min";
|
||||
public static final String PASSWORD_MAX_KEY = "lockscreen.password_max";
|
||||
public static final String PASSWORD_MIN_LETTERS_KEY = "lockscreen.password_min_letters";
|
||||
public static final String PASSWORD_MIN_LOWERCASE_KEY = "lockscreen.password_min_lowercase";
|
||||
public static final String PASSWORD_MIN_UPPERCASE_KEY = "lockscreen.password_min_uppercase";
|
||||
public static final String PASSWORD_MIN_NUMERIC_KEY = "lockscreen.password_min_numeric";
|
||||
public static final String PASSWORD_MIN_SYMBOLS_KEY = "lockscreen.password_min_symbols";
|
||||
public static final String PASSWORD_MIN_NONLETTER_KEY = "lockscreen.password_min_nonletter";
|
||||
|
||||
private static final String TAG = "ChooseLockPassword";
|
||||
|
||||
@Override
|
||||
@@ -113,12 +104,6 @@ public class ChooseLockPassword extends SettingsActivity {
|
||||
return this;
|
||||
}
|
||||
|
||||
public IntentBuilder setPasswordLengthRange(int min, int max) {
|
||||
mIntent.putExtra(PASSWORD_MIN_KEY, min);
|
||||
mIntent.putExtra(PASSWORD_MAX_KEY, max);
|
||||
return this;
|
||||
}
|
||||
|
||||
public IntentBuilder setUserId(int userId) {
|
||||
mIntent.putExtra(Intent.EXTRA_USER_ID, userId);
|
||||
return this;
|
||||
@@ -454,54 +439,32 @@ public class ChooseLockPassword extends SettingsActivity {
|
||||
}
|
||||
|
||||
private void setupPasswordRequirementsView(View view) {
|
||||
// Construct passwordRequirements and requirementDescriptions.
|
||||
List<Integer> passwordRequirements = new ArrayList<>();
|
||||
List<String> requirementDescriptions = new ArrayList<>();
|
||||
final List<Integer> passwordRequirements = new ArrayList<>();
|
||||
if (mPasswordMinUpperCase > 0) {
|
||||
passwordRequirements.add(MIN_UPPER_LETTERS_IN_PASSWORD);
|
||||
requirementDescriptions.add(getResources().getQuantityString(
|
||||
R.plurals.lockpassword_password_requires_uppercase, mPasswordMinUpperCase,
|
||||
mPasswordMinUpperCase));
|
||||
}
|
||||
if (mPasswordMinLowerCase > 0) {
|
||||
passwordRequirements.add(MIN_LOWER_LETTERS_IN_PASSWORD);
|
||||
requirementDescriptions.add(getResources().getQuantityString(
|
||||
R.plurals.lockpassword_password_requires_lowercase, mPasswordMinLowerCase,
|
||||
mPasswordMinLowerCase));
|
||||
}
|
||||
if (mPasswordMinLetters > 0) {
|
||||
if (mPasswordMinLetters > mPasswordMinUpperCase + mPasswordMinLowerCase) {
|
||||
passwordRequirements.add(MIN_LETTER_IN_PASSWORD);
|
||||
requirementDescriptions.add(getResources().getQuantityString(
|
||||
R.plurals.lockpassword_password_requires_letters, mPasswordMinLetters,
|
||||
mPasswordMinLetters));
|
||||
}
|
||||
}
|
||||
if (mPasswordMinNumeric > 0) {
|
||||
passwordRequirements.add(MIN_NUMBER_IN_PASSWORD);
|
||||
requirementDescriptions.add(getResources().getQuantityString(
|
||||
R.plurals.lockpassword_password_requires_numeric, mPasswordMinNumeric,
|
||||
mPasswordMinNumeric));
|
||||
}
|
||||
if (mPasswordMinSymbols > 0) {
|
||||
passwordRequirements.add(MIN_SYMBOLS_IN_PASSWORD);
|
||||
requirementDescriptions.add(getResources().getQuantityString(
|
||||
R.plurals.lockpassword_password_requires_symbols, mPasswordMinSymbols,
|
||||
mPasswordMinSymbols));
|
||||
}
|
||||
if (mPasswordMinNonLetter > 0) {
|
||||
if (mPasswordMinNonLetter > mPasswordMinNumeric + mPasswordMinSymbols) {
|
||||
passwordRequirements.add(MIN_NON_LETTER_IN_PASSWORD);
|
||||
requirementDescriptions.add(getResources().getQuantityString(
|
||||
R.plurals.lockpassword_password_requires_nonletter, mPasswordMinNonLetter,
|
||||
|
||||
mPasswordMinNonLetter));
|
||||
}
|
||||
}
|
||||
// Convert list to array.
|
||||
mPasswordRequirements = passwordRequirements.stream().mapToInt(i -> i).toArray();
|
||||
mPasswordRestrictionView =
|
||||
(RecyclerView) view.findViewById(R.id.password_requirements_view);
|
||||
mPasswordRestrictionView = view.findViewById(R.id.password_requirements_view);
|
||||
mPasswordRestrictionView.setLayoutManager(new LinearLayoutManager(getActivity()));
|
||||
mPasswordRequirementAdapter = new PasswordRequirementAdapter();
|
||||
mPasswordRestrictionView.setAdapter(mPasswordRequirementAdapter);
|
||||
@@ -582,29 +545,15 @@ public class ChooseLockPassword extends SettingsActivity {
|
||||
final int dpmPasswordQuality = mLockPatternUtils.getRequestedPasswordQuality(mUserId);
|
||||
mRequestedQuality = Math.max(intent.getIntExtra(LockPatternUtils.PASSWORD_TYPE_KEY,
|
||||
mRequestedQuality), dpmPasswordQuality);
|
||||
mPasswordMinLength = Math.max(Math.max(
|
||||
LockPatternUtils.MIN_LOCK_PASSWORD_SIZE,
|
||||
intent.getIntExtra(PASSWORD_MIN_KEY, mPasswordMinLength)),
|
||||
mPasswordMinLength = Math.max(LockPatternUtils.MIN_LOCK_PASSWORD_SIZE,
|
||||
mLockPatternUtils.getRequestedMinimumPasswordLength(mUserId));
|
||||
mPasswordMaxLength = intent.getIntExtra(PASSWORD_MAX_KEY, mPasswordMaxLength);
|
||||
mPasswordMinLetters = Math.max(intent.getIntExtra(PASSWORD_MIN_LETTERS_KEY,
|
||||
mPasswordMinLetters), mLockPatternUtils.getRequestedPasswordMinimumLetters(
|
||||
mUserId));
|
||||
mPasswordMinUpperCase = Math.max(intent.getIntExtra(PASSWORD_MIN_UPPERCASE_KEY,
|
||||
mPasswordMinUpperCase), mLockPatternUtils.getRequestedPasswordMinimumUpperCase(
|
||||
mUserId));
|
||||
mPasswordMinLowerCase = Math.max(intent.getIntExtra(PASSWORD_MIN_LOWERCASE_KEY,
|
||||
mPasswordMinLowerCase), mLockPatternUtils.getRequestedPasswordMinimumLowerCase(
|
||||
mUserId));
|
||||
mPasswordMinNumeric = Math.max(intent.getIntExtra(PASSWORD_MIN_NUMERIC_KEY,
|
||||
mPasswordMinNumeric), mLockPatternUtils.getRequestedPasswordMinimumNumeric(
|
||||
mUserId));
|
||||
mPasswordMinSymbols = Math.max(intent.getIntExtra(PASSWORD_MIN_SYMBOLS_KEY,
|
||||
mPasswordMinSymbols), mLockPatternUtils.getRequestedPasswordMinimumSymbols(
|
||||
mUserId));
|
||||
mPasswordMinNonLetter = Math.max(intent.getIntExtra(PASSWORD_MIN_NONLETTER_KEY,
|
||||
mPasswordMinNonLetter), mLockPatternUtils.getRequestedPasswordMinimumNonLetter(
|
||||
mUserId));
|
||||
mPasswordMaxLength = mLockPatternUtils.getMaximumPasswordLength(mRequestedQuality);
|
||||
mPasswordMinLetters = mLockPatternUtils.getRequestedPasswordMinimumLetters(mUserId);
|
||||
mPasswordMinUpperCase = mLockPatternUtils.getRequestedPasswordMinimumUpperCase(mUserId);
|
||||
mPasswordMinLowerCase = mLockPatternUtils.getRequestedPasswordMinimumLowerCase(mUserId);
|
||||
mPasswordMinNumeric = mLockPatternUtils.getRequestedPasswordMinimumNumeric(mUserId);
|
||||
mPasswordMinSymbols = mLockPatternUtils.getRequestedPasswordMinimumSymbols(mUserId);
|
||||
mPasswordMinNonLetter = mLockPatternUtils.getRequestedPasswordMinimumNonLetter(mUserId);
|
||||
|
||||
// Modify the value based on dpm policy.
|
||||
switch (dpmPasswordQuality) {
|
||||
|
||||
@@ -170,9 +170,9 @@ public class SetupChooseLockGeneric extends ChooseLockGeneric {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Intent getLockPasswordIntent(int quality, int minLength, int maxLength) {
|
||||
protected Intent getLockPasswordIntent(int quality) {
|
||||
final Intent intent = SetupChooseLockPassword.modifyIntentForSetup(
|
||||
getContext(), super.getLockPasswordIntent(quality, minLength, maxLength));
|
||||
getContext(), super.getLockPasswordIntent(quality));
|
||||
SetupWizardUtils.copySetupExtras(getActivity().getIntent(), intent);
|
||||
return intent;
|
||||
}
|
||||
|
||||
@@ -53,10 +53,12 @@ public class DeviceIndexUpdateJobService extends JobService {
|
||||
@Override
|
||||
public boolean onStartJob(JobParameters params) {
|
||||
if (DEBUG) Log.d(TAG, "onStartJob");
|
||||
mRunningJob = true;
|
||||
Thread thread = new Thread(() -> updateIndex(params));
|
||||
thread.setPriority(Thread.MIN_PRIORITY);
|
||||
thread.start();
|
||||
if (!mRunningJob) {
|
||||
mRunningJob = true;
|
||||
Thread thread = new Thread(() -> updateIndex(params));
|
||||
thread.setPriority(Thread.MIN_PRIORITY);
|
||||
thread.start();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -122,7 +124,7 @@ public class DeviceIndexUpdateJobService extends JobService {
|
||||
}
|
||||
|
||||
protected CharSequence findTitle(Slice loadedSlice, SliceMetadata metaData) {
|
||||
ListContent content = new ListContent(this, loadedSlice);
|
||||
ListContent content = new ListContent(null, loadedSlice);
|
||||
SliceItem headerItem = content.getHeaderItem();
|
||||
if (headerItem == null) {
|
||||
if (content.getRowItems().size() != 0) {
|
||||
|
||||
@@ -18,6 +18,8 @@ package com.android.settings.slices;
|
||||
|
||||
import static android.Manifest.permission.READ_SEARCH_INDEXABLES;
|
||||
|
||||
import static com.android.settings.wifi.calling.WifiCallingSliceHelper.PATH_WIFI_CALLING;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.app.slice.SliceManager;
|
||||
import android.content.ContentResolver;
|
||||
@@ -32,7 +34,13 @@ import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
|
||||
import androidx.slice.Slice;
|
||||
import androidx.slice.SliceProvider;
|
||||
import androidx.slice.builders.ListBuilder;
|
||||
import androidx.slice.builders.SliceAction;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settingslib.utils.ThreadUtils;
|
||||
|
||||
import java.net.URISyntaxException;
|
||||
@@ -160,6 +168,11 @@ public class SettingsSliceProvider extends SliceProvider {
|
||||
switch (path) {
|
||||
case "/" + PATH_WIFI:
|
||||
return createWifiSlice(sliceUri);
|
||||
case "/" + PATH_WIFI_CALLING:
|
||||
return FeatureFactory.getFactory(getContext())
|
||||
.getSlicesFeatureProvider()
|
||||
.getNewWifiCallingSliceHelper(getContext())
|
||||
.createWifiCallingSlice(sliceUri);
|
||||
}
|
||||
|
||||
SliceData cachedSliceData = mSliceWeakDataCache.get(sliceUri);
|
||||
|
||||
@@ -21,6 +21,7 @@ import static com.android.settings.slices.SettingsSliceProvider.ACTION_TOGGLE_CH
|
||||
import static com.android.settings.slices.SettingsSliceProvider.ACTION_WIFI_CHANGED;
|
||||
import static com.android.settings.slices.SettingsSliceProvider.EXTRA_SLICE_KEY;
|
||||
import static com.android.settings.slices.SettingsSliceProvider.EXTRA_SLICE_PLATFORM_DEFINED;
|
||||
import static com.android.settings.wifi.calling.WifiCallingSliceHelper.ACTION_WIFI_CALLING_CHANGED;
|
||||
|
||||
import android.app.slice.Slice;
|
||||
import android.content.BroadcastReceiver;
|
||||
@@ -79,6 +80,12 @@ public class SliceBroadcastReceiver extends BroadcastReceiver {
|
||||
context.getContentResolver().notifyChange(uri, null);
|
||||
}, 1000);
|
||||
break;
|
||||
case ACTION_WIFI_CALLING_CHANGED:
|
||||
FeatureFactory.getFactory(context)
|
||||
.getSlicesFeatureProvider()
|
||||
.getNewWifiCallingSliceHelper(context)
|
||||
.handleWifiCallingChanged(intent);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@ package com.android.settings.slices;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.android.settings.wifi.calling.WifiCallingSliceHelper;
|
||||
|
||||
/**
|
||||
* Manages Slices in Settings.
|
||||
*/
|
||||
@@ -24,4 +26,9 @@ public interface SlicesFeatureProvider {
|
||||
* If the data is already indexed, the data will not change.
|
||||
*/
|
||||
void indexSliceData(Context context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets new WifiCallingSliceHelper object
|
||||
*/
|
||||
WifiCallingSliceHelper getNewWifiCallingSliceHelper(Context context);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.android.settings.slices;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.android.settings.wifi.calling.WifiCallingSliceHelper;
|
||||
import com.android.settingslib.utils.ThreadUtils;
|
||||
|
||||
/**
|
||||
@@ -39,4 +40,9 @@ public class SlicesFeatureProviderImpl implements SlicesFeatureProvider {
|
||||
SlicesIndexer indexer = getSliceIndexer(context);
|
||||
indexer.indexSliceData();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public WifiCallingSliceHelper getNewWifiCallingSliceHelper(Context context) {
|
||||
return new WifiCallingSliceHelper(context);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,363 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.wifi.calling;
|
||||
|
||||
import static android.app.slice.Slice.EXTRA_TOGGLE_STATE;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.PersistableBundle;
|
||||
import androidx.core.graphics.drawable.IconCompat;
|
||||
import android.telephony.CarrierConfigManager;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.slice.Slice;
|
||||
import androidx.slice.builders.ListBuilder;
|
||||
import androidx.slice.builders.SliceAction;
|
||||
|
||||
import com.android.ims.ImsManager;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.slices.SliceBroadcastReceiver;
|
||||
import com.android.settings.slices.SliceBuilderUtils;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.FutureTask;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
|
||||
/**
|
||||
* Helper class to control slices for wifi calling settings.
|
||||
*/
|
||||
public class WifiCallingSliceHelper {
|
||||
|
||||
private static final String TAG = "WifiCallingSliceHelper";
|
||||
|
||||
/**
|
||||
* Settings slice path to wifi calling setting.
|
||||
*/
|
||||
public static final String PATH_WIFI_CALLING = "wifi_calling";
|
||||
|
||||
/**
|
||||
* Action passed for changes to wifi calling slice (toggle).
|
||||
*/
|
||||
public static final String ACTION_WIFI_CALLING_CHANGED =
|
||||
"com.android.settings.wifi.calling.action.WIFI_CALLING_CHANGED";
|
||||
|
||||
/**
|
||||
* Action for Wifi calling Settings activity which
|
||||
* allows setting configuration for Wifi calling
|
||||
* related settings
|
||||
*/
|
||||
public static final String ACTION_WIFI_CALLING_SETTINGS_ACTIVITY =
|
||||
"android.settings.WIFI_CALLING_SETTINGS";
|
||||
|
||||
/**
|
||||
* Timeout for querying wifi calling setting from ims manager.
|
||||
*/
|
||||
private static final int TIMEOUT_MILLIS = 2000;
|
||||
|
||||
/**
|
||||
* Time for which data contained in the slice can remain fresh.
|
||||
*/
|
||||
private static final int SLICE_TTL_MILLIS = 60000;
|
||||
|
||||
protected SubscriptionManager mSubscriptionManager;
|
||||
private final Context mContext;
|
||||
|
||||
@VisibleForTesting
|
||||
public WifiCallingSliceHelper(Context context) {
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Slice object for wifi calling settings.
|
||||
*
|
||||
* If wifi calling is being turned on and if wifi calling activation is needed for the current
|
||||
* carrier, this method will return Slice with instructions to go to Settings App.
|
||||
*
|
||||
* If wifi calling is not supported for the current carrier, this method will return slice with
|
||||
* not supported message.
|
||||
*
|
||||
* If wifi calling setting can be changed, this method will return the slice to toggle wifi
|
||||
* calling option with ACTION_WIFI_CALLING_CHANGED as endItem.
|
||||
*/
|
||||
public Slice createWifiCallingSlice(Uri sliceUri) {
|
||||
final int subId = getDefaultVoiceSubId();
|
||||
final String carrierName = getSimCarrierName();
|
||||
|
||||
if (subId <= SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
|
||||
Log.d(TAG, "Invalid subscription Id");
|
||||
return getNonActionableWifiCallingSlice(
|
||||
mContext.getString(R.string.wifi_calling_settings_title),
|
||||
mContext.getString(R.string.wifi_calling_not_supported, carrierName),
|
||||
sliceUri, SliceBuilderUtils.getSettingsIntent(mContext));
|
||||
}
|
||||
|
||||
final ImsManager imsManager = getImsManager(subId);
|
||||
|
||||
if (!imsManager.isWfcEnabledByPlatform()
|
||||
|| !imsManager.isWfcProvisionedOnDevice()) {
|
||||
Log.d(TAG, "Wifi calling is either not provisioned or not enabled by Platform");
|
||||
return getNonActionableWifiCallingSlice(
|
||||
mContext.getString(R.string.wifi_calling_settings_title),
|
||||
mContext.getString(R.string.wifi_calling_not_supported, carrierName),
|
||||
sliceUri, SliceBuilderUtils.getSettingsIntent(mContext));
|
||||
}
|
||||
|
||||
try {
|
||||
final boolean isWifiCallingEnabled = isWifiCallingEnabled(imsManager);
|
||||
final Intent activationAppIntent =
|
||||
getWifiCallingCarrierActivityIntent(subId);
|
||||
|
||||
// Send this actionable wifi calling slice to toggle the setting
|
||||
// only when there is no need for wifi calling activation with the server
|
||||
if (activationAppIntent != null && !isWifiCallingEnabled) {
|
||||
Log.d(TAG, "Needs Activation");
|
||||
// Activation needed for the next action of the user
|
||||
// Give instructions to go to settings app
|
||||
return getNonActionableWifiCallingSlice(
|
||||
mContext.getString(R.string.wifi_calling_settings_title),
|
||||
mContext.getString(
|
||||
R.string.wifi_calling_settings_activation_instructions),
|
||||
sliceUri, getActivityIntent(ACTION_WIFI_CALLING_SETTINGS_ACTIVITY));
|
||||
}
|
||||
return getWifiCallingSlice(sliceUri, mContext, isWifiCallingEnabled);
|
||||
} catch (InterruptedException | TimeoutException | ExecutionException e) {
|
||||
Log.e(TAG, "Unable to read the current WiFi calling status", e);
|
||||
return getNonActionableWifiCallingSlice(
|
||||
mContext.getString(R.string.wifi_calling_settings_title),
|
||||
mContext.getString(R.string.wifi_calling_turn_on),
|
||||
sliceUri, getActivityIntent(ACTION_WIFI_CALLING_SETTINGS_ACTIVITY));
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isWifiCallingEnabled(ImsManager imsManager)
|
||||
throws InterruptedException, ExecutionException, TimeoutException {
|
||||
final FutureTask<Boolean> isWifiOnTask = new FutureTask<>(new Callable<Boolean>() {
|
||||
@Override
|
||||
public Boolean call() {
|
||||
return imsManager.isWfcEnabledByUser();
|
||||
}
|
||||
});
|
||||
final ExecutorService executor = Executors.newSingleThreadExecutor();
|
||||
executor.execute(isWifiOnTask);
|
||||
|
||||
Boolean isWifiEnabledByUser = false;
|
||||
isWifiEnabledByUser = isWifiOnTask.get(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
|
||||
|
||||
return isWifiEnabledByUser && imsManager.isNonTtyOrTtyOnVolteEnabled();
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a toggle slice where the intent takes you to the wifi calling page and the toggle
|
||||
* enables/disables wifi calling.
|
||||
*/
|
||||
private Slice getWifiCallingSlice(Uri sliceUri, Context mContext,
|
||||
boolean isWifiCallingEnabled) {
|
||||
|
||||
final IconCompat icon = IconCompat.createWithResource(mContext, R.drawable.wifi_signal);
|
||||
final String title = mContext.getString(R.string.wifi_calling_settings_title);
|
||||
return new ListBuilder(mContext, sliceUri, SLICE_TTL_MILLIS)
|
||||
.setColor(R.color.material_blue_500)
|
||||
.addRow(b -> b
|
||||
.setTitle(title)
|
||||
.addEndItem(
|
||||
new SliceAction(
|
||||
getBroadcastIntent(ACTION_WIFI_CALLING_CHANGED),
|
||||
null /* actionTitle */, isWifiCallingEnabled))
|
||||
.setPrimaryAction(new SliceAction(
|
||||
getActivityIntent(ACTION_WIFI_CALLING_SETTINGS_ACTIVITY),
|
||||
icon,
|
||||
title)))
|
||||
.build();
|
||||
}
|
||||
|
||||
protected ImsManager getImsManager(int subId) {
|
||||
return ImsManager.getInstance(mContext, SubscriptionManager.getPhoneId(subId));
|
||||
}
|
||||
|
||||
private Integer getWfcMode(ImsManager imsManager)
|
||||
throws InterruptedException, ExecutionException, TimeoutException {
|
||||
FutureTask<Integer> wfcModeTask = new FutureTask<>(new Callable<Integer>() {
|
||||
@Override
|
||||
public Integer call() {
|
||||
return imsManager.getWfcMode(false);
|
||||
}
|
||||
});
|
||||
ExecutorService executor = Executors.newSingleThreadExecutor();
|
||||
executor.execute(wfcModeTask);
|
||||
return wfcModeTask.get(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles wifi calling setting change from wifi calling slice and posts notification. Should be
|
||||
* called when intent action is ACTION_WIFI_CALLING_CHANGED. Executed in @WorkerThread
|
||||
*
|
||||
* @param intent action performed
|
||||
*/
|
||||
public void handleWifiCallingChanged(Intent intent) {
|
||||
final int subId = getDefaultVoiceSubId();
|
||||
|
||||
if (subId > SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
|
||||
final ImsManager imsManager = getImsManager(subId);
|
||||
if (imsManager.isWfcEnabledByPlatform()
|
||||
|| imsManager.isWfcProvisionedOnDevice()) {
|
||||
final boolean currentValue = imsManager.isWfcEnabledByUser()
|
||||
&& imsManager.isNonTtyOrTtyOnVolteEnabled();
|
||||
final boolean newValue = intent.getBooleanExtra(EXTRA_TOGGLE_STATE,
|
||||
currentValue);
|
||||
final Intent activationAppIntent =
|
||||
getWifiCallingCarrierActivityIntent(subId);
|
||||
if (!newValue || activationAppIntent == null) {
|
||||
// If either the action is to turn off wifi calling setting
|
||||
// or there is no activation involved - Update the setting
|
||||
if (newValue != currentValue) {
|
||||
imsManager.setWfcSetting(newValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// notify change in slice in any case to get re-queried. This would result in displaying
|
||||
// appropriate message with the updated setting.
|
||||
final Uri uri = SliceBuilderUtils.getUri(PATH_WIFI_CALLING, false /*isPlatformSlice*/);
|
||||
mContext.getContentResolver().notifyChange(uri, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Slice with the title and subtitle provided as arguments with wifi signal Icon.
|
||||
*
|
||||
* @param title Title of the slice
|
||||
* @param subtitle Subtitle of the slice
|
||||
* @param sliceUri slice uri
|
||||
* @return Slice with title and subtitle
|
||||
*/
|
||||
// TODO(b/79548264) asses different scenarios and return null instead of non-actionable slice
|
||||
private Slice getNonActionableWifiCallingSlice(String title, String subtitle, Uri sliceUri,
|
||||
PendingIntent primaryActionIntent) {
|
||||
final IconCompat icon = IconCompat.createWithResource(mContext, R.drawable.wifi_signal);
|
||||
return new ListBuilder(mContext, sliceUri, SLICE_TTL_MILLIS)
|
||||
.setColor(R.color.material_blue_500)
|
||||
.addRow(b -> b
|
||||
.setTitle(title)
|
||||
.setSubtitle(subtitle)
|
||||
.setPrimaryAction(new SliceAction(
|
||||
primaryActionIntent, icon,
|
||||
title)))
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} when the key is enabled for the carrier, and {@code false} otherwise.
|
||||
*/
|
||||
private boolean isCarrierConfigManagerKeyEnabled(Context mContext, String key,
|
||||
int subId, boolean defaultValue) {
|
||||
final CarrierConfigManager configManager = getCarrierConfigManager(mContext);
|
||||
boolean ret = false;
|
||||
if (configManager != null) {
|
||||
final PersistableBundle bundle = configManager.getConfigForSubId(subId);
|
||||
if (bundle != null) {
|
||||
ret = bundle.getBoolean(key, defaultValue);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
protected CarrierConfigManager getCarrierConfigManager(Context mContext) {
|
||||
return mContext.getSystemService(CarrierConfigManager.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current default voice subId obtained from SubscriptionManager
|
||||
*/
|
||||
protected int getDefaultVoiceSubId() {
|
||||
if (mSubscriptionManager == null) {
|
||||
mSubscriptionManager = mContext.getSystemService(SubscriptionManager.class);
|
||||
}
|
||||
return SubscriptionManager.getDefaultVoiceSubscriptionId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Intent of the activation app required to activate wifi calling or null if there is no
|
||||
* need for activation.
|
||||
*/
|
||||
protected Intent getWifiCallingCarrierActivityIntent(int subId) {
|
||||
final CarrierConfigManager configManager = getCarrierConfigManager(mContext);
|
||||
if (configManager == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final PersistableBundle bundle = configManager.getConfigForSubId(subId);
|
||||
if (bundle == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final String carrierApp = bundle.getString(
|
||||
CarrierConfigManager.KEY_WFC_EMERGENCY_ADDRESS_CARRIER_APP_STRING);
|
||||
if (TextUtils.isEmpty(carrierApp)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final ComponentName componentName = ComponentName.unflattenFromString(carrierApp);
|
||||
if (componentName == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final Intent intent = new Intent();
|
||||
intent.setComponent(componentName);
|
||||
return intent;
|
||||
}
|
||||
|
||||
private PendingIntent getBroadcastIntent(String action) {
|
||||
final Intent intent = new Intent(action);
|
||||
intent.setClass(mContext, SliceBroadcastReceiver.class);
|
||||
return PendingIntent.getBroadcast(mContext, 0 /* requestCode */, intent,
|
||||
PendingIntent.FLAG_CANCEL_CURRENT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns PendingIntent to start activity specified by action
|
||||
*/
|
||||
private PendingIntent getActivityIntent(String action) {
|
||||
final Intent intent = new Intent(action);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
return PendingIntent.getActivity(mContext, 0 /* requestCode */, intent, 0 /* flags */);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns carrier id name of the current Subscription
|
||||
*/
|
||||
private String getSimCarrierName() {
|
||||
final TelephonyManager telephonyManager = mContext.getSystemService(TelephonyManager.class);
|
||||
final CharSequence carrierName = telephonyManager.getSimCarrierIdName();
|
||||
if (carrierName == null) {
|
||||
return mContext.getString(R.string.carrier);
|
||||
}
|
||||
return carrierName.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -27,28 +27,42 @@ import android.net.wifi.WifiConfiguration;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserManager;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import android.provider.SearchIndexableResource;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SettingsActivity;
|
||||
import com.android.settings.dashboard.RestrictedDashboardFragment;
|
||||
import com.android.settings.search.BaseSearchIndexProvider;
|
||||
import com.android.settings.widget.SwitchBar;
|
||||
import com.android.settings.widget.SwitchBarController;
|
||||
import com.android.settingslib.TetherUtil;
|
||||
import com.android.settingslib.core.AbstractPreferenceController;
|
||||
import com.android.settingslib.search.SearchIndexable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
@SearchIndexable
|
||||
public class WifiTetherSettings extends RestrictedDashboardFragment
|
||||
implements WifiTetherBasePreferenceController.OnTetherConfigUpdateListener {
|
||||
|
||||
private static final String TAG = "WifiTetherSettings";
|
||||
private static final IntentFilter TETHER_STATE_CHANGE_FILTER;
|
||||
private static final String KEY_WIFI_TETHER_AUTO_OFF = "wifi_tether_auto_turn_off";
|
||||
private static final String KEY_WIFI_TETHER_SCREEN = "wifi_tether_settings_screen";
|
||||
@VisibleForTesting
|
||||
static final String KEY_WIFI_TETHER_NETWORK_NAME = "wifi_tether_network_name";
|
||||
@VisibleForTesting
|
||||
static final String KEY_WIFI_TETHER_NETWORK_PASSWORD = "wifi_tether_network_password";
|
||||
@VisibleForTesting
|
||||
static final String KEY_WIFI_TETHER_AUTO_OFF = "wifi_tether_auto_turn_off";
|
||||
@VisibleForTesting
|
||||
static final String KEY_WIFI_TETHER_NETWORK_AP_BAND = "wifi_tether_network_ap_band";
|
||||
|
||||
private WifiTetherSwitchBarController mSwitchBarController;
|
||||
private WifiTetherSSIDPreferenceController mSSIDPreferenceController;
|
||||
@@ -182,6 +196,33 @@ public class WifiTetherSettings extends RestrictedDashboardFragment
|
||||
.updateDisplay();
|
||||
}
|
||||
|
||||
public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
|
||||
new BaseSearchIndexProvider() {
|
||||
@Override
|
||||
public List<SearchIndexableResource> getXmlResourcesToIndex(
|
||||
Context context, boolean enabled) {
|
||||
final SearchIndexableResource sir = new SearchIndexableResource(context);
|
||||
sir.xmlResId = R.xml.wifi_tether_settings;
|
||||
return Arrays.asList(sir);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getNonIndexableKeys(Context context) {
|
||||
final List<String> keys = super.getNonIndexableKeys(context);
|
||||
|
||||
if (!TetherUtil.isTetherAvailable(context)) {
|
||||
keys.add(KEY_WIFI_TETHER_NETWORK_NAME);
|
||||
keys.add(KEY_WIFI_TETHER_NETWORK_PASSWORD);
|
||||
keys.add(KEY_WIFI_TETHER_AUTO_OFF);
|
||||
keys.add(KEY_WIFI_TETHER_NETWORK_AP_BAND);
|
||||
}
|
||||
|
||||
// Remove duplicate
|
||||
keys.add(KEY_WIFI_TETHER_SCREEN);
|
||||
return keys;
|
||||
}
|
||||
};
|
||||
|
||||
@VisibleForTesting
|
||||
class TetherChangeReceiver extends BroadcastReceiver {
|
||||
@Override
|
||||
|
||||
@@ -21,7 +21,6 @@ com.android.settings.enterprise.ApplicationListFragment$AdminGrantedPermissionMi
|
||||
com.android.settings.enterprise.ApplicationListFragment$EnterpriseInstalledPackages
|
||||
com.android.settings.enterprise.EnterpriseSetDefaultAppsListFragment
|
||||
com.android.settings.inputmethod.KeyboardLayoutPickerFragment
|
||||
com.android.settings.wifi.tether.WifiTetherSettings
|
||||
com.android.settings.wifi.SavedAccessPointsWifiSettings
|
||||
com.android.settings.notification.ZenModeEventRuleSettings
|
||||
com.android.settings.notification.ZenModeScheduleRuleSettings
|
||||
|
||||
150
tests/robotests/src/com/android/settings/TetherSettingsTest.java
Normal file
150
tests/robotests/src/com/android/settings/TetherSettingsTest.java
Normal file
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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;
|
||||
|
||||
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.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.net.ConnectivityManager;
|
||||
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
public class TetherSettingsTest {
|
||||
|
||||
private Context mContext;
|
||||
|
||||
@Mock
|
||||
private ConnectivityManager mConnectivityManager;
|
||||
@Mock
|
||||
private UserManager mUserManager;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mContext = spy(RuntimeEnvironment.application);
|
||||
|
||||
MockitoAnnotations.initMocks(this);
|
||||
doReturn(mConnectivityManager)
|
||||
.when(mContext).getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
doReturn(mUserManager)
|
||||
.when(mContext).getSystemService(Context.USER_SERVICE);
|
||||
|
||||
setupIsTetherAvailable(true);
|
||||
|
||||
when(mConnectivityManager.getTetherableUsbRegexs()).thenReturn(new String[]{});
|
||||
when(mConnectivityManager.getTetherableBluetoothRegexs()).thenReturn(new String[]{});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTetherNonIndexableKeys_tetherAvailable_keysNotReturned() {
|
||||
// To let TetherUtil.isTetherAvailable return true, select one of the combinations
|
||||
setupIsTetherAvailable(true);
|
||||
|
||||
final List<String> niks =
|
||||
TetherSettings.SEARCH_INDEX_DATA_PROVIDER.getNonIndexableKeys(mContext);
|
||||
|
||||
assertThat(niks).doesNotContain(TetherSettings.KEY_TETHER_PREFS_SCREEN);
|
||||
assertThat(niks).doesNotContain(TetherSettings.KEY_WIFI_TETHER);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTetherNonIndexableKeys_tetherNotAvailable_keysReturned() {
|
||||
// To let TetherUtil.isTetherAvailable return false, select one of the combinations
|
||||
setupIsTetherAvailable(false);
|
||||
|
||||
final List<String> niks =
|
||||
TetherSettings.SEARCH_INDEX_DATA_PROVIDER.getNonIndexableKeys(mContext);
|
||||
|
||||
assertThat(niks).contains(TetherSettings.KEY_TETHER_PREFS_SCREEN);
|
||||
assertThat(niks).contains(TetherSettings.KEY_WIFI_TETHER);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTetherNonIndexableKeys_usbNotAvailable_usbKeyReturned() {
|
||||
when(mConnectivityManager.getTetherableUsbRegexs()).thenReturn(new String[]{});
|
||||
|
||||
final List<String> niks =
|
||||
TetherSettings.SEARCH_INDEX_DATA_PROVIDER.getNonIndexableKeys(mContext);
|
||||
|
||||
assertThat(niks).contains(TetherSettings.KEY_USB_TETHER_SETTINGS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTetherNonIndexableKeys_usbAvailable_usbKeyNotReturned() {
|
||||
// We can ignore the condition of Utils.isMonkeyRunning()
|
||||
// In normal case, monkey and robotest should not execute at the same time
|
||||
when(mConnectivityManager.getTetherableUsbRegexs()).thenReturn(new String[]{"dummyRegex"});
|
||||
|
||||
final List<String> niks =
|
||||
TetherSettings.SEARCH_INDEX_DATA_PROVIDER.getNonIndexableKeys(mContext);
|
||||
|
||||
assertThat(niks).doesNotContain(TetherSettings.KEY_USB_TETHER_SETTINGS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTetherNonIndexableKeys_bluetoothNotAvailable_bluetoothKeyReturned() {
|
||||
when(mConnectivityManager.getTetherableBluetoothRegexs()).thenReturn(new String[]{});
|
||||
|
||||
final List<String> niks =
|
||||
TetherSettings.SEARCH_INDEX_DATA_PROVIDER.getNonIndexableKeys(mContext);
|
||||
|
||||
assertThat(niks).contains(TetherSettings.KEY_ENABLE_BLUETOOTH_TETHERING);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTetherNonIndexableKeys_bluetoothAvailable_bluetoothKeyNotReturned() {
|
||||
when(mConnectivityManager.getTetherableBluetoothRegexs())
|
||||
.thenReturn(new String[]{"dummyRegex"});
|
||||
|
||||
final List<String> niks =
|
||||
TetherSettings.SEARCH_INDEX_DATA_PROVIDER.getNonIndexableKeys(mContext);
|
||||
|
||||
assertThat(niks).doesNotContain(TetherSettings.KEY_ENABLE_BLUETOOTH_TETHERING);
|
||||
}
|
||||
|
||||
private void setupIsTetherAvailable(boolean returnValue) {
|
||||
when(mConnectivityManager.isTetheringSupported()).thenReturn(true);
|
||||
|
||||
// For RestrictedLockUtils.checkIfRestrictionEnforced
|
||||
final int userId = UserHandle.myUserId();
|
||||
List<UserManager.EnforcingUser> enforcingUsers = new ArrayList<>();
|
||||
when(mUserManager.getUserRestrictionSources(
|
||||
UserManager.DISALLOW_CONFIG_TETHERING, UserHandle.of(userId)))
|
||||
.thenReturn(enforcingUsers);
|
||||
|
||||
// For RestrictedLockUtils.hasBaseUserRestriction
|
||||
when(mUserManager.hasBaseUserRestriction(
|
||||
UserManager.DISALLOW_CONFIG_TETHERING, UserHandle.of(userId)))
|
||||
.thenReturn(!returnValue);
|
||||
}
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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.BluetoothDelayReportsPreferenceController
|
||||
.BLUETOOTH_DISABLE_AVDTP_DELAY_REPORTS_PROPERTY;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.SystemProperties;
|
||||
import androidx.preference.SwitchPreference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
public class BluetoothDelayReportsPreferenceControllerTest {
|
||||
|
||||
@Mock
|
||||
private PreferenceScreen mPreferenceScreen;
|
||||
|
||||
private Context mContext;
|
||||
private SwitchPreference mPreference;
|
||||
private BluetoothDelayReportsPreferenceController mController;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = RuntimeEnvironment.application;
|
||||
mPreference = new SwitchPreference(mContext);
|
||||
mController = spy(new BluetoothDelayReportsPreferenceController(mContext));
|
||||
when(mPreferenceScreen.findPreference(mController.getPreferenceKey()))
|
||||
.thenReturn(mPreference);
|
||||
mController.displayPreference(mPreferenceScreen);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPreferenceChanged_settingDisabled_turnOnDelayReports() {
|
||||
mController.onPreferenceChange(mPreference, true /* new value */);
|
||||
|
||||
final boolean mode = SystemProperties.getBoolean(
|
||||
BLUETOOTH_DISABLE_AVDTP_DELAY_REPORTS_PROPERTY, false /* default */);
|
||||
|
||||
assertThat(mode).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPreferenceChanged_settingDisabled_turnOffDelayReports() {
|
||||
mController.onPreferenceChange(mPreference, false /* new value */);
|
||||
|
||||
final boolean mode = SystemProperties.getBoolean(
|
||||
BLUETOOTH_DISABLE_AVDTP_DELAY_REPORTS_PROPERTY, false /* default */);
|
||||
|
||||
assertThat(mode).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_settingDisabled_preferenceShouldBeChecked() {
|
||||
SystemProperties.set(BLUETOOTH_DISABLE_AVDTP_DELAY_REPORTS_PROPERTY,
|
||||
Boolean.toString(true));
|
||||
mController.updateState(mPreference);
|
||||
|
||||
assertThat(mPreference.isChecked()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_settingDisabled_preferenceShouldNotBeChecked() {
|
||||
SystemProperties.set(BLUETOOTH_DISABLE_AVDTP_DELAY_REPORTS_PROPERTY,
|
||||
Boolean.toString(false));
|
||||
mController.updateState(mPreference);
|
||||
|
||||
assertThat(mPreference.isChecked()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onDeveloperOptionsDisabled_shouldDisablePreference() {
|
||||
mController.onDeveloperOptionsDisabled();
|
||||
|
||||
final boolean mode = SystemProperties.getBoolean(
|
||||
BLUETOOTH_DISABLE_AVDTP_DELAY_REPORTS_PROPERTY, false /* default */);
|
||||
|
||||
assertThat(mode).isFalse();
|
||||
assertThat(mPreference.isEnabled()).isFalse();
|
||||
assertThat(mPreference.isChecked()).isFalse();
|
||||
}
|
||||
}
|
||||
@@ -1,120 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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.BluetoothInbandRingingPreferenceController.BLUETOOTH_DISABLE_INBAND_RINGING_PROPERTY;
|
||||
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.os.SystemProperties;
|
||||
import androidx.preference.SwitchPreference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
public class BluetoothInbandRingingPreferenceControllerTest {
|
||||
|
||||
@Mock
|
||||
private SwitchPreference mPreference;
|
||||
@Mock
|
||||
private PreferenceScreen mPreferenceScreen;
|
||||
|
||||
private Context mContext;
|
||||
private BluetoothInbandRingingPreferenceController mController;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = RuntimeEnvironment.application;
|
||||
mController = spy(new BluetoothInbandRingingPreferenceController(mContext));
|
||||
doReturn(true).when(mController).isInbandRingingSupported();
|
||||
when(mPreferenceScreen.findPreference(mController.getPreferenceKey())).thenReturn(
|
||||
mPreference);
|
||||
mController.displayPreference(mPreferenceScreen);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isAvailable_inbandRingingNotSupported_shouldReturnFalse() {
|
||||
doReturn(false).when(mController).isInbandRingingSupported();
|
||||
assertThat(mController.isAvailable()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isAvailable_inbandRingingSupported_shouldReturnTrue() {
|
||||
assertThat(mController.isAvailable()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPreferenceChanged_settingEnabled_turnOnBluetoothSnoopLog() {
|
||||
mController.onPreferenceChange(mPreference, true /* new value */);
|
||||
|
||||
final boolean mode = SystemProperties
|
||||
.getBoolean(BLUETOOTH_DISABLE_INBAND_RINGING_PROPERTY, false /* default */);
|
||||
|
||||
assertThat(mode).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPreferenceChanged_settingDisabled_turnOffBluetoothSnoopLog() {
|
||||
mController.onPreferenceChange(mPreference, false /* new value */);
|
||||
|
||||
final boolean mode = SystemProperties
|
||||
.getBoolean(BLUETOOTH_DISABLE_INBAND_RINGING_PROPERTY, false /* default */);
|
||||
|
||||
assertThat(mode).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_settingEnabled_preferenceShouldBeChecked() {
|
||||
SystemProperties.set(BLUETOOTH_DISABLE_INBAND_RINGING_PROPERTY, Boolean.toString(true));
|
||||
mController.updateState(mPreference);
|
||||
|
||||
verify(mPreference).setChecked(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_settingDisabled_preferenceShouldNotBeChecked() {
|
||||
SystemProperties.set(BLUETOOTH_DISABLE_INBAND_RINGING_PROPERTY, Boolean.toString(false));
|
||||
mController.updateState(mPreference);
|
||||
|
||||
verify(mPreference).setChecked(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onDeveloperOptionsDisabled_shouldDisablePreference() {
|
||||
mController.onDeveloperOptionsDisabled();
|
||||
|
||||
final boolean mode = SystemProperties
|
||||
.getBoolean(BLUETOOTH_DISABLE_INBAND_RINGING_PROPERTY, false /* default */);
|
||||
|
||||
assertThat(mode).isFalse();
|
||||
verify(mPreference).setEnabled(false);
|
||||
verify(mPreference).setChecked(false);
|
||||
}
|
||||
}
|
||||
@@ -131,7 +131,6 @@ public class DevelopmentSettingsDashboardFragmentTest {
|
||||
@Config(shadows = {
|
||||
ShadowPictureColorModePreferenceController.class,
|
||||
ShadowAdbPreferenceController.class,
|
||||
ShadowBluetoothInbandRingingPreferenceController.class,
|
||||
ShadowClearAdbKeysPreferenceController.class
|
||||
})
|
||||
public void searchIndex_pageEnabled_shouldNotAddKeysToNonIndexable() {
|
||||
@@ -282,15 +281,6 @@ public class DevelopmentSettingsDashboardFragmentTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Implements(BluetoothInbandRingingPreferenceController.class)
|
||||
public static class ShadowBluetoothInbandRingingPreferenceController {
|
||||
|
||||
@Implementation
|
||||
public boolean isAvailable() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@Implements(ClearAdbKeysPreferenceController.class)
|
||||
public static class ShadowClearAdbKeysPreferenceController {
|
||||
|
||||
|
||||
@@ -15,40 +15,44 @@
|
||||
*/
|
||||
package com.android.settings.deviceinfo;
|
||||
|
||||
import static com.android.settings.deviceinfo.DeviceModelPreferenceController.getDeviceModel;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.Fragment;
|
||||
import android.app.FragmentManager;
|
||||
import android.app.FragmentTransaction;
|
||||
import android.content.Context;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
import android.os.Build;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Answers;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceManager;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
public class DeviceModelPreferenceControllerTest {
|
||||
|
||||
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||
private Fragment mFragment;
|
||||
@Mock
|
||||
private Preference mPreference;
|
||||
@Mock
|
||||
private PreferenceScreen mPreferenceScreen;
|
||||
private final String KEY = "device_model_key";
|
||||
|
||||
@Mock
|
||||
private Fragment mFragment;
|
||||
private Preference mPreference;
|
||||
private PreferenceScreen mPreferenceScreen;
|
||||
private Context mContext;
|
||||
private DeviceModelPreferenceController mController;
|
||||
|
||||
@@ -56,35 +60,49 @@ public class DeviceModelPreferenceControllerTest {
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = RuntimeEnvironment.application;
|
||||
mController = new DeviceModelPreferenceController(mContext, mFragment);
|
||||
when(mPreferenceScreen.findPreference(mController.getPreferenceKey()))
|
||||
.thenReturn(mPreference);
|
||||
when(mPreference.getKey()).thenReturn(mController.getPreferenceKey());
|
||||
mController = new DeviceModelPreferenceController(mContext, KEY);
|
||||
mController.setHost(mFragment);
|
||||
mPreference = new Preference(mContext);
|
||||
mPreference.setKey(KEY);
|
||||
final PreferenceManager preferenceManager = new PreferenceManager(mContext);
|
||||
mPreferenceScreen = preferenceManager.createPreferenceScreen(mContext);
|
||||
mPreferenceScreen.addPreference(mPreference);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isAvailable_returnTrueIfVisible() {
|
||||
assertThat(mController.isAvailable()).isTrue();
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(
|
||||
BasePreferenceController.AVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(qualifiers = "mcc999")
|
||||
public void isAvailable_returnFalseIfNotVisible() {
|
||||
assertThat(mController.isAvailable()).isFalse();
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(
|
||||
BasePreferenceController.UNSUPPORTED_ON_DEVICE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void displayPref_shouldSetSummary() {
|
||||
mController.displayPreference(mPreferenceScreen);
|
||||
public void updatePreference_summaryShouldContainBuildModel() {
|
||||
mController.updateState(mPreference);
|
||||
|
||||
verify(mPreference).setSummary(mContext.getString(R.string.model_summary, getDeviceModel()));
|
||||
assertThat(containBuildModel(mPreference.getSummary())).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void clickPreference_shouldLaunchHardwareInfoDialog() {
|
||||
FragmentManager fragmentManager = mock(FragmentManager.class);
|
||||
when(mFragment.getFragmentManager()).thenReturn(fragmentManager);
|
||||
when(fragmentManager.beginTransaction()).thenReturn(mock(FragmentTransaction.class));
|
||||
|
||||
assertThat(mController.handlePreferenceTreeClick(mPreference)).isTrue();
|
||||
verify(mFragment).getFragmentManager();
|
||||
verify(mFragment.getFragmentManager().beginTransaction())
|
||||
verify(fragmentManager.beginTransaction())
|
||||
.add(any(HardwareInfoDialogFragment.class), eq(HardwareInfoDialogFragment.TAG));
|
||||
}
|
||||
|
||||
private boolean containBuildModel(CharSequence result) {
|
||||
final String oracle = mContext.getResources().getString(R.string.model_summary,
|
||||
Build.MODEL);
|
||||
return result.toString().contains(oracle);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,10 @@ import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Fragment;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.provider.Settings;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
@@ -150,4 +153,36 @@ public class PrivateDnsModeDialogPreferenceTest {
|
||||
assertThat(mSaveButton.isEnabled()).named("provider: " + invalid).isFalse();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnClick_positiveButtonClicked_saveData() {
|
||||
// Set the default settings to OFF
|
||||
final ContentResolver contentResolver = mContext.getContentResolver();
|
||||
Settings.Global.putString(contentResolver, Settings.Global.PRIVATE_DNS_MODE,
|
||||
ConnectivityManager.PRIVATE_DNS_MODE_OFF);
|
||||
|
||||
mPreference.mMode = ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC;
|
||||
mPreference.onClick(null, DialogInterface.BUTTON_POSITIVE);
|
||||
|
||||
// Change to OPPORTUNISTIC
|
||||
assertThat(Settings.Global.getString(contentResolver,
|
||||
Settings.Global.PRIVATE_DNS_MODE)).isEqualTo(
|
||||
ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnClick_negativeButtonClicked_doNothing() {
|
||||
// Set the default settings to OFF
|
||||
final ContentResolver contentResolver = mContext.getContentResolver();
|
||||
Settings.Global.putString(contentResolver, Settings.Global.PRIVATE_DNS_MODE,
|
||||
ConnectivityManager.PRIVATE_DNS_MODE_OFF);
|
||||
|
||||
mPreference.mMode = ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC;
|
||||
mPreference.onClick(null, DialogInterface.BUTTON_NEGATIVE);
|
||||
|
||||
// Still equal to OFF
|
||||
assertThat(Settings.Global.getString(contentResolver,
|
||||
Settings.Global.PRIVATE_DNS_MODE)).isEqualTo(
|
||||
ConnectivityManager.PRIVATE_DNS_MODE_OFF);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,13 +134,13 @@ public class ZenModeSettingsTest {
|
||||
public void testGetCallsSettingSummary_contacts() {
|
||||
Policy policy = new Policy(Policy.PRIORITY_CATEGORY_ALARMS | Policy.PRIORITY_CATEGORY_CALLS,
|
||||
Policy.PRIORITY_SENDERS_CONTACTS, 0, 0);
|
||||
assertThat(mBuilder.getCallsSettingSummary(policy)).isEqualTo("From contacts only");
|
||||
assertThat(mBuilder.getCallsSettingSummary(policy)).isEqualTo("From contacts");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetCallsSettingSummary_repeatCallers() {
|
||||
Policy policy = new Policy(Policy.PRIORITY_CATEGORY_REPEAT_CALLERS, 0, 0, 0);
|
||||
assertThat(mBuilder.getCallsSettingSummary(policy)).isEqualTo("From repeat callers only");
|
||||
assertThat(mBuilder.getCallsSettingSummary(policy)).isEqualTo("From repeat callers");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -88,23 +88,14 @@ public class ZenModeVisEffectsCustomPreferenceControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isAvailable_menuOff_noVisEffects() {
|
||||
public void isAvailable_noVisEffects() {
|
||||
mBackend.mPolicy = new NotificationManager.Policy(0, 0, 0, 0);
|
||||
mController.mShowMenuSelected = false;
|
||||
assertThat(mController.isAvailable()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isAvailable_menuOn_noVisEffects() {
|
||||
mBackend.mPolicy = new NotificationManager.Policy(0, 0, 0, 0);
|
||||
mController.mShowMenuSelected = true;
|
||||
assertThat(mController.isAvailable()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isAvailable_menuOn_visEffects() {
|
||||
public void isAvailable_visEffects() {
|
||||
mBackend.mPolicy = new NotificationManager.Policy(0, 0, 0, 1);
|
||||
mController.mShowMenuSelected = false;
|
||||
assertThat(mController.isAvailable()).isTrue();
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,11 @@ import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_OF
|
||||
import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_ON;
|
||||
import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_STATUS_BAR;
|
||||
|
||||
import static com.android.settings.notification.ZenOnboardingActivity.ALWAYS_SHOW_THRESHOLD;
|
||||
import static com.android.settings.notification.ZenOnboardingActivity
|
||||
.PREF_KEY_SUGGESTION_FIRST_DISPLAY_TIME;
|
||||
import static com.android.settings.notification.ZenOnboardingActivity.isSuggestionComplete;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
@@ -39,20 +44,22 @@ import static org.mockito.Mockito.when;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.NotificationManager.Policy;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.provider.Settings;
|
||||
|
||||
import com.android.internal.logging.MetricsLogger;
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.testutils.FakeFeatureFactory;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Answers;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.Robolectric;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
public class ZenOnboardingActivityTest {
|
||||
@@ -64,6 +71,9 @@ public class ZenOnboardingActivityTest {
|
||||
|
||||
ZenOnboardingActivity mActivity;
|
||||
|
||||
private Context mContext;
|
||||
private FakeFeatureFactory mFeatureFactory;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
@@ -75,6 +85,11 @@ public class ZenOnboardingActivityTest {
|
||||
mActivity.setMetricsLogger(mMetricsLogger);
|
||||
|
||||
mActivity.setupUI();
|
||||
|
||||
mContext = RuntimeEnvironment.application;
|
||||
mFeatureFactory = FakeFeatureFactory.setupForTest();
|
||||
when(mFeatureFactory.suggestionsFeatureProvider.getSharedPrefs(any(Context.class)))
|
||||
.thenReturn(getSharedPreferences());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -124,4 +139,73 @@ public class ZenOnboardingActivityTest {
|
||||
|
||||
verify(mNm, never()).setNotificationPolicy(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isSuggestionComplete_zenUpdated() {
|
||||
setZenUpdated(true);
|
||||
setShowSettingsSuggestion(false);
|
||||
setWithinTimeThreshold(true);
|
||||
assertThat(isSuggestionComplete(mContext)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isSuggestionComplete_withinTimeThreshold() {
|
||||
setZenUpdated(false);
|
||||
setShowSettingsSuggestion(false);
|
||||
setWithinTimeThreshold(true);
|
||||
assertThat(isSuggestionComplete(mContext)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isSuggestionComplete_showSettingsSuggestionTrue() {
|
||||
setZenUpdated(false);
|
||||
setShowSettingsSuggestion(true);
|
||||
setWithinTimeThreshold(false);
|
||||
assertThat(isSuggestionComplete(mContext)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isSuggestionComplete_showSettingsSuggestionFalse_notWithinTimeThreshold() {
|
||||
setZenUpdated(false);
|
||||
setShowSettingsSuggestion(false);
|
||||
setWithinTimeThreshold(false);
|
||||
assertThat(isSuggestionComplete(mContext)).isTrue();
|
||||
}
|
||||
|
||||
private void setZenUpdated(boolean updated) {
|
||||
int zenUpdated = 0;
|
||||
if (updated) {
|
||||
zenUpdated = 1;
|
||||
}
|
||||
|
||||
Settings.Global.putInt(mContext.getContentResolver(),
|
||||
Settings.Global.ZEN_SETTINGS_UPDATED, zenUpdated);
|
||||
}
|
||||
|
||||
private void setWithinTimeThreshold(boolean withinTime) {
|
||||
long firstTime = System.currentTimeMillis();
|
||||
|
||||
if (withinTime) {
|
||||
firstTime -= ALWAYS_SHOW_THRESHOLD / 2;
|
||||
} else {
|
||||
firstTime -= ALWAYS_SHOW_THRESHOLD * 2;
|
||||
}
|
||||
|
||||
getSharedPreferences().edit().putLong(PREF_KEY_SUGGESTION_FIRST_DISPLAY_TIME,
|
||||
firstTime).commit();
|
||||
}
|
||||
|
||||
private void setShowSettingsSuggestion(boolean show) {
|
||||
int showZenSuggestion = 0;
|
||||
if (show) {
|
||||
showZenSuggestion = 1;
|
||||
}
|
||||
|
||||
Settings.Global.putInt(mContext.getContentResolver(),
|
||||
Settings.Global.SHOW_ZEN_SETTINGS_SUGGESTION, showZenSuggestion);
|
||||
}
|
||||
|
||||
private SharedPreferences getSharedPreferences() {
|
||||
return mContext.getSharedPreferences("test_zen_sugg", Context.MODE_PRIVATE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,7 +67,6 @@ public class ChooseLockPasswordTest {
|
||||
Intent intent = new IntentBuilder(application)
|
||||
.setPassword("password")
|
||||
.setPasswordQuality(DevicePolicyManager.PASSWORD_QUALITY_NUMERIC)
|
||||
.setPasswordLengthRange(123, 456)
|
||||
.setUserId(123)
|
||||
.build();
|
||||
|
||||
@@ -77,12 +76,6 @@ public class ChooseLockPasswordTest {
|
||||
assertThat(intent.getStringExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD))
|
||||
.named("EXTRA_KEY_PASSWORD")
|
||||
.isEqualTo("password");
|
||||
assertThat(intent.getIntExtra(ChooseLockPassword.PASSWORD_MIN_KEY, 0))
|
||||
.named("PASSWORD_MIN_KEY")
|
||||
.isEqualTo(123);
|
||||
assertThat(intent.getIntExtra(ChooseLockPassword.PASSWORD_MAX_KEY, 0))
|
||||
.named("PASSWORD_MAX_KEY")
|
||||
.isEqualTo(456);
|
||||
assertThat(intent.getIntExtra(LockPatternUtils.PASSWORD_TYPE_KEY, 0))
|
||||
.named("PASSWORD_TYPE_KEY")
|
||||
.isEqualTo(DevicePolicyManager.PASSWORD_QUALITY_NUMERIC);
|
||||
@@ -96,7 +89,6 @@ public class ChooseLockPasswordTest {
|
||||
Intent intent = new IntentBuilder(application)
|
||||
.setChallenge(12345L)
|
||||
.setPasswordQuality(DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC)
|
||||
.setPasswordLengthRange(123, 456)
|
||||
.setUserId(123)
|
||||
.build();
|
||||
|
||||
@@ -106,12 +98,6 @@ public class ChooseLockPasswordTest {
|
||||
assertThat(intent.getLongExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, 0L))
|
||||
.named("EXTRA_KEY_CHALLENGE")
|
||||
.isEqualTo(12345L);
|
||||
assertThat(intent.getIntExtra(ChooseLockPassword.PASSWORD_MIN_KEY, 0))
|
||||
.named("PASSWORD_MIN_KEY")
|
||||
.isEqualTo(123);
|
||||
assertThat(intent.getIntExtra(ChooseLockPassword.PASSWORD_MAX_KEY, 0))
|
||||
.named("PASSWORD_MAX_KEY")
|
||||
.isEqualTo(456);
|
||||
assertThat(intent.getIntExtra(LockPatternUtils.PASSWORD_TYPE_KEY, 0))
|
||||
.named("PASSWORD_TYPE_KEY")
|
||||
.isEqualTo(DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC);
|
||||
|
||||
@@ -30,6 +30,8 @@ import com.android.settings.R;
|
||||
import com.android.settings.Settings;
|
||||
import com.android.settings.fingerprint.FingerprintEnrollSuggestionActivity;
|
||||
import com.android.settings.fingerprint.FingerprintSuggestionActivity;
|
||||
import com.android.settings.notification.ZenOnboardingActivity;
|
||||
import com.android.settings.notification.ZenSuggestionActivity;
|
||||
import com.android.settings.support.NewDeviceIntroSuggestionActivity;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
import com.android.settings.wallpaper.WallpaperSuggestionActivity;
|
||||
@@ -82,6 +84,14 @@ public class SettingsSuggestionsTest {
|
||||
R.string.night_display_suggestion_summary);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void zenSuggestion_isValid() {
|
||||
assertSuggestionEquals(
|
||||
ZenSuggestionActivity.class.getName(),
|
||||
R.string.zen_suggestion_title,
|
||||
R.string.zen_suggestion_summary);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void newDeviceIntroSuggestion_isValid() {
|
||||
assertSuggestionEquals(
|
||||
|
||||
@@ -78,7 +78,7 @@ public class NewDeviceIntroSuggestionActivityTest {
|
||||
final long currentTime = System.currentTimeMillis();
|
||||
|
||||
getSharedPreferences().edit().putLong(PREF_KEY_SUGGGESTION_FIRST_DISPLAY_TIME,
|
||||
currentTime - 2 * PERMANENT_DISMISS_THRESHOLD);
|
||||
currentTime - 2 * PERMANENT_DISMISS_THRESHOLD).commit();
|
||||
assertThat(isSuggestionComplete(mContext)).isTrue();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,316 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.wifi.calling;
|
||||
|
||||
import static android.app.slice.Slice.EXTRA_TOGGLE_STATE;
|
||||
import static android.app.slice.Slice.HINT_TITLE;
|
||||
import static android.app.slice.SliceItem.FORMAT_TEXT;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
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.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Resources;
|
||||
import android.net.Uri;
|
||||
import android.telephony.CarrierConfigManager;
|
||||
|
||||
import androidx.slice.Slice;
|
||||
import androidx.slice.SliceItem;
|
||||
import androidx.slice.SliceMetadata;
|
||||
import androidx.slice.SliceProvider;
|
||||
import androidx.slice.core.SliceAction;
|
||||
import androidx.slice.core.SliceQuery;
|
||||
import androidx.slice.widget.SliceLiveData;
|
||||
|
||||
import com.android.ims.ImsManager;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.slices.SettingsSliceProvider;
|
||||
import com.android.settings.slices.SliceBroadcastReceiver;
|
||||
import com.android.settings.slices.SliceBuilderUtils;
|
||||
import com.android.settings.slices.SliceData;
|
||||
import com.android.settings.slices.SlicesFeatureProvider;
|
||||
import com.android.settings.testutils.FakeFeatureFactory;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
public class WifiCallingSliceHelperTest {
|
||||
|
||||
private Context mContext;
|
||||
@Mock
|
||||
private CarrierConfigManager mMockCarrierConfigManager;
|
||||
|
||||
@Mock
|
||||
private ImsManager mMockImsManager;
|
||||
|
||||
private final Uri mWfcURI = Uri.parse("content://com.android.settings.slices/wifi_calling");
|
||||
|
||||
private FakeWifiCallingSliceHelper mWfcSliceHelper;
|
||||
private SettingsSliceProvider mProvider;
|
||||
private SliceBroadcastReceiver mReceiver;
|
||||
private FakeFeatureFactory mFeatureFactory;
|
||||
private SlicesFeatureProvider mSlicesFeatureProvider;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = spy(RuntimeEnvironment.application);
|
||||
|
||||
//setup for SettingsSliceProvider tests
|
||||
mProvider = spy(new SettingsSliceProvider());
|
||||
doReturn(mContext).when(mProvider).getContext();
|
||||
|
||||
//setup for SliceBroadcastReceiver test
|
||||
mReceiver = spy(new SliceBroadcastReceiver());
|
||||
|
||||
mFeatureFactory = FakeFeatureFactory.setupForTest();
|
||||
mSlicesFeatureProvider = mFeatureFactory.getSlicesFeatureProvider();
|
||||
|
||||
// Prevent crash in SliceMetadata.
|
||||
Resources resources = spy(mContext.getResources());
|
||||
doReturn(60).when(resources).getDimensionPixelSize(anyInt());
|
||||
doReturn(resources).when(mContext).getResources();
|
||||
|
||||
mWfcSliceHelper = new FakeWifiCallingSliceHelper(mContext);
|
||||
|
||||
// Set-up specs for SliceMetadata.
|
||||
SliceProvider.setSpecs(SliceLiveData.SUPPORTED_SPECS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_CreateWifiCallingSlice_invalidSubId() {
|
||||
mWfcSliceHelper.setDefaultVoiceSubId(-1);
|
||||
|
||||
final Slice slice = mWfcSliceHelper.createWifiCallingSlice(mWfcURI);
|
||||
|
||||
testWifiCallingSettingsUnavailableSlice(slice, null,
|
||||
SliceBuilderUtils.getSettingsIntent(mContext));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_CreateWifiCallingSlice_wfcNotSupported() {
|
||||
doReturn(false).when(mMockImsManager).isWfcEnabledByPlatform();
|
||||
|
||||
final Slice slice = mWfcSliceHelper.createWifiCallingSlice(mWfcURI);
|
||||
|
||||
assertThat(mWfcSliceHelper.getDefaultVoiceSubId()).isEqualTo(1);
|
||||
testWifiCallingSettingsUnavailableSlice(slice, null,
|
||||
SliceBuilderUtils.getSettingsIntent(mContext));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_CreateWifiCallingSlice_needsActivation() {
|
||||
/* In cases where activation is needed and the user action
|
||||
would be turning on the wifi calling (i.e. if wifi calling is
|
||||
turned off) we need to guide the user to wifi calling settings
|
||||
activity so the user can perform the activation there.(PrimaryAction)
|
||||
*/
|
||||
doReturn(true).when(mMockImsManager).isWfcEnabledByPlatform();
|
||||
doReturn(true).when(mMockImsManager).isWfcProvisionedOnDevice();
|
||||
doReturn(false).when(mMockImsManager).isWfcEnabledByUser();
|
||||
doReturn(false).when(mMockImsManager).isNonTtyOrTtyOnVolteEnabled();
|
||||
doReturn(null).when(mMockCarrierConfigManager).getConfigForSubId(1);
|
||||
mWfcSliceHelper.setActivationAppIntent(new Intent()); // dummy Intent
|
||||
|
||||
final Slice slice = mWfcSliceHelper.createWifiCallingSlice(mWfcURI);
|
||||
|
||||
assertThat(mWfcSliceHelper.getDefaultVoiceSubId()).isEqualTo(1);
|
||||
testWifiCallingSettingsUnavailableSlice(slice, null,
|
||||
getActivityIntent(WifiCallingSliceHelper.ACTION_WIFI_CALLING_SETTINGS_ACTIVITY));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_CreateWifiCallingSlice_success() {
|
||||
doReturn(true).when(mMockImsManager).isWfcEnabledByPlatform();
|
||||
doReturn(true).when(mMockImsManager).isWfcProvisionedOnDevice();
|
||||
doReturn(true).when(mMockImsManager).isWfcEnabledByUser();
|
||||
doReturn(true).when(mMockImsManager).isNonTtyOrTtyOnVolteEnabled();
|
||||
doReturn(null).when(mMockCarrierConfigManager).getConfigForSubId(1);
|
||||
|
||||
final Slice slice = mWfcSliceHelper.createWifiCallingSlice(mWfcURI);
|
||||
|
||||
assertThat(mWfcSliceHelper.getDefaultVoiceSubId()).isEqualTo(1);
|
||||
testWifiCallingSettingsToggleSlice(slice, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_SettingSliceProvider_getsRightSliceWifiCalling() {
|
||||
doReturn(true).when(mMockImsManager).isWfcEnabledByPlatform();
|
||||
doReturn(true).when(mMockImsManager).isWfcProvisionedOnDevice();
|
||||
doReturn(true).when(mMockImsManager).isWfcEnabledByUser();
|
||||
doReturn(true).when(mMockImsManager).isNonTtyOrTtyOnVolteEnabled();
|
||||
doReturn(null).when(mMockCarrierConfigManager).getConfigForSubId(1);
|
||||
doReturn(mWfcSliceHelper).when(mSlicesFeatureProvider)
|
||||
.getNewWifiCallingSliceHelper(mContext);
|
||||
|
||||
final Slice slice = mProvider.onBindSlice(mWfcURI);
|
||||
|
||||
assertThat(mWfcSliceHelper.getDefaultVoiceSubId()).isEqualTo(1);
|
||||
testWifiCallingSettingsToggleSlice(slice, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_SliceBroadcastReceiver_toggleOffWifiCalling() {
|
||||
doReturn(true).when(mMockImsManager).isWfcEnabledByPlatform();
|
||||
doReturn(true).when(mMockImsManager).isWfcProvisionedOnDevice();
|
||||
doReturn(false).when(mMockImsManager).isWfcEnabledByUser();
|
||||
doReturn(true).when(mMockImsManager).isNonTtyOrTtyOnVolteEnabled();
|
||||
doReturn(mWfcSliceHelper).when(mSlicesFeatureProvider)
|
||||
.getNewWifiCallingSliceHelper(mContext);
|
||||
mWfcSliceHelper.setActivationAppIntent(null);
|
||||
|
||||
ArgumentCaptor<Boolean> mWfcSettingCaptor = ArgumentCaptor.forClass(Boolean.class);
|
||||
|
||||
// turn on Wifi calling setting
|
||||
Intent intent = new Intent(WifiCallingSliceHelper.ACTION_WIFI_CALLING_CHANGED);
|
||||
intent.putExtra(EXTRA_TOGGLE_STATE, true);
|
||||
|
||||
// change the setting
|
||||
mReceiver.onReceive(mContext, intent);
|
||||
|
||||
verify((mMockImsManager)).setWfcSetting(mWfcSettingCaptor.capture());
|
||||
|
||||
// assert the change
|
||||
assertThat(mWfcSettingCaptor.getValue()).isTrue();
|
||||
}
|
||||
|
||||
private void testWifiCallingSettingsUnavailableSlice(Slice slice,
|
||||
SliceData sliceData, PendingIntent expectedPrimaryAction) {
|
||||
final SliceMetadata metadata = SliceMetadata.from(mContext, slice);
|
||||
|
||||
//Check there is no toggle action
|
||||
final List<SliceAction> toggles = metadata.getToggles();
|
||||
assertThat(toggles).isEmpty();
|
||||
|
||||
// Check whether the primary action is to open wifi calling settings activity
|
||||
final PendingIntent primaryPendingIntent =
|
||||
metadata.getPrimaryAction().getAction();
|
||||
assertThat(primaryPendingIntent).isEqualTo(expectedPrimaryAction);
|
||||
|
||||
// Check the title
|
||||
final List<SliceItem> sliceItems = slice.getItems();
|
||||
assertTitle(sliceItems, mContext.getString(R.string.wifi_calling_settings_title));
|
||||
}
|
||||
|
||||
private void testWifiCallingSettingsToggleSlice(Slice slice,
|
||||
SliceData sliceData) {
|
||||
final SliceMetadata metadata = SliceMetadata.from(mContext, slice);
|
||||
|
||||
final List<SliceAction> toggles = metadata.getToggles();
|
||||
assertThat(toggles).hasSize(1);
|
||||
|
||||
final SliceAction mainToggleAction = toggles.get(0);
|
||||
|
||||
// Check intent in Toggle Action
|
||||
final PendingIntent togglePendingIntent = mainToggleAction.getAction();
|
||||
final PendingIntent expectedToggleIntent = getBroadcastIntent(
|
||||
WifiCallingSliceHelper.ACTION_WIFI_CALLING_CHANGED);
|
||||
assertThat(togglePendingIntent).isEqualTo(expectedToggleIntent);
|
||||
|
||||
// Check primary intent
|
||||
final PendingIntent primaryPendingIntent = metadata.getPrimaryAction().getAction();
|
||||
final PendingIntent expectedPendingIntent =
|
||||
getActivityIntent(WifiCallingSliceHelper.ACTION_WIFI_CALLING_SETTINGS_ACTIVITY);
|
||||
assertThat(primaryPendingIntent).isEqualTo(expectedPendingIntent);
|
||||
|
||||
// Check the title
|
||||
final List<SliceItem> sliceItems = slice.getItems();
|
||||
assertTitle(sliceItems, mContext.getString(R.string.wifi_calling_settings_title));
|
||||
}
|
||||
|
||||
private PendingIntent getBroadcastIntent(String action) {
|
||||
final Intent intent = new Intent(action);
|
||||
intent.setClass(mContext, SliceBroadcastReceiver.class);
|
||||
return PendingIntent.getBroadcast(mContext, 0 /* requestCode */, intent,
|
||||
PendingIntent.FLAG_CANCEL_CURRENT);
|
||||
}
|
||||
|
||||
private PendingIntent getActivityIntent(String action) {
|
||||
final Intent intent = new Intent(action);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
return PendingIntent.getActivity(mContext, 0 /* requestCode */, intent, 0 /* flags */);
|
||||
}
|
||||
|
||||
private void assertTitle(List<SliceItem> sliceItems, String title) {
|
||||
boolean hasTitle = false;
|
||||
for (SliceItem item : sliceItems) {
|
||||
List<SliceItem> titleItems = SliceQuery.findAll(item, FORMAT_TEXT, HINT_TITLE,
|
||||
null /* non-hints */);
|
||||
if (titleItems == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
hasTitle = true;
|
||||
for (SliceItem subTitleItem : titleItems) {
|
||||
assertThat(subTitleItem.getText()).isEqualTo(title);
|
||||
}
|
||||
}
|
||||
assertThat(hasTitle).isTrue();
|
||||
}
|
||||
private class FakeWifiCallingSliceHelper extends WifiCallingSliceHelper {
|
||||
int mSubId = 1;
|
||||
|
||||
private Intent mActivationAppIntent;
|
||||
FakeWifiCallingSliceHelper(Context context) {
|
||||
super(context);
|
||||
mActivationAppIntent = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CarrierConfigManager getCarrierConfigManager(Context mContext) {
|
||||
return mMockCarrierConfigManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ImsManager getImsManager(int subId) {
|
||||
return mMockImsManager;
|
||||
}
|
||||
|
||||
protected int getDefaultVoiceSubId() {
|
||||
return mSubId;
|
||||
}
|
||||
|
||||
protected void setDefaultVoiceSubId(int id) {
|
||||
mSubId = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Intent getWifiCallingCarrierActivityIntent(int subId) {
|
||||
return mActivationAppIntent;
|
||||
}
|
||||
|
||||
public void setActivationAppIntent(Intent intent) {
|
||||
mActivationAppIntent = intent;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.wifi.tether;
|
||||
|
||||
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.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.net.ConnectivityManager;
|
||||
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
public class WifiTetherSettingsTest {
|
||||
|
||||
private Context mContext;
|
||||
|
||||
@Mock
|
||||
private ConnectivityManager mConnectivityManager;
|
||||
@Mock
|
||||
private UserManager mUserManager;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mContext = spy(RuntimeEnvironment.application);
|
||||
|
||||
MockitoAnnotations.initMocks(this);
|
||||
doReturn(mConnectivityManager)
|
||||
.when(mContext).getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
doReturn(mUserManager)
|
||||
.when(mContext).getSystemService(Context.USER_SERVICE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWifiTetherNonIndexableKeys_tetherAvailable_keysNotReturned() {
|
||||
// To let TetherUtil.isTetherAvailable return true, select one of the combinations
|
||||
setupIsTetherAvailable(true);
|
||||
|
||||
final List<String> niks =
|
||||
WifiTetherSettings.SEARCH_INDEX_DATA_PROVIDER.getNonIndexableKeys(mContext);
|
||||
|
||||
assertThat(niks).doesNotContain(WifiTetherSettings.KEY_WIFI_TETHER_NETWORK_NAME);
|
||||
assertThat(niks).doesNotContain(WifiTetherSettings.KEY_WIFI_TETHER_NETWORK_PASSWORD);
|
||||
assertThat(niks).doesNotContain(WifiTetherSettings.KEY_WIFI_TETHER_AUTO_OFF);
|
||||
assertThat(niks).doesNotContain(WifiTetherSettings.KEY_WIFI_TETHER_NETWORK_AP_BAND);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWifiTetherNonIndexableKeys_tetherNotAvailable_keysReturned() {
|
||||
// To let TetherUtil.isTetherAvailable return false, select one of the combinations
|
||||
setupIsTetherAvailable(false);
|
||||
|
||||
final List<String> niks =
|
||||
WifiTetherSettings.SEARCH_INDEX_DATA_PROVIDER.getNonIndexableKeys(mContext);
|
||||
|
||||
assertThat(niks).contains(WifiTetherSettings.KEY_WIFI_TETHER_NETWORK_NAME);
|
||||
assertThat(niks).contains(WifiTetherSettings.KEY_WIFI_TETHER_NETWORK_PASSWORD);
|
||||
assertThat(niks).contains(WifiTetherSettings.KEY_WIFI_TETHER_AUTO_OFF);
|
||||
assertThat(niks).contains(WifiTetherSettings.KEY_WIFI_TETHER_NETWORK_AP_BAND);
|
||||
}
|
||||
|
||||
private void setupIsTetherAvailable(boolean returnValue) {
|
||||
when(mConnectivityManager.isTetheringSupported()).thenReturn(true);
|
||||
|
||||
// For RestrictedLockUtils.checkIfRestrictionEnforced
|
||||
final int userId = UserHandle.myUserId();
|
||||
List<UserManager.EnforcingUser> enforcingUsers = new ArrayList<>();
|
||||
when(mUserManager.getUserRestrictionSources(
|
||||
UserManager.DISALLOW_CONFIG_TETHERING, UserHandle.of(userId)))
|
||||
.thenReturn(enforcingUsers);
|
||||
|
||||
// For RestrictedLockUtils.hasBaseUserRestriction
|
||||
when(mUserManager.hasBaseUserRestriction(
|
||||
UserManager.DISALLOW_CONFIG_TETHERING, UserHandle.of(userId)))
|
||||
.thenReturn(!returnValue);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user