• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 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 
17 
18 package com.android.carouseltest;
19 
20 import java.util.ArrayList;
21 import java.util.List;
22 import com.android.carouseltest.R;
23 
24 import com.android.ex.carousel.CarouselController;
25 import com.android.ex.carousel.CarouselViewHelper;
26 
27 import android.app.Activity;
28 import android.app.ActivityManager;
29 import android.app.IThumbnailReceiver;
30 import android.app.ActivityManager.RunningTaskInfo;
31 import android.content.ActivityNotFoundException;
32 import android.content.Context;
33 import android.content.Intent;
34 import android.content.pm.ActivityInfo;
35 import android.content.pm.PackageManager;
36 import android.content.pm.ResolveInfo;
37 import android.content.res.Configuration;
38 import android.content.res.Resources;
39 import android.graphics.Bitmap;
40 import android.graphics.BitmapFactory;
41 import android.graphics.Canvas;
42 import android.graphics.Matrix;
43 import android.graphics.Paint;
44 import android.graphics.Bitmap.Config;
45 import android.graphics.drawable.Drawable;
46 import android.os.Bundle;
47 import android.os.RemoteException;
48 import android.util.Log;
49 import android.view.View;
50 
51 public class TaskSwitcherActivity extends Activity {
52     private static final String TAG = "TaskSwitcherActivity";
53     private static final int CARD_SLOTS = 56;
54     private static final int MAX_TASKS = 20;
55     private static final int VISIBLE_SLOTS = 7;
56     protected static final boolean DBG = false;
57     private ActivityManager mActivityManager;
58     private List<RunningTaskInfo> mRunningTaskList;
59     private boolean mPortraitMode = true;
60     private ArrayList<ActivityDescription> mActivityDescriptions
61             = new ArrayList<ActivityDescription>();
62     private CarouselController mController;
63     private MyCarouselView mView;
64     private Bitmap mBlankBitmap = Bitmap.createBitmap(128, 128, Config.RGB_565);
65     private LocalCarouselViewHelper mHelper;
66 
67     static class ActivityDescription {
68         int id;
69         Bitmap thumbnail;
70         Drawable icon;
71         CharSequence label;
72         CharSequence description;
73         Intent intent;
74         Matrix matrix;
75 
ActivityDescription(Bitmap _thumbnail, Drawable _icon, String _label, String _desc, int _id)76         public ActivityDescription(Bitmap _thumbnail,
77                 Drawable _icon, String _label, String _desc, int _id)
78         {
79             thumbnail = _thumbnail;
80             icon = _icon;
81             label = _label;
82             description = _desc;
83             id = _id;
84         }
85 
clear()86         public void clear() {
87             icon = null;
88             thumbnail = null;
89             label = null;
90             description = null;
91             intent = null;
92             matrix = null;
93             id = -1;
94         }
95     };
96 
findActivityDescription(int id)97     private ActivityDescription findActivityDescription(int id) {
98         for (int i = 0; i < mActivityDescriptions.size(); i++) {
99             ActivityDescription item = mActivityDescriptions.get(i);
100             if (item != null && item.id == id) {
101                 return item;
102             }
103         }
104         return null;
105     }
106 
107     class LocalCarouselViewHelper extends CarouselViewHelper {
108         private static final int DETAIL_TEXTURE_WIDTH = 256;
109         private static final int DETAIL_TEXTURE_HEIGHT = 80;
110         private Paint mPaint = new Paint();
111         private DetailTextureParameters mDetailTextureParameters
112                 = new DetailTextureParameters(5.0f, 5.0f);
113 
LocalCarouselViewHelper(Context context)114         public LocalCarouselViewHelper(Context context) {
115             super(context);
116         }
117 
118         @Override
getDetailTextureParameters(int id)119         public DetailTextureParameters getDetailTextureParameters(int id) {
120             return mDetailTextureParameters;
121         }
122 
123         @Override
onCardSelected(int n)124         public void onCardSelected(int n) {
125             if (n < mActivityDescriptions.size()) {
126                 ActivityDescription item = mActivityDescriptions.get(n);
127                 // prepare a launch intent and send it
128                 if (item.intent != null) {
129                     item.intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
130                     try {
131                         Log.v(TAG, "Starting intent " + item.intent);
132                         startActivity(item.intent);
133                         overridePendingTransition(R.anim.zoom_enter, R.anim.zoom_exit);
134                     } catch (ActivityNotFoundException e) {
135                         Log.w("Recent", "Unable to launch recent task", e);
136                     }
137                     finish();
138                 }
139             }
140         }
141 
142         @Override
getTexture(int n)143         public Bitmap getTexture(int n) {
144             ActivityDescription desc = mActivityDescriptions.get(n);
145             Bitmap bitmap = desc.thumbnail == null ? mBlankBitmap : desc.thumbnail;
146             return bitmap;
147         }
148 
149         @Override
getDetailTexture(int n)150         public Bitmap getDetailTexture(int n) {
151             Bitmap bitmap = null;
152             if (n < mActivityDescriptions.size()) {
153                 ActivityDescription item = mActivityDescriptions.get(n);
154                 bitmap = Bitmap.createBitmap(DETAIL_TEXTURE_WIDTH, DETAIL_TEXTURE_HEIGHT,
155                     Bitmap.Config.ARGB_8888);
156                 Canvas canvas = new Canvas(bitmap);
157                 canvas.drawARGB(128,128,128,255);
158                 mPaint.setTextSize(15.0f);
159                 mPaint.setColor(0xffffffff);
160                 mPaint.setAntiAlias(true);
161                 canvas.drawText(item.label.toString(),0, DETAIL_TEXTURE_HEIGHT/2, mPaint);
162             }
163             return bitmap;
164         }
165     };
166 
167     private final IThumbnailReceiver mThumbnailReceiver = new IThumbnailReceiver.Stub() {
168 
169         public void finished() throws RemoteException {
170 
171         }
172 
173         public void newThumbnail(final int id, final Bitmap bitmap, CharSequence description)
174                 throws RemoteException {
175             int w = bitmap.getWidth();
176             int h = bitmap.getHeight();
177             Log.v(TAG, "New thumbnail for id=" + id + ", dimensions=" + w + "x" + h
178                     + " description '" + description + "'");
179             ActivityDescription info = findActivityDescription(id);
180             if (info != null) {
181                 info.thumbnail = bitmap;
182                 final int thumbWidth = bitmap.getWidth();
183                 final int thumbHeight = bitmap.getHeight();
184                 if ((mPortraitMode && thumbWidth > thumbHeight)
185                         || (!mPortraitMode && thumbWidth < thumbHeight)) {
186                     Matrix matrix = new Matrix();
187                     matrix.setRotate(90.0f, (float) thumbWidth / 2, (float) thumbHeight / 2);
188                     info.matrix = matrix;
189                 } else {
190                     info.matrix = null;
191                 }
192             } else {
193                 Log.v(TAG, "Can't find view for id " + id);
194             }
195         }
196     };
197 
198     @Override
onCreate(Bundle savedInstanceState)199     protected void onCreate(Bundle savedInstanceState) {
200         super.onCreate(savedInstanceState);
201 
202         final Resources res = getResources();
203         final View decorView = getWindow().getDecorView();
204 
205         mController = new CarouselController();
206         mView = new MyCarouselView(this, mController);
207         mHelper = new LocalCarouselViewHelper(this);
208         mHelper.setCarouselView(mView);
209         mView.setSlotCount(CARD_SLOTS);
210         mView.setVisibleSlots(VISIBLE_SLOTS);
211         mView.createCards(1);
212         mView.setStartAngle((float) -(2.0f*Math.PI * 5 / CARD_SLOTS));
213         mView.setDefaultBitmap(BitmapFactory.decodeResource(res, R.drawable.wait));
214         mView.setLoadingBitmap(BitmapFactory.decodeResource(res, R.drawable.wait));
215         mView.setBackgroundColor(0.1f, 0.1f, 0.1f, 1.0f);
216 
217         mActivityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
218         mPortraitMode = decorView.getHeight() > decorView.getWidth();
219 
220         refresh();
221         setContentView(mView);
222     }
223 
224     @Override
onResume()225     protected void onResume() {
226         super.onResume();
227         mHelper.onResume();
228         refresh();
229     }
230 
231     @Override
onPause()232     protected void onPause() {
233         super.onPause();
234         mHelper.onPause();
235     }
236 
237     @Override
onConfigurationChanged(Configuration newConfig)238     public void onConfigurationChanged(Configuration newConfig) {
239         super.onConfigurationChanged(newConfig);
240         mPortraitMode = newConfig.orientation == Configuration.ORIENTATION_PORTRAIT;
241         Log.v(TAG, "CONFIG CHANGE, mPortraitMode = " + mPortraitMode);
242         refresh();
243     }
244 
updateRunningTasks()245     void updateRunningTasks() {
246         mRunningTaskList = mActivityManager.getRunningTasks(MAX_TASKS + 2, 0, mThumbnailReceiver);
247         Log.v(TAG, "Portrait: " + mPortraitMode);
248         for (RunningTaskInfo r : mRunningTaskList) {
249             if (r.thumbnail != null) {
250                 int thumbWidth = r.thumbnail.getWidth();
251                 int thumbHeight = r.thumbnail.getHeight();
252                 Log.v(TAG, "Got thumbnail " + thumbWidth + "x" + thumbHeight);
253                 ActivityDescription desc = findActivityDescription(r.id);
254                 if (desc != null) {
255                     desc.thumbnail = r.thumbnail;
256                     desc.description = r.description;
257                     if ((mPortraitMode && thumbWidth > thumbHeight)
258                             || (!mPortraitMode && thumbWidth < thumbHeight)) {
259                         Matrix matrix = new Matrix();
260                         matrix.setRotate(90.0f, (float) thumbWidth / 2, (float) thumbHeight / 2);
261                         desc.matrix = matrix;
262                     }
263                 } else {
264                     Log.v(TAG, "Couldn't find ActivityDesc for id=" + r.id);
265                 }
266             } else {
267                 Log.v(TAG, "*** RUNNING THUMBNAIL WAS NULL ***");
268             }
269         }
270         // HACK refresh carousel
271         mView.createCards(mActivityDescriptions.size());
272     }
273 
updateRecentTasks()274     private void updateRecentTasks() {
275         final PackageManager pm = getPackageManager();
276         final ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
277 
278         final List<ActivityManager.RecentTaskInfo> recentTasks =
279                 am.getRecentTasks(MAX_TASKS + 2, ActivityManager.RECENT_IGNORE_UNAVAILABLE);
280 
281         ActivityInfo homeInfo = new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME)
282                     .resolveActivityInfo(pm, 0);
283 
284         //IconUtilities iconUtilities = new IconUtilities(this);
285 
286         int numTasks = recentTasks.size();
287         mActivityDescriptions.clear();
288         for (int i = 1, index = 0; i < numTasks && (index < MAX_TASKS + 2); ++i) {
289             final ActivityManager.RecentTaskInfo recentInfo = recentTasks.get(i);
290 
291             Intent intent = new Intent(recentInfo.baseIntent);
292             if (recentInfo.origActivity != null) {
293                 intent.setComponent(recentInfo.origActivity);
294             }
295 
296             // Skip the current home activity.
297             if (homeInfo != null
298                     && homeInfo.packageName.equals(intent.getComponent().getPackageName())
299                     && homeInfo.name.equals(intent.getComponent().getClassName())) {
300                 continue;
301             }
302 
303             intent.setFlags((intent.getFlags()&~Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED)
304                     | Intent.FLAG_ACTIVITY_NEW_TASK);
305             final ResolveInfo resolveInfo = pm.resolveActivity(intent, 0);
306             if (resolveInfo != null) {
307                 final ActivityInfo info = resolveInfo.activityInfo;
308                 final String title = info.loadLabel(pm).toString();
309                 Drawable icon = info.loadIcon(pm);
310 
311                 int id = recentInfo.id;
312                 if (id != -1 && title != null && title.length() > 0 && icon != null) {
313                     //icon = iconUtilities.createIconDrawable(icon);
314                     ActivityDescription item = new ActivityDescription(null, icon, title, null, id);
315                     item.intent = intent;
316                     mActivityDescriptions.add(item);
317                     Log.v(TAG, "Added item[" + index + "], id=" + item.id);
318                     ++index;
319                 } else {
320                     Log.v(TAG, "SKIPPING item " + id);
321                 }
322             }
323         }
324     }
325 
refresh()326     private void refresh() {
327         updateRecentTasks();
328         updateRunningTasks();
329         mView.createCards(mActivityDescriptions.size());
330     }
331 }
332