Merge "Use SoftAp API to get number of connected device"
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 51a811d..5a4db20 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -476,7 +476,7 @@
</intent-filter>
</activity>
- <service android:name=".TetherService"
+ <service android:name=".wifi.tether.TetherService"
android:exported="true"
android:permission="android.permission.TETHER_PRIVILEGED" />
@@ -3311,6 +3311,25 @@
</intent-filter>
</activity>
+ <activity android:name="Settings$AdvancedConnectedDeviceActivity"
+ android:label="@string/connected_device_connections_title"
+ android:taskAffinity="com.android.settings"
+ android:parentActivityName="Settings$ConnectedDeviceDashboardActivity"
+ android:enabled="false">
+ <intent-filter android:priority="1">
+ <action android:name="com.android.settings.ADVANCED_CONNECTED_DEVICE_SETTINGS" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
+ android:value="com.android.settings.connecteddevice.AdvancedConnectedDeviceDashboardFragment" />
+ <meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
+ android:value="true" />
+ </activity>
+
<provider android:name=".slices.SettingsSliceProvider"
android:authorities="com.android.settings.slices"
android:exported="true">
diff --git a/res/layout/master_clear.xml b/res/layout/master_clear.xml
index 779e504..f81c7e8 100644
--- a/res/layout/master_clear.xml
+++ b/res/layout/master_clear.xml
@@ -93,7 +93,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
- android:paddingEnd="8dp"
+ android:paddingEnd="@dimen/reset_checkbox_padding_end"
android:focusable="false"
android:clickable="false"
android:duplicateParentState="true" />
@@ -104,14 +104,14 @@
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:paddingTop="12dp"
- android:textSize="18sp"
+ android:paddingTop="@dimen/reset_checkbox_title_padding_top"
+ android:textSize="@dimen/reset_checkbox_title_text_size"
android:text="@string/erase_external_storage" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:paddingTop="4sp"
- android:textSize="14sp"
+ android:paddingTop="@dimen/reset_checkbox_summary_padding_top"
+ android:textSize="@dimen/reset_checkbox_summary_text_size"
android:text="@string/erase_external_storage_description" />
</LinearLayout>
</LinearLayout>
diff --git a/res/layout/reset_esim_checkbox.xml b/res/layout/reset_esim_checkbox.xml
new file mode 100644
index 0000000..e76ced0
--- /dev/null
+++ b/res/layout/reset_esim_checkbox.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:focusable="true"
+ android:clickable="true"
+ android:visibility="gone">
+
+ <CheckBox android:id="@+id/erase_esim"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
+ android:paddingEnd="@dimen/reset_checkbox_padding_end"
+ android:focusable="false"
+ android:clickable="false"
+ android:duplicateParentState="true" />
+
+ <LinearLayout android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
+ android:orientation="vertical">
+
+ <TextView android:id="@+id/erase_esim_title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingTop="@dimen/reset_checkbox_title_padding_top"
+ android:textSize="@dimen/reset_checkbox_title_text_size" />
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingTop="@dimen/reset_checkbox_summary_padding_top"
+ android:textSize="@dimen/reset_checkbox_summary_text_size"
+ android:text="@string/reset_esim_desc" />
+ </LinearLayout>
+</LinearLayout>
diff --git a/res/layout/reset_network.xml b/res/layout/reset_network.xml
index be966dd..1850bb2 100644
--- a/res/layout/reset_network.xml
+++ b/res/layout/reset_network.xml
@@ -14,7 +14,8 @@
limitations under the License.
-->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
@@ -27,7 +28,8 @@
android:layout_marginTop="12dp"
android:layout_weight="1">
- <LinearLayout android:layout_width="match_parent"
+ <LinearLayout
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
@@ -38,6 +40,11 @@
android:textDirection="locale"
android:text="@string/reset_network_desc" />
+ <include layout="@layout/reset_esim_checkbox"
+ android:id="@+id/erase_esim_container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+
</LinearLayout>
</ScrollView>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 339eaf2..d4071ed 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -311,4 +311,11 @@
<dimen name="suggestion_card_title_padding_bottom_one_card">6dp</dimen>
<dimen name="suggestion_card_title_padding_bottom_multiple_cards">8dp</dimen>
+ <!-- Padding for the reset screens -->
+ <dimen name="reset_checkbox_padding_end">8dp</dimen>
+ <dimen name="reset_checkbox_title_padding_top">12dp</dimen>
+ <dimen name="reset_checkbox_summary_padding_top">4dp</dimen>
+ <dimen name="reset_checkbox_title_text_size">18sp</dimen>
+ <dimen name="reset_checkbox_summary_text_size">14sp</dimen>
+
</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 4182fd9..164f6d5 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -3213,6 +3213,10 @@
<string name="reset_network_title">Reset Wi-Fi, mobile & Bluetooth</string>
<!-- SD card & phone storage settings screen, message on screen after user selects Reset network settings [CHAR LIMIT=NONE] -->
<string name="reset_network_desc">This will reset all network settings, including:\n\n<li>Wi\u2011Fi</li>\n<li>Mobile data</li>\n<li>Bluetooth</li>"</string>
+ <!-- SD card & phone storage settings screen, title for the checkbox to let user decide whether erase eSIM data together [CHAR LIMIT=NONE] -->
+ <string name="reset_esim_title">Also reset eSIMs</string>
+ <!-- SD card & phone storage settings screen, message for the checkbox to let user decide whether erase eSIM data together [CHAR LIMIT=NONE] -->
+ <string name="reset_esim_desc">Erase all eSIMs on the phone. You\u2019ll have to contract your carrier to redownload your eSIMs. This will not cancel your mobile service plan.</string>
<!-- SD card & phone storage settings screen, button on screen after user selects Reset network settings -->
<string name="reset_network_button_text">Reset settings</string>
<!-- SD card & phone storage settings screen, message on screen after user selects Reset settings button -->
@@ -3225,6 +3229,10 @@
<string name="network_reset_not_available">Network reset is not available for this user</string>
<!-- Reset settings complete toast text [CHAR LIMIT=75] -->
<string name="reset_network_complete_toast">Network settings have been reset</string>
+ <!-- Title of the error message shown when error happens during erase eSIM data [CHAR LIMIT=NONE] -->
+ <string name="reset_esim_error_title">Cant\u2019t reset eSIMs</string>
+ <!-- Message of the error message shown when error happens during erase eSIM data [CHAR LIMIT=NONE] -->
+ <string name="reset_esim_error_msg">The eSIMs can\u2019tt be reset due to an error.</string>
<!-- Master Clear -->
<!-- Button title to factory data reset the entire device -->
diff --git a/src/com/android/settings/MasterClear.java b/src/com/android/settings/MasterClear.java
index 3cc722b..dd7ef80 100644
--- a/src/com/android/settings/MasterClear.java
+++ b/src/com/android/settings/MasterClear.java
@@ -76,7 +76,7 @@
private static final String TAG = "MasterClear";
private static final int KEYGUARD_REQUEST = 55;
- private static final int CREDENTIAL_CONFIRM_REQUEST = 56;
+ @VisibleForTesting static final int CREDENTIAL_CONFIRM_REQUEST = 56;
static final String ERASE_EXTERNAL_EXTRA = "erase_sd";
static final String ERASE_ESIMS_EXTRA = "erase_esim";
@@ -157,9 +157,12 @@
.setAction("android.accounts.action.PRE_FACTORY_RESET");
// Check to make sure that the intent is supported.
final PackageManager pm = context.getPackageManager();
- final List<ResolveInfo> resolutions =
- pm.queryIntentActivities(requestAccountConfirmation, 0);
- if (resolutions != null && resolutions.size() > 0) {
+ final ResolveInfo resolution = pm.resolveActivity(requestAccountConfirmation, 0);
+ if (resolution != null
+ && resolution.activityInfo != null
+ && packageName.equals(resolution.activityInfo.packageName)) {
+ // Note that we need to check the packagename to make sure that an Activity resolver
+ // wasn't returned.
getActivity().startActivityForResult(
requestAccountConfirmation, CREDENTIAL_CONFIRM_REQUEST);
return true;
diff --git a/src/com/android/settings/ResetNetwork.java b/src/com/android/settings/ResetNetwork.java
index 0f08c26..f64f6dc 100644
--- a/src/com/android/settings/ResetNetwork.java
+++ b/src/com/android/settings/ResetNetwork.java
@@ -18,20 +18,28 @@
import android.annotation.Nullable;
import android.app.Activity;
+import android.content.ContentResolver;
+import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.os.Bundle;
import android.os.UserHandle;
import android.os.UserManager;
+import android.provider.Settings;
+import android.provider.Settings.Global;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
+import android.telephony.euicc.EuiccManager;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
+import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
+import android.widget.CheckBox;
import android.widget.Spinner;
+import android.widget.TextView;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.telephony.PhoneConstants;
@@ -64,6 +72,8 @@
private View mContentView;
private Spinner mSubscriptionSpinner;
private Button mInitiateButton;
+ private View mEsimContainer;
+ private CheckBox mEsimCheckbox;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
@@ -107,6 +117,7 @@
SubscriptionInfo subscription = mSubscriptions.get(selectedIndex);
args.putInt(PhoneConstants.SUBSCRIPTION_KEY, subscription.getSubscriptionId());
}
+ args.putBoolean(MasterClear.ERASE_ESIMS_EXTRA, mEsimCheckbox.isChecked());
((SettingsActivity) getActivity()).startPreferencePanel(
this, ResetNetworkConfirm.class.getName(),
args, R.string.reset_network_confirm_title, null, null, 0);
@@ -141,6 +152,8 @@
*/
private void establishInitialState() {
mSubscriptionSpinner = (Spinner) mContentView.findViewById(R.id.reset_network_subscription);
+ mEsimContainer = mContentView.findViewById(R.id.erase_esim_container);
+ mEsimCheckbox = mContentView.findViewById(R.id.erase_esim);
mSubscriptions = SubscriptionManager.from(getActivity()).getActiveSubscriptionInfoList();
if (mSubscriptions != null && mSubscriptions.size() > 0) {
@@ -192,6 +205,30 @@
}
mInitiateButton = (Button) mContentView.findViewById(R.id.initiate_reset_network);
mInitiateButton.setOnClickListener(mInitiateListener);
+ if (showEuiccSettings(getContext())) {
+ mEsimContainer.setVisibility(View.VISIBLE);
+ TextView title = mContentView.findViewById(R.id.erase_esim_title);
+ title.setText(R.string.reset_esim_title);
+ mEsimContainer.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ mEsimCheckbox.toggle();
+ }
+ });
+ } else {
+ mEsimCheckbox.setChecked(false /* checked */);
+ }
+ }
+
+ private boolean showEuiccSettings(Context context) {
+ EuiccManager euiccManager =
+ (EuiccManager) context.getSystemService(Context.EUICC_SERVICE);
+ if (!euiccManager.isEnabled()) {
+ return false;
+ }
+ ContentResolver resolver = context.getContentResolver();
+ return Settings.Global.getInt(resolver, Global.EUICC_PROVISIONED, 0) != 0
+ || Settings.Global.getInt(resolver, Global.DEVELOPMENT_SETTINGS_ENABLED, 0) != 0;
}
@Override
diff --git a/src/com/android/settings/ResetNetworkConfirm.java b/src/com/android/settings/ResetNetworkConfirm.java
index 58b8289..53d9386 100644
--- a/src/com/android/settings/ResetNetworkConfirm.java
+++ b/src/com/android/settings/ResetNetworkConfirm.java
@@ -16,6 +16,7 @@
package com.android.settings;
+import android.app.AlertDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothManager;
import android.content.ContentResolver;
@@ -24,9 +25,12 @@
import android.net.NetworkPolicyManager;
import android.net.Uri;
import android.net.wifi.WifiManager;
+import android.os.AsyncTask;
import android.os.Bundle;
+import android.os.RecoverySystem;
import android.os.UserHandle;
import android.os.UserManager;
+import android.support.annotation.VisibleForTesting;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.view.LayoutInflater;
@@ -39,6 +43,7 @@
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.telephony.PhoneConstants;
import com.android.settings.core.InstrumentedPreferenceFragment;
+import com.android.settings.wrapper.RecoverySystemWrapper;
import com.android.settingslib.RestrictedLockUtils;
import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
@@ -57,6 +62,43 @@
private View mContentView;
private int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+ @VisibleForTesting boolean mEraseEsim;
+ @VisibleForTesting EraseEsimAsyncTask mEraseEsimTask;
+ @VisibleForTesting static RecoverySystemWrapper mRecoverySystem;
+
+ /**
+ * Async task used to erase all the eSIM profiles from the phone. If error happens during
+ * erasing eSIM profiles or timeout, an error msg is shown.
+ */
+ private static class EraseEsimAsyncTask extends AsyncTask<Void, Void, Boolean> {
+ private final Context mContext;
+ private final String mPackageName;
+
+ EraseEsimAsyncTask(Context context, String packageName) {
+ mContext = context;
+ mPackageName = packageName;
+ }
+
+ @Override
+ protected Boolean doInBackground(Void... params) {
+ return mRecoverySystem.wipeEuiccData(
+ mContext, true /* isWipeEuicc */, mPackageName);
+ }
+
+ @Override
+ protected void onPostExecute(Boolean succeeded) {
+ if (succeeded) {
+ Toast.makeText(mContext, R.string.reset_network_complete_toast, Toast.LENGTH_SHORT)
+ .show();
+ } else {
+ new AlertDialog.Builder(mContext)
+ .setTitle(R.string.reset_esim_error_title)
+ .setMessage(R.string.reset_esim_error_msg)
+ .setPositiveButton(android.R.string.ok, null /* listener */)
+ .show();
+ }
+ }
+ }
/**
* The user has gone through the multiple confirmation, so now we go ahead
@@ -69,7 +111,8 @@
if (Utils.isMonkeyRunning()) {
return;
}
- // TODO maybe show a progress dialog if this ends up taking a while
+ // TODO maybe show a progress screen if this ends up taking a while and won't let user
+ // go back until the tasks finished.
Context context = getActivity();
ConnectivityManager connectivityManager = (ConnectivityManager)
@@ -108,11 +151,20 @@
ImsManager.factoryReset(context);
restoreDefaultApn(context);
+ esimFactoryReset(context, context.getPackageName());
+ }
+ };
+ @VisibleForTesting
+ void esimFactoryReset(Context context, String packageName) {
+ if (mEraseEsim) {
+ mEraseEsimTask = new EraseEsimAsyncTask(context, packageName);
+ mEraseEsimTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+ } else {
Toast.makeText(context, R.string.reset_network_complete_toast, Toast.LENGTH_SHORT)
.show();
}
- };
+ }
/**
* Restore APN settings to default.
@@ -163,6 +215,16 @@
if (args != null) {
mSubId = args.getInt(PhoneConstants.SUBSCRIPTION_KEY,
SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+ mEraseEsim = args.getBoolean(MasterClear.ERASE_ESIMS_EXTRA);
+ }
+ mRecoverySystem = new RecoverySystemWrapper();
+ }
+
+ @Override
+ public void onDestroy() {
+ if (mEraseEsimTask != null) {
+ mEraseEsimTask.cancel(true /* mayInterruptIfRunning */);
+ mEraseEsimTask = null;
}
}
diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
index 5e815bc..d13a62d 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -178,5 +178,10 @@
public static class StorageDashboardActivity extends SettingsActivity {}
public static class UserAndAccountDashboardActivity extends SettingsActivity {}
public static class SystemDashboardActivity extends SettingsActivity {}
+ public static class AdvancedConnectedDeviceActivity extends SettingsActivity {
+ public static final boolean isEnabled() {
+ return FeatureFlagUtils.isEnabled(null /* context */, CONNECTED_DEVICE_V2);
+ }
+ }
}
diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java
index 1c674b6..f45ac5e 100644
--- a/src/com/android/settings/Utils.java
+++ b/src/com/android/settings/Utils.java
@@ -515,7 +515,8 @@
Fragment resultTo, int resultRequestCode, String titleResPackageName, int titleResId,
CharSequence title, boolean isShortcut, int metricsCategory) {
startWithFragment(context, fragmentName, args, resultTo, resultRequestCode,
- titleResPackageName, titleResId, title, isShortcut, metricsCategory, 0);
+ titleResPackageName, titleResId, title, isShortcut, metricsCategory,
+ Intent.FLAG_ACTIVITY_NEW_TASK);
}
diff --git a/src/com/android/settings/core/gateway/SettingsGateway.java b/src/com/android/settings/core/gateway/SettingsGateway.java
index 0a4b1f2..026cc2b 100644
--- a/src/com/android/settings/core/gateway/SettingsGateway.java
+++ b/src/com/android/settings/core/gateway/SettingsGateway.java
@@ -57,6 +57,7 @@
import com.android.settings.applications.manageapplications.ManageApplications;
import com.android.settings.bluetooth.BluetoothDeviceDetailsFragment;
import com.android.settings.bluetooth.BluetoothSettings;
+import com.android.settings.connecteddevice.AdvancedConnectedDeviceDashboardFragment;
import com.android.settings.connecteddevice.ConnectedDeviceDashboardFragment;
import com.android.settings.connecteddevice.ConnectedDeviceDashboardFragmentOld;
import com.android.settings.datausage.DataPlanUsageSummary;
@@ -254,7 +255,8 @@
LockscreenDashboardFragment.class.getName(),
BluetoothDeviceDetailsFragment.class.getName(),
DataUsageList.class.getName(),
- DirectoryAccessDetails.class.getName()
+ DirectoryAccessDetails.class.getName(),
+ AdvancedConnectedDeviceDashboardFragment.class.getName()
};
public static final String[] SETTINGS_FOR_RESTRICTED = {
diff --git a/src/com/android/settings/datetime/timezone/ZonePicker.java b/src/com/android/settings/datetime/timezone/ZonePicker.java
index eafbaa2..d0d1720 100644
--- a/src/com/android/settings/datetime/timezone/ZonePicker.java
+++ b/src/com/android/settings/datetime/timezone/ZonePicker.java
@@ -31,6 +31,7 @@
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
+import android.widget.LinearLayout;
import android.widget.Spinner;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
@@ -56,11 +57,14 @@
private List<RegionInfo> mRegions;
private Map<String, List<TimeZoneInfo>> mZoneInfos;
private List<TimeZoneInfo> mFixedOffsetTimeZones;
- private TimeZoneAdapter mTimeZoneAdapter;
private String mSelectedTimeZone;
private boolean mSelectByRegion;
private DataLoader mDataLoader;
+ private TimeZoneAdapter mTimeZoneAdapter;
+
private RecyclerView mRecyclerView;
+ private LinearLayout mRegionSpinnerLayout;
+ private Spinner mRegionSpinner;
@Override
public int getMetricsCategory() {
@@ -88,15 +92,17 @@
final ArrayAdapter<RegionInfo> regionAdapter = new ArrayAdapter<>(getContext(),
R.layout.filter_spinner_item, mRegions);
regionAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
- final Spinner spinner = view.findViewById(R.id.tz_region_spinner);
- spinner.setAdapter(regionAdapter);
- spinner.setOnItemSelectedListener(this);
- setupForCurrentTimeZone(spinner);
+
+ mRegionSpinnerLayout = view.findViewById(R.id.tz_region_spinner_layout);
+ mRegionSpinner = view.findViewById(R.id.tz_region_spinner);
+ mRegionSpinner.setAdapter(regionAdapter);
+ mRegionSpinner.setOnItemSelectedListener(this);
+ setupForCurrentTimeZone();
setHasOptionsMenu(true);
return view;
}
- private void setupForCurrentTimeZone(Spinner spinner) {
+ private void setupForCurrentTimeZone() {
final String localeRegionId = mLocale.getCountry().toUpperCase(Locale.ROOT);
final String currentTimeZone = TimeZone.getDefault().getID();
boolean fixedOffset = currentTimeZone.startsWith("Etc/GMT") ||
@@ -105,12 +111,12 @@
for (int regionIndex = 0; regionIndex < mRegions.size(); regionIndex++) {
final RegionInfo region = mRegions.get(regionIndex);
if (localeRegionId.equals(region.getId())) {
- spinner.setSelection(regionIndex);
+ mRegionSpinner.setSelection(regionIndex);
}
if (!fixedOffset) {
for (String timeZoneId: region.getTimeZoneIds()) {
if (TextUtils.equals(timeZoneId, mSelectedTimeZone)) {
- spinner.setSelection(regionIndex);
+ mRegionSpinner.setSelection(regionIndex);
return;
}
}
@@ -179,16 +185,15 @@
private void setSelectByRegion(boolean selectByRegion) {
mSelectByRegion = selectByRegion;
- getView().findViewById(R.id.tz_region_spinner_layout).setVisibility(
+ mRegionSpinnerLayout.setVisibility(
mSelectByRegion ? View.VISIBLE : View.GONE);
List<TimeZoneInfo> tzInfos;
if (selectByRegion) {
- Spinner regionSpinner = getView().findViewById(R.id.tz_region_spinner);
- int selectedRegion = regionSpinner.getSelectedItemPosition();
+ int selectedRegion = mRegionSpinner.getSelectedItemPosition();
if (selectedRegion == -1) {
// Arbitrarily pick the first item if no region was selected above.
selectedRegion = 0;
- regionSpinner.setSelection(selectedRegion);
+ mRegionSpinner.setSelection(selectedRegion);
}
tzInfos = getTimeZoneInfos(mRegions.get(selectedRegion));
} else {
diff --git a/src/com/android/settings/display/TimeoutPreferenceController.java b/src/com/android/settings/display/TimeoutPreferenceController.java
index 1d86999..84f9641 100644
--- a/src/com/android/settings/display/TimeoutPreferenceController.java
+++ b/src/com/android/settings/display/TimeoutPreferenceController.java
@@ -13,9 +13,11 @@
*/
package com.android.settings.display;
-import android.app.admin.DevicePolicyManager;
+import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT;
+
import android.content.Context;
import android.os.UserHandle;
+import android.os.UserManager;
import android.provider.Settings;
import android.support.v7.preference.Preference;
import android.util.Log;
@@ -25,10 +27,9 @@
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.wrapper.DevicePolicyManagerWrapper;
import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
import com.android.settingslib.core.AbstractPreferenceController;
-import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT;
-
public class TimeoutPreferenceController extends AbstractPreferenceController implements
PreferenceControllerMixin, Preference.OnPreferenceChangeListener {
@@ -69,6 +70,13 @@
timeoutListPreference.removeUnusableTimeouts(maxTimeout, admin);
}
updateTimeoutPreferenceDescription(timeoutListPreference, currentTimeout);
+
+ EnforcedAdmin admin = RestrictedLockUtils.checkIfRestrictionEnforced(
+ mContext, UserManager.DISALLOW_CONFIG_SCREEN_TIMEOUT,
+ UserHandle.myUserId());
+ if(admin != null) {
+ timeoutListPreference.removeUnusableTimeouts(0/* disable all*/, admin);
+ }
}
@Override
diff --git a/src/com/android/settings/fuelgauge/BatteryInfo.java b/src/com/android/settings/fuelgauge/BatteryInfo.java
index acd8144..c4c795b 100644
--- a/src/com/android/settings/fuelgauge/BatteryInfo.java
+++ b/src/com/android/settings/fuelgauge/BatteryInfo.java
@@ -272,7 +272,7 @@
void onParsingDone();
}
- private static void parse(BatteryStats stats, BatteryDataParser... parsers) {
+ public static void parse(BatteryStats stats, BatteryDataParser... parsers) {
long startWalltime = 0;
long endWalltime = 0;
long historyStart = 0;
diff --git a/src/com/android/settings/fuelgauge/batterytip/BatteryTipPolicy.java b/src/com/android/settings/fuelgauge/batterytip/BatteryTipPolicy.java
index 6af859b..a580db1 100644
--- a/src/com/android/settings/fuelgauge/batterytip/BatteryTipPolicy.java
+++ b/src/com/android/settings/fuelgauge/batterytip/BatteryTipPolicy.java
@@ -19,9 +19,12 @@
import android.content.Context;
import android.provider.Settings;
import android.support.annotation.VisibleForTesting;
+import android.text.format.DateUtils;
import android.util.KeyValueListParser;
import android.util.Log;
+import java.time.Duration;
+
/**
* Class to store the policy for battery tips, which comes from
* {@link Settings.Global}
@@ -34,6 +37,8 @@
private static final String KEY_BATTERY_SAVER_TIP_ENABLED = "battery_saver_tip_enabled";
private static final String KEY_HIGH_USAGE_ENABLED = "high_usage_enabled";
private static final String KEY_HIGH_USAGE_APP_COUNT = "high_usage_app_count";
+ private static final String KEY_HIGH_USAGE_PERIOD_MS = "high_usage_period_ms";
+ private static final String KEY_HIGH_USAGE_BATTERY_DRAINING = "high_usage_battery_draining";
private static final String KEY_APP_RESTRICTION_ENABLED = "app_restriction_enabled";
private static final String KEY_REDUCED_BATTERY_ENABLED = "reduced_battery_enabled";
private static final String KEY_REDUCED_BATTERY_PERCENT = "reduced_battery_percent";
@@ -81,6 +86,24 @@
public final int highUsageAppCount;
/**
+ * The size of the window(milliseconds) for checking if the device is being heavily used
+ *
+ * @see Settings.Global#BATTERY_TIP_CONSTANTS
+ * @see #KEY_HIGH_USAGE_PERIOD_MS
+ */
+ public final long highUsagePeriodMs;
+
+ /**
+ * The battery draining threshold to detect whether device is heavily used.
+ * If battery drains more than {@link #highUsageBatteryDraining} in last {@link
+ * #highUsagePeriodMs}, treat device as heavily used.
+ *
+ * @see Settings.Global#BATTERY_TIP_CONSTANTS
+ * @see #KEY_HIGH_USAGE_BATTERY_DRAINING
+ */
+ public final int highUsageBatteryDraining;
+
+ /**
* {@code true} if app restriction tip is enabled
*
* @see Settings.Global#BATTERY_TIP_CONSTANTS
@@ -143,6 +166,9 @@
batterySaverTipEnabled = mParser.getBoolean(KEY_BATTERY_SAVER_TIP_ENABLED, true);
highUsageEnabled = mParser.getBoolean(KEY_HIGH_USAGE_ENABLED, true);
highUsageAppCount = mParser.getInt(KEY_HIGH_USAGE_APP_COUNT, 3);
+ highUsagePeriodMs = mParser.getLong(KEY_HIGH_USAGE_PERIOD_MS,
+ Duration.ofHours(2).toMillis());
+ highUsageBatteryDraining = mParser.getInt(KEY_HIGH_USAGE_BATTERY_DRAINING, 25);
appRestrictionEnabled = mParser.getBoolean(KEY_APP_RESTRICTION_ENABLED, true);
reducedBatteryEnabled = mParser.getBoolean(KEY_REDUCED_BATTERY_ENABLED, false);
reducedBatteryPercent = mParser.getInt(KEY_REDUCED_BATTERY_PERCENT, 50);
diff --git a/src/com/android/settings/fuelgauge/batterytip/HighUsageDataParser.java b/src/com/android/settings/fuelgauge/batterytip/HighUsageDataParser.java
new file mode 100644
index 0000000..cc5aed6
--- /dev/null
+++ b/src/com/android/settings/fuelgauge/batterytip/HighUsageDataParser.java
@@ -0,0 +1,79 @@
+/*
+ * 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.fuelgauge.batterytip;
+
+import android.os.BatteryStats;
+
+import com.android.settings.fuelgauge.BatteryInfo;
+
+/**
+ * DataParser used to go through battery data and detect whether battery is
+ * heavily used.
+ */
+public class HighUsageDataParser implements BatteryInfo.BatteryDataParser {
+ /**
+ * time period to check the battery usage
+ */
+ private final long mTimePeriodMs;
+ /**
+ * treat device as heavily used if battery usage is more than {@code threshold}. 1 means 1%
+ * battery usage.
+ */
+ private int mThreshold;
+ private long mEndTimeMs;
+ private byte mEndBatteryLevel;
+ private byte mLastPeriodBatteryLevel;
+ private int mBatteryDrain;
+
+ public HighUsageDataParser(long timePeriodMs, int threshold) {
+ mTimePeriodMs = timePeriodMs;
+ mThreshold = threshold;
+ }
+
+ @Override
+ public void onParsingStarted(long startTime, long endTime) {
+ mEndTimeMs = endTime;
+ }
+
+ @Override
+ public void onDataPoint(long time, BatteryStats.HistoryItem record) {
+ if (record.currentTime <= mEndTimeMs - mTimePeriodMs) {
+ // Since onDataPoint is invoked sorted by time, so we could use this way to get the
+ // closet battery level 'mTimePeriodMs' time ago.
+ mLastPeriodBatteryLevel = record.batteryLevel;
+ }
+ mEndBatteryLevel = record.batteryLevel;
+ }
+
+ @Override
+ public void onDataGap() {
+ // do nothing
+ }
+
+ @Override
+ public void onParsingDone() {
+ mBatteryDrain = mLastPeriodBatteryLevel - mEndBatteryLevel;
+ }
+
+ /**
+ * Return {@code true} if the battery drain in {@link #mTimePeriodMs} is too much
+ */
+ public boolean isDeviceHeavilyUsed() {
+ return mBatteryDrain > mThreshold;
+ }
+}
+
diff --git a/src/com/android/settings/fuelgauge/batterytip/detectors/HighUsageDetector.java b/src/com/android/settings/fuelgauge/batterytip/detectors/HighUsageDetector.java
index 3c69667..ed3fa04 100644
--- a/src/com/android/settings/fuelgauge/batterytip/detectors/HighUsageDetector.java
+++ b/src/com/android/settings/fuelgauge/batterytip/detectors/HighUsageDetector.java
@@ -19,13 +19,14 @@
import android.content.Context;
import android.os.BatteryStats;
import android.support.annotation.VisibleForTesting;
-import android.text.format.DateUtils;
import com.android.internal.os.BatterySipper;
import com.android.internal.os.BatteryStatsHelper;
import com.android.settings.fuelgauge.BatteryUtils;
import com.android.settings.fuelgauge.batterytip.BatteryTipPolicy;
import com.android.settings.fuelgauge.batterytip.AppInfo;
+import com.android.settings.fuelgauge.BatteryInfo;
+import com.android.settings.fuelgauge.batterytip.HighUsageDataParser;
import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
import com.android.settings.fuelgauge.batterytip.tips.HighUsageTip;
@@ -43,6 +44,8 @@
private List<AppInfo> mHighUsageAppList;
private Context mContext;
@VisibleForTesting
+ HighUsageDataParser mDataParser;
+ @VisibleForTesting
BatteryUtils mBatteryUtils;
public HighUsageDetector(Context context, BatteryTipPolicy policy,
@@ -52,32 +55,42 @@
mBatteryStatsHelper = batteryStatsHelper;
mHighUsageAppList = new ArrayList<>();
mBatteryUtils = BatteryUtils.getInstance(context);
+ mDataParser = new HighUsageDataParser(mPolicy.highUsagePeriodMs,
+ mPolicy.highUsageBatteryDraining);
}
@Override
public BatteryTip detect() {
final long screenUsageTimeMs = mBatteryUtils.calculateScreenUsageTime(mBatteryStatsHelper);
- //TODO(b/70570352): Change it to detect whether battery drops 25% in last 2 hours
- if (mPolicy.highUsageEnabled && screenUsageTimeMs > DateUtils.HOUR_IN_MILLIS) {
- final List<BatterySipper> batterySippers = mBatteryStatsHelper.getUsageList();
- for (int i = 0, size = batterySippers.size(); i < size; i++) {
- final BatterySipper batterySipper = batterySippers.get(i);
- if (!mBatteryUtils.shouldHideSipper(batterySipper)) {
- final long foregroundTimeMs = mBatteryUtils.getProcessTimeMs(
- BatteryUtils.StatusType.FOREGROUND, batterySipper.uidObj,
- BatteryStats.STATS_SINCE_CHARGED);
- mHighUsageAppList.add(new AppInfo.Builder()
- .setPackageName(mBatteryUtils.getPackageName(batterySipper.getUid()))
- .setScreenOnTimeMs(foregroundTimeMs)
- .build());
+ if (mPolicy.highUsageEnabled) {
+ parseBatteryData();
+ if (mDataParser.isDeviceHeavilyUsed()) {
+ final List<BatterySipper> batterySippers = mBatteryStatsHelper.getUsageList();
+ for (int i = 0, size = batterySippers.size(); i < size; i++) {
+ final BatterySipper batterySipper = batterySippers.get(i);
+ if (!mBatteryUtils.shouldHideSipper(batterySipper)) {
+ final long foregroundTimeMs = mBatteryUtils.getProcessTimeMs(
+ BatteryUtils.StatusType.FOREGROUND, batterySipper.uidObj,
+ BatteryStats.STATS_SINCE_CHARGED);
+ mHighUsageAppList.add(new AppInfo.Builder()
+ .setPackageName(
+ mBatteryUtils.getPackageName(batterySipper.getUid()))
+ .setScreenOnTimeMs(foregroundTimeMs)
+ .build());
+ }
}
- }
- mHighUsageAppList = mHighUsageAppList.subList(0,
- Math.min(mPolicy.highUsageAppCount, mHighUsageAppList.size()));
- Collections.sort(mHighUsageAppList, Collections.reverseOrder());
+ mHighUsageAppList = mHighUsageAppList.subList(0,
+ Math.min(mPolicy.highUsageAppCount, mHighUsageAppList.size()));
+ Collections.sort(mHighUsageAppList, Collections.reverseOrder());
+ }
}
return new HighUsageTip(screenUsageTimeMs, mHighUsageAppList);
}
+
+ @VisibleForTesting
+ void parseBatteryData() {
+ BatteryInfo.parse(mBatteryStatsHelper.getStats(), mDataParser);
+ }
}
diff --git a/src/com/android/settings/search/SearchFeatureProvider.java b/src/com/android/settings/search/SearchFeatureProvider.java
index 878bbfd..cbe49f8 100644
--- a/src/com/android/settings/search/SearchFeatureProvider.java
+++ b/src/com/android/settings/search/SearchFeatureProvider.java
@@ -48,6 +48,11 @@
DatabaseIndexingManager getIndexingManager(Context context);
+ /**
+ * @return a {@link SearchIndexableResources} to be used for indexing search results.
+ */
+ SearchIndexableResources getSearchIndexableResources();
+
default String getSettingsIntelligencePkgName() {
return "com.android.settings.intelligence";
}
diff --git a/src/com/android/settings/search/SearchFeatureProviderImpl.java b/src/com/android/settings/search/SearchFeatureProviderImpl.java
index ccd4ff1..78c47ed 100644
--- a/src/com/android/settings/search/SearchFeatureProviderImpl.java
+++ b/src/com/android/settings/search/SearchFeatureProviderImpl.java
@@ -36,6 +36,7 @@
private static final String METRICS_ACTION_SETTINGS_INDEX = "search_synchronous_indexing";
private DatabaseIndexingManager mDatabaseIndexingManager;
+ private SearchIndexableResources mSearchIndexableResources;
@Override
public void verifyLaunchSearchResultPageCaller(Context context, ComponentName caller) {
@@ -72,6 +73,14 @@
.histogram(context, METRICS_ACTION_SETTINGS_INDEX, indexingTime);
}
+ @Override
+ public SearchIndexableResources getSearchIndexableResources() {
+ if (mSearchIndexableResources == null) {
+ mSearchIndexableResources = new SearchIndexableResourcesImpl();
+ }
+ return mSearchIndexableResources;
+ }
+
protected boolean isSignatureWhitelisted(Context context, String callerPackage) {
return false;
}
diff --git a/src/com/android/settings/search/SearchIndexableResources.java b/src/com/android/settings/search/SearchIndexableResources.java
index b0159cf..5a0a131 100644
--- a/src/com/android/settings/search/SearchIndexableResources.java
+++ b/src/com/android/settings/search/SearchIndexableResources.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014 The Android Open Source Project
+ * 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.
@@ -16,170 +16,14 @@
package com.android.settings.search;
-import android.support.annotation.VisibleForTesting;
-
-import com.android.settings.DateTimeSettings;
-import com.android.settings.DisplaySettings;
-import com.android.settings.LegalSettings;
-import com.android.settings.accessibility.AccessibilitySettings;
-import com.android.settings.accessibility.AccessibilityShortcutPreferenceFragment;
-import com.android.settings.accessibility.MagnificationPreferenceFragment;
-import com.android.settings.accounts.UserAndAccountDashboardFragment;
-import com.android.settings.applications.AppAndNotificationDashboardFragment;
-import com.android.settings.applications.DefaultAppSettings;
-import com.android.settings.applications.SpecialAccessSettings;
-import com.android.settings.applications.assist.ManageAssist;
-import com.android.settings.backup.BackupSettingsActivity;
-import com.android.settings.backup.BackupSettingsFragment;
-import com.android.settings.bluetooth.BluetoothSettings;
-import com.android.settings.connecteddevice.AdvancedConnectedDeviceDashboardFragment;
-import com.android.settings.connecteddevice.ConnectedDeviceDashboardFragment;
-import com.android.settings.connecteddevice.ConnectedDeviceDashboardFragmentOld;
-import com.android.settings.datausage.DataUsageSummary;
-import com.android.settings.deletionhelper.AutomaticStorageManagerSettings;
-import com.android.settings.development.DevelopmentSettingsDashboardFragment;
-import com.android.settings.deviceinfo.DeviceInfoSettings;
-import com.android.settings.deviceinfo.StorageDashboardFragment;
-import com.android.settings.deviceinfo.StorageSettings;
-import com.android.settings.display.AmbientDisplaySettings;
-import com.android.settings.display.NightDisplaySettings;
-import com.android.settings.display.ScreenZoomSettings;
-import com.android.settings.dream.DreamSettings;
-import com.android.settings.enterprise.EnterprisePrivacySettings;
-import com.android.settings.fuelgauge.BatterySaverSettings;
-import com.android.settings.fuelgauge.PowerUsageAdvanced;
-import com.android.settings.fuelgauge.PowerUsageSummary;
-import com.android.settings.fuelgauge.SmartBatterySettings;
-import com.android.settings.gestures.AssistGestureSettings;
-import com.android.settings.gestures.DoubleTapPowerSettings;
-import com.android.settings.gestures.DoubleTapScreenSettings;
-import com.android.settings.gestures.DoubleTwistGestureSettings;
-import com.android.settings.gestures.GestureSettings;
-import com.android.settings.gestures.PickupGestureSettings;
-import com.android.settings.gestures.SwipeToNotificationSettings;
-import com.android.settings.inputmethod.AvailableVirtualKeyboardFragment;
-import com.android.settings.inputmethod.PhysicalKeyboardFragment;
-import com.android.settings.inputmethod.VirtualKeyboardFragment;
-import com.android.settings.language.LanguageAndInputSettings;
-import com.android.settings.location.LocationMode;
-import com.android.settings.location.LocationSettings;
-import com.android.settings.location.ScanningSettings;
-import com.android.settings.network.NetworkDashboardFragment;
-import com.android.settings.nfc.PaymentSettings;
-import com.android.settings.notification.ConfigureNotificationSettings;
-import com.android.settings.notification.SoundSettings;
-import com.android.settings.notification.ZenModeAutomationSettings;
-import com.android.settings.notification.ZenModeBehaviorSettings;
-import com.android.settings.notification.ZenModeSettings;
-import com.android.settings.print.PrintSettingsFragment;
-import com.android.settings.security.EncryptionAndCredential;
-import com.android.settings.security.LockscreenDashboardFragment;
-import com.android.settings.security.ScreenPinningSettings;
-import com.android.settings.security.SecuritySettingsV2;
-import com.android.settings.security.screenlock.ScreenLockSettings;
-import com.android.settings.sim.SimSettings;
-import com.android.settings.support.SupportDashboardActivity;
-import com.android.settings.system.ResetDashboardFragment;
-import com.android.settings.system.SystemDashboardFragment;
-import com.android.settings.tts.TextToSpeechSettings;
-import com.android.settings.tts.TtsEnginePreferenceFragment;
-import com.android.settings.users.UserSettings;
-import com.android.settings.wallpaper.WallpaperTypeSettings;
-import com.android.settings.wfd.WifiDisplaySettings;
-import com.android.settings.wifi.ConfigureWifiSettings;
-import com.android.settings.wifi.WifiSettings;
-
import java.util.Collection;
-import java.util.HashSet;
-import java.util.Set;
-public final class SearchIndexableResources {
+public interface SearchIndexableResources {
- @VisibleForTesting
- static final Set<Class> sProviders = new HashSet<>();
-
- @VisibleForTesting
- static void addIndex(Class indexClass) {
- sProviders.add(indexClass);
- }
-
- static {
- addIndex(WifiSettings.class);
- addIndex(NetworkDashboardFragment.class);
- addIndex(ConfigureWifiSettings.class);
- addIndex(BluetoothSettings.class);
- addIndex(SimSettings.class);
- addIndex(DataUsageSummary.class);
- addIndex(ScreenZoomSettings.class);
- addIndex(DisplaySettings.class);
- addIndex(AmbientDisplaySettings.class);
- addIndex(WallpaperTypeSettings.class);
- addIndex(AppAndNotificationDashboardFragment.class);
- addIndex(SoundSettings.class);
- addIndex(ZenModeSettings.class);
- addIndex(StorageSettings.class);
- addIndex(PowerUsageAdvanced.class);
- addIndex(DefaultAppSettings.class);
- addIndex(ManageAssist.class);
- addIndex(SpecialAccessSettings.class);
- addIndex(UserSettings.class);
- addIndex(AssistGestureSettings.class);
- addIndex(PickupGestureSettings.class);
- addIndex(DoubleTapScreenSettings.class);
- addIndex(DoubleTapPowerSettings.class);
- addIndex(DoubleTwistGestureSettings.class);
- addIndex(SwipeToNotificationSettings.class);
- addIndex(GestureSettings.class);
- addIndex(LanguageAndInputSettings.class);
- addIndex(LocationSettings.class);
- addIndex(LocationMode.class);
- addIndex(ScanningSettings.class);
- addIndex(SecuritySettingsV2.class);
- addIndex(ScreenLockSettings.class);
- addIndex(EncryptionAndCredential.class);
- addIndex(ScreenPinningSettings.class);
- addIndex(UserAndAccountDashboardFragment.class);
- addIndex(VirtualKeyboardFragment.class);
- addIndex(AvailableVirtualKeyboardFragment.class);
- addIndex(PhysicalKeyboardFragment.class);
- addIndex(BackupSettingsActivity.class);
- addIndex(BackupSettingsFragment.class);
- addIndex(DateTimeSettings.class);
- addIndex(AccessibilitySettings.class);
- addIndex(PrintSettingsFragment.class);
- addIndex(DevelopmentSettingsDashboardFragment.class);
- addIndex(DeviceInfoSettings.class);
- addIndex(LegalSettings.class);
- addIndex(SystemDashboardFragment.class);
- addIndex(ResetDashboardFragment.class);
- addIndex(StorageDashboardFragment.class);
- addIndex(ConnectedDeviceDashboardFragment.class);
- addIndex(ConnectedDeviceDashboardFragmentOld.class);
- addIndex(AdvancedConnectedDeviceDashboardFragment.class);
- addIndex(EnterprisePrivacySettings.class);
- addIndex(PaymentSettings.class);
- addIndex(TextToSpeechSettings.class);
- addIndex(TtsEnginePreferenceFragment.class);
- addIndex(MagnificationPreferenceFragment.class);
- addIndex(AccessibilityShortcutPreferenceFragment.class);
- addIndex(DreamSettings.class);
- addIndex(SupportDashboardActivity.class);
- addIndex(AutomaticStorageManagerSettings.class);
- addIndex(ConfigureNotificationSettings.class);
- addIndex(PowerUsageSummary.class);
- addIndex(BatterySaverSettings.class);
- addIndex(LockscreenDashboardFragment.class);
- addIndex(WifiDisplaySettings.class);
- addIndex(ZenModeBehaviorSettings.class);
- addIndex(ZenModeAutomationSettings.class);
- addIndex(NightDisplaySettings.class);
- addIndex(SmartBatterySettings.class);
- }
-
- private SearchIndexableResources() {
- }
-
- public static Collection<Class> providerValues() {
- return sProviders;
- }
-}
\ No newline at end of file
+ /**
+ * Returns a collection of classes that should be indexed for search.
+ *
+ * Each class should have the SEARCH_INDEX_DATA_PROVIDER public static member.
+ */
+ Collection<Class> getProviderValues();
+}
diff --git a/src/com/android/settings/search/SearchIndexableResourcesImpl.java b/src/com/android/settings/search/SearchIndexableResourcesImpl.java
new file mode 100644
index 0000000..2c20703
--- /dev/null
+++ b/src/com/android/settings/search/SearchIndexableResourcesImpl.java
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2014 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.search;
+
+import android.support.annotation.VisibleForTesting;
+
+import com.android.settings.DateTimeSettings;
+import com.android.settings.DisplaySettings;
+import com.android.settings.LegalSettings;
+import com.android.settings.accessibility.AccessibilitySettings;
+import com.android.settings.accessibility.AccessibilityShortcutPreferenceFragment;
+import com.android.settings.accessibility.MagnificationPreferenceFragment;
+import com.android.settings.accounts.UserAndAccountDashboardFragment;
+import com.android.settings.applications.AppAndNotificationDashboardFragment;
+import com.android.settings.applications.DefaultAppSettings;
+import com.android.settings.applications.SpecialAccessSettings;
+import com.android.settings.applications.assist.ManageAssist;
+import com.android.settings.backup.BackupSettingsActivity;
+import com.android.settings.backup.BackupSettingsFragment;
+import com.android.settings.bluetooth.BluetoothSettings;
+import com.android.settings.connecteddevice.AdvancedConnectedDeviceDashboardFragment;
+import com.android.settings.connecteddevice.ConnectedDeviceDashboardFragment;
+import com.android.settings.connecteddevice.ConnectedDeviceDashboardFragmentOld;
+import com.android.settings.datausage.DataUsageSummary;
+import com.android.settings.deletionhelper.AutomaticStorageManagerSettings;
+import com.android.settings.development.DevelopmentSettingsDashboardFragment;
+import com.android.settings.deviceinfo.DeviceInfoSettings;
+import com.android.settings.deviceinfo.StorageDashboardFragment;
+import com.android.settings.deviceinfo.StorageSettings;
+import com.android.settings.display.AmbientDisplaySettings;
+import com.android.settings.display.NightDisplaySettings;
+import com.android.settings.display.ScreenZoomSettings;
+import com.android.settings.dream.DreamSettings;
+import com.android.settings.enterprise.EnterprisePrivacySettings;
+import com.android.settings.fuelgauge.BatterySaverSettings;
+import com.android.settings.fuelgauge.PowerUsageAdvanced;
+import com.android.settings.fuelgauge.PowerUsageSummary;
+import com.android.settings.fuelgauge.SmartBatterySettings;
+import com.android.settings.gestures.AssistGestureSettings;
+import com.android.settings.gestures.DoubleTapPowerSettings;
+import com.android.settings.gestures.DoubleTapScreenSettings;
+import com.android.settings.gestures.DoubleTwistGestureSettings;
+import com.android.settings.gestures.GestureSettings;
+import com.android.settings.gestures.PickupGestureSettings;
+import com.android.settings.gestures.SwipeToNotificationSettings;
+import com.android.settings.inputmethod.AvailableVirtualKeyboardFragment;
+import com.android.settings.inputmethod.PhysicalKeyboardFragment;
+import com.android.settings.inputmethod.VirtualKeyboardFragment;
+import com.android.settings.language.LanguageAndInputSettings;
+import com.android.settings.location.LocationMode;
+import com.android.settings.location.LocationSettings;
+import com.android.settings.location.ScanningSettings;
+import com.android.settings.network.NetworkDashboardFragment;
+import com.android.settings.nfc.PaymentSettings;
+import com.android.settings.notification.ConfigureNotificationSettings;
+import com.android.settings.notification.SoundSettings;
+import com.android.settings.notification.ZenModeAutomationSettings;
+import com.android.settings.notification.ZenModeBehaviorSettings;
+import com.android.settings.notification.ZenModeSettings;
+import com.android.settings.print.PrintSettingsFragment;
+import com.android.settings.security.EncryptionAndCredential;
+import com.android.settings.security.LockscreenDashboardFragment;
+import com.android.settings.security.ScreenPinningSettings;
+import com.android.settings.security.SecuritySettingsV2;
+import com.android.settings.security.screenlock.ScreenLockSettings;
+import com.android.settings.sim.SimSettings;
+import com.android.settings.support.SupportDashboardActivity;
+import com.android.settings.system.ResetDashboardFragment;
+import com.android.settings.system.SystemDashboardFragment;
+import com.android.settings.tts.TextToSpeechSettings;
+import com.android.settings.tts.TtsEnginePreferenceFragment;
+import com.android.settings.users.UserSettings;
+import com.android.settings.wallpaper.WallpaperTypeSettings;
+import com.android.settings.wfd.WifiDisplaySettings;
+import com.android.settings.wifi.ConfigureWifiSettings;
+import com.android.settings.wifi.WifiSettings;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+public class SearchIndexableResourcesImpl implements SearchIndexableResources {
+
+ private final Set<Class> sProviders = new HashSet<>();
+
+ @VisibleForTesting
+ void addIndex(Class indexClass) {
+ sProviders.add(indexClass);
+ }
+
+ public SearchIndexableResourcesImpl() {
+ addIndex(WifiSettings.class);
+ addIndex(NetworkDashboardFragment.class);
+ addIndex(ConfigureWifiSettings.class);
+ addIndex(BluetoothSettings.class);
+ addIndex(SimSettings.class);
+ addIndex(DataUsageSummary.class);
+ addIndex(ScreenZoomSettings.class);
+ addIndex(DisplaySettings.class);
+ addIndex(AmbientDisplaySettings.class);
+ addIndex(WallpaperTypeSettings.class);
+ addIndex(AppAndNotificationDashboardFragment.class);
+ addIndex(SoundSettings.class);
+ addIndex(ZenModeSettings.class);
+ addIndex(StorageSettings.class);
+ addIndex(PowerUsageAdvanced.class);
+ addIndex(DefaultAppSettings.class);
+ addIndex(ManageAssist.class);
+ addIndex(SpecialAccessSettings.class);
+ addIndex(UserSettings.class);
+ addIndex(AssistGestureSettings.class);
+ addIndex(PickupGestureSettings.class);
+ addIndex(DoubleTapScreenSettings.class);
+ addIndex(DoubleTapPowerSettings.class);
+ addIndex(DoubleTwistGestureSettings.class);
+ addIndex(SwipeToNotificationSettings.class);
+ addIndex(GestureSettings.class);
+ addIndex(LanguageAndInputSettings.class);
+ addIndex(LocationSettings.class);
+ addIndex(LocationMode.class);
+ addIndex(ScanningSettings.class);
+ addIndex(SecuritySettingsV2.class);
+ addIndex(ScreenLockSettings.class);
+ addIndex(EncryptionAndCredential.class);
+ addIndex(ScreenPinningSettings.class);
+ addIndex(UserAndAccountDashboardFragment.class);
+ addIndex(VirtualKeyboardFragment.class);
+ addIndex(AvailableVirtualKeyboardFragment.class);
+ addIndex(PhysicalKeyboardFragment.class);
+ addIndex(BackupSettingsActivity.class);
+ addIndex(BackupSettingsFragment.class);
+ addIndex(DateTimeSettings.class);
+ addIndex(AccessibilitySettings.class);
+ addIndex(PrintSettingsFragment.class);
+ addIndex(DevelopmentSettingsDashboardFragment.class);
+ addIndex(DeviceInfoSettings.class);
+ addIndex(LegalSettings.class);
+ addIndex(SystemDashboardFragment.class);
+ addIndex(ResetDashboardFragment.class);
+ addIndex(StorageDashboardFragment.class);
+ addIndex(ConnectedDeviceDashboardFragment.class);
+ addIndex(ConnectedDeviceDashboardFragmentOld.class);
+ addIndex(AdvancedConnectedDeviceDashboardFragment.class);
+ addIndex(EnterprisePrivacySettings.class);
+ addIndex(PaymentSettings.class);
+ addIndex(TextToSpeechSettings.class);
+ addIndex(TtsEnginePreferenceFragment.class);
+ addIndex(MagnificationPreferenceFragment.class);
+ addIndex(AccessibilityShortcutPreferenceFragment.class);
+ addIndex(DreamSettings.class);
+ addIndex(SupportDashboardActivity.class);
+ addIndex(AutomaticStorageManagerSettings.class);
+ addIndex(ConfigureNotificationSettings.class);
+ addIndex(PowerUsageSummary.class);
+ addIndex(BatterySaverSettings.class);
+ addIndex(LockscreenDashboardFragment.class);
+ addIndex(WifiDisplaySettings.class);
+ addIndex(ZenModeBehaviorSettings.class);
+ addIndex(ZenModeAutomationSettings.class);
+ addIndex(NightDisplaySettings.class);
+ addIndex(SmartBatterySettings.class);
+ }
+
+ @Override
+ public Collection<Class> getProviderValues() {
+ return sProviders;
+ }
+}
diff --git a/src/com/android/settings/search/SettingsSearchIndexablesProvider.java b/src/com/android/settings/search/SettingsSearchIndexablesProvider.java
index 0c98b9c..3ef1b85 100644
--- a/src/com/android/settings/search/SettingsSearchIndexablesProvider.java
+++ b/src/com/android/settings/search/SettingsSearchIndexablesProvider.java
@@ -175,7 +175,8 @@
}
private List<String> getNonIndexableKeysFromProvider(Context context) {
- final Collection<Class> values = SearchIndexableResources.providerValues();
+ final Collection<Class> values = FeatureFactory.getFactory(context)
+ .getSearchFeatureProvider().getSearchIndexableResources().getProviderValues();
final List<String> nonIndexableKeys = new ArrayList<>();
for (Class<?> clazz : values) {
@@ -209,7 +210,8 @@
}
private List<SearchIndexableResource> getSearchIndexableResourcesFromProvider(Context context) {
- Collection<Class> values = SearchIndexableResources.providerValues();
+ Collection<Class> values = FeatureFactory.getFactory(context)
+ .getSearchFeatureProvider().getSearchIndexableResources().getProviderValues();
List<SearchIndexableResource> resourceList = new ArrayList<>();
for (Class<?> clazz : values) {
@@ -236,7 +238,8 @@
}
private List<SearchIndexableRaw> getSearchIndexableRawFromProvider(Context context) {
- final Collection<Class> values = SearchIndexableResources.providerValues();
+ final Collection<Class> values = FeatureFactory.getFactory(context)
+ .getSearchFeatureProvider().getSearchIndexableResources().getProviderValues();
final List<SearchIndexableRaw> rawList = new ArrayList<>();
for (Class<?> clazz : values) {
diff --git a/src/com/android/settings/slices/SliceDataConverter.java b/src/com/android/settings/slices/SliceDataConverter.java
index c10753f..e5a21e4 100644
--- a/src/com/android/settings/slices/SliceDataConverter.java
+++ b/src/com/android/settings/slices/SliceDataConverter.java
@@ -27,9 +27,9 @@
import android.util.Xml;
import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.overlay.FeatureFactory;
import com.android.settings.search.DatabaseIndexingUtils;
import com.android.settings.search.Indexable.SearchIndexProvider;
-import com.android.settings.search.SearchIndexableResources;
import com.android.settings.search.XmlParserUtils;
import org.xmlpull.v1.XmlPullParser;
@@ -62,7 +62,8 @@
* @return a list of {@link SliceData} to be indexed and later referenced as a Slice.
*
* The collection works as follows:
- * - Collects a list of Fragments from {@link SearchIndexableResources}.
+ * - Collects a list of Fragments from
+ * {@link FeatureFactory#getSearchFeatureProvider()}.
* - From each fragment, grab a {@link SearchIndexProvider}.
* - For each provider, collect XML resource layout and a list of
* {@link com.android.settings.core.BasePreferenceController}.
@@ -72,7 +73,8 @@
return mSliceData;
}
- final Collection<Class> indexableClasses = SearchIndexableResources.providerValues();
+ final Collection<Class> indexableClasses = FeatureFactory.getFactory(mContext)
+ .getSearchFeatureProvider().getSearchIndexableResources().getProviderValues();
for (Class clazz : indexableClasses) {
final String fragmentName = clazz.getName();
diff --git a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
index 13ffd5b..4d9ad27 100644
--- a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
+++ b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
@@ -280,7 +280,7 @@
.setButton1Text(R.string.forget)
.setButton1Positive(false)
.setButton1OnClickListener(view -> forgetNetwork())
- .setButton2Text(R.string.support_sign_in_button_text)
+ .setButton2Text(R.string.wifi_sign_in_button_text)
.setButton2Positive(true)
.setButton2OnClickListener(view -> signIntoNetwork());
diff --git a/src/com/android/settings/HotspotOffReceiver.java b/src/com/android/settings/wifi/tether/HotspotOffReceiver.java
similarity index 97%
rename from src/com/android/settings/HotspotOffReceiver.java
rename to src/com/android/settings/wifi/tether/HotspotOffReceiver.java
index 4083082..fcbf888 100644
--- a/src/com/android/settings/HotspotOffReceiver.java
+++ b/src/com/android/settings/wifi/tether/HotspotOffReceiver.java
@@ -1,5 +1,5 @@
-package com.android.settings;
+package com.android.settings.wifi.tether;
import android.content.BroadcastReceiver;
import android.content.Context;
diff --git a/src/com/android/settings/TetherService.java b/src/com/android/settings/wifi/tether/TetherService.java
similarity index 98%
rename from src/com/android/settings/TetherService.java
rename to src/com/android/settings/wifi/tether/TetherService.java
index fce3f27..e491de8 100644
--- a/src/com/android/settings/TetherService.java
+++ b/src/com/android/settings/wifi/tether/TetherService.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.settings;
+package com.android.settings.wifi.tether;
import android.app.Activity;
import android.app.AlarmManager;
@@ -167,11 +167,16 @@
SharedPreferences prefs = getSharedPreferences(PREFS, MODE_PRIVATE);
prefs.edit().putString(KEY_TETHERS, tethersToString(mCurrentTethers)).commit();
+ unregisterReceivers();
if (DEBUG) Log.d(TAG, "Destroying TetherService");
- unregisterReceiver(mReceiver);
super.onDestroy();
}
+ private void unregisterReceivers() {
+ unregisterReceiver(mReceiver);
+ mHotspotReceiver.unregister();
+ }
+
private void removeTypeAtIndex(int index) {
mCurrentTethers.remove(index);
// If we are currently in the middle of a check, we may need to adjust the
diff --git a/src/com/android/settings/wrapper/RecoverySystemWrapper.java b/src/com/android/settings/wrapper/RecoverySystemWrapper.java
new file mode 100644
index 0000000..8a36969
--- /dev/null
+++ b/src/com/android/settings/wrapper/RecoverySystemWrapper.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.wrapper;
+
+import android.content.Context;
+import android.os.RecoverySystem;
+
+/**
+ * This class replicates a subset of the {@link RecoverySystem}.
+ * The interface exists so that we can use a thin wrapper around the RecoverySystem in
+ * production code and a mock in tests.
+ */
+public class RecoverySystemWrapper {
+
+ /**
+ * Returns whether wipe Euicc data successfully or not.
+ *
+ * @param isWipeEuicc whether we want to wipe Euicc data or not
+ * @param packageName the package name of the caller app.
+ */
+ public boolean wipeEuiccData(
+ Context context, final boolean isWipeEuicc, final String packageName) {
+ return RecoverySystem.wipeEuiccData(context, isWipeEuicc, packageName);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/MasterClearTest.java b/tests/robotests/src/com/android/settings/MasterClearTest.java
index 361bc8f..26cfc3a 100644
--- a/tests/robotests/src/com/android/settings/MasterClearTest.java
+++ b/tests/robotests/src/com/android/settings/MasterClearTest.java
@@ -19,16 +19,24 @@
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import static org.robolectric.Shadows.shadowOf;
+import android.accounts.Account;
+import android.accounts.AccountManager;
import android.app.Activity;
import android.app.Fragment;
import android.content.ComponentName;
import android.content.ContentResolver;
+import android.content.Context;
import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.provider.Settings;
import android.view.LayoutInflater;
@@ -46,6 +54,7 @@
import org.mockito.MockitoAnnotations;
import org.robolectric.Robolectric;
import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowAccountManager;
import org.robolectric.shadows.ShadowActivity;
@RunWith(SettingsRobolectricTestRunner.class)
@@ -55,6 +64,9 @@
shadows = {ShadowUtils.class}
)
public class MasterClearTest {
+ private static final String TEST_ACCOUNT_TYPE = "android.test.account.type";
+ private static final String TEST_CONFIRMATION_PACKAGE = "android.test.confirmation.pkg";
+ private static final String TEST_ACCOUNT_NAME = "test@example.com";
@Mock
private MasterClear mMasterClear;
@@ -62,7 +74,18 @@
private ScrollView mScrollView;
@Mock
private LinearLayout mLinearLayout;
+
+ @Mock
+ private PackageManager mPackageManager;
+
+ @Mock
+ private AccountManager mAccountManager;
+
+ @Mock
+ private Activity mMockActivity;
+
private ShadowActivity mShadowActivity;
+ private ShadowAccountManager mShadowAccountManager;
private Activity mActivity;
private View mContentView;
@@ -86,6 +109,7 @@
mMasterClear = spy(new MasterClear());
mActivity = Robolectric.setupActivity(Activity.class);
mShadowActivity = shadowOf(mActivity);
+ // mShadowAccountManager = shadowOf(AccountManager.get(mActivity));
mContentView = LayoutInflater.from(mActivity).inflate(R.layout.master_clear, null);
// Make scrollView only have one child
@@ -162,9 +186,61 @@
@Test
public void testTryShowAccountConfirmation_unsupported() {
- doReturn(mActivity).when(mMasterClear).getActivity();
- /* Using the default resources, account confirmation shouldn't trigger */
- assertThat(mMasterClear.tryShowAccountConfirmation()).isFalse();
+ when(mMasterClear.getActivity()).thenReturn(mActivity);
+ /* Using the default resources, account confirmation shouldn't trigger */
+ assertThat(mMasterClear.tryShowAccountConfirmation()).isFalse();
+ }
+
+ @Test
+ public void testTryShowAccountConfirmation_no_relevant_accounts() {
+ when(mMasterClear.getActivity()).thenReturn(mMockActivity);
+ when(mMockActivity.getString(R.string.account_type)).thenReturn(TEST_ACCOUNT_TYPE);
+ when(mMockActivity.getString(R.string.account_confirmation_package)).thenReturn(TEST_CONFIRMATION_PACKAGE);
+
+ Account[] accounts = new Account[0];
+ when(mMockActivity.getSystemService(Context.ACCOUNT_SERVICE)).thenReturn(mAccountManager);
+ when(mAccountManager.getAccountsByType(TEST_ACCOUNT_TYPE)).thenReturn(accounts);
+ assertThat(mMasterClear.tryShowAccountConfirmation()).isFalse();
+ }
+
+ @Test
+ public void testTryShowAccountConfirmation_unresolved() {
+ when(mMasterClear.getActivity()).thenReturn(mMockActivity);
+ when(mMockActivity.getString(R.string.account_type)).thenReturn(TEST_ACCOUNT_TYPE);
+ when(mMockActivity.getString(R.string.account_confirmation_package)).thenReturn(TEST_CONFIRMATION_PACKAGE);
+ Account[] accounts = new Account[] { new Account(TEST_ACCOUNT_NAME, TEST_ACCOUNT_TYPE) };
+ when(mMockActivity.getSystemService(Context.ACCOUNT_SERVICE)).thenReturn(mAccountManager);
+ when(mAccountManager.getAccountsByType(TEST_ACCOUNT_TYPE)).thenReturn(accounts);
+ // The package manager should not resolve the confirmation intent targeting the non-existent
+ // confirmation package.
+ when(mMockActivity.getPackageManager()).thenReturn(mPackageManager);
+ assertThat(mMasterClear.tryShowAccountConfirmation()).isFalse();
+ }
+
+ @Test
+ public void testTryShowAccountConfirmation_ok() {
+ when(mMasterClear.getActivity()).thenReturn(mMockActivity);
+ // Only try to show account confirmation if the appropriate resource overlays are available.
+ when(mMockActivity.getString(R.string.account_type)).thenReturn(TEST_ACCOUNT_TYPE);
+ when(mMockActivity.getString(R.string.account_confirmation_package)).thenReturn(TEST_CONFIRMATION_PACKAGE);
+ // Add accounts to trigger the search for a resolving intent.
+ Account[] accounts = new Account[] { new Account(TEST_ACCOUNT_NAME, TEST_ACCOUNT_TYPE) };
+ when(mMockActivity.getSystemService(Context.ACCOUNT_SERVICE)).thenReturn(mAccountManager);
+ when(mAccountManager.getAccountsByType(TEST_ACCOUNT_TYPE)).thenReturn(accounts);
+ // The package manager should not resolve the confirmation intent targeting the non-existent
+ // confirmation package.
+ when(mMockActivity.getPackageManager()).thenReturn(mPackageManager);
+
+ ActivityInfo activityInfo = new ActivityInfo();
+ activityInfo.packageName = TEST_CONFIRMATION_PACKAGE;
+ ResolveInfo resolveInfo = new ResolveInfo();
+ resolveInfo.activityInfo = activityInfo;
+ when(mPackageManager.resolveActivity(any(), eq(0))).thenReturn(resolveInfo);
+
+ // Finally mock out the startActivityForResultCall
+ doNothing().when(mMockActivity).startActivityForResult(any(), eq(MasterClear.CREDENTIAL_CONFIRM_REQUEST));
+
+ assertThat(mMasterClear.tryShowAccountConfirmation()).isTrue();
}
private void initScrollView(int height, int scrollY, int childBottom) {
diff --git a/tests/robotests/src/com/android/settings/ResetNetworkConfirmTest.java b/tests/robotests/src/com/android/settings/ResetNetworkConfirmTest.java
new file mode 100644
index 0000000..354cacf
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/ResetNetworkConfirmTest.java
@@ -0,0 +1,93 @@
+/*
+ * 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;
+
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyBoolean;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+import android.app.Activity;
+import android.content.Context;
+
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.wrapper.RecoverySystemWrapper;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.Robolectric;
+import org.robolectric.annotation.Config;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(
+ manifest = TestConfig.MANIFEST_PATH,
+ sdk = TestConfig.SDK_VERSION
+)
+public class ResetNetworkConfirmTest {
+
+ private Activity mActivity;
+ @Mock
+ private ResetNetworkConfirm mResetNetworkConfirm;
+ @Mock
+ private RecoverySystemWrapper mRecoverySystem;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mResetNetworkConfirm = spy(new ResetNetworkConfirm());
+ mRecoverySystem = spy(new RecoverySystemWrapper());
+ ResetNetworkConfirm.mRecoverySystem = mRecoverySystem;
+ mActivity = Robolectric.setupActivity(Activity.class);
+ }
+
+ @Test
+ public void testResetNetworkData_resetEsim() {
+ mResetNetworkConfirm.mEraseEsim = true;
+ doReturn(true)
+ .when(mRecoverySystem).wipeEuiccData(any(Context.class), anyBoolean(), anyString());
+
+ mResetNetworkConfirm.esimFactoryReset(mActivity, "" /* packageName */);
+ try {
+ // Waiting the Async task finished
+ Thread.sleep(10000); // 10 sec
+ } catch (InterruptedException ignore) {
+
+ }
+
+ Assert.assertNotNull(mResetNetworkConfirm.mEraseEsimTask);
+ verify(mRecoverySystem).wipeEuiccData(any(Context.class), anyBoolean(), anyString());
+ }
+
+ @Test
+ public void testResetNetworkData_notResetEsim() {
+ mResetNetworkConfirm.mEraseEsim = false;
+
+ mResetNetworkConfirm.esimFactoryReset(mActivity, "" /* packageName */);
+
+ Assert.assertNull(mResetNetworkConfirm.mEraseEsimTask);
+ verify(mRecoverySystem, never())
+ .wipeEuiccData(any(Context.class), anyBoolean(), anyString());
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/core/XmlControllerAttributeTest.java b/tests/robotests/src/com/android/settings/core/XmlControllerAttributeTest.java
index c561d0d..8ded9d6 100644
--- a/tests/robotests/src/com/android/settings/core/XmlControllerAttributeTest.java
+++ b/tests/robotests/src/com/android/settings/core/XmlControllerAttributeTest.java
@@ -2,6 +2,8 @@
import static com.google.common.truth.Truth.assertWithMessage;
+import static org.mockito.Mockito.mock;
+
import android.content.Context;
import android.content.res.XmlResourceParser;
import android.provider.SearchIndexableResource;
@@ -13,10 +15,12 @@
import com.android.settings.TestConfig;
import com.android.settings.search.DatabaseIndexingUtils;
import com.android.settings.search.Indexable;
-import com.android.settings.search.SearchIndexableResources;
+import com.android.settings.search.SearchFeatureProvider;
+import com.android.settings.search.SearchFeatureProviderImpl;
import com.android.settings.search.XmlParserUtils;
import com.android.settings.security.SecuritySettings;
import com.android.settings.security.SecuritySettingsV2;
+import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import org.junit.After;
@@ -82,19 +86,21 @@
+ "IllegalAccessException. Please fix the following classes:\n";
Context mContext;
-
- private Set<Class> mProviderClassesCopy;
+ SearchFeatureProvider mSearchProvider;
+ private FakeFeatureFactory mFakeFeatureFactory;
@Before
public void setUp() {
mContext = RuntimeEnvironment.application;
- mProviderClassesCopy = new HashSet<>(SearchIndexableResources.providerValues());
+ mSearchProvider = new SearchFeatureProviderImpl();
+ mFakeFeatureFactory = FakeFeatureFactory.setupForTest();
+ mFakeFeatureFactory.searchFeatureProvider = mSearchProvider;
}
@After
public void cleanUp() {
- SearchIndexableResources.providerValues().clear();
- SearchIndexableResources.providerValues().addAll(mProviderClassesCopy);
+ mFakeFeatureFactory.searchFeatureProvider = mock(
+ SearchFeatureProvider.class);
}
@Test
@@ -156,7 +162,8 @@
private Set<Integer> getIndexableXml() {
Set<Integer> xmlResSet = new HashSet();
- Collection<Class> indexableClasses = SearchIndexableResources.providerValues();
+ Collection<Class> indexableClasses =
+ mSearchProvider.getSearchIndexableResources().getProviderValues();
indexableClasses.removeAll(illegalClasses);
for (Class clazz : indexableClasses) {
diff --git a/tests/robotests/src/com/android/settings/display/TimeoutPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/TimeoutPreferenceControllerTest.java
index 33bc4f8..d4af8b8 100644
--- a/tests/robotests/src/com/android/settings/display/TimeoutPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/display/TimeoutPreferenceControllerTest.java
@@ -20,8 +20,12 @@
import static com.google.common.truth.Truth.assertThat;
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertTrue;
+
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -34,16 +38,20 @@
import com.android.settings.TimeoutListPreference;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.ShadowDevicePolicyManagerWrapper;
+import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
+import java.util.ArrayList;
import java.util.Collections;
+import java.util.List;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION,
@@ -93,4 +101,34 @@
mController.updateState(mPreference);
verify(mPreference).removeUnusableTimeouts(timeout, null);
}
+
+ @Test
+ public void testUpdateStateWithAdminTimeoutsAndRestriction() {
+ final int profileUserId = UserHandle.myUserId();
+ final long timeout = 100;
+ when(mUserManager.getProfiles(profileUserId)).thenReturn(Collections.emptyList());
+ ShadowDevicePolicyManagerWrapper.setMaximumTimeToLock(profileUserId, timeout);
+
+ int userId = UserHandle.myUserId();
+ List<UserManager.EnforcingUser> enforcingUsers = new ArrayList<>();
+ // Add two enforcing users so that RestrictedLockUtils.checkIfRestrictionEnforced returns
+ // non-null.
+ enforcingUsers.add(new UserManager.EnforcingUser(userId,
+ UserManager.RESTRICTION_SOURCE_DEVICE_OWNER));
+ enforcingUsers.add(new UserManager.EnforcingUser(userId,
+ UserManager.RESTRICTION_SOURCE_PROFILE_OWNER));
+ when(mUserManager.getUserRestrictionSources(
+ UserManager.DISALLOW_CONFIG_SCREEN_TIMEOUT, UserHandle.of(userId)))
+ .thenReturn(enforcingUsers);
+
+ mController.updateState(mPreference);
+
+ ArgumentCaptor<Long> longCaptor = ArgumentCaptor.forClass(Long.class);
+ ArgumentCaptor<EnforcedAdmin> adminCaptor = ArgumentCaptor.forClass(EnforcedAdmin.class);
+
+ verify(mPreference, times(2)).removeUnusableTimeouts(
+ longCaptor.capture(), adminCaptor.capture());
+ assertEquals(0, (long)longCaptor.getValue());
+ assertTrue(adminCaptor.getValue() != null);
+ }
}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipLoaderTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipLoaderTest.java
index 53c9766..83b3225 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipLoaderTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipLoaderTest.java
@@ -37,6 +37,7 @@
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.RuntimeEnvironment;
@@ -54,7 +55,7 @@
BatteryTip.TipType.BATTERY_SAVER,
BatteryTip.TipType.LOW_BATTERY,
BatteryTip.TipType.SUMMARY};
- @Mock
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
private BatteryStatsHelper mBatteryStatsHelper;
@Mock
private PowerManager mPowerManager;
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipPolicyTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipPolicyTest.java
index bb9a37b..78c86f8 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipPolicyTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipPolicyTest.java
@@ -24,6 +24,7 @@
import android.content.Context;
import android.provider.Settings;
+import android.text.format.DateUtils;
import com.android.settings.TestConfig;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
@@ -42,6 +43,8 @@
+ ",battery_saver_tip_enabled=false"
+ ",high_usage_enabled=true"
+ ",high_usage_app_count=5"
+ + ",high_usage_period_ms=2000"
+ + ",high_usage_battery_draining=30"
+ ",app_restriction_enabled=true"
+ ",reduced_battery_enabled=true"
+ ",reduced_battery_percent=30"
@@ -66,6 +69,8 @@
assertThat(batteryTipPolicy.batterySaverTipEnabled).isFalse();
assertThat(batteryTipPolicy.highUsageEnabled).isTrue();
assertThat(batteryTipPolicy.highUsageAppCount).isEqualTo(5);
+ assertThat(batteryTipPolicy.highUsagePeriodMs).isEqualTo(2000);
+ assertThat(batteryTipPolicy.highUsageBatteryDraining).isEqualTo(30);
assertThat(batteryTipPolicy.appRestrictionEnabled).isTrue();
assertThat(batteryTipPolicy.reducedBatteryEnabled).isTrue();
assertThat(batteryTipPolicy.reducedBatteryPercent).isEqualTo(30);
@@ -85,6 +90,8 @@
assertThat(batteryTipPolicy.batterySaverTipEnabled).isTrue();
assertThat(batteryTipPolicy.highUsageEnabled).isTrue();
assertThat(batteryTipPolicy.highUsageAppCount).isEqualTo(3);
+ assertThat(batteryTipPolicy.highUsagePeriodMs).isEqualTo(2 * DateUtils.HOUR_IN_MILLIS);
+ assertThat(batteryTipPolicy.highUsageBatteryDraining).isEqualTo(25);
assertThat(batteryTipPolicy.appRestrictionEnabled).isTrue();
assertThat(batteryTipPolicy.reducedBatteryEnabled).isFalse();
assertThat(batteryTipPolicy.reducedBatteryPercent).isEqualTo(50);
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/HighUsageDataParserTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/HighUsageDataParserTest.java
new file mode 100644
index 0000000..5bdae0c
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/HighUsageDataParserTest.java
@@ -0,0 +1,86 @@
+/*
+ * 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.fuelgauge.batterytip;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.os.BatteryStats;
+import android.text.format.DateUtils;
+
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+
+import java.time.Duration;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class HighUsageDataParserTest {
+ private static final long PERIOD_ONE_MINUTE_MS = Duration.ofMinutes(1).toMillis();
+ private static final long END_TIME_MS = 2 * PERIOD_ONE_MINUTE_MS;
+ private static final int THRESHOLD_LOW = 10;
+ private static final int THRESHOLD_HIGH = 20;
+ private HighUsageDataParser mDataParser;
+ private BatteryStats.HistoryItem mFirstItem;
+ private BatteryStats.HistoryItem mSecondItem;
+ private BatteryStats.HistoryItem mThirdItem;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+
+ mFirstItem = new BatteryStats.HistoryItem();
+ mFirstItem.batteryLevel = 100;
+ mFirstItem.currentTime = 0;
+ mSecondItem = new BatteryStats.HistoryItem();
+ mSecondItem.batteryLevel = 95;
+ mSecondItem.currentTime = PERIOD_ONE_MINUTE_MS;
+ mThirdItem = new BatteryStats.HistoryItem();
+ mThirdItem.batteryLevel = 80;
+ mThirdItem.currentTime = END_TIME_MS;
+ }
+
+ @Test
+ public void testDataParser_thresholdLow_isHeavilyUsed() {
+ mDataParser = new HighUsageDataParser(PERIOD_ONE_MINUTE_MS, THRESHOLD_LOW);
+ parseData();
+
+ assertThat(mDataParser.isDeviceHeavilyUsed()).isTrue();
+ }
+
+ @Test
+ public void testDataParser_thresholdHigh_notHeavilyUsed() {
+ mDataParser = new HighUsageDataParser(PERIOD_ONE_MINUTE_MS, THRESHOLD_HIGH);
+ parseData();
+
+ assertThat(mDataParser.isDeviceHeavilyUsed()).isFalse();
+ }
+
+ private void parseData() {
+ mDataParser.onParsingStarted(0, END_TIME_MS);
+ mDataParser.onDataPoint(0, mFirstItem);
+ mDataParser.onDataPoint(PERIOD_ONE_MINUTE_MS, mSecondItem);
+ mDataParser.onDataPoint(END_TIME_MS, mThirdItem);
+
+ mDataParser.onParsingDone();
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/HighUsageDetectorTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/HighUsageDetectorTest.java
index 2a71991..8df7c56 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/HighUsageDetectorTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/HighUsageDetectorTest.java
@@ -18,6 +18,8 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
@@ -31,6 +33,7 @@
import com.android.settings.fuelgauge.BatteryInfo;
import com.android.settings.fuelgauge.BatteryUtils;
import com.android.settings.fuelgauge.batterytip.BatteryTipPolicy;
+import com.android.settings.fuelgauge.batterytip.HighUsageDataParser;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import org.junit.Before;
@@ -55,6 +58,8 @@
private BatteryUtils mBatteryUtils;
@Mock
private BatterySipper mBatterySipper;
+ @Mock
+ private HighUsageDataParser mDataParser;
private BatteryTipPolicy mPolicy;
private HighUsageDetector mHighUsageDetector;
@@ -66,8 +71,10 @@
mContext = RuntimeEnvironment.application;
mPolicy = spy(new BatteryTipPolicy(mContext));
- mHighUsageDetector = new HighUsageDetector(mContext, mPolicy, mBatteryStatsHelper);
+ mHighUsageDetector = spy(new HighUsageDetector(mContext, mPolicy, mBatteryStatsHelper));
mHighUsageDetector.mBatteryUtils = mBatteryUtils;
+ mHighUsageDetector.mDataParser = mDataParser;
+ doNothing().when(mHighUsageDetector).parseBatteryData();
mUsageList = new ArrayList<>();
mUsageList.add(mBatterySipper);
@@ -82,8 +89,7 @@
@Test
public void testDetect_containsHighUsageApp_tipVisible() {
- doReturn(2 * DateUtils.HOUR_IN_MILLIS).when(mBatteryUtils).calculateScreenUsageTime(
- mBatteryStatsHelper);
+ doReturn(true).when(mDataParser).isDeviceHeavilyUsed();
doReturn(mUsageList).when(mBatteryStatsHelper).getUsageList();
doReturn(DateUtils.HOUR_IN_MILLIS).when(mBatteryUtils).getProcessTimeMs(
BatteryUtils.StatusType.FOREGROUND, mBatterySipper.uidObj,
diff --git a/tests/robotests/src/com/android/settings/search/SearchIndexProviderCodeInspector.java b/tests/robotests/src/com/android/settings/search/SearchIndexProviderCodeInspector.java
index f84f9a2..d610363 100644
--- a/tests/robotests/src/com/android/settings/search/SearchIndexProviderCodeInspector.java
+++ b/tests/robotests/src/com/android/settings/search/SearchIndexProviderCodeInspector.java
@@ -121,7 +121,8 @@
continue;
}
// Must be in SearchProviderRegistry
- if (!SearchIndexableResources.providerValues().contains(clazz)) {
+ SearchFeatureProvider provider = new SearchFeatureProviderImpl();
+ if (!provider.getSearchIndexableResources().getProviderValues().contains(clazz)) {
if (!notInSearchIndexableRegistryGrandfatherList.remove(className)) {
notInSearchProviderRegistry.add(className);
}
diff --git a/tests/robotests/src/com/android/settings/search/SearchIndexableResourcesTest.java b/tests/robotests/src/com/android/settings/search/SearchIndexableResourcesTest.java
index eedb324..72dd94c 100644
--- a/tests/robotests/src/com/android/settings/search/SearchIndexableResourcesTest.java
+++ b/tests/robotests/src/com/android/settings/search/SearchIndexableResourcesTest.java
@@ -21,12 +21,14 @@
import static junit.framework.Assert.fail;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import android.database.Cursor;
import android.text.TextUtils;
import com.android.settings.TestConfig;
+import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.wifi.WifiSettings;
@@ -36,49 +38,56 @@
import org.junit.runner.RunWith;
import org.robolectric.annotation.Config;
-import java.util.HashSet;
-import java.util.Set;
-
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class SearchIndexableResourcesTest {
- Set<Class> sProviderClassCopy;
+ SearchFeatureProviderImpl mSearchProvider;
+ private FakeFeatureFactory mFakeFeatureFactory;
@Before
public void setUp() {
- sProviderClassCopy = new HashSet<>(SearchIndexableResources.sProviders);
+ mSearchProvider = new SearchFeatureProviderImpl();
+ mFakeFeatureFactory = FakeFeatureFactory.setupForTest();
+ mFakeFeatureFactory.searchFeatureProvider = mSearchProvider;
}
@After
public void cleanUp() {
- SearchIndexableResources.sProviders.clear();
- SearchIndexableResources.sProviders.addAll(sProviderClassCopy);
+ mFakeFeatureFactory.searchFeatureProvider = mock(
+ SearchFeatureProvider.class);
}
@Test
public void testAddIndex() {
final Class stringClass = java.lang.String.class;
// Confirms that String.class isn't contained in SearchIndexableResources.
- assertThat(SearchIndexableResources.sProviders).doesNotContain(stringClass);
- final int beforeCount = SearchIndexableResources.providerValues().size();
+ assertThat(mSearchProvider.getSearchIndexableResources().getProviderValues())
+ .doesNotContain(stringClass);
+ final int beforeCount =
+ mSearchProvider.getSearchIndexableResources().getProviderValues().size();
- SearchIndexableResources.addIndex(java.lang.String.class);
+ ( (SearchIndexableResourcesImpl) mSearchProvider.getSearchIndexableResources())
+ .addIndex(java.lang.String.class);
- assertThat(SearchIndexableResources.sProviders).contains(stringClass);
- final int afterCount = SearchIndexableResources.providerValues().size();
+ assertThat(mSearchProvider.getSearchIndexableResources().getProviderValues())
+ .contains(stringClass);
+ final int afterCount =
+ mSearchProvider.getSearchIndexableResources().getProviderValues().size();
assertThat(afterCount).isEqualTo(beforeCount + 1);
}
@Test
public void testIndexHasWifiSettings() {
- assertThat(sProviderClassCopy).contains(WifiSettings.class);
+ assertThat(mSearchProvider.getSearchIndexableResources().getProviderValues())
+ .contains(WifiSettings.class);
}
@Test
public void testNonIndexableKeys_GetsKeyFromProvider() {
- SearchIndexableResources.sProviders.clear();
- SearchIndexableResources.addIndex(FakeIndexProvider.class);
+ mSearchProvider.getSearchIndexableResources().getProviderValues().clear();
+ ( (SearchIndexableResourcesImpl) mSearchProvider.getSearchIndexableResources())
+ .addIndex(FakeIndexProvider.class);
SettingsSearchIndexablesProvider provider = spy(new SettingsSearchIndexablesProvider());
@@ -97,7 +106,7 @@
@Test
public void testAllClassNamesHaveProviders() {
- for (Class clazz: sProviderClassCopy) {
+ for (Class clazz: mSearchProvider.getSearchIndexableResources().getProviderValues()) {
if(DatabaseIndexingUtils.getSearchIndexProvider(clazz) == null) {
fail(clazz.getName() + "is not an index provider");
}
diff --git a/tests/robotests/src/com/android/settings/search/SettingsSearchIndexablesProviderTest.java b/tests/robotests/src/com/android/settings/search/SettingsSearchIndexablesProviderTest.java
index efeaed7..cca2794 100644
--- a/tests/robotests/src/com/android/settings/search/SettingsSearchIndexablesProviderTest.java
+++ b/tests/robotests/src/com/android/settings/search/SettingsSearchIndexablesProviderTest.java
@@ -2,6 +2,7 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import android.Manifest;
@@ -14,6 +15,7 @@
import com.android.settings.R;
import com.android.settings.TestConfig;
import com.android.settings.search.indexing.FakeSettingsFragment;
+import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import org.junit.After;
@@ -23,9 +25,6 @@
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
-import java.util.HashSet;
-import java.util.Set;
-
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class SettingsSearchIndexablesProviderTest {
@@ -33,8 +32,8 @@
private final String BASE_AUTHORITY = "com.android.settings";
private SettingsSearchIndexablesProvider mProvider;
-
- Set<Class> sProviderClasses;
+ private SearchFeatureProvider mFeatureProvider;
+ private FakeFeatureFactory mFakeFeatureFactory;
Context mContext;
@Before
@@ -49,15 +48,18 @@
info.readPermission = Manifest.permission.READ_SEARCH_INDEXABLES;
mProvider.attachInfo(mContext, info);
- sProviderClasses = new HashSet<>(SearchIndexableResources.sProviders);
- SearchIndexableResources.sProviders.clear();
- SearchIndexableResources.sProviders.add(FakeSettingsFragment.class);
+ mFeatureProvider = new SearchFeatureProviderImpl();
+ mFeatureProvider.getSearchIndexableResources().getProviderValues().clear();
+ mFeatureProvider.getSearchIndexableResources().getProviderValues()
+ .add(FakeSettingsFragment.class);
+ mFakeFeatureFactory = FakeFeatureFactory.setupForTest();
+ mFakeFeatureFactory.searchFeatureProvider = mFeatureProvider;
}
@After
public void cleanUp() {
- SearchIndexableResources.sProviders.clear();
- SearchIndexableResources.sProviders.addAll(sProviderClasses);
+ mFakeFeatureFactory.searchFeatureProvider = mock(
+ SearchFeatureProvider.class);
}
@Test
diff --git a/tests/robotests/src/com/android/settings/slices/SliceBroadcastReceiverTest.java b/tests/robotests/src/com/android/settings/slices/SliceBroadcastReceiverTest.java
index efd1cc5..f5d5ff0 100644
--- a/tests/robotests/src/com/android/settings/slices/SliceBroadcastReceiverTest.java
+++ b/tests/robotests/src/com/android/settings/slices/SliceBroadcastReceiverTest.java
@@ -19,6 +19,8 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.mock;
+
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
@@ -26,8 +28,9 @@
import com.android.settings.TestConfig;
import com.android.settings.search.FakeIndexProvider;
-import com.android.settings.search.SearchIndexableResources;
-import com.android.settings.testutils.DatabaseTestUtils;
+import com.android.settings.search.SearchFeatureProvider;
+import com.android.settings.search.SearchFeatureProviderImpl;
+import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import org.junit.After;
@@ -37,9 +40,6 @@
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
-import java.util.HashSet;
-import java.util.Set;
-
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class SliceBroadcastReceiverTest {
@@ -54,30 +54,30 @@
private Context mContext;
private SQLiteDatabase mDb;
private SliceBroadcastReceiver mReceiver;
-
- private Set<Class> mProviderClassesCopy;
+ private SearchFeatureProvider mSearchFeatureProvider;
+ private FakeFeatureFactory mFakeFeatureFactory;
@Before
public void setUp() {
mContext = RuntimeEnvironment.application;
mDb = SlicesDatabaseHelper.getInstance(mContext).getWritableDatabase();
mReceiver = new SliceBroadcastReceiver();
- mProviderClassesCopy = new HashSet<>(SearchIndexableResources.providerValues());
SlicesDatabaseHelper helper = SlicesDatabaseHelper.getInstance(mContext);
helper.setIndexedState();
+ mSearchFeatureProvider = new SearchFeatureProviderImpl();
+ mFakeFeatureFactory = FakeFeatureFactory.setupForTest();
+ mFakeFeatureFactory.searchFeatureProvider = mSearchFeatureProvider;
}
@After
public void cleanUp() {
- DatabaseTestUtils.clearDb(mContext);
- SearchIndexableResources.providerValues().clear();
- SearchIndexableResources.providerValues().addAll(mProviderClassesCopy);
+ mFakeFeatureFactory.searchFeatureProvider = mock(SearchFeatureProvider.class);
}
@Test
public void testOnReceive_toggleChanged() {
String key = "key";
- SearchIndexableResources.providerValues().clear();
+ mSearchFeatureProvider.getSearchIndexableResources().getProviderValues().clear();
insertSpecialCase(key);
// Turn on toggle setting
FakeToggleController fakeToggleController = new FakeToggleController(mContext, key);
diff --git a/tests/robotests/src/com/android/settings/slices/SliceDataConverterTest.java b/tests/robotests/src/com/android/settings/slices/SliceDataConverterTest.java
index b5c0b5f..1d0ac41 100644
--- a/tests/robotests/src/com/android/settings/slices/SliceDataConverterTest.java
+++ b/tests/robotests/src/com/android/settings/slices/SliceDataConverterTest.java
@@ -18,11 +18,15 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.mock;
+
import android.content.Context;
import com.android.settings.TestConfig;
import com.android.settings.search.FakeIndexProvider;
-import com.android.settings.search.SearchIndexableResources;
+import com.android.settings.search.SearchFeatureProvider;
+import com.android.settings.search.SearchFeatureProviderImpl;
+import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import org.junit.After;
@@ -32,9 +36,7 @@
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
-import java.util.HashSet;
import java.util.List;
-import java.util.Set;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
@@ -49,28 +51,31 @@
Context mContext;
- private Set<Class> mProviderClassesCopy;
-
SliceDataConverter mSliceDataConverter;
+ SearchFeatureProvider mSearchFeatureProvider;
+ private FakeFeatureFactory mFakeFeatureFactory;
@Before
public void setUp() {
mContext = RuntimeEnvironment.application;
- mProviderClassesCopy = new HashSet<>(SearchIndexableResources.providerValues());
mSliceDataConverter = new SliceDataConverter(mContext);
+ mSearchFeatureProvider = new SearchFeatureProviderImpl();
+ mFakeFeatureFactory = FakeFeatureFactory.setupForTest();
+ mFakeFeatureFactory.searchFeatureProvider = mSearchFeatureProvider;
}
@After
public void cleanUp() {
- SearchIndexableResources.providerValues().clear();
- SearchIndexableResources.providerValues().addAll(mProviderClassesCopy);
+ mFakeFeatureFactory.searchFeatureProvider = mock(
+ SearchFeatureProvider.class);
}
@Test
@Config(qualifiers = "mcc999")
public void testFakeProvider_convertsFakeData() {
- SearchIndexableResources.providerValues().clear();
- SearchIndexableResources.providerValues().add(FakeIndexProvider.class);
+ mSearchFeatureProvider.getSearchIndexableResources().getProviderValues().clear();
+ mSearchFeatureProvider.getSearchIndexableResources().getProviderValues()
+ .add(FakeIndexProvider.class);
List<SliceData> sliceDataList = mSliceDataConverter.getSliceData();
diff --git a/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java b/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java
index b4592b8..3325332 100644
--- a/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java
+++ b/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java
@@ -55,7 +55,6 @@
public final LocaleFeatureProvider localeFeatureProvider;
public final ApplicationFeatureProvider applicationFeatureProvider;
public final EnterprisePrivacyFeatureProvider enterprisePrivacyFeatureProvider;
- public final SearchFeatureProvider searchFeatureProvider;
public final SurveyFeatureProvider surveyFeatureProvider;
public final SecurityFeatureProvider securityFeatureProvider;
public final SuggestionFeatureProvider suggestionsFeatureProvider;
@@ -65,6 +64,7 @@
public final DataPlanFeatureProvider dataPlanFeatureProvider;
public final SmsMirroringFeatureProvider smsMirroringFeatureProvider;
public final SlicesFeatureProvider slicesFeatureProvider;
+ public SearchFeatureProvider searchFeatureProvider;
/**
* Call this in {@code @Before} method of the test class to use fake factory.
diff --git a/tests/robotests/src/com/android/settings/TetherServiceTest.java b/tests/robotests/src/com/android/settings/wifi/tether/TetherServiceTest.java
similarity index 72%
rename from tests/robotests/src/com/android/settings/TetherServiceTest.java
rename to tests/robotests/src/com/android/settings/wifi/tether/TetherServiceTest.java
index 0275c15..583bd52 100644
--- a/tests/robotests/src/com/android/settings/TetherServiceTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/tether/TetherServiceTest.java
@@ -13,17 +13,23 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.settings;
+package com.android.settings.wifi.tether;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import android.content.Context;
import android.content.Intent;
+import android.content.SharedPreferences;
import android.net.wifi.WifiManager;
+import com.android.settings.TestConfig;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import java.util.ArrayList;
@@ -87,4 +93,22 @@
mService.cancelAlarmIfNecessary();
verify(mContext).unregisterReceiver(any(HotspotOffReceiver.class));
}
+
+ @Test
+ public void onDestroy_shouldUnregisterReceiver() {
+ final ArrayList<Integer> tethers = new ArrayList<>();
+ ReflectionHelpers.setField(mService, "mCurrentTethers", tethers);
+ ReflectionHelpers.setField(mService, "mBase", mContext);
+ final SharedPreferences prefs = mock(SharedPreferences .class);
+ final SharedPreferences.Editor editor = mock(SharedPreferences.Editor.class);
+ when(mContext.getSharedPreferences(anyString(), anyInt())).thenReturn(prefs);
+ when(prefs.edit()).thenReturn(editor);
+ when(editor.putString(anyString(), anyString())).thenReturn(editor);
+ final HotspotOffReceiver hotspotOffReceiver = mock(HotspotOffReceiver.class);
+ mService.setHotspotOffReceiver(hotspotOffReceiver);
+
+ mService.onDestroy();
+
+ verify(hotspotOffReceiver).unregister();
+ }
}
diff --git a/tests/unit/src/com/android/settings/core/PreferenceControllerContractTest.java b/tests/unit/src/com/android/settings/core/PreferenceControllerContractTest.java
index 86e8dc1..b16c700 100644
--- a/tests/unit/src/com/android/settings/core/PreferenceControllerContractTest.java
+++ b/tests/unit/src/com/android/settings/core/PreferenceControllerContractTest.java
@@ -26,6 +26,7 @@
import android.support.test.runner.AndroidJUnit4;
import android.util.ArraySet;
+import com.android.settings.overlay.FeatureFactory;
import com.android.settings.search.DatabaseIndexingUtils;
import com.android.settings.search.Indexable;
import com.android.settings.search.SearchIndexableResources;
@@ -54,7 +55,10 @@
public void controllersInSearchShouldImplementPreferenceControllerMixin() {
final Set<String> errorClasses = new ArraySet<>();
- for (Class clazz : SearchIndexableResources.providerValues()) {
+ final SearchIndexableResources resources =
+ FeatureFactory.getFactory(mContext).getSearchFeatureProvider()
+ .getSearchIndexableResources();
+ for (Class<?> clazz : resources.getProviderValues()) {
final Indexable.SearchIndexProvider provider =
DatabaseIndexingUtils.getSearchIndexProvider(clazz);
diff --git a/tests/unit/src/com/android/settings/core/UniquePreferenceTest.java b/tests/unit/src/com/android/settings/core/UniquePreferenceTest.java
index 36865a4..8fe2358 100644
--- a/tests/unit/src/com/android/settings/core/UniquePreferenceTest.java
+++ b/tests/unit/src/com/android/settings/core/UniquePreferenceTest.java
@@ -31,6 +31,7 @@
import android.util.Log;
import android.util.Xml;
+import com.android.settings.overlay.FeatureFactory;
import com.android.settings.search.DatabaseIndexingUtils;
import com.android.settings.search.Indexable;
import com.android.settings.search.SearchIndexableRaw;
@@ -100,7 +101,10 @@
final Set<String> uniqueKeys = new HashSet<>();
final Set<String> nullKeyClasses = new HashSet<>();
final Set<String> duplicatedKeys = new HashSet<>();
- for (Class<?> clazz : SearchIndexableResources.providerValues()) {
+ final SearchIndexableResources resources =
+ FeatureFactory.getFactory(mContext).getSearchFeatureProvider()
+ .getSearchIndexableResources();
+ for (Class<?> clazz : resources.getProviderValues()) {
verifyPreferenceKeys(uniqueKeys, duplicatedKeys, nullKeyClasses, clazz);
}
diff --git a/tests/unit/src/com/android/settings/core/UserRestrictionTest.java b/tests/unit/src/com/android/settings/core/UserRestrictionTest.java
index f37c30b..6d6f06c 100644
--- a/tests/unit/src/com/android/settings/core/UserRestrictionTest.java
+++ b/tests/unit/src/com/android/settings/core/UserRestrictionTest.java
@@ -32,6 +32,7 @@
import android.util.Log;
import android.util.Xml;
+import com.android.settings.overlay.FeatureFactory;
import com.android.settings.search.DatabaseIndexingUtils;
import com.android.settings.search.Indexable;
import com.android.settings.search.SearchIndexableResources;
@@ -65,7 +66,8 @@
UserManager.DISALLOW_CONFIG_VPN,
UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS,
UserManager.DISALLOW_AIRPLANE_MODE,
- UserManager.DISALLOW_CONFIG_BRIGHTNESS
+ UserManager.DISALLOW_CONFIG_BRIGHTNESS,
+ UserManager.DISALLOW_CONFIG_SCREEN_TIMEOUT
);
@Before
@@ -79,7 +81,10 @@
@Test
public void userRestrictionAttributeShouldBeValid()
throws IOException, XmlPullParserException, Resources.NotFoundException {
- for (Class<?> clazz : SearchIndexableResources.providerValues()) {
+ final SearchIndexableResources resources =
+ FeatureFactory.getFactory(mContext).getSearchFeatureProvider()
+ .getSearchIndexableResources();
+ for (Class<?> clazz : resources.getProviderValues()) {
verifyUserRestriction(clazz);
}
}
diff --git a/tests/unit/src/com/android/settings/TetherServiceTest.java b/tests/unit/src/com/android/settings/wifi/tether/TetherServiceTest.java
similarity index 98%
rename from tests/unit/src/com/android/settings/TetherServiceTest.java
rename to tests/unit/src/com/android/settings/wifi/tether/TetherServiceTest.java
index 899ea7a..7bf5798 100644
--- a/tests/unit/src/com/android/settings/TetherServiceTest.java
+++ b/tests/unit/src/com/android/settings/wifi/tether/TetherServiceTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.settings;
+package com.android.settings.wifi.tether;
import static org.junit.Assert.*;
import static org.mockito.Matchers.*;
@@ -49,17 +49,13 @@
import android.content.SharedPreferences.Editor;
import android.content.res.Resources;
import android.net.ConnectivityManager;
-import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.ResultReceiver;
import android.os.SystemClock;
import android.test.ServiceTestCase;
-import android.test.mock.MockResources;
import android.util.Log;
-import com.android.settings.TetherService;
-
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;