Snap for 4615953 from 032e7c0def to pi-release
Change-Id: Id475665239df500b34dcbfec83ff78a18969692a
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
21
res/xml/usb_default_fragment.xml
Normal file
21
res/xml/usb_default_fragment.xml
Normal 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>
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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:
|
||||
|
||||
34
src/com/android/settings/wrapper/UsbManagerWrapper.java
Normal file
34
src/com/android/settings/wrapper/UsbManagerWrapper.java
Normal 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);
|
||||
}
|
||||
}
|
||||
@@ -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()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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)));
|
||||
}
|
||||
}
|
||||
@@ -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]);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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()));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user