OSDN Git Service

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