1 /* //device/apps/Settings/src/com/android/settings/Keyguard.java 2 ** 3 ** Copyright 2006, The Android Open Source Project 4 ** 5 ** Licensed under the Apache License, Version 2.0 (the "License"); 6 ** you may not use this file except in compliance with the License. 7 ** You may obtain a copy of the License at 8 ** 9 ** http://www.apache.org/licenses/LICENSE-2.0 10 ** 11 ** Unless required by applicable law or agreed to in writing, software 12 ** distributed under the License is distributed on an "AS IS" BASIS, 13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 ** See the License for the specific language governing permissions and 15 ** limitations under the License. 16 */ 17 18 package com.android.development; 19 20 import android.app.Activity; 21 import android.app.ActivityManagerNative; 22 import android.content.Context; 23 import android.content.Intent; 24 import android.content.SharedPreferences; 25 import android.content.pm.PackageManager.NameNotFoundException; 26 import android.os.RemoteException; 27 import android.os.IBinder; 28 import android.os.Parcel; 29 import android.os.ServiceManager; 30 import android.os.ServiceManagerNative; 31 import android.provider.Settings; 32 import android.os.Bundle; 33 import android.util.Log; 34 import android.view.IWindowManager; 35 import android.view.View; 36 import android.widget.ArrayAdapter; 37 import android.widget.Button; 38 import android.widget.CheckBox; 39 import android.widget.CompoundButton; 40 import android.widget.Spinner; 41 import android.widget.Toast; 42 import android.widget.AdapterView.OnItemSelectedListener; 43 44 import java.io.FileInputStream; 45 import java.io.FileOutputStream; 46 import java.util.Map; 47 48 public class DevelopmentSettings extends Activity { 49 private static final String TAG = "DevelopmentSettings"; 50 private static final int DEBUG_APP_REQUEST = 1; 51 52 private Button mDebugAppButton; 53 private CheckBox mWaitForDebuggerCB; 54 private CheckBox mAlwaysFinishCB; 55 private CheckBox mShowLoadCB; 56 private CheckBox mShowCpuCB; 57 private CheckBox mEnableGLCB; 58 private CheckBox mShowUpdatesCB; 59 private CheckBox mShowBackgroundCB; 60 private CheckBox mShowSleepCB; 61 private CheckBox mShowXmppCB; 62 private CheckBox mCompatibilityModeCB; 63 private Spinner mMaxProcsSpinner; 64 private Spinner mWindowAnimationScaleSpinner; 65 private Spinner mTransitionAnimationScaleSpinner; 66 private Spinner mFontHintingSpinner; 67 68 private String mDebugApp; 69 private boolean mWaitForDebugger; 70 private boolean mAlwaysFinish; 71 private int mProcessLimit; 72 private boolean mShowSleep; 73 private boolean mShowXmpp; 74 private boolean mCompatibilityMode; 75 private AnimationScaleSelectedListener mWindowAnimationScale 76 = new AnimationScaleSelectedListener(0); 77 private AnimationScaleSelectedListener mTransitionAnimationScale 78 = new AnimationScaleSelectedListener(1); 79 private SharedPreferences mSharedPrefs; 80 private IWindowManager mWindowManager; 81 82 private static final boolean FONT_HINTING_ENABLED = true; 83 private static final String FONT_HINTING_FILE = "/data/misc/font-hack"; 84 85 @Override onCreate(Bundle icicle)86 public void onCreate(Bundle icicle) { 87 super.onCreate(icicle); 88 89 setContentView(R.layout.development_settings); 90 91 mDebugAppButton = (Button)findViewById(R.id.debug_app); 92 mDebugAppButton.setOnClickListener(mDebugAppClicked); 93 mWaitForDebuggerCB = (CheckBox)findViewById(R.id.wait_for_debugger); 94 mWaitForDebuggerCB.setOnClickListener(mWaitForDebuggerClicked); 95 mAlwaysFinishCB = (CheckBox)findViewById(R.id.always_finish); 96 mAlwaysFinishCB.setOnClickListener(mAlwaysFinishClicked); 97 mShowLoadCB = (CheckBox)findViewById(R.id.show_load); 98 mShowLoadCB.setOnClickListener(mShowLoadClicked); 99 mShowCpuCB = (CheckBox)findViewById(R.id.show_cpu); 100 mShowCpuCB.setOnCheckedChangeListener(new SurfaceFlingerClicker(1000)); 101 mEnableGLCB = (CheckBox)findViewById(R.id.enable_gl); 102 mEnableGLCB.getLayoutParams().height = 0; // doesn't do anything 103 mEnableGLCB.setOnCheckedChangeListener(new SurfaceFlingerClicker(1004)); 104 mShowUpdatesCB = (CheckBox)findViewById(R.id.show_updates); 105 mShowUpdatesCB.setOnCheckedChangeListener(new SurfaceFlingerClicker(1002)); 106 mShowBackgroundCB = (CheckBox)findViewById(R.id.show_background); 107 mShowBackgroundCB.setOnCheckedChangeListener(new SurfaceFlingerClicker(1003)); 108 mShowSleepCB = (CheckBox)findViewById(R.id.show_sleep); 109 mShowSleepCB.setOnClickListener(mShowSleepClicked); 110 mShowXmppCB = (CheckBox)findViewById(R.id.show_xmpp); 111 mShowXmppCB.setOnClickListener(mShowXmppClicked); 112 mCompatibilityModeCB = (CheckBox)findViewById(R.id.compatibility_mode); 113 mCompatibilityModeCB.setOnClickListener(mCompatibilityModeClicked); 114 mMaxProcsSpinner = (Spinner)findViewById(R.id.max_procs); 115 mMaxProcsSpinner.setOnItemSelectedListener(mMaxProcsChanged); 116 ArrayAdapter<String> adapter = new ArrayAdapter<String>( 117 this, 118 android.R.layout.simple_spinner_item, 119 new String[] { 120 "No App Process Limit", 121 "Max 1 App Process", 122 "Max 2 App Processes", 123 "Max 3 App Processes", 124 "Max 4 App Processes" }); 125 adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 126 mMaxProcsSpinner.setAdapter(adapter); 127 mWindowAnimationScaleSpinner = setupAnimationSpinner( 128 R.id.window_animation_scale, mWindowAnimationScale, "Window"); 129 mTransitionAnimationScaleSpinner = setupAnimationSpinner( 130 R.id.transition_animation_scale, mTransitionAnimationScale, "Transition"); 131 132 if (FONT_HINTING_ENABLED) { 133 mFontHintingSpinner = (Spinner)findViewById(R.id.font_hinting); 134 mFontHintingSpinner.setOnItemSelectedListener(mFontHintingChanged); 135 adapter = new ArrayAdapter<String>( 136 this, 137 android.R.layout.simple_spinner_item, 138 new String[] { 139 "Light Hinting", 140 "Medium Hinting" }); 141 adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 142 mFontHintingSpinner.setAdapter(adapter); 143 } 144 mSharedPrefs = getSharedPreferences("global", 0); 145 mWindowManager = IWindowManager.Stub.asInterface(ServiceManager.getService("window")); 146 } 147 setupAnimationSpinner(int resid, AnimationScaleSelectedListener listener, String name)148 Spinner setupAnimationSpinner(int resid, 149 AnimationScaleSelectedListener listener, String name) { 150 Spinner spinner = (Spinner)findViewById(resid); 151 spinner.setOnItemSelectedListener(listener); 152 ArrayAdapter adapter = new ArrayAdapter<String>( 153 this, 154 android.R.layout.simple_spinner_item, 155 new String[] { 156 name + " Animation Scale 1x", 157 name + " Animation Scale 2x", 158 name + " Animation Scale 5x", 159 name + " Animation Scale 10x", 160 name + " Animation Off" }); 161 adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 162 spinner.setAdapter(adapter); 163 listener.spinner = spinner; 164 return spinner; 165 } 166 167 @Override onResume()168 public void onResume() { 169 super.onResume(); 170 updateDebugOptions(); 171 updateFinishOptions(); 172 updateProcessLimitOptions(); 173 updateSharedOptions(); 174 updateFlingerOptions(); 175 updateSleepOptions(); 176 updateXmppOptions(); 177 updateCompatibilityOptions(); 178 179 try { 180 FileInputStream in = new FileInputStream( FONT_HINTING_FILE ); 181 int mode = in.read() - 48; 182 if (mode >= 0 && mode < 3) 183 mFontHintingSpinner.setSelection(mode); 184 in.close(); 185 } catch (Exception e) { 186 } 187 188 mWindowAnimationScale.load(); 189 mTransitionAnimationScale.load(); 190 } 191 writeDebugOptions()192 private void writeDebugOptions() { 193 try { 194 ActivityManagerNative.getDefault().setDebugApp( 195 mDebugApp, mWaitForDebugger, true); 196 } catch (RemoteException ex) { 197 } 198 } 199 updateDebugOptions()200 private void updateDebugOptions() { 201 mDebugApp = Settings.System.getString( 202 getContentResolver(), Settings.System.DEBUG_APP); 203 mWaitForDebugger = Settings.System.getInt( 204 getContentResolver(), Settings.System.WAIT_FOR_DEBUGGER, 0) != 0; 205 206 mDebugAppButton.setText( 207 mDebugApp == null || mDebugApp.length() == 0 ? "(none)" : mDebugApp); 208 mWaitForDebuggerCB.setChecked(mWaitForDebugger); 209 } 210 writeFinishOptions()211 private void writeFinishOptions() { 212 try { 213 ActivityManagerNative.getDefault().setAlwaysFinish(mAlwaysFinish); 214 } catch (RemoteException ex) { 215 } 216 } 217 updateFinishOptions()218 private void updateFinishOptions() { 219 mAlwaysFinish = Settings.System.getInt( 220 getContentResolver(), Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 221 mAlwaysFinishCB.setChecked(mAlwaysFinish); 222 } 223 writeProcessLimitOptions()224 private void writeProcessLimitOptions() { 225 try { 226 ActivityManagerNative.getDefault().setProcessLimit(mProcessLimit); 227 } catch (RemoteException ex) { 228 } 229 } 230 updateProcessLimitOptions()231 private void updateProcessLimitOptions() { 232 try { 233 mProcessLimit = ActivityManagerNative.getDefault().getProcessLimit(); 234 mMaxProcsSpinner.setSelection(mProcessLimit); 235 } catch (RemoteException ex) { 236 } 237 } 238 updateSharedOptions()239 private void updateSharedOptions() { 240 mShowLoadCB.setChecked(Settings.System.getInt(getContentResolver(), 241 Settings.System.SHOW_PROCESSES, 0) != 0); 242 } 243 writeCompatibilityOptions()244 private void writeCompatibilityOptions() { 245 Settings.System.putInt(getContentResolver(), 246 Settings.System.COMPATIBILITY_MODE, mCompatibilityMode ? 0 : 1); 247 } 248 updateCompatibilityOptions()249 private void updateCompatibilityOptions() { 250 mCompatibilityMode = Settings.System.getInt( 251 getContentResolver(), Settings.System.COMPATIBILITY_MODE, 1) == 0; 252 mCompatibilityModeCB.setChecked(mCompatibilityMode); 253 } 254 updateFlingerOptions()255 private void updateFlingerOptions() { 256 // magic communication with surface flinger. 257 try { 258 IBinder flinger = ServiceManager.getService("SurfaceFlinger"); 259 if (flinger != null) { 260 Parcel data = Parcel.obtain(); 261 Parcel reply = Parcel.obtain(); 262 data.writeInterfaceToken("android.ui.ISurfaceComposer"); 263 flinger.transact(1010, data, reply, 0); 264 int v; 265 v = reply.readInt(); 266 mShowCpuCB.setChecked(v != 0); 267 v = reply.readInt(); 268 mEnableGLCB.setChecked(v != 0); 269 v = reply.readInt(); 270 mShowUpdatesCB.setChecked(v != 0); 271 v = reply.readInt(); 272 mShowBackgroundCB.setChecked(v != 0); 273 reply.recycle(); 274 data.recycle(); 275 } 276 } catch (RemoteException ex) { 277 } 278 } 279 writeSleepOptions()280 private void writeSleepOptions() { 281 try { 282 FileOutputStream os = new FileOutputStream( 283 "/sys/devices/platform/gpio_sleep_debug/enable", true); 284 if(mShowSleep) 285 os.write(new byte[] { (byte)'1' }); 286 else 287 os.write(new byte[] { (byte)'0' }); 288 os.close(); 289 } catch (Exception e) { 290 Log.w(TAG, "Failed setting gpio_sleep_debug"); 291 } 292 } 293 updateSleepOptions()294 private void updateSleepOptions() { 295 try { 296 FileInputStream is = new FileInputStream( 297 "/sys/devices/platform/gpio_sleep_debug/enable"); 298 int character = is.read(); 299 mShowSleep = character == '1'; 300 is.close(); 301 } catch (Exception e) { 302 Log.w(TAG, "Failed reading gpio_sleep_debug"); 303 mShowSleep = false; 304 } 305 mShowSleepCB.setChecked(mShowSleep); 306 } 307 writeXmppOptions()308 private void writeXmppOptions() { 309 Settings.System.setShowGTalkServiceStatus(getContentResolver(), mShowXmpp); 310 } 311 updateXmppOptions()312 private void updateXmppOptions() { 313 mShowXmpp = Settings.System.getShowGTalkServiceStatus(getContentResolver()); 314 mShowXmppCB.setChecked(mShowXmpp); 315 } 316 317 private View.OnClickListener mDebugAppClicked = new View.OnClickListener() { 318 public void onClick(View v) { 319 Intent intent = new Intent(Intent.ACTION_MAIN); 320 intent.setClass(DevelopmentSettings.this, AppPicker.class); 321 startActivityForResult(intent, DEBUG_APP_REQUEST); 322 } 323 }; 324 325 @Override onActivityResult(int requestCode, int resultCode, Intent intent)326 public void onActivityResult(int requestCode, int resultCode, Intent intent) { 327 if (requestCode == DEBUG_APP_REQUEST && resultCode == RESULT_OK) { 328 mDebugApp = intent.getAction(); 329 writeDebugOptions(); 330 updateDebugOptions(); 331 } 332 } 333 334 private View.OnClickListener mWaitForDebuggerClicked = 335 new View.OnClickListener() { 336 public void onClick(View v) { 337 mWaitForDebugger = ((CheckBox)v).isChecked(); 338 writeDebugOptions(); 339 updateDebugOptions(); 340 } 341 }; 342 343 private View.OnClickListener mAlwaysFinishClicked = 344 new View.OnClickListener() { 345 public void onClick(View v) { 346 mAlwaysFinish = ((CheckBox)v).isChecked(); 347 writeFinishOptions(); 348 updateFinishOptions(); 349 } 350 }; 351 352 private View.OnClickListener mCompatibilityModeClicked = 353 new View.OnClickListener() { 354 public void onClick(View v) { 355 mCompatibilityMode = ((CheckBox)v).isChecked(); 356 writeCompatibilityOptions(); 357 updateCompatibilityOptions(); 358 Toast toast = Toast.makeText(DevelopmentSettings.this, 359 R.string.development_settings_compatibility_mode_toast, 360 Toast.LENGTH_LONG); 361 toast.show(); 362 } 363 }; 364 365 private View.OnClickListener mShowLoadClicked = new View.OnClickListener() { 366 public void onClick(View v) { 367 boolean value = ((CheckBox)v).isChecked(); 368 Settings.System.putInt(getContentResolver(), 369 Settings.System.SHOW_PROCESSES, value ? 1 : 0); 370 Intent service = (new Intent()) 371 .setClassName("android", "com.android.server.LoadAverageService"); 372 if (value) { 373 startService(service); 374 } else { 375 stopService(service); 376 } 377 } 378 }; 379 380 private class SurfaceFlingerClicker implements CheckBox.OnCheckedChangeListener { SurfaceFlingerClicker(int code)381 SurfaceFlingerClicker(int code) { 382 mCode = code; 383 } 384 onCheckedChanged(CompoundButton buttonView, boolean isChecked)385 public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 386 try { 387 IBinder flinger = ServiceManager.getService("SurfaceFlinger"); 388 if (flinger != null) { 389 Parcel data = Parcel.obtain(); 390 data.writeInterfaceToken("android.ui.ISurfaceComposer"); 391 data.writeInt(isChecked ? 1 : 0); 392 flinger.transact(mCode, data, null, 0); 393 data.recycle(); 394 395 updateFlingerOptions(); 396 } 397 } catch (RemoteException ex) { 398 } 399 } 400 401 final int mCode; 402 } 403 404 private View.OnClickListener mShowSleepClicked = 405 new View.OnClickListener() { 406 public void onClick(View v) { 407 mShowSleep = ((CheckBox)v).isChecked(); 408 writeSleepOptions(); 409 updateSleepOptions(); 410 } 411 }; 412 413 private View.OnClickListener mShowXmppClicked = new View.OnClickListener() { 414 public void onClick(View v) { 415 mShowXmpp = ((CheckBox)v).isChecked(); 416 // can streamline these calls, but keeping consistent with the 417 // other development settings code. 418 writeXmppOptions(); 419 updateXmppOptions(); 420 } 421 }; 422 423 private Spinner.OnItemSelectedListener mMaxProcsChanged 424 = new Spinner.OnItemSelectedListener() { 425 public void onItemSelected(android.widget.AdapterView av, View v, 426 int position, long id) { 427 mProcessLimit = position; 428 writeProcessLimitOptions(); 429 } 430 431 public void onNothingSelected(android.widget.AdapterView av) { 432 } 433 }; 434 435 private Spinner.OnItemSelectedListener mFontHintingChanged 436 = new Spinner.OnItemSelectedListener() { 437 public void onItemSelected(android.widget.AdapterView av, View v, 438 int position, long id) { 439 try { 440 FileOutputStream out = new FileOutputStream( FONT_HINTING_FILE ); 441 out.write(position+48); 442 out.close(); 443 } catch (Exception e) { 444 Log.w(TAG, "Failed to write font hinting settings to /data/misc/font-hack"); 445 } 446 } 447 448 public void onNothingSelected(android.widget.AdapterView av) { 449 } 450 }; 451 452 class AnimationScaleSelectedListener implements OnItemSelectedListener { 453 final int which; 454 float scale; 455 Spinner spinner; 456 AnimationScaleSelectedListener(int _which)457 AnimationScaleSelectedListener(int _which) { 458 which = _which; 459 } 460 load()461 void load() { 462 try { 463 scale = mWindowManager.getAnimationScale(which); 464 465 if (scale > 0.1f && scale < 2.0f) { 466 spinner.setSelection(0); 467 } else if (scale >= 2.0f && scale < 3.0f) { 468 spinner.setSelection(1); 469 } else if (scale >= 4.9f && scale < 6.0f) { 470 spinner.setSelection(2); 471 } else if (scale >= 9.9f && scale < 11.0f) { 472 spinner.setSelection(3); 473 } else { 474 spinner.setSelection(4); 475 } 476 } catch (RemoteException e) { 477 } 478 } 479 onItemSelected(android.widget.AdapterView av, View v, int position, long id)480 public void onItemSelected(android.widget.AdapterView av, View v, 481 int position, long id) { 482 switch (position) { 483 case 0: scale = 1.0f; break; 484 case 1: scale = 2.0f; break; 485 case 2: scale = 5.0f; break; 486 case 3: scale = 10.0f; break; 487 case 4: scale = 0.0f; break; 488 default: break; 489 } 490 491 try { 492 mWindowManager.setAnimationScale(which, scale); 493 } catch (RemoteException e) { 494 } 495 } 496 onNothingSelected(android.widget.AdapterView av)497 public void onNothingSelected(android.widget.AdapterView av) { 498 } 499 } 500 } 501