Merge "Modify Comparator in ZonePicker"
diff --git a/res/layout/private_dns_mode_dialog.xml b/res/layout/private_dns_mode_dialog.xml
new file mode 100644
index 0000000..4347055
--- /dev/null
+++ b/res/layout/private_dns_mode_dialog.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<RadioGroup
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:padding="8dip">
+
+ <RadioButton
+ android:id="@+id/private_dns_mode_off"
+ android:text="@string/private_dns_mode_off"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_margin="8dip"
+ />
+
+ <RadioButton
+ android:id="@+id/private_dns_mode_opportunistic"
+ android:text="@string/private_dns_mode_opportunistic"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_margin="8dip"
+ />
+
+ <RadioButton
+ android:id="@+id/private_dns_mode_provider"
+ android:text="@string/private_dns_mode_provider"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_margin="8dip"
+ />
+
+ <EditText
+ android:id="@+id/private_dns_mode_provider_hostname"
+ android:hint="@string/private_dns_mode_provider_hostname_hint"
+ style="@android:style/Widget.CompoundButton.RadioButton"
+ android:imeOptions="actionDone"
+ android:inputType="textFilter|textUri"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="8dip"
+ android:layout_marginEnd="8dip"
+ />
+
+</RadioGroup>
diff --git a/res/values-ar/arrays.xml b/res/values-ar/arrays.xml
index a31ead4..d8029fa 100644
--- a/res/values-ar/arrays.xml
+++ b/res/values-ar/arrays.xml
@@ -219,7 +219,7 @@
<item msgid="7471182818083460781">"IS95A"</item>
</string-array>
<string-array name="mvno_type_entries">
- <item msgid="4367119357633573465">"None"</item>
+ <item msgid="4367119357633573465">"بدون"</item>
<item msgid="6062567900587138000">"SPN"</item>
<item msgid="2454085083342423481">"IMSI"</item>
<item msgid="2681427309183221543">"GID"</item>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index b207009..467ad12 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -6288,7 +6288,7 @@
<!-- Call Manager settings summary. [CHAR LIMIT=50] -->
<string name="call_manager_summary"><xliff:g id="app">%1$s</xliff:g></string>
<!-- Cell Broadcast settings title. [CHAR LIMIT=50] -->
- <string name="cell_broadcast_settings">Emergency broadcasts</string>
+ <string name="cell_broadcast_settings">Emergency alerts</string>
<!-- Network operators settings title. [CHAR LIMIT=50] -->
<string name="network_operators_settings">Network operators</string>
<!-- Access point names title. [CHAR LIMIT=50] -->
diff --git a/res/xml/development_prefs.xml b/res/xml/development_prefs.xml
index 7c0c0b3..2b4a85a 100644
--- a/res/xml/development_prefs.xml
+++ b/res/xml/development_prefs.xml
@@ -257,10 +257,13 @@
android:entries="@array/bluetooth_a2dp_codec_ldac_playback_quality_titles"
android:entryValues="@array/bluetooth_a2dp_codec_ldac_playback_quality_values" />
- <SwitchPreference
- android:key="dns_tls"
- android:title="@string/dns_tls"
- android:summary="@string/dns_tls_summary" />
+ <com.android.settings.development.PrivateDnsModeDialogPreference
+ android:key="select_private_dns_configuration"
+ android:title="@string/select_private_dns_configuration_title"
+ android:dialogTitle="@string/select_private_dns_configuration_dialog_title"
+ android:dialogLayout="@layout/private_dns_mode_dialog"
+ android:positiveButtonText="@string/save"
+ android:negativeButtonText="@string/cancel" />
</PreferenceCategory>
diff --git a/src/com/android/settings/PrivacySettings.java b/src/com/android/settings/PrivacySettings.java
index a44e182..e547570 100644
--- a/src/com/android/settings/PrivacySettings.java
+++ b/src/com/android/settings/PrivacySettings.java
@@ -63,7 +63,6 @@
@VisibleForTesting
static final String DATA_MANAGEMENT = "data_management";
private static final String BACKUP_INACTIVE = "backup_inactive";
- private static final String FACTORY_RESET = "factory_reset";
private static final String TAG = "PrivacySettings";
private IBackupManager mBackupManager;
private Preference mBackup;
@@ -245,9 +244,5 @@
nonVisibleKeys.add(AUTO_RESTORE);
nonVisibleKeys.add(CONFIGURE_ACCOUNT);
}
- if (RestrictedLockUtils.hasBaseUserRestriction(context,
- UserManager.DISALLOW_FACTORY_RESET, UserHandle.myUserId())) {
- nonVisibleKeys.add(FACTORY_RESET);
- }
}
}
diff --git a/src/com/android/settings/development/DevelopmentSettings.java b/src/com/android/settings/development/DevelopmentSettings.java
index c0792e7..23cf4cc 100644
--- a/src/com/android/settings/development/DevelopmentSettings.java
+++ b/src/com/android/settings/development/DevelopmentSettings.java
@@ -217,7 +217,7 @@
private static final String BLUETOOTH_SELECT_A2DP_CHANNEL_MODE_KEY = "bluetooth_select_a2dp_channel_mode";
private static final String BLUETOOTH_SELECT_A2DP_LDAC_PLAYBACK_QUALITY_KEY = "bluetooth_select_a2dp_ldac_playback_quality";
- private static final String DNS_TLS_KEY = "dns_tls";
+ private static final String PRIVATE_DNS_PREF_KEY = "select_private_dns_configuration";
private static final String INACTIVE_APPS_KEY = "inactive_apps";
@@ -295,8 +295,6 @@
private ListPreference mBluetoothSelectA2dpChannelMode;
private ListPreference mBluetoothSelectA2dpLdacPlaybackQuality;
- private SwitchPreference mDnsTls;
-
private SwitchPreference mOtaDisableAutomaticUpdate;
private SwitchPreference mWifiAllowScansWithTraffic;
private SwitchPreference mStrictMode;
@@ -511,7 +509,7 @@
mBluetoothSelectA2dpLdacPlaybackQuality = addListPreference(BLUETOOTH_SELECT_A2DP_LDAC_PLAYBACK_QUALITY_KEY);
initBluetoothConfigurationValues();
- mDnsTls = findAndInitSwitchPref(DNS_TLS_KEY);
+ updatePrivateDnsSummary();
mWindowAnimationScale = addListPreference(WINDOW_ANIMATION_SCALE_KEY);
mTransitionAnimationScale = addListPreference(TRANSITION_ANIMATION_SCALE_KEY);
@@ -829,8 +827,7 @@
updateBluetoothDisableAbsVolumeOptions();
updateBluetoothEnableInbandRingingOptions();
updateBluetoothA2dpConfigurationValues();
- updateSwitchPreference(mDnsTls, Settings.Global.getInt(cr,
- Settings.Global.DNS_TLS_DISABLED, 0) == 0);
+ updatePrivateDnsSummary();
}
private void resetDangerousOptions() {
@@ -2183,6 +2180,13 @@
}
}
+ private void updatePrivateDnsSummary() {
+ final String summary = PrivateDnsModeDialogPreference.getSummaryStringForModeFromSettings(
+ getActivity().getContentResolver(), getActivity().getResources());
+ final Preference pref = findPreference(PRIVATE_DNS_PREF_KEY);
+ pref.setSummary(summary);
+ }
+
private void writeImmediatelyDestroyActivitiesOptions() {
try {
ActivityManager.getService().setAlwaysFinish(
@@ -2534,10 +2538,6 @@
writeBluetoothDisableAbsVolumeOptions();
} else if (preference == mBluetoothEnableInbandRinging) {
writeBluetoothEnableInbandRingingOptions();
- } else if (preference == mDnsTls) {
- Settings.Global.putInt(getActivity().getContentResolver(),
- Settings.Global.DNS_TLS_DISABLED,
- mDnsTls.isChecked() ? 0 : 1);
} else if (SHORTCUT_MANAGER_RESET_KEY.equals(preference.getKey())) {
resetShortcutManagerThrottling();
} else {
diff --git a/src/com/android/settings/development/PrivateDnsModeDialogPreference.java b/src/com/android/settings/development/PrivateDnsModeDialogPreference.java
new file mode 100644
index 0000000..ee44b08
--- /dev/null
+++ b/src/com/android/settings/development/PrivateDnsModeDialogPreference.java
@@ -0,0 +1,246 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.settings.development;
+
+import static android.net.ConnectivityManager.PRIVATE_DNS_DEFAULT_MODE;
+import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OFF;
+import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC;
+import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.res.Resources;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.support.v14.preference.PreferenceDialogFragment;
+import android.support.v7.preference.DialogPreference;
+import android.text.Editable;
+import android.text.TextUtils;
+import android.text.TextWatcher;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.inputmethod.EditorInfo;
+import android.view.KeyEvent;
+import android.view.View;
+import android.view.ViewGroup.LayoutParams;
+import android.view.ViewGroup.MarginLayoutParams;
+import android.widget.CompoundButton;
+import android.widget.CompoundButton.OnCheckedChangeListener;
+import android.widget.EditText;
+import android.widget.RadioButton;
+import android.widget.TextView;
+import android.widget.TextView.OnEditorActionListener;
+
+import com.android.settings.R;
+import com.android.settingslib.CustomDialogPreference;
+
+
+public class PrivateDnsModeDialogPreference extends CustomDialogPreference
+ implements OnCheckedChangeListener, TextWatcher, OnEditorActionListener {
+ private static final String TAG = PrivateDnsModeDialogPreference.class.getSimpleName();
+
+ private static final String MODE_KEY = Settings.Global.PRIVATE_DNS_MODE;
+ private static final String HOSTNAME_KEY = Settings.Global.PRIVATE_DNS_SPECIFIER;
+ private String mMode;
+ private EditText mEditText;
+
+ public static String getSummaryStringForModeFromSettings(ContentResolver cr, Resources res) {
+ final String mode = getModeFromSettings(cr);
+ switch (mode) {
+ case PRIVATE_DNS_MODE_OFF:
+ return res.getString(R.string.private_dns_mode_off);
+ case PRIVATE_DNS_MODE_OPPORTUNISTIC:
+ return res.getString(R.string.private_dns_mode_opportunistic);
+ case PRIVATE_DNS_MODE_PROVIDER_HOSTNAME:
+ return getHostnameFromSettings(cr);
+ default:
+ return "unknown";
+ }
+ }
+
+ public PrivateDnsModeDialogPreference(Context context, AttributeSet attrs, int defStyleAttr,
+ int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ }
+
+ public PrivateDnsModeDialogPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+
+ public PrivateDnsModeDialogPreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public PrivateDnsModeDialogPreference(Context context) {
+ super(context);
+ }
+
+ // This is called first when the dialog is launched.
+ @Override
+ protected void onBindDialogView(View view) {
+ final String mode = getModeFromSettings();
+
+ RadioButton rb = (RadioButton) view.findViewById(R.id.private_dns_mode_off);
+ if (mode.equals(PRIVATE_DNS_MODE_OFF)) rb.setChecked(true);
+ rb.setOnCheckedChangeListener(this);
+
+ rb = (RadioButton) view.findViewById(R.id.private_dns_mode_opportunistic);
+ if (mode.equals(PRIVATE_DNS_MODE_OPPORTUNISTIC)) rb.setChecked(true);
+ rb.setOnCheckedChangeListener(this);
+
+ rb = (RadioButton) view.findViewById(R.id.private_dns_mode_provider);
+ if (mode.equals(PRIVATE_DNS_MODE_PROVIDER_HOSTNAME)) rb.setChecked(true);
+ rb.setOnCheckedChangeListener(this);
+
+ mEditText = (EditText) view.findViewById(R.id.private_dns_mode_provider_hostname);
+ mEditText.setOnEditorActionListener(this);
+ mEditText.addTextChangedListener(this);
+
+ // (Mostly) Fix the EditText field's indentation to align underneath the
+ // displayed radio button text, and not under the radio button itself.
+ final int padding = rb.isLayoutRtl()
+ ? rb.getCompoundPaddingRight()
+ : rb.getCompoundPaddingLeft();
+ final MarginLayoutParams marginParams = (MarginLayoutParams) mEditText.getLayoutParams();
+ marginParams.setMarginStart(marginParams.getMarginStart() + padding);
+ mEditText.setLayoutParams(marginParams);
+ mEditText.setText(getHostnameFromSettings());
+
+ setDialogValue(mode);
+ }
+
+ @Override
+ protected void onDialogClosed(boolean positiveResult) {
+ if (!positiveResult) return;
+
+ saveDialogValue();
+ setSummary(getSummaryStringForModeFromSettings(
+ getContext().getContentResolver(), getContext().getResources()));
+ }
+
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ if (!isChecked) return;
+
+ switch (buttonView.getId()) {
+ case R.id.private_dns_mode_off:
+ setDialogValue(PRIVATE_DNS_MODE_OFF);
+ break;
+ case R.id.private_dns_mode_opportunistic:
+ setDialogValue(PRIVATE_DNS_MODE_OPPORTUNISTIC);
+ break;
+ case R.id.private_dns_mode_provider:
+ setDialogValue(PRIVATE_DNS_MODE_PROVIDER_HOSTNAME);
+ break;
+ default:
+ // Unknown button; ignored.
+ break;
+ }
+ }
+
+ @Override
+ public boolean onEditorAction(TextView tv, int actionId, KeyEvent k) {
+ if (actionId == EditorInfo.IME_ACTION_DONE) {
+ saveDialogValue();
+ getDialog().dismiss();
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) { return; }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) { return; }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ final String hostname = s.toString();
+ final boolean appearsValid = isWeaklyValidatedHostname(hostname);
+ // TODO: Disable the "positive button" ("Save") when appearsValid is false.
+ }
+
+ private void setDialogValue(String mode) {
+ mMode = mode;
+ final boolean txtEnabled = mMode.equals(PRIVATE_DNS_MODE_PROVIDER_HOSTNAME);
+ mEditText.setEnabled(txtEnabled);
+ }
+
+ private void saveDialogValue() {
+ if (!isValidMode(mMode)) {
+ mMode = PRIVATE_DNS_DEFAULT_MODE;
+ }
+
+ if (mMode.equals(PRIVATE_DNS_MODE_PROVIDER_HOSTNAME)) {
+ final String hostname = mEditText.getText().toString();
+ if (isWeaklyValidatedHostname(hostname)) {
+ saveHostnameToSettings(hostname);
+ } else {
+ // TODO: Once quasi-validation of hostnames works and acceptable
+ // user signaling is working, this can be deleted.
+ mMode = PRIVATE_DNS_MODE_OPPORTUNISTIC;
+ if (TextUtils.isEmpty(hostname)) saveHostnameToSettings("");
+ }
+ }
+
+ saveModeToSettings(mMode);
+ }
+
+ private String getModeFromSettings() {
+ return getModeFromSettings(getContext().getContentResolver());
+ }
+
+ private void saveModeToSettings(String value) {
+ Settings.Global.putString(getContext().getContentResolver(), MODE_KEY, value);
+ }
+
+ private String getHostnameFromSettings() {
+ return getHostnameFromSettings(getContext().getContentResolver());
+ }
+
+ private void saveHostnameToSettings(String hostname) {
+ Settings.Global.putString(getContext().getContentResolver(), HOSTNAME_KEY, hostname);
+ }
+
+ private static String getModeFromSettings(ContentResolver cr) {
+ final String mode = Settings.Global.getString(cr, MODE_KEY);
+ return isValidMode(mode) ? mode : PRIVATE_DNS_DEFAULT_MODE;
+ }
+
+ private static boolean isValidMode(String mode) {
+ return !TextUtils.isEmpty(mode) && (
+ mode.equals(PRIVATE_DNS_MODE_OFF) ||
+ mode.equals(PRIVATE_DNS_MODE_OPPORTUNISTIC) ||
+ mode.equals(PRIVATE_DNS_MODE_PROVIDER_HOSTNAME));
+ }
+
+ private static String getHostnameFromSettings(ContentResolver cr) {
+ return Settings.Global.getString(cr, HOSTNAME_KEY);
+ }
+
+ private static boolean isWeaklyValidatedHostname(String hostname) {
+ // TODO: Find and use a better validation method. Specifically:
+ // [1] this should reject IP string literals, and
+ // [2] do the best, simplest, future-proof verification that
+ // the input approximates a DNS hostname.
+ final String WEAK_HOSTNAME_REGEX = "^[a-zA-Z0-9_.-]+$";
+ return hostname.matches(WEAK_HOSTNAME_REGEX);
+ }
+}
diff --git a/src/com/android/settings/deviceinfo/MigrateEstimateTask.java b/src/com/android/settings/deviceinfo/MigrateEstimateTask.java
index 395b6a2..c41ebe0 100644
--- a/src/com/android/settings/deviceinfo/MigrateEstimateTask.java
+++ b/src/com/android/settings/deviceinfo/MigrateEstimateTask.java
@@ -16,51 +16,40 @@
package com.android.settings.deviceinfo;
-import android.content.ComponentName;
+import static com.android.settings.deviceinfo.StorageSettings.TAG;
+
+import android.app.usage.ExternalStorageStats;
+import android.app.usage.StorageStatsManager;
import android.content.Context;
import android.content.Intent;
-import android.content.ServiceConnection;
+import android.content.pm.UserInfo;
import android.net.TrafficStats;
import android.os.AsyncTask;
-import android.os.IBinder;
-import android.os.RemoteException;
import android.os.UserHandle;
+import android.os.UserManager;
import android.os.storage.StorageManager;
import android.os.storage.VolumeInfo;
import android.telecom.Log;
import android.text.format.DateUtils;
import android.text.format.Formatter;
-import com.android.internal.app.IMediaContainerService;
+import java.io.IOException;
+import java.util.UUID;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import static com.android.settings.deviceinfo.StorageSettings.TAG;
-
-public abstract class MigrateEstimateTask extends AsyncTask<Void, Void, Long> implements
- ServiceConnection {
+public abstract class MigrateEstimateTask extends AsyncTask<Void, Void, Long> {
private static final String EXTRA_SIZE_BYTES = "size_bytes";
- private static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
- "com.android.defcontainer", "com.android.defcontainer.DefaultContainerService");
-
/**
* Assume roughly a Class 10 card.
*/
private static final long SPEED_ESTIMATE_BPS = 10 * TrafficStats.MB_IN_BYTES;
private final Context mContext;
- private final StorageManager mStorage;
-
- private final CountDownLatch mConnected = new CountDownLatch(1);
- private IMediaContainerService mService;
private long mSizeBytes = -1;
public MigrateEstimateTask(Context context) {
mContext = context;
- mStorage = context.getSystemService(StorageManager.class);
}
public void copyFrom(Intent intent) {
@@ -77,31 +66,36 @@
return mSizeBytes;
}
+ final UserManager user = mContext.getSystemService(UserManager.class);
+ final StorageManager storage = mContext.getSystemService(StorageManager.class);
+ final StorageStatsManager stats = mContext.getSystemService(StorageStatsManager.class);
+
final VolumeInfo privateVol = mContext.getPackageManager().getPrimaryStorageCurrentVolume();
- final VolumeInfo emulatedVol = mStorage.findEmulatedForPrivate(privateVol);
+ final VolumeInfo emulatedVol = storage.findEmulatedForPrivate(privateVol);
if (emulatedVol == null) {
Log.w(TAG, "Failed to find current primary storage");
return -1L;
}
- final String path = emulatedVol.getPath().getAbsolutePath();
- Log.d(TAG, "Estimating for current path " + path);
-
- final Intent intent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
- mContext.bindServiceAsUser(intent, this, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM);
-
try {
- if (mConnected.await(15, TimeUnit.SECONDS)) {
- return mService.calculateDirectorySize(path);
- }
- } catch (InterruptedException | RemoteException e) {
- Log.w(TAG, "Failed to measure " + path);
- } finally {
- mContext.unbindService(this);
- }
+ final UUID emulatedUuid = storage.getUuidForPath(emulatedVol.getPath());
+ Log.d(TAG, "Measuring size of " + emulatedUuid);
- return -1L;
+ long size = 0;
+ for (UserInfo u : user.getUsers()) {
+ final ExternalStorageStats s = stats.queryExternalStatsForUser(emulatedUuid,
+ UserHandle.of(u.id));
+ size += s.getTotalBytes();
+ if (u.id == UserHandle.USER_SYSTEM) {
+ size += s.getObbBytes();
+ }
+ }
+ return size;
+ } catch (IOException e) {
+ Log.w(TAG, "Failed to measure", e);
+ return -1L;
+ }
}
@Override
@@ -116,16 +110,4 @@
}
public abstract void onPostExecute(String size, String time);
-
- @Override
- public void onServiceConnected(ComponentName name, IBinder service) {
- mService = IMediaContainerService.Stub.asInterface(service);
- mConnected.countDown();
- }
-
- @Override
- public void onServiceDisconnected(ComponentName name) {
- // Ignored; we leave service in place for the background thread to
- // run into DeadObjectException
- }
}
diff --git a/src/com/android/settings/location/LocationSettingsBase.java b/src/com/android/settings/location/LocationSettingsBase.java
index 741d607..1ea21b6 100644
--- a/src/com/android/settings/location/LocationSettingsBase.java
+++ b/src/com/android/settings/location/LocationSettingsBase.java
@@ -16,6 +16,7 @@
package com.android.settings.location;
+import android.app.ActivityManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -28,17 +29,14 @@
import com.android.settings.SettingsPreferenceFragment;
+import static com.android.settingslib.Utils.updateLocationMode;
+
/**
* A base class that listens to location settings change and modifies location
* settings.
*/
public abstract class LocationSettingsBase extends SettingsPreferenceFragment {
private static final String TAG = "LocationSettingsBase";
- /** Broadcast intent action when the location mode is about to change. */
- private static final String MODE_CHANGING_ACTION =
- "com.android.settings.location.MODE_CHANGING";
- private static final String CURRENT_MODE_KEY = "CURRENT_MODE";
- private static final String NEW_MODE_KEY = "NEW_MODE";
private int mCurrentMode;
private BroadcastReceiver mReceiver;
@@ -90,15 +88,6 @@
return um.hasUserRestriction(UserManager.DISALLOW_SHARE_LOCATION);
}
- public static boolean updateLocationMode(Context context, int oldMode, int newMode) {
- Intent intent = new Intent(MODE_CHANGING_ACTION);
- intent.putExtra(CURRENT_MODE_KEY, oldMode);
- intent.putExtra(NEW_MODE_KEY, newMode);
- context.sendBroadcast(intent, android.Manifest.permission.WRITE_SECURE_SETTINGS);
- return Settings.Secure.putInt(context.getContentResolver(), Settings.Secure.LOCATION_MODE,
- newMode);
- }
-
public void setLocationMode(int mode) {
Context context = getActivity();
if (isRestricted(context)) {
@@ -115,7 +104,7 @@
return;
}
- updateLocationMode(context, mCurrentMode, mode);
+ updateLocationMode(context, mCurrentMode, mode, ActivityManager.getCurrentUser());
refreshLocationMode();
}
diff --git a/src/com/android/settings/users/UserSettings.java b/src/com/android/settings/users/UserSettings.java
index bef2e9a..ec055f1 100644
--- a/src/com/android/settings/users/UserSettings.java
+++ b/src/com/android/settings/users/UserSettings.java
@@ -450,6 +450,10 @@
private void onUserCreated(int userId) {
mAddedUserId = userId;
mAddingUser = false;
+ if (!isResumed()) {
+ Log.w(TAG, "Cannot show dialog after onPause");
+ return;
+ }
if (mUserManager.getUserInfo(userId).isRestricted()) {
showDialog(DIALOG_SETUP_PROFILE);
} else {
diff --git a/tests/robotests/README.md b/tests/robotests/README.md
new file mode 100644
index 0000000..648f1af
--- /dev/null
+++ b/tests/robotests/README.md
@@ -0,0 +1,24 @@
+# Running Settings Robolectric tests
+
+
+## The full suite
+```
+$ croot
+$ make RunSettingsRoboTests
+```
+
+## Running a single test class
+
+```
+$ croot
+$ make RunSettingsRoboTests ROBOTEST_FILTER=<ClassName>
+```
+
+For example:
+
+```
+make RunSettingsRoboTests ROBOTEST_FILTER=CodeInspectionTest
+```
+
+You can also use partial class name in ROBOTEST_FILTER. If the partial class name matches
+multiple file names, all of them will be executed.