diff --git a/OWNERS b/OWNERS new file mode 100644 index 00000000000..e19e56fdbf0 --- /dev/null +++ b/OWNERS @@ -0,0 +1,15 @@ +# Use this reviewer by default. +pixel-sw-exp-reviews+gerrit@google.com + +# People who can approve changes for submission +asapperstein@google.com +asargent@google.com +dehboxturtle@google.com +dhnishi@google.com +dling@google.com +jackqdyulei@google.com +mfritze@google.com +zhfan@google.com + +# Emergency approvers in case the above are not available +miket@google.com diff --git a/res/values/config.xml b/res/values/config.xml index 92c11f6c27e..f964d5ee241 100755 --- a/res/values/config.xml +++ b/res/values/config.xml @@ -44,6 +44,9 @@ false + + false + com.android.settings.overlay.FeatureFactoryImpl diff --git a/res/values/strings.xml b/res/values/strings.xml index c58f6bb3b30..e278176b780 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -3633,8 +3633,6 @@ Recently opened apps See all %1$d apps - - ^1 ago @@ -4644,12 +4642,10 @@ Mobile network scanning - - ^1 ago - App usage since full charge (^1 ago) + App usage since full charge (^1) - Device usage since full charge (^1 ago) + Device usage since full charge (^1) Amount of time screen has been on since full charge @@ -8260,6 +8256,9 @@ To apply Camera HAL HDR+ change, reboot device + + Camera Laser Sensor + Automatic system updates diff --git a/res/xml/apn_editor.xml b/res/xml/apn_editor.xml index eac78e97f62..b1e332bd7c4 100644 --- a/res/xml/apn_editor.xml +++ b/res/xml/apn_editor.xml @@ -22,6 +22,7 @@ android:key="apn_name" android:singleLine="true" android:inputType="text" + android:persistent="false" /> diff --git a/res/xml/development_prefs.xml b/res/xml/development_prefs.xml index 11a579aece7..64d43adee43 100644 --- a/res/xml/development_prefs.xml +++ b/res/xml/development_prefs.xml @@ -163,6 +163,10 @@ android:title="@string/telephony_monitor_switch" android:summary="@string/telephony_monitor_switch_summary"/> + + diff --git a/res/xml/device_info_status.xml b/res/xml/device_info_status.xml index 6fe43ec87b0..3456f9199ea 100644 --- a/res/xml/device_info_status.xml +++ b/res/xml/device_info_status.xml @@ -23,13 +23,13 @@ android:enabled="false" android:shouldDisableView="false" android:title="@string/battery_status_title" - android:summary="@string/device_info_not_available" /> + android:summary="@string/summary_placeholder" /> + + + - - - - diff --git a/src/com/android/settings/ApnEditor.java b/src/com/android/settings/ApnEditor.java index e61f9594dac..50a7a77309a 100644 --- a/src/com/android/settings/ApnEditor.java +++ b/src/com/android/settings/ApnEditor.java @@ -297,6 +297,11 @@ public class ApnEditor extends SettingsPreferenceFragment getPreferenceScreen().getPreference(i).setOnPreferenceChangeListener(this); } + } + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); fillUi(); } diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java index 417ac0faeb5..fa61cecdf2f 100644 --- a/src/com/android/settings/Utils.java +++ b/src/com/android/settings/Utils.java @@ -52,8 +52,11 @@ import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.hardware.fingerprint.FingerprintManager; import android.icu.text.MeasureFormat; +import android.icu.text.RelativeDateTimeFormatter; +import android.icu.text.RelativeDateTimeFormatter.RelativeUnit; import android.icu.util.Measure; import android.icu.util.MeasureUnit; +import android.icu.util.ULocale; import android.net.ConnectivityManager; import android.net.LinkProperties; import android.net.Network; @@ -860,6 +863,48 @@ public final class Utils extends com.android.settingslib.Utils { return sb; } + /** + * Returns relative time for the given millis in the past, in a short format such as "2 days + * ago", "5 hr. ago", "40 min. ago", or "29 sec. ago". + * + *

