</intent-filter>
</receiver>
- <activity android:name="ActivityPicker" android:label="@string/activity_picker_label">
+ <activity android:name="ActivityPicker"
+ android:label="@string/activity_picker_label"
+ android:theme="@android:style/Theme.Light">
<intent-filter>
<action android:name="android.intent.action.PICK_ACTIVITY" />
<category android:name="android.intent.category.DEFAULT" />
</receiver>
<!-- Standard picker for widgets -->
- <activity android:name="AppWidgetPickActivity" android:label="@string/widget_picker_title">
+ <activity android:name="AppWidgetPickActivity"
+ android:label="@string/widget_picker_title"
+ android:theme="@android:style/Theme.Light">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_PICK" />
<category android:name="android.intent.category.DEFAULT" />
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="?android:attr/listPreferredItemHeight"
+ android:gravity="center_vertical">
+
+ <RelativeLayout
+ android:id="@+android:id/text_layout"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="16sp"
+ android:layout_marginRight="6sp"
+ android:layout_marginTop="6sp"
+ android:layout_marginBottom="6sp"
+ android:layout_weight="1"
+ android:focusable="true"
+ android:background="@android:drawable/menuitem_background">
+
+ <TextView
+ android:id="@+android:id/title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:focusable="true"
+ android:singleLine="true"
+ android:textAppearance="?android:attr/textAppearanceLarge" />
+
+ <TextView
+ android:id="@+android:id/summary"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@android:id/title"
+ android:layout_alignLeft="@android:id/title"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:maxLines="2" />
+
+ </RelativeLayout>
+
+ <RadioButton
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+android:id/apn_radiobutton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="4dip"
+ android:layout_marginRight="4dip"
+ android:layout_gravity="center_vertical"
+ android:clickable="true" />
+
+</LinearLayout>
android:layout_height="wrap_content" />
</RelativeLayout>
+ <!-- Other controls section -->
+ <TextView
+ style="?android:attr/listSeparatorTextViewStyle"
+ android:text="@string/controls_label" />
+
+ <RelativeLayout
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical">
+ <Button android:id="@+id/force_stop_button"
+ android:layout_alignParentRight="true"
+ android:layout_alignParentTop="true"
+ android:layout_centerHorizontal="true"
+ android:layout_width="150dip"
+ android:text="@string/force_stop"
+ android:layout_height="wrap_content" />
+ </RelativeLayout>
+
<!-- Permissions section -->
<LinearLayout
android:id="@+id/permissions_section"
android:layout_height="fill_parent"
android:orientation="vertical"/>
</LinearLayout>
-
- <!-- Prefered activities section -->
- <TextView
- style="?android:attr/listSeparatorTextViewStyle"
- android:text="@string/controls_label" />
-
- <RelativeLayout
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical">
- <Button android:id="@+id/force_stop_button"
- android:layout_alignParentRight="true"
- android:layout_alignParentTop="true"
- android:layout_centerHorizontal="true"
- android:layout_width="150dip"
- android:text="@string/force_stop"
- android:layout_height="wrap_content" />
- </RelativeLayout>
</LinearLayout>
</ScrollView>
<string name="device_info_not_available">"該当なし"</string>
<string name="device_status_activity_title">"端末の状態"</string>
<string name="device_status">"端末の状態"</string>
- <string name="device_status_summary">"電話番号、端末識別番号、電波状態など"</string>
+ <string name="device_status_summary">"電池残量、電話番号、ネットワークなど"</string>
<string name="storage_settings_title">"SDカード & 端末容量"</string>
<string name="storage_settings_summary">"SDカードの取り外し、空き容量の表示"</string>
<string name="status_number">"電話番号"</string>
<string name="auto_launch_label">"いつもこのアプリケーションを選択する操作"</string>
<string name="permissions_label">"許可"</string>
<string name="cache_header_label">"キャッシュ"</string>
- <string name="clear_cache_btn_text">"キャッシュをクリア"</string>
+ <string name="clear_cache_btn_text">"キャッシュを消去"</string>
<string name="cache_size_label">"キャッシュ"</string>
<string name="controls_label">"コントロール"</string>
<string name="force_stop">"強制停止"</string>
<string name="auto_punctuate_summary">"英語: Spaceキー2回でピリオド(.)を挿入"</string>
<string name="show_password">"パスワードを表示"</string>
<string name="show_password_summary">"入力時にパスワードを表示する"</string>
+ <!-- no translation found for ime_security_warning (3458652708716006477) -->
+ <skip />
<string name="user_dict_settings_titlebar">"ユーザー辞書"</string>
<string name="user_dict_settings_title">"ユーザー辞書"</string>
<string name="user_dict_settings_summary">"ユーザー辞書への語句の追加と削除"</string>
<string name="sound_and_display_settings_summary">Set ringtones, notifications, screen brightness</string>
<!-- Sound settings screen, setting option name checkbox -->
<string name="silent_mode_title">Silent mode</string>
- <!-- Sound settings screen, setting option summary text -->
+ <!-- Sound settings screen, setting option summary text when going into silent mode. Media and alarms sounds WILL NOT be silenced in silent mode. -->
<string name="silent_mode_summary">All sounds except media & alarms are silenced</string>
+ <!-- Sound settings screen, setting option summary text when going into silent mode. Media WILL NOT be silenced in silent mode, but alarms WILL be silenced. -->
+ <string name="silent_mode_incl_alarm_summary">All sounds except media are silenced</string>
<!-- Sound settings screen, setting option name to pick ringtone (a list dialog comes up)-->
<string name="ringtone_title">Phone ringtone</string>
<!-- Sound settings screen, setting option summary text -->
--- /dev/null
+/*
+ * 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.
+ * 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 android.content.ContentUris;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.preference.Preference;
+import android.provider.Telephony;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.View.OnClickListener;
+import android.widget.CompoundButton;
+import android.widget.RadioButton;
+import android.widget.RelativeLayout;
+
+public class ApnPreference extends Preference implements
+ CompoundButton.OnCheckedChangeListener, OnClickListener {
+ final static String TAG = "ApnPreference";
+
+ /**
+ * @param context
+ * @param attrs
+ * @param defStyle
+ */
+ public ApnPreference(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ init();
+ }
+
+ /**
+ * @param context
+ * @param attrs
+ */
+ public ApnPreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init();
+ }
+
+ /**
+ * @param context
+ */
+ public ApnPreference(Context context) {
+ super(context);
+ init();
+ }
+
+ private static String mSelectedKey = null;
+ private static CompoundButton mCurrentChecked = null;
+ private boolean mProtectFromCheckedChange = false;
+ private boolean mSelectable = true;
+
+ @Override
+ public View getView(View convertView, ViewGroup parent) {
+ View view = super.getView(convertView, parent);
+
+ View widget = view.findViewById(R.id.apn_radiobutton);
+ if ((widget != null) && widget instanceof RadioButton) {
+ RadioButton rb = (RadioButton) widget;
+ if (mSelectable) {
+ rb.setOnCheckedChangeListener(this);
+
+ boolean isChecked = getKey().equals(mSelectedKey);
+ if (isChecked) {
+ mCurrentChecked = rb;
+ mSelectedKey = getKey();
+ }
+
+ mProtectFromCheckedChange = true;
+ rb.setChecked(isChecked);
+ mProtectFromCheckedChange = false;
+ } else {
+ rb.setVisibility(View.GONE);
+ }
+ }
+
+ View textLayout = view.findViewById(R.id.text_layout);
+ if ((textLayout != null) && textLayout instanceof RelativeLayout) {
+ textLayout.setOnClickListener(this);
+ }
+
+ return view;
+ }
+
+ private void init() {
+ setLayoutResource(R.layout.apn_preference_layout);
+ }
+
+ public boolean isChecked() {
+ return getKey().equals(mSelectedKey);
+ }
+
+ public void setChecked(boolean checked) {
+ mSelectedKey = getKey();
+ }
+
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ Log.i(TAG, "ID: " + getKey() + " :" + isChecked);
+ if (mProtectFromCheckedChange) {
+ return;
+ }
+
+ if (isChecked) {
+ if (mCurrentChecked != null) {
+ mCurrentChecked.setChecked(false);
+ }
+ mCurrentChecked = buttonView;
+ mSelectedKey = getKey();
+ callChangeListener(mSelectedKey);
+ } else {
+ mCurrentChecked = null;
+ mSelectedKey = null;
+ }
+ }
+
+ public void onClick(android.view.View v) {
+ if ((v != null) && (R.id.text_layout == v.getId())) {
+ Context context = getContext();
+ if (context != null) {
+ int pos = Integer.parseInt(getKey());
+ Uri url = ContentUris.withAppendedId(Telephony.Carriers.CONTENT_URI, pos);
+ context.startActivity(new Intent(Intent.ACTION_EDIT, url));
+ }
+ }
+ }
+
+ public void setSelectable(boolean selectable) {
+ mSelectable = selectable;
+ }
+
+ public boolean getSelectable() {
+ return mSelectable;
+ }
+}
import android.app.Dialog;
import android.app.ProgressDialog;
+import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.ContentUris;
+import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
+import android.content.IntentFilter;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceGroup;
import android.preference.PreferenceScreen;
import android.provider.Telephony;
-import android.text.TextUtils;
+import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
-public class ApnSettings extends PreferenceActivity {
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.TelephonyIntents;
+import com.android.internal.telephony.TelephonyProperties;
+
+import java.util.ArrayList;
+
+public class ApnSettings extends PreferenceActivity implements
+ Preference.OnPreferenceChangeListener {
+ static final String TAG = "ApnSettings";
public static final String EXTRA_POSITION = "position";
public static final String RESTORE_CARRIERS_URI =
"content://telephony/carriers/restore";
+ public static final String PREFERRED_APN_URI =
+ "content://telephony/carriers/preferapn";
+
+ public static final String APN_ID = "apn_id";
private static final int ID_INDEX = 0;
private static final int NAME_INDEX = 1;
private static final int APN_INDEX = 2;
+ private static final int TYPES_INDEX = 3;
private static final int MENU_NEW = Menu.FIRST;
private static final int MENU_RESTORE = Menu.FIRST + 1;
private static final int DIALOG_RESTORE_DEFAULTAPN = 1001;
private static final Uri DEFAULTAPN_URI = Uri.parse(RESTORE_CARRIERS_URI);
+ private static final Uri PREFERAPN_URI = Uri.parse(PREFERRED_APN_URI);
private static boolean mRestoreDefaultApnMode;
private RestoreApnUiHandler mRestoreApnUiHandler;
private RestoreApnProcessHandler mRestoreApnProcessHandler;
- private Cursor mCursor;
+ private String mSelectedKey;
+
+ private IntentFilter mMobileStateFilter;
+
+ private final BroadcastReceiver mMobileStateReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (intent.getAction().equals(
+ TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED)) {
+ Phone.DataState state = getMobileDataState(intent);
+ switch (state) {
+ case CONNECTED:
+ if (!mRestoreDefaultApnMode) {
+ fillList();
+ } else {
+ showDialog(DIALOG_RESTORE_DEFAULTAPN);
+ }
+ break;
+ }
+ }
+ }
+ };
+
+ private static Phone.DataState getMobileDataState(Intent intent) {
+ String str = intent.getStringExtra(Phone.STATE_KEY);
+ if (str != null) {
+ return Enum.valueOf(Phone.DataState.class, str);
+ } else {
+ return Phone.DataState.DISCONNECTED;
+ }
+ }
@Override
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
addPreferencesFromResource(R.xml.apn_settings);
+ getListView().setItemsCanFocus(true);
+
+ mMobileStateFilter = new IntentFilter(
+ TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED);
}
@Override
protected void onResume() {
super.onResume();
+ registerReceiver(mMobileStateReceiver, mMobileStateFilter);
+
if (!mRestoreDefaultApnMode) {
fillList();
} else {
}
}
+ @Override
+ protected void onPause() {
+ super.onPause();
+
+ unregisterReceiver(mMobileStateReceiver);
+ }
+
private void fillList() {
- mCursor = managedQuery(Telephony.Carriers.CONTENT_URI, new String[] {
- "_id", "name", "apn"}, null, Telephony.Carriers.DEFAULT_SORT_ORDER);
+ String where = "numeric=\""
+ + android.os.SystemProperties.get(TelephonyProperties.PROPERTY_SIM_OPERATOR_NUMERIC, "")
+ + "\"";
+
+ Cursor cursor = managedQuery(Telephony.Carriers.CONTENT_URI, new String[] {
+ "_id", "name", "apn", "type"}, where,
+ Telephony.Carriers.DEFAULT_SORT_ORDER);
PreferenceGroup apnList = (PreferenceGroup) findPreference("apn_list");
apnList.removeAll();
- mCursor.moveToFirst();
- while (!mCursor.isAfterLast()) {
- String name = mCursor.getString(NAME_INDEX);
- String apn = mCursor.getString(APN_INDEX);
-
- 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);
+ ArrayList<Preference> mmsApnList = new ArrayList<Preference>();
+
+ 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);
}
}
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;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
+import android.os.SystemClock;
import android.text.format.Formatter;
import android.util.Config;
import android.util.Log;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
+import java.util.concurrent.CountDownLatch;
/**
* Activity to pick an application that will be used to display installation information and
// Log information boolean
private boolean localLOGV = Config.LOGV || false;
+ private static final boolean DEBUG_SIZE = false;
+ private static final boolean DEBUG_TIME = false;
// attributes used as keys when passing values to InstalledAppDetails activity
public static final String APP_PKG_PREFIX = "com.android.settings.";
private static final int REFRESH_APP_RESOURCE = HANDLER_MESSAGE_BASE+7;
private static final int REFRESH_DONE = HANDLER_MESSAGE_BASE+8;
private static final int NEXT_LOAD_STEP = HANDLER_MESSAGE_BASE+9;
+ private static final int COMPUTE_END = HANDLER_MESSAGE_BASE+10;
+
// observer object used for computing pkg sizes
private PkgSizeObserver mObserver;
private static final int DLG_BASE = 0;
private static final int DLG_LOADING = DLG_BASE + 1;
- // compute index used to track the application size computations
- private int mComputeIndex;
-
// Size resource used for packages whose size computation failed for some reason
private CharSequence mInvalidSizeStr;
private CharSequence mComputingSizeStr;
// Thread to load resources
ResourceLoaderThread mResourceThread;
+ private TaskRunner mSizeComputor;
String mCurrentPkgName;
// initiate the first computation and loading of resources
private boolean mJustCreated = true;
private boolean mFirst = false;
+ private long mLoadTimeStart;
/*
* Handler class to handle messages for various operations
switch (msg.what) {
case INIT_PKG_INFO:
if(localLOGV) Log.i(TAG, "Message INIT_PKG_INFO");
- List<ApplicationInfo> newList = getInstalledApps(FILTER_APPS_ALL);
if (!mJustCreated) {
// Add or delete newly created packages by comparing lists
+ List<ApplicationInfo> newList = getInstalledApps(FILTER_APPS_ALL);
updateAppList(newList);
}
// Retrieve the package list and init some structures
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 {
- // End computation here
- mComputeSizes = true;
- mFirst = true;
- 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");
mAppInfoAdapter.addToList(pkgName, ps);
break;
case REFRESH_APP_RESOURCE:
- AppInfo aInfo = (AppInfo) msg.obj;
+ AppInfo aInfo = (AppInfo) msg.obj;
if(aInfo == null) {
- Log.w(TAG, "Error loading icons for applications");
+ Log.w(TAG, "Error loading resources");
} else {
mAppInfoAdapter.updateAppsResourceInfo(aInfo);
}
// 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.sortList(mSortOrder);
+ mAppInfoAdapter.sortBaseList(mSortOrder);
if (mJustCreated) {
// Set the adapter here.
mJustCreated = false;
}
};
+ 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<ApplicationInfo> 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<ApplicationInfo> 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
// some initialization code used when kicking off the size computation
private void initAppList(List<ApplicationInfo> appList, int filterOption) {
setProgressBarIndeterminateVisibility(true);
- mComputeIndex = 0;
mComputeSizes = false;
mLoadLabels = false;
// Initialize lists
// Utility method to start a thread to read application labels and icons
private void initResourceThread() {
- //load resources now
- if(mResourceThread.isAlive()) {
- mResourceThread.interrupt();
- mResourceThread = new ResourceLoaderThread();
+ if ((mResourceThread != null) && mResourceThread.isAlive()) {
+ mResourceThread.setAbort();
+ }
+ mResourceThread = new ResourceLoaderThread();
+ List<ApplicationInfo> 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<ApplicationInfo> appList = mAppInfoAdapter.getBaseAppList();
+ if ((appList != null) && (appList.size()) > 0) {
+ mSizeComputor = new TaskRunner(appList);
} else {
mComputeSizes = true;
}
class ResourceLoaderThread extends Thread {
List<ApplicationInfo> mAppList;
+ volatile boolean abort = false;
+ public void setAbort() {
+ abort = true;
+ }
void loadAllResources(List<ApplicationInfo> appList) {
mAppList = appList;
start();
}
public void run() {
- Map<String, AppInfo> iconMap = new HashMap<String, AppInfo>();
- 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);
+ 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, appName, appIcon);
+ 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 doneMsg = mHandler.obtainMessage(REFRESH_DONE);
- mHandler.sendMessage(doneMsg);
+ if (DEBUG_TIME) Log.i(TAG, "Took "+(SystemClock.elapsedRealtime()-start)+" ms to load app resources");
}
}
public Drawable appIcon;
public CharSequence appSize;
public PackageStats appStats;
-
+
public void refreshIcon(AppInfo pInfo) {
- appName = pInfo.appName;
- appIcon = pInfo.appIcon;
+ 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;
} else {
mAppList = appList;
}
- mAppLocalList = getFilteredApps(appList, filterOption);
- int sortOrder = SORT_ORDER_ALPHA;
if (mAppPropCache != null) {
// Retain previous sort order
- sortOrder = mSortOrder;
+ int sortOrder = mSortOrder;
mAppPropMap = mAppPropCache;
+ // TODO is this required?
+ sortAppList(mAppList, sortOrder);
} else {
// Recreate property map
mAppPropMap = new TreeMap<String, AppInfo>();
// Re init the comparators
mAlphaComparator = null;
mSizeComparator = null;
-
- sortAppList(sortOrder);
+
+ mAppLocalList = getFilteredApps(appList, filterOption);
int imax = appList.size();
for (int i = 0; i < imax; i++) {
ApplicationInfo info = appList.get(i);
}
public AppInfoAdapter(Context c, List<ApplicationInfo> appList) {
- initMapFromList(appList, mFilterApps);
+ mAppList = appList;
}
public int getCount() {
return mAppPropMap.get(mAppLocalList.get(position).packageName).index;
}
- public List<ApplicationInfo> getAppList() {
- return mAppLocalList;
+ public List<ApplicationInfo> getBaseAppList() {
+ return mAppList;
}
public View getView(int position, View convertView, ViewGroup parent) {
}
}
- public void sortAppList(int sortOrder) {
- Collections.sort(mAppLocalList, getAppComparator(sortOrder));
+ public void sortAppList(List<ApplicationInfo> 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) {
if (localLOGV) Log.i(TAG, "sortOrder = "+sortOrder);
- sortAppList(sortOrder);
+ sortAppList(mAppLocalList, sortOrder);
adjustIndex();
notifyDataSetChanged();
}
}
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<String, AppInfo> iconMap) {
- if(iconMap == null) {
- Log.w(TAG, "Null iconMap when refreshing icon in List Adapter");
- return true;
- }
- boolean changed = false;
- for (ApplicationInfo info : mAppList) {
- 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;
- }
public boolean updateAppsResourceInfo(AppInfo pInfo) {
- if(pInfo == null) {
+ if((pInfo == null) || (pInfo.pkgName == null)) {
Log.w(TAG, "Null info when refreshing icon in List Adapter");
return false;
}
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) {
@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;
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();
// register receiver
mReceiver.registerReceiver();
sendMessageToHandler(INIT_PKG_INFO);
@Override
public void onStop() {
super.onStop();
+ // Stop the background threads
+ mResourceThread.setAbort();
+ mSizeComputor.setAbort();
// clear all messages related to application list
clearMessagesInHandler();
// register receiver here
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();
private void queueCommand(BluetoothJob job) {
Log.d(TAG, workQueue.toString());
synchronized (workQueue) {
- boolean processNow = false;
- long now = System.currentTimeMillis();
-
- Iterator<BluetoothJob> it = workQueue.iterator();
- while (it.hasNext()) {
- BluetoothJob existingJob = it.next();
-
- // Remove any pending CONNECTS when we receive a DISCONNECT
- if (job.command == BluetoothCommand.DISCONNECT) {
- if (existingJob.timeSent == 0
- && existingJob.command == BluetoothCommand.CONNECT
- && existingJob.device.mAddress.equals(job.device.mAddress)
- && existingJob.profile == job.profile) {
- 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();
- processNow = true;
- continue;
- }
- }
+ boolean processNow = pruneQueue(job);
// Add job to queue
Log.d(TAG, "Adding: " + job.toString());
}
}
}
+
+ private boolean pruneQueue(BluetoothJob job) {
+ boolean removedStaleItems = false;
+ long now = System.currentTimeMillis();
+ Iterator<BluetoothJob> 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;
}
public void onProfileStateChanged() {
- // Remove the first item and process the next one
- BluetoothJob job = workQueue.poll();
+ Log.d(TAG, "onProfileStateChanged:" + workQueue.toString());
+ BluetoothJob job = workQueue.peek();
if (job == null) {
- Log.w(TAG, "Yikes, onProfileStateChanged called but job queue is empty");
+ 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) {
- Log.w(TAG, "Yikes, onProfileStateChanged called but the address differ. this.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();
* notification when it finishes processing a command
*/
private void processCommands() {
+ Log.d(TAG, "processCommands:" + workQueue.toString());
Iterator<BluetoothJob> it = workQueue.iterator();
while (it.hasNext()) {
BluetoothJob job = it.next();
}
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");
}
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() {
}
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 signalDbm = mPhoneStateReceiver.getSignalStrengthDbm();
- int signalAsu = mPhoneStateReceiver.getSignalStrength();
+ if (-1 == signalDbm) signalDbm = 0;
- if (-1 == signalAsu) signalAsu = 0;
+ int signalAsu = mPhoneStateReceiver.getSignalStrength();
- mSignalStrength.setSummary(String.valueOf(signalDbm) + " "
- + r.getString(R.string.radioInfo_display_dbm) + " "
- + String.valueOf(signalAsu) + " "
- + r.getString(R.string.radioInfo_display_asu));
+ 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() {