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 (bindServiceAsUser(intent, conn, Context.BIND_AUTO_CREATE, UserHandle.OWNER)) { 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 (bindServiceAsUser(intent, conn, Context.BIND_AUTO_CREATE, 264 new UserHandle(mSecondUser))) { 265 mConnections.add(conn); 266 } else { 267 Toast.makeText(ActivityTestMain.this, "Failed to bind", 268 Toast.LENGTH_LONG).show(); 269 } 270 return true; 271 } 272 }); 273 menu.add("Density!").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { 274 @Override public boolean onMenuItemClick(MenuItem item) { 275 if (mOverrideConfig == null) { 276 mOverrideConfig = new Configuration(); 277 } 278 if (mOverrideConfig.densityDpi == Configuration.DENSITY_DPI_UNDEFINED) { 279 mOverrideConfig.densityDpi = (getApplicationContext().getResources() 280 .getConfiguration().densityDpi*2)/3; 281 } else { 282 mOverrideConfig.densityDpi = Configuration.DENSITY_DPI_UNDEFINED; 283 } 284 recreate(); 285 return true; 286 } 287 }); 288 menu.add("HashArray").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { 289 @Override public boolean onMenuItemClick(MenuItem item) { 290 ArrayMapTests.run(); 291 return true; 292 } 293 }); 294 return true; 295 } 296 297 @Override 298 protected void onStart() { 299 super.onStart(); 300 buildUi(); 301 } 302 303 @Override 304 protected void onSaveInstanceState(Bundle outState) { 305 super.onSaveInstanceState(outState); 306 if (mOverrideConfig != null) { 307 outState.putParcelable(KEY_CONFIGURATION, mOverrideConfig); 308 } 309 } 310 311 @Override 312 protected void onStop() { 313 super.onStop(); 314 for (ServiceConnection conn : mConnections) { 315 unbindService(conn); 316 } 317 mConnections.clear(); 318 } 319 320 private View scrollWrap(View view) { 321 ScrollView scroller = new ScrollView(this); 322 scroller.addView(view, new ScrollView.LayoutParams(ScrollView.LayoutParams.MATCH_PARENT, 323 ScrollView.LayoutParams.MATCH_PARENT)); 324 return scroller; 325 } 326 327 private void buildUi() { 328 LinearLayout top = new LinearLayout(this); 329 top.setOrientation(LinearLayout.VERTICAL); 330 331 List<ActivityManager.RecentTaskInfo> recents = mAm.getRecentTasks(10, 332 ActivityManager.RECENT_WITH_EXCLUDED); 333 if (recents != null) { 334 for (int i=0; i<recents.size(); i++) { 335 ActivityManager.RecentTaskInfo r = recents.get(i); 336 ActivityManager.TaskThumbnails tt = mAm.getTaskThumbnails(r.persistentId); 337 TextView tv = new TextView(this); 338 tv.setText(r.baseIntent.getComponent().flattenToShortString()); 339 top.addView(tv, new LinearLayout.LayoutParams( 340 LinearLayout.LayoutParams.WRAP_CONTENT, 341 LinearLayout.LayoutParams.WRAP_CONTENT)); 342 LinearLayout item = new LinearLayout(this); 343 item.setOrientation(LinearLayout.HORIZONTAL); 344 addThumbnail(item, tt != null ? tt.mainThumbnail : null, r, tt, -1); 345 for (int j=0; j<tt.numSubThumbbails; j++) { 346 addThumbnail(item, tt.getSubThumbnail(j), r, tt, j); 347 } 348 top.addView(item, new LinearLayout.LayoutParams( 349 LinearLayout.LayoutParams.WRAP_CONTENT, 350 LinearLayout.LayoutParams.WRAP_CONTENT)); 351 } 352 } 353 354 setContentView(scrollWrap(top)); 355 } 356} 357