diff options
Diffstat (limited to 'src')
66 files changed, 1504 insertions, 1338 deletions
diff --git a/src/com/android/settings/ApnEditor.java b/src/com/android/settings/ApnEditor.java index 181d0aa..2ed7438 100644 --- a/src/com/android/settings/ApnEditor.java +++ b/src/com/android/settings/ApnEditor.java @@ -30,7 +30,6 @@ import android.preference.EditTextPreference; import android.preference.ListPreference; import android.preference.MultiSelectListPreference; import android.preference.Preference; -import android.preference.PreferenceActivity; import android.preference.SwitchPreference; import android.provider.Telephony; import android.telephony.ServiceState; @@ -43,7 +42,10 @@ import android.view.Menu; import android.view.MenuItem; import com.android.internal.logging.MetricsLogger; +import java.util.ArrayList; import java.util.HashSet; +import java.util.Iterator; +import java.util.List; import java.util.Set; public class ApnEditor extends InstrumentedPreferenceActivity @@ -66,6 +68,7 @@ public class ApnEditor extends InstrumentedPreferenceActivity private static final int MENU_SAVE = Menu.FIRST + 1; private static final int MENU_CANCEL = Menu.FIRST + 2; private static final int ERROR_DIALOG_ID = 0; + private static final int DUPLICATE_DIALOG_ID = 1; private static String sNotSet; private EditTextPreference mName; @@ -714,11 +717,81 @@ public class ApnEditor extends InstrumentedPreferenceActivity values.put(Telephony.Carriers.MVNO_MATCH_DATA, checkNotSet(mMvnoMatchData.getText())); values.put(Telephony.Carriers.CARRIER_ENABLED, mCarrierEnabled.isChecked() ? 1 : 0); + + if (isDuplicate(values)) { + showDialog(DUPLICATE_DIALOG_ID); + return false; + } + getContentResolver().update(mUri, values, null, null); return true; } + private boolean isDuplicate(ContentValues row) { + if (!getResources().getBoolean(R.bool.config_enable_duplicate_apn_checking)) { + return false; + } + + final Set<String> keys = row.keySet(); + + StringBuilder queryBuilder = new StringBuilder(); + List<String> selectionArgsList = new ArrayList<>(); + + final Iterator<String> iterator = keys.iterator(); + while (iterator.hasNext()) { + final String key = iterator.next(); + + if (!keyForDuplicateCheck(key) || row.getAsString(key).isEmpty()) { + // Skip keys which don't interest us for the duplicate query. + // Or if the user hasn't yet filled a field in (empty value), skip it. + continue; + } + + queryBuilder.append(key); + queryBuilder.append("=?"); + queryBuilder.append(" AND "); + + selectionArgsList.add(row.getAsString(key)); + } + // remove extra AND at the end + queryBuilder.delete(queryBuilder.length() - " AND ".length(), queryBuilder.length()); + + String[] selectionArgs = new String[selectionArgsList.size()]; + selectionArgsList.toArray(selectionArgs); + + try (Cursor query = getContentResolver().query(Telephony.Carriers.CONTENT_URI, + sProjection, queryBuilder.toString(), selectionArgs, null)) { + return query.getCount() > (mNewApn ? 0 : 1); + } catch (Exception e) { + Log.e(TAG, "error querying for duplicates", e); + return false; + } + } + + /** + * Helper method to decide what columns should be considered valid when checking for + * potential duplicate APNs before allowing the user to add a new one. + * + * @param key the column of the row we want to check + * @return whether to include this key-value pair in the duplicate query + */ + private static boolean keyForDuplicateCheck(String key) { + switch (key) { + case Telephony.Carriers.APN: + case Telephony.Carriers.MMSPROXY: + case Telephony.Carriers.MMSPORT: + case Telephony.Carriers.MMSC: + case Telephony.Carriers.TYPE: + case Telephony.Carriers.MCC: + case Telephony.Carriers.MNC: + case Telephony.Carriers.NUMERIC: + return true; + default: + return false; + } + } + private String getErrorMsg() { String errorMsg = null; @@ -751,6 +824,12 @@ public class ApnEditor extends InstrumentedPreferenceActivity .setPositiveButton(android.R.string.ok, null) .setMessage(msg) .create(); + } else if (id == DUPLICATE_DIALOG_ID) { + return new AlertDialog.Builder(this) + .setTitle(R.string.duplicate_apn_error_title) + .setPositiveButton(android.R.string.ok, null) + .setMessage(getString(R.string.duplicate_apn_error_message)) + .create(); } return super.onCreateDialog(id); diff --git a/src/com/android/settings/ButtonSettings.java b/src/com/android/settings/ButtonSettings.java index 30ac090..09c9b7d 100644 --- a/src/com/android/settings/ButtonSettings.java +++ b/src/com/android/settings/ButtonSettings.java @@ -628,25 +628,8 @@ public class ButtonSettings extends SettingsPreferenceFragment implements } private static void writeDisableNavkeysOption(Context context, boolean enabled) { - final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); - final int defaultBrightness = context.getResources().getInteger( - com.android.internal.R.integer.config_buttonBrightnessSettingDefault); - CMSettings.Secure.putInt(context.getContentResolver(), CMSettings.Secure.DEV_FORCE_SHOW_NAVBAR, enabled ? 1 : 0); - CMHardwareManager hardware = CMHardwareManager.getInstance(context); - hardware.set(CMHardwareManager.FEATURE_KEY_DISABLE, enabled); - - /* Save/restore button timeouts to disable them in softkey mode */ - if (enabled) { - CMSettings.Secure.putInt(context.getContentResolver(), - CMSettings.Secure.BUTTON_BRIGHTNESS, 0); - } else { - int oldBright = prefs.getInt(ButtonBacklightBrightness.KEY_BUTTON_BACKLIGHT, - defaultBrightness); - CMSettings.Secure.putInt(context.getContentResolver(), - CMSettings.Secure.BUTTON_BRIGHTNESS, oldBright); - } } private void updateDisableNavkeysOption() { diff --git a/src/com/android/settings/ChooseLockSettingsHelper.java b/src/com/android/settings/ChooseLockSettingsHelper.java index 665bffe..11d03a7 100644 --- a/src/com/android/settings/ChooseLockSettingsHelper.java +++ b/src/com/android/settings/ChooseLockSettingsHelper.java @@ -25,6 +25,8 @@ import android.os.UserHandle; import com.android.internal.widget.LockPatternUtils; +import org.cyanogenmod.internal.util.CmLockPatternUtils; + public final class ChooseLockSettingsHelper { static final String EXTRA_KEY_TYPE = "type"; @@ -36,12 +38,14 @@ public final class ChooseLockSettingsHelper { private LockPatternUtils mLockPatternUtils; + private CmLockPatternUtils mCmLockPatternUtils; private Activity mActivity; private Fragment mFragment; public ChooseLockSettingsHelper(Activity activity) { mActivity = activity; mLockPatternUtils = new LockPatternUtils(activity); + mCmLockPatternUtils = new CmLockPatternUtils(activity); } public ChooseLockSettingsHelper(Activity activity, Fragment fragment) { @@ -53,6 +57,10 @@ public final class ChooseLockSettingsHelper { return mLockPatternUtils; } + public CmLockPatternUtils cmUtils() { + return mCmLockPatternUtils; + } + /** * If a pattern, password or PIN exists, prompt the user before allowing them to change it. * diff --git a/src/com/android/settings/DataUsageSummary.java b/src/com/android/settings/DataUsageSummary.java index 1da268e..63120e3 100644 --- a/src/com/android/settings/DataUsageSummary.java +++ b/src/com/android/settings/DataUsageSummary.java @@ -81,8 +81,6 @@ import android.net.TrafficStats; import android.os.AsyncTask; import android.os.Bundle; import android.os.INetworkManagementService; -import android.os.Parcel; -import android.os.Parcelable; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemProperties; @@ -98,7 +96,6 @@ import android.text.format.Formatter; import android.text.format.Time; import android.util.Log; import android.util.SparseArray; -import android.util.SparseBooleanArray; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; @@ -131,19 +128,20 @@ import android.widget.Toast; import com.android.internal.logging.MetricsLogger; import com.android.internal.telephony.PhoneConstants; import com.android.settings.drawable.InsetBoundsDrawable; -import com.android.settings.net.ChartData; -import com.android.settings.net.ChartDataLoader; import com.android.settings.net.DataUsageMeteredSettings; -import com.android.settings.net.NetworkPolicyEditor; -import com.android.settings.net.SummaryForAllUidLoader; -import com.android.settings.net.UidDetail; -import com.android.settings.net.UidDetailProvider; import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.search.Indexable; import com.android.settings.search.SearchIndexableRaw; import com.android.settings.widget.ChartDataUsageView; import com.android.settings.widget.ChartDataUsageView.DataUsageChartListener; import com.android.settings.widget.ChartNetworkSeriesView; +import com.android.settingslib.AppItem; +import com.android.settingslib.NetworkPolicyEditor; +import com.android.settingslib.net.ChartData; +import com.android.settingslib.net.ChartDataLoader; +import com.android.settingslib.net.SummaryForAllUidLoader; +import com.android.settingslib.net.UidDetail; +import com.android.settingslib.net.UidDetailProvider; import com.google.android.collect.Lists; import libcore.util.Objects; @@ -734,6 +732,13 @@ public class DataUsageSummary extends HighlightingFragment implements Indexable mTabHost.addTab(buildTabSpec(TAB_ETHERNET, R.string.data_usage_tab_ethernet)); } + if (getResources().getBoolean(R.bool.config_gcf_disable_default_tabtext_allcaps)) { + for (int i = 0; i < mTabWidget.getTabCount(); i++) { + TextView tv = (TextView) mTabWidget.getChildAt(i).findViewById(android.R.id.title); + tv.setAllCaps(false); + } + } + final boolean noTabs = mTabWidget.getTabCount() == 0; final boolean multipleTabs = mTabWidget.getTabCount() > 1; mTabWidget.setVisibility(multipleTabs ? View.VISIBLE : View.GONE); @@ -903,7 +908,7 @@ public class DataUsageSummary extends HighlightingFragment implements Indexable mBinding = false; int seriesColor = context.getColor(R.color.sim_noitification); - if (mCurrentTab != null && mCurrentTab.length() > TAB_MOBILE.length() ){ + if (mCurrentTab != null && mCurrentTab.startsWith(TAB_MOBILE)) { final int slotId = Integer.parseInt(mCurrentTab.substring(TAB_MOBILE.length(), mCurrentTab.length())); final SubscriptionInfo sir = mSubscriptionManager @@ -1631,70 +1636,6 @@ public class DataUsageSummary extends HighlightingFragment implements Indexable } } - public static class AppItem implements Comparable<AppItem>, Parcelable { - public static final int CATEGORY_USER = 0; - public static final int CATEGORY_APP_TITLE = 1; - public static final int CATEGORY_APP = 2; - - public final int key; - public boolean restricted; - public int category; - - public SparseBooleanArray uids = new SparseBooleanArray(); - public long total; - - public AppItem() { - this.key = 0; - } - - public AppItem(int key) { - this.key = key; - } - - public AppItem(Parcel parcel) { - key = parcel.readInt(); - uids = parcel.readSparseBooleanArray(); - total = parcel.readLong(); - } - - public void addUid(int uid) { - uids.put(uid, true); - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(key); - dest.writeSparseBooleanArray(uids); - dest.writeLong(total); - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public int compareTo(AppItem another) { - int comparison = Integer.compare(category, another.category); - if (comparison == 0) { - comparison = Long.compare(another.total, total); - } - return comparison; - } - - public static final Creator<AppItem> CREATOR = new Creator<AppItem>() { - @Override - public AppItem createFromParcel(Parcel in) { - return new AppItem(in); - } - - @Override - public AppItem[] newArray(int size) { - return new AppItem[size]; - } - }; - } - /** * Adapter of applications, sorted by total usage descending. */ diff --git a/src/com/android/settings/DevelopmentSettings.java b/src/com/android/settings/DevelopmentSettings.java index 2f753ef..d7a4145 100644 --- a/src/com/android/settings/DevelopmentSettings.java +++ b/src/com/android/settings/DevelopmentSettings.java @@ -76,6 +76,7 @@ import android.view.ViewGroup; import android.view.accessibility.AccessibilityManager; import android.widget.Switch; import android.widget.TextView; +import android.widget.Toast; import com.android.internal.logging.MetricsLogger; import com.android.settings.fuelgauge.InactiveApps; @@ -125,6 +126,7 @@ public class DevelopmentSettings extends SettingsPreferenceFragment private static final String BUGREPORT_IN_POWER_KEY = "bugreport_in_power"; private static final String OPENGL_TRACES_PROPERTY = "debug.egl.trace"; private static final String TUNER_UI_KEY = "tuner_ui"; + private static final String COLOR_TEMPERATURE_PROPERTY = "persist.sys.debug.color_temp"; private static final String DEBUG_APP_KEY = "debug_app"; private static final String WAIT_FOR_DEBUGGER_KEY = "wait_for_debugger"; @@ -166,6 +168,7 @@ public class DevelopmentSettings extends SettingsPreferenceFragment private static final String WIFI_LEGACY_DHCP_CLIENT_KEY = "legacy_dhcp_client"; private static final String MOBILE_DATA_ALWAYS_ON = "mobile_data_always_on"; private static final String KEY_COLOR_MODE = "color_mode"; + private static final String COLOR_TEMPERATURE_KEY = "color_temperature"; private static final String INACTIVE_APPS_KEY = "inactive_apps"; @@ -291,6 +294,8 @@ public class DevelopmentSettings extends SettingsPreferenceFragment private SwitchPreference mDevelopmentShortcut; + private SwitchPreference mColorTemperaturePreference; + private final ArrayList<Preference> mAllPrefs = new ArrayList<Preference>(); private final ArrayList<SwitchPreference> mResetSwitchPrefs @@ -484,6 +489,15 @@ public class DevelopmentSettings extends SettingsPreferenceFragment removePreference(KEY_COLOR_MODE); mColorModePreference = null; } + + mColorTemperaturePreference = (SwitchPreference) findPreference(COLOR_TEMPERATURE_KEY); + if (getResources().getBoolean(R.bool.config_enableColorTemperature)) { + mAllPrefs.add(mColorTemperaturePreference); + mResetSwitchPrefs.add(mColorTemperaturePreference); + } else { + removePreference(COLOR_TEMPERATURE_KEY); + mColorTemperaturePreference = null; + } } private ListPreference addListPreference(String prefKey) { @@ -720,6 +734,9 @@ public class DevelopmentSettings extends SettingsPreferenceFragment updateAdvancedRebootOptions(); updateDevelopmentShortcutOptions(); updateUpdateRecoveryOptions(); + if (mColorTemperaturePreference != null) { + updateColorTemperature(); + } } private void writeAdvancedRebootOptions() { @@ -1410,6 +1427,18 @@ public class DevelopmentSettings extends SettingsPreferenceFragment } } + private void updateColorTemperature() { + updateSwitchPreference(mColorTemperaturePreference, + SystemProperties.getBoolean(COLOR_TEMPERATURE_PROPERTY, false)); + } + + private void writeColorTemperature() { + SystemProperties.set(COLOR_TEMPERATURE_PROPERTY, + mColorTemperaturePreference.isChecked() ? "1" : "0"); + pokeSystemProperties(); + Toast.makeText(getActivity(), R.string.color_temperature_toast, Toast.LENGTH_LONG).show(); + } + private void updateUSBAudioOptions() { updateSwitchPreference(mUSBAudio, Settings.Secure.getInt(getContentResolver(), Settings.Secure.USB_AUDIO_AUTOMATIC_ROUTING_DISABLED, 0) != 0); @@ -1773,13 +1802,19 @@ public class DevelopmentSettings extends SettingsPreferenceFragment pokeSystemProperties(); } - private void resetUpdateRecoveryOptions() { + private static void resetUpdateRecoveryOptions() { // User builds should update recovery by default if ("user".equals(Build.TYPE)) { SystemProperties.set(UPDATE_RECOVERY_PROPERTY, "true"); } } + public static void initializeUpdateRecoveryOption() { + if (TextUtils.isEmpty(SystemProperties.get(UPDATE_RECOVERY_PROPERTY))) { + resetUpdateRecoveryOptions(); + } + } + @Override public void onSwitchChanged(Switch switchView, boolean isChecked) { if (switchView != mSwitchBar.getSwitch()) { @@ -1987,6 +2022,8 @@ public class DevelopmentSettings extends SettingsPreferenceFragment writeLegacyDhcpClientOptions(); } else if (preference == mMobileDataAlwaysOn) { writeMobileDataAlwaysOnOptions(); + } else if (preference == mColorTemperaturePreference) { + writeColorTemperature(); } else if (preference == mUSBAudio) { writeUSBAudioOptions(); } else if (preference == mAdvancedReboot) { diff --git a/src/com/android/settings/DeviceInfoSettings.java b/src/com/android/settings/DeviceInfoSettings.java index 3b255f0..949eaab 100644 --- a/src/com/android/settings/DeviceInfoSettings.java +++ b/src/com/android/settings/DeviceInfoSettings.java @@ -209,10 +209,9 @@ public class DeviceInfoSettings extends SettingsPreferenceFragment implements In // Remove manual entry if none present. removePreferenceIfBoolFalse(KEY_MANUAL, R.bool.config_show_manual); - // Remove regulatory information if none present or config_show_regulatory_info is disabled + // Remove regulatory information if none present final Intent intent = new Intent(Settings.ACTION_SHOW_REGULATORY_INFO); - if (getPackageManager().queryIntentActivities(intent, 0).isEmpty() - || !getResources().getBoolean(R.bool.config_show_regulatory_info)) { + if (getPackageManager().queryIntentActivities(intent, 0).isEmpty()) { Preference pref = findPreference(KEY_REGULATORY_INFO); if (pref != null) { getPreferenceScreen().removePreference(pref); diff --git a/src/com/android/settings/IccLockSettings.java b/src/com/android/settings/IccLockSettings.java index 6f72b66..ff7c2bd 100644 --- a/src/com/android/settings/IccLockSettings.java +++ b/src/com/android/settings/IccLockSettings.java @@ -34,6 +34,7 @@ import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.util.Log; +import android.view.MenuItem; import android.view.View; import android.widget.ListView; import android.widget.Toast; @@ -210,6 +211,16 @@ public class IccLockSettings extends InstrumentedPreferenceActivity updatePreferences(); } + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == android.R.id.home) { + finish(); + return true; + } + return false; + } + + private void updatePreferences() { mPinDialog.setEnabled(mPhone != null); mPinToggle.setEnabled(mPhone != null); diff --git a/src/com/android/settings/LegalSettings.java b/src/com/android/settings/LegalSettings.java index cd91d20..a28fae5 100644 --- a/src/com/android/settings/LegalSettings.java +++ b/src/com/android/settings/LegalSettings.java @@ -22,9 +22,14 @@ import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; +import android.net.Uri; import android.os.Bundle; +import android.os.SystemProperties; +import android.preference.Preference; import android.preference.PreferenceGroup; +import android.preference.PreferenceScreen; import android.provider.SearchIndexableResource; +import android.util.Log; import com.android.internal.logging.MetricsLogger; import com.android.settings.search.BaseSearchIndexProvider; @@ -36,10 +41,13 @@ import java.util.List; public class LegalSettings extends SettingsPreferenceFragment implements Indexable { + private static final String LOG_TAG = "LegalSettings"; private static final String KEY_TERMS = "terms"; private static final String KEY_LICENSE = "license"; private static final String KEY_COPYRIGHT = "copyright"; private static final String KEY_WEBVIEW_LICENSE = "webview_license"; + private static final String PROPERTY_CMLICENSE_URL = "ro.cmlegal.url"; + private static final String KEY_CM_LICENSE = "cmlicense"; public void onCreate(Bundle icicle) { super.onCreate(icicle); @@ -59,6 +67,22 @@ public class LegalSettings extends SettingsPreferenceFragment implements Indexab } @Override + public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) { + if (preference.getKey().equals(KEY_CM_LICENSE)) { + String userCMLicenseUrl = SystemProperties.get(PROPERTY_CMLICENSE_URL); + final Intent intent = new Intent(Intent.ACTION_VIEW); + intent.addCategory(Intent.CATEGORY_DEFAULT); + intent.setData(Uri.parse(userCMLicenseUrl)); + try { + startActivity(intent); + } catch (Exception e) { + Log.e(LOG_TAG, "Unable to start activity " + intent.toString()); + } + } + return super.onPreferenceTreeClick(preferenceScreen, preference); + } + + @Override protected int getMetricsCategory() { return MetricsLogger.ABOUT_LEGAL_SETTINGS; } diff --git a/src/com/android/settings/ResetNetworkConfirm.java b/src/com/android/settings/ResetNetworkConfirm.java index db4b9a5..df708b9 100644 --- a/src/com/android/settings/ResetNetworkConfirm.java +++ b/src/com/android/settings/ResetNetworkConfirm.java @@ -34,6 +34,7 @@ import android.widget.Button; import android.widget.Spinner; import android.widget.Toast; +import com.android.ims.ImsManager; import com.android.internal.logging.MetricsLogger; import com.android.internal.telephony.PhoneConstants; @@ -100,6 +101,8 @@ public class ResetNetworkConfirm extends InstrumentedFragment { btManager.getAdapter().factoryReset(); } + ImsManager.factoryReset(context); + Toast.makeText(context, R.string.reset_network_complete_toast, Toast.LENGTH_SHORT) .show(); } diff --git a/src/com/android/settings/SecuritySettings.java b/src/com/android/settings/SecuritySettings.java index 450273b..8f2db6b 100644 --- a/src/com/android/settings/SecuritySettings.java +++ b/src/com/android/settings/SecuritySettings.java @@ -62,6 +62,9 @@ import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.search.Index; import com.android.settings.search.Indexable; import com.android.settings.search.SearchIndexableRaw; + +import org.cyanogenmod.internal.util.CmLockPatternUtils; + import cyanogenmod.providers.CMSettings; import java.util.ArrayList; @@ -81,12 +84,14 @@ public class SecuritySettings extends SettingsPreferenceFragment new Intent(TrustAgentService.SERVICE_INTERFACE); // Fitler types for this panel - private static final String FILTER_TYPE_EXTRA = "filter_type"; - private static final int TYPE_LOCKSCREEN_EXTRA = 0; + protected static final String FILTER_TYPE_EXTRA = "filter_type"; + protected static final int TYPE_LOCKSCREEN_EXTRA = 0; private static final int TYPE_SECURITY_EXTRA = 1; + private static final int TYPE_EXTERNAL_RESOLUTION = 2; // Lock Settings private static final String KEY_UNLOCK_SET_OR_CHANGE = "unlock_set_or_change"; + private static final String KEY_DIRECTLY_SHOW = "directlyshow"; private static final String KEY_VISIBLE_PATTERN = "visiblepattern"; private static final String KEY_VISIBLE_ERROR_PATTERN = "visible_error_pattern"; private static final String KEY_VISIBLE_DOTS = "visibledots"; @@ -122,15 +127,15 @@ public class SecuritySettings extends SettingsPreferenceFragment // These switch preferences need special handling since they're not all stored in Settings. private static final String SWITCH_PREFERENCE_KEYS[] = { KEY_LOCK_AFTER_TIMEOUT, - KEY_VISIBLE_PATTERN, KEY_VISIBLE_ERROR_PATTERN, KEY_VISIBLE_DOTS, + KEY_VISIBLE_PATTERN, KEY_VISIBLE_ERROR_PATTERN, KEY_VISIBLE_DOTS, KEY_DIRECTLY_SHOW, KEY_POWER_INSTANTLY_LOCKS, KEY_SHOW_PASSWORD, KEY_TOGGLE_INSTALL_APPLICATIONS }; // Only allow one trust agent on the platform. private static final boolean ONLY_ONE_TRUST_AGENT = true; - private static final int MY_USER_ID = UserHandle.myUserId(); + protected static final int MY_USER_ID = UserHandle.myUserId(); - private static final String LIVE_LOCK_SCREEN_FEATURE = "org.cyanogenmod.livelockscreen"; + protected static final String LIVE_LOCK_SCREEN_FEATURE = "org.cyanogenmod.livelockscreen"; private PackageManager mPM; private DevicePolicyManager mDPM; @@ -140,6 +145,7 @@ public class SecuritySettings extends SettingsPreferenceFragment private LockPatternUtils mLockPatternUtils; private ListPreference mLockAfter; + private SwitchPreference mDirectlyShow; private SwitchPreference mVisiblePattern; private SwitchPreference mVisibleErrorPattern; private SwitchPreference mVisibleDots; @@ -186,6 +192,13 @@ public class SecuritySettings extends SettingsPreferenceFragment } } + Bundle extras = getActivity().getIntent().getExtras(); + // Even uglier hack to make cts verifier expectations make sense. + if (extras.get(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS) != null && + extras.get(SettingsActivity.EXTRA_SHOW_FRAGMENT_AS_SHORTCUT) == null) { + mFilterType = TYPE_EXTERNAL_RESOLUTION; + } + mSubscriptionManager = SubscriptionManager.from(getActivity()); mLockPatternUtils = new LockPatternUtils(getActivity()); @@ -200,7 +213,7 @@ public class SecuritySettings extends SettingsPreferenceFragment } } - private static int getResIdForLockUnlockScreen(Context context, + protected static int getResIdForLockUnlockScreen(Context context, LockPatternUtils lockPatternUtils) { int resid = 0; if (!lockPatternUtils.isSecure(MY_USER_ID)) { @@ -258,7 +271,12 @@ public class SecuritySettings extends SettingsPreferenceFragment root.addPreference(mLockscreenDisabledPreference); } - if (mFilterType == TYPE_LOCKSCREEN_EXTRA) { + final boolean securityOrExternal = mFilterType == TYPE_SECURITY_EXTRA + || mFilterType == TYPE_EXTERNAL_RESOLUTION; + final boolean lockscreenOrExternal = mFilterType == TYPE_LOCKSCREEN_EXTRA + || mFilterType == TYPE_EXTERNAL_RESOLUTION; + + if (lockscreenOrExternal) { // Add options for lock/unlock screen final int resid = getResIdForLockUnlockScreen(getActivity(), mLockPatternUtils); addPreferencesFromResource(resid); @@ -275,7 +293,7 @@ public class SecuritySettings extends SettingsPreferenceFragment } } - if (mIsPrimary && mFilterType == TYPE_SECURITY_EXTRA) { + if (mIsPrimary && securityOrExternal) { if (LockPatternUtils.isDeviceEncryptionEnabled()) { // The device is currently encrypted. addPreferencesFromResource(R.xml.security_settings_encrypted); @@ -285,7 +303,7 @@ public class SecuritySettings extends SettingsPreferenceFragment } } - if (mFilterType == TYPE_LOCKSCREEN_EXTRA) { + if (lockscreenOrExternal) { // Fingerprint and trust agents PreferenceGroup securityCategory = (PreferenceGroup) root.findPreference(KEY_SECURITY_CATEGORY); @@ -301,6 +319,9 @@ public class SecuritySettings extends SettingsPreferenceFragment updateLockAfterPreferenceSummary(); } + // directly show + mDirectlyShow = (SwitchPreference) root.findPreference(KEY_DIRECTLY_SHOW); + // visible pattern mVisiblePattern = (SwitchPreference) root.findPreference(KEY_VISIBLE_PATTERN); @@ -334,7 +355,9 @@ public class SecuritySettings extends SettingsPreferenceFragment liveLockPreference.setSummary(R.string.live_lock_screen_summary); generalCategory.addPreference(liveLockPreference); } - } else { + } + + if (securityOrExternal) { // Append the rest of the settings addPreferencesFromResource(R.xml.security_settings_misc); @@ -532,7 +555,7 @@ public class SecuritySettings extends SettingsPreferenceFragment } } - private static ArrayList<TrustAgentComponentInfo> getActiveTrustAgents( + protected static ArrayList<TrustAgentComponentInfo> getActiveTrustAgents( PackageManager pm, LockPatternUtils utils, DevicePolicyManager dpm) { ArrayList<TrustAgentComponentInfo> result = new ArrayList<TrustAgentComponentInfo>(); List<ResolveInfo> resolveInfos = pm.queryIntentServices(TRUST_AGENT_INTENT, @@ -707,6 +730,10 @@ public class SecuritySettings extends SettingsPreferenceFragment createPreferenceHierarchy(); final LockPatternUtils lockPatternUtils = mChooseLockSettingsHelper.utils(); + final CmLockPatternUtils cmLockPatternUtils = mChooseLockSettingsHelper.cmUtils(); + if (mDirectlyShow != null) { + mDirectlyShow.setChecked(cmLockPatternUtils.shouldPassToSecurityView(MY_USER_ID)); + } if (mVisiblePattern != null) { mVisiblePattern.setChecked(lockPatternUtils.isVisiblePatternEnabled(MY_USER_ID)); } @@ -793,6 +820,7 @@ public class SecuritySettings extends SettingsPreferenceFragment boolean result = true; final String key = preference.getKey(); final LockPatternUtils lockPatternUtils = mChooseLockSettingsHelper.utils(); + final CmLockPatternUtils cmLockPatternUtils = mChooseLockSettingsHelper.cmUtils(); if (KEY_LOCK_AFTER_TIMEOUT.equals(key)) { int timeout = Integer.parseInt((String) value); try { @@ -802,6 +830,8 @@ public class SecuritySettings extends SettingsPreferenceFragment Log.e("SecuritySettings", "could not persist lockAfter timeout setting", e); } updateLockAfterPreferenceSummary(); + } else if (KEY_DIRECTLY_SHOW.equals(key)) { + cmLockPatternUtils.setPassToSecurityView((Boolean) value, MY_USER_ID); } else if (KEY_VISIBLE_PATTERN.equals(key)) { lockPatternUtils.setVisiblePatternEnabled((Boolean) value, MY_USER_ID); } else if (KEY_VISIBLE_ERROR_PATTERN.equals(key)) { @@ -859,14 +889,8 @@ public class SecuritySettings extends SettingsPreferenceFragment List<SearchIndexableResource> result = new ArrayList<SearchIndexableResource>(); - LockPatternUtils lockPatternUtils = new LockPatternUtils(context); - // Add options for lock/unlock screen - int resId = getResIdForLockUnlockScreen(context, lockPatternUtils); - - SearchIndexableResource sir = new SearchIndexableResource(context); - sir.xmlResId = resId; - result.add(sir); - + int resId = 0; + SearchIndexableResource sir; if (mIsPrimary) { DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE); @@ -917,22 +941,6 @@ public class SecuritySettings extends SettingsPreferenceFragment result.add(data); } - // Fingerprint - FingerprintManager fpm = - (FingerprintManager) context.getSystemService(Context.FINGERPRINT_SERVICE); - if (fpm.isHardwareDetected()) { - // This catches the title which can be overloaded in an overlay - data = new SearchIndexableRaw(context); - data.title = res.getString(R.string.security_settings_fingerprint_preference_title); - data.screenTitle = screenTitle; - result.add(data); - // Fallback for when the above doesn't contain "fingerprint" - data = new SearchIndexableRaw(context); - data.title = res.getString(R.string.fingerprint_manage_category_title); - data.screenTitle = screenTitle; - result.add(data); - } - // Credential storage final UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE); diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java index 27dfc80..332d9b3 100644 --- a/src/com/android/settings/SettingsActivity.java +++ b/src/com/android/settings/SettingsActivity.java @@ -293,7 +293,8 @@ public class SettingsActivity extends Activity R.id.print_settings, R.id.home_settings, R.id.dashboard, - R.id.privacy_settings_cyanogenmod + R.id.privacy_settings_cyanogenmod, + R.id.button_settings }; private static final String[] ENTRY_FRAGMENTS = { diff --git a/src/com/android/settings/UserAdapter.java b/src/com/android/settings/UserAdapter.java index dcdc7eb..2ac908e 100644 --- a/src/com/android/settings/UserAdapter.java +++ b/src/com/android/settings/UserAdapter.java @@ -33,7 +33,7 @@ import android.widget.SpinnerAdapter; import android.widget.TextView; import com.android.internal.util.UserIcons; -import com.android.settings.drawable.CircleFramedDrawable; +import com.android.settingslib.drawable.CircleFramedDrawable; import java.util.ArrayList; @@ -173,4 +173,4 @@ public class UserAdapter implements SpinnerAdapter, ListAdapter { public boolean isEnabled(int position) { return true; } -}
\ No newline at end of file +} diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java index ef633e1..837c36c 100644 --- a/src/com/android/settings/Utils.java +++ b/src/com/android/settings/Utils.java @@ -95,10 +95,10 @@ import android.widget.TabWidget; import com.android.internal.util.UserIcons; import com.android.settings.UserAdapter.UserDetails; +import com.android.settings.bluetooth.BluetoothSettings; import com.android.settings.dashboard.DashboardTile; -import com.android.settings.drawable.CircleFramedDrawable; import com.android.settingslib.applications.ApplicationsState; -import com.android.settings.bluetooth.BluetoothSettings; +import com.android.settingslib.drawable.CircleFramedDrawable; import java.io.IOException; import java.io.InputStream; @@ -486,6 +486,20 @@ public final class Utils { return (level * 100) / scale; } + public static boolean isDockBatteryPresent(Intent batteryChangedIntent) { + return batteryChangedIntent.getBooleanExtra(BatteryManager.EXTRA_DOCK_PRESENT, true); + } + + public static String getDockBatteryPercentage(Intent batteryChangedIntent) { + return formatPercentage(getDockBatteryLevel(batteryChangedIntent)); + } + + public static int getDockBatteryLevel(Intent batteryChangedIntent) { + int level = batteryChangedIntent.getIntExtra(BatteryManager.EXTRA_DOCK_LEVEL, 0); + int scale = batteryChangedIntent.getIntExtra(BatteryManager.EXTRA_DOCK_SCALE, 100); + return (level * 100) / scale; + } + public static String getBatteryStatus(Resources res, Intent batteryChangedIntent) { final Intent intent = batteryChangedIntent; @@ -518,6 +532,36 @@ public final class Utils { return statusString; } + public static String getDockBatteryStatus(Resources res, Intent batteryChangedIntent) { + final Intent intent = batteryChangedIntent; + + int plugType = intent.getIntExtra(BatteryManager.EXTRA_DOCK_PLUGGED, 0); + int status = intent.getIntExtra(BatteryManager.EXTRA_DOCK_STATUS, + BatteryManager.BATTERY_STATUS_UNKNOWN); + String statusString; + if (status == BatteryManager.BATTERY_STATUS_CHARGING) { + int resId; + if (plugType == BatteryManager.BATTERY_DOCK_PLUGGED_AC) { + resId = R.string.battery_info_status_charging_dock_ac; + } else if (plugType == BatteryManager.BATTERY_DOCK_PLUGGED_USB) { + resId = R.string.battery_info_status_charging_dock_usb; + } else { + resId = R.string.battery_info_status_charging; + } + statusString = res.getString(resId); + } else if (status == BatteryManager.BATTERY_STATUS_DISCHARGING) { + statusString = res.getString(R.string.battery_info_status_discharging); + } else if (status == BatteryManager.BATTERY_STATUS_NOT_CHARGING) { + statusString = res.getString(R.string.battery_info_status_not_charging); + } else if (status == BatteryManager.BATTERY_STATUS_FULL) { + statusString = res.getString(R.string.battery_info_status_full); + } else { + statusString = res.getString(R.string.battery_info_status_unknown); + } + + return statusString; + } + public static void forcePrepareCustomPreferencesList( ViewGroup parent, View child, ListView list, boolean ignoreSidePadding) { list.setScrollBarStyle(View.SCROLLBARS_OUTSIDE_OVERLAY); @@ -562,36 +606,6 @@ public final class Utils { view.setPaddingRelative(paddingStart, 0, paddingEnd, paddingBottom); } - /** - * Return string resource that best describes combination of tethering - * options available on this device. - */ - public static int getTetheringLabel(ConnectivityManager cm) { - String[] usbRegexs = cm.getTetherableUsbRegexs(); - String[] wifiRegexs = cm.getTetherableWifiRegexs(); - String[] bluetoothRegexs = cm.getTetherableBluetoothRegexs(); - - boolean usbAvailable = usbRegexs.length != 0; - boolean wifiAvailable = wifiRegexs.length != 0; - boolean bluetoothAvailable = bluetoothRegexs.length != 0; - - if (wifiAvailable && usbAvailable && bluetoothAvailable) { - return R.string.tether_settings_title_all; - } else if (wifiAvailable && usbAvailable) { - return R.string.tether_settings_title_all; - } else if (wifiAvailable && bluetoothAvailable) { - return R.string.tether_settings_title_all; - } else if (wifiAvailable) { - return R.string.tether_settings_title_wifi; - } else if (usbAvailable && bluetoothAvailable) { - return R.string.tether_settings_title_usb_bluetooth; - } else if (usbAvailable) { - return R.string.tether_settings_title_usb; - } else { - return R.string.tether_settings_title_bluetooth; - } - } - /* Used by UserSettings as well. Call this on a non-ui thread. */ public static boolean copyMeProfilePhoto(Context context, UserInfo user) { Uri contactUri = Profile.CONTENT_URI; @@ -1043,45 +1057,6 @@ public final class Utils { } /** - * Returns a circular icon for a user. - */ - public static Drawable getUserIcon(Context context, UserManager um, UserInfo user) { - if (user.isManagedProfile()) { - // We use predefined values for managed profiles - Bitmap b = BitmapFactory.decodeResource(context.getResources(), - com.android.internal.R.drawable.ic_corp_icon); - return CircleFramedDrawable.getInstance(context, b); - } - if (user.iconPath != null) { - Bitmap icon = um.getUserIcon(user.id); - if (icon != null) { - return CircleFramedDrawable.getInstance(context, icon); - } - } - return CircleFramedDrawable.getInstance(context, UserIcons.convertToBitmap( - UserIcons.getDefaultUserIcon(user.id, /* light= */ false))); - } - - /** - * Returns a label for the user, in the form of "User: user name" or "Work profile". - */ - public static String getUserLabel(Context context, UserInfo info) { - String name = info != null ? info.name : null; - if (info.isManagedProfile()) { - // We use predefined values for managed profiles - return context.getString(R.string.managed_user_title); - } else if (info.isGuest()) { - name = context.getString(R.string.user_guest); - } - if (name == null && info != null) { - name = Integer.toString(info.id); - } else if (info == null) { - name = context.getString(R.string.unknown); - } - return context.getResources().getString(R.string.running_process_item_user_label, name); - } - - /** * Return whether or not the user should have a SIM Cards option in Settings. * TODO: Change back to returning true if count is greater than one after testing. * TODO: See bug 16533525. @@ -1089,8 +1064,8 @@ public final class Utils { public static boolean showSimCardTile(Context context) { final TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); - - return tm.getSimCount() > 1; + final boolean isPrimary = UserHandle.myUserId() == UserHandle.USER_OWNER; + return isPrimary && tm.getSimCount() > 1; } /** diff --git a/src/com/android/settings/WifiCallingSettings.java b/src/com/android/settings/WifiCallingSettings.java index d928de2..f4d143d 100644 --- a/src/com/android/settings/WifiCallingSettings.java +++ b/src/com/android/settings/WifiCallingSettings.java @@ -23,9 +23,11 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.Bundle; +import android.os.PersistableBundle; import android.preference.ListPreference; import android.preference.Preference; import android.preference.PreferenceScreen; +import android.telephony.CarrierConfigManager; import android.telephony.PhoneStateListener; import android.telephony.TelephonyManager; import android.util.Log; @@ -58,6 +60,7 @@ public class WifiCallingSettings extends SettingsPreferenceFragment private TextView mEmptyView; private boolean mValidListener = false; + private boolean mEditableWfcMode = true; private final PhoneStateListener mPhoneStateListener = new PhoneStateListener() { /* @@ -161,6 +164,15 @@ public class WifiCallingSettings extends SettingsPreferenceFragment mIntentFilter = new IntentFilter(); mIntentFilter.addAction(ImsManager.ACTION_IMS_REGISTRATION_ERROR); + + CarrierConfigManager configManager = (CarrierConfigManager) + getSystemService(Context.CARRIER_CONFIG_SERVICE); + if (configManager != null) { + PersistableBundle b = configManager.getConfig(); + if (b != null) { + mEditableWfcMode = b.getBoolean(CarrierConfigManager.KEY_EDITABLE_WFC_MODE_BOOL); + } + } } @Override @@ -246,6 +258,7 @@ public class WifiCallingSettings extends SettingsPreferenceFragment } else { preferenceScreen.removePreference(mButtonWfcMode); } + preferenceScreen.setEnabled(mEditableWfcMode); } @Override diff --git a/src/com/android/settings/WirelessSettings.java b/src/com/android/settings/WirelessSettings.java index 13ce21a..4a0c9e3 100644 --- a/src/com/android/settings/WirelessSettings.java +++ b/src/com/android/settings/WirelessSettings.java @@ -338,7 +338,7 @@ public class WirelessSettings extends SettingsPreferenceFragment implements Inde getPreferenceScreen().removePreference(findPreference(KEY_TETHER_SETTINGS)); } else { Preference p = findPreference(KEY_TETHER_SETTINGS); - p.setTitle(Utils.getTetheringLabel(cm)); + p.setTitle(com.android.settingslib.Utils.getTetheringLabel(cm)); // Grey out if provisioning is not available. p.setEnabled(!TetherSettings diff --git a/src/com/android/settings/applications/AppOpsSummary.java b/src/com/android/settings/applications/AppOpsSummary.java index 395ebbf..be153de 100644 --- a/src/com/android/settings/applications/AppOpsSummary.java +++ b/src/com/android/settings/applications/AppOpsSummary.java @@ -153,7 +153,9 @@ public class AppOpsSummary extends InstrumentedFragment { Resources.Theme theme = tabs.getContext().getTheme(); TypedValue typedValue = new TypedValue(); theme.resolveAttribute(android.R.attr.colorAccent, typedValue, true); - final int colorAccent = getContext().getColor(typedValue.resourceId); + final int colorAccent = typedValue.resourceId != 0 + ? getContext().getColor(typedValue.resourceId) + : getContext().getColor(R.color.switch_accent_color); tabs.setTabIndicatorColor(colorAccent); // We have to do this now because PreferenceFrameLayout looks at it diff --git a/src/com/android/settings/applications/AppStateWriteSettingsBridge.java b/src/com/android/settings/applications/AppStateWriteSettingsBridge.java index 7cdf7ea..ef743fa 100644 --- a/src/com/android/settings/applications/AppStateWriteSettingsBridge.java +++ b/src/com/android/settings/applications/AppStateWriteSettingsBridge.java @@ -34,11 +34,9 @@ public class AppStateWriteSettingsBridge extends AppStateAppOpsBridge { private static final String TAG = "AppStateWriteSettingsBridge"; private static final int APP_OPS_OP_CODE = AppOpsManager.OP_WRITE_SETTINGS; private static final String PM_WRITE_SETTINGS = Manifest.permission.WRITE_SETTINGS; - private static final String PM_CHANGE_NETWORK_STATE = Manifest.permission.CHANGE_NETWORK_STATE; - // CHANGE_NETWORK_STATE is now merged with WRITE_SETTINGS + private static final String[] PM_PERMISSIONS = { - PM_WRITE_SETTINGS, - PM_CHANGE_NETWORK_STATE + PM_WRITE_SETTINGS }; public AppStateWriteSettingsBridge(Context context, ApplicationsState appState, Callback diff --git a/src/com/android/settings/applications/InstalledAppDetails.java b/src/com/android/settings/applications/InstalledAppDetails.java index c866d29..4d29c73 100755 --- a/src/com/android/settings/applications/InstalledAppDetails.java +++ b/src/com/android/settings/applications/InstalledAppDetails.java @@ -70,20 +70,20 @@ import com.android.internal.logging.MetricsLogger; import com.android.internal.os.BatterySipper; import com.android.internal.os.BatteryStatsHelper; import com.android.settings.DataUsageSummary; -import com.android.settings.DataUsageSummary.AppItem; import com.android.settings.R; import com.android.settings.SettingsActivity; import com.android.settings.Utils; import com.android.settings.applications.PermissionsSummaryHelper.PermissionsResultCallback; import com.android.settings.fuelgauge.BatteryEntry; import com.android.settings.fuelgauge.PowerUsageDetail; -import com.android.settings.net.ChartData; -import com.android.settings.net.ChartDataLoader; import com.android.settings.notification.AppNotificationSettings; import com.android.settings.notification.NotificationBackend; import com.android.settings.notification.NotificationBackend.AppRow; -import com.android.settingslib.applications.ApplicationsState; +import com.android.settingslib.AppItem; import com.android.settingslib.applications.ApplicationsState.AppEntry; +import com.android.settingslib.applications.ApplicationsState; +import com.android.settingslib.net.ChartData; +import com.android.settingslib.net.ChartDataLoader; import java.lang.ref.WeakReference; import java.util.ArrayList; diff --git a/src/com/android/settings/applications/RunningState.java b/src/com/android/settings/applications/RunningState.java index 2286a24..c63bcd8 100644 --- a/src/com/android/settings/applications/RunningState.java +++ b/src/com/android/settings/applications/RunningState.java @@ -45,8 +45,8 @@ import android.util.Log; import android.util.SparseArray; import com.android.settings.R; -import com.android.settings.Utils; import com.android.settingslib.applications.InterestingConfigChanges; +import com.android.settingslib.Utils; import java.util.ArrayList; import java.util.Collections; diff --git a/src/com/android/settings/cyanogenmod/BootReceiver.java b/src/com/android/settings/cyanogenmod/BootReceiver.java index 19d2434..19c2794 100644 --- a/src/com/android/settings/cyanogenmod/BootReceiver.java +++ b/src/com/android/settings/cyanogenmod/BootReceiver.java @@ -19,6 +19,9 @@ package com.android.settings.cyanogenmod; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; +import android.content.SharedPreferences; +import android.preference.PreferenceManager; + import com.android.settings.ButtonSettings; import com.android.settings.R; import com.android.settings.Utils; @@ -27,21 +30,39 @@ import com.android.settings.hardware.VibratorIntensity; import com.android.settings.inputmethod.InputMethodAndLanguageSettings; import com.android.settings.livedisplay.DisplayGamma; import com.android.settings.location.LocationSettings; +import com.android.settings.DevelopmentSettings; public class BootReceiver extends BroadcastReceiver { private static final String TAG = "BootReceiver"; + private static final String ONE_TIME_TUNABLE_RESTORE = "hardware_tunable_restored"; @Override public void onReceive(Context ctx, Intent intent) { - /* Restore the hardware tunable values */ - ButtonSettings.restoreKeyDisabler(ctx); - DisplayGamma.restore(ctx); - VibratorIntensity.restore(ctx); - InputMethodAndLanguageSettings.restore(ctx); + if (!hasRestoredTunable(ctx)) { + /* Restore the hardware tunable values */ + ButtonSettings.restoreKeyDisabler(ctx); + DisplayGamma.restore(ctx); + VibratorIntensity.restore(ctx); + InputMethodAndLanguageSettings.restore(ctx); + setRestoredTunable(ctx); + } + LocationSettings.restore(ctx); // Extract the contributors database ContributorsCloudFragment.extractContributorsCloudDatabase(ctx); + + DevelopmentSettings.initializeUpdateRecoveryOption(); + } + + private boolean hasRestoredTunable(Context context) { + SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); + return preferences.getBoolean(ONE_TIME_TUNABLE_RESTORE, false); + } + + private void setRestoredTunable(Context context) { + SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); + preferences.edit().putBoolean(ONE_TIME_TUNABLE_RESTORE, true).apply(); } } diff --git a/src/com/android/settings/cyanogenmod/CMGlobalSettingSwitchPreference.java b/src/com/android/settings/cyanogenmod/CMGlobalSettingSwitchPreference.java new file mode 100644 index 0000000..8609659 --- /dev/null +++ b/src/com/android/settings/cyanogenmod/CMGlobalSettingSwitchPreference.java @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2016 The CyanogenMod 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.cyanogenmod; + +import android.content.Context; +import android.preference.SwitchPreference; +import android.util.AttributeSet; + +import cyanogenmod.providers.CMSettings; + +public class CMGlobalSettingSwitchPreference extends SwitchPreference { + public CMGlobalSettingSwitchPreference(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + } + + public CMGlobalSettingSwitchPreference(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public CMGlobalSettingSwitchPreference(Context context) { + super(context, null); + } + + @Override + protected boolean persistBoolean(boolean value) { + if (shouldPersist()) { + if (value == getPersistedBoolean(!value)) { + // It's already there, so the same as persisting + return true; + } + CMSettings.Global.putInt(getContext().getContentResolver(), getKey(), value ? 1 : 0); + return true; + } + return false; + } + + @Override + protected boolean getPersistedBoolean(boolean defaultReturnValue) { + if (!shouldPersist()) { + return defaultReturnValue; + } + return CMSettings.Global.getInt(getContext().getContentResolver(), + getKey(), defaultReturnValue ? 1 : 0) != 0; + } + + @Override + protected boolean isPersisted() { + // Using getString instead of getInt so we can simply check for null + // instead of catching an exception. (All values are stored as strings.) + return CMSettings.Global.getString(getContext().getContentResolver(), getKey()) != null; + } +} diff --git a/src/com/android/settings/cyanogenmod/CMSecureSettingSwitchPreference.java b/src/com/android/settings/cyanogenmod/CMSecureSettingSwitchPreference.java index d425236..878ee95 100644 --- a/src/com/android/settings/cyanogenmod/CMSecureSettingSwitchPreference.java +++ b/src/com/android/settings/cyanogenmod/CMSecureSettingSwitchPreference.java @@ -18,8 +18,8 @@ package com.android.settings.cyanogenmod; import android.content.Context; import android.preference.SwitchPreference; -import android.provider.Settings; import android.util.AttributeSet; + import cyanogenmod.providers.CMSettings; public class CMSecureSettingSwitchPreference extends SwitchPreference { diff --git a/src/com/android/settings/cyanogenmod/CMSystemSettingSwitchPreference.java b/src/com/android/settings/cyanogenmod/CMSystemSettingSwitchPreference.java index c60638a..d8199e4 100644 --- a/src/com/android/settings/cyanogenmod/CMSystemSettingSwitchPreference.java +++ b/src/com/android/settings/cyanogenmod/CMSystemSettingSwitchPreference.java @@ -5,7 +5,7 @@ * 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 + * 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, @@ -19,6 +19,7 @@ package com.android.settings.cyanogenmod; import android.content.Context; import android.preference.SwitchPreference; import android.util.AttributeSet; + import cyanogenmod.providers.CMSettings; public class CMSystemSettingSwitchPreference extends SwitchPreference { diff --git a/src/com/android/settings/cyanogenmod/LockscreenSettingsAlias.java b/src/com/android/settings/cyanogenmod/LockscreenSettingsAlias.java new file mode 100644 index 0000000..d6ca06a --- /dev/null +++ b/src/com/android/settings/cyanogenmod/LockscreenSettingsAlias.java @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2016 The CyanogenMod 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.cyanogenmod; + +import com.android.internal.widget.LockPatternUtils; +import com.android.settings.SecuritySettings; +import com.android.settings.search.BaseSearchIndexProvider; +import com.android.settings.search.SearchIndexableRaw; + +import android.content.Context; +import android.content.pm.PackageManager; +import android.content.res.Resources; +import android.hardware.fingerprint.FingerprintManager; +import android.os.Bundle; +import android.os.UserHandle; +import android.os.UserManager; +import android.provider.SearchIndexableResource; +import com.android.settings.R; +import java.util.ArrayList; +import java.util.List; + +public class LockscreenSettingsAlias extends SecuritySettings { + public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = + new SecuritySearchIndexProvider(); + + private static class SecuritySearchIndexProvider extends BaseSearchIndexProvider { + + boolean mIsPrimary; + + public SecuritySearchIndexProvider() { + super(); + + mIsPrimary = MY_USER_ID == UserHandle.USER_OWNER; + } + + @Override + public List<SearchIndexableResource> getXmlResourcesToIndex( + Context context, boolean enabled) { + + List<SearchIndexableResource> result = new ArrayList<SearchIndexableResource>(); + + LockPatternUtils lockPatternUtils = new LockPatternUtils(context); + // Add options for lock/unlock screen + int resId = getResIdForLockUnlockScreen(context, lockPatternUtils); + + SearchIndexableResource sir = new SearchIndexableResource(context); + sir.xmlResId = resId; + result.add(sir); + + return result; + } + + @Override + public List<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled) { + final List<SearchIndexableRaw> result = new ArrayList<SearchIndexableRaw>(); + final Resources res = context.getResources(); + + final String screenTitle = res.getString(R.string.lockscreen_settings); + + SearchIndexableRaw data = new SearchIndexableRaw(context); + data.title = screenTitle; + data.screenTitle = screenTitle; + result.add(data); + + if (!mIsPrimary) { + int resId = (UserManager.get(context).isLinkedUser()) ? + R.string.profile_info_settings_title : R.string.user_info_settings_title; + + data = new SearchIndexableRaw(context); + data.title = res.getString(resId); + data.screenTitle = screenTitle; + result.add(data); + } + + // Fingerprint + FingerprintManager fpm = + (FingerprintManager) context.getSystemService(Context.FINGERPRINT_SERVICE); + if (fpm.isHardwareDetected()) { + // This catches the title which can be overloaded in an overlay + data = new SearchIndexableRaw(context); + data.title = res.getString(R.string.security_settings_fingerprint_preference_title); + data.screenTitle = screenTitle; + result.add(data); + // Fallback for when the above doesn't contain "fingerprint" + data = new SearchIndexableRaw(context); + data.title = res.getString(R.string.fingerprint_manage_category_title); + data.screenTitle = screenTitle; + result.add(data); + } + + PackageManager pm = context.getPackageManager(); + if (pm.hasSystemFeature(LIVE_LOCK_SCREEN_FEATURE)) { + data = new SearchIndexableRaw(context); + data.title = res.getString(R.string.live_lock_screen_title); + data.screenTitle = screenTitle; + result.add(data); + } + + return result; + } + } + + @Override + public void onCreate(Bundle savedInstanceState) { + Bundle bundle = getArguments(); + if (bundle != null) { + bundle.putInt(FILTER_TYPE_EXTRA, TYPE_LOCKSCREEN_EXTRA); + } + super.onCreate(savedInstanceState); + } +} diff --git a/src/com/android/settings/cyanogenmod/PowerMenuActions.java b/src/com/android/settings/cyanogenmod/PowerMenuActions.java index 932d4e5..6a02a97 100644 --- a/src/com/android/settings/cyanogenmod/PowerMenuActions.java +++ b/src/com/android/settings/cyanogenmod/PowerMenuActions.java @@ -35,7 +35,9 @@ import com.android.internal.logging.MetricsLogger; import com.android.settings.R; import com.android.settings.SettingsPreferenceFragment; import com.android.internal.util.cm.PowerMenuConstants; + import cyanogenmod.providers.CMSettings; + import org.cyanogenmod.internal.logging.CMMetricsLogger; import static com.android.internal.util.cm.PowerMenuConstants.*; @@ -49,7 +51,6 @@ public class PowerMenuActions extends SettingsPreferenceFragment { private CheckBoxPreference mRebootPref; private CheckBoxPreference mScreenshotPref; - private CheckBoxPreference mProfilePref; private CheckBoxPreference mAirplanePref; private CheckBoxPreference mUsersPref; private CheckBoxPreference mSettingsPref; @@ -252,17 +253,6 @@ public class PowerMenuActions extends SettingsPreferenceFragment { private void updatePreferences() { boolean bugreport = Settings.Secure.getInt(getContentResolver(), Settings.Secure.BUGREPORT_IN_POWER_MENU, 0) != 0; - boolean profiles = CMSettings.System.getInt(getContentResolver(), - CMSettings.System.SYSTEM_PROFILES_ENABLED, 1) != 0; - - if (mProfilePref != null) { - mProfilePref.setEnabled(profiles); - if (profiles) { - mProfilePref.setSummary(null); - } else { - mProfilePref.setSummary(R.string.power_menu_profiles_disabled); - } - } if (mBugReportPref != null) { mBugReportPref.setEnabled(bugreport); diff --git a/src/com/android/settings/cyanogenmod/SpamList.java b/src/com/android/settings/cyanogenmod/SpamList.java index 1403987..184ca6c 100644 --- a/src/com/android/settings/cyanogenmod/SpamList.java +++ b/src/com/android/settings/cyanogenmod/SpamList.java @@ -119,7 +119,7 @@ public class SpamList extends ListFragment { @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { menu.add(0, MENU_NOTIFICATIONS, 0, R.string.volume_notification_description) - .setIcon(R.drawable.ic_settings_notifications) + .setIcon(R.drawable.ic_filter_notifications) .setAlphabeticShortcut('n') .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_WITH_TEXT); diff --git a/src/com/android/settings/deviceinfo/Status.java b/src/com/android/settings/deviceinfo/Status.java index 270da97..4c905eb 100644 --- a/src/com/android/settings/deviceinfo/Status.java +++ b/src/com/android/settings/deviceinfo/Status.java @@ -425,9 +425,9 @@ public class Status extends InstrumentedPreferenceActivity { public static String getSarValues(Resources res) { String headLevel = String.format(res.getString(R.string.maximum_head_level, - TextUtils.split(res.getString(R.string.sar_head_level), ","))); + res.getString(R.string.sar_head_level).split(","))); String bodyLevel = String.format(res.getString(R.string.maximum_body_level, - TextUtils.split(res.getString(R.string.sar_body_level), ","))); + res.getString(R.string.sar_body_level).split(","))); return headLevel + "\n" + bodyLevel; } diff --git a/src/com/android/settings/deviceinfo/StorageSettings.java b/src/com/android/settings/deviceinfo/StorageSettings.java index c36d0df..8f56a7c 100644 --- a/src/com/android/settings/deviceinfo/StorageSettings.java +++ b/src/com/android/settings/deviceinfo/StorageSettings.java @@ -23,8 +23,8 @@ import android.app.Fragment; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; -import android.graphics.Color; import android.graphics.drawable.Drawable; +import android.graphics.PorterDuff; import android.os.AsyncTask; import android.os.Bundle; import android.os.storage.DiskInfo; @@ -63,16 +63,10 @@ public class StorageSettings extends SettingsPreferenceFragment implements Index private static final String TAG_VOLUME_UNMOUNTED = "volume_unmounted"; private static final String TAG_DISK_INIT = "disk_init"; - static final int COLOR_PUBLIC = Color.parseColor("#ff9e9e9e"); - static final int COLOR_WARNING = Color.parseColor("#fff4511e"); - static final int[] COLOR_PRIVATE = new int[] { - Color.parseColor("#ff26a69a"), - Color.parseColor("#ffab47bc"), - Color.parseColor("#fff2a600"), - Color.parseColor("#ffec407a"), - Color.parseColor("#ffc0ca33"), - }; + private int mPublicColor; + + private int[] mPrivateColors; private StorageManager mStorageManager; @@ -108,6 +102,14 @@ public class StorageSettings extends SettingsPreferenceFragment implements Index mInternalSummary = new StorageSummaryPreference(context); setHasOptionsMenu(true); + mPublicColor = context.getColor(R.color.storage_volume_color_public); + mPrivateColors = new int[] { + context.getColor(R.color.storage_volume_color_private1), + context.getColor(R.color.storage_volume_color_private2), + context.getColor(R.color.storage_volume_color_private3), + context.getColor(R.color.storage_volume_color_private4), + context.getColor(R.color.storage_volume_color_private5), + }; } private final StorageEventListener mStorageListener = new StorageEventListener() { @@ -147,7 +149,7 @@ public class StorageSettings extends SettingsPreferenceFragment implements Index for (VolumeInfo vol : volumes) { if (vol.getType() == VolumeInfo.TYPE_PRIVATE) { - final int color = COLOR_PRIVATE[privateCount++ % COLOR_PRIVATE.length]; + final int color = mPrivateColors[privateCount++ % mPrivateColors.length]; mInternalCategory.addPreference( new StorageVolumePreference(context, vol, color)); if (vol.isMountedReadable()) { @@ -157,7 +159,7 @@ public class StorageSettings extends SettingsPreferenceFragment implements Index } } else if (vol.getType() == VolumeInfo.TYPE_PUBLIC) { mExternalCategory.addPreference( - new StorageVolumePreference(context, vol, COLOR_PUBLIC)); + new StorageVolumePreference(context, vol, mPublicColor)); } } @@ -169,7 +171,8 @@ public class StorageSettings extends SettingsPreferenceFragment implements Index // TODO: add actual storage type to record final Drawable icon = context.getDrawable(R.drawable.ic_sim_sd); icon.mutate(); - icon.setTint(COLOR_PUBLIC); + icon.setTint(mPublicColor); + icon.setTintMode(PorterDuff.Mode.SRC_ATOP); final Preference pref = new Preference(context); pref.setKey(rec.getFsUuid()); diff --git a/src/com/android/settings/deviceinfo/StorageVolumePreference.java b/src/com/android/settings/deviceinfo/StorageVolumePreference.java index e59f3f6..7668884 100644 --- a/src/com/android/settings/deviceinfo/StorageVolumePreference.java +++ b/src/com/android/settings/deviceinfo/StorageVolumePreference.java @@ -18,8 +18,10 @@ package com.android.settings.deviceinfo; import android.content.Context; import android.content.res.ColorStateList; +import android.content.res.Resources; import android.graphics.Color; import android.graphics.drawable.Drawable; +import android.graphics.PorterDuff; import android.os.storage.StorageManager; import android.os.storage.VolumeInfo; import android.preference.Preference; @@ -77,7 +79,7 @@ public class StorageVolumePreference extends Preference { mUsedPercent = (int) ((usedBytes * 100) / totalBytes); if (freeBytes < mStorageManager.getStorageLowBytes(path)) { - mColor = StorageSettings.COLOR_WARNING; + mColor = context.getColor(R.color.storage_volume_color_warning); icon = context.getDrawable(R.drawable.ic_warning_24dp); } @@ -88,6 +90,7 @@ public class StorageVolumePreference extends Preference { icon.mutate(); icon.setTint(mColor); + icon.setTintMode(PorterDuff.Mode.SRC_ATOP); setIcon(icon); if (volume.getType() == VolumeInfo.TYPE_PUBLIC @@ -99,9 +102,12 @@ public class StorageVolumePreference extends Preference { @Override protected void onBindView(View view) { + final ImageView unmount = (ImageView) view.findViewById(R.id.unmount); + if (unmount != null) { - unmount.setImageTintList(ColorStateList.valueOf(Color.parseColor("#8a000000"))); + unmount.setImageTintList(ColorStateList.valueOf( + getContext().getColor(R.color.eject_icon_tint_color))); unmount.setOnClickListener(mUnmountListener); } diff --git a/src/com/android/settings/drawable/CircleFramedDrawable.java b/src/com/android/settings/drawable/CircleFramedDrawable.java deleted file mode 100644 index 31b8922..0000000 --- a/src/com/android/settings/drawable/CircleFramedDrawable.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (C) 2013 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.drawable; - -import android.content.Context; -import android.content.res.Resources; -import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.ColorFilter; -import android.graphics.Paint; -import android.graphics.Path; -import android.graphics.PixelFormat; -import android.graphics.PorterDuff; -import android.graphics.PorterDuffXfermode; -import android.graphics.Rect; -import android.graphics.RectF; -import android.graphics.drawable.Drawable; - -import com.android.settings.R; - -/** - * Converts the user avatar icon to a circularly clipped one. - * TODO: Move this to an internal framework class and share with the one in Keyguard. - */ -public class CircleFramedDrawable extends Drawable { - - private final Bitmap mBitmap; - private final int mSize; - private final Paint mPaint; - - private float mScale; - private Rect mSrcRect; - private RectF mDstRect; - - public static CircleFramedDrawable getInstance(Context context, Bitmap icon) { - Resources res = context.getResources(); - float iconSize = res.getDimension(R.dimen.circle_avatar_size); - - CircleFramedDrawable instance = new CircleFramedDrawable(icon, (int) iconSize); - return instance; - } - - public CircleFramedDrawable(Bitmap icon, int size) { - super(); - mSize = size; - - mBitmap = Bitmap.createBitmap(mSize, mSize, Bitmap.Config.ARGB_8888); - final Canvas canvas = new Canvas(mBitmap); - - final int width = icon.getWidth(); - final int height = icon.getHeight(); - final int square = Math.min(width, height); - - final Rect cropRect = new Rect((width - square) / 2, (height - square) / 2, square, square); - final RectF circleRect = new RectF(0f, 0f, mSize, mSize); - - final Path fillPath = new Path(); - fillPath.addArc(circleRect, 0f, 360f); - - canvas.drawColor(0, PorterDuff.Mode.CLEAR); - - // opaque circle matte - mPaint = new Paint(); - mPaint.setAntiAlias(true); - mPaint.setColor(Color.BLACK); - mPaint.setStyle(Paint.Style.FILL); - canvas.drawPath(fillPath, mPaint); - - // mask in the icon where the bitmap is opaque - mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); - canvas.drawBitmap(icon, cropRect, circleRect, mPaint); - - // prepare paint for frame drawing - mPaint.setXfermode(null); - - mScale = 1f; - - mSrcRect = new Rect(0, 0, mSize, mSize); - mDstRect = new RectF(0, 0, mSize, mSize); - } - - @Override - public void draw(Canvas canvas) { - final float inside = mScale * mSize; - final float pad = (mSize - inside) / 2f; - - mDstRect.set(pad, pad, mSize - pad, mSize - pad); - canvas.drawBitmap(mBitmap, mSrcRect, mDstRect, null); - } - - public void setScale(float scale) { - mScale = scale; - } - - public float getScale() { - return mScale; - } - - @Override - public int getOpacity() { - return PixelFormat.TRANSLUCENT; - } - - @Override - public void setAlpha(int alpha) { - } - - @Override - public void setColorFilter(ColorFilter cf) { - } - - @Override - public int getIntrinsicWidth() { - return mSize; - } - - @Override - public int getIntrinsicHeight() { - return mSize; - } -} diff --git a/src/com/android/settings/fingerprint/FingerprintEnrollIntroduction.java b/src/com/android/settings/fingerprint/FingerprintEnrollIntroduction.java index beb1a8f..5753459 100644 --- a/src/com/android/settings/fingerprint/FingerprintEnrollIntroduction.java +++ b/src/com/android/settings/fingerprint/FingerprintEnrollIntroduction.java @@ -20,6 +20,7 @@ import android.app.admin.DevicePolicyManager; import android.content.Intent; import android.os.Bundle; import android.os.UserHandle; +import android.text.TextUtils; import android.view.View; import com.android.internal.logging.MetricsLogger; @@ -40,7 +41,15 @@ public class FingerprintEnrollIntroduction extends FingerprintEnrollBase { setContentView(R.layout.fingerprint_enroll_introduction); setHeaderText(R.string.security_settings_fingerprint_enroll_introduction_title); findViewById(R.id.cancel_button).setOnClickListener(this); - findViewById(R.id.learn_more_button).setOnClickListener(this); + + final View learnMoreButton = findViewById(R.id.learn_more_button); + // If help url is not overlaid, remove the button. + if (TextUtils.isEmpty(getString(R.string.help_url_fingerprint))) { + learnMoreButton.setVisibility(View.GONE); + } else { + learnMoreButton.setOnClickListener(this); + } + final int passwordQuality = new ChooseLockSettingsHelper(this).utils() .getActivePasswordQuality(UserHandle.myUserId()); mHasPassword = passwordQuality != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; diff --git a/src/com/android/settings/fuelgauge/BatteryEntry.java b/src/com/android/settings/fuelgauge/BatteryEntry.java index c034d19..fb211dc 100644 --- a/src/com/android/settings/fuelgauge/BatteryEntry.java +++ b/src/com/android/settings/fuelgauge/BatteryEntry.java @@ -32,7 +32,7 @@ import android.util.Log; import com.android.internal.os.BatterySipper; import com.android.settings.R; -import com.android.settings.Utils; +import com.android.settingslib.Utils; import java.util.ArrayList; import java.util.HashMap; diff --git a/src/com/android/settings/fuelgauge/BatteryHistoryChart.java b/src/com/android/settings/fuelgauge/BatteryHistoryChart.java index 76acf69..85813eb 100644 --- a/src/com/android/settings/fuelgauge/BatteryHistoryChart.java +++ b/src/com/android/settings/fuelgauge/BatteryHistoryChart.java @@ -128,6 +128,7 @@ public class BatteryHistoryChart extends View { final Paint mBatteryWarnPaint = new Paint(Paint.ANTI_ALIAS_FLAG); final Paint mBatteryCriticalPaint = new Paint(Paint.ANTI_ALIAS_FLAG); final Paint mTimeRemainPaint = new Paint(Paint.ANTI_ALIAS_FLAG); + final Paint mDockBatteryBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG); final Paint mChargingPaint = new Paint(); final Paint mScreenOnPaint = new Paint(); final Paint mGpsOnPaint = new Paint(); @@ -146,6 +147,7 @@ public class BatteryHistoryChart extends View { final Path mBatWarnPath = new Path(); final Path mBatCriticalPath = new Path(); final Path mTimeRemainPath = new Path(); + final Path mDockBatLevelPath = new Path(); final Path mChargingPath = new Path(); final Path mScreenOnPath = new Path(); final Path mGpsOnPath = new Path(); @@ -156,13 +158,17 @@ public class BatteryHistoryChart extends View { final Path mDateLinePath = new Path(); BatteryStats mStats; + BatteryStats mDockStats; Intent mBatteryBroadcast; long mStatsPeriod; int mBatteryLevel; + long mDockStatsPeriod; + int mDockBatteryLevel; String mMaxPercentLabelString; String mMinPercentLabelString; String mDurationString; String mChargeLabelString; + String mDockChargeLabelString; String mChargeDurationString; String mDrainString; String mChargingLabel; @@ -213,13 +219,21 @@ public class BatteryHistoryChart extends View { int mLevelRight; int mNumHist; + int mDockNumHist; long mHistStart; long mHistDataEnd; long mHistEnd; long mStartWallTime; long mEndDataWallTime; long mEndWallTime; + long mDockHistStart; + long mDockHistDataEnd; + long mDockHistEnd; + long mDockStartWallTime; + long mDockEndDataWallTime; + long mDockEndWallTime; boolean mDischarging; + boolean mDockDischarging; int mBatLow; int mBatHigh; boolean mHaveWifi; @@ -234,6 +248,8 @@ public class BatteryHistoryChart extends View { Bitmap mBitmap; Canvas mCanvas; + private final boolean mDockBatterySupported; + static class TextAttrs { ColorStateList textColor = null; int textSize = 15; @@ -356,6 +372,10 @@ public class BatteryHistoryChart extends View { if (DEBUG) Log.d(TAG, "New BatteryHistoryChart!"); + BatteryManager mBatteryService = (BatteryManager) context.getSystemService( + Context.BATTERY_SERVICE); + mDockBatterySupported = mBatteryService.isDockBatterySupported(); + mBatteryWarnLevel = mContext.getResources().getInteger( com.android.internal.R.integer.config_lowBatteryWarningLevel); mBatteryCriticalLevel = mContext.getResources().getInteger( @@ -374,6 +394,10 @@ public class BatteryHistoryChart extends View { mBatteryCriticalPaint.setStyle(Paint.Style.STROKE); mTimeRemainPaint.setColor(0xFFCED7BB); mTimeRemainPaint.setStyle(Paint.Style.FILL); + if (mDockBatterySupported) { + mDockBatteryBackgroundPaint.setColor(0x803CA8B8); + mDockBatteryBackgroundPaint.setStyle(Paint.Style.FILL); + } mChargingPaint.setStyle(Paint.Style.STROKE); mScreenOnPaint.setStyle(Paint.Style.STROKE); mGpsOnPaint.setStyle(Paint.Style.STROKE); @@ -629,6 +653,93 @@ public class BatteryHistoryChart extends View { if (mHistEnd <= mHistStart) mHistEnd = mHistStart+1; } + void setDockStats(BatteryStats dockStats, Intent broadcast) { + mDockStats = dockStats; + if (mDockBatterySupported && dockStats != null) { + final long elapsedRealtimeUs = SystemClock.elapsedRealtime() * 1000; + + long uSecTime = mDockStats.computeBatteryRealtime(elapsedRealtimeUs, + BatteryStats.STATS_SINCE_CHARGED); + mDockStatsPeriod = uSecTime; + + mDockBatteryLevel = com.android.settings.Utils.getDockBatteryLevel(mBatteryBroadcast); + String batteryPercentString = Utils.formatPercentage(mDockBatteryLevel); + long remainingTimeUs = 0; + mDockDischarging = true; + if (mBatteryBroadcast.getBooleanExtra(BatteryManager.EXTRA_DOCK_PRESENT, false)) { + // We need to add a extra check over the status because of dock batteries + // PlugType doesn't means that the dock battery is charging (some devices + // doesn't charge under dock usb) + int plugType = mBatteryBroadcast.getIntExtra(BatteryManager.EXTRA_DOCK_PLUGGED, 0); + int status = mBatteryBroadcast.getIntExtra(BatteryManager.EXTRA_DOCK_STATUS, + BatteryManager.BATTERY_STATUS_UNKNOWN); + boolean plugged = plugType != 0 && + (status == BatteryManager.BATTERY_STATUS_CHARGING || + status == BatteryManager.BATTERY_STATUS_FULL); + if (!plugged) { + mDockChargeLabelString = batteryPercentString; + } else { + final String statusLabel = com.android.settings.Utils.getDockBatteryStatus( + getResources(), mBatteryBroadcast); + mDockChargeLabelString = getContext().getResources().getString( + R.string.power_charging, batteryPercentString, statusLabel); + } + } else { + mDockChargeLabelString = getContext().getResources().getString( + R.string.dock_battery_not_present); + } + + int pos = 0; + int lastInteresting = 0; + byte lastLevel = -1; + long lastWallTime = 0; + long lastRealtime = 0; + boolean first = true; + if (dockStats.startIteratingHistoryLocked()) { + final HistoryItem rec = new HistoryItem(); + while (dockStats.getNextHistoryLocked(rec)) { + pos++; + if (first) { + first = false; + mDockHistStart = rec.time; + } + if (rec.cmd == HistoryItem.CMD_CURRENT_TIME + || rec.cmd == HistoryItem.CMD_RESET) { + // If there is a ridiculously large jump in time, then we won't be + // able to create a good chart with that data, so just ignore the + // times we got before and pretend like our data extends back from + // the time we have now. + // Also, if we are getting a time change and we are less than 5 minutes + // since the start of the history real time, then also use this new + // time to compute the base time, since whatever time we had before is + // pretty much just noise. + if (rec.currentTime > (lastWallTime+(180*24*60*60*1000L)) + || rec.time < (mDockHistStart+(5*60*1000L))) { + mDockStartWallTime = 0; + } + lastWallTime = rec.currentTime; + lastRealtime = rec.time; + if (mDockStartWallTime == 0) { + mDockStartWallTime = lastWallTime - (lastRealtime-mDockHistStart); + } + } + if (rec.isDeltaData()) { + if (rec.batteryLevel != lastLevel || pos == 1) { + lastLevel = rec.batteryLevel; + } + lastInteresting = pos; + mDockHistDataEnd = rec.time; + } + } + } + mDockHistEnd = mDockHistDataEnd + (remainingTimeUs/1000); + mDockEndDataWallTime = lastWallTime + mDockHistDataEnd - lastRealtime; + mDockEndWallTime = mDockEndDataWallTime + (remainingTimeUs/1000); + mDockNumHist = lastInteresting; + if (mDockHistEnd <= mDockHistStart) mDockHistEnd = mDockHistStart+1; + } + } + @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { mMaxPercentLabelStringWidth = (int)mTextPaint.measureText(mMaxPercentLabelString); @@ -642,6 +753,9 @@ public class BatteryHistoryChart extends View { mHeaderTextDescent = (int)mHeaderTextPaint.descent(); int headerTextHeight = mHeaderTextDescent - mHeaderTextAscent; mHeaderHeight = headerTextHeight*2 - mTextAscent; + if (mDockBatterySupported) { + mHeaderHeight += headerTextHeight; + } setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec), getDefaultSize(mChartMinHeight+mHeaderHeight, heightMeasureSpec)); } @@ -650,18 +764,7 @@ public class BatteryHistoryChart extends View { int lastX, boolean lastCharging, boolean lastScreenOn, boolean lastGpsOn, boolean lastFlashlightOn, boolean lastCameraOn, boolean lastWifiRunning, boolean lastCpuRunning, Path lastPath) { - if (curLevelPath != null) { - if (lastX >= 0 && lastX < w) { - if (lastPath != null) { - lastPath.lineTo(w, y); - } - curLevelPath.lineTo(w, y); - } - curLevelPath.lineTo(w, mLevelTop+levelh); - curLevelPath.lineTo(startX, mLevelTop+levelh); - curLevelPath.close(); - } - + finishCurLevelPath(w, levelh, startX, y, curLevelPath, lastX, lastPath); if (lastCharging) { mChargingPath.lineTo(w, h-mChargingOffset); } @@ -688,6 +791,21 @@ public class BatteryHistoryChart extends View { } } + void finishCurLevelPath(int w, int levelh, int startX, int y, + Path curLevelPath, int lastX, Path lastPath) { + if (curLevelPath != null) { + if (lastX >= 0 && lastX < w) { + if (lastPath != null) { + lastPath.lineTo(w, y); + } + curLevelPath.lineTo(w, y); + } + curLevelPath.lineTo(w, mLevelTop+levelh); + curLevelPath.lineTo(startX, mLevelTop+levelh); + curLevelPath.close(); + } + } + private boolean is24Hour() { return DateFormat.is24HourFormat(getContext()); } @@ -782,8 +900,11 @@ public class BatteryHistoryChart extends View { mBatLevelPath.reset(); mBatGoodPath.reset(); mBatWarnPath.reset(); - mTimeRemainPath.reset(); mBatCriticalPath.reset(); + mTimeRemainPath.reset(); + if (mDockBatterySupported) { + mDockBatLevelPath.reset(); + } mScreenOnPath.reset(); mGpsOnPath.reset(); mFlashlightOnPath.reset(); @@ -795,9 +916,14 @@ public class BatteryHistoryChart extends View { mTimeLabels.clear(); mDateLabels.clear(); - final long walltimeStart = mStartWallTime; - final long walltimeChange = mEndWallTime > walltimeStart - ? (mEndWallTime-walltimeStart) : 1; + final long walltimeStart = mDockBatterySupported + ? Math.min(mStartWallTime, mDockStartWallTime) : mStartWallTime; + long w1 = mEndWallTime > walltimeStart ? (mEndWallTime-walltimeStart) : 1; + long w2 = mEndWallTime > walltimeStart ? (mEndWallTime-walltimeStart) : 1; + final long walltimeChange = mDockBatterySupported + ? Math.max(w1, w2) : w1; + + long curWalltime = mStartWallTime; long lastRealtime = 0; @@ -815,7 +941,7 @@ public class BatteryHistoryChart extends View { boolean lastFlashlightOn = false, lastCameraOn = false; boolean lastWifiRunning = false, lastWifiSupplRunning = false, lastCpuRunning = false; int lastWifiSupplState = BatteryStats.WIFI_SUPPL_STATE_INVALID; - final int N = mNumHist; + int N = mNumHist; if (mEndDataWallTime > mStartWallTime && mStats.startIteratingHistoryLocked()) { final HistoryItem rec = new HistoryItem(); while (mStats.getNextHistoryLocked(rec) && i < N) { @@ -1052,6 +1178,7 @@ public class BatteryHistoryChart extends View { finishPaths(x, h, levelh, startX, lastY, curLevelPath, lastX, lastCharging, lastScreenOn, lastGpsOn, lastFlashlightOn, lastCameraOn, lastWifiRunning, lastCpuRunning, lastLinePath); + int lastBatX = x; if (x < w) { // If we reserved room for the remaining time, create a final path to draw @@ -1069,6 +1196,117 @@ public class BatteryHistoryChart extends View { mTimeRemainPath.close(); } + // And now set the dock battery if is supported + if (mDockBatterySupported) { + x = mLevelLeft; + y = 0; + startX = mLevelLeft; + lastX = -1; + lastY = -1; + i = 0; + curLevelPath = null; + lastLinePath = null; + curWalltime = mDockStartWallTime; + lastRealtime = 0; + lastCharging = false; + N = mDockNumHist; + if (mDockEndDataWallTime > mDockStartWallTime + && mDockStats.startIteratingHistoryLocked()) { + final HistoryItem rec = new HistoryItem(); + while (mDockStats.getNextHistoryLocked(rec) && i < N) { + if (rec.isDeltaData()) { + curWalltime += rec.time-lastRealtime; + lastRealtime = rec.time; + int pos = (int)(((curWalltime-walltimeStart)*levelWidth)/walltimeChange); + x = mLevelLeft + pos; + if (x < 0) { + x = 0; + } + if (false) { + StringBuilder sb = new StringBuilder(128); + sb.append("walloff="); + TimeUtils.formatDuration(curWalltime - walltimeStart, sb); + sb.append(" wallchange="); + TimeUtils.formatDuration(walltimeChange, sb); + sb.append(" x="); + sb.append(x); + Log.d("foo", sb.toString()); + } + y = mLevelTop + levelh - ((rec.batteryLevel-batLow)*(levelh-1))/batChange; + + if (lastX != x) { + // We have moved by at least a pixel. + if (lastY != y) { + if (curLevelPath == null) { + curLevelPath = mDockBatLevelPath; + curLevelPath.moveTo(x, y); + startX = x; + } else { + curLevelPath.lineTo(x, y); + } + lastX = x; + lastY = y; + } + } + + } else { + long lastWalltime = curWalltime; + if (rec.cmd == HistoryItem.CMD_CURRENT_TIME + || rec.cmd == HistoryItem.CMD_RESET) { + if (rec.currentTime >= mDockStartWallTime) { + curWalltime = rec.currentTime; + } else { + curWalltime = mDockStartWallTime + (rec.time-mDockHistStart); + } + lastRealtime = rec.time; + } + + if (rec.cmd != HistoryItem.CMD_OVERFLOW + && (rec.cmd != HistoryItem.CMD_CURRENT_TIME + || Math.abs(lastWalltime-curWalltime) > (60*60*1000))) { + if (curLevelPath != null) { + finishCurLevelPath(x+1,levelh, startX, lastY, curLevelPath, lastX, + lastLinePath); + lastX = lastY = -1; + curLevelPath = null; + lastLinePath = null; + lastCharging = lastScreenOn = lastGpsOn = lastCpuRunning = false; + } + } + } + + i++; + } + mDockStats.finishIteratingHistoryLocked(); + } + + if (lastY < 0 || lastX < 0) { + // Didn't get any data... + x = lastX = mLevelLeft; + y = lastY = mLevelTop + levelh - ((mDockBatteryLevel-batLow)*(levelh-1))/batChange; + mDockBatLevelPath.moveTo(x, y); + curLevelPath = mDockBatLevelPath; + x = w; + } else { + // Figure out where the actual data ends on the screen. + int pos = (int)(((mDockEndDataWallTime-walltimeStart)*levelWidth)/walltimeChange); + x = mLevelLeft + pos; + if (x < 0) { + x = 0; + } + } + + if (x < lastBatX) { + if (curLevelPath != null) { + curLevelPath.lineTo(x, lastY); + } + x = lastBatX; + } + + finishCurLevelPath(x,levelh, startX, lastY, curLevelPath, lastX, + lastLinePath); + } + if (mStartWallTime > 0 && mEndWallTime > mStartWallTime) { // Create the time labels at the bottom. boolean is24hr = is24Hour(); @@ -1202,6 +1440,9 @@ public class BatteryHistoryChart extends View { if (DEBUG) Log.d(TAG, "Drawing time remain path."); canvas.drawPath(mTimeRemainPath, mTimeRemainPaint); } + if (mDockBatterySupported && !mDockBatLevelPath.isEmpty()) { + canvas.drawPath(mDockBatLevelPath, mDockBatteryBackgroundPaint); + } if (mTimeLabels.size() > 1) { int y = mLevelBottom - mTextAscent + (mThinLineWidth*4); int ytick = mLevelBottom+mThinLineWidth+(mThinLineWidth/2); @@ -1253,6 +1494,11 @@ public class BatteryHistoryChart extends View { mHeaderTextPaint.setTextAlign(textAlignLeft); if (DEBUG) Log.d(TAG, "Drawing charge label string: " + mChargeLabelString); canvas.drawText(mChargeLabelString, textStartX, headerTop, mHeaderTextPaint); + if (mDockBatterySupported) { + if (DEBUG) Log.d(TAG, "Drawing dock charge label string: " + mDockChargeLabelString); + canvas.drawText(mDockChargeLabelString, textStartX, + headerTop + (mHeaderTextDescent - mHeaderTextAscent), mHeaderTextPaint); + } int stringHalfWidth = mChargeDurationStringWidth / 2; if (layoutRtl) stringHalfWidth = -stringHalfWidth; int headerCenter = ((width-mChargeDurationStringWidth-mDrainStringWidth)/2) diff --git a/src/com/android/settings/fuelgauge/BatteryHistoryDetail.java b/src/com/android/settings/fuelgauge/BatteryHistoryDetail.java index c977063..c1afe7b 100644 --- a/src/com/android/settings/fuelgauge/BatteryHistoryDetail.java +++ b/src/com/android/settings/fuelgauge/BatteryHistoryDetail.java @@ -30,9 +30,11 @@ import com.android.settings.R; public class BatteryHistoryDetail extends InstrumentedFragment { public static final String EXTRA_STATS = "stats"; + public static final String EXTRA_DOCK_STATS = "dock_stats"; public static final String EXTRA_BROADCAST = "broadcast"; private BatteryStats mStats; + private BatteryStats mDockStats; private Intent mBatteryBroadcast; @Override @@ -40,6 +42,12 @@ public class BatteryHistoryDetail extends InstrumentedFragment { super.onCreate(icicle); String histFile = getArguments().getString(EXTRA_STATS); mStats = BatteryStatsHelper.statsFromFile(getActivity(), histFile); + String dockHistFile = getArguments().getString(EXTRA_DOCK_STATS); + if (dockHistFile != null) { + mDockStats = BatteryStatsHelper.statsFromFile(getActivity(), dockHistFile); + } else { + mDockStats = null; + } mBatteryBroadcast = getArguments().getParcelable(EXTRA_BROADCAST); } @@ -49,6 +57,7 @@ public class BatteryHistoryDetail extends InstrumentedFragment { BatteryHistoryChart chart = (BatteryHistoryChart)view.findViewById( R.id.battery_history_chart); chart.setStats(mStats, mBatteryBroadcast); + chart.setDockStats(mDockStats, mBatteryBroadcast); return view; } diff --git a/src/com/android/settings/fuelgauge/BatteryHistoryPreference.java b/src/com/android/settings/fuelgauge/BatteryHistoryPreference.java index 0bf85b5..8c13a76 100644 --- a/src/com/android/settings/fuelgauge/BatteryHistoryPreference.java +++ b/src/com/android/settings/fuelgauge/BatteryHistoryPreference.java @@ -38,8 +38,10 @@ import com.android.settings.SettingsActivity; public class BatteryHistoryPreference extends Preference { protected static final String BATTERY_HISTORY_FILE = "tmp_bat_history.bin"; + protected static final String DOCK_BATTERY_HISTORY_FILE = "tmp_dock_bat_history.bin"; private BatteryStats mStats; + private BatteryStats mDockStats; private Intent mBatteryBroadcast; private BatteryHistoryChart mChart; @@ -57,6 +59,11 @@ public class BatteryHistoryPreference extends Preference { mHelper.storeStatsHistoryInFile(BATTERY_HISTORY_FILE); Bundle args = new Bundle(); args.putString(BatteryHistoryDetail.EXTRA_STATS, BATTERY_HISTORY_FILE); + if (mDockStats != null) { + mHelper.storeDockStatsHistoryInFile(DOCK_BATTERY_HISTORY_FILE); + args.putString(BatteryHistoryDetail.EXTRA_DOCK_STATS, DOCK_BATTERY_HISTORY_FILE); + } + args.putParcelable(BatteryHistoryDetail.EXTRA_BROADCAST, mHelper.getBatteryBroadcast()); if (getContext() instanceof SettingsActivity) { @@ -71,6 +78,7 @@ public class BatteryHistoryPreference extends Preference { mChart = null; mHelper = batteryStats; mStats = batteryStats.getStats(); + mDockStats = batteryStats.getDockStats(); mBatteryBroadcast = batteryStats.getBatteryBroadcast(); if (getLayoutResource() != R.layout.battery_history_chart) { // Now we should have some data, set the layout we want. @@ -79,10 +87,6 @@ public class BatteryHistoryPreference extends Preference { notifyChanged(); } - BatteryStats getStats() { - return mStats; - } - @Override protected void onBindView(View view) { super.onBindView(view); @@ -95,6 +99,7 @@ public class BatteryHistoryPreference extends Preference { if (mChart == null) { // First time: use and initialize this chart. chart.setStats(mStats, mBatteryBroadcast); + chart.setDockStats(mDockStats, mBatteryBroadcast); mChart = chart; } else { // All future times: forget the newly inflated chart, re-use the diff --git a/src/com/android/settings/fuelgauge/PowerUsageDetail.java b/src/com/android/settings/fuelgauge/PowerUsageDetail.java index 129322b..910daa7 100644 --- a/src/com/android/settings/fuelgauge/PowerUsageDetail.java +++ b/src/com/android/settings/fuelgauge/PowerUsageDetail.java @@ -86,9 +86,10 @@ public class PowerUsageDetail extends PowerUsageBase implements Button.OnClickLi SettingsActivity caller, BatteryStatsHelper helper, int statsType, BatteryEntry entry, boolean showLocationButton) { // Initialize mStats if necessary. - helper.getStats(); + final BatteryStats stats = helper.getStats(); + helper.getDockStats(); - final int dischargeAmount = helper.getStats().getDischargeAmount(statsType); + final int dischargeAmount = stats.getDischargeAmount(statsType); Bundle args = new Bundle(); args.putString(PowerUsageDetail.EXTRA_TITLE, entry.name); args.putInt(PowerUsageDetail.EXTRA_PERCENT, (int) @@ -151,15 +152,13 @@ public class PowerUsageDetail extends PowerUsageBase implements Button.OnClickLi if (entry.sipper.drainType == BatterySipper.DrainType.APP) { Writer result = new StringWriter(); PrintWriter printWriter = new FastPrintWriter(result, false, 1024); - helper.getStats().dumpLocked(caller, printWriter, "", helper.getStatsType(), - uid.getUid()); + stats.dumpLocked(caller, printWriter, "", helper.getStatsType(), uid.getUid()); printWriter.flush(); args.putString(PowerUsageDetail.EXTRA_REPORT_DETAILS, result.toString()); result = new StringWriter(); printWriter = new FastPrintWriter(result, false, 1024); - helper.getStats().dumpCheckinLocked(caller, printWriter, helper.getStatsType(), - uid.getUid()); + stats.dumpCheckinLocked(caller, printWriter, helper.getStatsType(), uid.getUid()); printWriter.flush(); args.putString(PowerUsageDetail.EXTRA_REPORT_CHECKIN_DETAILS, result.toString()); @@ -485,7 +484,7 @@ public class PowerUsageDetail extends PowerUsageBase implements Button.OnClickLi } AppHeader.createAppHeader(this, appIcon, title, pkg != null ? AppInfoWithHeader.getInfoIntent(this, pkg) : null, - mDrainType != DrainType.APP ? android.R.color.white : 0); + mDrainType != DrainType.APP ? R.color.power_usage_ab_icon_tint : 0); } public void onClick(View v) { diff --git a/src/com/android/settings/fuelgauge/PowerUsageSummary.java b/src/com/android/settings/fuelgauge/PowerUsageSummary.java index ca62b5a..8f8a5a4 100644 --- a/src/com/android/settings/fuelgauge/PowerUsageSummary.java +++ b/src/com/android/settings/fuelgauge/PowerUsageSummary.java @@ -89,9 +89,10 @@ public class PowerUsageSummary extends PowerUsageBase private static final String KEY_BATTERY_SAVER = "low_power"; private static final int MENU_STATS_TYPE = Menu.FIRST; - private static final int MENU_BATTERY_SAVER = Menu.FIRST + 2; - private static final int MENU_HIGH_POWER_APPS = Menu.FIRST + 3; - private static final int MENU_HELP = Menu.FIRST + 4; + private static final int MENU_STATS_RESET = Menu.FIRST + 2; + private static final int MENU_BATTERY_SAVER = Menu.FIRST + 3; + private static final int MENU_HIGH_POWER_APPS = Menu.FIRST + 4; + private static final int MENU_HELP = Menu.FIRST + 5; private BatteryHistoryPreference mHistPref; private PreferenceGroup mAppListGroup; @@ -234,9 +235,12 @@ public class PowerUsageSummary extends PowerUsageBase public boolean onPreferenceChange(Preference preference, Object newValue) { if (newValue != null) { if (preference == mPerfProfilePref) { - mPerf.setPowerProfile(Integer.valueOf((String)(newValue))); - updatePerformanceSummary(); - return true; + Integer value = Integer.valueOf((String) (newValue)); + boolean powerProfileUpdated = mPerf.setPowerProfile(value); + if (powerProfileUpdated) { + updatePerformanceSummary(); + } + return powerProfileUpdated; } } return false; @@ -250,6 +254,12 @@ public class PowerUsageSummary extends PowerUsageBase .setAlphabeticShortcut('t'); } + MenuItem reset = menu.add(0, MENU_STATS_RESET, 0, R.string.menu_stats_reset) + .setIcon(R.drawable.ic_actionbar_delete) + .setAlphabeticShortcut('d'); + reset.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM | + MenuItem.SHOW_AS_ACTION_WITH_TEXT); + MenuItem batterySaver = menu.add(0, MENU_BATTERY_SAVER, 0, R.string.battery_saver); batterySaver.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER); @@ -269,6 +279,9 @@ public class PowerUsageSummary extends PowerUsageBase } refreshStats(); return true; + case MENU_STATS_RESET: + resetStats(); + return true; case MENU_BATTERY_SAVER: Resources res = getResources(); @@ -327,6 +340,24 @@ public class PowerUsageSummary extends PowerUsageBase mAppListGroup.addPreference(notAvailable); } + private void resetStats() { + AlertDialog dialog = new AlertDialog.Builder(getActivity()) + .setTitle(R.string.menu_stats_reset) + .setMessage(R.string.reset_stats_msg) + .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + // Reset stats and request a refresh to initialize vars + mStatsHelper.resetStatistics(); + refreshStats(); + mHandler.removeMessages(MSG_REFRESH_STATS); + } + }) + .setNegativeButton(android.R.string.cancel, null) + .create(); + dialog.show(); + } + private void refreshBatterySaverOptions() { if (mBatterySaverPref != null) { mBatterySaverPref.setEnabled(!mBatteryPluggedIn); diff --git a/src/com/android/settings/hardware/VibratorIntensity.java b/src/com/android/settings/hardware/VibratorIntensity.java index 8bb39ca..e847933 100644 --- a/src/com/android/settings/hardware/VibratorIntensity.java +++ b/src/com/android/settings/hardware/VibratorIntensity.java @@ -37,6 +37,7 @@ import android.widget.TextView; import android.widget.Button; import cyanogenmod.hardware.CMHardwareManager; +import cyanogenmod.providers.CMSettings; import com.android.settings.R; @@ -52,6 +53,7 @@ public class VibratorIntensity extends DialogPreference implements private int mDefaultValue; private int mWarningValue; private CMHardwareManager mHardware; + private final Vibrator mVibrator; private Drawable mProgressDrawable; private Drawable mProgressThumb; @@ -61,6 +63,7 @@ public class VibratorIntensity extends DialogPreference implements super(context, attrs); mHardware = CMHardwareManager.getInstance(context); + mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE); if (!mHardware.isSupported(CMHardwareManager.FEATURE_VIBRATOR)) { return; @@ -116,13 +119,8 @@ public class VibratorIntensity extends DialogPreference implements mRedFilter = new LightingColorFilter(Color.BLACK, getContext().getResources().getColor(android.R.color.holo_red_light)); - // Restore percent value from SharedPreferences object - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); - int defaultValue = intensityToPercent(mMinValue, mMaxValue, mDefaultValue); - int percent = prefs.getInt(PREF_NAME, defaultValue); - mSeekBar.setOnSeekBarChangeListener(this); - mSeekBar.setProgress(percent); + mSeekBar.setProgress(intensityToPercent(mMinValue, mMaxValue, mOriginalValue)); } @Override @@ -150,7 +148,8 @@ public class VibratorIntensity extends DialogPreference implements SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); prefs.edit().putInt(PREF_NAME, mSeekBar.getProgress()).commit(); } else { - mHardware.setVibratorIntensity(mHardware.getVibratorIntensity()); + CMSettings.Secure.putInt(getContext().getContentResolver(), + CMSettings.Secure.VIBRATOR_INTENSITY, mOriginalValue); } } @@ -160,14 +159,15 @@ public class VibratorIntensity extends DialogPreference implements return; } SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); - int vibrator = hardware.getVibratorIntensity(); int min = hardware.getVibratorMinIntensity(); int max = hardware.getVibratorMaxIntensity(); int defaultValue = intensityToPercent(min, max, hardware.getVibratorDefaultIntensity()); int percent = prefs.getInt(PREF_NAME, defaultValue); - hardware.setVibratorIntensity(percentToIntensity(min, max, percent)); + CMSettings.Secure.putInt(context.getContentResolver(), + CMSettings.Secure.VIBRATOR_INTENSITY, percentToIntensity(min, max, + percentToIntensity(min, max, percent))); } @Override @@ -183,8 +183,9 @@ public class VibratorIntensity extends DialogPreference implements mProgressThumb.setColorFilter(shouldWarn ? mRedFilter : null); } - mHardware.setVibratorIntensity(percentToIntensity(mMinValue, mMaxValue, - progress)); + CMSettings.Secure.putInt(getContext().getContentResolver(), + CMSettings.Secure.VIBRATOR_INTENSITY, percentToIntensity(mMinValue, mMaxValue, + progress)); mValue.setText(String.format("%d%%", progress)); } diff --git a/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java b/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java index 604d75f..1e7b35c 100644 --- a/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java +++ b/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java @@ -438,11 +438,13 @@ public class InputMethodAndLanguageSettings extends SettingsPreferenceFragment CMSettings.System.putInt(getActivity().getContentResolver(), CMSettings.System.HIGH_TOUCH_SENSITIVITY_ENABLE, mHighTouchSensitivityEnable ? 1 : 0); - return mHardware.set(CMHardwareManager.FEATURE_HIGH_TOUCH_SENSITIVITY, - mHighTouchSensitivityEnable); + return true; } else if (preference == mTouchscreenHovering) { - return mHardware.set(CMHardwareManager.FEATURE_TOUCH_HOVERING, - mTouchscreenHovering.isChecked()); + boolean touchHoveringEnable = mTouchscreenHovering.isChecked(); + CMSettings.Secure.putInt(getActivity().getContentResolver(), + CMSettings.Secure.FEATURE_TOUCH_HOVERING, + touchHoveringEnable ? 1 : 0); + return true; } else if (preference instanceof PreferenceScreen) { if (preference.getFragment() != null) { // Fragment will be handled correctly by the super class. @@ -786,21 +788,16 @@ public class InputMethodAndLanguageSettings extends SettingsPreferenceFragment if (hardware.isSupported(CMHardwareManager.FEATURE_HIGH_TOUCH_SENSITIVITY)) { final boolean enabled = prefs.getBoolean(KEY_HIGH_TOUCH_SENSITIVITY, hardware.get(CMHardwareManager.FEATURE_HIGH_TOUCH_SENSITIVITY)); - if (!hardware.set(CMHardwareManager.FEATURE_HIGH_TOUCH_SENSITIVITY, - enabled)) { - Log.e(TAG, "Failed to restore high touch sensitivity settings."); - } else { - Log.d(TAG, "High touch sensitivity settings restored."); - } + CMSettings.System.putInt(context.getContentResolver(), + CMSettings.System.HIGH_TOUCH_SENSITIVITY_ENABLE, + enabled ? 1 : 0); } if (hardware.isSupported(CMHardwareManager.FEATURE_TOUCH_HOVERING)) { final boolean enabled = prefs.getBoolean(KEY_TOUCHSCREEN_HOVERING, hardware.get(CMHardwareManager.FEATURE_TOUCH_HOVERING)); - if (!hardware.set(CMHardwareManager.FEATURE_TOUCH_HOVERING, enabled)) { - Log.e(TAG, "Failed to restore touch hovering settings."); - } else { - Log.d(TAG, "Touch hovering settings restored."); - } + CMSettings.Secure.putInt(context.getContentResolver(), + CMSettings.Secure.FEATURE_TOUCH_HOVERING, + enabled ? 1 : 0); } } diff --git a/src/com/android/settings/livedisplay/DisplayColor.java b/src/com/android/settings/livedisplay/DisplayColor.java index 010bed2..5db508f 100644 --- a/src/com/android/settings/livedisplay/DisplayColor.java +++ b/src/com/android/settings/livedisplay/DisplayColor.java @@ -267,7 +267,7 @@ public class DisplayColor extends DialogPreference { IntervalSeekBar isb = (IntervalSeekBar)seekBar; float fp = isb.getProgressFloat(); if (fromUser) { - mCurrentColors[mIndex] = fp; + mCurrentColors[mIndex] = fp > 1.0f ? 1.0f : fp; updateColors(mCurrentColors); } diff --git a/src/com/android/settings/livedisplay/DisplayGamma.java b/src/com/android/settings/livedisplay/DisplayGamma.java index e75e3a4..2b44cea 100644 --- a/src/com/android/settings/livedisplay/DisplayGamma.java +++ b/src/com/android/settings/livedisplay/DisplayGamma.java @@ -39,7 +39,9 @@ import android.widget.TextView; import com.android.settings.R; import cyanogenmod.hardware.CMHardwareManager; +import cyanogenmod.providers.CMSettings; +import java.util.ArrayList; import java.util.Arrays; /** @@ -165,7 +167,7 @@ public class DisplayGamma extends DialogPreference { mSeekBars[index][color].setGamma(val); mCurrentColors[index][color] = val; } - mHardware.setDisplayGammaCalibration(index, mCurrentColors[index]); + writeDisplayGamma(getContext(), index, mCurrentColors[index]); } } }); @@ -184,7 +186,7 @@ public class DisplayGamma extends DialogPreference { editor.apply(); } else if (mOriginalColors != null) { for (int i = 0; i < mNumberOfControls; i++) { - mHardware.setDisplayGammaCalibration(i, mOriginalColors[i]); + writeDisplayGamma(getContext(), i, mOriginalColors[i]); } } } @@ -204,7 +206,7 @@ public class DisplayGamma extends DialogPreference { // Restore the old state when the activity or dialog is being paused for (int i = 0; i < mNumberOfControls; i++) { - mHardware.setDisplayGammaCalibration(i, mOriginalColors[i]); + writeDisplayGamma(getContext(), i, mOriginalColors[i]); } mOriginalColors = null; @@ -229,7 +231,7 @@ public class DisplayGamma extends DialogPreference { for (int color = 0; color < BAR_COLORS.length; color++) { mSeekBars[index][color].setGamma(mCurrentColors[index][color]); } - mHardware.setDisplayGammaCalibration(index, mCurrentColors[index]); + writeDisplayGamma(getContext(), index, mCurrentColors[index]); } } @@ -259,7 +261,7 @@ public class DisplayGamma extends DialogPreference { rgb[0] = Integer.valueOf(values[0]); rgb[1] = Integer.valueOf(values[1]); rgb[2] = Integer.valueOf(values[2]); - hardware.setDisplayGammaCalibration(i, rgb); + writeDisplayGamma(context, i, rgb); } } } @@ -311,6 +313,19 @@ public class DisplayGamma extends DialogPreference { }; } + private static void writeDisplayGamma(Context context, int index, int[] entries) { + StringBuilder builder = new StringBuilder(); + for (int i = 0; i < entries.length; i++) { + builder.append(i); + if (i != entries.length - 1) { + builder.append("|"); + } + } + CMSettings.Secure.putString(context.getContentResolver(), + CMSettings.Secure.DISPLAY_GAMMA_CALIBRATION_PREFIX + index, + builder.toString()); + } + private class GammaSeekBar implements SeekBar.OnSeekBarChangeListener { private int mControlIndex; private int mColorIndex; @@ -350,8 +365,7 @@ public class DisplayGamma extends DialogPreference { public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { if (fromUser) { mCurrentColors[mControlIndex][mColorIndex] = progress + mMin; - mHardware.setDisplayGammaCalibration(mControlIndex, - mCurrentColors[mControlIndex]); + writeDisplayGamma(getContext(), mControlIndex, mCurrentColors[mControlIndex]); } mValue.setText(String.valueOf(progress + mMin)); } diff --git a/src/com/android/settings/net/ChartData.java b/src/com/android/settings/net/ChartData.java deleted file mode 100644 index 0b8969e..0000000 --- a/src/com/android/settings/net/ChartData.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2011 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.net; - -import android.net.NetworkStatsHistory; - -public class ChartData { - public NetworkStatsHistory network; - - public NetworkStatsHistory detail; - public NetworkStatsHistory detailDefault; - public NetworkStatsHistory detailForeground; -} diff --git a/src/com/android/settings/net/ChartDataLoader.java b/src/com/android/settings/net/ChartDataLoader.java deleted file mode 100644 index e0336b7..0000000 --- a/src/com/android/settings/net/ChartDataLoader.java +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright (C) 2011 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.net; - -import static android.net.NetworkStats.SET_DEFAULT; -import static android.net.NetworkStats.SET_FOREGROUND; -import static android.net.NetworkStats.TAG_NONE; -import static android.net.NetworkStatsHistory.FIELD_RX_BYTES; -import static android.net.NetworkStatsHistory.FIELD_TX_BYTES; -import static android.text.format.DateUtils.HOUR_IN_MILLIS; - -import android.content.AsyncTaskLoader; -import android.content.Context; -import android.net.INetworkStatsSession; -import android.net.NetworkStatsHistory; -import android.net.NetworkTemplate; -import android.os.Bundle; -import android.os.RemoteException; - -import com.android.settings.DataUsageSummary.AppItem; - -/** - * Loader for historical chart data for both network and UID details. - */ -public class ChartDataLoader extends AsyncTaskLoader<ChartData> { - private static final String KEY_TEMPLATE = "template"; - private static final String KEY_APP = "app"; - private static final String KEY_FIELDS = "fields"; - - private final INetworkStatsSession mSession; - private final Bundle mArgs; - - public static Bundle buildArgs(NetworkTemplate template, AppItem app) { - return buildArgs(template, app, FIELD_RX_BYTES | FIELD_TX_BYTES); - } - - public static Bundle buildArgs(NetworkTemplate template, AppItem app, int fields) { - final Bundle args = new Bundle(); - args.putParcelable(KEY_TEMPLATE, template); - args.putParcelable(KEY_APP, app); - args.putInt(KEY_FIELDS, fields); - return args; - } - - public ChartDataLoader(Context context, INetworkStatsSession session, Bundle args) { - super(context); - mSession = session; - mArgs = args; - } - - @Override - protected void onStartLoading() { - super.onStartLoading(); - forceLoad(); - } - - @Override - public ChartData loadInBackground() { - final NetworkTemplate template = mArgs.getParcelable(KEY_TEMPLATE); - final AppItem app = mArgs.getParcelable(KEY_APP); - final int fields = mArgs.getInt(KEY_FIELDS); - - try { - return loadInBackground(template, app, fields); - } catch (RemoteException e) { - // since we can't do much without history, and we don't want to - // leave with half-baked UI, we bail hard. - throw new RuntimeException("problem reading network stats", e); - } - } - - private ChartData loadInBackground(NetworkTemplate template, AppItem app, int fields) - throws RemoteException { - final ChartData data = new ChartData(); - data.network = mSession.getHistoryForNetwork(template, fields); - - if (app != null) { - // load stats for current uid and template - final int size = app.uids.size(); - for (int i = 0; i < size; i++) { - final int uid = app.uids.keyAt(i); - data.detailDefault = collectHistoryForUid( - template, uid, SET_DEFAULT, data.detailDefault); - data.detailForeground = collectHistoryForUid( - template, uid, SET_FOREGROUND, data.detailForeground); - } - - if (size > 0) { - data.detail = new NetworkStatsHistory(data.detailForeground.getBucketDuration()); - data.detail.recordEntireHistory(data.detailDefault); - data.detail.recordEntireHistory(data.detailForeground); - } else { - data.detailDefault = new NetworkStatsHistory(HOUR_IN_MILLIS); - data.detailForeground = new NetworkStatsHistory(HOUR_IN_MILLIS); - data.detail = new NetworkStatsHistory(HOUR_IN_MILLIS); - } - } - - return data; - } - - @Override - protected void onStopLoading() { - super.onStopLoading(); - cancelLoad(); - } - - @Override - protected void onReset() { - super.onReset(); - cancelLoad(); - } - - /** - * Collect {@link NetworkStatsHistory} for the requested UID, combining with - * an existing {@link NetworkStatsHistory} if provided. - */ - private NetworkStatsHistory collectHistoryForUid( - NetworkTemplate template, int uid, int set, NetworkStatsHistory existing) - throws RemoteException { - final NetworkStatsHistory history = mSession.getHistoryForUid( - template, uid, set, TAG_NONE, FIELD_RX_BYTES | FIELD_TX_BYTES); - - if (existing != null) { - existing.recordEntireHistory(history); - return existing; - } else { - return history; - } - } -} diff --git a/src/com/android/settings/net/DataUsageMeteredSettings.java b/src/com/android/settings/net/DataUsageMeteredSettings.java index ec1dd38..59a8b92 100644 --- a/src/com/android/settings/net/DataUsageMeteredSettings.java +++ b/src/com/android/settings/net/DataUsageMeteredSettings.java @@ -40,6 +40,7 @@ import com.android.settings.SettingsPreferenceFragment; import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.search.Indexable; import com.android.settings.search.SearchIndexableRaw; +import com.android.settingslib.NetworkPolicyEditor; import java.util.ArrayList; import java.util.List; diff --git a/src/com/android/settings/net/NetworkPolicyEditor.java b/src/com/android/settings/net/NetworkPolicyEditor.java deleted file mode 100644 index 1268c3f..0000000 --- a/src/com/android/settings/net/NetworkPolicyEditor.java +++ /dev/null @@ -1,252 +0,0 @@ -/* - * Copyright (C) 2011 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.net; - -import static android.net.NetworkPolicy.CYCLE_NONE; -import static android.net.NetworkPolicy.LIMIT_DISABLED; -import static android.net.NetworkPolicy.SNOOZE_NEVER; -import static android.net.NetworkPolicy.WARNING_DISABLED; -import static android.net.NetworkTemplate.MATCH_WIFI; -import static com.android.internal.util.Preconditions.checkNotNull; - -import android.net.NetworkPolicy; -import android.net.NetworkPolicyManager; -import android.net.NetworkTemplate; -import android.net.wifi.WifiInfo; -import android.os.AsyncTask; -import android.text.TextUtils; -import android.text.format.Time; - -import com.google.android.collect.Lists; - -import java.util.ArrayList; - -/** - * Utility class to modify list of {@link NetworkPolicy}. Specifically knows - * about which policies can coexist. This editor offers thread safety when - * talking with {@link NetworkPolicyManager}. - */ -public class NetworkPolicyEditor { - // TODO: be more robust when missing policies from service - - public static final boolean ENABLE_SPLIT_POLICIES = false; - - private NetworkPolicyManager mPolicyManager; - private ArrayList<NetworkPolicy> mPolicies = Lists.newArrayList(); - - public NetworkPolicyEditor(NetworkPolicyManager policyManager) { - mPolicyManager = checkNotNull(policyManager); - } - - public void read() { - final NetworkPolicy[] policies = mPolicyManager.getNetworkPolicies(); - - boolean modified = false; - mPolicies.clear(); - for (NetworkPolicy policy : policies) { - // TODO: find better place to clamp these - if (policy.limitBytes < -1) { - policy.limitBytes = LIMIT_DISABLED; - modified = true; - } - if (policy.warningBytes < -1) { - policy.warningBytes = WARNING_DISABLED; - modified = true; - } - - mPolicies.add(policy); - } - - // when we cleaned policies above, write back changes - if (modified) writeAsync(); - } - - public void writeAsync() { - // TODO: consider making more robust by passing through service - final NetworkPolicy[] policies = mPolicies.toArray(new NetworkPolicy[mPolicies.size()]); - new AsyncTask<Void, Void, Void>() { - @Override - protected Void doInBackground(Void... params) { - write(policies); - return null; - } - }.execute(); - } - - public void write(NetworkPolicy[] policies) { - mPolicyManager.setNetworkPolicies(policies); - } - - public boolean hasLimitedPolicy(NetworkTemplate template) { - final NetworkPolicy policy = getPolicy(template); - return policy != null && policy.limitBytes != LIMIT_DISABLED; - } - - public NetworkPolicy getOrCreatePolicy(NetworkTemplate template) { - NetworkPolicy policy = getPolicy(template); - if (policy == null) { - policy = buildDefaultPolicy(template); - mPolicies.add(policy); - } - return policy; - } - - public NetworkPolicy getPolicy(NetworkTemplate template) { - for (NetworkPolicy policy : mPolicies) { - if (policy.template.equals(template)) { - return policy; - } - } - return null; - } - - public NetworkPolicy getPolicyMaybeUnquoted(NetworkTemplate template) { - NetworkPolicy policy = getPolicy(template); - if (policy != null) { - return policy; - } else { - return getPolicy(buildUnquotedNetworkTemplate(template)); - } - } - - @Deprecated - private static NetworkPolicy buildDefaultPolicy(NetworkTemplate template) { - // TODO: move this into framework to share with NetworkPolicyManagerService - final int cycleDay; - final String cycleTimezone; - final boolean metered; - - if (template.getMatchRule() == MATCH_WIFI) { - cycleDay = CYCLE_NONE; - cycleTimezone = Time.TIMEZONE_UTC; - metered = false; - } else { - final Time time = new Time(); - time.setToNow(); - cycleDay = time.monthDay; - cycleTimezone = time.timezone; - metered = true; - } - - return new NetworkPolicy(template, cycleDay, cycleTimezone, WARNING_DISABLED, - LIMIT_DISABLED, SNOOZE_NEVER, SNOOZE_NEVER, metered, true); - } - - public int getPolicyCycleDay(NetworkTemplate template) { - final NetworkPolicy policy = getPolicy(template); - return (policy != null) ? policy.cycleDay : -1; - } - - public void setPolicyCycleDay(NetworkTemplate template, int cycleDay, String cycleTimezone) { - final NetworkPolicy policy = getOrCreatePolicy(template); - policy.cycleDay = cycleDay; - policy.cycleTimezone = cycleTimezone; - policy.inferred = false; - policy.clearSnooze(); - writeAsync(); - } - - public long getPolicyWarningBytes(NetworkTemplate template) { - final NetworkPolicy policy = getPolicy(template); - return (policy != null) ? policy.warningBytes : WARNING_DISABLED; - } - - public void setPolicyWarningBytes(NetworkTemplate template, long warningBytes) { - final NetworkPolicy policy = getOrCreatePolicy(template); - policy.warningBytes = warningBytes; - policy.inferred = false; - policy.clearSnooze(); - writeAsync(); - } - - public long getPolicyLimitBytes(NetworkTemplate template) { - final NetworkPolicy policy = getPolicy(template); - return (policy != null) ? policy.limitBytes : LIMIT_DISABLED; - } - - public void setPolicyLimitBytes(NetworkTemplate template, long limitBytes) { - final NetworkPolicy policy = getOrCreatePolicy(template); - policy.limitBytes = limitBytes; - policy.inferred = false; - policy.clearSnooze(); - writeAsync(); - } - - public boolean getPolicyMetered(NetworkTemplate template) { - NetworkPolicy policy = getPolicy(template); - if (policy != null) { - return policy.metered; - } else { - return false; - } - } - - public void setPolicyMetered(NetworkTemplate template, boolean metered) { - boolean modified = false; - - NetworkPolicy policy = getPolicy(template); - if (metered) { - if (policy == null) { - policy = buildDefaultPolicy(template); - policy.metered = true; - policy.inferred = false; - mPolicies.add(policy); - modified = true; - } else if (!policy.metered) { - policy.metered = true; - policy.inferred = false; - modified = true; - } - - } else { - if (policy == null) { - // ignore when policy doesn't exist - } else if (policy.metered) { - policy.metered = false; - policy.inferred = false; - modified = true; - } - } - - // Remove legacy unquoted policies while we're here - final NetworkTemplate unquoted = buildUnquotedNetworkTemplate(template); - final NetworkPolicy unquotedPolicy = getPolicy(unquoted); - if (unquotedPolicy != null) { - mPolicies.remove(unquotedPolicy); - modified = true; - } - - if (modified) writeAsync(); - } - - /** - * Build a revised {@link NetworkTemplate} that matches the same rule, but - * with an unquoted {@link NetworkTemplate#getNetworkId()}. Used to work - * around legacy bugs. - */ - private static NetworkTemplate buildUnquotedNetworkTemplate(NetworkTemplate template) { - if (template == null) return null; - final String networkId = template.getNetworkId(); - final String strippedNetworkId = WifiInfo.removeDoubleQuotes(networkId); - if (!TextUtils.equals(strippedNetworkId, networkId)) { - return new NetworkTemplate( - template.getMatchRule(), template.getSubscriberId(), strippedNetworkId); - } else { - return null; - } - } -} diff --git a/src/com/android/settings/net/SummaryForAllUidLoader.java b/src/com/android/settings/net/SummaryForAllUidLoader.java deleted file mode 100644 index 68dc799..0000000 --- a/src/com/android/settings/net/SummaryForAllUidLoader.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2011 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.net; - -import android.content.AsyncTaskLoader; -import android.content.Context; -import android.net.INetworkStatsSession; -import android.net.NetworkStats; -import android.net.NetworkTemplate; -import android.os.Bundle; -import android.os.RemoteException; - -public class SummaryForAllUidLoader extends AsyncTaskLoader<NetworkStats> { - private static final String KEY_TEMPLATE = "template"; - private static final String KEY_START = "start"; - private static final String KEY_END = "end"; - - private final INetworkStatsSession mSession; - private final Bundle mArgs; - - public static Bundle buildArgs(NetworkTemplate template, long start, long end) { - final Bundle args = new Bundle(); - args.putParcelable(KEY_TEMPLATE, template); - args.putLong(KEY_START, start); - args.putLong(KEY_END, end); - return args; - } - - public SummaryForAllUidLoader(Context context, INetworkStatsSession session, Bundle args) { - super(context); - mSession = session; - mArgs = args; - } - - @Override - protected void onStartLoading() { - super.onStartLoading(); - forceLoad(); - } - - @Override - public NetworkStats loadInBackground() { - final NetworkTemplate template = mArgs.getParcelable(KEY_TEMPLATE); - final long start = mArgs.getLong(KEY_START); - final long end = mArgs.getLong(KEY_END); - - try { - return mSession.getSummaryForAllUid(template, start, end, false); - } catch (RemoteException e) { - return null; - } - } - - @Override - protected void onStopLoading() { - super.onStopLoading(); - cancelLoad(); - } - - @Override - protected void onReset() { - super.onReset(); - cancelLoad(); - } -} diff --git a/src/com/android/settings/net/UidDetail.java b/src/com/android/settings/net/UidDetail.java deleted file mode 100644 index 0b14254..0000000 --- a/src/com/android/settings/net/UidDetail.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2011 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.net; - -import android.graphics.drawable.Drawable; - -public class UidDetail { - public CharSequence label; - public CharSequence contentDescription; - public CharSequence[] detailLabels; - public CharSequence[] detailContentDescriptions; - public Drawable icon; -} diff --git a/src/com/android/settings/net/UidDetailProvider.java b/src/com/android/settings/net/UidDetailProvider.java deleted file mode 100644 index a08c7de..0000000 --- a/src/com/android/settings/net/UidDetailProvider.java +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Copyright (C) 2011 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.net; - -import android.app.AppGlobals; -import android.content.Context; -import android.content.pm.ApplicationInfo; -import android.content.pm.IPackageManager; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.content.pm.PackageManager.NameNotFoundException; -import android.content.pm.UserInfo; -import android.content.res.Resources; -import android.graphics.drawable.Drawable; -import android.net.ConnectivityManager; -import android.net.TrafficStats; -import android.os.UserManager; -import android.os.UserHandle; -import android.os.RemoteException; -import android.text.TextUtils; -import android.util.Log; -import android.util.SparseArray; - -import com.android.settings.R; -import com.android.settings.Utils; - -/** - * Return details about a specific UID, handling special cases like - * {@link TrafficStats#UID_TETHERING} and {@link UserInfo}. - */ -public class UidDetailProvider { - private static final String TAG = "DataUsage"; - private final Context mContext; - private final SparseArray<UidDetail> mUidDetailCache; - - public static final int OTHER_USER_RANGE_START = -2000; - - public static int buildKeyForUser(int userHandle) { - return OTHER_USER_RANGE_START - userHandle; - } - - public static boolean isKeyForUser(int key) { - return key <= OTHER_USER_RANGE_START; - } - - public static int getUserIdForKey(int key) { - return OTHER_USER_RANGE_START - key; - } - - public UidDetailProvider(Context context) { - mContext = context.getApplicationContext(); - mUidDetailCache = new SparseArray<UidDetail>(); - } - - public void clearCache() { - synchronized (mUidDetailCache) { - mUidDetailCache.clear(); - } - } - - /** - * Resolve best descriptive label for the given UID. - */ - public UidDetail getUidDetail(int uid, boolean blocking) { - UidDetail detail; - - synchronized (mUidDetailCache) { - detail = mUidDetailCache.get(uid); - } - - if (detail != null) { - return detail; - } else if (!blocking) { - return null; - } - - detail = buildUidDetail(uid); - - synchronized (mUidDetailCache) { - mUidDetailCache.put(uid, detail); - } - - return detail; - } - - /** - * Build {@link UidDetail} object, blocking until all {@link Drawable} - * lookup is finished. - */ - private UidDetail buildUidDetail(int uid) { - final Resources res = mContext.getResources(); - final PackageManager pm = mContext.getPackageManager(); - - final UidDetail detail = new UidDetail(); - detail.label = pm.getNameForUid(uid); - detail.icon = pm.getDefaultActivityIcon(); - - // handle special case labels - switch (uid) { - case android.os.Process.SYSTEM_UID: - detail.label = res.getString(R.string.process_kernel_label); - detail.icon = pm.getDefaultActivityIcon(); - return detail; - case TrafficStats.UID_REMOVED: - detail.label = res.getString(UserManager.supportsMultipleUsers() - ? R.string.data_usage_uninstalled_apps_users - : R.string.data_usage_uninstalled_apps); - detail.icon = pm.getDefaultActivityIcon(); - return detail; - case TrafficStats.UID_TETHERING: - final ConnectivityManager cm = (ConnectivityManager) mContext.getSystemService( - Context.CONNECTIVITY_SERVICE); - detail.label = res.getString(Utils.getTetheringLabel(cm)); - detail.icon = pm.getDefaultActivityIcon(); - return detail; - } - - final UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE); - - // Handle keys that are actually user handles - if (isKeyForUser(uid)) { - final int userHandle = getUserIdForKey(uid); - final UserInfo info = um.getUserInfo(userHandle); - if (info != null) { - detail.label = Utils.getUserLabel(mContext, info); - detail.icon = Utils.getUserIcon(mContext, um, info); - return detail; - } - } - - // otherwise fall back to using packagemanager labels - final String[] packageNames = pm.getPackagesForUid(uid); - final int length = packageNames != null ? packageNames.length : 0; - try { - final int userId = UserHandle.getUserId(uid); - UserHandle userHandle = new UserHandle(userId); - IPackageManager ipm = AppGlobals.getPackageManager(); - if (length == 1) { - final ApplicationInfo info = ipm.getApplicationInfo(packageNames[0], - 0 /* no flags */, userId); - if (info != null) { - detail.label = info.loadLabel(pm).toString(); - detail.icon = um.getBadgedIconForUser(info.loadIcon(pm), - new UserHandle(userId)); - } - } else if (length > 1) { - detail.detailLabels = new CharSequence[length]; - detail.detailContentDescriptions = new CharSequence[length]; - for (int i = 0; i < length; i++) { - final String packageName = packageNames[i]; - final PackageInfo packageInfo = pm.getPackageInfo(packageName, 0); - final ApplicationInfo appInfo = ipm.getApplicationInfo(packageName, - 0 /* no flags */, userId); - - if (appInfo != null) { - detail.detailLabels[i] = appInfo.loadLabel(pm).toString(); - detail.detailContentDescriptions[i] = um.getBadgedLabelForUser( - detail.detailLabels[i], userHandle); - if (packageInfo.sharedUserLabel != 0) { - detail.label = pm.getText(packageName, packageInfo.sharedUserLabel, - packageInfo.applicationInfo).toString(); - detail.icon = um.getBadgedIconForUser(appInfo.loadIcon(pm), userHandle); - } - } - } - } - detail.contentDescription = um.getBadgedLabelForUser(detail.label, userHandle); - } catch (NameNotFoundException e) { - Log.w(TAG, "Error while building UI detail for uid "+uid, e); - } catch (RemoteException e) { - Log.w(TAG, "Error while building UI detail for uid "+uid, e); - } - - if (TextUtils.isEmpty(detail.label)) { - detail.label = Integer.toString(uid); - } - - return detail; - } -} diff --git a/src/com/android/settings/notification/OtherSoundSettings.java b/src/com/android/settings/notification/OtherSoundSettings.java index 55d2309..935aea5 100644 --- a/src/com/android/settings/notification/OtherSoundSettings.java +++ b/src/com/android/settings/notification/OtherSoundSettings.java @@ -56,6 +56,7 @@ import java.util.List; public class OtherSoundSettings extends SettingsPreferenceFragment implements Indexable { private static final String TAG = "OtherSoundSettings"; + private static final int DEFAULT_OFF = 0; private static final int DEFAULT_ON = 1; private static final int EMERGENCY_TONE_SILENT = 0; @@ -76,7 +77,6 @@ public class OtherSoundSettings extends SettingsPreferenceFragment implements In private static final String KEY_DOCK_AUDIO_MEDIA = "dock_audio_media"; private static final String KEY_EMERGENCY_TONE = "emergency_tone"; - private static final String KEY_POWER_NOTIFICATIONS = "power_notifications"; private static final String KEY_POWER_NOTIFICATIONS_VIBRATE = "power_notifications_vibrate"; private static final String KEY_POWER_NOTIFICATIONS_RINGTONE = "power_notifications_ringtone"; @@ -86,7 +86,6 @@ public class OtherSoundSettings extends SettingsPreferenceFragment implements In // Used for power notification uri string if set to silent private static final String POWER_NOTIFICATIONS_SILENT_URI = "silent"; - private SwitchPreference mPowerSounds; private SwitchPreference mPowerSoundsVibrate; private Preference mPowerSoundsRingtone; @@ -102,7 +101,7 @@ public class OtherSoundSettings extends SettingsPreferenceFragment implements In TYPE_SYSTEM, KEY_SCREEN_LOCKING_SOUNDS, System.LOCKSCREEN_SOUNDS_ENABLED, DEFAULT_ON); private static final SettingPref PREF_CHARGING_SOUNDS = new SettingPref( - TYPE_GLOBAL, KEY_CHARGING_SOUNDS, Global.CHARGING_SOUNDS_ENABLED, DEFAULT_ON); + TYPE_GLOBAL, KEY_CHARGING_SOUNDS, Global.CHARGING_SOUNDS_ENABLED, DEFAULT_OFF); private static final SettingPref PREF_DOCKING_SOUNDS = new SettingPref( TYPE_GLOBAL, KEY_DOCKING_SOUNDS, Global.DOCK_SOUNDS_ENABLED, DEFAULT_ON) { @@ -214,9 +213,6 @@ public class OtherSoundSettings extends SettingsPreferenceFragment implements In mContext = getActivity(); // power state change notification sounds - mPowerSounds = (SwitchPreference) findPreference(KEY_POWER_NOTIFICATIONS); - mPowerSounds.setChecked(CMSettings.Global.getInt(getContentResolver(), - CMSettings.Global.POWER_NOTIFICATIONS_ENABLED, 0) != 0); mPowerSoundsVibrate = (SwitchPreference) findPreference(KEY_POWER_NOTIFICATIONS_VIBRATE); mPowerSoundsVibrate.setChecked(CMSettings.Global.getInt(getContentResolver(), CMSettings.Global.POWER_NOTIFICATIONS_VIBRATE, 0) != 0); @@ -266,12 +262,7 @@ public class OtherSoundSettings extends SettingsPreferenceFragment implements In @Override public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) { - if (preference == mPowerSounds) { - CMSettings.Global.putInt(getContentResolver(), - CMSettings.Global.POWER_NOTIFICATIONS_ENABLED, - mPowerSounds.isChecked() ? 1 : 0); - - } else if (preference == mPowerSoundsVibrate) { + if (preference == mPowerSoundsVibrate) { CMSettings.Global.putInt(getContentResolver(), CMSettings.Global.POWER_NOTIFICATIONS_VIBRATE, mPowerSoundsVibrate.isChecked() ? 1 : 0); diff --git a/src/com/android/settings/notification/SoundSettings.java b/src/com/android/settings/notification/SoundSettings.java index bc8eea4..f51a342 100644 --- a/src/com/android/settings/notification/SoundSettings.java +++ b/src/com/android/settings/notification/SoundSettings.java @@ -259,7 +259,7 @@ public class SoundSettings extends SettingsPreferenceFragment implements Indexab if (mVoiceCapable) { final boolean enabled = Settings.Secure.getInt(getContentResolver(), Settings.Secure.VOLUME_LINK_NOTIFICATION, 1) == 1; - if (mVolumeLinkNotificationSwitch != null){ + if (mVolumeLinkNotificationSwitch != null) { mVolumeLinkNotificationSwitch.setChecked(enabled); } } @@ -271,7 +271,7 @@ public class SoundSettings extends SettingsPreferenceFragment implements Indexab ? com.android.internal.R.drawable.ic_audio_ring_notif_mute : mRingerMode == AudioManager.RINGER_MODE_VIBRATE || wasRingerModeVibrate() ? com.android.internal.R.drawable.ic_audio_ring_notif_vibrate - : com.android.internal.R.drawable.ic_audio_ring_notif); + : R.drawable.ic_audio_ring); } } diff --git a/src/com/android/settings/notification/ZenModePrioritySettings.java b/src/com/android/settings/notification/ZenModePrioritySettings.java index 6e34bf7..e8a8bb1 100644 --- a/src/com/android/settings/notification/ZenModePrioritySettings.java +++ b/src/com/android/settings/notification/ZenModePrioritySettings.java @@ -35,6 +35,7 @@ public class ZenModePrioritySettings extends ZenModeSettingsBase implements Inde private static final String KEY_MESSAGES = "messages"; private static final String KEY_CALLS = "calls"; private static final String KEY_REPEAT_CALLERS = "repeat_callers"; + private static final String KEY_ALLOW_LIGHTS = "zen_priority_allow_lights"; private static final int SOURCE_NONE = -1; @@ -145,6 +146,12 @@ public class ZenModePrioritySettings extends ZenModeSettingsBase implements Inde } }); + // Remove of the "Allow notification light" setting if LED is not supported + if (!getResources().getBoolean( + com.android.internal.R.bool.config_intrusiveNotificationLed)) { + root.removePreference(findPreference(KEY_ALLOW_LIGHTS)); + } + updateControls(); } diff --git a/src/com/android/settings/notificationlight/NotificationLightSettings.java b/src/com/android/settings/notificationlight/NotificationLightSettings.java index 1a5af49..95a354d 100644 --- a/src/com/android/settings/notificationlight/NotificationLightSettings.java +++ b/src/com/android/settings/notificationlight/NotificationLightSettings.java @@ -25,7 +25,7 @@ import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.Resources; -import android.graphics.Color; +import android.graphics.drawable.Drawable; import android.os.Bundle; import android.preference.Preference; import android.preference.PreferenceGroup; @@ -43,18 +43,20 @@ import android.widget.ListView; import com.android.settings.R; import com.android.settings.SettingsPreferenceFragment; +import com.android.settings.cyanogenmod.CMSystemSettingSwitchPreference; import com.android.settings.cyanogenmod.PackageListAdapter; import com.android.settings.cyanogenmod.PackageListAdapter.PackageItem; -import com.android.settings.cyanogenmod.CMSystemSettingSwitchPreference; import com.android.settings.cyanogenmod.SystemSettingSwitchPreference; +import org.cyanogenmod.internal.logging.CMMetricsLogger; + import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import cyanogenmod.providers.CMSettings; -import org.cyanogenmod.internal.logging.CMMetricsLogger; +import cyanogenmod.util.ColorUtils; public class NotificationLightSettings extends SettingsPreferenceFragment implements Preference.OnPreferenceChangeListener, AdapterView.OnItemLongClickListener { @@ -77,6 +79,7 @@ public class NotificationLightSettings extends SettingsPreferenceFragment implem private CMSystemSettingSwitchPreference mCustomEnabledPref; private CMSystemSettingSwitchPreference mMultipleLedsEnabledPref; private CMSystemSettingSwitchPreference mScreenOnLightsPref; + private CMSystemSettingSwitchPreference mAutoGenerateColors; private ApplicationLightPreference mDefaultPref; private ApplicationLightPreference mCallPref; private ApplicationLightPreference mVoicemailPref; @@ -84,6 +87,7 @@ public class NotificationLightSettings extends SettingsPreferenceFragment implem private PackageListAdapter mPackageAdapter; private String mPackageList; private Map<String, Package> mPackages; + private boolean mMultiColorLed; @Override public void onCreate(Bundle savedInstanceState) { @@ -97,7 +101,7 @@ public class NotificationLightSettings extends SettingsPreferenceFragment implem // Get the system defined default notification color mDefaultColor = - resources.getColor(com.android.internal.R.color.config_defaultNotificationColor); + resources.getColor(com.android.internal.R.color.config_defaultNotificationColor, null); mDefaultLedOn = resources.getInteger( com.android.internal.R.integer.config_defaultNotificationLedOn); @@ -111,6 +115,9 @@ public class NotificationLightSettings extends SettingsPreferenceFragment implem mDefaultPref = (ApplicationLightPreference) findPreference(DEFAULT_PREF); mDefaultPref.setOnPreferenceChangeListener(this); + mAutoGenerateColors = (CMSystemSettingSwitchPreference) + findPreference(CMSettings.System.NOTIFICATION_LIGHT_COLOR_AUTO); + // Advanced light settings mNotificationLedBrightnessPref = (PreferenceScreen) findPreference(CMSettings.System.NOTIFICATION_LIGHT_BRIGHTNESS_LEVEL); @@ -157,8 +164,13 @@ public class NotificationLightSettings extends SettingsPreferenceFragment implem mPackages = new HashMap<String, Package>(); setHasOptionsMenu(true); - if (!resources.getBoolean(com.android.internal.R.bool.config_multiColorNotificationLed)) { + mMultiColorLed = resources.getBoolean(com.android.internal.R.bool.config_multiColorNotificationLed); + if (!mMultiColorLed) { resetColors(); + PreferenceGroup mGeneralPrefs = (PreferenceGroup) prefSet.findPreference("general_section"); + mGeneralPrefs.removePreference(mAutoGenerateColors); + } else { + mAutoGenerateColors.setOnPreferenceChangeListener(this); } } @@ -275,10 +287,26 @@ public class NotificationLightSettings extends SettingsPreferenceFragment implem } } + private int getInitialColorForPackage(String packageName) { + boolean autoColor = CMSettings.System.getInt(getContentResolver(), + CMSettings.System.NOTIFICATION_LIGHT_COLOR_AUTO, mMultiColorLed ? 1 : 0) == 1; + int color = mDefaultColor; + if (autoColor) { + try { + Drawable icon = mPackageManager.getApplicationIcon(packageName); + color = ColorUtils.generateAlertColorFromDrawable(icon); + } catch (NameNotFoundException e) { + // shouldn't happen, but just return default + } + } + return color; + } + private void addCustomApplicationPref(String packageName) { Package pkg = mPackages.get(packageName); if (pkg == null) { - pkg = new Package(packageName, mDefaultColor, mDefaultLedOn, mDefaultLedOff); + int color = getInitialColorForPackage(packageName); + pkg = new Package(packageName, color, mDefaultLedOn, mDefaultLedOff); mPackages.put(packageName, pkg); savePackageList(false); refreshCustomApplicationPrefs(); @@ -411,7 +439,8 @@ public class NotificationLightSettings extends SettingsPreferenceFragment implem if (preference == mEnabledPref || preference == mCustomEnabledPref || preference == mMultipleLedsEnabledPref || preference == mNotificationLedBrightnessPref || - preference == mScreenOnLightsPref) { + preference == mScreenOnLightsPref || + preference == mAutoGenerateColors) { getActivity().invalidateOptionsMenu(); } else { ApplicationLightPreference lightPref = (ApplicationLightPreference) preference; diff --git a/src/com/android/settings/profiles/SetupActionsFragment.java b/src/com/android/settings/profiles/SetupActionsFragment.java index 7764073..d1ca91b 100644 --- a/src/com/android/settings/profiles/SetupActionsFragment.java +++ b/src/com/android/settings/profiles/SetupActionsFragment.java @@ -25,7 +25,6 @@ import android.content.ContentResolver; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; -import android.content.pm.PackageManager; import android.location.LocationManager; import android.media.AudioManager; import android.media.RingtoneManager; @@ -37,6 +36,8 @@ import android.os.AsyncTask; import android.os.Bundle; import android.preference.SeekBarVolumizer; import android.provider.Settings; +import android.telephony.SubscriptionInfo; +import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.text.Editable; import android.text.TextUtils; @@ -67,7 +68,6 @@ import cyanogenmod.profiles.RingModeSettings; import cyanogenmod.profiles.StreamSettings; import com.android.settings.R; -import com.android.settings.SettingsActivity; import com.android.settings.SubSettings; import com.android.settings.cyanogenmod.DeviceUtils; import com.android.settings.SettingsPreferenceFragment; @@ -81,11 +81,13 @@ import com.android.settings.profiles.actions.item.DozeModeItem; import com.android.settings.profiles.actions.item.Header; import com.android.settings.profiles.actions.item.Item; import com.android.settings.profiles.actions.item.LockModeItem; +import com.android.settings.profiles.actions.item.NotificationLightModeItem; import com.android.settings.profiles.actions.item.ProfileNameItem; import com.android.settings.profiles.actions.item.RingModeItem; import com.android.settings.profiles.actions.item.TriggerItem; import com.android.settings.profiles.actions.item.VolumeStreamItem; import com.android.settings.Utils; +import com.android.settings.utils.TelephonyUtils; import org.cyanogenmod.internal.logging.CMMetricsLogger; import java.util.ArrayList; @@ -99,13 +101,15 @@ import static cyanogenmod.profiles.ConnectionSettings.PROFILE_CONNECTION_NFC; import static cyanogenmod.profiles.ConnectionSettings.PROFILE_CONNECTION_SYNC; import static cyanogenmod.profiles.ConnectionSettings.PROFILE_CONNECTION_WIFI; import static cyanogenmod.profiles.ConnectionSettings.PROFILE_CONNECTION_WIFIAP; -import static cyanogenmod.profiles.ConnectionSettings.PROFILE_CONNECTION_WIMAX; public class SetupActionsFragment extends SettingsPreferenceFragment implements AdapterView.OnItemClickListener { private static final int RINGTONE_REQUEST_CODE = 1000; private static final int NEW_TRIGGER_REQUEST_CODE = 1001; + private static final int SET_NETWORK_MODE_REQUEST_CODE = 1002; + + public static final String EXTRA_NETWORK_MODE_PICKED = "network_mode_picker::chosen_value"; private static final int MENU_REMOVE = Menu.FIRST; private static final int MENU_FILL_PROFILE = Menu.FIRST + 1; @@ -123,6 +127,8 @@ public class SetupActionsFragment extends SettingsPreferenceFragment private static final String LAST_SELECTED_POSITION = "last_selected_position"; private static final int DIALOG_REMOVE_PROFILE = 10; + private static final int DIALOG_NOTIFICATION_LIGHT_MODE = 11; + private int mLastSelectedPosition = -1; private Item mSelectedItem; @@ -146,6 +152,11 @@ public class SetupActionsFragment extends SettingsPreferenceFragment Profile.DozeMode.ENABLE, Profile.DozeMode.DISABLE }; + private static final int[] NOTIFICATION_LIGHT_MAPPING = new int[] { + Profile.NotificationLightMode.DEFAULT, + Profile.NotificationLightMode.ENABLE, + Profile.NotificationLightMode.DISABLE + }; private List<Item> mItems = new ArrayList<Item>(); public static SetupActionsFragment newInstance(Profile profile, boolean newProfile) { @@ -217,10 +228,17 @@ public class SetupActionsFragment extends SettingsPreferenceFragment mItems.add(generateConnectionOverrideItem(PROFILE_CONNECTION_MOBILEDATA)); mItems.add(generateConnectionOverrideItem(PROFILE_CONNECTION_WIFIAP)); - final TelephonyManager tm = - (TelephonyManager) getActivity().getSystemService(Context.TELEPHONY_SERVICE); - if (tm.getPhoneType() == TelephonyManager.PHONE_TYPE_GSM) { - mItems.add(generateConnectionOverrideItem(PROFILE_CONNECTION_2G3G4G)); + final List<SubscriptionInfo> subs = SubscriptionManager.from(getContext()) + .getActiveSubscriptionInfoList(); + if (subs != null && subs.size() > 1) { + for (SubscriptionInfo sub : subs) { + mItems.add(generatePreferredNetworkOverrideItem(sub.getSubscriptionId())); + } + } else { + if (TelephonyManager.from(getContext()).getPhoneCount() == 1) { + mItems.add(generatePreferredNetworkOverrideItem( + SubscriptionManager.INVALID_SUBSCRIPTION_ID)); + } } } //if (WimaxHelper.isWimaxSupported(getActivity())) { @@ -256,6 +274,11 @@ public class SetupActionsFragment extends SettingsPreferenceFragment mItems.add(new DozeModeItem(mProfile)); } + if (getResources().getBoolean( + com.android.internal.R.bool.config_intrusiveNotificationLed)) { + mItems.add(new NotificationLightModeItem(mProfile)); + } + // app groups mItems.add(new Header(getString(R.string.profile_app_group_category_title))); @@ -324,6 +347,16 @@ public class SetupActionsFragment extends SettingsPreferenceFragment return super.onOptionsItemSelected(item); } + private ConnectionOverrideItem generatePreferredNetworkOverrideItem(int subId) { + ConnectionSettings settings = mProfile.getConnectionSettingWithSubId(subId); + if (settings == null) { + settings = new ConnectionSettings(ConnectionSettings.PROFILE_CONNECTION_2G3G4G); + settings.setSubId(subId); + mProfile.setConnectionSettings(settings); + } + return new ConnectionOverrideItem(settings.getConnectionId(), settings); + } + private ConnectionOverrideItem generateConnectionOverrideItem(int connectionId) { ConnectionSettings settings = mProfile.getSettingsForConnection(connectionId); if (settings == null) { @@ -522,16 +555,15 @@ public class SetupActionsFragment extends SettingsPreferenceFragment case DIALOG_DOZE_MODE: return requestDozeModeDialog(); + case DIALOG_NOTIFICATION_LIGHT_MODE: + return requestNotificationLightModeDialog(); + case DIALOG_RING_MODE: return requestRingModeDialog(((RingModeItem) mSelectedItem).getSettings()); case DIALOG_CONNECTION_OVERRIDE: ConnectionOverrideItem connItem = (ConnectionOverrideItem) mSelectedItem; - if (connItem.getConnectionType() == ConnectionSettings.PROFILE_CONNECTION_2G3G4G) { - return requestMobileConnectionOverrideDialog(connItem.getSettings()); - } else { - return requestConnectionOverrideDialog(connItem.getSettings()); - } + return requestConnectionOverrideDialog(connItem.getSettings()); case DIALOG_VOLUME_STREAM: VolumeStreamItem volumeItem = (VolumeStreamItem) mSelectedItem; @@ -641,6 +673,35 @@ public class SetupActionsFragment extends SettingsPreferenceFragment return builder.create(); } + private AlertDialog requestNotificationLightModeDialog() { + AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + final String[] notificationLightEntries = + getResources().getStringArray(R.array.profile_notification_light_entries); + + int defaultIndex = 0; // no action + for (int i = 0; i < NOTIFICATION_LIGHT_MAPPING.length; i++) { + if (NOTIFICATION_LIGHT_MAPPING[i] == mProfile.getNotificationLightMode()) { + defaultIndex = i; + break; + } + } + + builder.setTitle(R.string.notification_light_title); + builder.setSingleChoiceItems(notificationLightEntries, defaultIndex, + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int item) { + mProfile.setNotificationLightMode(NOTIFICATION_LIGHT_MAPPING[item]); + updateProfile(); + mAdapter.notifyDataSetChanged(); + dialog.dismiss(); + } + }); + + builder.setNegativeButton(android.R.string.cancel, null); + return builder.create(); + } + private AlertDialog requestAirplaneModeDialog(final AirplaneModeSettings setting) { AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); final String[] connectionNames = @@ -699,6 +760,29 @@ public class SetupActionsFragment extends SettingsPreferenceFragment if (requestCode == NEW_TRIGGER_REQUEST_CODE) { mProfile = mProfileManager.getProfile(mProfile.getUuid()); rebuildItemList(); + + } else if (requestCode == SET_NETWORK_MODE_REQUEST_CODE + && resultCode == Activity.RESULT_OK) { + + int selectedMode = Integer.parseInt(data.getStringExtra( + TelephonyUtils.EXTRA_NETWORK_PICKER_PICKED_VALUE)); + int subId = data.getIntExtra(TelephonyUtils.EXTRA_SUBID, + SubscriptionManager.getDefaultDataSubId()); + ConnectionOverrideItem connItem = (ConnectionOverrideItem) mSelectedItem; + final ConnectionSettings setting = connItem.getSettings(); +// final ConnectionSettings setting = mProfile.getConnectionSettingWithSubId(subId); + + switch (selectedMode) { + case ConnectionOverrideItem.CM_MODE_SYSTEM_DEFAULT: + setting.setOverride(false); + break; + default: + setting.setOverride(true); + setting.setValue(selectedMode); + } + mProfile.setConnectionSettings(setting); + mAdapter.notifyDataSetChanged(); + updateProfile(); } } @@ -757,6 +841,9 @@ public class SetupActionsFragment extends SettingsPreferenceFragment if (setting == null) { throw new UnsupportedOperationException("connection setting cannot be null"); } + if (setting.getConnectionId() == PROFILE_CONNECTION_2G3G4G) { + throw new UnsupportedOperationException("dialog must be requested from Telephony"); + } AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); final String[] connectionNames = getResources().getStringArray(R.array.profile_action_generic_connection_entries); @@ -770,7 +857,7 @@ public class SetupActionsFragment extends SettingsPreferenceFragment } } - builder.setTitle(ConnectionOverrideItem.getConnectionTitle(setting.getConnectionId())); + builder.setTitle(ConnectionOverrideItem.getConnectionTitle(getContext(), setting)); builder.setSingleChoiceItems(connectionNames, defaultIndex, new DialogInterface.OnClickListener() { @Override @@ -799,73 +886,6 @@ public class SetupActionsFragment extends SettingsPreferenceFragment return builder.create(); } - private AlertDialog requestMobileConnectionOverrideDialog(final ConnectionSettings setting) { - if (setting == null) { - throw new UnsupportedOperationException("connection setting cannot be null"); - } - AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); - boolean allow2g = true; - - // config_prefer_2g in p/s/Telephony - // if false, 2g is not available. - try { - final Context telephonyContext = getActivity() - .createPackageContext("com.android.phone", 0); - if (telephonyContext != null) { - int identifier = telephonyContext.getResources().getIdentifier("config_prefer_2g", - "bool", telephonyContext.getPackageName()); - if (identifier > 0) { - allow2g = telephonyContext.getResources().getBoolean(identifier); - android.util.Log.e("ro", "allow2g: " + allow2g); - } - } - } catch (PackageManager.NameNotFoundException e) { - // hmmm.... - } - - final String[] connectionNames = - getResources().getStringArray(allow2g ? R.array.profile_networkmode_entries_4g - : R.array.profile_networkmode_entries_no_2g); - final String[] connectionValues = - getResources().getStringArray(allow2g ? R.array.profile_networkmode_values_4g - : R.array.profile_networkmode_values_no_2g); - - int defaultIndex = connectionValues.length - 1; // no action is the last - if (setting.isOverride()) { - // need to match the value - final int value = setting.getValue(); - for (int i = 0; i < connectionValues.length; i++) { - if (Integer.parseInt(connectionValues[i]) == value) { - defaultIndex = i; - break; - } - } - } - - builder.setTitle(ConnectionOverrideItem.getConnectionTitle(setting.getConnectionId())); - builder.setSingleChoiceItems(connectionNames, defaultIndex, - new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int item) { - switch (item) { - case ConnectionOverrideItem.CM_MODE_UNCHANGED: - setting.setOverride(false); - break; - default: - setting.setOverride(true); - setting.setValue(Integer.parseInt(connectionValues[item])); - } - mProfile.setConnectionSettings(setting); - mAdapter.notifyDataSetChanged(); - updateProfile(); - dialog.dismiss(); - } - }); - - builder.setNegativeButton(android.R.string.cancel, null); - return builder.create(); - } - public AlertDialog requestVolumeDialog(int streamId, final StreamSettings streamSettings) { AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); @@ -1083,10 +1103,26 @@ public class SetupActionsFragment extends SettingsPreferenceFragment showDialog(DIALOG_LOCK_MODE); } else if (itemAtPosition instanceof DozeModeItem) { showDialog(DIALOG_DOZE_MODE); + } else if (itemAtPosition instanceof NotificationLightModeItem) { + showDialog(DIALOG_NOTIFICATION_LIGHT_MODE); } else if (itemAtPosition instanceof RingModeItem) { showDialog(DIALOG_RING_MODE); } else if (itemAtPosition instanceof ConnectionOverrideItem) { - showDialog(DIALOG_CONNECTION_OVERRIDE); + + ConnectionOverrideItem connItem = (ConnectionOverrideItem) mSelectedItem; + if (connItem.getConnectionType() == ConnectionSettings.PROFILE_CONNECTION_2G3G4G) { + final Intent intent = new Intent(TelephonyUtils.ACTION_PICK_NETWORK_MODE); + intent.putExtra(TelephonyUtils.EXTRA_NONE_TEXT, + getString(R.string.profile_action_none)); + intent.putExtra(TelephonyUtils.EXTRA_SHOW_NONE, true); + intent.putExtra(TelephonyUtils.EXTRA_SUBID, connItem.getSettings().getSubId()); + intent.putExtra(TelephonyUtils.EXTRA_INITIAL_NETWORK_VALUE, + connItem.getSettings().isOverride() + ? connItem.getSettings().getValue() : -1); + startActivityForResult(intent, SET_NETWORK_MODE_REQUEST_CODE); + } else { + showDialog(DIALOG_CONNECTION_OVERRIDE); + } } else if (itemAtPosition instanceof VolumeStreamItem) { showDialog(DIALOG_VOLUME_STREAM); } else if (itemAtPosition instanceof ProfileNameItem) { diff --git a/src/com/android/settings/profiles/actions/ItemListAdapter.java b/src/com/android/settings/profiles/actions/ItemListAdapter.java index 38a58a4..79cf22c 100644 --- a/src/com/android/settings/profiles/actions/ItemListAdapter.java +++ b/src/com/android/settings/profiles/actions/ItemListAdapter.java @@ -40,7 +40,8 @@ public class ItemListAdapter extends ArrayAdapter<Item> { TRIGGER_ITEM, APP_GROUP_ITEM, BRIGHTNESS_ITEM, - DOZEMODE_ITEM + DOZEMODE_ITEM, + NOTIFICATIONLIGHTMODE_ITEM } public ItemListAdapter(Context context, List<Item> items) { diff --git a/src/com/android/settings/profiles/actions/item/ConnectionOverrideItem.java b/src/com/android/settings/profiles/actions/item/ConnectionOverrideItem.java index ec7530d..00c8542 100644 --- a/src/com/android/settings/profiles/actions/item/ConnectionOverrideItem.java +++ b/src/com/android/settings/profiles/actions/item/ConnectionOverrideItem.java @@ -15,6 +15,8 @@ */ package com.android.settings.profiles.actions.item; +import android.content.Context; +import android.telephony.SubscriptionManager; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -25,16 +27,13 @@ import cyanogenmod.profiles.ConnectionSettings; import com.android.settings.R; import com.android.settings.profiles.actions.ItemListAdapter; +import com.android.settings.utils.TelephonyUtils; + public class ConnectionOverrideItem implements Item { int mConnectionId; ConnectionSettings mConnectionSettings; - public static final int CM_MODE_2G = 0; - public static final int CM_MODE_3G = 1; - public static final int CM_MODE_4G = 2; - public static final int CM_MODE_2G3G = 3; - public static final int CM_MODE_ALL = 4; - public static final int CM_MODE_UNCHANGED = 5; + public static final int CM_MODE_SYSTEM_DEFAULT = -1; public ConnectionOverrideItem(int connectionId, ConnectionSettings settings) { mConnectionId = connectionId; @@ -62,8 +61,8 @@ public class ConnectionOverrideItem implements Item { TextView title = (TextView) view.findViewById(R.id.title); TextView summary = (TextView) view.findViewById(R.id.summary); - title.setText(getConnectionTitle(mConnectionId)); - summary.setText(getSummary()); + title.setText(getConnectionTitle(view.getContext(), mConnectionSettings)); + summary.setText(getSummary(view.getContext())); return view; } @@ -73,61 +72,67 @@ public class ConnectionOverrideItem implements Item { return true; } - public static int getConnectionTitle(int connectionId) { - switch (connectionId) { + public static String getConnectionTitle(Context context, ConnectionSettings settings) { + int r = 0; + switch (settings.getConnectionId()) { case ConnectionSettings.PROFILE_CONNECTION_BLUETOOTH: - return R.string.toggleBluetooth; + r = R.string.toggleBluetooth; + break; case ConnectionSettings.PROFILE_CONNECTION_MOBILEDATA: - return R.string.toggleData; + r =R.string.toggleData; + break; case ConnectionSettings.PROFILE_CONNECTION_2G3G4G: - return R.string.toggle2g3g4g; + if (settings.getSubId() != SubscriptionManager.INVALID_SUBSCRIPTION_ID) { + final String displayName = SubscriptionManager.from(context) + .getActiveSubscriptionInfo(settings.getSubId()) + .getDisplayName() + .toString(); + return context.getString(R.string.toggle2g3g4g_msim, displayName); + } + r = R.string.toggle2g3g4g; + break; case ConnectionSettings.PROFILE_CONNECTION_GPS: - return R.string.toggleGPS; + r = R.string.toggleGPS; + break; case ConnectionSettings.PROFILE_CONNECTION_NFC: - return R.string.toggleNfc; + r = R.string.toggleNfc; + break; case ConnectionSettings.PROFILE_CONNECTION_SYNC: - return R.string.toggleSync; + r = R.string.toggleSync; + break; case ConnectionSettings.PROFILE_CONNECTION_WIFI: - return R.string.toggleWifi; + r = R.string.toggleWifi; + break; case ConnectionSettings.PROFILE_CONNECTION_WIFIAP: - return R.string.toggleWifiAp; - default: - return 0; + r = R.string.toggleWifiAp; + break; } + return context.getString(r); } - public int getSummary() { + public CharSequence getSummary(Context context) { + int resId = -1; if (mConnectionSettings != null) { if (mConnectionId == ConnectionSettings.PROFILE_CONNECTION_2G3G4G) { // different options if (mConnectionSettings.isOverride()) { - switch (mConnectionSettings.getValue()) { - case CM_MODE_2G: - return R.string.profile_networkmode_2g; - case CM_MODE_3G: - return R.string.profile_networkmode_3g; - case CM_MODE_4G: - return R.string.profile_networkmode_4g; - case CM_MODE_2G3G: - return R.string.profile_networkmode_2g3g; - default: - case CM_MODE_ALL: - return R.string.profile_networkmode_2g3g4g; - } + return TelephonyUtils.getNetworkModeString(context, + mConnectionSettings.getValue(), SubscriptionManager.getDefaultDataSubId()); } else { - return R.string.profile_action_none; + resId = R.string.profile_action_none; } } else if (mConnectionSettings.isOverride()) { // enabled, disabled, or none if (mConnectionSettings.getValue() == 1) { - return R.string.profile_action_enable; + resId = R.string.profile_action_enable; } else { - return R.string.profile_action_disable; + resId = R.string.profile_action_disable; } } else { - return R.string.profile_action_none; + resId = R.string.profile_action_none; } } else { - return R.string.profile_action_none; + resId = R.string.profile_action_none; } + return context.getString(resId); } public ConnectionSettings getSettings() { diff --git a/src/com/android/settings/profiles/actions/item/NotificationLightModeItem.java b/src/com/android/settings/profiles/actions/item/NotificationLightModeItem.java new file mode 100644 index 0000000..b2c9132 --- /dev/null +++ b/src/com/android/settings/profiles/actions/item/NotificationLightModeItem.java @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2014 The CyanogenMod 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.profiles.actions.item; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import cyanogenmod.app.Profile; + +import com.android.settings.R; +import com.android.settings.profiles.actions.ItemListAdapter; + +public class NotificationLightModeItem implements Item { + Profile mProfile; + + public NotificationLightModeItem(Profile profile) { + mProfile = profile; + } + + @Override + public ItemListAdapter.RowType getRowType() { + return ItemListAdapter.RowType.NOTIFICATIONLIGHTMODE_ITEM; + } + + @Override + public boolean isEnabled() { + return true; + } + + @Override + public View getView(LayoutInflater inflater, View convertView, ViewGroup parent) { + View view; + if (convertView == null) { + view = inflater.inflate(R.layout.list_two_line_item, parent, false); + // Do some initialization + } else { + view = convertView; + } + + TextView text = (TextView) view.findViewById(R.id.title); + text.setText(R.string.notification_light_title); + + TextView desc = (TextView) view.findViewById(R.id.summary); + desc.setText(getSummaryString(mProfile)); + + return view; + } + + public static int getSummaryString(Profile profile) { + switch (profile.getNotificationLightMode()) { + case Profile.NotificationLightMode.DEFAULT: + return R.string.profile_action_none; //"leave unchanged" + case Profile.NotificationLightMode.ENABLE: + return R.string.profile_action_enable; + case Profile.NotificationLightMode.DISABLE: + return R.string.profile_action_disable; + default: return 0; + } + } +} diff --git a/src/com/android/settings/search/IndexDatabaseHelper.java b/src/com/android/settings/search/IndexDatabaseHelper.java index 273960d..84a2922 100644 --- a/src/com/android/settings/search/IndexDatabaseHelper.java +++ b/src/com/android/settings/search/IndexDatabaseHelper.java @@ -28,7 +28,7 @@ public class IndexDatabaseHelper extends SQLiteOpenHelper { private static final String TAG = "IndexDatabaseHelper"; private static final String DATABASE_NAME = "search_index.db"; - private static final int DATABASE_VERSION = 116; + private static final int DATABASE_VERSION = 118; public interface Tables { public static final String TABLE_PREFS_INDEX = "prefs_index"; diff --git a/src/com/android/settings/search/Ranking.java b/src/com/android/settings/search/Ranking.java index 2dc1a89..4d80f14 100644 --- a/src/com/android/settings/search/Ranking.java +++ b/src/com/android/settings/search/Ranking.java @@ -53,6 +53,9 @@ import com.android.settings.wifi.AdvancedWifiSettings; import com.android.settings.wifi.SavedAccessPointsWifiSettings; import com.android.settings.wifi.WifiSettings; +import com.android.settings.ButtonSettings; +import com.android.settings.cyanogenmod.StatusBarSettings; + import java.util.HashMap; /** @@ -117,6 +120,8 @@ public final class Ranking { // Display sRankMap.put(DisplaySettings.class.getName(), RANK_DISPLAY); + sRankMap.put(ButtonSettings.class.getName(), RANK_DISPLAY); + sRankMap.put(StatusBarSettings.class.getName(), RANK_DISPLAY); // Wallpapers sRankMap.put(WallpaperTypeSettings.class.getName(), RANK_WALLPAPER); @@ -156,6 +161,7 @@ public final class Ranking { // Privacy sRankMap.put(PrivacySettings.class.getName(), RANK_PRIVACY); + sRankMap.put(com.android.settings.cyanogenmod.PrivacySettings.class.getName(), RANK_PRIVACY); // Date / Time sRankMap.put(DateTimeSettings.class.getName(), RANK_DATE_TIME); diff --git a/src/com/android/settings/search/SearchIndexableResources.java b/src/com/android/settings/search/SearchIndexableResources.java index a7a8264..afd48ae 100644 --- a/src/com/android/settings/search/SearchIndexableResources.java +++ b/src/com/android/settings/search/SearchIndexableResources.java @@ -54,6 +54,9 @@ import com.android.settings.wifi.AdvancedWifiSettings; import com.android.settings.wifi.SavedAccessPointsWifiSettings; import com.android.settings.wifi.WifiSettings; +import com.android.settings.ButtonSettings; +import com.android.settings.cyanogenmod.StatusBarSettings; + import java.util.Collection; import java.util.HashMap; @@ -82,7 +85,7 @@ public final class SearchIndexableResources { sResMap.put(SavedAccessPointsWifiSettings.class.getName(), new SearchIndexableResource( Ranking.getRankForClassName(SavedAccessPointsWifiSettings.class.getName()), - R.xml.wifi_display_saved_access_points, + NO_DATA_RES_ID, SavedAccessPointsWifiSettings.class.getName(), R.drawable.ic_settings_wireless)); @@ -309,6 +312,37 @@ public final class SearchIndexableResources { R.xml.wifi_calling_settings, WifiCallingSettings.class.getName(), R.drawable.ic_settings_wireless)); + + // CyanogenMod Settings + sResMap.put(ButtonSettings.class.getName(), + new SearchIndexableResource( + Ranking.getRankForClassName(ButtonSettings.class.getName()), + R.xml.button_settings, + ButtonSettings.class.getName(), + R.drawable.ic_settings_buttons)); + + sResMap.put(StatusBarSettings.class.getName(), + new SearchIndexableResource( + Ranking.getRankForClassName(StatusBarSettings.class.getName()), + R.xml.status_bar_settings, + StatusBarSettings.class.getName(), + R.drawable.ic_settings_statusbar)); + + sResMap.put(com.android.settings.cyanogenmod.PrivacySettings.class.getName(), + new SearchIndexableResource( + Ranking.getRankForClassName( + com.android.settings.cyanogenmod.PrivacySettings.class.getName()), + R.xml.privacy_settings_cyanogenmod, + com.android.settings.cyanogenmod.PrivacySettings.class.getName(), + R.drawable.ic_settings_privacy)); + + sResMap.put(com.android.settings.cyanogenmod.LockscreenSettingsAlias.class.getName(), + new SearchIndexableResource( + Ranking.getRankForClassName( + com.android.settings.cyanogenmod.LockscreenSettingsAlias.class.getName()), + NO_DATA_RES_ID, + com.android.settings.cyanogenmod.LockscreenSettingsAlias.class.getName(), + R.drawable.ic_settings_lockscreen)); } private SearchIndexableResources() { diff --git a/src/com/android/settings/sim/SimDialogActivity.java b/src/com/android/settings/sim/SimDialogActivity.java index 63124d7..0b73d65 100644 --- a/src/com/android/settings/sim/SimDialogActivity.java +++ b/src/com/android/settings/sim/SimDialogActivity.java @@ -178,7 +178,8 @@ public class SimDialogActivity extends Activity { sir = subInfoList.get(value); SubscriptionInfo defaultSub = subscriptionManager .getDefaultDataSubscriptionInfo(); - if (defaultSub.getSubscriptionId() != sir.getSubscriptionId()) { + if (defaultSub == null || defaultSub.getSubscriptionId() + != sir.getSubscriptionId()) { setDefaultDataSubId(context, sir.getSubscriptionId()); } break; @@ -237,7 +238,7 @@ public class SimDialogActivity extends Activity { } }; - int currentIndex = 0; + int currentIndex = -1; ArrayList<SubscriptionInfo> callsSubInfoList = new ArrayList<SubscriptionInfo>(); if (id == CALLS_PICK) { final TelecomManager telecomManager = TelecomManager.from(context); diff --git a/src/com/android/settings/sim/SimSettings.java b/src/com/android/settings/sim/SimSettings.java index 5f7ca31..20a401e 100644 --- a/src/com/android/settings/sim/SimSettings.java +++ b/src/com/android/settings/sim/SimSettings.java @@ -16,6 +16,7 @@ package com.android.settings.sim; +import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; import android.app.ProgressDialog; @@ -168,7 +169,10 @@ public class SimSettings extends RestrictedSettingsFragment implements Indexable @Override public void onSubscriptionsChanged() { if (DBG) log("onSubscriptionsChanged:"); - updateSubscriptions(); + Activity activity = getActivity(); + if (activity != null && !activity.isFinishing()) { + updateSubscriptions(); + } } }; diff --git a/src/com/android/settings/users/EditUserInfoController.java b/src/com/android/settings/users/EditUserInfoController.java index ab77101..a4c07bd 100644 --- a/src/com/android/settings/users/EditUserInfoController.java +++ b/src/com/android/settings/users/EditUserInfoController.java @@ -37,8 +37,8 @@ import android.widget.EditText; import android.widget.ImageView; import com.android.settings.R; -import com.android.settings.Utils; -import com.android.settings.drawable.CircleFramedDrawable; +import com.android.settingslib.Utils; +import com.android.settingslib.drawable.CircleFramedDrawable; /** * This class encapsulates a Dialog for editing the user nickname and photo. diff --git a/src/com/android/settings/users/EditUserPhotoController.java b/src/com/android/settings/users/EditUserPhotoController.java index 82e550e..f9f867d 100644 --- a/src/com/android/settings/users/EditUserPhotoController.java +++ b/src/com/android/settings/users/EditUserPhotoController.java @@ -45,7 +45,7 @@ import android.widget.ListAdapter; import android.widget.ListPopupWindow; import com.android.settings.R; -import com.android.settings.drawable.CircleFramedDrawable; +import com.android.settingslib.drawable.CircleFramedDrawable; import java.io.File; import java.io.FileNotFoundException; @@ -343,4 +343,4 @@ public class EditUserPhotoController { return title; } } -}
\ No newline at end of file +} diff --git a/src/com/android/settings/users/RestrictedProfileSettings.java b/src/com/android/settings/users/RestrictedProfileSettings.java index b0b86e4..2531aaa 100644 --- a/src/com/android/settings/users/RestrictedProfileSettings.java +++ b/src/com/android/settings/users/RestrictedProfileSettings.java @@ -86,7 +86,7 @@ public class RestrictedProfileSettings extends AppRestrictionsFragment } else { ((TextView) mHeaderView.findViewById(android.R.id.title)).setText(info.name); ((ImageView) mHeaderView.findViewById(android.R.id.icon)).setImageDrawable( - Utils.getUserIcon(getActivity(), mUserManager, info)); + com.android.settingslib.Utils.getUserIcon(getActivity(), mUserManager, info)); } } diff --git a/src/com/android/settings/users/UserSettings.java b/src/com/android/settings/users/UserSettings.java index 1849a9a..85d2700 100644 --- a/src/com/android/settings/users/UserSettings.java +++ b/src/com/android/settings/users/UserSettings.java @@ -64,10 +64,10 @@ import com.android.settings.SelectableEditTextPreference; import com.android.settings.SettingsActivity; import com.android.settings.SettingsPreferenceFragment; import com.android.settings.Utils; -import com.android.settings.drawable.CircleFramedDrawable; import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.search.Indexable; import com.android.settings.search.SearchIndexableRaw; +import com.android.settingslib.drawable.CircleFramedDrawable; import java.util.ArrayList; import java.util.Collections; diff --git a/src/com/android/settings/utils/TelephonyUtils.java b/src/com/android/settings/utils/TelephonyUtils.java new file mode 100644 index 0000000..35aab79 --- /dev/null +++ b/src/com/android/settings/utils/TelephonyUtils.java @@ -0,0 +1,231 @@ +package com.android.settings.utils; + +import android.content.Context; +import android.content.pm.PackageManager; +import android.content.res.Resources; +import android.os.PersistableBundle; +import android.telephony.CarrierConfigManager; +import android.telephony.TelephonyManager; +import android.text.TextUtils; +import android.util.Log; + +import com.android.internal.telephony.PhoneConstants; +import com.android.internal.telephony.RILConstants; + +/** + * Helper class which has the same logic as MobileNetworkSettings to display the same + * network modes and strings as it does. + */ +public class TelephonyUtils { + + private static final String TAG = TelephonyUtils.class.getSimpleName(); + + // from MobileNetworkSettings + public static final String ACTION_PICK_NETWORK_MODE = + "cyanogenmod.platform.intent.action.NETWORK_MODE_PICKER"; + public static final String EXTRA_NONE_TEXT = "network_mode_picker::neutral_text"; + public static final String EXTRA_SHOW_NONE = "network_mode_picker::show_none"; + public static final String EXTRA_INITIAL_NETWORK_VALUE = "network_mode_picker::selected_mode"; + public static final String EXTRA_NETWORK_PICKER_PICKED_VALUE = + "network_mode_picker::chosen_value"; + public static final String EXTRA_SUBID = "network_mode_picker::sub_id"; + + public static String getNetworkModeString(Context context, int networkMode, int subId) { + return getNetworkModeString(context, + networkMode, + TelephonyManager.from(context).getCurrentPhoneType(subId) /* phone type */, + show4GForLTE(context)/* show 4G for lte */, + isSupportTdscdma(context, subId)/* supports TDS CDMA*/, + isGlobalCDMA(context, subId, isLteOnCdma(context, subId))/* is Global cdma */, + isWorldMode(context)/* is worldwide */); + } + + public static String getNetworkModeString(Context context, int networkMode, + int phoneType, boolean show4GForLTE, boolean isSupportTdsCdma, boolean isGlobalCdma, + boolean isWorldMode) { + String r = null; + switch (networkMode) { + case RILConstants.NETWORK_MODE_TDSCDMA_WCDMA: + case RILConstants.NETWORK_MODE_TDSCDMA_GSM_WCDMA: + case RILConstants.NETWORK_MODE_TDSCDMA_GSM: + r = "network_3G"; + break; + case RILConstants.NETWORK_MODE_WCDMA_ONLY: + r = "network_wcdma_only"; + break; + case RILConstants.NETWORK_MODE_GSM_UMTS: + r = "network_gsm_umts"; + break; + case RILConstants.NETWORK_MODE_WCDMA_PREF: + r = "network_wcdma_pref"; + break; + case RILConstants.NETWORK_MODE_GSM_ONLY: + r = "network_gsm_only"; + break; + case RILConstants.NETWORK_MODE_LTE_GSM_WCDMA: + r = (show4GForLTE) + ? "network_4G" : "network_lte_gsm_wcdma"; + break; + case RILConstants.NETWORK_MODE_LTE_WCDMA: + r = (show4GForLTE) + ? "network_4G" : "network_lte_cdma"; + break; + case RILConstants.NETWORK_MODE_LTE_ONLY: + r = (show4GForLTE) + ? "network_4G_only" : "network_lte_only"; + break; + case RILConstants.NETWORK_MODE_LTE_CDMA_EVDO: + r = (show4GForLTE) + ? "network_4G" : "network_lte_cdma_and_evdo"; + break; + case RILConstants.NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA: + r = "network_3G"; + break; + case RILConstants.NETWORK_MODE_CDMA: + r = "network_cdma"; + break; + case RILConstants.NETWORK_MODE_EVDO_NO_CDMA: + r = "network_evdo_no_cdma"; + break; + case RILConstants.NETWORK_MODE_GLOBAL: + r = "network_3g_global"; + break; + case RILConstants.NETWORK_MODE_CDMA_NO_EVDO: + r = "network_cdma_no_evdo"; + break; + case RILConstants.NETWORK_MODE_TDSCDMA_ONLY: + r = "network_tdscdma"; + break; + case RILConstants.NETWORK_MODE_LTE_TDSCDMA_GSM: + case RILConstants.NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA: + case RILConstants.NETWORK_MODE_LTE_TDSCDMA: + case RILConstants.NETWORK_MODE_LTE_TDSCDMA_WCDMA: + case RILConstants.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA: + case RILConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA: + if (isSupportTdsCdma) { + r = "network_lte"; + } else { + if (phoneType == RILConstants.CDMA_PHONE || isGlobalCdma || isWorldMode) { + r = "network_global"; + } else { + r = (show4GForLTE) + ? "network_4G" : "network_lte"; + } + } + break; + default: + Log.w(TAG, "unknown phone mode: " + networkMode); + } + + if (r != null) { + // grab the phone resources + final Resources phoneResources = getPhoneResources(context); + if (phoneResources != null) { + int id = phoneResources.getIdentifier(r, "string", "com.android.phone"); + if (id > 0) { + return phoneResources.getString(id); + } else { + Log.w(TAG, "couldn't find resource id with name: " + r); + } + } + } + return null; + } + + private static boolean isSupportTdscdma(Context context, int subId) { + final Resources phoneResources = getPhoneResources(context); + if (phoneResources != null) { + int id = phoneResources.getIdentifier("config_support_tdscdma", + "bool", "com.android.phone"); + if (phoneResources.getBoolean(id)) { + return true; + } + + final String operatorNumeric = TelephonyManager.from(context) + .getSimOperatorNumericForSubscription(subId); + + int tdcdmaArrId = phoneResources.getIdentifier("config_support_tdscdma_roaming_on_networks", + "string-array", "com.android.phone"); + + if (tdcdmaArrId > 0) { + String[] numericArray = phoneResources.getStringArray(tdcdmaArrId); + if (numericArray.length == 0 || operatorNumeric == null) { + return false; + } + for (String numeric : numericArray) { + if (operatorNumeric.equals(numeric)) { + return true; + } + } + } + } + return false; + } + + private static boolean show4GForLTE(Context context) { + try { + Context con = context.createPackageContext("com.android.systemui", 0); + int id = con.getResources().getIdentifier("config_show4GForLTE", + "bool", "com.android.systemui"); + return con.getResources().getBoolean(id); + } catch (PackageManager.NameNotFoundException e) { + return false; + } + } + + private static boolean isGlobalCDMA(Context context, int subId, boolean isLteOnCdma) { + final CarrierConfigManager carrierConfigMan = (CarrierConfigManager) + context.getSystemService(Context.CARRIER_CONFIG_SERVICE); + final PersistableBundle carrierConfig = carrierConfigMan.getConfigForSubId(subId); + return isLteOnCdma + && carrierConfig.getBoolean(CarrierConfigManager.KEY_SHOW_CDMA_CHOICES_BOOL); + } + + private static boolean isLteOnCdma(Context context, int subId) { + return TelephonyManager.from(context).getLteOnCdmaMode(subId) + == PhoneConstants.LTE_ON_CDMA_TRUE; + } + + private static boolean isWorldMode(Context context) { + boolean worldModeOn = false; + final TelephonyManager tm = (TelephonyManager) + context.getSystemService(Context.TELEPHONY_SERVICE); + + Resources phoneResources = getPhoneResources(context); + if (phoneResources != null) { + int id = phoneResources.getIdentifier("config_world_mode", + "string", "com.android.phone"); + + if (id > 0) { + final String configString = phoneResources.getString(id); + + if (!TextUtils.isEmpty(configString)) { + String[] configArray = configString.split(";"); + // Check if we have World mode configuration set to True only or config is set to True + // and SIM GID value is also set and matches to the current SIM GID. + if (configArray != null && + ((configArray.length == 1 && configArray[0].equalsIgnoreCase("true")) || + (configArray.length == 2 && !TextUtils.isEmpty(configArray[1]) && + tm != null && configArray[1].equalsIgnoreCase(tm.getGroupIdLevel1())))) { + worldModeOn = true; + } + } + } else { + Log.w(TAG, "couldn't find resource of config_world_mode"); + } + } + + return worldModeOn; + } + + private static Resources getPhoneResources(Context context) { + try { + final Context packageContext = context.createPackageContext("com.android.phone", 0); + return packageContext.getResources(); + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + } + Log.w(TAG, "couldn't locate resources for com.android.phone!"); + return null; + } +} |