diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 6724ff5355d..a5586f7955e 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -3009,6 +3009,7 @@ android:theme="@style/Theme.BottomDialog" android:excludeFromRecents="true" android:launchMode="singleTop" + android:taskAffinity=".panel.SettingsPanelActivity" android:exported="true"> diff --git a/res/layout-land/panel_layout.xml b/res/layout-land/panel_layout.xml index 3975bfeaa3f..049fd0b579b 100644 --- a/res/layout-land/panel_layout.xml +++ b/res/layout-land/panel_layout.xml @@ -20,7 +20,7 @@ android:orientation="vertical"> - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/res/layout/settings_panel.xml b/res/layout/settings_panel.xml index aec898c99c6..3405ef0d844 100644 --- a/res/layout/settings_panel.xml +++ b/res/layout/settings_panel.xml @@ -16,4 +16,5 @@ \ No newline at end of file + android:layout_width="match_parent" + android:animateLayoutChanges="true"/> \ No newline at end of file diff --git a/res/values/strings.xml b/res/values/strings.xml index e01ab3b35bc..90b72e16395 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -2153,6 +2153,10 @@ Couldn\u2019t add device Device found + + Sharing Wi\u2011Fi with this device\u2026 + + Connecting\u2026 Retry @@ -3623,7 +3627,7 @@ Erase everything No reset was performed because the System Clear service isn\u2019t available. - + Erase all data? Factory reset is not available for this user diff --git a/res/xml/hardware_info.xml b/res/xml/hardware_info.xml new file mode 100644 index 00000000000..2e35101aca6 --- /dev/null +++ b/res/xml/hardware_info.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/xml/my_device_info.xml b/res/xml/my_device_info.xml index 918e8ec0cf3..83bf5c45d08 100644 --- a/res/xml/my_device_info.xml +++ b/res/xml/my_device_info.xml @@ -105,7 +105,8 @@ settings:keywords="@string/keywords_model_and_hardware" android:summary="@string/summary_placeholder" settings:allowDynamicSummaryInSlice="true" - settings:controller="com.android.settings.deviceinfo.DeviceModelPreferenceController"/> + android:fragment="com.android.settings.deviceinfo.hardwareinfo.HardwareInfoFragment" + settings:controller="com.android.settings.deviceinfo.HardwareInfoPreferenceController"/> mStats; + private List mRecentApps; private boolean mHasRecentApps; static { @@ -115,6 +118,9 @@ public class RecentAppsPreferenceController extends BasePreferenceController mIconDrawableFactory = IconDrawableFactory.newInstance(mContext); mPowerManager = mContext.getSystemService(PowerManager.class); mUsageStatsManager = mContext.getSystemService(UsageStatsManager.class); + mRecentApps = new ArrayList<>(); + mIsFirstLaunch = true; + reloadData(); } public void setFragment(Fragment fragment) { @@ -123,8 +129,7 @@ public class RecentAppsPreferenceController extends BasePreferenceController @Override public int getAvailabilityStatus() { - reloadData(); - return getDisplayableRecentAppList().isEmpty() ? AVAILABLE_UNSEARCHABLE : AVAILABLE; + return mRecentApps.isEmpty() ? AVAILABLE_UNSEARCHABLE : AVAILABLE; } @Override @@ -152,7 +157,11 @@ public class RecentAppsPreferenceController extends BasePreferenceController @Override public void updateState(Preference preference) { super.updateState(preference); - refreshUi(); + // In order to improve launch time, we don't load data again at first launch. + if (!mIsFirstLaunch) { + reloadData(); + refreshUi(); + } // Show total number of installed apps as See all's summary. new InstalledAppCounter(mContext, InstalledAppCounter.IGNORE_INSTALL_REASON, mContext.getPackageManager()) { @@ -167,6 +176,7 @@ public class RecentAppsPreferenceController extends BasePreferenceController } } }.execute(); + mIsFirstLaunch = false; } @Override @@ -177,11 +187,9 @@ public class RecentAppsPreferenceController extends BasePreferenceController @VisibleForTesting void refreshUi() { - reloadData(); - final List recentApps = getDisplayableRecentAppList(); - if (recentApps != null && !recentApps.isEmpty()) { + if (mRecentApps != null && !mRecentApps.isEmpty()) { mHasRecentApps = true; - displayRecentApps(recentApps); + displayRecentApps(); } else { mHasRecentApps = false; displayOnlyAppInfo(); @@ -197,6 +205,8 @@ public class RecentAppsPreferenceController extends BasePreferenceController : mUsageStatsManager.queryUsageStats( UsageStatsManager.INTERVAL_BEST, mCal.getTimeInMillis(), System.currentTimeMillis()); + + updateDisplayableRecentAppList(); } private void displayOnlyAppInfo() { @@ -206,10 +216,10 @@ public class RecentAppsPreferenceController extends BasePreferenceController mRecentAppsPreference.setVisible(false); } - private void displayRecentApps(List recentApps) { + private void displayRecentApps() { int showAppsCount = 0; - for (UsageStats stat : recentApps) { + for (UsageStats stat : mRecentApps) { final AppEntityInfo appEntityInfoInfo = createAppEntity(stat); if (appEntityInfoInfo != null) { mAppEntitiesController.setAppEntity(showAppsCount++, appEntityInfoInfo); @@ -246,8 +256,8 @@ public class RecentAppsPreferenceController extends BasePreferenceController .build(); } - private List getDisplayableRecentAppList() { - final List recentApps = new ArrayList<>(); + private void updateDisplayableRecentAppList() { + mRecentApps.clear(); final Map map = new ArrayMap<>(); final int statCount = mStats.size(); for (int i = 0; i < statCount; i++) { @@ -273,13 +283,12 @@ public class RecentAppsPreferenceController extends BasePreferenceController if (appEntry == null) { continue; } - recentApps.add(stat); + mRecentApps.add(stat); count++; if (count >= AppEntitiesHeaderController.MAXIMUM_APPS) { break; } } - return recentApps; } diff --git a/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminListItem.java b/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminListItem.java index 305281c4620..370a4dfe12f 100644 --- a/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminListItem.java +++ b/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminListItem.java @@ -30,6 +30,7 @@ class DeviceAdminListItem implements Comparable { private static final String TAG = "DeviceAdminListItem"; + private final UserHandle mUserHandle; private final String mKey; private final DeviceAdminInfo mInfo; private final CharSequence mName; @@ -39,7 +40,8 @@ class DeviceAdminListItem implements Comparable { public DeviceAdminListItem(Context context, DeviceAdminInfo info) { mInfo = info; - mKey = mInfo.getComponent().flattenToString(); + mUserHandle = new UserHandle(getUserIdFromDeviceAdminInfo(mInfo)); + mKey = mUserHandle.getIdentifier() + "@" + mInfo.getComponent().flattenToString(); mDPM = (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE); final PackageManager pm = context.getPackageManager(); mName = mInfo.loadLabel(pm); @@ -48,8 +50,7 @@ class DeviceAdminListItem implements Comparable { } catch (Resources.NotFoundException exception) { Log.w(TAG, "Setting description to null because can't find resource: " + mKey); } - mIcon = pm.getUserBadgedIcon(mInfo.loadIcon(pm), - new UserHandle(DeviceAdminUtils.getUserIdFromDeviceAdminInfo(mInfo))); + mIcon = pm.getUserBadgedIcon(mInfo.loadIcon(pm), mUserHandle); } @Override @@ -70,8 +71,7 @@ class DeviceAdminListItem implements Comparable { } public boolean isActive() { - return mDPM.isAdminActiveAsUser(mInfo.getComponent(), - DeviceAdminUtils.getUserIdFromDeviceAdminInfo(mInfo)); + return mDPM.isAdminActiveAsUser(mInfo.getComponent(), getUserIdFromDeviceAdminInfo(mInfo)); } public Drawable getIcon() { @@ -79,16 +79,25 @@ class DeviceAdminListItem implements Comparable { } public boolean isEnabled() { - return !mDPM.isRemovingAdmin(mInfo.getComponent(), - DeviceAdminUtils.getUserIdFromDeviceAdminInfo(mInfo)); + return !mDPM.isRemovingAdmin(mInfo.getComponent(), getUserIdFromDeviceAdminInfo(mInfo)); } public UserHandle getUser() { - return new UserHandle(DeviceAdminUtils.getUserIdFromDeviceAdminInfo(mInfo)); + return new UserHandle(getUserIdFromDeviceAdminInfo(mInfo)); } public Intent getLaunchIntent(Context context) { return new Intent(context, DeviceAdminAdd.class) .putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, mInfo.getComponent()); } + + /** + * Extracts the user id from a device admin info object. + * + * @param adminInfo the device administrator info. + * @return identifier of the user associated with the device admin. + */ + private static int getUserIdFromDeviceAdminInfo(DeviceAdminInfo adminInfo) { + return UserHandle.getUserId(adminInfo.getActivityInfo().applicationInfo.uid); + } } diff --git a/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminListPreferenceController.java b/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminListPreferenceController.java index 319d62f66c3..7b139d9770a 100644 --- a/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminListPreferenceController.java +++ b/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminListPreferenceController.java @@ -53,6 +53,9 @@ import com.android.settingslib.core.lifecycle.events.OnStop; import com.android.settingslib.widget.FooterPreference; import com.android.settingslib.widget.FooterPreferenceMixinCompat; +import org.xmlpull.v1.XmlPullParserException; + +import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -249,8 +252,7 @@ public class DeviceAdminListPreferenceController extends BasePreferenceControlle Log.w(TAG, "Unable to load component: " + activeAdmin); continue; } - final DeviceAdminInfo deviceAdminInfo = DeviceAdminUtils.createDeviceAdminInfo( - mContext, ai); + final DeviceAdminInfo deviceAdminInfo = createDeviceAdminInfo(mContext, ai); if (deviceAdminInfo == null) { continue; } @@ -286,7 +288,7 @@ public class DeviceAdminListPreferenceController extends BasePreferenceControlle && alreadyAddedComponents.contains(riComponentName)) { continue; } - DeviceAdminInfo deviceAdminInfo = DeviceAdminUtils.createDeviceAdminInfo( + DeviceAdminInfo deviceAdminInfo = createDeviceAdminInfo( mContext, resolveInfo.activityInfo); // add only visible ones (note: active admins are added regardless of visibility) if (deviceAdminInfo != null && deviceAdminInfo.isVisible()) { @@ -297,4 +299,20 @@ public class DeviceAdminListPreferenceController extends BasePreferenceControlle } } } + + /** + * Creates a device admin info object for the resolved intent that points to the component of + * the device admin. + * + * @param ai ActivityInfo for the admin component. + * @return new {@link DeviceAdminInfo} object or null if there was an error. + */ + private static DeviceAdminInfo createDeviceAdminInfo(Context context, ActivityInfo ai) { + try { + return new DeviceAdminInfo(context, ai); + } catch (XmlPullParserException | IOException e) { + Log.w(TAG, "Skipping " + ai, e); + } + return null; + } } diff --git a/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminUtils.java b/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminUtils.java deleted file mode 100644 index 13d9d20bece..00000000000 --- a/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminUtils.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.settings.applications.specialaccess.deviceadmin; - -import android.app.admin.DeviceAdminInfo; -import android.content.Context; -import android.content.pm.ActivityInfo; -import android.os.UserHandle; -import android.util.Log; - -import org.xmlpull.v1.XmlPullParserException; - -import java.io.IOException; - -public class DeviceAdminUtils { - - private static final String TAG = "DeviceAdminUtils"; - - /** - * Creates a device admin info object for the resolved intent that points to the component of - * the device admin. - * - * @param ai ActivityInfo for the admin component. - * @return new {@link DeviceAdminInfo} object or null if there was an error. - */ - public static DeviceAdminInfo createDeviceAdminInfo(Context context, ActivityInfo ai) { - try { - return new DeviceAdminInfo(context, ai); - } catch (XmlPullParserException | IOException e) { - Log.w(TAG, "Skipping " + ai, e); - } - return null; - } - - /** - * Extracts the user id from a device admin info object. - * - * @param adminInfo the device administrator info. - * @return identifier of the user associated with the device admin. - */ - public static int getUserIdFromDeviceAdminInfo(DeviceAdminInfo adminInfo) { - return UserHandle.getUserId(adminInfo.getActivityInfo().applicationInfo.uid); - } -} diff --git a/src/com/android/settings/deviceinfo/BuildNumberPreferenceController.java b/src/com/android/settings/deviceinfo/BuildNumberPreferenceController.java index ec0ab36d270..f13af9466cd 100644 --- a/src/com/android/settings/deviceinfo/BuildNumberPreferenceController.java +++ b/src/com/android/settings/deviceinfo/BuildNumberPreferenceController.java @@ -42,7 +42,6 @@ import com.android.settings.core.BasePreferenceController; import com.android.settings.core.InstrumentedPreferenceFragment; import com.android.settings.overlay.FeatureFactory; import com.android.settings.password.ChooseLockSettingsHelper; -import com.android.settings.slices.Copyable; import com.android.settingslib.RestrictedLockUtils; import com.android.settingslib.RestrictedLockUtilsInternal; import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; @@ -50,7 +49,7 @@ import com.android.settingslib.core.lifecycle.LifecycleObserver; import com.android.settingslib.core.lifecycle.events.OnStart; import com.android.settingslib.development.DevelopmentSettingsEnabler; -public class BuildNumberPreferenceController extends BasePreferenceController implements Copyable, +public class BuildNumberPreferenceController extends BasePreferenceController implements LifecycleObserver, OnStart { static final int TAPS_TO_BE_A_DEVELOPER = 7; @@ -108,6 +107,11 @@ public class BuildNumberPreferenceController extends BasePreferenceController im return true; } + @Override + public boolean isCopyableSlice() { + return true; + } + @Override public void copy() { final ClipboardManager clipboard = (ClipboardManager) mContext.getSystemService( diff --git a/src/com/android/settings/deviceinfo/HardwareInfoDialogFragment.java b/src/com/android/settings/deviceinfo/HardwareInfoDialogFragment.java deleted file mode 100644 index 34a714393dd..00000000000 --- a/src/com/android/settings/deviceinfo/HardwareInfoDialogFragment.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.settings.deviceinfo; - -import android.app.Dialog; -import android.app.settings.SettingsEnums; -import android.os.Build; -import android.os.Bundle; -import android.os.SystemProperties; -import android.text.TextUtils; -import android.view.LayoutInflater; -import android.view.View; -import android.widget.TextView; - -import androidx.annotation.VisibleForTesting; -import androidx.appcompat.app.AlertDialog; - -import com.android.settings.R; -import com.android.settings.core.instrumentation.InstrumentedDialogFragment; - -public class HardwareInfoDialogFragment extends InstrumentedDialogFragment { - - public static final String TAG = "HardwareInfo"; - - @Override - public int getMetricsCategory() { - return SettingsEnums.DIALOG_SETTINGS_HARDWARE_INFO; - } - - public static HardwareInfoDialogFragment newInstance() { - final HardwareInfoDialogFragment fragment = new HardwareInfoDialogFragment(); - return fragment; - } - - @Override - public Dialog onCreateDialog(Bundle savedInstanceState) { - final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()) - .setTitle(R.string.hardware_info) - .setPositiveButton(android.R.string.ok, null); - final View content = LayoutInflater.from(builder.getContext()) - .inflate(R.layout.dialog_hardware_info, null /* parent */); - // Model - setText(content, R.id.model_label, R.id.model_value, - DeviceModelPreferenceController.getDeviceModel()); - - // Serial number - setText(content, R.id.serial_number_label, R.id.serial_number_value, getSerialNumber()); - - // Hardware rev - setText(content, R.id.hardware_rev_label, R.id.hardware_rev_value, - SystemProperties.get("ro.boot.hardware.revision")); - - return builder.setView(content).create(); - } - - @VisibleForTesting - void setText(View content, int labelViewId, int valueViewId, String value) { - if (content == null) { - return; - } - final View labelView = content.findViewById(labelViewId); - final TextView valueView = content.findViewById(valueViewId); - if (!TextUtils.isEmpty(value)) { - labelView.setVisibility(View.VISIBLE); - valueView.setVisibility(View.VISIBLE); - valueView.setText(value); - } else { - labelView.setVisibility(View.GONE); - valueView.setVisibility(View.GONE); - } - } - - @VisibleForTesting - String getSerialNumber() { - return Build.getSerial(); - } -} diff --git a/src/com/android/settings/deviceinfo/DeviceModelPreferenceController.java b/src/com/android/settings/deviceinfo/HardwareInfoPreferenceController.java similarity index 71% rename from src/com/android/settings/deviceinfo/DeviceModelPreferenceController.java rename to src/com/android/settings/deviceinfo/HardwareInfoPreferenceController.java index 2797153457e..29f13912071 100644 --- a/src/com/android/settings/deviceinfo/DeviceModelPreferenceController.java +++ b/src/com/android/settings/deviceinfo/HardwareInfoPreferenceController.java @@ -17,11 +17,8 @@ package com.android.settings.deviceinfo; import android.content.Context; import android.os.Build; -import android.text.TextUtils; import android.util.Log; -import androidx.fragment.app.Fragment; -import androidx.preference.Preference; import androidx.preference.PreferenceScreen; import com.android.settings.R; @@ -31,21 +28,14 @@ import com.android.settingslib.DeviceInfoUtils; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; -public class DeviceModelPreferenceController extends BasePreferenceController { - +public class HardwareInfoPreferenceController extends BasePreferenceController { private static final String TAG = "DeviceModelPrefCtrl"; - private Fragment mHost; - - public DeviceModelPreferenceController(Context context, String key) { + public HardwareInfoPreferenceController(Context context, String key) { super(context, key); } - public void setHost(Fragment fragment) { - mHost = fragment; - } - @Override public void displayPreference(PreferenceScreen screen) { super.displayPreference(screen); @@ -54,7 +44,7 @@ public class DeviceModelPreferenceController extends BasePreferenceController { @Override public int getAvailabilityStatus() { return mContext.getResources().getBoolean(R.bool.config_show_device_model) - ? AVAILABLE : UNSUPPORTED_ON_DEVICE; + ? AVAILABLE_UNSEARCHABLE : UNSUPPORTED_ON_DEVICE; } @Override @@ -62,21 +52,6 @@ public class DeviceModelPreferenceController extends BasePreferenceController { return mContext.getResources().getString(R.string.model_summary, getDeviceModel()); } - @Override - public boolean handlePreferenceTreeClick(Preference preference) { - if (!TextUtils.equals(preference.getKey(), getPreferenceKey())) { - return false; - } - final HardwareInfoDialogFragment fragment = HardwareInfoDialogFragment.newInstance(); - fragment.show(mHost.getFragmentManager(), HardwareInfoDialogFragment.TAG); - return true; - } - - @Override - public boolean isSliceable() { - return true; - } - public static String getDeviceModel() { FutureTask msvSuffixTask = new FutureTask<>(() -> DeviceInfoUtils.getMsvSuffix()); diff --git a/src/com/android/settings/deviceinfo/PhoneNumberPreferenceController.java b/src/com/android/settings/deviceinfo/PhoneNumberPreferenceController.java index 598dfb1542f..3767860add0 100644 --- a/src/com/android/settings/deviceinfo/PhoneNumberPreferenceController.java +++ b/src/com/android/settings/deviceinfo/PhoneNumberPreferenceController.java @@ -35,14 +35,12 @@ import androidx.preference.PreferenceScreen; import com.android.settings.R; import com.android.settings.core.BasePreferenceController; -import com.android.settings.slices.Copyable; import com.android.settingslib.DeviceInfoUtils; import java.util.ArrayList; import java.util.List; -public class PhoneNumberPreferenceController extends BasePreferenceController implements - Copyable { +public class PhoneNumberPreferenceController extends BasePreferenceController { private final static String KEY_PHONE_NUMBER = "phone_number"; @@ -98,6 +96,11 @@ public class PhoneNumberPreferenceController extends BasePreferenceController im return true; } + @Override + public boolean isCopyableSlice() { + return true; + } + @Override public void copy() { final ClipboardManager clipboard = (ClipboardManager) mContext.getSystemService( diff --git a/src/com/android/settings/deviceinfo/aboutphone/MyDeviceInfoFragment.java b/src/com/android/settings/deviceinfo/aboutphone/MyDeviceInfoFragment.java index c20e857a803..e6afb7b821c 100644 --- a/src/com/android/settings/deviceinfo/aboutphone/MyDeviceInfoFragment.java +++ b/src/com/android/settings/deviceinfo/aboutphone/MyDeviceInfoFragment.java @@ -31,7 +31,6 @@ import com.android.settings.Utils; import com.android.settings.dashboard.DashboardFragment; import com.android.settings.deviceinfo.BluetoothAddressPreferenceController; import com.android.settings.deviceinfo.BuildNumberPreferenceController; -import com.android.settings.deviceinfo.DeviceModelPreferenceController; import com.android.settings.deviceinfo.DeviceNamePreferenceController; import com.android.settings.deviceinfo.FccEquipmentIdPreferenceController; import com.android.settings.deviceinfo.FeedbackPreferenceController; @@ -41,7 +40,6 @@ import com.android.settings.deviceinfo.RegulatoryInfoPreferenceController; import com.android.settings.deviceinfo.SafetyInfoPreferenceController; import com.android.settings.deviceinfo.UptimePreferenceController; import com.android.settings.deviceinfo.WifiMacAddressPreferenceController; -import com.android.settings.deviceinfo.firmwareversion.FirmwareVersionPreferenceController; import com.android.settings.deviceinfo.imei.ImeiInfoPreferenceController; import com.android.settings.deviceinfo.simstatus.SimStatusPreferenceController; import com.android.settings.search.BaseSearchIndexProvider; @@ -77,7 +75,6 @@ public class MyDeviceInfoFragment extends DashboardFragment @Override public void onAttach(Context context) { super.onAttach(context); - use(DeviceModelPreferenceController.class).setHost(this /* parent */); use(ImeiInfoPreferenceController.class).setHost(this /* parent */); use(DeviceNamePreferenceController.class).setHost(this /* parent */); mBuildNumberPreferenceController = use(BuildNumberPreferenceController.class); diff --git a/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionDetailPreferenceController.java b/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionDetailPreferenceController.java index 7a19fdef28e..9f3d6e5ed3b 100644 --- a/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionDetailPreferenceController.java +++ b/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionDetailPreferenceController.java @@ -31,12 +31,11 @@ import androidx.preference.Preference; import com.android.settings.R; import com.android.settings.Utils; import com.android.settings.core.BasePreferenceController; -import com.android.settings.slices.Copyable; +import com.android.settings.slices.Sliceable; import com.android.settingslib.RestrictedLockUtils; import com.android.settingslib.RestrictedLockUtilsInternal; -public class FirmwareVersionDetailPreferenceController extends BasePreferenceController implements - Copyable { +public class FirmwareVersionDetailPreferenceController extends BasePreferenceController { private static final String TAG = "firmwareDialogCtrl"; private static final int DELAY_TIMER_MILLIS = 500; @@ -119,7 +118,7 @@ public class FirmwareVersionDetailPreferenceController extends BasePreferenceCon @Override public void copy() { - Copyable.setCopyContent(mContext, getSummary(), + Sliceable.setCopyContent(mContext, getSummary(), mContext.getText(R.string.firmware_version)); } } diff --git a/src/com/android/settings/deviceinfo/hardwareinfo/DeviceModelPreferenceController.java b/src/com/android/settings/deviceinfo/hardwareinfo/DeviceModelPreferenceController.java new file mode 100644 index 00000000000..42c7b0104e7 --- /dev/null +++ b/src/com/android/settings/deviceinfo/hardwareinfo/DeviceModelPreferenceController.java @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.deviceinfo.hardwareinfo; + +import android.content.Context; + +import com.android.settings.deviceinfo.HardwareInfoPreferenceController; + +public class DeviceModelPreferenceController extends HardwareInfoPreferenceController { + + public DeviceModelPreferenceController(Context context, String key) { + super(context, key); + } + + @Override + public int getAvailabilityStatus() { + final int availability = super.getAvailabilityStatus(); + if (availability == AVAILABLE_UNSEARCHABLE) { + return AVAILABLE; + } + return availability; + } + + @Override + public boolean isSliceable() { + return true; + } +} diff --git a/src/com/android/settings/deviceinfo/hardwareinfo/HardwareInfoFragment.java b/src/com/android/settings/deviceinfo/hardwareinfo/HardwareInfoFragment.java new file mode 100644 index 00000000000..40e73efe882 --- /dev/null +++ b/src/com/android/settings/deviceinfo/hardwareinfo/HardwareInfoFragment.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.deviceinfo.hardwareinfo; + +import android.app.settings.SettingsEnums; +import android.content.Context; +import android.provider.SearchIndexableResource; + +import com.android.settings.R; +import com.android.settings.dashboard.DashboardFragment; +import com.android.settings.search.BaseSearchIndexProvider; +import com.android.settings.search.Indexable; +import com.android.settingslib.search.SearchIndexable; + +import java.util.ArrayList; +import java.util.List; + + +@SearchIndexable +public class HardwareInfoFragment extends DashboardFragment { + + public static final String TAG = "HardwareInfo"; + + @Override + public int getMetricsCategory() { + return SettingsEnums.DIALOG_SETTINGS_HARDWARE_INFO; + } + + @Override + protected int getPreferenceScreenResId() { + return R.xml.hardware_info; + } + + @Override + protected String getLogTag() { + return TAG; + } + + public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = + new BaseSearchIndexProvider() { + @Override + public List getXmlResourcesToIndex(Context context, + boolean enabled) { + final ArrayList result = new ArrayList<>(); + + final SearchIndexableResource sir = new SearchIndexableResource(context); + sir.xmlResId = R.xml.hardware_info; + result.add(sir); + return result; + } + + @Override + protected boolean isPageSearchEnabled(Context context) { + return context.getResources().getBoolean(R.bool.config_show_device_model); + } + }; +} diff --git a/src/com/android/settings/deviceinfo/hardwareinfo/HardwareRevisionPreferenceController.java b/src/com/android/settings/deviceinfo/hardwareinfo/HardwareRevisionPreferenceController.java new file mode 100644 index 00000000000..ec0cdb2a362 --- /dev/null +++ b/src/com/android/settings/deviceinfo/hardwareinfo/HardwareRevisionPreferenceController.java @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.deviceinfo.hardwareinfo; + +import android.content.Context; +import android.os.SystemProperties; + +import com.android.settings.R; +import com.android.settings.core.BasePreferenceController; + +public class HardwareRevisionPreferenceController extends BasePreferenceController { + + public HardwareRevisionPreferenceController(Context context, String preferenceKey) { + super(context, preferenceKey); + } + + @Override + public int getAvailabilityStatus() { + return mContext.getResources().getBoolean(R.bool.config_show_device_model) + ? AVAILABLE : UNSUPPORTED_ON_DEVICE; + } + + @Override + public boolean isSliceable() { + return true; + } + + @Override + public CharSequence getSummary() { + return SystemProperties.get("ro.boot.hardware.revision"); + } +} diff --git a/src/com/android/settings/deviceinfo/hardwareinfo/SerialNumberPreferenceController.java b/src/com/android/settings/deviceinfo/hardwareinfo/SerialNumberPreferenceController.java new file mode 100644 index 00000000000..01cd5f3b9e4 --- /dev/null +++ b/src/com/android/settings/deviceinfo/hardwareinfo/SerialNumberPreferenceController.java @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.deviceinfo.hardwareinfo; + +import android.content.Context; +import android.os.Build; + +import com.android.settings.R; +import com.android.settings.core.BasePreferenceController; +import com.android.settings.slices.Sliceable; + +public class SerialNumberPreferenceController extends BasePreferenceController { + + public SerialNumberPreferenceController(Context context, String preferenceKey) { + super(context, preferenceKey); + } + + @Override + public int getAvailabilityStatus() { + return mContext.getResources().getBoolean(R.bool.config_show_device_model) + ? AVAILABLE : UNSUPPORTED_ON_DEVICE; + } + + @Override + public boolean isSliceable() { + return true; + } + + @Override + public boolean isCopyableSlice() { + return true; + } + + @Override + public void copy() { + Sliceable.setCopyContent(mContext, getSummary(), + mContext.getText(R.string.status_serial_number)); + } + + @Override + public CharSequence getSummary() { + return Build.getSerial(); + } +} diff --git a/src/com/android/settings/deviceinfo/imei/ImeiInfoPreferenceController.java b/src/com/android/settings/deviceinfo/imei/ImeiInfoPreferenceController.java index 96ff83c6f84..77d975ed1eb 100644 --- a/src/com/android/settings/deviceinfo/imei/ImeiInfoPreferenceController.java +++ b/src/com/android/settings/deviceinfo/imei/ImeiInfoPreferenceController.java @@ -29,7 +29,7 @@ import androidx.preference.PreferenceScreen; import com.android.settings.R; import com.android.settings.core.BasePreferenceController; -import com.android.settings.slices.Copyable; +import com.android.settings.slices.Sliceable; import com.android.settingslib.Utils; import java.util.ArrayList; @@ -38,7 +38,7 @@ import java.util.List; /** * Controller that manages preference for single and multi sim devices. */ -public class ImeiInfoPreferenceController extends BasePreferenceController implements Copyable { +public class ImeiInfoPreferenceController extends BasePreferenceController { private final boolean mIsMultiSim; private final TelephonyManager mTelephonyManager; @@ -105,9 +105,14 @@ public class ImeiInfoPreferenceController extends BasePreferenceController imple return true; } + @Override + public boolean isCopyableSlice() { + return true; + } + @Override public void copy() { - Copyable.setCopyContent(mContext, getSummary(), mContext.getText(R.string.status_imei)); + Sliceable.setCopyContent(mContext, getSummary(), mContext.getText(R.string.status_imei)); } private void updatePreference(Preference preference, int simSlot) { diff --git a/src/com/android/settings/fuelgauge/batterytip/StatsManagerConfig.java b/src/com/android/settings/fuelgauge/batterytip/StatsManagerConfig.java index a0449f2e09e..153aa408698 100644 --- a/src/com/android/settings/fuelgauge/batterytip/StatsManagerConfig.java +++ b/src/com/android/settings/fuelgauge/batterytip/StatsManagerConfig.java @@ -65,6 +65,11 @@ public class StatsManagerConfig { AnomalyType.EXCESSIVE_CRASH_RATE, AnomalyType.EXCESSIVE_CRASH_LOOPING, AnomalyType.NUMBER_OF_OPEN_FILES, + AnomalyType.EXCESSIVE_CAMERA_USAGE_IN_BACKGROUND, + AnomalyType.EXCESSIVE_CONTACT_ACCESS, + AnomalyType.EXCESSIVE_AUDIO_IN_BACKGROUND, + AnomalyType.EXCESSIVE_CRASH_ANR_IN_BACKGROUND, + AnomalyType.BATTERY_DRAIN_FROM_UNUSED_APP, }) public @interface AnomalyType { /** @@ -218,6 +223,42 @@ public class StatsManagerConfig { * The application crashed because no more file descriptors were available. */ int NUMBER_OF_OPEN_FILES = 26; + + /** + * The application used an excessive amount of CPU while in a + * background process state. + */ + int EXCESSIVE_CPU_USAGE_IN_BACKGROUND = 27; + + /** + * The application kept the camera open for an excessive amount + * of time while in a bckground process state. + */ + int EXCESSIVE_CAMERA_USAGE_IN_BACKGROUND = 28; + + /** + * The application has accessed the contacts content provider an + * excessive amount. + */ + int EXCESSIVE_CONTACT_ACCESS = 29; + + /** + * The application has played too much audio while in a background + * process state. + */ + int EXCESSIVE_AUDIO_IN_BACKGROUND = 30; + + /** + * The application has crashed or ANRed too many times while in a + * background process state. + */ + int EXCESSIVE_CRASH_ANR_IN_BACKGROUND = 31; + + /** + * An application which has not been used by the user recently + * was detected to cause an excessive amount of battery drain. + */ + int BATTERY_DRAIN_FROM_UNUSED_APP = 32; } } diff --git a/src/com/android/settings/gestures/PreventRingingSwitchPreferenceController.java b/src/com/android/settings/gestures/PreventRingingSwitchPreferenceController.java index 35ff2ec5cf4..e21bb7563bf 100644 --- a/src/com/android/settings/gestures/PreventRingingSwitchPreferenceController.java +++ b/src/com/android/settings/gestures/PreventRingingSwitchPreferenceController.java @@ -61,6 +61,17 @@ public class PreventRingingSwitchPreferenceController extends AbstractPreference LayoutPreference pref = screen.findPreference(getPreferenceKey()); if (pref != null) { mSettingObserver = new SettingObserver(pref); + pref.setOnPreferenceClickListener(preference -> { + int preventRinging = Settings.Secure.getInt(mContext.getContentResolver(), + Settings.Secure.VOLUME_HUSH_GESTURE, + Settings.Secure.VOLUME_HUSH_VIBRATE); + boolean isChecked = preventRinging != Settings.Secure.VOLUME_HUSH_OFF; + Settings.Secure.putInt(mContext.getContentResolver(), + Settings.Secure.VOLUME_HUSH_GESTURE, isChecked + ? Settings.Secure.VOLUME_HUSH_OFF + : Settings.Secure.VOLUME_HUSH_VIBRATE); + return true; + }); mSwitch = pref.findViewById(R.id.switch_bar); if (mSwitch != null) { mSwitch.addOnSwitchChangeListener(this); diff --git a/src/com/android/settings/homepage/contextualcards/ContextualCardLoader.java b/src/com/android/settings/homepage/contextualcards/ContextualCardLoader.java index 42e18edd689..d6ea6ca668a 100644 --- a/src/com/android/settings/homepage/contextualcards/ContextualCardLoader.java +++ b/src/com/android/settings/homepage/contextualcards/ContextualCardLoader.java @@ -23,6 +23,7 @@ import static com.android.settings.slices.CustomSliceRegistry.NOTIFICATION_CHANN import android.content.Context; import android.database.ContentObserver; import android.database.Cursor; +import android.net.Uri; import android.os.Handler; import android.os.Looper; import android.text.format.DateUtils; diff --git a/src/com/android/settings/homepage/contextualcards/deviceinfo/DeviceInfoSlice.java b/src/com/android/settings/homepage/contextualcards/deviceinfo/DeviceInfoSlice.java index e278baae130..48a9aa54617 100644 --- a/src/com/android/settings/homepage/contextualcards/deviceinfo/DeviceInfoSlice.java +++ b/src/com/android/settings/homepage/contextualcards/deviceinfo/DeviceInfoSlice.java @@ -36,7 +36,7 @@ import androidx.slice.builders.SliceAction; import com.android.settings.R; import com.android.settings.SubSettings; import com.android.settings.Utils; -import com.android.settings.deviceinfo.DeviceModelPreferenceController; +import com.android.settings.deviceinfo.HardwareInfoPreferenceController; import com.android.settings.deviceinfo.aboutphone.MyDeviceInfoFragment; import com.android.settings.slices.CustomSliceRegistry; import com.android.settings.slices.CustomSliceable; @@ -107,7 +107,7 @@ public class DeviceInfoSlice implements CustomSliceable { } private CharSequence getDeviceModel() { - return DeviceModelPreferenceController.getDeviceModel(); + return HardwareInfoPreferenceController.getDeviceModel(); } @VisibleForTesting diff --git a/src/com/android/settings/nfc/NfcPreferenceController.java b/src/com/android/settings/nfc/NfcPreferenceController.java index 04f288d721b..2ca3b23daea 100644 --- a/src/com/android/settings/nfc/NfcPreferenceController.java +++ b/src/com/android/settings/nfc/NfcPreferenceController.java @@ -15,20 +15,26 @@ */ package com.android.settings.nfc; +import android.content.BroadcastReceiver; import android.content.Context; +import android.content.Intent; import android.content.IntentFilter; +import android.net.Uri; import android.nfc.NfcAdapter; import android.provider.Settings; - +import android.util.Log; import androidx.annotation.VisibleForTesting; import androidx.preference.PreferenceScreen; import androidx.preference.SwitchPreference; import com.android.settings.core.TogglePreferenceController; +import com.android.settings.slices.SliceBackgroundWorker; import com.android.settingslib.core.lifecycle.LifecycleObserver; import com.android.settingslib.core.lifecycle.events.OnPause; import com.android.settingslib.core.lifecycle.events.OnResume; +import java.io.IOException; + public class NfcPreferenceController extends TogglePreferenceController implements LifecycleObserver, OnResume, OnPause { @@ -51,8 +57,7 @@ public class NfcPreferenceController extends TogglePreferenceController return; } - final SwitchPreference switchPreference = - (SwitchPreference) screen.findPreference(getPreferenceKey()); + final SwitchPreference switchPreference = screen.findPreference(getPreferenceKey()); mNfcEnabler = new NfcEnabler(mContext, switchPreference); @@ -86,14 +91,6 @@ public class NfcPreferenceController extends TogglePreferenceController : UNSUPPORTED_ON_DEVICE; } - @Override - public IntentFilter getIntentFilter() { - final IntentFilter filter = new IntentFilter(); - filter.addAction(NfcAdapter.ACTION_ADAPTER_STATE_CHANGED); - filter.addAction(NfcAdapter.EXTRA_ADAPTER_STATE); - return filter; - } - @Override public boolean hasAsyncUpdate() { return true; @@ -104,6 +101,11 @@ public class NfcPreferenceController extends TogglePreferenceController return true; } + @Override + public Class getBackgroundWorkerClass() { + return NfcSliceWorker.class; + } + @Override public void onResume() { if (mAirplaneModeObserver != null) { @@ -135,4 +137,77 @@ public class NfcPreferenceController extends TogglePreferenceController Settings.Global.AIRPLANE_MODE_TOGGLEABLE_RADIOS); return toggleable != null && toggleable.contains(Settings.Global.RADIO_NFC); } + + /** + * Listener for background changes to NFC. + * + *

+ * Listen to broadcasts from {@link NfcAdapter}. The worker will call notify changed on the + * NFC Slice only when the following extras are present in the broadcast: + *

    + *
  • {@link NfcAdapter#STATE_ON}
  • + *
  • {@link NfcAdapter#STATE_OFF}
  • + *
+ */ + public static class NfcSliceWorker extends SliceBackgroundWorker { + + private static final String TAG = "NfcSliceWorker"; + + private static final IntentFilter NFC_FILTER = + new IntentFilter(NfcAdapter.ACTION_ADAPTER_STATE_CHANGED); + + private NfcUpdateReceiver mUpdateObserver; + + public NfcSliceWorker(Context context, Uri uri) { + super(context, uri); + mUpdateObserver = new NfcUpdateReceiver(this); + } + + @Override + protected void onSlicePinned() { + getContext().registerReceiver(mUpdateObserver, NFC_FILTER); + } + + @Override + protected void onSliceUnpinned() { + getContext().unregisterReceiver(mUpdateObserver); + } + + @Override + public void close() throws IOException { + mUpdateObserver = null; + } + + public void updateSlice() { + notifySliceChange(); + } + + public class NfcUpdateReceiver extends BroadcastReceiver { + + private final int NO_EXTRA = -1; + + private final NfcSliceWorker mSliceBackgroundWorker; + + public NfcUpdateReceiver(NfcSliceWorker sliceWorker) { + mSliceBackgroundWorker = sliceWorker; + } + + @Override + public void onReceive(Context context, Intent intent) { + final int nfcStateExtra = intent.getIntExtra(NfcAdapter.EXTRA_ADAPTER_STATE, + NO_EXTRA); + + // Do nothing if state change is empty, or an intermediate step. + if ( (nfcStateExtra == NO_EXTRA) + || (nfcStateExtra == NfcAdapter.STATE_TURNING_ON) + || (nfcStateExtra == NfcAdapter.STATE_TURNING_OFF)) { + Log.d(TAG, "Transitional update, dropping broadcast"); + return; + } + + Log.d(TAG, "Nfc broadcast received, updating Slice."); + mSliceBackgroundWorker.updateSlice(); + } + } + } } diff --git a/src/com/android/settings/notification/NotificationAssistantPreferenceController.java b/src/com/android/settings/notification/NotificationAssistantPreferenceController.java index 5c591b894ac..66f27fef953 100644 --- a/src/com/android/settings/notification/NotificationAssistantPreferenceController.java +++ b/src/com/android/settings/notification/NotificationAssistantPreferenceController.java @@ -16,18 +16,46 @@ package com.android.settings.notification; +import android.content.ComponentName; import android.content.Context; +import android.content.pm.PackageManager; +import android.os.UserHandle; import com.android.settings.core.BasePreferenceController; +import com.android.settingslib.applications.DefaultAppInfo; +import com.android.settingslib.widget.CandidateInfo; + +import com.google.common.annotations.VisibleForTesting; public class NotificationAssistantPreferenceController extends BasePreferenceController { + @VisibleForTesting + protected NotificationBackend mNotificationBackend; + private PackageManager mPackageManager; + public NotificationAssistantPreferenceController(Context context, String preferenceKey) { super(context, preferenceKey); + mNotificationBackend = new NotificationBackend(); + mPackageManager = mContext.getPackageManager(); } @Override public int getAvailabilityStatus() { return BasePreferenceController.AVAILABLE; } + + @Override + public CharSequence getSummary() { + CandidateInfo appSelected = new NotificationAssistantPicker.CandidateNone(mContext); + ComponentName assistant = mNotificationBackend.getAllowedNotificationAssistant(); + if (assistant != null) { + appSelected = createCandidateInfo(assistant); + } + return appSelected.loadLabel(); + } + + @VisibleForTesting + protected CandidateInfo createCandidateInfo(ComponentName cn) { + return new DefaultAppInfo(mContext, mPackageManager, UserHandle.myUserId(), cn); + } } diff --git a/src/com/android/settings/notification/RingtonePreferenceControllerBase.java b/src/com/android/settings/notification/RingtonePreferenceControllerBase.java index 7b37855c6f7..733d0d937d7 100644 --- a/src/com/android/settings/notification/RingtonePreferenceControllerBase.java +++ b/src/com/android/settings/notification/RingtonePreferenceControllerBase.java @@ -50,13 +50,18 @@ public abstract class RingtonePreferenceControllerBase extends AbstractPreferenc } private void updateSummary(Preference preference) { - Uri ringtoneUri = RingtoneManager.getActualDefaultRingtoneUri(mContext, getRingtoneType()); - final CharSequence summary = Ringtone.getTitle( - mContext, ringtoneUri, false /* followSettingsUri */, true /* allowRemote */); + final Uri ringtoneUri = RingtoneManager.getActualDefaultRingtoneUri( + mContext, getRingtoneType()); + + final CharSequence summary; + if (ringtoneUri == null) { + summary = null; + } else { + summary = Ringtone.getTitle( + mContext, ringtoneUri, false /* followSettingsUri */, true /* allowRemote */); + } if (summary != null) { - ThreadUtils.postOnMainThread(() -> { - preference.setSummary(summary); - }); + ThreadUtils.postOnMainThread(() -> preference.setSummary(summary)); } } diff --git a/src/com/android/settings/slices/Copyable.java b/src/com/android/settings/slices/Copyable.java deleted file mode 100644 index a480063a71c..00000000000 --- a/src/com/android/settings/slices/Copyable.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.settings.slices; - -import static android.content.Context.CLIPBOARD_SERVICE; - -import android.content.ClipData; -import android.content.ClipboardManager; -import android.content.Context; -import android.widget.Toast; - -import com.android.settings.R; - -/** - * Provide the copy ability for preference controller to copy the data to the clipboard. - */ -public interface Copyable { - /** - * Copy the key slice information to the clipboard. - * It is highly recommended to show the toast to notify users when implemented this function. - */ - void copy(); - - /** - * Set the copy content to the clipboard and show the toast. - */ - static void setCopyContent(Context context, CharSequence copyContent, - CharSequence messageTitle) { - final ClipboardManager clipboard = (ClipboardManager) context.getSystemService( - CLIPBOARD_SERVICE); - final ClipData clip = ClipData.newPlainText("text", copyContent); - clipboard.setPrimaryClip(clip); - - final String toast = context.getString(R.string.copyable_slice_toast, messageTitle); - Toast.makeText(context, toast, Toast.LENGTH_SHORT).show(); - } -} diff --git a/src/com/android/settings/slices/CustomSliceable.java b/src/com/android/settings/slices/CustomSliceable.java index b48f22a5237..0b97bedc54f 100644 --- a/src/com/android/settings/slices/CustomSliceable.java +++ b/src/com/android/settings/slices/CustomSliceable.java @@ -83,18 +83,6 @@ public interface CustomSliceable extends Sliceable { */ Intent getIntent(); - /** - * Settings Slices which require background work, such as updating lists should implement a - * {@link SliceBackgroundWorker} and return it here. An example of background work is updating - * a list of Wifi networks available in the area. - * - * @return a {@link Class} to perform background work for the - * slice. - */ - default Class getBackgroundWorkerClass() { - return null; - } - /** * Standardize the intents returned to indicate actions by the Slice. *

diff --git a/src/com/android/settings/slices/SettingsSliceProvider.java b/src/com/android/settings/slices/SettingsSliceProvider.java index 5c662e5c7e0..397b2fc631c 100644 --- a/src/com/android/settings/slices/SettingsSliceProvider.java +++ b/src/com/android/settings/slices/SettingsSliceProvider.java @@ -153,7 +153,7 @@ public class SettingsSliceProvider extends SliceProvider { if (filter != null) { registerIntentToUri(filter, sliceUri); } - ThreadUtils.postOnMainThread(() -> startBackgroundWorker(sliceable)); + ThreadUtils.postOnMainThread(() -> startBackgroundWorker(sliceable, sliceUri)); return; } @@ -326,20 +326,19 @@ public class SettingsSliceProvider extends SliceProvider { } } - private void startBackgroundWorker(CustomSliceable sliceable) { + private void startBackgroundWorker(Sliceable sliceable, Uri uri) { final Class workerClass = sliceable.getBackgroundWorkerClass(); if (workerClass == null) { return; } - final Uri uri = sliceable.getUri(); if (mPinnedWorkers.containsKey(uri)) { return; } Log.d(TAG, "Starting background worker for: " + uri); final SliceBackgroundWorker worker = SliceBackgroundWorker.getInstance( - getContext(), sliceable); + getContext(), sliceable, uri); mPinnedWorkers.put(uri, worker); worker.onSlicePinned(); } @@ -397,6 +396,8 @@ public class SettingsSliceProvider extends SliceProvider { registerIntentToUri(filter, uri); } + ThreadUtils.postOnMainThread(() -> startBackgroundWorker(controller, uri)); + final List pinnedSlices = getContext().getSystemService( SliceManager.class).getPinnedSlices(); if (pinnedSlices.contains(uri)) { diff --git a/src/com/android/settings/slices/SliceBackgroundWorker.java b/src/com/android/settings/slices/SliceBackgroundWorker.java index 995394e7d41..559aa711e2a 100644 --- a/src/com/android/settings/slices/SliceBackgroundWorker.java +++ b/src/com/android/settings/slices/SliceBackgroundWorker.java @@ -80,13 +80,12 @@ public abstract class SliceBackgroundWorker implements Closeable { * Returns the singleton instance of the {@link SliceBackgroundWorker} for specified {@link * CustomSliceable} */ - static SliceBackgroundWorker getInstance(Context context, CustomSliceable sliceable) { - final Uri uri = sliceable.getUri(); + static SliceBackgroundWorker getInstance(Context context, Sliceable sliceable, Uri uri) { SliceBackgroundWorker worker = getInstance(uri); if (worker == null) { final Class workerClass = sliceable.getBackgroundWorkerClass(); - worker = createInstance(context, uri, workerClass); + worker = createInstance(context.getApplicationContext(), uri, workerClass); LIVE_WORKERS.put(uri, worker); } return worker; diff --git a/src/com/android/settings/slices/SliceBroadcastReceiver.java b/src/com/android/settings/slices/SliceBroadcastReceiver.java index 061cf1893f7..b2ea5830fe2 100644 --- a/src/com/android/settings/slices/SliceBroadcastReceiver.java +++ b/src/com/android/settings/slices/SliceBroadcastReceiver.java @@ -184,7 +184,7 @@ public class SliceBroadcastReceiver extends BroadcastReceiver { final BasePreferenceController controller = getPreferenceController(context, key); - if (!(controller instanceof Copyable)) { + if (!(controller instanceof Sliceable)) { throw new IllegalArgumentException( "Copyable action passed for a non-copyable key:" + key); } @@ -197,7 +197,7 @@ public class SliceBroadcastReceiver extends BroadcastReceiver { return; } - ((Copyable) controller).copy(); + controller.copy(); } /** diff --git a/src/com/android/settings/slices/SliceBuilderUtils.java b/src/com/android/settings/slices/SliceBuilderUtils.java index 8f8543131ab..c3869a6d5d6 100644 --- a/src/com/android/settings/slices/SliceBuilderUtils.java +++ b/src/com/android/settings/slices/SliceBuilderUtils.java @@ -93,7 +93,7 @@ public class SliceBuilderUtils { return buildUnavailableSlice(context, sliceData); } - if (controller instanceof Copyable) { + if (controller.isCopyableSlice()) { return buildCopyableSlice(context, sliceData, controller); } diff --git a/src/com/android/settings/slices/Sliceable.java b/src/com/android/settings/slices/Sliceable.java index ddec2e1a973..c1661f8392a 100644 --- a/src/com/android/settings/slices/Sliceable.java +++ b/src/com/android/settings/slices/Sliceable.java @@ -16,7 +16,15 @@ package com.android.settings.slices; +import static android.content.Context.CLIPBOARD_SERVICE; + +import android.content.ClipData; +import android.content.ClipboardManager; +import android.content.Context; import android.content.IntentFilter; +import android.widget.Toast; + +import com.android.settings.R; /** * A collection of API making a PreferenceController "sliceable" @@ -55,4 +63,44 @@ public interface Sliceable { default boolean hasAsyncUpdate() { return false; } + + /** + * Copy the key slice information to the clipboard. + * It is highly recommended to show the toast to notify users when implemented this function. + */ + default void copy() { + } + + /** + * Whether or not it's a copyable slice. + */ + default boolean isCopyableSlice() { + return false; + } + + /** + * Set the copy content to the clipboard and show the toast. + */ + static void setCopyContent(Context context, CharSequence copyContent, + CharSequence messageTitle) { + final ClipboardManager clipboard = (ClipboardManager) context.getSystemService( + CLIPBOARD_SERVICE); + final ClipData clip = ClipData.newPlainText("text", copyContent); + clipboard.setPrimaryClip(clip); + + final String toast = context.getString(R.string.copyable_slice_toast, messageTitle); + Toast.makeText(context, toast, Toast.LENGTH_SHORT).show(); + } + + /** + * Settings Slices which require background work, such as updating lists should implement a + * {@link SliceBackgroundWorker} and return it here. An example of background work is updating + * a list of Wifi networks available in the area. + * + * @return a {@link Class} to perform background work for the + * slice. + */ + default Class getBackgroundWorkerClass() { + return null; + } } diff --git a/src/com/android/settings/slices/SlicesIndexer.java b/src/com/android/settings/slices/SlicesIndexer.java index ec2be2922de..1b3a25ef876 100644 --- a/src/com/android/settings/slices/SlicesIndexer.java +++ b/src/com/android/settings/slices/SlicesIndexer.java @@ -71,7 +71,7 @@ class SlicesIndexer implements Runnable { long startTime = System.currentTimeMillis(); database.beginTransaction(); try { - mHelper.reconstruct(mHelper.getWritableDatabase()); + mHelper.reconstruct(database); List indexData = getSliceData(); insertSliceData(database, indexData); diff --git a/src/com/android/settings/wifi/AddNetworkFragment.java b/src/com/android/settings/wifi/AddNetworkFragment.java index 651b25f8a9e..81b6c85dfc9 100644 --- a/src/com/android/settings/wifi/AddNetworkFragment.java +++ b/src/com/android/settings/wifi/AddNetworkFragment.java @@ -19,12 +19,14 @@ package com.android.settings.wifi; import android.app.Activity; import android.app.settings.SettingsEnums; import android.content.Intent; +import android.net.wifi.WifiConfiguration; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.ImageButton; +import android.widget.TextView; import androidx.annotation.VisibleForTesting; @@ -40,7 +42,10 @@ public class AddNetworkFragment extends InstrumentedFragment implements WifiConf final static int SUBMIT_BUTTON_ID = android.R.id.button1; @VisibleForTesting final static int CANCEL_BUTTON_ID = android.R.id.button2; - final static int SCANNER_BUTTON_ID = R.id.ssid_scanner_button; + final static int SSID_SCANNER_BUTTON_ID = R.id.ssid_scanner_button; + final static int PASSWORD_SCANNER_BUTTON_ID = R.id.password_scanner_button; + + private static final int REQUEST_CODE_WIFI_DPP_ENROLLEE_QR_CODE_SCANNER = 0; private WifiConfigController mUIController; private Button mSubmitBtn; @@ -68,10 +73,12 @@ public class AddNetworkFragment extends InstrumentedFragment implements WifiConf mSubmitBtn = rootView.findViewById(SUBMIT_BUTTON_ID); mCancelBtn = rootView.findViewById(CANCEL_BUTTON_ID); - final ImageButton scannerButton = rootView.findViewById(SCANNER_BUTTON_ID); + final ImageButton ssidScannerButton = rootView.findViewById(SSID_SCANNER_BUTTON_ID); + final ImageButton passwordScannerButton = rootView.findViewById(PASSWORD_SCANNER_BUTTON_ID); mSubmitBtn.setOnClickListener(this); mCancelBtn.setOnClickListener(this); - scannerButton.setOnClickListener(this); + ssidScannerButton.setOnClickListener(this); + passwordScannerButton.setOnClickListener(this); mUIController = new WifiConfigController(this, rootView, null, getMode()); return rootView; @@ -85,6 +92,8 @@ public class AddNetworkFragment extends InstrumentedFragment implements WifiConf @Override public void onClick(View view) { + String ssid = null; + switch (view.getId()) { case SUBMIT_BUTTON_ID: handleSubmitAction(); @@ -92,14 +101,33 @@ public class AddNetworkFragment extends InstrumentedFragment implements WifiConf case CANCEL_BUTTON_ID: handleCancelAction(); break; - case SCANNER_BUTTON_ID: + case SSID_SCANNER_BUTTON_ID: + final TextView ssidEditText = getView().findViewById(R.id.ssid); + ssid = ssidEditText.getText().toString(); + // No break and flows to case PASSWORD_SCANNER_BUTTON_ID + case PASSWORD_SCANNER_BUTTON_ID: // Launch QR code scanner to join a network. - getContext().startActivity( - WifiDppUtils.getEnrolleeQrCodeScannerIntent(/* ssid */ null)); + startActivityForResult(WifiDppUtils.getEnrolleeQrCodeScannerIntent(ssid), + REQUEST_CODE_WIFI_DPP_ENROLLEE_QR_CODE_SCANNER); break; } } + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + + if (requestCode == REQUEST_CODE_WIFI_DPP_ENROLLEE_QR_CODE_SCANNER) { + if (resultCode != Activity.RESULT_OK) { + return; + } + + final WifiConfiguration config = data.getParcelableExtra( + WifiDialogActivity.KEY_WIFI_CONFIGURATION); + successfullyFinish(config); + } + } + @Override public int getMode() { return WifiConfigUiBase.MODE_CONNECT; @@ -158,9 +186,13 @@ public class AddNetworkFragment extends InstrumentedFragment implements WifiConf @VisibleForTesting void handleSubmitAction() { + successfullyFinish(mUIController.getConfig()); + } + + private void successfullyFinish(WifiConfiguration config) { final Intent intent = new Intent(); final Activity activity = getActivity(); - intent.putExtra(WIFI_CONFIG_KEY, mUIController.getConfig()); + intent.putExtra(WIFI_CONFIG_KEY, config); activity.setResult(Activity.RESULT_OK, intent); activity.finish(); } diff --git a/src/com/android/settings/wifi/WifiDialog.java b/src/com/android/settings/wifi/WifiDialog.java index 7d5f3b30f4f..fbea824a00d 100644 --- a/src/com/android/settings/wifi/WifiDialog.java +++ b/src/com/android/settings/wifi/WifiDialog.java @@ -18,15 +18,16 @@ package com.android.settings.wifi; import android.content.Context; import android.content.DialogInterface; +import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.ImageButton; +import android.widget.TextView; import androidx.appcompat.app.AlertDialog; import com.android.settings.R; -import com.android.settings.wifi.dpp.WifiDppUtils; import com.android.settingslib.RestrictedLockUtils; import com.android.settingslib.RestrictedLockUtilsInternal; import com.android.settingslib.wifi.AccessPoint; @@ -40,6 +41,9 @@ public class WifiDialog extends AlertDialog implements WifiConfigUiBase, default void onSubmit(WifiDialog dialog) { } + + default void onScan(WifiDialog dialog, String ssid) { + } } private static final int BUTTON_SUBMIT = DialogInterface.BUTTON_POSITIVE; @@ -80,18 +84,6 @@ public class WifiDialog extends AlertDialog implements WifiConfigUiBase, @Override protected void onCreate(Bundle savedInstanceState) { mView = getLayoutInflater().inflate(R.layout.wifi_dialog, /* root */ null); - final ImageButton scannerButton = mView.findViewById(R.id.password_scanner_button); - if (scannerButton != null) { - scannerButton.setOnClickListener((View v) -> { - String ssid = null; - if (mAccessPoint != null) { - ssid = mAccessPoint.getSsidStr(); - } - // Launch QR code scanner to join a network. - getContext().startActivity( - WifiDppUtils.getEnrolleeQrCodeScannerIntent(ssid)); - }); - } setView(mView); mController = new WifiConfigController(this, mView, mAccessPoint, mMode); super.onCreate(savedInstanceState); @@ -109,6 +101,35 @@ public class WifiDialog extends AlertDialog implements WifiConfigUiBase, } } + @Override + protected void onStart() { + View.OnClickListener onClickScannerButtonListener = v -> { + if (mListener == null) { + return; + } + + String ssid = null; + if (mAccessPoint == null) { + final TextView ssidEditText = findViewById(R.id.ssid); + ssid = ssidEditText.getText().toString(); + } else { + ssid = mAccessPoint.getSsidStr(); + } + mListener.onScan(/* WifiDialog */ this, ssid); + }; + + final ImageButton ssidScannerButton = findViewById(R.id.ssid_scanner_button); + ssidScannerButton.setOnClickListener(onClickScannerButtonListener); + + final ImageButton passwordScannerButton = findViewById(R.id.password_scanner_button); + passwordScannerButton.setOnClickListener(onClickScannerButtonListener); + + if (mHideSubmitButton) { + ssidScannerButton.setVisibility(View.GONE); + passwordScannerButton.setVisibility(View.GONE); + } + } + public void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); mController.updatePassword(); diff --git a/src/com/android/settings/wifi/WifiDialogActivity.java b/src/com/android/settings/wifi/WifiDialogActivity.java index c32bcf3d0c6..35de66e265d 100644 --- a/src/com/android/settings/wifi/WifiDialogActivity.java +++ b/src/com/android/settings/wifi/WifiDialogActivity.java @@ -29,6 +29,7 @@ import android.util.Log; import androidx.annotation.VisibleForTesting; import com.android.settings.SetupWizardUtils; +import com.android.settings.wifi.dpp.WifiDppUtils; import com.android.settingslib.wifi.AccessPoint; import com.google.android.setupcompat.util.WizardManagerHelper; @@ -49,10 +50,13 @@ public class WifiDialogActivity extends Activity implements WifiDialog.WifiDialo @VisibleForTesting static final String KEY_CONNECT_FOR_CALLER = "connect_for_caller"; - private static final String KEY_WIFI_CONFIGURATION = "wifi_configuration"; + public static final String KEY_WIFI_CONFIGURATION = "wifi_configuration"; + private static final int RESULT_CONNECTED = RESULT_FIRST_USER; private static final int RESULT_FORGET = RESULT_FIRST_USER + 1; + private static final int REQUEST_CODE_WIFI_DPP_ENROLLEE_QR_CODE_SCANNER = 0; + private WifiDialog mDialog; @Override @@ -162,4 +166,25 @@ public class WifiDialogActivity extends Activity implements WifiDialog.WifiDialo mDialog = null; finish(); } + + @Override + public void onScan(WifiDialog dialog, String ssid) { + // Launch QR code scanner to join a network. + startActivityForResult(WifiDppUtils.getEnrolleeQrCodeScannerIntent(ssid), + REQUEST_CODE_WIFI_DPP_ENROLLEE_QR_CODE_SCANNER); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + + if (requestCode == REQUEST_CODE_WIFI_DPP_ENROLLEE_QR_CODE_SCANNER) { + if (resultCode != RESULT_OK) { + return; + } + + setResult(RESULT_CONNECTED, data); + finish(); + } + } } diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java index 4ca9f8680c0..27c495ed3db 100644 --- a/src/com/android/settings/wifi/WifiSettings.java +++ b/src/com/android/settings/wifi/WifiSettings.java @@ -117,6 +117,8 @@ public class WifiSettings extends RestrictedSettingsFragment private static final String PREF_KEY_SAVED_NETWORKS = "saved_networks"; private static final String PREF_KEY_STATUS_MESSAGE = "wifi_status_message"; + private static final int REQUEST_CODE_WIFI_DPP_ENROLLEE_QR_CODE_SCANNER = 0; + private static boolean isVerboseLoggingEnabled() { return WifiTracker.sVerboseLogging || Log.isLoggable(TAG, Log.VERBOSE); } @@ -427,10 +429,17 @@ public class WifiSettings extends RestrictedSettingsFragment public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); - // Only handle request comes from AddNetworkFragment if (requestCode == ADD_NETWORK_REQUEST) { handleAddNetworkRequest(resultCode, data); return; + } else if (requestCode == REQUEST_CODE_WIFI_DPP_ENROLLEE_QR_CODE_SCANNER) { + if (resultCode == Activity.RESULT_OK) { + if (mDialog != null) { + mDialog.dismiss(); + } + mWifiTracker.resumeScanning(); + } + return; } final boolean formerlyRestricted = mIsRestricted; @@ -1065,6 +1074,13 @@ public class WifiSettings extends RestrictedSettingsFragment } } + @Override + public void onScan(WifiDialog dialog, String ssid) { + // Launch QR code scanner to join a network. + startActivityForResult(WifiDppUtils.getEnrolleeQrCodeScannerIntent(ssid), + REQUEST_CODE_WIFI_DPP_ENROLLEE_QR_CODE_SCANNER); + } + /* package */ void submit(WifiConfigController configController) { final WifiConfiguration config = configController.getConfig(); diff --git a/src/com/android/settings/wifi/dpp/WifiDppAddDeviceFragment.java b/src/com/android/settings/wifi/dpp/WifiDppAddDeviceFragment.java index 97b2ebefc8f..9e731ba7936 100644 --- a/src/com/android/settings/wifi/dpp/WifiDppAddDeviceFragment.java +++ b/src/com/android/settings/wifi/dpp/WifiDppAddDeviceFragment.java @@ -172,6 +172,9 @@ public class WifiDppAddDeviceFragment extends WifiDppQrCodeBaseFragment { mLatestStatusCode = code; } + if (isGoingInitiator()) { + mSummary.setText(R.string.wifi_dpp_sharing_wifi_with_this_device); + } mProgressBar.setVisibility(isGoingInitiator() ? View.VISIBLE : View.INVISIBLE); mButtonRight.setVisibility(isGoingInitiator() ? View.INVISIBLE : View.VISIBLE); } @@ -255,7 +258,7 @@ public class WifiDppAddDeviceFragment extends WifiDppQrCodeBaseFragment { mTitle.setText(information); } - mSummary.setText(getString(R.string.wifi_dpp_add_device_to_wifi, getSsid())); + updateSummary(); mWifiApPictureView = view.findViewById(R.id.wifi_ap_picture_view); mChooseDifferentNetwork = view.findViewById(R.id.choose_different_network); @@ -273,6 +276,7 @@ public class WifiDppAddDeviceFragment extends WifiDppQrCodeBaseFragment { mProgressBar.setVisibility(View.VISIBLE); mButtonRight.setVisibility(View.INVISIBLE); startWifiDppConfiguratorInitiator(); + updateSummary(); }); if (savedInstanceState != null) { @@ -342,4 +346,12 @@ public class WifiDppAddDeviceFragment extends WifiDppQrCodeBaseFragment { return model.isGoingInitiator(); } + + private void updateSummary() { + if (isGoingInitiator()) { + mSummary.setText(R.string.wifi_dpp_sharing_wifi_with_this_device); + } else { + mSummary.setText(getString(R.string.wifi_dpp_add_device_to_wifi, getSsid())); + } + } } diff --git a/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java b/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java index e664a0508e7..a19069bd99c 100644 --- a/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java +++ b/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java @@ -31,7 +31,6 @@ import android.net.wifi.WifiManager; import android.os.Bundle; import android.os.Handler; import android.os.Message; -import android.provider.Settings; import android.text.TextUtils; import android.util.Log; import android.util.Size; @@ -48,6 +47,7 @@ import android.widget.TextView; import androidx.lifecycle.ViewModelProviders; import com.android.settings.R; +import com.android.settings.wifi.WifiDialogActivity; import com.android.settings.wifi.qrcode.QrCamera; import com.android.settings.wifi.qrcode.QrDecorateView; @@ -77,6 +77,7 @@ public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment impl // Key for Bundle usage private static final String KEY_IS_CONFIGURATOR_MODE = "key_is_configurator_mode"; private static final String KEY_LATEST_ERROR_CODE = "key_latest_error_code"; + private static final String KEY_WIFI_CONFIGURATION = "key_wifi_configuration"; private ProgressBar mProgressBar; private QrCamera mCamera; @@ -93,6 +94,9 @@ public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment impl /** QR code data scanned by camera */ private WifiQrCode mWifiQrCode; + /** The WifiConfiguration connecting for enrollee usage */ + private WifiConfiguration mWifiConfiguration; + private int mLatestStatusCode = WifiDppUtils.EASY_CONNECT_EVENT_FAILURE_NONE; @Override @@ -102,6 +106,7 @@ public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment impl if (savedInstanceState != null) { mIsConfiguratorMode = savedInstanceState.getBoolean(KEY_IS_CONFIGURATOR_MODE); mLatestStatusCode = savedInstanceState.getInt(KEY_LATEST_ERROR_CODE); + mWifiConfiguration = savedInstanceState.getParcelable(KEY_WIFI_CONFIGURATION); } final WifiDppInitiatorViewModel model = @@ -224,13 +229,7 @@ public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment impl } else { mTitle.setText(R.string.wifi_dpp_scan_qr_code); - String description; - if (TextUtils.isEmpty(mSsid)) { - description = getString(R.string.wifi_dpp_scan_qr_code_join_unknown_network, mSsid); - } else { - description = getString(R.string.wifi_dpp_scan_qr_code_join_network, mSsid); - } - mSummary.setText(description); + updateEnrolleeSummary(); } mErrorMessage = view.findViewById(R.id.error_message); @@ -410,6 +409,7 @@ public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment impl if (!mIsConfiguratorMode) { mProgressBar.setVisibility(View.VISIBLE); startWifiDppEnrolleeInitiator((WifiQrCode)msg.obj); + updateEnrolleeSummary(); } break; @@ -417,6 +417,7 @@ public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment impl mErrorMessage.setVisibility(View.INVISIBLE); final WifiNetworkConfig wifiNetworkConfig = (WifiNetworkConfig)msg.obj; + mWifiConfiguration = wifiNetworkConfig.getWifiConfigurationOrNull(); wifiNetworkConfig.connect(getContext(), /* listener */ WifiDppQrCodeScannerFragment.this); break; @@ -431,6 +432,7 @@ public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment impl public void onSaveInstanceState(Bundle outState) { outState.putBoolean(KEY_IS_CONFIGURATOR_MODE, mIsConfiguratorMode); outState.putInt(KEY_LATEST_ERROR_CODE, mLatestStatusCode); + outState.putParcelable(KEY_WIFI_CONFIGURATION, mWifiConfiguration); super.onSaveInstanceState(outState); } @@ -446,6 +448,7 @@ public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment impl for (WifiConfiguration wifiConfig : wifiConfigs) { if (wifiConfig.networkId == newNetworkId) { mLatestStatusCode = WifiDppUtils.EASY_CONNECT_EVENT_SUCCESS; + mWifiConfiguration = wifiConfig; wifiManager.connect(wifiConfig, WifiDppQrCodeScannerFragment.this); return; } @@ -453,6 +456,7 @@ public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment impl Log.e(TAG, "Invalid networkId " + newNetworkId); mLatestStatusCode = EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_GENERIC; + updateEnrolleeSummary(); mProgressBar.setVisibility(View.INVISIBLE); showErrorMessage(getString(R.string.wifi_dpp_check_connection_try_again)); restartCamera(); @@ -520,6 +524,7 @@ public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment impl } mLatestStatusCode = code; + updateEnrolleeSummary(); mProgressBar.setVisibility(View.INVISIBLE); restartCamera(); } @@ -539,9 +544,11 @@ public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment impl @Override public void onSuccess() { - startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS)); + final Intent resultIntent = new Intent(); + resultIntent.putExtra(WifiDialogActivity.KEY_WIFI_CONFIGURATION, mWifiConfiguration); + final Activity hostActivity = getActivity(); - hostActivity.setResult(Activity.RESULT_OK); + hostActivity.setResult(Activity.RESULT_OK, resultIntent); hostActivity.finish(); } @@ -578,4 +585,18 @@ public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment impl mCamera.start(surfaceTexture); } + + private void updateEnrolleeSummary() { + if (isGoingInitiator()) { + mSummary.setText(R.string.wifi_dpp_connecting); + } else { + String description; + if (TextUtils.isEmpty(mSsid)) { + description = getString(R.string.wifi_dpp_scan_qr_code_join_unknown_network, mSsid); + } else { + description = getString(R.string.wifi_dpp_scan_qr_code_join_network, mSsid); + } + mSummary.setText(description); + } + } } diff --git a/src/com/android/settings/wifi/dpp/WifiDppUtils.java b/src/com/android/settings/wifi/dpp/WifiDppUtils.java index 24cd1d75a63..6c991cffdbe 100644 --- a/src/com/android/settings/wifi/dpp/WifiDppUtils.java +++ b/src/com/android/settings/wifi/dpp/WifiDppUtils.java @@ -95,6 +95,11 @@ public class WifiDppUtils { /** * Returns an intent to launch QR code scanner for Wi-Fi DPP enrollee. * + * After enrollee success, the callee activity will return connecting WifiConfiguration by + * putExtra {@code WifiDialogActivity.KEY_WIFI_CONFIGURATION} for + * {@code Activity#setResult(int resultCode, Intent data)}. The calling object should check + * if it's available before using it. + * * @param ssid The data corresponding to {@code WifiConfiguration} SSID * @return Intent for launching QR code scanner */ diff --git a/src/com/android/settings/wifi/dpp/WifiNetworkConfig.java b/src/com/android/settings/wifi/dpp/WifiNetworkConfig.java index 979e602bf4a..6135cba190e 100644 --- a/src/com/android/settings/wifi/dpp/WifiNetworkConfig.java +++ b/src/com/android/settings/wifi/dpp/WifiNetworkConfig.java @@ -228,7 +228,7 @@ public class WifiNetworkConfig { /** * This is a simplified method from {@code WifiConfigController.getConfig()} */ - private WifiConfiguration getWifiConfigurationOrNull() { + WifiConfiguration getWifiConfigurationOrNull() { if (!isValidConfig(this)) { return null; } diff --git a/tests/robotests/src/com/android/settings/applications/RecentAppsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/RecentAppsPreferenceControllerTest.java index 1411bc0a30f..e2a16579ad4 100644 --- a/tests/robotests/src/com/android/settings/applications/RecentAppsPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/applications/RecentAppsPreferenceControllerTest.java @@ -25,9 +25,9 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.argThat; -import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -146,6 +146,7 @@ public class RecentAppsPreferenceControllerTest { when(mUsageStatsManager.queryUsageStats(anyInt(), anyLong(), anyLong())) .thenReturn(stats); mAppEntry.info = mApplicationInfo; + mController.reloadData(); assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE); } @@ -157,13 +158,17 @@ public class RecentAppsPreferenceControllerTest { } @Test - public void displayPreferenceAndUpdateState_shouldRefreshUi() { - doNothing().when(mController).refreshUi(); - + public void displayPreference_shouldNotReloadData() { mController.displayPreference(mScreen); - mController.updateState(mScreen); - verify(mController, times(2)).refreshUi(); + verify(mController, never()).reloadData(); + } + + @Test + public void displayPreference_shouldRefreshUi() { + mController.displayPreference(mScreen); + + verify(mController).refreshUi(); } @Test @@ -173,6 +178,25 @@ public class RecentAppsPreferenceControllerTest { assertThat(mController.mAppEntitiesController).isNotNull(); } + @Test + public void updateState_firstLaunch_shouldNotReloadData() { + mController.mIsFirstLaunch = true; + + mController.updateState(mRecentAppsPreference); + + verify(mController, never()).reloadData(); + } + + @Test + public void updateState_afterFirstLaunch_shouldReloadDataAndRefreshUi() { + mController.mIsFirstLaunch = false; + + mController.updateState(mRecentAppsPreference); + + verify(mController).reloadData(); + verify(mController).refreshUi(); + } + @Test public void updateState_threeValidRecentOpenAppsSet_setAppEntityThreeTime() { final List stats = new ArrayList<>(); @@ -203,6 +227,7 @@ public class RecentAppsPreferenceControllerTest { when(mUsageStatsManager.queryUsageStats(anyInt(), anyLong(), anyLong())) .thenReturn(stats); mAppEntry.info = mApplicationInfo; + mController.mIsFirstLaunch = false; mController.updateState(mRecentAppsPreference); @@ -243,6 +268,7 @@ public class RecentAppsPreferenceControllerTest { when(mUsageStatsManager.queryUsageStats(anyInt(), anyLong(), anyLong())) .thenReturn(stats); mAppEntry.info = mApplicationInfo; + mController.mIsFirstLaunch = false; mController.updateState(mRecentAppsPreference); @@ -274,6 +300,7 @@ public class RecentAppsPreferenceControllerTest { when(mUsageStatsManager.queryUsageStats(anyInt(), anyLong(), anyLong())) .thenReturn(stats); mAppEntry.info = mApplicationInfo; + mController.mIsFirstLaunch = false; mController.updateState(mRecentAppsPreference); @@ -314,6 +341,7 @@ public class RecentAppsPreferenceControllerTest { // Make sure stat2 is considered an instant app. ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider", (InstantAppDataProvider) (ApplicationInfo info) -> info == stat2Entry.info); + mController.mIsFirstLaunch = false; mController.updateState(mRecentAppsPreference); @@ -389,6 +417,7 @@ public class RecentAppsPreferenceControllerTest { .thenReturn(new ResolveInfo()); when(mUsageStatsManager.queryUsageStats(anyInt(), anyLong(), anyLong())) .thenReturn(stats); + mController.mIsFirstLaunch = false; mController.updateState(mRecentAppsPreference); diff --git a/tests/robotests/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminListItemTest.java b/tests/robotests/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminListItemTest.java index 17703e334dd..7392fb1376a 100644 --- a/tests/robotests/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminListItemTest.java +++ b/tests/robotests/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminListItemTest.java @@ -67,7 +67,7 @@ public class DeviceAdminListItemTest { DeviceAdminListItem item = new DeviceAdminListItem(mContext, mDeviceAdminInfo); - assertThat(item.getKey()).isEqualTo(cn.flattenToShortString()); + assertThat(item.getKey()).isEqualTo("0@" + cn.flattenToShortString()); assertThat(item.getName()).isEqualTo(label); assertThat(item.getDescription()).isEqualTo(description); } diff --git a/tests/robotests/src/com/android/settings/deviceinfo/HardwareInfoDialogFragmentTest.java b/tests/robotests/src/com/android/settings/deviceinfo/HardwareInfoDialogFragmentTest.java deleted file mode 100644 index 29d9a7c8aa2..00000000000 --- a/tests/robotests/src/com/android/settings/deviceinfo/HardwareInfoDialogFragmentTest.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.settings.deviceinfo; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; - -import android.os.SystemProperties; -import android.view.View; - -import androidx.fragment.app.FragmentActivity; - -import com.android.settings.R; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.robolectric.Robolectric; -import org.robolectric.RobolectricTestRunner; - -@RunWith(RobolectricTestRunner.class) -public class HardwareInfoDialogFragmentTest { - - private FragmentActivity mActivity; - - @Before - public void setUp() { - mActivity = Robolectric.setupActivity(FragmentActivity.class); - } - - @Test - public void display_shouldShowHardwareRevision() { - final String TEST_HARDWARE_REV = "123"; - SystemProperties.set("ro.boot.hardware.revision", TEST_HARDWARE_REV); - - final HardwareInfoDialogFragment fragment = spy(HardwareInfoDialogFragment.newInstance()); - doReturn("").when(fragment).getSerialNumber(); - fragment.show(mActivity.getSupportFragmentManager(), HardwareInfoDialogFragment.TAG); - - verify(fragment).setText( - any(View.class), eq(R.id.model_label), eq(R.id.model_value), - anyString()); - - verify(fragment).setText( - any(View.class), eq(R.id.hardware_rev_label), eq(R.id.hardware_rev_value), - anyString()); - } -} diff --git a/tests/robotests/src/com/android/settings/deviceinfo/hardwareinfo/DeviceModelPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/hardwareinfo/DeviceModelPreferenceControllerTest.java new file mode 100644 index 00000000000..1204c443e1d --- /dev/null +++ b/tests/robotests/src/com/android/settings/deviceinfo/hardwareinfo/DeviceModelPreferenceControllerTest.java @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.deviceinfo.hardwareinfo; + +import static com.google.common.truth.Truth.assertThat; + +import android.content.Context; + +import com.android.settings.core.BasePreferenceController; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.MockitoAnnotations; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; + +@RunWith(RobolectricTestRunner.class) +public class DeviceModelPreferenceControllerTest { + + private Context mContext; + private DeviceModelPreferenceController mController; + + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mContext = RuntimeEnvironment.application; + mController = new DeviceModelPreferenceController(mContext, "test_key"); + } + + @Test + public void getAvailabilityStatus_configAllowed_available() { + assertThat(mController.getAvailabilityStatus()).isEqualTo( + BasePreferenceController.AVAILABLE); + } + + @Test + @Config(qualifiers = "mcc999") + public void getAvailabilityStatus_configDisallowed_unavailable() { + assertThat(mController.getAvailabilityStatus()).isEqualTo( + BasePreferenceController.UNSUPPORTED_ON_DEVICE); + } + + @Test + public void isAlwaysSliceable() { + assertThat(mController.isSliceable()).isTrue(); + } +} diff --git a/tests/robotests/src/com/android/settings/deviceinfo/DeviceModelPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/hardwareinfo/HardwareInfoPreferenceControllerTest.java similarity index 64% rename from tests/robotests/src/com/android/settings/deviceinfo/DeviceModelPreferenceControllerTest.java rename to tests/robotests/src/com/android/settings/deviceinfo/hardwareinfo/HardwareInfoPreferenceControllerTest.java index 6418cf8bb6f..413c4921bbd 100644 --- a/tests/robotests/src/com/android/settings/deviceinfo/DeviceModelPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/deviceinfo/hardwareinfo/HardwareInfoPreferenceControllerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 The Android Open Source Project + * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,56 +13,44 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.android.settings.deviceinfo; +package com.android.settings.deviceinfo.hardwareinfo; import static com.google.common.truth.Truth.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - import android.content.Context; import android.os.Build; -import androidx.fragment.app.Fragment; -import androidx.fragment.app.FragmentManager; -import androidx.fragment.app.FragmentTransaction; import androidx.preference.Preference; import androidx.preference.PreferenceManager; import androidx.preference.PreferenceScreen; import com.android.settings.R; import com.android.settings.core.BasePreferenceController; +import com.android.settings.deviceinfo.HardwareInfoPreferenceController; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; @RunWith(RobolectricTestRunner.class) -public class DeviceModelPreferenceControllerTest { +public class HardwareInfoPreferenceControllerTest { private final String KEY = "device_model"; - @Mock - private Fragment mFragment; private Preference mPreference; private PreferenceScreen mPreferenceScreen; private Context mContext; - private DeviceModelPreferenceController mController; + private HardwareInfoPreferenceController mController; @Before public void setUp() { MockitoAnnotations.initMocks(this); mContext = RuntimeEnvironment.application; - mController = new DeviceModelPreferenceController(mContext, KEY); - mController.setHost(mFragment); + mController = new HardwareInfoPreferenceController(mContext, KEY); mPreference = new Preference(mContext); mPreference.setKey(KEY); final PreferenceManager preferenceManager = new PreferenceManager(mContext); @@ -73,7 +61,7 @@ public class DeviceModelPreferenceControllerTest { @Test public void isAvailable_returnTrueIfVisible() { assertThat(mController.getAvailabilityStatus()).isEqualTo( - BasePreferenceController.AVAILABLE); + BasePreferenceController.AVAILABLE_UNSEARCHABLE); } @Test @@ -90,22 +78,6 @@ public class DeviceModelPreferenceControllerTest { assertThat(containBuildModel(mPreference.getSummary())).isTrue(); } - @Test - public void clickPreference_shouldLaunchHardwareInfoDialog() { - FragmentManager fragmentManager = mock(FragmentManager.class); - when(mFragment.getFragmentManager()).thenReturn(fragmentManager); - when(fragmentManager.beginTransaction()).thenReturn(mock(FragmentTransaction.class)); - - assertThat(mController.handlePreferenceTreeClick(mPreference)).isTrue(); - verify(fragmentManager.beginTransaction()) - .add(any(HardwareInfoDialogFragment.class), eq(HardwareInfoDialogFragment.TAG)); - } - - @Test - public void isSliceable_shouldBeTrue() { - assertThat(mController.isSliceable()).isTrue(); - } - private boolean containBuildModel(CharSequence result) { final String oracle = mContext.getResources().getString(R.string.model_summary, Build.MODEL); diff --git a/tests/robotests/src/com/android/settings/deviceinfo/hardwareinfo/SerialNumberPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/hardwareinfo/SerialNumberPreferenceControllerTest.java new file mode 100644 index 00000000000..c2ae4af703e --- /dev/null +++ b/tests/robotests/src/com/android/settings/deviceinfo/hardwareinfo/SerialNumberPreferenceControllerTest.java @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.deviceinfo.hardwareinfo; + + +import static com.google.common.truth.Truth.assertThat; + +import android.content.ClipData; +import android.content.ClipboardManager; +import android.content.Context; +import android.os.Build; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; + +@RunWith(RobolectricTestRunner.class) +public class SerialNumberPreferenceControllerTest { + + private Context mContext; + private SerialNumberPreferenceController mController; + + @Before + public void setUp() { + mContext = RuntimeEnvironment.application; + mController = new SerialNumberPreferenceController(mContext, "test"); + } + + @Test + public void isCopyableSlice() { + assertThat(mController.isSliceable()).isTrue(); + assertThat(mController.isCopyableSlice()).isTrue(); + } + + @Test + public void copy_shouldPutSerialNumberToClipBoard() { + mController.copy(); + + final ClipboardManager clipboardManager = mContext.getSystemService(ClipboardManager.class); + final ClipData data = clipboardManager.getPrimaryClip(); + + assertThat(data.getItemAt(0).getText().toString()).contains(Build.getSerial()); + } +} diff --git a/tests/robotests/src/com/android/settings/gestures/PreventRingingSwitchPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/PreventRingingSwitchPreferenceControllerTest.java index 5f221f578f7..85eeacc4ce2 100644 --- a/tests/robotests/src/com/android/settings/gestures/PreventRingingSwitchPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/gestures/PreventRingingSwitchPreferenceControllerTest.java @@ -18,6 +18,7 @@ package com.android.settings.gestures; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; @@ -29,8 +30,10 @@ import android.content.res.Resources; import android.provider.Settings; import androidx.preference.Preference; +import androidx.preference.PreferenceScreen; import com.android.settings.widget.SwitchBar; +import com.android.settingslib.widget.LayoutPreference; import org.junit.Before; import org.junit.Test; @@ -95,4 +98,16 @@ public class PreventRingingSwitchPreferenceControllerTest { mController.updateState(mPreference); verify(mController.mSwitch, times(1)).setChecked(true); } + + @Test + public void testPreferenceClickListenerAttached() { + PreferenceScreen preferenceScreen = mock(PreferenceScreen.class); + LayoutPreference mLayoutPreference = mock(LayoutPreference.class); + when(preferenceScreen.findPreference(mController.getPreferenceKey())).thenReturn( + mLayoutPreference); + mController.displayPreference(preferenceScreen); + + verify(mLayoutPreference, times(1)) + .setOnPreferenceClickListener(any()); + } } diff --git a/tests/robotests/src/com/android/settings/nfc/NfcPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/nfc/NfcPreferenceControllerTest.java index 8883ddf7e3a..e3672c92dc9 100644 --- a/tests/robotests/src/com/android/settings/nfc/NfcPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/nfc/NfcPreferenceControllerTest.java @@ -19,10 +19,13 @@ package com.android.settings.nfc; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.Context; +import android.content.Intent; +import android.net.Uri; import android.nfc.NfcAdapter; import android.nfc.NfcManager; import android.os.UserManager; @@ -31,6 +34,10 @@ import android.provider.Settings; import androidx.preference.PreferenceScreen; import androidx.preference.SwitchPreference; +import com.android.settings.nfc.NfcPreferenceController.NfcSliceWorker; +import com.android.settings.nfc.NfcPreferenceController.NfcSliceWorker.NfcUpdateReceiver; +import com.android.settings.slices.SliceBuilderUtils; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -246,4 +253,67 @@ public class NfcPreferenceControllerTest { assertThat(mNfcController.mAirplaneModeObserver).isNull(); } + + @Test + public void ncfSliceWorker_nfcBroadcast_noExtra_sliceDoesntUpdate() { + final NfcSliceWorker worker = spy(new NfcSliceWorker(mContext, getDummyUri())); + final NfcUpdateReceiver receiver = worker.new NfcUpdateReceiver(worker); + final Intent triggerIntent = new Intent(NfcAdapter.ACTION_ADAPTER_STATE_CHANGED); + + receiver.onReceive(mContext, triggerIntent); + + verify(worker, times(0)).updateSlice(); + } + + @Test + public void ncfSliceWorker_nfcBroadcast_turningOn_sliceDoesntUpdate() { + final NfcSliceWorker worker = spy(new NfcSliceWorker(mContext, getDummyUri())); + final NfcUpdateReceiver receiver = worker.new NfcUpdateReceiver(worker); + final Intent triggerIntent = new Intent(NfcAdapter.ACTION_ADAPTER_STATE_CHANGED); + triggerIntent.putExtra(NfcAdapter.EXTRA_ADAPTER_STATE, NfcAdapter.STATE_TURNING_ON); + + receiver.onReceive(mContext, triggerIntent); + + verify(worker, times(0)).updateSlice(); + } + + @Test + public void ncfSliceWorker_nfcBroadcast_turningOff_sliceDoesntUpdate() { + final NfcSliceWorker worker = spy(new NfcSliceWorker(mContext, getDummyUri())); + final NfcUpdateReceiver receiver = worker.new NfcUpdateReceiver(worker); + final Intent triggerIntent = new Intent(NfcAdapter.ACTION_ADAPTER_STATE_CHANGED); + triggerIntent.putExtra(NfcAdapter.EXTRA_ADAPTER_STATE, NfcAdapter.STATE_TURNING_OFF); + + receiver.onReceive(mContext, triggerIntent); + + verify(worker, times(0)).updateSlice(); + } + + @Test + public void ncfSliceWorker_nfcBroadcast_nfcOn_sliceUpdates() { + final NfcSliceWorker worker = spy(new NfcSliceWorker(mContext, getDummyUri())); + final NfcUpdateReceiver receiver = worker.new NfcUpdateReceiver(worker); + final Intent triggerIntent = new Intent(NfcAdapter.ACTION_ADAPTER_STATE_CHANGED); + triggerIntent.putExtra(NfcAdapter.EXTRA_ADAPTER_STATE, NfcAdapter.STATE_ON); + + receiver.onReceive(mContext, triggerIntent); + + verify(worker).updateSlice(); + } + + @Test + public void ncfSliceWorker_nfcBroadcast_nfcOff_sliceUpdates() { + final NfcSliceWorker worker = spy(new NfcSliceWorker(mContext, getDummyUri())); + final NfcUpdateReceiver receiver = worker.new NfcUpdateReceiver(worker); + final Intent triggerIntent = new Intent(NfcAdapter.ACTION_ADAPTER_STATE_CHANGED); + triggerIntent.putExtra(NfcAdapter.EXTRA_ADAPTER_STATE, NfcAdapter.STATE_OFF); + + receiver.onReceive(mContext, triggerIntent); + + verify(worker).updateSlice(); + } + + private Uri getDummyUri() { + return SliceBuilderUtils.getUri("action/nfc", false); + } } diff --git a/tests/robotests/src/com/android/settings/notification/NotificationAssistantPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/NotificationAssistantPreferenceControllerTest.java new file mode 100644 index 00000000000..b2f65e06d7b --- /dev/null +++ b/tests/robotests/src/com/android/settings/notification/NotificationAssistantPreferenceControllerTest.java @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.notification; + +import static junit.framework.TestCase.assertEquals; + +import static org.mockito.Mockito.when; + +import android.content.ComponentName; +import android.content.Context; +import android.content.pm.PackageManager; +import android.graphics.drawable.Drawable; +import android.os.Debug; + +import com.android.settingslib.widget.CandidateInfo; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Answers; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; + +@RunWith(RobolectricTestRunner.class) +public class NotificationAssistantPreferenceControllerTest { + + private static final String KEY = "TEST_KEY"; + @Mock(answer = Answers.RETURNS_DEEP_STUBS) + private Context mContext; + @Mock + private NotificationBackend mBackend; + private NotificationAssistantPreferenceController mPreferenceController; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mContext = RuntimeEnvironment.application; + mPreferenceController = new TestPreferenceController(mContext, mBackend); + } + + @Test + public void testGetSummary_noAssistant() { + when(mBackend.getAllowedNotificationAssistant()).thenReturn(null); + CharSequence noneLabel = new NotificationAssistantPicker.CandidateNone(mContext) + .loadLabel(); + assertEquals(noneLabel, mPreferenceController.getSummary()); + } + + @Test + public void testGetSummary_TestAssistant() { + String testName = "test_pkg/test_cls"; + when(mBackend.getAllowedNotificationAssistant()).thenReturn( + ComponentName.unflattenFromString(testName)); + assertEquals(testName, mPreferenceController.getSummary()); + } + + private final class TestPreferenceController extends NotificationAssistantPreferenceController { + + private TestPreferenceController(Context context, NotificationBackend backend) { + super(context, KEY); + mNotificationBackend = backend; + } + + @Override + public String getPreferenceKey() { + return KEY; + } + + @Override + protected CandidateInfo createCandidateInfo(ComponentName cn) { + return new CandidateInfo(true) { + @Override + public CharSequence loadLabel() { return cn.flattenToString(); } + + @Override + public Drawable loadIcon() { return null; } + + @Override + public String getKey() { return null; } + }; + } + } + +} diff --git a/tests/robotests/src/com/android/settings/notification/RingtonePreferenceControllerBaseTest.java b/tests/robotests/src/com/android/settings/notification/RingtonePreferenceControllerBaseTest.java index f22a78225a2..2fb1738f25a 100644 --- a/tests/robotests/src/com/android/settings/notification/RingtonePreferenceControllerBaseTest.java +++ b/tests/robotests/src/com/android/settings/notification/RingtonePreferenceControllerBaseTest.java @@ -20,31 +20,31 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import android.content.Context; import android.media.RingtoneManager; +import android.provider.Settings; import androidx.preference.Preference; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; @RunWith(RobolectricTestRunner.class) public class RingtonePreferenceControllerBaseTest { - @Mock private Context mContext; private RingtonePreferenceControllerBase mController; @Before public void setUp() { - MockitoAnnotations.initMocks(this); + mContext = RuntimeEnvironment.application; mController = new RingtonePreferenceControllerBaseTestable(mContext); } @@ -56,14 +56,26 @@ public class RingtonePreferenceControllerBaseTest { @Test public void updateState_shouldSetSummary() { Preference preference = mock(Preference.class); + Settings.System.putString(mContext.getContentResolver(), Settings.System.RINGTONE, + "content://test/ringtone"); mController.updateState(preference); verify(preference).setSummary(anyString()); } + @Test + public void updateState_nullRingtone_shouldNotGetTitle() { + Preference preference = mock(Preference.class); + Settings.System.putString(mContext.getContentResolver(), Settings.System.RINGTONE, null); + + mController.updateState(preference); + + verify(preference, never()).setSummary(anyString()); + } + private class RingtonePreferenceControllerBaseTestable - extends RingtonePreferenceControllerBase { + extends RingtonePreferenceControllerBase { RingtonePreferenceControllerBaseTestable(Context context) { super(context); } diff --git a/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java b/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java index 726e4bdf300..a693f349894 100644 --- a/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java +++ b/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java @@ -64,6 +64,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import org.robolectric.Robolectric; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; @@ -183,6 +184,20 @@ public class SettingsSliceProviderTest { verify(mProvider).registerIntentToUri(eq(FakeToggleController.INTENT_FILTER), eq(uri)); } + @Test + public void loadSlice_registersBackgroundListener() { + insertSpecialCase(KEY); + final Uri uri = SliceBuilderUtils.getUri(INTENT_PATH, false); + + mProvider.loadSlice(uri); + + Robolectric.flushForegroundThreadScheduler(); + Robolectric.flushBackgroundThreadScheduler(); + + assertThat(mProvider.mPinnedWorkers.get(uri).getClass()) + .isEqualTo(FakeToggleController.TestWorker.class); + } + @Test public void testLoadSlice_doesNotCacheWithoutPin() { insertSpecialCase(KEY); diff --git a/tests/robotests/src/com/android/settings/testutils/FakeCopyableController.java b/tests/robotests/src/com/android/settings/testutils/FakeCopyableController.java index 31e955c8cdf..e51a2492844 100644 --- a/tests/robotests/src/com/android/settings/testutils/FakeCopyableController.java +++ b/tests/robotests/src/com/android/settings/testutils/FakeCopyableController.java @@ -19,9 +19,8 @@ package com.android.settings.testutils; import android.content.Context; import com.android.settings.core.BasePreferenceController; -import com.android.settings.slices.Copyable; -public class FakeCopyableController extends BasePreferenceController implements Copyable { +public class FakeCopyableController extends BasePreferenceController { public FakeCopyableController(Context context, String preferenceKey) { super(context, preferenceKey); @@ -38,6 +37,7 @@ public class FakeCopyableController extends BasePreferenceController implements } @Override - public void copy() { + public boolean isCopyableSlice() { + return true; } } diff --git a/tests/robotests/src/com/android/settings/testutils/FakeToggleController.java b/tests/robotests/src/com/android/settings/testutils/FakeToggleController.java index d1677cd7382..e7854874c54 100644 --- a/tests/robotests/src/com/android/settings/testutils/FakeToggleController.java +++ b/tests/robotests/src/com/android/settings/testutils/FakeToggleController.java @@ -19,10 +19,14 @@ package com.android.settings.testutils; import android.content.Context; import android.content.IntentFilter; +import android.net.Uri; import android.net.wifi.WifiManager; import android.provider.Settings; import com.android.settings.core.TogglePreferenceController; +import com.android.settings.slices.SliceBackgroundWorker; + +import java.io.IOException; public class FakeToggleController extends TogglePreferenceController { @@ -70,6 +74,11 @@ public class FakeToggleController extends TogglePreferenceController { return true; } + @Override + public Class getBackgroundWorkerClass() { + return TestWorker.class; + } + @Override public boolean hasAsyncUpdate() { return mIsAsyncUpdate; @@ -78,4 +87,23 @@ public class FakeToggleController extends TogglePreferenceController { public void setAsyncUpdate(boolean isAsyncUpdate) { mIsAsyncUpdate = isAsyncUpdate; } + + public static class TestWorker extends SliceBackgroundWorker { + + public TestWorker(Context context, Uri uri) { + super(context, uri); + } + + @Override + protected void onSlicePinned() { + } + + @Override + protected void onSliceUnpinned() { + } + + @Override + public void close() throws IOException { + } + } } diff --git a/tests/unit/src/com/android/settings/DisplaySettingsTest.java b/tests/unit/src/com/android/settings/DisplaySettingsTest.java deleted file mode 100644 index cc9cd819319..00000000000 --- a/tests/unit/src/com/android/settings/DisplaySettingsTest.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.settings; - -import static androidx.test.espresso.Espresso.onView; -import static androidx.test.espresso.action.ViewActions.click; -import static androidx.test.espresso.matcher.ViewMatchers.withText; - -import android.app.Instrumentation; -import android.content.Context; -import android.content.Intent; -import android.support.test.uiautomator.UiDevice; - -import androidx.test.InstrumentationRegistry; -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class DisplaySettingsTest { - - private Instrumentation mInstrumentation; - private Context mContext; - private UiDevice mDevice; - - @Before - public void setUp() { - mInstrumentation = InstrumentationRegistry.getInstrumentation(); - mContext = mInstrumentation.getTargetContext(); - mDevice = UiDevice.getInstance(mInstrumentation); - } - - @Test - public void launchBrightnessLevel_shouldNotCrash() { - mInstrumentation.startActivitySync( - new Intent(mContext, DisplaySettings.class)); - onView(withText(mContext.getString(R.string.brightness))).perform(click()); - // should not crash - mDevice.pressBack(); // dismiss the brightness dialog - } -} diff --git a/tests/unit/src/com/android/settings/EncryptionInterstitialTest.java b/tests/unit/src/com/android/settings/EncryptionInterstitialTest.java deleted file mode 100644 index 503a78c6bb8..00000000000 --- a/tests/unit/src/com/android/settings/EncryptionInterstitialTest.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.settings; - -import static androidx.test.espresso.Espresso.onView; -import static androidx.test.espresso.action.ViewActions.click; -import static androidx.test.espresso.matcher.ViewMatchers.withId; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import android.app.Activity; -import android.app.Instrumentation; -import android.app.Instrumentation.ActivityMonitor; -import android.app.Instrumentation.ActivityResult; -import android.content.Context; -import android.content.Intent; - -import androidx.test.InstrumentationRegistry; -import androidx.test.filters.MediumTest; -import androidx.test.runner.AndroidJUnit4; - -import com.google.android.setupcompat.PartnerCustomizationLayout; -import com.google.android.setupcompat.template.FooterBarMixin; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -@RunWith(AndroidJUnit4.class) -@MediumTest -public class EncryptionInterstitialTest { - - private Instrumentation mInstrumentation; - private Context mContext; - private TestActivityMonitor mActivityMonitor; - - @Before - public void setUp() { - mInstrumentation = InstrumentationRegistry.getInstrumentation(); - mContext = mInstrumentation.getTargetContext(); - mActivityMonitor = new TestActivityMonitor(); - mInstrumentation.addMonitor(mActivityMonitor); - } - - @After - public void tearDown() { - mInstrumentation.removeMonitor(mActivityMonitor); - } - - @Test - public void clickYes_shouldRequirePassword() { - final Activity activity = mInstrumentation.startActivitySync( - new Intent(mContext, EncryptionInterstitial.class) - .putExtra("extra_unlock_method_intent", new Intent("test.unlock.intent"))); - final PartnerCustomizationLayout layout = activity.findViewById(R.id.setup_wizard_layout); - layout.getMixin(FooterBarMixin.class).getPrimaryButtonView().performClick(); - - mActivityMonitor.waitForActivityWithTimeout(1000); - assertEquals(1, mActivityMonitor.getHits()); - - assertTrue(mActivityMonitor.mMatchedIntent.getBooleanExtra( - EncryptionInterstitial.EXTRA_REQUIRE_PASSWORD, false)); - } - - @Test - public void clickNo_shouldNotRequirePassword() { - final Activity activity = mInstrumentation.startActivitySync( - new Intent(mContext, EncryptionInterstitial.class) - .putExtra("extra_unlock_method_intent", new Intent("test.unlock.intent"))); - final PartnerCustomizationLayout layout = activity.findViewById(R.id.setup_wizard_layout); - layout.getMixin(FooterBarMixin.class).getSecondaryButtonView().performClick(); - - mActivityMonitor.waitForActivityWithTimeout(1000); - assertEquals(1, mActivityMonitor.getHits()); - - assertFalse(mActivityMonitor.mMatchedIntent.getBooleanExtra( - EncryptionInterstitial.EXTRA_REQUIRE_PASSWORD, true)); - } - - private static class TestActivityMonitor extends ActivityMonitor { - - Intent mMatchedIntent = null; - - @Override - public ActivityResult onStartActivity(Intent intent) { - if ("test.unlock.intent".equals(intent.getAction())) { - mMatchedIntent = intent; - return new ActivityResult(Activity.RESULT_OK, null); - } - return null; - } - } -} diff --git a/tests/unit/src/com/android/settings/ManagedAccessSettingsLowRamTest.java b/tests/unit/src/com/android/settings/ManagedAccessSettingsLowRamTest.java deleted file mode 100644 index 426b8a4270b..00000000000 --- a/tests/unit/src/com/android/settings/ManagedAccessSettingsLowRamTest.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.settings; - -import static androidx.test.espresso.Espresso.onView; -import static androidx.test.espresso.action.ViewActions.click; -import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist; -import static androidx.test.espresso.assertion.ViewAssertions.matches; -import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; -import static androidx.test.espresso.matcher.ViewMatchers.withText; - -import android.app.ActivityManager; -import android.app.Instrumentation; -import android.content.Context; -import android.content.Intent; -import android.provider.Settings; - -import androidx.test.InstrumentationRegistry; -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class ManagedAccessSettingsLowRamTest { - - private Instrumentation mInstrumentation; - private Context mTargetContext; - - @Before - public void setUp() { - mInstrumentation = InstrumentationRegistry.getInstrumentation(); - mTargetContext = mInstrumentation.getTargetContext(); - } - - @Test - public void testManagedAccessOptionsVisibility() throws Exception { - mInstrumentation.startActivitySync(new Intent(mTargetContext, - com.android.settings.Settings.AppAndNotificationDashboardActivity.class)); - onView(withText(mTargetContext.getString(R.string.expand_button_title))).perform(click()); - onView(withText(mTargetContext.getString(R.string.special_access))).perform(click()); - - String[] managedServiceLabels = new String[] {"Do Not Disturb access", - "VR helper services", "Notification access", "Picture-in-picture"}; - for (String label : managedServiceLabels) { - if (ActivityManager.isLowRamDeviceStatic()) { - onView(withText(label)).check(doesNotExist()); - } else { - onView(withText(label)).check(matches(isDisplayed())); - } - } - } - - @Test - public void launchNotificationSetting_onlyWorksIfNotLowRam() { - final Intent intent = new Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS); - - mInstrumentation.startActivitySync(intent); - - final String label = "This feature is not available on this device"; - if (ActivityManager.isLowRamDeviceStatic()) { - onView(withText(label)).check(matches(isDisplayed())); - } else { - onView(withText(label)).check(doesNotExist()); - } - } - - @Test - public void launchDndSetting_onlyWorksIfNotLowRam() { - final Intent intent = new Intent(Settings.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS); - - mInstrumentation.startActivitySync(intent); - - final String label = "This feature is not available on this device"; - if (ActivityManager.isLowRamDeviceStatic()) { - onView(withText(label)).check(matches(isDisplayed())); - } else { - onView(withText(label)).check(doesNotExist()); - } - } - - @Test - public void launchVrSetting_onlyWorksIfNotLowRam() { - final Intent intent = new Intent(Settings.ACTION_VR_LISTENER_SETTINGS); - - mInstrumentation.startActivitySync(intent); - - final String label = "This feature is not available on this device"; - if (ActivityManager.isLowRamDeviceStatic()) { - onView(withText(label)).check(matches(isDisplayed())); - } else { - onView(withText(label)).check(doesNotExist()); - } - } - - @Test - public void launchPictureInPictureSetting_onlyWorksIfNotLowRam() { - final Intent intent = new Intent(Settings.ACTION_PICTURE_IN_PICTURE_SETTINGS); - - mInstrumentation.startActivitySync(intent); - - final String label = "This feature is not available on this device"; - if (ActivityManager.isLowRamDeviceStatic()) { - onView(withText(label)).check(matches(isDisplayed())); - } else { - onView(withText(label)).check(doesNotExist()); - } - } -} diff --git a/tests/unit/src/com/android/settings/RegulatoryInfoDisplayActivityTest.java b/tests/unit/src/com/android/settings/RegulatoryInfoDisplayActivityTest.java index 48f9f5d53f4..1701ddff900 100644 --- a/tests/unit/src/com/android/settings/RegulatoryInfoDisplayActivityTest.java +++ b/tests/unit/src/com/android/settings/RegulatoryInfoDisplayActivityTest.java @@ -16,12 +16,6 @@ package com.android.settings; -import static androidx.test.espresso.Espresso.onView; -import static androidx.test.espresso.assertion.ViewAssertions.matches; -import static androidx.test.espresso.matcher.RootMatchers.isDialog; -import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; -import static androidx.test.espresso.matcher.ViewMatchers.withId; - import static junit.framework.Assert.fail; import android.app.Instrumentation; @@ -29,8 +23,6 @@ import android.app.UiAutomation; import android.content.Context; import android.content.Intent; import android.content.pm.ResolveInfo; -import android.graphics.Bitmap; -import android.util.Log; import androidx.test.InstrumentationRegistry; import androidx.test.filters.SmallTest; @@ -40,10 +32,6 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; - @RunWith(AndroidJUnit4.class) @SmallTest public class RegulatoryInfoDisplayActivityTest { @@ -82,73 +70,4 @@ public class RegulatoryInfoDisplayActivityTest { return; } } - - @Test - public void launchRegulatoryInfo_shouldNotCrash() { - final Context context = mInstrumentation.getTargetContext(); - final boolean hasRegulatoryInfo = context.getResources() - .getBoolean(R.bool.config_show_regulatory_info); - - if (!hasRegulatoryInfo) { - return; - } - // Launch intent - mInstrumentation.startActivitySync(mRegulatoryInfoIntent); - - onView(withId(R.id.regulatoryInfo)) - .inRoot(isDialog()) - .check(matches(isDisplayed())); - } - - @Test - public void launchRegulatoryInfo_withInfoImage_shouldDisplay() throws IOException { - // TODO: Remove "setenforce 0" when selinux rules is updated to give read permission for - // regulatory info. - mUiAutomation.executeShellCommand("setenforce 0"); - - final boolean tempFileCreated = ensureRegulatoryInfoImageExists(); - try { - final Context context = mInstrumentation.getTargetContext(); - final boolean hasRegulatoryInfo = context.getResources() - .getBoolean(R.bool.config_show_regulatory_info); - - if (!hasRegulatoryInfo) { - return; - } - // Launch intent - mInstrumentation.startActivitySync(mRegulatoryInfoIntent); - - onView(withId(R.id.regulatoryInfo)) - .inRoot(isDialog()) - .check(matches(isDisplayed())); - } finally { - if (tempFileCreated) { - final String filename = - RegulatoryInfoDisplayActivity.getRegulatoryInfoImageFileName(); - new File(filename).delete(); - Log.d(TAG, "Deleting temp file " + filename); - } - } - } - - /** - * Ensures regulatory label image exists on disk. - * - * @return true if a test image is created. - */ - private boolean ensureRegulatoryInfoImageExists() throws IOException { - final String filename = RegulatoryInfoDisplayActivity.getRegulatoryInfoImageFileName(); - if (new File(filename).exists()) { - return false; - } - Log.d(TAG, "Creating temp file " + filename); - final Bitmap bitmap = Bitmap.createBitmap(400 /* width */, 400 /* height */, - Bitmap.Config.ARGB_8888); - final FileOutputStream out = new FileOutputStream(filename); - bitmap.compress(Bitmap.CompressFormat.PNG, 100 /* quality */, out); - out.close(); - return true; - } - - } diff --git a/tests/unit/src/com/android/settings/SettingsHookTests.java b/tests/unit/src/com/android/settings/SettingsHookTests.java deleted file mode 100644 index ee0bbb6e076..00000000000 --- a/tests/unit/src/com/android/settings/SettingsHookTests.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (C) 2010 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; - -import android.content.Context; -import android.content.Intent; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.test.ActivityInstrumentationTestCase2; - -import java.util.List; - -/** - * Tests for the Settings operator/manufacturer hook. - * - * Running all tests: - * - * make SettingsTests - * adb push SettingsTests.apk /system/app/SettingsTests.apk - * adb shell am instrument \ - * -w com.android.settings.tests/android.test.InstrumentationTestRunner - */ -public class SettingsHookTests extends ActivityInstrumentationTestCase2 { - - private static final String PACKAGE_NAME = "com.android.settings.tests.unit"; - - private static final String KEY_SETTINGS_ROOT = "parent"; - private static final String KEY_SETTINGS_OPERATOR = "operator_settings"; - private static final String KEY_SETTINGS_MANUFACTURER = "manufacturer_settings"; - - private static final String INTENT_OPERATOR_HOOK = "com.android.settings.OPERATOR_APPLICATION_SETTING"; - private static final String INTENT_MANUFACTURER_HOOK = "com.android.settings.MANUFACTURER_APPLICATION_SETTING"; - - private Settings mSettings; - - public SettingsHookTests() { - super("com.android.settings", Settings.class); - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - mSettings = getActivity(); - } - - /** - * Test that the operator/manufacturer settings hook test application is - * available and that it's installed in the device's system image. - */ - public void testSettingsHookTestAppAvailable() throws Exception { - Context context = mSettings.getApplicationContext(); - PackageManager pm = context.getPackageManager(); - ApplicationInfo applicationInfo = pm.getApplicationInfo(PACKAGE_NAME, 0); - assertTrue((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0); - } - - /** - * Test that the operator test activity has registered an intent-filter for - * an action named 'android.settings.OPERATOR_APPLICATION_SETTING'. - */ - public void testOperatorIntentFilter() { - boolean result = false; - Context context = mSettings.getApplicationContext(); - PackageManager pm = context.getPackageManager(); - Intent intent = new Intent(INTENT_OPERATOR_HOOK); - List list = pm.queryIntentActivities(intent, 0); - for (ResolveInfo resolveInfo : list) { - if (resolveInfo.activityInfo.packageName.equals(PACKAGE_NAME)) { - result = true; - } - } - assertTrue("Intent-filter not found", result); - } - - /** - * Test that the manufacturer test activity has registered an intent-filter - * for an action named 'android.settings.MANUFACTURER_APPLICATION_SETTING'. - */ - public void testManufacturerIntentFilter() { - boolean result = false; - Context context = mSettings.getApplicationContext(); - PackageManager pm = context.getPackageManager(); - Intent intent = new Intent(INTENT_MANUFACTURER_HOOK); - List list = pm.queryIntentActivities(intent, 0); - for (ResolveInfo resolveInfo : list) { - if (resolveInfo.activityInfo.packageName.equals(PACKAGE_NAME)) { - result = true; - } - } - assertTrue("Intent-filter not found", result); - } - - /** - * Test that the operator preference is available in the Settings - * application. - */ - public void testOperatorPreferenceAvailable() { -// TODO: fix this test case to work with fragments -// PreferenceGroup root = (PreferenceGroup)mSettings.findPreference(KEY_SETTINGS_ROOT); -// Preference operatorPreference = root.findPreference(KEY_SETTINGS_OPERATOR); -// assertNotNull(operatorPreference); - } - - /** - * Test that the manufacturer preference is available in the Settings - * application. - */ - public void testManufacturerPreferenceAvailable() { -// TODO: fix this test case to work with fragments -// PreferenceGroup root = (PreferenceGroup)mSettings.findPreference(KEY_SETTINGS_ROOT); -// Preference manufacturerHook = root.findPreference(KEY_SETTINGS_MANUFACTURER); -// assertNotNull(manufacturerHook); - } - -} diff --git a/tests/unit/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragmentTest.java b/tests/unit/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragmentTest.java index f8d06a8a83d..0c27379a0fd 100644 --- a/tests/unit/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragmentTest.java +++ b/tests/unit/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragmentTest.java @@ -30,6 +30,7 @@ import static org.hamcrest.Matchers.allOf; import android.app.Instrumentation; import android.os.Bundle; + import android.provider.Settings; import android.widget.CompoundButton; @@ -63,14 +64,6 @@ public class AccessibilityShortcutPreferenceFragmentTest { mActivity = mActivityRule.getActivity(); } - @Test - public void lockScreenPreference_defaultBeforeDialogShown_isOff() { - setDialogShown(false); - setOnLockscreen(null); - startFragment(); - assertLockscreenSwitchIsCheckedIs(false); - } - @Test public void lockScreenPreference_setOnBeforeDialogShown_isOn() { setDialogShown(false); @@ -87,14 +80,6 @@ public class AccessibilityShortcutPreferenceFragmentTest { assertLockscreenSwitchIsCheckedIs(true); } - @Test - public void lockScreenPreference_setOffAfterDialogShown_isOn() { - setDialogShown(true); - setOnLockscreen(false); - startFragment(); - assertLockscreenSwitchIsCheckedIs(false); - } - private void startFragment() { mInstrumentation.runOnMainSync(() -> { new SubSettingLauncher(mActivity) diff --git a/tests/unit/src/com/android/settings/applications/DefaultAppSettingsTest.java b/tests/unit/src/com/android/settings/applications/DefaultAppSettingsTest.java deleted file mode 100644 index 1dd899eb7e2..00000000000 --- a/tests/unit/src/com/android/settings/applications/DefaultAppSettingsTest.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.settings.applications; - -import android.content.Context; -import android.content.Intent; -import android.support.test.uiautomator.UiDevice; -import android.support.test.uiautomator.UiObject; -import android.support.test.uiautomator.UiSelector; -import android.test.InstrumentationTestCase; -import android.widget.TextView; - -import androidx.test.filters.SmallTest; - -import com.android.settings.R; - -import org.junit.Test; - -/** - * Test for Advanced App preferences. - */ -@SmallTest -public class DefaultAppSettingsTest extends InstrumentationTestCase { - - private UiDevice mDevice; - private Context mTargetContext; - private String mTargetPackage; - - @Override - protected void setUp() throws Exception { - super.setUp(); - mDevice = UiDevice.getInstance(getInstrumentation()); - mTargetContext = getInstrumentation().getTargetContext(); - mTargetPackage = mTargetContext.getPackageName(); - } - - @Test - public void testSelectDefaultHome_shouldLaunchHomePicker() throws Exception { - launchDefaultApps(); - final String titleHomeApp = mTargetContext.getResources().getString(R.string.home_app); - mDevice.findObject(new UiSelector().text(titleHomeApp)).click(); - final UiObject actionBar = mDevice.findObject(new UiSelector().resourceId( - "com.android.settings:id/action_bar")); - final UiObject title = actionBar.getChild( - new UiSelector().className(TextView.class.getName())); - assertEquals(titleHomeApp, title.getText()); - } - - private void launchDefaultApps() throws Exception { - final Intent settingsIntent = new Intent(Intent.ACTION_MAIN) - .addCategory(Intent.CATEGORY_LAUNCHER) - .setPackage(mTargetPackage) - .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - getInstrumentation().getContext().startActivity(settingsIntent); - final String titleApps = mTargetContext.getResources().getString( - R.string.app_and_notification_dashboard_title); - mDevice.findObject(new UiSelector().text(titleApps)).click(); - final String titleAdvance = mTargetContext.getResources().getString( - R.string.advanced_section_header); - mDevice.findObject(new UiSelector().text(titleAdvance)).click(); - final String titleDefaultApps = mTargetContext.getResources().getString( - R.string.app_default_dashboard_title); - mDevice.findObject(new UiSelector().text(titleDefaultApps)).click(); - } - -} diff --git a/tests/unit/src/com/android/settings/applications/ManageApplicationsLaunchTest.java b/tests/unit/src/com/android/settings/applications/ManageApplicationsLaunchTest.java deleted file mode 100644 index c98a43d5c84..00000000000 --- a/tests/unit/src/com/android/settings/applications/ManageApplicationsLaunchTest.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.settings.applications; - -import static androidx.test.espresso.Espresso.onView; -import static androidx.test.espresso.assertion.ViewAssertions.matches; -import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; -import static androidx.test.espresso.matcher.ViewMatchers.withText; - -import static org.hamcrest.Matchers.allOf; - -import android.app.Instrumentation; -import android.content.Intent; -import android.provider.Settings; - -import androidx.test.InstrumentationRegistry; -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -@SmallTest -@RunWith(AndroidJUnit4.class) -public class ManageApplicationsLaunchTest { - - private Instrumentation mInstrumentation; - - @Before - public void setUp() { - mInstrumentation = InstrumentationRegistry.getInstrumentation(); - } - - @Test - public void launchAppsSettings_shouldShowAppList() throws Exception { - final Intent appsSettingsIntent = new - Intent(Settings.ACTION_MANAGE_APPLICATIONS_SETTINGS); - - mInstrumentation.startActivitySync(appsSettingsIntent); - - onView(allOf(withText("Calculator"))).check(matches(isDisplayed())); - } -} diff --git a/tests/unit/src/com/android/settings/applications/SpecialAppAccessSettingsTest.java b/tests/unit/src/com/android/settings/applications/SpecialAppAccessSettingsTest.java deleted file mode 100644 index 4738d594a0f..00000000000 --- a/tests/unit/src/com/android/settings/applications/SpecialAppAccessSettingsTest.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.settings.applications; - -import android.content.Context; -import android.content.Intent; -import android.support.test.uiautomator.UiDevice; -import android.support.test.uiautomator.UiObject; -import android.support.test.uiautomator.UiObjectNotFoundException; -import android.support.test.uiautomator.UiScrollable; -import android.support.test.uiautomator.UiSelector; -import android.test.InstrumentationTestCase; -import android.widget.TextView; - -import androidx.test.filters.SmallTest; - -import com.android.settings.R; - -import org.junit.Test; - -/** - * Test for Special App Access preferences. - */ -@SmallTest -public class SpecialAppAccessSettingsTest extends InstrumentationTestCase { - - private UiDevice mDevice; - private Context mTargetContext; - private String mTargetPackage; - - @Override - protected void setUp() throws Exception { - super.setUp(); - mDevice = UiDevice.getInstance(getInstrumentation()); - mTargetContext = getInstrumentation().getTargetContext(); - mTargetPackage = mTargetContext.getPackageName(); - } - - @Test - public void testSelectPictureInPicture_shouldNotCrash() throws Exception { - launchSpecialApps(); - final String titlePictureInPictureApp = - mTargetContext.getResources().getString(R.string.picture_in_picture_title); - - // select Picture-in-Picture - mDevice.findObject(new UiSelector().text(titlePictureInPictureApp)).click(); - - // Picture-in-picture settings page should launch and no crash - final UiObject actionBar = mDevice.findObject(new UiSelector().resourceId( - "com.android.settings:id/action_bar")); - final UiObject title = actionBar.getChild( - new UiSelector().className(TextView.class.getName())); - assertEquals(titlePictureInPictureApp, title.getText()); - } - - private void launchSpecialApps() throws Exception { - final Intent settingsIntent = new Intent(Intent.ACTION_MAIN) - .addCategory(Intent.CATEGORY_LAUNCHER) - .setPackage(mTargetPackage) - .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - getInstrumentation().getContext().startActivity(settingsIntent); - final String titleApps = mTargetContext.getResources().getString( - R.string.app_and_notification_dashboard_title); - mDevice.findObject(new UiSelector().text(titleApps)).click(); - final String titleAdvance = mTargetContext.getResources().getString( - R.string.advanced_section_header); - mDevice.findObject(new UiSelector().text(titleAdvance)).click(); - final String titleSpecialApps = mTargetContext.getResources().getString( - R.string.special_access); - - try { - // scollbar may or may not be present, depending on how many recents app are there. If - // the page is scrollable, scroll to the bottom to show the special app access settings. - final UiScrollable settings = new UiScrollable( - new UiSelector().packageName(mTargetContext.getPackageName()).scrollable(true)); - settings.scrollTextIntoView(titleSpecialApps); - } catch (UiObjectNotFoundException e) { - // ignore - } - - mDevice.findObject(new UiSelector().text(titleSpecialApps)).click(); - } - -} diff --git a/tests/unit/src/com/android/settings/backup/BackupIntentTest.java b/tests/unit/src/com/android/settings/backup/BackupIntentTest.java index 0115c569aef..54e7451d8a2 100644 --- a/tests/unit/src/com/android/settings/backup/BackupIntentTest.java +++ b/tests/unit/src/com/android/settings/backup/BackupIntentTest.java @@ -39,7 +39,7 @@ import java.util.List; public class BackupIntentTest { private static final String INTENT_PRIVACY_SETTINGS = "android.settings.PRIVACY_SETTINGS"; private static final String BACKUP_SETTINGS_ACTIVITY = - "com.android.settings.backup.UserBackupSettingsActivity"; + "com.android.settings.Settings$PrivacyDashboardActivity"; private Context mContext; diff --git a/tests/unit/src/com/android/settings/bluetooth/BluetoothDeviceDetailsRotationTest.java b/tests/unit/src/com/android/settings/bluetooth/BluetoothDeviceDetailsRotationTest.java deleted file mode 100644 index aec6dd22df1..00000000000 --- a/tests/unit/src/com/android/settings/bluetooth/BluetoothDeviceDetailsRotationTest.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.settings.bluetooth; - -import static org.mockito.Mockito.when; - -import android.app.Instrumentation; -import android.content.Context; -import android.content.Intent; -import android.os.Bundle; -import android.os.RemoteException; -import android.support.test.uiautomator.UiDevice; - -import androidx.test.InstrumentationRegistry; -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import com.android.settings.SettingsActivity; -import com.android.settings.core.SubSettingLauncher; -import com.android.settingslib.bluetooth.CachedBluetoothDevice; -import com.android.settingslib.bluetooth.LocalBluetoothManager; -import com.android.settingslib.core.instrumentation.Instrumentable; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Answers; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class BluetoothDeviceDetailsRotationTest { - private Context mContext; - private UiDevice mUiDevice; - private Instrumentation mInstrumentation; - - @Mock(answer = Answers.RETURNS_DEEP_STUBS) - private CachedBluetoothDevice mCachedDevice; - - @Mock(answer = Answers.RETURNS_DEEP_STUBS) - private LocalBluetoothManager mBluetoothManager; - - private String mDeviceAddress; - - @Before - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - mContext = InstrumentationRegistry.getTargetContext(); - mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); - mInstrumentation = InstrumentationRegistry.getInstrumentation(); - - mDeviceAddress = "AA:BB:CC:DD:EE:FF"; - when(mCachedDevice.getAddress()).thenReturn(mDeviceAddress); - when(mCachedDevice.getName()).thenReturn("Mock Device"); - - BluetoothDeviceDetailsFragment.sTestDataFactory = - new BluetoothDeviceDetailsFragment.TestDataFactory() { - @Override - public CachedBluetoothDevice getDevice(String deviceAddress) { - return mCachedDevice; - } - - @Override - public LocalBluetoothManager getManager(Context context) { - return mBluetoothManager; - } - }; - } - - @Test - public void rotation() { - Intent intent = new Intent("android.settings.BLUETOOTH_SETTINGS"); - SettingsActivity activity = (SettingsActivity) mInstrumentation.startActivitySync(intent); - Bundle args = new Bundle(1); - args.putString(BluetoothDeviceDetailsFragment.KEY_DEVICE_ADDRESS, mDeviceAddress); - new SubSettingLauncher(activity) - .setDestination(BluetoothDeviceDetailsFragment.class.getName()) - .setTitleText("test") - .setArguments(args) - .setSourceMetricsCategory(Instrumentable.METRICS_CATEGORY_UNKNOWN) - .launch(); - try { - mUiDevice.setOrientationLeft(); - mUiDevice.setOrientationNatural(); - mUiDevice.setOrientationRight(); - mUiDevice.setOrientationNatural(); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } -} \ No newline at end of file diff --git a/tests/unit/src/com/android/settings/bluetooth/DevicePickerActivityTest.java b/tests/unit/src/com/android/settings/bluetooth/DevicePickerActivityTest.java deleted file mode 100644 index e531e0a9740..00000000000 --- a/tests/unit/src/com/android/settings/bluetooth/DevicePickerActivityTest.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.settings.bluetooth; - -import android.app.Instrumentation; -import android.content.Intent; - -import androidx.test.InstrumentationRegistry; -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class DevicePickerActivityTest { - - private Instrumentation mInstrumentation; - - @Before - public void setUp() throws Exception { - mInstrumentation = InstrumentationRegistry.getInstrumentation(); - } - - @Test - public void startActivityNoCrash() { - mInstrumentation.startActivitySync( - new Intent("android.bluetooth.devicepicker.action.LAUNCH")); - // No crash - } -} diff --git a/tests/unit/src/com/android/settings/connecteddevice/ConnectedDeviceActivityTest.java b/tests/unit/src/com/android/settings/connecteddevice/ConnectedDeviceActivityTest.java deleted file mode 100644 index 2957c4cfdc6..00000000000 --- a/tests/unit/src/com/android/settings/connecteddevice/ConnectedDeviceActivityTest.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.settings.connecteddevice; - -import static com.google.common.truth.Truth.assertThat; - -import android.app.Instrumentation; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.text.TextUtils; - -import androidx.test.InstrumentationRegistry; -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.util.List; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class ConnectedDeviceActivityTest { - private static final String INTENT_ACTION = "android.intent.action.MAIN"; - private static final String CONNECTED_DEVICE_TITLE = "Connected devices"; - - private Instrumentation mInstrumentation; - - @Before - public void setUp() throws Exception { - mInstrumentation = InstrumentationRegistry.getInstrumentation(); - } - - @Test - public void queryConnectedDeviceActivity_onlyOneResponse() { - final PackageManager packageManager = mInstrumentation.getContext().getPackageManager(); - final Intent intent = new Intent(INTENT_ACTION); - - int count = 0; - final List resolveInfoList = packageManager.queryIntentActivities(intent, - PackageManager.GET_META_DATA); - for (ResolveInfo info : resolveInfoList) { - if (TextUtils.equals(info.activityInfo.loadLabel(packageManager).toString(), - CONNECTED_DEVICE_TITLE)) { - count++; - } - } - - assertThat(count).isEqualTo(1); - } - -} diff --git a/tests/unit/src/com/android/settings/dashboard/PreferenceThemeTest.java b/tests/unit/src/com/android/settings/dashboard/PreferenceThemeTest.java index 18a5e70f32d..0ae5597f356 100644 --- a/tests/unit/src/com/android/settings/dashboard/PreferenceThemeTest.java +++ b/tests/unit/src/com/android/settings/dashboard/PreferenceThemeTest.java @@ -18,13 +18,9 @@ package com.android.settings.dashboard; import static androidx.test.espresso.Espresso.onView; import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist; -import static androidx.test.espresso.assertion.ViewAssertions.matches; -import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; import static androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility; import static androidx.test.espresso.matcher.ViewMatchers.withId; -import static com.android.settings.dashboard.FirstIdViewMatcher.withFirstId; - import static org.hamcrest.Matchers.allOf; import android.app.Instrumentation; @@ -57,12 +53,6 @@ public class PreferenceThemeTest { mTargetPackage = mTargetContext.getPackageName(); } - @Test - public void startPhoneStatus_preferenceIconSpaceReserved() throws InterruptedException { - launchPhoneStatus(); - onView(withFirstId(R.id.icon_frame)).check(matches(isDisplayed())); - } - @Test public void startSetupWizardLockScreen_preferenceIconSpaceNotReserved() { launchSetupWizardLockScreen(); @@ -72,14 +62,6 @@ public class PreferenceThemeTest { onView(withId(R.id.icon_container)).check(doesNotExist()); } - private void launchPhoneStatus() { - final Intent settingsIntent = new Intent("android.settings.DEVICE_INFO_SETTINGS") - .addCategory(Intent.CATEGORY_DEFAULT) - .setPackage(mTargetPackage) - .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - InstrumentationRegistry.getInstrumentation().startActivitySync(settingsIntent); - } - private void launchSetupWizardLockScreen() { final Intent settingsIntent = new Intent("com.android.settings.SETUP_LOCK_SCREEN") .addCategory(Intent.CATEGORY_DEFAULT) diff --git a/tests/unit/src/com/android/settings/datausage/MobileDataUsageActivityTest.java b/tests/unit/src/com/android/settings/datausage/MobileDataUsageActivityTest.java deleted file mode 100644 index 066d1997141..00000000000 --- a/tests/unit/src/com/android/settings/datausage/MobileDataUsageActivityTest.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.settings; - -import static junit.framework.Assert.assertEquals; - -import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.net.NetworkTemplate; -import android.telephony.SubscriptionManager; -import android.telephony.TelephonyManager; - -import androidx.test.InstrumentationRegistry; -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import org.junit.Test; -import org.junit.runner.RunWith; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class MobileDataUsageActivityTest { - private static final String TAG = "MobileDataUsageTest"; - @Test - public void test_mobileDataUsageIntent() { - final Context context = InstrumentationRegistry.getTargetContext(); - final PackageManager packageManager = context.getPackageManager(); - final int subId = SubscriptionManager.getDefaultSubscriptionId(); - final NetworkTemplate template = getNetworkTemplate(context, subId); - - Intent intent = new Intent(android.provider.Settings.ACTION_MOBILE_DATA_USAGE); - intent.putExtra(android.provider.Settings.EXTRA_NETWORK_TEMPLATE, template); - intent.putExtra(android.provider.Settings.EXTRA_SUB_ID, subId); - - assertEquals(packageManager.queryIntentActivities(intent, 0).size(), 1); - - context.startActivity(intent); - // Should exit gracefully without crashing. - } - - private NetworkTemplate getNetworkTemplate(Context context, int subId) { - TelephonyManager tm = (TelephonyManager) context - .getSystemService(Context.TELEPHONY_SERVICE); - NetworkTemplate mobileAll = NetworkTemplate.buildTemplateMobileAll( - tm.getSubscriberId(subId)); - return NetworkTemplate.normalize(mobileAll, - tm.getMergedSubscriberIds()); - } -} diff --git a/tests/unit/src/com/android/settings/datetime/timezone/model/TimeZoneDataTest.java b/tests/unit/src/com/android/settings/datetime/timezone/model/TimeZoneDataTest.java index 26595292f3d..a04c08d37e7 100644 --- a/tests/unit/src/com/android/settings/datetime/timezone/model/TimeZoneDataTest.java +++ b/tests/unit/src/com/android/settings/datetime/timezone/model/TimeZoneDataTest.java @@ -56,9 +56,6 @@ public class TimeZoneDataTest { */ assertThat(mTimeZoneData.lookupCountryCodesForZoneId("Europe/Simferopol").isEmpty()) .isTrue(); - // Metlakatla has the same time as Anchorage after 2015 - assertThat(mTimeZoneData.lookupCountryCodesForZoneId("America/Metlakatla").isEmpty()) - .isTrue(); assertThat(mTimeZoneData.lookupCountryCodesForZoneId("Europe/London").isEmpty()) .isFalse(); assertThat(mTimeZoneData.lookupCountryCodesForZoneId("America/Los_Angeles").isEmpty()) diff --git a/tests/unit/src/com/android/settings/deviceinfo/StorageDashboardFragmentTest.java b/tests/unit/src/com/android/settings/deviceinfo/StorageDashboardFragmentTest.java deleted file mode 100644 index a0053be5a37..00000000000 --- a/tests/unit/src/com/android/settings/deviceinfo/StorageDashboardFragmentTest.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.android.settings.deviceinfo; - -import static androidx.test.espresso.Espresso.onView; -import static androidx.test.espresso.action.ViewActions.click; -import static androidx.test.espresso.intent.Intents.intended; -import static androidx.test.espresso.intent.matcher.IntentMatchers.hasExtra; -import static androidx.test.espresso.matcher.ViewMatchers.withText; - -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.equalTo; - -import androidx.test.espresso.intent.rule.IntentsTestRule; -import androidx.test.filters.SmallTest; - -import com.android.settings.R; -import com.android.settings.Settings.StorageDashboardActivity; -import com.android.settings.deletionhelper.AutomaticStorageManagerSettings; - -import org.junit.Rule; -import org.junit.Test; - -@SmallTest -public class StorageDashboardFragmentTest { - - public static final String EXTRA_KEY = ":settings:show_fragment"; - - @Rule - public IntentsTestRule mActivityRule = - new IntentsTestRule<>(StorageDashboardActivity.class, true, true); - - @Test - public void testStorageManagePreference_canClickTextView() throws InterruptedException { - // Click on the actual textbox instead of just somewhere in the preference - onView(withText(R.string.automatic_storage_manager_preference_title)).perform(click()); - - // Check that it worked by seeing if we switched screens - intended(hasExtra(equalTo(EXTRA_KEY), - containsString(AutomaticStorageManagerSettings.class.getName()))); - - } -} diff --git a/tests/unit/src/com/android/settings/dream/DreamSettingsLaunchTest.java b/tests/unit/src/com/android/settings/dream/DreamSettingsLaunchTest.java deleted file mode 100644 index 6a2abd54552..00000000000 --- a/tests/unit/src/com/android/settings/dream/DreamSettingsLaunchTest.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.settings.dream; - -import android.content.Context; -import android.content.Intent; -import android.provider.Settings; - -import androidx.test.InstrumentationRegistry; -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import org.junit.Test; -import org.junit.runner.RunWith; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class DreamSettingsLaunchTest { - - @Test - public void launchFromIntent_doesNotCrash() { - final Context context = InstrumentationRegistry.getTargetContext(); - Intent intent = new Intent(Settings.ACTION_DREAM_SETTINGS); - - context.startActivity(intent); - } -} diff --git a/tests/unit/src/com/android/settings/notification/AppNotificationSettingsTest.java b/tests/unit/src/com/android/settings/notification/AppNotificationSettingsTest.java index ede4631abd6..19b1360247d 100644 --- a/tests/unit/src/com/android/settings/notification/AppNotificationSettingsTest.java +++ b/tests/unit/src/com/android/settings/notification/AppNotificationSettingsTest.java @@ -41,6 +41,7 @@ import android.app.NotificationManager; import android.content.Context; import android.content.Intent; import android.provider.Settings; +import android.support.test.uiautomator.UiDevice; import androidx.test.InstrumentationRegistry; import androidx.test.espresso.intent.Intents; @@ -55,7 +56,9 @@ import org.junit.runner.RunWith; @RunWith(AndroidJUnit4.class) @SmallTest public class AppNotificationSettingsTest { + private static final String WM_DISMISS_KEYGUARD_COMMAND = "wm dismiss-keyguard"; + private UiDevice mUiDevice; private Context mTargetContext; private Instrumentation mInstrumentation; @@ -68,9 +71,14 @@ public class AppNotificationSettingsTest { private NotificationChannel mUngroupedChannel; @Before - public void setUp() { + public void setUp() throws Exception { mInstrumentation = InstrumentationRegistry.getInstrumentation(); mTargetContext = mInstrumentation.getTargetContext(); + + mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); + mUiDevice.wakeUp(); + mUiDevice.executeShellCommand(WM_DISMISS_KEYGUARD_COMMAND); + mNm = (NotificationManager) mTargetContext.getSystemService(Context.NOTIFICATION_SERVICE); mGroup1 = new NotificationChannelGroup(this.getClass().getName() + "1", "group1"); @@ -87,7 +95,8 @@ public class AppNotificationSettingsTest { @Test public void launchNotificationSetting_shouldNotHaveAppInfoLink() { final Intent intent = new Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS) - .putExtra(Settings.EXTRA_APP_PACKAGE, mTargetContext.getPackageName()); + .putExtra(Settings.EXTRA_APP_PACKAGE, mTargetContext.getPackageName()) + .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); mInstrumentation.startActivitySync(intent); @@ -99,60 +108,38 @@ public class AppNotificationSettingsTest { @Test public void launchNotificationSetting_showGroupsWithMultipleChannels() { final Intent intent = new Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS) - .putExtra(Settings.EXTRA_APP_PACKAGE, mTargetContext.getPackageName()); + .putExtra(Settings.EXTRA_APP_PACKAGE, mTargetContext.getPackageName()) + .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); mInstrumentation.startActivitySync(intent); onView(allOf(withText(mGroup1.getName().toString()))).check( matches(isDisplayed())); - try { - onView(allOf(withText(mGroup1Channel1.getName().toString()))) - .check(matches(isDisplayed())); - fail("Channel erroneously appearing"); - } catch (Exception e) { - // expected - } - // links to group page - Intents.init(); - onView(allOf(withText(mGroup1.getName().toString()))).perform(click()); - intended(allOf(hasExtra(EXTRA_SHOW_FRAGMENT, - ChannelGroupNotificationSettings.class.getName()))); - Intents.release(); + onView(allOf(withText(mGroup1Channel1.getName().toString()))).check( + matches(isDisplayed())); + onView(allOf(withText(mGroup1Channel2.getName().toString()))).check( + matches(isDisplayed())); } @Test public void launchNotificationSetting_showUngroupedChannels() { final Intent intent = new Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS) - .putExtra(Settings.EXTRA_APP_PACKAGE, mTargetContext.getPackageName()); + .putExtra(Settings.EXTRA_APP_PACKAGE, mTargetContext.getPackageName()) + .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); mInstrumentation.startActivitySync(intent); onView(allOf(withText(mUngroupedChannel.getName().toString()))) .check(matches(isDisplayed())); - // links directly to channel page - Intents.init(); - onView(allOf(withText(mUngroupedChannel.getName().toString()))).perform(click()); - intended(allOf(hasExtra(EXTRA_SHOW_FRAGMENT, ChannelNotificationSettings.class.getName()))); - Intents.release(); } @Test public void launchNotificationSetting_showGroupsWithOneChannel() { final Intent intent = new Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS) - .putExtra(Settings.EXTRA_APP_PACKAGE, mTargetContext.getPackageName()); + .putExtra(Settings.EXTRA_APP_PACKAGE, mTargetContext.getPackageName()) + .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); mInstrumentation.startActivitySync(intent); + onView(allOf(withText(mGroup2.getName().toString()))) + .check(matches(isDisplayed())); onView(allOf(withText(mGroup2Channel1.getName().toString()))) .check(matches(isDisplayed())); - try { - onView(allOf(withText(mGroup2.getName().toString()))).check( - matches(isDisplayed())); - fail("Group erroneously appearing"); - } catch (Exception e) { - // expected - } - - // links directly to channel page - Intents.init(); - onView(allOf(withText(mGroup2Channel1.getName().toString()))).perform(click()); - intended(allOf(hasExtra(EXTRA_SHOW_FRAGMENT, ChannelNotificationSettings.class.getName()))); - Intents.release(); } private NotificationChannel createChannel(NotificationChannelGroup group, diff --git a/tests/unit/src/com/android/settings/notification/ChannelNotificationSettingsTest.java b/tests/unit/src/com/android/settings/notification/ChannelNotificationSettingsTest.java index f7a5a82327b..9a3a99455c9 100644 --- a/tests/unit/src/com/android/settings/notification/ChannelNotificationSettingsTest.java +++ b/tests/unit/src/com/android/settings/notification/ChannelNotificationSettingsTest.java @@ -36,6 +36,7 @@ import android.content.Intent; import android.os.Process; import android.os.ServiceManager; import android.provider.Settings; +import android.support.test.uiautomator.UiDevice; import androidx.test.InstrumentationRegistry; import androidx.test.filters.SmallTest; @@ -48,17 +49,23 @@ import org.junit.runner.RunWith; @RunWith(AndroidJUnit4.class) @SmallTest public class ChannelNotificationSettingsTest { + private static final String WM_DISMISS_KEYGUARD_COMMAND = "wm dismiss-keyguard"; + private UiDevice mUiDevice; private Context mTargetContext; private Instrumentation mInstrumentation; private NotificationChannel mNotificationChannel; private NotificationManager mNm; @Before - public void setUp() { + public void setUp() throws Exception { mInstrumentation = InstrumentationRegistry.getInstrumentation(); mTargetContext = mInstrumentation.getTargetContext(); + mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); + mUiDevice.wakeUp(); + mUiDevice.executeShellCommand(WM_DISMISS_KEYGUARD_COMMAND); + mNm = (NotificationManager) mTargetContext.getSystemService(Context.NOTIFICATION_SERVICE); mNotificationChannel = new NotificationChannel(this.getClass().getName(), this.getClass().getName(), IMPORTANCE_MIN); @@ -69,7 +76,8 @@ public class ChannelNotificationSettingsTest { public void launchNotificationSetting_shouldNotCrash() { final Intent intent = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS) .putExtra(Settings.EXTRA_APP_PACKAGE, mTargetContext.getPackageName()) - .putExtra(Settings.EXTRA_CHANNEL_ID, mNotificationChannel.getId()); + .putExtra(Settings.EXTRA_CHANNEL_ID, mNotificationChannel.getId()) + .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); mInstrumentation.startActivitySync(intent); onView(allOf(withText(mNotificationChannel.getName().toString()))).check( @@ -90,12 +98,12 @@ public class ChannelNotificationSettingsTest { final Intent intent = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS) .putExtra(Settings.EXTRA_APP_PACKAGE, mTargetContext.getPackageName()) - .putExtra(Settings.EXTRA_CHANNEL_ID, blocked.getId()); + .putExtra(Settings.EXTRA_CHANNEL_ID, blocked.getId()) + .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); mInstrumentation.startActivitySync(intent); - onView(allOf(withText("Off"), isDisplayed())).check(matches(isDisplayed())); - onView(allOf(withText("Android is blocking this category of notifications from" - + " appearing on this device"))).check(matches(isDisplayed())); + onView(allOf(withText("At your request, Android is blocking this category of notifications" + + " from appearing on this device"))).check(matches(isDisplayed())); try { onView(allOf(withText("On the lock screen"))).check(matches(isDisplayed())); diff --git a/tests/unit/src/com/android/settings/notification/ZenModeSettingsIntegrationTest.java b/tests/unit/src/com/android/settings/notification/ZenModeSettingsIntegrationTest.java index 2fe4074928b..4120a07f7a1 100644 --- a/tests/unit/src/com/android/settings/notification/ZenModeSettingsIntegrationTest.java +++ b/tests/unit/src/com/android/settings/notification/ZenModeSettingsIntegrationTest.java @@ -37,27 +37,29 @@ public class ZenModeSettingsIntegrationTest { @Test public void testZenModeSettingsPreferences() { launchZenSettings(); - onView(withText("Behavior")).check(matches(isDisplayed())); - onView(withText("Turn on automatically")).check(matches(isDisplayed())); + onView(withText("Calls")).check(matches(isDisplayed())); + onView(withText("SMS, MMS, and messaging apps")).check(matches(isDisplayed())); + onView(withText("Restrict notifications")).check(matches(isDisplayed())); + onView(withText("Duration")).check(matches(isDisplayed())); + onView(withText("Schedules")).check(matches(isDisplayed())); } @Test public void testZenModeBehaviorPreferences() { launchZenBehaviorSettings(); - onView(withText("Alarms")).check(matches(isDisplayed())); - onView(withText("Media and system feedback")).check(matches(isDisplayed())); - onView(withText("Reminders")).check(matches(isDisplayed())); - onView(withText("Events")).check(matches(isDisplayed())); - onView(withText("Messages")).check(matches(isDisplayed())); onView(withText("Calls")).check(matches(isDisplayed())); - onView(withText("Repeat callers")).check(matches(isDisplayed())); + onView(withText("SMS, MMS, and messaging apps")).check(matches(isDisplayed())); + onView(withText("Restrict notifications")).check(matches(isDisplayed())); + onView(withText("Duration")).check(matches(isDisplayed())); + onView(withText("Schedules")).check(matches(isDisplayed())); } @Test public void testZenModeAutomationPreferences() { launchZenAutomationSettings(); - onView(withText("Weekend")).check(matches(isDisplayed())); - onView(withText("Add rule")).check(matches(isDisplayed())); + onView(withText("Sleeping")).check(matches(isDisplayed())); + onView(withText("Event")).check(matches(isDisplayed())); + onView(withText("Add more")).check(matches(isDisplayed())); } private void launchZenSettings() { diff --git a/tests/unit/src/com/android/settings/tests/DrawOverlayDetailsTest.java b/tests/unit/src/com/android/settings/tests/DrawOverlayDetailsTest.java deleted file mode 100644 index d450bf0cea3..00000000000 --- a/tests/unit/src/com/android/settings/tests/DrawOverlayDetailsTest.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2016 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.tests; - -import static androidx.test.espresso.Espresso.onView; -import static androidx.test.espresso.Espresso.openActionBarOverflowOrOptionsMenu; -import static androidx.test.espresso.action.ViewActions.click; -import static androidx.test.espresso.assertion.ViewAssertions.matches; -import static androidx.test.espresso.matcher.ViewMatchers.isEnabled; -import static androidx.test.espresso.matcher.ViewMatchers.withText; - -import static org.hamcrest.core.IsNot.not; - -import android.app.Instrumentation; -import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.support.test.uiautomator.UiDevice; -import android.support.test.uiautomator.UiScrollable; -import android.support.test.uiautomator.UiSelector; - -import androidx.test.InstrumentationRegistry; -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import com.android.settings.R; - -import org.junit.Test; -import org.junit.runner.RunWith; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class DrawOverlayDetailsTest { - private final static String PACKAGE_SYSTEM_UI = "com.android.systemui"; - - @Test - public void testSystemUiDrawOverlayDetails_Disabled() throws Exception{ - Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation(); - instrumentation.startActivitySync(new Intent(android.provider.Settings - .ACTION_MANAGE_OVERLAY_PERMISSION)); - - final Context targetContext = instrumentation.getTargetContext(); - - final PackageManager packageManager = targetContext.getPackageManager(); - final String appName = (String) packageManager.getApplicationLabel(packageManager - .getApplicationInfo(PACKAGE_SYSTEM_UI, PackageManager.GET_META_DATA)); - - final UiDevice device = UiDevice.getInstance(instrumentation); - device.waitForIdle(); - - openActionBarOverflowOrOptionsMenu(targetContext); - onView(withText(targetContext.getString(R.string.menu_show_system))).perform(click()); - device.waitForIdle(); - - final UiScrollable settings = new UiScrollable( - new UiSelector().packageName(targetContext.getPackageName()).scrollable(true)); - settings.scrollTextIntoView(appName); - onView(withText(appName)).perform(click()); - onView(withText(targetContext.getString(R.string.permit_draw_overlay))).check(matches - (not(isEnabled()))); - } - -} diff --git a/tests/unit/src/com/android/settings/tests/KeepOnScreenTest.java b/tests/unit/src/com/android/settings/tests/KeepOnScreenTest.java deleted file mode 100644 index b930ffb1f67..00000000000 --- a/tests/unit/src/com/android/settings/tests/KeepOnScreenTest.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) 2016 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.tests; - -import static androidx.test.espresso.Espresso.onView; -import static androidx.test.espresso.action.ViewActions.click; -import static androidx.test.espresso.matcher.ViewMatchers.withText; - -import static junit.framework.Assert.assertEquals; - -import android.app.Instrumentation; -import android.content.Context; -import android.content.Intent; -import android.os.BatteryManager; -import android.provider.Settings; - -import androidx.test.InstrumentationRegistry; -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import com.android.settings.R; - -import org.junit.Test; -import org.junit.runner.RunWith; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class KeepOnScreenTest { - private static int EXPECTED_FLAG = BatteryManager.BATTERY_PLUGGED_AC - | BatteryManager.BATTERY_PLUGGED_USB | BatteryManager.BATTERY_PLUGGED_WIRELESS; - - @Test - public void testStayAwake_turnOn_StayAwakeWhileWirelessCharging() throws Exception{ - Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation(); - instrumentation.startActivitySync(new Intent(android.provider.Settings - .ACTION_APPLICATION_DEVELOPMENT_SETTINGS)); - - final Context targetContext = instrumentation.getTargetContext(); - final int prevFlag = Settings.Global.getInt(targetContext.getContentResolver(), Settings - .Global.STAY_ON_WHILE_PLUGGED_IN); - - // Turn on "Stay Awake" if needed - if (prevFlag == 0) { - onView(withText(R.string.keep_screen_on)).perform(click()); - } - - final int currentFlag = Settings.Global.getInt(targetContext.getContentResolver(), Settings - .Global.STAY_ON_WHILE_PLUGGED_IN); - - assertEquals(EXPECTED_FLAG, currentFlag); - - // Since this app doesn't have permission(and shouldn't have) to change global setting, we - // can only tearDown in this way - if (prevFlag != currentFlag) { - onView(withText(R.string.keep_screen_on)).perform(click()); - } - } -} diff --git a/tests/unit/src/com/android/settings/tests/PrivateVolumeSettingsTest.java b/tests/unit/src/com/android/settings/tests/PrivateVolumeSettingsTest.java deleted file mode 100644 index 2760a0782a4..00000000000 --- a/tests/unit/src/com/android/settings/tests/PrivateVolumeSettingsTest.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2016 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.tests; - -import static androidx.test.espresso.Espresso.onView; -import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist; -import static androidx.test.espresso.matcher.ViewMatchers.withText; - -import android.app.Instrumentation; -import android.content.Intent; - -import androidx.test.InstrumentationRegistry; -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import org.junit.Test; -import org.junit.runner.RunWith; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class PrivateVolumeSettingsTest { - @Test - public void test_ManageStorageNotShown() { - Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation(); - instrumentation.startActivitySync( - new Intent(android.provider.Settings.ACTION_INTERNAL_STORAGE_SETTINGS)); - onView(withText(com.android.settings.R.string.storage_menu_manage)).check(doesNotExist()); - } -} \ No newline at end of file diff --git a/tests/unit/src/com/android/settings/tests/SettingsRestoreAfterCloseTest.java b/tests/unit/src/com/android/settings/tests/SettingsRestoreAfterCloseTest.java deleted file mode 100644 index 3c6caf78644..00000000000 --- a/tests/unit/src/com/android/settings/tests/SettingsRestoreAfterCloseTest.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (C) 2016 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.tests; - -import android.app.ActivityManager; -import android.content.Context; -import android.content.Intent; -import android.provider.Settings; -import android.support.test.uiautomator.By; -import android.support.test.uiautomator.UiDevice; -import android.support.test.uiautomator.Until; - -import androidx.test.InstrumentationRegistry; -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class SettingsRestoreAfterCloseTest { - private static final String PACKAGE_SETTINGS = "com.android.settings"; - private static final int TIME_OUT = 2000; - - private boolean mAlwaysFinish; - - @Before - public void setUp() throws Exception { - // To make sure when we press home button, the activity will be destroyed by OS - Context context = InstrumentationRegistry.getContext(); - mAlwaysFinish = Settings.Global.getInt( - context.getContentResolver(), Settings.Global - .ALWAYS_FINISH_ACTIVITIES, 0) - != 0; - - ActivityManager.getService().setAlwaysFinish(true); - } - - @After - public void tearDown() throws Exception { - ActivityManager.getService().setAlwaysFinish(mAlwaysFinish); - } - - @Test - public void testRtlStability_AppCloseAndReOpen_shouldNotCrash() throws Exception { - - final UiDevice uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation - ()); - uiDevice.pressHome(); - - // Open the settings app - startSettingsMainActivity(uiDevice); - - // Press home button - uiDevice.pressHome(); - final String launcherPackage = uiDevice.getLauncherPackageName(); - uiDevice.wait(Until.hasObject(By.pkg(launcherPackage).depth(0)), TIME_OUT); - - // Open the settings again - startSettingsMainActivity(uiDevice); - } - - private void startSettingsMainActivity(UiDevice uiDevice) { - Context context = InstrumentationRegistry.getContext(); - context.startActivity(new Intent(android.provider.Settings.ACTION_SETTINGS)); - uiDevice.wait(Until.hasObject(By.pkg(PACKAGE_SETTINGS).depth(0)), TIME_OUT); - } -} diff --git a/tests/unit/src/com/android/settings/users/UserSettingsTest.java b/tests/unit/src/com/android/settings/users/UserSettingsTest.java deleted file mode 100644 index 93f62f39a15..00000000000 --- a/tests/unit/src/com/android/settings/users/UserSettingsTest.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (C) 2016 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.users; - -import static com.google.common.truth.Truth.assertThat; - -import android.content.Context; -import android.content.Intent; -import android.support.test.uiautomator.UiDevice; -import android.support.test.uiautomator.UiObject; -import android.support.test.uiautomator.UiObjectNotFoundException; -import android.support.test.uiautomator.UiScrollable; -import android.support.test.uiautomator.UiSelector; - -import androidx.test.InstrumentationRegistry; -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class UserSettingsTest { - - private static final String SYSTEM = "System"; - private static final String ADVANCED = "Advanced"; - private static final String USERS = "Multiple users"; - private static final String EMERGNENCY_INFO = "Emergency information"; - private static final String ADD_USERS_WHEN_LOCKED = "Add users"; - private static final String SWITCH_USER_BUTTON = "com.android.systemui:id/multi_user_switch"; - private static final String SETTINGS_BUTTON = "com.android.systemui:id/settings_button"; - private static final String PRIMARY_USER = "Owner"; - private static final String GUEST_USER = "Guest"; - private static final String ADD_GUEST = "Add guest"; - private static final String CONTINUE = "Yes, continue"; - - private UiDevice mDevice; - private Context mContext; - private String mTargetPackage; - - @Before - public void setUp() { - mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); - mContext = InstrumentationRegistry.getTargetContext(); - mTargetPackage = mContext.getPackageName(); - } - - @Test - public void testEmergencyInfoNotExists() throws Exception { - launchUserSettings(); - UiObject emergencyInfoPreference = - mDevice.findObject(new UiSelector().text(EMERGNENCY_INFO)); - - assertThat(emergencyInfoPreference.exists()).isFalse(); - } - - @Test - public void testAddUsersWhenLockedNotExists() throws Exception { - launchUserSettings(); - UiObject addUsersPreference = - mDevice.findObject(new UiSelector().text(ADD_USERS_WHEN_LOCKED)); - assertThat(addUsersPreference.exists()).isFalse(); - } - - @Test - public void testUsersExistsOnSecondaryUser() throws Exception { - // switch to guest user - switchToOrCreateGuest(); - // launch settings (launch from intent doesn't work, hence launch from quick settings) - mDevice.openQuickSettings(); - mDevice.findObject(new UiSelector().resourceId(SETTINGS_BUTTON)).click(); - // launch system settings and expand whole screen - final UiScrollable settings = new UiScrollable( - new UiSelector().packageName(mTargetPackage).scrollable(true)); - final String titleSystem = SYSTEM; - settings.scrollTextIntoView(titleSystem); - mDevice.findObject(new UiSelector().text(titleSystem)).click(); - mDevice.findObject(new UiSelector().text(ADVANCED)).click(); - - final boolean hasUsersSettings = mDevice.findObject(new UiSelector().text(USERS)).exists(); - - // switch back to primary user - mDevice.openQuickSettings(); - mDevice.findObject(new UiSelector().resourceId(SWITCH_USER_BUTTON)).click(); - mDevice.findObject(new UiSelector().text(PRIMARY_USER)).click(); - - assertThat(hasUsersSettings).isTrue(); - } - - private void launchSettings() { - Intent settingsIntent = new Intent(Intent.ACTION_MAIN) - .addCategory(Intent.CATEGORY_LAUNCHER) - .setPackage(mTargetPackage) - .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - mContext.startActivity(settingsIntent); - } - - private void launchUserSettings() throws Exception { - launchSettings(); - final UiScrollable settings = new UiScrollable( - new UiSelector().packageName(mTargetPackage).scrollable(true)); - final String titleSystem = SYSTEM; - settings.scrollTextIntoView(titleSystem); - mDevice.findObject(new UiSelector().text(titleSystem)).click(); - mDevice.findObject(new UiSelector().text(ADVANCED)).click(); - mDevice.findObject(new UiSelector().text(USERS)).click(); - } - - private void switchToOrCreateGuest() throws UiObjectNotFoundException { - mDevice.openQuickSettings(); - mDevice.findObject(new UiSelector().resourceId(SWITCH_USER_BUTTON)).click(); - // if no existing guest user, select "Add guest", otherwise select "Guest" - final UiObject addGuest = mDevice.findObject(new UiSelector().text(ADD_GUEST)); - if (addGuest.exists()) { - addGuest.click(); - mDevice.waitForIdle(); - mDevice.pressBack(); - } else { - mDevice.findObject(new UiSelector().text(GUEST_USER)).click(); - mDevice.waitForIdle(); - mDevice.findObject(new UiSelector().text(CONTINUE)).click(); - mDevice.waitForIdle(); - } - } -} diff --git a/tests/unit/src/com/android/settings/wifi/tether/WifiTetherSettingsTest.java b/tests/unit/src/com/android/settings/wifi/tether/WifiTetherSettingsTest.java index cb586e43432..2de66110c55 100644 --- a/tests/unit/src/com/android/settings/wifi/tether/WifiTetherSettingsTest.java +++ b/tests/unit/src/com/android/settings/wifi/tether/WifiTetherSettingsTest.java @@ -56,7 +56,8 @@ public class WifiTetherSettingsTest { mTetherActivityIntent = new Intent() .setClassName(mInstrumentation.getTargetContext().getPackageName(), Settings.TetherSettingsActivity.class.getName()) - .setPackage(mInstrumentation.getTargetContext().getPackageName()); + .setPackage(mInstrumentation.getTargetContext().getPackageName()) + .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); } @After @@ -69,7 +70,6 @@ public class WifiTetherSettingsTest { launchWifiTetherActivity(); onView(withText("Hotspot name")).check(matches(isDisplayed())); onView(withText("Hotspot password")).check(matches(isDisplayed())); - onView(withText("AP Band")).check(matches(isDisplayed())); } private void launchWifiTetherActivity() {