();
- if (name != null && apn != null && TextUtils.getTrimmedLength(name) > 0
- && TextUtils.getTrimmedLength(apn) > 0) {
- Preference pref = new Preference((Context) this);
- pref.setKey(mCursor.getString(ID_INDEX));
- pref.setTitle(name);
- pref.setSummary(apn);
- pref.setPersistent(false);
+ mSelectedKey = getSelectedApnKey();
+ cursor.moveToFirst();
+ while (!cursor.isAfterLast()) {
+ String name = cursor.getString(NAME_INDEX);
+ String apn = cursor.getString(APN_INDEX);
+ String key = cursor.getString(ID_INDEX);
+ String type = cursor.getString(TYPES_INDEX);
+
+ ApnPreference pref = new ApnPreference(this);
+
+ pref.setKey(key);
+ pref.setTitle(name);
+ pref.setSummary(apn);
+ pref.setPersistent(false);
+ pref.setOnPreferenceChangeListener(this);
+
+ boolean selectable = ((type == null) || !type.equals("mms"));
+ pref.setSelectable(selectable);
+ if (selectable) {
+ if ((mSelectedKey != null) && mSelectedKey.equals(key)) {
+ pref.setChecked(true);
+ }
apnList.addPreference(pref);
+ } else {
+ mmsApnList.add(pref);
}
+ cursor.moveToNext();
+ }
+ cursor.close();
- mCursor.moveToNext();
+ for (Preference preference : mmsApnList) {
+ apnList.addPreference(preference);
}
}
@@ -148,6 +231,39 @@ public class ApnSettings extends PreferenceActivity {
return true;
}
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ Log.d(TAG, "onPreferenceChange(): Preference - " + preference
+ + ", newValue - " + newValue + ", newValue type - "
+ + newValue.getClass());
+ if (newValue instanceof String) {
+ setSelectedApnKey((String) newValue);
+ }
+
+ return true;
+ }
+
+ private void setSelectedApnKey(String key) {
+ mSelectedKey = key;
+ ContentResolver resolver = getContentResolver();
+
+ ContentValues values = new ContentValues();
+ values.put(APN_ID, mSelectedKey);
+ resolver.update(PREFERAPN_URI, values, null, null);
+ }
+
+ private String getSelectedApnKey() {
+ String key = null;
+
+ Cursor cursor = managedQuery(PREFERAPN_URI, new String[] {"_id"},
+ null, Telephony.Carriers.DEFAULT_SORT_ORDER);
+ if (cursor.getCount() > 0) {
+ cursor.moveToFirst();
+ key = cursor.getString(ID_INDEX);
+ }
+ cursor.close();
+ return key;
+ }
+
private boolean restoreDefaultApn() {
showDialog(DIALOG_RESTORE_DEFAULTAPN);
mRestoreDefaultApnMode = true;
diff --git a/src/com/android/settings/AppWidgetPickActivity.java b/src/com/android/settings/AppWidgetPickActivity.java
index 0a6371204b8..cddc6875cb4 100644
--- a/src/com/android/settings/AppWidgetPickActivity.java
+++ b/src/com/android/settings/AppWidgetPickActivity.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,16 +16,14 @@
package com.android.settings;
-import android.app.LauncherActivity;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProviderInfo;
-import android.content.ComponentName;
+import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
-import android.view.View;
-import android.widget.ListView;
+import android.os.Parcelable;
import android.util.Log;
import java.text.Collator;
@@ -34,98 +32,208 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
-public class AppWidgetPickActivity extends LauncherActivity
-{
+/**
+ * Displays a list of {@link AppWidgetProviderInfo} widgets, along with any
+ * injected special widgets specified through
+ * {@link AppWidgetManager#EXTRA_CUSTOM_INFO} and
+ * {@link AppWidgetManager#EXTRA_CUSTOM_EXTRAS}.
+ *
+ * When an installed {@link AppWidgetProviderInfo} is selected, this activity
+ * will bind it to the given {@link AppWidgetManager#EXTRA_APPWIDGET_ID},
+ * otherwise it will return the requested extras.
+ */
+public class AppWidgetPickActivity extends ActivityPicker {
private static final String TAG = "AppWidgetPickActivity";
+ private static final boolean LOGD = false;
- AppWidgetManager mAppWidgetManager;
- int mAppWidgetId;
+ private PackageManager mPackageManager;
+ private AppWidgetManager mAppWidgetManager;
+
+ /**
+ * The allocated {@link AppWidgetManager#EXTRA_APPWIDGET_ID} that this
+ * activity is binding.
+ */
+ private int mAppWidgetId;
- public AppWidgetPickActivity() {
- mAppWidgetManager = AppWidgetManager.getInstance(this);
- }
-
@Override
public void onCreate(Bundle icicle) {
+ mPackageManager = getPackageManager();
+ mAppWidgetManager = AppWidgetManager.getInstance(this);
+
super.onCreate(icicle);
-
- Bundle extras = getIntent().getExtras();
- mAppWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID);
-
- setResultData(RESULT_CANCELED);
- }
-
- @Override
- public void onListItemClick(ListView l, View v, int position, long id)
- {
- Intent intent = intentForPosition(position);
- int result;
- try {
- mAppWidgetManager.bindAppWidgetId(mAppWidgetId, intent.getComponent());
- result = RESULT_OK;
- } catch (IllegalArgumentException e) {
- // This is thrown if they're already bound, or otherwise somehow
- // bogus. Set the result to canceled, and exit. The app *should*
- // clean up at this point. We could pass the error along, but
- // it's not clear that that's useful -- the widget will simply not
- // appear.
- result = RESULT_CANCELED;
+
+ // Set default return data
+ setResultData(RESULT_CANCELED, null);
+
+ // Read the appWidgetId passed our direction, otherwise bail if not found
+ final Intent intent = getIntent();
+ if (intent.hasExtra(AppWidgetManager.EXTRA_APPWIDGET_ID)) {
+ mAppWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
+ AppWidgetManager.INVALID_APPWIDGET_ID);
+ } else {
+ finish();
}
- setResultData(result);
- finish();
}
+ /**
+ * Create list entries for any custom widgets requested through
+ * {@link AppWidgetManager#EXTRA_CUSTOM_INFO}.
+ */
+ void putCustomAppWidgets(List items) {
+ final Bundle extras = getIntent().getExtras();
+
+ // get and validate the extras they gave us
+ ArrayList customInfo = null;
+ ArrayList customExtras = null;
+ try_custom_items: {
+ customInfo = extras.getParcelableArrayList(AppWidgetManager.EXTRA_CUSTOM_INFO);
+ if (customInfo == null || customInfo.size() == 0) {
+ Log.i(TAG, "EXTRA_CUSTOM_INFO not present.");
+ break try_custom_items;
+ }
+
+ int customInfoSize = customInfo.size();
+ for (int i=0; i makeListItems() {
- List installed = mAppWidgetManager.getInstalledProviders();
- PackageManager pm = getPackageManager();
+ public void onClick(DialogInterface dialog, int which) {
+ Intent intent = getIntentForPosition(which);
+
+ int result;
+ if (intent.getExtras() != null) {
+ // If there are any extras, it's because this entry is custom.
+ // Don't try to bind it, just pass it back to the app.
+ setResultData(RESULT_OK, intent);
+ } else {
+ try {
+ mAppWidgetManager.bindAppWidgetId(mAppWidgetId, intent.getComponent());
+ result = RESULT_OK;
+ } catch (IllegalArgumentException e) {
+ // This is thrown if they're already bound, or otherwise somehow
+ // bogus. Set the result to canceled, and exit. The app *should*
+ // clean up at this point. We could pass the error along, but
+ // it's not clear that that's useful -- the widget will simply not
+ // appear.
+ result = RESULT_CANCELED;
+ }
+ setResultData(result, null);
+ }
+ finish();
+ }
- Drawable defaultIcon = null;
- IconResizer resizer = new IconResizer();
+ /**
+ * Create list entries for the given {@link AppWidgetProviderInfo} widgets,
+ * inserting extras if provided.
+ */
+ void putAppWidgetItems(List appWidgets,
+ List customExtras, List items) {
+ final int size = appWidgets.size();
+ for (int i = 0; i < size; i++) {
+ AppWidgetProviderInfo info = appWidgets.get(i);
+
+ CharSequence label = info.label;
+ Drawable icon = null;
- ArrayList result = new ArrayList();
- final int N = installed.size();
- for (int i=0; i() {
+ }
+
+ /**
+ * Build and return list of items to be shown in dialog. This will mix both
+ * installed {@link AppWidgetProviderInfo} and those provided through
+ * {@link AppWidgetManager#EXTRA_CUSTOM_INFO}, sorting them alphabetically.
+ */
+ @Override
+ protected List getItems() {
+ List items = new ArrayList();
+
+ putInstalledAppWidgets(items);
+ putCustomAppWidgets(items);
+
+ // Sort all items together by label
+ Collections.sort(items, new Comparator() {
Collator mCollator = Collator.getInstance();
- public int compare(ListItem lhs, ListItem rhs) {
+ public int compare(PickAdapter.Item lhs, PickAdapter.Item rhs) {
return mCollator.compare(lhs.label, rhs.label);
}
});
- return result;
+
+ return items;
}
- void setResultData(int code) {
- Intent result = new Intent();
+ /**
+ * Create list entries for installed {@link AppWidgetProviderInfo} widgets.
+ */
+ void putInstalledAppWidgets(List items) {
+ List installed = mAppWidgetManager.getInstalledProviders();
+ putAppWidgetItems(installed, null, items);
+ }
+
+ /**
+ * Convenience method for setting the result code and intent. This method
+ * correctly injects the {@link AppWidgetManager#EXTRA_APPWIDGET_ID} that
+ * most hosts expect returned.
+ */
+ void setResultData(int code, Intent intent) {
+ Intent result = intent != null ? intent : new Intent();
result.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
setResult(code, result);
}
}
-
diff --git a/src/com/android/settings/BatteryInfo.java b/src/com/android/settings/BatteryInfo.java
index f9962fa2f40..eb7ddb49f1b 100644
--- a/src/com/android/settings/BatteryInfo.java
+++ b/src/com/android/settings/BatteryInfo.java
@@ -43,9 +43,6 @@ public class BatteryInfo extends Activity {
private TextView mTemperature;
private TextView mTechnology;
private TextView mUptime;
- private TextView mAwakeBattery;
- private TextView mAwakePlugged;
- private TextView mScreenOn;
private IBatteryStats mBatteryStats;
private IPowerManager mScreenStats;
@@ -58,6 +55,7 @@ public class BatteryInfo extends Activity {
case EVENT_TICK:
updateBatteryStats();
sendEmptyMessageDelayed(EVENT_TICK, 1000);
+
break;
}
}
@@ -157,9 +155,6 @@ public class BatteryInfo extends Activity {
mVoltage = (TextView)findViewById(R.id.voltage);
mTemperature = (TextView)findViewById(R.id.temperature);
mUptime = (TextView) findViewById(R.id.uptime);
- mAwakeBattery = (TextView) findViewById(R.id.awakeBattery);
- mAwakePlugged = (TextView) findViewById(R.id.awakePlugged);
- mScreenOn = (TextView) findViewById(R.id.screenOn);
// Get awake time plugged in and on battery
mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService("batteryinfo"));
@@ -182,27 +177,6 @@ public class BatteryInfo extends Activity {
long uptime = SystemClock.elapsedRealtime();
mUptime.setText(DateUtils.formatElapsedTime(uptime / 1000));
- if (mBatteryStats != null) {
- try {
- long awakeTimeBattery = mBatteryStats.getAwakeTimeBattery() / 1000;
- long awakeTimePluggedIn = mBatteryStats.getAwakeTimePlugged() / 1000;
- mAwakeBattery.setText(DateUtils.formatElapsedTime(awakeTimeBattery / 1000)
- + " (" + (100 * awakeTimeBattery / uptime) + "%)");
- mAwakePlugged.setText(DateUtils.formatElapsedTime(awakeTimePluggedIn / 1000)
- + " (" + (100 * awakeTimePluggedIn / uptime) + "%)");
- } catch (RemoteException re) {
- mAwakeBattery.setText("Unknown");
- mAwakePlugged.setText("Unknown");
- }
- }
- if (mScreenStats != null) {
- try {
- long screenOnTime = mScreenStats.getScreenOnTime();
- mScreenOn.setText(DateUtils.formatElapsedTime(screenOnTime / 1000));
- } catch (RemoteException re) {
- mScreenOn.setText("Unknown");
- }
- }
}
}
diff --git a/src/com/android/settings/BrightnessPreference.java b/src/com/android/settings/BrightnessPreference.java
index a9851cc93a2..9f554632631 100644
--- a/src/com/android/settings/BrightnessPreference.java
+++ b/src/com/android/settings/BrightnessPreference.java
@@ -93,7 +93,7 @@ public class BrightnessPreference extends SeekBarPreference implements
IHardwareService hardware = IHardwareService.Stub.asInterface(
ServiceManager.getService("hardware"));
if (hardware != null) {
- hardware.setScreenBacklight(brightness);
+ hardware.setBacklights(brightness);
}
} catch (RemoteException doe) {
diff --git a/src/com/android/settings/ChooseLockPattern.java b/src/com/android/settings/ChooseLockPattern.java
index 3ddd669a98f..d0c375844ae 100644
--- a/src/com/android/settings/ChooseLockPattern.java
+++ b/src/com/android/settings/ChooseLockPattern.java
@@ -481,8 +481,15 @@ public class ChooseLockPattern extends Activity implements View.OnClickListener{
}
private void saveChosenPatternAndFinish() {
+ final boolean lockVirgin = !mLockPatternUtils.isPatternEverChosen();
+
mLockPatternUtils.saveLockPattern(mChosenPattern);
mLockPatternUtils.setLockPatternEnabled(true);
+
+ if (lockVirgin) {
+ mLockPatternUtils.setVisiblePatternEnabled(true);
+ mLockPatternUtils.setTactileFeedbackEnabled(false);
+ }
setResult(RESULT_FINISHED);
finish();
diff --git a/src/com/android/settings/InputMethodsSettings.java b/src/com/android/settings/InputMethodsSettings.java
deleted file mode 100644
index 51b770d0942..00000000000
--- a/src/com/android/settings/InputMethodsSettings.java
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package com.android.settings;
-
-import java.util.HashSet;
-import java.util.List;
-
-import android.content.Context;
-import android.content.Intent;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.os.SystemProperties;
-import android.preference.Preference;
-import android.preference.PreferenceActivity;
-import android.preference.PreferenceScreen;
-import android.preference.CheckBoxPreference;
-import android.provider.Settings;
-import android.text.TextUtils;
-import android.view.inputmethod.InputMethodInfo;
-import android.view.inputmethod.InputMethodManager;
-
-/*
- * Displays preferences for input methods.
- */
-public class InputMethodsSettings extends PreferenceActivity {
- private List mInputMethodProperties;
-
- final TextUtils.SimpleStringSplitter mStringColonSplitter
- = new TextUtils.SimpleStringSplitter(':');
-
- private String mLastInputMethodId;
- private String mLastTickedInputMethodId;
-
- static public String getInputMethodIdFromKey(String key) {
- return key;
- }
-
- @Override
- protected void onCreate(Bundle icicle) {
- super.onCreate(icicle);
-
- addPreferencesFromResource(R.xml.input_methods_prefs);
-
- InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
-
- mInputMethodProperties = imm.getInputMethodList();
-
- mLastInputMethodId = Settings.Secure.getString(getContentResolver(),
- Settings.Secure.DEFAULT_INPUT_METHOD);
-
- int N = (mInputMethodProperties == null ? 0 : mInputMethodProperties
- .size());
- for (int i = 0; i < N; ++i) {
- InputMethodInfo property = mInputMethodProperties.get(i);
- String prefKey = property.getId();
-
- CharSequence label = property.loadLabel(getPackageManager());
-
- // Add a check box.
- CheckBoxPreference chkbxPref = new CheckBoxPreference(this);
- chkbxPref.setKey(prefKey);
- chkbxPref.setTitle(label);
- getPreferenceScreen().addPreference(chkbxPref);
-
- // If setting activity is available, add a setting screen entry.
- if (null != property.getSettingsActivity()) {
- PreferenceScreen prefScreen = new PreferenceScreen(this, null);
- prefScreen.setKey(property.getSettingsActivity());
- prefScreen.setTitle(getResources().getString(
- R.string.input_methods_settings_label_format, label));
- getPreferenceScreen().addPreference(prefScreen);
- }
- }
- }
-
- @Override
- protected void onResume() {
- super.onResume();
-
- final HashSet enabled = new HashSet();
- String enabledStr = Settings.Secure.getString(getContentResolver(),
- Settings.Secure.ENABLED_INPUT_METHODS);
- if (enabledStr != null) {
- final TextUtils.SimpleStringSplitter splitter = mStringColonSplitter;
- splitter.setString(enabledStr);
- while (splitter.hasNext()) {
- enabled.add(splitter.next());
- }
- }
-
- // Update the statuses of the Check Boxes.
- int N = mInputMethodProperties.size();
- for (int i = 0; i < N; ++i) {
- final String id = mInputMethodProperties.get(i).getId();
- CheckBoxPreference pref = (CheckBoxPreference) findPreference(mInputMethodProperties
- .get(i).getId());
- pref.setChecked(enabled.contains(id));
- }
- mLastTickedInputMethodId = null;
- }
-
- @Override
- protected void onPause() {
- super.onPause();
-
- StringBuilder builder = new StringBuilder(256);
-
- boolean haveLastInputMethod = false;
-
- int firstEnabled = -1;
- int N = mInputMethodProperties.size();
- for (int i = 0; i < N; ++i) {
- final String id = mInputMethodProperties.get(i).getId();
- CheckBoxPreference pref = (CheckBoxPreference) findPreference(id);
- boolean hasIt = id.equals(mLastInputMethodId);
- if (pref.isChecked()) {
- if (builder.length() > 0) builder.append(':');
- builder.append(id);
- if (firstEnabled < 0) {
- firstEnabled = i;
- }
- if (hasIt) haveLastInputMethod = true;
- } else if (hasIt) {
- mLastInputMethodId = mLastTickedInputMethodId;
- }
- }
-
- // If the last input method is unset, set it as the first enabled one.
- if (null == mLastInputMethodId || "".equals(mLastInputMethodId)) {
- if (firstEnabled >= 0) {
- mLastInputMethodId = mInputMethodProperties.get(firstEnabled).getId();
- } else {
- mLastInputMethodId = null;
- }
- }
-
- Settings.Secure.putString(getContentResolver(),
- Settings.Secure.ENABLED_INPUT_METHODS, builder.toString());
- Settings.Secure.putString(getContentResolver(),
- Settings.Secure.DEFAULT_INPUT_METHOD, mLastInputMethodId);
- }
-
- @Override
- public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,
- Preference preference) {
-
- // Those monkeys kept committing suicide, so we add this property
- // to disable this functionality
- if (!TextUtils.isEmpty(SystemProperties.get("ro.monkey"))) {
- return false;
- }
-
- if (preference instanceof CheckBoxPreference) {
- CheckBoxPreference chkPref = (CheckBoxPreference) preference;
- String id = getInputMethodIdFromKey(chkPref.getKey());
- if (chkPref.isChecked()) {
- mLastTickedInputMethodId = id;
- } else if (id.equals(mLastTickedInputMethodId)) {
- mLastTickedInputMethodId = null;
- }
- } else if (preference instanceof PreferenceScreen) {
- if (preference.getIntent() == null) {
- PreferenceScreen pref = (PreferenceScreen) preference;
- String activityName = pref.getKey();
- String packageName = activityName.substring(0, activityName
- .lastIndexOf("."));
- if (activityName.length() > 0) {
- Intent i = new Intent(Intent.ACTION_MAIN);
- i.setClassName(packageName, activityName);
- startActivity(i);
- }
- }
- }
-
- return false;
- }
-}
diff --git a/src/com/android/settings/LanguageSettings.java b/src/com/android/settings/LanguageSettings.java
index dd447be2fd6..cbab3901981 100644
--- a/src/com/android/settings/LanguageSettings.java
+++ b/src/com/android/settings/LanguageSettings.java
@@ -16,8 +16,12 @@
package com.android.settings;
+import android.app.AlertDialog;
+import android.app.Dialog;
import android.content.Context;
+import android.content.DialogInterface;
import android.content.Intent;
+import android.content.pm.ApplicationInfo;
import android.content.res.Configuration;
import android.os.Bundle;
import android.os.Environment;
@@ -29,6 +33,7 @@ import android.preference.PreferenceGroup;
import android.preference.PreferenceScreen;
import android.provider.Settings;
import android.text.TextUtils;
+import android.view.View.OnClickListener;
import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodManager;
@@ -74,12 +79,12 @@ public class LanguageSettings extends PreferenceActivity {
mHaveHardKeyboard = true;
}
mCheckboxes = new ArrayList();
- mRootDirectory = Environment.getRootDirectory().getAbsolutePath();
onCreateIMM();
}
private boolean isSystemIme(InputMethodInfo property) {
- return property.getServiceInfo().applicationInfo.sourceDir.startsWith(mRootDirectory);
+ return (property.getServiceInfo().applicationInfo.flags
+ & ApplicationInfo.FLAG_SYSTEM) != 0;
}
private void onCreateIMM() {
@@ -161,8 +166,6 @@ public class LanguageSettings extends PreferenceActivity {
StringBuilder builder = new StringBuilder(256);
- boolean haveLastInputMethod = false;
-
int firstEnabled = -1;
int N = mInputMethodProperties.size();
for (int i = 0; i < N; ++i) {
@@ -178,7 +181,6 @@ public class LanguageSettings extends PreferenceActivity {
if (firstEnabled < 0) {
firstEnabled = i;
}
- if (hasIt) haveLastInputMethod = true;
} else if (hasIt) {
mLastInputMethodId = mLastTickedInputMethodId;
}
@@ -196,7 +198,8 @@ public class LanguageSettings extends PreferenceActivity {
Settings.Secure.putString(getContentResolver(),
Settings.Secure.ENABLED_INPUT_METHODS, builder.toString());
Settings.Secure.putString(getContentResolver(),
- Settings.Secure.DEFAULT_INPUT_METHOD, mLastInputMethodId);
+ Settings.Secure.DEFAULT_INPUT_METHOD,
+ mLastInputMethodId != null ? mLastInputMethodId : "");
}
@Override
@@ -210,10 +213,49 @@ public class LanguageSettings extends PreferenceActivity {
}
if (preference instanceof CheckBoxPreference) {
- CheckBoxPreference chkPref = (CheckBoxPreference) preference;
- String id = getInputMethodIdFromKey(chkPref.getKey());
+ final CheckBoxPreference chkPref = (CheckBoxPreference) preference;
+ final String id = getInputMethodIdFromKey(chkPref.getKey());
if (chkPref.isChecked()) {
- mLastTickedInputMethodId = id;
+ InputMethodInfo selImi = null;
+ final int N = mInputMethodProperties.size();
+ for (int i=0; i newList = getInstalledApps(FILTER_APPS_ALL);
- int oldCount = mAppPropCache.size();
- boolean idxArr[] = new boolean[oldCount];
- for ( int i = 0; i < oldCount; i++) {
- idxArr[i] = false;
- }
-
- if (newList != null) {
- for (ApplicationInfo app : newList) {
- AppInfo aInfo = mAppPropCache.get(app.packageName);
- if ( aInfo == null) {
- // New package. post an ADD_PKG message
- if(localLOGV) Log.i(TAG, "Adding pkg: "+app.packageName);
- updatePackageList(Intent.ACTION_PACKAGE_ADDED, app.packageName);
- } else {
- idxArr[aInfo.index] = true;
- }
- }
- Set keyList = mAppPropCache.keySet();
- for (String key : keyList) {
- AppInfo aInfo = mAppPropCache.get(key);
- int idx = aInfo.index;
- if (!idxArr[idx]) {
- String pkg = aInfo.pkgName;
- if(localLOGV) Log.i(TAG, "Deleting pkg: " + pkg);
- updatePackageList(Intent.ACTION_PACKAGE_REMOVED, pkg);
- }
- }
- }
+ updateAppList(newList);
}
// Retrieve the package list and init some structures
initAppList(mFilterApps);
@@ -294,61 +273,13 @@ public class ManageApplications extends ListActivity implements
if(ps == null) {
Log.i(TAG, "Invalid package stats for package:"+pkgName);
} else {
- int pkgId = mAppInfoAdapter.getIndex(pkgName);
- if(mComputeIndex != pkgId) {
- //spurious call from stale observer
- Log.w(TAG, "Stale call back from PkgSizeObserver");
- break;
- }
mAppInfoAdapter.updateAppSize(pkgName, ps);
}
- mComputeIndex++;
- if (mComputeIndex < mAppInfoAdapter.getCount()) {
- // initiate compute package size for next pkg in list
- mObserver.invokeGetSizeInfo(mAppInfoAdapter.getApplicationInfo(
- mComputeIndex),
- COMPUTE_PKG_SIZE_DONE);
- } else {
- // check for added/removed packages
- Set keys = mAddRemoveMap.keySet();
- Iterator iter = keys.iterator();
- List removeList = new ArrayList();
- boolean added = false;
- boolean removed = false;
- while (iter.hasNext()) {
- String key = iter.next();
- if (mAddRemoveMap.get(key) == Boolean.TRUE) {
- // add
- try {
- info = mPm.getApplicationInfo(key, 0);
- mAppInfoAdapter.addApplicationInfo(info);
- added = true;
- } catch (NameNotFoundException e) {
- Log.w(TAG, "Invalid added package:"+key+" Ignoring entry");
- }
- } else {
- // remove
- removeList.add(key);
- removed = true;
- }
- }
- // remove uninstalled packages from list
- if (removed) {
- mAppInfoAdapter.removeFromList(removeList);
- }
- // handle newly installed packages
- if (added) {
- mObserver.invokeGetSizeInfo(mAppInfoAdapter.getApplicationInfo(
- mComputeIndex),
- COMPUTE_PKG_SIZE_DONE);
- } else {
- // end computation here
- mComputeSizes = true;
- mFirst = true;
- mAppInfoAdapter.sortList(mSortOrder);
- mHandler.sendEmptyMessage(NEXT_LOAD_STEP);
- }
- }
+ break;
+ case COMPUTE_END :
+ mComputeSizes = true;
+ mFirst = true;
+ mHandler.sendEmptyMessage(NEXT_LOAD_STEP);
break;
case REMOVE_PKG:
if(localLOGV) Log.i(TAG, "Message REMOVE_PKG");
@@ -381,8 +312,7 @@ public class ManageApplications extends ListActivity implements
} else if(menuOption != mFilterApps) {
// Option to filter list
mFilterApps = menuOption;
- boolean ret = mAppInfoAdapter.resetAppList(mFilterApps,
- getInstalledApps(mFilterApps));
+ boolean ret = mAppInfoAdapter.resetAppList(mFilterApps);
if(!ret) {
// Reset cache
mAppPropCache = null;
@@ -398,7 +328,7 @@ public class ManageApplications extends ListActivity implements
Log.w(TAG, "Ignoring message:ADD_PKG_START for null pkgName");
break;
}
- if (!mComputeSizes) {
+ if (!mComputeSizes || !mLoadLabels) {
Boolean currB = mAddRemoveMap.get(pkgName);
if (currB == null || (currB.equals(Boolean.FALSE))) {
mAddRemoveMap.put(pkgName, Boolean.TRUE);
@@ -406,11 +336,11 @@ public class ManageApplications extends ListActivity implements
break;
}
try {
- info = mPm.getApplicationInfo(pkgName, 0);
- } catch (NameNotFoundException e) {
- Log.w(TAG, "Couldnt find application info for:"+pkgName);
- break;
- }
+ info = mPm.getApplicationInfo(pkgName, 0);
+ } catch (NameNotFoundException e) {
+ Log.w(TAG, "Couldnt find application info for:"+pkgName);
+ break;
+ }
mObserver.invokeGetSizeInfo(info, ADD_PKG_DONE);
break;
case ADD_PKG_DONE:
@@ -422,19 +352,33 @@ public class ManageApplications extends ListActivity implements
ps = data.getParcelable(ATTR_APP_PKG_STATS);
mAppInfoAdapter.addToList(pkgName, ps);
break;
- case REFRESH_ICONS:
- Map iconMap = (Map) msg.obj;
- if(iconMap == null) {
- Log.w(TAG, "Error loading icons for applications");
+ case REFRESH_APP_RESOURCE:
+ AppInfo aInfo = (AppInfo) msg.obj;
+ if(aInfo == null) {
+ Log.w(TAG, "Error loading resources");
} else {
- mAppInfoAdapter.updateAppsResourceInfo(iconMap);
+ mAppInfoAdapter.updateAppsResourceInfo(aInfo);
}
+ break;
+ case REFRESH_DONE:
mLoadLabels = true;
mHandler.sendEmptyMessage(NEXT_LOAD_STEP);
break;
case NEXT_LOAD_STEP:
if (mComputeSizes && mLoadLabels) {
doneLoadingData();
+ // Check for added/removed packages
+ Set keys = mAddRemoveMap.keySet();
+ for (String key : keys) {
+ if (mAddRemoveMap.get(key) == Boolean.TRUE) {
+ // Add the package
+ updatePackageList(Intent.ACTION_PACKAGE_ADDED, key);
+ } else {
+ // Remove the package
+ updatePackageList(Intent.ACTION_PACKAGE_REMOVED, key);
+ }
+ }
+ mAddRemoveMap.clear();
} else if (!mComputeSizes && !mLoadLabels) {
// Either load the package labels or initiate get size info
if (mSizesFirst) {
@@ -446,12 +390,13 @@ public class ManageApplications extends ListActivity implements
// Create list view from the adapter here. Wait till the sort order
// of list is defined. its either by label or by size. so atleast one of the
// first steps should be complete before filling the list
+ mAppInfoAdapter.sortBaseList(mSortOrder);
if (mJustCreated) {
// Set the adapter here.
mJustCreated = false;
mListView.setAdapter(mAppInfoAdapter);
dismissLoadingMsg();
- }
+ }
if (!mComputeSizes) {
initComputeSizes();
} else if (!mLoadLabels) {
@@ -465,7 +410,130 @@ public class ManageApplications extends ListActivity implements
}
};
+ class SizeObserver extends IPackageStatsObserver.Stub {
+ private int mMsgId;
+ private CountDownLatch mCount;
+
+ SizeObserver(int msgId) {
+ mMsgId = msgId;
+ }
+
+ public void invokeGetSize(String packageName, CountDownLatch count) {
+ mCount = count;
+ mPm.getPackageSizeInfo(packageName, this);
+ }
+
+ public void onGetStatsCompleted(PackageStats pStats, boolean pSucceeded) {
+ AppInfo appInfo = null;
+ Bundle data = new Bundle();
+ data.putString(ATTR_PKG_NAME, pStats.packageName);
+ if(pSucceeded && pStats != null) {
+ if (localLOGV) Log.i(TAG, "onGetStatsCompleted::"+pStats.packageName+", ("+
+ pStats.cacheSize+","+
+ pStats.codeSize+", "+pStats.dataSize);
+ data.putParcelable(ATTR_APP_PKG_STATS, pStats);
+ } else {
+ Log.w(TAG, "Invalid package stats from PackageManager");
+ }
+ //post message to Handler
+ Message msg = mHandler.obtainMessage(mMsgId, data);
+ msg.setData(data);
+ mHandler.sendMessage(msg);
+ mCount.countDown();
+ }
+ }
+
+ class TaskRunner extends Thread {
+ private List mPkgList;
+ private SizeObserver mSizeObserver;
+ private static final int END_MSG = COMPUTE_END;
+ private static final int mMsgId = COMPUTE_PKG_SIZE_DONE;
+ volatile boolean abort = false;
+
+ TaskRunner(List appList) {
+ mPkgList = appList;
+ mSizeObserver = new SizeObserver(mMsgId);
+ start();
+ }
+
+ public void setAbort() {
+ abort = true;
+ }
+
+ public void run() {
+ long startTime;
+ if (DEBUG_SIZE || DEBUG_TIME) {
+ startTime = SystemClock.elapsedRealtime();
+ }
+ int size = mPkgList.size();
+ for (int i = 0; i < size; i++) {
+ if (abort) {
+ // Exit if abort has been set.
+ break;
+ }
+ CountDownLatch count = new CountDownLatch(1);
+ String packageName = mPkgList.get(i).packageName;
+ long startPkgTime;
+ if (DEBUG_SIZE) {
+ startPkgTime = SystemClock.elapsedRealtime();
+ }
+ mSizeObserver.invokeGetSize(packageName, count);
+ try {
+ count.await();
+ } catch (InterruptedException e) {
+ Log.i(TAG, "Failed computing size for pkg : "+packageName);
+ }
+ if (DEBUG_SIZE) Log.i(TAG, "Took "+(SystemClock.elapsedRealtime() - startPkgTime) +
+ " ms to compute size for pkg : "+packageName);
+ }
+ if (DEBUG_SIZE || DEBUG_TIME) Log.i(TAG, "Took "+ (SystemClock.elapsedRealtime() - startTime)+ " ms to compute resources " );
+ mHandler.sendEmptyMessage(END_MSG);
+ }
+ }
+ /*
+ * This method compares the current cache against a new list of
+ * installed applications and tries to update the list with add or remove
+ * messages.
+ */
+ private boolean updateAppList(List newList) {
+ if ((newList == null) || (mAppPropCache == null)) {
+ return false;
+ }
+ Set existingList = new HashSet();
+ boolean ret = false;
+ // Loop over new list and find out common elements between old and new lists
+ for (ApplicationInfo info : newList) {
+ String pkgName = info.packageName;
+ AppInfo aInfo = mAppPropCache.get(pkgName);
+ if (aInfo != null) {
+ existingList.add(pkgName);
+ } else {
+ // New package. update info by refreshing
+ if (localLOGV) Log.i(TAG, "New pkg :"+pkgName+" installed when paused");
+ updatePackageList(Intent.ACTION_PACKAGE_ADDED, pkgName);
+ ret = true;
+ }
+ }
+ // Loop over old list and figure out state entries
+ List deletedList = null;
+ Set staleList = mAppPropCache.keySet();
+ for (String pkgName : staleList) {
+ if (!existingList.contains(pkgName)) {
+ if (localLOGV) Log.i(TAG, "Pkg :"+pkgName+" deleted when paused");
+ if (deletedList == null) {
+ deletedList = new ArrayList();
+ deletedList.add(pkgName);
+ }
+ ret = true;
+ }
+ }
+ // Delete right away
+ if (deletedList != null) {
+ mAppInfoAdapter.removeFromList(deletedList);
+ }
+ return ret;
+ }
private void doneLoadingData() {
setProgressBarIndeterminateVisibility(false);
@@ -524,44 +592,101 @@ public class ManageApplications extends ListActivity implements
}
}
+ /*
+ * Utility method used to figure out list of apps based on filterOption
+ * If the framework supports an additional flag to indicate running apps
+ * we can get away with some code here.
+ */
+ List getFilteredApps(List pAppList, int filterOption) {
+ List retList = new ArrayList();
+ if(pAppList == null) {
+ return retList;
+ }
+ if (filterOption == FILTER_APPS_THIRD_PARTY) {
+ List appList =new ArrayList ();
+ for (ApplicationInfo appInfo : pAppList) {
+ boolean flag = false;
+ if ((appInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) {
+ // Updated system app
+ flag = true;
+ } else if ((appInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
+ // Non-system app
+ flag = true;
+ }
+ if (flag) {
+ appList.add(appInfo);
+ }
+ }
+ return appList;
+ } else if (filterOption == FILTER_APPS_RUNNING) {
+ List appList =new ArrayList ();
+ List procList = getRunningAppProcessesList();
+ if ((procList == null) || (procList.size() == 0)) {
+ return appList;
+ }
+ // Retrieve running processes from ActivityManager
+ HashMap runningMap =
+ new HashMap();
+ for (ActivityManager.RunningAppProcessInfo appProcInfo : procList) {
+ if ((appProcInfo != null) && (appProcInfo.pkgList != null)){
+ int size = appProcInfo.pkgList.length;
+ for (int i = 0; i < size; i++) {
+ runningMap.put(appProcInfo.pkgList[i], appProcInfo);
+ }
+ }
+ }
+ // Query list to find running processes in current list
+ for (ApplicationInfo appInfo : pAppList) {
+ if (runningMap.get(appInfo.packageName) != null) {
+ appList.add(appInfo);
+ }
+ }
+ return appList;
+ } else {
+ return pAppList;
+ }
+ }
+
private List getRunningAppProcessesList() {
ActivityManager am = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
return am.getRunningAppProcesses();
}
- // some initialization code used when kicking off the size computation
private void initAppList(int filterOption) {
- // Initialize lists
- List appList = getInstalledApps(filterOption);
- initAppList(appList, filterOption);
+ initAppList(null, filterOption);
}
// some initialization code used when kicking off the size computation
private void initAppList(List appList, int filterOption) {
setProgressBarIndeterminateVisibility(true);
- mComputeIndex = 0;
mComputeSizes = false;
mLoadLabels = false;
// Initialize lists
mAddRemoveMap = new TreeMap();
- mAppInfoAdapter.resetAppList(filterOption, appList);
+ mAppInfoAdapter.initMapFromList(appList, filterOption);
}
// Utility method to start a thread to read application labels and icons
private void initResourceThread() {
- //load resources now
- if(mResourceThread.isAlive()) {
- mResourceThread.interrupt();
+ if ((mResourceThread != null) && mResourceThread.isAlive()) {
+ mResourceThread.setAbort();
+ }
+ mResourceThread = new ResourceLoaderThread();
+ List appList = mAppInfoAdapter.getBaseAppList();
+ if ((appList != null) && (appList.size()) > 0) {
+ mResourceThread.loadAllResources(appList);
}
- mResourceThread.loadAllResources(mAppInfoAdapter.getAppList());
}
private void initComputeSizes() {
- // initiate compute pkg sizes
+ // Initiate compute package sizes
if (localLOGV) Log.i(TAG, "Initiating compute sizes for first time");
- if (mAppInfoAdapter.getCount() > 0) {
- mObserver.invokeGetSizeInfo(mAppInfoAdapter.getApplicationInfo(0),
- COMPUTE_PKG_SIZE_DONE);
+ if ((mSizeComputor != null) && (mSizeComputor.isAlive())) {
+ mSizeComputor.setAbort();
+ }
+ List appList = mAppInfoAdapter.getBaseAppList();
+ if ((appList != null) && (appList.size()) > 0) {
+ mSizeComputor = new TaskRunner(appList);
} else {
mComputeSizes = true;
}
@@ -591,27 +716,55 @@ public class ManageApplications extends ListActivity implements
class ResourceLoaderThread extends Thread {
List mAppList;
+ volatile boolean abort = false;
+ public void setAbort() {
+ abort = true;
+ }
void loadAllResources(List appList) {
mAppList = appList;
start();
}
public void run() {
- Map iconMap = new HashMap();
- if(mAppList == null || mAppList.size() <= 0) {
+ long start;
+ if (DEBUG_TIME) {
+ start = SystemClock.elapsedRealtime();
+ }
+ int imax;
+ if(mAppList == null || (imax = mAppList.size()) <= 0) {
Log.w(TAG, "Empty or null application list");
} else {
- for (ApplicationInfo appInfo : mAppList) {
+ for (int i = 0; i < imax; i++) {
+ if (abort) {
+ return;
+ }
+ ApplicationInfo appInfo = mAppList.get(i);
CharSequence appName = appInfo.loadLabel(mPm);
- Drawable appIcon = appInfo.loadIcon(mPm);
- iconMap.put(appInfo.packageName,
- new AppInfo(appInfo.packageName, appName, appIcon));
+ Message msg = mHandler.obtainMessage(REFRESH_APP_RESOURCE);
+ msg.obj = new AppInfo(appInfo.packageName, appName, null);
+ mHandler.sendMessage(msg);
}
+ Message doneMsg = mHandler.obtainMessage(REFRESH_DONE);
+ mHandler.sendMessage(doneMsg);
+ if (DEBUG_TIME) Log.i(TAG, "Took "+(SystemClock.elapsedRealtime()-start)+" ms to load app labels");
+ long startIcons;
+ if (DEBUG_TIME) {
+ startIcons = SystemClock.elapsedRealtime();
+ }
+ for (int i = (imax-1); i >= 0; i--) {
+ if (abort) {
+ return;
+ }
+ ApplicationInfo appInfo = mAppList.get(i);
+ Drawable appIcon = appInfo.loadIcon(mPm);
+ Message msg = mHandler.obtainMessage(REFRESH_APP_RESOURCE);
+ msg.obj = new AppInfo(appInfo.packageName, null, appIcon);
+ mHandler.sendMessage(msg);
+ }
+ if (DEBUG_TIME) Log.i(TAG, "Took "+(SystemClock.elapsedRealtime()-startIcons)+" ms to load app icons");
}
- Message msg = mHandler.obtainMessage(REFRESH_ICONS);
- msg.obj = iconMap;
- mHandler.sendMessage(msg);
+ if (DEBUG_TIME) Log.i(TAG, "Took "+(SystemClock.elapsedRealtime()-start)+" ms to load app resources");
}
}
@@ -625,12 +778,18 @@ public class ManageApplications extends ListActivity implements
public Drawable appIcon;
public CharSequence appSize;
public PackageStats appStats;
-
- public void refreshIcon(AppInfo pInfo) {
- appName = pInfo.appName;
- appIcon = pInfo.appIcon;
- }
+ public void refreshIcon(AppInfo pInfo) {
+ if (pInfo == null) {
+ return;
+ }
+ if (pInfo.appName != null) {
+ appName = pInfo.appName;
+ }
+ if (pInfo.appIcon != null) {
+ appIcon = pInfo.appIcon;
+ }
+ }
public AppInfo(String pName, CharSequence aName, Drawable aIcon) {
index = -1;
pkgName = pName;
@@ -700,6 +859,7 @@ public class ManageApplications extends ListActivity implements
*/
class AppInfoAdapter extends BaseAdapter {
private Map mAppPropMap;
+ private List mAppList;
private List mAppLocalList;
ApplicationInfo.DisplayNameComparator mAlphaComparator;
AppInfoComparator mSizeComparator;
@@ -710,34 +870,51 @@ public class ManageApplications extends ListActivity implements
}
return mAppPropCache.get(packageName);
}
-
- public AppInfoAdapter(Context c, List appList) {
- mAppLocalList = appList;
- boolean useCache = false;
- int sortOrder = SORT_ORDER_ALPHA;
- int imax = mAppLocalList.size();
- if(mAppPropCache != null) {
- useCache = true;
- // Activity has been resumed. can use the cache to populate values initially
- mAppPropMap = mAppPropCache;
- sortOrder = mSortOrder;
+
+ // Make sure the cache or map contains entries for all elements
+ // in appList for a valid sort.
+ public void initMapFromList(List appList, int filterOption) {
+ if (appList == null) {
+ // Just refresh the list
+ appList = mAppList;
+ } else {
+ mAppList = appList;
}
- sortAppList(sortOrder);
- // Recreate property map
- mAppPropMap = new TreeMap();
+ if (mAppPropCache != null) {
+ // Retain previous sort order
+ int sortOrder = mSortOrder;
+ mAppPropMap = mAppPropCache;
+ // TODO is this required?
+ sortAppList(mAppList, sortOrder);
+ } else {
+ // Recreate property map
+ mAppPropMap = new TreeMap();
+ }
+ // Re init the comparators
+ mAlphaComparator = null;
+ mSizeComparator = null;
+
+ mAppLocalList = getFilteredApps(appList, filterOption);
+ int imax = appList.size();
for (int i = 0; i < imax; i++) {
- ApplicationInfo info = mAppLocalList.get(i);
- AppInfo aInfo = getFromCache(info.packageName);
+ ApplicationInfo info = appList.get(i);
+ AppInfo aInfo = mAppPropMap.get(info.packageName);
if(aInfo == null){
aInfo = new AppInfo(info.packageName, i,
- info.packageName, mDefaultAppIcon, null);
+ info.packageName, mDefaultAppIcon, null);
+ if (localLOGV) Log.i(TAG, "Creating entry pkg:"+info.packageName+" to map");
} else {
aInfo.index = i;
+ if (localLOGV) Log.i(TAG, "Adding pkg:"+info.packageName+" to map");
}
mAppPropMap.put(info.packageName, aInfo);
}
}
+ public AppInfoAdapter(Context c, List appList) {
+ mAppList = appList;
+ }
+
public int getCount() {
return mAppLocalList.size();
}
@@ -772,14 +949,6 @@ public class ManageApplications extends ListActivity implements
}
return mAppLocalList.get(position);
}
-
- public void addApplicationInfo(ApplicationInfo info) {
- if(info == null) {
- Log.w(TAG, "Ignoring null add in List Adapter");
- return;
- }
- mAppLocalList.add(info);
- }
public long getItemId(int position) {
int imax = mAppLocalList.size();
@@ -790,8 +959,8 @@ public class ManageApplications extends ListActivity implements
return mAppPropMap.get(mAppLocalList.get(position).packageName).index;
}
- public List getAppList() {
- return mAppLocalList;
+ public List getBaseAppList() {
+ return mAppList;
}
public View getView(int position, View convertView, ViewGroup parent) {
@@ -843,33 +1012,46 @@ public class ManageApplications extends ListActivity implements
private void adjustIndex() {
int imax = mAppLocalList.size();
- ApplicationInfo info;
for (int i = 0; i < imax; i++) {
- info = mAppLocalList.get(i);
+ ApplicationInfo info = mAppLocalList.get(i);
mAppPropMap.get(info.packageName).index = i;
}
}
- public void sortAppList(int sortOrder) {
- Collections.sort(mAppLocalList, getAppComparator(sortOrder));
+ public void sortAppList(List appList, int sortOrder) {
+ Collections.sort(appList, getAppComparator(sortOrder));
+ }
+
+ public void sortBaseList(int sortOrder) {
+ if (localLOGV) Log.i(TAG, "Sorting base list based on sortOrder = "+sortOrder);
+ sortAppList(mAppList, sortOrder);
+ mAppLocalList = getFilteredApps(mAppList, mFilterApps);
+ adjustIndex();
}
public void sortList(int sortOrder) {
- sortAppList(sortOrder);
+ if (localLOGV) Log.i(TAG, "sortOrder = "+sortOrder);
+ sortAppList(mAppLocalList, sortOrder);
adjustIndex();
notifyDataSetChanged();
}
- public boolean resetAppList(int filterOption, List appList) {
- // Create application list based on the filter value
- mAppLocalList = appList;
+ /*
+ * Reset the application list associated with this adapter.
+ * @param filterOption Sort the list based on this value
+ * @param appList the actual application list that is used to reset
+ * @return Return a boolean value to indicate inconsistency
+ */
+ public boolean resetAppList(int filterOption) {
+ // Change application list based on filter option
+ mAppLocalList = getFilteredApps(mAppList, filterOption);
// Check for all properties in map before sorting. Populate values from cache
for(ApplicationInfo applicationInfo : mAppLocalList) {
AppInfo appInfo = mAppPropMap.get(applicationInfo.packageName);
if(appInfo == null) {
AppInfo rInfo = getFromCache(applicationInfo.packageName);
if(rInfo == null) {
- // Need to load resources again. Inconsistency somewhere
+ // Need to load resources again. Inconsistency somewhere
return false;
}
mAppPropMap.put(applicationInfo.packageName, rInfo);
@@ -898,59 +1080,40 @@ public class ManageApplications extends ListActivity implements
}
return mSizeComparator;
}
-
- /*
- * This method updates resource information in the package map.
- *
- * @param iconMap a map of package names and attributes
- * @return A boolean value to indicate if the property map has to be
- * refreshed completely
- */
- public boolean updateAppsResourceInfo(Map iconMap) {
- if(iconMap == null) {
- Log.w(TAG, "Null iconMap when refreshing icon in List Adapter");
+
+ public boolean updateAppsResourceInfo(AppInfo pInfo) {
+ if((pInfo == null) || (pInfo.pkgName == null)) {
+ Log.w(TAG, "Null info when refreshing icon in List Adapter");
+ return false;
+ }
+ AppInfo aInfo = mAppPropMap.get(pInfo.pkgName);
+ if (aInfo != null) {
+ aInfo.refreshIcon(pInfo);
+ notifyDataSetChanged();
return true;
}
- boolean changed = false;
- for (ApplicationInfo info : mAppLocalList) {
- AppInfo pInfo = iconMap.get(info.packageName);
- if(pInfo != null) {
- AppInfo aInfo = mAppPropMap.get(info.packageName);
- if (aInfo != null) {
- aInfo.refreshIcon(pInfo);
- } else {
- return false;
- }
- changed = true;
- }
- }
- if(changed) {
- notifyDataSetChanged();
- }
- return true;
+ return false;
}
private boolean shouldBeInList(int filterOption, ApplicationInfo info) {
// Match filter here
- boolean addToCurrList = false;
if (filterOption == FILTER_APPS_RUNNING) {
List runningList = getInstalledApps(FILTER_APPS_RUNNING);
for (ApplicationInfo running : runningList) {
if (running.packageName.equalsIgnoreCase(info.packageName)) {
- addToCurrList = true;
- break;
+ return true;
}
}
} else if (filterOption == FILTER_APPS_THIRD_PARTY) {
if ((info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
- addToCurrList = true;
+ return true;
} else if ((info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) {
- addToCurrList = true;
+ return true;
}
} else {
return true;
}
- return addToCurrList;
+ return false;
}
/*
@@ -961,20 +1124,15 @@ public class ManageApplications extends ListActivity implements
* @param ps PackageStats of new package
*/
public void addToList(String pkgName, PackageStats ps) {
- if(pkgName == null) {
- Log.w(TAG, "Adding null pkg to List Adapter");
+ if((pkgName == null) || (ps == null)) {
+ if (pkgName == null) {
+ Log.w(TAG, "Adding null pkg to List Adapter");
+ } else {
+ Log.w(TAG, "Adding pkg : "+pkgName+" with invalid PackageStats");
+ }
return;
}
boolean notInList = true;
- int newIdx = getIndex(pkgName);
- if (newIdx != -1) {
- notInList = false;
- if (mAppPropMap.get(pkgName) != null) {
- // weird. just ignore entry
- Log.i(TAG, "Package:"+pkgName+" already added");
- return;
- }
- }
// Get ApplicationInfo
ApplicationInfo info = null;
try {
@@ -988,14 +1146,17 @@ public class ManageApplications extends ListActivity implements
Log.i(TAG, "Null ApplicationInfo for package:"+pkgName);
return;
}
- // Add entry to map
- mAppPropMap.put(pkgName, new AppInfo(pkgName, newIdx,
+ // Add entry to local list
+ mAppList.add(info);
+ // Add entry to map. Note that the index gets adjusted later on based on
+ // whether the newly added package is part of displayed list
+ mAppPropMap.put(pkgName, new AppInfo(pkgName, -1,
info.loadLabel(mPm), info.loadIcon(mPm), ps));
// Add to list
if (notInList && (shouldBeInList(mFilterApps, info))) {
// Binary search returns a negative index (ie -index) of the position where
// this might be inserted.
- newIdx = Collections.binarySearch(mAppLocalList, info,
+ int newIdx = Collections.binarySearch(mAppLocalList, info,
getAppComparator(mSortOrder));
if(newIdx >= 0) {
Log.i(TAG, "Strange. Package:"+pkgName+" is not new");
@@ -1010,11 +1171,30 @@ public class ManageApplications extends ListActivity implements
}
}
+ private void removePkgListBase(List pkgNames) {
+ for (String pkg : pkgNames) {
+ removePkgBase(pkg);
+ }
+ }
+
+ private void removePkgBase(String pkgName) {
+ int imax = mAppList.size();
+ for (int i = 0; i < imax; i++) {
+ ApplicationInfo app = mAppList.get(i);
+ if (app.packageName.equalsIgnoreCase(pkgName)) {
+ if (localLOGV) Log.i(TAG, "Removing pkg: "+pkgName+" from base list");
+ mAppList.remove(i);
+ return;
+ }
+ }
+ }
+
public void removeFromList(List pkgNames) {
if(pkgNames == null) {
Log.w(TAG, "Removing null pkg list from List Adapter");
return;
}
+ removePkgListBase(pkgNames);
int imax = mAppLocalList.size();
boolean found = false;
ApplicationInfo info;
@@ -1042,7 +1222,7 @@ public class ManageApplications extends ListActivity implements
}
// Sort idxArr
Arrays.sort(idxArr);
- // remove the packages based on decending indices
+ // remove the packages based on descending indices
for (k = kmax-1; k >= 0; k--) {
// Check if package has been found in the list of existing apps first
if(idxArr[k] == -1) {
@@ -1051,13 +1231,13 @@ public class ManageApplications extends ListActivity implements
info = mAppLocalList.get(idxArr[k]);
mAppLocalList.remove(idxArr[k]);
mAppPropMap.remove(info.packageName);
- if (localLOGV) Log.i(TAG, "Removed pkg:"+info.packageName+ " list");
+ if (localLOGV) Log.i(TAG, "Removed pkg:"+info.packageName+ " from display list");
}
if (found) {
adjustIndex();
notifyDataSetChanged();
}
- }
+ }
public void updateAppSize(String pkgName, PackageStats ps) {
if(pkgName == null) {
@@ -1098,6 +1278,10 @@ public class ManageApplications extends ListActivity implements
mHandler.removeMessages(REORDER_LIST);
mHandler.removeMessages(ADD_PKG_START);
mHandler.removeMessages(ADD_PKG_DONE);
+ mHandler.removeMessages(REFRESH_APP_RESOURCE);
+ mHandler.removeMessages(REFRESH_DONE);
+ mHandler.removeMessages(NEXT_LOAD_STEP);
+ mHandler.removeMessages(COMPUTE_END);
}
private void sendMessageToHandler(int msgId, int arg1) {
@@ -1201,8 +1385,8 @@ public class ManageApplications extends ListActivity implements
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- Intent lIntent = getIntent();
- String action = lIntent.getAction();
+ Intent intent = getIntent();
+ String action = intent.getAction();
if (action.equals(Intent.ACTION_MANAGE_PACKAGE_STORAGE)) {
mSortOrder = SORT_ORDER_SIZE;
mSizesFirst = true;
@@ -1213,6 +1397,7 @@ public class ManageApplications extends ListActivity implements
requestWindowFeature(Window.FEATURE_PROGRESS);
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.compute_sizes);
+ showLoadingMsg();
mDefaultAppIcon =Resources.getSystem().getDrawable(
com.android.internal.R.drawable.sym_def_app_icon);
mInvalidSizeStr = getText(R.string.invalid_size_value);
@@ -1231,7 +1416,6 @@ public class ManageApplications extends ListActivity implements
lv.setItemsCanFocus(true);
lv.setOnItemClickListener(this);
mListView = lv;
- showLoadingMsg();
}
@Override
@@ -1249,28 +1433,38 @@ public class ManageApplications extends ListActivity implements
private void showLoadingMsg() {
- showDialog(DLG_LOADING);
+ if (DEBUG_TIME) {
+ mLoadTimeStart = SystemClock.elapsedRealtime();
+ }
+ showDialog(DLG_LOADING);
if(localLOGV) Log.i(TAG, "Displaying Loading message");
}
private void dismissLoadingMsg() {
if(localLOGV) Log.i(TAG, "Dismissing Loading message");
dismissDialog(DLG_LOADING);
+ if (DEBUG_TIME) Log.i(TAG, "Displayed loading message for "+
+ (SystemClock.elapsedRealtime() - mLoadTimeStart));
}
@Override
public void onStart() {
super.onStart();
- // Create a thread to load resources
- mResourceThread = new ResourceLoaderThread();
- sendMessageToHandler(INIT_PKG_INFO);
// register receiver
mReceiver.registerReceiver();
+ sendMessageToHandler(INIT_PKG_INFO);
}
@Override
public void onStop() {
super.onStop();
+ // Stop the background threads
+ if (mResourceThread != null) {
+ mResourceThread.setAbort();
+ }
+ if (mSizeComputor != null) {
+ mSizeComputor.setAbort();
+ }
// clear all messages related to application list
clearMessagesInHandler();
// register receiver here
diff --git a/src/com/android/settings/SoundAndDisplaySettings.java b/src/com/android/settings/SoundAndDisplaySettings.java
index 8905b859fd7..e8cb10f98d9 100644
--- a/src/com/android/settings/SoundAndDisplaySettings.java
+++ b/src/com/android/settings/SoundAndDisplaySettings.java
@@ -162,6 +162,13 @@ public class SoundAndDisplaySettings extends PreferenceActivity implements
mVibrate.setChecked(vibrateSetting);
}
+ int silentModeStreams = Settings.System.getInt(getContentResolver(),
+ Settings.System.MODE_RINGER_STREAMS_AFFECTED, 0);
+ boolean isAlarmInclSilentMode = (silentModeStreams & (1 << AudioManager.STREAM_ALARM)) != 0;
+ mSilent.setSummary(isAlarmInclSilentMode ?
+ R.string.silent_mode_incl_alarm_summary :
+ R.string.silent_mode_summary);
+
boolean animations = true;
try {
mAnimationScales = mWindowManager.getAnimationScales();
diff --git a/src/com/android/settings/battery_history/BatteryHistory.java b/src/com/android/settings/battery_history/BatteryHistory.java
index dcf6cbf78b1..ad6479aff1e 100644
--- a/src/com/android/settings/battery_history/BatteryHistory.java
+++ b/src/com/android/settings/battery_history/BatteryHistory.java
@@ -18,6 +18,7 @@ package com.android.settings.battery_history;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.Formatter;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -73,7 +74,7 @@ public class BatteryHistory extends Activity implements OnClickListener, OnItemS
private BatteryStats mStats;
private int mWhich = BatteryStats.STATS_UNPLUGGED;
- private int mType = CPU_USAGE;
+ private int mType = MISC_USAGE;
private GraphableButton[] mButtons;
IBatteryStats mBatteryInfo;
@@ -401,6 +402,7 @@ public class BatteryHistory extends Activity implements OnClickListener, OnItemS
class MiscUsage extends Graphable {
int mInfoLabelRes;
+ String mInfoLabel;
double[] mUsage;
double mTotalRealtime;
@@ -415,6 +417,17 @@ public class BatteryHistory extends Activity implements OnClickListener, OnItemS
mTotalRealtime = totalRealtime;
}
+ public MiscUsage(String name, String infoLabel, long value,
+ long totalRealtime) {
+ mName = name;
+
+ mInfoLabel = infoLabel;
+
+ mUsage = new double[2];
+ mUsage[0] = value;
+ mTotalRealtime = totalRealtime;
+ }
+
public String getLabel() {
return mName;
}
@@ -432,7 +445,7 @@ public class BatteryHistory extends Activity implements OnClickListener, OnItemS
}
public void getInfo(StringBuilder info) {
- info.append(getString(mInfoLabelRes));
+ info.append(mInfoLabel != null ? mInfoLabel : getString(mInfoLabelRes));
info.append(' ');
formatTime(mUsage[0], info);
info.append(" (");
@@ -656,6 +669,19 @@ public class BatteryHistory extends Activity implements OnClickListener, OnItemS
Collections.sort(mWakelockUsage);
}
+ private final StringBuilder mFormatBuilder = new StringBuilder(8);
+ private final Formatter mFormatter = new Formatter(mFormatBuilder);
+
+ private final String formatRatio(long num, long den) {
+ if (den == 0L) {
+ return "---%";
+ }
+ float perc = ((float)num) / ((float)den) * 100;
+ mFormatBuilder.setLength(0);
+ mFormatter.format("%.1f%%", perc);
+ return mFormatBuilder.toString();
+ }
+
private void processMiscUsage() {
mMiscUsage.clear();
@@ -666,7 +692,8 @@ public class BatteryHistory extends Activity implements OnClickListener, OnItemS
long time = mStats.computeBatteryUptime(SystemClock.uptimeMillis() * 1000, mWhich) / 1000;
if (time > 0) {
mMiscUsage.add(new MiscUsage(getString(
- R.string.battery_history_awake_label),
+ R.string.battery_history_awake_label)
+ + " (" + formatRatio(time, whichRealtime) + ")",
R.string.battery_history_awake,
time, whichRealtime));
}
@@ -674,7 +701,8 @@ public class BatteryHistory extends Activity implements OnClickListener, OnItemS
time = mStats.getScreenOnTime(batteryRealtime, mWhich) / 1000;
if (time > 0) {
mMiscUsage.add(new MiscUsage(getString(
- R.string.battery_history_screen_on_label),
+ R.string.battery_history_screen_on_label)
+ + " (" + formatRatio(time, whichRealtime) + ")",
R.string.battery_history_screen_on,
time, whichRealtime));
}
@@ -682,11 +710,36 @@ public class BatteryHistory extends Activity implements OnClickListener, OnItemS
time = mStats.getPhoneOnTime(batteryRealtime, mWhich) / 1000;
if (time > 0) {
mMiscUsage.add(new MiscUsage(getString(
- R.string.battery_history_phone_on_label),
+ R.string.battery_history_phone_on_label)
+ + " (" + formatRatio(time, whichRealtime) + ")",
R.string.battery_history_phone_on,
time, whichRealtime));
}
+ time = mStats.getWifiOnTime(batteryRealtime, mWhich) / 1000;
+ if (time > 0) {
+ mMiscUsage.add(new MiscUsage("Wifi On ("
+ + formatRatio(time, whichRealtime) + ")",
+ "Time spent with Wifi on:",
+ time, whichRealtime));
+ }
+
+ time = mStats.getWifiRunningTime(batteryRealtime, mWhich) / 1000;
+ if (time > 0) {
+ mMiscUsage.add(new MiscUsage("Wifi Running ("
+ + formatRatio(time, whichRealtime) + ")",
+ "Time spent with Wifi running:",
+ time, whichRealtime));
+ }
+
+ time = mStats.getBluetoothOnTime(batteryRealtime, mWhich) / 1000;
+ if (time > 0) {
+ mMiscUsage.add(new MiscUsage("Bluetooth On ("
+ + formatRatio(time, whichRealtime) + ")",
+ "Time spent with Bluetooth on:",
+ time, whichRealtime));
+ }
+
Collections.sort(mMiscUsage);
}
@@ -815,12 +868,22 @@ public class BatteryHistory extends Activity implements OnClickListener, OnItemS
setContentView(R.layout.battery_history);
+ mStats = (BatteryStats)getLastNonConfigurationInstance();
+ if (icicle != null) {
+ if (mStats == null) {
+ mStats = (BatteryStats)icicle.getParcelable("stats");
+ }
+ mType = icicle.getInt("type");
+ mWhich = icicle.getInt("which");
+ }
+
mGraphLayout = (LinearLayout) findViewById(R.id.graphLayout);
mTextLayout = (LinearLayout) findViewById(R.id.textLayout);
mDetailsText = (TextView) findViewById(R.id.detailsText);
mMessageText = (TextView) findViewById(R.id.messageText);
mTypeSpinner = (Spinner) findViewById(R.id.typeSpinner);
+ mTypeSpinner.setSelection(mType);
mTypeSpinner.setOnItemSelectedListener(this);
mWhichSpinner = (Spinner) findViewById(R.id.whichSpinner);
@@ -845,14 +908,6 @@ public class BatteryHistory extends Activity implements OnClickListener, OnItemS
mBatteryInfo = IBatteryStats.Stub.asInterface(
ServiceManager.getService("batteryinfo"));
- mStats = (BatteryStats)getLastNonConfigurationInstance();
- if (icicle != null) {
- if (mStats == null) {
- mStats = (BatteryStats)icicle.getParcelable("stats");
- }
- mType = icicle.getInt("type");
- mWhich = icicle.getInt("which");
- }
if (mStats == null) {
load();
}
diff --git a/src/com/android/settings/battery_history/GraphableButton.java b/src/com/android/settings/battery_history/GraphableButton.java
index 39028d03638..fb90a0d1ce9 100644
--- a/src/com/android/settings/battery_history/GraphableButton.java
+++ b/src/com/android/settings/battery_history/GraphableButton.java
@@ -15,11 +15,11 @@ public class GraphableButton extends Button {
static {
sPaint[0] = new Paint();
sPaint[0].setStyle(Paint.Style.FILL);
- sPaint[0].setColor(Color.BLUE);
+ sPaint[0].setColor(0xFF0080FF);
sPaint[1] = new Paint();
sPaint[1].setStyle(Paint.Style.FILL);
- sPaint[1].setColor(Color.RED);
+ sPaint[1].setColor(0xFFFF6060);
}
double[] mValues;
diff --git a/src/com/android/settings/bluetooth/BluetoothDiscoverableEnabler.java b/src/com/android/settings/bluetooth/BluetoothDiscoverableEnabler.java
index f1a2a1e409d..d458c5fdd0b 100644
--- a/src/com/android/settings/bluetooth/BluetoothDiscoverableEnabler.java
+++ b/src/com/android/settings/bluetooth/BluetoothDiscoverableEnabler.java
@@ -92,7 +92,6 @@ public class BluetoothDiscoverableEnabler implements Preference.OnPreferenceChan
}
IntentFilter filter = new IntentFilter(BluetoothIntent.SCAN_MODE_CHANGED_ACTION);
- filter.addAction(BluetoothIntent.DISABLED_ACTION);
mContext.registerReceiver(mReceiver, filter);
mCheckBoxPreference.setOnPreferenceChangeListener(this);
diff --git a/src/com/android/settings/bluetooth/BluetoothEnabler.java b/src/com/android/settings/bluetooth/BluetoothEnabler.java
index 661700fd3c5..82961b86215 100644
--- a/src/com/android/settings/bluetooth/BluetoothEnabler.java
+++ b/src/com/android/settings/bluetooth/BluetoothEnabler.java
@@ -17,8 +17,9 @@
package com.android.settings.bluetooth;
import com.android.settings.R;
-import com.android.settings.bluetooth.LocalBluetoothManager.ExtendedBluetoothState;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -70,15 +71,15 @@ public class BluetoothEnabler implements Preference.OnPreferenceChangeListener {
return;
}
- ExtendedBluetoothState state = mLocalManager.getBluetoothState();
+ int state = mLocalManager.getBluetoothState();
// This is the widget enabled state, not the preference toggled state
- mCheckBoxPreference.setEnabled(state == ExtendedBluetoothState.ENABLED ||
- state == ExtendedBluetoothState.DISABLED);
+ mCheckBoxPreference.setEnabled(state == BluetoothDevice.BLUETOOTH_STATE_ON ||
+ state == BluetoothDevice.BLUETOOTH_STATE_OFF);
// BT state is not a sticky broadcast, so set it manually
handleStateChanged(state);
mContext.registerReceiver(mReceiver,
- new IntentFilter(LocalBluetoothManager.EXTENDED_BLUETOOTH_STATE_CHANGED_ACTION));
+ new IntentFilter(BluetoothIntent.BLUETOOTH_STATE_CHANGED_ACTION));
mCheckBoxPreference.setOnPreferenceChangeListener(this);
}
@@ -106,22 +107,24 @@ public class BluetoothEnabler implements Preference.OnPreferenceChangeListener {
mLocalManager.setBluetoothEnabled(enable);
}
- private void handleStateChanged(ExtendedBluetoothState state) {
+ private void handleStateChanged(int state) {
- if (state == ExtendedBluetoothState.DISABLED || state == ExtendedBluetoothState.ENABLED) {
- mCheckBoxPreference.setChecked(state == ExtendedBluetoothState.ENABLED);
- mCheckBoxPreference
- .setSummary(state == ExtendedBluetoothState.DISABLED ? mOriginalSummary : null);
+ if (state == BluetoothDevice.BLUETOOTH_STATE_OFF ||
+ state == BluetoothDevice.BLUETOOTH_STATE_ON) {
+ mCheckBoxPreference.setChecked(state == BluetoothDevice.BLUETOOTH_STATE_ON);
+ mCheckBoxPreference.setSummary(state == BluetoothDevice.BLUETOOTH_STATE_OFF ?
+ mOriginalSummary :
+ null);
mCheckBoxPreference.setEnabled(isEnabledByDependency());
- } else if (state == ExtendedBluetoothState.ENABLING ||
- state == ExtendedBluetoothState.DISABLING) {
- mCheckBoxPreference.setSummary(state == ExtendedBluetoothState.ENABLING
+ } else if (state == BluetoothDevice.BLUETOOTH_STATE_TURNING_ON ||
+ state == BluetoothDevice.BLUETOOTH_STATE_TURNING_OFF) {
+ mCheckBoxPreference.setSummary(state == BluetoothDevice.BLUETOOTH_STATE_TURNING_ON
? R.string.wifi_starting
: R.string.wifi_stopping);
- } else if (state == ExtendedBluetoothState.UNKNOWN) {
+ } else {
mCheckBoxPreference.setChecked(false);
mCheckBoxPreference.setSummary(R.string.wifi_error);
mCheckBoxPreference.setEnabled(true);
diff --git a/src/com/android/settings/bluetooth/BluetoothEventRedirector.java b/src/com/android/settings/bluetooth/BluetoothEventRedirector.java
index 2ad5726ddc7..71b91d33a0a 100644
--- a/src/com/android/settings/bluetooth/BluetoothEventRedirector.java
+++ b/src/com/android/settings/bluetooth/BluetoothEventRedirector.java
@@ -16,8 +16,6 @@
package com.android.settings.bluetooth;
-import com.android.settings.bluetooth.LocalBluetoothManager.ExtendedBluetoothState;
-
import android.bluetooth.BluetoothA2dp;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHeadset;
@@ -50,12 +48,10 @@ public class BluetoothEventRedirector {
String action = intent.getAction();
String address = intent.getStringExtra(BluetoothIntent.ADDRESS);
- if (action.equals(BluetoothIntent.ENABLED_ACTION)) {
- mManager.setBluetoothStateInt(ExtendedBluetoothState.ENABLED);
-
- } else if (action.equals(BluetoothIntent.DISABLED_ACTION)) {
- mManager.setBluetoothStateInt(ExtendedBluetoothState.DISABLED);
-
+ if (action.equals(BluetoothIntent.BLUETOOTH_STATE_CHANGED_ACTION)) {
+ int state = intent.getIntExtra(BluetoothIntent.BLUETOOTH_STATE,
+ BluetoothError.ERROR);
+ mManager.setBluetoothStateInt(state);
} else if (action.equals(BluetoothIntent.DISCOVERY_STARTED_ACTION)) {
mManager.onScanningStateChanged(true);
@@ -86,25 +82,29 @@ public class BluetoothEventRedirector {
}
} else if (action.equals(BluetoothIntent.HEADSET_STATE_CHANGED_ACTION)) {
- mManager.getLocalDeviceManager().onProfileStateChanged(address);
-
int newState = intent.getIntExtra(BluetoothIntent.HEADSET_STATE, 0);
int oldState = intent.getIntExtra(BluetoothIntent.HEADSET_PREVIOUS_STATE, 0);
if (newState == BluetoothHeadset.STATE_DISCONNECTED &&
oldState == BluetoothHeadset.STATE_CONNECTING) {
Log.i(TAG, "Failed to connect BT headset");
}
-
- } else if (action.equals(BluetoothA2dp.SINK_STATE_CHANGED_ACTION)) {
- mManager.getLocalDeviceManager().onProfileStateChanged(address);
+ boolean transientState = !(newState == BluetoothHeadset.STATE_CONNECTED
+ || newState == BluetoothHeadset.STATE_DISCONNECTED);
+ mManager.getLocalDeviceManager().onProfileStateChanged(address,transientState);
+
+ } else if (action.equals(BluetoothA2dp.SINK_STATE_CHANGED_ACTION)) {
int newState = intent.getIntExtra(BluetoothA2dp.SINK_STATE, 0);
int oldState = intent.getIntExtra(BluetoothA2dp.SINK_PREVIOUS_STATE, 0);
if (newState == BluetoothA2dp.STATE_DISCONNECTED &&
oldState == BluetoothA2dp.STATE_CONNECTING) {
Log.i(TAG, "Failed to connect BT A2DP");
}
-
+
+ boolean transientState = !(newState == BluetoothA2dp.STATE_CONNECTED
+ || newState == BluetoothA2dp.STATE_DISCONNECTED);
+ mManager.getLocalDeviceManager().onProfileStateChanged(address, transientState);
+
} else if (action.equals(BluetoothIntent.REMOTE_DEVICE_CLASS_UPDATED_ACTION)) {
mManager.getLocalDeviceManager().onBtClassChanged(address);
@@ -120,8 +120,7 @@ public class BluetoothEventRedirector {
IntentFilter filter = new IntentFilter();
// Bluetooth on/off broadcasts
- filter.addAction(BluetoothIntent.ENABLED_ACTION);
- filter.addAction(BluetoothIntent.DISABLED_ACTION);
+ filter.addAction(BluetoothIntent.BLUETOOTH_STATE_CHANGED_ACTION);
// Discovery broadcasts
filter.addAction(BluetoothIntent.DISCOVERY_STARTED_ACTION);
diff --git a/src/com/android/settings/bluetooth/BluetoothNamePreference.java b/src/com/android/settings/bluetooth/BluetoothNamePreference.java
index 3065b26c5e5..40bab2ccae8 100644
--- a/src/com/android/settings/bluetooth/BluetoothNamePreference.java
+++ b/src/com/android/settings/bluetooth/BluetoothNamePreference.java
@@ -17,6 +17,7 @@
package com.android.settings.bluetooth;
import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothError;
import android.bluetooth.BluetoothIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -39,7 +40,14 @@ public class BluetoothNamePreference extends EditTextPreference {
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
- setSummaryToName();
+ String action = intent.getAction();
+ if (action.equals(BluetoothIntent.NAME_CHANGED_ACTION)) {
+ setSummaryToName();
+ } else if (action.equals(BluetoothIntent.BLUETOOTH_STATE_CHANGED_ACTION) &&
+ (intent.getIntExtra(BluetoothIntent.BLUETOOTH_STATE,
+ BluetoothError.ERROR) == BluetoothDevice.BLUETOOTH_STATE_ON)) {
+ setSummaryToName();
+ }
}
};
@@ -53,7 +61,7 @@ public class BluetoothNamePreference extends EditTextPreference {
public void resume() {
IntentFilter filter = new IntentFilter();
- filter.addAction(BluetoothIntent.ENABLED_ACTION);
+ filter.addAction(BluetoothIntent.BLUETOOTH_STATE_CHANGED_ACTION);
filter.addAction(BluetoothIntent.NAME_CHANGED_ACTION);
getContext().registerReceiver(mReceiver, filter);
}
diff --git a/src/com/android/settings/bluetooth/BluetoothSettings.java b/src/com/android/settings/bluetooth/BluetoothSettings.java
index 5adada3c424..e6ac5fdb3c8 100644
--- a/src/com/android/settings/bluetooth/BluetoothSettings.java
+++ b/src/com/android/settings/bluetooth/BluetoothSettings.java
@@ -18,11 +18,12 @@ package com.android.settings.bluetooth;
import com.android.settings.ProgressCategory;
import com.android.settings.R;
-import com.android.settings.bluetooth.LocalBluetoothManager.ExtendedBluetoothState;
import java.util.List;
import java.util.WeakHashMap;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -117,8 +118,8 @@ public class BluetoothSettings extends PreferenceActivity
mLocalManager.startScanning(false);
- registerReceiver(mReceiver,
- new IntentFilter(LocalBluetoothManager.EXTENDED_BLUETOOTH_STATE_CHANGED_ACTION));
+ registerReceiver(mReceiver,
+ new IntentFilter(BluetoothIntent.BLUETOOTH_STATE_CHANGED_ACTION));
mLocalManager.setForegroundActivity(this);
}
@@ -248,12 +249,12 @@ public class BluetoothSettings extends PreferenceActivity
mDeviceList.setProgress(started);
}
- private void onBluetoothStateChanged(ExtendedBluetoothState bluetoothState) {
+ private void onBluetoothStateChanged(int bluetoothState) {
// When bluetooth is enabled (and we are in the activity, which we are),
// we should start a scan
- if (bluetoothState == ExtendedBluetoothState.ENABLED) {
+ if (bluetoothState == BluetoothDevice.BLUETOOTH_STATE_ON) {
mLocalManager.startScanning(false);
- } else if (bluetoothState == ExtendedBluetoothState.DISABLED) {
+ } else if (bluetoothState == BluetoothDevice.BLUETOOTH_STATE_OFF) {
mDeviceList.setProgress(false);
}
}
diff --git a/src/com/android/settings/bluetooth/LocalBluetoothDevice.java b/src/com/android/settings/bluetooth/LocalBluetoothDevice.java
index a4885401e23..199a4225baf 100644
--- a/src/com/android/settings/bluetooth/LocalBluetoothDevice.java
+++ b/src/com/android/settings/bluetooth/LocalBluetoothDevice.java
@@ -20,22 +20,23 @@ import com.android.settings.R;
import com.android.settings.bluetooth.LocalBluetoothProfileManager.Profile;
import android.app.AlertDialog;
-import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothClass;
-import android.bluetooth.IBluetoothDeviceCallback;
+import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Resources;
-import android.os.IBinder;
-import android.os.RemoteException;
import android.text.TextUtils;
import android.util.Log;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuItem;
+import java.text.DateFormat;
import java.util.ArrayList;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.LinkedList;
import java.util.List;
/**
@@ -71,6 +72,193 @@ public class LocalBluetoothDevice implements Comparable {
*/
private boolean mIsConnectingErrorPossible;
+ // Max time to hold the work queue if we don't get or missed a response
+ // from the bt framework.
+ private static final long MAX_WAIT_TIME_FOR_FRAMEWORK = 25 * 1000;
+
+ private enum BluetoothCommand {
+ CONNECT, DISCONNECT,
+ }
+
+ class BluetoothJob {
+ final BluetoothCommand command; // CONNECT, DISCONNECT
+ final LocalBluetoothDevice device;
+ final Profile profile; // HEADSET, A2DP, etc
+ // 0 means this command was not been sent to the bt framework.
+ long timeSent;
+
+ public BluetoothJob(BluetoothCommand command,
+ LocalBluetoothDevice device, Profile profile) {
+ this.command = command;
+ this.device = device;
+ this.profile = profile;
+ this.timeSent = 0;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append(command.name());
+ sb.append(" Address:").append(device.mAddress);
+ sb.append(" Profile:").append(profile.name());
+ sb.append(" TimeSent:");
+ if (timeSent == 0) {
+ sb.append("not yet");
+ } else {
+ sb.append(DateFormat.getTimeInstance().format(new Date(timeSent)));
+ }
+ return sb.toString();
+ }
+ }
+
+ /**
+ * We want to serialize connect and disconnect calls. http://b/170538
+ * This are some headsets that may have L2CAP resource limitation. We want
+ * to limit the bt bandwidth usage.
+ *
+ * A queue to keep track of asynchronous calls to the bt framework. The
+ * first item, if exist, should be in progress i.e. went to the bt framework
+ * already, waiting for a notification to come back. The second item and
+ * beyond have not been sent to the bt framework yet.
+ */
+ private static LinkedList workQueue = new LinkedList();
+
+ private void queueCommand(BluetoothJob job) {
+ Log.d(TAG, workQueue.toString());
+ synchronized (workQueue) {
+ boolean processNow = pruneQueue(job);
+
+ // Add job to queue
+ Log.d(TAG, "Adding: " + job.toString());
+ workQueue.add(job);
+
+ // if there's nothing pending from before, send the command to bt
+ // framework immediately.
+ if (workQueue.size() == 1 || processNow) {
+ Log.d(TAG, "workQueue.size() == 1 || TimeOut -> process command now");
+ // If the failed to process, just drop it from the queue.
+ // There will be no callback to remove this from the queue.
+ processCommands();
+ }
+ }
+ }
+
+ private boolean pruneQueue(BluetoothJob job) {
+ boolean removedStaleItems = false;
+ long now = System.currentTimeMillis();
+ Iterator it = workQueue.iterator();
+ while (it.hasNext()) {
+ BluetoothJob existingJob = it.next();
+
+ // Remove any pending CONNECTS when we receive a DISCONNECT
+ if (job != null && job.command == BluetoothCommand.DISCONNECT) {
+ if (existingJob.timeSent == 0
+ && existingJob.command == BluetoothCommand.CONNECT
+ && existingJob.device.mAddress.equals(job.device.mAddress)
+ && existingJob.profile == job.profile) {
+ Log.d(TAG, "Removed because of a pending disconnect. " + existingJob);
+ it.remove();
+ continue;
+ }
+ }
+
+ // Defensive Code: Remove any job that older than a preset time.
+ // We never got a call back. It is better to have overlapping
+ // calls than to get stuck.
+ Log.d(TAG, "Age:" + (now - existingJob.timeSent));
+ if (existingJob.timeSent != 0
+ && (now - existingJob.timeSent) >= MAX_WAIT_TIME_FOR_FRAMEWORK) {
+ Log.w(TAG, "Timeout. Removing Job:" + existingJob.toString());
+ it.remove();
+ removedStaleItems = true;
+ continue;
+ }
+ }
+ return removedStaleItems;
+ }
+
+ private boolean processCommand(BluetoothJob job) {
+ boolean successful = false;
+ if (job.timeSent == 0) {
+ job.timeSent = System.currentTimeMillis();
+ switch (job.command) {
+ case CONNECT:
+ successful = connectInt(job.device, job.profile);
+ break;
+ case DISCONNECT:
+ successful = disconnectInt(job.device, job.profile);
+ break;
+ }
+
+ if (successful) {
+ Log.d(TAG, "Command sent successfully:" + job.toString());
+ } else {
+ Log.d(TAG, "Framework rejected command immediately:" + job.toString());
+ }
+
+ } else {
+ Log.d(TAG, "Job already has a sent time. Skip. " + job.toString());
+ }
+
+ return successful;
+ }
+
+ public void onProfileStateChanged() {
+ Log.d(TAG, "onProfileStateChanged:" + workQueue.toString());
+ BluetoothJob job = workQueue.peek();
+ if (job == null) {
+ Log.v(TAG, "Yikes, onProfileStateChanged called but job queue is empty. "
+ + "(Okay for device initiated actions and BluetoothA2dpService initiated "
+ + "Auto-connections)");
+ return;
+ } else if (job.device.mAddress != mAddress) {
+ // This can happen in 2 cases: 1) BT device initiated pairing and
+ // 2) disconnects of one headset that's triggered by connects of
+ // another.
+ Log.v(TAG, "onProfileStateChanged called. The addresses differ. this.mAddress="
+ + mAddress + " workQueue.head=" + job.toString());
+
+ // Check to see if we need to remove the stale items from the queue
+ if (!pruneQueue(null)) {
+ // nothing in the queue was modify. Just ignore the notification and return.
+ return;
+ }
+ } else {
+ // Remove the first item and process the next one
+ Log.d(TAG, "LocalBluetoothDevice.onProfileStateChanged() called. MAC addr matched");
+ workQueue.poll();
+ }
+
+ processCommands();
+ }
+
+ /*
+ * This method is called in 2 places:
+ * 1) queryCommand() - when someone or something want to connect or
+ * disconnect
+ * 2) onProfileStateChanged() - when the framework sends an intent
+ * notification when it finishes processing a command
+ */
+ private void processCommands() {
+ Log.d(TAG, "processCommands:" + workQueue.toString());
+ Iterator it = workQueue.iterator();
+ while (it.hasNext()) {
+ BluetoothJob job = it.next();
+ if (processCommand(job)) {
+ // Sent to bt framework. Done for now. Will remove this job
+ // from queue when we get an event
+ return;
+ } else {
+ /*
+ * If the command failed immediately, there will be no event
+ * callbacks. So delete the job immediately and move on to the
+ * next one
+ */
+ it.remove();
+ }
+ }
+ }
+
LocalBluetoothDevice(Context context, String address) {
mLocalManager = LocalBluetoothManager.getInstance(context);
if (mLocalManager == null) {
@@ -102,12 +290,19 @@ public class LocalBluetoothDevice implements Comparable {
}
public void disconnect(Profile profile) {
+ queueCommand(new BluetoothJob(BluetoothCommand.DISCONNECT, this, profile));
+ }
+
+ private boolean disconnectInt(LocalBluetoothDevice device, Profile profile) {
LocalBluetoothProfileManager profileManager =
LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile);
- int status = profileManager.getConnectionStatus(mAddress);
+ int status = profileManager.getConnectionStatus(device.mAddress);
if (SettingsBtStatus.isConnectionStatusConnected(status)) {
- profileManager.disconnect(mAddress);
+ if (profileManager.disconnect(device.mAddress) == BluetoothDevice.RESULT_SUCCESS) {
+ return true;
+ }
}
+ return false;
}
public void askDisconnect() {
@@ -153,7 +348,7 @@ public class LocalBluetoothDevice implements Comparable {
LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile);
if (profileManager.isPreferred(mAddress)) {
hasAtLeastOnePreferredProfile = true;
- connectInt(profile);
+ queueCommand(new BluetoothJob(BluetoothCommand.CONNECT, this, profile));
}
}
@@ -173,27 +368,30 @@ public class LocalBluetoothDevice implements Comparable {
LocalBluetoothProfileManager profileManager =
LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile);
profileManager.setPreferred(mAddress, true);
- connectInt(profile);
+ queueCommand(new BluetoothJob(BluetoothCommand.CONNECT, this, profile));
}
}
public void connect(Profile profile) {
// Reset the only-show-one-error-dialog tracking variable
mIsConnectingErrorPossible = true;
- connectInt(profile);
+ queueCommand(new BluetoothJob(BluetoothCommand.CONNECT, this, profile));
}
- public void connectInt(Profile profile) {
- if (!ensurePaired()) return;
+ private boolean connectInt(LocalBluetoothDevice device, Profile profile) {
+ if (!device.ensurePaired()) return false;
LocalBluetoothProfileManager profileManager =
LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile);
- int status = profileManager.getConnectionStatus(mAddress);
+ int status = profileManager.getConnectionStatus(device.mAddress);
if (!SettingsBtStatus.isConnectionStatusConnected(status)) {
- if (profileManager.connect(mAddress) != BluetoothDevice.RESULT_SUCCESS) {
- Log.i(TAG, "Failed to connect " + profile.toString() + " to " + mName);
+ if (profileManager.connect(device.mAddress) == BluetoothDevice.RESULT_SUCCESS) {
+ return true;
}
+ Log.i(TAG, "Failed to connect " + profile.toString() + " to " + device.mName);
}
+ Log.i(TAG, "Not connected");
+ return false;
}
public void showConnectingError() {
@@ -228,6 +426,24 @@ public class LocalBluetoothDevice implements Comparable {
}
public void unpair() {
+ synchronized (workQueue) {
+ // Remove any pending commands for this device
+ boolean processNow = false;
+ Iterator it = workQueue.iterator();
+ while (it.hasNext()) {
+ BluetoothJob job = it.next();
+ if (job.device.mAddress.equals(this.mAddress)) {
+ it.remove();
+ if (job.timeSent != 0) {
+ processNow = true;
+ }
+ }
+ }
+ if (processNow) {
+ processCommands();
+ }
+ }
+
BluetoothDevice manager = mLocalManager.getBluetoothManager();
switch (getBondState()) {
diff --git a/src/com/android/settings/bluetooth/LocalBluetoothDeviceManager.java b/src/com/android/settings/bluetooth/LocalBluetoothDeviceManager.java
index 6bb2b4afe16..9527980b5a5 100644
--- a/src/com/android/settings/bluetooth/LocalBluetoothDeviceManager.java
+++ b/src/com/android/settings/bluetooth/LocalBluetoothDeviceManager.java
@@ -16,11 +16,8 @@
package com.android.settings.bluetooth;
-import android.app.AlertDialog;
import android.bluetooth.BluetoothDevice;
import android.util.Log;
-import android.widget.Toast;
-import android.content.Context;
import com.android.settings.R;
import com.android.settings.bluetooth.LocalBluetoothManager.Callback;
@@ -190,10 +187,13 @@ public class LocalBluetoothDeviceManager {
R.string.bluetooth_pairing_error_message);
}
- public synchronized void onProfileStateChanged(String address) {
+ public synchronized void onProfileStateChanged(String address, boolean transientState) {
LocalBluetoothDevice device = findDevice(address);
if (device == null) return;
+ if (!transientState) {
+ device.onProfileStateChanged();
+ }
device.refresh();
}
diff --git a/src/com/android/settings/bluetooth/LocalBluetoothManager.java b/src/com/android/settings/bluetooth/LocalBluetoothManager.java
index 4671fac6e8e..1a848b2d066 100644
--- a/src/com/android/settings/bluetooth/LocalBluetoothManager.java
+++ b/src/com/android/settings/bluetooth/LocalBluetoothManager.java
@@ -25,6 +25,8 @@ import android.app.Activity;
import android.app.AlertDialog;
import android.bluetooth.BluetoothA2dp;
import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothError;
+import android.bluetooth.BluetoothIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
@@ -40,8 +42,6 @@ public class LocalBluetoothManager {
private static final String TAG = "LocalBluetoothManager";
static final boolean V = true;
- public static final String EXTENDED_BLUETOOTH_STATE_CHANGED_ACTION =
- "com.android.settings.bluetooth.intent.action.EXTENDED_BLUETOOTH_STATE_CHANGED";
private static final String SHARED_PREFERENCES_NAME = "bluetooth_settings";
private static LocalBluetoothManager INSTANCE;
@@ -60,8 +60,7 @@ public class LocalBluetoothManager {
private BluetoothEventRedirector mEventRedirector;
private BluetoothA2dp mBluetoothA2dp;
- public static enum ExtendedBluetoothState { ENABLED, ENABLING, DISABLED, DISABLING, UNKNOWN }
- private ExtendedBluetoothState mState = ExtendedBluetoothState.UNKNOWN;
+ private int mState = BluetoothError.ERROR;
private List mCallbacks = new ArrayList();
@@ -182,34 +181,27 @@ public class LocalBluetoothManager {
}
}
- public ExtendedBluetoothState getBluetoothState() {
+ public int getBluetoothState() {
- if (mState == ExtendedBluetoothState.UNKNOWN) {
+ if (mState == BluetoothError.ERROR) {
syncBluetoothState();
}
return mState;
}
- void setBluetoothStateInt(ExtendedBluetoothState state) {
+ void setBluetoothStateInt(int state) {
mState = state;
-
- /*
- * TODO: change to callback method. originally it was broadcast to
- * parallel the framework's method, but it just complicates things here.
- */
- // If this were a real API, I'd add as an extra
- mContext.sendBroadcast(new Intent(EXTENDED_BLUETOOTH_STATE_CHANGED_ACTION));
-
- if (state == ExtendedBluetoothState.ENABLED || state == ExtendedBluetoothState.DISABLED) {
- mLocalDeviceManager.onBluetoothStateChanged(state == ExtendedBluetoothState.ENABLED);
+ if (state == BluetoothDevice.BLUETOOTH_STATE_ON ||
+ state == BluetoothDevice.BLUETOOTH_STATE_OFF) {
+ mLocalDeviceManager.onBluetoothStateChanged(state == BluetoothDevice.BLUETOOTH_STATE_ON);
}
}
private void syncBluetoothState() {
setBluetoothStateInt(mManager.isEnabled()
- ? ExtendedBluetoothState.ENABLED
- : ExtendedBluetoothState.DISABLED);
+ ? BluetoothDevice.BLUETOOTH_STATE_ON
+ : BluetoothDevice.BLUETOOTH_STATE_OFF);
}
public void setBluetoothEnabled(boolean enabled) {
@@ -219,8 +211,8 @@ public class LocalBluetoothManager {
if (wasSetStateSuccessful) {
setBluetoothStateInt(enabled
- ? ExtendedBluetoothState.ENABLING
- : ExtendedBluetoothState.DISABLING);
+ ? BluetoothDevice.BLUETOOTH_STATE_TURNING_ON
+ : BluetoothDevice.BLUETOOTH_STATE_TURNING_OFF);
} else {
if (V) {
Log.v(TAG,
diff --git a/src/com/android/settings/bluetooth/LocalBluetoothProfileManager.java b/src/com/android/settings/bluetooth/LocalBluetoothProfileManager.java
index 50edf86f4f9..24563a767ef 100644
--- a/src/com/android/settings/bluetooth/LocalBluetoothProfileManager.java
+++ b/src/com/android/settings/bluetooth/LocalBluetoothProfileManager.java
@@ -72,19 +72,22 @@ public abstract class LocalBluetoothProfileManager {
/**
* Temporary method to fill profiles based on a device's class.
*
+ * NOTE: This list happens to define the connection order. We should put this logic in a more
+ * well known place when this method is no longer temporary.
+ *
* @param btClass The class
* @param profiles The list of profiles to fill
*/
public static void fill(int btClass, List profiles) {
profiles.clear();
- if (BluetoothA2dp.doesClassMatchSink(btClass)) {
- profiles.add(Profile.A2DP);
- }
-
if (BluetoothHeadset.doesClassMatch(btClass)) {
profiles.add(Profile.HEADSET);
}
+
+ if (BluetoothA2dp.doesClassMatchSink(btClass)) {
+ profiles.add(Profile.A2DP);
+ }
}
protected LocalBluetoothProfileManager(LocalBluetoothManager localManager) {
@@ -214,7 +217,7 @@ public abstract class LocalBluetoothProfileManager {
*/
String address = mService.getHeadsetAddress();
if (TextUtils.isEmpty(address)) return;
- mLocalManager.getLocalDeviceManager().onProfileStateChanged(address);
+ mLocalManager.getLocalDeviceManager().onProfileStateChanged(address, true);
}
});
}
diff --git a/src/com/android/settings/deviceinfo/Status.java b/src/com/android/settings/deviceinfo/Status.java
index 96366b8914e..9162d25d12b 100644
--- a/src/com/android/settings/deviceinfo/Status.java
+++ b/src/com/android/settings/deviceinfo/Status.java
@@ -74,7 +74,6 @@ public class Status extends PreferenceActivity {
private Resources mRes;
private Preference mSignalStrength;
private Preference mUptime;
- private Preference mAwakeTime;
private static String sUnknown;
@@ -178,9 +177,9 @@ public class Status extends PreferenceActivity {
}
mPhone = PhoneFactory.getDefaultPhone();
- mSignalStrength = findPreference("signal_strength");
+ // Note - missing in zaku build, be careful later...
+ mSignalStrength = findPreference("signal_strength");
mUptime = findPreference("up_time");
- mAwakeTime = findPreference("awake_time");
setSummaryText("imei", mPhone.getDeviceId());
setSummaryText("imei_sv",
@@ -238,11 +237,13 @@ public class Status extends PreferenceActivity {
}
private void setSummaryText(String preference, String text) {
- if (TextUtils.isEmpty(text)) {
- text = sUnknown;
- }
-
- findPreference(preference).setSummary(text);
+ if (TextUtils.isEmpty(text)) {
+ text = sUnknown;
+ }
+ // some preferences may be missing
+ if (findPreference(preference) != null) {
+ findPreference(preference).setSummary(text);
+ }
}
private void updateNetworkType() {
@@ -300,27 +301,30 @@ public class Status extends PreferenceActivity {
}
void updateSignalStrength() {
- int state =
- mPhoneStateReceiver.getServiceState().getState();
- Resources r = getResources();
+ // not loaded in some versions of the code (e.g., zaku)
+ if (mSignalStrength != null) {
+ int state =
+ mPhoneStateReceiver.getServiceState().getState();
+ Resources r = getResources();
- if ((ServiceState.STATE_OUT_OF_SERVICE == state) ||
- (ServiceState.STATE_POWER_OFF == state)) {
- mSignalStrength.setSummary("0");
+ if ((ServiceState.STATE_OUT_OF_SERVICE == state) ||
+ (ServiceState.STATE_POWER_OFF == state)) {
+ mSignalStrength.setSummary("0");
+ }
+
+ int signalDbm = mPhoneStateReceiver.getSignalStrengthDbm();
+
+ if (-1 == signalDbm) signalDbm = 0;
+
+ int signalAsu = mPhoneStateReceiver.getSignalStrength();
+
+ if (-1 == signalAsu) signalAsu = 0;
+
+ mSignalStrength.setSummary(String.valueOf(signalDbm) + " "
+ + r.getString(R.string.radioInfo_display_dbm) + " "
+ + String.valueOf(signalAsu) + " "
+ + r.getString(R.string.radioInfo_display_asu));
}
-
- int signalDbm = mPhoneStateReceiver.getSignalStrengthDbm();
-
- if (-1 == signalDbm) signalDbm = 0;
-
- int signalAsu = mPhoneStateReceiver.getSignalStrength();
-
- if (-1 == signalAsu) signalAsu = 0;
-
- mSignalStrength.setSummary(String.valueOf(signalDbm) + " "
- + r.getString(R.string.radioInfo_display_dbm) + " "
- + String.valueOf(signalAsu) + " "
- + r.getString(R.string.radioInfo_display_asu));
}
private void setWifiStatus() {
@@ -357,7 +361,6 @@ public class Status extends PreferenceActivity {
}
mUptime.setSummary(convert(ut));
- mAwakeTime.setSummary(convert(at) + " (" + (((1000 * at / ut) + 5) / 10) + "%)");
}
private String pad(int n) {