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