Snap for 4615953 from 032e7c0def to pi-release

Change-Id: Id475665239df500b34dcbfec83ff78a18969692a
This commit is contained in:
android-build-team Robot
2018-02-22 08:26:04 +00:00
44 changed files with 983 additions and 832 deletions

View File

@@ -20,24 +20,39 @@
android:id="@+id/instant_app_button_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="4dp"
android:paddingStart="8dp"
android:paddingEnd="8dp"
android:visibility="gone">
<Button
android:id="@+id/install"
style="@style/ActionPrimaryButton"
android:enabled="false"
android:gravity="center"
android:paddingTop="24dp"
android:paddingStart="68dp"
android:paddingEnd="24dp"
android:orientation="horizontal">
<FrameLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/install_text"/>
android:layout_height="wrap_content">
<Button
android:id="@+id/install"
style="@style/ActionPrimaryButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="4dp"
android:text="@string/install_text"/>
<Button
android:id="@+id/launch"
style="@style/ActionPrimaryButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="4dp"
android:text="@string/launch_instant_app"/>
</FrameLayout>
<Space
android:layout_width="16dp"
android:layout_height="wrap_content" />
<Button
android:id="@+id/clear_data"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginBottom="4dp"
android:text="@string/clear_instant_app_data"/>
</LinearLayout>

View File

@@ -31,6 +31,7 @@
android:gravity="start|center_vertical"
android:minWidth="56dp"
android:orientation="horizontal"
android:paddingStart="4dp"
android:paddingEnd="8dp"
android:paddingTop="4dp"
android:paddingBottom="4dp">

View File

@@ -150,15 +150,6 @@
<!-- Whether default_home should be shown or not. -->
<bool name="config_show_default_home">true</bool>
<!-- Whether color correction preference should be shown or not. -->
<bool name="config_show_color_correction_preference">true</bool>
<!-- Whether color inversion preference should be shown or not. -->
<bool name="config_show_color_inversion_preference">true</bool>
<!-- Whether accessibility shortcut preference should be shown or not. -->
<bool name="config_show_accessibility_shortcut_preference">true</bool>
<!-- Whether assist_and_voice_input should be shown or not. -->
<bool name="config_show_assist_and_voice_input">true</bool>

View File

@@ -8096,6 +8096,10 @@
for this device should be used for. These options are less commonly used.
Choices are usb_use_tethering, usb_use_photo_transfers, usb_use_MIDI, and usb_use_power_only.-->
<string name="usb_use_also">Also use USB for</string>
<!-- The label that leads to the Default USB configuration window. -->
<string name="usb_default_label">Default USB Configuration</string>
<!-- Description at the footer of the default USB configuration window that describes how the setting works. -->
<string name="usb_default_info">When another device is connected and your phone is unlocked, these settings will be applied. Only connect to trusted devices.</string>
<!-- Settings item title for USB preference [CHAR LIMIT=35] -->
<string name="usb_pref">USB</string>

View File

@@ -235,12 +235,11 @@
android:title="@string/tethering_hardware_offload"
android:summary="@string/tethering_hardware_offload_summary" />
<ListPreference
android:key="select_usb_configuration"
android:title="@string/select_usb_configuration_title"
android:dialogTitle="@string/select_usb_configuration_dialog_title"
android:entries="@array/usb_configuration_titles"
android:entryValues="@array/usb_configuration_values" />
<Preference
android:key="default_usb_configuration"
android:fragment="com.android.settings.connecteddevice.usb.UsbDefaultFragment"
android:icon="@drawable/ic_usb"
android:title="@string/usb_default_label"/>
<SwitchPreference
android:key="bluetooth_show_devices_without_names"

View File

@@ -36,7 +36,8 @@
<com.android.settings.widget.MasterSwitchPreference
android:fragment="com.android.settings.fuelgauge.batterysaver.BatterySaverSettings"
android:key="battery_saver_summary"
android:title="@string/battery_saver"/>
android:title="@string/battery_saver"
settings:controller="com.android.settings.fuelgauge.BatterySaverController"/>
<Preference
android:fragment="com.android.settings.fuelgauge.SmartBatterySettings"

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
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.
-->
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
android:title="@string/usb_pref"
android:key="usb_default_fragment">
</PreferenceScreen>

View File

