diff options
Diffstat (limited to 'src/com/android/settings')
-rw-r--r-- | src/com/android/settings/CryptKeeper.java | 77 | ||||
-rw-r--r-- | src/com/android/settings/DateTimeSettings.java | 50 | ||||
-rw-r--r-- | src/com/android/settings/IccLockSettings.java | 74 | ||||
-rw-r--r-- | src/com/android/settings/fuelgauge/BatteryHistoryChart.java | 26 | ||||
-rw-r--r-- | src/com/android/settings/sim/SimBootReceiver.java | 142 | ||||
-rw-r--r-- | src/com/android/settings/sim/SimSettings.java | 96 |
6 files changed, 336 insertions, 129 deletions
diff --git a/src/com/android/settings/CryptKeeper.java b/src/com/android/settings/CryptKeeper.java index 33fa9fd..f386abb 100644 --- a/src/com/android/settings/CryptKeeper.java +++ b/src/com/android/settings/CryptKeeper.java @@ -88,17 +88,15 @@ public class CryptKeeper extends Activity implements TextView.OnEditorActionList private static final String TAG = "CryptKeeper"; private static final String DECRYPT_STATE = "trigger_restart_framework"; + /** Message sent to us to indicate encryption update progress. */ private static final int MESSAGE_UPDATE_PROGRESS = 1; - /** Message sent to us to cool-down (waste user's time between password attempts) */ - private static final int MESSAGE_COOLDOWN = 2; /** Message sent to us to indicate alerting the user that we are waiting for password entry */ - private static final int MESSAGE_NOTIFY = 3; + private static final int MESSAGE_NOTIFY = 2; // Constants used to control policy. - private static final int MAX_FAILED_ATTEMPTS = 30; + private static final int MAX_FAILED_ATTEMPTS = 100; private static final int COOL_DOWN_ATTEMPTS = 10; - private static final int COOL_DOWN_INTERVAL = 30; // 30 seconds // Intent action for launching the Emergency Dialer activity. static final String ACTION_EMERGENCY_DIAL = "com.android.phone.EmergencyDialer.DIAL"; @@ -119,7 +117,10 @@ public class CryptKeeper extends Activity implements TextView.OnEditorActionList private boolean mCorrupt; /** A flag to indicate when the back event should be ignored */ private boolean mIgnoreBack = false; - private int mCooldown; + /** When set, blocks unlocking. Set every COOL_DOWN_ATTEMPTS attempts, only cleared + by power cycling phone. */ + private boolean mCooldown = false; + PowerManager.WakeLock mWakeLock; private EditText mPasswordEntry; private LockPatternView mLockPatternView; @@ -138,6 +139,7 @@ public class CryptKeeper extends Activity implements TextView.OnEditorActionList // When the user enters a short pin/password, run this to show an error, // but don't count it against attempts. private final Runnable mFakeUnlockAttemptRunnable = new Runnable() { + @Override public void run() { handleBadAttempt(1 /* failedAttempt */); } @@ -235,7 +237,9 @@ public class CryptKeeper extends Activity implements TextView.OnEditorActionList mLockPatternView.postDelayed(mClearPatternRunnable, WRONG_PATTERN_CLEAR_TIMEOUT_MS); } if ((failedAttempts % COOL_DOWN_ATTEMPTS) == 0) { - mCooldown = COOL_DOWN_INTERVAL; + mCooldown = true; + // No need to setBackFunctionality(false) - it's already done + // at this point. cooldown(); } else { final TextView status = (TextView) findViewById(R.id.status); @@ -322,10 +326,6 @@ public class CryptKeeper extends Activity implements TextView.OnEditorActionList updateProgress(); break; - case MESSAGE_COOLDOWN: - cooldown(); - break; - case MESSAGE_NOTIFY: notifyUser(); break; @@ -495,7 +495,7 @@ public class CryptKeeper extends Activity implements TextView.OnEditorActionList @Override public void onPostExecute(java.lang.Void v) { - if(passwordType == StorageManager.CRYPT_TYPE_PIN) { + if (passwordType == StorageManager.CRYPT_TYPE_PIN) { setContentView(R.layout.crypt_keeper_pin_entry); mStatusString = R.string.enter_pin; } else if (passwordType == StorageManager.CRYPT_TYPE_PATTERN) { @@ -518,11 +518,12 @@ public class CryptKeeper extends Activity implements TextView.OnEditorActionList if (mLockPatternView != null) { mLockPatternView.setInStealthMode(!pattern_visible); } - - if (mCooldown > 0) { + if (mCooldown) { + // in case we are cooling down and coming back from emergency dialler setBackFunctionality(false); - cooldown(); // in case we are cooling down and coming back from emergency dialler + cooldown(); } + } }.execute(); } else if (!mValidationRequested) { @@ -535,7 +536,6 @@ public class CryptKeeper extends Activity implements TextView.OnEditorActionList @Override public void onStop() { super.onStop(); - mHandler.removeMessages(MESSAGE_COOLDOWN); mHandler.removeMessages(MESSAGE_UPDATE_PROGRESS); mHandler.removeMessages(MESSAGE_NOTIFY); } @@ -672,39 +672,20 @@ public class CryptKeeper extends Activity implements TextView.OnEditorActionList mHandler.sendEmptyMessageDelayed(MESSAGE_UPDATE_PROGRESS, 1000); } - /** Disable password input for a while to force the user to waste time between retries */ + /** Insist on a power cycle to force the user to waste time between retries. + * + * Call setBackFunctionality(false) before calling this. */ private void cooldown() { - final TextView status = (TextView) findViewById(R.id.status); - - if (mCooldown <= 0) { - // Re-enable the password entry and back presses. - if (mPasswordEntry != null) { - mPasswordEntry.setEnabled(true); - final InputMethodManager imm = (InputMethodManager) getSystemService( - Context.INPUT_METHOD_SERVICE); - imm.showSoftInput(mPasswordEntry, 0); - setBackFunctionality(true); - } - if (mLockPatternView != null) { - mLockPatternView.setEnabled(true); - } - status.setText(mStatusString); - } else { - // Disable the password entry and back presses. - if (mPasswordEntry != null) { - mPasswordEntry.setEnabled(false); - } - if (mLockPatternView != null) { - mLockPatternView.setEnabled(false); - } - - CharSequence template = getText(R.string.crypt_keeper_cooldown); - status.setText(TextUtils.expandTemplate(template, Integer.toString(mCooldown))); - - mCooldown--; - mHandler.removeMessages(MESSAGE_COOLDOWN); - mHandler.sendEmptyMessageDelayed(MESSAGE_COOLDOWN, 1000); // Tick every second + // Disable the password entry. + if (mPasswordEntry != null) { + mPasswordEntry.setEnabled(false); + } + if (mLockPatternView != null) { + mLockPatternView.setEnabled(false); } + + final TextView status = (TextView) findViewById(R.id.status); + status.setText(R.string.crypt_keeper_force_power_cycle); } /** @@ -810,7 +791,7 @@ public class CryptKeeper extends Activity implements TextView.OnEditorActionList // Asynchronously throw up the IME, since there are issues with requesting it to be shown // immediately. - if (mLockPatternView == null && mCooldown <= 0) { + if (mLockPatternView == null && !mCooldown) { mHandler.postDelayed(new Runnable() { @Override public void run() { imm.showSoftInputUnchecked(0, null); diff --git a/src/com/android/settings/DateTimeSettings.java b/src/com/android/settings/DateTimeSettings.java index f34008d..6f41fd5 100644 --- a/src/com/android/settings/DateTimeSettings.java +++ b/src/com/android/settings/DateTimeSettings.java @@ -59,7 +59,6 @@ public class DateTimeSettings extends SettingsPreferenceFragment // The date value is dummy (independent of actual date). private Calendar mDummyDate; - private static final String KEY_DATE_FORMAT = "date_format"; private static final String KEY_AUTO_TIME = "auto_time"; private static final String KEY_AUTO_TIME_ZONE = "auto_zone"; @@ -75,7 +74,6 @@ public class DateTimeSettings extends SettingsPreferenceFragment private SwitchPreference mAutoTimeZonePref; private Preference mTimeZone; private Preference mDatePref; - private ListPreference mDateFormat; @Override public void onCreate(Bundle icicle) { @@ -121,41 +119,10 @@ public class DateTimeSettings extends SettingsPreferenceFragment mTime24Pref = findPreference("24 hour"); mTimeZone = findPreference("timezone"); mDatePref = findPreference("date"); - mDateFormat = (ListPreference) findPreference(KEY_DATE_FORMAT); if (isFirstRun) { getPreferenceScreen().removePreference(mTime24Pref); - getPreferenceScreen().removePreference(mDateFormat); } - String [] dateFormats = getResources().getStringArray(R.array.date_format_values); - String [] formattedDates = new String[dateFormats.length]; - String currentFormat = getDateFormat(); - // Initialize if DATE_FORMAT is not set in the system settings - // This can happen after a factory reset (or data wipe) - if (currentFormat == null) { - currentFormat = ""; - } - - // Prevents duplicated values on date format selector. - mDummyDate.set(mDummyDate.get(Calendar.YEAR), mDummyDate.DECEMBER, 31, 13, 0, 0); - - for (int i = 0; i < formattedDates.length; i++) { - String formatted = - DateFormat.getDateFormatForSetting(getActivity(), dateFormats[i]) - .format(mDummyDate.getTime()); - - if (dateFormats[i].length() == 0) { - formattedDates[i] = getResources(). - getString(R.string.normal_date_format, formatted); - } else { - formattedDates[i] = formatted; - } - } - - mDateFormat.setEntries(formattedDates); - mDateFormat.setEntryValues(R.array.date_format_values); - mDateFormat.setValue(currentFormat); - mTimePref.setEnabled(!autoTimeEnabled); mDatePref.setEnabled(!autoTimeEnabled); mTimeZone.setEnabled(!autoTimeZoneEnabled); @@ -189,17 +156,15 @@ public class DateTimeSettings extends SettingsPreferenceFragment } public void updateTimeAndDateDisplay(Context context) { - java.text.DateFormat shortDateFormat = DateFormat.getDateFormat(context); final Calendar now = Calendar.getInstance(); mDummyDate.setTimeZone(now.getTimeZone()); // We use December 31st because it's unambiguous when demonstrating the date format. // We use 13:00 so we can demonstrate the 12/24 hour options. mDummyDate.set(now.get(Calendar.YEAR), 11, 31, 13, 0, 0); Date dummyDate = mDummyDate.getTime(); + mDatePref.setSummary(DateFormat.getLongDateFormat(context).format(now.getTime())); mTimePref.setSummary(DateFormat.getTimeFormat(getActivity()).format(now.getTime())); mTimeZone.setSummary(getTimeZoneText(now.getTimeZone(), true)); - mDatePref.setSummary(shortDateFormat.format(now.getTime())); - mDateFormat.setSummary(shortDateFormat.format(dummyDate)); mTime24Pref.setSummary(DateFormat.getTimeFormat(getActivity()).format(dummyDate)); } @@ -227,13 +192,7 @@ public class DateTimeSettings extends SettingsPreferenceFragment @Override public void onSharedPreferenceChanged(SharedPreferences preferences, String key) { - if (key.equals(KEY_DATE_FORMAT)) { - String format = preferences.getString(key, - getResources().getString(R.string.default_date_format)); - Settings.System.putString(getContentResolver(), - Settings.System.DATE_FORMAT, format); - updateTimeAndDateDisplay(getActivity()); - } else if (key.equals(KEY_AUTO_TIME)) { + if (key.equals(KEY_AUTO_TIME)) { boolean autoEnabled = preferences.getBoolean(key, true); Settings.Global.putInt(getContentResolver(), Settings.Global.AUTO_TIME, autoEnabled ? 1 : 0); @@ -350,11 +309,6 @@ public class DateTimeSettings extends SettingsPreferenceFragment is24Hour? HOURS_24 : HOURS_12); } - private String getDateFormat() { - return Settings.System.getString(getContentResolver(), - Settings.System.DATE_FORMAT); - } - private boolean getAutoState(String name) { try { return Settings.Global.getInt(getContentResolver(), name) > 0; diff --git a/src/com/android/settings/IccLockSettings.java b/src/com/android/settings/IccLockSettings.java index b988572..d8744cc 100644 --- a/src/com/android/settings/IccLockSettings.java +++ b/src/com/android/settings/IccLockSettings.java @@ -29,13 +29,26 @@ import android.preference.CheckBoxPreference; import android.preference.Preference; import android.preference.PreferenceActivity; import android.preference.PreferenceScreen; +import android.telephony.SubscriptionInfo; +import android.telephony.SubscriptionManager; +import android.telephony.TelephonyManager; import android.util.Log; +import android.view.View; +import android.widget.ListView; +import android.widget.TabHost; +import android.widget.TabHost.OnTabChangeListener; +import android.widget.TabHost.TabContentFactory; +import android.widget.TabHost.TabSpec; +import android.widget.TabWidget; import android.widget.Toast; import com.android.internal.telephony.Phone; import com.android.internal.telephony.PhoneFactory; import com.android.internal.telephony.TelephonyIntents; +import java.util.ArrayList; +import java.util.List; + /** * Implements the preference screen to enable/disable ICC lock and * also the dialogs to change the ICC PIN. In the former case, enabling/disabling @@ -86,6 +99,10 @@ public class IccLockSettings extends PreferenceActivity // Are we trying to enable or disable ICC lock? private boolean mToState; + private TabHost mTabHost; + private TabWidget mTabWidget; + private ListView mListView; + private Phone mPhone; private EditPinPreference mPinDialog; @@ -143,6 +160,10 @@ public class IccLockSettings extends PreferenceActivity @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + final Context context = getApplicationContext(); + final TelephonyManager tm = + (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); + final int numSims = tm.getSimCount(); if (Utils.isMonkeyRunning()) { finish(); @@ -182,13 +203,38 @@ public class IccLockSettings extends PreferenceActivity // Don't need any changes to be remembered getPreferenceScreen().setPersistent(false); + if (numSims > 1) { + setContentView(R.layout.icc_lock_tabs); + + mTabHost = (TabHost) findViewById(android.R.id.tabhost); + mTabWidget = (TabWidget) findViewById(android.R.id.tabs); + mListView = (ListView) findViewById(android.R.id.list); + + mTabHost.setup(); + mTabHost.setOnTabChangedListener(mTabListener); + mTabHost.clearAllTabs(); + + for (int i = 0; i < numSims; ++i) { + final SubscriptionInfo subInfo = Utils.findRecordBySlotId(i); + mTabHost.addTab(buildTabSpec(String.valueOf(i), + String.valueOf(subInfo == null + ? context.getString(R.string.sim_editor_title, i + 1) + : subInfo.getDisplayName()))); + } + } + mPhone = PhoneFactory.getDefaultPhone(); mRes = getResources(); updatePreferences(); } private void updatePreferences() { - mPinToggle.setChecked(mPhone.getIccCard().getIccLockEnabled()); + mPinDialog.setEnabled(mPhone != null); + mPinToggle.setEnabled(mPhone != null); + + if (mPhone != null) { + mPinToggle.setChecked(mPhone.getIccCard().getIccLockEnabled()); + } } @Override @@ -418,4 +464,30 @@ public class IccLockSettings extends PreferenceActivity setDialogValues(); mDialogState = OFF_MODE; } + + private OnTabChangeListener mTabListener = new OnTabChangeListener() { + @Override + public void onTabChanged(String tabId) { + final int slotId = Integer.parseInt(tabId); + final SubscriptionInfo sir = Utils.findRecordBySlotId(slotId); + + mPhone = (sir == null) ? null + : PhoneFactory.getPhone(SubscriptionManager.getPhoneId(sir.getSubscriptionId())); + + // The User has changed tab; update the body. + updatePreferences(); + } + }; + + private TabContentFactory mEmptyTabContent = new TabContentFactory() { + @Override + public View createTabContent(String tag) { + return new View(mTabHost.getContext()); + } + }; + + private TabSpec buildTabSpec(String tag, String title) { + return mTabHost.newTabSpec(tag).setIndicator(title).setContent( + mEmptyTabContent); + } } diff --git a/src/com/android/settings/fuelgauge/BatteryHistoryChart.java b/src/com/android/settings/fuelgauge/BatteryHistoryChart.java index 78e3c6d..3312162 100644 --- a/src/com/android/settings/fuelgauge/BatteryHistoryChart.java +++ b/src/com/android/settings/fuelgauge/BatteryHistoryChart.java @@ -667,33 +667,11 @@ public class BatteryHistoryChart extends View { } private boolean isDayFirst() { - String value = Settings.System.getString(mContext.getContentResolver(), - Settings.System.DATE_FORMAT); - if (value == null) { - LocaleData d = LocaleData.get(mContext.getResources().getConfiguration().locale); - value = d.shortDateFormat4; - } + LocaleData d = LocaleData.get(mContext.getResources().getConfiguration().locale); + String value = d.shortDateFormat4; return value.indexOf('M') > value.indexOf('d'); } - /* - private void buildTime() { - java.text.DateFormat shortDateFormat = DateFormat.getDateFormat(context); - final Calendar now = Calendar.getInstance(); - mDummyDate.setTimeZone(now.getTimeZone()); - // We use December 31st because it's unambiguous when demonstrating the date format. - // We use 13:00 so we can demonstrate the 12/24 hour options. - mDummyDate.set(now.get(Calendar.YEAR), 11, 31, 13, 0, 0); - Date dummyDate = mDummyDate.getTime(); - mTimePref.setSummary(DateFormat.getTimeFormat(getActivity()).format(now.getTime())); - mTimeZone.setSummary(getTimeZoneText(now.getTimeZone(), true)); - mDatePref.setSummary(shortDateFormat.format(now.getTime())); - mDateFormat.setSummary(shortDateFormat.format(dummyDate)); - mTime24Pref.setSummary(DateFormat.getTimeFormat(getActivity()).format(dummyDate)); - - } - */ - @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); diff --git a/src/com/android/settings/sim/SimBootReceiver.java b/src/com/android/settings/sim/SimBootReceiver.java new file mode 100644 index 0000000..2d9d15e --- /dev/null +++ b/src/com/android/settings/sim/SimBootReceiver.java @@ -0,0 +1,142 @@ +/* + * 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.sim; + +import com.android.settings.R; +import com.android.settings.Settings.SimSettingsActivity; + +import java.util.List; + +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.SharedPreferences.Editor; +import android.content.res.Resources; +import android.support.v4.app.NotificationCompat; +import android.telephony.SubscriptionInfo; +import android.telephony.SubscriptionListener; +import android.telephony.SubscriptionManager; +import android.telephony.TelephonyManager; +import android.util.Log; + +import com.android.settings.Utils; + +public class SimBootReceiver extends BroadcastReceiver { + private static final int SLOT_EMPTY = -1; + private static final int NOTIFICATION_ID = 1; + private static final String SHARED_PREFERENCES_NAME = "sim_state"; + private static final String SLOT_PREFIX = "sim_slot_"; + + private SharedPreferences mSharedPreferences = null; + private TelephonyManager mTelephonyManager; + private Context mContext; + + @Override + public void onReceive(Context context, Intent intent) { + mTelephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); + mContext = context; + mSharedPreferences = mContext.getSharedPreferences(SHARED_PREFERENCES_NAME, + Context.MODE_PRIVATE); + + SubscriptionManager.register(mContext, mSubscriptionListener, + SubscriptionListener.LISTEN_SUBSCRIPTION_INFO_LIST_CHANGED); + } + + private void detectChangeAndNotify() { + final int numSlots = mTelephonyManager.getSimCount(); + + // Do not create notifications on single SIM devices. + if (numSlots < 2) { + return; + } + + // We wait until SubscriptionManager returns a valid list of Subscription informations + // by checking if the list is empty. + // This is not completely correct, but works for most cases. + // See Bug: 18377252 + if (SubscriptionManager.getActiveSubscriptionInfoList().size() < 1) { + return; + } + + for (int i = 0; i < numSlots; i++) { + final SubscriptionInfo sir = Utils.findRecordBySlotId(i); + final String key = SLOT_PREFIX+i; + final int lastSubId = getLastSubId(key); + + if (sir != null) { + final int currentSubId = sir.getSubscriptionId(); + if (lastSubId != currentSubId) { + createNotification(mContext); + setLastSubId(key, currentSubId); + } + } else if (lastSubId != SLOT_EMPTY) { + createNotification(mContext); + setLastSubId(key, SLOT_EMPTY); + } + } + } + + private int getLastSubId(String strSlotId) { + return mSharedPreferences.getInt(strSlotId, SLOT_EMPTY); + } + + private void setLastSubId(String strSlotId, int value) { + Editor editor = mSharedPreferences.edit(); + editor.putInt(strSlotId, value); + editor.commit(); + } + + private void createNotification(Context context){ + final Resources resources = context.getResources(); + + NotificationCompat.Builder builder = + new NotificationCompat.Builder(context) + .setSmallIcon(R.drawable.ic_sim_card_alert_white_48dp) + .setColor(resources.getColor(R.color.sim_noitification)) + .setContentTitle(resources.getString(R.string.sim_notification_title)) + .setContentText(resources.getString(R.string.sim_notification_summary)); + Intent resultIntent = new Intent(context, SimSettingsActivity.class); + resultIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + PendingIntent resultPendingIntent = + PendingIntent.getActivity( + context, + 0, + resultIntent, + PendingIntent.FLAG_CANCEL_CURRENT + ); + builder.setContentIntent(resultPendingIntent); + NotificationManager notificationManager = + (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); + notificationManager.notify(NOTIFICATION_ID, builder.build()); + } + + public static void cancelNotification(Context context) { + NotificationManager notificationManager = + (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); + notificationManager.cancel(NOTIFICATION_ID); + } + + private final SubscriptionListener mSubscriptionListener = new SubscriptionListener() { + @Override + public void onSubscriptionInfoChanged() { + detectChangeAndNotify(); + } + }; +} diff --git a/src/com/android/settings/sim/SimSettings.java b/src/com/android/settings/sim/SimSettings.java index c9ff731..e2f56cb 100644 --- a/src/com/android/settings/sim/SimSettings.java +++ b/src/com/android/settings/sim/SimSettings.java @@ -22,7 +22,10 @@ import android.content.ContentUris; import android.content.DialogInterface; import android.content.res.Resources; import android.database.Cursor; +import android.graphics.Paint; import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.ShapeDrawable; +import android.graphics.drawable.shapes.OvalShape; import android.net.Uri; import android.os.Bundle; import android.preference.Preference; @@ -129,6 +132,8 @@ public class SimSettings extends RestrictedSettingsFragment implements Indexable createPreferences(); updateAllOptions(); + + SimBootReceiver.cancelNotification(getActivity()); } private void createPreferences() { @@ -390,8 +395,10 @@ public class SimSettings extends RestrictedSettingsFragment implements Indexable private class SimPreference extends Preference{ private SubscriptionInfo mSubInfoRecord; private int mSlotId; - private int[] tintArr; + private int[] mTintArr; Context mContext; + private String[] mColorStrings; + private int mTintSelectorPos; public SimPreference(Context context, SubscriptionInfo subInfoRecord, int slotId) { super(context); @@ -401,7 +408,9 @@ public class SimSettings extends RestrictedSettingsFragment implements Indexable mSlotId = slotId; setKey("sim" + mSlotId); update(); - tintArr = context.getResources().getIntArray(com.android.internal.R.array.sim_colors); + mTintArr = context.getResources().getIntArray(com.android.internal.R.array.sim_colors); + mColorStrings = context.getResources().getStringArray(R.array.color_picker); + mTintSelectorPos = 0; } public void update() { @@ -442,14 +451,15 @@ public class SimSettings extends RestrictedSettingsFragment implements Indexable nameText.setText(mSubInfoRecord.getDisplayName()); final Spinner tintSpinner = (Spinner) dialogLayout.findViewById(R.id.spinner); - ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(getContext(), - R.array.color_picker, android.R.layout.simple_spinner_item); + SelectColorAdapter adapter = new SelectColorAdapter(getContext(), + R.layout.settings_color_picker_item, mColorStrings); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); tintSpinner.setAdapter(adapter); - for (int i = 0; i < tintArr.length; i++) { - if (tintArr[i] == mSubInfoRecord.getIconTint()) { + for (int i = 0; i < mTintArr.length; i++) { + if (mTintArr[i] == mSubInfoRecord.getIconTint()) { tintSpinner.setSelection(i); + mTintSelectorPos = i; break; } } @@ -459,6 +469,7 @@ public class SimSettings extends RestrictedSettingsFragment implements Indexable public void onItemSelected(AdapterView<?> parent, View view, int pos, long id){ tintSpinner.setSelection(pos); + mTintSelectorPos = pos; } @Override @@ -494,7 +505,7 @@ public class SimSettings extends RestrictedSettingsFragment implements Indexable final int tintSelected = tintSpinner.getSelectedItemPosition(); int subscriptionId = mSubInfoRecord.getSubscriptionId(); - int tint = tintArr[tintSelected]; + int tint = mTintArr[tintSelected]; mSubInfoRecord.setIconTint(tint); SubscriptionManager.setIconTint(tint, subscriptionId); Utils.findRecordBySubId(subscriptionId).setIconTint(tint); @@ -513,6 +524,76 @@ public class SimSettings extends RestrictedSettingsFragment implements Indexable builder.create().show(); } + + private class SelectColorAdapter extends ArrayAdapter<CharSequence> { + private Context mContext; + private int mResId; + + public SelectColorAdapter( + Context context, int resource, String[] arr) { + super(context, resource, arr); + mContext = context; + mResId = resource; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + LayoutInflater inflater = (LayoutInflater) + mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + + View rowView; + final ViewHolder holder; + Resources res = getResources(); + int iconSize = res.getDimensionPixelSize(R.dimen.color_swatch_size); + int strokeWidth = res.getDimensionPixelSize(R.dimen.color_swatch_stroke_width); + + if (convertView == null) { + // Cache views for faster scrolling + rowView = inflater.inflate(mResId, null); + holder = new ViewHolder(); + ShapeDrawable drawable = new ShapeDrawable(new OvalShape()); + drawable.setIntrinsicHeight(iconSize); + drawable.setIntrinsicWidth(iconSize); + drawable.getPaint().setStrokeWidth(strokeWidth); + holder.label = (TextView) rowView.findViewById(R.id.color_text); + holder.icon = (ImageView) rowView.findViewById(R.id.color_icon); + holder.swatch = drawable; + rowView.setTag(holder); + } else { + rowView = convertView; + holder = (ViewHolder) rowView.getTag(); + } + + holder.label.setText(getItem(position)); + holder.swatch.getPaint().setColor(mTintArr[position]); + holder.swatch.getPaint().setStyle(Paint.Style.FILL_AND_STROKE); + holder.icon.setVisibility(View.VISIBLE); + holder.icon.setImageDrawable(holder.swatch); + return rowView; + } + + @Override + public View getDropDownView(int position, View convertView, ViewGroup parent) { + View rowView = getView(position, convertView, parent); + final ViewHolder holder = (ViewHolder) rowView.getTag(); + + if (mTintSelectorPos == position) { + holder.swatch.getPaint().setStyle(Paint.Style.FILL_AND_STROKE); + } else { + holder.swatch.getPaint().setStyle(Paint.Style.STROKE); + } + holder.icon.setVisibility(View.VISIBLE); + return rowView; + } + + private class ViewHolder { + TextView label; + ImageView icon; + ShapeDrawable swatch; + } + } + + } /** @@ -558,5 +639,4 @@ public class SimSettings extends RestrictedSettingsFragment implements Indexable return result; } }; - } |