diff options
author | Dianne Hackborn <hackbod@google.com> | 2012-02-14 13:25:41 -0800 |
---|---|---|
committer | Dianne Hackborn <hackbod@google.com> | 2012-02-14 13:46:27 -0800 |
commit | 9244df4c6422931697a0cf6e327b15cd71b6d8c4 (patch) | |
tree | 7ed5a0462b6086e0d86d62bf5965cd43b9c64832 /src/com/android | |
parent | 31c5ec82021271f2e1745a2de37c543e67dcec17 (diff) | |
download | packages_apps_Settings-9244df4c6422931697a0cf6e327b15cd71b6d8c4.zip packages_apps_Settings-9244df4c6422931697a0cf6e327b15cd71b6d8c4.tar.gz packages_apps_Settings-9244df4c6422931697a0cf6e327b15cd71b6d8c4.tar.bz2 |
Add debug app / wait for debugger dev options.
Re-organize dev options a bit.
Change-Id: I291b177c87cb8fb4bd8316d05aa6eadfaaf5f0d2
Diffstat (limited to 'src/com/android')
-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 |
4 files changed, 285 insertions, 55 deletions
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); |