Snap for 5434517 from 14b8b27f1c to qt-release

Change-Id: If62175109f62fb725561703a61c74ee2d4440e00
This commit is contained in:
android-build-team Robot
2019-04-04 03:04:50 +00:00
75 changed files with 921 additions and 450 deletions

View File

@@ -1032,7 +1032,8 @@
<activity
android:name=".slices.SliceDeepLinkSpringBoard"
android:excludeFromRecents="true"
android:theme="@android:style/Theme.NoDisplay">
android:theme="@android:style/Theme.NoDisplay"
android:permission="android.permission.MODIFY_PHONE_STATE">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
@@ -2674,6 +2675,13 @@
</intent-filter>
</activity>
<activity
android:name=".flashlight.FlashlightHandleActivity"
android:theme="@android:style/Theme.NoDisplay"
android:excludeFromRecents="true"
android:exported="true"
android:label="@string/power_flashlight"/>
<activity
android:name="Settings$WifiCallingSettingsActivity"
android:label="@string/wifi_calling_settings_title">

View File

@@ -6,35 +6,5 @@
android:tint="?android:attr/colorAccent">
<path
android:fillColor="#FF000000"
android:pathData="M7,4v3H4V4H7M9,2H2v7h7V2L9,2z"/>
<path
android:fillColor="#FF000000"
android:pathData="M15,11l-8,0l0,2l8,0l0,-2z"/>
<path
android:fillColor="#FF000000"
android:pathData="M13,2l-2,0l0,11l2,0l0,-11z"/>
<path
android:fillColor="#FF000000"
android:pathData="M22,15l-11,0l0,2l11,0l0,-2z"/>
<path
android:fillColor="#FF000000"
android:pathData="M13,17l-2,0l0,5l2,0l0,-5z"/>
<path
android:fillColor="#FF000000"
android:pathData="M17,13l-2,0l0,9l2,0l0,-9z"/>
<path
android:fillColor="#FF000000"
android:pathData="M22,19l-3,0l0,3l3,0l0,-3z"/>
<path
android:fillColor="#FF000000"
android:pathData="M5,11l-3,0l0,2l3,0l0,-2z"/>
<path
android:fillColor="#FF000000"
android:pathData="M22,11l-5,0l0,2l5,0l0,-2z"/>
<path
android:fillColor="#FF000000"
android:pathData="M20,4v3h-3V4H20M22,2h-7v7h7V2L22,2z"/>
<path
android:fillColor="#FF000000"
android:pathData="M7,17v3H4v-3H7M9,15H2v7h7V15L9,15z"/>
android:pathData="M3,9h6V3H3V9zM5,5h2v2H5V5zM15,3v6h6V3H15zM19,7h-2V5h2V7zM3,21h6v-6H3V21zM5,17h2v2H5V17zM13,15v2h-2v-2v-2v-2h2v2h2v-2h2v2v2H13zM17,19h4v2h-4h-2v-2v-2h2V19zM19,11h2v6h-2V11zM7,11h2v2H7V11zM11,19h2v2h-2V19zM5,13H3v-2h2V13zM13,9h-2V3h2V9z"/>
</vector>

View File

@@ -6,29 +6,5 @@
android:tint="?android:attr/colorAccent">
<path
android:fillColor="#FF000000"
android:pathData="M9,2l-7,0l0,2l7,0l0,-2z"/>
<path
android:fillColor="#FF000000"
android:pathData="M22,2l-7,0l0,2l7,0l0,-2z"/>
<path
android:fillColor="#FF000000"
android:pathData="M22,11l-20,0l0,2l20,0l0,-2z"/>
<path
android:fillColor="#FF000000"
android:pathData="M22,2l-2,0l0,7l2,0l0,-7z"/>
<path
android:fillColor="#FF000000"
android:pathData="M4,2l-2,0l0,7l2,0l0,-7z"/>
<path
android:fillColor="#FF000000"
android:pathData="M9,20l-7,0l0,2l7,0l0,-2z"/>
<path
android:fillColor="#FF000000"
android:pathData="M22,20l-7,0l0,2l7,0l0,-2z"/>
<path
android:fillColor="#FF000000"
android:pathData="M22,15l-2,0l0,7l2,0l0,-7z"/>
<path
android:fillColor="#FF000000"
android:pathData="M4,15l-2,0l0,7l2,0l0,-7z"/>
android:pathData="M3,9h6V3H3V9zM5,5h2v2H5V5zM15,3v6h6V3H15zM19,7h-2V5h2V7zM3,21h6v-6H3V21zM5,17h2v2H5V17zM17,15h4v2h-4v4h-2v-4h-4v-2h4v-4h2V15zM7,11h2v2H7V11zM5,13H3v-2h2V13zM13,9h-2V3h2V9z"/>
</vector>

View File

@@ -72,8 +72,6 @@
<attr name="controller" format="string" />
<!-- {@code true} when the controller declared represents a slice from {@link android.app.SettingsSliceContract} -->
<attr name="platform_slice" format="boolean" />
<!-- Whether or not dynamic summary text from PreferenceController is allowed when creating slice object, by default it's false. -->
<attr name="allowDynamicSummaryInSlice" format="boolean" />
<!-- customized subtitle if it's an unavailable slice -->
<attr name="unavailableSliceSubtitle" format="string" />
</declare-styleable>

View File

@@ -319,14 +319,6 @@
<dimen name="screen_pinning_padding_start">64dp</dimen>
<dimen name="screen_pinning_padding_end">64dp</dimen>
<!-- Suggestion/condition header padding -->
<dimen name="suggestion_condition_header_padding_collapsed">10dp</dimen>
<dimen name="suggestion_condition_header_padding_expanded">5dp</dimen>
<dimen name="condition_header_height">36dp</dimen>
<!-- Condition cards size and padding -->
<dimen name="condition_card_elevation">2dp</dimen>
<!-- Padding for the reset screens -->
<dimen name="reset_checkbox_padding_end">8dp</dimen>
<dimen name="reset_checkbox_title_padding_top">12dp</dimen>
@@ -334,12 +326,6 @@
<dimen name="reset_checkbox_title_text_size">18sp</dimen>
<dimen name="reset_checkbox_summary_text_size">14sp</dimen>
<!-- Bottombar size and padding -->
<dimen name="homepage_bottomsheet_height">90dp</dimen>
<dimen name="homepage_bottombar_height">56dp</dimen>
<dimen name="homepage_bottombar_top_margin">34dp</dimen>
<dimen name="homepage_bottombar_fab_cradle">68dp</dimen>
<!-- Homepage cards size and padding -->
<dimen name="homepage_card_icon_size">24dp</dimen>
<dimen name="homepage_card_vertical_margin">8dp</dimen>
@@ -369,8 +355,6 @@
<dimen name="homepage_card_dismissal_button_margin_end">6dp</dimen>
<!-- Horizontal divider size and margin -->
<dimen name="horizontal_divider_margin_top">4dp</dimen>
<dimen name="horizontal_divider_margin_bottom">8dp</dimen>
<dimen name="horizontal_divider_height">.75dp</dimen>
<!-- Vertical divider size -->

View File

@@ -7152,6 +7152,9 @@
<string name="keywords_time_zone">timezone</string>
<!-- Search keyword for "Display over other apps" settings [CHAR_LIMIT=NONE]-->
<string name="keywords_draw_overlay">Chat head</string>
<!-- Search keyword for "Flashlight" settings [CHAR_LIMIT=NONE]-->
<string name="keywords_flashlight">Flashlight, Light, Torch</string>
<string name="keywords_change_wifi_state">wifi, wi-fi, toggle, control</string>
<string name="keywords_more_default_sms_app">text message, texting, messages, messaging, default</string>
<string name="keywords_more_mobile_networks">cellular, mobile, cell carrier, wireless, data, 4g,3g, 2g, lte</string>

View File

@@ -16,6 +16,7 @@
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto"
android:key="data_usage_wifi_screen">
<com.android.settings.datausage.TemplatePreferenceCategory
@@ -24,7 +25,8 @@
<com.android.settings.datausage.DataUsagePreference
android:key="wifi_data_usage"
android:title="@string/wifi_data_usage" />
android:title="@string/wifi_data_usage"
settings:searchable="false"/>
</com.android.settings.datausage.TemplatePreferenceCategory>

View File

@@ -28,7 +28,6 @@
android:title="@string/firmware_version"
android:summary="@string/summary_placeholder"
settings:enableCopying="true"
settings:allowDynamicSummaryInSlice="true"
settings:controller="com.android.settings.deviceinfo.firmwareversion.FirmwareVersionDetailPreferenceController"/>
<!-- Security patch -->
@@ -68,7 +67,6 @@
android:title="@string/build_number"
android:summary="@string/summary_placeholder"
settings:enableCopying="true"
settings:allowDynamicSummaryInSlice="true"
settings:controller="com.android.settings.deviceinfo.firmwareversion.SimpleBuildNumberPreferenceController"/>
</PreferenceScreen>

View File

@@ -27,7 +27,6 @@
android:key="hardware_info_device_model"
android:title="@string/model_info"
android:summary="@string/summary_placeholder"
settings:allowDynamicSummaryInSlice="true"
settings:controller="com.android.settings.deviceinfo.hardwareinfo.DeviceModelPreferenceController"
settings:enableCopying="true"/>
@@ -36,7 +35,6 @@
android:key="hardware_info_device_serial"
android:title="@string/status_serial_number"
android:summary="@string/summary_placeholder"
settings:allowDynamicSummaryInSlice="true"
settings:controller="com.android.settings.deviceinfo.hardwareinfo.SerialNumberPreferenceController"
settings:enableCopying="true"/>
@@ -45,7 +43,6 @@
android:key="hardware_info_device_revision"
android:title="@string/hardware_revision"
android:summary="@string/summary_placeholder"
settings:allowDynamicSummaryInSlice="true"
settings:controller="com.android.settings.deviceinfo.hardwareinfo.HardwareRevisionPreferenceController"
settings:enableCopying="true"/>

View File

@@ -52,7 +52,6 @@
android:title="@string/status_number"
android:summary="@string/summary_placeholder"
android:selectable="false"
settings:allowDynamicSummaryInSlice="true"
settings:controller="com.android.settings.deviceinfo.PhoneNumberPreferenceController"
settings:enableCopying="true"/>
@@ -104,7 +103,6 @@
android:title="@string/hardware_info"
settings:keywords="@string/keywords_model_and_hardware"
android:summary="@string/summary_placeholder"
settings:allowDynamicSummaryInSlice="true"
android:fragment="com.android.settings.deviceinfo.hardwareinfo.HardwareInfoFragment"
settings:controller="com.android.settings.deviceinfo.HardwareInfoPreferenceController"/>
@@ -115,7 +113,6 @@
android:title="@string/status_imei"
settings:keywords="@string/keywords_imei_info"
android:summary="@string/summary_placeholder"
settings:allowDynamicSummaryInSlice="true"
settings:controller="com.android.settings.deviceinfo.imei.ImeiInfoPreferenceController"/>
<!-- Android version -->
@@ -124,7 +121,6 @@
android:order="32"
android:title="@string/firmware_version"
android:summary="@string/summary_placeholder"
settings:allowDynamicSummaryInSlice="true"
android:fragment="com.android.settings.deviceinfo.firmwareversion.FirmwareVersionSettings"
settings:controller="com.android.settings.deviceinfo.firmwareversion.FirmwareVersionPreferenceController"/>

View File

@@ -28,7 +28,6 @@
android:icon="@drawable/ic_volume_remote"
android:title="@string/remote_media_volume_option_title"
android:order="-185"
settings:allowDynamicSummaryInSlice="true"
settings:controller="com.android.settings.notification.RemoteVolumePreferenceController"/>
<!-- Media volume -->
@@ -37,7 +36,6 @@
android:icon="@drawable/ic_media_stream"
android:title="@string/media_volume_option_title"
android:order="-180"
settings:allowDynamicSummaryInSlice="true"
settings:controller="com.android.settings.notification.MediaVolumePreferenceController"/>
<!-- Media output switcher -->
@@ -54,7 +52,6 @@
android:icon="@drawable/ic_local_phone_24_lib"
android:title="@string/call_volume_option_title"
android:order="-170"
settings:allowDynamicSummaryInSlice="true"
settings:controller="com.android.settings.notification.CallVolumePreferenceController"/>
<!-- Hands free profile output switcher -->
@@ -71,7 +68,6 @@
android:icon="@drawable/ic_notifications"
android:title="@string/ring_volume_option_title"
android:order="-160"
settings:allowDynamicSummaryInSlice="true"
settings:controller="com.android.settings.notification.RingVolumePreferenceController"/>
@@ -81,7 +77,6 @@
android:icon="@*android:drawable/ic_audio_alarm"
android:title="@string/alarm_volume_option_title"
android:order="-150"
settings:allowDynamicSummaryInSlice="true"
settings:controller="com.android.settings.notification.AlarmVolumePreferenceController"/>
<!-- Notification volume -->

View File

@@ -41,4 +41,8 @@
android:key="saved_networks"
android:title="@string/wifi_saved_access_points_label"
android:fragment="com.android.settings.wifi.savedaccesspoints.SavedAccessPointsWifiSettings"/>
<com.android.settings.datausage.DataUsagePreference
android:key="wifi_data_usage"
android:title="@string/wifi_data_usage"/>
</PreferenceScreen>

View File