The unit is chosen to have good information value while only using one unit. So 27 hours + * and 50 minutes would be formatted as "28 hr. ago", while 50 hours would be formatted as + * "2 days ago". + * + * @param context the application context + * @param millis the elapsed time in milli seconds + * @param withSeconds include seconds? + * @return the formatted elapsed time + */ + public static CharSequence formatRelativeTime(Context context, double millis, + boolean withSeconds) { + final int seconds = (int) Math.floor(millis / 1000); + final RelativeUnit unit; + final int value; + if (withSeconds && seconds < 2 * SECONDS_PER_MINUTE) { + unit = RelativeUnit.SECONDS; + value = seconds; + } else if (seconds < 2 * SECONDS_PER_HOUR) { + unit = RelativeUnit.MINUTES; + value = (seconds + SECONDS_PER_MINUTE / 2) / SECONDS_PER_MINUTE; + } else if (seconds < 2 * SECONDS_PER_DAY) { + unit = RelativeUnit.HOURS; + value = (seconds + SECONDS_PER_HOUR / 2) / SECONDS_PER_HOUR; + } else { + unit = RelativeUnit.DAYS; + value = (seconds + SECONDS_PER_DAY / 2) / SECONDS_PER_DAY; + } + + final Locale locale = context.getResources().getConfiguration().locale; + final RelativeDateTimeFormatter formatter = RelativeDateTimeFormatter.getInstance( + ULocale.forLocale(locale), + null /* default NumberFormat */, + RelativeDateTimeFormatter.Style.SHORT, + android.icu.text.DisplayContext.CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE); + + return formatter.format(value, RelativeDateTimeFormatter.Direction.LAST, unit); + } + /** * Queries for the UserInfo of a user. Returns null if the user doesn't exist (was removed). * @param userManager Instance of UserManager diff --git a/src/com/android/settings/accessibility/OWNERS b/src/com/android/settings/accessibility/OWNERS new file mode 100644 index 00000000000..28dfdefabef --- /dev/null +++ b/src/com/android/settings/accessibility/OWNERS @@ -0,0 +1,3 @@ +# Default reviewers for this and subdirectories. +pweaver@google.com +zork@google.com \ No newline at end of file diff --git a/src/com/android/settings/applications/RecentAppsPreferenceController.java b/src/com/android/settings/applications/RecentAppsPreferenceController.java index d0f7584eaed..69a36f67a53 100644 --- a/src/com/android/settings/applications/RecentAppsPreferenceController.java +++ b/src/com/android/settings/applications/RecentAppsPreferenceController.java @@ -235,10 +235,8 @@ public class RecentAppsPreferenceController extends AbstractPreferenceController pref.setKey(pkgName); pref.setTitle(appEntry.label); pref.setIcon(mIconDrawableFactory.getBadgedIcon(appEntry.info)); - pref.setSummary(TextUtils.expandTemplate( - mContext.getResources().getText(R.string.recent_app_summary), - Utils.formatElapsedTime(mContext, - System.currentTimeMillis() - stat.getLastTimeUsed(), false))); + pref.setSummary(Utils.formatRelativeTime(mContext, + System.currentTimeMillis() - stat.getLastTimeUsed(), false)); pref.setOrder(i); pref.setOnPreferenceClickListener(preference -> { AppInfoBase.startAppInfoFragment(InstalledAppDetails.class, diff --git a/src/com/android/settings/backup/OWNERS b/src/com/android/settings/backup/OWNERS new file mode 100644 index 00000000000..c026a350e75 --- /dev/null +++ b/src/com/android/settings/backup/OWNERS @@ -0,0 +1,6 @@ +# Default reviewers for this and subdirectories. +bryanmawhinney@google.com +cprins@google.com +jorlow@google.com +philippov@google.com +stefanot@google.com \ No newline at end of file diff --git a/src/com/android/settings/bluetooth/OWNERS b/src/com/android/settings/bluetooth/OWNERS new file mode 100644 index 00000000000..2b829785e51 --- /dev/null +++ b/src/com/android/settings/bluetooth/OWNERS @@ -0,0 +1,7 @@ +# Default reviewers for this and subdirectories. +asargent@google.com +eisenbach@google.com +jackqdyulei@google.com +siyuanh@google.com + +# Emergency approvers in case the above are not available \ No newline at end of file diff --git a/src/com/android/settings/development/CameraLaserSensorPreferenceController.java b/src/com/android/settings/development/CameraLaserSensorPreferenceController.java new file mode 100644 index 00000000000..26bfc805227 --- /dev/null +++ b/src/com/android/settings/development/CameraLaserSensorPreferenceController.java @@ -0,0 +1,104 @@ +/* + * 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.development; + +import android.content.Context; +import android.os.SystemProperties; +import android.support.v14.preference.SwitchPreference; +import android.support.v7.preference.Preference; +import android.support.v7.preference.PreferenceScreen; +import android.widget.Toast; + +import com.android.internal.annotations.VisibleForTesting; +import com.android.settings.R; +import com.android.settings.core.PreferenceControllerMixin; +import com.android.settingslib.core.AbstractPreferenceController; + +public class CameraLaserSensorPreferenceController extends AbstractPreferenceController + implements PreferenceControllerMixin { + + private static final String KEY_CAMERA_LASER_SENSOR_SWITCH = "camera_laser_sensor_switch"; + @VisibleForTesting + static final String BUILD_TYPE = "ro.build.type"; + @VisibleForTesting + static final String PROPERTY_CAMERA_LASER_SENSOR = "persist.camera.stats.disablehaf"; + @VisibleForTesting + static final int ENABLED = 0; + @VisibleForTesting + static final int DISABLED = 2; + + private SwitchPreference mPreference; + + public CameraLaserSensorPreferenceController(Context context) { + super(context); + } + + @Override + public void displayPreference(PreferenceScreen screen) { + super.displayPreference(screen); + mPreference = (SwitchPreference) screen.findPreference(KEY_CAMERA_LASER_SENSOR_SWITCH); + updatePreference(); + } + + @Override + public String getPreferenceKey() { + return KEY_CAMERA_LASER_SENSOR_SWITCH; + } + + @Override + public boolean isAvailable() { + String buildType = SystemProperties.get(BUILD_TYPE); + return mContext.getResources().getBoolean(R.bool.config_show_camera_laser_sensor) && + (buildType.equals("userdebug") || buildType.equals("eng")); + } + + @Override + public void updateState(Preference preference) { + updatePreference(); + } + + @Override + public boolean handlePreferenceTreeClick(Preference preference) { + if (KEY_CAMERA_LASER_SENSOR_SWITCH.equals(preference.getKey())) { + final SwitchPreference switchPreference = (SwitchPreference)preference; + String value = Integer.toString(switchPreference.isChecked() ? ENABLED : DISABLED); + SystemProperties.set(PROPERTY_CAMERA_LASER_SENSOR, value); + return true; + } + return false; + } + + public void enablePreference(boolean enabled) { + if (isAvailable()) { + mPreference.setEnabled(enabled); + } + } + + public boolean updatePreference() { + if (!isAvailable()) { + return false; + } + final boolean enabled = isLaserSensorEnabled(); + mPreference.setChecked(enabled); + return enabled; + } + + private boolean isLaserSensorEnabled() { + String prop = SystemProperties.get(PROPERTY_CAMERA_LASER_SENSOR, Integer.toString(ENABLED)); + return prop.equals(Integer.toString(ENABLED)); + } +} diff --git a/src/com/android/settings/development/DevelopmentSettings.java b/src/com/android/settings/development/DevelopmentSettings.java index 3115dc48526..d96adf45e70 100644 --- a/src/com/android/settings/development/DevelopmentSettings.java +++ b/src/com/android/settings/development/DevelopmentSettings.java @@ -332,6 +332,7 @@ public class DevelopmentSettings extends RestrictedSettingsFragment private BugReportInPowerPreferenceController mBugReportInPowerController; private TelephonyMonitorPreferenceController mTelephonyMonitorController; private CameraHalHdrplusPreferenceController mCameraHalHdrplusController; + private CameraLaserSensorPreferenceController mCameraLaserSensorController; private BroadcastReceiver mEnableAdbReceiver; @@ -379,6 +380,7 @@ public class DevelopmentSettings extends RestrictedSettingsFragment mWebViewAppPrefController = new WebViewAppPreferenceController(getActivity()); mVerifyAppsOverUsbController = new VerifyAppsOverUsbPreferenceController(getActivity()); mCameraHalHdrplusController = new CameraHalHdrplusPreferenceController(getActivity()); + mCameraLaserSensorController = new CameraLaserSensorPreferenceController(getActivity()); setIfOnlyAvailableForAdmins(true); if (isUiRestricted() || !Utils.isDeviceProvisioned(getActivity())) { @@ -417,6 +419,8 @@ public class DevelopmentSettings extends RestrictedSettingsFragment mCameraHalHdrplusController.displayPreference(preferenceScreen); mEnableAdbController.displayPreference(preferenceScreen); + mCameraLaserSensorController.displayPreference(getPreferenceScreen()); + mKeepScreenOn = (RestrictedSwitchPreference) findAndInitSwitchPref(KEEP_SCREEN_ON); mBtHciSnoopLog = findAndInitSwitchPref(BT_HCI_SNOOP_LOG); mEnableOemUnlock = (RestrictedSwitchPreference) findAndInitSwitchPref(ENABLE_OEM_UNLOCK); @@ -625,6 +629,7 @@ public class DevelopmentSettings extends RestrictedSettingsFragment mLogpersistController.enablePreference(enabled); mWebViewAppPrefController.enablePreference(enabled); mCameraHalHdrplusController.enablePreference(enabled); + mCameraLaserSensorController.enablePreference(enabled); updateAllOptions(); } @@ -771,6 +776,7 @@ public class DevelopmentSettings extends RestrictedSettingsFragment mHaveDebugSettings |= mBugReportInPowerController.updatePreference(); mHaveDebugSettings |= mTelephonyMonitorController.updatePreference(); mHaveDebugSettings |= mCameraHalHdrplusController.updatePreference(); + mHaveDebugSettings |= mCameraLaserSensorController.updatePreference(); updateSwitchPreference(mKeepScreenOn, Settings.Global.getInt(cr, Settings.Global.STAY_ON_WHILE_PLUGGED_IN, 0) != 0); updateSwitchPreference(mBtHciSnoopLog, SystemProperties.getBoolean( @@ -2224,6 +2230,10 @@ public class DevelopmentSettings extends RestrictedSettingsFragment return true; } + if (mCameraLaserSensorController.handlePreferenceTreeClick(preference)) { + return true; + } + if (preference == mClearAdbKeys) { if (mAdbKeysDialog != null) dismissDialogs(); mAdbKeysDialog = new AlertDialog.Builder(getActivity()) diff --git a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java index 30be65483f5..919dc3a4bef 100644 --- a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java +++ b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java @@ -17,12 +17,16 @@ package com.android.settings.development; import android.content.Context; +import android.os.Bundle; import android.os.UserManager; import android.provider.SearchIndexableResource; import android.util.Log; +import android.widget.Switch; import com.android.internal.logging.nano.MetricsProto; import com.android.settings.R; +import com.android.settings.SettingsActivity; +import com.android.settings.Utils; import com.android.settings.dashboard.RestrictedDashboardFragment; import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.search.Indexable; @@ -33,21 +37,67 @@ import com.android.settingslib.development.DevelopmentSettingsEnabler; import java.util.Arrays; import java.util.List; -public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFragment { +public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFragment + implements SwitchBar.OnSwitchChangeListener { private static final String TAG = "DevSettingsDashboard"; + private boolean mIsAvailable = true; private SwitchBar mSwitchBar; + private DevelopmentSwitchBarController mSwitchBarController; public DevelopmentSettingsDashboardFragment() { super(UserManager.DISALLOW_DEBUGGING_FEATURES); } + @Override + public void onActivityCreated(Bundle icicle) { + super.onActivityCreated(icicle); + // Apply page-level restrictions + setIfOnlyAvailableForAdmins(true); + if (isUiRestricted() || !Utils.isDeviceProvisioned(getActivity())) { + // Block access to developer options if the user is not the owner, if user policy + // restricts it, or if the device has not been provisioned + mIsAvailable = false; + // Show error message + if (!isUiRestrictedByOnlyAdmin()) { + getEmptyTextView().setText(R.string.development_settings_not_available); + } + getPreferenceScreen().removeAll(); + return; + } + // Set up master switch + mSwitchBar = ((SettingsActivity) getActivity()).getSwitchBar(); + mSwitchBarController = new DevelopmentSwitchBarController( + this /* DevelopmentSettings */, mSwitchBar, mIsAvailable, getLifecycle()); + mSwitchBar.show(); + } + @Override public int getMetricsCategory() { return MetricsProto.MetricsEvent.DEVELOPMENT; } + @Override + public void onSwitchChanged(Switch switchView, boolean isChecked) { + if (switchView != mSwitchBar.getSwitch()) { + return; + } + final boolean developmentEnabledState = + DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(getContext()); + if (isChecked != developmentEnabledState) { + if (isChecked) { + EnableDevelopmentSettingWarningDialog.show(this /* host */); + } else { + // TODO: Reset dangerous options (move logic from DevelopmentSettings). + // resetDangerousOptions(); + DevelopmentSettingsEnabler.setDevelopmentSettingsEnabled(getContext(), false); + // TODO: Refresh all prefs' enabled state (move logic from DevelopmentSettings). + // setPrefsEnabledState(false); + } + } + } + @Override protected String getLogTag() { return TAG; @@ -69,6 +119,16 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra return buildPreferenceControllers(context); } + void onEnableDevelopmentOptionsConfirmed() { + DevelopmentSettingsEnabler.setDevelopmentSettingsEnabled(getContext(), true); + // TODO: Refresh all prefs' enabled state (move logic from DevelopmentSettings). + } + + void onEnableDevelopmentOptionsRejected() { + // Reset the toggle + mSwitchBar.setChecked(false); + } + private static List buildPreferenceControllers(Context context) { return null; } diff --git a/src/com/android/settings/development/DevelopmentSwitchBarController.java b/src/com/android/settings/development/DevelopmentSwitchBarController.java index 168f7c062b3..ae875b39961 100644 --- a/src/com/android/settings/development/DevelopmentSwitchBarController.java +++ b/src/com/android/settings/development/DevelopmentSwitchBarController.java @@ -22,18 +22,39 @@ import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.core.lifecycle.LifecycleObserver; import com.android.settingslib.core.lifecycle.events.OnStart; import com.android.settingslib.core.lifecycle.events.OnStop; +import com.android.settingslib.development.DevelopmentSettingsEnabler; public class DevelopmentSwitchBarController implements LifecycleObserver, OnStart, OnStop { private final SwitchBar mSwitchBar; private final boolean mIsAvailable; private final DevelopmentSettings mSettings; + private final DevelopmentSettingsDashboardFragment mNewSettings; + /** + * @deprecated in favor of the other constructor. + */ + @Deprecated public DevelopmentSwitchBarController(DevelopmentSettings settings, SwitchBar switchBar, boolean isAvailable, Lifecycle lifecycle) { mSwitchBar = switchBar; mIsAvailable = isAvailable && !Utils.isMonkeyRunning(); mSettings = settings; + mNewSettings = null; + + if (mIsAvailable) { + lifecycle.addObserver(this); + } else { + mSwitchBar.setEnabled(false); + } + } + + public DevelopmentSwitchBarController(DevelopmentSettingsDashboardFragment settings, + SwitchBar switchBar, boolean isAvailable, Lifecycle lifecycle) { + mSwitchBar = switchBar; + mIsAvailable = isAvailable && !Utils.isMonkeyRunning(); + mSettings = null; + mNewSettings = settings; if (mIsAvailable) { lifecycle.addObserver(this); @@ -44,11 +65,24 @@ public class DevelopmentSwitchBarController implements LifecycleObserver, OnStar @Override public void onStart() { - mSwitchBar.addOnSwitchChangeListener(mSettings); + if (mSettings != null) { + mSwitchBar.addOnSwitchChangeListener(mSettings); + } + if (mNewSettings != null) { + final boolean developmentEnabledState = DevelopmentSettingsEnabler + .isDevelopmentSettingsEnabled(mNewSettings.getContext()); + mSwitchBar.setChecked(developmentEnabledState); + mSwitchBar.addOnSwitchChangeListener(mNewSettings); + } } @Override public void onStop() { - mSwitchBar.removeOnSwitchChangeListener(mSettings); + if (mSettings != null) { + mSwitchBar.removeOnSwitchChangeListener(mSettings); + } + if (mNewSettings != null) { + mSwitchBar.removeOnSwitchChangeListener(mNewSettings); + } } } diff --git a/src/com/android/settings/development/EnableDevelopmentSettingWarningDialog.java b/src/com/android/settings/development/EnableDevelopmentSettingWarningDialog.java new file mode 100644 index 00000000000..3c3d645911f --- /dev/null +++ b/src/com/android/settings/development/EnableDevelopmentSettingWarningDialog.java @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.development; + +import android.app.AlertDialog; +import android.app.Dialog; +import android.app.FragmentManager; +import android.content.DialogInterface; +import android.os.Bundle; + +import com.android.internal.logging.nano.MetricsProto; +import com.android.settings.R; +import com.android.settings.core.instrumentation.InstrumentedDialogFragment; + +public class EnableDevelopmentSettingWarningDialog extends InstrumentedDialogFragment + implements DialogInterface.OnClickListener { + + public static final String TAG = "EnableDevSettingDlg"; + + public static void show( + DevelopmentSettingsDashboardFragment host) { + final EnableDevelopmentSettingWarningDialog dialog = + new EnableDevelopmentSettingWarningDialog(); + dialog.setTargetFragment(host, 0 /* requestCode */); + final FragmentManager manager = host.getActivity().getFragmentManager(); + if (manager.findFragmentByTag(TAG) == null) { + dialog.show(manager, TAG); + } + } + + @Override + public int getMetricsCategory() { + return MetricsProto.MetricsEvent.DIALOG_ENABLE_DEVELOPMENT_OPTIONS; + } + + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + return new AlertDialog.Builder(getActivity()) + .setMessage(R.string.dev_settings_warning_message) + .setTitle(R.string.dev_settings_warning_title) + .setPositiveButton(android.R.string.yes, this) + .setNegativeButton(android.R.string.no, this) + .create(); + } + + @Override + public void onClick(DialogInterface dialog, int which) { + final DevelopmentSettingsDashboardFragment host = + (DevelopmentSettingsDashboardFragment) getTargetFragment(); + if (which == DialogInterface.BUTTON_POSITIVE) { + host.onEnableDevelopmentOptionsConfirmed(); + } else { + host.onEnableDevelopmentOptionsRejected(); + } + } +} diff --git a/src/com/android/settings/deviceinfo/Status.java b/src/com/android/settings/deviceinfo/Status.java index faa4134a935..228774f2657 100644 --- a/src/com/android/settings/deviceinfo/Status.java +++ b/src/com/android/settings/deviceinfo/Status.java @@ -32,6 +32,7 @@ import android.os.PersistableBundle; import android.os.SystemClock; import android.os.SystemProperties; import android.os.UserManager; +import android.provider.SearchIndexableResource; import android.support.v7.preference.Preference; import android.support.v7.preference.PreferenceScreen; import android.telephony.CarrierConfigManager; @@ -44,13 +45,17 @@ import com.android.internal.util.ArrayUtils; import com.android.settings.R; import com.android.settings.SettingsPreferenceFragment; import com.android.settings.Utils; +import com.android.settings.search.BaseSearchIndexProvider; +import com.android.settings.search.Indexable; import java.lang.ref.WeakReference; +import java.util.Arrays; +import java.util.List; import static android.content.Context.CONNECTIVITY_SERVICE; import static android.content.Context.WIFI_SERVICE; -public class Status extends SettingsPreferenceFragment { +public class Status extends SettingsPreferenceFragment implements Indexable { private static final String KEY_BATTERY_STATUS = "battery_status"; private static final String KEY_BATTERY_LEVEL = "battery_level"; @@ -330,4 +335,19 @@ public class Status extends SettingsPreferenceFragment { return h + ":" + pad(m) + ":" + pad(s); } + + /** + * For Search. + */ + public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = + new BaseSearchIndexProvider() { + + @Override + public List getXmlResourcesToIndex( + Context context, boolean enabled) { + final SearchIndexableResource sir = new SearchIndexableResource(context); + sir.xmlResId = R.xml.device_info_status; + return Arrays.asList(sir); + } + }; } diff --git a/src/com/android/settings/enterprise/OWNERS b/src/com/android/settings/enterprise/OWNERS new file mode 100644 index 00000000000..bab2fe2d1b9 --- /dev/null +++ b/src/com/android/settings/enterprise/OWNERS @@ -0,0 +1,4 @@ +# Default reviewers for this and subdirectories. +sandness@google.com + +# Emergency approvers in case the above are not available \ No newline at end of file diff --git a/src/com/android/settings/fingerprint/OWNERS b/src/com/android/settings/fingerprint/OWNERS new file mode 100644 index 00000000000..937b3030fd6 --- /dev/null +++ b/src/com/android/settings/fingerprint/OWNERS @@ -0,0 +1,5 @@ +# Default reviewers for this and subdirectories. +jaggies@google.com +yukl@google.com + +# Emergency approvers in case the above are not available \ No newline at end of file diff --git a/src/com/android/settings/fuelgauge/OWNERS b/src/com/android/settings/fuelgauge/OWNERS new file mode 100644 index 00000000000..5b26c46d340 --- /dev/null +++ b/src/com/android/settings/fuelgauge/OWNERS @@ -0,0 +1,6 @@ +# Default reviewers for this and subdirectories. +dehboxturtle@google.com +jackqdyulei@google.com + +# Emergency approvers in case the above are not available +asapperstein@google.com \ No newline at end of file diff --git a/src/com/android/settings/fuelgauge/PowerUsageAdvanced.java b/src/com/android/settings/fuelgauge/PowerUsageAdvanced.java index fe002b0fc37..d29364dfcc6 100644 --- a/src/com/android/settings/fuelgauge/PowerUsageAdvanced.java +++ b/src/com/android/settings/fuelgauge/PowerUsageAdvanced.java @@ -124,6 +124,9 @@ public class PowerUsageAdvanced extends PowerUsageBase { mPackageManager = context.getPackageManager(); mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE); mBatteryUtils = BatteryUtils.getInstance(context); + + // init the summary so other preferences won't have unnecessary move + updateHistPrefSummary(context); } @Override @@ -175,7 +178,13 @@ public class PowerUsageAdvanced extends PowerUsageBase { } updatePreference(mHistPref); refreshPowerUsageDataList(mStatsHelper, mUsageListGroup); + updateHistPrefSummary(context); + BatteryEntry.startRequestQueue(); + BatteryUtils.logRuntime(TAG, "refreshUI", startTime); + } + + private void updateHistPrefSummary(Context context) { Intent batteryIntent = context.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); final boolean plugged = batteryIntent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1) != 0; @@ -186,9 +195,6 @@ public class PowerUsageAdvanced extends PowerUsageBase { } else { mHistPref.hideBottomSummary(); } - - BatteryEntry.startRequestQueue(); - BatteryUtils.logRuntime(TAG, "refreshUI", startTime); } @VisibleForTesting diff --git a/src/com/android/settings/fuelgauge/PowerUsageSummary.java b/src/com/android/settings/fuelgauge/PowerUsageSummary.java index 1596aca70b8..9798749ebad 100644 --- a/src/com/android/settings/fuelgauge/PowerUsageSummary.java +++ b/src/com/android/settings/fuelgauge/PowerUsageSummary.java @@ -533,7 +533,7 @@ public class PowerUsageSummary extends PowerUsageBase implements updateScreenPreference(); updateLastFullChargePreference(lastFullChargeTime); - final CharSequence timeSequence = Utils.formatElapsedTime(context, lastFullChargeTime, + final CharSequence timeSequence = Utils.formatRelativeTime(context, lastFullChargeTime, false); final int resId = mShowAllApps ? R.string.power_usage_list_summary_device : R.string.power_usage_list_summary; @@ -682,10 +682,8 @@ public class PowerUsageSummary extends PowerUsageBase implements @VisibleForTesting void updateLastFullChargePreference(long timeMs) { - final CharSequence timeSequence = Utils.formatElapsedTime(getContext(), timeMs, false); - mLastFullChargePref.setSubtitle( - TextUtils.expandTemplate(getText(R.string.power_last_full_charge_summary), - timeSequence)); + final CharSequence timeSequence = Utils.formatRelativeTime(getContext(), timeMs, false); + mLastFullChargePref.setSubtitle(timeSequence); } @VisibleForTesting diff --git a/src/com/android/settings/inputmethod/OWNERS b/src/com/android/settings/inputmethod/OWNERS new file mode 100644 index 00000000000..9f333949ff1 --- /dev/null +++ b/src/com/android/settings/inputmethod/OWNERS @@ -0,0 +1,5 @@ +# Default reviewers for this and subdirectories. +yukawa@google.com +michaelwr@google.com + +# Emergency approvers in case the above are not available \ No newline at end of file diff --git a/src/com/android/settings/location/LocationSettings.java b/src/com/android/settings/location/LocationSettings.java index 34e8cc39f47..d66b3105d2d 100644 --- a/src/com/android/settings/location/LocationSettings.java +++ b/src/com/android/settings/location/LocationSettings.java @@ -35,7 +35,6 @@ import android.util.Log; import android.widget.Switch; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; -import com.android.settings.DimmableIconPreference; import com.android.settings.R; import com.android.settings.SettingsActivity; import com.android.settings.Utils; @@ -43,6 +42,7 @@ import com.android.settings.applications.InstalledAppDetails; import com.android.settings.dashboard.SummaryLoader; import com.android.settings.widget.SwitchBar; import com.android.settingslib.RestrictedLockUtils; +import com.android.settingslib.RestrictedPreference; import com.android.settingslib.RestrictedSwitchPreference; import com.android.settingslib.location.RecentLocationApps; @@ -207,8 +207,8 @@ public class LocationSettings extends LocationSettingsBase List recentLocationPrefs = new ArrayList<>(recentLocationRequests.size()); for (final RecentLocationApps.Request request : recentLocationRequests) { - DimmableIconPreference pref = new DimmableIconPreference(getPrefContext(), - request.contentDescription); + RestrictedPreference pref = new RestrictedPreference(getPrefContext()); + pref.setSummary(request.contentDescription); pref.setIcon(request.icon); pref.setTitle(request.label); pref.setOnPreferenceClickListener( diff --git a/src/com/android/settings/location/OWNERS b/src/com/android/settings/location/OWNERS new file mode 100644 index 00000000000..5feda773f3a --- /dev/null +++ b/src/com/android/settings/location/OWNERS @@ -0,0 +1,10 @@ +# Default reviewers for this and subdirectories. +asalo@google.com +lifu@google.com +mstogaitis@google.com +palanki@google.com +sooniln@google.com +weiwa@google.com +wyattriley@google.com + +# Emergency approvers in case the above are not available \ No newline at end of file diff --git a/src/com/android/settings/nfc/OWNERS b/src/com/android/settings/nfc/OWNERS new file mode 100644 index 00000000000..f11f74f19db --- /dev/null +++ b/src/com/android/settings/nfc/OWNERS @@ -0,0 +1,5 @@ +# Default reviewers for this and subdirectories. +eisenbach@google.com +kandoiruchi@google.com + +# Emergency approvers in case the above are not available \ No newline at end of file diff --git a/src/com/android/settings/notification/OWNERS b/src/com/android/settings/notification/OWNERS new file mode 100644 index 00000000000..0d73685a875 --- /dev/null +++ b/src/com/android/settings/notification/OWNERS @@ -0,0 +1,4 @@ +# Default reviewers for this and subdirectories. +asc@google.com +dsandler@google.com +juliacr@google.com \ No newline at end of file diff --git a/src/com/android/settings/password/OWNERS b/src/com/android/settings/password/OWNERS new file mode 100644 index 00000000000..cac6e3f3df7 --- /dev/null +++ b/src/com/android/settings/password/OWNERS @@ -0,0 +1,7 @@ +# Default reviewers for this and subdirectories. +jaggies@google.com +kchyn@google.com +paulcrowley@google.com +rubinxu@google.com + +# Emergency approvers in case the above are not available \ No newline at end of file diff --git a/src/com/android/settings/search/SearchIndexableResources.java b/src/com/android/settings/search/SearchIndexableResources.java index 044a00c6eb7..c946d46dc10 100644 --- a/src/com/android/settings/search/SearchIndexableResources.java +++ b/src/com/android/settings/search/SearchIndexableResources.java @@ -46,6 +46,7 @@ import com.android.settings.datausage.DataUsageMeteredSettings; import com.android.settings.datausage.DataUsageSummary; import com.android.settings.deletionhelper.AutomaticStorageManagerSettings; import com.android.settings.development.DevelopmentSettings; +import com.android.settings.deviceinfo.Status; import com.android.settings.deviceinfo.StorageDashboardFragment; import com.android.settings.deviceinfo.StorageSettings; import com.android.settings.display.AmbientDisplaySettings; @@ -190,6 +191,7 @@ public final class SearchIndexableResources { addIndex(PrintSettingsFragment.class, NO_DATA_RES_ID, R.drawable.ic_settings_print); addIndex(DevelopmentSettings.class, NO_DATA_RES_ID, R.drawable.ic_settings_development); addIndex(DeviceInfoSettings.class, NO_DATA_RES_ID, R.drawable.ic_settings_about); + addIndex(Status.class, NO_DATA_RES_ID, 0 /* icon */); addIndex(LegalSettings.class, NO_DATA_RES_ID, R.drawable.ic_settings_about); addIndex(ZenModeVisualInterruptionSettings.class, R.xml.zen_mode_visual_interruptions_settings, diff --git a/src/com/android/settings/tts/OWNERS b/src/com/android/settings/tts/OWNERS new file mode 100644 index 00000000000..01068dcf299 --- /dev/null +++ b/src/com/android/settings/tts/OWNERS @@ -0,0 +1,6 @@ +# Default reviewers for this and subdirectories. +fergus@google.com +nielse@google.com +ssancho@google.com + +# Emergency approvers in case the above are not available \ No newline at end of file diff --git a/src/com/android/settings/users/OWNERS b/src/com/android/settings/users/OWNERS new file mode 100644 index 00000000000..59096bec798 --- /dev/null +++ b/src/com/android/settings/users/OWNERS @@ -0,0 +1,6 @@ +# Default reviewers for this and subdirectories. +dling@google.com +yamasani@google.com +zhfan@google.com + +# Emergency approvers in case the above are not available \ No newline at end of file diff --git a/src/com/android/settings/wifi/ConfigureWifiSettings.java b/src/com/android/settings/wifi/ConfigureWifiSettings.java index 43f25f11977..4199a6d3b97 100644 --- a/src/com/android/settings/wifi/ConfigureWifiSettings.java +++ b/src/com/android/settings/wifi/ConfigureWifiSettings.java @@ -19,6 +19,8 @@ import static android.content.Context.WIFI_SERVICE; import android.content.Context; import android.content.Intent; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; import android.net.NetworkScoreManager; import android.net.wifi.WifiManager; import android.provider.SearchIndexableResource; @@ -42,6 +44,8 @@ public class ConfigureWifiSettings extends DashboardFragment { private static final String TAG = "ConfigureWifiSettings"; + public static final String KEY_IP_ADDRESS = "current_ip_address"; + private WifiWakeupPreferenceController mWifiWakeupPreferenceController; private UseOpenWifiPreferenceController mUseOpenWifiPreferenceController; @@ -114,5 +118,22 @@ public class ConfigureWifiSettings extends DashboardFragment { sir.xmlResId = R.xml.wifi_configure_settings; return Arrays.asList(sir); } + + @Override + public List getNonIndexableKeys(Context context) { + List keys = super.getNonIndexableKeys(context); + + // If connected to WiFi, this IP address will be the same as the Status IP. + // Or, if there is no connection they will say unavailable. + ConnectivityManager cm = (ConnectivityManager) + context.getSystemService(Context.CONNECTIVITY_SERVICE); + NetworkInfo info = cm.getActiveNetworkInfo(); + if (info == null + || info.getType() == ConnectivityManager.TYPE_WIFI) { + keys.add(KEY_IP_ADDRESS); + } + + return keys; + } }; } diff --git a/src/com/android/settings/wifi/OWNERS b/src/com/android/settings/wifi/OWNERS new file mode 100644 index 00000000000..3090f13bd3c --- /dev/null +++ b/src/com/android/settings/wifi/OWNERS @@ -0,0 +1,9 @@ +# Default reviewers for this and subdirectories. +asargent@google.com +easchwar@google.com +dling@google.com +jlapenna@google.com +sghuman@google.com +zhfan@google.com + +# Emergency approvers in case the above are not available \ No newline at end of file diff --git a/src/com/android/settings/wifi/WifiConfigController.java b/src/com/android/settings/wifi/WifiConfigController.java index 5a3d426d125..3cf7f930bda 100644 --- a/src/com/android/settings/wifi/WifiConfigController.java +++ b/src/com/android/settings/wifi/WifiConfigController.java @@ -492,7 +492,7 @@ public class WifiConfigController implements TextWatcher, } } - /* package */ WifiConfiguration getConfig() { + public WifiConfiguration getConfig() { if (mMode == WifiConfigUiBase.MODE_VIEW) { return null; } diff --git a/src/com/android/settings/wifi/WifiDialog.java b/src/com/android/settings/wifi/WifiDialog.java index 81f2a14ee62..cb3f8df1e77 100644 --- a/src/com/android/settings/wifi/WifiDialog.java +++ b/src/com/android/settings/wifi/WifiDialog.java @@ -27,8 +27,7 @@ import com.android.settings.R; import com.android.settingslib.RestrictedLockUtils; import com.android.settingslib.wifi.AccessPoint; -// TODO(b/64069122) Have this extend a dialogfragment to handle the fullscreen launch case. -class WifiDialog extends AlertDialog implements WifiConfigUiBase, DialogInterface.OnClickListener { +public class WifiDialog extends AlertDialog implements WifiConfigUiBase, DialogInterface.OnClickListener { public interface WifiDialogListener { void onForget(WifiDialog dialog); diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java index ef6a650a8b0..f3b08bf1dac 100644 --- a/src/com/android/settings/wifi/WifiSettings.java +++ b/src/com/android/settings/wifi/WifiSettings.java @@ -884,17 +884,20 @@ public class WifiSettings extends RestrictedSettingsFragment * {@link #mConnectedAccessPointPreferenceCategory}. */ private void addConnectedAccessPointPreference(AccessPoint connectedAp) { - String key = connectedAp.getBssid(); - LongPressAccessPointPreference pref = (LongPressAccessPointPreference) - getCachedPreference(key); - if (pref == null) { - pref = createLongPressActionPointPreference(connectedAp); - } + final LongPressAccessPointPreference pref = getOrCreatePreference(connectedAp); // Save the state of the current access point in the bundle so that we can restore it // in the Wifi Network Details Fragment pref.getAccessPoint().saveWifiState(pref.getExtras()); - pref.setFragment(WifiNetworkDetailsFragment.class.getName()); + + // Launch details page on click. + pref.setOnPreferenceClickListener(preference -> { + SettingsActivity activity = (SettingsActivity) WifiSettings.this.getActivity(); + activity.startPreferencePanel(this, + WifiNetworkDetailsFragment.class.getName(), pref.getExtras(), + R.string.wifi_details_title, null, null, 0); + return true; + }); pref.refresh(); mConnectedAccessPointPreferenceCategory.addPreference(pref); @@ -905,6 +908,15 @@ public class WifiSettings extends RestrictedSettingsFragment } } + private LongPressAccessPointPreference getOrCreatePreference(AccessPoint ap) { + LongPressAccessPointPreference pref = (LongPressAccessPointPreference) + getCachedPreference(AccessPointPreference.generatePreferenceKey(ap)); + if (pref == null) { + pref = createLongPressActionPointPreference(ap); + } + return pref; + } + /** Removes all preferences and hide the {@link #mConnectedAccessPointPreferenceCategory}. */ private void removeConnectedAccessPointPreference() { mConnectedAccessPointPreferenceCategory.removeAll(); diff --git a/src/com/android/settings/wifi/details/WifiDetailActionBarObserver.java b/src/com/android/settings/wifi/details/WifiDetailActionBarObserver.java deleted file mode 100644 index 81413d29b85..00000000000 --- a/src/com/android/settings/wifi/details/WifiDetailActionBarObserver.java +++ /dev/null @@ -1,45 +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.wifi.details; - -import android.app.Fragment; -import android.content.Context; -import android.os.Bundle; -import com.android.settings.R; -import com.android.settingslib.core.lifecycle.LifecycleObserver; -import com.android.settingslib.core.lifecycle.events.OnCreate; - -/** - * ActionBar lifecycle observer for {@link WifiNetworkDetailsFragment}. - */ -public class WifiDetailActionBarObserver implements LifecycleObserver, OnCreate { - - private final Fragment mFragment; - private final Context mContext; - - public WifiDetailActionBarObserver(Context context, Fragment fragment) { - mContext = context; - mFragment = fragment; - } - - @Override - public void onCreate(Bundle savedInstanceState) { - if (mFragment.getActivity() != null) { - mFragment.getActivity().getActionBar() - .setTitle(mContext.getString(R.string.wifi_details_title)); - } - } -} diff --git a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java index 0996416abaa..014fb0f84ac 100644 --- a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java +++ b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java @@ -21,6 +21,7 @@ import static android.net.NetworkCapabilities.TRANSPORT_WIFI; import static com.android.settings.wifi.WifiSettings.isEditabilityLockedDown; +import android.app.Activity; import android.app.Fragment; import android.content.BroadcastReceiver; import android.content.Context; @@ -48,7 +49,7 @@ import android.support.v7.preference.PreferenceScreen; import android.text.TextUtils; import android.util.Log; import android.widget.ImageView; - +import android.widget.Toast; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.nano.MetricsProto; import com.android.settings.R; @@ -60,13 +61,14 @@ import com.android.settings.vpn2.ConnectivityManagerWrapper; import com.android.settings.widget.ActionButtonPreference; import com.android.settings.widget.EntityHeaderController; import com.android.settings.wifi.WifiDetailPreference; +import com.android.settings.wifi.WifiDialog; +import com.android.settings.wifi.WifiDialog.WifiDialogListener; import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.core.lifecycle.LifecycleObserver; import com.android.settingslib.core.lifecycle.events.OnPause; import com.android.settingslib.core.lifecycle.events.OnResume; import com.android.settingslib.wifi.AccessPoint; - import java.net.Inet4Address; import java.net.Inet6Address; import java.net.InetAddress; @@ -79,7 +81,9 @@ import java.util.stream.Collectors; * {@link WifiNetworkDetailsFragment}. */ public class WifiDetailPreferenceController extends AbstractPreferenceController - implements PreferenceControllerMixin, LifecycleObserver, OnPause, OnResume { + implements PreferenceControllerMixin, WifiDialogListener, LifecycleObserver, OnPause, + OnResume { + private static final String TAG = "WifiDetailsPrefCtrl"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); @@ -121,7 +125,7 @@ public class WifiDetailPreferenceController extends AbstractPreferenceController private NetworkCapabilities mNetworkCapabilities; private int mRssiSignalLevel = -1; private String[] mSignalStr; - private final WifiConfiguration mWifiConfig; + private WifiConfiguration mWifiConfig; private WifiInfo mWifiInfo; private final WifiManager mWifiManager; private final MetricsFeatureProvider mMetricsFeatureProvider; @@ -147,9 +151,21 @@ public class WifiDetailPreferenceController extends AbstractPreferenceController @Override public void onReceive(Context context, Intent intent) { switch (intent.getAction()) { + case WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION: + if (!intent.getBooleanExtra(WifiManager.EXTRA_MULTIPLE_NETWORKS_CHANGED, + false /* defaultValue */)) { + // only one network changed + WifiConfiguration wifiConfiguration = intent + .getParcelableExtra(WifiManager.EXTRA_WIFI_CONFIGURATION); + if (mAccessPoint.matches(wifiConfiguration)) { + mWifiConfig = wifiConfiguration; + } + } + // fall through case WifiManager.NETWORK_STATE_CHANGED_ACTION: case WifiManager.RSSI_CHANGED_ACTION: updateInfo(); + break; } } }; @@ -239,6 +255,8 @@ public class WifiDetailPreferenceController extends AbstractPreferenceController mFilter = new IntentFilter(); mFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); mFilter.addAction(WifiManager.RSSI_CHANGED_ACTION); + mFilter.addAction(WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION); + lifecycle.addObserver(this); } @@ -334,7 +352,7 @@ public class WifiDetailPreferenceController extends AbstractPreferenceController return; } - // Update whether the forgot button should be displayed. + // Update whether the forget button should be displayed. mButtonsPref.setButton1Visible(canForgetNetwork()); refreshNetworkState(); @@ -520,6 +538,32 @@ public class WifiDetailPreferenceController extends AbstractPreferenceController mConnectivityManagerWrapper.startCaptivePortalApp(mNetwork); } + @Override + public void onForget(WifiDialog dialog) { + // can't forget network from a 'modify' dialog + } + + @Override + public void onSubmit(WifiDialog dialog) { + if (dialog.getController() != null) { + mWifiManager.save(dialog.getController().getConfig(), new WifiManager.ActionListener() { + @Override + public void onSuccess() { + } + + @Override + public void onFailure(int reason) { + Activity activity = mFragment.getActivity(); + if (activity != null) { + Toast.makeText(activity, + R.string.wifi_failed_save_message, + Toast.LENGTH_SHORT).show(); + } + } + }); + } + } + /** * Wrapper for testing compatibility. */ diff --git a/src/com/android/settings/wifi/details/WifiNetworkDetailsFragment.java b/src/com/android/settings/wifi/details/WifiNetworkDetailsFragment.java index 4918889ff9d..765bebccb2b 100644 --- a/src/com/android/settings/wifi/details/WifiNetworkDetailsFragment.java +++ b/src/com/android/settings/wifi/details/WifiNetworkDetailsFragment.java @@ -15,17 +15,25 @@ */ package com.android.settings.wifi.details; +import static com.android.settings.wifi.WifiSettings.WIFI_DIALOG_ID; + +import android.app.Dialog; import android.content.Context; import android.net.ConnectivityManager; import android.net.wifi.WifiManager; import android.os.Bundle; import android.os.Handler; import android.os.Looper; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; import com.android.internal.logging.nano.MetricsProto; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settings.R; import com.android.settings.dashboard.DashboardFragment; import com.android.settings.vpn2.ConnectivityManagerWrapperImpl; -import com.android.settings.wifi.WifiDetailPreference; +import com.android.settings.wifi.WifiConfigUiBase; +import com.android.settings.wifi.WifiDialog; import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.wifi.AccessPoint; import java.util.ArrayList; @@ -44,13 +52,9 @@ public class WifiNetworkDetailsFragment extends DashboardFragment { private AccessPoint mAccessPoint; private WifiDetailPreferenceController mWifiDetailPreferenceController; - private WifiDetailActionBarObserver mWifiDetailActionBarObserver; @Override public void onAttach(Context context) { - mWifiDetailActionBarObserver = new WifiDetailActionBarObserver(context, this); - getLifecycle().addObserver(mWifiDetailActionBarObserver); - mAccessPoint = new AccessPoint(context, getArguments()); super.onAttach(context); } @@ -70,6 +74,44 @@ public class WifiNetworkDetailsFragment extends DashboardFragment { return R.xml.wifi_network_details_fragment; } + @Override + public int getDialogMetricsCategory(int dialogId) { + if (dialogId == WIFI_DIALOG_ID) { + return MetricsEvent.DIALOG_WIFI_AP_EDIT; + } + return 0; + } + + @Override + public Dialog onCreateDialog(int dialogId) { + if (getActivity() == null || mWifiDetailPreferenceController == null + || mAccessPoint == null) { + return null; + } + return WifiDialog.createModal(getActivity(), mWifiDetailPreferenceController, mAccessPoint, + WifiConfigUiBase.MODE_MODIFY); + } + + + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + MenuItem item = menu.add(0, Menu.FIRST, 0, R.string.wifi_modify); + item.setIcon(R.drawable.ic_mode_edit); + item.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); + super.onCreateOptionsMenu(menu, inflater); + } + + @Override + public boolean onOptionsItemSelected(MenuItem menuItem) { + switch (menuItem.getItemId()) { + case Menu.FIRST: + showDialog(WIFI_DIALOG_ID); + return true; + default: + return super.onOptionsItemSelected(menuItem); + } + } + @Override protected List getPreferenceControllers(Context context) { ConnectivityManager cm = context.getSystemService(ConnectivityManager.class); diff --git a/src/com/android/settings/wifi/tether/WifiTetherApBandPreferenceController.java b/src/com/android/settings/wifi/tether/WifiTetherApBandPreferenceController.java index 37da38ec3c7..5a08c58d1f7 100644 --- a/src/com/android/settings/wifi/tether/WifiTetherApBandPreferenceController.java +++ b/src/com/android/settings/wifi/tether/WifiTetherApBandPreferenceController.java @@ -16,6 +16,9 @@ package com.android.settings.wifi.tether; +import static android.net.wifi.WifiConfiguration.AP_BAND_2GHZ; +import static android.net.wifi.WifiConfiguration.AP_BAND_5GHZ; + import android.content.Context; import android.net.wifi.WifiConfiguration; import android.support.v7.preference.ListPreference; @@ -24,9 +27,6 @@ import android.support.v7.preference.PreferenceScreen; import com.android.settings.R; -import static android.net.wifi.WifiConfiguration.AP_BAND_2GHZ; -import static android.net.wifi.WifiConfiguration.AP_BAND_5GHZ; - public class WifiTetherApBandPreferenceController extends WifiTetherBasePreferenceController { private static final String PREF_KEY = "wifi_tether_network_ap_band"; @@ -41,10 +41,14 @@ public class WifiTetherApBandPreferenceController extends WifiTetherBasePreferen super(context, listener); mBandEntries = mContext.getResources().getStringArray(R.array.wifi_ap_band_config_full); final WifiConfiguration config = mWifiManager.getWifiApConfiguration(); - if (config != null) { + if (config == null) { + mBandIndex = 0; + } else if (is5GhzBandSupported()) { mBandIndex = config.apBand; } else { - mBandIndex = 0; + config.apBand = 0; + mWifiManager.setWifiApConfiguration(config); + mBandIndex = config.apBand; } } @@ -77,10 +81,11 @@ public class WifiTetherApBandPreferenceController extends WifiTetherBasePreferen } private boolean is5GhzBandSupported() { - if (mBandIndex > 0) { - return true; + final String countryCode = mWifiManager.getCountryCode(); + if (!mWifiManager.isDualBandSupported() || countryCode == null) { + return false; } - return mWifiManager.is5GHzBandSupported(); + return true; } public int getBandIndex() { diff --git a/tests/robotests/assets/grandfather_not_implementing_indexable b/tests/robotests/assets/grandfather_not_implementing_indexable index e38064a4253..bbb4bb20039 100644 --- a/tests/robotests/assets/grandfather_not_implementing_indexable +++ b/tests/robotests/assets/grandfather_not_implementing_indexable @@ -20,7 +20,6 @@ com.android.settings.applications.ProcessStatsDetail com.android.settings.wifi.WifiInfo com.android.settings.applications.VrListenerSettings com.android.settings.inputmethod.UserDictionaryList -com.android.settings.deviceinfo.Status com.android.settings.datausage.DataSaverSummary com.android.settings.notification.ChannelNotificationSettings com.android.settings.notification.ChannelGroupNotificationSettings diff --git a/tests/robotests/src/com/android/settings/UtilsTest.java b/tests/robotests/src/com/android/settings/UtilsTest.java index 33ead1fd4d0..19b87a1b1fa 100644 --- a/tests/robotests/src/com/android/settings/UtilsTest.java +++ b/tests/robotests/src/com/android/settings/UtilsTest.java @@ -173,6 +173,105 @@ public class UtilsTest { assertThat(ttsSpans[0].getType()).isEqualTo(TtsSpan.TYPE_MEASURE); } + @Test + public void testFormatRelativeTime_WithSeconds_ShowSeconds() { + final double testMillis = 40 * DateUtils.SECOND_IN_MILLIS; + final String expectedTime = "40 sec. ago"; + + assertThat(Utils.formatRelativeTime(mContext, testMillis, true).toString()).isEqualTo( + expectedTime); + } + + @Test + public void testFormatRelativeTime_NoSeconds_DoNotShowSeconds() { + final double testMillis = 40 * DateUtils.SECOND_IN_MILLIS; + final String expectedTime = "1 min. ago"; + + assertThat(Utils.formatRelativeTime(mContext, testMillis, false).toString()).isEqualTo( + expectedTime); + } + + @Test + public void testFormatRelativeTime_LessThanTwoMinutes_withSeconds() { + final double testMillis = 119 * DateUtils.SECOND_IN_MILLIS; + final String expectedTime = "119 sec. ago"; + + assertThat(Utils.formatRelativeTime(mContext, testMillis, true).toString()).isEqualTo( + expectedTime); + } + + @Test + public void testFormatRelativeTime_LessThanTwoMinutes_NoSeconds() { + final double testMillis = 119 * DateUtils.SECOND_IN_MILLIS; + final String expectedTime = "2 min. ago"; + + assertThat(Utils.formatRelativeTime(mContext, testMillis, false).toString()).isEqualTo( + expectedTime); + } + + @Test + public void testFormatRelativeTime_TwoMinutes_withSeconds() { + final double testMillis = 2 * DateUtils.MINUTE_IN_MILLIS; + final String expectedTime = "2 min. ago"; + + assertThat(Utils.formatRelativeTime(mContext, testMillis, true).toString()).isEqualTo( + expectedTime); + } + + @Test + public void testFormatRelativeTime_LessThanTwoHours_withSeconds() { + final double testMillis = 119 * DateUtils.MINUTE_IN_MILLIS; + final String expectedTime = "119 min. ago"; + + assertThat(Utils.formatRelativeTime(mContext, testMillis, true).toString()).isEqualTo( + expectedTime); + } + + @Test + public void testFormatRelativeTime_TwoHours_withSeconds() { + final double testMillis = 2 * DateUtils.HOUR_IN_MILLIS; + final String expectedTime = "2 hr. ago"; + + assertThat(Utils.formatRelativeTime(mContext, testMillis, true).toString()).isEqualTo( + expectedTime); + } + + @Test + public void testFormatRelativeTime_LessThanTwoDays_withSeconds() { + final double testMillis = 47 * DateUtils.HOUR_IN_MILLIS; + final String expectedTime = "47 hr. ago"; + + assertThat(Utils.formatRelativeTime(mContext, testMillis, true).toString()).isEqualTo( + expectedTime); + } + + @Test + public void testFormatRelativeTime_TwoDays_withSeconds() { + final double testMillis = 2 * DateUtils.DAY_IN_MILLIS; + final String expectedTime = "2 days ago"; + + assertThat(Utils.formatRelativeTime(mContext, testMillis, true).toString()).isEqualTo( + expectedTime); + } + + @Test + public void testFormatRelativeTime_FormatZero_WithSeconds() { + final double testMillis = 0; + final String expectedTime = "0 sec. ago"; + + assertThat(Utils.formatRelativeTime(mContext, testMillis, true).toString()).isEqualTo( + expectedTime); + } + + @Test + public void testFormatRelativeTime_FormatZero_NoSeconds() { + final double testMillis = 0; + final String expectedTime = "0 min. ago"; + + assertThat(Utils.formatRelativeTime(mContext, testMillis, false).toString()).isEqualTo( + expectedTime); + } + @Test public void testInitializeVolumeDoesntBreakOnNullVolume() { VolumeInfo info = new VolumeInfo("id", 0, new DiskInfo("id", 0), ""); diff --git a/tests/robotests/src/com/android/settings/applications/RecentAppsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/RecentAppsPreferenceControllerTest.java index 2510f201faa..5e85f9b7e48 100644 --- a/tests/robotests/src/com/android/settings/applications/RecentAppsPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/applications/RecentAppsPreferenceControllerTest.java @@ -249,8 +249,6 @@ public class RecentAppsPreferenceControllerTest { when(mUsageStatsManager.queryUsageStats(anyInt(), anyLong(), anyLong())) .thenReturn(stats); - when(mMockContext.getResources().getText(eq(R.string.recent_app_summary))) - .thenReturn(mContext.getResources().getText(R.string.recent_app_summary)); final Configuration configuration = new Configuration(); configuration.locale = Locale.US; when(mMockContext.getResources().getConfiguration()).thenReturn(configuration); @@ -258,7 +256,7 @@ public class RecentAppsPreferenceControllerTest { mController = new RecentAppsPreferenceController(mMockContext, mAppState, null); mController.displayPreference(mScreen); - verify(mCategory).addPreference(argThat(summaryMatches("0m ago"))); + verify(mCategory).addPreference(argThat(summaryMatches("0 min. ago"))); } private static ArgumentMatcher summaryMatches(String expected) { diff --git a/tests/robotests/src/com/android/settings/development/CameraLaserSensorPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/CameraLaserSensorPreferenceControllerTest.java new file mode 100644 index 00000000000..7aab99d7c87 --- /dev/null +++ b/tests/robotests/src/com/android/settings/development/CameraLaserSensorPreferenceControllerTest.java @@ -0,0 +1,175 @@ +/* + * 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.development; + +import android.content.Context; +import android.os.SystemProperties; +import android.support.v14.preference.SwitchPreference; +import android.support.v7.preference.PreferenceScreen; + +import com.android.settings.R; +import com.android.settings.testutils.SettingsRobolectricTestRunner; +import com.android.settings.TestConfig; +import com.android.settings.testutils.shadow.SettingsShadowSystemProperties; + +import org.junit.After; +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.annotation.Config; +import org.robolectric.RuntimeEnvironment; + +import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@RunWith(SettingsRobolectricTestRunner.class) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION, + shadows = {SettingsShadowSystemProperties.class}) +public class CameraLaserSensorPreferenceControllerTest { + + @Mock(answer = Answers.RETURNS_DEEP_STUBS) + private Context mContext; + @Mock + private PreferenceScreen mScreen; + @Mock + private SwitchPreference mPreference; + + static final String USERDEBUG_BUILD = "userdebug"; + static final String ENG_BUILD = "eng"; + static final String USER_BUILD = "user"; + + private CameraLaserSensorPreferenceController mController; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mController = new CameraLaserSensorPreferenceController(mContext); + when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference); + when(mPreference.getKey()).thenReturn(mController.getPreferenceKey()); + } + + @After + public void tearDown() { + SettingsShadowSystemProperties.clear(); + } + + @Test + public void isAvailable_withConfigNoShow_shouldReturnFalse() { + when(mContext.getResources().getBoolean(R.bool.config_show_camera_laser_sensor)) + .thenReturn(false); + assertThat(mController.isAvailable()).isFalse(); + } + + @Test + public void isAvailable_withUserdebugBuild_shouldReturnTrue() { + when(mContext.getResources().getBoolean(R.bool.config_show_camera_laser_sensor)) + .thenReturn(true); + + SettingsShadowSystemProperties.set( + CameraLaserSensorPreferenceController.BUILD_TYPE, USERDEBUG_BUILD); + + assertThat(mController.isAvailable()).isTrue(); + } + + @Test + public void isAvailable_withEngBuild_shouldReturnTrue() { + when(mContext.getResources().getBoolean(R.bool.config_show_camera_laser_sensor)) + .thenReturn(true); + + SettingsShadowSystemProperties.set( + CameraLaserSensorPreferenceController.BUILD_TYPE, ENG_BUILD); + + assertThat(mController.isAvailable()).isTrue(); + } + + @Test + public void isAvailable_withUserBuild_shouldReturnFalse() { + when(mContext.getResources().getBoolean(R.bool.config_show_camera_laser_sensor)) + .thenReturn(true); + + SettingsShadowSystemProperties.set( + CameraLaserSensorPreferenceController.BUILD_TYPE, USER_BUILD); + + assertThat(mController.isAvailable()).isFalse(); + } + + @Test + public void displayPreference_cameraLaserSensorEnabled_shouldCheckedPreference() { + when(mContext.getResources().getBoolean(R.bool.config_show_camera_laser_sensor)) + .thenReturn(true); + + SettingsShadowSystemProperties.set( + CameraLaserSensorPreferenceController.PROPERTY_CAMERA_LASER_SENSOR, + Integer.toString(CameraLaserSensorPreferenceController.ENABLED)); + SettingsShadowSystemProperties.set( + CameraLaserSensorPreferenceController.BUILD_TYPE, USERDEBUG_BUILD); + + mController.displayPreference(mScreen); + + verify(mPreference).setChecked(true); + } + + @Test + public void displayPreference_cameraLaserSensorEnabled_shouldUncheckedPreference() { + when(mContext.getResources().getBoolean(R.bool.config_show_camera_laser_sensor)) + .thenReturn(true); + + SettingsShadowSystemProperties.set( + CameraLaserSensorPreferenceController.PROPERTY_CAMERA_LASER_SENSOR, + Integer.toString(CameraLaserSensorPreferenceController.DISABLED)); + SettingsShadowSystemProperties.set( + CameraLaserSensorPreferenceController.BUILD_TYPE, USERDEBUG_BUILD); + + mController.displayPreference(mScreen); + + verify(mPreference).setChecked(false); + } + + @Test + public void handlePreferenceTreeClick_preferenceChecked_shouldEnableCameraLaserSensor() { + when(mContext.getResources().getBoolean(R.bool.config_show_camera_laser_sensor)) + .thenReturn(true); + + when(mPreference.isChecked()).thenReturn(true); + + mController.handlePreferenceTreeClick(mPreference); + + assertThat(Integer.toString(CameraLaserSensorPreferenceController.ENABLED).equals( + SystemProperties.get( + CameraLaserSensorPreferenceController.PROPERTY_CAMERA_LASER_SENSOR, + Integer.toString(CameraLaserSensorPreferenceController.ENABLED)))).isTrue(); + } + + @Test + public void handlePreferenceTreeClick_preferenceUnchecked_shouldDisableCameraLaserSensor() { + when(mContext.getResources().getBoolean(R.bool.config_show_camera_laser_sensor)) + .thenReturn(true); + + when(mPreference.isChecked()).thenReturn(false); + + mController.handlePreferenceTreeClick(mPreference); + + assertThat(Integer.toString(CameraLaserSensorPreferenceController.DISABLED).equals( + SystemProperties.get( + CameraLaserSensorPreferenceController.PROPERTY_CAMERA_LASER_SENSOR, + Integer.toString(CameraLaserSensorPreferenceController.ENABLED)))).isTrue(); + } +} diff --git a/tests/robotests/src/com/android/settings/development/DevelopmentSettingsDashboardFragmentTest.java b/tests/robotests/src/com/android/settings/development/DevelopmentSettingsDashboardFragmentTest.java index 04ff721167f..a001aafcdb1 100644 --- a/tests/robotests/src/com/android/settings/development/DevelopmentSettingsDashboardFragmentTest.java +++ b/tests/robotests/src/com/android/settings/development/DevelopmentSettingsDashboardFragmentTest.java @@ -17,22 +17,32 @@ package com.android.settings.development; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; import android.content.Context; import android.provider.SearchIndexableResource; +import android.provider.Settings; import com.android.internal.logging.nano.MetricsProto; import com.android.settings.R; import com.android.settings.TestConfig; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.testutils.shadow.SettingsShadowResources; +import com.android.settings.widget.SwitchBar; +import com.android.settings.widget.ToggleSwitch; import com.android.settingslib.development.DevelopmentSettingsEnabler; +import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.MockitoAnnotations; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; +import org.robolectric.annotation.Implementation; +import org.robolectric.annotation.Implements; +import org.robolectric.util.ReflectionHelpers; import java.util.List; @@ -44,11 +54,24 @@ import java.util.List; }) public class DevelopmentSettingsDashboardFragmentTest { + private SwitchBar mSwitchBar; + private ToggleSwitch mSwitch; + private Context mContext; private DevelopmentSettingsDashboardFragment mDashboard; @Before public void setUp() { - mDashboard = new DevelopmentSettingsDashboardFragment(); + MockitoAnnotations.initMocks(this); + mContext = RuntimeEnvironment.application; + mSwitchBar = new SwitchBar(mContext); + mSwitch = mSwitchBar.getSwitch(); + mDashboard = spy(new DevelopmentSettingsDashboardFragment()); + ReflectionHelpers.setField(mDashboard, "mSwitchBar", mSwitchBar); + } + + @After + public void tearDown() { + ShadowEnableDevelopmentSettingWarningDialog.reset(); } @Test @@ -95,4 +118,62 @@ public class DevelopmentSettingsDashboardFragmentTest { assertThat(nonIndexableKeys).doesNotContain("development_prefs_screen"); } + + @Test + @Config(shadows = { + ShadowEnableDevelopmentSettingWarningDialog.class + }) + public void onSwitchChanged_sameState_shouldDoNothing() { + when(mDashboard.getContext()).thenReturn(mContext); + Settings.Global.putInt(mContext.getContentResolver(), + Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0); + + mDashboard.onSwitchChanged(mSwitch, false /* isChecked */); + assertThat(ShadowEnableDevelopmentSettingWarningDialog.mShown).isFalse(); + } + + @Test + @Config(shadows = { + ShadowEnableDevelopmentSettingWarningDialog.class + }) + public void onSwitchChanged_turnOn_shouldShowWarningDialog() { + when(mDashboard.getContext()).thenReturn(mContext); + Settings.Global.putInt(mContext.getContentResolver(), + Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0); + + mDashboard.onSwitchChanged(mSwitch, true /* isChecked */); + assertThat(ShadowEnableDevelopmentSettingWarningDialog.mShown).isTrue(); + } + + @Test + @Config(shadows = { + ShadowEnableDevelopmentSettingWarningDialog.class + }) + public void onSwitchChanged_turnOff_shouldTurnOff() { + when(mDashboard.getContext()).thenReturn(mContext); + Settings.Global.putInt(mContext.getContentResolver(), + Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 1); + + mDashboard.onSwitchChanged(mSwitch, false /* isChecked */); + + assertThat(ShadowEnableDevelopmentSettingWarningDialog.mShown).isFalse(); + assertThat(DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(mContext)) + .isFalse(); + } + + @Implements(EnableDevelopmentSettingWarningDialog.class) + public static class ShadowEnableDevelopmentSettingWarningDialog { + + static boolean mShown; + + public static void reset() { + mShown = false; + } + + @Implementation + public static void show( + DevelopmentSettingsDashboardFragment host) { + mShown = true; + } + } } diff --git a/tests/robotests/src/com/android/settings/development/DevelopmentSwitchBarControllerTest.java b/tests/robotests/src/com/android/settings/development/DevelopmentSwitchBarControllerTest.java index a53b83662cb..6f79fafc98f 100644 --- a/tests/robotests/src/com/android/settings/development/DevelopmentSwitchBarControllerTest.java +++ b/tests/robotests/src/com/android/settings/development/DevelopmentSwitchBarControllerTest.java @@ -17,6 +17,7 @@ package com.android.settings.development; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.when; import com.android.settings.TestConfig; import com.android.settings.testutils.SettingsRobolectricTestRunner; @@ -45,6 +46,8 @@ public class DevelopmentSwitchBarControllerTest { @Mock private DevelopmentSettings mSettings; + @Mock + private DevelopmentSettingsDashboardFragment mNewSettings; private Lifecycle mLifecycle; private SwitchBar mSwitchBar; private DevelopmentSwitchBarController mController; @@ -76,6 +79,21 @@ public class DevelopmentSwitchBarControllerTest { assertThat(listeners).doesNotContain(mSettings); } + @Test + public void runThroughLifecycle_v2_isMonkeyRun_shouldNotRegisterListener() { + ShadowUtils.setIsUserAMonkey(true); + mController = new DevelopmentSwitchBarController(mNewSettings, mSwitchBar, + true /* isAvailable */, mLifecycle); + final ArrayList listeners = + ReflectionHelpers.getField(mSwitchBar, "mSwitchChangeListeners"); + + mLifecycle.onStart(); + assertThat(listeners).doesNotContain(mNewSettings); + + mLifecycle.onStop(); + assertThat(listeners).doesNotContain(mNewSettings); + } + @Test public void runThroughLifecycle_isNotMonkeyRun_shouldRegisterAndRemoveListener() { ShadowUtils.setIsUserAMonkey(false); @@ -91,6 +109,22 @@ public class DevelopmentSwitchBarControllerTest { assertThat(listeners).doesNotContain(mSettings); } + @Test + public void runThroughLifecycle_v2_isNotMonkeyRun_shouldRegisterAndRemoveListener() { + when(mNewSettings.getContext()).thenReturn(RuntimeEnvironment.application); + ShadowUtils.setIsUserAMonkey(false); + mController = new DevelopmentSwitchBarController(mNewSettings, mSwitchBar, + true /* isAvailable */, mLifecycle); + final ArrayList listeners = + ReflectionHelpers.getField(mSwitchBar, "mSwitchChangeListeners"); + + mLifecycle.onStart(); + assertThat(listeners).contains(mNewSettings); + + mLifecycle.onStop(); + assertThat(listeners).doesNotContain(mNewSettings); + } + @Test public void buildController_unavailable_shouldDisableSwitchBar() { ShadowUtils.setIsUserAMonkey(false); diff --git a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java index db4fb6daa82..89a4208d84e 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java @@ -411,18 +411,11 @@ public class PowerUsageSummaryTest { @Test public void testUpdateLastFullChargePreference_showCorrectSummary() { - final CharSequence formattedString = mRealContext.getText( - R.string.power_last_full_charge_summary); - final CharSequence timeSequence = Utils.formatElapsedTime(mRealContext, - TIME_SINCE_LAST_FULL_CHARGE_MS, false); - final CharSequence expectedSummary = TextUtils.expandTemplate( - formattedString, timeSequence); - doReturn(formattedString).when(mFragment).getText(R.string.power_last_full_charge_summary); doReturn(mRealContext).when(mFragment).getContext(); mFragment.updateLastFullChargePreference(TIME_SINCE_LAST_FULL_CHARGE_MS); - assertThat(mLastFullChargePref.getSubtitle()).isEqualTo(expectedSummary); + assertThat(mLastFullChargePref.getSubtitle()).isEqualTo("2 hr. ago"); } @Test diff --git a/tests/robotests/src/com/android/settings/wifi/ConfigureWifiSettingsTest.java b/tests/robotests/src/com/android/settings/wifi/ConfigureWifiSettingsTest.java new file mode 100644 index 00000000000..687287be8a4 --- /dev/null +++ b/tests/robotests/src/com/android/settings/wifi/ConfigureWifiSettingsTest.java @@ -0,0 +1,83 @@ +package com.android.settings.wifi; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; + +import android.content.Context; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; +import com.android.settings.TestConfig; +import com.android.settings.testutils.SettingsRobolectricTestRunner; +import com.android.settings.testutils.XmlTestUtils; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; + +import java.util.List; + +@RunWith(SettingsRobolectricTestRunner.class) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) +public class ConfigureWifiSettingsTest { + + private Context mContext; + + @Before + public void setUp() { + mContext = spy(RuntimeEnvironment.application); + } + + @Test + public void testNonIndexableKeys_existInXmlLayout() { + final List niks = ConfigureWifiSettings.SEARCH_INDEX_DATA_PROVIDER + .getNonIndexableKeys(mContext); + final int xmlId = new ConfigureWifiSettings().getPreferenceScreenResId(); + + final List keys = XmlTestUtils.getKeysFromPreferenceXml(mContext, xmlId); + + assertThat(keys).containsAllIn(niks); + } + + @Test + public void testNonIndexableKeys_noConnection_blocksIP() { + ConnectivityManager manager = mock(ConnectivityManager.class); + when(manager.getActiveNetworkInfo()).thenReturn(null); + doReturn(manager).when(mContext).getSystemService(Context.CONNECTIVITY_SERVICE); + + final List niks = ConfigureWifiSettings.SEARCH_INDEX_DATA_PROVIDER + .getNonIndexableKeys(mContext); + assertThat(niks).contains(ConfigureWifiSettings.KEY_IP_ADDRESS); + } + + @Test + public void testNonIndexableKeys_wifiConnection_blocksIP() { + ConnectivityManager manager = mock(ConnectivityManager.class); + NetworkInfo info = mock(NetworkInfo.class); + when(info.getType()).thenReturn(ConnectivityManager.TYPE_WIFI); + when(manager.getActiveNetworkInfo()).thenReturn(info); + doReturn(manager).when(mContext).getSystemService(Context.CONNECTIVITY_SERVICE); + + final List niks = ConfigureWifiSettings.SEARCH_INDEX_DATA_PROVIDER + .getNonIndexableKeys(mContext); + assertThat(niks).contains(ConfigureWifiSettings.KEY_IP_ADDRESS); + } + + @Test + public void testNonIndexableKeys_mobileConnection_blocksIP() { + ConnectivityManager manager = mock(ConnectivityManager.class); + NetworkInfo info = mock(NetworkInfo.class); + when(info.getType()).thenReturn(ConnectivityManager.TYPE_MOBILE); + when(manager.getActiveNetworkInfo()).thenReturn(info); + doReturn(manager).when(mContext).getSystemService(Context.CONNECTIVITY_SERVICE); + + final List niks = ConfigureWifiSettings.SEARCH_INDEX_DATA_PROVIDER + .getNonIndexableKeys(mContext); + assertThat(niks).doesNotContain(ConfigureWifiSettings.KEY_IP_ADDRESS); + } +} diff --git a/tests/robotests/src/com/android/settings/wifi/details/WifiDetailActionBarObserverTest.java b/tests/robotests/src/com/android/settings/wifi/details/WifiDetailActionBarObserverTest.java deleted file mode 100644 index c573d3cb658..00000000000 --- a/tests/robotests/src/com/android/settings/wifi/details/WifiDetailActionBarObserverTest.java +++ /dev/null @@ -1,69 +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.wifi.details; - -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.app.ActionBar; -import android.app.Activity; -import android.content.Context; -import android.os.Bundle; -import com.android.settings.R; -import com.android.settings.TestConfig; -import com.android.settings.testutils.SettingsRobolectricTestRunner; -import com.android.settingslib.core.lifecycle.Lifecycle; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.RuntimeEnvironment; -import org.robolectric.annotation.Config; - -@RunWith(SettingsRobolectricTestRunner.class) -@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) -public class WifiDetailActionBarObserverTest { - - @Mock private Bundle mockBundle; - @Mock private Activity mockActivity; - @Mock private ActionBar mockActionBar; - @Mock private WifiNetworkDetailsFragment mockFragment; - - private Context mContext = RuntimeEnvironment.application; - private Lifecycle mLifecycle; - private WifiDetailActionBarObserver mObserver; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - - mLifecycle = new Lifecycle(); - - when(mockFragment.getActivity()).thenReturn(mockActivity); - when(mockActivity.getActionBar()).thenReturn(mockActionBar); - - mObserver = new WifiDetailActionBarObserver(mContext, mockFragment); - mLifecycle.addObserver(mObserver); - } - - @Test - public void actionBarIsSetToNetworkInfo() { - mLifecycle.onCreate(mockBundle); - - verify(mockActionBar).setTitle(mContext.getString(R.string.wifi_details_title)); - } -} diff --git a/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherApBandPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherApBandPreferenceControllerTest.java index a7e00ab544e..8f0b143ae02 100644 --- a/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherApBandPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherApBandPreferenceControllerTest.java @@ -16,6 +16,12 @@ package com.android.settings.wifi.tether; +import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + import android.content.Context; import android.net.ConnectivityManager; import android.net.wifi.WifiManager; @@ -35,12 +41,6 @@ import org.mockito.MockitoAnnotations; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; -import static com.google.common.truth.Truth.assertThat; -import static org.mockito.Matchers.anyString; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - @RunWith(SettingsRobolectricTestRunner.class) @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) public class WifiTetherApBandPreferenceControllerTest { @@ -75,16 +75,30 @@ public class WifiTetherApBandPreferenceControllerTest { @Test public void display_5GhzSupported_shouldDisplayFullList() { - when(mWifiManager.is5GHzBandSupported()).thenReturn(true); + when(mWifiManager.getCountryCode()).thenReturn("US"); + when(mWifiManager.isDualBandSupported()).thenReturn(true); mController.displayPreference(mScreen); assertThat(mListPreference.getEntries().length).isEqualTo(2); } + @Test + public void display_noCountryCode_shouldDisable() { + when(mWifiManager.getCountryCode()).thenReturn(null); + when(mWifiManager.isDualBandSupported()).thenReturn(true); + + mController.displayPreference(mScreen); + + assertThat(mListPreference.getEntries()).isNull(); + assertThat(mListPreference.isEnabled()).isFalse(); + assertThat(mListPreference.getSummary()) + .isEqualTo(RuntimeEnvironment.application.getString(R.string.wifi_ap_choose_2G)); + } + @Test public void display_5GhzNotSupported_shouldDisable() { - when(mWifiManager.is5GHzBandSupported()).thenReturn(false); + when(mWifiManager.isDualBandSupported()).thenReturn(false); mController.displayPreference(mScreen);