Snap for 4781697 from 8e060b42dd to qt-release

Change-Id: I42516df05f6a0e4b1f152bd44dc1e142200de816
This commit is contained in:
android-build-team Robot
2018-05-15 09:34:22 +00:00
52 changed files with 1536 additions and 687 deletions

View File

@@ -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"

View File

@@ -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>

View File

@@ -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">Dont 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>

View File

@@ -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"

View File

@@ -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

View File

@@ -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

View File

@@ -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>

View File

@@ -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"

View File

@@ -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>

View File

@@ -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/>

View File

@@ -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 />

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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");
}
}

View File

@@ -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);
}
}

View File

@@ -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));

View File

@@ -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));

View File

@@ -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;
}
}

View File

@@ -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));

View File

@@ -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

View File

@@ -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

View File

@@ -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);

View File

@@ -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<>();

View File

@@ -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());

View File

@@ -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);

View File

@@ -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;
}
}

View File

@@ -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();
}
}

View File

@@ -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();
}

View File

@@ -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) {

View File

@@ -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;
}

View File

@@ -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) {

View File

@@ -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);

View File

@@ -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;
}
}

View File

@@ -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);
}

View File

@@ -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);
}
}

View File

@@ -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();
}
}

View File

@@ -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

View File

@@ -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

View 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);
}
}

View File

@@ -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();
}
}

View File

@@ -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);
}
}

View File

@@ -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 {

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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

View File

@@ -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();
}

View File

@@ -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);
}
}

View File

@@ -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);

View File

@@ -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(

View File

@@ -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();
}

View File

@@ -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;
}
}
}

View File

@@ -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);
}
}