Home | History | Annotate | Download | only in carouseltest
      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 
     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 
     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 
     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 
    114         public LocalCarouselViewHelper(Context context) {
    115             super(context);
    116         }
    117 
    118         @Override
    119         public DetailTextureParameters getDetailTextureParameters(int id) {
    120             return mDetailTextureParameters;
    121         }
    122 
    123         @Override
    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
    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
    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
    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
    225     protected void onResume() {
    226         super.onResume();
    227         mHelper.onResume();
    228         refresh();
    229     }
    230 
    231     @Override
    232     protected void onPause() {
    233         super.onPause();
    234         mHelper.onPause();
    235     }
    236 
    237     @Override
    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 
    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 
    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 
    326     private void refresh() {
    327         updateRecentTasks();
    328         updateRunningTasks();
    329         mView.createCards(mActivityDescriptions.size());
    330     }
    331 }
    332