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