diff options
-rw-r--r-- | AndroidManifest.xml | 3 | ||||
-rw-r--r-- | res/values/strings.xml | 21 | ||||
-rw-r--r-- | res/xml/development_prefs.xml | 53 | ||||
-rw-r--r-- | src/com/android/settings/AppPicker.java | 144 | ||||
-rw-r--r-- | src/com/android/settings/DevelopmentSettings.java | 76 | ||||
-rw-r--r-- | src/com/android/settings/applications/AppViewHolder.java | 64 | ||||
-rw-r--r-- | src/com/android/settings/applications/ManageApplications.java | 56 |
7 files changed, 342 insertions, 75 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 5185f9a..e8ddf2d 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -1019,6 +1019,9 @@ android:resource="@id/development_settings" /> </activity-alias> + <activity android:name=".AppPicker" android:label="@string/select_application" + android:theme="@android:style/Theme.Holo.Dialog" /> + <activity android:name="Settings$UsbSettingsActivity" android:label="@string/storage_title_usb" android:clearTaskOnLaunch="true"> diff --git a/res/values/strings.xml b/res/values/strings.xml index 258df34..a936af5 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -3480,6 +3480,27 @@ <!-- HDCP checking dialog title, used for debug purposes only. [CHAR LIMIT=25] --> <string name="hdcp_checking_dialog_title">Set HDCP checking behavior</string> + <!-- Preference category for app debugging development settings. [CHAR LIMIT=50] --> + <string name="debug_debugging_category">Debugging</string> + + <!-- UI debug setting: select current app to debug [CHAR LIMIT=50] --> + <string name="debug_app">Select debug app</string> + <!-- UI debug setting: no debug app has been set [CHAR LIMIT=50] --> + <string name="debug_app_not_set">No debug application set</string> + <!-- UI debug setting: debug app has been set [CHAR LIMIT=50] --> + <string name="debug_app_set">Debugging application: <xliff:g id="app_name">%1$s</xliff:g></string> + + <!-- UI debug setting: title for app picker dialog [CHAR LIMIT=50] --> + <string name="select_application">Select application</string> + <!-- UI debug setting: label for app picker to select no applicatiojn [CHAR LIMIT=50] --> + <string name="no_application">Nothing</string> + + <!-- UI debug setting: wait for debugger to attach to debugging process? [CHAR LIMIT=50] --> + <string name="wait_for_debugger">Wait for debugger</string> + <!-- UI debug setting: wait for debugger to attach to debugging process summary [CHAR LIMIT=50] --> + <string name="wait_for_debugger_summary">Debugged application waits for debugger to + attach before executing</string> + <!-- Preference category for user interface debugging development settings. [CHAR LIMIT=25] --> <string name="debug_ui_category">User interface</string> diff --git a/res/xml/development_prefs.xml b/res/xml/development_prefs.xml index d0c01a7..fc41f5e 100644 --- a/res/xml/development_prefs.xml +++ b/res/xml/development_prefs.xml @@ -16,11 +16,6 @@ <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" android:title="@string/development_settings_title"> - - <CheckBoxPreference - android:key="enable_adb" - android:title="@string/enable_adb" - android:summary="@string/enable_adb_summary"/> <Preference android:key="verifier_device_identifier" @@ -29,16 +24,22 @@ android:summary="@string/verifier_device_identifier_not_available" android:persistent="false" /> + <PreferenceScreen + android:key="local_backup_password" + android:title="@string/local_backup_password_title" + android:summary="@string/local_backup_password_summary_none" + android:persistent="false" > + <intent + android:action="android.settings.privacy.SET_FULL_BACKUP_PASSWORD" + android:targetPackage="com.android.settings" + android:targetClass="com.android.settings.SetFullBackupPassword" /> + </PreferenceScreen> + <CheckBoxPreference android:key="keep_screen_on" android:title="@string/keep_screen_on" android:summary="@string/keep_screen_on_summary"/> - <CheckBoxPreference - android:key="allow_mock_location" - android:title="@string/allow_mock_location" - android:summary="@string/allow_mock_location_summary"/> - <ListPreference android:key="hdcp_checking" android:title="@string/hdcp_checking_title" @@ -46,16 +47,28 @@ android:entries="@array/hdcp_checking_titles" android:entryValues="@array/hdcp_checking_values" /> - <PreferenceScreen - android:key="local_backup_password" - android:title="@string/local_backup_password_title" - android:summary="@string/local_backup_password_summary_none" - android:persistent="false" > - <intent - android:action="android.settings.privacy.SET_FULL_BACKUP_PASSWORD" - android:targetPackage="com.android.settings" - android:targetClass="com.android.settings.SetFullBackupPassword" /> - </PreferenceScreen> + <PreferenceCategory android:key="debug_debugging_category" + android:title="@string/debug_debugging_category"> + + <CheckBoxPreference + android:key="enable_adb" + android:title="@string/enable_adb" + android:summary="@string/enable_adb_summary"/> + + <CheckBoxPreference + android:key="allow_mock_location" + android:title="@string/allow_mock_location" + android:summary="@string/allow_mock_location_summary"/> + + <PreferenceScreen android:key="debug_app" + android:title="@string/debug_app" /> + + <CheckBoxPreference + android:key="wait_for_debugger" + android:title="@string/wait_for_debugger" + android:summary="@string/wait_for_debugger_summary"/> + + </PreferenceCategory> <PreferenceCategory android:key="debug_ui_category" android:title="@string/debug_ui_category"> diff --git a/src/com/android/settings/AppPicker.java b/src/com/android/settings/AppPicker.java new file mode 100644 index 0000000..e58b835 --- /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<MyApplicationInfo> { + private final List<MyApplicationInfo> mPackageInfoList = new ArrayList<MyApplicationInfo>(); + private final LayoutInflater mInflater; + + public AppListAdapter(Context context) { + super(context, 0); + mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + List<ApplicationInfo> pkgs = context.getPackageManager().getInstalledApplications(0); + for (int i=0; i<pkgs.size(); i++) { + ApplicationInfo ai = pkgs.get(i); + if (ai.uid == Process.SYSTEM_UID) { + continue; + } + // On a user build, we only allow debugging of apps that + // are marked as debuggable. Otherwise (for platform development) + // we allow all apps. + if ((ai.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0 + && "user".equals(Build.TYPE)) { + continue; + } + MyApplicationInfo info = new MyApplicationInfo(); + info.info = ai; + info.label = info.info.loadLabel(getPackageManager()).toString(); + mPackageInfoList.add(info); + } + Collections.sort(mPackageInfoList, sDisplayNameComparator); + MyApplicationInfo info = new MyApplicationInfo(); + info.label = context.getText(R.string.no_application); + mPackageInfoList.add(0, info); + addAll(mPackageInfoList); + } + + @Override + 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 = AppViewHolder.createOrRecycle(mInflater, convertView); + convertView = holder.rootView; + MyApplicationInfo info = getItem(position); + holder.appName.setText(info.label); + if (info.info != null) { + holder.appIcon.setImageDrawable(info.info.loadIcon(getPackageManager())); + holder.appSize.setText(info.info.packageName); + } else { + holder.appIcon.setImageDrawable(null); + holder.appSize.setText(""); + } + holder.disabled.setVisibility(View.GONE); + holder.checkBox.setVisibility(View.GONE); + return convertView; + } + } + + private final static Comparator<MyApplicationInfo> sDisplayNameComparator + = new Comparator<MyApplicationInfo>() { + 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 7b4e0eb..d235633 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<mAllPrefs.size(); i++) { mAllPrefs.get(i).setEnabled(enabled); } + updateAllOptions(); } @Override @@ -262,7 +277,6 @@ public class DevelopmentSettings extends PreferenceFragment Settings.Secure.DEVELOPMENT_SETTINGS_ENABLED, 0) != 0; mEnabledSwitch.setChecked(mLastEnabledState); setPrefsEnabledState(mLastEnabledState); - updateAllOptions(); } private void updateAllOptions() { @@ -275,6 +289,7 @@ public class DevelopmentSettings extends PreferenceFragment Settings.Secure.ALLOW_MOCK_LOCATION, 0) != 0); updateHdcpValues(); updatePasswordSummary(); + updateDebuggerOptions(); updateStrictModeVisualOptions(); updatePointerLocationOptions(); updateShowTouchesOptions(); @@ -295,6 +310,7 @@ public class DevelopmentSettings extends PreferenceFragment onPreferenceTreeClick(null, cb); } } + resetDebuggerOptions(); writeAnimationScaleOption(0, mWindowAnimationScale, null); writeAnimationScaleOption(1, mTransitionAnimationScale, null); writeAnimationScaleOption(2, mAnimatorDurationScale, null); @@ -333,6 +349,45 @@ public class DevelopmentSettings extends PreferenceFragment } } + private void writeDebuggerOptions() { + try { + ActivityManagerNative.getDefault().setDebugApp( + mDebugApp, mWaitForDebugger.isChecked(), true); + } catch (RemoteException ex) { + } + } + + private void resetDebuggerOptions() { + try { + ActivityManagerNative.getDefault().setDebugApp( + null, false, true); + } catch (RemoteException ex) { + } + } + + private void updateDebuggerOptions() { + mDebugApp = Settings.System.getString( + getActivity().getContentResolver(), Settings.System.DEBUG_APP); + mWaitForDebugger.setChecked(Settings.System.getInt( + getActivity().getContentResolver(), Settings.System.WAIT_FOR_DEBUGGER, 0) != 0); + if (mDebugApp != null && mDebugApp.length() > 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 @@ -576,6 +631,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) { if (Utils.isMonkeyRunning()) { @@ -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 0000000..2a12f9b --- /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 948ddb0..b522077 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); |