/* * 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.util.ArrayList; import android.app.ActionBar; import android.app.Activity; import android.app.ActivityManagerNative; import android.app.AlertDialog; import android.app.Dialog; import android.app.backup.IBackupManager; import android.content.ContentResolver; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.VerifierDeviceIdentity; import android.os.BatteryManager; import android.os.Build; import android.os.Bundle; import android.os.IBinder; import android.os.Parcel; import android.os.RemoteException; import android.os.ServiceManager; import android.os.StrictMode; import android.os.SystemProperties; import android.preference.CheckBoxPreference; import android.preference.ListPreference; import android.preference.Preference; import android.preference.PreferenceFragment; import android.preference.PreferenceScreen; import android.preference.Preference.OnPreferenceChangeListener; import android.provider.Settings; import android.text.TextUtils; import android.view.Gravity; import android.view.IWindowManager; import android.widget.CompoundButton; import android.widget.Switch; /* * Displays preferences for application developers. */ public class DevelopmentSettings extends PreferenceFragment implements DialogInterface.OnClickListener, DialogInterface.OnDismissListener, OnPreferenceChangeListener, CompoundButton.OnCheckedChangeListener { private static final String ENABLE_ADB = "enable_adb"; private static final String VERIFIER_DEVICE_IDENTIFIER = "verifier_device_identifier"; private static final String KEEP_SCREEN_ON = "keep_screen_on"; private static final String ALLOW_MOCK_LOCATION = "allow_mock_location"; private static final String HDCP_CHECKING_KEY = "hdcp_checking"; private static final String HDCP_CHECKING_PROPERTY = "persist.sys.hdcp_checking"; 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 STRICT_MODE_KEY = "strict_mode"; private static final String POINTER_LOCATION_KEY = "pointer_location"; private static final String SHOW_TOUCHES_KEY = "show_touches"; private static final String SHOW_SCREEN_UPDATES_KEY = "show_screen_updates"; private static final String DISABLE_OVERLAYS_KEY = "disable_overlays"; private static final String SHOW_CPU_USAGE_KEY = "show_cpu_usage"; private static final String FORCE_HARDWARE_UI_KEY = "force_hw_ui"; private static final String WINDOW_ANIMATION_SCALE_KEY = "window_animation_scale"; private static final String TRANSITION_ANIMATION_SCALE_KEY = "transition_animation_scale"; private static final String ANIMATOR_DURATION_SCALE_KEY = "animator_duration_scale"; private static final String IMMEDIATELY_DESTROY_ACTIVITIES_KEY = "immediately_destroy_activities"; private static final String APP_PROCESS_LIMIT_KEY = "app_process_limit"; private static final String SHOW_ALL_ANRS_KEY = "show_all_anrs"; private IWindowManager mWindowManager; private IBackupManager mBackupManager; private Switch mEnabledSwitch; private boolean mLastEnabledState; private CheckBoxPreference mEnableAdb; private CheckBoxPreference mKeepScreenOn; private CheckBoxPreference mAllowMockLocation; private PreferenceScreen mPassword; private CheckBoxPreference mStrictMode; private CheckBoxPreference mPointerLocation; private CheckBoxPreference mShowTouches; private CheckBoxPreference mShowScreenUpdates; private CheckBoxPreference mDisableOverlays; private CheckBoxPreference mShowCpuUsage; private CheckBoxPreference mForceHardwareUi; private ListPreference mWindowAnimationScale; private ListPreference mTransitionAnimationScale; private ListPreference mAnimatorDurationScale; private CheckBoxPreference mImmediatelyDestroyActivities; private ListPreference mAppProcessLimit; private CheckBoxPreference mShowAllANRs; private final ArrayList mAllPrefs = new ArrayList(); private final ArrayList mResetCbPrefs = new ArrayList(); // To track whether a confirmation dialog was clicked. private boolean mDialogClicked; private Dialog mEnableDialog; private Dialog mAdbDialog; @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); mWindowManager = IWindowManager.Stub.asInterface(ServiceManager.getService("window")); mBackupManager = IBackupManager.Stub.asInterface( ServiceManager.getService(Context.BACKUP_SERVICE)); addPreferencesFromResource(R.xml.development_prefs); mEnableAdb = (CheckBoxPreference) findPreference(ENABLE_ADB); mAllPrefs.add(mEnableAdb); mResetCbPrefs.add(mEnableAdb); mKeepScreenOn = (CheckBoxPreference) findPreference(KEEP_SCREEN_ON); mAllPrefs.add(mKeepScreenOn); mResetCbPrefs.add(mKeepScreenOn); mAllowMockLocation = (CheckBoxPreference) findPreference(ALLOW_MOCK_LOCATION); mAllPrefs.add(mAllowMockLocation); mResetCbPrefs.add(mAllowMockLocation); mPassword = (PreferenceScreen) findPreference(LOCAL_BACKUP_PASSWORD); mAllPrefs.add(mPassword); 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); mShowTouches = (CheckBoxPreference) findPreference(SHOW_TOUCHES_KEY); mAllPrefs.add(mShowTouches); mResetCbPrefs.add(mShowTouches); mShowScreenUpdates = (CheckBoxPreference) findPreference(SHOW_SCREEN_UPDATES_KEY); mAllPrefs.add(mShowScreenUpdates); mResetCbPrefs.add(mShowScreenUpdates); mDisableOverlays = (CheckBoxPreference) findPreference(DISABLE_OVERLAYS_KEY); mAllPrefs.add(mDisableOverlays); mResetCbPrefs.add(mDisableOverlays); mShowCpuUsage = (CheckBoxPreference) findPreference(SHOW_CPU_USAGE_KEY); mAllPrefs.add(mShowCpuUsage); mResetCbPrefs.add(mShowCpuUsage); mForceHardwareUi = (CheckBoxPreference) findPreference(FORCE_HARDWARE_UI_KEY); mAllPrefs.add(mForceHardwareUi); mResetCbPrefs.add(mForceHardwareUi); mWindowAnimationScale = (ListPreference) findPreference(WINDOW_ANIMATION_SCALE_KEY); mAllPrefs.add(mWindowAnimationScale); mWindowAnimationScale.setOnPreferenceChangeListener(this); mTransitionAnimationScale = (ListPreference) findPreference(TRANSITION_ANIMATION_SCALE_KEY); mAllPrefs.add(mTransitionAnimationScale); mTransitionAnimationScale.setOnPreferenceChangeListener(this); mAnimatorDurationScale = (ListPreference) findPreference(ANIMATOR_DURATION_SCALE_KEY); mAllPrefs.add(mAnimatorDurationScale); mAnimatorDurationScale.setOnPreferenceChangeListener(this); mImmediatelyDestroyActivities = (CheckBoxPreference) findPreference( IMMEDIATELY_DESTROY_ACTIVITIES_KEY); mAllPrefs.add(mImmediatelyDestroyActivities); mResetCbPrefs.add(mImmediatelyDestroyActivities); mAppProcessLimit = (ListPreference) findPreference(APP_PROCESS_LIMIT_KEY); mAllPrefs.add(mAppProcessLimit); mAppProcessLimit.setOnPreferenceChangeListener(this); mShowAllANRs = (CheckBoxPreference) findPreference( SHOW_ALL_ANRS_KEY); mAllPrefs.add(mShowAllANRs); mResetCbPrefs.add(mShowAllANRs); final Preference verifierDeviceIdentifier = findPreference(VERIFIER_DEVICE_IDENTIFIER); final PackageManager pm = getActivity().getPackageManager(); final VerifierDeviceIdentity verifierIndentity = pm.getVerifierDeviceIdentity(); if (verifierIndentity != null) { verifierDeviceIdentifier.setSummary(verifierIndentity.toString()); } Preference hdcpChecking = findPreference(HDCP_CHECKING_KEY); if (hdcpChecking != null) { mAllPrefs.add(hdcpChecking); } removeHdcpOptionsForProduction(); } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); final Activity activity = getActivity(); mEnabledSwitch = new Switch(activity); final int padding = activity.getResources().getDimensionPixelSize( R.dimen.action_bar_switch_padding); mEnabledSwitch.setPadding(0, 0, padding, 0); mEnabledSwitch.setOnCheckedChangeListener(this); } @Override public void onStart() { super.onStart(); final Activity activity = getActivity(); activity.getActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM, ActionBar.DISPLAY_SHOW_CUSTOM); activity.getActionBar().setCustomView(mEnabledSwitch, new ActionBar.LayoutParams( ActionBar.LayoutParams.WRAP_CONTENT, ActionBar.LayoutParams.WRAP_CONTENT, Gravity.CENTER_VERTICAL | Gravity.RIGHT)); } @Override public void onStop() { super.onStop(); final Activity activity = getActivity(); activity.getActionBar().setDisplayOptions(0, ActionBar.DISPLAY_SHOW_CUSTOM); activity.getActionBar().setCustomView(null); } private void removeHdcpOptionsForProduction() { if ("user".equals(Build.TYPE)) { Preference hdcpChecking = findPreference(HDCP_CHECKING_KEY); if (hdcpChecking != null) { // Remove the preference getPreferenceScreen().removePreference(hdcpChecking); mAllPrefs.remove(hdcpChecking); } } } private void setPrefsEnabledState(boolean enabled) { for (int i=0; i= limit) { mAppProcessLimit.setValueIndex(i); mAppProcessLimit.setSummary(mAppProcessLimit.getEntries()[i]); return; } } mAppProcessLimit.setValueIndex(0); mAppProcessLimit.setSummary(mAppProcessLimit.getEntries()[0]); } catch (RemoteException e) { } } private void writeAppProcessLimitOptions(Object newValue) { try { int limit = newValue != null ? Integer.parseInt(newValue.toString()) : -1; ActivityManagerNative.getDefault().setProcessLimit(limit); updateAppProcessLimitOptions(); } catch (RemoteException e) { } } private void writeShowAllANRsOptions() { Settings.Secure.putInt(getActivity().getContentResolver(), Settings.Secure.ANR_SHOW_BACKGROUND, mShowAllANRs.isChecked() ? 1 : 0); } private void updateShowAllANRsOptions() { mShowAllANRs.setChecked(Settings.Secure.getInt( getActivity().getContentResolver(), Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0); } @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if (buttonView == mEnabledSwitch) { if (isChecked != mLastEnabledState) { if (isChecked) { mDialogClicked = false; if (mEnableDialog != null) dismissDialogs(); mEnableDialog = new AlertDialog.Builder(getActivity()).setMessage( getActivity().getResources().getString( R.string.dev_settings_warning_message)) .setTitle(R.string.dev_settings_warning_title) .setIcon(android.R.drawable.ic_dialog_alert) .setPositiveButton(android.R.string.yes, this) .setNegativeButton(android.R.string.no, this) .show(); mEnableDialog.setOnDismissListener(this); } else { resetDangerousOptions(); Settings.Secure.putInt(getActivity().getContentResolver(), Settings.Secure.DEVELOPMENT_SETTINGS_ENABLED, 0); mLastEnabledState = isChecked; setPrefsEnabledState(mLastEnabledState); } } } } @Override public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) { if (Utils.isMonkeyRunning()) { return false; } if (preference == mEnableAdb) { if (mEnableAdb.isChecked()) { mDialogClicked = false; if (mAdbDialog != null) dismissDialogs(); mAdbDialog = new AlertDialog.Builder(getActivity()).setMessage( getActivity().getResources().getString(R.string.adb_warning_message)) .setTitle(R.string.adb_warning_title) .setIcon(android.R.drawable.ic_dialog_alert) .setPositiveButton(android.R.string.yes, this) .setNegativeButton(android.R.string.no, this) .show(); mAdbDialog.setOnDismissListener(this); } else { Settings.Secure.putInt(getActivity().getContentResolver(), Settings.Secure.ADB_ENABLED, 0); } } else if (preference == mKeepScreenOn) { Settings.System.putInt(getActivity().getContentResolver(), Settings.System.STAY_ON_WHILE_PLUGGED_IN, mKeepScreenOn.isChecked() ? (BatteryManager.BATTERY_PLUGGED_AC | BatteryManager.BATTERY_PLUGGED_USB) : 0); } else if (preference == mAllowMockLocation) { Settings.Secure.putInt(getActivity().getContentResolver(), Settings.Secure.ALLOW_MOCK_LOCATION, mAllowMockLocation.isChecked() ? 1 : 0); } else if (preference == mStrictMode) { writeStrictModeVisualOptions(); } else if (preference == mPointerLocation) { writePointerLocationOptions(); } else if (preference == mShowTouches) { writeShowTouchesOptions(); } else if (preference == mShowScreenUpdates) { writeShowUpdatesOption(); } else if (preference == mDisableOverlays) { writeDisableOverlaysOption(); } else if (preference == mShowCpuUsage) { writeCpuUsageOptions(); } else if (preference == mImmediatelyDestroyActivities) { writeImmediatelyDestroyActivitiesOptions(); } else if (preference == mShowAllANRs) { writeShowAllANRsOptions(); } else if (preference == mForceHardwareUi) { writeHardwareUiOptions(); } return false; } @Override public boolean onPreferenceChange(Preference preference, Object newValue) { if (HDCP_CHECKING_KEY.equals(preference.getKey())) { SystemProperties.set(HDCP_CHECKING_PROPERTY, newValue.toString()); updateHdcpValues(); return true; } else if (preference == mWindowAnimationScale) { writeAnimationScaleOption(0, mWindowAnimationScale, newValue); return true; } else if (preference == mTransitionAnimationScale) { writeAnimationScaleOption(1, mTransitionAnimationScale, newValue); return true; } else if (preference == mAnimatorDurationScale) { writeAnimationScaleOption(2, mAnimatorDurationScale, newValue); return true; } else if (preference == mAppProcessLimit) { writeAppProcessLimitOptions(newValue); return true; } return false; } private void dismissDialogs() { if (mAdbDialog != null) { mAdbDialog.dismiss(); mAdbDialog = null; } if (mEnableDialog != null) { mEnableDialog.dismiss(); mEnableDialog = null; } } public void onClick(DialogInterface dialog, int which) { if (dialog == mAdbDialog) { if (which == DialogInterface.BUTTON_POSITIVE) { mDialogClicked = true; Settings.Secure.putInt(getActivity().getContentResolver(), Settings.Secure.ADB_ENABLED, 1); } else { // Reset the toggle mEnableAdb.setChecked(false); } } else if (dialog == mEnableDialog) { if (which == DialogInterface.BUTTON_POSITIVE) { mDialogClicked = true; Settings.Secure.putInt(getActivity().getContentResolver(), Settings.Secure.DEVELOPMENT_SETTINGS_ENABLED, 1); mLastEnabledState = true; setPrefsEnabledState(mLastEnabledState); } else { // Reset the toggle mEnabledSwitch.setChecked(false); } } } public void onDismiss(DialogInterface dialog) { // Assuming that onClick gets called first if (dialog == mAdbDialog) { if (!mDialogClicked) { mEnableAdb.setChecked(false); } mAdbDialog = null; } else if (dialog == mEnableDialog) { if (!mDialogClicked) { mEnabledSwitch.setChecked(false); } mEnableDialog = null; } } @Override public void onDestroy() { dismissDialogs(); super.onDestroy(); } }