1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.tv.settings.system;
18
19import com.android.tv.settings.ActionBehavior;
20import com.android.tv.settings.ActionKey;
21import com.android.tv.settings.BaseSettingsActivity;
22import com.android.tv.settings.R;
23import com.android.tv.settings.util.SettingsHelper;
24import com.android.tv.settings.dialog.old.Action;
25import com.android.tv.settings.dialog.old.ActionAdapter;
26import com.android.tv.settings.dialog.old.ActionFragment;
27import com.android.tv.settings.dialog.old.ContentFragment;
28import com.android.tv.settings.dialog.old.EditTextFragment;
29
30import android.app.ActivityManagerNative;
31import android.app.ActivityThread;
32import android.bluetooth.BluetoothAdapter;
33import android.content.ContentResolver;
34import android.content.Context;
35import android.content.Intent;
36import android.content.pm.ApplicationInfo;
37import android.net.wifi.WifiManager;
38import android.os.Build;
39import android.os.Bundle;
40import android.os.IBinder;
41import android.os.Parcel;
42import android.os.PowerManager;
43import android.os.Process;
44import android.os.RemoteException;
45import android.os.ServiceManager;
46import android.os.StrictMode;
47import android.os.SystemProperties;
48import android.provider.Settings;
49import android.util.Log;
50import android.view.HardwareRenderer;
51import android.view.IWindowManager;
52import android.view.View;
53
54import java.io.BufferedWriter;
55import java.io.File;
56import java.io.FileWriter;
57import java.io.IOException;
58import java.text.Collator;
59import java.util.ArrayList;
60import java.util.Collections;
61import java.util.Comparator;
62import java.util.List;
63
64public class DeveloperOptionsActivity extends BaseSettingsActivity
65        implements ActionAdapter.Listener {
66
67    private static final String TAG = "DeveloperOptionsActivity";
68    private static final boolean DEBUG = false;
69
70    private static final int INDEX_WINDOW_ANIMATION_SCALE = 0;
71    private static final int INDEX_TRANSITION_ANIMATION_SCALE = 1;
72    private static final int INDEX_ANIMATOR_DURATION_SCALE = 2;
73    private static final String KEY_SCALE = "scale_value";
74    private static final String OPENGL_TRACES_PROPERTY = "debug.egl.trace";
75    private static final String HDCP_CHECKING_PROPERTY = "persist.sys.hdcp_checking";
76
77    private static final String HDMI_OPTIMIZATION_PROPERTY = "persist.sys.hdmi.resolution";
78
79    private static SettingsHelper mHelper;
80    private ContentResolver mContentResolver;
81    private IWindowManager mWindowManager;
82    private final List<MyApplicationInfo> mPackageInfoList = new ArrayList<MyApplicationInfo>();
83    private WifiManager mWifiManager;
84
85    @Override
86    public void onCreate(Bundle savedInstanceState) {
87        mHelper = new SettingsHelper(this);
88        mContentResolver = getContentResolver();
89        mWindowManager = IWindowManager.Stub.asInterface(ServiceManager.getService("window"));
90
91        mWifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
92
93
94        super.onCreate(savedInstanceState);
95    }
96
97    @Override
98    protected void refreshActionList() {
99        mActions.clear();
100        switch ((ActionType) mState) {
101            case DEVELOPER_OVERVIEW:
102                mActions.add(ActionType.DEVELOPER_GENERAL.toAction(mResources));
103                mActions.add(ActionType.DEVELOPER_DEBUGGING.toAction(mResources));
104                mActions.add(ActionType.DEVELOPER_INPUT.toAction(mResources));
105                mActions.add(ActionType.DEVELOPER_DRAWING.toAction(mResources));
106                mActions.add(ActionType.DEVELOPER_MONITORING.toAction(mResources));
107                mActions.add(ActionType.DEVELOPER_APPS.toAction(mResources));
108                break;
109            case DEVELOPER_GENERAL:
110                mActions.add(ActionType.DEVELOPER_GENERAL_STAY_AWAKE.toAction(mResources,
111                        mHelper.getGlobalIntSetting(Settings.Global.STAY_ON_WHILE_PLUGGED_IN)));
112                if (!"user".equals(Build.TYPE)) {
113                    mActions.add(ActionType.DEVELOPER_GENERAL_HDCP_CHECKING.toAction(mResources,
114                            getHdcpStatus(mHelper.getSystemProperties(HDCP_CHECKING_PROPERTY))));
115                }
116                mActions.add(ActionType.DEVELOPER_GENERAL_HDMI_OPTIMIZATION.toAction(mResources,
117                        getHdmiOptimizationStatus(mHelper.getSystemProperties(
118                                HDMI_OPTIMIZATION_PROPERTY))));
119                mActions.add(ActionType.DEVELOPER_GENERAL_BT_HCI_LOG.toAction(mResources,
120                        mHelper.getStatusStringFromBoolean(
121                                mHelper.getSecureIntValueSettingToBoolean(
122                                        Settings.Secure.BLUETOOTH_HCI_LOG))));
123                break;
124            case EMAIL_ADDRESS:
125                break;
126            case DEVELOPER_DEBUGGING:
127                mActions.add(ActionType.DEVELOPER_DEBUGGING_USB_DEBUGGING.toAction(
128                        mResources, mHelper.getGlobalIntSetting(Settings.Global.ADB_ENABLED)));
129                mActions.add(ActionType.DEVELOPER_DEBUGGING_ALLOW_MOCK_LOCATIONS.toAction(
130                        mResources,
131                        mHelper.getSecureStatusIntSetting(Settings.Secure.ALLOW_MOCK_LOCATION)));
132                mActions.add(ActionType.DEVELOPER_DEBUGGING_SELECT_DEBUG_APP.toAction(
133                        mResources, getDebugApp()));
134                mActions.add(ActionType.DEVELOPER_DEBUGGING_WAIT_FOR_DEBUGGER.toAction(
135                        mResources,
136                        mHelper.getGlobalIntSetting(Settings.Global.WAIT_FOR_DEBUGGER)));
137                mActions.add(
138                        ActionType.DEVELOPER_DEBUGGING_VERIFY_APPS_OVER_USB.toAction(mResources,
139                                mHelper.getGlobalIntSetting(
140                                        Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB)));
141                mActions.add(
142                        ActionType.DEVELOPER_DEBUGGING_WIFI_VERBOSE_LOGGING.toAction(mResources,
143                                mWifiManager.getVerboseLoggingLevel() > 0 ? "On" : "Off"));
144                break;
145            case DEVELOPER_INPUT:
146                mActions.add(ActionType.DEVELOPER_INPUT_SHOW_TOUCHES.toAction(
147                        mResources, mHelper.getSystemIntSetting(Settings.System.SHOW_TOUCHES)));
148                mActions.add(ActionType.DEVELOPER_INPUT_POINTER_LOCATION.toAction(
149                        mResources, mHelper.getSystemIntSetting(Settings.System.POINTER_LOCATION)));
150                break;
151            case DEVELOPER_GENERAL_REBOOT:
152                mActions.add(ActionType.OK.toAction(mResources));
153                mActions.add(ActionType.CANCEL.toAction(mResources));
154                break;
155            case DEVELOPER_GENERAL_STAY_AWAKE:
156            case DEVELOPER_DEBUGGING_USB_DEBUGGING:
157            case DEVELOPER_GENERAL_BT_HCI_LOG:
158            case DEVELOPER_DEBUGGING_VERIFY_APPS_OVER_USB:
159            case DEVELOPER_DEBUGGING_WIFI_VERBOSE_LOGGING:
160            case DEVELOPER_DEBUGGING_ALLOW_MOCK_LOCATIONS:
161            case DEVELOPER_DEBUGGING_WAIT_FOR_DEBUGGER:
162            case DEVELOPER_INPUT_SHOW_TOUCHES:
163            case DEVELOPER_INPUT_POINTER_LOCATION:
164            case DEVELOPER_DRAWING_SHOW_GPU_VIEW_UPDATES:
165            case DEVELOPER_DRAWING_SHOW_HARDWARE_LAYER:
166            case DEVELOPER_DRAWING_SHOW_LAYOUT_BOUNDS:
167            case DEVELOPER_DRAWING_SHOW_SURFACE_UPDATES:
168            case DEVELOPER_APPS_DONT_KEEP_ACTIVITIES:
169            case DEVELOPER_APPS_SHOW_ALL_ANRS:
170            case DEVELOPER_MONITORING_SHOW_CPU_USAGE:
171            case DEVELOPER_MONITORING_STRICT_MODE_ENABLED:
172                mActions = getEnableActions(((ActionType) mState).name(), getProperty());
173                break;
174            case DEVELOPER_DRAWING:
175                mActions.add(ActionType.DEVELOPER_DRAWING_SHOW_LAYOUT_BOUNDS.toAction(
176                        mResources,
177                        mHelper.getSystemBooleanProperties(View.DEBUG_LAYOUT_PROPERTY)));
178                mActions.add(
179                        ActionType.DEVELOPER_DRAWING_SHOW_GPU_VIEW_UPDATES.toAction(
180                                mResources, mHelper.getSystemBooleanProperties(
181                                        HardwareRenderer.DEBUG_DIRTY_REGIONS_PROPERTY)));
182                mActions.add(ActionType.DEVELOPER_DRAWING_SHOW_GPU_OVERDRAW.toAction(
183                        mResources, getGpuOverdrawLabel()));
184                mActions.add(ActionType.DEVELOPER_DRAWING_SHOW_HARDWARE_LAYER.toAction(
185                        mResources, mHelper.getSystemBooleanProperties(
186                                HardwareRenderer.DEBUG_SHOW_LAYERS_UPDATES_PROPERTY)));
187                mActions.add(
188                        ActionType.DEVELOPER_DRAWING_SHOW_SURFACE_UPDATES.toAction(
189                                mResources, mHelper.getStatusStringFromBoolean(
190                                        getShowUpdatesOption())));
191                mActions.add(
192                        ActionType.DEVELOPER_DRAWING_WINDOW_ANIMATION_SCALE.toAction(mResources,
193                                getAnimationScaleValue(INDEX_WINDOW_ANIMATION_SCALE) + ""));
194                mActions.add(ActionType.DEVELOPER_DRAWING_TRANSITION_ANIMATION_SCALE.toAction(
195                        mResources, getAnimationScaleValue(INDEX_TRANSITION_ANIMATION_SCALE) + ""));
196                mActions.add(
197                        ActionType.DEVELOPER_DRAWING_ANIMATOR_DURATION_SCALE.toAction(mResources,
198                                getAnimationScaleValue(INDEX_ANIMATOR_DURATION_SCALE) + ""));
199                break;
200            case DEVELOPER_DEBUGGING_SELECT_DEBUG_APP:
201                mActions = getApps();
202                break;
203            case DEVELOPER_GENERAL_HDCP_CHECKING:
204                mActions = Action.createActionsFromArrays(
205                        mResources.getStringArray(R.array.hdcp_checking_values),
206                        mResources.getStringArray(R.array.hdcp_checking_summaries),
207                        1 /* non zero check set ID */,
208                        mHelper.getSystemProperties(HDCP_CHECKING_PROPERTY));
209                break;
210            case DEVELOPER_GENERAL_HDMI_OPTIMIZATION:
211                mActions = Action.createActionsFromArrays(
212                        mResources.getStringArray(R.array.hdmi_optimization_values),
213                        mResources.getStringArray(R.array.hdmi_optimization_entries),
214                        1 /* non zero check set ID */,
215                        mHelper.getSystemProperties(HDMI_OPTIMIZATION_PROPERTY));
216                break;
217            case DEVELOPER_DRAWING_ANIMATOR_DURATION_SCALE:
218                mActions = getAnimationScaleActions(INDEX_ANIMATOR_DURATION_SCALE);
219                break;
220            case DEVELOPER_DRAWING_TRANSITION_ANIMATION_SCALE:
221                mActions = getAnimationScaleActions(INDEX_TRANSITION_ANIMATION_SCALE);
222                break;
223            case DEVELOPER_DRAWING_WINDOW_ANIMATION_SCALE:
224                mActions = getAnimationScaleActions(INDEX_WINDOW_ANIMATION_SCALE);
225                break;
226            case DEVELOPER_MONITORING_PROFILE_GPU_RENDERING:
227                mActions = Action.createActionsFromArrays(
228                        mResources.getStringArray(R.array.track_frame_time_values),
229                        mResources.getStringArray(R.array.track_frame_time_entries));
230                break;
231            case DEVELOPER_DRAWING_SHOW_GPU_OVERDRAW:
232                mActions = Action.createActionsFromArrays(
233                        mResources.getStringArray(R.array.debug_hw_overdraw_values),
234                        mResources.getStringArray(R.array.debug_hw_overdraw_entries), 1,
235                        getGpuOverdrawValue());
236                break;
237            case DEVELOPER_MONITORING_ENABLE_TRACES:
238                mActions = Action.createActionsFromArrays(
239                        mResources.getStringArray(R.array.enable_opengl_traces_values),
240                        mResources.getStringArray(R.array.enable_opengl_traces_entries));
241                break;
242            case DEVELOPER_APPS_BACKGROUND_PROCESS_LIMIT:
243                mActions = Action.createActionsFromArrays(
244                        mResources.getStringArray(R.array.app_process_limit_values),
245                        mResources.getStringArray(R.array.app_process_limit_entries));
246                break;
247            case DEVELOPER_MONITORING:
248                mActions.add(
249                        ActionType.DEVELOPER_MONITORING_STRICT_MODE_ENABLED.toAction(
250                                mResources, mHelper.getStatusStringFromBoolean(
251                                        SystemProperties.getBoolean(StrictMode.VISUAL_PROPERTY,
252                                                false))));
253                mActions.add(ActionType.DEVELOPER_MONITORING_SHOW_CPU_USAGE.toAction(
254                        mResources, mHelper.getGlobalIntSetting(Settings.Global.SHOW_PROCESSES)));
255                mActions.add(
256                        ActionType.DEVELOPER_MONITORING_PROFILE_GPU_RENDERING.toAction(mResources,
257                                SystemProperties.get(HardwareRenderer.PROFILE_PROPERTY)));
258                mActions.add(ActionType.DEVELOPER_MONITORING_ENABLE_TRACES.toAction(
259                        mResources, SystemProperties.get(OPENGL_TRACES_PROPERTY)));
260                break;
261            case DEVELOPER_APPS:
262                mActions.add(ActionType.DEVELOPER_APPS_DONT_KEEP_ACTIVITIES.toAction(
263                        mResources, mHelper.getGlobalIntSetting(
264                                Settings.Global.ALWAYS_FINISH_ACTIVITIES)));
265                mActions.add(
266                        ActionType.DEVELOPER_APPS_BACKGROUND_PROCESS_LIMIT.toAction(
267                                mResources, getAppProcessLimit() + ""));
268                mActions.add(ActionType.DEVELOPER_APPS_SHOW_ALL_ANRS.toAction(
269                        mResources,
270                        mHelper.getSecureStatusIntSetting(Settings.Secure.ANR_SHOW_BACKGROUND)));
271                break;
272            default:
273                break;
274        }
275    }
276
277    @Override
278    protected void updateView() {
279        refreshActionList();
280
281        switch ((ActionType) mState) {
282            case DEVELOPER_OVERVIEW:
283                setView(R.string.system_developer_options, R.string.settings_app_name, 0,
284                        R.drawable.ic_settings_developeroptions);
285                break;
286            case DEVELOPER_GENERAL:
287                setView(R.string.system_general, R.string.system_developer_options, 0, 0);
288                break;
289            case EMAIL_ADDRESS:
290                mContentFragment = EditTextFragment.newInstance(
291                        mResources.getString(R.string.system_email_address));
292                mActionFragment = ActionFragment.newInstance(mActions);
293                setContentAndActionFragments(mContentFragment, mActionFragment);
294                break;
295            case DEVELOPER_DEBUGGING:
296                setView(R.string.system_debugging, R.string.system_developer_options, 0, 0);
297                break;
298            case DEVELOPER_INPUT:
299                setView(R.string.system_input, R.string.system_developer_options, 0, 0);
300                break;
301            case DEVELOPER_GENERAL_STAY_AWAKE:
302            case DEVELOPER_GENERAL_REBOOT:
303            case DEVELOPER_DEBUGGING_USB_DEBUGGING:
304            case DEVELOPER_GENERAL_BT_HCI_LOG:
305            case DEVELOPER_DEBUGGING_VERIFY_APPS_OVER_USB:
306            case DEVELOPER_DEBUGGING_WIFI_VERBOSE_LOGGING:
307            case DEVELOPER_DEBUGGING_ALLOW_MOCK_LOCATIONS:
308            case DEVELOPER_DEBUGGING_WAIT_FOR_DEBUGGER:
309            case DEVELOPER_INPUT_SHOW_TOUCHES:
310            case DEVELOPER_INPUT_POINTER_LOCATION:
311            case DEVELOPER_DRAWING_SHOW_GPU_VIEW_UPDATES:
312            case DEVELOPER_DRAWING_SHOW_GPU_OVERDRAW:
313            case DEVELOPER_DRAWING_SHOW_HARDWARE_LAYER:
314            case DEVELOPER_DRAWING_SHOW_LAYOUT_BOUNDS:
315            case DEVELOPER_DRAWING_SHOW_SURFACE_UPDATES:
316            case DEVELOPER_APPS_DONT_KEEP_ACTIVITIES:
317            case DEVELOPER_APPS_SHOW_ALL_ANRS:
318            case DEVELOPER_MONITORING_SHOW_CPU_USAGE:
319            case DEVELOPER_MONITORING_STRICT_MODE_ENABLED:
320                setView(((ActionType) mState).getTitle(mResources), getPrevState() != null ?
321                        ((ActionType) getPrevState()).getTitle(mResources) : null,
322                        ((ActionType) mState).getDescription(mResources), 0);
323                break;
324            case DEVELOPER_DRAWING:
325                setView(R.string.system_drawing, R.string.system_developer_options, 0, 0);
326                break;
327            case DEVELOPER_DEBUGGING_SELECT_DEBUG_APP:
328                setView(R.string.system_select_debug_app, R.string.system_debugging, 0, 0);
329                break;
330            case DEVELOPER_GENERAL_HDCP_CHECKING:
331                setView(R.string.system_hdcp_checking, R.string.system_general, 0, 0);
332                break;
333            case DEVELOPER_GENERAL_HDMI_OPTIMIZATION:
334                setView(R.string.system_hdmi_optimization, R.string.system_general,
335                        R.string.system_desc_hdmi_optimization, 0);
336                break;
337            case DEVELOPER_DRAWING_ANIMATOR_DURATION_SCALE:
338                setView(R.string.system_animator_duration_scale, R.string.system_drawing, 0, 0);
339                break;
340            case DEVELOPER_DRAWING_TRANSITION_ANIMATION_SCALE:
341                setView(R.string.system_transition_animation_scale, R.string.system_drawing, 0, 0);
342                break;
343            case DEVELOPER_DRAWING_WINDOW_ANIMATION_SCALE:
344                setView(R.string.system_window_animation_scale, R.string.system_drawing, 0, 0);
345                break;
346            case DEVELOPER_MONITORING_PROFILE_GPU_RENDERING:
347                setView(R.string.system_profile_gpu_rendering, R.string.system_monitoring, 0, 0);
348                break;
349            case DEVELOPER_MONITORING_ENABLE_TRACES:
350                setView(R.string.system_enable_traces, R.string.system_developer_options, 0, 0);
351                break;
352            case DEVELOPER_APPS_BACKGROUND_PROCESS_LIMIT:
353                setView(R.string.system_background_process_limit, R.string.system_apps, 0, 0);
354                break;
355            case DEVELOPER_MONITORING:
356                setView(R.string.system_monitoring, R.string.system_developer_options, 0, 0);
357                break;
358            case DEVELOPER_APPS:
359                setView(R.string.system_apps, R.string.system_developer_options, 0, 0);
360                break;
361            default:
362                break;
363        }
364    }
365
366
367    @Override
368    public void onActionClicked(Action action) {
369        /*
370         * For list preferences
371         */
372        final String key = action.getKey();
373        switch ((ActionType) mState) {
374            case DEVELOPER_DEBUGGING_SELECT_DEBUG_APP:
375                setDebugApp(key);
376                goBack();
377                return;
378            case DEVELOPER_GENERAL_HDCP_CHECKING:
379                mHelper.setSystemProperties(HDCP_CHECKING_PROPERTY, key);
380                goBack();
381                return;
382            case DEVELOPER_GENERAL_HDMI_OPTIMIZATION:
383                String currentValue = mHelper.getSystemProperties(HDMI_OPTIMIZATION_PROPERTY);
384                if (!key.equals(currentValue)) {
385                    mHelper.setSystemProperties(HDMI_OPTIMIZATION_PROPERTY, key);
386                    setState(ActionType.DEVELOPER_GENERAL_REBOOT, true);
387                } else {
388                    goBack();
389                }
390                return;
391            case DEVELOPER_DRAWING_ANIMATOR_DURATION_SCALE:
392                setAnimationScaleOption(INDEX_ANIMATOR_DURATION_SCALE, action);
393                goBack();
394                return;
395            case DEVELOPER_DRAWING_TRANSITION_ANIMATION_SCALE:
396                setAnimationScaleOption(INDEX_TRANSITION_ANIMATION_SCALE, action);
397                goBack();
398                return;
399            case DEVELOPER_DRAWING_WINDOW_ANIMATION_SCALE:
400                setAnimationScaleOption(INDEX_WINDOW_ANIMATION_SCALE, action);
401                goBack();
402                return;
403            case DEVELOPER_DRAWING_SHOW_GPU_OVERDRAW:
404                mHelper.setSystemProperties(HardwareRenderer.DEBUG_OVERDRAW_PROPERTY,
405                        action.getKey());
406                goBack();
407                return;
408            case DEVELOPER_MONITORING_PROFILE_GPU_RENDERING:
409                mHelper.setSystemProperties(HardwareRenderer.PROFILE_PROPERTY, key);
410                goBack();
411                return;
412            case DEVELOPER_MONITORING_ENABLE_TRACES:
413                mHelper.setSystemProperties(OPENGL_TRACES_PROPERTY, key);
414                goBack();
415                return;
416            case DEVELOPER_APPS_BACKGROUND_PROCESS_LIMIT:
417                setAppProcessLimit(key);
418                goBack();
419                return;
420            case DEVELOPER_GENERAL_REBOOT:
421                if (ActionType.OK.toAction(mResources).getKey().equals(action.getKey())) {
422                    PowerManager manager = (PowerManager) getSystemService(POWER_SERVICE);
423                    manager.reboot(null);
424                } else {
425                    goBack();
426                }
427                return;
428            default:
429                break;
430        }
431
432        /*
433         * For regular states
434         */
435        ActionKey<ActionType, ActionBehavior> actionKey = new ActionKey<ActionType, ActionBehavior>(
436                ActionType.class, ActionBehavior.class, action.getKey());
437        final ActionType type = actionKey.getType();
438        final ActionBehavior behavior = actionKey.getBehavior();
439        if (behavior == null) {
440            Log.w(TAG, "Could not find behavior for " + action.getKey());
441            return;
442        }
443        switch (behavior) {
444            case ON:
445                setProperty(true);
446                break;
447            case OFF:
448                setProperty(false);
449                break;
450            case INIT:
451                setState(type, true);
452                break;
453            default:
454        }
455    }
456
457    @Override
458    protected void setProperty(boolean enable) {
459        switch ((ActionType) mState) {
460            case DEVELOPER_GENERAL_STAY_AWAKE:
461                mHelper.setGlobalIntSetting(Settings.Global.STAY_ON_WHILE_PLUGGED_IN, enable);
462                break;
463            case DEVELOPER_GENERAL_BT_HCI_LOG:
464                mHelper.setSecureIntSetting(Settings.Secure.BLUETOOTH_HCI_LOG, enable);
465                BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
466                adapter.configHciSnoopLog(enable);
467                break;
468            case DEVELOPER_DEBUGGING_USB_DEBUGGING:
469                mHelper.setGlobalIntSetting(Settings.Global.ADB_ENABLED, enable);
470                break;
471            case DEVELOPER_DEBUGGING_ALLOW_MOCK_LOCATIONS:
472                mHelper.setSecureIntSetting(Settings.Secure.ALLOW_MOCK_LOCATION, enable);
473                break;
474            case DEVELOPER_DEBUGGING_WAIT_FOR_DEBUGGER:
475                mHelper.setGlobalIntSetting(Settings.Global.WAIT_FOR_DEBUGGER, enable);
476                break;
477            case DEVELOPER_DEBUGGING_VERIFY_APPS_OVER_USB:
478                mHelper.setGlobalIntSetting(Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, enable);
479                break;
480            case DEVELOPER_DEBUGGING_WIFI_VERBOSE_LOGGING:
481                mWifiManager.enableVerboseLogging(enable ? 1 : 0);
482                break;
483            case DEVELOPER_INPUT_SHOW_TOUCHES:
484                mHelper.setSystemIntSetting(Settings.System.SHOW_TOUCHES, enable);
485                break;
486            case DEVELOPER_INPUT_POINTER_LOCATION:
487                mHelper.setSystemIntSetting(Settings.System.POINTER_LOCATION, enable);
488                break;
489            case DEVELOPER_DRAWING_SHOW_HARDWARE_LAYER:
490                mHelper.setSystemProperties(HardwareRenderer.DEBUG_SHOW_LAYERS_UPDATES_PROPERTY,
491                        Boolean.toString(enable));
492                break;
493            case DEVELOPER_DRAWING_SHOW_LAYOUT_BOUNDS:
494                mHelper.setSystemProperties(View.DEBUG_LAYOUT_PROPERTY, Boolean.toString(enable));
495                break;
496            case DEVELOPER_DRAWING_SHOW_SURFACE_UPDATES:
497                setShowUpdatesOption(enable);
498                break;
499            case DEVELOPER_DRAWING_SHOW_GPU_VIEW_UPDATES:
500                mHelper.setSystemProperties(
501                        HardwareRenderer.DEBUG_DIRTY_REGIONS_PROPERTY, Boolean.toString(enable));
502                break;
503            case DEVELOPER_MONITORING_SHOW_CPU_USAGE:
504                mHelper.setGlobalIntSetting(Settings.Global.SHOW_PROCESSES, enable);
505                Intent service = (new Intent()).setClassName("com.android.systemui",
506                        "com.android.systemui.LoadAverageService");
507                if (enable) {
508                    startService(service);
509                } else {
510                    stopService(service);
511                }
512                break;
513            case DEVELOPER_MONITORING_STRICT_MODE_ENABLED:
514                setStrictModeVisualOptions(enable);
515                break;
516            case DEVELOPER_APPS_DONT_KEEP_ACTIVITIES:
517                try {
518                    ActivityManagerNative.getDefault().setAlwaysFinish(enable);
519                } catch (RemoteException ex) {
520                }
521                break;
522            case DEVELOPER_APPS_SHOW_ALL_ANRS:
523                mHelper.setSecureIntSetting(Settings.Secure.ANR_SHOW_BACKGROUND, enable);
524                break;
525            default:
526                break;
527        }
528        goBack();
529    }
530
531    private boolean getProperty() {
532        switch ((ActionType) mState) {
533            case DEVELOPER_GENERAL_STAY_AWAKE:
534                return mHelper.getGlobalIntSettingToInt(Settings.Global.STAY_ON_WHILE_PLUGGED_IN) ==
535                    1;
536            case DEVELOPER_GENERAL_BT_HCI_LOG:
537                return mHelper.getSecureIntValueSettingToBoolean(Settings.Secure.BLUETOOTH_HCI_LOG);
538            case DEVELOPER_DEBUGGING_USB_DEBUGGING:
539                return mHelper.getGlobalIntSettingToInt(Settings.Global.ADB_ENABLED) == 1;
540            case DEVELOPER_DEBUGGING_ALLOW_MOCK_LOCATIONS:
541                return mHelper.getSecureIntValueSettingToBoolean(
542                        Settings.Secure.ALLOW_MOCK_LOCATION);
543            case DEVELOPER_DEBUGGING_WAIT_FOR_DEBUGGER:
544                return mHelper.getGlobalIntSettingToInt(Settings.Global.WAIT_FOR_DEBUGGER) == 1;
545            case DEVELOPER_DEBUGGING_VERIFY_APPS_OVER_USB:
546                return mHelper.getGlobalIntSettingToInt(
547                        Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB) == 1;
548            case DEVELOPER_DEBUGGING_WIFI_VERBOSE_LOGGING:
549                return mWifiManager.getVerboseLoggingLevel() > 0;
550            case DEVELOPER_INPUT_SHOW_TOUCHES:
551                return mHelper.getSystemIntSettingToBoolean(Settings.System.SHOW_TOUCHES);
552            case DEVELOPER_INPUT_POINTER_LOCATION:
553                return mHelper.getSystemIntSettingToBoolean(Settings.System.POINTER_LOCATION);
554            case DEVELOPER_DRAWING_SHOW_HARDWARE_LAYER:
555                return SystemProperties.getBoolean(
556                        HardwareRenderer.DEBUG_SHOW_LAYERS_UPDATES_PROPERTY, false);
557            case DEVELOPER_DRAWING_SHOW_LAYOUT_BOUNDS:
558                return SystemProperties.getBoolean(View.DEBUG_LAYOUT_PROPERTY, false);
559            case DEVELOPER_DRAWING_SHOW_SURFACE_UPDATES:
560                return getShowUpdatesOption();
561            case DEVELOPER_DRAWING_SHOW_GPU_VIEW_UPDATES:
562                return SystemProperties.getBoolean(
563                        HardwareRenderer.DEBUG_DIRTY_REGIONS_PROPERTY, false);
564            case DEVELOPER_MONITORING_SHOW_CPU_USAGE:
565                return mHelper.getGlobalIntSettingToInt(Settings.Global.SHOW_PROCESSES) == 1;
566            case DEVELOPER_MONITORING_STRICT_MODE_ENABLED:
567                return SystemProperties.getBoolean(StrictMode.VISUAL_PROPERTY, false);
568            case DEVELOPER_APPS_DONT_KEEP_ACTIVITIES:
569                return mHelper.getGlobalIntSettingToInt(Settings.Global.ALWAYS_FINISH_ACTIVITIES) ==
570                        1;
571            case DEVELOPER_APPS_SHOW_ALL_ANRS:
572                return mHelper.getSecureIntValueSettingToBoolean(
573                        Settings.Secure.ANR_SHOW_BACKGROUND);
574            default:
575        }
576        return false;
577    }
578
579    private ArrayList<Action> getEnableActions(String type, boolean enabled) {
580        ArrayList<Action> actions = new ArrayList<Action>();
581        actions.add(ActionBehavior.ON.toAction(ActionBehavior.getOnKey(type), mResources, enabled));
582        actions.add(ActionBehavior.OFF.toAction(ActionBehavior.getOffKey(type), mResources,
583                !enabled));
584        return actions;
585    }
586
587    class MyApplicationInfo {
588        ApplicationInfo info;
589        CharSequence label;
590    }
591
592    private ArrayList<Action> getApps() {
593        mPackageInfoList.clear();
594        List<ApplicationInfo> pkgs = getPackageManager().getInstalledApplications(0);
595        for (int i = 0; i < pkgs.size(); i++) {
596            ApplicationInfo ai = pkgs.get(i);
597            if (ai.uid == Process.SYSTEM_UID) {
598                continue;
599            }
600            // On a user build, we only allow debugging of apps that
601            // are marked as debuggable. Otherwise (for platform development)
602            // we allow all apps.
603            if ((ai.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0
604                    && "user".equals(Build.TYPE)) {
605                continue;
606            }
607            MyApplicationInfo info = new MyApplicationInfo();
608            info.info = ai;
609            info.label = info.info.loadLabel(getPackageManager()).toString();
610            mPackageInfoList.add(info);
611        }
612        Collections.sort(mPackageInfoList, sDisplayNameComparator);
613        MyApplicationInfo info = new MyApplicationInfo();
614        info.label = mResources.getString(R.string.no_application);
615        mPackageInfoList.add(0, info);
616
617        ArrayList<Action> actions = new ArrayList<Action>();
618        int totalApps = mPackageInfoList.size();
619        for (int i = 0; i < totalApps; i++) {
620            MyApplicationInfo app = mPackageInfoList.get(i);
621            if (app.info != null) {
622                actions.add(new Action.Builder()
623                        .key(app.info.packageName)
624                        .title(app.label.toString())
625                        .description(app.info.packageName)
626                        .build());
627            } else {
628                actions.add(new Action.Builder()
629                        .key("")
630                        .title(app.label.toString())
631                        .description("")
632                        .build());
633            }
634        }
635
636        return actions;
637    }
638
639    private final static Comparator<MyApplicationInfo> sDisplayNameComparator
640            = new Comparator<MyApplicationInfo>() {
641                    @Override
642                public final int
643                        compare(MyApplicationInfo a, MyApplicationInfo b) {
644                    return collator.compare(a.label, b.label);
645                }
646
647                private final Collator collator = Collator.getInstance();
648            };
649
650
651
652    private String getDebugApp() {
653        return Settings.Global.getString(mContentResolver, Settings.Global.DEBUG_APP);
654    }
655
656    private void setDebugApp(String debugApp){
657        boolean waitForDebugger =
658                mHelper.getGlobalIntSettingToInt(Settings.Global.WAIT_FOR_DEBUGGER) > 0 ? true
659                : false;
660        try {
661            ActivityManagerNative.getDefault().setDebugApp(debugApp, waitForDebugger, true);
662        } catch (RemoteException e) {
663            e.printStackTrace();
664        }
665    }
666
667    private void setShowUpdatesOption(boolean enable) {
668        try {
669            IBinder flinger = ServiceManager.getService("SurfaceFlinger");
670            if (flinger != null) {
671                Parcel data = Parcel.obtain();
672                data.writeInterfaceToken("android.ui.ISurfaceComposer");
673                final int showUpdates = enable ? 1 : 0;
674                data.writeInt(showUpdates);
675                flinger.transact(1002, data, null, 0);
676                data.recycle();
677            }
678        } catch (RemoteException ex) {
679        }
680    }
681
682    private boolean getShowUpdatesOption() {
683        // magic communication with surface flinger.
684        int showUpdates = 0;
685        try {
686            IBinder flinger = ServiceManager.getService("SurfaceFlinger");
687            if (flinger != null) {
688                Parcel data = Parcel.obtain();
689                Parcel reply = Parcel.obtain();
690                data.writeInterfaceToken("android.ui.ISurfaceComposer");
691                flinger.transact(1010, data, reply, 0);
692                @SuppressWarnings("unused")
693                int showCpu = reply.readInt();
694                @SuppressWarnings("unused")
695                int enableGL = reply.readInt();
696                showUpdates = reply.readInt();
697                reply.recycle();
698                data.recycle();
699            }
700        } catch (RemoteException ex) {
701        }
702        return showUpdates > 0;
703    }
704
705    private void setStrictModeVisualOptions(boolean enable) {
706        try {
707            mWindowManager.setStrictModeVisualIndicatorPreference(enable
708                    ? "1" : "");
709        } catch (RemoteException e) {
710        }
711    }
712
713    private ArrayList<Action> getAnimationScaleActions(int index) {
714        String[] keys = null;
715        String[] titles = null;
716        float scaleValue = getAnimationScaleValue(index);
717        switch (index) {
718            case INDEX_ANIMATOR_DURATION_SCALE:
719                keys = getResources().getStringArray(R.array.animator_duration_scale_values);
720                titles = getResources().getStringArray(R.array.animator_duration_scale_entries);
721                break;
722            case INDEX_TRANSITION_ANIMATION_SCALE:
723                keys = getResources().getStringArray(R.array.transition_animation_scale_values);
724                titles = getResources().getStringArray(R.array.transition_animation_scale_entries);
725                break;
726            case INDEX_WINDOW_ANIMATION_SCALE:
727                keys = getResources().getStringArray(R.array.window_animation_scale_values);
728                titles = getResources().getStringArray(R.array.window_animation_scale_entries);
729                break;
730            default:
731                return null;
732        }
733
734        ArrayList<Action> actions = new ArrayList<Action>();
735        for (int i = 0; i < keys.length; i++) {
736            Action.Builder builder = new Action.Builder();
737            float keyScaleValue = Float.parseFloat(keys[i]);
738            builder.key(keys[i])
739                    .title(titles[i])
740                    .checkSetId(1)
741                    .intent(new Intent().putExtra(KEY_SCALE, keyScaleValue))
742                    .checked(keyScaleValue == scaleValue);
743            actions.add(builder.build());
744        }
745        return actions;
746    }
747
748    private void setAnimationScaleOption(int which, Action action) {
749        try {
750            float scale = action != null ? action.getIntent().getFloatExtra(KEY_SCALE, 1.0f) : 1;
751            mWindowManager.setAnimationScale(which, scale);
752        } catch (RemoteException e) {
753        }
754    }
755
756    private float getAnimationScaleValue(int which) {
757        float scale = 0;
758        try {
759            scale = mWindowManager.getAnimationScale(which);
760        } catch (RemoteException e) {
761        }
762        return scale;
763    }
764
765    private String getGpuOverdrawValue() {
766        String value = SystemProperties.get(HardwareRenderer.DEBUG_OVERDRAW_PROPERTY);
767        if (value == null) {
768            value = "false"; // default value.
769        }
770        return value;
771    }
772
773    private String getGpuOverdrawLabel() {
774        // This is a little ugly, but this shouldn't be called much.
775        ArrayList<Action> actions = Action.createActionsFromArrays(
776                mResources.getStringArray(R.array.debug_hw_overdraw_values),
777                mResources.getStringArray(R.array.debug_hw_overdraw_entries), 1,
778                getGpuOverdrawValue());
779
780        for (Action action : actions) {
781            if (action.isChecked()) {
782                return action.getTitle();
783            }
784        }
785        return actions.get(0).getTitle();
786    }
787
788    private int getAppProcessLimit() {
789        try {
790            return ActivityManagerNative.getDefault().getProcessLimit();
791        } catch (RemoteException e) {
792        }
793        return 0;
794    }
795
796    private void setAppProcessLimit(Object newValue) {
797        try {
798            int limit = newValue != null ? Integer.parseInt(newValue.toString()) : -1;
799            ActivityManagerNative.getDefault().setProcessLimit(limit);
800        } catch (RemoteException e) {
801        }
802    }
803
804    @Override
805    protected Object getInitialState() {
806        return ActionType.DEVELOPER_OVERVIEW;
807    }
808
809    /**
810     * Gets the HDCP status based on string value.
811     */
812    private String getHdcpStatus(String value) {
813        // Defaults to drm-only. Needs to match with R.array.hdcp_checking_values
814        // This is matches phone DevelopmentSettings.
815        int index = 1;
816        String[] keys = getResources().getStringArray(R.array.hdcp_checking_values);
817        String[] summaries = getResources().getStringArray(R.array.hdcp_checking_summaries);
818        for (int keyIndex = 0; keyIndex < keys.length; ++keyIndex) {
819            if (keys[keyIndex].equals(value)) {
820                index = keyIndex;
821                break;
822            }
823        }
824        return summaries[index];
825    }
826
827    /**
828     * Gets HDMI optimization status based on string value.
829     */
830    private String getHdmiOptimizationStatus(String value) {
831        int index = 0;
832        String[] keys = getResources().getStringArray(R.array.hdmi_optimization_values);
833        String[] summaries = getResources().getStringArray(R.array.hdmi_optimization_entries);
834        for (int keyIndex = 0; keyIndex < keys.length; ++keyIndex) {
835            if (keys[keyIndex].equals(value)) {
836                index = keyIndex;
837                break;
838            }
839        }
840        return summaries[index];
841    }
842}
843