ActivityTestMain.java revision a4e102ee580282dc7abeb22f4a025813e53b9431
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.makeLaunchTaskBehindAnimation();
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, ActivityManager.REMOVE_TASK_KILL_PROCESS);
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        mAm = (ActivityManager)getSystemService(ACTIVITY_SERVICE);
144        if (savedInstanceState != null) {
145            mOverrideConfig = savedInstanceState.getParcelable(KEY_CONFIGURATION);
146            if (mOverrideConfig != null) {
147                applyOverrideConfiguration(mOverrideConfig);
148            }
149        }
150
151        UserManager um = (UserManager)getSystemService(Context.USER_SERVICE);
152        List<UserInfo> users = um.getUsers();
153        mSecondUser = Integer.MAX_VALUE;
154        for (UserInfo ui : users) {
155            if (ui.id != 0 && mSecondUser > ui.id) {
156                mSecondUser = ui.id;
157            }
158        }
159
160        /*
161        AlertDialog ad = new AlertDialog.Builder(this).setTitle("title").setMessage("message").create();
162        ad.getWindow().getAttributes().type = WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
163        ad.show();
164        */
165    }
166
167    @Override
168    public boolean onCreateOptionsMenu(Menu menu) {
169        menu.add("Animate!").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
170            @Override
171            public boolean onMenuItemClick(MenuItem item) {
172                AlertDialog.Builder builder = new AlertDialog.Builder(ActivityTestMain.this,
173                        R.style.SlowDialog);
174                builder.setTitle("This is a title");
175                builder.show();
176                return true;
177            }
178        });
179        menu.add("Bind!").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
180            @Override public boolean onMenuItemClick(MenuItem item) {
181                Intent intent = new Intent(ActivityTestMain.this, SingleUserService.class);
182                ServiceConnection conn = new ServiceConnection() {
183                    @Override
184                    public void onServiceConnected(ComponentName name, IBinder service) {
185                        Log.i(TAG, "Service connected " + name + " " + service);
186                    }
187                    @Override
188                    public void onServiceDisconnected(ComponentName name) {
189                        Log.i(TAG, "Service disconnected " + name);
190                    }
191                };
192                if (bindService(intent, conn, Context.BIND_AUTO_CREATE)) {
193                    mConnections.add(conn);
194                } else {
195                    Toast.makeText(ActivityTestMain.this, "Failed to bind",
196                            Toast.LENGTH_LONG).show();
197                }
198                return true;
199            }
200        });
201        menu.add("Start!").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
202            @Override public boolean onMenuItemClick(MenuItem item) {
203                Intent intent = new Intent(ActivityTestMain.this, SingleUserService.class);
204                startService(intent);
205                return true;
206            }
207        });
208        menu.add("Send!").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
209            @Override public boolean onMenuItemClick(MenuItem item) {
210                Intent intent = new Intent(ActivityTestMain.this, SingleUserReceiver.class);
211                sendOrderedBroadcast(intent, null, new BroadcastResultReceiver(),
212                        null, Activity.RESULT_OK, null, null);
213                return true;
214            }
215        });
216        menu.add("Call!").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
217            @Override public boolean onMenuItemClick(MenuItem item) {
218                ContentProviderClient cpl = getContentResolver().acquireContentProviderClient(
219                        SingleUserProvider.AUTHORITY);
220                Bundle res = null;
221                try {
222                    res = cpl.call("getuser", null, null);
223                } catch (RemoteException e) {
224                }
225                int user = res != null ? res.getInt("user", -1) : -1;
226                Toast.makeText(ActivityTestMain.this,
227                        "Provider executed as user "
228                        + (user >= 0 ? Integer.toString(user) : "unknown"),
229                        Toast.LENGTH_LONG).show();
230                cpl.release();
231                return true;
232            }
233        });
234        menu.add("Send to user 0!").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
235            @Override public boolean onMenuItemClick(MenuItem item) {
236                Intent intent = new Intent(ActivityTestMain.this, UserTarget.class);
237                sendOrderedBroadcastAsUser(intent, new UserHandle(0), null,
238                        new BroadcastResultReceiver(),
239                        null, Activity.RESULT_OK, null, null);
240                return true;
241            }
242        });
243        menu.add("Send to user " + mSecondUser + "!").setOnMenuItemClickListener(
244                new MenuItem.OnMenuItemClickListener() {
245            @Override public boolean onMenuItemClick(MenuItem item) {
246                Intent intent = new Intent(ActivityTestMain.this, UserTarget.class);
247                sendOrderedBroadcastAsUser(intent, new UserHandle(mSecondUser), null,
248                        new BroadcastResultReceiver(),
249                        null, Activity.RESULT_OK, null, null);
250                return true;
251            }
252        });
253        menu.add("Bind to user 0!").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
254            @Override public boolean onMenuItemClick(MenuItem item) {
255                Intent intent = new Intent(ActivityTestMain.this, ServiceUserTarget.class);
256                ServiceConnection conn = new ServiceConnection() {
257                    @Override
258                    public void onServiceConnected(ComponentName name, IBinder service) {
259                        Log.i(TAG, "Service connected " + name + " " + service);
260                    }
261                    @Override
262                    public void onServiceDisconnected(ComponentName name) {
263                        Log.i(TAG, "Service disconnected " + name);
264                    }
265                };
266                if (bindServiceAsUser(intent, conn, Context.BIND_AUTO_CREATE, UserHandle.OWNER)) {
267                    mConnections.add(conn);
268                } else {
269                    Toast.makeText(ActivityTestMain.this, "Failed to bind",
270                            Toast.LENGTH_LONG).show();
271                }
272                return true;
273            }
274        });
275        menu.add("Bind to user " + mSecondUser + "!").setOnMenuItemClickListener(
276                new MenuItem.OnMenuItemClickListener() {
277            @Override public boolean onMenuItemClick(MenuItem item) {
278                Intent intent = new Intent(ActivityTestMain.this, ServiceUserTarget.class);
279                ServiceConnection conn = new ServiceConnection() {
280                    @Override
281                    public void onServiceConnected(ComponentName name, IBinder service) {
282                        Log.i(TAG, "Service connected " + name + " " + service);
283                    }
284                    @Override
285                    public void onServiceDisconnected(ComponentName name) {
286                        Log.i(TAG, "Service disconnected " + name);
287                    }
288                };
289                if (bindServiceAsUser(intent, conn, Context.BIND_AUTO_CREATE,
290                        new UserHandle(mSecondUser))) {
291                    mConnections.add(conn);
292                } else {
293                    Toast.makeText(ActivityTestMain.this, "Failed to bind",
294                            Toast.LENGTH_LONG).show();
295                }
296                return true;
297            }
298        });
299        menu.add("Density!").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
300            @Override public boolean onMenuItemClick(MenuItem item) {
301                if (mOverrideConfig == null) {
302                    mOverrideConfig = new Configuration();
303                }
304                if (mOverrideConfig.densityDpi == Configuration.DENSITY_DPI_UNDEFINED) {
305                    mOverrideConfig.densityDpi = (getApplicationContext().getResources()
306                            .getConfiguration().densityDpi*2)/3;
307                } else {
308                    mOverrideConfig.densityDpi = Configuration.DENSITY_DPI_UNDEFINED;
309                }
310                recreate();
311                return true;
312            }
313        });
314        menu.add("HashArray").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
315            @Override public boolean onMenuItemClick(MenuItem item) {
316                ArrayMapTests.run();
317                return true;
318            }
319        });
320        menu.add("Add App Recent").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
321            @Override public boolean onMenuItemClick(MenuItem item) {
322                addAppRecents(1);
323                return true;
324            }
325        });
326        menu.add("Add App 10x Recent").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
327            @Override public boolean onMenuItemClick(MenuItem item) {
328                addAppRecents(10);
329                return true;
330            }
331        });
332        menu.add("Exclude!").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
333            @Override public boolean onMenuItemClick(MenuItem item) {
334                setExclude(true);
335                return true;
336            }
337        });
338        menu.add("Include!").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
339            @Override public boolean onMenuItemClick(MenuItem item) {
340                setExclude(false);
341                return true;
342            }
343        });
344        menu.add("Open Doc").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
345            @Override public boolean onMenuItemClick(MenuItem item) {
346                ActivityManager.AppTask task = findDocTask();
347                if (task == null) {
348                    Intent intent = new Intent(ActivityTestMain.this, DocActivity.class);
349                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT
350                            | Intent.FLAG_ACTIVITY_MULTIPLE_TASK
351                            | Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
352                    startActivity(intent);
353                } else {
354                    task.moveToFront();
355                }
356                return true;
357            }
358        });
359        menu.add("Stack Doc").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
360            @Override public boolean onMenuItemClick(MenuItem item) {
361                ActivityManager.AppTask task = findDocTask();
362                if (task != null) {
363                    ActivityManager.RecentTaskInfo recent = task.getTaskInfo();
364                    Intent intent = new Intent(ActivityTestMain.this, DocActivity.class);
365                    if (recent.id >= 0) {
366                        // Stack on top.
367                        intent.putExtra(DocActivity.LABEL, "Stacked");
368                    } else {
369                        // Start root activity.
370                        intent.putExtra(DocActivity.LABEL, "New Root");
371                    }
372                    task.startActivity(ActivityTestMain.this, intent, null);
373                }
374                return true;
375            }
376        });
377        menu.add("Spam!").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
378            @Override public boolean onMenuItemClick(MenuItem item) {
379                scheduleSpam(false);
380                return true;
381            }
382        });
383        return true;
384    }
385
386    @Override
387    protected void onStart() {
388        super.onStart();
389        buildUi();
390    }
391
392    @Override
393    protected void onPause() {
394        super.onPause();
395        Log.i(TAG, "I'm such a slooow poor loser");
396        try {
397            Thread.sleep(500);
398        } catch (InterruptedException e) {
399        }
400        Log.i(TAG, "See?");
401    }
402
403    @Override
404    protected void onSaveInstanceState(Bundle outState) {
405        super.onSaveInstanceState(outState);
406        if (mOverrideConfig != null) {
407            outState.putParcelable(KEY_CONFIGURATION, mOverrideConfig);
408        }
409    }
410
411    @Override
412    protected void onStop() {
413        super.onStop();
414        for (ServiceConnection conn : mConnections) {
415            unbindService(conn);
416        }
417        mConnections.clear();
418    }
419
420    @Override
421    protected void onDestroy() {
422        super.onDestroy();
423        mHandler.removeMessages(MSG_SPAM);
424    }
425
426    void addAppRecents(int count) {
427        ActivityManager am = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
428        Intent intent = new Intent(Intent.ACTION_MAIN);
429        intent.addCategory(Intent.CATEGORY_LAUNCHER);
430        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
431        intent.setComponent(new ComponentName(this, ActivityTestMain.class));
432        for (int i=0; i<count; i++) {
433            ActivityManager.TaskDescription desc = new ActivityManager.TaskDescription();
434            desc.setLabel("Added #" + i);
435            Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.icon);
436            if ((i&1) == 0) {
437                desc.setIcon(bitmap);
438            }
439            int taskId = am.addAppTask(this, intent, desc, bitmap);
440            Log.i(TAG, "Added new task id #" + taskId);
441        }
442    }
443
444    void setExclude(boolean exclude) {
445        ActivityManager am = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
446        List<ActivityManager.AppTask> tasks = am.getAppTasks();
447        int taskId = getTaskId();
448        for (int i=0; i<tasks.size(); i++) {
449            ActivityManager.AppTask task = tasks.get(i);
450            if (task.getTaskInfo().id == taskId) {
451                task.setExcludeFromRecents(exclude);
452            }
453        }
454    }
455
456    ActivityManager.AppTask findDocTask() {
457        ActivityManager am = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
458        List<ActivityManager.AppTask> tasks = am.getAppTasks();
459        if (tasks != null) {
460            for (int i=0; i<tasks.size(); i++) {
461                ActivityManager.AppTask task = tasks.get(i);
462                ActivityManager.RecentTaskInfo recent = task.getTaskInfo();
463                if (recent.baseIntent != null
464                        && recent.baseIntent.getComponent().getClassName().equals(
465                                DocActivity.class.getCanonicalName())) {
466                    return task;
467                }
468            }
469        }
470        return null;
471    }
472
473    void scheduleSpam(boolean fg) {
474        mHandler.removeMessages(MSG_SPAM);
475        Message msg = mHandler.obtainMessage(MSG_SPAM, fg ? 1 : 0, 0);
476        mHandler.sendMessageDelayed(msg, 500);
477    }
478
479    private View scrollWrap(View view) {
480        ScrollView scroller = new ScrollView(this);
481        scroller.addView(view, new ScrollView.LayoutParams(ScrollView.LayoutParams.MATCH_PARENT,
482                ScrollView.LayoutParams.MATCH_PARENT));
483        return scroller;
484    }
485
486    private void buildUi() {
487        LinearLayout top = new LinearLayout(this);
488        top.setOrientation(LinearLayout.VERTICAL);
489
490        List<ActivityManager.RecentTaskInfo> recents = mAm.getRecentTasks(10,
491                ActivityManager.RECENT_WITH_EXCLUDED);
492        if (recents != null) {
493            for (int i=0; i<recents.size(); i++) {
494                ActivityManager.RecentTaskInfo r = recents.get(i);
495                ActivityManager.TaskThumbnail tt = mAm.getTaskThumbnail(r.persistentId);
496                TextView tv = new TextView(this);
497                tv.setText(r.baseIntent.getComponent().flattenToShortString());
498                top.addView(tv, new LinearLayout.LayoutParams(
499                        LinearLayout.LayoutParams.WRAP_CONTENT,
500                        LinearLayout.LayoutParams.WRAP_CONTENT));
501                LinearLayout item = new LinearLayout(this);
502                item.setOrientation(LinearLayout.HORIZONTAL);
503                addThumbnail(item, tt != null ? tt.mainThumbnail : null, r, tt);
504                top.addView(item, new LinearLayout.LayoutParams(
505                        LinearLayout.LayoutParams.WRAP_CONTENT,
506                        LinearLayout.LayoutParams.WRAP_CONTENT));
507            }
508        }
509
510        setContentView(scrollWrap(top));
511    }
512}
513