StrictModeActivity.java revision 9b6c0ab8ab190f3430a395edf689bf4d56c7c57d
1/* 2 * Copyright (C) 2010 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.strictmodetest; 18 19import android.app.Activity; 20import android.content.ComponentName; 21import android.content.ContentQueryMap; 22import android.content.ContentResolver; 23import android.content.ContentValues; 24import android.content.Context; 25import android.content.IContentProvider; 26import android.content.Intent; 27import android.content.ServiceConnection; 28import android.content.pm.PackageManager; 29import android.content.pm.ResolveInfo; 30import android.content.res.Configuration; 31import android.content.res.Resources; 32import android.database.Cursor; 33import android.database.Cursor; 34import android.database.SQLException; 35import android.database.sqlite.SQLiteDatabase; 36import android.net.LocalSocket; 37import android.net.LocalSocketAddress; 38import android.net.Uri; 39import android.os.Bundle; 40import android.os.Debug; 41import android.os.Handler; 42import android.os.IBinder; 43import android.os.Parcel; 44import android.os.RemoteException; 45import android.os.ServiceManager; 46import android.os.StrictMode; 47import android.os.SystemClock; 48import android.telephony.TelephonyManager; 49import android.text.TextUtils; 50import android.util.AndroidException; 51import android.util.Config; 52import android.util.Log; 53import android.view.View; 54import android.widget.Button; 55import android.widget.CheckBox; 56import android.widget.TextView; 57 58import org.apache.http.HttpResponse; 59import org.apache.http.client.methods.HttpUriRequest; 60import org.apache.http.client.methods.HttpGet; 61import org.apache.http.impl.client.DefaultHttpClient; 62 63import java.io.File; 64import java.io.FileInputStream; 65import java.io.FileOutputStream; 66import java.io.IOException; 67import java.io.InputStream; 68import java.io.OutputStream; 69import java.io.RandomAccessFile; 70import java.net.InetAddress; 71import java.net.URL; 72 73public class StrictModeActivity extends Activity { 74 75 private static final String TAG = "StrictModeActivity"; 76 private static final Uri SYSTEM_SETTINGS_URI = Uri.parse("content://settings/system"); 77 78 private ContentResolver cr; 79 80 private final static class SimpleConnection implements ServiceConnection { 81 public IService stub = null; 82 public void onServiceConnected(ComponentName name, IBinder service) { 83 stub = IService.Stub.asInterface(service); 84 Log.v(TAG, "Service connected: " + name); 85 } 86 public void onServiceDisconnected(ComponentName name) { 87 stub = null; 88 Log.v(TAG, "Service disconnected: " + name); 89 } 90 } 91 92 private final SimpleConnection mLocalServiceConn = new SimpleConnection(); 93 private final SimpleConnection mRemoteServiceConn = new SimpleConnection(); 94 95 /** Called when the activity is first created. */ 96 @Override 97 public void onCreate(Bundle savedInstanceState) { 98 super.onCreate(savedInstanceState); 99 setContentView(R.layout.main); 100 101 cr = getContentResolver(); 102 final SQLiteDatabase db = openOrCreateDatabase("foo.db", MODE_PRIVATE, null); 103 104 final Button readButton = (Button) findViewById(R.id.read_button); 105 readButton.setOnClickListener(new View.OnClickListener() { 106 public void onClick(View v) { 107 Cursor c = null; 108 try { 109 c = db.rawQuery("SELECT * FROM foo", null); 110 } finally { 111 if (c != null) c.close(); 112 } 113 } 114 }); 115 116 final Button writeButton = (Button) findViewById(R.id.write_button); 117 writeButton.setOnClickListener(new View.OnClickListener() { 118 public void onClick(View v) { 119 db.execSQL("CREATE TABLE IF NOT EXISTS FOO (a INT)"); 120 } 121 }); 122 123 final Button dnsButton = (Button) findViewById(R.id.dns_button); 124 dnsButton.setOnClickListener(new View.OnClickListener() { 125 public void onClick(View v) { 126 Log.d(TAG, "Doing DNS lookup for www.l.google.com... " 127 + "(may be cached by InetAddress)"); 128 try { 129 InetAddress[] addrs = InetAddress.getAllByName("www.l.google.com"); 130 for (int i = 0; i < addrs.length; ++i) { 131 Log.d(TAG, "got: " + addrs[i]); 132 } 133 } catch (java.net.UnknownHostException e) { 134 Log.d(TAG, "DNS error: " + e); 135 } 136 } 137 }); 138 139 final Button httpButton = (Button) findViewById(R.id.http_button); 140 httpButton.setOnClickListener(new View.OnClickListener() { 141 public void onClick(View v) { 142 try { 143 // Note: not using AndroidHttpClient, as that comes with its 144 // own pre-StrictMode network-on-Looper thread check. The 145 // intent of this test is that we test the network stack's 146 // instrumentation for StrictMode instead. 147 DefaultHttpClient httpClient = new DefaultHttpClient(); 148 HttpResponse res = httpClient.execute( 149 new HttpGet("http://www.android.com/favicon.ico")); 150 Log.d(TAG, "Fetched http response: " + res); 151 } catch (IOException e) { 152 Log.d(TAG, "HTTP fetch error: " + e); 153 } 154 } 155 }); 156 157 final Button http2Button = (Button) findViewById(R.id.http2_button); 158 http2Button.setOnClickListener(new View.OnClickListener() { 159 public void onClick(View v) { 160 try { 161 // Usually this ends up tripping in DNS resolution, 162 // so see http3Button below, which connects directly to an IP 163 InputStream is = new URL("http://www.android.com/") 164 .openConnection() 165 .getInputStream(); 166 Log.d(TAG, "Got input stream: " + is); 167 } catch (IOException e) { 168 Log.d(TAG, "HTTP fetch error: " + e); 169 } 170 } 171 }); 172 173 final Button http3Button = (Button) findViewById(R.id.http3_button); 174 http3Button.setOnClickListener(new View.OnClickListener() { 175 public void onClick(View v) { 176 try { 177 // One of Google's web IPs, as of 2010-06-16.... 178 InputStream is = new URL("http://74.125.19.14/") 179 .openConnection() 180 .getInputStream(); 181 Log.d(TAG, "Got input stream: " + is); 182 } catch (IOException e) { 183 Log.d(TAG, "HTTP fetch error: " + e); 184 } 185 } 186 }); 187 188 final Button binderLocalButton = (Button) findViewById(R.id.binder_local_button); 189 binderLocalButton.setOnClickListener(new View.OnClickListener() { 190 public void onClick(View v) { 191 try { 192 boolean value = mLocalServiceConn.stub.doDiskWrite(123 /* dummy */); 193 Log.d(TAG, "local writeToDisk returned: " + value); 194 } catch (RemoteException e) { 195 Log.d(TAG, "local binderButton error: " + e); 196 } 197 } 198 }); 199 200 final Button binderRemoteButton = (Button) findViewById(R.id.binder_remote_button); 201 binderRemoteButton.setOnClickListener(new View.OnClickListener() { 202 public void onClick(View v) { 203 try { 204 boolean value = mRemoteServiceConn.stub.doDiskWrite(123 /* dummy */); 205 Log.d(TAG, "remote writeToDisk returned: " + value); 206 } catch (RemoteException e) { 207 Log.d(TAG, "remote binderButton error: " + e); 208 } 209 } 210 }); 211 212 final Button binderCheckButton = (Button) findViewById(R.id.binder_check_button); 213 binderCheckButton.setOnClickListener(new View.OnClickListener() { 214 public void onClick(View v) { 215 int policy; 216 try { 217 policy = mLocalServiceConn.stub.getThreadPolicy(); 218 Log.d(TAG, "local service policy: " + policy); 219 policy = mRemoteServiceConn.stub.getThreadPolicy(); 220 Log.d(TAG, "remote service policy: " + policy); 221 } catch (RemoteException e) { 222 Log.d(TAG, "binderCheckButton error: " + e); 223 } 224 } 225 }); 226 227 final Button serviceDumpButton = (Button) findViewById(R.id.service_dump); 228 serviceDumpButton.setOnClickListener(new View.OnClickListener() { 229 public void onClick(View v) { 230 Log.d(TAG, "About to do a service dump..."); 231 File file = new File("/sdcard/strictmode-service-dump.txt"); 232 FileOutputStream output = null; 233 final int oldPolicy = StrictMode.getThreadBlockingPolicy(); 234 try { 235 StrictMode.setThreadBlockingPolicy(0); 236 output = new FileOutputStream(file); 237 StrictMode.setThreadBlockingPolicy(oldPolicy); 238 boolean dumped = Debug.dumpService("cpuinfo", 239 output.getFD(), new String[0]); 240 Log.d(TAG, "Dumped = " + dumped); 241 } catch (IOException e) { 242 Log.e(TAG, "Can't dump service", e); 243 } finally { 244 StrictMode.setThreadBlockingPolicy(oldPolicy); 245 } 246 Log.d(TAG, "Did service dump."); 247 } 248 }); 249 250 final CheckBox checkNoWrite = (CheckBox) findViewById(R.id.policy_no_write); 251 final CheckBox checkNoRead = (CheckBox) findViewById(R.id.policy_no_reads); 252 final CheckBox checkNoNetwork = (CheckBox) findViewById(R.id.policy_no_network); 253 final CheckBox checkPenaltyLog = (CheckBox) findViewById(R.id.policy_penalty_log); 254 final CheckBox checkPenaltyDialog = (CheckBox) findViewById(R.id.policy_penalty_dialog); 255 final CheckBox checkPenaltyDeath = (CheckBox) findViewById(R.id.policy_penalty_death); 256 final CheckBox checkPenaltyDropBox = (CheckBox) findViewById(R.id.policy_penalty_dropbox); 257 258 View.OnClickListener changePolicy = new View.OnClickListener() { 259 public void onClick(View v) { 260 int newPolicy = 0; 261 if (checkNoWrite.isChecked()) newPolicy |= StrictMode.DISALLOW_DISK_WRITE; 262 if (checkNoRead.isChecked()) newPolicy |= StrictMode.DISALLOW_DISK_READ; 263 if (checkNoNetwork.isChecked()) newPolicy |= StrictMode.DISALLOW_NETWORK; 264 if (checkPenaltyLog.isChecked()) newPolicy |= StrictMode.PENALTY_LOG; 265 if (checkPenaltyDialog.isChecked()) newPolicy |= StrictMode.PENALTY_DIALOG; 266 if (checkPenaltyDeath.isChecked()) newPolicy |= StrictMode.PENALTY_DEATH; 267 if (checkPenaltyDropBox.isChecked()) newPolicy |= StrictMode.PENALTY_DROPBOX; 268 Log.v(TAG, "Changing policy to: " + newPolicy); 269 StrictMode.setThreadBlockingPolicy(newPolicy); 270 } 271 }; 272 checkNoWrite.setOnClickListener(changePolicy); 273 checkNoRead.setOnClickListener(changePolicy); 274 checkNoNetwork.setOnClickListener(changePolicy); 275 checkPenaltyLog.setOnClickListener(changePolicy); 276 checkPenaltyDialog.setOnClickListener(changePolicy); 277 checkPenaltyDeath.setOnClickListener(changePolicy); 278 checkPenaltyDropBox.setOnClickListener(changePolicy); 279 } 280 281 private void fileReadLoop() { 282 RandomAccessFile raf = null; 283 File filename = getFileStreamPath("test.dat"); 284 try { 285 long sumNanos = 0; 286 byte[] buf = new byte[512]; 287 288 //raf = new RandomAccessFile(filename, "rw"); 289 //raf.write(buf); 290 //raf.close(); 291 //raf = null; 292 293 // The data's almost certainly cached -- it's not clear what we're testing here 294 raf = new RandomAccessFile(filename, "r"); 295 raf.seek(0); 296 raf.read(buf); 297 } catch (IOException e) { 298 Log.e(TAG, "File read failed", e); 299 } finally { 300 try { if (raf != null) raf.close(); } catch (IOException e) {} 301 } 302 } 303 304 // Returns milliseconds taken, or -1 on failure. 305 private long settingsWrite(int mode) { 306 Cursor c = null; 307 long startTime = SystemClock.uptimeMillis(); 308 // The database will take care of replacing duplicates. 309 try { 310 ContentValues values = new ContentValues(); 311 values.put("name", "dummy_for_testing"); 312 values.put("value", "" + startTime); 313 Uri uri = cr.insert(SYSTEM_SETTINGS_URI, values); 314 Log.v(TAG, "inserted uri: " + uri); 315 } catch (SQLException e) { 316 Log.w(TAG, "sqliteexception during write: " + e); 317 return -1; 318 } 319 long duration = SystemClock.uptimeMillis() - startTime; 320 return duration; 321 } 322 323 @Override public void onResume() { 324 super.onResume(); 325 bindService(new Intent(this, LocalService.class), 326 mLocalServiceConn, Context.BIND_AUTO_CREATE); 327 bindService(new Intent(this, RemoteService.class), 328 mRemoteServiceConn, Context.BIND_AUTO_CREATE); 329 } 330 331 @Override public void onPause() { 332 super.onPause(); 333 unbindService(mLocalServiceConn); 334 unbindService(mRemoteServiceConn); 335 } 336} 337