Snap for 4587185 from 99fc2a7ea4 to pi-release
Change-Id: I0e3a4949b189ea71a7b1e1305f27dc1b25c019f4
This commit is contained in:
@@ -22,7 +22,7 @@
|
||||
<dimen name="action_bar_switch_padding">16dip</dimen>
|
||||
|
||||
<dimen name="app_icon_size">40dip</dimen>
|
||||
<dimen name="secondary_app_icon_size">24dp</dimen>
|
||||
<dimen name="secondary_app_icon_size">32dp</dimen>
|
||||
<dimen name="min_tap_target_size">48dp</dimen>
|
||||
<dimen name="screen_margin_sides">64dip</dimen>
|
||||
<dimen name="screen_margin_top">72dip</dimen>
|
||||
|
||||
@@ -2259,9 +2259,9 @@
|
||||
<!-- Wireless networks, item title to go into the WFC settings [CHAR LIMIT=30] -->
|
||||
<string name="wifi_calling_settings_title">Wi-Fi calling</string>
|
||||
<!-- Title of suggestion to turn on wifi calling [CHAR LIMIT=30] -->
|
||||
<string name="wifi_calling_suggestion_title">Turn on Wi-Fi Calling</string>
|
||||
<string name="wifi_calling_suggestion_title">Extend call coverage with Wi\u2011Fi</string>
|
||||
<!-- Summary of suggestion to turn on wifi calling [CHAR LIMIT=60] -->
|
||||
<string name="wifi_calling_suggestion_summary">Extend coverage by calling over Wi-Fi</string>
|
||||
<string name="wifi_calling_suggestion_summary">Turn on Wi\u2011Fi calling</string>
|
||||
<!-- Title of WFC preference item [CHAR LIMIT=30] -->
|
||||
<string name="wifi_calling_mode_title">Calling preference</string>
|
||||
<!-- Title of WFC preference selection dialog [CHAR LIMIT=30] -->
|
||||
@@ -4842,6 +4842,41 @@
|
||||
<string name="battery_tip_dialog_message" product="tablet">Your tablet was used heavily and this consumed a lot of battery. Your battery is behaving normally.\n\n Your tablet was used for about <xliff:g id="hour">%1$s</xliff:g> since last full charge.\n\n Total usage:</string>
|
||||
<!-- Message for battery tip dialog to show the status about the battery [CHAR LIMIT=NONE] -->
|
||||
<string name="battery_tip_dialog_message" product="device">Your device was used heavily and this consumed a lot of battery. Your battery is behaving normally.\n\n Your device was used for about <xliff:g id="hour">%1$s</xliff:g> since last full charge.\n\n Total usage:</string>
|
||||
<!-- Title for restricted app preference, showing how many app need to be restricted [CHAR LIMIT=NONE] -->
|
||||
<plurals name="battery_tip_restrict_title">
|
||||
<item quantity="one">Restrict %1$d app</item>
|
||||
<item quantity="other">Restrict %1$d apps</item>
|
||||
</plurals>
|
||||
<!-- Title for restricted app preference, showing how many app been restricted [CHAR LIMIT=NONE] -->
|
||||
<plurals name="battery_tip_restrict_handled_title">
|
||||
<item quantity="one">%1$d recently restricted</item>
|
||||
<item quantity="other">%1$d apps recently restricted</item>
|
||||
</plurals>
|
||||
<!-- Summary for restricted app preference, showing the impact of the apps [CHAR LIMIT=NONE] -->
|
||||
<plurals name="battery_tip_restrict_summary">
|
||||
<item quantity="one">%1$s has high battery usage</item>
|
||||
<item quantity="other">%2$d apps have high battery usage</item>
|
||||
</plurals>
|
||||
<!-- Summary for restricted app preference, showing the impact of the apps [CHAR LIMIT=NONE] -->
|
||||
<string name="battery_tip_restrict_handled_summary">App changes are in progress</string>
|
||||
|
||||
<!-- Title for dialog to restrict the app [CHAR LIMIT=NONE] -->
|
||||
<plurals name="battery_tip_restrict_app_dialog_title">
|
||||
<item quantity="one">Restrict app?</item>
|
||||
<item quantity="other">Restrict %1$d apps?</item>
|
||||
</plurals>
|
||||
<!-- Message for battery tip dialog to show the restrict app list [CHAR LIMIT=NONE] -->
|
||||
<string name="battery_tip_restrict_app_dialog_message">To save battery, you can stop this app from running in the background when it’s not being used.</string>
|
||||
<!-- OK button for battery tip dialog to show the restrict app list [CHAR LIMIT=NONE] -->
|
||||
<string name="battery_tip_restrict_app_dialog_ok">Restrict</string>
|
||||
<!-- Title for dialog to remove restriction for the app [CHAR LIMIT=NONE] -->
|
||||
<string name="battery_tip_unrestrict_app_dialog_title">Remove restriction for <xliff:g id="app">%1$s</xliff:g>?</string>
|
||||
<!-- Message for dialog to show the impact if remove restriction for app [CHAR LIMIT=NONE] -->
|
||||
<string name="battery_tip_unrestrict_app_dialog_message">This app will be able to use battery in the background. This may cause your battery to be used up faster.</string>
|
||||
<!-- OK button for dialog to remove restriction for app [CHAR LIMIT=NONE] -->
|
||||
<string name="battery_tip_unrestrict_app_dialog_ok">Remove</string>
|
||||
<!-- CANCEL button for dialog to remove restriction for app [CHAR LIMIT=NONE] -->
|
||||
<string name="battery_tip_unrestrict_app_dialog_cancel">Not now</string>
|
||||
|
||||
<!-- Title for the smart battery manager preference [CHAR LIMIT=NONE] -->
|
||||
<string name="smart_battery_manager_title">Smart battery manager</string>
|
||||
|
||||
@@ -49,5 +49,9 @@
|
||||
|
||||
<PreferenceCategory
|
||||
android:key="location_services"
|
||||
android:title="@string/location_category_location_services" />
|
||||
android:title="@string/location_category_location_services"/>
|
||||
|
||||
<PreferenceCategory
|
||||
android:key="location_footer"
|
||||
settings:allowDividerAbove="false"/>
|
||||
</PreferenceScreen>
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.settings;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.app.Activity;
|
||||
import android.app.StatusBarManager;
|
||||
import android.content.Context;
|
||||
@@ -35,11 +36,11 @@ import android.widget.Button;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.settings.core.InstrumentedPreferenceFragment;
|
||||
import com.android.settings.core.InstrumentedFragment;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
public class CryptKeeperConfirm extends InstrumentedPreferenceFragment {
|
||||
public class CryptKeeperConfirm extends InstrumentedFragment {
|
||||
|
||||
private static final String TAG = "CryptKeeperConfirm";
|
||||
|
||||
@@ -153,6 +154,12 @@ public class CryptKeeperConfirm extends InstrumentedPreferenceFragment {
|
||||
mFinalButton.setOnClickListener(mFinalClickListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
getActivity().setTitle(R.string.crypt_keeper_confirm_title);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
|
||||
@@ -55,7 +55,7 @@ import android.widget.ScrollView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.settings.core.InstrumentedPreferenceFragment;
|
||||
import com.android.settings.core.InstrumentedFragment;
|
||||
import com.android.settings.password.ChooseLockSettingsHelper;
|
||||
import com.android.settings.password.ConfirmLockPattern;
|
||||
import com.android.settingslib.RestrictedLockUtils;
|
||||
@@ -72,7 +72,7 @@ import java.util.List;
|
||||
*
|
||||
* This is the initial screen.
|
||||
*/
|
||||
public class MasterClear extends InstrumentedPreferenceFragment {
|
||||
public class MasterClear extends InstrumentedFragment {
|
||||
private static final String TAG = "MasterClear";
|
||||
|
||||
@VisibleForTesting static final int KEYGUARD_REQUEST = 55;
|
||||
|
||||
@@ -33,7 +33,7 @@ import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.settings.core.InstrumentedPreferenceFragment;
|
||||
import com.android.settings.core.InstrumentedFragment;
|
||||
import com.android.settingslib.RestrictedLockUtils;
|
||||
|
||||
import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
|
||||
@@ -48,7 +48,7 @@ import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
|
||||
*
|
||||
* This is the confirmation screen.
|
||||
*/
|
||||
public class MasterClearConfirm extends InstrumentedPreferenceFragment {
|
||||
public class MasterClearConfirm extends InstrumentedFragment {
|
||||
|
||||
private View mContentView;
|
||||
private boolean mEraseSdCard;
|
||||
|
||||
@@ -41,9 +41,9 @@ import android.widget.TextView;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.settings.SettingsPreferenceFragment.SettingsDialogFragment;
|
||||
import com.android.settings.core.InstrumentedPreferenceFragment;
|
||||
import com.android.settings.core.InstrumentedFragment;
|
||||
|
||||
public class ProxySelector extends InstrumentedPreferenceFragment implements DialogCreatable {
|
||||
public class ProxySelector extends InstrumentedFragment implements DialogCreatable {
|
||||
private static final String TAG = "ProxySelector";
|
||||
|
||||
EditText mHostnameField;
|
||||
@@ -58,11 +58,6 @@ public class ProxySelector extends InstrumentedPreferenceFragment implements Dia
|
||||
private SettingsDialogFragment mDialogFragment;
|
||||
private View mView;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle icicle) {
|
||||
super.onCreate(icicle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
@@ -179,6 +174,8 @@ public class ProxySelector extends InstrumentedPreferenceFragment implements Dia
|
||||
String title = intent.getStringExtra("title");
|
||||
if (!TextUtils.isEmpty(title)) {
|
||||
activity.setTitle(title);
|
||||
} else {
|
||||
activity.setTitle(R.string.proxy_settings_title);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ import android.widget.TextView;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.internal.telephony.PhoneConstants;
|
||||
import com.android.settings.core.InstrumentedPreferenceFragment;
|
||||
import com.android.settings.core.InstrumentedFragment;
|
||||
import com.android.settings.password.ChooseLockSettingsHelper;
|
||||
import com.android.settings.password.ConfirmLockPattern;
|
||||
import com.android.settingslib.RestrictedLockUtils;
|
||||
@@ -61,7 +61,7 @@ import java.util.List;
|
||||
*
|
||||
* This is the initial screen.
|
||||
*/
|
||||
public class ResetNetwork extends InstrumentedPreferenceFragment {
|
||||
public class ResetNetwork extends InstrumentedFragment {
|
||||
private static final String TAG = "ResetNetwork";
|
||||
|
||||
// Arbitrary to avoid conficts
|
||||
|
||||
@@ -42,8 +42,8 @@ import android.widget.Toast;
|
||||
import com.android.ims.ImsManager;
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.internal.telephony.PhoneConstants;
|
||||
import com.android.settings.core.InstrumentedPreferenceFragment;
|
||||
import com.android.settings.wrapper.RecoverySystemWrapper;
|
||||
import com.android.settings.core.InstrumentedFragment;
|
||||
import com.android.settingslib.RestrictedLockUtils;
|
||||
|
||||
import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
|
||||
@@ -58,7 +58,7 @@ import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
|
||||
*
|
||||
* This is the confirmation screen.
|
||||
*/
|
||||
public class ResetNetworkConfirm extends InstrumentedPreferenceFragment {
|
||||
public class ResetNetworkConfirm extends InstrumentedFragment {
|
||||
|
||||
private View mContentView;
|
||||
private int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
|
||||
|
||||
@@ -65,7 +65,7 @@ import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.app.UnlaunchableAppActivity;
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.settings.core.InstrumentedPreferenceFragment;
|
||||
import com.android.settings.core.InstrumentedFragment;
|
||||
|
||||
import java.security.cert.CertificateEncodingException;
|
||||
import java.security.cert.X509Certificate;
|
||||
@@ -75,7 +75,7 @@ import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.IntConsumer;
|
||||
|
||||
public class TrustedCredentialsSettings extends InstrumentedPreferenceFragment
|
||||
public class TrustedCredentialsSettings extends InstrumentedFragment
|
||||
implements TrustedCredentialsDialogBuilder.DelegateInterface {
|
||||
|
||||
public static final String ARG_SHOW_NEW_FOR_USER = "ARG_SHOW_NEW_FOR_USER";
|
||||
@@ -117,7 +117,8 @@ public class TrustedCredentialsSettings extends InstrumentedPreferenceFragment
|
||||
private final int mContentView;
|
||||
private final boolean mSwitch;
|
||||
|
||||
private Tab(String tag, int label, int view, int progress, int contentView, boolean withSwitch) {
|
||||
private Tab(String tag, int label, int view, int progress, int contentView,
|
||||
boolean withSwitch) {
|
||||
mTag = tag;
|
||||
mLabel = label;
|
||||
mView = view;
|
||||
|
||||
@@ -34,7 +34,7 @@ import android.widget.TextView;
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.core.InstrumentedPreferenceFragment;
|
||||
import com.android.settings.core.InstrumentedFragment;
|
||||
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
|
||||
import com.android.settingslib.utils.ThreadUtils;
|
||||
|
||||
@@ -45,7 +45,7 @@ import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
||||
public class RunningServiceDetails extends InstrumentedPreferenceFragment
|
||||
public class RunningServiceDetails extends InstrumentedFragment
|
||||
implements RunningState.OnRefreshUiListener {
|
||||
static final String TAG = "RunningServicesDetails";
|
||||
|
||||
|
||||
@@ -251,16 +251,16 @@ public class DefaultAutofillPicker extends DefaultAppPickerFragment {
|
||||
static final class AutofillSettingIntentProvider implements SettingIntentProvider {
|
||||
|
||||
private final String mSelectedKey;
|
||||
private final PackageManager mPackageManager;
|
||||
private final Context mContext;
|
||||
|
||||
public AutofillSettingIntentProvider(PackageManager packageManager, String key) {
|
||||
public AutofillSettingIntentProvider(Context context, String key) {
|
||||
mSelectedKey = key;
|
||||
mPackageManager = packageManager;
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Intent getIntent() {
|
||||
final List<ResolveInfo> resolveInfos = mPackageManager.queryIntentServices(
|
||||
final List<ResolveInfo> resolveInfos = mContext.getPackageManager().queryIntentServices(
|
||||
AUTOFILL_PROBE, PackageManager.GET_META_DATA);
|
||||
|
||||
for (ResolveInfo resolveInfo : resolveInfos) {
|
||||
@@ -270,7 +270,7 @@ public class DefaultAutofillPicker extends DefaultAppPickerFragment {
|
||||
if (TextUtils.equals(mSelectedKey, flattenKey)) {
|
||||
final String settingsActivity;
|
||||
try {
|
||||
settingsActivity = new AutofillServiceInfo(mPackageManager, serviceInfo)
|
||||
settingsActivity = new AutofillServiceInfo(mContext, serviceInfo)
|
||||
.getSettingsActivity();
|
||||
} catch (SecurityException e) {
|
||||
// Service does not declare the proper permission, ignore it.
|
||||
|
||||
@@ -53,7 +53,7 @@ public class DefaultAutofillPreferenceController extends DefaultAppPreferenceCon
|
||||
}
|
||||
final DefaultAutofillPicker.AutofillSettingIntentProvider intentProvider =
|
||||
new DefaultAutofillPicker.AutofillSettingIntentProvider(
|
||||
mPackageManager.getPackageManager(), info.getKey());
|
||||
mContext, info.getKey());
|
||||
return intentProvider.getIntent();
|
||||
}
|
||||
|
||||
|
||||
@@ -268,6 +268,7 @@ public class DashboardSummary extends InstrumentedFragment
|
||||
mSummaryLoader.updateSummaryToCache(category);
|
||||
mStagingCategory = category;
|
||||
if (mSuggestionControllerMixin == null) {
|
||||
mAdapter.setCategory(mStagingCategory);
|
||||
return;
|
||||
}
|
||||
if (mSuggestionControllerMixin.isSuggestionLoaded()) {
|
||||
|
||||
@@ -21,12 +21,12 @@ import android.hardware.fingerprint.FingerprintManager.AuthenticationResult;
|
||||
import android.os.CancellationSignal;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.settings.core.InstrumentedPreferenceFragment;
|
||||
import com.android.settings.core.InstrumentedFragment;
|
||||
|
||||
/**
|
||||
* Sidecar fragment to handle the state around fingerprint authentication
|
||||
*/
|
||||
public class FingerprintAuthenticateSidecar extends InstrumentedPreferenceFragment {
|
||||
public class FingerprintAuthenticateSidecar extends InstrumentedFragment {
|
||||
|
||||
private static final String TAG = "FingerprintAuthenticateSidecar";
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ import android.content.Context;
|
||||
import android.hardware.fingerprint.Fingerprint;
|
||||
import android.hardware.fingerprint.FingerprintManager;
|
||||
import android.os.Bundle;
|
||||
import com.android.settings.core.InstrumentedPreferenceFragment;
|
||||
import com.android.settings.core.InstrumentedFragment;
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import android.os.UserHandle;
|
||||
import java.util.Queue;
|
||||
@@ -31,7 +31,7 @@ import android.util.Log;
|
||||
/**
|
||||
* Sidecar fragment to handle the state around fingerprint removal.
|
||||
*/
|
||||
public class FingerprintRemoveSidecar extends InstrumentedPreferenceFragment {
|
||||
public class FingerprintRemoveSidecar extends InstrumentedFragment {
|
||||
|
||||
private static final String TAG = "FingerprintRemoveSidecar";
|
||||
private Listener mListener;
|
||||
@@ -99,20 +99,6 @@ public class FingerprintRemoveSidecar extends InstrumentedPreferenceFragment {
|
||||
setRetainInstance(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
|
||||
}
|
||||
|
||||
public void setListener(Listener listener) {
|
||||
if (mListener == null && listener != null) {
|
||||
while (!mFingerprintsRemoved.isEmpty()) {
|
||||
|
||||
@@ -46,6 +46,8 @@ import com.android.settings.Utils;
|
||||
import com.android.settings.applications.LayoutPreference;
|
||||
import com.android.settings.dashboard.DashboardFragment;
|
||||
import com.android.settings.fuelgauge.anomaly.AnomalyUtils;
|
||||
import com.android.settings.fuelgauge.batterytip.BatteryTipPreferenceController;
|
||||
import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
|
||||
import com.android.settings.wrapper.DevicePolicyManagerWrapper;
|
||||
import com.android.settings.fuelgauge.anomaly.Anomaly;
|
||||
import com.android.settings.fuelgauge.anomaly.AnomalyDialogFragment;
|
||||
@@ -69,7 +71,7 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements
|
||||
ButtonActionDialogFragment.AppButtonsDialogListener,
|
||||
AnomalyDialogFragment.AnomalyDialogListener,
|
||||
LoaderManager.LoaderCallbacks<List<Anomaly>>,
|
||||
BackgroundActivityPreferenceController.WarningConfirmationListener {
|
||||
BatteryTipPreferenceController.BatteryTipListener {
|
||||
|
||||
public static final String TAG = "AdvancedPowerUsageDetail";
|
||||
public static final String EXTRA_UID = "extra_uid";
|
||||
@@ -373,8 +375,8 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLimitBackgroundActivity() {
|
||||
mBackgroundActivityPreferenceController.setRestricted(
|
||||
public void onBatteryTipHandled(BatteryTip batteryTip) {
|
||||
mBackgroundActivityPreferenceController.updateSummary(
|
||||
findPreference(mBackgroundActivityPreferenceController.getPreferenceKey()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,27 +14,22 @@
|
||||
|
||||
package com.android.settings.fuelgauge;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.AppOpsManager;
|
||||
import android.app.Dialog;
|
||||
import android.app.Fragment;
|
||||
import android.app.admin.DevicePolicyManager;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserManager;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
import android.support.v14.preference.SwitchPreference;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.core.PreferenceControllerMixin;
|
||||
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
|
||||
import com.android.settings.fuelgauge.batterytip.AppInfo;
|
||||
import com.android.settings.fuelgauge.batterytip.BatteryTipDialogFragment;
|
||||
import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
|
||||
import com.android.settings.fuelgauge.batterytip.tips.RestrictAppTip;
|
||||
import com.android.settings.fuelgauge.batterytip.tips.UnrestrictAppTip;
|
||||
import com.android.settings.wrapper.DevicePolicyManagerWrapper;
|
||||
import com.android.settingslib.core.AbstractPreferenceController;
|
||||
import com.android.settingslib.fuelgauge.PowerWhitelistBackend;
|
||||
@@ -99,15 +94,6 @@ public class BackgroundActivityPreferenceController extends AbstractPreferenceCo
|
||||
return mTargetPackage != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called from the warning dialog, if the user decides to go ahead and disable background
|
||||
* activity for this package
|
||||
*/
|
||||
public void setRestricted(Preference preference) {
|
||||
mBatteryUtils.setForceAppStandby(mUid, mTargetPackage, AppOpsManager.MODE_IGNORED);
|
||||
updateSummary(preference);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return KEY_BACKGROUND_ACTIVITY;
|
||||
@@ -119,20 +105,13 @@ public class BackgroundActivityPreferenceController extends AbstractPreferenceCo
|
||||
final int mode = mAppOpsManager
|
||||
.checkOpNoThrow(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, mUid, mTargetPackage);
|
||||
final boolean restricted = mode == AppOpsManager.MODE_IGNORED;
|
||||
if (!restricted) {
|
||||
showDialog();
|
||||
return false;
|
||||
}
|
||||
mBatteryUtils.setForceAppStandby(mUid, mTargetPackage, AppOpsManager.MODE_ALLOWED);
|
||||
updateSummary(preference);
|
||||
return true;
|
||||
showDialog(restricted);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void updateSummary(Preference preference) {
|
||||
public void updateSummary(Preference preference) {
|
||||
if (mPowerWhitelistBackend.isWhitelisted(mTargetPackage)) {
|
||||
preference.setSummary(R.string.background_activity_summary_whitelisted);
|
||||
return;
|
||||
@@ -150,42 +129,16 @@ public class BackgroundActivityPreferenceController extends AbstractPreferenceCo
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void showDialog() {
|
||||
final WarningDialogFragment dialogFragment = new WarningDialogFragment();
|
||||
void showDialog(boolean restricted) {
|
||||
final AppInfo appInfo = new AppInfo.Builder()
|
||||
.setPackageName(mTargetPackage)
|
||||
.build();
|
||||
BatteryTip tip = restricted
|
||||
? new UnrestrictAppTip(BatteryTip.StateType.NEW, appInfo)
|
||||
: new RestrictAppTip(BatteryTip.StateType.NEW, appInfo);
|
||||
|
||||
final BatteryTipDialogFragment dialogFragment = BatteryTipDialogFragment.newInstance(tip);
|
||||
dialogFragment.setTargetFragment(mFragment, 0 /* requestCode */);
|
||||
dialogFragment.show(mFragment.getFragmentManager(), TAG);
|
||||
}
|
||||
|
||||
interface WarningConfirmationListener {
|
||||
void onLimitBackgroundActivity();
|
||||
}
|
||||
|
||||
/**
|
||||
* Warning dialog to show to the user as turning off background activity can lead to
|
||||
* apps misbehaving as their background task scheduling guarantees will no longer be honored.
|
||||
*/
|
||||
public static class WarningDialogFragment extends InstrumentedDialogFragment {
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
// TODO (b/65494831): add metric id
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
final WarningConfirmationListener listener =
|
||||
(WarningConfirmationListener) getTargetFragment();
|
||||
return new AlertDialog.Builder(getContext())
|
||||
.setTitle(R.string.background_activity_warning_dialog_title)
|
||||
.setMessage(R.string.background_activity_warning_dialog_text)
|
||||
.setPositiveButton(R.string.dlg_ok, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
listener.onLimitBackgroundActivity();
|
||||
}
|
||||
})
|
||||
.setNegativeButton(R.string.dlg_cancel, null)
|
||||
.create();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,10 @@ import com.android.settings.fuelgauge.batterytip.BatteryTipPreferenceController.
|
||||
import com.android.settings.fuelgauge.batterytip.actions.BatteryTipAction;
|
||||
import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
|
||||
import com.android.settings.fuelgauge.batterytip.tips.HighUsageTip;
|
||||
import com.android.settings.fuelgauge.batterytip.tips.RestrictAppTip;
|
||||
import com.android.settings.fuelgauge.batterytip.tips.UnrestrictAppTip;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Dialog Fragment to show action dialog for each anomaly
|
||||
@@ -84,6 +88,39 @@ public class BatteryTipDialogFragment extends InstrumentedDialogFragment impleme
|
||||
.setView(view)
|
||||
.setPositiveButton(android.R.string.ok, null)
|
||||
.create();
|
||||
case BatteryTip.TipType.APP_RESTRICTION:
|
||||
final RestrictAppTip restrictAppTip = (RestrictAppTip) mBatteryTip;
|
||||
final List<AppInfo> restrictedAppList = restrictAppTip.getRestrictAppList();
|
||||
final int num = restrictedAppList.size();
|
||||
|
||||
final AlertDialog.Builder builder = new AlertDialog.Builder(context)
|
||||
.setTitle(context.getResources().getQuantityString(
|
||||
R.plurals.battery_tip_restrict_app_dialog_title, num, num))
|
||||
.setMessage(getString(R.string.battery_tip_restrict_app_dialog_message))
|
||||
.setPositiveButton(R.string.battery_tip_restrict_app_dialog_ok, this)
|
||||
.setNegativeButton(android.R.string.cancel, null);
|
||||
|
||||
// TODO(b/72385333): consider building dialog with 5+ apps when strings are done
|
||||
if (num > 1) {
|
||||
final RecyclerView restrictionView = (RecyclerView) LayoutInflater.from(
|
||||
context).inflate(R.layout.recycler_view, null);
|
||||
restrictionView.setLayoutManager(new LinearLayoutManager(context));
|
||||
restrictionView.setAdapter(new HighUsageAdapter(context, restrictedAppList));
|
||||
builder.setView(restrictionView);
|
||||
}
|
||||
|
||||
return builder.create();
|
||||
case BatteryTip.TipType.REMOVE_APP_RESTRICTION:
|
||||
final UnrestrictAppTip unrestrictAppTip = (UnrestrictAppTip) mBatteryTip;
|
||||
final CharSequence name = Utils.getApplicationLabel(context,
|
||||
unrestrictAppTip.getPackageName());
|
||||
|
||||
return new AlertDialog.Builder(context)
|
||||
.setTitle(getString(R.string.battery_tip_unrestrict_app_dialog_title, name))
|
||||
.setMessage(R.string.battery_tip_unrestrict_app_dialog_message)
|
||||
.setPositiveButton(R.string.battery_tip_unrestrict_app_dialog_ok, this)
|
||||
.setNegativeButton(R.string.battery_tip_unrestrict_app_dialog_cancel, null)
|
||||
.create();
|
||||
default:
|
||||
throw new IllegalArgumentException("unknown type " + mBatteryTip.getType());
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import com.android.settings.fuelgauge.batterytip.detectors.EarlyWarningDetector;
|
||||
import com.android.settings.fuelgauge.batterytip.detectors.HighUsageDetector;
|
||||
import com.android.settings.fuelgauge.batterytip.detectors.LowBatteryDetector;
|
||||
import com.android.settings.fuelgauge.batterytip.detectors.SmartBatteryDetector;
|
||||
import com.android.settings.fuelgauge.batterytip.detectors.RestrictAppDetector;
|
||||
import com.android.settings.fuelgauge.batterytip.detectors.SummaryDetector;
|
||||
import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
|
||||
import com.android.settings.fuelgauge.batterytip.tips.LowBatteryTip;
|
||||
@@ -70,6 +71,7 @@ public class BatteryTipLoader extends AsyncLoader<List<BatteryTip>> {
|
||||
tips.add(new SmartBatteryDetector(policy, context.getContentResolver()).detect());
|
||||
tips.add(new EarlyWarningDetector(policy, context).detect());
|
||||
tips.add(new SummaryDetector(policy).detect());
|
||||
tips.add(new RestrictAppDetector(policy).detect());
|
||||
|
||||
Collections.sort(tips);
|
||||
return tips;
|
||||
|
||||
@@ -17,12 +17,17 @@
|
||||
package com.android.settings.fuelgauge.batterytip;
|
||||
|
||||
import android.app.Fragment;
|
||||
import android.content.Context;
|
||||
|
||||
import com.android.settings.SettingsActivity;
|
||||
import com.android.settings.fuelgauge.batterytip.actions.BatterySaverAction;
|
||||
import com.android.settings.fuelgauge.batterytip.actions.BatteryTipAction;
|
||||
import com.android.settings.fuelgauge.batterytip.actions.RestrictAppAction;
|
||||
import com.android.settings.fuelgauge.batterytip.actions.SmartBatteryAction;
|
||||
import com.android.settings.fuelgauge.batterytip.actions.UnrestrictAppAction;
|
||||
import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
|
||||
import com.android.settings.fuelgauge.batterytip.tips.RestrictAppTip;
|
||||
import com.android.settings.fuelgauge.batterytip.tips.UnrestrictAppTip;
|
||||
|
||||
/**
|
||||
* Utility class for {@link BatteryTip}
|
||||
@@ -42,7 +47,11 @@ public class BatteryTipUtils {
|
||||
case BatteryTip.TipType.SMART_BATTERY_MANAGER:
|
||||
return new SmartBatteryAction(settingsActivity, fragment);
|
||||
case BatteryTip.TipType.BATTERY_SAVER:
|
||||
return new BatterySaverAction(settingsActivity.getApplicationContext());
|
||||
return new BatterySaverAction(settingsActivity);
|
||||
case BatteryTip.TipType.APP_RESTRICTION:
|
||||
return new RestrictAppAction(settingsActivity, (RestrictAppTip) batteryTip);
|
||||
case BatteryTip.TipType.REMOVE_APP_RESTRICTION:
|
||||
return new UnrestrictAppAction(settingsActivity, (UnrestrictAppTip) batteryTip);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -77,7 +77,9 @@ public class HighUsageAdapter extends RecyclerView.Adapter<HighUsageAdapter.View
|
||||
Utils.getBadgedIcon(mIconDrawableFactory, mPackageManager, app.packageName,
|
||||
UserHandle.myUserId()));
|
||||
holder.appName.setText(Utils.getApplicationLabel(mContext, app.packageName));
|
||||
holder.appTime.setText(Utils.formatElapsedTime(mContext, app.screenOnTimeMs, false));
|
||||
if (app.screenOnTimeMs != 0) {
|
||||
holder.appTime.setText(Utils.formatElapsedTime(mContext, app.screenOnTimeMs, false));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.fuelgauge.batterytip.actions;
|
||||
|
||||
import android.app.AppOpsManager;
|
||||
import android.content.Context;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.settings.fuelgauge.BatteryUtils;
|
||||
import com.android.settings.fuelgauge.batterytip.AppInfo;
|
||||
import com.android.settings.fuelgauge.batterytip.tips.RestrictAppTip;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Action to restrict the apps, then app is not allowed to run in the background.
|
||||
*/
|
||||
public class RestrictAppAction extends BatteryTipAction {
|
||||
private RestrictAppTip mRestrictAppTip;
|
||||
@VisibleForTesting
|
||||
BatteryUtils mBatteryUtils;
|
||||
|
||||
public RestrictAppAction(Context context, RestrictAppTip tip) {
|
||||
super(context);
|
||||
mRestrictAppTip = tip;
|
||||
mBatteryUtils = BatteryUtils.getInstance(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the action when user clicks positive button
|
||||
*/
|
||||
@Override
|
||||
public void handlePositiveAction() {
|
||||
final List<AppInfo> appInfos = mRestrictAppTip.getRestrictAppList();
|
||||
|
||||
for (int i = 0, size = appInfos.size(); i < size; i++) {
|
||||
final String packageName = appInfos.get(i).packageName;
|
||||
// Force app standby, then app can't run in the background
|
||||
mBatteryUtils.setForceAppStandby(mBatteryUtils.getPackageUid(packageName), packageName,
|
||||
AppOpsManager.MODE_IGNORED);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.fuelgauge.batterytip.actions;
|
||||
|
||||
import android.app.AppOpsManager;
|
||||
import android.content.Context;
|
||||
|
||||
import com.android.settings.fuelgauge.BatteryUtils;
|
||||
import com.android.settings.fuelgauge.batterytip.tips.UnrestrictAppTip;
|
||||
|
||||
/**
|
||||
* Action to clear the restriction to the app
|
||||
*/
|
||||
public class UnrestrictAppAction extends BatteryTipAction {
|
||||
private UnrestrictAppTip mUnRestrictAppTip;
|
||||
private BatteryUtils mBatteryUtils;
|
||||
|
||||
public UnrestrictAppAction(Context context, UnrestrictAppTip tip) {
|
||||
super(context);
|
||||
mUnRestrictAppTip = tip;
|
||||
mBatteryUtils = BatteryUtils.getInstance(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the action when user clicks positive button
|
||||
*/
|
||||
@Override
|
||||
public void handlePositiveAction() {
|
||||
final String packageName = mUnRestrictAppTip.getPackageName();
|
||||
// Clear force app standby, then app can run in the background
|
||||
mBatteryUtils.setForceAppStandby(mBatteryUtils.getPackageUid(packageName), packageName,
|
||||
AppOpsManager.MODE_ALLOWED);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.fuelgauge.batterytip.detectors;
|
||||
|
||||
import com.android.settings.fuelgauge.batterytip.AppInfo;
|
||||
import com.android.settings.fuelgauge.batterytip.BatteryTipPolicy;
|
||||
import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
|
||||
import com.android.settings.fuelgauge.batterytip.tips.RestrictAppTip;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Detector whether to show summary tip. This detector should be executed as the last
|
||||
* {@link BatteryTipDetector} since it need the most up-to-date {@code visibleTips}
|
||||
*/
|
||||
public class RestrictAppDetector implements BatteryTipDetector {
|
||||
private BatteryTipPolicy mPolicy;
|
||||
|
||||
public RestrictAppDetector(BatteryTipPolicy policy) {
|
||||
mPolicy = policy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BatteryTip detect() {
|
||||
// TODO(b/70570352): Detect restrict apps here, get data from database
|
||||
final List<AppInfo> highUsageApps = new ArrayList<>();
|
||||
return new RestrictAppTip(
|
||||
highUsageApps.isEmpty() ? BatteryTip.StateType.INVISIBLE : BatteryTip.StateType.NEW,
|
||||
highUsageApps);
|
||||
}
|
||||
}
|
||||
@@ -50,7 +50,8 @@ public abstract class BatteryTip implements Comparable<BatteryTip>, Parcelable {
|
||||
TipType.SMART_BATTERY_MANAGER,
|
||||
TipType.APP_RESTRICTION,
|
||||
TipType.REDUCED_BATTERY,
|
||||
TipType.LOW_BATTERY})
|
||||
TipType.LOW_BATTERY,
|
||||
TipType.REMOVE_APP_RESTRICTION})
|
||||
public @interface TipType {
|
||||
int SMART_BATTERY_MANAGER = 0;
|
||||
int APP_RESTRICTION = 1;
|
||||
@@ -59,6 +60,7 @@ public abstract class BatteryTip implements Comparable<BatteryTip>, Parcelable {
|
||||
int REDUCED_BATTERY = 4;
|
||||
int LOW_BATTERY = 5;
|
||||
int SUMMARY = 6;
|
||||
int REMOVE_APP_RESTRICTION = 7;
|
||||
}
|
||||
|
||||
private static final String KEY_PREFIX = "key_battery_tip";
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.fuelgauge.batterytip.tips;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.os.Parcel;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.fuelgauge.batterytip.AppInfo;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Tip to suggest user to restrict some bad apps
|
||||
*/
|
||||
public class RestrictAppTip extends BatteryTip {
|
||||
private List<AppInfo> mRestrictAppList;
|
||||
|
||||
public RestrictAppTip(@StateType int state, List<AppInfo> restrictApps) {
|
||||
super(TipType.APP_RESTRICTION, state, true /* showDialog */);
|
||||
mRestrictAppList = restrictApps;
|
||||
}
|
||||
|
||||
public RestrictAppTip(@StateType int state, AppInfo appInfo) {
|
||||
super(TipType.APP_RESTRICTION, state, true /* showDialog */);
|
||||
mRestrictAppList = new ArrayList<>();
|
||||
mRestrictAppList.add(appInfo);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
RestrictAppTip(Parcel in) {
|
||||
super(in);
|
||||
mRestrictAppList = in.createTypedArrayList(AppInfo.CREATOR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getTitle(Context context) {
|
||||
final int num = mRestrictAppList.size();
|
||||
return context.getResources().getQuantityString(
|
||||
mState == StateType.HANDLED
|
||||
? R.plurals.battery_tip_restrict_handled_title
|
||||
: R.plurals.battery_tip_restrict_title,
|
||||
num, num);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getSummary(Context context) {
|
||||
final int num = mRestrictAppList.size();
|
||||
final CharSequence appLabel = num > 0 ? Utils.getApplicationLabel(context,
|
||||
mRestrictAppList.get(0).packageName) : "";
|
||||
return mState == StateType.HANDLED
|
||||
? context.getString(R.string.battery_tip_restrict_handled_summary)
|
||||
: context.getResources().getQuantityString(R.plurals.battery_tip_restrict_summary,
|
||||
num, appLabel, num);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIconId() {
|
||||
return mState == StateType.HANDLED
|
||||
? R.drawable.ic_perm_device_information_green_24dp
|
||||
: R.drawable.ic_battery_alert_24dp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(BatteryTip tip) {
|
||||
mState = tip.mState;
|
||||
}
|
||||
|
||||
public List<AppInfo> getRestrictAppList() {
|
||||
return mRestrictAppList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
super.writeToParcel(dest, flags);
|
||||
dest.writeTypedList(mRestrictAppList);
|
||||
}
|
||||
|
||||
public static final Creator CREATOR = new Creator() {
|
||||
public BatteryTip createFromParcel(Parcel in) {
|
||||
return new RestrictAppTip(in);
|
||||
}
|
||||
|
||||
public BatteryTip[] newArray(int size) {
|
||||
return new RestrictAppTip[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.fuelgauge.batterytip.tips;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Parcel;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.settings.fuelgauge.batterytip.AppInfo;
|
||||
|
||||
/**
|
||||
* Tip to suggest user to remove app restriction. This is the empty tip and it is only used in
|
||||
* {@link com.android.settings.fuelgauge.AdvancedPowerUsageDetail} to create dialog.
|
||||
*/
|
||||
public class UnrestrictAppTip extends BatteryTip {
|
||||
private AppInfo mAppInfo;
|
||||
|
||||
public UnrestrictAppTip(@StateType int state, AppInfo appInfo) {
|
||||
super(TipType.REMOVE_APP_RESTRICTION, state, true /* showDialog */);
|
||||
mAppInfo = appInfo;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
UnrestrictAppTip(Parcel in) {
|
||||
super(in);
|
||||
mAppInfo = in.readParcelable(getClass().getClassLoader());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getTitle(Context context) {
|
||||
// Don't need title since this is an empty tip
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getSummary(Context context) {
|
||||
// Don't need summary since this is an empty tip
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIconId() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public String getPackageName() {
|
||||
return mAppInfo.packageName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(BatteryTip tip) {
|
||||
mState = tip.mState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
super.writeToParcel(dest, flags);
|
||||
dest.writeParcelable(mAppInfo, flags);
|
||||
}
|
||||
|
||||
public static final Creator CREATOR = new Creator() {
|
||||
public BatteryTip createFromParcel(Parcel in) {
|
||||
return new UnrestrictAppTip(in);
|
||||
}
|
||||
|
||||
public BatteryTip[] newArray(int size) {
|
||||
return new UnrestrictAppTip[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -27,7 +27,7 @@ import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.settings.core.InstrumentedPreferenceFragment;
|
||||
import com.android.settings.core.InstrumentedFragment;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SettingsActivity;
|
||||
import com.android.settings.inputmethod.UserDictionaryAddWordContents.LocaleRenderer;
|
||||
@@ -41,7 +41,7 @@ import java.util.Locale;
|
||||
* As opposed to the UserDictionaryActivity, this is only invoked within Settings
|
||||
* from the UserDictionarySettings.
|
||||
*/
|
||||
public class UserDictionaryAddWordFragment extends InstrumentedPreferenceFragment
|
||||
public class UserDictionaryAddWordFragment extends InstrumentedFragment
|
||||
implements AdapterView.OnItemSelectedListener,
|
||||
com.android.internal.app.LocalePicker.LocaleSelectionListener {
|
||||
|
||||
@@ -55,7 +55,6 @@ public class UserDictionaryAddWordFragment extends InstrumentedPreferenceFragmen
|
||||
public void onActivityCreated(final Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
setHasOptionsMenu(true);
|
||||
getActivity().getActionBar().setTitle(R.string.user_dict_settings_title);
|
||||
// Keep the instance so that we remember mContents when configuration changes (eg rotation)
|
||||
setRetainInstance(true);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,223 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the
|
||||
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
package com.android.settings.location;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.location.LocationManager;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.support.v7.preference.PreferenceCategory;
|
||||
import android.util.Log;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
import com.android.settingslib.core.lifecycle.LifecycleObserver;
|
||||
import com.android.settingslib.core.lifecycle.events.OnPause;
|
||||
import com.android.settingslib.widget.FooterPreference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Preference controller for location footer preference category
|
||||
*/
|
||||
public class LocationFooterPreferenceController extends LocationBasePreferenceController
|
||||
implements LifecycleObserver, OnPause {
|
||||
private static final String TAG = "LocationFooter";
|
||||
private static final String KEY_LOCATION_FOOTER = "location_footer";
|
||||
private static final Intent INJECT_INTENT =
|
||||
new Intent(LocationManager.SETTINGS_FOOTER_DISPLAYED_ACTION);
|
||||
private final Context mContext;
|
||||
private final PackageManager mPackageManager;
|
||||
private Collection<ComponentName> mFooterInjectors;
|
||||
|
||||
public LocationFooterPreferenceController(Context context, Lifecycle lifecycle) {
|
||||
super(context, lifecycle);
|
||||
mContext = context;
|
||||
mPackageManager = mContext.getPackageManager();
|
||||
mFooterInjectors = new ArrayList<>();
|
||||
if (lifecycle != null) {
|
||||
lifecycle.addObserver(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return KEY_LOCATION_FOOTER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert footer preferences. Send a {@link LocationManager#SETTINGS_FOOTER_DISPLAYED_ACTION}
|
||||
* broadcast to receivers who have injected a footer
|
||||
*/
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
PreferenceCategory category = (PreferenceCategory) preference;
|
||||
category.removeAll();
|
||||
mFooterInjectors.clear();
|
||||
Collection<FooterData> footerData = getFooterData();
|
||||
for (FooterData data : footerData) {
|
||||
// Generate a footer preference with the given text
|
||||
FooterPreference footerPreference = new FooterPreference(preference.getContext());
|
||||
String footerString;
|
||||
try {
|
||||
footerString =
|
||||
mPackageManager
|
||||
.getResourcesForApplication(data.applicationInfo)
|
||||
.getString(data.footerStringRes);
|
||||
} catch (NameNotFoundException exception) {
|
||||
if (Log.isLoggable(TAG, Log.WARN)) {
|
||||
Log.w(
|
||||
TAG,
|
||||
"Resources not found for application "
|
||||
+ data.applicationInfo.packageName);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
footerPreference.setTitle(footerString);
|
||||
// Inject the footer
|
||||
category.addPreference(footerPreference);
|
||||
// Send broadcast to the injector announcing a footer has been injected
|
||||
sendBroadcastFooterDisplayed(data.componentName);
|
||||
mFooterInjectors.add(data.componentName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Do nothing on location mode changes.
|
||||
*/
|
||||
@Override
|
||||
public void onLocationModeChanged(int mode, boolean restricted) {}
|
||||
|
||||
/**
|
||||
* Location footer preference group should be displayed if there is at least one footer to
|
||||
* inject.
|
||||
*/
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return !getFooterData().isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a {@link LocationManager#SETTINGS_FOOTER_REMOVED_ACTION} broadcast to footer injectors
|
||||
* when LocationFragment is on pause
|
||||
*/
|
||||
@Override
|
||||
public void onPause() {
|
||||
// Send broadcast to the footer injectors. Notify them the footer is not visible.
|
||||
for (ComponentName componentName : mFooterInjectors) {
|
||||
final Intent intent = new Intent(LocationManager.SETTINGS_FOOTER_REMOVED_ACTION);
|
||||
intent.setComponent(componentName);
|
||||
mContext.sendBroadcast(intent);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a {@link LocationManager#SETTINGS_FOOTER_DISPLAYED_ACTION} broadcast to a footer
|
||||
* injector.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
void sendBroadcastFooterDisplayed(ComponentName componentName) {
|
||||
Intent intent = new Intent(LocationManager.SETTINGS_FOOTER_DISPLAYED_ACTION);
|
||||
intent.setComponent(componentName);
|
||||
mContext.sendBroadcast(intent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of strings with text provided by ACTION_INJECT_FOOTER broadcast receivers.
|
||||
*/
|
||||
private Collection<FooterData> getFooterData() {
|
||||
// Fetch footer text from system apps
|
||||
final List<ResolveInfo> resolveInfos =
|
||||
mPackageManager.queryBroadcastReceivers(
|
||||
INJECT_INTENT, PackageManager.GET_META_DATA);
|
||||
if (resolveInfos == null) {
|
||||
if (Log.isLoggable(TAG, Log.ERROR)) {
|
||||
Log.e(TAG, "Unable to resolve intent " + INJECT_INTENT);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
} else if (Log.isLoggable(TAG, Log.DEBUG)) {
|
||||
Log.d(TAG, "Found broadcast receivers: " + resolveInfos);
|
||||
}
|
||||
|
||||
final Collection<FooterData> footerDataList = new ArrayList<>(resolveInfos.size());
|
||||
for (ResolveInfo resolveInfo : resolveInfos) {
|
||||
final ActivityInfo activityInfo = resolveInfo.activityInfo;
|
||||
final ApplicationInfo appInfo = activityInfo.applicationInfo;
|
||||
|
||||
// If a non-system app tries to inject footer, ignore it
|
||||
if ((appInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
|
||||
if (Log.isLoggable(TAG, Log.WARN)) {
|
||||
Log.w(TAG, "Ignoring attempt to inject footer from app not in system image: "
|
||||
+ resolveInfo);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the footer text resource id from broadcast receiver's metadata
|
||||
if (activityInfo.metaData == null) {
|
||||
if (Log.isLoggable(TAG, Log.DEBUG)) {
|
||||
Log.d(TAG, "No METADATA in broadcast receiver " + activityInfo.name);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
final int footerTextRes =
|
||||
activityInfo.metaData.getInt(LocationManager.METADATA_SETTINGS_FOOTER_STRING);
|
||||
if (footerTextRes == 0) {
|
||||
if (Log.isLoggable(TAG, Log.WARN)) {
|
||||
Log.w(
|
||||
TAG,
|
||||
"No mapping of integer exists for "
|
||||
+ LocationManager.METADATA_SETTINGS_FOOTER_STRING);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
footerDataList.add(
|
||||
new FooterData(
|
||||
footerTextRes,
|
||||
appInfo,
|
||||
new ComponentName(activityInfo.packageName, activityInfo.name)));
|
||||
}
|
||||
return footerDataList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Contains information related to a footer.
|
||||
*/
|
||||
private static class FooterData {
|
||||
|
||||
// The string resource of the footer
|
||||
final int footerStringRes;
|
||||
|
||||
// Application info of receiver injecting this footer
|
||||
final ApplicationInfo applicationInfo;
|
||||
|
||||
// The component that injected the footer. It must be a receiver of broadcast
|
||||
// LocationManager.SETTINGS_FOOTER_DISPLAYED_ACTION
|
||||
final ComponentName componentName;
|
||||
|
||||
FooterData(int footerRes, ApplicationInfo appInfo, ComponentName componentName) {
|
||||
this.footerStringRes = footerRes;
|
||||
this.applicationInfo = appInfo;
|
||||
this.componentName = componentName;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -131,9 +131,10 @@ public class LocationSettings extends DashboardFragment {
|
||||
controllers.add(new LocationForWorkPreferenceController(context, lifecycle));
|
||||
controllers.add(
|
||||
new RecentLocationRequestPreferenceController(context, fragment, lifecycle));
|
||||
controllers.add(new LocationScanningPreferenceController(context));
|
||||
controllers.add(
|
||||
new LocationServicePreferenceController(context, fragment, lifecycle));
|
||||
controllers.add(new LocationScanningPreferenceController(context));
|
||||
controllers.add(new LocationFooterPreferenceController(context, lifecycle));
|
||||
return controllers;
|
||||
}
|
||||
|
||||
|
||||
@@ -50,7 +50,6 @@ public class NetworkScorerPicker extends InstrumentedPreferenceFragment implemen
|
||||
@Override
|
||||
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
|
||||
super.onCreatePreferences(savedInstanceState, rootKey);
|
||||
addPreferencesFromResource(R.xml.network_scorer_picker_prefs);
|
||||
updateCandidates();
|
||||
}
|
||||
|
||||
@@ -69,6 +68,11 @@ public class NetworkScorerPicker extends InstrumentedPreferenceFragment implemen
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getPreferenceScreenResId() {
|
||||
return R.xml.network_scorer_picker_prefs;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public void updateCandidates() {
|
||||
final PreferenceScreen screen = getPreferenceScreen();
|
||||
|
||||
@@ -29,7 +29,7 @@ import android.widget.Switch;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.settingslib.HelpUtils;
|
||||
import com.android.settings.core.InstrumentedPreferenceFragment;
|
||||
import com.android.settings.core.InstrumentedFragment;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SettingsActivity;
|
||||
import com.android.settings.ShowAdminSupportDetailsDialog;
|
||||
@@ -38,7 +38,7 @@ import com.android.settingslib.RestrictedLockUtils;
|
||||
|
||||
import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
|
||||
|
||||
public class AndroidBeam extends InstrumentedPreferenceFragment
|
||||
public class AndroidBeam extends InstrumentedFragment
|
||||
implements SwitchBar.OnSwitchChangeListener {
|
||||
private View mView;
|
||||
private NfcAdapter mNfcAdapter;
|
||||
|
||||
@@ -64,7 +64,7 @@ import com.android.settings.R;
|
||||
import com.android.settings.SettingsActivity;
|
||||
import com.android.settings.SetupWizardUtils;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.core.InstrumentedPreferenceFragment;
|
||||
import com.android.settings.core.InstrumentedFragment;
|
||||
import com.android.settings.notification.RedactionInterstitial;
|
||||
import com.android.settings.widget.ImeAwareEditText;
|
||||
import com.android.setupwizardlib.GlifLayout;
|
||||
@@ -168,7 +168,7 @@ public class ChooseLockPassword extends SettingsActivity {
|
||||
layout.setFitsSystemWindows(false);
|
||||
}
|
||||
|
||||
public static class ChooseLockPasswordFragment extends InstrumentedPreferenceFragment
|
||||
public static class ChooseLockPasswordFragment extends InstrumentedFragment
|
||||
implements OnClickListener, OnEditorActionListener, TextWatcher,
|
||||
SaveAndFinishWorker.Listener {
|
||||
private static final String KEY_FIRST_PIN = "first_pin";
|
||||
|
||||
@@ -43,7 +43,7 @@ import com.android.settings.R;
|
||||
import com.android.settings.SettingsActivity;
|
||||
import com.android.settings.SetupWizardUtils;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.core.InstrumentedPreferenceFragment;
|
||||
import com.android.settings.core.InstrumentedFragment;
|
||||
import com.android.settings.notification.RedactionInterstitial;
|
||||
import com.android.setupwizardlib.GlifLayout;
|
||||
|
||||
@@ -153,7 +153,7 @@ public class ChooseLockPattern extends SettingsActivity {
|
||||
return super.onKeyDown(keyCode, event);
|
||||
}
|
||||
|
||||
public static class ChooseLockPatternFragment extends InstrumentedPreferenceFragment
|
||||
public static class ChooseLockPatternFragment extends InstrumentedFragment
|
||||
implements View.OnClickListener, SaveAndFinishWorker.Listener {
|
||||
|
||||
public static final int CONFIRM_EXISTING_REQUEST = 55;
|
||||
|
||||
@@ -52,13 +52,13 @@ import android.widget.TextView;
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.core.InstrumentedPreferenceFragment;
|
||||
import com.android.settings.core.InstrumentedFragment;
|
||||
import com.android.settings.fingerprint.FingerprintUiHelper;
|
||||
|
||||
/**
|
||||
* Base fragment to be shared for PIN/Pattern/Password confirmation fragments.
|
||||
*/
|
||||
public abstract class ConfirmDeviceCredentialBaseFragment extends InstrumentedPreferenceFragment
|
||||
public abstract class ConfirmDeviceCredentialBaseFragment extends InstrumentedFragment
|
||||
implements FingerprintUiHelper.Callback {
|
||||
|
||||
public static final String PACKAGE = "com.android.settings";
|
||||
|
||||
@@ -113,11 +113,6 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
|
||||
@@ -104,11 +104,6 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
|
||||
@@ -157,6 +157,7 @@ public class CryptKeeperSettings extends InstrumentedPreferenceFragment {
|
||||
}
|
||||
}
|
||||
}
|
||||
activity.setTitle(R.string.crypt_keeper_encrypt_title);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -39,13 +39,12 @@ import com.android.settingslib.core.lifecycle.LifecycleObserver;
|
||||
import com.android.settingslib.core.lifecycle.events.OnStart;
|
||||
import com.android.settingslib.core.lifecycle.events.OnStop;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class WifiTetherPreferenceController extends AbstractPreferenceController
|
||||
implements PreferenceControllerMixin, LifecycleObserver, OnStart, OnStop {
|
||||
|
||||
public static final IntentFilter WIFI_TETHER_INTENT_FILTER;
|
||||
private static final String WIFI_TETHER_SETTINGS = "wifi_tether";
|
||||
private static final IntentFilter AIRPLANE_INTENT_FILTER = new IntentFilter(
|
||||
Intent.ACTION_AIRPLANE_MODE_CHANGED);
|
||||
|
||||
private final ConnectivityManager mConnectivityManager;
|
||||
private final String[] mWifiRegexs;
|
||||
@@ -58,12 +57,6 @@ public class WifiTetherPreferenceController extends AbstractPreferenceController
|
||||
@VisibleForTesting
|
||||
WifiTetherSoftApManager mWifiTetherSoftApManager;
|
||||
|
||||
static {
|
||||
WIFI_TETHER_INTENT_FILTER = new IntentFilter(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
|
||||
WIFI_TETHER_INTENT_FILTER.addAction(ConnectivityManager.ACTION_TETHER_STATE_CHANGED);
|
||||
WIFI_TETHER_INTENT_FILTER.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
|
||||
}
|
||||
|
||||
public WifiTetherPreferenceController(Context context, Lifecycle lifecycle) {
|
||||
this(context, lifecycle, true /* initSoftApManager */);
|
||||
}
|
||||
@@ -113,7 +106,7 @@ public class WifiTetherPreferenceController extends AbstractPreferenceController
|
||||
@Override
|
||||
public void onStart() {
|
||||
if (mPreference != null) {
|
||||
mContext.registerReceiver(mReceiver, WIFI_TETHER_INTENT_FILTER);
|
||||
mContext.registerReceiver(mReceiver, AIRPLANE_INTENT_FILTER);
|
||||
clearSummaryForAirplaneMode();
|
||||
if (mWifiTetherSoftApManager != null) {
|
||||
mWifiTetherSoftApManager.registerSoftApCallback();
|
||||
@@ -140,6 +133,7 @@ public class WifiTetherPreferenceController extends AbstractPreferenceController
|
||||
@Override
|
||||
public void onStateChanged(int state, int failureReason) {
|
||||
mSoftApState = state;
|
||||
handleWifiApStateChanged(state, failureReason);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -162,34 +156,21 @@ public class WifiTetherPreferenceController extends AbstractPreferenceController
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
String action = intent.getAction();
|
||||
if (WifiManager.WIFI_AP_STATE_CHANGED_ACTION.equals(action)) {
|
||||
int state = intent.getIntExtra(
|
||||
WifiManager.EXTRA_WIFI_AP_STATE, WifiManager.WIFI_AP_STATE_FAILED);
|
||||
int reason = intent.getIntExtra(WifiManager.EXTRA_WIFI_AP_FAILURE_REASON,
|
||||
WifiManager.SAP_START_FAILURE_GENERAL);
|
||||
handleWifiApStateChanged(state, reason);
|
||||
} else if (ConnectivityManager.ACTION_TETHER_STATE_CHANGED.equals(action)) {
|
||||
List<String> active = intent.getStringArrayListExtra(
|
||||
ConnectivityManager.EXTRA_ACTIVE_TETHER);
|
||||
List<String> errored = intent.getStringArrayListExtra(
|
||||
ConnectivityManager.EXTRA_ERRORED_TETHER);
|
||||
updateTetherState(active.toArray(), errored.toArray());
|
||||
} else if (Intent.ACTION_AIRPLANE_MODE_CHANGED.equals(action)) {
|
||||
if (Intent.ACTION_AIRPLANE_MODE_CHANGED.equals(action)) {
|
||||
clearSummaryForAirplaneMode();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private void handleWifiApStateChanged(int state, int reason) {
|
||||
@VisibleForTesting
|
||||
void handleWifiApStateChanged(int state, int reason) {
|
||||
switch (state) {
|
||||
case WifiManager.WIFI_AP_STATE_ENABLING:
|
||||
mPreference.setSummary(R.string.wifi_tether_starting);
|
||||
break;
|
||||
case WifiManager.WIFI_AP_STATE_ENABLED:
|
||||
/**
|
||||
* Summary on enable is handled by tether
|
||||
* broadcast notice
|
||||
*/
|
||||
WifiConfiguration wifiConfig = mWifiManager.getWifiApConfiguration();
|
||||
updateConfigSummary(wifiConfig);
|
||||
break;
|
||||
case WifiManager.WIFI_AP_STATE_DISABLING:
|
||||
mPreference.setSummary(R.string.wifi_tether_stopping);
|
||||
@@ -208,32 +189,6 @@ public class WifiTetherPreferenceController extends AbstractPreferenceController
|
||||
}
|
||||
}
|
||||
|
||||
private void updateTetherState(Object[] tethered, Object[] errored) {
|
||||
boolean wifiTethered = matchRegex(tethered);
|
||||
boolean wifiErrored = matchRegex(errored);
|
||||
|
||||
if (wifiTethered) {
|
||||
WifiConfiguration wifiConfig = mWifiManager.getWifiApConfiguration();
|
||||
updateConfigSummary(wifiConfig);
|
||||
} else if (wifiErrored) {
|
||||
mPreference.setSummary(R.string.wifi_error);
|
||||
} else {
|
||||
mPreference.setSummary(R.string.wifi_hotspot_off_subtext);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean matchRegex(Object[] tethers) {
|
||||
for (Object o : tethers) {
|
||||
String s = (String) o;
|
||||
for (String regex : mWifiRegexs) {
|
||||
if (s.matches(regex)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void updateConfigSummary(WifiConfiguration wifiConfig) {
|
||||
final String s = mContext.getString(
|
||||
com.android.internal.R.string.wifi_tether_configure_ssid_default);
|
||||
|
||||
@@ -21,6 +21,7 @@ import static android.net.ConnectivityManager.TETHERING_WIFI;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.os.Handler;
|
||||
@@ -36,12 +37,19 @@ import com.android.settingslib.core.lifecycle.events.OnStop;
|
||||
public class WifiTetherSwitchBarController implements SwitchWidgetController.OnSwitchChangeListener,
|
||||
LifecycleObserver, OnStart, OnStop {
|
||||
|
||||
private static final IntentFilter WIFI_INTENT_FILTER;
|
||||
|
||||
private final Context mContext;
|
||||
private final SwitchWidgetController mSwitchBar;
|
||||
private final ConnectivityManager mConnectivityManager;
|
||||
private final DataSaverBackend mDataSaverBackend;
|
||||
private final WifiManager mWifiManager;
|
||||
|
||||
static {
|
||||
WIFI_INTENT_FILTER = new IntentFilter(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
|
||||
WIFI_INTENT_FILTER.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
|
||||
}
|
||||
|
||||
WifiTetherSwitchBarController(Context context, SwitchWidgetController switchBar) {
|
||||
mContext = context;
|
||||
mSwitchBar = switchBar;
|
||||
@@ -56,8 +64,7 @@ public class WifiTetherSwitchBarController implements SwitchWidgetController.OnS
|
||||
@Override
|
||||
public void onStart() {
|
||||
mSwitchBar.startListening();
|
||||
mContext.registerReceiver(mReceiver,
|
||||
WifiTetherPreferenceController.WIFI_TETHER_INTENT_FILTER);
|
||||
mContext.registerReceiver(mReceiver, WIFI_INTENT_FILTER);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -104,10 +104,5 @@ public class DefaultAutofillPreferenceControllerTest {
|
||||
final DefaultAppInfo info = mController.getDefaultAppInfo();
|
||||
|
||||
assertThat(info).isNotNull();
|
||||
|
||||
mController.getSettingIntent(info);
|
||||
|
||||
verify(mPackageManager.getPackageManager()).queryIntentServices(
|
||||
DefaultAutofillPicker.AUTOFILL_PROBE, PackageManager.GET_META_DATA);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,6 +67,8 @@ public class DashboardSummaryTest {
|
||||
private ConditionManager mConditionManager;
|
||||
@Mock
|
||||
private SummaryLoader mSummaryLoader;
|
||||
@Mock
|
||||
private SuggestionControllerMixin mSuggestionControllerMixin;
|
||||
|
||||
private Context mContext;
|
||||
private DashboardSummary mSummary;
|
||||
@@ -111,12 +113,31 @@ public class DashboardSummaryTest {
|
||||
|
||||
@Test
|
||||
public void updateCategory_shouldGetCategoryFromFeatureProvider() {
|
||||
ReflectionHelpers.setField(mSummary, "mSuggestionControllerMixin",
|
||||
mSuggestionControllerMixin);
|
||||
|
||||
when(mSuggestionControllerMixin.isSuggestionLoaded()).thenReturn(true);
|
||||
doReturn(mock(Activity.class)).when(mSummary).getActivity();
|
||||
mSummary.onAttach(mContext);
|
||||
mSummary.updateCategory();
|
||||
|
||||
verify(mSummaryLoader).updateSummaryToCache(nullable(DashboardCategory.class));
|
||||
verify(mDashboardFeatureProvider).getTilesForCategory(CategoryKey.CATEGORY_HOMEPAGE);
|
||||
verify(mAdapter).setCategory(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateCategory_shouldGetCategoryFromFeatureProvider_evenIfSuggestionDisabled() {
|
||||
when(mFeatureFactory.suggestionsFeatureProvider.isSuggestionEnabled(any(Context.class)))
|
||||
.thenReturn(false);
|
||||
|
||||
doReturn(mock(Activity.class)).when(mSummary).getActivity();
|
||||
mSummary.onAttach(mContext);
|
||||
mSummary.updateCategory();
|
||||
|
||||
verify(mSummaryLoader).updateSummaryToCache(nullable(DashboardCategory.class));
|
||||
verify(mDashboardFeatureProvider).getTilesForCategory(CategoryKey.CATEGORY_HOMEPAGE);
|
||||
verify(mAdapter).setCategory(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -142,18 +142,17 @@ public class BackgroundActivityPreferenceControllerTest {
|
||||
|
||||
mController.handlePreferenceTreeClick(mPreference);
|
||||
|
||||
verify(mController).showDialog();
|
||||
verify(mController).showDialog(false /* restrict */);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHandlePreferenceTreeClick_unRestrictApp_setModeAllowed() {
|
||||
public void testHandlePreferenceTreeClick_unRestrictApp_showDialog() {
|
||||
doReturn(AppOpsManager.MODE_IGNORED).when(mAppOpsManager).checkOpNoThrow(anyInt(),
|
||||
anyInt(), anyString());
|
||||
|
||||
mController.handlePreferenceTreeClick(mPreference);
|
||||
|
||||
verify(mBatteryUtils).setForceAppStandby(UID_LOW_SDK, LOW_SDK_PACKAGE,
|
||||
AppOpsManager.MODE_ALLOWED);
|
||||
verify(mController).showDialog(true /* restrict */);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -211,17 +210,4 @@ public class BackgroundActivityPreferenceControllerTest {
|
||||
public void testIsAvailable_ReturnTrue() {
|
||||
assertThat(mController.isAvailable()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWarningDialog() {
|
||||
BackgroundActivityPreferenceController.WarningDialogFragment dialogFragment =
|
||||
new BackgroundActivityPreferenceController.WarningDialogFragment();
|
||||
dialogFragment.setTargetFragment(mFragment, 0);
|
||||
FragmentTestUtil.startFragment(dialogFragment);
|
||||
final AlertDialog dialog = (AlertDialog) ShadowDialog.getLatestDialog();
|
||||
ShadowAlertDialog shadowDialog = shadowOf(dialog);
|
||||
final Button okButton = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
|
||||
shadowDialog.clickOn(okButton.getId());
|
||||
verify(mFragment).onLimitBackgroundActivity();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
@@ -523,4 +524,27 @@ public class BatteryUtilsTest {
|
||||
public void testIsLegacyApp_SdkLargerOrEqualThanO_ReturnFalse() {
|
||||
assertThat(mBatteryUtils.isLegacyApp(HIGH_SDK_PACKAGE)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetForceAppStandby_forcePreOApp_forceTwoRestrictions() {
|
||||
mBatteryUtils.setForceAppStandby(UID, LOW_SDK_PACKAGE, AppOpsManager.MODE_IGNORED);
|
||||
|
||||
// Restrict both OP_RUN_IN_BACKGROUND and OP_RUN_ANY_IN_BACKGROUND
|
||||
verify(mAppOpsManager).setMode(AppOpsManager.OP_RUN_IN_BACKGROUND, UID, LOW_SDK_PACKAGE,
|
||||
AppOpsManager.MODE_IGNORED);
|
||||
verify(mAppOpsManager).setMode(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, UID, LOW_SDK_PACKAGE,
|
||||
AppOpsManager.MODE_IGNORED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetForceAppStandby_forceOApp_forceOneRestriction() {
|
||||
mBatteryUtils.setForceAppStandby(UID, HIGH_SDK_PACKAGE, AppOpsManager.MODE_IGNORED);
|
||||
|
||||
// Don't restrict OP_RUN_IN_BACKGROUND because it is already been restricted for O app
|
||||
verify(mAppOpsManager, never()).setMode(AppOpsManager.OP_RUN_IN_BACKGROUND, UID,
|
||||
HIGH_SDK_PACKAGE, AppOpsManager.MODE_IGNORED);
|
||||
// Restrict OP_RUN_ANY_IN_BACKGROUND
|
||||
verify(mAppOpsManager).setMode(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, UID,
|
||||
HIGH_SDK_PACKAGE, AppOpsManager.MODE_IGNORED);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,10 +27,13 @@ import android.text.format.DateUtils;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.TestConfig;
|
||||
import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
|
||||
import com.android.settings.fuelgauge.batterytip.tips.HighUsageTip;
|
||||
import com.android.settings.fuelgauge.batterytip.tips.RestrictAppTip;
|
||||
import com.android.settings.fuelgauge.batterytip.tips.UnrestrictAppTip;
|
||||
import com.android.settings.testutils.FakeFeatureFactory;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
import com.android.settings.testutils.shadow.ShadowRuntimePermissionPresenter;
|
||||
import com.android.settings.testutils.shadow.ShadowUtils;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -47,14 +50,18 @@ import java.util.List;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION,
|
||||
shadows = ShadowRuntimePermissionPresenter.class)
|
||||
shadows = ShadowUtils.class)
|
||||
public class BatteryTipDialogFragmentTest {
|
||||
private static final String PACKAGE_NAME = "com.android.app";
|
||||
private static final String DISPLAY_NAME = "app";
|
||||
private static final long SCREEN_TIME_MS = DateUtils.HOUR_IN_MILLIS;
|
||||
|
||||
private BatteryTipDialogFragment mDialogFragment;
|
||||
private Context mContext;
|
||||
private HighUsageTip mHighUsageTip;
|
||||
private RestrictAppTip mRestrictedOneAppTip;
|
||||
private RestrictAppTip mRestrictAppsTip;
|
||||
private UnrestrictAppTip mUnrestrictAppTip;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
@@ -64,9 +71,22 @@ public class BatteryTipDialogFragmentTest {
|
||||
FakeFeatureFactory.setupForTest();
|
||||
|
||||
List<AppInfo> highUsageTips = new ArrayList<>();
|
||||
highUsageTips.add(new AppInfo.Builder().setScreenOnTimeMs(SCREEN_TIME_MS).setPackageName(
|
||||
PACKAGE_NAME).build());
|
||||
final AppInfo appInfo = new AppInfo.Builder()
|
||||
.setScreenOnTimeMs(SCREEN_TIME_MS)
|
||||
.setPackageName(PACKAGE_NAME)
|
||||
.build();
|
||||
highUsageTips.add(appInfo);
|
||||
mHighUsageTip = new HighUsageTip(SCREEN_TIME_MS, highUsageTips);
|
||||
|
||||
final List<AppInfo> restrictApps = new ArrayList<>();
|
||||
restrictApps.add(appInfo);
|
||||
mRestrictedOneAppTip = new RestrictAppTip(BatteryTip.StateType.NEW,
|
||||
new ArrayList<>(restrictApps));
|
||||
restrictApps.add(appInfo);
|
||||
mRestrictAppsTip = new RestrictAppTip(BatteryTip.StateType.NEW,
|
||||
new ArrayList<>(restrictApps));
|
||||
|
||||
mUnrestrictAppTip = new UnrestrictAppTip(BatteryTip.StateType.NEW, appInfo);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -82,5 +102,49 @@ public class BatteryTipDialogFragmentTest {
|
||||
mContext.getString(R.string.battery_tip_dialog_message, "1h"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnCreateDialog_restrictOneAppTip_fireRestrictOneAppDialog() {
|
||||
mDialogFragment = BatteryTipDialogFragment.newInstance(mRestrictedOneAppTip);
|
||||
|
||||
FragmentTestUtil.startFragment(mDialogFragment);
|
||||
|
||||
final AlertDialog dialog = (AlertDialog) ShadowDialog.getLatestDialog();
|
||||
ShadowAlertDialog shadowDialog = shadowOf(dialog);
|
||||
|
||||
assertThat(shadowDialog.getTitle()).isEqualTo("Restrict app?");
|
||||
assertThat(shadowDialog.getMessage()).isEqualTo(
|
||||
mContext.getString(R.string.battery_tip_restrict_app_dialog_message));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnCreateDialog_restrictAppsTip_fireRestrictAppsDialog() {
|
||||
mDialogFragment = BatteryTipDialogFragment.newInstance(mRestrictAppsTip);
|
||||
|
||||
FragmentTestUtil.startFragment(mDialogFragment);
|
||||
|
||||
final AlertDialog dialog = (AlertDialog) ShadowDialog.getLatestDialog();
|
||||
ShadowAlertDialog shadowDialog = shadowOf(dialog);
|
||||
|
||||
assertThat(shadowDialog.getTitle()).isEqualTo("Restrict 2 apps?");
|
||||
assertThat(shadowDialog.getMessage()).isEqualTo(
|
||||
mContext.getString(R.string.battery_tip_restrict_app_dialog_message));
|
||||
assertThat(shadowDialog.getView()).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnCreateDialog_unRestrictAppTip_fireUnRestrictDialog() {
|
||||
mDialogFragment = BatteryTipDialogFragment.newInstance(mUnrestrictAppTip);
|
||||
ShadowUtils.setApplicationLabel(PACKAGE_NAME, DISPLAY_NAME);
|
||||
|
||||
FragmentTestUtil.startFragment(mDialogFragment);
|
||||
|
||||
final AlertDialog dialog = (AlertDialog) ShadowDialog.getLatestDialog();
|
||||
ShadowAlertDialog shadowDialog = shadowOf(dialog);
|
||||
|
||||
assertThat(shadowDialog.getTitle()).isEqualTo("Remove restriction for app?");
|
||||
assertThat(shadowDialog.getMessage()).isEqualTo(
|
||||
mContext.getString(R.string.battery_tip_unrestrict_app_dialog_message));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -51,6 +51,7 @@ import java.util.List;
|
||||
public class BatteryTipLoaderTest {
|
||||
private static final int[] TIP_ORDER = {
|
||||
BatteryTip.TipType.SMART_BATTERY_MANAGER,
|
||||
BatteryTip.TipType.APP_RESTRICTION,
|
||||
BatteryTip.TipType.HIGH_DEVICE_USAGE,
|
||||
BatteryTip.TipType.BATTERY_SAVER,
|
||||
BatteryTip.TipType.LOW_BATTERY,
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.settings.fuelgauge.batterytip.actions;
|
||||
|
||||
import static org.mockito.Matchers.anyInt;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import android.app.AppOpsManager;
|
||||
import android.content.Context;
|
||||
|
||||
import com.android.settings.TestConfig;
|
||||
import com.android.settings.fuelgauge.BatteryUtils;
|
||||
import com.android.settings.fuelgauge.batterytip.AppInfo;
|
||||
import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
|
||||
import com.android.settings.fuelgauge.batterytip.tips.RestrictAppTip;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
|
||||
public class RestrictAppActionTest {
|
||||
private static final String PACKAGE_NAME_1 = "com.android.app1";
|
||||
private static final String PACKAGE_NAME_2 = "com.android.app2";
|
||||
|
||||
@Mock
|
||||
private BatteryUtils mBatteryUtils;
|
||||
private Context mContext;
|
||||
private RestrictAppAction mRestrictAppAction;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
mContext = RuntimeEnvironment.application;
|
||||
final List<AppInfo> mAppInfos = new ArrayList<>();
|
||||
mAppInfos.add(new AppInfo.Builder()
|
||||
.setPackageName(PACKAGE_NAME_1)
|
||||
.build());
|
||||
mAppInfos.add(new AppInfo.Builder()
|
||||
.setPackageName(PACKAGE_NAME_2)
|
||||
.build());
|
||||
|
||||
mRestrictAppAction = new RestrictAppAction(mContext, new RestrictAppTip(
|
||||
BatteryTip.StateType.NEW, mAppInfos));
|
||||
mRestrictAppAction.mBatteryUtils = mBatteryUtils;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHandlePositiveAction() {
|
||||
mRestrictAppAction.handlePositiveAction();
|
||||
|
||||
verify(mBatteryUtils).setForceAppStandby(anyInt(), eq(PACKAGE_NAME_1),
|
||||
eq(AppOpsManager.MODE_IGNORED));
|
||||
verify(mBatteryUtils).setForceAppStandby(anyInt(), eq(PACKAGE_NAME_2),
|
||||
eq(AppOpsManager.MODE_IGNORED));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.settings.fuelgauge.batterytip.tips;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.spy;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Parcel;
|
||||
|
||||
import com.android.settings.TestConfig;
|
||||
import com.android.settings.fuelgauge.batterytip.AppInfo;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
|
||||
public class RestrictAppTipTest {
|
||||
private static final String PACKAGE_NAME = "com.android.app";
|
||||
private static final String DISPLAY_NAME = "app";
|
||||
|
||||
private Context mContext;
|
||||
private RestrictAppTip mNewBatteryTip;
|
||||
private RestrictAppTip mHandledBatteryTip;
|
||||
private List<AppInfo> mUsageAppList;
|
||||
@Mock
|
||||
private ApplicationInfo mApplicationInfo;
|
||||
@Mock
|
||||
private PackageManager mPackageManager;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
mContext = spy(RuntimeEnvironment.application);
|
||||
doReturn(mPackageManager).when(mContext).getPackageManager();
|
||||
doReturn(mApplicationInfo).when(mPackageManager).getApplicationInfo(PACKAGE_NAME,
|
||||
PackageManager.MATCH_DISABLED_COMPONENTS | PackageManager.MATCH_ANY_USER);
|
||||
doReturn(DISPLAY_NAME).when(mApplicationInfo).loadLabel(mPackageManager);
|
||||
|
||||
mUsageAppList = new ArrayList<>();
|
||||
mUsageAppList.add(new AppInfo.Builder()
|
||||
.setPackageName(PACKAGE_NAME)
|
||||
.build());
|
||||
mNewBatteryTip = new RestrictAppTip(BatteryTip.StateType.NEW, mUsageAppList);
|
||||
mHandledBatteryTip = new RestrictAppTip(BatteryTip.StateType.HANDLED, mUsageAppList);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParcelable() {
|
||||
Parcel parcel = Parcel.obtain();
|
||||
mNewBatteryTip.writeToParcel(parcel, mNewBatteryTip.describeContents());
|
||||
parcel.setDataPosition(0);
|
||||
|
||||
final RestrictAppTip parcelTip = new RestrictAppTip(parcel);
|
||||
|
||||
assertThat(parcelTip.getType()).isEqualTo(BatteryTip.TipType.APP_RESTRICTION);
|
||||
assertThat(parcelTip.getState()).isEqualTo(BatteryTip.StateType.NEW);
|
||||
final AppInfo app = parcelTip.getRestrictAppList().get(0);
|
||||
assertThat(app.packageName).isEqualTo(PACKAGE_NAME);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetTitle_stateNew_showRestrictTitle() {
|
||||
assertThat(mNewBatteryTip.getTitle(mContext)).isEqualTo("Restrict 1 app");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetTitle_stateHandled_showHandledTitle() {
|
||||
assertThat(mHandledBatteryTip.getTitle(mContext)).isEqualTo("1 recently restricted");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSummary_stateNew_showRestrictSummary() {
|
||||
assertThat(mNewBatteryTip.getSummary(mContext)).isEqualTo(
|
||||
"app has high battery usage");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSummary_stateHandled_showHandledSummary() {
|
||||
assertThat(mHandledBatteryTip.getSummary(mContext)).isEqualTo(
|
||||
"App changes are in progress");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.settings.fuelgauge.batterytip.tips;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.os.Parcel;
|
||||
|
||||
import com.android.settings.TestConfig;
|
||||
import com.android.settings.fuelgauge.batterytip.AppInfo;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
|
||||
public class UnrestrictAppTipTest {
|
||||
private static final String PACKAGE_NAME = "com.android.app";
|
||||
|
||||
private UnrestrictAppTip mBatteryTip;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
AppInfo appInfo = new AppInfo.Builder()
|
||||
.setPackageName(PACKAGE_NAME)
|
||||
.build();
|
||||
mBatteryTip = new UnrestrictAppTip(BatteryTip.StateType.NEW, appInfo);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParcelable() {
|
||||
Parcel parcel = Parcel.obtain();
|
||||
mBatteryTip.writeToParcel(parcel, mBatteryTip.describeContents());
|
||||
parcel.setDataPosition(0);
|
||||
|
||||
final UnrestrictAppTip parcelTip = new UnrestrictAppTip(parcel);
|
||||
|
||||
assertThat(parcelTip.getType()).isEqualTo(BatteryTip.TipType.REMOVE_APP_RESTRICTION);
|
||||
assertThat(parcelTip.getState()).isEqualTo(BatteryTip.StateType.NEW);
|
||||
assertThat(parcelTip.getPackageName()).isEqualTo(PACKAGE_NAME);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,220 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.settings.location;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.anyInt;
|
||||
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 static org.mockito.Mockito.when;
|
||||
|
||||
import android.arch.lifecycle.LifecycleOwner;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.res.Resources;
|
||||
import android.location.LocationManager;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.support.v7.preference.PreferenceCategory;
|
||||
import com.android.settings.TestConfig;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
/** Unit tests for {@link LocationFooterPreferenceController} */
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
|
||||
public class LocationFooterPreferenceControllerTest {
|
||||
|
||||
@Mock
|
||||
private PreferenceCategory mPreferenceCategory;
|
||||
@Mock
|
||||
private PackageManager mPackageManager;
|
||||
@Mock
|
||||
private Resources mResources;
|
||||
private Context mContext;
|
||||
private LocationFooterPreferenceController mController;
|
||||
private LifecycleOwner mLifecycleOwner;
|
||||
private Lifecycle mLifecycle;
|
||||
private static final int TEST_RES_ID = 1234;
|
||||
private static final String TEST_TEXT = "text";
|
||||
|
||||
@Before
|
||||
public void setUp() throws NameNotFoundException {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = spy(RuntimeEnvironment.application);
|
||||
when(mContext.getPackageManager()).thenReturn(mPackageManager);
|
||||
mLifecycleOwner = () -> mLifecycle;
|
||||
mLifecycle = new Lifecycle(mLifecycleOwner);
|
||||
when(mPreferenceCategory.getContext()).thenReturn(mContext);
|
||||
mController = spy(new LocationFooterPreferenceController(mContext, mLifecycle));
|
||||
when(mPackageManager.getResourcesForApplication(any(ApplicationInfo.class)))
|
||||
.thenReturn(mResources);
|
||||
when(mResources.getString(TEST_RES_ID)).thenReturn(TEST_TEXT);
|
||||
doNothing().when(mPreferenceCategory).removeAll();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isAvailable_hasValidFooter_returnsTrue() throws NameNotFoundException {
|
||||
final List<ResolveInfo> testResolveInfos = new ArrayList<>();
|
||||
testResolveInfos.add(
|
||||
getTestResolveInfo(/*isSystemApp*/ true, /*hasRequiredMetadata*/ true));
|
||||
when(mPackageManager.queryBroadcastReceivers(any(Intent.class), anyInt()))
|
||||
.thenReturn(testResolveInfos);
|
||||
|
||||
assertThat(mController.isAvailable()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isAvailable_noSystemApp_returnsFalse() throws NameNotFoundException {
|
||||
final List<ResolveInfo> testResolveInfos = new ArrayList<>();
|
||||
testResolveInfos.add(
|
||||
getTestResolveInfo(/*isSystemApp*/ false, /*hasRequiredMetadata*/ true));
|
||||
when(mPackageManager.queryBroadcastReceivers(any(Intent.class), anyInt()))
|
||||
.thenReturn(testResolveInfos);
|
||||
assertThat(mController.isAvailable()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isAvailable_noRequiredMetadata_returnsFalse() throws NameNotFoundException {
|
||||
final List<ResolveInfo> testResolveInfos = new ArrayList<>();
|
||||
testResolveInfos.add(
|
||||
getTestResolveInfo(/*isSystemApp*/ true, /*hasRequiredMetadata*/ false));
|
||||
when(mPackageManager.queryBroadcastReceivers(any(Intent.class), anyInt()))
|
||||
.thenReturn(testResolveInfos);
|
||||
assertThat(mController.isAvailable()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sendBroadcastFooterInject() {
|
||||
ArgumentCaptor<Intent> intent = ArgumentCaptor.forClass(Intent.class);
|
||||
final ActivityInfo activityInfo =
|
||||
getTestResolveInfo(/*isSystemApp*/ true, /*hasRequiredMetadata*/ true).activityInfo;
|
||||
mController.sendBroadcastFooterDisplayed(
|
||||
new ComponentName(activityInfo.packageName, activityInfo.name));
|
||||
verify(mContext).sendBroadcast(intent.capture());
|
||||
assertThat(intent.getValue().getAction())
|
||||
.isEqualTo(LocationManager.SETTINGS_FOOTER_DISPLAYED_ACTION);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_sendBroadcast() throws NameNotFoundException {
|
||||
final List<ResolveInfo> testResolveInfos = new ArrayList<>();
|
||||
testResolveInfos.add(
|
||||
getTestResolveInfo(/*isSystemApp*/ true, /*hasRequiredMetadata*/ true));
|
||||
when(mPackageManager.queryBroadcastReceivers(any(), anyInt()))
|
||||
.thenReturn(testResolveInfos);
|
||||
mController.updateState(mPreferenceCategory);
|
||||
ArgumentCaptor<Intent> intent = ArgumentCaptor.forClass(Intent.class);
|
||||
verify(mContext).sendBroadcast(intent.capture());
|
||||
assertThat(intent.getValue().getAction())
|
||||
.isEqualTo(LocationManager.SETTINGS_FOOTER_DISPLAYED_ACTION);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_addPreferences() throws NameNotFoundException {
|
||||
final List<ResolveInfo> testResolveInfos = new ArrayList<>();
|
||||
testResolveInfos.add(
|
||||
getTestResolveInfo(/*isSystemApp*/ true, /*hasRequiredMetadata*/ true));
|
||||
when(mPackageManager.queryBroadcastReceivers(any(Intent.class), anyInt()))
|
||||
.thenReturn(testResolveInfos);
|
||||
mController.updateState(mPreferenceCategory);
|
||||
ArgumentCaptor<Preference> pref = ArgumentCaptor.forClass(Preference.class);
|
||||
verify(mPreferenceCategory).addPreference(pref.capture());
|
||||
assertThat(pref.getValue().getTitle()).isEqualTo(TEST_TEXT);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_notSystemApp_ignore() throws NameNotFoundException {
|
||||
final List<ResolveInfo> testResolveInfos = new ArrayList<>();
|
||||
testResolveInfos.add(
|
||||
getTestResolveInfo(/*isSystemApp*/ false, /*hasRequiredMetadata*/ true));
|
||||
when(mPackageManager.queryBroadcastReceivers(any(Intent.class), anyInt()))
|
||||
.thenReturn(testResolveInfos);
|
||||
mController.updateState(mPreferenceCategory);
|
||||
verify(mPreferenceCategory, never()).addPreference(any(Preference.class));
|
||||
verify(mContext, never()).sendBroadcast(any(Intent.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_thenOnPause_sendBroadcasts() throws NameNotFoundException {
|
||||
final List<ResolveInfo> testResolveInfos = new ArrayList<>();
|
||||
testResolveInfos.add(
|
||||
getTestResolveInfo(/*isSystemApp*/ true, /*hasRequiredMetadata*/ true));
|
||||
when(mPackageManager.queryBroadcastReceivers(any(Intent.class), anyInt()))
|
||||
.thenReturn(testResolveInfos);
|
||||
mController.updateState(mPreferenceCategory);
|
||||
ArgumentCaptor<Intent> intent = ArgumentCaptor.forClass(Intent.class);
|
||||
verify(mContext).sendBroadcast(intent.capture());
|
||||
assertThat(intent.getValue().getAction())
|
||||
.isEqualTo(LocationManager.SETTINGS_FOOTER_DISPLAYED_ACTION);
|
||||
|
||||
mController.onPause();
|
||||
verify(mContext, times(2)).sendBroadcast(intent.capture());
|
||||
assertThat(intent.getValue().getAction())
|
||||
.isEqualTo(LocationManager.SETTINGS_FOOTER_REMOVED_ACTION);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPause_doNotSendBroadcast() {
|
||||
mController.onPause();
|
||||
verify(mContext, never()).sendBroadcast(any(Intent.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a ResolveInfo object for testing
|
||||
* @param isSystemApp If true, the application is a system app.
|
||||
* @param hasRequiredMetaData If true, the broadcast receiver has a valid value for
|
||||
* {@link LocationManager#METADATA_SETTINGS_FOOTER_STRING}
|
||||
*/
|
||||
private ResolveInfo getTestResolveInfo(boolean isSystemApp, boolean hasRequiredMetaData) {
|
||||
ResolveInfo testResolveInfo = new ResolveInfo();
|
||||
ApplicationInfo testAppInfo = new ApplicationInfo();
|
||||
if (isSystemApp) {
|
||||
testAppInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
|
||||
}
|
||||
ActivityInfo testActivityInfo = new ActivityInfo();
|
||||
testActivityInfo.name = "TestActivityName";
|
||||
testActivityInfo.packageName = "TestPackageName";
|
||||
testActivityInfo.applicationInfo = testAppInfo;
|
||||
if (hasRequiredMetaData) {
|
||||
testActivityInfo.metaData = new Bundle();
|
||||
testActivityInfo.metaData.putInt(
|
||||
LocationManager.METADATA_SETTINGS_FOOTER_STRING, TEST_RES_ID);
|
||||
}
|
||||
testResolveInfo.activityInfo = testActivityInfo;
|
||||
return testResolveInfo;
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,9 @@ import com.android.settings.wrapper.FingerprintManagerWrapper;
|
||||
import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Implements(Utils.class)
|
||||
public class ShadowUtils {
|
||||
|
||||
@@ -34,6 +37,7 @@ public class ShadowUtils {
|
||||
private static boolean sIsUserAMonkey;
|
||||
private static boolean sIsDemoUser;
|
||||
private static ComponentName sDeviceOwnerComponentName;
|
||||
private static Map<String, String> sAppNameMap;
|
||||
|
||||
@Implementation
|
||||
public static int enforceSameOwner(Context context, int userId) {
|
||||
@@ -89,4 +93,19 @@ public class ShadowUtils {
|
||||
public static int getManagedProfileId(UserManager um, int parentUserId) {
|
||||
return UserHandle.USER_NULL;
|
||||
}
|
||||
|
||||
@Implementation
|
||||
public static CharSequence getApplicationLabel(Context context, String packageName) {
|
||||
if (sAppNameMap != null) {
|
||||
return sAppNameMap.get(packageName);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void setApplicationLabel(String packageName, String appLabel) {
|
||||
if (sAppNameMap == null) {
|
||||
sAppNameMap = new HashMap<>();
|
||||
}
|
||||
sAppNameMap.put(packageName, appLabel);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,6 +36,8 @@ import org.robolectric.annotation.Config;
|
||||
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
|
||||
public class AppPreferenceTest {
|
||||
|
||||
private static final int EXPECTED_APP_ICON_SIZE_DP = 32;
|
||||
|
||||
private Context mContext;
|
||||
private View mRootView;
|
||||
private AppPreference mPref;
|
||||
@@ -75,4 +77,12 @@ public class AppPreferenceTest {
|
||||
assertThat(mHolder.findViewById(R.id.summary_container).getVisibility())
|
||||
.isEqualTo(View.GONE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void foobar_testName() {
|
||||
// Can't use isEquals() to compare float. Use isWithIn().of() instead.
|
||||
assertThat(mContext.getResources().getDimension(R.dimen.secondary_app_icon_size))
|
||||
.isWithin(0.01f)
|
||||
.of(EXPECTED_APP_ICON_SIZE_DP);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,7 +73,8 @@ import java.util.ArrayList;
|
||||
})
|
||||
public class WifiTetherPreferenceControllerTest {
|
||||
|
||||
@Mock
|
||||
private static final String SSID = "Pixel";
|
||||
|
||||
private Context mContext;
|
||||
@Mock
|
||||
private ConnectivityManager mConnectivityManager;
|
||||
@@ -81,6 +82,8 @@ public class WifiTetherPreferenceControllerTest {
|
||||
private WifiManager mWifiManager;
|
||||
@Mock
|
||||
private PreferenceScreen mScreen;
|
||||
@Mock
|
||||
private WifiConfiguration mWifiConfiguration;
|
||||
|
||||
private WifiTetherPreferenceController mController;
|
||||
private Lifecycle mLifecycle;
|
||||
@@ -90,6 +93,8 @@ public class WifiTetherPreferenceControllerTest {
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
mContext = spy(RuntimeEnvironment.application);
|
||||
mLifecycleOwner = () -> mLifecycle;
|
||||
mLifecycle = new Lifecycle(mLifecycleOwner);
|
||||
FakeFeatureFactory.setupForTest();
|
||||
@@ -98,10 +103,13 @@ public class WifiTetherPreferenceControllerTest {
|
||||
.thenReturn(mConnectivityManager);
|
||||
when(mContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(mWifiManager);
|
||||
when(mScreen.findPreference(anyString())).thenReturn(mPreference);
|
||||
when(mWifiManager.getWifiApConfiguration()).thenReturn(mWifiConfiguration);
|
||||
mWifiConfiguration.SSID = SSID;
|
||||
|
||||
when(mConnectivityManager.getTetherableWifiRegexs()).thenReturn(new String[]{"1", "2"});
|
||||
mController = new WifiTetherPreferenceController(mContext, mLifecycle,
|
||||
false /* initSoftApManager */);
|
||||
mController.displayPreference(mScreen);
|
||||
}
|
||||
|
||||
@After
|
||||
@@ -127,7 +135,6 @@ public class WifiTetherPreferenceControllerTest {
|
||||
public void startAndStop_shouldRegisterUnregisterReceiver() {
|
||||
final BroadcastReceiver receiver = ReflectionHelpers.getField(mController, "mReceiver");
|
||||
|
||||
mController.displayPreference(mScreen);
|
||||
mLifecycle.handleLifecycleEvent(ON_START);
|
||||
mLifecycle.handleLifecycleEvent(ON_STOP);
|
||||
|
||||
@@ -166,48 +173,6 @@ public class WifiTetherPreferenceControllerTest {
|
||||
verify(pref).setChecked(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReceiver_apStateChangedToDisabled_shouldUpdatePreferenceSummary() {
|
||||
mController.displayPreference(mScreen);
|
||||
receiveApStateChangedBroadcast(WifiManager.WIFI_AP_STATE_DISABLED);
|
||||
assertThat(mPreference.getSummary().toString()).isEqualTo(
|
||||
RuntimeEnvironment.application.getString(R.string.wifi_hotspot_off_subtext));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReceiver_apStateChangedToDisabling_shouldUpdatePreferenceSummary() {
|
||||
mController.displayPreference(mScreen);
|
||||
receiveApStateChangedBroadcast(WifiManager.WIFI_AP_STATE_DISABLING);
|
||||
assertThat(mPreference.getSummary().toString()).isEqualTo(
|
||||
RuntimeEnvironment.application.getString(R.string.wifi_tether_stopping));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReceiver_apStateChangedToEnabling_shouldUpdatePreferenceSummary() {
|
||||
mController.displayPreference(mScreen);
|
||||
receiveApStateChangedBroadcast(WifiManager.WIFI_AP_STATE_ENABLING);
|
||||
assertThat(mPreference.getSummary().toString()).isEqualTo(
|
||||
RuntimeEnvironment.application.getString(R.string.wifi_tether_starting));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReceiver_apStateChangedToEnabled_shouldNotUpdatePreferenceSummary() {
|
||||
mController.displayPreference(mScreen);
|
||||
receiveApStateChangedBroadcast(WifiManager.WIFI_AP_STATE_DISABLED);
|
||||
assertThat(mPreference.getSummary().toString()).isEqualTo(
|
||||
RuntimeEnvironment.application.getString(R.string.wifi_hotspot_off_subtext));
|
||||
|
||||
// When turning on the hotspot, we receive STATE_ENABLING followed by STATE_ENABLED. The
|
||||
// first should change the status to wifi_tether_starting, and the second should not change
|
||||
// this.
|
||||
receiveApStateChangedBroadcast(WifiManager.WIFI_AP_STATE_ENABLING);
|
||||
assertThat(mPreference.getSummary().toString()).isEqualTo(
|
||||
RuntimeEnvironment.application.getString(R.string.wifi_tether_starting));
|
||||
receiveApStateChangedBroadcast(WifiManager.WIFI_AP_STATE_ENABLED);
|
||||
assertThat(mPreference.getSummary().toString()).isEqualTo(
|
||||
RuntimeEnvironment.application.getString(R.string.wifi_tether_starting));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReceiver_goingToAirplaneMode_shouldClearPreferenceSummary() {
|
||||
final ContentResolver cr = mock(ContentResolver.class);
|
||||
@@ -224,22 +189,32 @@ public class WifiTetherPreferenceControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReceiver_tetherEnabled_shouldUpdatePreferenceSummary() {
|
||||
mController.displayPreference(mScreen);
|
||||
final BroadcastReceiver receiver = ReflectionHelpers.getField(mController, "mReceiver");
|
||||
final Intent broadcast = new Intent(ConnectivityManager.ACTION_TETHER_STATE_CHANGED);
|
||||
final ArrayList<String> activeTethers = new ArrayList<>();
|
||||
activeTethers.add("1");
|
||||
broadcast.putStringArrayListExtra(ConnectivityManager.EXTRA_ACTIVE_TETHER, activeTethers);
|
||||
broadcast.putStringArrayListExtra(ConnectivityManager.EXTRA_ERRORED_TETHER,
|
||||
new ArrayList<>());
|
||||
final WifiConfiguration configuration = new WifiConfiguration();
|
||||
configuration.SSID = "test-ap";
|
||||
when(mWifiManager.getWifiApConfiguration()).thenReturn(configuration);
|
||||
public void testHandleWifiApStateChanged_stateEnabling_showEnablingSummary() {
|
||||
mController.handleWifiApStateChanged(WifiManager.WIFI_AP_STATE_ENABLING, 0 /* reason */);
|
||||
|
||||
receiver.onReceive(RuntimeEnvironment.application, broadcast);
|
||||
assertThat(mPreference.getSummary()).isEqualTo("Turning hotspot on\u2026");
|
||||
}
|
||||
|
||||
verify(mContext).getString(eq(R.string.wifi_tether_enabled_subtext), any());
|
||||
@Test
|
||||
public void testHandleWifiApStateChanged_stateEnabled_showEnabledSummary() {
|
||||
mController.handleWifiApStateChanged(WifiManager.WIFI_AP_STATE_ENABLED, 0 /* reason */);
|
||||
|
||||
assertThat(mPreference.getSummary()).isEqualTo("Pixel is active");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHandleWifiApStateChanged_stateDisabling_showDisablingSummary() {
|
||||
mController.handleWifiApStateChanged(WifiManager.WIFI_AP_STATE_DISABLING, 0 /* reason */);
|
||||
|
||||
assertThat(mPreference.getSummary()).isEqualTo("Turning off hotspot\u2026");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHandleWifiApStateChanged_stateDisabled_showDisabledSummary() {
|
||||
mController.handleWifiApStateChanged(WifiManager.WIFI_AP_STATE_DISABLED, 0 /* reason */);
|
||||
|
||||
assertThat(mPreference.getSummary()).isEqualTo(
|
||||
"Not sharing internet or content with other devices");
|
||||
}
|
||||
|
||||
@Implements(WifiTetherSettings.class)
|
||||
@@ -285,17 +260,4 @@ public class WifiTetherPreferenceControllerTest {
|
||||
onStopCalled = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to cause the controller to receive a WIFI_AP_STATE_CHANGED_ACTION with a specific
|
||||
* state.
|
||||
*
|
||||
* @param state - the state, as specified by one of the WifiManager.WIFI_AP_STATE_* values
|
||||
*/
|
||||
private void receiveApStateChangedBroadcast(int state) {
|
||||
final BroadcastReceiver receiver = ReflectionHelpers.getField(mController, "mReceiver");
|
||||
final Intent broadcast = new Intent(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
|
||||
broadcast.putExtra(WifiManager.EXTRA_WIFI_AP_STATE, state);
|
||||
receiver.onReceive(RuntimeEnvironment.application, broadcast);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user