@@ -41,7 +41,6 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.provider.Settings;
import android.provider.Telephony;
import android.telephony.CarrierConfigManager;
import android.telephony.CellIdentityCdma;
import android.telephony.CellIdentityGsm;
@@ -89,7 +88,6 @@ import com.android.ims.ImsConfig;
import com.android.ims.ImsException;
import com.android.ims.ImsManager;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneConfigurationManager;
import com.android.internal.telephony.PhoneFactory;
import java.io.IOException;
@@ -471,7 +469,7 @@ public class RadioInfo extends Activity {
if (isDsdsSupported()) {
dsdsSwitch.setVisibility(View.VISIBLE);
dsdsSwitch.setOnClickListener(v -> {
if (mTelephonyManager.isRebootRequiredForModemConfigChange()) {
if (mTelephonyManager.doesSwitchMultiSimConfigTriggerReboot()) {
// Undo the click action until user clicks the confirm dialog.
dsdsSwitch.toggle();
showDsdsChangeDialog();

View File

@@ -927,6 +927,7 @@ public class ManageApplications extends InstrumentedFragment
private boolean mHasReceivedBridgeCallback;
private FileViewHolderController mExtraViewController;
private SearchFilter mSearchFilter;
private PowerWhitelistBackend mBackend;
// This is to remember and restore the last scroll position when this
// fragment is paused. We need this special handling because app entries are added gradually
@@ -1361,8 +1362,9 @@ public class ManageApplications extends InstrumentedFragment
return true;
}
ApplicationsState.AppEntry entry = mEntries.get(position);
return !PowerWhitelistBackend.getInstance(mContext)
.isSysWhitelisted(entry.info.packageName);
return !mBackend.isSysWhitelisted(entry.info.packageName)
&& !mBackend.isDefaultActiveApp(entry.info.packageName);
}
@Override

View File

@@ -112,7 +112,7 @@ public class UserBackupSettingsActivity extends FragmentActivity implements Inde
data.screenTitle = context.getString(R.string.settings_label);
data.keywords = context.getString(R.string.keywords_backup);
data.intentTargetPackage = context.getPackageName();
data.intentTargetClass = com.android.settings.backup.UserBackupSettingsActivity.class.getName();
data.intentTargetClass = UserBackupSettingsActivity.class.getName();
data.intentAction = Intent.ACTION_MAIN;
data.key = BACKUP_SEARCH_INDEX_KEY;
result.add(data);

View File

@@ -18,6 +18,8 @@ package com.android.settings.biometrics.face;
import android.content.Context;
import android.hardware.face.FaceManager;
import android.hardware.face.FaceManager.GetFeatureCallback;
import android.hardware.face.FaceManager.SetFeatureCallback;
import androidx.preference.PreferenceScreen;
import androidx.preference.SwitchPreference;
@@ -37,6 +39,28 @@ public class FaceSettingsAttentionPreferenceController extends TogglePreferenceC
private FaceManager mFaceManager;
private SwitchPreference mPreference;
private final SetFeatureCallback mSetFeatureCallback = new SetFeatureCallback() {
@Override
public void onCompleted(boolean success, int feature) {
if (feature == FaceManager.FEATURE_REQUIRE_ATTENTION) {
mPreference.setEnabled(true);
if (!success) {
mPreference.setChecked(!mPreference.isChecked());
}
}
}
};
private final GetFeatureCallback mGetFeatureCallback = new GetFeatureCallback() {
@Override
public void onCompleted(boolean success, int feature, boolean value) {
if (feature == FaceManager.FEATURE_REQUIRE_ATTENTION && success) {
mPreference.setEnabled(true);
mPreference.setChecked(value);
}
}
};
public FaceSettingsAttentionPreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey);
mFaceManager = Utils.getFaceManagerOrNull(context);
@@ -64,12 +88,22 @@ public class FaceSettingsAttentionPreferenceController extends TogglePreferenceC
if (!FaceSettings.isAvailable(mContext)) {
return true;
}
return mFaceManager.getFeature(FaceManager.FEATURE_REQUIRE_ATTENTION);
// Set to disabled until we know the true value.
mPreference.setEnabled(false);
mFaceManager.getFeature(FaceManager.FEATURE_REQUIRE_ATTENTION, mGetFeatureCallback);
// Ideally returns a cached value.
return true;
}
@Override
public boolean setChecked(boolean isChecked) {
mFaceManager.setFeature(FaceManager.FEATURE_REQUIRE_ATTENTION, isChecked, mToken);
// Optimistically update state and set to disabled until we know it succeeded.
mPreference.setEnabled(false);
mPreference.setChecked(isChecked);
mFaceManager.setFeature(FaceManager.FEATURE_REQUIRE_ATTENTION, isChecked, mToken,
mSetFeatureCallback);
return true;
}

View File

@@ -21,6 +21,7 @@ import android.app.KeyguardManager;
import android.app.admin.DevicePolicyManager;
import android.app.settings.SettingsEnums;
import android.content.Intent;
import android.hardware.fingerprint.FingerprintManager;
import android.os.Bundle;
import android.os.UserHandle;
import android.os.storage.StorageManager;
@@ -30,6 +31,7 @@ import android.widget.TextView;
import com.android.internal.widget.LockPatternUtils;
import com.android.settings.R;
import com.android.settings.SetupWizardUtils;
import com.android.settings.Utils;
import com.android.settings.password.ChooseLockGeneric.ChooseLockGenericFragment;
import com.android.settings.password.SetupChooseLockGeneric;
import com.android.settings.password.SetupSkipDialog;
@@ -37,6 +39,11 @@ import com.android.settings.password.SetupSkipDialog;
import com.google.android.setupcompat.template.FooterButton;
public class SetupFingerprintEnrollIntroduction extends FingerprintEnrollIntroduction {
/**
* Returns the number of fingerprint enrolled.
*/
private static final String EXTRA_FINGERPRINT_ENROLLED_COUNT = "fingerprint_enrolled_count";
private static final String KEY_LOCK_SCREEN_PRESENT = "wasLockScreenPresent";
private boolean mAlreadyHadLockScreenSetup = false;
@@ -99,10 +106,17 @@ public class SetupFingerprintEnrollIntroduction extends FingerprintEnrollIntrodu
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// if lock was already present, do not return intent data since it must have been
// reported in previous attempts
if (requestCode == BIOMETRIC_FIND_SENSOR_REQUEST && isKeyguardSecure()
&& !mAlreadyHadLockScreenSetup) {
data = getMetricIntent(data);
if (requestCode == BIOMETRIC_FIND_SENSOR_REQUEST && isKeyguardSecure()) {
if(!mAlreadyHadLockScreenSetup) {
data = getMetricIntent(data);
}
// Report fingerprint count if user adding a new fingerprint
if(resultCode == RESULT_FINISHED) {
data = setFingerprintCount(data);
}
}
super.onActivityResult(requestCode, resultCode, data);
}
@@ -114,6 +128,19 @@ public class SetupFingerprintEnrollIntroduction extends FingerprintEnrollIntrodu
data.putExtra(SetupChooseLockGeneric.
SetupChooseLockGenericFragment.EXTRA_PASSWORD_QUALITY,
lockPatternUtils.getKeyguardStoredPasswordQuality(UserHandle.myUserId()));
return data;
}
private Intent setFingerprintCount(Intent data) {
if (data == null) {
data = new Intent();
}
final FingerprintManager fpm = Utils.getFingerprintManagerOrNull(this);
if (fpm != null) {
int enrolled = fpm.getEnrolledFingerprints(mUserId).size();
data.putExtra(EXTRA_FINGERPRINT_ENROLLED_COUNT, enrolled);
}
return data;
}

View File

@@ -21,6 +21,7 @@ package com.android.settings.core;
*/
public class FeatureFlags {
public static final String AUDIO_SWITCHER_SETTINGS = "settings_audio_switcher";
public static final String DYNAMIC_SYSTEM = "settings_dynamic_system";
public static final String HEARING_AID_SETTINGS = "settings_bluetooth_hearing_aid";
public static final String MOBILE_NETWORK_V2 = "settings_mobile_network_v2";
public static final String NETWORK_INTERNET_V2 = "settings_network_and_internet_v2";

View File

@@ -72,7 +72,6 @@ public class PreferenceXmlParserUtils {
MetadataFlag.FLAG_NEED_PREF_SUMMARY,
MetadataFlag.FLAG_NEED_PREF_ICON,
MetadataFlag.FLAG_NEED_SEARCHABLE,
MetadataFlag.FLAG_ALLOW_DYNAMIC_SUMMARY_IN_SLICE,
MetadataFlag.FLAG_UNAVAILABLE_SLICE_SUBTITLE})
@Retention(RetentionPolicy.SOURCE)
public @interface MetadataFlag {
@@ -87,9 +86,8 @@ public class PreferenceXmlParserUtils {
int FLAG_NEED_PLATFORM_SLICE_FLAG = 1 << 7;
int FLAG_NEED_KEYWORDS = 1 << 8;
int FLAG_NEED_SEARCHABLE = 1 << 9;
int FLAG_ALLOW_DYNAMIC_SUMMARY_IN_SLICE = 1 << 10;
int FLAG_NEED_PREF_APPEND = 1 << 11;
int FLAG_UNAVAILABLE_SLICE_SUBTITLE = 1 << 12;
int FLAG_NEED_PREF_APPEND = 1 << 10;
int FLAG_UNAVAILABLE_SLICE_SUBTITLE = 1 << 11;
}
public static final String METADATA_PREF_TYPE = "type";
@@ -101,8 +99,6 @@ public class PreferenceXmlParserUtils {
public static final String METADATA_PLATFORM_SLICE_FLAG = "platform_slice";
public static final String METADATA_KEYWORDS = "keywords";
public static final String METADATA_SEARCHABLE = "searchable";
public static final String METADATA_ALLOW_DYNAMIC_SUMMARY_IN_SLICE =
"allow_dynamic_summary_in_slice";
public static final String METADATA_APPEND = "staticPreferenceLocation";
public static final String METADATA_UNAVAILABLE_SLICE_SUBTITLE =
"unavailable_slice_subtitle";
@@ -246,10 +242,6 @@ public class PreferenceXmlParserUtils {
preferenceMetadata.putBoolean(METADATA_SEARCHABLE,
isSearchable(preferenceAttributes));
}
if (hasFlag(flags, MetadataFlag.FLAG_ALLOW_DYNAMIC_SUMMARY_IN_SLICE)) {
preferenceMetadata.putBoolean(METADATA_ALLOW_DYNAMIC_SUMMARY_IN_SLICE,
isDynamicSummaryAllowed(preferenceAttributes));
}
if (hasFlag(flags, MetadataFlag.FLAG_NEED_PREF_APPEND) && hasPrefScreenFlag) {
preferenceMetadata.putBoolean(METADATA_APPEND,
isAppended(preferenceScreenAttributes));
@@ -267,14 +259,6 @@ public class PreferenceXmlParserUtils {
return metadata;
}
/**
* Returns the fragment name if this preference launches a child fragment.
*/
public static String getDataChildFragment(Context context, AttributeSet attrs) {
return getStringData(context, attrs, R.styleable.Preference,
R.styleable.Preference_android_fragment);
}
/**
* Call {@link #extractMetadata(Context, int, int)} with a {@link MetadataFlag} instead.
*/
@@ -342,11 +326,6 @@ public class PreferenceXmlParserUtils {
return styledAttributes.getBoolean(R.styleable.Preference_searchable, true /* default */);
}
private static boolean isDynamicSummaryAllowed(TypedArray styledAttributes) {
return styledAttributes.getBoolean(R.styleable.Preference_allowDynamicSummaryInSlice,
false /* default */);
}
private static String getKeywords(TypedArray styledAttributes) {
return styledAttributes.getString(R.styleable.Preference_keywords);
}

View File

@@ -192,7 +192,9 @@ public class DashboardFeatureProviderImpl implements DashboardFeatureProvider {
@VisibleForTesting
void bindIcon(Preference preference, Tile tile, boolean forceRoundedIcon) {
final Icon tileIcon = tile.getIcon(mContext);
// Use preference context instead here when get icon from Tile, as we are using the context
// to get the style to tint the icon. Using mContext here won't get the correct style.
final Icon tileIcon = tile.getIcon(preference.getContext());
if (tileIcon != null) {
Drawable iconDrawable = tileIcon.loadDrawable(preference.getContext());
if (forceRoundedIcon

View File

@@ -18,8 +18,6 @@ package com.android.settings.dashboard;
import android.app.Activity;
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Icon;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.ArrayMap;
@@ -410,10 +408,6 @@ public abstract class DashboardFragment extends SettingsPreferenceFragment
final Context context = getContext();
mSummaryLoader = new SummaryLoader(getActivity(), getCategoryKey());
mSummaryLoader.setSummaryConsumer(this);
final TypedArray a = context.obtainStyledAttributes(new int[]{
android.R.attr.colorControlNormal});
final int tintColor = a.getColor(0, context.getColor(android.R.color.white));
a.recycle();
// Install dashboard tiles.
final boolean forceRoundedIcons = shouldForceRoundedIcon();
for (Tile tile : tiles) {
@@ -425,12 +419,6 @@ public abstract class DashboardFragment extends SettingsPreferenceFragment
if (!displayTile(tile)) {
continue;
}
if (tile.isIconTintable(context)) {
final Icon icon = tile.getIcon(context);
if (icon != null) {
icon.setTint(tintColor);
}
}
if (mDashboardTilePrefKeys.contains(key)) {
// Have the key already, will rebind.
final Preference preference = screen.findPreference(key);

View File

@@ -17,11 +17,13 @@
package com.android.settings.development;
import android.content.Context;
import android.provider.DeviceConfig;
import android.provider.Settings;
import androidx.preference.Preference;
import androidx.preference.SwitchPreference;
import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settingslib.development.DeveloperOptionsPreferenceController;
@@ -32,6 +34,11 @@ public class AllowBackgroundActivityStartsPreferenceController
private static final String BACKGROUND_ACTIVITY_STARTS_ENABLED_KEY
= "allow_background_activity_starts";
/** Key in DeviceConfig that stores the default for the preference (as a boolean). */
@VisibleForTesting
static final String KEY_DEFAULT_BACKGROUND_ACTIVITY_STARTS_ENABLED =
"default_background_activity_starts_enabled";
public AllowBackgroundActivityStartsPreferenceController(Context context) {
super(context);
}
@@ -47,22 +54,38 @@ public class AllowBackgroundActivityStartsPreferenceController
return true;
}
private void writeSetting(boolean isEnabled) {
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.BACKGROUND_ACTIVITY_STARTS_ENABLED, isEnabled ? 1 : 0);
}
@Override
public void updateState(Preference preference) {
final int mode = Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.BACKGROUND_ACTIVITY_STARTS_ENABLED, 1);
((SwitchPreference) mPreference).setChecked(mode != 0);
Settings.Global.BACKGROUND_ACTIVITY_STARTS_ENABLED, -1);
boolean isEnabled = mode < 0 ? isDefaultEnabled() : mode != 0;
((SwitchPreference) mPreference).setChecked(isEnabled);
}
@Override
protected void onDeveloperOptionsSwitchDisabled() {
super.onDeveloperOptionsSwitchDisabled();
writeSetting(true);
((SwitchPreference) mPreference).setChecked(true);
clearSetting();
updateState(mPreference);
}
private void writeSetting(boolean isEnabled) {
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.BACKGROUND_ACTIVITY_STARTS_ENABLED, isEnabled ? 1 : 0);
}
private void clearSetting() {
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.BACKGROUND_ACTIVITY_STARTS_ENABLED, -1);
}
private boolean isDefaultEnabled() {
// The default in the absence of user preference is settable via DeviceConfig.
// Note that the default default is enabled.
return DeviceConfig.getBoolean(
DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
KEY_DEFAULT_BACKGROUND_ACTIVITY_STARTS_ENABLED,
/*defaultValue*/ true);
}
}

View File

@@ -36,6 +36,7 @@ public class FeatureFlagPersistent {
PERSISTENT_FLAGS = new HashSet<>();
PERSISTENT_FLAGS.add(FeatureFlags.HEARING_AID_SETTINGS);
PERSISTENT_FLAGS.add(FeatureFlags.NETWORK_INTERNET_V2);
PERSISTENT_FLAGS.add(FeatureFlags.DYNAMIC_SYSTEM);
}
public static boolean isEnabled(Context context, String feature) {

View File

@@ -101,6 +101,11 @@ public class PhoneNumberPreferenceController extends BasePreferenceController {
return true;
}
@Override
public boolean useDynamicSliceSummary() {
return true;
}
@Override
public void copy() {
final ClipboardManager clipboard = (ClipboardManager) mContext.getSystemService(

View File

@@ -58,6 +58,11 @@ public class FirmwareVersionDetailPreferenceController extends BasePreferenceCon
return AVAILABLE;
}
@Override
public boolean useDynamicSliceSummary() {
return true;
}
@Override
public boolean isSliceable() {
return true;

View File

@@ -55,6 +55,11 @@ public class SimpleBuildNumberPreferenceController extends BasePreferenceControl
return true;
}
@Override
public boolean useDynamicSliceSummary() {
return true;
}
@Override
public void copy() {
final ClipboardManager clipboard = (ClipboardManager) mContext.getSystemService(

View File

@@ -44,4 +44,9 @@ public class DeviceModelPreferenceController extends HardwareInfoPreferenceContr
public CharSequence getSummary() {
return HardwareInfoPreferenceController.getDeviceModel();
}
@Override
public boolean useDynamicSliceSummary() {
return true;
}
}

View File

@@ -34,6 +34,11 @@ public class HardwareRevisionPreferenceController extends BasePreferenceControll
? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
@Override
public boolean useDynamicSliceSummary() {
return true;
}
@Override
public boolean isSliceable() {
return true;

View File

@@ -45,6 +45,11 @@ public class SerialNumberPreferenceController extends BasePreferenceController {
return true;
}
@Override
public boolean useDynamicSliceSummary() {
return true;
}
@Override
public void copy() {
Sliceable.setCopyContent(mContext, getSummary(),

View File

@@ -110,6 +110,11 @@ public class ImeiInfoPreferenceController extends BasePreferenceController {
return true;
}
@Override
public boolean useDynamicSliceSummary() {
return true;
}
@Override
public void copy() {
Sliceable.setCopyContent(mContext, getSummary(), mContext.getText(R.string.status_imei));

View File

@@ -0,0 +1,78 @@
/*
* Copyright (C) 2019 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.flashlight;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.provider.Settings;
import com.android.settings.R;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
import com.android.settings.search.SearchIndexableRaw;
import com.android.settingslib.search.SearchIndexable;
import java.util.ArrayList;
import java.util.List;
/**
* Headless activity that toggles flashlight state when launched.
*/
@SearchIndexable(forTarget = SearchIndexable.MOBILE)
public class FlashlightHandleActivity extends Activity implements Indexable {
public static final String EXTRA_FALLBACK_TO_HOMEPAGE = "fallback_to_homepage";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Do nothing meaningful in this activity.
// The sole purpose of this activity is to provide a place to index flashlight
// into Settings search.
// Caller's choice: fallback to homepage, or just exit?
if (getIntent().getBooleanExtra(EXTRA_FALLBACK_TO_HOMEPAGE, false)) {
startActivity(new Intent(Settings.ACTION_SETTINGS));
}
finish();
}
public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider() {
@Override
public List<SearchIndexableRaw> getRawDataToIndex(Context context,
boolean enabled) {
final List<SearchIndexableRaw> result = new ArrayList<>();
SearchIndexableRaw data = new SearchIndexableRaw(context);
data.title = context.getString(R.string.power_flashlight);
data.screenTitle = context.getString(R.string.power_flashlight);
data.keywords = context.getString(R.string.keywords_flashlight);
data.intentTargetPackage = context.getPackageName();
data.intentTargetClass = FlashlightHandleActivity.class.getName();
data.intentAction = Intent.ACTION_MAIN;
data.key = "flashlight";
result.add(data);
return result;
}
};
}

View File

@@ -84,7 +84,7 @@ public class SettingsHomepageActivity extends SettingsBaseActivity {
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
);
getWindow().setStatusBarColor(getResources().getColor(R.color.homepage_status_bar_color));
getWindow().setStatusBarColor(getColor(R.color.homepage_status_bar_color));
}
@VisibleForTesting

View File

@@ -72,26 +72,29 @@ public class ContextualCardManager implements ContextualCardLoader.CardContentLo
static final long CARD_CONTENT_LOADER_TIMEOUT_MS = DateUtils.SECOND_IN_MILLIS;
@VisibleForTesting
static final String KEY_GLOBAL_CARD_LOADER_TIMEOUT = "global_card_loader_timeout_key";
@VisibleForTesting
static final String KEY_CONTEXTUAL_CARDS = "key_contextual_cards";
private static final String KEY_CONTEXTUAL_CARDS = "key_contextual_cards";
private static final String TAG = "ContextualCardManager";
//The list for Settings Custom Card
private static final int[] SETTINGS_CARDS =
{ContextualCard.CardType.CONDITIONAL, ContextualCard.CardType.LEGACY_SUGGESTION};
@VisibleForTesting
final List<ContextualCard> mContextualCards;
private final Context mContext;
private final ControllerRendererPool mControllerRendererPool;
private final Lifecycle mLifecycle;
private final List<LifecycleObserver> mLifecycleObservers;
private ContextualCardUpdateListener mListener;
@VisibleForTesting
final List<ContextualCard> mContextualCards;
@VisibleForTesting
long mStartTime;
@VisibleForTesting
boolean mIsFirstLaunch;
@VisibleForTesting
List<String> mSavedCards;
private ContextualCardUpdateListener mListener;
public ContextualCardManager(Context context, Lifecycle lifecycle, Bundle savedInstanceState) {
mContext = context;
@@ -128,7 +131,8 @@ public class ContextualCardManager implements ContextualCardLoader.CardContentLo
}
}
private void setupController(@ContextualCard.CardType int cardType) {
@VisibleForTesting
void setupController(@ContextualCard.CardType int cardType) {
final ContextualCardController controller = mControllerRendererPool.getController(mContext,
cardType);
if (controller == null) {
@@ -211,7 +215,7 @@ public class ContextualCardManager implements ContextualCardLoader.CardContentLo
final MetricsFeatureProvider metricsFeatureProvider =
FeatureFactory.getFactory(mContext).getMetricsFeatureProvider();
final long timeoutLimit = getCardLoaderTimeout(mContext);
final long timeoutLimit = getCardLoaderTimeout();
if (loadTime <= timeoutLimit) {
onContextualCardUpdated(cards.stream()
.collect(groupingBy(ContextualCard::getCardType)));
@@ -275,7 +279,7 @@ public class ContextualCardManager implements ContextualCardLoader.CardContentLo
}
@VisibleForTesting
long getCardLoaderTimeout(Context context) {
long getCardLoaderTimeout() {
// Return the timeout limit if Settings.Global has the KEY_GLOBAL_CARD_LOADER_TIMEOUT key,
// else return default timeout.
return Settings.Global.getLong(mContext.getContentResolver(),
@@ -317,7 +321,8 @@ public class ContextualCardManager implements ContextualCardLoader.CardContentLo
return result;
}
private List<ContextualCard> getCardsToKeep(List<ContextualCard> cards) {
@VisibleForTesting
List<ContextualCard> getCardsToKeep(List<ContextualCard> cards) {
if (mSavedCards != null) {
//screen rotate
final List<ContextualCard> cardsToKeep = cards.stream()

View File

@@ -22,14 +22,15 @@ import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.LayoutRes;
import androidx.annotation.VisibleForTesting;
import androidx.lifecycle.LifecycleOwner;
import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.android.settings.homepage.contextualcards.conditional.ConditionContextualCardRenderer;
import com.android.settings.homepage.contextualcards.slices.SwipeDismissalDelegate;
import com.android.settings.homepage.contextualcards.slices.SliceContextualCardRenderer;
import com.android.settings.homepage.contextualcards.slices.SwipeDismissalDelegate;
import java.util.ArrayList;
import java.util.List;
@@ -43,9 +44,11 @@ public class ContextualCardsAdapter extends RecyclerView.Adapter<RecyclerView.Vi
private static final int HALF_WIDTH = 1;
private static final int FULL_WIDTH = 2;
@VisibleForTesting
final List<ContextualCard> mContextualCards;
private final Context mContext;
private final ControllerRendererPool mControllerRendererPool;
private final List<ContextualCard> mContextualCards;
private final LifecycleOwner mLifecycleOwner;
private RecyclerView mRecyclerView;

View File

@@ -26,6 +26,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.util.ArrayMap;
import androidx.annotation.VisibleForTesting;
import androidx.annotation.WorkerThread;
@@ -50,6 +51,7 @@ import com.android.settingslib.utils.ThreadUtils;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
public class BatteryFixSlice implements CustomSliceable {
@@ -57,11 +59,18 @@ public class BatteryFixSlice implements CustomSliceable {
static final String PREFS = "battery_fix_prefs";
@VisibleForTesting
static final String KEY_CURRENT_TIPS_TYPE = "current_tip_type";
static final String KEY_CURRENT_TIPS_STATE = "current_tip_state";
private static final List<Integer> UNIMPORTANT_BATTERY_TIPS = Arrays.asList(
BatteryTip.TipType.SUMMARY,
BatteryTip.TipType.BATTERY_SAVER
);
// A map tracking which BatteryTip and which state of that tip is not important.
private static final Map<Integer, List<Integer>> UNIMPORTANT_BATTERY_TIPS;
static {
UNIMPORTANT_BATTERY_TIPS = new ArrayMap<>();
UNIMPORTANT_BATTERY_TIPS.put(BatteryTip.TipType.SUMMARY,
Arrays.asList(BatteryTip.StateType.NEW, BatteryTip.StateType.HANDLED));
UNIMPORTANT_BATTERY_TIPS.put(BatteryTip.TipType.BATTERY_SAVER,
Arrays.asList(BatteryTip.StateType.HANDLED));
}
private static final String TAG = "BatteryFixSlice";
@@ -82,9 +91,8 @@ public class BatteryFixSlice implements CustomSliceable {
new ListBuilder(mContext, BATTERY_FIX_SLICE_URI, ListBuilder.INFINITY)
.setAccentColor(COLOR_NOT_TINTED);
// TipType.SUMMARY is battery good
if (UNIMPORTANT_BATTERY_TIPS.contains(readBatteryTipAvailabilityCache(mContext))) {
return buildBatteryGoodSlice(sliceBuilder, true);
if (!isBatteryTipAvailableFromCache(mContext)) {
return buildBatteryGoodSlice(sliceBuilder, true /* isError */);
}
final SliceBackgroundWorker worker = SliceBackgroundWorker.getInstance(getUri());
@@ -92,7 +100,7 @@ public class BatteryFixSlice implements CustomSliceable {
if (batteryTips == null) {
// Because we need wait slice background worker return data
return buildBatteryGoodSlice(sliceBuilder, false);
return buildBatteryGoodSlice(sliceBuilder, false /* isError */);
}
for (BatteryTip batteryTip : batteryTips) {
@@ -161,15 +169,23 @@ public class BatteryFixSlice implements CustomSliceable {
// TODO(b/114807643): we should find a better way to get current battery tip type quickly
// Now we save battery tip type to shared preference when battery level changes
public static void updateBatteryTipAvailabilityCache(Context context) {
ThreadUtils.postOnBackgroundThread(() -> {
refreshBatteryTips(context);
});
ThreadUtils.postOnBackgroundThread(() -> refreshBatteryTips(context));
}
@VisibleForTesting
static int readBatteryTipAvailabilityCache(Context context) {
static boolean isBatteryTipAvailableFromCache(Context context) {
final SharedPreferences prefs = context.getSharedPreferences(PREFS, MODE_PRIVATE);
return prefs.getInt(KEY_CURRENT_TIPS_TYPE, BatteryTip.TipType.SUMMARY);
final int type = prefs.getInt(KEY_CURRENT_TIPS_TYPE, BatteryTip.TipType.SUMMARY);
final int state = prefs.getInt(KEY_CURRENT_TIPS_STATE, BatteryTip.StateType.INVISIBLE);
if (state == BatteryTip.StateType.INVISIBLE) {
// State is INVISIBLE, We should not show anything.
return false;
}
final boolean unimportant = UNIMPORTANT_BATTERY_TIPS.containsKey(type)
&& UNIMPORTANT_BATTERY_TIPS.get(type).contains(state);
return !unimportant;
}
@WorkerThread
@@ -180,10 +196,11 @@ public class BatteryFixSlice implements CustomSliceable {
final List<BatteryTip> batteryTips = loader.loadInBackground();
for (BatteryTip batteryTip : batteryTips) {
if (batteryTip.getState() != BatteryTip.StateType.INVISIBLE) {
SharedPreferences.Editor editor = context.getSharedPreferences(PREFS,
MODE_PRIVATE).edit();
editor.putInt(KEY_CURRENT_TIPS_TYPE, batteryTip.getType());
editor.apply();
context.getSharedPreferences(PREFS, MODE_PRIVATE)
.edit()
.putInt(KEY_CURRENT_TIPS_TYPE, batteryTip.getType())
.putInt(KEY_CURRENT_TIPS_STATE, batteryTip.getState())
.apply();
break;
}
}

View File

@@ -437,15 +437,6 @@ public class NotificationChannelSlice implements CustomSliceable {
.setData(getUri());
}
private PackageInfo getPackageInfo(String packageName) {
try {
return mContext.getPackageManager().getPackageInfo(packageName, 0);
} catch (PackageManager.NameNotFoundException e) {
Log.w(TAG, "No such package to get package info.");
return null;
}
}
private boolean isChannelEnabled(NotificationChannelGroup group, NotificationChannel channel,
NotificationBackend.AppRow appRow) {
final RestrictedLockUtils.EnforcedAdmin suspendedAppsAdmin =

View File

@@ -17,14 +17,10 @@
package com.android.settings.homepage.contextualcards.slices;
import android.content.Context;
import android.util.Log;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import androidx.slice.Slice;
import androidx.slice.SliceItem;
import androidx.slice.widget.EventInfo;
import androidx.slice.widget.SliceView;
import com.android.settings.R;
@@ -32,13 +28,10 @@ import com.android.settings.homepage.contextualcards.ContextualCard;
import com.android.settings.homepage.contextualcards.ContextualCardFeatureProvider;
import com.android.settings.overlay.FeatureFactory;
import java.util.Set;
/**
* Card renderer helper for {@link ContextualCard} built as slice full card.
*/
class SliceFullCardRendererHelper {
private static final String TAG = "SliceFCRendererHelper";
private final Context mContext;

View File

@@ -96,11 +96,10 @@ public class NetworkSelectSettings extends DashboardFragment {
com.android.internal.R.bool.config_enableNewAutoSelectNetworkUI);
mSubId = getArguments().getInt(Settings.EXTRA_SUB_ID);
mConnectedPreferenceCategory =
(PreferenceCategory) findPreference(PREF_KEY_CONNECTED_NETWORK_OPERATOR);
mPreferenceCategory =
(PreferenceCategory) findPreference(PREF_KEY_NETWORK_OPERATORS);
mConnectedPreferenceCategory = findPreference(PREF_KEY_CONNECTED_NETWORK_OPERATOR);
mPreferenceCategory = findPreference(PREF_KEY_NETWORK_OPERATORS);
mStatusMessagePreference = new Preference(getContext());
mStatusMessagePreference.setSelectable(false);
mSelectedPreference = null;
mTelephonyManager = TelephonyManager.from(getContext()).createForSubscriptionId(mSubId);
mNetworkScanHelper = new NetworkScanHelper(

View File

@@ -16,41 +16,57 @@
package com.android.settings.network.telephony.gsm;
import android.app.ProgressDialog;
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.PersistableBundle;
import android.os.SystemClock;
import android.provider.Settings;
import android.telephony.CarrierConfigManager;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import androidx.preference.SwitchPreference;
import com.android.settings.R;
import com.android.settings.core.SubSettingLauncher;
import com.android.settings.network.telephony.MobileNetworkUtils;
import com.android.settings.network.telephony.NetworkSelectSettings;
import com.android.settings.network.telephony.TelephonyTogglePreferenceController;
import com.android.settingslib.utils.ThreadUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* Preference controller for "Auto Select Network"
*/
public class AutoSelectPreferenceController extends TelephonyTogglePreferenceController {
private static final long MINIMUM_DIALOG_TIME_MILLIS = TimeUnit.SECONDS.toMillis(1);
private final Handler mUiHandler;
private int mSubId;
private TelephonyManager mTelephonyManager;
private boolean mOnlyAutoSelectInHome;
private List<OnNetworkSelectModeListener> mListeners;
@VisibleForTesting
ProgressDialog mProgressDialog;
@VisibleForTesting
SwitchPreference mSwitchPreference;
public AutoSelectPreferenceController(Context context, String key) {
super(context, key);
mTelephonyManager = context.getSystemService(TelephonyManager.class);
mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
mListeners = new ArrayList<>();
mUiHandler = new Handler(Looper.getMainLooper());
}
@Override
@@ -60,6 +76,12 @@ public class AutoSelectPreferenceController extends TelephonyTogglePreferenceCon
: CONDITIONALLY_UNAVAILABLE;
}
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
mSwitchPreference = screen.findPreference(getPreferenceKey());
}
@Override
public boolean isChecked() {
return mTelephonyManager.getNetworkSelectionMode()
@@ -86,14 +108,28 @@ public class AutoSelectPreferenceController extends TelephonyTogglePreferenceCon
@Override
public boolean setChecked(boolean isChecked) {
if (isChecked) {
mTelephonyManager.setNetworkSelectionModeAutomatic();
final long startMillis = SystemClock.elapsedRealtime();
showAutoSelectProgressBar();
mSwitchPreference.setEnabled(false);
ThreadUtils.postOnBackgroundThread(() -> {
// set network selection mode in background
mTelephonyManager.setNetworkSelectionModeAutomatic();
final int mode = mTelephonyManager.getNetworkSelectionMode();
for (OnNetworkSelectModeListener lsn : mListeners) {
lsn.onNetworkSelectModeChanged();
}
// Manually check whether it is successfully
return mTelephonyManager.getNetworkSelectionMode()
== TelephonyManager.NETWORK_SELECTION_MODE_AUTO;
//Update UI in UI thread
final long durationMillis = SystemClock.elapsedRealtime() - startMillis;
mUiHandler.postDelayed(() -> {
mSwitchPreference.setEnabled(true);
mSwitchPreference.setChecked(
mode == TelephonyManager.NETWORK_SELECTION_MODE_AUTO);
for (OnNetworkSelectModeListener lsn : mListeners) {
lsn.onNetworkSelectModeChanged();
}
dismissProgressBar();
},
Math.max(MINIMUM_DIALOG_TIME_MILLIS - durationMillis, 0));
});
return false;
} else {
final Bundle bundle = new Bundle();
bundle.putInt(Settings.EXTRA_SUB_ID, mSubId);
@@ -126,6 +162,24 @@ public class AutoSelectPreferenceController extends TelephonyTogglePreferenceCon
return this;
}
private void showAutoSelectProgressBar() {
if (mProgressDialog == null) {
mProgressDialog = new ProgressDialog(mContext);
mProgressDialog.setMessage(
mContext.getResources().getString(R.string.register_automatically));
mProgressDialog.setCanceledOnTouchOutside(false);
mProgressDialog.setCancelable(false);
mProgressDialog.setIndeterminate(true);
}
mProgressDialog.show();
}
private void dismissProgressBar() {
if (mProgressDialog != null && mProgressDialog.isShowing()) {
mProgressDialog.dismiss();
}
}
/**
* Callback when network select mode is changed
*

View File

@@ -26,7 +26,6 @@ import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
import com.android.settings.accounts.AccountRestrictionHelper;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.core.SliderPreferenceController;
import com.android.settingslib.RestrictedPreference;
@@ -35,7 +34,7 @@ import com.android.settingslib.RestrictedPreference;
* restriction
*/
public abstract class AdjustVolumeRestrictedPreferenceController extends
SliderPreferenceController implements PreferenceControllerMixin {
SliderPreferenceController {
private AccountRestrictionHelper mHelper;

View File

@@ -22,8 +22,7 @@ import android.text.TextUtils;
import com.android.settings.R;
public class AlarmVolumePreferenceController extends
VolumeSeekBarPreferenceController {
public class AlarmVolumePreferenceController extends VolumeSeekBarPreferenceController {
private static final String KEY_ALARM_VOLUME = "alarm_volume";
@@ -42,6 +41,11 @@ public class AlarmVolumePreferenceController extends
return TextUtils.equals(getPreferenceKey(), "alarm_volume");
}
@Override
public boolean useDynamicSliceSummary() {
return true;
}
@Override
public String getPreferenceKey() {
return KEY_ALARM_VOLUME;

View File

@@ -43,6 +43,11 @@ public class CallVolumePreferenceController extends VolumeSeekBarPreferenceContr
return TextUtils.equals(getPreferenceKey(), "call_volume");
}
@Override
public boolean useDynamicSliceSummary() {
return true;
}
@Override
public int getAudioStream() {
if (mAudioManager.isBluetoothScoOn()) {

View File

@@ -22,8 +22,7 @@ import android.text.TextUtils;
import com.android.settings.R;
public class MediaVolumePreferenceController extends
VolumeSeekBarPreferenceController {
public class MediaVolumePreferenceController extends VolumeSeekBarPreferenceController {
private static final String KEY_MEDIA_VOLUME = "media_volume";
@@ -43,6 +42,11 @@ public class MediaVolumePreferenceController extends
return TextUtils.equals(getPreferenceKey(), KEY_MEDIA_VOLUME);
}
@Override
public boolean useDynamicSliceSummary() {
return true;
}
@Override
public String getPreferenceKey() {
return KEY_MEDIA_VOLUME;

View File

@@ -37,8 +37,7 @@ import java.io.IOException;
import java.util.List;
import java.util.Objects;
public class RemoteVolumePreferenceController extends
VolumeSeekBarPreferenceController {
public class RemoteVolumePreferenceController extends VolumeSeekBarPreferenceController {
private static final String KEY_REMOTE_VOLUME = "remote_volume";
@VisibleForTesting
@@ -167,6 +166,11 @@ public class RemoteVolumePreferenceController extends
return TextUtils.equals(getPreferenceKey(), KEY_REMOTE_VOLUME);
}
@Override
public boolean useDynamicSliceSummary() {
return true;
}
@Override
public String getPreferenceKey() {
return KEY_REMOTE_VOLUME;

View File

@@ -95,6 +95,11 @@ public class RingVolumePreferenceController extends VolumeSeekBarPreferenceContr
return TextUtils.equals(getPreferenceKey(), KEY_RING_VOLUME);
}
@Override
public boolean useDynamicSliceSummary() {
return true;
}
@Override
public int getAudioStream() {
return AudioManager.STREAM_RING;

View File

@@ -188,8 +188,8 @@ public class SliceBuilderUtils {
* @return the summary text for a {@link Slice} built for {@param sliceData}.
*/
public static CharSequence getSubtitleText(Context context,
AbstractPreferenceController controller, SliceData sliceData) {
final boolean isDynamicSummaryAllowed = sliceData.isDynamicSummaryAllowed();
BasePreferenceController controller, SliceData sliceData) {
final boolean isDynamicSummaryAllowed = controller.useDynamicSliceSummary();
CharSequence summaryText = controller.getSummary();
// Priority 1 : User prefers showing the dynamic summary in slice view rather than static

View File

@@ -73,8 +73,6 @@ public class SliceData {
private final boolean mIsPlatformDefined;
private final boolean mIsDynamicSummaryAllowed;
private final String mUnavailableSliceSubtitle;
public String getKey() {
@@ -121,10 +119,6 @@ public class SliceData {
return mIsPlatformDefined;
}
public boolean isDynamicSummaryAllowed() {
return mIsDynamicSummaryAllowed;
}
public String getUnavailableSliceSubtitle() {
return mUnavailableSliceSubtitle;
}
@@ -141,7 +135,6 @@ public class SliceData {
mPreferenceController = builder.mPrefControllerClassName;
mSliceType = builder.mSliceType;
mIsPlatformDefined = builder.mIsPlatformDefined;
mIsDynamicSummaryAllowed = builder.mIsDynamicSummaryAllowed;
mUnavailableSliceSubtitle = builder.mUnavailableSliceSubtitle;
}
@@ -182,8 +175,6 @@ public class SliceData {
private boolean mIsPlatformDefined;
private boolean mIsDynamicSummaryAllowed;
private String mUnavailableSliceSubtitle;
public Builder setKey(String key) {
@@ -241,11 +232,6 @@ public class SliceData {
return this;
}
public Builder setDynamicSummaryAllowed(boolean isDynamicSummaryAllowed) {
mIsDynamicSummaryAllowed = isDynamicSummaryAllowed;
return this;
}
public Builder setUnavailableSliceSubtitle(
String unavailableSliceSubtitle) {
mUnavailableSliceSubtitle = unavailableSliceSubtitle;

View File

@@ -16,7 +16,6 @@
package com.android.settings.slices;
import static com.android.settings.core.PreferenceXmlParserUtils.METADATA_ALLOW_DYNAMIC_SUMMARY_IN_SLICE;
import static com.android.settings.core.PreferenceXmlParserUtils.METADATA_CONTROLLER;
import static com.android.settings.core.PreferenceXmlParserUtils.METADATA_ICON;
import static com.android.settings.core.PreferenceXmlParserUtils.METADATA_KEY;
@@ -189,7 +188,6 @@ class SliceDataConverter {
| MetadataFlag.FLAG_NEED_PREF_ICON
| MetadataFlag.FLAG_NEED_PREF_SUMMARY
| MetadataFlag.FLAG_NEED_PLATFORM_SLICE_FLAG
| MetadataFlag.FLAG_ALLOW_DYNAMIC_SUMMARY_IN_SLICE
| MetadataFlag.FLAG_UNAVAILABLE_SLICE_SUBTITLE);
for (Bundle bundle : metadata) {
@@ -207,8 +205,6 @@ class SliceDataConverter {
final int sliceType = SliceBuilderUtils.getSliceType(mContext, controllerClassName,
key);
final boolean isPlatformSlice = bundle.getBoolean(METADATA_PLATFORM_SLICE_FLAG);
final boolean isDynamicSummaryAllowed = bundle.getBoolean(
METADATA_ALLOW_DYNAMIC_SUMMARY_IN_SLICE);
final String unavailableSliceSubtitle = bundle.getString(
METADATA_UNAVAILABLE_SLICE_SUBTITLE);
@@ -222,7 +218,6 @@ class SliceDataConverter {
.setFragmentName(fragmentName)
.setSliceType(sliceType)
.setPlatformDefined(isPlatformSlice)
.setDynamicSummaryAllowed(isDynamicSummaryAllowed)
.setUnavailableSliceSubtitle(unavailableSliceSubtitle)
.build();

View File

@@ -78,6 +78,13 @@ public interface Sliceable {
return false;
}
/**
* Whether or not summary comes from something dynamic (ie, not hardcoded in xml)
*/
default boolean useDynamicSliceSummary() {
return false;
}
/**
* Set the copy content to the clipboard and show the toast.
*/

View File

@@ -49,7 +49,6 @@ public class SlicesDatabaseAccessor {
IndexColumns.CONTROLLER,
IndexColumns.PLATFORM_SLICE,
IndexColumns.SLICE_TYPE,
IndexColumns.ALLOW_DYNAMIC_SUMMARY_IN_SLICE,
IndexColumns.UNAVAILABLE_SLICE_SUBTITLE,
};
@@ -166,8 +165,6 @@ public class SlicesDatabaseAccessor {
cursor.getColumnIndex(IndexColumns.CONTROLLER));
final boolean isPlatformDefined = cursor.getInt(
cursor.getColumnIndex(IndexColumns.PLATFORM_SLICE)) == TRUE;
final boolean isDynamicSummaryAllowed = cursor.getInt(
cursor.getColumnIndex(IndexColumns.ALLOW_DYNAMIC_SUMMARY_IN_SLICE)) == TRUE;
int sliceType = cursor.getInt(
cursor.getColumnIndex(IndexColumns.SLICE_TYPE));
final String unavailableSliceSubtitle = cursor.getString(
@@ -189,7 +186,6 @@ public class SlicesDatabaseAccessor {
.setUri(uri)
.setPlatformDefined(isPlatformDefined)
.setSliceType(sliceType)
.setDynamicSummaryAllowed(isDynamicSummaryAllowed)
.setUnavailableSliceSubtitle(unavailableSliceSubtitle)
.build();
}

View File

@@ -36,7 +36,7 @@ public class SlicesDatabaseHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "slices_index.db";
private static final String SHARED_PREFS_TAG = "slices_shared_prefs";
private static final int DATABASE_VERSION = 4;
private static final int DATABASE_VERSION = 5;
public interface Tables {
String TABLE_SLICES_INDEX = "slices_index";
@@ -94,12 +94,6 @@ public class SlicesDatabaseHelper extends SQLiteOpenHelper {
*/
String SLICE_TYPE = "slice_type";
/**
* Boolean flag, {@code true} when the slice object prefers using the dynamic summary from
* preference controller.
*/
String ALLOW_DYNAMIC_SUMMARY_IN_SLICE = "allow_dynamic_summary_in_slice";
/**
* Customized subtitle if it's a unavailable slice
*/
@@ -129,8 +123,6 @@ public class SlicesDatabaseHelper extends SQLiteOpenHelper {
", " +
IndexColumns.SLICE_TYPE +
", " +
IndexColumns.ALLOW_DYNAMIC_SUMMARY_IN_SLICE +
", " +
IndexColumns.UNAVAILABLE_SLICE_SUBTITLE +
");";

View File

@@ -110,8 +110,6 @@ class SlicesIndexer implements Runnable {
values.put(IndexColumns.CONTROLLER, dataRow.getPreferenceController());
values.put(IndexColumns.PLATFORM_SLICE, dataRow.isPlatformDefined());
values.put(IndexColumns.SLICE_TYPE, dataRow.getSliceType());
values.put(IndexColumns.ALLOW_DYNAMIC_SUMMARY_IN_SLICE,
dataRow.isDynamicSummaryAllowed());
values.put(IndexColumns.UNAVAILABLE_SLICE_SUBTITLE,
dataRow.getUnavailableSliceSubtitle());

View File

@@ -33,6 +33,7 @@ import android.net.Network;
import android.net.NetworkInfo;
import android.net.NetworkInfo.State;
import android.net.NetworkRequest;
import android.net.NetworkTemplate;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.os.Bundle;
@@ -60,6 +61,8 @@ import com.android.settings.SettingsActivity;
import com.android.settings.core.FeatureFlags;
import com.android.settings.core.SubSettingLauncher;
import com.android.settings.dashboard.SummaryLoader;
import com.android.settings.datausage.DataUsageUtils;
import com.android.settings.datausage.DataUsagePreference;
import com.android.settings.location.ScanningSettings;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
@@ -115,6 +118,8 @@ public class WifiSettings extends RestrictedSettingsFragment
private static final String PREF_KEY_CONFIGURE_WIFI_SETTINGS = "configure_settings";
private static final String PREF_KEY_SAVED_NETWORKS = "saved_networks";
private static final String PREF_KEY_STATUS_MESSAGE = "wifi_status_message";
@VisibleForTesting
static final String PREF_KEY_DATA_USAGE = "wifi_data_usage";
private static final int REQUEST_CODE_WIFI_DPP_ENROLLEE_QR_CODE_SCANNER = 0;
@@ -181,6 +186,8 @@ public class WifiSettings extends RestrictedSettingsFragment
Preference mConfigureWifiSettingsPreference;
@VisibleForTesting
Preference mSavedNetworksPreference;
@VisibleForTesting
DataUsagePreference mDataUsagePreference;
private LinkablePreference mStatusMessagePreference;
// For Search
@@ -237,6 +244,11 @@ public class WifiSettings extends RestrictedSettingsFragment
mAddWifiNetworkPreference = new AddWifiNetworkPreference(getPrefContext());
mStatusMessagePreference = (LinkablePreference) findPreference(PREF_KEY_STATUS_MESSAGE);
mUserBadgeCache = new AccessPointPreference.UserBadgeCache(getPackageManager());
mDataUsagePreference = findPreference(PREF_KEY_DATA_USAGE);
mDataUsagePreference.setVisible(DataUsageUtils.hasWifiRadio(getContext()));
mDataUsagePreference.setTemplate(NetworkTemplate.buildTemplateWifiWildcard(),
0 /*subId*/,
null /*service*/);
}
@Override

View File

@@ -838,7 +838,7 @@ public class WifiDetailPreferenceController extends AbstractPreferenceController
* Returns whether the user can sign into the network represented by this preference.
*/
private boolean canSignIntoNetwork() {
return WifiUtils.canSignIntoNetwork(mNetworkCapabilities);
return mAccessPoint.isActive() && WifiUtils.canSignIntoNetwork(mNetworkCapabilities);
}
/**

View File

@@ -140,6 +140,11 @@ public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment impl
break;
case MESSAGE_SCAN_WIFI_DPP_SUCCESS:
if (mCamera != null) {
mCamera.stop();
}
mDecorateView.setFocused(true);
mErrorMessage.setVisibility(View.INVISIBLE);
if (mScanWifiDppSuccessListener == null) {
@@ -154,15 +159,24 @@ public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment impl
mSummary.sendAccessibilityEvent(
AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
}
WifiDppUtils.triggerVibrationForQrCodeRecognition(getContext());
break;
case MESSAGE_SCAN_ZXING_WIFI_FORMAT_SUCCESS:
if (mCamera != null) {
mCamera.stop();
}
mDecorateView.setFocused(true);
mErrorMessage.setVisibility(View.INVISIBLE);
final WifiNetworkConfig wifiNetworkConfig = (WifiNetworkConfig)msg.obj;
mWifiConfiguration = wifiNetworkConfig.getWifiConfigurationOrNull();
wifiNetworkConfig.connect(getContext(),
/* listener */ WifiDppQrCodeScannerFragment.this);
WifiDppUtils.triggerVibrationForQrCodeRecognition(getContext());
break;
default:
@@ -409,11 +423,6 @@ public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment impl
}
private void handleWifiDpp() {
if (mCamera != null) {
mCamera.stop();
}
mDecorateView.setFocused(true);
Message message = mHandler.obtainMessage(MESSAGE_SCAN_WIFI_DPP_SUCCESS);
message.obj = new WifiQrCode(mWifiQrCode.getQrCode());
@@ -421,11 +430,6 @@ public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment impl
}
private void handleZxingWifiFormat() {
if (mCamera != null) {
mCamera.stop();
}
mDecorateView.setFocused(true);
Message message = mHandler.obtainMessage(MESSAGE_SCAN_ZXING_WIFI_FORMAT_SUCCESS);
message.obj = new WifiQrCode(mWifiQrCode.getQrCode()).getWifiNetworkConfig();

View File

@@ -26,6 +26,8 @@ import android.net.wifi.WifiManager;
import android.os.CancellationSignal;
import android.os.Handler;
import android.os.Looper;
import android.os.VibrationEffect;
import android.os.Vibrator;
import android.text.TextUtils;
import android.util.FeatureFlagUtils;
@@ -35,6 +37,8 @@ import com.android.settingslib.wifi.AccessPoint;
import java.util.List;
import java.time.Duration;
/**
* Here are the items shared by both WifiDppConfiguratorActivity & WifiDppEnrolleeActivity
*
@@ -94,6 +98,8 @@ public class WifiDppUtils {
*/
public static final int EASY_CONNECT_EVENT_SUCCESS = 1;
private static final Duration VIBRATE_DURATION_QR_CODE_RECOGNITION = Duration.ofMillis(3);
/**
* Returns whether the device support WiFi DPP.
*/
@@ -386,4 +392,14 @@ public class WifiDppUtils {
}
return false;
}
static void triggerVibrationForQrCodeRecognition(Context context) {
Vibrator vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
if (vibrator == null) {
return;
}
vibrator.vibrate(VibrationEffect.createOneShot(
VIBRATE_DURATION_QR_CODE_RECOGNITION.toMillis(),
VibrationEffect.DEFAULT_AMPLITUDE));
}
}

View File

@@ -25,15 +25,13 @@
android:title="title"
android:icon="@drawable/ic_android"
android:summary="summary1"
settings:controller="com.android.settings.core.BadPreferenceController"
settings:allowDynamicSummaryInSlice="true"/>
settings:controller="com.android.settings.core.BadPreferenceController"/>
<Preference
android:key="key2"
android:title="title"
android:icon="@drawable/ic_android"
android:summary="summary2"
settings:controller="com.android.settings.slices.FakePreferenceController"
settings:allowDynamicSummaryInSlice="true"/>
settings:controller="com.android.settings.slices.FakePreferenceController"/>
</PreferenceScreen>

View File

@@ -27,7 +27,6 @@
settings:controller="com.android.settings.slices.FakePreferenceController"
settings:keywords="a, b, c"
settings:platform_slice="true"
settings:allowDynamicSummaryInSlice="true"
settings:unavailableSliceSubtitle="subtitleOfUnavailableSlice"/>
</PreferenceScreen>

View File

@@ -172,8 +172,7 @@ public class SetupFingerprintEnrollIntroductionTest {
layout.getMixin(FooterBarMixin.class).getSecondaryButtonView();
skipButton.performClick();
ShadowActivity shadowActivity = Shadows.shadowOf(activity);
assertThat(shadowActivity.getResultIntent()).isNull();
assertThat(Shadows.shadowOf(activity).getResultIntent()).isNull();
}
@Test
@@ -182,7 +181,10 @@ public class SetupFingerprintEnrollIntroductionTest {
SetupFingerprintEnrollIntroduction activity = mController.create().resume().get();
activity.onActivityResult(BiometricEnrollIntroduction.BIOMETRIC_FIND_SENSOR_REQUEST,
BiometricEnrollBase.RESULT_FINISHED, null);
assertThat(Shadows.shadowOf(activity).getResultIntent()).isNull();
ShadowActivity shadowActivity = Shadows.shadowOf(activity);
assertThat(shadowActivity.getResultIntent()).isNotNull();
assertThat(shadowActivity.getResultIntent().hasExtra(
SetupChooseLockGenericFragment.EXTRA_PASSWORD_QUALITY)).isFalse();
}
@Test
@@ -201,7 +203,8 @@ public class SetupFingerprintEnrollIntroductionTest {
SetupFingerprintEnrollIntroduction activity = mController.create().resume().get();
activity.onActivityResult(BiometricEnrollIntroduction.BIOMETRIC_FIND_SENSOR_REQUEST,
BiometricEnrollBase.RESULT_FINISHED, null);
assertThat(Shadows.shadowOf(activity).getResultIntent()).isNull();
ShadowActivity shadowActivity = Shadows.shadowOf(activity);
assertThat(shadowActivity.getResultIntent()).isNull();
}
@Test

View File

@@ -29,4 +29,9 @@ public class BadPreferenceController extends BasePreferenceController {
public int getAvailabilityStatus() {
return AVAILABLE;
}
@Override
public boolean useDynamicSliceSummary() {
return true;
}
}

View File

@@ -16,7 +16,6 @@
package com.android.settings.core;
import static com.android.settings.core.PreferenceXmlParserUtils.METADATA_ALLOW_DYNAMIC_SUMMARY_IN_SLICE;
import static com.android.settings.core.PreferenceXmlParserUtils.METADATA_APPEND;
import static com.android.settings.core.PreferenceXmlParserUtils.METADATA_KEY;
import static com.android.settings.core.PreferenceXmlParserUtils.METADATA_KEYWORDS;
@@ -293,30 +292,6 @@ public class PreferenceXmlParserUtilsTest {
assertThat(foundKey).isTrue();
}
@Test
@Config(qualifiers = "mcc999")
public void extractMetadata_requestIsDynamicSummaryAllowed_shouldDefaultToFalse()
throws Exception {
final List<Bundle> metadata = PreferenceXmlParserUtils.extractMetadata(mContext,
R.xml.display_settings, MetadataFlag.FLAG_ALLOW_DYNAMIC_SUMMARY_IN_SLICE);
for (Bundle bundle : metadata) {
assertThat(bundle.getBoolean(METADATA_ALLOW_DYNAMIC_SUMMARY_IN_SLICE)).isFalse();
}
}
@Test
@Config(qualifiers = "mcc998")
public void extractMetadata_requestIsDynamicSummaryAllowed_shouldReturnAttributeValue()
throws Exception {
final List<Bundle> metadata = PreferenceXmlParserUtils.extractMetadata(mContext,
R.xml.location_settings, MetadataFlag.FLAG_ALLOW_DYNAMIC_SUMMARY_IN_SLICE);
for (Bundle bundle : metadata) {
assertThat(bundle.getBoolean(METADATA_ALLOW_DYNAMIC_SUMMARY_IN_SLICE)).isTrue();
}
}
@Test
@Config(qualifiers = "mcc999")
public void extractMetadata_requestAppendProperty_shouldDefaultToFalse()

View File

@@ -16,17 +16,22 @@
package com.android.settings.development;
import static com.android.settings.development.AllowBackgroundActivityStartsPreferenceController.KEY_DEFAULT_BACKGROUND_ACTIVITY_STARTS_ENABLED;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.provider.DeviceConfig;
import android.provider.Settings;
import androidx.preference.PreferenceScreen;
import androidx.preference.SwitchPreference;
import com.android.settings.testutils.shadow.ShadowDeviceConfig;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -34,8 +39,10 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = {ShadowDeviceConfig.class})
public class AllowBackgroundActivityStartsPreferenceControllerTest {
@Mock
@@ -60,20 +67,14 @@ public class AllowBackgroundActivityStartsPreferenceControllerTest {
public void onPreferenceChange_settingEnabled_allowBackgroundActivityStartsShouldBeOn() {
mController.onPreferenceChange(mPreference, true /* new value */);
final int mode = Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.BACKGROUND_ACTIVITY_STARTS_ENABLED, 1 /* default */);
assertThat(mode).isEqualTo(1);
assertThat(getModeFroMSettings()).isEqualTo(1);
}
@Test
public void onPreferenceChange_settingDisabled_allowBackgroundActivityStartsShouldBeOff() {
mController.onPreferenceChange(mPreference, false /* new value */);
final int mode = Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.BACKGROUND_ACTIVITY_STARTS_ENABLED, 1 /* default */);
assertThat(mode).isEqualTo(0);
assertThat(getModeFroMSettings()).isEqualTo(0);
}
@Test
@@ -83,7 +84,7 @@ public class AllowBackgroundActivityStartsPreferenceControllerTest {
mController.updateState(mPreference);
verify(mPreference).setChecked(false);
}
}
@Test
public void updateState_settingEnabled_preferenceShouldBeChecked() {
@@ -95,11 +96,64 @@ public class AllowBackgroundActivityStartsPreferenceControllerTest {
}
@Test
public void onDeveloperOptionsSwitchDisabled_shouldDisablePreference() {
public void updateState_settingReset_defaultDisabled_preferenceShouldNotBeChecked() {
setDefault(false);
mController.updateState(mPreference);
verify(mPreference).setChecked(false);
}
@Test
public void updateState_settingReset_defaultEnabled_preferenceShouldBeChecked() {
setDefault(true);
mController.updateState(mPreference);
verify(mPreference).setChecked(true);
}
@Test
public void onDeveloperOptionsSwitchDisabled_noDefault_shouldResetPreference() {
mController.onDeveloperOptionsSwitchDisabled();
verify(mPreference).setChecked(true);
verify(mPreference).setEnabled(false);
assertThat(getModeFroMSettings()).isEqualTo(-1);
}
@Test
public void onDeveloperOptionsSwitchDisabled_defaultDisabled_shouldResetPreference() {
setDefault(false);
mController.onDeveloperOptionsSwitchDisabled();
verify(mPreference).setChecked(false);
verify(mPreference).setEnabled(false);
assertThat(getModeFroMSettings()).isEqualTo(-1);
}
@Test
public void onDeveloperOptionsSwitchDisabled_defaultEnabled_shouldResetPreference() {
setDefault(true);
mController.onDeveloperOptionsSwitchDisabled();
verify(mPreference).setChecked(true);
verify(mPreference).setEnabled(false);
assertThat(getModeFroMSettings()).isEqualTo(-1);
}
private int getModeFroMSettings() {
return Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.BACKGROUND_ACTIVITY_STARTS_ENABLED, 999 /* default */);
}
private void setDefault(boolean defaultEnabled) {
DeviceConfig.setProperty(
DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
KEY_DEFAULT_BACKGROUND_ACTIVITY_STARTS_ENABLED,
Boolean.toString(defaultEnabled),
false /* makeDefault */);
}
}

View File

@@ -16,21 +16,25 @@
package com.android.settings.homepage.contextualcards;
import static com.android.settings.homepage.contextualcards.ContextualCardManager.KEY_CONTEXTUAL_CARDS;
import static com.android.settings.homepage.contextualcards.slices.SliceContextualCardRenderer.VIEW_TYPE_DEFERRED_SETUP;
import static com.android.settings.homepage.contextualcards.slices.SliceContextualCardRenderer.VIEW_TYPE_FULL_WIDTH;
import static com.android.settings.homepage.contextualcards.slices.SliceContextualCardRenderer.VIEW_TYPE_HALF_WIDTH;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyMap;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.provider.Settings;
import android.util.ArrayMap;
@@ -39,6 +43,8 @@ import com.android.settings.homepage.contextualcards.conditional.ConditionHeader
import com.android.settings.homepage.contextualcards.conditional.ConditionalContextualCard;
import com.android.settings.intelligence.ContextualCardProto;
import com.android.settings.slices.CustomSliceRegistry;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import org.junit.Before;
import org.junit.Test;
@@ -62,6 +68,8 @@ public class ContextualCardManagerTest {
@Mock
ContextualCardUpdateListener mListener;
@Mock
Lifecycle mLifecycle;
private Context mContext;
private ContextualCardManager mManager;
@@ -70,9 +78,71 @@ public class ContextualCardManagerTest {
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application;
final ContextualCardsFragment fragment = new ContextualCardsFragment();
mManager = new ContextualCardManager(mContext, fragment.getSettingsLifecycle(),
null /* bundle */);
mManager = new ContextualCardManager(mContext, mLifecycle, null /* bundle */);
}
@Test
public void constructor_noSavedInstanceState_shouldSetFirstLaunch() {
assertThat(mManager.mIsFirstLaunch).isTrue();
}
@Test
public void constructor_noSavedInstanceState_shouldNotHaveSavedCards() {
assertThat(mManager.mSavedCards).isNull();
}
@Test
public void constructor_hasSavedInstanceState_shouldContainExpectedSavedCards() {
final Bundle outState = new Bundle();
final ArrayList<String> cards = getContextualCardList().stream()
.map(ContextualCard::getName)
.collect(Collectors.toCollection(ArrayList::new));
outState.putStringArrayList(KEY_CONTEXTUAL_CARDS, cards);
mManager = new ContextualCardManager(mContext, mLifecycle, outState);
final List<String> actualCards = mManager.mSavedCards.stream().collect(Collectors.toList());
final List<String> expectedCards = Arrays.asList("test_wifi", "test_flashlight",
"test_connected", "test_gesture", "test_battery");
assertThat(actualCards).containsExactlyElementsIn(expectedCards);
}
@Test
public void constructor_hasSettingsCustomCards_shouldSetUpCustomControllers() {
final ControllerRendererPool pool = mManager.getControllerRendererPool();
final List<Integer> actual = pool.getControllers().stream()
.map(ContextualCardController::getCardType)
.collect(Collectors.toList());
final List<Integer> expected = Arrays.asList(ContextualCard.CardType.CONDITIONAL,
ContextualCard.CardType.LEGACY_SUGGESTION);
assertThat(actual).containsExactlyElementsIn(expected);
}
@Test
public void setupController_notLifecycleObserverInstance_shouldNotAttachToLifecycle() {
// 3 invocations in constructor(ContextualCardManager, Conditional and LegacySuggestion)
verify(mLifecycle, times(3)).addObserver(any(LifecycleObserver.class));
mManager.setupController(ContextualCard.CardType.SLICE);
// After 3 times call in the constructor, addObserver() shouldn't be called again.
verify(mLifecycle, times(3)).addObserver(any(LifecycleObserver.class));
}
@Test
public void sortCards_shouldBeDescendingOrder() {
final List<ContextualCard> cards = new ArrayList<>();
final ContextualCard card1 =
buildContextualCard(TEST_SLICE_URI).mutate().setRankingScore(99.0).build();
final ContextualCard card2 =
buildContextualCard("context://test/test2").mutate().setRankingScore(88.0).build();
cards.add(card1);
cards.add(card2);
final List<ContextualCard> sortedCards = mManager.sortCards(cards);
assertThat(sortedCards.get(0).getSliceUri()).isEqualTo(Uri.parse(TEST_SLICE_URI));
}
@Test
@@ -128,7 +198,7 @@ public class ContextualCardManagerTest {
@Test
public void getCardLoaderTimeout_noConfiguredTimeout_shouldReturnDefaultTimeout() {
final long timeout = mManager.getCardLoaderTimeout(mContext);
final long timeout = mManager.getCardLoaderTimeout();
assertThat(timeout).isEqualTo(ContextualCardManager.CARD_CONTENT_LOADER_TIMEOUT_MS);
}
@@ -139,7 +209,7 @@ public class ContextualCardManagerTest {
Settings.Global.putLong(mContext.getContentResolver(),
ContextualCardManager.KEY_GLOBAL_CARD_LOADER_TIMEOUT, configuredTimeout);
final long timeout = mManager.getCardLoaderTimeout(mContext);
final long timeout = mManager.getCardLoaderTimeout();
assertThat(timeout).isEqualTo(configuredTimeout);
}
@@ -151,6 +221,7 @@ public class ContextualCardManagerTest {
doNothing().when(manager).onContextualCardUpdated(anyMap());
manager.onFinishCardLoading(new ArrayList<>());
verify(manager).onContextualCardUpdated(nullable(Map.class));
}
@@ -161,6 +232,7 @@ public class ContextualCardManagerTest {
doNothing().when(manager).onContextualCardUpdated(anyMap());
manager.onFinishCardLoading(new ArrayList<>());
verify(manager, never()).onContextualCardUpdated(anyMap());
}
@@ -177,8 +249,18 @@ public class ContextualCardManagerTest {
assertThat(mManager.mContextualCards).hasSize(2);
}
@Test
public void onFinishCardLoading_newLaunch_shouldSetIsFirstLaunchBackToFalse() {
assertThat(mManager.mIsFirstLaunch).isTrue();
mManager.onFinishCardLoading(new ArrayList<>());
assertThat(mManager.mIsFirstLaunch).isFalse();
}
@Test
public void onFinishCardLoading_hasSavedCard_shouldOnlyShowSavedCard() {
// test screen rotation
mManager.setListener(mListener);
final List<String> savedCardNames = new ArrayList<>();
savedCardNames.add(TEST_SLICE_NAME);
@@ -204,7 +286,8 @@ public class ContextualCardManagerTest {
}
@Test
public void onFinishCardLoading_reloadData_shouldOnlyShowOldCard() {
public void onFinishCardLoading_reloadData_hasNewCard_shouldOnlyShowOldCard() {
// test card dismissal cases
mManager.setListener(mListener);
mManager.mIsFirstLaunch = false;
//old card
@@ -228,7 +311,6 @@ public class ContextualCardManagerTest {
assertThat(actualCards).containsExactlyElementsIn(expectedCards);
}
@Test
public void getCardsWithViewType_noSuggestionCards_shouldNotHaveHalfCards() {
final List<Integer> categories = Arrays.asList(
@@ -411,6 +493,17 @@ public class ContextualCardManagerTest {
}
}
@Test
public void getCardsToKeep_hasSavedCard_shouldResetSavedCards() {
final List<String> savedCardNames = new ArrayList<>();
savedCardNames.add(TEST_SLICE_NAME);
mManager.mSavedCards = savedCardNames;
mManager.getCardsToKeep(getContextualCardList());
assertThat(mManager.mSavedCards).isNull();
}
private ContextualCard buildContextualCard(String sliceUri) {
return new ContextualCard.Builder()
.setName(TEST_SLICE_NAME)

View File

@@ -0,0 +1,187 @@
/*
* Copyright (C) 2019 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.homepage.contextualcards;
import static com.android.settings.homepage.contextualcards.slices.SliceContextualCardRenderer.VIEW_TYPE_DEFERRED_SETUP;
import static com.android.settings.homepage.contextualcards.slices.SliceContextualCardRenderer.VIEW_TYPE_FULL_WIDTH;
import static com.google.common.truth.Truth.assertThat;
import android.app.Activity;
import android.net.Uri;
import android.util.ArrayMap;
import android.view.LayoutInflater;
import android.view.View;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.android.settings.R;
import com.android.settings.homepage.contextualcards.conditional.ConditionContextualCardRenderer;
import com.android.settings.homepage.contextualcards.conditional.ConditionContextualCardRenderer.ConditionalCardHolder;
import com.android.settings.homepage.contextualcards.conditional.ConditionalContextualCard;
import com.android.settings.homepage.contextualcards.slices.SliceContextualCardRenderer;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.MockitoAnnotations;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.android.controller.ActivityController;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@RunWith(RobolectricTestRunner.class)
public class ContextualCardsAdapterTest {
private static final Uri TEST_SLICE_URI = Uri.parse("content://test/test");
private static final String TEST_SLICE_NAME = "test_name";
private Activity mActivity;
private ContextualCardManager mManager;
private ContextualCardsAdapter mAdapter;
@Before
public void setUp() {
final ActivityController<Activity> activityController = Robolectric.buildActivity(
Activity.class);
mActivity = activityController.get();
mActivity.setTheme(R.style.Theme_Settings_Home);
activityController.create();
final ContextualCardsFragment fragment = new ContextualCardsFragment();
mManager = new ContextualCardManager(mActivity, fragment.getSettingsLifecycle(),
null /* bundle */);
mAdapter = new ContextualCardsAdapter(mActivity, fragment, mManager);
}
@Test
public void getItemViewType_sliceFullWidth_shouldReturnSliceFullWidthViewType() {
mAdapter.mContextualCards.addAll(getContextualCardList());
final int viewType = mAdapter.getItemViewType(1);
assertThat(viewType).isEqualTo(SliceContextualCardRenderer.VIEW_TYPE_FULL_WIDTH);
}
@Test
public void getItemCount_cardList_shouldReturnListSize() {
final List<ContextualCard> cards = getContextualCardList();
mAdapter.mContextualCards.addAll(cards);
final int count = mAdapter.getItemCount();
assertThat(count).isEqualTo(cards.size());
}
@Test
public void onCreateViewHolder_conditionalCard_shouldReturnConditionalCardHolder() {
final RecyclerView recyclerView = new RecyclerView(mActivity);
recyclerView.setLayoutManager(new LinearLayoutManager(mActivity));
final RecyclerView.ViewHolder holder = mAdapter.onCreateViewHolder(recyclerView,
ConditionContextualCardRenderer.VIEW_TYPE_FULL_WIDTH);
assertThat(holder).isInstanceOf(ConditionalCardHolder.class);
}
@Test
public void onBindViewHolder_conditionalCard_shouldSetTestTitle() {
mAdapter.mContextualCards.add(buildConditionContextualCard());
final RecyclerView recyclerView = new RecyclerView(mActivity);
recyclerView.setLayoutManager(new LinearLayoutManager(mActivity));
final View view = LayoutInflater.from(mActivity)
.inflate(ConditionContextualCardRenderer.VIEW_TYPE_FULL_WIDTH, recyclerView, false);
final ConditionalCardHolder holder = new ConditionalCardHolder(view);
mAdapter.onBindViewHolder(holder, 0);
assertThat(holder.title.getText()).isEqualTo("test_title");
}
@Test
public void onContextualCardUpdated_emptyList_shouldClearCardList() {
mAdapter.mContextualCards.addAll(getContextualCardList());
final Map<Integer, List<ContextualCard>> cardsToUpdate = new ArrayMap<>();
final List<ContextualCard> newCardList = new ArrayList<>();
cardsToUpdate.put(ContextualCard.CardType.DEFAULT, newCardList);
mAdapter.onContextualCardUpdated(cardsToUpdate);
assertThat(mAdapter.mContextualCards).isEmpty();
}
@Test
public void onContextualCardUpdated_newCardList_shouldUpdateCardList() {
mAdapter.mContextualCards.addAll(getContextualCardList());
final Map<Integer, List<ContextualCard>> cardsToUpdate = new ArrayMap<>();
final List<ContextualCard> newCardList = new ArrayList<>();
newCardList.add(buildContextualCard(TEST_SLICE_URI));
cardsToUpdate.put(ContextualCard.CardType.DEFAULT, newCardList);
mAdapter.onContextualCardUpdated(cardsToUpdate);
assertThat(mAdapter.mContextualCards).isEqualTo(newCardList);
}
@Test
public void onSwiped_shouldSetIsPendingDismissToTrue() {
mAdapter.mContextualCards.addAll(getContextualCardList());
assertThat(mAdapter.mContextualCards.get(0).isPendingDismiss()).isFalse();
mAdapter.onSwiped(0);
assertThat(mAdapter.mContextualCards.get(0).isPendingDismiss()).isTrue();
}
private List<ContextualCard> getContextualCardList() {
final List<ContextualCard> cards = new ArrayList<>();
cards.add(new ContextualCard.Builder()
.setName("test_name")
.setCardType(ContextualCard.CardType.SLICE)
.setSliceUri(TEST_SLICE_URI)
.setViewType(VIEW_TYPE_DEFERRED_SETUP)
.build());
cards.add(new ContextualCard.Builder()
.setName("test_name_1")
.setCardType(ContextualCard.CardType.SLICE)
.setSliceUri(TEST_SLICE_URI)
.setViewType(SliceContextualCardRenderer.VIEW_TYPE_FULL_WIDTH)
.build());
return cards;
}
private ContextualCard buildContextualCard(Uri sliceUri) {
return new ContextualCard.Builder()
.setName(TEST_SLICE_NAME)
.setCardType(ContextualCard.CardType.SLICE)
.setSliceUri(sliceUri)
.setViewType(VIEW_TYPE_FULL_WIDTH)
.build();
}
private ContextualCard buildConditionContextualCard() {
return new ConditionalContextualCard.Builder()
.setConditionId(123)
.setName("test_name")
.setTitleText("test_title")
.setViewType(ConditionContextualCardRenderer.VIEW_TYPE_FULL_WIDTH)
.build();
}
}

View File

@@ -16,15 +16,9 @@
package com.android.settings.homepage.contextualcards.slices;
import static android.content.Context.MODE_PRIVATE;
import static com.android.settings.homepage.contextualcards.slices.BatteryFixSlice.KEY_CURRENT_TIPS_TYPE;
import static com.android.settings.homepage.contextualcards.slices.BatteryFixSlice.PREFS;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.content.SharedPreferences;
import androidx.slice.Slice;
import androidx.slice.SliceMetadata;
@@ -74,24 +68,12 @@ public class BatteryFixSliceTest {
ShadowBatteryTipLoader.reset();
}
@Test
public void readBatteryTipFromPref_readCorrectValue() {
int target = 111;
final SharedPreferences.Editor editor = mContext.getSharedPreferences(PREFS,
MODE_PRIVATE).edit();
editor.putInt(KEY_CURRENT_TIPS_TYPE, target);
editor.commit();
assertThat(BatteryFixSlice.readBatteryTipAvailabilityCache(mContext)).isEqualTo(target);
}
@Test
@Config(shadows = {
ShadowBatteryStatsHelperLoader.class,
ShadowBatteryTipLoader.class
})
public void updateBatteryTipAvailabilityCache_writeCorrectValue() {
public void updateBatteryTipAvailabilityCache_hasImportantTip_shouldReturnTrue() {
final List<BatteryTip> tips = new ArrayList<>();
tips.add(new LowBatteryTip(BatteryTip.StateType.INVISIBLE, false, ""));
tips.add(new EarlyWarningTip(BatteryTip.StateType.NEW, false));
@@ -99,8 +81,7 @@ public class BatteryFixSliceTest {
BatteryFixSlice.updateBatteryTipAvailabilityCache(mContext);
assertThat(BatteryFixSlice.readBatteryTipAvailabilityCache(mContext)).isEqualTo(
BatteryTip.TipType.BATTERY_SAVER);
assertThat(BatteryFixSlice.isBatteryTipAvailableFromCache(mContext)).isTrue();
}
@Test
@@ -111,7 +92,7 @@ public class BatteryFixSliceTest {
public void getSlice_unimportantSlice_shouldSkip() {
final List<BatteryTip> tips = new ArrayList<>();
tips.add(new LowBatteryTip(BatteryTip.StateType.INVISIBLE, false, ""));
tips.add(new EarlyWarningTip(BatteryTip.StateType.NEW, false));
tips.add(new EarlyWarningTip(BatteryTip.StateType.HANDLED, false));
ShadowBatteryTipLoader.setBatteryTips(tips);
BatteryFixSlice.updateBatteryTipAvailabilityCache(mContext);

View File

@@ -23,13 +23,14 @@ import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.PersistableBundle;
import android.telephony.CarrierConfigManager;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import androidx.preference.Preference;
import androidx.preference.SwitchPreference;
import com.android.settings.R;
@@ -39,6 +40,7 @@ import org.junit.runner.RunWith;
import org.mockito.Answers;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
@@ -53,10 +55,12 @@ public class AutoSelectPreferenceControllerTest {
private SubscriptionManager mSubscriptionManager;
@Mock
private CarrierConfigManager mCarrierConfigManager;
@Mock
private ProgressDialog mProgressDialog;
private PersistableBundle mCarrierConfig;
private AutoSelectPreferenceController mController;
private Preference mPreference;
private SwitchPreference mSwitchPreference;
private Context mContext;
@Before
@@ -75,18 +79,22 @@ public class AutoSelectPreferenceControllerTest {
true);
when(mCarrierConfigManager.getConfigForSubId(SUB_ID)).thenReturn(mCarrierConfig);
mPreference = new Preference(mContext);
mSwitchPreference = new SwitchPreference(mContext);
mController = new AutoSelectPreferenceController(mContext, "auto_select");
mController.mProgressDialog = mProgressDialog;
mController.mSwitchPreference = mSwitchPreference;
mController.init(SUB_ID);
}
@Test
public void setChecked_isChecked_updateValue() {
public void setChecked_isChecked_showProgressDialog() {
when(mTelephonyManager.getNetworkSelectionMode()).thenReturn(
TelephonyManager.NETWORK_SELECTION_MODE_AUTO);
assertThat(mController.setChecked(true)).isTrue();
assertThat(mController.setChecked(true)).isFalse();
Robolectric.flushBackgroundThreadScheduler();
verify(mProgressDialog).show();
verify(mTelephonyManager).setNetworkSelectionModeAutomatic();
}
@@ -94,9 +102,9 @@ public class AutoSelectPreferenceControllerTest {
public void updateState_isRoaming_enabled() {
when(mTelephonyManager.getServiceState().getRoaming()).thenReturn(true);
mController.updateState(mPreference);
mController.updateState(mSwitchPreference);
assertThat(mPreference.isEnabled()).isTrue();
assertThat(mSwitchPreference.isEnabled()).isTrue();
}
@Test
@@ -104,10 +112,10 @@ public class AutoSelectPreferenceControllerTest {
when(mTelephonyManager.getServiceState().getRoaming()).thenReturn(false);
doReturn(OPERATOR_NAME).when(mTelephonyManager).getSimOperatorName();
mController.updateState(mPreference);
mController.updateState(mSwitchPreference);
assertThat(mPreference.isEnabled()).isFalse();
assertThat(mPreference.getSummary()).isEqualTo(
assertThat(mSwitchPreference.isEnabled()).isFalse();
assertThat(mSwitchPreference.getSummary()).isEqualTo(
mContext.getString(R.string.manual_mode_disallowed_summary,
mTelephonyManager.getSimOperatorName()));
}

View File

@@ -40,4 +40,9 @@ public class FakePreferenceController extends BasePreferenceController {
public boolean isSliceable() {
return true;
}
@Override
public boolean useDynamicSliceSummary() {
return true;
}
}

View File

@@ -69,7 +69,6 @@ public class SliceBuilderUtilsTest {
private final Class SLIDER_CONTROLLER = FakeSliderController.class;
private final Class COPYABLE_CONTROLLER = FakeCopyableController.class;
private final Class CONTEXT_CONTROLLER = FakeContextOnlyPreferenceController.class;
private final boolean IS_DYNAMIC_SUMMARY_ALLOWED = false;
private final String INTENT_PATH = SettingsSlicesContract.PATH_SETTING_INTENT + "/" + KEY;
private final String ACTION_PATH = SettingsSlicesContract.PATH_SETTING_ACTION + "/" + KEY;
@@ -206,7 +205,7 @@ public class SliceBuilderUtilsTest {
@Test
public void getDynamicSummary_allowDynamicSummary_returnsControllerSummary() {
final SliceData data = getDummyData(true /*isDynamicSummaryAllowed*/);
final SliceData data = getDummyData();
final FakePreferenceController controller = spy(
new FakePreferenceController(mContext, KEY));
final String controllerSummary = "new_Summary";
@@ -219,27 +218,17 @@ public class SliceBuilderUtilsTest {
@Test
public void getDynamicSummary_allowDynamicSummary_nullSummary_returnsNull() {
final SliceData data = getDummyData(true /*isDynamicSummaryAllowed*/);
final SliceData data = getDummyData();
final FakePreferenceController controller = spy(
new FakePreferenceController(mContext, KEY));
final String controllerSummary = null;
doReturn(controllerSummary).when(controller).getSummary();
doReturn(null).when(controller).getSummary();
final CharSequence summary = SliceBuilderUtils.getSubtitleText(mContext, controller, data);
assertThat(summary).isNull();
}
@Test
public void getDynamicSummary_returnsScreenTitle() {
final SliceData data = getDummyData();
final FakePreferenceController controller = new FakePreferenceController(mContext, KEY);
final CharSequence summary = SliceBuilderUtils.getSubtitleText(mContext, controller, data);
assertThat(summary).isEqualTo(data.getScreenTitle());
}
@Test
public void getDynamicSummary_noScreenTitle_returnsPrefControllerSummary() {
final SliceData data = getDummyData("", "");
@@ -272,17 +261,7 @@ public class SliceBuilderUtilsTest {
final FakePreferenceController controller = new FakePreferenceController(mContext, KEY);
final CharSequence summary = SliceBuilderUtils.getSubtitleText(mContext, controller, data);
assertThat(summary).isEqualTo("");
}
@Test
public void
getDynamicSummary_emptyScreenTitle_placeHolderControllerSummary_returnsEmptyString() {
final SliceData data = getDummyData(mContext.getString(R.string.summary_placeholder), null);
final FakePreferenceController controller = new FakePreferenceController(mContext, KEY);
final CharSequence summary = SliceBuilderUtils.getSubtitleText(mContext, controller, data);
assertThat(summary).isEqualTo("");
assertThat(summary).isNull();
}
@Test
@@ -295,7 +274,7 @@ public class SliceBuilderUtilsTest {
CharSequence summary = SliceBuilderUtils.getSubtitleText(mContext, controller, data);
assertThat(summary).isEqualTo("");
assertThat(summary).isEqualTo(summaryPlaceholder);
}
@Test
@@ -449,7 +428,7 @@ public class SliceBuilderUtilsTest {
R.drawable.ic_settings_accent).toIcon().getResId();
final SliceData data = getDummyData(FakeUnavailablePreferenceController.class,
SUMMARY, SliceData.SliceType.SWITCH, SCREEN_TITLE, 0 /* icon */,
IS_DYNAMIC_SUMMARY_ALLOWED, null /* unavailableSliceSubtitle */);
null /* unavailableSliceSubtitle */);
Settings.Global.putInt(mContext.getContentResolver(),
FakeUnavailablePreferenceController.AVAILABILITY_KEY,
BasePreferenceController.DISABLED_DEPENDENT_SETTING);
@@ -523,7 +502,7 @@ public class SliceBuilderUtilsTest {
final String subtitleOfUnavailableSlice = "subtitleOfUnavailableSlice";
final SliceData data = getDummyData(FakeUnavailablePreferenceController.class,
SUMMARY, SliceData.SliceType.SWITCH, SCREEN_TITLE, 0 /* icon */,
IS_DYNAMIC_SUMMARY_ALLOWED, subtitleOfUnavailableSlice);
subtitleOfUnavailableSlice);
Settings.Global.putInt(mContext.getContentResolver(),
FakeUnavailablePreferenceController.AVAILABILITY_KEY,
BasePreferenceController.DISABLED_DEPENDENT_SETTING);
@@ -551,32 +530,26 @@ public class SliceBuilderUtilsTest {
private SliceData getDummyData() {
return getDummyData(TOGGLE_CONTROLLER, SUMMARY, SliceData.SliceType.SWITCH, SCREEN_TITLE,
ICON, IS_DYNAMIC_SUMMARY_ALLOWED, null /* unavailableSliceSubtitle */);
}
private SliceData getDummyData(boolean isDynamicSummaryAllowed) {
return getDummyData(TOGGLE_CONTROLLER, SUMMARY, SliceData.SliceType.SWITCH, SCREEN_TITLE,
ICON, isDynamicSummaryAllowed, null /* unavailableSliceSubtitle */);
ICON, null /* unavailableSliceSubtitle */);
}
private SliceData getDummyData(Class prefController, int sliceType, int icon) {
return getDummyData(prefController, SUMMARY, sliceType, SCREEN_TITLE,
icon, IS_DYNAMIC_SUMMARY_ALLOWED, null /* unavailableSliceSubtitle */);
icon, null /* unavailableSliceSubtitle */);
}
private SliceData getDummyData(String summary, String screenTitle) {
return getDummyData(TOGGLE_CONTROLLER, summary, SliceData.SliceType.SWITCH, screenTitle,
ICON, IS_DYNAMIC_SUMMARY_ALLOWED, null /* unavailableSliceSubtitle */);
ICON, null /* unavailableSliceSubtitle */);
}
private SliceData getDummyData(Class prefController, int sliceType) {
return getDummyData(prefController, SUMMARY, sliceType, SCREEN_TITLE, ICON,
IS_DYNAMIC_SUMMARY_ALLOWED, null /* unavailableSliceSubtitle */);
null /* unavailableSliceSubtitle */);
}
private SliceData getDummyData(Class prefController, String summary, int sliceType,
String screenTitle, int icon, boolean isDynamicSummaryAllowed,
String unavailableSliceSubtitle) {
String screenTitle, int icon, String unavailableSliceSubtitle) {
return new SliceData.Builder()
.setKey(KEY)
.setTitle(TITLE)
@@ -588,7 +561,6 @@ public class SliceBuilderUtilsTest {
.setUri(URI)
.setPreferenceControllerClassName(prefController.getName())
.setSliceType(sliceType)
.setDynamicSummaryAllowed(isDynamicSummaryAllowed)
.setUnavailableSliceSubtitle(unavailableSliceSubtitle)
.build();
}

View File

@@ -124,7 +124,6 @@ public class SliceDataConverterTest {
assertThat(fakeSlice.getPreferenceController()).isEqualTo(FAKE_CONTROLLER_NAME);
assertThat(fakeSlice.getSliceType()).isEqualTo(SliceData.SliceType.SLIDER);
assertThat(fakeSlice.isPlatformDefined()).isTrue(); // from XML
assertThat(fakeSlice.isDynamicSummaryAllowed()).isTrue(); // from XML
assertThat(fakeSlice.getUnavailableSliceSubtitle()).isEqualTo(
"subtitleOfUnavailableSlice"); // from XML
}

View File

@@ -38,7 +38,6 @@ public class SliceDataTest {
private final String PREF_CONTROLLER = "com.android.settings.slices.tester";
private final int SLICE_TYPE = SliceData.SliceType.SWITCH;
private final boolean IS_PLATFORM_DEFINED = true;
private final boolean IS_DYNAMIC_SUMMARY_ALLOWED = true;
private final String UNAVAILABLE_SLICE_SUBTITLE = "subtitleOfUnavailableSlice";
@Test
@@ -55,7 +54,6 @@ public class SliceDataTest {
.setPreferenceControllerClassName(PREF_CONTROLLER)
.setSliceType(SLICE_TYPE)
.setPlatformDefined(IS_PLATFORM_DEFINED)
.setDynamicSummaryAllowed(IS_DYNAMIC_SUMMARY_ALLOWED)
.setUnavailableSliceSubtitle(UNAVAILABLE_SLICE_SUBTITLE);
SliceData data = builder.build();
@@ -71,7 +69,6 @@ public class SliceDataTest {
assertThat(data.getPreferenceController()).isEqualTo(PREF_CONTROLLER);
assertThat(data.getSliceType()).isEqualTo(SLICE_TYPE);
assertThat(data.isPlatformDefined()).isEqualTo(IS_PLATFORM_DEFINED);
assertThat(data.isDynamicSummaryAllowed()).isEqualTo(IS_DYNAMIC_SUMMARY_ALLOWED);
assertThat(data.getUnavailableSliceSubtitle()).isEqualTo(UNAVAILABLE_SLICE_SUBTITLE);
}
@@ -220,31 +217,6 @@ public class SliceDataTest {
assertThat(data.getPreferenceController()).isEqualTo(PREF_CONTROLLER);
}
@Test
public void testBuilder_noDynamicSummaryAllowed_buildsMatchingObject() {
SliceData.Builder builder = new SliceData.Builder()
.setKey(KEY)
.setTitle(TITLE)
.setSummary(SUMMARY)
.setScreenTitle(SCREEN_TITLE)
.setIcon(ICON)
.setFragmentName(FRAGMENT_NAME)
.setUri(URI)
.setPreferenceControllerClassName(PREF_CONTROLLER);
SliceData data = builder.build();
assertThat(data.getKey()).isEqualTo(KEY);
assertThat(data.getTitle()).isEqualTo(TITLE);
assertThat(data.getSummary()).isEqualTo(SUMMARY);
assertThat(data.getScreenTitle()).isEqualTo(SCREEN_TITLE);
assertThat(data.getIconResource()).isEqualTo(ICON);
assertThat(data.getFragmentClassName()).isEqualTo(FRAGMENT_NAME);
assertThat(data.getUri()).isEqualTo(URI);
assertThat(data.getPreferenceController()).isEqualTo(PREF_CONTROLLER);
assertThat(data.isDynamicSummaryAllowed()).isFalse();
}
@Test
public void testEquality_identicalObjects() {
SliceData.Builder builder = new SliceData.Builder()
@@ -255,8 +227,7 @@ public class SliceDataTest {
.setIcon(ICON)
.setFragmentName(FRAGMENT_NAME)
.setUri(URI)
.setPreferenceControllerClassName(PREF_CONTROLLER)
.setDynamicSummaryAllowed(IS_DYNAMIC_SUMMARY_ALLOWED);
.setPreferenceControllerClassName(PREF_CONTROLLER);
SliceData dataOne = builder.build();
SliceData dataTwo = builder.build();

View File

@@ -108,14 +108,13 @@ public class SlicesDatabaseAccessorTest {
assertThat(data.getFragmentClassName()).isEqualTo(FAKE_FRAGMENT_NAME);
assertThat(data.getUri()).isNull();
assertThat(data.getPreferenceController()).isEqualTo(FAKE_CONTROLLER_NAME);
assertThat(data.isDynamicSummaryAllowed()).isFalse(); /* default value */
assertThat(data.getUnavailableSliceSubtitle()).isNull();
}
@Test
public void testGetSliceDataFromKey_allowDynamicSummary_validSliceReturned() {
String key = "key";
insertSpecialCase(key, true /* isPlatformSlice */, true /* isDynamicSummaryAllowed */,
insertSpecialCase(key, true /* isPlatformSlice */,
null /* customizedUnavailableSliceSubtitle */);
SliceData data = mAccessor.getSliceDataFromKey(key);
@@ -129,27 +128,6 @@ public class SlicesDatabaseAccessorTest {
assertThat(data.getFragmentClassName()).isEqualTo(FAKE_FRAGMENT_NAME);
assertThat(data.getUri()).isNull();
assertThat(data.getPreferenceController()).isEqualTo(FAKE_CONTROLLER_NAME);
assertThat(data.isDynamicSummaryAllowed()).isTrue();
}
@Test
public void testGetSliceDataFromKey_doNotAllowDynamicSummary_validSliceReturned() {
String key = "key";
insertSpecialCase(key, true /* isPlatformSlice */, false /* isDynamicSummaryAllowed */,
null /* customizedUnavailableSliceSubtitle */);
SliceData data = mAccessor.getSliceDataFromKey(key);
assertThat(data.getKey()).isEqualTo(key);
assertThat(data.getTitle()).isEqualTo(FAKE_TITLE);
assertThat(data.getSummary()).isEqualTo(FAKE_SUMMARY);
assertThat(data.getScreenTitle()).isEqualTo(FAKE_SCREEN_TITLE);
assertThat(data.getKeywords()).isEqualTo(FAKE_KEYWORDS);
assertThat(data.getIconResource()).isEqualTo(FAKE_ICON);
assertThat(data.getFragmentClassName()).isEqualTo(FAKE_FRAGMENT_NAME);
assertThat(data.getUri()).isNull();
assertThat(data.getPreferenceController()).isEqualTo(FAKE_CONTROLLER_NAME);
assertThat(data.isDynamicSummaryAllowed()).isFalse();
}
@Test(expected = IllegalStateException.class)
@@ -249,7 +227,7 @@ public class SlicesDatabaseAccessorTest {
@Test
public void testGetSliceDataFromKey_defaultUnavailableSlice_validSliceReturned() {
String key = "key";
insertSpecialCase(key, true /* isPlatformSlice */, true /* isDynamicSummaryAllowed */,
insertSpecialCase(key, true /* isPlatformSlice */,
null /* customizedUnavailableSliceSubtitle */);
SliceData data = mAccessor.getSliceDataFromKey(key);
@@ -270,8 +248,7 @@ public class SlicesDatabaseAccessorTest {
public void testGetSliceDataFromKey_customizeSubtitleOfUnavailableSlice_validSliceReturned() {
String key = "key";
String subtitle = "subtitle";
insertSpecialCase(key, true /* isPlatformSlice */, true /* isDynamicSummaryAllowed */,
subtitle);
insertSpecialCase(key, true /* isPlatformSlice */, subtitle);
SliceData data = mAccessor.getSliceDataFromKey(key);
@@ -292,12 +269,11 @@ public class SlicesDatabaseAccessorTest {
}
private void insertSpecialCase(String key, boolean isPlatformSlice) {
insertSpecialCase(key, isPlatformSlice, false /* isDynamicSummaryAllowed */,
null /*customizedUnavailableSliceSubtitle*/);
insertSpecialCase(key, isPlatformSlice, null /*customizedUnavailableSliceSubtitle*/);
}
private void insertSpecialCase(String key, boolean isPlatformSlice,
boolean isDynamicSummaryAllowed, String customizedUnavailableSliceSubtitle) {
String customizedUnavailableSliceSubtitle) {
ContentValues values = new ContentValues();
values.put(SlicesDatabaseHelper.IndexColumns.KEY, key);
values.put(SlicesDatabaseHelper.IndexColumns.TITLE, FAKE_TITLE);
@@ -308,8 +284,6 @@ public class SlicesDatabaseAccessorTest {
values.put(SlicesDatabaseHelper.IndexColumns.FRAGMENT, FAKE_FRAGMENT_NAME);
values.put(SlicesDatabaseHelper.IndexColumns.CONTROLLER, FAKE_CONTROLLER_NAME);
values.put(SlicesDatabaseHelper.IndexColumns.PLATFORM_SLICE, isPlatformSlice);
values.put(SlicesDatabaseHelper.IndexColumns.ALLOW_DYNAMIC_SUMMARY_IN_SLICE,
isDynamicSummaryAllowed);
values.put(SlicesDatabaseHelper.IndexColumns.SLICE_TYPE, SliceData.SliceType.INTENT);
values.put(SlicesDatabaseHelper.IndexColumns.UNAVAILABLE_SLICE_SUBTITLE,
customizedUnavailableSliceSubtitle);

View File

@@ -74,7 +74,6 @@ public class SlicesDatabaseHelperTest {
IndexColumns.CONTROLLER,
IndexColumns.PLATFORM_SLICE,
IndexColumns.SLICE_TYPE,
IndexColumns.ALLOW_DYNAMIC_SUMMARY_IN_SLICE,
IndexColumns.UNAVAILABLE_SLICE_SUBTITLE,
};

View File

@@ -53,7 +53,6 @@ public class SlicesIndexerTest {
private final Uri URI = Uri.parse("content://com.android.settings.slices/test");
private final String PREF_CONTROLLER = "com.android.settings.slices.tester";
private final boolean PLATFORM_DEFINED = true;
private final boolean IS_DYNAMIC_SUMMARY_ALLOWED = true;
private final int SLICE_TYPE = SliceData.SliceType.SLIDER;
private final String UNAVAILABLE_SLICE_SUBTITLE = "subtitleOfUnavailableSlice";
@@ -142,10 +141,6 @@ public class SlicesIndexerTest {
.isEqualTo(1 /* true */);
assertThat(cursor.getInt(cursor.getColumnIndex(IndexColumns.SLICE_TYPE)))
.isEqualTo(SLICE_TYPE);
assertThat(cursor.getInt(
cursor.getColumnIndex(
IndexColumns.ALLOW_DYNAMIC_SUMMARY_IN_SLICE)))
.isEqualTo(1 /* true */);
assertThat(cursor.getString(
cursor.getColumnIndex(IndexColumns.UNAVAILABLE_SLICE_SUBTITLE)))
.isEqualTo(UNAVAILABLE_SLICE_SUBTITLE);
@@ -183,7 +178,6 @@ public class SlicesIndexerTest {
.setPreferenceControllerClassName(PREF_CONTROLLER)
.setPlatformDefined(PLATFORM_DEFINED)
.setSliceType(SLICE_TYPE)
.setDynamicSummaryAllowed(IS_DYNAMIC_SUMMARY_ALLOWED)
.setUnavailableSliceSubtitle(UNAVAILABLE_SLICE_SUBTITLE);
for (int i = 0; i < KEYS.length; i++) {

View File

@@ -19,8 +19,10 @@ import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -29,13 +31,19 @@ import android.app.Activity;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.os.Bundle;
import android.os.PowerManager;
import android.os.UserManager;
import android.provider.Settings;
import androidx.fragment.app.FragmentActivity;
import androidx.preference.Preference;
import com.android.settings.R;
import com.android.settings.datausage.DataUsagePreference;
import com.android.settings.search.SearchIndexableRaw;
import com.android.settings.testutils.shadow.ShadowDataUsageUtils;
import com.android.settingslib.wifi.WifiTracker;
import org.junit.Before;
@@ -58,6 +66,8 @@ public class WifiSettingsTest {
private WifiTracker mWifiTracker;
@Mock
private PowerManager mPowerManager;
@Mock
private DataUsagePreference mDataUsagePreference;
private Context mContext;
private WifiSettings mWifiSettings;
@@ -159,4 +169,40 @@ public class WifiSettingsTest {
assertThat(mWifiSettings.mAddWifiNetworkPreference.getTitle()).isEqualTo(
mContext.getString(R.string.wifi_add_network));
}
private void setUpForOnCreate() {
final FragmentActivity activity = mock(FragmentActivity.class);
when(mWifiSettings.getActivity()).thenReturn(activity);
final Resources.Theme theme = mContext.getTheme();
when(activity.getTheme()).thenReturn(theme);
UserManager userManager = mock(UserManager.class);
when(activity.getSystemService(Context.USER_SERVICE))
.thenReturn(userManager);
when(mWifiSettings.findPreference(WifiSettings.PREF_KEY_DATA_USAGE))
.thenReturn(mDataUsagePreference);
}
@Test
@Config(shadows = {ShadowDataUsageUtils.class})
public void checkDataUsagePreference_perferenceInvisibleIfWifiNotSupported() {
setUpForOnCreate();
ShadowDataUsageUtils.IS_WIFI_SUPPORTED = false;
mWifiSettings.onCreate(Bundle.EMPTY);
verify(mDataUsagePreference).setVisible(false);
}
@Test
@Config(shadows = {ShadowDataUsageUtils.class})
public void checkDataUsagePreference_perferenceVisibleIfWifiSupported() {
setUpForOnCreate();
ShadowDataUsageUtils.IS_WIFI_SUPPORTED = true;
mWifiSettings.onCreate(Bundle.EMPTY);
verify(mDataUsagePreference).setVisible(true);
verify(mDataUsagePreference).setTemplate(any(), eq(0) /*subId*/, eq(null) /*service*/);
}
}

View File

@@ -1404,6 +1404,27 @@ public class WifiDetailPreferenceControllerTest {
.action(mockActivity, MetricsProto.MetricsEvent.ACTION_WIFI_SIGNIN);
}
@Test
public void testSignInButton_shouldHideSignInButtonForDisconnectedNetwork() {
setUpForDisconnectedNetwork();
NetworkCapabilities nc = makeNetworkCapabilities();
nc.addCapability(NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL);
when(mockConnectivityManager.getNetworkCapabilities(mockNetwork))
.thenReturn(new NetworkCapabilities(nc));
// verify onResume
displayAndResume();
verify(mockButtonsPref, never()).setButton2Visible(true);
verify(mockButtonsPref).setButton2Visible(false);
// verify onCapabilitiesChanged
updateNetworkCapabilities(nc);
verify(mockButtonsPref, never()).setButton2Visible(true);
verify(mockButtonsPref).setButton2Visible(false);
}
@Test
public void testRefreshRssiViews_shouldNotUpdateIfLevelIsSame() {
displayAndResume();
@@ -1437,7 +1458,6 @@ public class WifiDetailPreferenceControllerTest {
verify(mockSignalStrengthPref, times(2)).setVisible(false);
}
private ActionButtonsPreference createMock() {
final ActionButtonsPreference pref = mock(ActionButtonsPreference.class);
when(pref.setButton1Text(anyInt())).thenReturn(pref);