@@ -33,7 +33,6 @@ import android.os.UserHandle;
import android.os.Vibrator;
import android.provider.SearchIndexableResource;
import android.provider.Settings;
import android.support.annotation.VisibleForTesting;
import android.support.v14.preference.SwitchPreference;
import android.support.v4.content.ContextCompat;
import android.support.v7.preference.ListPreference;
@@ -93,6 +92,8 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
// Preferences
private static final String TOGGLE_HIGH_TEXT_CONTRAST_PREFERENCE =
"toggle_high_text_contrast_preference";
private static final String TOGGLE_INVERSION_PREFERENCE =
"toggle_inversion_preference";
private static final String TOGGLE_POWER_BUTTON_ENDS_CALL_PREFERENCE =
"toggle_power_button_ends_call_preference";
private static final String TOGGLE_LOCK_SCREEN_ROTATION_PREFERENCE =
@@ -104,6 +105,8 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
"toggle_master_mono";
private static final String SELECT_LONG_PRESS_TIMEOUT_PREFERENCE =
"select_long_press_timeout_preference";
private static final String ACCESSIBILITY_SHORTCUT_PREFERENCE =
"accessibility_shortcut_preference";
private static final String CAPTIONING_PREFERENCE_SCREEN =
"captioning_preference_screen";
private static final String DISPLAY_MAGNIFICATION_PREFERENCE_SCREEN =
@@ -116,13 +119,8 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
"autoclick_preference_screen";
private static final String VIBRATION_PREFERENCE_SCREEN =
"vibration_preference_screen";
@VisibleForTesting static final String TOGGLE_INVERSION_PREFERENCE =
"toggle_inversion_preference";
@VisibleForTesting static final String DISPLAY_DALTONIZER_PREFERENCE_SCREEN =
private static final String DISPLAY_DALTONIZER_PREFERENCE_SCREEN =
"daltonizer_preference_screen";
@VisibleForTesting static final String ACCESSIBILITY_SHORTCUT_PREFERENCE =
"accessibility_shortcut_preference";
// Extras passed to sub-fragments.
static final String EXTRA_PREFERENCE_KEY = "preference_key";
@@ -627,8 +625,6 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
displayCategory.addPreference(mToggleInversionPreference);
displayCategory.addPreference(mDisplayDaltonizerPreferenceScreen);
}
checkColorCorrectionVisibility(mDisplayDaltonizerPreferenceScreen);
checkColorInversionVisibility(mToggleInversionPreference);
// Text contrast.
mToggleHighTextContrastPreference.setChecked(
@@ -683,7 +679,6 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
updateAutoclickSummary(mAutoclickPreferenceScreen);
updateAccessibilityShortcut(mAccessibilityShortcutPreferenceScreen);
checkAccessibilityShortcutVisibility(mAccessibilityShortcutPreferenceScreen);
}
private void updateMagnificationSummary(Preference pref) {
@@ -804,27 +799,6 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
}
}
@VisibleForTesting void checkColorCorrectionVisibility(Preference preference) {
if (!getContext().getResources().getBoolean(
R.bool.config_show_color_correction_preference)) {
removePreference(DISPLAY_DALTONIZER_PREFERENCE_SCREEN);
}
}
@VisibleForTesting void checkColorInversionVisibility(Preference preference) {
if (!getContext().getResources().getBoolean(
R.bool.config_show_color_inversion_preference)) {
removePreference(TOGGLE_INVERSION_PREFERENCE);
}
}
@VisibleForTesting void checkAccessibilityShortcutVisibility(Preference preference) {
if (!getContext().getResources().getBoolean(
R.bool.config_show_accessibility_shortcut_preference)) {
removePreference(ACCESSIBILITY_SHORTCUT_PREFERENCE);
}
}
private static void configureMagnificationPreferenceIfNeeded(Preference preference) {
// Some devices support only a single magnification mode. In these cases, we redirect to
// the magnification mode's UI directly, rather than showing a PreferenceScreen with a
@@ -860,12 +834,6 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
keys.add(FONT_SIZE_PREFERENCE_SCREEN);
keys.add(KEY_DISPLAY_SIZE);
// Remove Accessibility Shortcuts if it's not visible
if (!context.getResources().getBoolean(
R.bool.config_show_accessibility_shortcut_preference)) {
keys.add(ACCESSIBILITY_SHORTCUT_PREFERENCE);
}
// Duplicates in Language & Input
keys.add(TTS_SETTINGS_PREFERENCE);

View File

@@ -17,24 +17,13 @@
package com.android.settings.applications;
import android.annotation.UserIdInt;
import android.app.Fragment;
import android.content.Intent;
import android.view.View;
import com.android.settings.applications.instantapps.InstantAppButtonsController;
import java.util.List;
import java.util.Set;
public interface ApplicationFeatureProvider {
/**
* Returns a new {@link InstantAppButtonsController} instance for showing buttons
* only relevant to instant apps.
*/
InstantAppButtonsController newInstantAppButtonsController(Fragment fragment,
View view, InstantAppButtonsController.ShowDialogDelegate showDialogDelegate);
/**
* Calculates the total number of apps installed on the device via policy in the current user
* and all its managed profiles.

View File

@@ -16,7 +16,6 @@
package com.android.settings.applications;
import android.app.Fragment;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ComponentInfo;
@@ -26,9 +25,7 @@ import android.content.pm.UserInfo;
import android.os.RemoteException;
import android.os.UserManager;
import android.util.ArraySet;
import android.view.View;
import com.android.settings.applications.instantapps.InstantAppButtonsController;
import com.android.settings.wrapper.DevicePolicyManagerWrapper;
import com.android.settings.wrapper.IPackageManagerWrapper;
import com.android.settingslib.wrapper.PackageManagerWrapper;
@@ -54,12 +51,6 @@ public class ApplicationFeatureProviderImpl implements ApplicationFeatureProvide
mUm = UserManager.get(mContext);
}
@Override
public InstantAppButtonsController newInstantAppButtonsController(Fragment fragment,
View view, InstantAppButtonsController.ShowDialogDelegate showDialogDelegate) {
return new InstantAppButtonsController(mContext, fragment, view, showDialogDelegate);
}
@Override
public void calculateNumberOfPolicyInstalledApps(boolean async, NumberOfAppsCallback callback) {
final CurrentUserAndManagedProfilePolicyInstalledAppCounter counter =

View File

@@ -86,6 +86,7 @@ public class AppInfoDashboardFragment extends DashboardFragment
@VisibleForTesting static final int UNINSTALL_ALL_USERS_MENU = 1;
@VisibleForTesting static final int UNINSTALL_UPDATES = 2;
static final int FORCE_STOP_MENU = 3;
static final int INSTALL_INSTANT_APP_MENU = 4;
// Result code identifiers
@VisibleForTesting
@@ -103,6 +104,7 @@ public class AppInfoDashboardFragment extends DashboardFragment
static final int DLG_FORCE_STOP = DLG_BASE + 1;
private static final int DLG_DISABLE = DLG_BASE + 2;
private static final int DLG_SPECIAL_DISABLE = DLG_BASE + 3;
static final int DLG_CLEAR_INSTANT_APP = DLG_BASE + 4;
private static final String KEY_ADVANCED_APP_INFO_CATEGORY = "advanced_app_info";
@@ -244,7 +246,7 @@ public class AppInfoDashboardFragment extends DashboardFragment
// The following are controllers for preferences that don't need to refresh the preference
// state when app state changes.
mInstantAppButtonPreferenceController =
new InstantAppButtonsPreferenceController(context, this, packageName);
new InstantAppButtonsPreferenceController(context, this, packageName, lifecycle);
controllers.add(mInstantAppButtonPreferenceController);
controllers.add(new AppBatteryPreferenceController(context, this, packageName, lifecycle));
controllers.add(new AppMemoryPreferenceController(context, this, lifecycle));

View File

@@ -18,30 +18,62 @@ package com.android.settings.applications.appinfo;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Bundle;
import android.os.UserHandle;
import android.support.annotation.VisibleForTesting;
import android.support.v7.preference.PreferenceScreen;
import android.text.TextUtils;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.applications.ApplicationFeatureProvider;
import com.android.settings.applications.AppStoreUtil;
import com.android.settings.applications.LayoutPreference;
import com.android.settings.applications.instantapps.InstantAppButtonsController;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.applications.AppUtils;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnCreateOptionsMenu;
import com.android.settingslib.core.lifecycle.events.OnOptionsItemSelected;
import com.android.settingslib.core.lifecycle.events.OnPrepareOptionsMenu;
import com.android.settingslib.wrapper.PackageManagerWrapper;
public class InstantAppButtonsPreferenceController extends BasePreferenceController {
import java.util.List;
public class InstantAppButtonsPreferenceController extends BasePreferenceController implements
LifecycleObserver, OnCreateOptionsMenu, OnPrepareOptionsMenu, OnOptionsItemSelected,
DialogInterface.OnClickListener {
private static final String KEY_INSTANT_APP_BUTTONS = "instant_app_buttons";
private static final String META_DATA_DEFAULT_URI = "default-url";
private final AppInfoDashboardFragment mParent;
private final String mPackageName;
private InstantAppButtonsController mInstantAppButtonsController;
private final PackageManagerWrapper mPackageManagerWrapper;
private String mLaunchUri;
private LayoutPreference mPreference;
private MenuItem mInstallMenu;
public InstantAppButtonsPreferenceController(Context context, AppInfoDashboardFragment parent,
String packageName) {
String packageName, Lifecycle lifecycle) {
super(context, KEY_INSTANT_APP_BUTTONS);
mParent = parent;
mPackageName = packageName;
mPackageManagerWrapper = new PackageManagerWrapper(context.getPackageManager());
mLaunchUri = getDefaultLaunchUri();
if (lifecycle != null) {
lifecycle.addObserver(this);
}
}
@Override
@@ -53,22 +85,98 @@ public class InstantAppButtonsPreferenceController extends BasePreferenceControl
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
LayoutPreference buttons =
(LayoutPreference) screen.findPreference(KEY_INSTANT_APP_BUTTONS);
mInstantAppButtonsController = getApplicationFeatureProvider()
.newInstantAppButtonsController(mParent,
buttons.findViewById(R.id.instant_app_button_container),
id -> mParent.showDialogInner(id, 0))
.setPackageName(mPackageName)
.show();
mPreference = (LayoutPreference) screen.findPreference(KEY_INSTANT_APP_BUTTONS);
initButtons(mPreference.findViewById(R.id.instant_app_button_container));
}
public AlertDialog createDialog(int id) {
return mInstantAppButtonsController.createDialog(id);
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
if (!TextUtils.isEmpty(mLaunchUri)) {
menu.add(0, AppInfoDashboardFragment.INSTALL_INSTANT_APP_MENU, 2, R.string.install_text)
.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
}
}
@VisibleForTesting
ApplicationFeatureProvider getApplicationFeatureProvider() {
return FeatureFactory.getFactory(mContext).getApplicationFeatureProvider(mContext);
@Override
public boolean onOptionsItemSelected(MenuItem menuItem) {
if (menuItem.getItemId() == AppInfoDashboardFragment.INSTALL_INSTANT_APP_MENU) {
final Intent appStoreIntent = AppStoreUtil.getAppStoreLink(mContext, mPackageName);
if (appStoreIntent != null) {
mParent.startActivity(appStoreIntent);
}
return true;
}
return false;
}
@Override
public void onPrepareOptionsMenu(Menu menu) {
mInstallMenu = menu.findItem(AppInfoDashboardFragment.INSTALL_INSTANT_APP_MENU);
final Intent appStoreIntent = AppStoreUtil.getAppStoreLink(mContext, mPackageName);
if (appStoreIntent == null) {
mInstallMenu.setEnabled(false);
}
}
@Override
public void onClick(DialogInterface dialog, int which) {
FeatureFactory.getFactory(mContext).getMetricsFeatureProvider()
.action(mContext, MetricsEvent.ACTION_SETTINGS_CLEAR_INSTANT_APP, mPackageName);
mPackageManagerWrapper.deletePackageAsUser(
mPackageName, null, 0, UserHandle.myUserId());
}
AlertDialog createDialog(int id) {
if (id == AppInfoDashboardFragment.DLG_CLEAR_INSTANT_APP) {
AlertDialog confirmDialog = new AlertDialog.Builder(mContext)
.setPositiveButton(R.string.clear_instant_app_data, this)
.setNegativeButton(R.string.cancel, null)
.setTitle(R.string.clear_instant_app_data)
.setMessage(mContext.getString(R.string.clear_instant_app_confirmation))
.create();
return confirmDialog;
}
return null;
}
private void initButtons(View view) {
final Button installButton = view.findViewById(R.id.install);
final Button clearDataButton = view.findViewById(R.id.clear_data);
final Button launchButton = view.findViewById(R.id.launch);
if (!TextUtils.isEmpty(mLaunchUri)) {
installButton.setVisibility(View.GONE);
final Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(mLaunchUri));
launchButton.setOnClickListener(v -> mParent.startActivity(intent));
} else {
launchButton.setVisibility(View.GONE);
final Intent appStoreIntent = AppStoreUtil.getAppStoreLink(mContext, mPackageName);
if (appStoreIntent != null) {
installButton.setOnClickListener(v -> mParent.startActivity(appStoreIntent));
} else {
installButton.setEnabled(false);
}
}
clearDataButton.setOnClickListener(
v -> mParent.showDialogInner(mParent.DLG_CLEAR_INSTANT_APP, 0));
}
private String getDefaultLaunchUri() {
final PackageManager manager = mContext.getPackageManager();
final Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
intent.setPackage(mPackageName);
final List<ResolveInfo> infos = manager.queryIntentActivities(
intent, PackageManager.GET_META_DATA | PackageManager.MATCH_INSTANT);
for (ResolveInfo info : infos) {
final Bundle metaData = info.activityInfo.metaData;
if (metaData != null) {
final String launchUri = metaData.getString(META_DATA_DEFAULT_URI);
if (!TextUtils.isEmpty(launchUri)) {
return launchUri;
}
}
}
return null;
}
}

View File

@@ -1,113 +0,0 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.applications.instantapps;
import android.app.AlertDialog;
import android.app.Fragment;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.UserHandle;
import android.view.View;
import android.widget.Button;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.applications.AppStoreUtil;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.wrapper.PackageManagerWrapper;
/** Encapsulates a container for buttons relevant to instant apps */
public class InstantAppButtonsController implements DialogInterface.OnClickListener {
public interface ShowDialogDelegate {
/**
* Delegate that should be called when this controller wants to show a dialog.
*/
void showDialog(int id);
}
private final Context mContext;
private final Fragment mFragment;
private final View mView;
private final PackageManagerWrapper mPackageManagerWrapper;
private final ShowDialogDelegate mShowDialogDelegate;
private String mPackageName;
public static final int DLG_BASE = 0x5032;
public static final int DLG_CLEAR_APP = DLG_BASE + 1;
public InstantAppButtonsController(
Context context,
Fragment fragment,
View view,
ShowDialogDelegate showDialogDelegate) {
mContext = context;
mFragment = fragment;
mView = view;
mShowDialogDelegate = showDialogDelegate;
mPackageManagerWrapper = new PackageManagerWrapper(context.getPackageManager());
}
public InstantAppButtonsController setPackageName(String packageName) {
mPackageName = packageName;
return this;
}
public void bindButtons() {
Button installButton = (Button)mView.findViewById(R.id.install);
Button clearDataButton = (Button)mView.findViewById(R.id.clear_data);
Intent appStoreIntent = AppStoreUtil.getAppStoreLink(mContext, mPackageName);
if (appStoreIntent != null) {
installButton.setEnabled(true);
installButton.setOnClickListener(v -> mFragment.startActivity(appStoreIntent));
}
clearDataButton.setOnClickListener(v -> mShowDialogDelegate.showDialog(DLG_CLEAR_APP));
}
public AlertDialog createDialog(int id) {
if (id == DLG_CLEAR_APP) {
AlertDialog dialog = new AlertDialog.Builder(mFragment.getActivity())
.setPositiveButton(R.string.clear_instant_app_data, this)
.setNegativeButton(R.string.cancel, null)
.setTitle(R.string.clear_instant_app_data)
.setMessage(mContext.getString(R.string.clear_instant_app_confirmation))
.create();
return dialog;
}
return null;
}
public void onClick(DialogInterface dialog, int which) {
if (which == DialogInterface.BUTTON_POSITIVE) {
FeatureFactory.getFactory(mContext)
.getMetricsFeatureProvider()
.action(mContext,
MetricsEvent.ACTION_SETTINGS_CLEAR_INSTANT_APP,
mPackageName);
mPackageManagerWrapper.deletePackageAsUser(
mPackageName, null, 0, UserHandle.myUserId());
}
}
public InstantAppButtonsController show() {
bindButtons();
mView.setVisibility(View.VISIBLE);
return this;
}
}

View File

@@ -21,10 +21,12 @@ import android.hardware.usb.UsbManager;
import android.hardware.usb.UsbPort;
import android.hardware.usb.UsbPortStatus;
import android.net.ConnectivityManager;
import android.os.UserHandle;
import android.os.UserManager;
import android.support.annotation.VisibleForTesting;
import com.android.settings.wrapper.UsbManagerWrapper;
import com.android.settings.wrapper.UserManagerWrapper;
public class UsbBackend {
public static final int MODE_POWER_MASK = 0x01;
@@ -47,31 +49,31 @@ public class UsbBackend {
private UsbManager mUsbManager;
@VisibleForTesting
UsbManagerPassThrough mUsbManagerPassThrough;
UsbManagerWrapper mUsbManagerWrapper;
private UsbPort mPort;
private UsbPortStatus mPortStatus;
private Context mContext;
public UsbBackend(Context context) {
this(context, new UserRestrictionUtil(context), null);
this(context, new UserManagerWrapper(UserManager.get(context)), null);
}
@VisibleForTesting
public UsbBackend(Context context, UserRestrictionUtil userRestrictionUtil,
UsbManagerPassThrough usbManagerPassThrough) {
public UsbBackend(Context context, UserManagerWrapper userManagerWrapper,
UsbManagerWrapper usbManagerWrapper) {
mContext = context;
mUsbManager = context.getSystemService(UsbManager.class);
mUsbManagerPassThrough = usbManagerPassThrough;
if (mUsbManagerPassThrough == null) {
mUsbManagerPassThrough = new UsbManagerPassThrough(mUsbManager);
mUsbManagerWrapper = usbManagerWrapper;
if (mUsbManagerWrapper == null) {
mUsbManagerWrapper = new UsbManagerWrapper(mUsbManager);
}
mFileTransferRestricted = userRestrictionUtil.isUsbFileTransferRestricted();
mFileTransferRestrictedBySystem = userRestrictionUtil.isUsbFileTransferRestrictedBySystem();
mTetheringRestricted = userRestrictionUtil.isUsbTetheringRestricted();
mTetheringRestrictedBySystem = userRestrictionUtil.isUsbTetheringRestrictedBySystem();
mFileTransferRestricted = userManagerWrapper.isUsbFileTransferRestricted();
mFileTransferRestrictedBySystem = userManagerWrapper.isUsbFileTransferRestrictedBySystem();
mTetheringRestricted = userManagerWrapper.isUsbTetheringRestricted();
mTetheringRestrictedBySystem = userManagerWrapper.isUsbTetheringRestrictedBySystem();
mMidiSupported = context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_MIDI);
ConnectivityManager cm =
@@ -106,37 +108,15 @@ public class UsbBackend {
}
public int getUsbDataMode() {
long functions = mUsbManagerPassThrough.getCurrentFunctions();
if (functions == UsbManager.FUNCTION_MTP) {
return MODE_DATA_MTP;
} else if (functions == UsbManager.FUNCTION_PTP) {
return MODE_DATA_PTP;
} else if (functions == UsbManager.FUNCTION_MIDI) {
return MODE_DATA_MIDI;
} else if (functions == UsbManager.FUNCTION_RNDIS) {
return MODE_DATA_TETHER;
}
return MODE_DATA_NONE;
return usbFunctionToMode(mUsbManagerWrapper.getCurrentFunctions());
}
private void setUsbFunction(int mode) {
switch (mode) {
case MODE_DATA_MTP:
mUsbManager.setCurrentFunctions(UsbManager.FUNCTION_MTP);
break;
case MODE_DATA_PTP:
mUsbManager.setCurrentFunctions(UsbManager.FUNCTION_PTP);
break;
case MODE_DATA_MIDI:
mUsbManager.setCurrentFunctions(UsbManager.FUNCTION_MIDI);
break;
case MODE_DATA_TETHER:
mUsbManager.setCurrentFunctions(UsbManager.FUNCTION_RNDIS);
break;
default:
mUsbManager.setCurrentFunctions(UsbManager.FUNCTION_NONE);
break;
}
public void setDefaultUsbMode(int mode) {
mUsbManager.setScreenUnlockedFunctions(modeToUsbFunction(mode & MODE_DATA_MASK));
}
public int getDefaultUsbMode() {
return usbFunctionToMode(mUsbManager.getScreenUnlockedFunctions());
}
public void setMode(int mode) {
@@ -153,11 +133,6 @@ public class UsbBackend {
setUsbFunction(mode & MODE_DATA_MASK);
}
private int modeToPower(int mode) {
return (mode & MODE_POWER_MASK) == MODE_POWER_SOURCE
? UsbPort.POWER_ROLE_SOURCE : UsbPort.POWER_ROLE_SINK;
}
public boolean isModeDisallowed(int mode) {
if (mFileTransferRestricted && ((mode & MODE_DATA_MASK) == MODE_DATA_MTP
|| (mode & MODE_DATA_MASK) == MODE_DATA_PTP)) {
@@ -201,47 +176,40 @@ public class UsbBackend {
return (mode & MODE_POWER_MASK) != MODE_POWER_SOURCE;
}
// Wrapper class to enable testing with UserManager APIs
public static class UserRestrictionUtil {
private UserManager mUserManager;
public UserRestrictionUtil(Context context) {
mUserManager = UserManager.get(context);
private static int usbFunctionToMode(long functions) {
if (functions == UsbManager.FUNCTION_MTP) {
return MODE_DATA_MTP;
} else if (functions == UsbManager.FUNCTION_PTP) {
return MODE_DATA_PTP;
} else if (functions == UsbManager.FUNCTION_MIDI) {
return MODE_DATA_MIDI;
} else if (functions == UsbManager.FUNCTION_RNDIS) {
return MODE_DATA_TETHER;
}
return MODE_DATA_NONE;
}
public boolean isUsbFileTransferRestricted() {
return mUserManager.hasUserRestriction(UserManager.DISALLOW_USB_FILE_TRANSFER);
}
public boolean isUsbTetheringRestricted() {
return mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING);
}
public boolean isUsbFileTransferRestrictedBySystem() {
return mUserManager.hasBaseUserRestriction(
UserManager.DISALLOW_USB_FILE_TRANSFER, UserHandle.of(UserHandle.myUserId()));
}
public boolean isUsbTetheringRestrictedBySystem() {
return mUserManager.hasBaseUserRestriction(
UserManager.DISALLOW_CONFIG_TETHERING, UserHandle.of(UserHandle.myUserId()));
private static long modeToUsbFunction(int mode) {
switch (mode) {
case MODE_DATA_MTP:
return UsbManager.FUNCTION_MTP;
case MODE_DATA_PTP:
return UsbManager.FUNCTION_PTP;
case MODE_DATA_MIDI:
return UsbManager.FUNCTION_MIDI;
case MODE_DATA_TETHER:
return UsbManager.FUNCTION_RNDIS;
default:
return UsbManager.FUNCTION_NONE;
}
}
// Temporary pass-through to allow roboelectric to use getCurrentFunctions()
public static class UsbManagerPassThrough {
private UsbManager mUsbManager;
private static int modeToPower(int mode) {
return (mode & MODE_POWER_MASK) == MODE_POWER_SOURCE
? UsbPort.POWER_ROLE_SOURCE : UsbPort.POWER_ROLE_SINK;
}
public UsbManagerPassThrough(UsbManager manager) {
mUsbManager = manager;
}
public long getCurrentFunctions() {
return mUsbManager.getCurrentFunctions();
}
public long usbFunctionsFromString(String str) {
return UsbManager.usbFunctionsFromString(str);
}
private void setUsbFunction(int mode) {
mUsbManager.setCurrentFunctions(modeToUsbFunction(mode));
}
}

View File

@@ -0,0 +1,159 @@
/*
* 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.connecteddevice.usb;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.hardware.usb.UsbManager;
import android.os.Bundle;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.widget.RadioButtonPickerFragment;
import com.android.settingslib.widget.FooterPreference;
import com.android.settingslib.widget.FooterPreferenceMixin;
import com.google.android.collect.Lists;
import java.util.List;
/**
* Provides options for selecting the default USB mode.
*/
public class UsbDefaultFragment extends RadioButtonPickerFragment {
@VisibleForTesting
UsbBackend mUsbBackend;
private static final String[] FUNCTIONS_LIST = {
UsbManager.USB_FUNCTION_NONE,
UsbManager.USB_FUNCTION_MTP,
UsbManager.USB_FUNCTION_RNDIS,
UsbManager.USB_FUNCTION_MIDI,
UsbManager.USB_FUNCTION_PTP
};
@Override
public void onAttach(Context context) {
super.onAttach(context);
mUsbBackend = new UsbBackend(context);
}
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
super.onCreatePreferences(savedInstanceState, rootKey);
FooterPreferenceMixin footer = new FooterPreferenceMixin(this, this.getLifecycle());
FooterPreference pref = footer.createFooterPreference();
pref.setTitle(R.string.usb_default_info);
}
@Override
public int getMetricsCategory() {
return MetricsProto.MetricsEvent.USB_DEFAULT;
}
@Override
protected int getPreferenceScreenResId() {
return R.xml.usb_default_fragment;
}
@Override
protected List<? extends CandidateInfo> getCandidates() {
List<CandidateInfo> ret = Lists.newArrayList();
for (final String option : FUNCTIONS_LIST) {
int newMode = 0;
final String title;
final Context context = getContext();
if (option.equals(UsbManager.USB_FUNCTION_MTP)) {
newMode = UsbBackend.MODE_DATA_MTP;
title = context.getString(R.string.usb_use_file_transfers);
} else if (option.equals(UsbManager.USB_FUNCTION_PTP)) {
newMode = UsbBackend.MODE_DATA_PTP;
title = context.getString(R.string.usb_use_photo_transfers);
} else if (option.equals(UsbManager.USB_FUNCTION_MIDI)) {
newMode = UsbBackend.MODE_DATA_MIDI;
title = context.getString(R.string.usb_use_MIDI);
} else if (option.equals(UsbManager.USB_FUNCTION_RNDIS)) {
newMode = UsbBackend.MODE_DATA_TETHER;
title = context.getString(R.string.usb_use_tethering);
} else if (option.equals(UsbManager.USB_FUNCTION_NONE)) {
newMode = UsbBackend.MODE_DATA_NONE;
title = context.getString(R.string.usb_use_charging_only);
} else {
title = "";
}
// Only show supported and allowed options
if (mUsbBackend.isModeSupported(newMode)
&& !mUsbBackend.isModeDisallowedBySystem(newMode)
&& !mUsbBackend.isModeDisallowed(newMode)) {
ret.add(new CandidateInfo(true /* enabled */) {
@Override
public CharSequence loadLabel() {
return title;
}
@Override
public Drawable loadIcon() {
return null;
}
@Override
public String getKey() {
return option;
}
});
}
}
return ret;
}
@Override
protected String getDefaultKey() {
switch (mUsbBackend.getDefaultUsbMode()) {
case UsbBackend.MODE_DATA_MTP:
return UsbManager.USB_FUNCTION_MTP;
case UsbBackend.MODE_DATA_PTP:
return UsbManager.USB_FUNCTION_PTP;
case UsbBackend.MODE_DATA_TETHER:
return UsbManager.USB_FUNCTION_RNDIS;
case UsbBackend.MODE_DATA_MIDI:
return UsbManager.USB_FUNCTION_MIDI;
default:
return UsbManager.USB_FUNCTION_NONE;
}
}
@Override
protected boolean setDefaultKey(String key) {
int thisMode = UsbBackend.MODE_DATA_NONE;
if (key.equals(UsbManager.USB_FUNCTION_MTP)) {
thisMode = UsbBackend.MODE_DATA_MTP;
} else if (key.equals(UsbManager.USB_FUNCTION_PTP)) {
thisMode = UsbBackend.MODE_DATA_PTP;
} else if (key.equals(UsbManager.USB_FUNCTION_RNDIS)) {
thisMode = UsbBackend.MODE_DATA_TETHER;
} else if (key.equals(UsbManager.USB_FUNCTION_MIDI)) {
thisMode = UsbBackend.MODE_DATA_MIDI;
}
if (!Utils.isMonkeyRunning()) {
mUsbBackend.setDefaultUsbMode(thisMode);
}
return true;
}
}

View File

@@ -25,6 +25,8 @@ import com.android.settingslib.core.lifecycle.Lifecycle;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
/**
@@ -73,6 +75,44 @@ public abstract class BasePreferenceController extends AbstractPreferenceControl
protected Lifecycle mLifecycle;
/**
* Instantiate a controller as specified controller type and user-defined key.
* <p/>
* This is done through reflection. Do not use this method unless you know what you are doing.
*/
public static BasePreferenceController createInstance(Context context,
String controllerName, String key) {
try {
final Class<?> clazz = Class.forName(controllerName);
final Constructor<?> preferenceConstructor =
clazz.getConstructor(Context.class, String.class);
final Object[] params = new Object[] {context, key};
return (BasePreferenceController) preferenceConstructor.newInstance(params);
} catch (ClassNotFoundException | NoSuchMethodException | InstantiationException |
IllegalArgumentException | InvocationTargetException | IllegalAccessException e) {
throw new IllegalStateException(
"Invalid preference controller: " + controllerName, e);
}
}
/**
* Instantiate a controller as specified controller type.
* <p/>
* This is done through reflection. Do not use this method unless you know what you are doing.
*/
public static BasePreferenceController createInstance(Context context, String controllerName) {
try {
final Class<?> clazz = Class.forName(controllerName);
final Constructor<?> preferenceConstructor = clazz.getConstructor(Context.class);
final Object[] params = new Object[] {context};
return (BasePreferenceController) preferenceConstructor.newInstance(params);
} catch (ClassNotFoundException | NoSuchMethodException | InstantiationException |
IllegalArgumentException | InvocationTargetException | IllegalAccessException e) {
throw new IllegalStateException(
"Invalid preference controller: " + controllerName, e);
}
}
public BasePreferenceController(Context context, String preferenceKey) {
super(context);
mPreferenceKey = preferenceKey;

View File

@@ -17,6 +17,8 @@ import android.content.Context;
import android.support.v7.preference.Preference;
import android.support.v7.preference.TwoStatePreference;
import com.android.settings.widget.MasterSwitchPreference;
/**
* Abstract class that consolidates logic for updating toggle controllers.
* It automatically handles the getting and setting of the switch UI element.
@@ -46,7 +48,11 @@ public abstract class TogglePreferenceController extends BasePreferenceControlle
@Override
public final void updateState(Preference preference) {
((TwoStatePreference) preference).setChecked(isChecked());
if (preference instanceof TwoStatePreference) {
((TwoStatePreference) preference).setChecked(isChecked());
} if (preference instanceof MasterSwitchPreference) {
((MasterSwitchPreference) preference).setChecked(isChecked());
}
}
@Override

View File

@@ -27,9 +27,6 @@ import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.overlay.FeatureFactory;
@@ -58,7 +55,7 @@ public abstract class DashboardFragment extends SettingsPreferenceFragment
new ArrayMap<>();
private final Set<String> mDashboardTilePrefKeys = new ArraySet<>();
protected DashboardFeatureProvider mDashboardFeatureProvider;
private DashboardFeatureProvider mDashboardFeatureProvider;
private DashboardTilePlaceholderPreferenceController mPlaceholderPreferenceController;
private boolean mListeningToCategoryChange;
private SummaryLoader mSummaryLoader;
@@ -94,13 +91,6 @@ public abstract class DashboardFragment extends SettingsPreferenceFragment
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View view = super.onCreateView(inflater, container, savedInstanceState);
return view;
}
@Override
public void onCategoriesChanged() {
final DashboardCategory category =

View File

@@ -85,7 +85,7 @@ public class WorkModeCondition extends Condition {
@Override
public void onPrimaryClick() {
mManager.getContext().startActivity(new Intent(mManager.getContext(),
Settings.UserSettingsActivity.class)
Settings.AccountDashboardActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
}

View File

@@ -401,7 +401,6 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra
controllers.add(new WifiConnectedMacRandomizationPreferenceController(context));
controllers.add(new MobileDataAlwaysOnPreferenceController(context));
controllers.add(new TetheringHardwareAccelPreferenceController(context));
controllers.add(new SelectUsbConfigPreferenceController(context, lifecycle));
controllers.add(new BluetoothDeviceNoNamePreferenceController(context));
controllers.add(new BluetoothAbsoluteVolumePreferenceController(context));
controllers.add(new BluetoothInbandRingingPreferenceController(context));

View File

@@ -30,8 +30,8 @@ import android.support.v7.preference.PreferenceScreen;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.wrapper.UsbManagerWrapper;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.connecteddevice.usb.UsbBackend;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnCreate;
@@ -49,7 +49,7 @@ public class SelectUsbConfigPreferenceController extends
private final String[] mListSummaries;
private final UsbManager mUsbManager;
@VisibleForTesting
UsbBackend.UsbManagerPassThrough mUsbManagerPassThrough;
UsbManagerWrapper mUsbManagerWrapper;
private BroadcastReceiver mUsbReceiver;
private ListPreference mPreference;
@@ -59,7 +59,7 @@ public class SelectUsbConfigPreferenceController extends
mListValues = context.getResources().getStringArray(R.array.usb_configuration_values);
mListSummaries = context.getResources().getStringArray(R.array.usb_configuration_titles);
mUsbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
mUsbManagerPassThrough = new UsbBackend.UsbManagerPassThrough(mUsbManager);
mUsbManagerWrapper = new UsbManagerWrapper(mUsbManager);
mUsbReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -98,7 +98,7 @@ public class SelectUsbConfigPreferenceController extends
return false;
}
writeUsbConfigurationOption(mUsbManagerPassThrough
writeUsbConfigurationOption(mUsbManagerWrapper
.usbFunctionsFromString(newValue.toString()));
updateUsbConfigurationValues();
return true;
@@ -138,10 +138,10 @@ public class SelectUsbConfigPreferenceController extends
}
private void updateUsbConfigurationValues() {
long functions = mUsbManagerPassThrough.getCurrentFunctions();
long functions = mUsbManagerWrapper.getCurrentFunctions();
int index = 0;
for (int i = 0; i < mListValues.length; i++) {
if (functions == mUsbManagerPassThrough.usbFunctionsFromString(mListValues[i])) {
if (functions == mUsbManagerWrapper.usbFunctionsFromString(mListValues[i])) {
index = i;
break;
}

View File

@@ -21,42 +21,36 @@ import android.os.Handler;
import android.os.PowerManager;
import android.provider.Settings;
import android.support.annotation.VisibleForTesting;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.core.TogglePreferenceController;
import com.android.settings.dashboard.conditional.BatterySaverCondition;
import com.android.settings.dashboard.conditional.ConditionManager;
import com.android.settings.widget.MasterSwitchPreference;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnStart;
import com.android.settingslib.core.lifecycle.events.OnStop;
import static android.os.PowerManager.ACTION_POWER_SAVE_MODE_CHANGING;
public class BatterySaverController extends AbstractPreferenceController
implements PreferenceControllerMixin, Preference.OnPreferenceChangeListener,
LifecycleObserver, OnStart, OnStop, BatterySaverReceiver.BatterySaverListener {
public class BatterySaverController extends TogglePreferenceController
implements LifecycleObserver, OnStart, OnStop, BatterySaverReceiver.BatterySaverListener {
private static final String KEY_BATTERY_SAVER = "battery_saver_summary";
private final BatterySaverReceiver mBatteryStateChangeReceiver;
private final PowerManager mPowerManager;
private MasterSwitchPreference mBatterySaverPref;
public BatterySaverController(Context context, Lifecycle lifecycle) {
super(context);
public BatterySaverController(Context context) {
super(context, KEY_BATTERY_SAVER);
lifecycle.addObserver(this);
mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
mBatteryStateChangeReceiver = new BatterySaverReceiver(context);
mBatteryStateChangeReceiver.setBatterySaverListener(this);
}
@Override
public boolean isAvailable() {
return true;
public int getAvailabilityStatus() {
return AVAILABLE;
}
@Override
@@ -71,17 +65,9 @@ public class BatterySaverController extends AbstractPreferenceController
}
@Override
public void updateState(Preference preference) {
mBatterySaverPref.setChecked(mPowerManager.isPowerSaveMode());
updateSummary();
}
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
final boolean saverOn = (Boolean) newValue;
if (saverOn != mPowerManager.isPowerSaveMode()
&& !mPowerManager.setPowerSaveMode(saverOn)) {
// Do nothing if power save mode doesn't set correctly
public boolean setChecked(boolean isChecked) {
mBatterySaverPref.setChecked(isChecked);
if (!mPowerManager.setPowerSaveMode(isChecked)) {
return false;
}
@@ -90,6 +76,11 @@ public class BatterySaverController extends AbstractPreferenceController
return true;
}
@Override
public boolean isChecked() {
return mPowerManager.isPowerSaveMode();
}
@Override
public void onStart() {
mContext.getContentResolver().registerContentObserver(
@@ -110,7 +101,8 @@ public class BatterySaverController extends AbstractPreferenceController
ConditionManager.get(mContext).getCondition(BatterySaverCondition.class).refreshState();
}
private void updateSummary() {
@Override
public String getSummary() {
final boolean mode = mPowerManager.isPowerSaveMode();
final int format = mode ? R.string.battery_saver_on_summary
: R.string.battery_saver_off_summary;
@@ -119,10 +111,12 @@ public class BatterySaverController extends AbstractPreferenceController
final int percentFormat = percent > 0 ? R.string.battery_saver_desc_turn_on_auto_pct
: R.string.battery_saver_desc_turn_on_auto_never;
final String summary = mContext.getString(format, mContext.getString(percentFormat,
return mContext.getString(format, mContext.getString(percentFormat,
Utils.formatPercentage(percent)));
}
mBatterySaverPref.setSummary(summary);
private void updateSummary() {
mBatterySaverPref.setSummary(getSummary());
}
private final ContentObserver mObserver = new ContentObserver(new Handler()) {

View File

@@ -59,6 +59,7 @@ import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.utils.PowerUtil;
import com.android.settingslib.utils.StringUtil;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -232,17 +233,20 @@ public class PowerUsageSummary extends PowerUsageBase implements OnLongClickList
final SettingsActivity activity = (SettingsActivity) getActivity();
final List<AbstractPreferenceController> controllers = new ArrayList<>();
mBatteryHeaderPreferenceController = new BatteryHeaderPreferenceController(
context, activity, this /* host */, getLifecycle());
context, activity, this /* host */, lifecycle);
controllers.add(mBatteryHeaderPreferenceController);
mBatteryAppListPreferenceController = new BatteryAppListPreferenceController(context,
KEY_APP_LIST, lifecycle, activity, this);
controllers.add(mBatteryAppListPreferenceController);
mBatteryTipPreferenceController = new BatteryTipPreferenceController(context,
KEY_BATTERY_TIP, (SettingsActivity) getActivity(), this, this);
KEY_BATTERY_TIP, (SettingsActivity) getActivity(), this /* fragment */, this /*
BatteryTipListener */);
controllers.add(mBatteryTipPreferenceController);
controllers.add(new BatterySaverController(context, getLifecycle()));
BatterySaverController batterySaverController = new BatterySaverController(context);
controllers.add(batterySaverController);
controllers.add(new BatteryPercentagePreferenceController(context));
lifecycle.addObserver(batterySaverController);
return controllers;
}
@@ -322,7 +326,8 @@ public class PowerUsageSummary extends PowerUsageBase implements OnLongClickList
@VisibleForTesting
void updateLastFullChargePreference(long timeMs) {
final CharSequence timeSequence = StringUtil.formatRelativeTime(getContext(), timeMs, false);
final CharSequence timeSequence = StringUtil.formatRelativeTime(getContext(), timeMs,
false);
mLastFullChargePref.setSubtitle(timeSequence);
}

View File

@@ -314,12 +314,14 @@ public class PowerUsageSummaryLegacy extends PowerUsageBase implements
controllers.add(mBatteryHeaderPreferenceController);
controllers.add(new AutoBrightnessPreferenceController(context, KEY_AUTO_BRIGHTNESS));
controllers.add(new TimeoutPreferenceController(context, KEY_SCREEN_TIMEOUT));
controllers.add(new BatterySaverController(context, getLifecycle()));
controllers.add(new BatteryPercentagePreferenceController(context));
controllers.add(new AmbientDisplayPreferenceController(
context,
new AmbientDisplayConfiguration(context),
KEY_AMBIENT_DISPLAY));
BatterySaverController batterySaverController = new BatterySaverController(context);
controllers.add(batterySaverController);
getLifecycle().addObserver(batterySaverController);
return controllers;
}

View File

@@ -29,13 +29,15 @@ import com.android.settings.core.TogglePreferenceController;
*/
public class AutoBatterySaverPreferenceController extends TogglePreferenceController implements
Preference.OnPreferenceChangeListener {
private static final int LOW_POWER_MODE_TRIGGER_THRESHOLD = 15;
private final int mDefWarnLevel;
@VisibleForTesting
static final String KEY_AUTO_BATTERY_SAVER = "auto_battery_saver";
public AutoBatterySaverPreferenceController(Context context) {
super(context, KEY_AUTO_BATTERY_SAVER);
mDefWarnLevel = mContext.getResources().getInteger(
com.android.internal.R.integer.config_lowBatteryWarningLevel);
}
@Override
@@ -46,7 +48,7 @@ public class AutoBatterySaverPreferenceController extends TogglePreferenceContro
@Override
public boolean isChecked() {
return Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0) != 0;
Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, mDefWarnLevel) != 0;
}
@Override
@@ -54,7 +56,7 @@ public class AutoBatterySaverPreferenceController extends TogglePreferenceContro
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL,
isChecked
? LOW_POWER_MODE_TRIGGER_THRESHOLD
? mDefWarnLevel
: 0);
return true;
}

View File

@@ -42,12 +42,15 @@ public class AutoBatterySeekBarPreferenceController extends BasePreferenceContro
LifecycleObserver, OnStart, OnStop, SeekBarPreference.OnPreferenceChangeListener {
@VisibleForTesting
static final String KEY_AUTO_BATTERY_SEEK_BAR = "battery_saver_seek_bar";
private final int mDefWarnLevel;
private SeekBarPreference mPreference;
private AutoBatterySaverSettingObserver mContentObserver;
public AutoBatterySeekBarPreferenceController(Context context, Lifecycle lifecycle) {
super(context, KEY_AUTO_BATTERY_SEEK_BAR);
mContentObserver = new AutoBatterySaverSettingObserver(new Handler(Looper.getMainLooper()));
mDefWarnLevel = mContext.getResources().getInteger(
com.android.internal.R.integer.config_lowBatteryWarningLevel);
if (lifecycle != null) {
lifecycle.addObserver(this);
}
@@ -94,7 +97,7 @@ public class AutoBatterySeekBarPreferenceController extends BasePreferenceContro
void updatePreference(Preference preference) {
final ContentResolver contentResolver = mContext.getContentResolver();
final int level = Settings.Global.getInt(contentResolver,
Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0);
Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, mDefWarnLevel);
if (level == 0) {
preference.setVisible(false);
} else {

View File

@@ -33,9 +33,6 @@ import com.android.settings.core.TogglePreferenceController;
import com.android.settings.search.DatabaseIndexingUtils;
import com.android.settingslib.core.AbstractPreferenceController;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import androidx.app.slice.Slice;
import androidx.app.slice.builders.ListBuilder;
import androidx.app.slice.builders.ListBuilder.RowBuilder;
@@ -87,46 +84,16 @@ public class SliceBuilderUtils {
public static BasePreferenceController getPreferenceController(Context context,
SliceData sliceData) {
try {
return getController(context, sliceData, true /* isContextOnly */);
return BasePreferenceController.createInstance(context,
sliceData.getPreferenceController());
} catch (IllegalStateException e) {
// Do nothing
Log.d(TAG, "Could not find Context-only controller for preference controller: "
+ sliceData.getKey());
}
return getController(context, sliceData, false /* isContextOnly */);
}
/**
* Attempts to build a {@link BasePreferenceController} from {@param SliceData}.
*
* @param sliceData Backing data for the Slice.
* @param contextOnlyCtor {@code true} when the constructor for the
* {@link BasePreferenceController}
* only takes a {@link Context}. Else the constructor will be ({@link
* Context}, {@code String}.
*/
private static BasePreferenceController getController(Context context, SliceData sliceData,
boolean contextOnlyCtor) {
try {
Class<?> clazz = Class.forName(sliceData.getPreferenceController());
Constructor<?> preferenceConstructor;
Object[] params;
if (contextOnlyCtor) {
preferenceConstructor = clazz.getConstructor(Context.class);
params = new Object[]{context};
} else {
preferenceConstructor = clazz.getConstructor(Context.class, String.class);
params = new Object[]{context, sliceData.getKey()};
}
return (BasePreferenceController) preferenceConstructor.newInstance(params);
} catch (ClassNotFoundException | NoSuchMethodException | InstantiationException |
IllegalArgumentException | InvocationTargetException | IllegalAccessException e) {
throw new IllegalStateException(
"Invalid preference controller: " + sliceData.getPreferenceController(), e);
}
return BasePreferenceController.createInstance(context, sliceData.getPreferenceController(),
sliceData.getKey());
}
private static void addToggleAction(Context context, RowBuilder builder, boolean isChecked,

View File

@@ -517,6 +517,7 @@ public class WifiConfigController implements TextWatcher,
mAccessPoint.getSsidStr());
} else {
config.networkId = mAccessPoint.getConfig().networkId;
config.hiddenSSID = mAccessPoint.getConfig().hiddenSSID;
}
config.shared = mSharedCheckBox.isChecked();

View File

@@ -352,32 +352,6 @@ public class WifiSettings extends RestrictedSettingsFragment
getPreferenceScreen().removeAll();
}
/**
* Only update the AP list if there are not any APs currently shown.
*
* <p>Thus forceUpdate will only be called during cold start or when toggling between wifi on
* and off. In other use cases, the previous APs will remain until the next update is received
* from {@link WifiTracker}.
*/
private void conditionallyForceUpdateAPs() {
if (mAccessPointsPreferenceCategory.getPreferenceCount() > 0
&& mAccessPointsPreferenceCategory.getPreference(0) instanceof
AccessPointPreference) {
// Make sure we don't update due to callbacks initiated by sticky broadcasts in
// WifiTracker.
Log.d(TAG, "Did not force update APs due to existing APs displayed");
getView().removeCallbacks(mUpdateAccessPointsRunnable);
return;
}
setProgressBarVisible(true);
mWifiTracker.forceUpdate();
if (isVerboseLoggingEnabled()) {
Log.i(TAG, "WifiSettings force update APs: " + mWifiTracker.getAccessPoints());
}
getView().removeCallbacks(mUpdateAccessPointsRunnable);
updateAccessPointPreferences();
}
/**
* @return new WifiEnabler or null (as overridden by WifiSettingsForSetupWizard)
*/
@@ -682,7 +656,7 @@ public class WifiSettings extends RestrictedSettingsFragment
final int wifiState = mWifiManager.getWifiState();
switch (wifiState) {
case WifiManager.WIFI_STATE_ENABLED:
conditionallyForceUpdateAPs();
updateAccessPointPreferences();
break;
case WifiManager.WIFI_STATE_ENABLING:

View File

@@ -0,0 +1,34 @@
/*
* 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.wrapper;
import android.hardware.usb.UsbManager;
public class UsbManagerWrapper {
private UsbManager mUsbManager;
public UsbManagerWrapper(UsbManager manager) {
mUsbManager = manager;
}
public long getCurrentFunctions() {
return mUsbManager.getCurrentFunctions();
}
public long usbFunctionsFromString(String str) {
return UsbManager.usbFunctionsFromString(str);
}
}

View File

@@ -17,6 +17,7 @@
package com.android.settings.wrapper;
import android.content.pm.UserInfo;
import android.os.UserHandle;
import android.os.UserManager;
import java.util.List;
@@ -45,4 +46,22 @@ public class UserManagerWrapper {
public List<UserInfo> getProfiles(int userHandle) {
return mUserManager.getProfiles(userHandle);
}
public boolean isUsbFileTransferRestricted() {
return mUserManager.hasUserRestriction(UserManager.DISALLOW_USB_FILE_TRANSFER);
}
public boolean isUsbTetheringRestricted() {
return mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING);
}
public boolean isUsbFileTransferRestrictedBySystem() {
return mUserManager.hasBaseUserRestriction(
UserManager.DISALLOW_USB_FILE_TRANSFER, UserHandle.of(UserHandle.myUserId()));
}
public boolean isUsbTetheringRestrictedBySystem() {
return mUserManager.hasBaseUserRestriction(
UserManager.DISALLOW_CONFIG_TETHERING, UserHandle.of(UserHandle.myUserId()));
}
}

View File

@@ -47,7 +47,6 @@
<bool name="config_show_trust_agent_click_intent">false</bool>
<bool name="config_show_wallpaper_attribution">false</bool>
<bool name="config_show_default_home">false</bool>
<bool name="config_show_accessibility_shortcut_preference">false</bool>
<bool name="config_show_assist_and_voice_input">false</bool>
<bool name="config_show_phone_language">false</bool>
<bool name="config_show_virtual_keyboard_pref">false</bool>
@@ -55,8 +54,6 @@
<bool name="config_show_tts_settings_summary">false</bool>
<bool name="config_show_pointer_speed">false</bool>
<bool name="config_show_vibrate_input_devices">false</bool>
<bool name="config_show_color_correction_preference">false</bool>
<bool name="config_show_color_inversion_preference">false</bool>
<bool name="config_show_system_update_settings">false</bool>
<bool name="config_wifi_support_connected_mac_randomization">false</bool>
<bool name="config_show_device_model">false</bool>

View File

@@ -1,42 +0,0 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.internal.accessibility;
import android.content.ComponentName;
import java.util.HashMap;
import java.util.Map;
/**
* Fake controller to make robolectric test compile. Should be removed when Robolectric supports
* API 25.
*/
public class AccessibilityShortcutController {
public static Map<ComponentName, AccessibilityShortcutController.ToggleableFrameworkFeatureInfo>
getFrameworkShortcutFeaturesMap() {
return new HashMap<>();
}
public static class ToggleableFrameworkFeatureInfo {
private String mSettingKey;
public String getSettingKey() {
return mSettingKey;
}
}
}

View File

@@ -16,137 +16,35 @@
package com.android.settings.accessibility;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import android.content.Context;
import android.support.v7.preference.Preference;
import com.android.settings.R;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
import com.android.settings.testutils.XmlTestUtils;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import java.util.ArrayList;
import java.util.List;
import static com.google.common.truth.Truth.assertThat;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class AccessibilitySettingsTest {
private Context mContext;
private AccessibilitySettings mFragment;
private boolean mAccessibilityShortcutPreferenceRemoved;
private boolean mColorInversionPreferenceRemoved;
private boolean mColorCorrectionPreferenceRemoved;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = spy(RuntimeEnvironment.application);
mFragment = new AccessibilitySettings() {
@Override
public Context getContext() {
return mContext;
}
@Override
protected boolean removePreference(String key) {
if (AccessibilitySettings.ACCESSIBILITY_SHORTCUT_PREFERENCE.equals(key)) {
mAccessibilityShortcutPreferenceRemoved = true;
return true;
}
if (AccessibilitySettings.TOGGLE_INVERSION_PREFERENCE.equals(key)) {
mColorInversionPreferenceRemoved = true;
return true;
}
if (AccessibilitySettings.DISPLAY_DALTONIZER_PREFERENCE_SCREEN.equals(key)) {
mColorCorrectionPreferenceRemoved = true;
return true;
}
return false;
}
};
}
@Test
public void testNonIndexableKeys_existInXmlLayout() {
final Context context = RuntimeEnvironment.application;
final List<String> niks = AccessibilitySettings.SEARCH_INDEX_DATA_PROVIDER
.getNonIndexableKeys(mContext);
.getNonIndexableKeys(context);
final List<String> keys = new ArrayList<>();
keys.addAll(XmlTestUtils.getKeysFromPreferenceXml(mContext, R.xml.accessibility_settings));
keys.addAll(XmlTestUtils.getKeysFromPreferenceXml(context, R.xml.accessibility_settings));
assertThat(keys).containsAllIn(niks);
}
@Test
public void testAccessibilityShortcutPreference_byDefault_shouldBeShown() {
final Preference preference = new Preference(mContext);
mFragment.checkAccessibilityShortcutVisibility(preference);
assertThat(mAccessibilityShortcutPreferenceRemoved).isFalse();
}
@Test
@Config(qualifiers = "mcc999")
public void testAccessibilityShortcutPreference_ifDisabled_shouldNotBeShown() {
final Preference preference = new Preference(mContext);
mFragment.checkAccessibilityShortcutVisibility(preference);
assertThat(mAccessibilityShortcutPreferenceRemoved).isTrue();
}
@Test
@Config(qualifiers = "mcc999")
public void testNonIndexableKeys_ifAccessibilityShortcutNotVisible_containsKey() {
final List<String> niks = AccessibilitySettings.SEARCH_INDEX_DATA_PROVIDER
.getNonIndexableKeys(mContext);
assertThat(niks).contains(AccessibilitySettings.ACCESSIBILITY_SHORTCUT_PREFERENCE);
}
@Test
public void testColorInversionPreference_byDefault_shouldBeShown() {
final Preference preference = new Preference(mContext);
mFragment.checkColorInversionVisibility(preference);
assertThat(mColorInversionPreferenceRemoved).isEqualTo(false);
}
@Test
@Config(qualifiers = "mcc999")
public void testColorInversionPreference_ifDisabled_shouldNotBeShown() {
final Preference preference = new Preference(mContext);
mFragment.checkColorInversionVisibility(preference);
assertThat(mColorInversionPreferenceRemoved).isEqualTo(true);
}
@Test
public void testColorCorrectionPreference_byDefault_shouldBeShown() {
final Preference preference = new Preference(mContext);
mFragment.checkColorCorrectionVisibility(preference);
assertThat(mColorCorrectionPreferenceRemoved).isEqualTo(false);
}
@Test
@Config(qualifiers = "mcc999")
public void testColorCorrectionPreference_ifDisabled_shouldNotBeShown() {
final Preference preference = new Preference(mContext);
mFragment.checkColorCorrectionVisibility(preference);
assertThat(mColorCorrectionPreferenceRemoved).isEqualTo(true);
}
}

View File

@@ -18,28 +18,40 @@ package com.android.settings.applications.appinfo;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq;
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;
import android.app.AlertDialog;
import android.app.Fragment;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.support.v7.preference.PreferenceManager;
import android.support.v7.preference.PreferenceScreen;
import android.text.TextUtils;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import com.android.settings.R;
import com.android.settings.TestConfig;
import com.android.settings.applications.LayoutPreference;
import com.android.settings.applications.instantapps.InstantAppButtonsController;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settingslib.applications.AppUtils;
import com.android.settingslib.applications.instantapps.InstantAppDataProvider;
import com.android.settingslib.wrapper.PackageManagerWrapper;
import org.junit.Before;
import org.junit.Test;
@@ -54,27 +66,48 @@ import org.robolectric.util.ReflectionHelpers;
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class InstantAppButtonsPreferenceControllerTest {
private static final String TEST_INSTALLER_PACKAGE_NAME = "com.installer";
private static final String TEST_INSTALLER_ACTIVITY_NAME = "com.installer.InstallerActivity";
private static final String TEST_AIA_PACKAGE_NAME = "test.aia.package";
@Mock
private PackageManager mPackageManager;
@Mock
private ApplicationInfo mAppInfo;
@Mock
private AppInfoDashboardFragment mFragment;
@Mock
private LayoutPreference mPreference;
private Context mContext;
private PreferenceScreen mScreen;
private PreferenceManager mPreferenceManager;
private Button mLaunchButton;
private Button mInstallButton;
private Button mClearAppButton;
private InstantAppButtonsPreferenceController mController;
private FakeFeatureFactory mFeatureFactory;
@Before
public void setUp() throws PackageManager.NameNotFoundException {
MockitoAnnotations.initMocks(this);
mFeatureFactory = FakeFeatureFactory.setupForTest();
mContext = spy(RuntimeEnvironment.application);
when(mContext.getPackageManager()).thenReturn(mPackageManager);
final PackageInfo packageInfo = mock(PackageInfo.class);
packageInfo.applicationInfo = mAppInfo;
when(mFragment.getPackageInfo()).thenReturn(packageInfo);
mController =
spy(new InstantAppButtonsPreferenceController(mContext, mFragment, "Package1"));
mPreferenceManager = new PreferenceManager(mContext);
mScreen = mPreferenceManager.createPreferenceScreen(mContext);
when(mFragment.getPreferenceManager()).thenReturn(mPreferenceManager);
final View buttons = View.inflate(
RuntimeEnvironment.application, R.layout.instant_app_buttons, null /* parent */);
mLaunchButton = buttons.findViewById(R.id.launch);
mInstallButton = buttons.findViewById(R.id.install);
mClearAppButton = buttons.findViewById(R.id.clear_data);
mController = spy(new InstantAppButtonsPreferenceController(
mContext, mFragment, TEST_AIA_PACKAGE_NAME, null /* lifecycle */));
when(mPreference.getKey()).thenReturn("instant_app_buttons");
mScreen.addPreference(mPreference);
when(mPreference.findViewById(R.id.instant_app_button_container)).thenReturn(buttons);
}
@Test
@@ -94,39 +127,164 @@ public class InstantAppButtonsPreferenceControllerTest {
}
@Test
public void displayPreference_shouldSetPreferenceTitle() {
final PreferenceScreen screen = mock(PreferenceScreen.class);
final LayoutPreference preference = mock(LayoutPreference.class);
when(screen.findPreference(mController.getPreferenceKey())).thenReturn(preference);
when(mController.getApplicationFeatureProvider())
.thenReturn(mFeatureFactory.applicationFeatureProvider);
final InstantAppButtonsController buttonsController =
mock(InstantAppButtonsController.class);
when(buttonsController.setPackageName(nullable(String.class)))
.thenReturn(buttonsController);
when(mFeatureFactory.applicationFeatureProvider.newInstantAppButtonsController(
nullable(Fragment.class), nullable(View.class),
nullable(InstantAppButtonsController.ShowDialogDelegate.class)))
.thenReturn(buttonsController);
public void onCreateOptionsMenu_noLaunchUri_shouldNotAddInstallInstantAppMenu() {
final Menu menu = mock(Menu.class);
when(menu.add(anyInt(), anyInt(), anyInt(), anyInt())).thenReturn(mock(MenuItem.class));
mController.displayPreference(screen);
mController.onCreateOptionsMenu(menu, null /* inflater */);
verify(buttonsController).setPackageName(nullable(String.class));
verify(buttonsController).show();
verify(menu, never()).add(anyInt(), eq(AppInfoDashboardFragment.INSTALL_INSTANT_APP_MENU),
anyInt(), eq(R.string.install_text));
}
@Test
public void createDialog_shouldReturnDialogFromButtonController() {
final InstantAppButtonsController buttonsController =
mock(InstantAppButtonsController.class);
ReflectionHelpers.setField(
mController, "mInstantAppButtonsController", buttonsController);
final AlertDialog mockDialog = mock(AlertDialog.class);
when(buttonsController.createDialog(InstantAppButtonsController.DLG_CLEAR_APP))
.thenReturn(mockDialog);
public void onCreateOptionsMenu_hasLaunchUri_shouldAddForceStop() {
ReflectionHelpers.setField(mController, "mLaunchUri", "www.test.launch");
final Menu menu = mock(Menu.class);
when(menu.add(anyInt(), anyInt(), anyInt(), anyInt())).thenReturn(mock(MenuItem.class));
assertThat(mController.createDialog(InstantAppButtonsController.DLG_CLEAR_APP))
.isEqualTo(mockDialog);
mController.onCreateOptionsMenu(menu, null /* inflater */);
verify(menu).add(anyInt(), eq(AppInfoDashboardFragment.INSTALL_INSTANT_APP_MENU),
anyInt(), eq(R.string.install_text));
}
@Test
public void onPrepareOptionsMenu_noAppStoreLink_shoulDisableInstallInstantAppMenu() {
ReflectionHelpers.setField(mController, "mLaunchUri", "www.test.launch");
final Menu menu = mock(Menu.class);
final MenuItem menuItem = mock(MenuItem.class);
when(menu.findItem(AppInfoDashboardFragment.INSTALL_INSTANT_APP_MENU)).thenReturn(menuItem);
mController.onPrepareOptionsMenu(menu);
verify(menuItem).setEnabled(false);
}
@Test
public void onPrepareOptionsMenu_hasAppStoreLink_shoulNotDisableInstallInstantAppMenu() {
ReflectionHelpers.setField(mController, "mLaunchUri", "www.test.launch");
final ResolveInfo resolveInfo = mock(ResolveInfo.class);
final ActivityInfo activityInfo = mock(ActivityInfo.class);
resolveInfo.activityInfo = activityInfo;
activityInfo.packageName = TEST_INSTALLER_PACKAGE_NAME;
activityInfo.name = TEST_INSTALLER_ACTIVITY_NAME;
when(mPackageManager.resolveActivity(any(), anyInt())).thenReturn(resolveInfo);
final Menu menu = mock(Menu.class);
final MenuItem menuItem = mock(MenuItem.class);
when(menu.findItem(AppInfoDashboardFragment.INSTALL_INSTANT_APP_MENU)).thenReturn(menuItem);
mController.onPrepareOptionsMenu(menu);
verify(menuItem, never()).setEnabled(false);
}
@Test
public void onOptionsItemSelected_shouldOpenAppStore() {
final ResolveInfo resolveInfo = mock(ResolveInfo.class);
final ActivityInfo activityInfo = mock(ActivityInfo.class);
resolveInfo.activityInfo = activityInfo;
activityInfo.packageName = TEST_INSTALLER_PACKAGE_NAME;
activityInfo.name = TEST_INSTALLER_ACTIVITY_NAME;
when(mPackageManager.resolveActivity(any(), anyInt())).thenReturn(resolveInfo);
mController.displayPreference(mScreen);
final ComponentName componentName =
new ComponentName(TEST_INSTALLER_PACKAGE_NAME, TEST_INSTALLER_ACTIVITY_NAME);
final MenuItem menu = mock(MenuItem.class);
when(menu.getItemId()).thenReturn(AppInfoDashboardFragment.INSTALL_INSTANT_APP_MENU);
mController.onOptionsItemSelected(menu);
verify(mFragment).startActivity(argThat(intent-> intent != null
&& intent.getAction().equals(Intent.ACTION_SHOW_APP_INFO)
&& intent.getComponent().equals(componentName)));
}
@Test
public void displayPreference_noLaunchUri_shouldShowHideLaunchButton() {
mController.displayPreference(mScreen);
assertThat(mLaunchButton.getVisibility()).isEqualTo(View.GONE);
}
@Test
public void displayPreference_hasLaunchUri_shouldShowHideInstallButton() {
ReflectionHelpers.setField(mController, "mLaunchUri", "www.test.launch");
mController.displayPreference(mScreen);
assertThat(mInstallButton.getVisibility()).isEqualTo(View.GONE);
}
@Test
public void displayPreference_noAppStoreLink_shoulDisableInstallButton() {
mController.displayPreference(mScreen);
assertThat(mInstallButton.isEnabled()).isFalse();
}
@Test
public void displayPreference_hasAppStoreLink_shoulSetClickListenerForInstallButton() {
final ResolveInfo resolveInfo = mock(ResolveInfo.class);
final ActivityInfo activityInfo = mock(ActivityInfo.class);
resolveInfo.activityInfo = activityInfo;
activityInfo.packageName = TEST_INSTALLER_PACKAGE_NAME;
activityInfo.name = TEST_INSTALLER_ACTIVITY_NAME;
when(mPackageManager.resolveActivity(any(), anyInt())).thenReturn(resolveInfo);
mController.displayPreference(mScreen);
assertThat(mInstallButton.hasOnClickListeners()).isTrue();
}
@Test
public void displayPreference_shoulSetClickListenerForClearButton() {
mController.displayPreference(mScreen);
assertThat(mClearAppButton.hasOnClickListeners()).isTrue();
}
@Test
public void clickLaunchButton_shouldLaunchViewIntent() {
final String launchUri = "www.test.launch";
ReflectionHelpers.setField(mController, "mLaunchUri", launchUri);
mController.displayPreference(mScreen);
mLaunchButton.callOnClick();
verify(mFragment).startActivity(argThat(intent-> intent != null
&& intent.getAction().equals(Intent.ACTION_VIEW)
&& TextUtils.equals(intent.getDataString(), launchUri)));
}
@Test
public void clickInstallButton_shouldOpenAppStore() {
final ResolveInfo resolveInfo = mock(ResolveInfo.class);
final ActivityInfo activityInfo = mock(ActivityInfo.class);
resolveInfo.activityInfo = activityInfo;
activityInfo.packageName = TEST_INSTALLER_PACKAGE_NAME;
activityInfo.name = TEST_INSTALLER_ACTIVITY_NAME;
when(mPackageManager.resolveActivity(any(), anyInt())).thenReturn(resolveInfo);
mController.displayPreference(mScreen);
final ComponentName componentName =
new ComponentName(TEST_INSTALLER_PACKAGE_NAME, TEST_INSTALLER_ACTIVITY_NAME);
mInstallButton.callOnClick();
verify(mFragment).startActivity(argThat(intent-> intent != null
&& intent.getAction().equals(Intent.ACTION_SHOW_APP_INFO)
&& intent.getComponent().equals(componentName)));
}
@Test
public void onClick_shouldDeleteApp() {
PackageManagerWrapper packageManagerWrapper = mock(PackageManagerWrapper.class);
ReflectionHelpers.setField(mController, "mPackageManagerWrapper", packageManagerWrapper);
mController.onClick(mock(DialogInterface.class), DialogInterface.BUTTON_POSITIVE);
verify(packageManagerWrapper)
.deletePackageAsUser(eq(TEST_AIA_PACKAGE_NAME), any(), anyInt(),anyInt());
}
}

View File

@@ -1,181 +0,0 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.applications.instantapps;
import static com.android.settings.applications.instantapps.InstantAppButtonsController
.ShowDialogDelegate;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
import android.annotation.SuppressLint;
import android.app.Fragment;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.view.View;
import android.widget.Button;
import com.android.settings.R;
import com.android.settings.TestConfig;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import com.android.settingslib.wrapper.PackageManagerWrapper;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Answers;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.annotation.Config;
import org.robolectric.util.ReflectionHelpers;
/** Tests for the InstantAppButtonsController. */
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = 23)
public class InstantAppButtonsControllerTest {
private static final String TEST_INSTALLER_PACKAGE_NAME = "com.installer";
private static final String TEST_INSTALLER_ACTIVITY_NAME = "com.installer.InstallerActivity";
private static final String TEST_AIA_PACKAGE_NAME = "test.aia.package";
private static ComponentName sTestInstallerComponent;
@BeforeClass
public static void beforeClass() {
sTestInstallerComponent =
new ComponentName(
TEST_INSTALLER_PACKAGE_NAME,
TEST_INSTALLER_ACTIVITY_NAME);
}
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
Context mockContext;
@Mock
PackageManager mockPackageManager;
@Mock
PackageManagerWrapper mockPackageManagerWrapper;
@Mock
View mockView;
@Mock
ShowDialogDelegate mockShowDialogDelegate;
@Mock
Button mockInstallButton;
@Mock
Button mockClearButton;
@Mock
MetricsFeatureProvider mockMetricsFeatureProvider;
@Mock
ResolveInfo mockResolveInfo;
@Mock
ActivityInfo mockActivityInfo;
private PackageManager stubPackageManager;
private FakeFeatureFactory fakeFeatureFactory;
private TestFragment testFragment;
private InstantAppButtonsController controller;
private View.OnClickListener receivedListener;
@Before
public void init() {
MockitoAnnotations.initMocks(this);
testFragment = new TestFragment();
when(mockView.findViewById(R.id.install)).thenReturn(mockInstallButton);
when(mockView.findViewById(R.id.clear_data)).thenReturn(mockClearButton);
mockResolveInfo.activityInfo = mockActivityInfo;
mockActivityInfo.packageName = TEST_INSTALLER_PACKAGE_NAME;
mockActivityInfo.name = TEST_INSTALLER_ACTIVITY_NAME;
when(mockContext.getPackageManager()).thenReturn(mockPackageManager);
when(mockPackageManager.resolveActivity(any(), anyInt())).thenReturn(mockResolveInfo);
controller = new InstantAppButtonsController(
mockContext, testFragment, mockView, mockShowDialogDelegate);
controller.setPackageName(TEST_AIA_PACKAGE_NAME);
ReflectionHelpers.setField(
controller, "mPackageManagerWrapper", mockPackageManagerWrapper);
FakeFeatureFactory.setupForTest();
}
@Test
public void testInstallListenerTriggersInstall() {
doAnswer(invocation -> {
receivedListener = (View.OnClickListener) invocation.getArguments()[0];
return null;
}).when(mockInstallButton).setOnClickListener(any());
controller.bindButtons();
assertThat(receivedListener).isNotNull();
receivedListener.onClick(mockInstallButton);
assertThat(testFragment.getStartActivityIntent()).isNotNull();
assertThat(testFragment.getStartActivityIntent().getComponent())
.isEqualTo(sTestInstallerComponent);
}
@Test
public void testClearListenerShowsDialog() {
doAnswer(invocation -> {
receivedListener = (View.OnClickListener) invocation.getArguments()[0];
return null;
}).when(mockClearButton).setOnClickListener(any());
controller.bindButtons();
assertThat(receivedListener).isNotNull();
receivedListener.onClick(mockClearButton);
verify(mockShowDialogDelegate).showDialog(InstantAppButtonsController.DLG_CLEAR_APP);
}
@Test
public void testDialogInterfaceOnClick_positiveClearsApp() {
controller.onClick(mock(DialogInterface.class), DialogInterface.BUTTON_POSITIVE);
verify(mockPackageManagerWrapper)
.deletePackageAsUser(eq(TEST_AIA_PACKAGE_NAME), any(), anyInt(),anyInt());
}
@Test
public void testDialogInterfaceOnClick_nonPositiveDoesNothing() {
controller.onClick(mock(DialogInterface.class), DialogInterface.BUTTON_NEGATIVE);
controller.onClick(mock(DialogInterface.class), DialogInterface.BUTTON_NEUTRAL);
verifyZeroInteractions(mockPackageManagerWrapper);
}
@SuppressLint("ValidFragment")
private class TestFragment extends Fragment {
private Intent startActivityIntent;
public Intent getStartActivityIntent() {
return startActivityIntent;
}
@Override
public void startActivity(Intent intent) {
startActivityIntent = intent;
}
}
}

View File

@@ -27,9 +27,9 @@ import android.content.pm.PackageManager;
import android.hardware.usb.UsbManager;
import android.net.ConnectivityManager;
import com.android.settings.connecteddevice.usb.UsbBackend;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
import com.android.settings.wrapper.UserManagerWrapper;
import org.junit.Before;
import org.junit.Test;
@@ -47,7 +47,7 @@ public class UsbBackendTest {
@Mock
private UsbManager mUsbManager;
@Mock
private UsbBackend.UserRestrictionUtil mUserRestrictionUtil;
private UserManagerWrapper mUserManagerWrapper;
@Mock
private ConnectivityManager mConnectivityManager;
@@ -63,7 +63,7 @@ public class UsbBackendTest {
@Test
public void constructor_noUsbPort_shouldNotCrash() {
UsbBackend usbBackend = new UsbBackend(mContext, mUserRestrictionUtil, null);
UsbBackend usbBackend = new UsbBackend(mContext, mUserManagerWrapper, null);
// Should not crash
}
}

View File

@@ -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.connecteddevice.usb;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.hardware.usb.UsbManager;
import com.android.settings.TestConfig;
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.annotation.Config;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class UsbDefaultFragmentTest {
@Mock
private UsbBackend mUsbBackend;
private UsbDefaultFragment mFragment;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mFragment = new UsbDefaultFragment();
mFragment.mUsbBackend = mUsbBackend;
}
@Test
public void testGetDefaultKey_isNone_shouldReturnNone() {
when(mUsbBackend.getDefaultUsbMode()).thenReturn(UsbBackend.MODE_DATA_NONE);
assertThat(mFragment.getDefaultKey()).isEqualTo(UsbManager.USB_FUNCTION_NONE);
}
@Test
public void testGetDefaultKey_isMtp_shouldReturnMtp() {
when(mUsbBackend.getDefaultUsbMode()).thenReturn(UsbBackend.MODE_DATA_MTP);
assertThat(mFragment.getDefaultKey()).isEqualTo(UsbManager.USB_FUNCTION_MTP);
}
@Test
public void testGetDefaultKey_isPtp_shouldReturnPtp() {
when(mUsbBackend.getDefaultUsbMode()).thenReturn(UsbBackend.MODE_DATA_PTP);
assertThat(mFragment.getDefaultKey()).isEqualTo(UsbManager.USB_FUNCTION_PTP);
}
@Test
public void testGetDefaultKey_isRndis_shouldReturnRndis() {
when(mUsbBackend.getDefaultUsbMode()).thenReturn(UsbBackend.MODE_DATA_TETHER);
assertThat(mFragment.getDefaultKey()).isEqualTo(UsbManager.USB_FUNCTION_RNDIS);
}
@Test
public void testGetDefaultKey_isMidi_shouldReturnMidi() {
when(mUsbBackend.getDefaultUsbMode()).thenReturn(UsbBackend.MODE_DATA_MIDI);
assertThat(mFragment.getDefaultKey()).isEqualTo(UsbManager.USB_FUNCTION_MIDI);
}
@Test
public void testSetDefaultKey_isNone_shouldSetNone() {
mFragment.setDefaultKey(UsbManager.USB_FUNCTION_NONE);
verify(mUsbBackend).setDefaultUsbMode(UsbBackend.MODE_DATA_NONE);
}
@Test
public void testSetDefaultKey_isMtp_shouldSetMtp() {
mFragment.setDefaultKey(UsbManager.USB_FUNCTION_MTP);
verify(mUsbBackend).setDefaultUsbMode(UsbBackend.MODE_DATA_MTP);
}
@Test
public void testSetDefaultKey_isPtp_shouldSetPtp() {
mFragment.setDefaultKey(UsbManager.USB_FUNCTION_PTP);
verify(mUsbBackend).setDefaultUsbMode(UsbBackend.MODE_DATA_PTP);
}
@Test
public void testSetDefaultKey_isRndis_shouldSetRndis() {
mFragment.setDefaultKey(UsbManager.USB_FUNCTION_RNDIS);
verify(mUsbBackend).setDefaultUsbMode(UsbBackend.MODE_DATA_TETHER);
}
@Test
public void testSetDefaultKey_isMidi_shouldSetMidi() {
mFragment.setDefaultKey(UsbManager.USB_FUNCTION_MIDI);
verify(mUsbBackend).setDefaultUsbMode(UsbBackend.MODE_DATA_MIDI);
}
}

View File

@@ -0,0 +1,68 @@
/*
* 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.dashboard.conditional;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.ComponentName;
import android.content.Context;
import com.android.settings.Settings;
import com.android.settings.TestConfig;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class WorkModeConditionTest {
@Mock
private ConditionManager mConditionManager;
private Context mContext;
private WorkModeCondition mCondition;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = spy(RuntimeEnvironment.application);
FakeFeatureFactory.setupForTest();
when(mConditionManager.getContext()).thenReturn(mContext);
mCondition = new WorkModeCondition(mConditionManager);
}
@Test
public void onPrimaryClick_shouldLaunchAccountsSetting() {
final ComponentName componentName =
new ComponentName(mContext, Settings.AccountDashboardActivity.class);
mCondition.onPrimaryClick();
verify(mContext).startActivity(
argThat(intent-> intent.getComponent().equals(componentName)));
}
}

View File

@@ -44,7 +44,7 @@ import android.support.v7.preference.PreferenceScreen;
import com.android.settings.R;
import com.android.settings.TestConfig;
import com.android.settings.connecteddevice.usb.UsbBackend;
import com.android.settings.wrapper.UsbManagerWrapper;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.ShadowUtils;
import com.android.settingslib.core.lifecycle.Lifecycle;
@@ -73,7 +73,7 @@ public class SelectUsbConfigPreferenceControllerTest {
@Mock
private PackageManager mPackageManager;
@Mock
private UsbBackend.UsbManagerPassThrough mUsbManagerPassThrough;
private UsbManagerWrapper mUsbManagerWrapper;
private Context mContext;
private LifecycleOwner mLifecycleOwner;
@@ -106,12 +106,12 @@ public class SelectUsbConfigPreferenceControllerTest {
mController = spy(new SelectUsbConfigPreferenceController(mContext, mLifecycle));
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
mController.displayPreference(mScreen);
mController.mUsbManagerPassThrough = mUsbManagerPassThrough;
mController.mUsbManagerWrapper = mUsbManagerWrapper;
when(mUsbManagerPassThrough.usbFunctionsFromString("mtp")).thenReturn(UsbManagerExtras.MTP);
when(mUsbManagerPassThrough.usbFunctionsFromString("rndis"))
when(mUsbManagerWrapper.usbFunctionsFromString("mtp")).thenReturn(UsbManagerExtras.MTP);
when(mUsbManagerWrapper.usbFunctionsFromString("rndis"))
.thenReturn(UsbManagerExtras.RNDIS);
when(mUsbManagerPassThrough.usbFunctionsFromString("none"))
when(mUsbManagerWrapper.usbFunctionsFromString("none"))
.thenReturn(UsbManagerExtras.NONE);
}
@@ -123,7 +123,7 @@ public class SelectUsbConfigPreferenceControllerTest {
@Test
public void onPreferenceChange_setCharging_shouldEnableCharging() {
when(mUsbManagerPassThrough.getCurrentFunctions()).thenReturn(
when(mUsbManagerWrapper.getCurrentFunctions()).thenReturn(
UsbManagerExtras.usbFunctionsFromString(mValues[0]));
doNothing().when(mController).setCurrentFunctions(anyLong());
mController.onPreferenceChange(mPreference, mValues[0]);
@@ -158,7 +158,7 @@ public class SelectUsbConfigPreferenceControllerTest {
@Test
public void onPreferenceChange_setMtp_shouldEnableMtp() {
when(mUsbManagerPassThrough.getCurrentFunctions())
when(mUsbManagerWrapper.getCurrentFunctions())
.thenReturn(UsbManagerExtras.usbFunctionsFromString(mValues[1]));
doNothing().when(mController).setCurrentFunctions(anyLong());
mController.onPreferenceChange(mPreference, mValues[1]);
@@ -169,7 +169,7 @@ public class SelectUsbConfigPreferenceControllerTest {
@Test
public void onPreferenceChange_monkeyUser_shouldReturnFalse() {
when(mUsbManagerPassThrough.getCurrentFunctions())
when(mUsbManagerWrapper.getCurrentFunctions())
.thenReturn(UsbManagerExtras.usbFunctionsFromString(mValues[1]));
ShadowUtils.setIsUserAMonkey(true);
doNothing().when(mController).setCurrentFunctions(anyLong());
@@ -182,7 +182,7 @@ public class SelectUsbConfigPreferenceControllerTest {
@Test
public void updateState_chargingEnabled_shouldSetPreferenceToCharging() {
when(mUsbManagerPassThrough.getCurrentFunctions())
when(mUsbManagerWrapper.getCurrentFunctions())
.thenReturn(UsbManagerExtras.usbFunctionsFromString(mValues[0]));
mController.updateState(mPreference);
@@ -193,7 +193,7 @@ public class SelectUsbConfigPreferenceControllerTest {
@Test
public void updateState_RndisEnabled_shouldEnableRndis() {
when(mUsbManagerPassThrough.getCurrentFunctions())
when(mUsbManagerWrapper.getCurrentFunctions())
.thenReturn(UsbManagerExtras.usbFunctionsFromString(mValues[3]));
mController.updateState(mPreference);
@@ -204,7 +204,7 @@ public class SelectUsbConfigPreferenceControllerTest {
@Test
public void updateState_noValueSet_shouldEnableChargingAsDefault() {
when(mUsbManagerPassThrough.getCurrentFunctions()).thenReturn(UsbManagerExtras.NONE);
when(mUsbManagerWrapper.getCurrentFunctions()).thenReturn(UsbManagerExtras.NONE);
mController.updateState(mPreference);
verify(mPreference).setValue(mValues[0]);

View File

@@ -53,7 +53,7 @@ public class BatterySaverControllerTest {
public void setUp() {
MockitoAnnotations.initMocks(this);
mBatterySaverController = spy(new BatterySaverController(mContext, mLifecycle));
mBatterySaverController = spy(new BatterySaverController(mContext));
ReflectionHelpers.setField(mBatterySaverController, "mPowerManager", mPowerManager);
ReflectionHelpers.setField(mBatterySaverController, "mBatterySaverPref", mBatterySaverPref);
doNothing().when(mBatterySaverController).refreshConditionManager();

View File

@@ -25,6 +25,7 @@ import android.support.v14.preference.SwitchPreference;
import com.android.settings.TestConfig;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.SettingsShadowResources;
import org.junit.Before;
import org.junit.Test;
@@ -34,7 +35,8 @@ import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION, shadows =
SettingsShadowResources.class)
public class AutoBatterySaverPreferenceControllerTest {
private AutoBatterySaverPreferenceController mController;
@@ -45,6 +47,8 @@ public class AutoBatterySaverPreferenceControllerTest {
public void setUp() {
MockitoAnnotations.initMocks(this);
SettingsShadowResources.overrideResource(
com.android.internal.R.integer.config_lowBatteryWarningLevel, 15);
mContext = RuntimeEnvironment.application;
mPreference = new SwitchPreference(mContext);
mController = new AutoBatterySaverPreferenceController(mContext);
@@ -84,4 +88,9 @@ public class AutoBatterySaverPreferenceControllerTest {
Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0)).isEqualTo(0);
}
@Test
public void testIsChecked_useDefaultValue_returnTrue() {
assertThat(mController.isChecked()).isTrue();
}
}

View File

@@ -24,6 +24,7 @@ import android.support.v14.preference.SwitchPreference;
import com.android.settings.TestConfig;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.SettingsShadowResources;
import com.android.settings.widget.SeekBarPreference;
import com.android.settingslib.core.lifecycle.Lifecycle;
@@ -35,9 +36,11 @@ import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION, shadows =
SettingsShadowResources.class)
public class AutoBatterySeekBarPreferenceControllerTest {
private static final int TRIGGER_LEVEL = 15;
private static final int TRIGGER_LEVEL = 20;
private static final int DEFAULT_LEVEL = 15;
private AutoBatterySeekBarPreferenceController mController;
private Context mContext;
@@ -51,6 +54,8 @@ public class AutoBatterySeekBarPreferenceControllerTest {
mLifecycleOwner = () -> mLifecycle;
mLifecycle = new Lifecycle(mLifecycleOwner);
SettingsShadowResources.overrideResource(
com.android.internal.R.integer.config_lowBatteryWarningLevel, DEFAULT_LEVEL);
mContext = RuntimeEnvironment.application;
mPreference = new SeekBarPreference(mContext);
mPreference.setMax(100);
@@ -67,6 +72,14 @@ public class AutoBatterySeekBarPreferenceControllerTest {
assertThat(mPreference.isVisible()).isFalse();
}
@Test
public void testPreference_defaultValue_preferenceVisible() {
mController.updateState(mPreference);
assertThat(mPreference.isVisible()).isTrue();
assertThat(mPreference.getProgress()).isEqualTo(DEFAULT_LEVEL);
}
@Test
public void testPreference_lowPowerLevelNotZero_updatePreference() {
Settings.Global.putInt(mContext.getContentResolver(),
@@ -74,7 +87,7 @@ public class AutoBatterySeekBarPreferenceControllerTest {
mController.updateState(mPreference);
assertThat(mPreference.isVisible()).isTrue();
assertThat(mPreference.getTitle()).isEqualTo("Turn on automatically at 15%");
assertThat(mPreference.getTitle()).isEqualTo("Turn on automatically at 20%");
assertThat(mPreference.getProgress()).isEqualTo(TRIGGER_LEVEL);
}

View File

@@ -51,6 +51,7 @@ import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
import com.android.settings.Settings.WifiSettingsActivity;
import com.android.settingslib.utils.ThreadUtils;
import com.android.settingslib.wifi.AccessPoint;
import com.android.settingslib.wifi.TestAccessPointBuilder;
import com.android.settingslib.wifi.WifiTracker;
@@ -260,26 +261,6 @@ public class WifiSettingsUiTest {
matches(isDisplayed()));
}
@Test
public void resumingAp_shouldNotForceUpdateWhenExistingAPsAreListed() {
setWifiState(WifiManager.WIFI_STATE_ENABLED);
setupConnectedAccessPoint();
when(mWifiTracker.isConnected()).thenReturn(true);
launchActivity();
onView(withText(resourceString(WIFI_DISPLAY_STATUS_CONNECTED))).check(
matches(isDisplayed()));
verify(mWifiTracker).forceUpdate();
Activity activity = mActivityRule.getActivity();
activity.finish();
getInstrumentation().waitForIdleSync();
getInstrumentation().callActivityOnStart(activity);
verify(mWifiTracker, atMost(1)).forceUpdate();
}
@Test
public void changingSecurityStateOnApShouldNotCauseMultipleListItems() {
setWifiState(WifiManager.WIFI_STATE_ENABLED);
@@ -305,10 +286,10 @@ public class WifiSettingsUiTest {
onView(withText(TEST_SSID)).check(matches(isDisplayed()));
mWifiListener.onAccessPointsChanged();
ThreadUtils.postOnMainThread(() -> mWifiListener.onAccessPointsChanged());
onView(withText(TEST_SSID)).check(matches(isDisplayed()));
mWifiListener.onAccessPointsChanged();
ThreadUtils.postOnMainThread(() -> mWifiListener.onAccessPointsChanged());
onView(withText(TEST_SSID)).check(matches(isDisplayed()));
}
@@ -367,7 +348,6 @@ public class WifiSettingsUiTest {
launchActivity();
verify(mWifiTracker, atMost(1)).forceUpdate();
verify(mWifiTracker, times(1)).getAccessPoints();
onView(withText(WIFI_DISPLAY_STATUS_CONNECTED)).check(matches(isDisplayed()));