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);