ActivityTestMain.java revision e5c42621095a12e7d22ca5ab871dacd28c9bff41
1/*
2 * Copyright (C) 2011 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.google.android.test.activity;
18
19import java.util.ArrayList;
20import java.util.List;
21
22import android.app.Activity;
23import android.app.ActivityManager;
24import android.app.ActivityOptions;
25import android.app.AlertDialog;
26import android.app.PendingIntent;
27import android.content.ActivityNotFoundException;
28import android.content.BroadcastReceiver;
29import android.content.ComponentName;
30import android.content.ContentProviderClient;
31import android.content.Intent;
32import android.content.ServiceConnection;
33import android.graphics.BitmapFactory;
34import android.os.Bundle;
35import android.os.Handler;
36import android.os.IBinder;
37import android.os.Message;
38import android.os.RemoteException;
39import android.os.UserHandle;
40import android.os.UserManager;
41import android.graphics.Bitmap;
42import android.widget.ImageView;
43import android.widget.LinearLayout;
44import android.widget.TextView;
45import android.widget.ScrollView;
46import android.widget.Toast;
47import android.view.Menu;
48import android.view.MenuItem;
49import android.view.View;
50import android.content.Context;
51import android.content.pm.UserInfo;
52import android.content.res.Configuration;
53import android.util.Log;
54
55public class ActivityTestMain extends Activity {
56    static final String TAG = "ActivityTest";
57
58    static final String KEY_CONFIGURATION = "configuration";
59
60    ActivityManager mAm;
61    Configuration mOverrideConfig;
62    int mSecondUser;
63
64    ArrayList<ServiceConnection> mConnections = new ArrayList<ServiceConnection>();
65
66    ServiceConnection mIsolatedConnection;
67
68    static final int MSG_SPAM = 1;
69
70    final Handler mHandler = new Handler() {
71        @Override
72        public void handleMessage(Message msg) {
73            switch (msg.what) {
74                case MSG_SPAM: {
75                    boolean fg = msg.arg1 != 0;
76                    Intent intent = new Intent(ActivityTestMain.this, SpamActivity.class);
77                    Bundle options = null;
78                    if (fg) {
79                        ActivityOptions opts = ActivityOptions.makeTaskLaunchBehind();
80                        options = opts.toBundle();
81                    }
82                    startActivity(intent, options);
83                    scheduleSpam(!fg);
84                } break;
85            }
86            super.handleMessage(msg);
87        }
88    };
89
90    class BroadcastResultReceiver extends BroadcastReceiver {
91        @Override
92        public void onReceive(Context context, Intent intent) {
93            Bundle res = getResultExtras(true);
94            int user = res.getInt("user", -1);
95            Toast.makeText(ActivityTestMain.this,
96                    "Receiver executed as user "
97                    + (user >= 0 ? Integer.toString(user) : "unknown"),
98                    Toast.LENGTH_LONG).show();
99        }
100    }
101
102    private void addThumbnail(LinearLayout container, Bitmap bm,
103            final ActivityManager.RecentTaskInfo task,
104            final ActivityManager.TaskThumbnail thumbs) {
105        ImageView iv = new ImageView(this);
106        if (bm != null) {
107            iv.setImageBitmap(bm);
108        }
109        iv.setBackgroundResource(android.R.drawable.gallery_thumb);
110        int w = getResources().getDimensionPixelSize(android.R.dimen.thumbnail_width);
111        int h = getResources().getDimensionPixelSize(android.R.dimen.thumbnail_height);
112        container.addView(iv, new LinearLayout.LayoutParams(w, h));
113
114        iv.setOnClickListener(new View.OnClickListener() {
115            @Override
116            public void onClick(View v) {
117                if (task.id >= 0 && thumbs != null) {
118                    mAm.moveTaskToFront(task.id, ActivityManager.MOVE_TASK_WITH_HOME);
119                } else {
120                    try {
121                        startActivity(task.baseIntent);
122                    } catch (ActivityNotFoundException e) {
123                        Log.w("foo", "Unable to start task: " + e);
124                    }
125                }
126                buildUi();
127            }
128        });
129        iv.setOnLongClickListener(new View.OnLongClickListener() {
130            @Override
131            public boolean onLongClick(View v) {
132                if (task.id >= 0 && thumbs != null) {
133                    mAm.removeTask(task.id);
134                    buildUi();
135                    return true;
136                }
137                return false;
138            }
139        });
140    }
141
142    @Override
143    protected void onCreate(Bundle savedInstanceState) {
144        super.onCreate(savedInstanceState);
145
146        Log.i(TAG, "Referrer: " + getReferrer());
147
148        mAm = (ActivityManager)getSystemService(ACTIVITY_SERVICE);
149        if (savedInstanceState != null) {
150            mOverrideConfig = savedInstanceState.getParcelable(KEY_CONFIGURATION);
151            if (mOverrideConfig != null) {
152                applyOverrideConfiguration(mOverrideConfig);
153            }
154        }
155
156        UserManager um = (UserManager)getSystemService(Context.USER_SERVICE);
157        List<UserInfo> users = um.getUsers();
158        mSecondUser = Integer.MAX_VALUE;
159        for (UserInfo ui : users) {
160            if (ui.id != 0 && mSecondUser > ui.id) {
161                mSecondUser = ui.id;
162            }
163        }
164
165        /*
166        AlertDialog ad = new AlertDialog.Builder(this).setTitle("title").setMessage("message").create();
167        ad.getWindow().getAttributes().type = WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
168        ad.show();
169        */
170    }
171
172    @Override
173    public boolean onCreateOptionsMenu(Menu menu) {
174        menu.add("Animate!").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
175            @Override
176            public boolean onMenuItemClick(MenuItem item) {
177                AlertDialog.Builder builder = new AlertDialog.Builder(ActivityTestMain.this,
178                        R.style.SlowDialog);
179                builder.setTitle("This is a title");
180                builder.show();
181                return true;
182            }
183        });
184        menu.add("Bind!").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
185            @Override public boolean onMenuItemClick(MenuItem item) {
186                Intent intent = new Intent(ActivityTestMain.this, SingleUserService.class);
187                ServiceConnection conn = new ServiceConnection() {
188                    @Override
189                    public void onServiceConnected(ComponentName name, IBinder service) {
190                        Log.i(TAG, "Service connected " + name + " " + service);
191                    }
192                    @Override
193                    public void onServiceDisconnected(ComponentName name) {
194                        Log.i(TAG, "Service disconnected " + name);
195                    }
196                };
197                if (bindService(intent, conn, Context.BIND_AUTO_CREATE)) {
198                    mConnections.add(conn);
199                } else {
200                    Toast.makeText(ActivityTestMain.this, "Failed to bind",
201                            Toast.LENGTH_LONG).show();
202                }
203                return true;
204            }
205        });
206        menu.add("Start!").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
207            @Override public boolean onMenuItemClick(MenuItem item) {
208                Intent intent = new Intent(ActivityTestMain.this, SingleUserService.class);
209                startService(intent);
210                return true;
211            }
212        });
213        menu.add("Rebind Isolated!").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
214            @Override public boolean onMenuItemClick(MenuItem item) {
215                Intent intent = new Intent(ActivityTestMain.this, IsolatedService.class);
216                ServiceConnection conn = new ServiceConnection() {
217                    @Override
218                    public void onServiceConnected(ComponentName name, IBinder service) {
219                        Log.i(TAG, "Isolated service connected " + name + " " + service);
220                    }
221                    @Override
222                    public void onServiceDisconnected(ComponentName name) {
223                        Log.i(TAG, "Isolated service disconnected " + name);
224                    }
225                };
226                if (mIsolatedConnection != null) {
227                    Log.i(TAG, "Unbinding existing service: " + mIsolatedConnection);
228                    unbindService(mIsolatedConnection);
229                    mIsolatedConnection = null;
230                }
231                Log.i(TAG, "Binding new service: " + conn);
232                if (bindService(intent, conn, Context.BIND_AUTO_CREATE)) {
233                    mIsolatedConnection = conn;
234                } else {
235                    Toast.makeText(ActivityTestMain.this, "Failed to bind",
236                            Toast.LENGTH_LONG).show();
237                }
238                return true;
239            }
240        });
241        menu.add("Send!").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
242            @Override public boolean onMenuItemClick(MenuItem item) {
243                Intent intent = new Intent(ActivityTestMain.this, SingleUserReceiver.class);
244                sendOrderedBroadcast(intent, null, new BroadcastResultReceiver(),
245                        null, Activity.RESULT_OK, null, null);
246                return true;
247            }
248        });
249        menu.add("Call!").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
250            @Override public boolean onMenuItemClick(MenuItem item) {
251                ContentProviderClient cpl = getContentResolver().acquireContentProviderClient(
252                        SingleUserProvider.AUTHORITY);
253                Bundle res = null;
254                try {
255                    res = cpl.call("getuser", null, null);
256                } catch (RemoteException e) {
257                }
258                int user = res != null ? res.getInt("user", -1) : -1;
259                Toast.makeText(ActivityTestMain.this,
260                        "Provider executed as user "
261                        + (user >= 0 ? Integer.toString(user) : "unknown"),
262                        Toast.LENGTH_LONG).show();
263                cpl.release();
264                return true;
265            }
266        });
267        menu.add("Send to user 0!").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
268            @Override public boolean onMenuItemClick(MenuItem item) {
269                Intent intent = new Intent(ActivityTestMain.this, UserTarget.class);
270                sendOrderedBroadcastAsUser(intent, new UserHandle(0), null,
271                        new BroadcastResultReceiver(),
272                        null, Activity.RESULT_OK, null, null);
273                return true;
274            }
275        });
276        menu.add("Send to user " + mSecondUser + "!").setOnMenuItemClickListener(
277                new MenuItem.OnMenuItemClickListener() {
278            @Override public boolean onMenuItemClick(MenuItem item) {
279                Intent intent = new Intent(ActivityTestMain.this, UserTarget.class);
280                sendOrderedBroadcastAsUser(intent, new UserHandle(mSecondUser), null,
281                        new BroadcastResultReceiver(),
282                        null, Activity.RESULT_OK, null, null);
283                return true;
284            }
285        });
286        menu.add("Bind to user 0!").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
287            @Override public boolean onMenuItemClick(MenuItem item) {
288                Intent intent = new Intent(ActivityTestMain.this, ServiceUserTarget.class);
289                ServiceConnection conn = new ServiceConnection() {
290                    @Override
291                    public void onServiceConnected(ComponentName name, IBinder service) {
292                        Log.i(TAG, "Service connected " + name + " " + service);
293                    }
294                    @Override
295                    public void onServiceDisconnected(ComponentName name) {
296                        Log.i(TAG, "Service disconnected " + name);
297                    }
298                };
299                if (bindServiceAsUser(intent, conn, Context.BIND_AUTO_CREATE, UserHandle.OWNER)) {
300                    mConnections.add(conn);
301                } else {
302                    Toast.makeText(ActivityTestMain.this, "Failed to bind",
303                            Toast.LENGTH_LONG).show();
304                }
305                return true;
306            }
307        });
308        menu.add("Bind to user " + mSecondUser + "!").setOnMenuItemClickListener(
309                new MenuItem.OnMenuItemClickListener() {
310            @Override public boolean onMenuItemClick(MenuItem item) {
311                Intent intent = new Intent(ActivityTestMain.this, ServiceUserTarget.class);
312                ServiceConnection conn = new ServiceConnection() {
313                    @Override
314                    public void onServiceConnected(ComponentName name, IBinder service) {
315                        Log.i(TAG, "Service connected " + name + " " + service);
316                    }
317                    @Override
318                    public void onServiceDisconnected(ComponentName name) {
319                        Log.i(TAG, "Service disconnected " + name);
320                    }
321                };
322                if (bindServiceAsUser(intent, conn, Context.BIND_AUTO_CREATE,
323                        new UserHandle(mSecondUser))) {
324                    mConnections.add(conn);
325                } else {
326                    Toast.makeText(ActivityTestMain.this, "Failed to bind",
327                            Toast.LENGTH_LONG).show();
328                }
329                return true;
330            }
331        });
332        menu.add("Density!").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
333            @Override public boolean onMenuItemClick(MenuItem item) {
334                if (mOverrideConfig == null) {
335                    mOverrideConfig = new Configuration();
336                }
337                if (mOverrideConfig.densityDpi == Configuration.DENSITY_DPI_UNDEFINED) {
338                    mOverrideConfig.densityDpi = (getApplicationContext().getResources()
339                            .getConfiguration().densityDpi*2)/3;
340                } else {
341                    mOverrideConfig.densityDpi = Configuration.DENSITY_DPI_UNDEFINED;
342                }
343                recreate();
344                return true;
345            }
346        });
347        menu.add("HashArray").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
348            @Override public boolean onMenuItemClick(MenuItem item) {
349                ArrayMapTests.run();
350                return true;
351            }
352        });
353        menu.add("Add App Recent").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
354            @Override public boolean onMenuItemClick(MenuItem item) {
355                addAppRecents(1);
356                return true;
357            }
358        });
359        menu.add("Add App 10x Recent").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
360            @Override public boolean onMenuItemClick(MenuItem item) {
361                addAppRecents(10);
362                return true;
363            }
364        });
365        menu.add("Exclude!").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
366            @Override public boolean onMenuItemClick(MenuItem item) {
367                setExclude(true);
368                return true;
369            }
370        });
371        menu.add("Include!").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
372            @Override public boolean onMenuItemClick(MenuItem item) {
373                setExclude(false);
374                return true;
375            }
376        });
377        menu.add("Open Doc").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
378            @Override public boolean onMenuItemClick(MenuItem item) {
379                ActivityManager.AppTask task = findDocTask();
380                if (task == null) {
381                    Intent intent = new Intent(ActivityTestMain.this, DocActivity.class);
382                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT
383                            | Intent.FLAG_ACTIVITY_MULTIPLE_TASK
384                            | Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
385                    startActivity(intent);
386                } else {
387                    task.moveToFront();
388                }
389                return true;
390            }
391        });
392        menu.add("Stack Doc").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
393            @Override public boolean onMenuItemClick(MenuItem item) {
394                ActivityManager.AppTask task = findDocTask();
395                if (task != null) {
396                    ActivityManager.RecentTaskInfo recent = task.getTaskInfo();
397                    Intent intent = new Intent(ActivityTestMain.this, DocActivity.class);
398                    if (recent.id >= 0) {
399                        // Stack on top.
400                        intent.putExtra(DocActivity.LABEL, "Stacked");
401                    } else {
402                        // Start root activity.
403                        intent.putExtra(DocActivity.LABEL, "New Root");
404                    }
405                    task.startActivity(ActivityTestMain.this, intent, null);
406                }
407                return true;
408            }
409        });
410        menu.add("Spam!").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
411            @Override public boolean onMenuItemClick(MenuItem item) {
412                scheduleSpam(false);
413                return true;
414            }
415        });
416        menu.add("Track time").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
417            @Override public boolean onMenuItemClick(MenuItem item) {
418                Intent intent = new Intent(Intent.ACTION_SEND);
419                intent.setType("text/plain");
420                intent.putExtra(Intent.EXTRA_TEXT, "We are sharing this with you!");
421                ActivityOptions options = ActivityOptions.makeBasic();
422                Intent receiveIntent = new Intent(ActivityTestMain.this, TrackTimeReceiver.class);
423                receiveIntent.putExtra("something", "yeah, this is us!");
424                options.requestUsageTimeReport(PendingIntent.getBroadcast(ActivityTestMain.this,
425                        0, receiveIntent, PendingIntent.FLAG_CANCEL_CURRENT));
426                startActivity(Intent.createChooser(intent, "Who do you love?"), options.toBundle());
427                return true;
428            }
429        });
430        menu.add("Transaction fail").setOnMenuItemClickListener(
431                new MenuItem.OnMenuItemClickListener() {
432            @Override public boolean onMenuItemClick(MenuItem item) {
433                Intent intent = new Intent(Intent.ACTION_MAIN);
434                intent.putExtra("gulp", new int[1024*1024]);
435                startActivity(intent);
436                return true;
437            }
438        });
439        return true;
440    }
441
442    @Override
443    protected void onStart() {
444        super.onStart();
445        buildUi();
446    }
447
448    @Override
449    protected void onPause() {
450        super.onPause();
451        Log.i(TAG, "I'm such a slooow poor loser");
452        try {
453            Thread.sleep(500);
454        } catch (InterruptedException e) {
455        }
456        Log.i(TAG, "See?");
457    }
458
459    @Override
460    protected void onSaveInstanceState(Bundle outState) {
461        super.onSaveInstanceState(outState);
462        if (mOverrideConfig != null) {
463            outState.putParcelable(KEY_CONFIGURATION, mOverrideConfig);
464        }
465    }
466
467    @Override
468    protected void onStop() {
469        super.onStop();
470        for (ServiceConnection conn : mConnections) {
471            unbindService(conn);
472        }
473        mConnections.clear();
474        if (mIsolatedConnection != null) {
475            unbindService(mIsolatedConnection);
476            mIsolatedConnection = null;
477        }
478    }
479
480    @Override
481    protected void onDestroy() {
482        super.onDestroy();
483        mHandler.removeMessages(MSG_SPAM);
484    }
485
486    void addAppRecents(int count) {
487        ActivityManager am = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
488        Intent intent = new Intent(Intent.ACTION_MAIN);
489        intent.addCategory(Intent.CATEGORY_LAUNCHER);
490        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
491        intent.setComponent(new ComponentName(this, ActivityTestMain.class));
492        for (int i=0; i<count; i++) {
493            ActivityManager.TaskDescription desc = new ActivityManager.TaskDescription();
494            desc.setLabel("Added #" + i);
495            Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.icon);
496            if ((i&1) == 0) {
497                desc.setIcon(bitmap);
498            }
499            int taskId = am.addAppTask(this, intent, desc, bitmap);
500            Log.i(TAG, "Added new task id #" + taskId);
501        }
502    }
503
504    void setExclude(boolean exclude) {
505        ActivityManager am = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
506        List<ActivityManager.AppTask> tasks = am.getAppTasks();
507        int taskId = getTaskId();
508        for (int i=0; i<tasks.size(); i++) {
509            ActivityManager.AppTask task = tasks.get(i);
510            if (task.getTaskInfo().id == taskId) {
511                task.setExcludeFromRecents(exclude);
512            }
513        }
514    }
515
516    ActivityManager.AppTask findDocTask() {
517        ActivityManager am = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
518        List<ActivityManager.AppTask> tasks = am.getAppTasks();
519        if (tasks != null) {
520            for (int i=0; i<tasks.size(); i++) {
521                ActivityManager.AppTask task = tasks.get(i);
522                ActivityManager.RecentTaskInfo recent = task.getTaskInfo();
523                if (recent.baseIntent != null
524                        && recent.baseIntent.getComponent().getClassName().equals(
525                                DocActivity.class.getCanonicalName())) {
526                    return task;
527                }
528            }
529        }
530        return null;
531    }
532
533    void scheduleSpam(boolean fg) {
534        mHandler.removeMessages(MSG_SPAM);
535        Message msg = mHandler.obtainMessage(MSG_SPAM, fg ? 1 : 0, 0);
536        mHandler.sendMessageDelayed(msg, 500);
537    }
538
539    private View scrollWrap(View view) {
540        ScrollView scroller = new ScrollView(this);
541        scroller.addView(view, new ScrollView.LayoutParams(ScrollView.LayoutParams.MATCH_PARENT,
542                ScrollView.LayoutParams.MATCH_PARENT));
543        return scroller;
544    }
545
546    private void buildUi() {
547        LinearLayout top = new LinearLayout(this);
548        top.setOrientation(LinearLayout.VERTICAL);
549
550        List<ActivityManager.RecentTaskInfo> recents = mAm.getRecentTasks(10,
551                ActivityManager.RECENT_WITH_EXCLUDED);
552        if (recents != null) {
553            for (int i=0; i<recents.size(); i++) {
554                ActivityManager.RecentTaskInfo r = recents.get(i);
555                ActivityManager.TaskThumbnail tt = mAm.getTaskThumbnail(r.persistentId);
556                TextView tv = new TextView(this);
557                tv.setText(r.baseIntent.getComponent().flattenToShortString());
558                top.addView(tv, new LinearLayout.LayoutParams(
559                        LinearLayout.LayoutParams.WRAP_CONTENT,
560                        LinearLayout.LayoutParams.WRAP_CONTENT));
561                LinearLayout item = new LinearLayout(this);
562                item.setOrientation(LinearLayout.HORIZONTAL);
563                addThumbnail(item, tt != null ? tt.mainThumbnail : null, r, tt);
564                top.addView(item, new LinearLayout.LayoutParams(
565                        LinearLayout.LayoutParams.WRAP_CONTENT,
566                        LinearLayout.LayoutParams.WRAP_CONTENT));
567            }
568        }
569
570        setContentView(scrollWrap(top));
571    }
572}
573