Snap for 4509671 from 1b279f97e9 to pi-release
Change-Id: Ia4f313e6c2d29eabc4b7d0ad61a6e7ef83286b15
This commit is contained in:
@@ -51,4 +51,7 @@
|
||||
|
||||
<!-- Whether location mode is available or not. -->
|
||||
<bool name="config_location_mode_available">true</bool>
|
||||
|
||||
<!-- Whether wallpaper attribution should be shown or not. -->
|
||||
<bool name="config_show_wallpaper_attribution">true</bool>
|
||||
</resources>
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
|
||||
<style name="GlifV2Theme" parent="SuwThemeGlifV2">
|
||||
<!-- For all Alert Dialogs -->
|
||||
<item name="android:alertDialogTheme">@style/ThemeOverlay.AlertDialog</item>
|
||||
<item name="android:alertDialogTheme">@style/GlifV2ThemeAlertDialog</item>
|
||||
<item name="android:windowBackground">?android:attr/colorBackground</item>
|
||||
<item name="*android:preferencePanelStyle">@*android:style/PreferencePanel.Dialog</item>
|
||||
<item name="fingerprint_layout_theme">@style/FingerprintLayoutTheme</item>
|
||||
@@ -83,7 +83,7 @@
|
||||
|
||||
<style name="GlifV2Theme.Light" parent="SuwThemeGlifV2.Light">
|
||||
<!-- For all Alert Dialogs -->
|
||||
<item name="android:alertDialogTheme">@style/ThemeOverlay.AlertDialog</item>
|
||||
<item name="android:alertDialogTheme">@style/GlifV2ThemeAlertDialog.Light</item>
|
||||
<item name="android:windowBackground">?android:attr/colorBackground</item>
|
||||
<item name="*android:preferencePanelStyle">@*android:style/PreferencePanel.Dialog</item>
|
||||
<item name="fingerprint_layout_theme">@style/FingerprintLayoutTheme</item>
|
||||
@@ -242,6 +242,14 @@
|
||||
<item name="android:windowSoftInputMode">adjustResize</item>
|
||||
</style>
|
||||
|
||||
<style name="GlifV2ThemeAlertDialog" parent="SuwAlertDialogTheme">
|
||||
<item name="android:windowSoftInputMode">adjustResize</item>
|
||||
</style>
|
||||
|
||||
<style name="GlifV2ThemeAlertDialog.Light" parent="SuwAlertDialogTheme.Light">
|
||||
<item name="android:windowSoftInputMode">adjustResize</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.AlertDialog" parent="@*android:style/Theme.DeviceDefault.Settings.Dialog.Alert">
|
||||
<item name="android:windowSoftInputMode">adjustResize</item>
|
||||
|
||||
|
||||
@@ -14,7 +14,10 @@
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<PreferenceScreen
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:settings="http://schemas.android.com/apk/res-auto"
|
||||
settings:initialExpandedChildrenCount="5">
|
||||
|
||||
<com.android.settings.applications.LayoutPreference
|
||||
android:key="connection_header"
|
||||
|
||||
@@ -24,13 +24,14 @@ import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.os.Bundle;
|
||||
import android.provider.SearchIndexableResource;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
import android.support.v7.preference.PreferenceGroup;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.search.BaseSearchIndexProvider;
|
||||
import com.android.settings.search.Indexable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@@ -40,7 +41,7 @@ public class LegalSettings extends SettingsPreferenceFragment implements Indexab
|
||||
private static final String KEY_LICENSE = "license";
|
||||
private static final String KEY_COPYRIGHT = "copyright";
|
||||
private static final String KEY_WEBVIEW_LICENSE = "webview_license";
|
||||
private static final String KEY_WALLPAPER_ATTRIBUTIONS = "wallpaper_attributions";
|
||||
@VisibleForTesting static final String KEY_WALLPAPER_ATTRIBUTIONS = "wallpaper_attributions";
|
||||
|
||||
public void onCreate(Bundle icicle) {
|
||||
super.onCreate(icicle);
|
||||
@@ -57,6 +58,8 @@ public class LegalSettings extends SettingsPreferenceFragment implements Indexab
|
||||
Utils.UPDATE_PREFERENCE_FLAG_SET_TITLE_TO_MATCHING_ACTIVITY);
|
||||
Utils.updatePreferenceToSpecificActivityOrRemove(act, parentPreference, KEY_WEBVIEW_LICENSE,
|
||||
Utils.UPDATE_PREFERENCE_FLAG_SET_TITLE_TO_MATCHING_ACTIVITY);
|
||||
|
||||
checkWallpaperAttributionAvailability(act);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -64,6 +67,14 @@ public class LegalSettings extends SettingsPreferenceFragment implements Indexab
|
||||
return MetricsEvent.ABOUT_LEGAL_SETTINGS;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void checkWallpaperAttributionAvailability(Context context) {
|
||||
if (!context.getResources().getBoolean(
|
||||
R.bool.config_show_wallpaper_attribution)) {
|
||||
removePreference(KEY_WALLPAPER_ATTRIBUTIONS);
|
||||
}
|
||||
}
|
||||
|
||||
public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
|
||||
new BaseSearchIndexProvider() {
|
||||
|
||||
|
||||
@@ -1142,11 +1142,11 @@ public class RadioInfo extends Activity {
|
||||
switch (state) {
|
||||
case TelephonyManager.DATA_CONNECTED:
|
||||
//FIXME: Replace with a TelephonyManager call
|
||||
phone.setDataEnabled(false);
|
||||
phone.setUserDataEnabled(false);
|
||||
break;
|
||||
case TelephonyManager.DATA_DISCONNECTED:
|
||||
//FIXME: Replace with a TelephonyManager call
|
||||
phone.setDataEnabled(true);
|
||||
phone.setUserDataEnabled(true);
|
||||
break;
|
||||
default:
|
||||
// do nothing
|
||||
|
||||
@@ -15,11 +15,11 @@
|
||||
*/
|
||||
package com.android.settings.applications;
|
||||
|
||||
import com.android.settings.fuelgauge.PowerWhitelistBackend;
|
||||
import com.android.settingslib.applications.ApplicationsState;
|
||||
import com.android.settingslib.applications.ApplicationsState.AppEntry;
|
||||
import com.android.settingslib.applications.ApplicationsState.AppFilter;
|
||||
import com.android.settingslib.applications.ApplicationsState.CompoundFilter;
|
||||
import com.android.settingslib.fuelgauge.PowerWhitelistBackend;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* 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.appinfo;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.support.v7.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.applications.LayoutPreference;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settings.widget.EntityHeaderController;
|
||||
import com.android.settingslib.applications.AppUtils;
|
||||
import com.android.settingslib.applications.ApplicationsState.AppEntry;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
|
||||
public class AppHeaderViewPreferenceController extends BasePreferenceController
|
||||
implements AppInfoDashboardFragment.Callback {
|
||||
|
||||
private static final String KEY_HEADER = "header_view";
|
||||
|
||||
private LayoutPreference mHeader;
|
||||
private final AppInfoDashboardFragment mParent;
|
||||
private final String mPackageName;
|
||||
private final Lifecycle mLifecycle;
|
||||
|
||||
public AppHeaderViewPreferenceController(Context context, AppInfoDashboardFragment parent,
|
||||
String packageName, Lifecycle lifecycle) {
|
||||
super(context, KEY_HEADER);
|
||||
mParent = parent;
|
||||
mPackageName = packageName;
|
||||
mLifecycle = lifecycle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAvailabilityStatus() {
|
||||
return AVAILABLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
super.displayPreference(screen);
|
||||
mHeader = (LayoutPreference) screen.findPreference(KEY_HEADER);
|
||||
final Activity activity = mParent.getActivity();
|
||||
EntityHeaderController
|
||||
.newInstance(activity, mParent, mHeader.findViewById(R.id.entity_header))
|
||||
.setRecyclerView(mParent.getListView(), mLifecycle)
|
||||
.setPackageName(mPackageName)
|
||||
.setHasAppInfoLink(false)
|
||||
.setButtonActions(EntityHeaderController.ActionType.ACTION_APP_PREFERENCE,
|
||||
EntityHeaderController.ActionType.ACTION_NONE)
|
||||
.styleActionBar(activity)
|
||||
.bindHeaderButtons();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshUi() {
|
||||
setAppLabelAndIcon(mParent.getPackageInfo(), mParent.getAppEntry());
|
||||
}
|
||||
|
||||
// Utility method to set application label and icon.
|
||||
private void setAppLabelAndIcon(PackageInfo pkgInfo, AppEntry appEntry) {
|
||||
final Activity activity = mParent.getActivity();
|
||||
final boolean isInstantApp = AppUtils.isInstant(pkgInfo.applicationInfo);
|
||||
final CharSequence summary = isInstantApp
|
||||
? null : mContext.getString(Utils.getInstallationStatus(appEntry.info));
|
||||
EntityHeaderController
|
||||
.newInstance(activity, mParent, mHeader.findViewById(R.id.entity_header))
|
||||
.setLabel(appEntry)
|
||||
.setIcon(appEntry)
|
||||
.setSummary(summary)
|
||||
.setIsInstantApp(isInstantApp)
|
||||
.done(activity, false /* rebindActions */);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -107,7 +107,6 @@ public class AppInfoDashboardFragment extends DashboardFragment
|
||||
private static final int DLG_DISABLE = DLG_BASE + 2;
|
||||
private static final int DLG_SPECIAL_DISABLE = DLG_BASE + 3;
|
||||
|
||||
private static final String KEY_HEADER = "header_view";
|
||||
private static final String KEY_ADVANCED_APP_INFO_CATEGORY = "advanced_app_info";
|
||||
|
||||
public static final String ARG_PACKAGE_NAME = "package";
|
||||
@@ -135,7 +134,6 @@ public class AppInfoDashboardFragment extends DashboardFragment
|
||||
|
||||
private boolean mInitialized;
|
||||
private boolean mShowUninstalled;
|
||||
private LayoutPreference mHeader;
|
||||
private boolean mUpdatedSysApp = false;
|
||||
private boolean mDisableAfterUninstall;
|
||||
|
||||
@@ -213,6 +211,8 @@ public class AppInfoDashboardFragment extends DashboardFragment
|
||||
|
||||
// The following are controllers for preferences that needs to refresh the preference state
|
||||
// when app state changes.
|
||||
controllers.add(
|
||||
new AppHeaderViewPreferenceController(context, this, packageName, lifecycle));
|
||||
controllers.add(new AppStoragePreferenceController(context, this, lifecycle));
|
||||
controllers.add(new AppDataUsagePreferenceController(context, this, lifecycle));
|
||||
controllers.add(new AppNotificationPreferenceController(context, this));
|
||||
@@ -275,25 +275,6 @@ public class AppInfoDashboardFragment extends DashboardFragment
|
||||
return mPackageInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
if (mFinishing) {
|
||||
return;
|
||||
}
|
||||
final Activity activity = getActivity();
|
||||
mHeader = (LayoutPreference) findPreference(KEY_HEADER);
|
||||
EntityHeaderController.newInstance(activity, this, mHeader.findViewById(R.id.entity_header))
|
||||
.setRecyclerView(getListView(), getLifecycle())
|
||||
.setPackageName(mPackageName)
|
||||
.setHasAppInfoLink(false)
|
||||
.setButtonActions(EntityHeaderController.ActionType.ACTION_APP_PREFERENCE,
|
||||
EntityHeaderController.ActionType.ACTION_NONE)
|
||||
.styleActionBar(activity)
|
||||
.bindHeaderButtons();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPackageSizeChanged(String packageName) {
|
||||
if (!TextUtils.equals(packageName, mPackageName)) {
|
||||
@@ -382,22 +363,6 @@ public class AppInfoDashboardFragment extends DashboardFragment
|
||||
}
|
||||
}
|
||||
|
||||
// Utility method to set application label and icon.
|
||||
private void setAppLabelAndIcon(PackageInfo pkgInfo) {
|
||||
final View appSnippet = mHeader.findViewById(R.id.entity_header);
|
||||
mState.ensureIcon(mAppEntry);
|
||||
final Activity activity = getActivity();
|
||||
final boolean isInstantApp = AppUtils.isInstant(mPackageInfo.applicationInfo);
|
||||
final CharSequence summary =
|
||||
isInstantApp ? null : getString(Utils.getInstallationStatus(mAppEntry.info));
|
||||
EntityHeaderController.newInstance(activity, this, appSnippet)
|
||||
.setLabel(mAppEntry)
|
||||
.setIcon(mAppEntry)
|
||||
.setSummary(summary)
|
||||
.setIsInstantApp(isInstantApp)
|
||||
.done(activity, false /* rebindActions */);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
boolean shouldShowUninstallForAll(AppEntry appEntry) {
|
||||
boolean showIt = true;
|
||||
@@ -433,11 +398,9 @@ public class AppInfoDashboardFragment extends DashboardFragment
|
||||
return false; // onCreate must have failed, make sure to exit
|
||||
}
|
||||
|
||||
|
||||
setAppLabelAndIcon(mPackageInfo);
|
||||
mState.ensureIcon(mAppEntry);
|
||||
|
||||
// Update the preference summaries.
|
||||
final Activity context = getActivity();
|
||||
for (Callback callback : mCallbacks) {
|
||||
callback.refreshUi();
|
||||
}
|
||||
@@ -450,7 +413,7 @@ public class AppInfoDashboardFragment extends DashboardFragment
|
||||
// All other times: if the app no longer exists then we want
|
||||
// to go away.
|
||||
try {
|
||||
final ApplicationInfo ainfo = context.getPackageManager().getApplicationInfo(
|
||||
final ApplicationInfo ainfo = getActivity().getPackageManager().getApplicationInfo(
|
||||
mAppEntry.info.packageName,
|
||||
PackageManager.MATCH_DISABLED_COMPONENTS
|
||||
| PackageManager.MATCH_ANY_USER);
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.android.settings.applications.defaultapps;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
@@ -110,6 +111,14 @@ public class DefaultHomePicker extends DefaultAppPickerFragment {
|
||||
IntentFilter.MATCH_CATEGORY_EMPTY,
|
||||
allComponents.toArray(new ComponentName[0]),
|
||||
component);
|
||||
|
||||
// Launch the new Home app so the change is immediately visible even if
|
||||
// the Home button is not pressed.
|
||||
final Context context = getContext();
|
||||
Intent i = new Intent(Intent.ACTION_MAIN);
|
||||
i.addCategory(Intent.CATEGORY_HOME);
|
||||
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
context.startActivity(i);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -101,7 +101,6 @@ import com.android.settings.core.FeatureFlags;
|
||||
import com.android.settings.core.InstrumentedPreferenceFragment;
|
||||
import com.android.settings.dashboard.SummaryLoader;
|
||||
import com.android.settings.fuelgauge.HighPowerDetail;
|
||||
import com.android.settings.fuelgauge.PowerWhitelistBackend;
|
||||
import com.android.settings.notification.AppNotificationSettings;
|
||||
import com.android.settings.notification.ConfigureNotificationSettings;
|
||||
import com.android.settings.notification.NotificationBackend;
|
||||
@@ -114,6 +113,7 @@ import com.android.settingslib.applications.ApplicationsState.AppFilter;
|
||||
import com.android.settingslib.applications.ApplicationsState.CompoundFilter;
|
||||
import com.android.settingslib.applications.ApplicationsState.VolumeFilter;
|
||||
import com.android.settingslib.applications.StorageStatsSource;
|
||||
import com.android.settingslib.fuelgauge.PowerWhitelistBackend;
|
||||
import com.android.settingslib.utils.ThreadUtils;
|
||||
import com.android.settingslib.wrapper.PackageManagerWrapper;
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ import com.android.settings.core.PreferenceControllerMixin;
|
||||
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
|
||||
import com.android.settings.wrapper.DevicePolicyManagerWrapper;
|
||||
import com.android.settingslib.core.AbstractPreferenceController;
|
||||
import com.android.settingslib.fuelgauge.PowerWhitelistBackend;
|
||||
|
||||
/**
|
||||
* Controller to control whether an app can run in the background
|
||||
|
||||
@@ -25,6 +25,7 @@ import com.android.settings.SettingsActivity;
|
||||
import com.android.settings.applications.manageapplications.ManageApplications;
|
||||
import com.android.settings.core.PreferenceControllerMixin;
|
||||
import com.android.settingslib.core.AbstractPreferenceController;
|
||||
import com.android.settingslib.fuelgauge.PowerWhitelistBackend;
|
||||
|
||||
/**
|
||||
* Controller that jumps to high power optimization fragment
|
||||
|
||||
@@ -36,6 +36,7 @@ import com.android.settings.applications.AppInfoBase;
|
||||
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settingslib.applications.ApplicationsState.AppEntry;
|
||||
import com.android.settingslib.fuelgauge.PowerWhitelistBackend;
|
||||
|
||||
public class HighPowerDetail extends InstrumentedDialogFragment implements OnClickListener,
|
||||
View.OnClickListener {
|
||||
|
||||
@@ -1,103 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.settings.fuelgauge;
|
||||
|
||||
import android.os.IDeviceIdleController;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
|
||||
import android.util.ArraySet;
|
||||
import android.util.Log;
|
||||
|
||||
|
||||
/**
|
||||
* Handles getting/changing the whitelist for the exceptions to battery saving features.
|
||||
*/
|
||||
public class PowerWhitelistBackend {
|
||||
|
||||
private static final String TAG = "PowerWhitelistBackend";
|
||||
|
||||
private static final String DEVICE_IDLE_SERVICE = "deviceidle";
|
||||
|
||||
private static PowerWhitelistBackend sInstance;
|
||||
|
||||
private final IDeviceIdleController mDeviceIdleService;
|
||||
private final ArraySet<String> mWhitelistedApps = new ArraySet<>();
|
||||
private final ArraySet<String> mSysWhitelistedApps = new ArraySet<>();
|
||||
|
||||
public PowerWhitelistBackend() {
|
||||
mDeviceIdleService = IDeviceIdleController.Stub.asInterface(
|
||||
ServiceManager.getService(DEVICE_IDLE_SERVICE));
|
||||
refreshList();
|
||||
}
|
||||
|
||||
public int getWhitelistSize() {
|
||||
return mWhitelistedApps.size();
|
||||
}
|
||||
|
||||
public boolean isSysWhitelisted(String pkg) {
|
||||
return mSysWhitelistedApps.contains(pkg);
|
||||
}
|
||||
|
||||
public boolean isWhitelisted(String pkg) {
|
||||
return mWhitelistedApps.contains(pkg);
|
||||
}
|
||||
|
||||
public void addApp(String pkg) {
|
||||
try {
|
||||
mDeviceIdleService.addPowerSaveWhitelistApp(pkg);
|
||||
mWhitelistedApps.add(pkg);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "Unable to reach IDeviceIdleController", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeApp(String pkg) {
|
||||
try {
|
||||
mDeviceIdleService.removePowerSaveWhitelistApp(pkg);
|
||||
mWhitelistedApps.remove(pkg);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "Unable to reach IDeviceIdleController", e);
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void refreshList() {
|
||||
mSysWhitelistedApps.clear();
|
||||
mWhitelistedApps.clear();
|
||||
try {
|
||||
String[] whitelistedApps = mDeviceIdleService.getFullPowerWhitelist();
|
||||
for (String app : whitelistedApps) {
|
||||
mWhitelistedApps.add(app);
|
||||
}
|
||||
String[] sysWhitelistedApps = mDeviceIdleService.getSystemPowerWhitelist();
|
||||
for (String app : sysWhitelistedApps) {
|
||||
mSysWhitelistedApps.add(app);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "Unable to reach IDeviceIdleController", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static PowerWhitelistBackend getInstance() {
|
||||
if (sInstance == null) {
|
||||
sInstance = new PowerWhitelistBackend();
|
||||
}
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -881,7 +881,7 @@ public class WifiSettings extends RestrictedSettingsFragment
|
||||
SettingsActivity activity = (SettingsActivity) WifiSettings.this.getActivity();
|
||||
activity.startPreferencePanel(this,
|
||||
WifiNetworkDetailsFragment.class.getName(), pref.getExtras(),
|
||||
R.string.wifi_details_title, null, null, 0);
|
||||
-1 /* resId */, pref.getTitle(), null, 0 /* resultRequestCode */);
|
||||
});
|
||||
|
||||
pref.refresh();
|
||||
|
||||
@@ -21,4 +21,5 @@
|
||||
<bool name="config_show_connectivity_monitor">false</bool>
|
||||
<bool name="config_display_recent_apps">false</bool>
|
||||
<bool name="config_location_mode_available">false</bool>
|
||||
</resources>
|
||||
<bool name="config_show_wallpaper_attribution">false</bool>
|
||||
</resources>
|
||||
|
||||
@@ -15,23 +15,49 @@
|
||||
*/
|
||||
package com.android.settings;
|
||||
|
||||
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 com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
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.List;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
|
||||
public class LegalSettingsTest {
|
||||
|
||||
private Context mContext;
|
||||
private LegalSettings mFragment;
|
||||
private boolean mWallpaperRemoved;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = spy(RuntimeEnvironment.application);
|
||||
mFragment = new LegalSettings() {
|
||||
@Override
|
||||
protected boolean removePreference(String key) {
|
||||
if (LegalSettings.KEY_WALLPAPER_ATTRIBUTIONS.equals(key)) {
|
||||
mWallpaperRemoved = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNonIndexableKeys_existInXmlLayout() {
|
||||
final Context context = RuntimeEnvironment.application;
|
||||
@@ -43,4 +69,19 @@ public class LegalSettingsTest {
|
||||
|
||||
assertThat(keys).containsAllIn(niks);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWallpaperAttributions_byDefault_shouldBeShown() {
|
||||
mFragment.checkWallpaperAttributionAvailability(mContext);
|
||||
|
||||
assertThat(mWallpaperRemoved).isEqualTo(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(qualifiers = "mcc999")
|
||||
public void testWallpaperAttributions_ifDisabled_shouldNotBeShown() {
|
||||
mFragment.checkWallpaperAttributionAvailability(mContext);
|
||||
|
||||
assertThat(mWallpaperRemoved).isEqualTo(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* 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.appinfo;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.support.v7.preference.PreferenceScreen;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.TestConfig;
|
||||
import com.android.settings.applications.LayoutPreference;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
import com.android.settingslib.applications.ApplicationsState;
|
||||
|
||||
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 AppHeaderViewPreferenceControllerTest {
|
||||
|
||||
@Mock
|
||||
private AppInfoDashboardFragment mFragment;
|
||||
@Mock
|
||||
private Activity mActivity;
|
||||
|
||||
private Context mContext;
|
||||
private AppHeaderViewPreferenceController mController;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = RuntimeEnvironment.application;
|
||||
when(mFragment.getActivity()).thenReturn(mActivity);
|
||||
when(mActivity.getApplicationContext()).thenReturn(mContext);
|
||||
mController = new AppHeaderViewPreferenceController(mContext, mFragment, "Package1", null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void refreshUi_shouldRefreshButton() {
|
||||
final PackageInfo packageInfo = mock(PackageInfo.class);
|
||||
final ApplicationsState.AppEntry appEntry = mock(ApplicationsState.AppEntry.class);
|
||||
final String appLabel = "App1";
|
||||
appEntry.label = appLabel;
|
||||
final ApplicationInfo info = new ApplicationInfo();
|
||||
info.flags = ApplicationInfo.FLAG_INSTALLED;
|
||||
info.enabled = true;
|
||||
packageInfo.applicationInfo = info;
|
||||
appEntry.info = info;
|
||||
when(mFragment.getAppEntry()).thenReturn(appEntry);
|
||||
when(mFragment.getPackageInfo()).thenReturn(packageInfo);
|
||||
|
||||
final PreferenceScreen screen = mock(PreferenceScreen.class);
|
||||
final LayoutPreference preference = mock(LayoutPreference.class);
|
||||
when(screen.findPreference(mController.getPreferenceKey())).thenReturn(preference);
|
||||
final View header = mock(View.class);
|
||||
when(preference.findViewById(R.id.entity_header)).thenReturn(header);
|
||||
final TextView title = mock(TextView.class);
|
||||
when(header.findViewById(R.id.entity_header_title)).thenReturn(title);
|
||||
final TextView summary = mock(TextView.class);
|
||||
when(header.findViewById(R.id.entity_header_summary)).thenReturn(summary);
|
||||
mController.displayPreference(screen);
|
||||
|
||||
mController.refreshUi();
|
||||
|
||||
verify(title).setText(appLabel);
|
||||
verify(summary).setText(mContext.getString(R.string.installed));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -73,6 +73,7 @@ public class DefaultHomePickerTest {
|
||||
@Mock
|
||||
private PackageManager mPackageManager;
|
||||
|
||||
private Context mContext;
|
||||
private DefaultHomePicker mPicker;
|
||||
|
||||
@Before
|
||||
@@ -85,7 +86,8 @@ public class DefaultHomePickerTest {
|
||||
mPicker.onAttach((Context) mActivity);
|
||||
|
||||
ReflectionHelpers.setField(mPicker, "mPm", mPackageManagerWrapper);
|
||||
doReturn(RuntimeEnvironment.application).when(mPicker).getContext();
|
||||
mContext = spy(RuntimeEnvironment.application);
|
||||
doReturn(mContext).when(mPicker).getContext();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -94,6 +96,7 @@ public class DefaultHomePickerTest {
|
||||
|
||||
verify(mPackageManagerWrapper).replacePreferredActivity(any(IntentFilter.class),
|
||||
anyInt(), any(ComponentName[].class), any(ComponentName.class));
|
||||
verify(mContext).startActivity(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -41,6 +41,7 @@ import com.android.settings.TestConfig;
|
||||
import com.android.settings.testutils.shadow.SettingsShadowResources;
|
||||
import com.android.settings.testutils.shadow.ShadowFragment;
|
||||
import com.android.settings.wrapper.DevicePolicyManagerWrapper;
|
||||
import com.android.settingslib.fuelgauge.PowerWhitelistBackend;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
@@ -120,10 +120,11 @@ public class BatteryOptimizationPreferenceControllerTest {
|
||||
/**
|
||||
* Create this test class so we could mock it
|
||||
*/
|
||||
public static class TestPowerWhitelistBackend extends PowerWhitelistBackend {
|
||||
public static class TestPowerWhitelistBackend extends
|
||||
com.android.settingslib.fuelgauge.PowerWhitelistBackend {
|
||||
|
||||
@Override
|
||||
void refreshList() {
|
||||
public void refreshList() {
|
||||
// Do nothing so we could mock it without error
|
||||
}
|
||||
}
|
||||
|
||||
36
tests/uitests/Android.mk
Normal file
36
tests/uitests/Android.mk
Normal file
@@ -0,0 +1,36 @@
|
||||
# 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.
|
||||
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_PACKAGE_NAME := SettingsUITests
|
||||
LOCAL_COMPATIBILITY_SUITE := device-tests
|
||||
LOCAL_SRC_FILES := $(call all-java-files-under, src)
|
||||
LOCAL_MODULE_TAGS := tests
|
||||
LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base
|
||||
LOCAL_STATIC_JAVA_LIBRARIES := \
|
||||
app-helpers-base \
|
||||
launcher-helper-lib \
|
||||
settings-helper \
|
||||
timeresult-helper-lib \
|
||||
ub-uiautomator \
|
||||
sysui-helper \
|
||||
google-sysui-helper \
|
||||
metrics-helper-lib \
|
||||
platform-test-annotations \
|
||||
|
||||
#LOCAL_SDK_VERSION := current
|
||||
|
||||
include $(BUILD_PACKAGE)
|
||||
34
tests/uitests/AndroidManifest.xml
Normal file
34
tests/uitests/AndroidManifest.xml
Normal file
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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.
|
||||
-->
|
||||
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.android.settings.ui">
|
||||
|
||||
<application>
|
||||
<uses-library android:name="android.test.runner" />
|
||||
</application>
|
||||
|
||||
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
|
||||
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
|
||||
<uses-permission android:name="android.permission.READ_LOGS" />
|
||||
|
||||
<instrumentation
|
||||
android:name="android.support.test.runner.AndroidJUnitRunner"
|
||||
android:targetPackage="com.android.settings.ui"
|
||||
android:label="Android Settings Functional UI Tests" />
|
||||
</manifest>
|
||||
27
tests/uitests/AndroidTest.xml
Normal file
27
tests/uitests/AndroidTest.xml
Normal file
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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.
|
||||
-->
|
||||
<configuration description="Run Android Settings Functional UI Tests.">
|
||||
<target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
|
||||
<option name="test-file-name" value="SettingsUITests.apk" />
|
||||
</target_preparer>
|
||||
|
||||
<option name="test-suite-tag" value="apct" />
|
||||
<option name="test-tag" value="SettingsUITests" />
|
||||
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
|
||||
<option name="package" value="com.android.settings.ui" />
|
||||
<option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
|
||||
</test>
|
||||
</configuration>
|
||||
@@ -0,0 +1,224 @@
|
||||
/*
|
||||
* 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.ui;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.RemoteException;
|
||||
import android.provider.Settings;
|
||||
import android.support.test.uiautomator.By;
|
||||
import android.support.test.uiautomator.Direction;
|
||||
import android.support.test.uiautomator.UiDevice;
|
||||
import android.support.test.uiautomator.UiObject2;
|
||||
import android.support.test.uiautomator.Until;
|
||||
import android.test.InstrumentationTestCase;
|
||||
import android.test.suitebuilder.annotation.MediumTest;
|
||||
import android.test.suitebuilder.annotation.Suppress;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
|
||||
/** Verifies basic functionality of the About Phone screen */
|
||||
public class AboutPhoneSettingsTests extends InstrumentationTestCase {
|
||||
private static final boolean LOCAL_LOGV = false;
|
||||
private static final String TAG = "AboutPhoneSettingsTest";
|
||||
private static final int TIMEOUT = 2000;
|
||||
private static final String SETTINGS_PACKAGE = "com.android.settings";
|
||||
|
||||
private UiDevice mDevice;
|
||||
|
||||
// TODO: retrieve using name/ids from com.android.settings package
|
||||
private static final String[] sResourceTexts = {
|
||||
"Status",
|
||||
"Legal information",
|
||||
"Regulatory labels",
|
||||
"Model",
|
||||
"Android version",
|
||||
"Android security patch level",
|
||||
"Baseband version",
|
||||
"Kernel version",
|
||||
"Build number"
|
||||
};
|
||||
|
||||
private static final String[] sClickableResourceTexts = {
|
||||
"Status", "Legal information", "Regulatory labels",
|
||||
};
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
if (LOCAL_LOGV) {
|
||||
Log.d(TAG, "-------");
|
||||
}
|
||||
super.setUp();
|
||||
mDevice = UiDevice.getInstance(getInstrumentation());
|
||||
try {
|
||||
mDevice.setOrientationNatural();
|
||||
} catch (RemoteException e) {
|
||||
throw new RuntimeException("Failed to freeze device orientaion", e);
|
||||
}
|
||||
|
||||
// make sure we are in a clean state before starting the test
|
||||
mDevice.pressHome();
|
||||
Thread.sleep(TIMEOUT * 2);
|
||||
launchAboutPhoneSettings(Settings.ACTION_DEVICE_INFO_SETTINGS);
|
||||
// TODO: make sure we are always at the top of the app
|
||||
// currently this will fail if the user has navigated into submenus
|
||||
UiObject2 view =
|
||||
mDevice.wait(
|
||||
Until.findObject(By.res(SETTINGS_PACKAGE + ":id/main_content")), TIMEOUT);
|
||||
assertNotNull("Could not find main About Phone screen", view);
|
||||
view.scroll(Direction.UP, 1.0f);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
// Adding an extra pressBack so we exit About Phone Settings
|
||||
// and finish the test cleanly
|
||||
mDevice.pressBack();
|
||||
mDevice.pressHome(); // finish settings activity
|
||||
mDevice.waitForIdle(TIMEOUT * 2); // give UI time to finish animating
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
private void launchAboutPhoneSettings(String aboutSetting) throws Exception {
|
||||
Intent aboutIntent = new Intent(aboutSetting);
|
||||
aboutIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
getInstrumentation().getContext().startActivity(aboutIntent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callable actions that can be taken when a UIObject2 is found
|
||||
*
|
||||
* @param device The current UiDevice
|
||||
* @param item The UiObject2 that was found and can be acted on
|
||||
*
|
||||
* @return {@code true} if the call was successful, and {@code false} otherwise
|
||||
*/
|
||||
public interface UIObject2Callback {
|
||||
boolean call(UiDevice device, UiObject2 item) throws Exception;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clicks the given item and then presses the Back button
|
||||
*
|
||||
* <p>Used to test whether a given UiObject2 can be successfully clicked.
|
||||
* Presses Back to restore state to the previous screen.
|
||||
*
|
||||
* @param device The device that can be used to press Back
|
||||
* @param item The item to click
|
||||
*
|
||||
* @return {@code true} if clicking the item succeeded, and {@code false} otherwise
|
||||
*/
|
||||
public class UiObject2Clicker implements UIObject2Callback {
|
||||
public boolean call(UiDevice device, UiObject2 item) throws Exception {
|
||||
item.click();
|
||||
Thread.sleep(TIMEOUT * 2); // give UI time to finish animating
|
||||
boolean pressWorked = device.pressBack();
|
||||
Thread.sleep(TIMEOUT * 2);
|
||||
return pressWorked;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes items found in the view and optionally takes some action.
|
||||
*
|
||||
* @param device The current UiDevice
|
||||
* @param itemsLeftToFind The items to search for in the current view
|
||||
* @param action Action to call on each item that is found; pass {@code null} to take no action
|
||||
*/
|
||||
private void removeItemsAndTakeAction(
|
||||
UiDevice device, ArrayList<String> itemsLeftToFind, UIObject2Callback action) throws Exception {
|
||||
for (Iterator<String> iterator = itemsLeftToFind.iterator(); iterator.hasNext(); ) {
|
||||
String itemText = iterator.next();
|
||||
UiObject2 item = device.wait(Until.findObject(By.text(itemText)), TIMEOUT);
|
||||
if (item != null) {
|
||||
if (LOCAL_LOGV) {
|
||||
Log.d(TAG, itemText + " is present");
|
||||
}
|
||||
iterator.remove();
|
||||
if (action != null) {
|
||||
boolean success = action.call(device, item);
|
||||
assertTrue("Calling action after " + itemText + " did not work", success);
|
||||
}
|
||||
} else {
|
||||
if (LOCAL_LOGV) {
|
||||
Log.d(TAG, "Could not find " + itemText);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches for UI elements in the current view and optionally takes some action.
|
||||
*
|
||||
* <p>Will scroll down the screen until it has found all elements or reached the bottom.
|
||||
* This allows elements to be found and acted on even if they change order.
|
||||
*
|
||||
* @param device The current UiDevice
|
||||
* @param itemsToFind The items to search for in the current view
|
||||
* @param action Action to call on each item that is found; pass {@code null} to take no action
|
||||
*/
|
||||
public void searchForItemsAndTakeAction(UiDevice device, String[] itemsToFind, UIObject2Callback action)
|
||||
throws Exception {
|
||||
|
||||
ArrayList<String> itemsLeftToFind = new ArrayList<String>(Arrays.asList(itemsToFind));
|
||||
assertFalse(
|
||||
"There must be at least one item to search for on the screen!",
|
||||
itemsLeftToFind.isEmpty());
|
||||
|
||||
if (LOCAL_LOGV) {
|
||||
Log.d(TAG, "items: " + TextUtils.join(", ", itemsLeftToFind));
|
||||
}
|
||||
boolean canScrollDown = true;
|
||||
while (canScrollDown && !itemsLeftToFind.isEmpty()) {
|
||||
removeItemsAndTakeAction(device, itemsLeftToFind, action);
|
||||
|
||||
// when we've finished searching the current view, scroll down
|
||||
UiObject2 view =
|
||||
device.wait(
|
||||
Until.findObject(By.res(SETTINGS_PACKAGE + ":id/main_content")),
|
||||
TIMEOUT * 2);
|
||||
if (view != null) {
|
||||
canScrollDown = view.scroll(Direction.DOWN, 1.0f);
|
||||
} else {
|
||||
canScrollDown = false;
|
||||
}
|
||||
}
|
||||
// check the last items once we have reached the bottom of the view
|
||||
removeItemsAndTakeAction(device, itemsLeftToFind, action);
|
||||
|
||||
assertTrue(
|
||||
"The following items were not found on the screen: "
|
||||
+ TextUtils.join(", ", itemsLeftToFind),
|
||||
itemsLeftToFind.isEmpty());
|
||||
}
|
||||
|
||||
@MediumTest // UI interaction
|
||||
public void testAllMenuEntriesExist() throws Exception {
|
||||
searchForItemsAndTakeAction(mDevice, sResourceTexts, null);
|
||||
}
|
||||
|
||||
// Suppressing this test as it might be causing other test failures
|
||||
// Will verify that this test is the cause before proceeding with solution
|
||||
@Suppress
|
||||
@MediumTest // UI interaction
|
||||
public void testClickableEntriesCanBeClicked() throws Exception {
|
||||
searchForItemsAndTakeAction(mDevice, sClickableResourceTexts, new UiObject2Clicker());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,279 @@
|
||||
/*
|
||||
* 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.ui;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.os.RemoteException;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
import android.provider.Settings;
|
||||
import android.support.test.metricshelper.MetricsAsserts;
|
||||
import android.support.test.uiautomator.By;
|
||||
import android.support.test.uiautomator.Direction;
|
||||
import android.support.test.uiautomator.UiDevice;
|
||||
import android.support.test.uiautomator.UiObject2;
|
||||
import android.support.test.uiautomator.Until;
|
||||
import android.system.helpers.SettingsHelper;
|
||||
import android.test.InstrumentationTestCase;
|
||||
import android.test.suitebuilder.annotation.MediumTest;
|
||||
import android.test.suitebuilder.annotation.Suppress;
|
||||
|
||||
import android.metrics.MetricsReader;
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
|
||||
public class AccessibilitySettingsTests extends InstrumentationTestCase {
|
||||
|
||||
private static final String SETTINGS_PACKAGE = "com.android.settings";
|
||||
private static final int TIMEOUT = 2000;
|
||||
private UiDevice mDevice;
|
||||
private MetricsReader mMetricsReader;
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
mDevice = UiDevice.getInstance(getInstrumentation());
|
||||
try {
|
||||
mDevice.setOrientationNatural();
|
||||
} catch (RemoteException e) {
|
||||
throw new RuntimeException("failed to freeze device orientaion", e);
|
||||
}
|
||||
mMetricsReader = new MetricsReader();
|
||||
// Clear out old logs
|
||||
mMetricsReader.checkpoint();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
// Need to finish settings activity
|
||||
mDevice.pressBack();
|
||||
mDevice.pressHome();
|
||||
mDevice.waitForIdle();
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
@Presubmit
|
||||
@MediumTest
|
||||
public void testHighContrastTextOn() throws Exception {
|
||||
verifyAccessibilitySettingOnOrOff("High contrast text",
|
||||
Settings.Secure.ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED, 0, 1);
|
||||
}
|
||||
|
||||
@Presubmit
|
||||
@MediumTest
|
||||
public void testHighContrastTextOff() throws Exception {
|
||||
verifyAccessibilitySettingOnOrOff("High contrast text",
|
||||
Settings.Secure.ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED, 1, 0);
|
||||
}
|
||||
|
||||
@Presubmit
|
||||
@MediumTest
|
||||
public void testPowerButtonEndsCallOn() throws Exception {
|
||||
verifyAccessibilitySettingOnOrOff("Power button ends call",
|
||||
Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR, 1, 2);
|
||||
}
|
||||
|
||||
@Presubmit
|
||||
@MediumTest
|
||||
public void testPowerButtonEndsCallOff() throws Exception {
|
||||
verifyAccessibilitySettingOnOrOff("Power button ends call",
|
||||
Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR, 2, 1);
|
||||
}
|
||||
|
||||
/* Suppressing these four tests. The settings don't play
|
||||
* nice with Settings.System.putInt or Settings.Secure.putInt.
|
||||
* Need further clarification. Filed bug b/27792029
|
||||
*/
|
||||
@Suppress
|
||||
@MediumTest
|
||||
public void testAutoRotateScreenOn() throws Exception {
|
||||
verifyAccessibilitySettingOnOrOff("Auto-rotate screen",
|
||||
Settings.System.ACCELEROMETER_ROTATION, 0, 1);
|
||||
}
|
||||
|
||||
@Suppress
|
||||
@MediumTest
|
||||
public void testAutoRotateScreenOff() throws Exception {
|
||||
verifyAccessibilitySettingOnOrOff("Auto-rotate screen",
|
||||
Settings.System.ACCELEROMETER_ROTATION, 1, 0);
|
||||
}
|
||||
|
||||
@Suppress
|
||||
@MediumTest
|
||||
public void testMonoAudioOn() throws Exception {
|
||||
verifyAccessibilitySettingOnOrOff("Mono audio",
|
||||
Settings.System.MASTER_MONO, 0, 1);
|
||||
}
|
||||
|
||||
@Suppress
|
||||
@MediumTest
|
||||
public void testMonoAudioOff() throws Exception {
|
||||
verifyAccessibilitySettingOnOrOff("Mono audio",
|
||||
Settings.System.MASTER_MONO, 1, 0);
|
||||
}
|
||||
|
||||
@Presubmit
|
||||
@MediumTest
|
||||
public void testLargeMousePointerOn() throws Exception {
|
||||
verifyAccessibilitySettingOnOrOff("Large mouse pointer",
|
||||
Settings.Secure.ACCESSIBILITY_LARGE_POINTER_ICON, 0, 1);
|
||||
}
|
||||
|
||||
@Presubmit
|
||||
@MediumTest
|
||||
public void testLargeMousePointerOff() throws Exception {
|
||||
verifyAccessibilitySettingOnOrOff("Large mouse pointer",
|
||||
Settings.Secure.ACCESSIBILITY_LARGE_POINTER_ICON, 1, 0);
|
||||
}
|
||||
|
||||
@Presubmit
|
||||
@MediumTest
|
||||
public void testColorCorrection() throws Exception {
|
||||
verifySettingToggleAfterScreenLoad("Color correction",
|
||||
Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED);
|
||||
MetricsAsserts.assertHasVisibilityLog("Missing color correction log",
|
||||
mMetricsReader, MetricsEvent.ACCESSIBILITY_TOGGLE_DALTONIZER, true);
|
||||
}
|
||||
|
||||
// Suppressing this test, since UiAutomator + talkback don't play nice
|
||||
@Suppress
|
||||
@MediumTest
|
||||
public void testTalkback() throws Exception {
|
||||
verifySettingToggleAfterScreenLoad("TalkBack",
|
||||
Settings.Secure.ACCESSIBILITY_ENABLED);
|
||||
}
|
||||
|
||||
@Presubmit
|
||||
@MediumTest
|
||||
public void testCaptions() throws Exception {
|
||||
verifySettingToggleAfterScreenLoad("Captions",
|
||||
Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED);
|
||||
MetricsAsserts.assertHasVisibilityLog("Missing captions log",
|
||||
mMetricsReader, MetricsEvent.ACCESSIBILITY_CAPTION_PROPERTIES, true);
|
||||
}
|
||||
|
||||
@Presubmit
|
||||
@MediumTest
|
||||
public void testMagnificationGesture() throws Exception {
|
||||
verifySettingToggleAfterScreenLoad("Magnification", "Magnify with triple-tap",
|
||||
Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED);
|
||||
MetricsAsserts.assertHasVisibilityLog("Missing magnification log",
|
||||
mMetricsReader, MetricsEvent.ACCESSIBILITY_TOGGLE_SCREEN_MAGNIFICATION, true);
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testClickAfterPointerStopsMoving() throws Exception {
|
||||
verifySettingToggleAfterScreenLoad("Click after pointer stops moving",
|
||||
Settings.Secure.ACCESSIBILITY_AUTOCLICK_ENABLED);
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testAccessibilitySettingsLoadLog() throws Exception {
|
||||
launchAccessibilitySettings();
|
||||
MetricsAsserts.assertHasVisibilityLog("Missing accessibility settings load log",
|
||||
mMetricsReader, MetricsEvent.ACCESSIBILITY, true);
|
||||
}
|
||||
|
||||
public void launchAccessibilitySettings() throws Exception {
|
||||
SettingsHelper.launchSettingsPage(getInstrumentation().getContext(),
|
||||
Settings.ACTION_ACCESSIBILITY_SETTINGS);
|
||||
}
|
||||
|
||||
private void verifyAccessibilitySettingOnOrOff(String settingText,
|
||||
String settingFlag, int initialFlagValue, int expectedFlagValue)
|
||||
throws Exception {
|
||||
Settings.Secure.putInt(getInstrumentation().getContext().getContentResolver(),
|
||||
settingFlag, initialFlagValue);
|
||||
launchAccessibilitySettings();
|
||||
UiObject2 settingsTitle = findItemOnScreen(settingText);
|
||||
settingsTitle.click();
|
||||
Thread.sleep(TIMEOUT);
|
||||
int settingValue = Settings.Secure
|
||||
.getInt(getInstrumentation().getContext().getContentResolver(), settingFlag);
|
||||
assertEquals(settingText + " not correctly set after toggle",
|
||||
expectedFlagValue, settingValue);
|
||||
}
|
||||
|
||||
private void verifySettingToggleAfterScreenLoad(String settingText, String settingFlag)
|
||||
throws Exception {
|
||||
verifySettingToggleAfterScreenLoad(settingText, null, settingFlag);
|
||||
}
|
||||
|
||||
private void verifySettingToggleAfterScreenLoad
|
||||
(String settingText, String subSetting, String settingFlag) throws Exception {
|
||||
// Load accessibility settings
|
||||
launchAccessibilitySettings();
|
||||
Settings.Secure.putInt(getInstrumentation().getContext().getContentResolver(),
|
||||
settingFlag, 0);
|
||||
Thread.sleep(TIMEOUT);
|
||||
// Tap on setting required
|
||||
UiObject2 settingTitle = findItemOnScreen(settingText);
|
||||
// Load screen
|
||||
settingTitle.click();
|
||||
Thread.sleep(TIMEOUT);
|
||||
if (subSetting != null) {
|
||||
UiObject2 subSettingObject = findItemOnScreen(subSetting);
|
||||
subSettingObject.click();
|
||||
Thread.sleep(TIMEOUT);
|
||||
}
|
||||
// Toggle value
|
||||
UiObject2 settingToggle = mDevice.wait(Until.findObject(By.text("Off")),
|
||||
TIMEOUT);
|
||||
settingToggle.click();
|
||||
dismissOpenDialog();
|
||||
Thread.sleep(TIMEOUT);
|
||||
// Assert new value
|
||||
int settingValue = Settings.Secure.
|
||||
getInt(getInstrumentation().getContext().getContentResolver(), settingFlag);
|
||||
assertEquals(settingText + " value not set correctly", 1, settingValue);
|
||||
// Toogle value
|
||||
settingToggle.click();
|
||||
dismissOpenDialog();
|
||||
mDevice.pressBack();
|
||||
Thread.sleep(TIMEOUT);
|
||||
// Assert reset to old value
|
||||
settingValue = Settings.Secure.
|
||||
getInt(getInstrumentation().getContext().getContentResolver(), settingFlag);
|
||||
assertEquals(settingText + " value not set correctly", 0, settingValue);
|
||||
}
|
||||
|
||||
private UiObject2 findItemOnScreen(String item) throws Exception {
|
||||
int count = 0;
|
||||
UiObject2 settingsPanel = mDevice.wait(Until.findObject
|
||||
(By.res(SETTINGS_PACKAGE, "list")), TIMEOUT);
|
||||
while (settingsPanel.fling(Direction.UP) && count < 3) {
|
||||
count++;
|
||||
}
|
||||
count = 0;
|
||||
UiObject2 setting = null;
|
||||
while(count < 3 && setting == null) {
|
||||
setting = mDevice.wait(Until.findObject(By.text(item)), TIMEOUT);
|
||||
if (setting == null) {
|
||||
settingsPanel.scroll(Direction.DOWN, 1.0f);
|
||||
}
|
||||
count++;
|
||||
}
|
||||
return setting;
|
||||
}
|
||||
|
||||
private void dismissOpenDialog() throws Exception {
|
||||
UiObject2 okButton = mDevice.wait(Until.findObject
|
||||
(By.res("android:id/button1")), TIMEOUT*2);
|
||||
if (okButton != null) {
|
||||
okButton.click();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* 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.ui;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.RemoteException;
|
||||
import android.provider.Settings;
|
||||
import android.support.test.uiautomator.By;
|
||||
import android.support.test.uiautomator.Direction;
|
||||
import android.support.test.uiautomator.UiDevice;
|
||||
import android.support.test.uiautomator.UiObject2;
|
||||
import android.support.test.uiautomator.Until;
|
||||
import android.system.helpers.ActivityHelper;
|
||||
import android.test.InstrumentationTestCase;
|
||||
import android.test.suitebuilder.annotation.MediumTest;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
|
||||
/** Verifies basic functionality of the About Phone screen */
|
||||
public class AppsSettingsTests extends InstrumentationTestCase {
|
||||
private static final boolean LOCAL_LOGV = false;
|
||||
private static final String SETTINGS_PACKAGE = "com.android.settings";
|
||||
private static final String TAG = "AboutPhoneSettingsTest";
|
||||
private static final int TIMEOUT = 2000;
|
||||
private ActivityHelper mActivityHelper = null;
|
||||
|
||||
private UiDevice mDevice;
|
||||
|
||||
private static final String[] sResourceTexts = {
|
||||
"Storage",
|
||||
"Data usage",
|
||||
"Permissions",
|
||||
"App notifications",
|
||||
"Open by default",
|
||||
"Battery",
|
||||
"Memory"
|
||||
};
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
if (LOCAL_LOGV) {
|
||||
Log.d(TAG, "-------");
|
||||
}
|
||||
super.setUp();
|
||||
mDevice = UiDevice.getInstance(getInstrumentation());
|
||||
mActivityHelper = ActivityHelper.getInstance();
|
||||
try {
|
||||
mDevice.setOrientationNatural();
|
||||
} catch (RemoteException e) {
|
||||
throw new RuntimeException("Failed to freeze device orientaion", e);
|
||||
}
|
||||
|
||||
// make sure we are in a clean state before starting the test
|
||||
mDevice.pressHome();
|
||||
Thread.sleep(TIMEOUT * 2);
|
||||
launchAppsSettings();
|
||||
UiObject2 view =
|
||||
mDevice.wait(
|
||||
Until.findObject(By.text("All apps")), TIMEOUT);
|
||||
assertNotNull("Could not find Settings > Apps screen", view);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
mDevice.pressBack();
|
||||
mDevice.pressHome(); // finish settings activity
|
||||
mDevice.waitForIdle(TIMEOUT * 2); // give UI time to finish animating
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testAppSettingsListForCalculator() {
|
||||
UiObject2 calculator = mDevice.wait(
|
||||
Until.findObject(By.text("Calculator")), TIMEOUT);
|
||||
calculator.click();
|
||||
for (String setting : sResourceTexts) {
|
||||
UiObject2 appSetting =
|
||||
mDevice.wait(
|
||||
Until.findObject(By.text(setting)), TIMEOUT);
|
||||
assertNotNull("Missing setting for Calculator: " + setting, appSetting);
|
||||
appSetting.scroll(Direction.DOWN, 10.0f);
|
||||
}
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testDisablingAndEnablingSystemApp() throws Exception {
|
||||
launchAppsSettings();
|
||||
UiObject2 calculator = mDevice.wait(
|
||||
Until.findObject(By.text("Calculator")), TIMEOUT);
|
||||
calculator.click();
|
||||
mDevice.waitForIdle(TIMEOUT);
|
||||
UiObject2 appInfoList = mDevice.wait(
|
||||
Until.findObject(By.res(SETTINGS_PACKAGE, "list")), TIMEOUT);
|
||||
appInfoList.scroll(Direction.DOWN, 100.0f);
|
||||
UiObject2 disableButton = mDevice.wait(
|
||||
Until.findObject(By.text("DISABLE")), TIMEOUT);
|
||||
disableButton.click();
|
||||
mDevice.waitForIdle(TIMEOUT);
|
||||
// Click on "Disable App" on dialog.
|
||||
mDevice.wait(
|
||||
Until.findObject(By.text("DISABLE APP")), TIMEOUT).click();
|
||||
mDevice.waitForIdle(TIMEOUT);
|
||||
UiObject2 enableButton = mDevice.wait(
|
||||
Until.findObject(By.text("ENABLE")), TIMEOUT);
|
||||
assertNotNull("App not disabled successfully", enableButton);
|
||||
enableButton.click();
|
||||
mDevice.waitForIdle(TIMEOUT);
|
||||
disableButton = mDevice.wait(
|
||||
Until.findObject(By.text("DISABLE")), TIMEOUT);
|
||||
assertNotNull("App not enabled successfully", disableButton);
|
||||
}
|
||||
|
||||
private void launchAppsSettings() throws Exception {
|
||||
Intent appsSettingsIntent = new
|
||||
Intent(Settings.ACTION_MANAGE_APPLICATIONS_SETTINGS);
|
||||
mActivityHelper.launchIntent(appsSettingsIntent);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* 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.ui;
|
||||
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.metrics.MetricsReader;
|
||||
import android.os.RemoteException;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
import android.provider.Settings;
|
||||
import android.support.test.metricshelper.MetricsAsserts;
|
||||
import android.support.test.uiautomator.By;
|
||||
import android.support.test.uiautomator.BySelector;
|
||||
import android.support.test.uiautomator.UiDevice;
|
||||
import android.support.test.uiautomator.UiObject2;
|
||||
import android.support.test.uiautomator.Until;
|
||||
import android.test.InstrumentationTestCase;
|
||||
import android.test.suitebuilder.annotation.MediumTest;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
|
||||
public class BluetoothNetworkSettingsTests extends InstrumentationTestCase {
|
||||
|
||||
private static final String SETTINGS_PACKAGE = "com.android.settings";
|
||||
private static final int TIMEOUT = 2000;
|
||||
private static final int LONG_TIMEOUT = 40000;
|
||||
private UiDevice mDevice;
|
||||
private MetricsReader mMetricsReader;
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
mDevice = UiDevice.getInstance(getInstrumentation());
|
||||
try {
|
||||
mDevice.setOrientationNatural();
|
||||
} catch (RemoteException e) {
|
||||
throw new RuntimeException("failed to freeze device orientaion", e);
|
||||
}
|
||||
mMetricsReader = new MetricsReader();
|
||||
// Clear out old logs
|
||||
mMetricsReader.checkpoint();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
mDevice.pressBack();
|
||||
mDevice.pressHome();
|
||||
mDevice.waitForIdle();
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
@Presubmit
|
||||
@MediumTest
|
||||
public void testBluetoothEnabled() throws Exception {
|
||||
verifyBluetoothOnOrOff(true);
|
||||
MetricsAsserts.assertHasActionLog("missing bluetooth toggle log",
|
||||
mMetricsReader, MetricsEvent.ACTION_BLUETOOTH_TOGGLE);
|
||||
}
|
||||
|
||||
@Presubmit
|
||||
@MediumTest
|
||||
public void testBluetoothDisabled() throws Exception {
|
||||
verifyBluetoothOnOrOff(false);
|
||||
MetricsAsserts.assertHasActionLog("missing bluetooth toggle log",
|
||||
mMetricsReader, MetricsEvent.ACTION_BLUETOOTH_TOGGLE);
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testRenameOption() throws Exception {
|
||||
launchBluetoothSettings();
|
||||
verifyUiObjectClicked(By.text("Device name"), "Rename preference");
|
||||
verifyUiObjectClicked(By.text("CANCEL"), "CANCEL button");
|
||||
|
||||
MetricsAsserts.assertHasActionLog("missing bluetooth rename device log",
|
||||
mMetricsReader, MetricsEvent.ACTION_BLUETOOTH_RENAME);
|
||||
MetricsAsserts.assertHasVisibilityLog("missing bluetooth rename dialog log",
|
||||
mMetricsReader, MetricsEvent.DIALOG_BLUETOOTH_RENAME, true);
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testReceivedFilesOption() throws Exception {
|
||||
launchBluetoothSettings();
|
||||
verifyUiObjectClicked(By.text("Received files"), "Received files preference");
|
||||
|
||||
MetricsAsserts.assertHasActionLog("missing bluetooth received files log",
|
||||
mMetricsReader, MetricsEvent.ACTION_BLUETOOTH_FILES);
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testHelpFeedbackOverflowOption() throws Exception {
|
||||
launchBluetoothSettings();
|
||||
|
||||
// Verify help & feedback
|
||||
assertNotNull("Help & feedback item not found under Bluetooth Settings",
|
||||
mDevice.wait(Until.findObject(By.desc("Help & feedback")), TIMEOUT));
|
||||
}
|
||||
|
||||
public void launchBluetoothSettings() throws Exception {
|
||||
Intent btIntent = new Intent(Settings.ACTION_BLUETOOTH_SETTINGS);
|
||||
btIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
getInstrumentation().getContext().startActivity(btIntent);
|
||||
Thread.sleep(TIMEOUT * 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the {@link UiObject2} by {@code itemSelector} and try to click it if possible.
|
||||
*
|
||||
* If not find, throw assertion error
|
||||
* @param itemSelector used to find the {@link UiObject2}
|
||||
* @param text the description of the {@link UiObject2}
|
||||
*/
|
||||
private void verifyUiObjectClicked(BySelector itemSelector, String text) throws Exception {
|
||||
UiObject2 uiObject2 = mDevice.wait(Until.findObject(itemSelector), TIMEOUT);
|
||||
assertNotNull(text + "is not present in bluetooth settings page", uiObject2);
|
||||
uiObject2.click();
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles the Bluetooth switch and verifies that the change is reflected in Settings
|
||||
*
|
||||
* @param verifyOn set to whether you want the setting turned On or Off
|
||||
*/
|
||||
private void verifyBluetoothOnOrOff(boolean verifyOn) throws Exception {
|
||||
String switchText = "ON";
|
||||
BluetoothAdapter bluetoothAdapter = ((BluetoothManager) getInstrumentation().getContext()
|
||||
.getSystemService(Context.BLUETOOTH_SERVICE)).getAdapter();
|
||||
if (verifyOn) {
|
||||
switchText = "OFF";
|
||||
bluetoothAdapter.disable();
|
||||
} else {
|
||||
bluetoothAdapter.enable();
|
||||
}
|
||||
launchBluetoothSettings();
|
||||
mDevice.wait(Until
|
||||
.findObject(By.res(SETTINGS_PACKAGE, "switch_widget").text(switchText)), TIMEOUT)
|
||||
.click();
|
||||
Thread.sleep(TIMEOUT);
|
||||
String bluetoothValue =
|
||||
Settings.Global.getString(getInstrumentation().getContext().getContentResolver(),
|
||||
Settings.Global.BLUETOOTH_ON);
|
||||
if (verifyOn) {
|
||||
assertEquals("1", bluetoothValue);
|
||||
} else {
|
||||
assertEquals("0", bluetoothValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* 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.ui;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.nfc.NfcAdapter;
|
||||
import android.nfc.NfcManager;
|
||||
import android.os.RemoteException;
|
||||
import android.support.test.InstrumentationRegistry;
|
||||
import android.support.test.filters.MediumTest;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
import android.support.test.uiautomator.By;
|
||||
import android.support.test.uiautomator.UiDevice;
|
||||
import android.support.test.uiautomator.UiObject2;
|
||||
import android.support.test.uiautomator.Until;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
@MediumTest
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class ConnectedDeviceTests {
|
||||
|
||||
private static final String SETTINGS_PACKAGE = "com.android.settings";
|
||||
private static final int TIMEOUT = 2000;
|
||||
private UiDevice mDevice;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
|
||||
try {
|
||||
mDevice.setOrientationNatural();
|
||||
} catch (RemoteException e) {
|
||||
throw new RuntimeException("failed to freeze device orientation", e);
|
||||
}
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
mDevice.pressBack();
|
||||
mDevice.pressHome();
|
||||
}
|
||||
|
||||
// This NFC toggle test is set up this way since there's no way to set
|
||||
// the NFC flag to enabled or disabled without touching UI.
|
||||
// This way, we get coverage for whether or not the toggle button works.
|
||||
@Test
|
||||
public void testNFCToggle() throws Exception {
|
||||
NfcManager manager = (NfcManager) InstrumentationRegistry.getTargetContext()
|
||||
.getSystemService(Context.NFC_SERVICE);
|
||||
NfcAdapter nfcAdapter = manager.getDefaultAdapter();
|
||||
boolean nfcInitiallyEnabled = nfcAdapter.isEnabled();
|
||||
InstrumentationRegistry.getContext().startActivity(new Intent()
|
||||
.setClassName(
|
||||
SETTINGS_PACKAGE,
|
||||
"com.android.settings.Settings$ConnectedDeviceDashboardActivity"));
|
||||
UiObject2 nfcSetting = mDevice.wait(Until.findObject(By.text("NFC")), TIMEOUT);
|
||||
nfcSetting.click();
|
||||
Thread.sleep(TIMEOUT * 2);
|
||||
if (nfcInitiallyEnabled) {
|
||||
assertFalse("NFC wasn't disabled on toggle", nfcAdapter.isEnabled());
|
||||
nfcSetting.click();
|
||||
Thread.sleep(TIMEOUT * 2);
|
||||
assertTrue("NFC wasn't enabled on toggle", nfcAdapter.isEnabled());
|
||||
} else {
|
||||
assertTrue("NFC wasn't enabled on toggle", nfcAdapter.isEnabled());
|
||||
nfcSetting.click();
|
||||
Thread.sleep(TIMEOUT * 2);
|
||||
assertFalse("NFC wasn't disabled on toggle", nfcAdapter.isEnabled());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* 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.ui;
|
||||
|
||||
import android.os.RemoteException;
|
||||
import android.provider.Settings;
|
||||
import android.support.test.uiautomator.By;
|
||||
import android.support.test.uiautomator.UiDevice;
|
||||
import android.support.test.uiautomator.Until;
|
||||
import android.system.helpers.SettingsHelper;
|
||||
import android.test.InstrumentationTestCase;
|
||||
import android.test.suitebuilder.annotation.MediumTest;
|
||||
import android.test.suitebuilder.annotation.Suppress;
|
||||
|
||||
public class DataUsageSettingsTests extends InstrumentationTestCase {
|
||||
|
||||
private static final String SETTINGS_PACKAGE = "com.android.settings";
|
||||
private static final int TIMEOUT = 2000;
|
||||
private UiDevice mDevice;
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
mDevice = UiDevice.getInstance(getInstrumentation());
|
||||
try {
|
||||
mDevice.setOrientationNatural();
|
||||
} catch (RemoteException e) {
|
||||
throw new RuntimeException("failed to freeze device orientaion", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
// Need to finish settings activity
|
||||
mDevice.pressBack();
|
||||
mDevice.pressHome();
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testElementsOnDataUsageScreen() throws Exception {
|
||||
launchDataUsageSettings();
|
||||
assertNotNull("Data usage element not found",
|
||||
mDevice.wait(Until.findObject(By.text("Usage")),
|
||||
TIMEOUT));
|
||||
assertNotNull("Data usage bar not found",
|
||||
mDevice.wait(Until.findObject(By.res(SETTINGS_PACKAGE,
|
||||
"color_bar")), TIMEOUT));
|
||||
assertNotNull("WiFi Data usage element not found",
|
||||
mDevice.wait(Until.findObject(By.text("Wi-Fi data usage")),
|
||||
TIMEOUT));
|
||||
assertNotNull("Network restrictions element not found",
|
||||
mDevice.wait(Until.findObject(By.text("Network restrictions")),
|
||||
TIMEOUT));
|
||||
}
|
||||
|
||||
public void launchDataUsageSettings() throws Exception {
|
||||
SettingsHelper.launchSettingsPage(getInstrumentation().getContext(),
|
||||
Settings.ACTION_SETTINGS);
|
||||
mDevice.wait(Until
|
||||
.findObject(By.text("Network & Internet")), TIMEOUT)
|
||||
.click();
|
||||
Thread.sleep(TIMEOUT * 2);
|
||||
assertNotNull("Network & internet screen not loaded", mDevice.wait(
|
||||
Until.findObject(By.text("Data usage")), TIMEOUT));
|
||||
mDevice.wait(Until
|
||||
.findObject(By.text("Data usage")), TIMEOUT)
|
||||
.click();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,268 @@
|
||||
/*
|
||||
* 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.ui;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
import android.provider.Settings;
|
||||
import android.support.test.uiautomator.By;
|
||||
import android.support.test.uiautomator.UiDevice;
|
||||
import android.support.test.uiautomator.UiObject2;
|
||||
import android.support.test.uiautomator.Until;
|
||||
import android.system.helpers.SettingsHelper;
|
||||
import android.system.helpers.SettingsHelper.SettingsType;
|
||||
import android.test.InstrumentationTestCase;
|
||||
import android.test.suitebuilder.annotation.MediumTest;
|
||||
import android.test.suitebuilder.annotation.Suppress;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class DisplaySettingsTest extends InstrumentationTestCase {
|
||||
|
||||
private static final String PAGE = Settings.ACTION_DISPLAY_SETTINGS;
|
||||
private static final int TIMEOUT = 2000;
|
||||
private static final FontSetting FONT_SMALL = new FontSetting("Small", 0.85f);
|
||||
private static final FontSetting FONT_NORMAL = new FontSetting("Default", 1.00f);
|
||||
private static final FontSetting FONT_LARGE = new FontSetting("Large", 1.15f);
|
||||
private static final FontSetting FONT_HUGE = new FontSetting("Largest", 1.30f);
|
||||
|
||||
private UiDevice mDevice;
|
||||
private ContentResolver mResolver;
|
||||
private SettingsHelper mHelper;
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
mDevice = UiDevice.getInstance(getInstrumentation());
|
||||
mDevice.setOrientationNatural();
|
||||
mResolver = getInstrumentation().getContext().getContentResolver();
|
||||
mHelper = new SettingsHelper();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tearDown() throws Exception {
|
||||
// reset settings we touched that may impact others
|
||||
Settings.System.putFloat(mResolver, Settings.System.FONT_SCALE, 1.00f);
|
||||
mDevice.waitForIdle();
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
@Presubmit
|
||||
@MediumTest
|
||||
public void testAdaptiveBrightness() throws Exception {
|
||||
SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE);
|
||||
mHelper.scrollVert(true);
|
||||
Thread.sleep(1000);
|
||||
|
||||
assertTrue(mHelper.verifyToggleSetting(SettingsType.SYSTEM, PAGE, "Adaptive brightness",
|
||||
Settings.System.SCREEN_BRIGHTNESS_MODE));
|
||||
assertTrue(mHelper.verifyToggleSetting(SettingsType.SYSTEM, PAGE, "Adaptive brightness",
|
||||
Settings.System.SCREEN_BRIGHTNESS_MODE));
|
||||
}
|
||||
|
||||
|
||||
// blocked on b/27487224
|
||||
@MediumTest
|
||||
@Suppress
|
||||
public void testDaydreamToggle() throws Exception {
|
||||
SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE);
|
||||
clickMore();
|
||||
Pattern p = Pattern.compile("On|Off");
|
||||
mHelper.clickSetting("Screen saver");
|
||||
Thread.sleep(1000);
|
||||
try {
|
||||
assertTrue(mHelper.verifyToggleSetting(SettingsType.SECURE, PAGE, p,
|
||||
Settings.Secure.SCREENSAVER_ENABLED, false));
|
||||
assertTrue(mHelper.verifyToggleSetting(SettingsType.SECURE, PAGE, p,
|
||||
Settings.Secure.SCREENSAVER_ENABLED, false));
|
||||
} finally {
|
||||
mDevice.pressBack();
|
||||
}
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testAccelRotation() throws Exception {
|
||||
SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE);
|
||||
mHelper.scrollVert(true);
|
||||
clickMore();
|
||||
Thread.sleep(4000);
|
||||
int currentAccelSetting = Settings.System.getInt(
|
||||
mResolver, Settings.System.ACCELEROMETER_ROTATION);
|
||||
mHelper.clickSetting("Auto-rotate screen");
|
||||
int newAccelSetting = Settings.System.getInt(
|
||||
mResolver, Settings.System.ACCELEROMETER_ROTATION);
|
||||
assertTrue("Accelorometer setting unchanged after toggle", currentAccelSetting != newAccelSetting);
|
||||
mHelper.clickSetting("Auto-rotate screen");
|
||||
int revertedAccelSetting = Settings.System.getInt(
|
||||
mResolver, Settings.System.ACCELEROMETER_ROTATION);
|
||||
assertTrue("Accelorometer setting unchanged after toggle", revertedAccelSetting != newAccelSetting);
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testDaydream() throws Exception {
|
||||
Settings.Secure.putInt(mResolver, Settings.Secure.SCREENSAVER_ENABLED, 1);
|
||||
SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE);
|
||||
clickMore();
|
||||
mHelper.scrollVert(false);
|
||||
mDevice.wait(Until.findObject(By.text("Screen saver")), TIMEOUT).click();
|
||||
try {
|
||||
assertTrue(mHelper.verifyRadioSetting(SettingsType.SECURE, PAGE,
|
||||
"Current screen saver", "Clock", Settings.Secure.SCREENSAVER_COMPONENTS,
|
||||
"com.google.android.deskclock/com.android.deskclock.Screensaver"));
|
||||
assertTrue(mHelper.verifyRadioSetting(SettingsType.SECURE, PAGE,
|
||||
"Current screen saver", "Colors", Settings.Secure.SCREENSAVER_COMPONENTS,
|
||||
"com.android.dreams.basic/com.android.dreams.basic.Colors"));
|
||||
assertTrue(mHelper.verifyRadioSetting(SettingsType.SECURE, PAGE,
|
||||
"Current screen saver", "Photos", Settings.Secure.SCREENSAVER_COMPONENTS,
|
||||
"com.google.android.apps.photos/com.google.android.apps.photos.daydream"
|
||||
+ ".PhotosDreamService"));
|
||||
} finally {
|
||||
mDevice.pressBack();
|
||||
Thread.sleep(2000);
|
||||
}
|
||||
}
|
||||
|
||||
@Presubmit
|
||||
@MediumTest
|
||||
public void testSleep15Seconds() throws Exception {
|
||||
SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE);
|
||||
mHelper.scrollVert(true);
|
||||
assertTrue(mHelper.verifyRadioSetting(SettingsType.SYSTEM, PAGE,
|
||||
"Sleep", "15 seconds", Settings.System.SCREEN_OFF_TIMEOUT, "15000"));
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testSleep30Seconds() throws Exception {
|
||||
SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE);
|
||||
mHelper.scrollVert(true);
|
||||
assertTrue(mHelper.verifyRadioSetting(SettingsType.SYSTEM, PAGE,
|
||||
"Sleep", "30 seconds", Settings.System.SCREEN_OFF_TIMEOUT, "30000"));
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testSleep1Minute() throws Exception {
|
||||
SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE);
|
||||
mHelper.scrollVert(true);
|
||||
assertTrue(mHelper.verifyRadioSetting(SettingsType.SYSTEM, PAGE,
|
||||
"Sleep", "1 minute", Settings.System.SCREEN_OFF_TIMEOUT, "60000"));
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testSleep2Minutes() throws Exception {
|
||||
SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE);
|
||||
mHelper.scrollVert(true);
|
||||
assertTrue(mHelper.verifyRadioSetting(SettingsType.SYSTEM, PAGE,
|
||||
"Sleep", "2 minutes", Settings.System.SCREEN_OFF_TIMEOUT, "120000"));
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testSleep5Minutes() throws Exception {
|
||||
SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE);
|
||||
mHelper.scrollVert(true);
|
||||
assertTrue(mHelper.verifyRadioSetting(SettingsType.SYSTEM, PAGE,
|
||||
"Sleep", "5 minutes", Settings.System.SCREEN_OFF_TIMEOUT, "300000"));
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testSleep10Minutes() throws Exception {
|
||||
SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE);
|
||||
mHelper.scrollVert(true);
|
||||
assertTrue(mHelper.verifyRadioSetting(SettingsType.SYSTEM, PAGE,
|
||||
"Sleep", "10 minutes", Settings.System.SCREEN_OFF_TIMEOUT, "600000"));
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testSleep30Minutes() throws Exception {
|
||||
SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE);
|
||||
mHelper.scrollVert(true);
|
||||
assertTrue(mHelper.verifyRadioSetting(SettingsType.SYSTEM, PAGE,
|
||||
"Sleep", "30 minutes", Settings.System.SCREEN_OFF_TIMEOUT, "1800000"));
|
||||
}
|
||||
|
||||
@Presubmit
|
||||
@MediumTest
|
||||
public void testFontSizeLarge() throws Exception {
|
||||
verifyFontSizeSetting(1.00f, FONT_LARGE);
|
||||
// Leaving the font size at large can make later tests fail, so reset it
|
||||
Settings.System.putFloat(mResolver, Settings.System.FONT_SCALE, 1.00f);
|
||||
// It takes a second for the new font size to be picked up
|
||||
Thread.sleep(2000);
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testFontSizeDefault() throws Exception {
|
||||
verifyFontSizeSetting(1.15f, FONT_NORMAL);
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testFontSizeLargest() throws Exception {
|
||||
verifyFontSizeSetting(1.00f, FONT_HUGE);
|
||||
// Leaving the font size at huge can make later tests fail, so reset it
|
||||
Settings.System.putFloat(mResolver, Settings.System.FONT_SCALE, 1.00f);
|
||||
// It takes a second for the new font size to be picked up
|
||||
Thread.sleep(2000);
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testFontSizeSmall() throws Exception {
|
||||
verifyFontSizeSetting(1.00f, FONT_SMALL);
|
||||
}
|
||||
|
||||
private void verifyFontSizeSetting(float resetValue, FontSetting setting)
|
||||
throws Exception {
|
||||
Settings.System.putFloat(mResolver, Settings.System.FONT_SCALE, resetValue);
|
||||
SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE);
|
||||
clickMore();
|
||||
mHelper.clickSetting("Font size");
|
||||
try {
|
||||
mDevice.wait(Until.findObject(By.desc(setting.getName())), TIMEOUT).click();
|
||||
Thread.sleep(1000);
|
||||
float changedValue = Settings.System.getFloat(
|
||||
mResolver, Settings.System.FONT_SCALE);
|
||||
assertEquals(setting.getSize(), changedValue, 0.0001);
|
||||
} finally {
|
||||
// Make sure to back out of the font menu
|
||||
mDevice.pressBack();
|
||||
}
|
||||
}
|
||||
|
||||
private void clickMore() throws InterruptedException {
|
||||
UiObject2 more = mDevice.wait(Until.findObject(By.text("Advanced")), TIMEOUT);
|
||||
if (more != null) {
|
||||
more.click();
|
||||
Thread.sleep(TIMEOUT);
|
||||
}
|
||||
}
|
||||
|
||||
private static class FontSetting {
|
||||
private final String mSizeName;
|
||||
private final float mSizeVal;
|
||||
|
||||
public FontSetting(String sizeName, float sizeVal) {
|
||||
mSizeName = sizeName;
|
||||
mSizeVal = sizeVal;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return mSizeName;
|
||||
}
|
||||
|
||||
public float getSize() {
|
||||
return mSizeVal;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* 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.ui;
|
||||
|
||||
import android.os.RemoteException;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
import android.provider.Settings;
|
||||
import android.support.test.InstrumentationRegistry;
|
||||
import android.support.test.filters.MediumTest;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
import android.support.test.uiautomator.By;
|
||||
import android.support.test.uiautomator.Direction;
|
||||
import android.support.test.uiautomator.UiDevice;
|
||||
import android.support.test.uiautomator.UiObject2;
|
||||
import android.support.test.uiautomator.Until;
|
||||
import android.system.helpers.SettingsHelper;
|
||||
|
||||
import com.android.settings.functional.testutils.SettingsTestUtils;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import static com.android.settings.functional.testutils.SettingsTestUtils.SETTINGS_PACKAGE;
|
||||
import static com.android.settings.functional.testutils.SettingsTestUtils.TIMEOUT;
|
||||
|
||||
@MediumTest
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class HomepageDisplayTests {
|
||||
|
||||
private static final String[] HOMEPAGE_ITEMS = {
|
||||
"Network & internet",
|
||||
"Connected devices",
|
||||
"Apps & notifications",
|
||||
"Battery",
|
||||
"Display",
|
||||
"Sound",
|
||||
"Storage",
|
||||
"Security & location",
|
||||
"Users & accounts",
|
||||
"Accessibility",
|
||||
"System",
|
||||
"Support & tips"
|
||||
};
|
||||
|
||||
private UiDevice mDevice;
|
||||
private SettingsHelper mSettingsHelper;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
|
||||
mSettingsHelper = new SettingsHelper();
|
||||
try {
|
||||
mDevice.setOrientationNatural();
|
||||
} catch (RemoteException e) {
|
||||
throw new RuntimeException("failed to freeze device orientaion", e);
|
||||
}
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
// Need to finish settings activity
|
||||
mDevice.pressHome();
|
||||
}
|
||||
|
||||
@Presubmit
|
||||
@Test
|
||||
public void testHomepageCategory() throws Exception {
|
||||
// Launch Settings
|
||||
SettingsHelper.launchSettingsPage(
|
||||
InstrumentationRegistry.getContext(), Settings.ACTION_SETTINGS);
|
||||
|
||||
// Scroll to top
|
||||
final UiObject2 view = mDevice.wait(
|
||||
Until.findObject(By.res(SETTINGS_PACKAGE, "main_content")),
|
||||
TIMEOUT);
|
||||
view.scroll(Direction.UP, 100f);
|
||||
|
||||
// Inspect each item
|
||||
for (String item : HOMEPAGE_ITEMS) {
|
||||
SettingsTestUtils.assertTitleMatch(mDevice, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,243 @@
|
||||
/*
|
||||
* 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.ui;
|
||||
|
||||
import android.os.RemoteException;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
import android.provider.Settings;
|
||||
import android.support.test.uiautomator.By;
|
||||
import android.support.test.uiautomator.Direction;
|
||||
import android.support.test.uiautomator.UiDevice;
|
||||
import android.support.test.uiautomator.UiObject2;
|
||||
import android.support.test.uiautomator.Until;
|
||||
import android.system.helpers.SettingsHelper;
|
||||
import android.test.InstrumentationTestCase;
|
||||
import android.test.suitebuilder.annotation.MediumTest;
|
||||
|
||||
|
||||
public class LocationSettingsTests extends InstrumentationTestCase {
|
||||
|
||||
private static final String SETTINGS_PACKAGE = "com.android.settings";
|
||||
private static final int TIMEOUT = 2000;
|
||||
private UiDevice mDevice;
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
mDevice = UiDevice.getInstance(getInstrumentation());
|
||||
try {
|
||||
mDevice.setOrientationNatural();
|
||||
} catch (RemoteException e) {
|
||||
throw new RuntimeException("failed to freeze device orientaion", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
mDevice.pressBack();
|
||||
mDevice.pressHome();
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testLoadingLocationSettings () throws Exception {
|
||||
// Load Security
|
||||
SettingsHelper.launchSettingsPage(getInstrumentation().getContext(),
|
||||
Settings.ACTION_SECURITY_SETTINGS);
|
||||
|
||||
SettingsHelper helper = new SettingsHelper();
|
||||
helper.scrollVert(true);
|
||||
// Tap on location
|
||||
UiObject2 settingsPanel = mDevice.wait(Until.findObject
|
||||
(By.res(SETTINGS_PACKAGE, "main_content")), TIMEOUT);
|
||||
int count = 0;
|
||||
UiObject2 locationTitle = null;
|
||||
while(count < 6 && locationTitle == null) {
|
||||
locationTitle = mDevice.wait(Until.findObject(By.text("Location")), TIMEOUT);
|
||||
if (locationTitle == null) {
|
||||
settingsPanel.scroll(Direction.DOWN, 1.0f);
|
||||
}
|
||||
count++;
|
||||
}
|
||||
// Verify location settings loads.
|
||||
locationTitle.click();
|
||||
Thread.sleep(TIMEOUT);
|
||||
assertNotNull("Location screen has not loaded correctly",
|
||||
mDevice.wait(Until.findObject(By.text("Location services")), TIMEOUT));
|
||||
}
|
||||
|
||||
@Presubmit
|
||||
@MediumTest
|
||||
public void testLocationSettingOn() throws Exception {
|
||||
verifyLocationSettingsOnOrOff(true);
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testLocationSettingOff() throws Exception {
|
||||
verifyLocationSettingsOnOrOff(false);
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testLocationDeviceOnlyMode() throws Exception {
|
||||
// Changing the value from default before testing the toggle to Device only mode
|
||||
Settings.Secure.putInt(getInstrumentation().getContext().getContentResolver(),
|
||||
Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_HIGH_ACCURACY);
|
||||
dismissAlertDialogs();
|
||||
Thread.sleep(TIMEOUT);
|
||||
verifyLocationSettingsMode(Settings.Secure.LOCATION_MODE_SENSORS_ONLY);
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testLocationBatterySavingMode() throws Exception {
|
||||
Settings.Secure.putInt(getInstrumentation().getContext().getContentResolver(),
|
||||
Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_SENSORS_ONLY);
|
||||
Thread.sleep(TIMEOUT);
|
||||
verifyLocationSettingsMode(Settings.Secure.LOCATION_MODE_BATTERY_SAVING);
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testLocationHighAccuracyMode() throws Exception {
|
||||
Settings.Secure.putInt(getInstrumentation().getContext().getContentResolver(),
|
||||
Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_SENSORS_ONLY);
|
||||
Thread.sleep(TIMEOUT);
|
||||
verifyLocationSettingsMode(Settings.Secure.LOCATION_MODE_HIGH_ACCURACY);
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testLocationSettingsElements() throws Exception {
|
||||
String[] textElements = {"Location", "Mode", "Recent location requests",
|
||||
"Location services"};
|
||||
SettingsHelper.launchSettingsPage(getInstrumentation().getContext(),
|
||||
Settings.ACTION_LOCATION_SOURCE_SETTINGS);
|
||||
Thread.sleep(TIMEOUT);
|
||||
for (String element : textElements) {
|
||||
assertNotNull(element + " item not found under Location Settings",
|
||||
mDevice.wait(Until.findObject(By.text(element)), TIMEOUT));
|
||||
}
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testLocationSettingsOverflowMenuElements() throws Exception {
|
||||
SettingsHelper.launchSettingsPage(getInstrumentation().getContext(),
|
||||
Settings.ACTION_LOCATION_SOURCE_SETTINGS);
|
||||
// Verify help & feedback
|
||||
assertNotNull("Help & feedback item not found under Location Settings",
|
||||
mDevice.wait(Until.findObject(By.desc("Help & feedback")), TIMEOUT));
|
||||
// Verify scanning
|
||||
assertNotNull("Scanning item not found under Location Settings",
|
||||
mDevice.wait(Until.findObject(By.text("Scanning")), TIMEOUT));
|
||||
}
|
||||
|
||||
private void verifyLocationSettingsMode(int mode) throws Exception {
|
||||
int modeIntValue = 1;
|
||||
String textMode = "Device only";
|
||||
if (mode == Settings.Secure.LOCATION_MODE_HIGH_ACCURACY) {
|
||||
modeIntValue = 3;
|
||||
textMode = "High accuracy";
|
||||
}
|
||||
else if (mode == Settings.Secure.LOCATION_MODE_BATTERY_SAVING) {
|
||||
modeIntValue = 2;
|
||||
textMode = "Battery saving";
|
||||
}
|
||||
// Load location settings
|
||||
SettingsHelper.launchSettingsPage(getInstrumentation().getContext(),
|
||||
Settings.ACTION_LOCATION_SOURCE_SETTINGS);
|
||||
// Tap on mode
|
||||
dismissAlertDialogs();
|
||||
// Load location settings
|
||||
mDevice.wait(Until.findObject(By.text("Mode")), TIMEOUT).click();
|
||||
Thread.sleep(TIMEOUT);
|
||||
assertNotNull("Location mode screen not loaded", mDevice.wait(Until.findObject
|
||||
(By.text("Location mode")), TIMEOUT));
|
||||
// Choose said mode
|
||||
mDevice.wait(Until.findObject(By.text(textMode)), TIMEOUT).click();
|
||||
Thread.sleep(TIMEOUT);
|
||||
dismissAlertDialogs();
|
||||
mDevice.wait(Until.findObject(By.desc("Navigate up")), TIMEOUT).click();
|
||||
Thread.sleep(TIMEOUT);
|
||||
if (mode == Settings.Secure.LOCATION_MODE_HIGH_ACCURACY ||
|
||||
mode == Settings.Secure.LOCATION_MODE_BATTERY_SAVING) {
|
||||
dismissAlertDialogs();
|
||||
}
|
||||
// get setting and verify value
|
||||
// Verify change of mode
|
||||
int locationSettingMode =
|
||||
Settings.Secure.getInt(getInstrumentation().getContext().getContentResolver(),
|
||||
Settings.Secure.LOCATION_MODE);
|
||||
assertEquals(mode + " value not set correctly for location.", modeIntValue,
|
||||
locationSettingMode);
|
||||
}
|
||||
|
||||
private void verifyLocationSettingsOnOrOff(boolean verifyOn) throws Exception {
|
||||
// Set location flag
|
||||
if (verifyOn) {
|
||||
Settings.Secure.putInt(getInstrumentation().getContext().getContentResolver(),
|
||||
Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF);
|
||||
}
|
||||
else {
|
||||
Settings.Secure.putInt(getInstrumentation().getContext().getContentResolver(),
|
||||
Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_HIGH_ACCURACY);
|
||||
}
|
||||
dismissAlertDialogs();
|
||||
// Load location settings
|
||||
SettingsHelper.launchSettingsPage(getInstrumentation().getContext(),
|
||||
Settings.ACTION_LOCATION_SOURCE_SETTINGS);
|
||||
dismissAlertDialogs();
|
||||
// Toggle UI
|
||||
mDevice.wait(Until.findObject(By.res(SETTINGS_PACKAGE, "switch_widget")), TIMEOUT).click();
|
||||
dismissAlertDialogs();
|
||||
Thread.sleep(TIMEOUT);
|
||||
// Verify change in setting
|
||||
int locationEnabled = Settings.Secure.getInt(getInstrumentation()
|
||||
.getContext().getContentResolver(),
|
||||
Settings.Secure.LOCATION_MODE);
|
||||
if (verifyOn) {
|
||||
assertFalse("Location not enabled correctly", locationEnabled == 0);
|
||||
}
|
||||
else {
|
||||
assertEquals("Location not disabled correctly", 0, locationEnabled);
|
||||
}
|
||||
}
|
||||
|
||||
// This method dismisses both alert dialogs that might popup and
|
||||
// interfere with the test. Since the order in which the dialog
|
||||
// shows up changes in no specific known way, we're checking for
|
||||
// both dialogs in any order for a robust test. Bug b/36233151
|
||||
// filed against Location team for specifications. This is a
|
||||
// workaround in the meantime to ensure coverage.
|
||||
private void dismissAlertDialogs() throws Exception {
|
||||
for (int count = 0; count < 2; count++) {
|
||||
UiObject2 agreeDialog = mDevice.wait(Until.findObject
|
||||
(By.text("Improve location accuracy?")), TIMEOUT);
|
||||
UiObject2 previousChoiceYesButton = mDevice.wait(Until.findObject
|
||||
(By.text("YES")), TIMEOUT);
|
||||
if (agreeDialog != null) {
|
||||
mDevice.wait(Until.findObject
|
||||
(By.text("AGREE")), TIMEOUT).click();
|
||||
Thread.sleep(TIMEOUT);
|
||||
assertNull("Improve location dialog not dismissed",
|
||||
mDevice.wait(Until.findObject
|
||||
(By.text("Improve location accuracy?")), TIMEOUT));
|
||||
}
|
||||
if (previousChoiceYesButton != null) {
|
||||
previousChoiceYesButton.click();
|
||||
// Short sleep to wait for the new screen
|
||||
Thread.sleep(TIMEOUT);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* 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.ui;
|
||||
|
||||
import android.os.RemoteException;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
import android.provider.Settings;
|
||||
import android.support.test.uiautomator.By;
|
||||
import android.support.test.uiautomator.UiDevice;
|
||||
import android.support.test.uiautomator.UiObject2;
|
||||
import android.support.test.uiautomator.Until;
|
||||
import android.system.helpers.SettingsHelper;
|
||||
import android.test.InstrumentationTestCase;
|
||||
import android.test.suitebuilder.annotation.MediumTest;
|
||||
|
||||
|
||||
public class MoreWirelessSettingsTests extends InstrumentationTestCase {
|
||||
|
||||
private static final String SETTINGS_PACKAGE = "com.android.settings";
|
||||
private static final int TIMEOUT = 2000;
|
||||
private UiDevice mDevice;
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
mDevice = UiDevice.getInstance(getInstrumentation());
|
||||
try {
|
||||
mDevice.setOrientationNatural();
|
||||
} catch (RemoteException e) {
|
||||
throw new RuntimeException("failed to freeze device orientaion", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
mDevice.pressBack();
|
||||
mDevice.pressHome();
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
@Presubmit
|
||||
@MediumTest
|
||||
public void testAirplaneModeEnabled() throws Exception {
|
||||
verifyAirplaneModeOnOrOff(true);
|
||||
// Toggling this via the wifi network settings page
|
||||
// because of bug b/34858716. Once that is fixed,
|
||||
// we should be able to set this via Settings putString.
|
||||
toggleAirplaneModeSwitch();
|
||||
}
|
||||
|
||||
@Presubmit
|
||||
@MediumTest
|
||||
public void testAirplaneModeDisabled() throws Exception {
|
||||
verifyAirplaneModeOnOrOff(false);
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testTetheringMenuLoad() throws Exception {
|
||||
SettingsHelper.launchSettingsPage(getInstrumentation().getContext(),
|
||||
Settings.ACTION_WIRELESS_SETTINGS);
|
||||
mDevice.wait(Until
|
||||
.findObject(By.text("Hotspot & tethering")), TIMEOUT)
|
||||
.click();
|
||||
Thread.sleep(TIMEOUT);
|
||||
UiObject2 usbTethering = mDevice.wait(Until
|
||||
.findObject(By.text("USB tethering")), TIMEOUT);
|
||||
assertNotNull("Tethering screen did not load correctly", usbTethering);
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testVPNMenuLoad() throws Exception {
|
||||
SettingsHelper.launchSettingsPage(getInstrumentation().getContext(),
|
||||
Settings.ACTION_WIRELESS_SETTINGS);
|
||||
mDevice.wait(Until
|
||||
.findObject(By.text("VPN")), TIMEOUT)
|
||||
.click();
|
||||
Thread.sleep(TIMEOUT);
|
||||
UiObject2 usbTethering = mDevice.wait(Until
|
||||
.findObject(By.res(SETTINGS_PACKAGE, "vpn_create")), TIMEOUT);
|
||||
assertNotNull("VPN screen did not load correctly", usbTethering);
|
||||
}
|
||||
|
||||
private void verifyAirplaneModeOnOrOff(boolean verifyOn) throws Exception {
|
||||
if (verifyOn) {
|
||||
Settings.Global.putString(getInstrumentation().getContext().getContentResolver(),
|
||||
Settings.Global.AIRPLANE_MODE_ON, "0");
|
||||
}
|
||||
else {
|
||||
Settings.Global.putString(getInstrumentation().getContext().getContentResolver(),
|
||||
Settings.Global.AIRPLANE_MODE_ON, "1");
|
||||
}
|
||||
toggleAirplaneModeSwitch();
|
||||
String airplaneModeValue = Settings.Global
|
||||
.getString(getInstrumentation().getContext().getContentResolver(),
|
||||
Settings.Global.AIRPLANE_MODE_ON);
|
||||
if (verifyOn) {
|
||||
assertEquals("1", airplaneModeValue);
|
||||
}
|
||||
else {
|
||||
assertEquals("0", airplaneModeValue);
|
||||
}
|
||||
}
|
||||
|
||||
private void toggleAirplaneModeSwitch() throws Exception {
|
||||
SettingsHelper.launchSettingsPage(getInstrumentation().getContext(),
|
||||
Settings.ACTION_WIRELESS_SETTINGS);
|
||||
mDevice.wait(Until
|
||||
.findObject(By.text("Airplane mode")), TIMEOUT)
|
||||
.click();
|
||||
Thread.sleep(TIMEOUT);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* 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.ui;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.RemoteException;
|
||||
import android.provider.Settings;
|
||||
import android.support.test.uiautomator.By;
|
||||
import android.support.test.uiautomator.BySelector;
|
||||
import android.support.test.uiautomator.Direction;
|
||||
import android.support.test.uiautomator.UiDevice;
|
||||
import android.support.test.uiautomator.UiObject2;
|
||||
import android.support.test.uiautomator.Until;
|
||||
import android.system.helpers.ActivityHelper;
|
||||
import android.system.helpers.SettingsHelper;
|
||||
import android.widget.ListView;
|
||||
import android.test.InstrumentationTestCase;
|
||||
import android.test.suitebuilder.annotation.MediumTest;
|
||||
import android.util.Log;
|
||||
|
||||
/** Verifies that you can get to the notification app listing page from the apps & notifications
|
||||
* page */
|
||||
public class NotificationSettingsTests extends InstrumentationTestCase {
|
||||
private static final boolean LOCAL_LOGV = false;
|
||||
private static final String TAG = "NotifiSettingsTests";
|
||||
private static final int TIMEOUT = 2000;
|
||||
private ActivityHelper mActivityHelper = null;
|
||||
private SettingsHelper mSettingsHelper = null;
|
||||
|
||||
private UiDevice mDevice;
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
if (LOCAL_LOGV) {
|
||||
Log.d(TAG, "-------");
|
||||
}
|
||||
super.setUp();
|
||||
mDevice = UiDevice.getInstance(getInstrumentation());
|
||||
mActivityHelper = ActivityHelper.getInstance();
|
||||
mSettingsHelper = SettingsHelper.getInstance();
|
||||
try {
|
||||
mDevice.setOrientationNatural();
|
||||
} catch (RemoteException e) {
|
||||
throw new RuntimeException("Failed to freeze device orientaion", e);
|
||||
}
|
||||
|
||||
// make sure we are in a clean state before starting the test
|
||||
mDevice.pressHome();
|
||||
Thread.sleep(TIMEOUT * 2);
|
||||
launchAppsSettings();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
mDevice.pressBack();
|
||||
mDevice.pressHome(); // finish settings activity
|
||||
mDevice.waitForIdle(TIMEOUT * 2); // give UI time to finish animating
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testNotificationsSettingsListForCalculator() {
|
||||
UiObject2 configureNotifications = mDevice.wait(
|
||||
Until.findObject(By.text("Notifications")), TIMEOUT);
|
||||
configureNotifications.click();
|
||||
mDevice.wait(Until.findObject(By.text("Blink light")), TIMEOUT);
|
||||
UiObject2 appNotifications = mDevice.wait(
|
||||
Until.findObject(By.text("On for all apps")), TIMEOUT);
|
||||
appNotifications.click();
|
||||
UiObject2 view =
|
||||
mDevice.wait(
|
||||
Until.findObject(By.text("All apps")), TIMEOUT);
|
||||
assertNotNull("Could not find Settings > Apps screen", view);
|
||||
UiObject2 app = mDevice.wait(Until.findObject(By.text("Calculator")), TIMEOUT);
|
||||
assertNotNull("Could not find Calculator notification settings", app);
|
||||
}
|
||||
|
||||
|
||||
@MediumTest
|
||||
public void testNotificationsSettingsListForPhone() {
|
||||
UiObject2 configureNotifications = mDevice.wait(
|
||||
Until.findObject(By.text("Notifications")), TIMEOUT);
|
||||
configureNotifications.click();
|
||||
mDevice.wait(Until.findObject(By.text("Blink light")), TIMEOUT);
|
||||
UiObject2 appNotifications = mDevice.wait(
|
||||
Until.findObject(By.text("On for all apps")), TIMEOUT);
|
||||
appNotifications.click();
|
||||
UiObject2 view =
|
||||
mDevice.wait(
|
||||
Until.findObject(By.text("All apps")), TIMEOUT);
|
||||
assertNotNull("Could not find Settings > Apps screen", view);
|
||||
|
||||
final BySelector preferenceListSelector = By.clazz(ListView.class).res("android:id/list");
|
||||
UiObject2 apps = mDevice.wait(Until.findObject(preferenceListSelector), TIMEOUT);
|
||||
|
||||
UiObject2 phone = scrollTo(mDevice, apps, By.text("Phone"), Direction.DOWN);
|
||||
assertNotNull("Could not find Phone notification settings", phone);
|
||||
phone.click();
|
||||
UiObject2 incomingCalls = mDevice.wait(Until.findObject(By.text("Incoming calls")), TIMEOUT);
|
||||
assertNotNull("Could not find incoming calls channel", incomingCalls);
|
||||
incomingCalls.click();
|
||||
|
||||
// here's the meat of this test: make sure that you cannot change
|
||||
// most settings for this channel
|
||||
|
||||
UiObject2 importance = mDevice.wait(Until.findObject(By.text("Importance")), TIMEOUT);
|
||||
assertNotNull("Could not find importance toggle", importance);
|
||||
assertFalse(importance.isEnabled());
|
||||
assertFalse(mDevice.wait(Until.findObject(By.text("Sound")), TIMEOUT).isEnabled());;
|
||||
assertFalse(mDevice.wait(Until.findObject(By.text("Vibrate")), TIMEOUT).isEnabled());
|
||||
assertFalse(mDevice.wait(Until.findObject(By.text("Override Do Not Disturb")), TIMEOUT).isEnabled());
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
private UiObject2 scrollTo(UiDevice device, UiObject2 scrollable,
|
||||
BySelector target, Direction direction) {
|
||||
while (!device.hasObject(target) && scrollable.scroll(direction, 1.0f)) {
|
||||
// continue
|
||||
}
|
||||
if (!device.hasObject(target)) {
|
||||
// Scroll once more if not found; in some cases UiObject2.scroll can return false when
|
||||
// the last item is not fully visible yet for list views.
|
||||
scrollable.scroll(direction, 1.0f);
|
||||
}
|
||||
return device.findObject(target);
|
||||
}
|
||||
|
||||
|
||||
private void launchAppsSettings() throws Exception {
|
||||
Intent appsSettingsIntent = new Intent(Settings.ACTION_SETTINGS);
|
||||
mActivityHelper.launchIntent(appsSettingsIntent);
|
||||
mSettingsHelper.flingSettingsToStart();
|
||||
UiObject2 view = mDevice.wait(
|
||||
Until.findObject(By.text("Apps & notifications")), TIMEOUT);
|
||||
view.click();
|
||||
UiObject2 title = mDevice.wait(
|
||||
Until.findObject(By.text("Apps & notifications")), TIMEOUT);
|
||||
assertNotNull("Could not find Settings > Apps & notifications screen", title);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* 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.ui;
|
||||
|
||||
import android.os.RemoteException;
|
||||
import android.provider.Settings;
|
||||
import android.support.test.InstrumentationRegistry;
|
||||
import android.support.test.filters.MediumTest;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
import android.support.test.uiautomator.UiDevice;
|
||||
import android.system.helpers.SettingsHelper;
|
||||
|
||||
import com.android.settings.functional.testutils.SettingsTestUtils;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@MediumTest
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class SecuritySettingsLaunchTest {
|
||||
|
||||
// Items we really want to always show
|
||||
private static final String[] CATEGORIES = new String[]{
|
||||
"Security status",
|
||||
"Device security",
|
||||
"Privacy",
|
||||
};
|
||||
|
||||
private UiDevice mDevice;
|
||||
private SettingsHelper mHelper;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
|
||||
mHelper = SettingsHelper.getInstance();
|
||||
try {
|
||||
mDevice.setOrientationNatural();
|
||||
} catch (RemoteException e) {
|
||||
throw new RuntimeException("failed to freeze device orientaion", e);
|
||||
}
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
// Go back to home for next test.
|
||||
mDevice.pressHome();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void launchSecuritySettings() throws Exception {
|
||||
// Launch Settings
|
||||
SettingsHelper.launchSettingsPage(
|
||||
InstrumentationRegistry.getContext(), Settings.ACTION_SECURITY_SETTINGS);
|
||||
mHelper.scrollVert(false);
|
||||
for (String category : CATEGORIES) {
|
||||
SettingsTestUtils.assertTitleMatch(mDevice, category);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,334 @@
|
||||
/*
|
||||
* 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.ui;
|
||||
|
||||
import android.app.NotificationManager;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.os.Handler;
|
||||
import android.os.SystemClock;
|
||||
import android.provider.Settings;
|
||||
import android.service.notification.ZenModeConfig;
|
||||
import android.support.test.uiautomator.UiObject2;
|
||||
import android.system.helpers.SettingsHelper;
|
||||
import android.system.helpers.SettingsHelper.SettingsType;
|
||||
import android.support.test.uiautomator.By;
|
||||
import android.support.test.uiautomator.UiDevice;
|
||||
import android.support.test.uiautomator.Until;
|
||||
import android.test.InstrumentationTestCase;
|
||||
import android.test.suitebuilder.annotation.MediumTest;
|
||||
import android.test.suitebuilder.annotation.Suppress;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public class SoundSettingsTest extends InstrumentationTestCase {
|
||||
private static final String PAGE = Settings.ACTION_SOUND_SETTINGS;
|
||||
private static final int TIMEOUT = 2000;
|
||||
|
||||
private UiDevice mDevice;
|
||||
private ContentResolver mResolver;
|
||||
private SettingsHelper mHelper;
|
||||
|
||||
|
||||
private HashMap ringtoneSounds = new HashMap<String, String>() {{
|
||||
put("angler","Dione");
|
||||
put("bullhead","Dione");
|
||||
put("marlin","Spaceship");
|
||||
put("sailfish","Spaceship");
|
||||
put("walleye","Copycat");
|
||||
put("taimen","Copycat");
|
||||
}};
|
||||
|
||||
private HashMap ringtoneCodes = new HashMap<String, String>() {{
|
||||
put("angler","38");
|
||||
put("bullhead","38");
|
||||
put("marlin","37");
|
||||
put("sailfish","37");
|
||||
put("walleye","26");
|
||||
put("taimen","26");
|
||||
}};
|
||||
|
||||
private HashMap alarmSounds = new HashMap<String, String>() {{
|
||||
put("angler","Awaken");
|
||||
put("bullhead","Awaken");
|
||||
put("marlin","Bounce");
|
||||
put("sailfish","Bounce");
|
||||
put("walleye","Cuckoo clock");
|
||||
put("taimen","Cuckoo clock");
|
||||
}};
|
||||
|
||||
private HashMap alarmCodes = new HashMap<String, String>() {{
|
||||
put("angler","6");
|
||||
put("bullhead","6");
|
||||
put("marlin","49");
|
||||
put("sailfish","49");
|
||||
put("walleye","15");
|
||||
put("taimen","15");
|
||||
}};
|
||||
|
||||
private HashMap notificationSounds = new HashMap<String, String>() {{
|
||||
put("angler","Ceres");
|
||||
put("bullhead","Ceres");
|
||||
put("marlin","Trill");
|
||||
put("sailfish","Trill");
|
||||
put("walleye","Pipes");
|
||||
put("taimen","Pipes");
|
||||
}};
|
||||
|
||||
|
||||
private HashMap notificationCodes = new HashMap<String, String>() {{
|
||||
put("angler","26");
|
||||
put("bullhead","26");
|
||||
put("marlin","57");
|
||||
put("sailfish","57");
|
||||
put("walleye","69");
|
||||
put("taimen","69");
|
||||
}};
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
mDevice = UiDevice.getInstance(getInstrumentation());
|
||||
mDevice.setOrientationNatural();
|
||||
mResolver = getInstrumentation().getContext().getContentResolver();
|
||||
mHelper = new SettingsHelper();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tearDown() throws Exception {
|
||||
mDevice.pressBack();
|
||||
mDevice.pressHome();
|
||||
mDevice.waitForIdle();
|
||||
mDevice.unfreezeRotation();
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testCallVibrate() throws Exception {
|
||||
assertTrue(mHelper.verifyToggleSetting(SettingsType.SYSTEM, PAGE,
|
||||
"Also vibrate for calls", Settings.System.VIBRATE_WHEN_RINGING));
|
||||
assertTrue(mHelper.verifyToggleSetting(SettingsType.SYSTEM, PAGE,
|
||||
"Also vibrate for calls", Settings.System.VIBRATE_WHEN_RINGING));
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testOtherSoundsDialPadTones() throws Exception {
|
||||
loadOtherSoundsPage();
|
||||
assertTrue("Dial pad tones not toggled", mHelper.verifyToggleSetting(
|
||||
SettingsType.SYSTEM, PAGE, "Dial pad tones",
|
||||
Settings.System.DTMF_TONE_WHEN_DIALING));
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testOtherSoundsScreenLocking() throws Exception {
|
||||
loadOtherSoundsPage();
|
||||
assertTrue("Screen locking sounds not toggled",
|
||||
mHelper.verifyToggleSetting(SettingsType.SYSTEM, PAGE,
|
||||
"Screen locking sounds", Settings.System.LOCKSCREEN_SOUNDS_ENABLED));
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testOtherSoundsCharging() throws Exception {
|
||||
loadOtherSoundsPage();
|
||||
assertTrue("Charging sounds not toggled",
|
||||
mHelper.verifyToggleSetting(SettingsType.GLOBAL, PAGE,
|
||||
"Charging sounds", Settings.Global.CHARGING_SOUNDS_ENABLED));
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testOtherSoundsTouch() throws Exception {
|
||||
loadOtherSoundsPage();
|
||||
assertTrue("Touch sounds not toggled",
|
||||
mHelper.verifyToggleSetting(SettingsType.SYSTEM, PAGE,
|
||||
"Touch sounds", Settings.System.SOUND_EFFECTS_ENABLED));
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testOtherSoundsVibrateOnTap() throws Exception {
|
||||
loadOtherSoundsPage();
|
||||
assertTrue("Vibrate on tap not toggled",
|
||||
mHelper.verifyToggleSetting(SettingsType.SYSTEM, PAGE,
|
||||
"Vibrate on tap", Settings.System.HAPTIC_FEEDBACK_ENABLED));
|
||||
}
|
||||
|
||||
private void loadOtherSoundsPage() throws Exception {
|
||||
launchSoundSettings();
|
||||
mHelper.scrollVert(false);
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
|
||||
private void launchSoundSettings() throws Exception {
|
||||
SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE);
|
||||
mHelper.scrollVert(false);
|
||||
clickMore();
|
||||
Thread.sleep(1000);
|
||||
mHelper.scrollVert(true);
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
|
||||
/*
|
||||
* Rather than verifying every ringtone, verify the ones least likely to change
|
||||
* (None and Hangouts) and an arbitrary one from the ringtone pool.
|
||||
*/
|
||||
@MediumTest
|
||||
public void testPhoneRingtoneNone() throws Exception {
|
||||
launchSoundSettings();
|
||||
mHelper.clickSetting("Phone ringtone");
|
||||
verifyRingtone(new RingtoneSetting("None", "null"),
|
||||
Settings.System.RINGTONE);
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
@Suppress
|
||||
public void testPhoneRingtoneHangouts() throws Exception {
|
||||
launchSoundSettings();
|
||||
mHelper.clickSetting("Phone ringtone");
|
||||
verifyRingtone(new RingtoneSetting("Hangouts Call", "31"), Settings.System.RINGTONE);
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testPhoneRingtone() throws Exception {
|
||||
launchSoundSettings();
|
||||
mHelper.clickSetting("Phone ringtone");
|
||||
String ringtone = ringtoneSounds.get(mDevice.getProductName()).toString();
|
||||
String ringtoneSettingValue = ringtoneCodes.get(mDevice.getProductName()).toString();
|
||||
verifyRingtone(new RingtoneSetting(ringtone, ringtoneSettingValue),
|
||||
Settings.System.RINGTONE);
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testNotificationRingtoneNone() throws Exception {
|
||||
launchSoundSettings();
|
||||
mHelper.clickSetting("Default notification sound");
|
||||
verifyRingtone(new RingtoneSetting("None", "null"),
|
||||
Settings.System.NOTIFICATION_SOUND);
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
@Suppress
|
||||
public void testNotificationRingtoneHangouts() throws Exception {
|
||||
launchSoundSettings();
|
||||
mHelper.clickSetting("Default notification sound");
|
||||
verifyRingtone(new RingtoneSetting("Hangouts Message", "30"),
|
||||
Settings.System.NOTIFICATION_SOUND);
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testNotificationRingtone() throws Exception {
|
||||
launchSoundSettings();
|
||||
mHelper.clickSetting("Default notification sound");
|
||||
String notificationRingtone = notificationSounds.get(mDevice.getProductName()).toString();
|
||||
String notificationSettingValue = notificationCodes.get(mDevice.getProductName()).toString();
|
||||
verifyRingtone(new RingtoneSetting(notificationRingtone, notificationSettingValue),
|
||||
Settings.System.NOTIFICATION_SOUND);
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testAlarmRingtoneNone() throws Exception {
|
||||
launchSoundSettings();
|
||||
mHelper.clickSetting("Default alarm sound");
|
||||
verifyRingtone(new RingtoneSetting("None", "null"),
|
||||
Settings.System.ALARM_ALERT);
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testAlarmRingtone() throws Exception {
|
||||
launchSoundSettings();
|
||||
String alarmRingtone = alarmSounds.get(mDevice.getProductName()).toString();
|
||||
String alarmSettingValue = alarmCodes.get(mDevice.getProductName()).toString();
|
||||
mHelper.clickSetting("Default alarm sound");
|
||||
verifyRingtone(new RingtoneSetting(alarmRingtone, alarmSettingValue),
|
||||
Settings.System.ALARM_ALERT);
|
||||
}
|
||||
|
||||
/*
|
||||
* This method verifies that setting a custom ringtone changes the
|
||||
* ringtone code setting on the system. Each ringtone sound corresponds
|
||||
* to an arbitrary code. To see which ringtone code this is on your device, run
|
||||
* adb shell settings get system ringtone
|
||||
* The number you see at the end of the file path is the one you need.
|
||||
* To see alarms and notifications ringtone codes, run the following:
|
||||
* adb shell settings get system alarm_alert
|
||||
* adb shell settings get system notification_sound
|
||||
* @param r Ringtone setting - the name of the ringtone as displayed on device
|
||||
* @param settingName - the code of the ringtone as explained above
|
||||
* @param dir - the direction in which to scroll
|
||||
*/
|
||||
private void verifyRingtone(RingtoneSetting r, String settingName) throws Exception {
|
||||
findRingtoneInList(r.getName()).click();
|
||||
if (mDevice.getProductName().equals("walleye") || mDevice.getProductName().equals("taimen")) {
|
||||
mDevice.wait(Until.findObject(By.text("SAVE")), TIMEOUT).click();
|
||||
}
|
||||
else {
|
||||
mDevice.wait(Until.findObject(By.text("OK")), TIMEOUT).click();
|
||||
}
|
||||
SystemClock.sleep(1000);
|
||||
if (r.getVal().equals("null")) {
|
||||
assertEquals(null,
|
||||
Settings.System.getString(mResolver, settingName));
|
||||
} else if (r.getName().contains("Hangouts")) {
|
||||
assertEquals("content://media/external/audio/media/" + r.getVal(),
|
||||
Settings.System.getString(mResolver, settingName));
|
||||
} else {
|
||||
assertEquals("content://media/internal/audio/media/" + r.getVal(),
|
||||
Settings.System.getString(mResolver, settingName));
|
||||
}
|
||||
}
|
||||
|
||||
private enum ScrollDir {
|
||||
UP,
|
||||
DOWN,
|
||||
NOSCROLL
|
||||
}
|
||||
|
||||
class RingtoneSetting {
|
||||
private final String mName;
|
||||
private final String mMediaVal;
|
||||
public RingtoneSetting(String name, String fname) {
|
||||
mName = name;
|
||||
mMediaVal = fname;
|
||||
}
|
||||
public String getName() {
|
||||
return mName;
|
||||
}
|
||||
public String getVal() {
|
||||
return mMediaVal;
|
||||
}
|
||||
}
|
||||
|
||||
private void clickMore() throws InterruptedException {
|
||||
UiObject2 more = mDevice.wait(Until.findObject(By.text("Advanced")), TIMEOUT);
|
||||
if (more != null) {
|
||||
more.click();
|
||||
Thread.sleep(TIMEOUT);
|
||||
}
|
||||
}
|
||||
|
||||
private UiObject2 findRingtoneInList(String ringtone) throws Exception {
|
||||
mHelper.scrollVert(false);
|
||||
SystemClock.sleep(1000);
|
||||
UiObject2 ringToneObject = mDevice.wait(Until.findObject(By.text(ringtone)), TIMEOUT);
|
||||
int count = 0;
|
||||
while (ringToneObject == null && count < 5) {
|
||||
mHelper.scrollVert(true);
|
||||
SystemClock.sleep(1000);
|
||||
ringToneObject = mDevice.wait(Until.findObject(By.text(ringtone)), TIMEOUT);
|
||||
count++;
|
||||
}
|
||||
return ringToneObject;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* 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.ui;
|
||||
|
||||
import android.os.RemoteException;
|
||||
import android.provider.Settings;
|
||||
import android.support.test.InstrumentationRegistry;
|
||||
import android.support.test.filters.MediumTest;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
import android.support.test.uiautomator.By;
|
||||
import android.support.test.uiautomator.UiDevice;
|
||||
import android.support.test.uiautomator.UiObject2;
|
||||
import android.support.test.uiautomator.Until;
|
||||
import android.system.helpers.SettingsHelper;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import static junit.framework.Assert.assertTrue;
|
||||
|
||||
@MediumTest
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class SyncSettingsTest {
|
||||
private static final int TIMEOUT = 2000;
|
||||
|
||||
private UiDevice mDevice;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
|
||||
|
||||
try {
|
||||
mDevice.setOrientationNatural();
|
||||
} catch (RemoteException e) {
|
||||
throw new RuntimeException("failed to freeze device orientaion", e);
|
||||
}
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
// Need to finish settings activity
|
||||
mDevice.pressHome();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void syncPageShouldHaveAddAccountButton() throws Exception {
|
||||
// Launch Settings
|
||||
SettingsHelper.launchSettingsPage(
|
||||
InstrumentationRegistry.getContext(), Settings.ACTION_SYNC_SETTINGS);
|
||||
UiObject2 addAccount = mDevice.wait(
|
||||
Until.findObject(By.text("Add account")), TIMEOUT);
|
||||
assertTrue(addAccount != null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,777 @@
|
||||
/*
|
||||
* 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.ui;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.os.RemoteException;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
import android.provider.Settings;
|
||||
import android.system.helpers.CommandsHelper;
|
||||
import android.system.helpers.SettingsHelper;
|
||||
import android.support.test.uiautomator.By;
|
||||
import android.support.test.uiautomator.BySelector;
|
||||
import android.support.test.uiautomator.Direction;
|
||||
import android.support.test.uiautomator.StaleObjectException;
|
||||
import android.support.test.uiautomator.UiDevice;
|
||||
import android.support.test.uiautomator.UiObject2;
|
||||
import android.support.test.uiautomator.Until;
|
||||
import android.test.InstrumentationTestCase;
|
||||
import android.test.suitebuilder.annotation.MediumTest;
|
||||
import android.test.suitebuilder.annotation.Suppress;
|
||||
import android.util.Log;
|
||||
import junit.framework.AssertionFailedError;
|
||||
|
||||
public class WirelessNetworkSettingsTests extends InstrumentationTestCase {
|
||||
// These back button presses are performed in tearDown() to exit Wifi
|
||||
// Settings sub-menus that a test might finish in. This number should be
|
||||
// high enough to account for the deepest sub-menu a test might enter.
|
||||
private static final int NUM_BACK_BUTTON_PRESSES = 5;
|
||||
private static final int TIMEOUT = 2000;
|
||||
private static final int SLEEP_TIME = 500;
|
||||
private static final String AIRPLANE_MODE_BROADCAST =
|
||||
"am broadcast -a android.intent.action.AIRPLANE_MODE";
|
||||
private static final String TAG="WirelessNetworkSettingsTests";
|
||||
|
||||
// Note: The values of these variables might affect flakiness in tests that involve
|
||||
// scrolling. Adjust where necessary.
|
||||
private static final float SCROLL_UP_PERCENT = 10.0f;
|
||||
private static final float SCROLL_DOWN_PERCENT = 0.5f;
|
||||
private static final int MAX_SCROLL_ATTEMPTS = 10;
|
||||
private static final int MAX_ADD_NETWORK_BUTTON_ATTEMPTS = 3;
|
||||
private static final int SCROLL_SPEED = 2000;
|
||||
|
||||
private static final String TEST_SSID = "testSsid";
|
||||
private static final String TEST_PW_GE_8_CHAR = "testPasswordGreaterThan8Char";
|
||||
private static final String TEST_PW_LT_8_CHAR = "lt8Char";
|
||||
private static final String TEST_DOMAIN = "testDomain.com";
|
||||
|
||||
private static final String SETTINGS_PACKAGE = "com.android.settings";
|
||||
|
||||
private static final String CHECKBOX_CLASS = "android.widget.CheckBox";
|
||||
private static final String SPINNER_CLASS = "android.widget.Spinner";
|
||||
private static final String EDIT_TEXT_CLASS = "android.widget.EditText";
|
||||
private static final String SCROLLVIEW_CLASS = "android.widget.ScrollView";
|
||||
private static final String LISTVIEW_CLASS = "android.widget.ListView";
|
||||
|
||||
private static final String ADD_NETWORK_MENU_CANCEL_BUTTON_TEXT = "CANCEL";
|
||||
private static final String ADD_NETWORK_MENU_SAVE_BUTTON_TEXT = "SAVE";
|
||||
private static final String ADD_NETWORK_PREFERENCE_TEXT = "Add network";
|
||||
private static final String CONFIGURE_WIFI_PREFERENCE_TEXT = "Wi‑Fi preferences";
|
||||
private static final String CONFIGURE_WIFI_ADVANCED_PREFERENCE_TEXT = "Advanced";
|
||||
private static final String CACERT_MENU_PLEASE_SELECT_TEXT = "Please select";
|
||||
private static final String CACERT_MENU_USE_SYSTEM_CERTS_TEXT = "Use system certificates";
|
||||
private static final String CACERT_MENU_DO_NOT_VALIDATE_TEXT = "Do not validate";
|
||||
private static final String USERCERT_MENU_PLEASE_SELECT_TEXT = "Please select";
|
||||
private static final String USERCERT_MENU_DO_NOT_PROVIDE_TEXT = "Do not provide";
|
||||
private static final String SECURITY_OPTION_NONE_TEXT = "None";
|
||||
private static final String SECURITY_OPTION_WEP_TEXT = "WEP";
|
||||
private static final String SECURITY_OPTION_PSK_TEXT = "WPA/WPA2 PSK";
|
||||
private static final String SECURITY_OPTION_EAP_TEXT = "802.1x EAP";
|
||||
private static final String EAP_METHOD_PEAP_TEXT = "PEAP";
|
||||
private static final String EAP_METHOD_TLS_TEXT = "TLS";
|
||||
private static final String EAP_METHOD_TTLS_TEXT = "TTLS";
|
||||
private static final String EAP_METHOD_PWD_TEXT = "PWD";
|
||||
private static final String EAP_METHOD_SIM_TEXT = "SIM";
|
||||
private static final String EAP_METHOD_AKA_TEXT = "AKA";
|
||||
private static final String EAP_METHOD_AKA_PRIME_TEXT = "AKA'";
|
||||
private static final String PHASE2_MENU_NONE_TEXT = "None";
|
||||
private static final String PHASE2_MENU_MSCHAPV2_TEXT = "MSCHAPV2";
|
||||
private static final String PHASE2_MENU_GTC_TEXT = "GTC";
|
||||
|
||||
private static final String ADD_NETWORK_MENU_ADV_TOGGLE_RES_ID = "wifi_advanced_togglebox";
|
||||
private static final String ADD_NETWORK_MENU_IP_SETTINGS_RES_ID = "ip_settings";
|
||||
private static final String ADD_NETWORK_MENU_PROXY_SETTINGS_RES_ID = "proxy_settings";
|
||||
private static final String ADD_NETWORK_MENU_SECURITY_OPTION_RES_ID = "security";
|
||||
private static final String ADD_NETWORK_MENU_EAP_METHOD_RES_ID = "method";
|
||||
private static final String ADD_NETWORK_MENU_SSID_RES_ID = "ssid";
|
||||
private static final String ADD_NETWORK_MENU_PHASE2_RES_ID = "phase2";
|
||||
private static final String ADD_NETWORK_MENU_CACERT_RES_ID = "ca_cert";
|
||||
private static final String ADD_NETWORK_MENU_USERCERT_RES_ID = "user_cert";
|
||||
private static final String ADD_NETWORK_MENU_NO_DOMAIN_WARNING_RES_ID = "no_domain_warning";
|
||||
private static final String ADD_NETWORK_MENU_NO_CACERT_WARNING_RES_ID = "no_ca_cert_warning";
|
||||
private static final String ADD_NETWORK_MENU_DOMAIN_LAYOUT_RES_ID = "l_domain";
|
||||
private static final String ADD_NETWORK_MENU_DOMAIN_RES_ID = "domain";
|
||||
private static final String ADD_NETWORK_MENU_IDENTITY_LAYOUT_RES_ID = "l_identity";
|
||||
private static final String ADD_NETWORK_MENU_ANONYMOUS_LAYOUT_RES_ID = "l_anonymous";
|
||||
private static final String ADD_NETWORK_MENU_PASSWORD_LAYOUT_RES_ID = "password_layout";
|
||||
private static final String ADD_NETWORK_MENU_SHOW_PASSWORD_LAYOUT_RES_ID =
|
||||
"show_password_layout";
|
||||
private static final String ADD_NETWORK_MENU_PASSWORD_RES_ID = "password";
|
||||
|
||||
private static final BySelector ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR =
|
||||
By.scrollable(true).clazz(SCROLLVIEW_CLASS);
|
||||
private static final BySelector SPINNER_OPTIONS_SCROLLABLE_BY_SELECTOR =
|
||||
By.scrollable(true).clazz(LISTVIEW_CLASS);
|
||||
|
||||
private UiDevice mDevice;
|
||||
private CommandsHelper mCommandsHelper;
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
mDevice = UiDevice.getInstance(getInstrumentation());
|
||||
try {
|
||||
mDevice.setOrientationNatural();
|
||||
} catch (RemoteException e) {
|
||||
throw new RuntimeException("failed to freeze device orientation", e);
|
||||
}
|
||||
// Ensure airplane mode is OFF so that wifi can be enabled using WiFiManager.
|
||||
Settings.Global.putString(getInstrumentation().getContext().getContentResolver(),
|
||||
Settings.Global.AIRPLANE_MODE_ON, "0");
|
||||
Log.d(TAG, "sending airplane mode broadcast to device");
|
||||
mCommandsHelper = CommandsHelper.getInstance();
|
||||
mCommandsHelper.executeShellCommand(AIRPLANE_MODE_BROADCAST);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
// Exit all settings sub-menus.
|
||||
for (int i = 0; i < NUM_BACK_BUTTON_PRESSES; ++i) {
|
||||
mDevice.pressBack();
|
||||
}
|
||||
mDevice.pressHome();
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
@Presubmit
|
||||
@MediumTest
|
||||
public void testWiFiEnabled() throws Exception {
|
||||
verifyWiFiOnOrOff(true);
|
||||
}
|
||||
|
||||
@Presubmit
|
||||
@MediumTest
|
||||
public void testWiFiDisabled() throws Exception {
|
||||
verifyWiFiOnOrOff(false);
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testWifiMenuLoadConfigure() throws Exception {
|
||||
loadWiFiConfigureMenu();
|
||||
Thread.sleep(SLEEP_TIME);
|
||||
UiObject2 configureWiFiHeading = mDevice.wait(Until.findObject
|
||||
(By.text(CONFIGURE_WIFI_PREFERENCE_TEXT)), TIMEOUT);
|
||||
assertNotNull("Configure WiFi menu has not loaded correctly", configureWiFiHeading);
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testNetworkNotificationsOn() throws Exception {
|
||||
verifyNetworkNotificationsOnOrOff(true);
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testNetworkNotificationsOff() throws Exception {
|
||||
verifyNetworkNotificationsOnOrOff(false);
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
public void testAddNetworkMenu_Default() throws Exception {
|
||||
loadAddNetworkMenu();
|
||||
|
||||
// Submit button should be disabled by default, while cancel button should be enabled.
|
||||
assertFalse(mDevice.wait(Until.findObject(
|
||||
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
|
||||
assertTrue(mDevice.wait(Until.findObject(
|
||||
By.text(ADD_NETWORK_MENU_CANCEL_BUTTON_TEXT)), TIMEOUT).isEnabled());
|
||||
|
||||
// Check that the SSID field is defaults to the hint.
|
||||
assertEquals("Enter the SSID", mDevice.wait(Until.findObject(By
|
||||
.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SSID_RES_ID)
|
||||
.clazz(EDIT_TEXT_CLASS)), TIMEOUT*2)
|
||||
.getText());
|
||||
|
||||
// Check Security defaults to None.
|
||||
assertEquals("None", mDevice.wait(Until.findObject(By
|
||||
.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SECURITY_OPTION_RES_ID)
|
||||
.clazz(SPINNER_CLASS)), TIMEOUT)
|
||||
.getChildren().get(0).getText());
|
||||
|
||||
// Check advanced options are collapsed by default.
|
||||
assertFalse(mDevice.wait(Until.findObject(By
|
||||
.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_ADV_TOGGLE_RES_ID)
|
||||
.clazz(CHECKBOX_CLASS)), TIMEOUT).isChecked());
|
||||
|
||||
}
|
||||
|
||||
@Suppress
|
||||
@MediumTest
|
||||
public void testAddNetworkMenu_Proxy() throws Exception {
|
||||
loadAddNetworkMenu();
|
||||
|
||||
// Toggle advanced options.
|
||||
mDevice.wait(Until.findObject(By
|
||||
.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_ADV_TOGGLE_RES_ID)
|
||||
.clazz(CHECKBOX_CLASS)), TIMEOUT).click();
|
||||
|
||||
// Verify Proxy defaults to None.
|
||||
BySelector proxySettingsBySelector =
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PROXY_SETTINGS_RES_ID)
|
||||
.clazz(SPINNER_CLASS);
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, proxySettingsBySelector);
|
||||
assertEquals("None", mDevice.wait(Until.findObject(proxySettingsBySelector), TIMEOUT)
|
||||
.getChildren().get(0).getText());
|
||||
|
||||
// Verify that Proxy Manual fields appear.
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, proxySettingsBySelector);
|
||||
mDevice.wait(Until.findObject(proxySettingsBySelector), TIMEOUT).click();
|
||||
mDevice.wait(Until.findObject(By.text("Manual")), TIMEOUT).click();
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, "proxy_warning_limited_support"));
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, "proxy_hostname"));
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, "proxy_exclusionlist"));
|
||||
|
||||
// Verify that Proxy Auto-Config options appear.
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, proxySettingsBySelector);
|
||||
mDevice.wait(Until.findObject(proxySettingsBySelector), TIMEOUT).click();
|
||||
mDevice.wait(Until.findObject(By.text("Proxy Auto-Config")), TIMEOUT).click();
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, "proxy_pac"));
|
||||
}
|
||||
|
||||
@Suppress
|
||||
@MediumTest
|
||||
public void testAddNetworkMenu_IpSettings() throws Exception {
|
||||
loadAddNetworkMenu();
|
||||
|
||||
// Toggle advanced options.
|
||||
mDevice.wait(Until.findObject(By
|
||||
.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_ADV_TOGGLE_RES_ID)
|
||||
.clazz(CHECKBOX_CLASS)), TIMEOUT).click();
|
||||
|
||||
// Verify IP settings defaults to DHCP.
|
||||
BySelector ipSettingsBySelector =
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_IP_SETTINGS_RES_ID).clazz(SPINNER_CLASS);
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, ipSettingsBySelector);
|
||||
assertEquals("DHCP", mDevice.wait(Until.findObject(ipSettingsBySelector), TIMEOUT)
|
||||
.getChildren().get(0).getText());
|
||||
|
||||
// Verify that Static IP settings options appear.
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, ipSettingsBySelector).click();
|
||||
mDevice.wait(Until.findObject(By.text("Static")), TIMEOUT).click();
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, "ipaddress"));
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, "gateway"));
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, "network_prefix_length"));
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, "dns1"));
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, "dns2"));
|
||||
}
|
||||
|
||||
@Suppress
|
||||
@MediumTest
|
||||
public void testPhase2Settings() throws Exception {
|
||||
loadAddNetworkMenu();
|
||||
selectSecurityOption(SECURITY_OPTION_EAP_TEXT);
|
||||
|
||||
BySelector phase2SettingsBySelector =
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PHASE2_RES_ID).clazz(SPINNER_CLASS);
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, phase2SettingsBySelector);
|
||||
assertEquals(PHASE2_MENU_NONE_TEXT, mDevice.wait(Until
|
||||
.findObject(phase2SettingsBySelector), TIMEOUT).getChildren().get(0).getText());
|
||||
mDevice.wait(Until.findObject(phase2SettingsBySelector), TIMEOUT).click();
|
||||
Thread.sleep(SLEEP_TIME);
|
||||
|
||||
// Verify Phase 2 authentication spinner options.
|
||||
assertNotNull(mDevice.wait(Until.findObject(By.text(PHASE2_MENU_NONE_TEXT)), TIMEOUT));
|
||||
assertNotNull(mDevice.wait(Until.findObject(By.text(PHASE2_MENU_MSCHAPV2_TEXT)), TIMEOUT));
|
||||
assertNotNull(mDevice.wait(Until.findObject(By.text(PHASE2_MENU_GTC_TEXT)), TIMEOUT));
|
||||
}
|
||||
|
||||
@Suppress
|
||||
@MediumTest
|
||||
public void testCaCertSettings() throws Exception {
|
||||
loadAddNetworkMenu();
|
||||
selectSecurityOption(SECURITY_OPTION_EAP_TEXT);
|
||||
|
||||
BySelector caCertSettingsBySelector =
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_CACERT_RES_ID).clazz(SPINNER_CLASS);
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, caCertSettingsBySelector);
|
||||
assertEquals(CACERT_MENU_PLEASE_SELECT_TEXT, mDevice.wait(Until
|
||||
.findObject(caCertSettingsBySelector), TIMEOUT).getChildren().get(0).getText());
|
||||
mDevice.wait(Until.findObject(caCertSettingsBySelector), TIMEOUT).click();
|
||||
Thread.sleep(SLEEP_TIME);
|
||||
|
||||
// Verify CA certificate spinner options.
|
||||
assertNotNull(mDevice.wait(Until.findObject(
|
||||
By.text(CACERT_MENU_PLEASE_SELECT_TEXT)), TIMEOUT));
|
||||
assertNotNull(mDevice.wait(Until.findObject(
|
||||
By.text(CACERT_MENU_USE_SYSTEM_CERTS_TEXT)), TIMEOUT));
|
||||
assertNotNull(mDevice.wait(Until.findObject(
|
||||
By.text(CACERT_MENU_DO_NOT_VALIDATE_TEXT)), TIMEOUT));
|
||||
|
||||
// Verify that a domain field and warning appear when the user selects the
|
||||
// "Use system certificates" option.
|
||||
mDevice.wait(Until.findObject(By.text(CACERT_MENU_USE_SYSTEM_CERTS_TEXT)), TIMEOUT).click();
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_DOMAIN_LAYOUT_RES_ID));
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_NO_DOMAIN_WARNING_RES_ID));
|
||||
|
||||
// Verify that a warning appears when the user chooses the "Do Not Validate" option.
|
||||
mDevice.wait(Until.findObject(caCertSettingsBySelector), TIMEOUT).click();
|
||||
mDevice.wait(Until.findObject(By.text(CACERT_MENU_DO_NOT_VALIDATE_TEXT)), TIMEOUT).click();
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_NO_CACERT_WARNING_RES_ID));
|
||||
}
|
||||
|
||||
@Suppress
|
||||
@MediumTest
|
||||
public void testAddNetwork_NoSecurity() throws Exception {
|
||||
loadAddNetworkMenu();
|
||||
selectSecurityOption(SECURITY_OPTION_NONE_TEXT);
|
||||
|
||||
// Entering an SSID is enough to enable the submit button. // TODO THIS GUY
|
||||
enterSSID(TEST_SSID);
|
||||
assertTrue(mDevice.wait(Until
|
||||
.findObject(By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
|
||||
}
|
||||
|
||||
@Suppress
|
||||
@MediumTest
|
||||
public void testAddNetwork_WEP() throws Exception {
|
||||
loadAddNetworkMenu();
|
||||
selectSecurityOption(SECURITY_OPTION_WEP_TEXT);
|
||||
assertFalse(mDevice.wait(Until.findObject(
|
||||
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
|
||||
|
||||
// Verify that WEP fields appear.
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PASSWORD_LAYOUT_RES_ID));
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SHOW_PASSWORD_LAYOUT_RES_ID));
|
||||
|
||||
// Entering an SSID alone does not enable the submit button.
|
||||
enterSSID(TEST_SSID);
|
||||
assertFalse(mDevice.wait(Until.findObject(
|
||||
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
|
||||
|
||||
// Submit button is only enabled after a password is entered.
|
||||
enterPassword(TEST_PW_GE_8_CHAR);
|
||||
assertTrue(mDevice.wait(Until
|
||||
.findObject(By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
|
||||
}
|
||||
|
||||
@Suppress
|
||||
@MediumTest
|
||||
public void testAddNetwork_PSK() throws Exception {
|
||||
loadAddNetworkMenu();
|
||||
selectSecurityOption(SECURITY_OPTION_PSK_TEXT);
|
||||
assertFalse(mDevice.wait(Until.findObject(
|
||||
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
|
||||
|
||||
// Verify that PSK fields appear.
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PASSWORD_LAYOUT_RES_ID));
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SHOW_PASSWORD_LAYOUT_RES_ID));
|
||||
|
||||
// Entering an SSID alone does not enable the submit button.
|
||||
enterSSID(TEST_SSID);
|
||||
assertFalse(mDevice.wait(Until.findObject(
|
||||
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
|
||||
|
||||
// Entering an password that is too short does not enable submit button.
|
||||
enterPassword(TEST_PW_LT_8_CHAR);
|
||||
assertFalse(mDevice.wait(Until.findObject(
|
||||
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
|
||||
|
||||
// Submit button is only enabled after a password of valid length is entered.
|
||||
enterPassword(TEST_PW_GE_8_CHAR);
|
||||
assertTrue(mDevice.wait(Until.findObject(
|
||||
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
|
||||
}
|
||||
|
||||
@Suppress
|
||||
@MediumTest
|
||||
public void testAddNetwork_EAP_PEAP() throws Exception {
|
||||
loadAddNetworkMenu();
|
||||
selectSecurityOption(SECURITY_OPTION_EAP_TEXT);
|
||||
assertFalse(mDevice.wait(Until.findObject(
|
||||
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
|
||||
|
||||
selectEAPMethod(EAP_METHOD_PEAP_TEXT);
|
||||
|
||||
// Verify that EAP-PEAP fields appear.
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PHASE2_RES_ID));
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_CACERT_RES_ID));
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_IDENTITY_LAYOUT_RES_ID));
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_ANONYMOUS_LAYOUT_RES_ID));
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PASSWORD_LAYOUT_RES_ID));
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SHOW_PASSWORD_LAYOUT_RES_ID));
|
||||
|
||||
// Entering an SSID alone does not enable the submit button.
|
||||
enterSSID(TEST_SSID);
|
||||
assertFalse(mDevice.wait(Until.findObject(
|
||||
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
|
||||
|
||||
verifyCaCertificateSubmitConditions();
|
||||
}
|
||||
|
||||
@Suppress
|
||||
@MediumTest
|
||||
public void testAddNetwork_EAP_TLS() throws Exception {
|
||||
loadAddNetworkMenu();
|
||||
selectSecurityOption(SECURITY_OPTION_EAP_TEXT);
|
||||
assertFalse(mDevice.wait(Until.findObject(
|
||||
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
|
||||
|
||||
selectEAPMethod(EAP_METHOD_TLS_TEXT);
|
||||
|
||||
// Verify that EAP-TLS fields appear.
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_CACERT_RES_ID));
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_USERCERT_RES_ID));
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_IDENTITY_LAYOUT_RES_ID));
|
||||
|
||||
// Entering an SSID alone does not enable the submit button.
|
||||
enterSSID(TEST_SSID);
|
||||
assertFalse(mDevice.wait(Until.findObject(
|
||||
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
|
||||
|
||||
// Selecting the User certificate "Do not provide" option alone does not enable the submit
|
||||
// button.
|
||||
selectUserCertificateOption(USERCERT_MENU_DO_NOT_PROVIDE_TEXT);
|
||||
assertFalse(mDevice.wait(Until.findObject(
|
||||
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
|
||||
|
||||
verifyCaCertificateSubmitConditions();
|
||||
}
|
||||
|
||||
@Suppress
|
||||
@MediumTest
|
||||
public void testAddNetwork_EAP_TTLS() throws Exception {
|
||||
loadAddNetworkMenu();
|
||||
selectSecurityOption(SECURITY_OPTION_EAP_TEXT);
|
||||
assertFalse(mDevice.wait(Until.findObject(
|
||||
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
|
||||
|
||||
selectEAPMethod(EAP_METHOD_TTLS_TEXT);
|
||||
|
||||
// Verify that EAP-TLS fields appear.
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PHASE2_RES_ID));
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_CACERT_RES_ID));
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_IDENTITY_LAYOUT_RES_ID));
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_ANONYMOUS_LAYOUT_RES_ID));
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PASSWORD_LAYOUT_RES_ID));
|
||||
|
||||
// Entering an SSID alone does not enable the submit button.
|
||||
enterSSID(TEST_SSID);
|
||||
assertFalse(mDevice.wait(Until.findObject(
|
||||
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
|
||||
|
||||
verifyCaCertificateSubmitConditions();
|
||||
}
|
||||
|
||||
@Suppress
|
||||
@MediumTest
|
||||
public void testAddNetwork_EAP_PWD() throws Exception {
|
||||
loadAddNetworkMenu();
|
||||
selectSecurityOption(SECURITY_OPTION_EAP_TEXT);
|
||||
assertFalse(mDevice.wait(Until.findObject(
|
||||
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
|
||||
|
||||
selectEAPMethod(EAP_METHOD_PWD_TEXT);
|
||||
|
||||
// Verify that EAP-TLS fields appear.
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_IDENTITY_LAYOUT_RES_ID));
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PASSWORD_LAYOUT_RES_ID));
|
||||
|
||||
// Entering an SSID alone enables the submit button.
|
||||
enterSSID(TEST_SSID);
|
||||
assertTrue(mDevice.wait(Until.findObject(
|
||||
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
|
||||
}
|
||||
|
||||
@Suppress
|
||||
@MediumTest
|
||||
public void testAddNetwork_EAP_SIM() throws Exception {
|
||||
loadAddNetworkMenu();
|
||||
selectSecurityOption(SECURITY_OPTION_EAP_TEXT);
|
||||
assertFalse(mDevice.wait(Until.findObject(
|
||||
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
|
||||
|
||||
selectEAPMethod(EAP_METHOD_SIM_TEXT);
|
||||
|
||||
// Entering an SSID alone enables the submit button.
|
||||
enterSSID(TEST_SSID);
|
||||
assertTrue(mDevice.wait(Until.findObject(
|
||||
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
|
||||
}
|
||||
|
||||
@Suppress
|
||||
@MediumTest
|
||||
public void testAddNetwork_EAP_AKA() throws Exception {
|
||||
loadAddNetworkMenu();
|
||||
selectSecurityOption(SECURITY_OPTION_EAP_TEXT);
|
||||
assertFalse(mDevice.wait(Until.findObject(
|
||||
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
|
||||
|
||||
selectEAPMethod(EAP_METHOD_AKA_TEXT);
|
||||
|
||||
// Entering an SSID alone enables the submit button.
|
||||
enterSSID(TEST_SSID);
|
||||
assertTrue(mDevice.wait(Until.findObject(
|
||||
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
|
||||
}
|
||||
|
||||
@Suppress
|
||||
@MediumTest
|
||||
public void testAddNetwork_EAP_AKA_PRIME() throws Exception {
|
||||
loadAddNetworkMenu();
|
||||
selectSecurityOption(SECURITY_OPTION_EAP_TEXT);
|
||||
assertFalse(mDevice.wait(Until.findObject(
|
||||
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
|
||||
|
||||
selectEAPMethod(EAP_METHOD_AKA_PRIME_TEXT);
|
||||
|
||||
// Entering an SSID alone enables the submit button.
|
||||
enterSSID(TEST_SSID);
|
||||
assertTrue(mDevice.wait(Until.findObject(
|
||||
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
|
||||
}
|
||||
|
||||
private void verifyKeepWiFiOnDuringSleep(String settingToBeVerified, int settingValue)
|
||||
throws Exception {
|
||||
loadWiFiConfigureMenu();
|
||||
mDevice.wait(Until.findObject(By.text("Keep Wi‑Fi on during sleep")), TIMEOUT)
|
||||
.click();
|
||||
mDevice.wait(Until.findObject(By.clazz("android.widget.CheckedTextView")
|
||||
.text(settingToBeVerified)), TIMEOUT).click();
|
||||
Thread.sleep(SLEEP_TIME);
|
||||
int keepWiFiOnSetting =
|
||||
Settings.Global.getInt(getInstrumentation().getContext().getContentResolver(),
|
||||
Settings.Global.WIFI_SLEEP_POLICY);
|
||||
assertEquals(settingValue, keepWiFiOnSetting);
|
||||
}
|
||||
|
||||
private void verifyNetworkNotificationsOnOrOff(boolean verifyOn)
|
||||
throws Exception {
|
||||
// Enable network recommendations to enable the toggle switch for Network
|
||||
// notifications
|
||||
Settings.Global.putString(getInstrumentation().getContext().getContentResolver(),
|
||||
Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED, "1");
|
||||
if (verifyOn) {
|
||||
Settings.Global.putString(getInstrumentation().getContext().getContentResolver(),
|
||||
Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, "0");
|
||||
}
|
||||
else {
|
||||
Settings.Global.putString(getInstrumentation().getContext().getContentResolver(),
|
||||
Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, "1");
|
||||
}
|
||||
loadWiFiConfigureMenu();
|
||||
mDevice.wait(Until.findObject(By.text("Open network notification")), TIMEOUT)
|
||||
.click();
|
||||
Thread.sleep(SLEEP_TIME);
|
||||
String wifiNotificationValue =
|
||||
Settings.Global.getString(getInstrumentation().getContext().getContentResolver(),
|
||||
Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON);
|
||||
if (verifyOn) {
|
||||
assertEquals("1", wifiNotificationValue);
|
||||
}
|
||||
else {
|
||||
assertEquals("0", wifiNotificationValue);
|
||||
}
|
||||
}
|
||||
|
||||
private void verifyWiFiOnOrOff(boolean verifyOn) throws Exception {
|
||||
String switchText = "On";
|
||||
if (verifyOn) {
|
||||
switchText = "Off";
|
||||
}
|
||||
loadWiFiSettingsPage(!verifyOn);
|
||||
mDevice.wait(Until
|
||||
.findObject(By.res(SETTINGS_PACKAGE, "switch_bar").text(switchText)), TIMEOUT)
|
||||
.click();
|
||||
Thread.sleep(SLEEP_TIME);
|
||||
String wifiValue =
|
||||
Settings.Global.getString(getInstrumentation().getContext().getContentResolver(),
|
||||
Settings.Global.WIFI_ON);
|
||||
if (verifyOn) {
|
||||
// 1 is Enabled, 2 is Enabled while airplane mode is ON.
|
||||
assertTrue(wifiValue.equals("1") || wifiValue.equals("2"));
|
||||
}
|
||||
else {
|
||||
assertEquals("0", wifiValue);
|
||||
}
|
||||
}
|
||||
|
||||
private void verifyCaCertificateSubmitConditions() throws Exception {
|
||||
// Selecting the CA certificate "Do not validate" option enables the submit button.
|
||||
selectCaCertificateOption(CACERT_MENU_DO_NOT_VALIDATE_TEXT);
|
||||
assertTrue(mDevice.wait(Until.findObject(
|
||||
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
|
||||
|
||||
// However, selecting the CA certificate "Use system certificates option" is not enough to
|
||||
// enable the submit button.
|
||||
selectCaCertificateOption(CACERT_MENU_USE_SYSTEM_CERTS_TEXT);
|
||||
assertFalse(mDevice.wait(Until.findObject(
|
||||
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
|
||||
|
||||
// Submit button is only enabled after a domain is entered as well.
|
||||
enterDomain(TEST_DOMAIN);
|
||||
assertTrue(mDevice.wait(Until.findObject(
|
||||
By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled());
|
||||
}
|
||||
|
||||
private void loadWiFiSettingsPage(boolean wifiEnabled) throws Exception {
|
||||
WifiManager wifiManager = (WifiManager)getInstrumentation().getContext()
|
||||
.getSystemService(Context.WIFI_SERVICE);
|
||||
wifiManager.setWifiEnabled(wifiEnabled);
|
||||
SettingsHelper.launchSettingsPage(getInstrumentation().getContext(),
|
||||
Settings.ACTION_WIFI_SETTINGS);
|
||||
}
|
||||
|
||||
private void loadWiFiConfigureMenu() throws Exception {
|
||||
loadWiFiSettingsPage(false);
|
||||
Thread.sleep(TIMEOUT);
|
||||
mDevice.wait(Until.findObject(By.text(CONFIGURE_WIFI_PREFERENCE_TEXT)), TIMEOUT).click();
|
||||
mDevice.wait(Until.findObject(
|
||||
By.text(CONFIGURE_WIFI_ADVANCED_PREFERENCE_TEXT)), TIMEOUT).click();
|
||||
}
|
||||
|
||||
private void loadAddNetworkMenu() throws Exception {
|
||||
loadWiFiSettingsPage(true);
|
||||
for (int attempts = 0; attempts < MAX_ADD_NETWORK_BUTTON_ATTEMPTS; ++attempts) {
|
||||
try {
|
||||
findOrScrollToObject(By.scrollable(true), By.text(ADD_NETWORK_PREFERENCE_TEXT))
|
||||
.click();
|
||||
} catch (StaleObjectException e) {
|
||||
// The network list might have been updated between when the Add network button was
|
||||
// found, and when it UI automator attempted to click on it. Retry.
|
||||
continue;
|
||||
}
|
||||
// If we get here, we successfully clicked on the Add network button, so we are done.
|
||||
Thread.sleep(SLEEP_TIME*5);
|
||||
return;
|
||||
}
|
||||
|
||||
fail("Failed to load Add Network Menu after " + MAX_ADD_NETWORK_BUTTON_ATTEMPTS
|
||||
+ " retries");
|
||||
}
|
||||
|
||||
private void selectSecurityOption(String securityOption) throws Exception {
|
||||
// We might not need to scroll to the security options if not enough add network menu
|
||||
// options are visible.
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SECURITY_OPTION_RES_ID)
|
||||
.clazz(SPINNER_CLASS)).click();
|
||||
Thread.sleep(SLEEP_TIME);
|
||||
mDevice.wait(Until.findObject(By.text(securityOption)), TIMEOUT).click();
|
||||
}
|
||||
|
||||
private void selectEAPMethod(String eapMethod) throws Exception {
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_EAP_METHOD_RES_ID).clazz(SPINNER_CLASS))
|
||||
.click();
|
||||
Thread.sleep(SLEEP_TIME);
|
||||
findOrScrollToObject(SPINNER_OPTIONS_SCROLLABLE_BY_SELECTOR, By.text(eapMethod)).click();
|
||||
}
|
||||
|
||||
private void selectUserCertificateOption(String userCertificateOption) throws Exception {
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_USERCERT_RES_ID).clazz(SPINNER_CLASS))
|
||||
.click();
|
||||
mDevice.wait(Until.findObject(By.text(userCertificateOption)), TIMEOUT).click();
|
||||
}
|
||||
|
||||
private void selectCaCertificateOption(String caCertificateOption) throws Exception {
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_CACERT_RES_ID).clazz(SPINNER_CLASS))
|
||||
.click();
|
||||
mDevice.wait(Until.findObject(By.text(caCertificateOption)), TIMEOUT).click();
|
||||
}
|
||||
|
||||
private void enterSSID(String ssid) throws Exception {
|
||||
// We might not need to scroll to the SSID option if not enough add network menu options
|
||||
// are visible.
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SSID_RES_ID).clazz(EDIT_TEXT_CLASS))
|
||||
.setText(ssid);
|
||||
}
|
||||
|
||||
private void enterPassword(String password) throws Exception {
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PASSWORD_RES_ID).clazz(EDIT_TEXT_CLASS))
|
||||
.setText(password);
|
||||
}
|
||||
|
||||
private void enterDomain(String domain) throws Exception {
|
||||
findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR,
|
||||
By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_DOMAIN_RES_ID)).setText(domain);
|
||||
}
|
||||
|
||||
// Use this if the UI object might or might not need to be scrolled to.
|
||||
private UiObject2 findOrScrollToObject(BySelector scrollableSelector, BySelector objectSelector)
|
||||
throws Exception {
|
||||
UiObject2 object = mDevice.wait(Until.findObject(objectSelector), TIMEOUT);
|
||||
if (object == null) {
|
||||
object = scrollToObject(scrollableSelector, objectSelector);
|
||||
}
|
||||
return object;
|
||||
}
|
||||
|
||||
private UiObject2 scrollToObject(BySelector scrollableSelector, BySelector objectSelector)
|
||||
throws Exception {
|
||||
UiObject2 scrollable = mDevice.wait(Until.findObject(scrollableSelector), TIMEOUT);
|
||||
if (scrollable == null) {
|
||||
fail("Could not find scrollable UI object identified by " + scrollableSelector);
|
||||
}
|
||||
UiObject2 found = null;
|
||||
// Scroll all the way up first, then all the way down.
|
||||
while (true) {
|
||||
// Optimization: terminate if we find the object while scrolling up to reset, so
|
||||
// we save the time spent scrolling down again.
|
||||
boolean canScrollAgain = scrollable.scroll(Direction.UP, SCROLL_UP_PERCENT,
|
||||
SCROLL_SPEED);
|
||||
found = mDevice.findObject(objectSelector);
|
||||
if (found != null) return found;
|
||||
if (!canScrollAgain) break;
|
||||
}
|
||||
for (int attempts = 0; found == null && attempts < MAX_SCROLL_ATTEMPTS; ++attempts) {
|
||||
// Return value of UiObject2.scroll() is not reliable, so do not use it in loop
|
||||
// condition, in case it causes this loop to terminate prematurely.
|
||||
scrollable.scroll(Direction.DOWN, SCROLL_DOWN_PERCENT, SCROLL_SPEED);
|
||||
found = mDevice.findObject(objectSelector);
|
||||
}
|
||||
if (found == null) {
|
||||
fail("Could not scroll to UI object identified by " + objectSelector);
|
||||
}
|
||||
return found;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* 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.functional.testutils;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import android.support.test.uiautomator.By;
|
||||
import android.support.test.uiautomator.Direction;
|
||||
import android.support.test.uiautomator.UiDevice;
|
||||
import android.support.test.uiautomator.UiObject2;
|
||||
import android.support.test.uiautomator.Until;
|
||||
|
||||
public class SettingsTestUtils {
|
||||
|
||||
public static final String SETTINGS_PACKAGE = "com.android.settings";
|
||||
public static final int TIMEOUT = 2000;
|
||||
|
||||
private void scrollToTop(UiDevice device) throws Exception {
|
||||
int count = 5;
|
||||
UiObject2 view = null;
|
||||
while (count >= 0) {
|
||||
view = device.wait(
|
||||
Until.findObject(By.res(SETTINGS_PACKAGE, "main_content")),
|
||||
TIMEOUT);
|
||||
view.scroll(Direction.UP, 1.0f);
|
||||
count--;
|
||||
}
|
||||
}
|
||||
|
||||
public static void assertTitleMatch(UiDevice device, String title) {
|
||||
int maxAttempt = 5;
|
||||
UiObject2 item = null;
|
||||
UiObject2 view = null;
|
||||
while (maxAttempt-- > 0) {
|
||||
item = device.wait(Until.findObject(By.res("android:id/title").text(title)), TIMEOUT);
|
||||
if (item == null) {
|
||||
view = device.wait(
|
||||
Until.findObject(By.res(SETTINGS_PACKAGE, "main_content")),
|
||||
TIMEOUT);
|
||||
view.scroll(Direction.DOWN, 1.0f);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
assertNotNull(String.format("%s in Setting has not been loaded correctly", title), item);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user