diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 5185f9acb8d..e8ddf2d3dd3 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -1019,6 +1019,9 @@
android:resource="@id/development_settings" />
+
+
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 258df343282..a936af52f7c 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -3480,6 +3480,27 @@
Set HDCP checking behavior
+
+ Debugging
+
+
+ Select debug app
+
+ No debug application set
+
+ Debugging application: %1$s
+
+
+ Select application
+
+ Nothing
+
+
+ Wait for debugger
+
+ Debugged application waits for debugger to
+ attach before executing
+
User interface
diff --git a/res/xml/development_prefs.xml b/res/xml/development_prefs.xml
index d0c01a76782..fc41f5e4e8d 100644
--- a/res/xml/development_prefs.xml
+++ b/res/xml/development_prefs.xml
@@ -16,11 +16,6 @@
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/com/android/settings/AppPicker.java b/src/com/android/settings/AppPicker.java
new file mode 100644
index 00000000000..e58b835a522
--- /dev/null
+++ b/src/com/android/settings/AppPicker.java
@@ -0,0 +1,144 @@
+/*
+ * 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.text.Collator;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import com.android.settings.applications.AppViewHolder;
+
+import android.app.ActivityManagerNative;
+import android.app.ListActivity;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Process;
+import android.os.RemoteException;
+import android.provider.Settings;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+
+public class AppPicker extends ListActivity {
+ private AppListAdapter mAdapter;
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ mAdapter = new AppListAdapter(this);
+ if (mAdapter.getCount() <= 0) {
+ finish();
+ } else {
+ setListAdapter(mAdapter);
+ }
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ }
+
+ @Override
+ protected void onListItemClick(ListView l, View v, int position, long id) {
+ MyApplicationInfo app = mAdapter.getItem(position);
+ Intent intent = new Intent();
+ if (app.info != null) intent.setAction(app.info.packageName);
+ setResult(RESULT_OK, intent);
+ finish();
+ }
+
+ class MyApplicationInfo {
+ ApplicationInfo info;
+ CharSequence label;
+ }
+
+ public class AppListAdapter extends ArrayAdapter {
+ private final List mPackageInfoList = new ArrayList();
+ private final LayoutInflater mInflater;
+
+ public AppListAdapter(Context context) {
+ super(context, 0);
+ mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ List pkgs = context.getPackageManager().getInstalledApplications(0);
+ for (int i=0; i sDisplayNameComparator
+ = new Comparator() {
+ public final int
+ compare(MyApplicationInfo a, MyApplicationInfo b) {
+ return collator.compare(a.label, b.label);
+ }
+
+ private final Collator collator = Collator.getInstance();
+ };
+}
diff --git a/src/com/android/settings/DevelopmentSettings.java b/src/com/android/settings/DevelopmentSettings.java
index 7b4e0eb1af6..d235633c88b 100644
--- a/src/com/android/settings/DevelopmentSettings.java
+++ b/src/com/android/settings/DevelopmentSettings.java
@@ -28,6 +28,7 @@ import android.content.ContentResolver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
+import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.VerifierDeviceIdentity;
import android.os.BatteryManager;
@@ -69,6 +70,8 @@ public class DevelopmentSettings extends PreferenceFragment
private static final String LOCAL_BACKUP_PASSWORD = "local_backup_password";
private static final String HARDWARE_UI_PROPERTY = "persist.sys.ui.hw";
+ private static final String DEBUG_APP_KEY = "debug_app";
+ private static final String WAIT_FOR_DEBUGGER_KEY = "wait_for_debugger";
private static final String STRICT_MODE_KEY = "strict_mode";
private static final String POINTER_LOCATION_KEY = "pointer_location";
private static final String SHOW_TOUCHES_KEY = "show_touches";
@@ -86,6 +89,8 @@ public class DevelopmentSettings extends PreferenceFragment
private static final String SHOW_ALL_ANRS_KEY = "show_all_anrs";
+ private static final int RESULT_DEBUG_APP = 1000;
+
private IWindowManager mWindowManager;
private IBackupManager mBackupManager;
@@ -97,6 +102,10 @@ public class DevelopmentSettings extends PreferenceFragment
private CheckBoxPreference mAllowMockLocation;
private PreferenceScreen mPassword;
+ private String mDebugApp;
+ private Preference mDebugAppPref;
+ private CheckBoxPreference mWaitForDebugger;
+
private CheckBoxPreference mStrictMode;
private CheckBoxPreference mPointerLocation;
private CheckBoxPreference mShowTouches;
@@ -144,10 +153,15 @@ public class DevelopmentSettings extends PreferenceFragment
mPassword = (PreferenceScreen) findPreference(LOCAL_BACKUP_PASSWORD);
mAllPrefs.add(mPassword);
+ mDebugAppPref = findPreference(DEBUG_APP_KEY);
+ mAllPrefs.add(mDebugAppPref);
+ mWaitForDebugger = (CheckBoxPreference) findPreference(WAIT_FOR_DEBUGGER_KEY);
+ mAllPrefs.add(mWaitForDebugger);
+ mResetCbPrefs.add(mWaitForDebugger);
+
mStrictMode = (CheckBoxPreference) findPreference(STRICT_MODE_KEY);
mAllPrefs.add(mStrictMode);
mResetCbPrefs.add(mStrictMode);
- mResetCbPrefs.add(mAllowMockLocation);
mPointerLocation = (CheckBoxPreference) findPreference(POINTER_LOCATION_KEY);
mAllPrefs.add(mPointerLocation);
mResetCbPrefs.add(mPointerLocation);
@@ -251,6 +265,7 @@ public class DevelopmentSettings extends PreferenceFragment
for (int i=0; i 0) {
+ String label;
+ try {
+ ApplicationInfo ai = getActivity().getPackageManager().getApplicationInfo(mDebugApp,
+ PackageManager.GET_DISABLED_COMPONENTS);
+ CharSequence lab = getActivity().getPackageManager().getApplicationLabel(ai);
+ label = lab != null ? lab.toString() : mDebugApp;
+ } catch (PackageManager.NameNotFoundException e) {
+ label = mDebugApp;
+ }
+ mDebugAppPref.setSummary(getResources().getString(R.string.debug_app_set, label));
+ mWaitForDebugger.setEnabled(true);
+ } else {
+ mDebugAppPref.setSummary(getResources().getString(R.string.debug_app_not_set));
+ mWaitForDebugger.setEnabled(false);
+ }
+ }
+
// Returns the current state of the system property that controls
// strictmode flashes. One of:
// 0: not explicitly set one way or another
@@ -575,6 +630,19 @@ public class DevelopmentSettings extends PreferenceFragment
}
}
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (requestCode == RESULT_DEBUG_APP) {
+ if (resultCode == Activity.RESULT_OK) {
+ mDebugApp = data.getAction();
+ writeDebuggerOptions();
+ updateDebuggerOptions();
+ }
+ } else {
+ super.onActivityResult(requestCode, resultCode, data);
+ }
+ }
+
@Override
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
@@ -607,6 +675,10 @@ public class DevelopmentSettings extends PreferenceFragment
Settings.Secure.putInt(getActivity().getContentResolver(),
Settings.Secure.ALLOW_MOCK_LOCATION,
mAllowMockLocation.isChecked() ? 1 : 0);
+ } else if (preference == mDebugAppPref) {
+ startActivityForResult(new Intent(getActivity(), AppPicker.class), RESULT_DEBUG_APP);
+ } else if (preference == mWaitForDebugger) {
+ writeDebuggerOptions();
} else if (preference == mStrictMode) {
writeStrictModeVisualOptions();
} else if (preference == mPointerLocation) {
diff --git a/src/com/android/settings/applications/AppViewHolder.java b/src/com/android/settings/applications/AppViewHolder.java
new file mode 100644
index 00000000000..2a12f9b50a5
--- /dev/null
+++ b/src/com/android/settings/applications/AppViewHolder.java
@@ -0,0 +1,64 @@
+package com.android.settings.applications;
+
+import com.android.settings.R;
+
+import android.content.Context;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.CheckBox;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+// View Holder used when displaying views
+public class AppViewHolder {
+ public ApplicationsState.AppEntry entry;
+ public View rootView;
+ public TextView appName;
+ public ImageView appIcon;
+ public TextView appSize;
+ public TextView disabled;
+ public CheckBox checkBox;
+
+ static public AppViewHolder createOrRecycle(LayoutInflater inflater, View convertView) {
+ if (convertView == null) {
+ convertView = inflater.inflate(R.layout.manage_applications_item, null);
+
+ // Creates a ViewHolder and store references to the two children views
+ // we want to bind data to.
+ AppViewHolder holder = new AppViewHolder();
+ holder.rootView = convertView;
+ holder.appName = (TextView) convertView.findViewById(R.id.app_name);
+ holder.appIcon = (ImageView) convertView.findViewById(R.id.app_icon);
+ holder.appSize = (TextView) convertView.findViewById(R.id.app_size);
+ holder.disabled = (TextView) convertView.findViewById(R.id.app_disabled);
+ holder.checkBox = (CheckBox) convertView.findViewById(R.id.app_on_sdcard);
+ convertView.setTag(holder);
+ return holder;
+ } else {
+ // Get the ViewHolder back to get fast access to the TextView
+ // and the ImageView.
+ return (AppViewHolder)convertView.getTag();
+ }
+ }
+
+ void updateSizeText(ManageApplications ma, int whichSize) {
+ if (ManageApplications.DEBUG) Log.i(ManageApplications.TAG, "updateSizeText of " + entry.label + " " + entry
+ + ": " + entry.sizeStr);
+ if (entry.sizeStr != null) {
+ switch (whichSize) {
+ case ManageApplications.SIZE_INTERNAL:
+ appSize.setText(entry.internalSizeStr);
+ break;
+ case ManageApplications.SIZE_EXTERNAL:
+ appSize.setText(entry.externalSizeStr);
+ break;
+ default:
+ appSize.setText(entry.sizeStr);
+ break;
+ }
+ } else if (entry.size == ApplicationsState.SIZE_INVALID) {
+ appSize.setText(ma.mInvalidSizeStr);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/com/android/settings/applications/ManageApplications.java b/src/com/android/settings/applications/ManageApplications.java
index 948ddb082a5..b522077c514 100644
--- a/src/com/android/settings/applications/ManageApplications.java
+++ b/src/com/android/settings/applications/ManageApplications.java
@@ -148,7 +148,7 @@ public class ManageApplications extends Fragment implements
private ApplicationsAdapter mApplicationsAdapter;
// Size resource used for packages whose size computation failed for some reason
- private CharSequence mInvalidSizeStr;
+ CharSequence mInvalidSizeStr;
private CharSequence mComputingSizeStr;
// layout inflater object used to inflate views
@@ -205,36 +205,6 @@ public class ManageApplications extends Fragment implements
}
};
- // View Holder used when displaying views
- static class AppViewHolder {
- ApplicationsState.AppEntry entry;
- TextView appName;
- ImageView appIcon;
- TextView appSize;
- TextView disabled;
- CheckBox checkBox;
-
- void updateSizeText(ManageApplications ma, int whichSize) {
- if (DEBUG) Log.i(TAG, "updateSizeText of " + entry.label + " " + entry
- + ": " + entry.sizeStr);
- if (entry.sizeStr != null) {
- switch (whichSize) {
- case SIZE_INTERNAL:
- appSize.setText(entry.internalSizeStr);
- break;
- case SIZE_EXTERNAL:
- appSize.setText(entry.externalSizeStr);
- break;
- default:
- appSize.setText(entry.sizeStr);
- break;
- }
- } else if (entry.size == ApplicationsState.SIZE_INVALID) {
- appSize.setText(ma.mInvalidSizeStr);
- }
- }
- }
-
/*
* Custom adapter implementation for the ListView
* This adapter maintains a map for each displayed application and its properties
@@ -477,28 +447,8 @@ public class ManageApplications extends Fragment implements
public View getView(int position, View convertView, ViewGroup parent) {
// A ViewHolder keeps references to children views to avoid unnecessary calls
// to findViewById() on each row.
- AppViewHolder holder;
-
- // When convertView is not null, we can reuse it directly, there is no need
- // to reinflate it. We only inflate a new View when the convertView supplied
- // by ListView is null.
- if (convertView == null) {
- convertView = mInflater.inflate(R.layout.manage_applications_item, null);
-
- // Creates a ViewHolder and store references to the two children views
- // we want to bind data to.
- holder = new AppViewHolder();
- holder.appName = (TextView) convertView.findViewById(R.id.app_name);
- holder.appIcon = (ImageView) convertView.findViewById(R.id.app_icon);
- holder.appSize = (TextView) convertView.findViewById(R.id.app_size);
- holder.disabled = (TextView) convertView.findViewById(R.id.app_disabled);
- holder.checkBox = (CheckBox) convertView.findViewById(R.id.app_on_sdcard);
- convertView.setTag(holder);
- } else {
- // Get the ViewHolder back to get fast access to the TextView
- // and the ImageView.
- holder = (AppViewHolder) convertView.getTag();
- }
+ AppViewHolder holder = AppViewHolder.createOrRecycle(mInflater, convertView);
+ convertView = holder.rootView;
// Bind the data efficiently with the holder
ApplicationsState.AppEntry entry = mEntries.get(position);