Merge "Fix bug #17459965 Take photo for Profile twice leads to "A resource was acquired at attached stack trace but never released" into lmp-dev
diff --git a/res/layout/bluetooth_device_settings.xml b/res/layout/bluetooth_device_settings.xml
index b87551a..b65ca0f 100644
--- a/res/layout/bluetooth_device_settings.xml
+++ b/res/layout/bluetooth_device_settings.xml
@@ -20,35 +20,9 @@
android:orientation="vertical"
android:gravity="center">
- <LinearLayout android:id="@+id/dialog_layout"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- android:paddingBottom="@dimen/bluetooth_dialog_padding"
- style="@style/bt_item" >
-
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/bluetooth_preference_paired_dialog_name_label"
- android:textAppearance="@android:style/TextAppearance.Material.Body1"
- android:textColor="?android:attr/textColorSecondary"
- android:textDirection="locale"
- style="@style/bt_item_label" />
-
- <EditText android:id="@+id/name"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:inputType="textNoSuggestions"
- android:maxLength="@integer/bluetooth_name_length"
- android:singleLine="true"
- style="@style/bt_item_edit_content" />
-
<fragment android:id="@+id/bluetooth_fragment_settings"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
class="com.android.settings.bluetooth.DeviceProfilesSettings" />
- </LinearLayout>
-
</LinearLayout>
diff --git a/res/layout/bluetooth_device_settings_header.xml b/res/layout/bluetooth_device_settings_header.xml
new file mode 100644
index 0000000..b1832c5
--- /dev/null
+++ b/res/layout/bluetooth_device_settings_header.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:gravity="center">
+
+ <LinearLayout android:id="@+id/dialog_layout"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:paddingBottom="@dimen/bluetooth_dialog_padding"
+ style="@style/bt_item" >
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/bluetooth_preference_paired_dialog_name_label"
+ android:textAppearance="@android:style/TextAppearance.Material.Body1"
+ android:textColor="?android:attr/textColorSecondary"
+ android:textDirection="locale"
+ style="@style/bt_item_label" />
+
+ <EditText android:id="@+id/name"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:inputType="textNoSuggestions"
+ android:maxLength="@integer/bluetooth_name_length"
+ android:singleLine="true"
+ style="@style/bt_item_edit_content" />
+
+ </LinearLayout>
+
+</LinearLayout>
diff --git a/res/layout/bluetooth_preference_category.xml b/res/layout/bluetooth_preference_category.xml
index 59a3e87..2b9a29a 100644
--- a/res/layout/bluetooth_preference_category.xml
+++ b/res/layout/bluetooth_preference_category.xml
@@ -22,4 +22,5 @@
android:textAppearance="@android:style/TextAppearance.Material.Body1"
android:textColor="?android:attr/textColorSecondary"
android:paddingTop="16dip"
+ android:paddingStart="16dip"
android:paddingBottom="16dip" />
diff --git a/res/layout/edit_user_info_dialog_content.xml b/res/layout/edit_user_info_dialog_content.xml
index d23f6f5..4d76e13 100644
--- a/res/layout/edit_user_info_dialog_content.xml
+++ b/res/layout/edit_user_info_dialog_content.xml
@@ -26,7 +26,7 @@
android:layout_height="56dip"
android:layout_gravity="bottom"
android:layout_marginEnd="6dp"
- android:contentDescription="@null"
+ android:contentDescription="@string/user_image_photo_selector"
android:background="@*android:drawable/spinner_background_holo_dark"
android:scaleType="fitCenter"/>
diff --git a/res/layout/preference_progress_category.xml b/res/layout/preference_progress_category.xml
index 5859fbf..1776fec 100644
--- a/res/layout/preference_progress_category.xml
+++ b/res/layout/preference_progress_category.xml
@@ -31,6 +31,7 @@
android:background="@null"
android:id="@+android:id/title"
android:paddingStart="0dp"
+ android:paddingTop="6dp"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
@@ -40,6 +41,7 @@
<ProgressBar
android:id="@+id/scanning_progress"
android:text="@string/progress_scanning"
+ android:paddingTop="6dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index afbd5c6..0b5f58a 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -91,7 +91,6 @@
<dimen name="notification_app_icon_size">64dp</dimen>
<dimen name="notification_app_icon_badge_size">20dp</dimen>
<dimen name="notification_app_icon_badge_margin">4dp</dimen>
- <dimen name="zen_mode_dropdown_width">160dp</dimen>
<dimen name="zen_downtime_checkbox_padding">7dp</dimen>
<dimen name="zen_downtime_margin">17dp</dimen>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 14d81df..e054423 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -5479,6 +5479,8 @@
<string name="user_image_take_photo" msgid="7496128293167402354">Take photo</string>
<!-- An option in a photo selection dialog, if there is no photo yet [CHAR LIMIT=50] -->
<string name="user_image_choose_photo" msgid="3746334626214970837">Choose photo from Gallery</string>
+ <!-- Accessibility message for the photo selector which is a button/popup with the current photo [CHAR LIMIT=50] -->
+ <string name="user_image_photo_selector">Select photo</string>
<!-- Text to display in regulatory info screen (from device overlay). -->
<string name="regulatory_info_text"></string>
diff --git a/src/com/android/settings/ConfirmLockPassword.java b/src/com/android/settings/ConfirmLockPassword.java
index 54acf73..a89d718 100644
--- a/src/com/android/settings/ConfirmLockPassword.java
+++ b/src/com/android/settings/ConfirmLockPassword.java
@@ -72,6 +72,8 @@
public static class ConfirmLockPasswordFragment extends Fragment implements OnClickListener,
OnEditorActionListener, TextWatcher {
+ private static final String KEY_NUM_WRONG_CONFIRM_ATTEMPTS
+ = "confirm_lock_password_fragment.key_num_wrong_confirm_attempts";
private static final long ERROR_MESSAGE_TIMEOUT = 3000;
private TextView mPasswordEntry;
private LockPatternUtils mLockPatternUtils;
@@ -93,6 +95,10 @@
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mLockPatternUtils = new LockPatternUtils(getActivity());
+ if (savedInstanceState != null) {
+ mNumWrongConfirmAttempts = savedInstanceState.getInt(
+ KEY_NUM_WRONG_CONFIRM_ATTEMPTS, 0);
+ }
}
@Override
@@ -166,6 +172,12 @@
}
}
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ outState.putInt(KEY_NUM_WRONG_CONFIRM_ATTEMPTS, mNumWrongConfirmAttempts);
+ }
+
private void handleNext() {
final String pin = mPasswordEntry.getText().toString();
if (mLockPatternUtils.checkPassword(pin)) {
diff --git a/src/com/android/settings/bluetooth/BluetoothSettings.java b/src/com/android/settings/bluetooth/BluetoothSettings.java
index a084137..1282409 100755
--- a/src/com/android/settings/bluetooth/BluetoothSettings.java
+++ b/src/com/android/settings/bluetooth/BluetoothSettings.java
@@ -44,6 +44,7 @@
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
+import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.TextView;
@@ -322,7 +323,6 @@
mMyDevicePreference.setSummary(getResources().getString(
R.string.bluetooth_is_visible_message, mLocalAdapter.getName()));
mMyDevicePreference.setSelectable(false);
- mMyDevicePreference.setEnabled(false);
preferenceScreen.addPreference(mMyDevicePreference);
getActivity().invalidateOptionsMenu();
@@ -401,11 +401,17 @@
parent.removeView(mSettingsDialogView);
}
}
+
if (profileFrag == null) {
LayoutInflater inflater = getActivity().getLayoutInflater();
mSettingsDialogView = inflater.inflate(R.layout.bluetooth_device_settings, null);
profileFrag = (DeviceProfilesSettings)activity.getFragmentManager()
.findFragmentById(R.id.bluetooth_fragment_settings);
+
+ // To enable scrolling we store the name field in a seperate header and add to
+ // the ListView of the profileFrag.
+ View header = inflater.inflate(R.layout.bluetooth_device_settings_header, null);
+ profileFrag.getListView().addHeaderView(header);
}
final View dialogLayout = mSettingsDialogView;
@@ -439,6 +445,10 @@
AlertDialog dialog = settingsDialog.create();
dialog.create();
dialog.show();
+
+ // We must ensure that clicking on the EditText will bring up the keyboard.
+ dialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+ | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
}
};
diff --git a/src/com/android/settings/bluetooth/HidProfile.java b/src/com/android/settings/bluetooth/HidProfile.java
index 8df2845..91e715d 100755
--- a/src/com/android/settings/bluetooth/HidProfile.java
+++ b/src/com/android/settings/bluetooth/HidProfile.java
@@ -169,7 +169,7 @@
public int getDrawableResource(BluetoothClass btClass) {
if (btClass == null) {
- return R.drawable.ic_bt_keyboard_hid;
+ return R.drawable.ic_lockscreen_ime;
}
return getHidClassDrawable(btClass);
}
@@ -178,7 +178,7 @@
switch (btClass.getDeviceClass()) {
case BluetoothClass.Device.PERIPHERAL_KEYBOARD:
case BluetoothClass.Device.PERIPHERAL_KEYBOARD_POINTING:
- return R.drawable.ic_bt_keyboard_hid;
+ return R.drawable.ic_lockscreen_ime;
case BluetoothClass.Device.PERIPHERAL_POINTING:
return R.drawable.ic_bt_pointing_hid;
default:
diff --git a/src/com/android/settings/notification/SettingPref.java b/src/com/android/settings/notification/SettingPref.java
index de01def..a06c35a 100644
--- a/src/com/android/settings/notification/SettingPref.java
+++ b/src/com/android/settings/notification/SettingPref.java
@@ -33,15 +33,15 @@
public static final int TYPE_GLOBAL = 1;
public static final int TYPE_SYSTEM = 2;
- private final int mType;
+ protected final int mType;
private final String mKey;
- private final String mSetting;
- private final int mDefault;
+ protected final String mSetting;
+ protected final int mDefault;
private final int[] mValues;
private final Uri mUri;
- private TwoStatePreference mTwoState;
- private DropDownPreference mDropDown;
+ protected TwoStatePreference mTwoState;
+ protected DropDownPreference mDropDown;
public SettingPref(int type, String key, String setting, int def, int... values) {
mType = type;
@@ -129,7 +129,7 @@
throw new IllegalArgumentException();
}
- private static boolean putInt(int type, ContentResolver cr, String setting, int value) {
+ protected static boolean putInt(int type, ContentResolver cr, String setting, int value) {
switch(type) {
case TYPE_GLOBAL:
return Global.putInt(cr, setting, value);
@@ -139,7 +139,7 @@
throw new IllegalArgumentException();
}
- private static int getInt(int type, ContentResolver cr, String setting, int def) {
+ protected static int getInt(int type, ContentResolver cr, String setting, int def) {
switch(type) {
case TYPE_GLOBAL:
return Global.getInt(cr, setting, def);
diff --git a/src/com/android/settings/notification/ZenModeConditionSelection.java b/src/com/android/settings/notification/ZenModeConditionSelection.java
index 610baba..856a7f6 100644
--- a/src/com/android/settings/notification/ZenModeConditionSelection.java
+++ b/src/com/android/settings/notification/ZenModeConditionSelection.java
@@ -19,13 +19,13 @@
import android.animation.LayoutTransition;
import android.app.INotificationManager;
import android.content.Context;
-import android.net.Uri;
import android.os.Handler;
import android.os.Message;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.service.notification.Condition;
import android.service.notification.IConditionListener;
+import android.service.notification.ZenModeConfig;
import android.util.Log;
import android.widget.CompoundButton;
import android.widget.RadioButton;
@@ -33,6 +33,9 @@
import com.android.settings.R;
+import java.util.ArrayList;
+import java.util.List;
+
public class ZenModeConditionSelection extends RadioGroup {
private static final String TAG = "ZenModeConditionSelection";
private static final boolean DEBUG = true;
@@ -40,18 +43,24 @@
private final INotificationManager mNoMan;
private final H mHandler = new H();
private final Context mContext;
+ private final List<Condition> mConditions;
+ private Condition mCondition;
public ZenModeConditionSelection(Context context) {
super(context);
mContext = context;
+ mConditions = new ArrayList<Condition>();
setLayoutTransition(new LayoutTransition());
final int p = mContext.getResources().getDimensionPixelSize(R.dimen.content_margin_left);
setPadding(p, p, p, 0);
mNoMan = INotificationManager.Stub.asInterface(
ServiceManager.getService(Context.NOTIFICATION_SERVICE));
final RadioButton b = newRadioButton(null);
- b.setText(R.string.zen_mode_default_option);
+ b.setText(mContext.getString(com.android.internal.R.string.zen_mode_forever));
b.setChecked(true);
+ for (int i = ZenModeConfig.MINUTE_BUCKETS.length - 1; i >= 0; --i) {
+ handleCondition(ZenModeConfig.toTimeCondition(ZenModeConfig.MINUTE_BUCKETS[i]));
+ }
}
private RadioButton newRadioButton(Condition condition) {
@@ -61,7 +70,7 @@
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
- handleSubscribe((Condition) button.getTag());
+ setCondition((Condition) button.getTag());
}
}
});
@@ -91,24 +100,35 @@
}
protected void handleConditions(Condition[] conditions) {
- for (final Condition c : conditions) {
- RadioButton v = (RadioButton) findViewWithTag(c.id);
- if (c.state == Condition.STATE_TRUE || c.state == Condition.STATE_UNKNOWN) {
- if (v == null) {
- v = newRadioButton(c);
- }
- }
- if (v != null) {
- v.setText(c.summary);
- v.setEnabled(c.state == Condition.STATE_TRUE);
- }
+ for (Condition c : conditions) {
+ handleCondition(c);
}
}
- protected void handleSubscribe(Condition c) {
- if (DEBUG) Log.d(TAG, "handleSubscribe " + c);
+ protected void handleCondition(Condition c) {
+ if (mConditions.contains(c)) return;
+ RadioButton v = (RadioButton) findViewWithTag(c.id);
+ if (c.state == Condition.STATE_TRUE || c.state == Condition.STATE_UNKNOWN) {
+ if (v == null) {
+ v = newRadioButton(c);
+ }
+ }
+ if (v != null) {
+ v.setText(c.summary);
+ v.setEnabled(c.state == Condition.STATE_TRUE);
+ }
+ mConditions.add(c);
+ }
+
+ protected void setCondition(Condition c) {
+ if (DEBUG) Log.d(TAG, "setCondition " + c);
+ mCondition = c;
+ }
+
+ public void confirmCondition() {
+ if (DEBUG) Log.d(TAG, "confirmCondition " + mCondition);
try {
- mNoMan.setZenModeCondition(c);
+ mNoMan.setZenModeCondition(mCondition);
} catch (RemoteException e) {
// noop
}
@@ -127,7 +147,7 @@
@Override
public void handleMessage(Message msg) {
- if (msg.what == CONDITIONS) handleConditions((Condition[])msg.obj);
+ if (msg.what == CONDITIONS) handleConditions((Condition[]) msg.obj);
}
}
}
diff --git a/src/com/android/settings/notification/ZenModeSettings.java b/src/com/android/settings/notification/ZenModeSettings.java
index 9ea3c93..091e121 100644
--- a/src/com/android/settings/notification/ZenModeSettings.java
+++ b/src/com/android/settings/notification/ZenModeSettings.java
@@ -46,11 +46,13 @@
import android.text.format.DateFormat;
import android.util.Log;
import android.util.SparseArray;
+import android.widget.ScrollView;
import android.widget.TimePicker;
import com.android.settings.R;
import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.Utils;
+import com.android.settings.notification.DropDownPreference.Callback;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
import com.android.settings.search.SearchIndexableRaw;
@@ -81,9 +83,10 @@
private static final String KEY_ENTRY = "entry";
private static final String KEY_CONDITION_PROVIDERS = "manage_condition_providers";
- private static final SettingPref PREF_ZEN_MODE = new SettingPref(SettingPref.TYPE_GLOBAL,
- KEY_ZEN_MODE, Global.ZEN_MODE, Global.ZEN_MODE_OFF, Global.ZEN_MODE_OFF,
- Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, Global.ZEN_MODE_NO_INTERRUPTIONS) {
+ private static final SettingPrefWithCallback PREF_ZEN_MODE = new SettingPrefWithCallback(
+ SettingPref.TYPE_GLOBAL, KEY_ZEN_MODE, Global.ZEN_MODE, Global.ZEN_MODE_OFF,
+ Global.ZEN_MODE_OFF, Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS,
+ Global.ZEN_MODE_NO_INTERRUPTIONS) {
protected String getCaption(Resources res, int value) {
switch (value) {
case Global.ZEN_MODE_NO_INTERRUPTIONS:
@@ -135,6 +138,7 @@
private PreferenceCategory mAutomationCategory;
private Preference mEntry;
private Preference mConditionProviders;
+ private AlertDialog mDialog;
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -149,6 +153,14 @@
if (DEBUG) Log.d(TAG, "Loaded mConfig=" + mConfig);
final Preference zenMode = PREF_ZEN_MODE.init(this);
+ PREF_ZEN_MODE.setCallback(new SettingPrefWithCallback.Callback() {
+ @Override
+ public void onSettingSelected(int value) {
+ if (value != Global.ZEN_MODE_OFF) {
+ showConditionSelection(value);
+ }
+ }
+ });
if (!Utils.isVoiceCapable(mContext)) {
zenMode.setTitle(R.string.zen_mode_option_title_novoice);
}
@@ -190,7 +202,6 @@
});
mStarred = (DropDownPreference) important.findPreference(KEY_STARRED);
- mStarred.setDropDownWidth(R.dimen.zen_mode_dropdown_width);
mStarred.addItem(R.string.zen_mode_from_anyone, ZenModeConfig.SOURCE_ANYONE);
mStarred.addItem(R.string.zen_mode_from_starred, ZenModeConfig.SOURCE_STAR);
mStarred.addItem(R.string.zen_mode_from_contacts, ZenModeConfig.SOURCE_CONTACT);
@@ -467,8 +478,44 @@
Global.putInt(getContentResolver(), Global.ZEN_MODE, value);
}
- protected ZenModeConditionSelection newConditionSelection() {
- return new ZenModeConditionSelection(mContext);
+ protected void showConditionSelection(final int newSettingsValue) {
+ if (mDialog != null) return;
+
+ final ZenModeConditionSelection zenModeConditionSelection =
+ new ZenModeConditionSelection(mContext);
+ DialogInterface.OnClickListener positiveListener = new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ zenModeConditionSelection.confirmCondition();
+ mDialog = null;
+ }
+ };
+ final int oldSettingsValue = PREF_ZEN_MODE.getValue(mContext);
+ ScrollView scrollView = new ScrollView(mContext);
+ scrollView.addView(zenModeConditionSelection);
+ mDialog = new AlertDialog.Builder(getActivity())
+ .setTitle(PREF_ZEN_MODE.getCaption(getResources(), newSettingsValue))
+ .setView(scrollView)
+ .setPositiveButton(R.string.okay, positiveListener)
+ .setNegativeButton(R.string.cancel_all_caps, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ cancelDialog(oldSettingsValue);
+ }
+ })
+ .setOnCancelListener(new DialogInterface.OnCancelListener() {
+ @Override
+ public void onCancel(DialogInterface dialog) {
+ cancelDialog(oldSettingsValue);
+ }
+ }).create();
+ mDialog.show();
+ }
+
+ protected void cancelDialog(int oldSettingsValue) {
+ // If not making a decision, reset drop down to current setting.
+ PREF_ZEN_MODE.setValueWithoutCallback(mContext, oldSettingsValue);
+ mDialog = null;
}
// Enable indexing of searchable data
@@ -499,6 +546,60 @@
}
};
+ private static class SettingPrefWithCallback extends SettingPref {
+
+ private Callback mCallback;
+ private int mValue;
+
+ public SettingPrefWithCallback(int type, String key, String setting, int def,
+ int... values) {
+ super(type, key, setting, def, values);
+ }
+
+ public void setCallback(Callback callback) {
+ mCallback = callback;
+ }
+
+ @Override
+ public void update(Context context) {
+ // Avoid callbacks from non-user changes.
+ mValue = getValue(context);
+ super.update(context);
+ }
+
+ @Override
+ protected boolean setSetting(Context context, int value) {
+ if (value == mValue) return true;
+ mValue = value;
+ if (mCallback != null) {
+ mCallback.onSettingSelected(value);
+ }
+ return super.setSetting(context, value);
+ }
+
+ @Override
+ public Preference init(SettingsPreferenceFragment settings) {
+ Preference ret = super.init(settings);
+ mValue = getValue(settings.getActivity());
+
+ return ret;
+ }
+
+ public boolean setValueWithoutCallback(Context context, int value) {
+ // Set the current value ahead of time, this way we won't trigger a callback.
+ mValue = value;
+ return putInt(mType, context.getContentResolver(), mSetting, value);
+ }
+
+ public int getValue(Context context) {
+ return getInt(mType, context.getContentResolver(), mSetting, mDefault);
+ }
+
+ public interface Callback {
+ void onSettingSelected(int value);
+ }
+ }
+
private final class SettingsObserver extends ContentObserver {
private final Uri ZEN_MODE_URI = Global.getUriFor(Global.ZEN_MODE);
private final Uri ZEN_MODE_CONFIG_ETAG_URI = Global.getUriFor(Global.ZEN_MODE_CONFIG_ETAG);