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.AlertDialog;
25import android.content.ActivityNotFoundException;
26import android.content.BroadcastReceiver;
27import android.content.ComponentName;
28import android.content.ContentProviderClient;
29import android.content.Intent;
30import android.content.ServiceConnection;
31import android.os.Bundle;
32import android.os.IBinder;
33import android.os.RemoteException;
34import android.os.UserHandle;
35import android.os.UserManager;
36import android.graphics.Bitmap;
37import android.widget.ImageView;
38import android.widget.LinearLayout;
39import android.widget.TextView;
40import android.widget.ScrollView;
41import android.widget.Toast;
42import android.view.Menu;
43import android.view.MenuItem;
44import android.view.View;
45import android.content.Context;
46import android.content.pm.UserInfo;
47import android.content.res.Configuration;
48import android.util.Log;
49
50public class ActivityTestMain extends Activity {
51    static final String TAG = "ActivityTest";
52
53    static final String KEY_CONFIGURATION = "configuration";
54
55    ActivityManager mAm;
56    Configuration mOverrideConfig;
57    int mSecondUser;
58
59    ArrayList<ServiceConnection> mConnections = new ArrayList<ServiceConnection>();
60
61    class BroadcastResultReceiver extends BroadcastReceiver {
62        @Override
63        public void onReceive(Context context, Intent intent) {
64            Bundle res = getResultExtras(true);
65            int user = res.getInt("user", -1);
66            Toast.makeText(ActivityTestMain.this,
67                    "Receiver executed as user "
68                    + (user >= 0 ? Integer.toString(user) : "unknown"),
69                    Toast.LENGTH_LONG).show();
70        }
71    }
72
73    private void addThumbnail(LinearLayout container, Bitmap bm,
74            final ActivityManager.RecentTaskInfo task,
75            final ActivityManager.TaskThumbnails thumbs, final int subIndex) {
76        ImageView iv = new ImageView(this);
77        if (bm != null) {
78            iv.setImageBitmap(bm);
79        }
80        iv.setBackgroundResource(android.R.drawable.gallery_thumb);
81        int w = getResources().getDimensionPixelSize(android.R.dimen.thumbnail_width);
82        int h = getResources().getDimensionPixelSize(android.R.dimen.thumbnail_height);
83        container.addView(iv, new LinearLayout.LayoutParams(w, h));
84
85        iv.setOnClickListener(new View.OnClickListener() {
86            @Override
87            public void onClick(View v) {
88                if (task.id >= 0 && thumbs != null) {
89                    if (subIndex < (thumbs.numSubThumbbails-1)) {
90                        mAm.removeSubTask(task.id, subIndex+1);
91                    }
92                    mAm.moveTaskToFront(task.id, ActivityManager.MOVE_TASK_WITH_HOME);
93                } else {
94                    try {
95                        startActivity(task.baseIntent);
96                    } catch (ActivityNotFoundException e) {
97                        Log.w("foo", "Unable to start task: " + e);
98                    }
99                }
100                buildUi();
101            }
102        });
103        iv.setOnLongClickListener(new View.OnLongClickListener() {
104            @Override
105            public boolean onLongClick(View v) {
106                if (task.id >= 0 && thumbs != null) {
107                    if (subIndex < 0) {
108                        mAm.removeTask(task.id, ActivityManager.REMOVE_TASK_KILL_PROCESS);
109                    } else {
110                        mAm.removeSubTask(task.id, subIndex);
111                    }
112                    buildUi();
113                    return true;
114                }
115                return false;
116            }
117        });
118    }
119
120    @Override
121    protected void onCreate(Bundle savedInstanceState) {
122        super.onCreate(savedInstanceState);
123
124        mAm = (ActivityManager)getSystemService(ACTIVITY_SERVICE);
125        if (savedInstanceState != null) {
126            mOverrideConfig = savedInstanceState.getParcelable(KEY_CONFIGURATION);
127            if (mOverrideConfig != null) {
128                applyOverrideConfiguration(mOverrideConfig);
129            }
130        }
131
132        UserManager um = (UserManager)getSystemService(Context.USER_SERVICE);
133        List<UserInfo> users = um.getUsers();
134        mSecondUser = Integer.MAX_VALUE;
135        for (UserInfo ui : users) {
136            if (ui.id != 0 && mSecondUser > ui.id) {
137                mSecondUser = ui.id;
138            }
139        }
140    }
141
142    @Override
143    public boolean onCreateOptionsMenu(Menu menu) {
144        menu.add("Animate!").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
145            @Override public boolean onMenuItemClick(MenuItem item) {
146                AlertDialog.Builder builder = new AlertDialog.Builder(ActivityTestMain.this,
147                        R.style.SlowDialog);
148                builder.setTitle("This is a title");
149                builder.show();
150                return true;
151            }
152        });
153        menu.add("Bind!").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
154            @Override public boolean onMenuItemClick(MenuItem item) {
155                Intent intent = new Intent(ActivityTestMain.this, SingleUserService.class);
156                ServiceConnection conn = new ServiceConnection() {
157                    @Override
158                    public void onServiceConnected(ComponentName name, IBinder service) {
159                        Log.i(TAG, "Service connected " + name + " " + service);
160                    }
161                    @Override
162                    public void onServiceDisconnected(ComponentName name) {
163                        Log.i(TAG, "Service disconnected " + name);
164                    }
165                };
166                if (bindService(intent, conn, Context.BIND_AUTO_CREATE)) {
167                    mConnections.add(conn);
168                } else {
169                    Toast.makeText(ActivityTestMain.this, "Failed to bind",
170                            Toast.LENGTH_LONG).show();
171                }
172                return true;
173            }
174        });
175        menu.add("Start!").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
176            @Override public boolean onMenuItemClick(MenuItem item) {
177                Intent intent = new Intent(ActivityTestMain.this, SingleUserService.class);
178                startService(intent);
179                return true;
180            }
181        });
182        menu.add("Send!").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
183            @Override public boolean onMenuItemClick(MenuItem item) {
184                Intent intent = new Intent(ActivityTestMain.this, SingleUserReceiver.class);
185                sendOrderedBroadcast(intent, null, new BroadcastResultReceiver(),
186                        null, Activity.RESULT_OK, null, null);
187                return true;
188            }
189        });
190        menu.add("Call!").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
191            @Override public boolean onMenuItemClick(MenuItem item) {
192                ContentProviderClient cpl = getContentResolver().acquireContentProviderClient(
193                        SingleUserProvider.AUTHORITY);
194                Bundle res = null;
195                try {
196                    res = cpl.call("getuser", null, null);
197                } catch (RemoteException e) {
198                }
199                int user = res != null ? res.getInt("user", -1) : -1;
200                Toast.makeText(ActivityTestMain.this,
201                        "Provider executed as user "
202                        + (user >= 0 ? Integer.toString(user) : "unknown"),
203                        Toast.LENGTH_LONG).show();
204                cpl.release();
205                return true;
206            }
207        });
208        menu.add("Send to user 0!").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
209            @Override public boolean onMenuItemClick(MenuItem item) {
210                Intent intent = new Intent(ActivityTestMain.this, UserTarget.class);
211                sendOrderedBroadcastAsUser(intent, new UserHandle(0), null,
212                        new BroadcastResultReceiver(),
213                        null, Activity.RESULT_OK, null, null);
214                return true;
215            }
216        });
217        menu.add("Send to user " + mSecondUser + "!").setOnMenuItemClickListener(
218                new MenuItem.OnMenuItemClickListener() {
219            @Override public boolean onMenuItemClick(MenuItem item) {
220                Intent intent = new Intent(ActivityTestMain.this, UserTarget.class);
221                sendOrderedBroadcastAsUser(intent, new UserHandle(mSecondUser), null,
222                        new BroadcastResultReceiver(),
223                        null, Activity.RESULT_OK, null, null);
224                return true;
225            }
226        });
227        menu.add("Bind to user 0!").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
228            @Override public boolean onMenuItemClick(MenuItem item) {
229                Intent intent = new Intent(ActivityTestMain.this, ServiceUserTarget.class);
230                ServiceConnection conn = new ServiceConnection() {
231                    @Override
232                    public void onServiceConnected(ComponentName name, IBinder service) {
233                        Log.i(TAG, "Service connected " + name + " " + service);
234                    }
235                    @Override
236                    public void onServiceDisconnected(ComponentName name) {
237                        Log.i(TAG, "Service disconnected " + name);
238                    }
239                };
240                if (bindService(intent, conn, Context.BIND_AUTO_CREATE, 0)) {
241                    mConnections.add(conn);
242                } else {
243                    Toast.makeText(ActivityTestMain.this, "Failed to bind",
244                            Toast.LENGTH_LONG).show();
245                }
246                return true;
247            }
248        });
249        menu.add("Bind to user " + mSecondUser + "!").setOnMenuItemClickListener(
250                new MenuItem.OnMenuItemClickListener() {
251            @Override public boolean onMenuItemClick(MenuItem item) {
252                Intent intent = new Intent(ActivityTestMain.this, ServiceUserTarget.class);
253                ServiceConnection conn = new ServiceConnection() {
254                    @Override
255                    public void onServiceConnected(ComponentName name, IBinder service) {
256                        Log.i(TAG, "Service connected " + name + " " + service);
257                    }
258                    @Override
259                    public void onServiceDisconnected(ComponentName name) {
260                        Log.i(TAG, "Service disconnected " + name);
261                    }
262                };
263                if (bindService(intent, conn, Context.BIND_AUTO_CREATE, mSecondUser)) {
264                    mConnections.add(conn);
265                } else {
266                    Toast.makeText(ActivityTestMain.this, "Failed to bind",
267                            Toast.LENGTH_LONG).show();
268                }
269                return true;
270            }
271        });
272        menu.add("Density!").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
273            @Override public boolean onMenuItemClick(MenuItem item) {
274                if (mOverrideConfig == null) {
275                    mOverrideConfig = new Configuration();
276                }
277                if (mOverrideConfig.densityDpi == Configuration.DENSITY_DPI_UNDEFINED) {
278                    mOverrideConfig.densityDpi = (getApplicationContext().getResources()
279                            .getConfiguration().densityDpi*2)/3;
280                } else {
281                    mOverrideConfig.densityDpi = Configuration.DENSITY_DPI_UNDEFINED;
282                }
283                recreate();
284                return true;
285            }
286        });
287        return true;
288    }
289
290    @Override
291    protected void onStart() {
292        super.onStart();
293        buildUi();
294    }
295
296    @Override
297    protected void onSaveInstanceState(Bundle outState) {
298        super.onSaveInstanceState(outState);
299        if (mOverrideConfig != null) {
300            outState.putParcelable(KEY_CONFIGURATION, mOverrideConfig);
301        }
302    }
303
304    @Override
305    protected void onStop() {
306        super.onStop();
307        for (ServiceConnection conn : mConnections) {
308            unbindService(conn);
309        }
310        mConnections.clear();
311    }
312
313    private View scrollWrap(View view) {
314        ScrollView scroller = new ScrollView(this);
315        scroller.addView(view, new ScrollView.LayoutParams(ScrollView.LayoutParams.MATCH_PARENT,
316                ScrollView.LayoutParams.MATCH_PARENT));
317        return scroller;
318    }
319
320    private void buildUi() {
321        LinearLayout top = new LinearLayout(this);
322        top.setOrientation(LinearLayout.VERTICAL);
323
324        List<ActivityManager.RecentTaskInfo> recents = mAm.getRecentTasks(10,
325                ActivityManager.RECENT_WITH_EXCLUDED);
326        if (recents != null) {
327            for (int i=0; i<recents.size(); i++) {
328                ActivityManager.RecentTaskInfo r = recents.get(i);
329                ActivityManager.TaskThumbnails tt = mAm.getTaskThumbnails(r.persistentId);
330                TextView tv = new TextView(this);
331                tv.setText(r.baseIntent.getComponent().flattenToShortString());
332                top.addView(tv, new LinearLayout.LayoutParams(
333                        LinearLayout.LayoutParams.WRAP_CONTENT,
334                        LinearLayout.LayoutParams.WRAP_CONTENT));
335                LinearLayout item = new LinearLayout(this);
336                item.setOrientation(LinearLayout.HORIZONTAL);
337                addThumbnail(item, tt != null ? tt.mainThumbnail : null, r, tt, -1);
338                for (int j=0; j<tt.numSubThumbbails; j++) {
339                    addThumbnail(item, tt.getSubThumbnail(j), r, tt, j);
340                }
341                top.addView(item, new LinearLayout.LayoutParams(
342                        LinearLayout.LayoutParams.WRAP_CONTENT,
343                        LinearLayout.LayoutParams.WRAP_CONTENT));
344            }
345        }
346
347        setContentView(scrollWrap(top));
348    }
349}
350