OSDN Git Service

9c6ae7a0cfb5765492756e55542b8f2b15564ed0
[android-x86/packages-apps-Settings.git] / src / com / android / settings / applications / ManageApplications.java
1 /*
2  * Copyright (C) 2006 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 package com.android.settings.applications;
18
19 import com.android.settings.R;
20 import com.android.settings.applications.ApplicationsState.AppEntry;
21
22 import android.app.TabActivity;
23 import android.content.Context;
24 import android.content.DialogInterface;
25 import android.content.Intent;
26 import android.content.pm.ApplicationInfo;
27 import android.net.Uri;
28 import android.os.Bundle;
29 import android.provider.Settings;
30 import android.util.Log;
31 import android.view.LayoutInflater;
32 import android.view.Menu;
33 import android.view.MenuItem;
34 import android.view.View;
35 import android.view.ViewGroup;
36 import android.view.Window;
37 import android.view.animation.AnimationUtils;
38 import android.widget.AbsListView;
39 import android.widget.AdapterView;
40 import android.widget.BaseAdapter;
41 import android.widget.Filter;
42 import android.widget.Filterable;
43 import android.widget.ImageView;
44 import android.widget.ListView;
45 import android.widget.TabHost;
46 import android.widget.TextView;
47 import android.widget.AdapterView.OnItemClickListener;
48
49 import java.util.ArrayList;
50 import java.util.Comparator;
51 import java.util.List;
52
53 /**
54  * Activity to pick an application that will be used to display installation information and
55  * options to uninstall/delete user data for system applications. This activity
56  * can be launched through Settings or via the ACTION_MANAGE_PACKAGE_STORAGE
57  * intent.
58  */
59 public class ManageApplications extends TabActivity implements
60         OnItemClickListener, DialogInterface.OnCancelListener,
61         TabHost.TabContentFactory, TabHost.OnTabChangeListener {
62     static final String TAG = "ManageApplications";
63     static final boolean DEBUG = false;
64     
65     // attributes used as keys when passing values to InstalledAppDetails activity
66     public static final String APP_CHG = "chg";
67     
68     // constant value that can be used to check return code from sub activity.
69     private static final int INSTALLED_APP_DETAILS = 1;
70     
71     // sort order that can be changed through the menu can be sorted alphabetically
72     // or size(descending)
73     private static final int MENU_OPTIONS_BASE = 0;
74     // Filter options used for displayed list of applications
75     public static final int FILTER_APPS_ALL = MENU_OPTIONS_BASE + 0;
76     public static final int FILTER_APPS_THIRD_PARTY = MENU_OPTIONS_BASE + 1;
77     public static final int FILTER_APPS_SDCARD = MENU_OPTIONS_BASE + 2;
78
79     public static final int SORT_ORDER_ALPHA = MENU_OPTIONS_BASE + 4;
80     public static final int SORT_ORDER_SIZE = MENU_OPTIONS_BASE + 5;
81     // sort order
82     private int mSortOrder = SORT_ORDER_ALPHA;
83     // Filter value
84     private int mFilterApps = FILTER_APPS_THIRD_PARTY;
85     
86     private ApplicationsState mApplicationsState;
87     private ApplicationsAdapter mApplicationsAdapter;
88     
89     // Size resource used for packages whose size computation failed for some reason
90     private CharSequence mInvalidSizeStr;
91     private CharSequence mComputingSizeStr;
92     
93     // layout inflater object used to inflate views
94     private LayoutInflater mInflater;
95     
96     private String mCurrentPkgName;
97     
98     private View mLoadingContainer;
99
100     private View mListContainer;
101
102     // ListView used to display list
103     private ListView mListView;
104     // Custom view used to display running processes
105     private RunningProcessesView mRunningProcessesView;
106     
107     // These are for keeping track of activity and tab switch state.
108     private int mCurView;
109     private boolean mCreatedRunning;
110
111     private boolean mResumedRunning;
112     private boolean mActivityResumed;
113     private Object mNonConfigInstance;
114     
115     final Runnable mRunningProcessesAvail = new Runnable() {
116         public void run() {
117             handleRunningProcessesAvail();
118         }
119     };
120
121     // View Holder used when displaying views
122     static class AppViewHolder {
123         ApplicationsState.AppEntry entry;
124         TextView appName;
125         ImageView appIcon;
126         TextView appSize;
127         TextView disabled;
128         
129         void updateSizeText(ManageApplications ma) {
130             if (DEBUG) Log.i(TAG, "updateSizeText of " + entry.label + " " + entry
131                     + ": " + entry.sizeStr);
132             if (entry.sizeStr != null) {
133                 appSize.setText(entry.sizeStr);
134             } else if (entry.size == ApplicationsState.SIZE_INVALID) {
135                 appSize.setText(ma.mInvalidSizeStr);
136             }
137         }
138     }
139     
140     /*
141      * Custom adapter implementation for the ListView
142      * This adapter maintains a map for each displayed application and its properties
143      * An index value on each AppInfo object indicates the correct position or index
144      * in the list. If the list gets updated dynamically when the user is viewing the list of
145      * applications, we need to return the correct index of position. This is done by mapping
146      * the getId methods via the package name into the internal maps and indices.
147      * The order of applications in the list is mirrored in mAppLocalList
148      */
149     class ApplicationsAdapter extends BaseAdapter implements Filterable,
150             ApplicationsState.Callbacks, AbsListView.RecyclerListener {
151         private final ApplicationsState mState;
152         private final ArrayList<View> mActive = new ArrayList<View>();
153         private ArrayList<ApplicationsState.AppEntry> mBaseEntries;
154         private ArrayList<ApplicationsState.AppEntry> mEntries;
155         private boolean mResumed;
156         private int mLastFilterMode=-1, mLastSortMode=-1;
157         private boolean mWaitingForData;
158         CharSequence mCurFilterPrefix;
159
160         private Filter mFilter = new Filter() {
161             @Override
162             protected FilterResults performFiltering(CharSequence constraint) {
163                 ArrayList<ApplicationsState.AppEntry> entries
164                         = applyPrefixFilter(constraint, mBaseEntries);
165                 FilterResults fr = new FilterResults();
166                 fr.values = entries;
167                 fr.count = entries.size();
168                 return fr;
169             }
170
171             @Override
172             protected void publishResults(CharSequence constraint, FilterResults results) {
173                 mCurFilterPrefix = constraint;
174                 mEntries = (ArrayList<ApplicationsState.AppEntry>)results.values;
175                 notifyDataSetChanged();
176             }
177         };
178
179         public ApplicationsAdapter(ApplicationsState state) {
180             mState = state;
181         }
182
183         public void resume(int filter, int sort) {
184             if (DEBUG) Log.i(TAG, "Resume!  mResumed=" + mResumed);
185             if (!mResumed) {
186                 mResumed = true;
187                 mState.resume(this);
188                 mLastFilterMode = filter;
189                 mLastSortMode = sort;
190                 rebuild(true);
191             } else {
192                 rebuild(filter, sort);
193             }
194         }
195
196         public void pause() {
197             if (mResumed) {
198                 mResumed = false;
199                 mState.pause();
200             }
201         }
202
203         public void rebuild(int filter, int sort) {
204             if (filter == mLastFilterMode && sort == mLastSortMode) {
205                 return;
206             }
207             mLastFilterMode = filter;
208             mLastSortMode = sort;
209             rebuild(true);
210         }
211         
212         public void rebuild(boolean eraseold) {
213             if (DEBUG) Log.i(TAG, "Rebuilding app list...");
214             ApplicationsState.AppFilter filterObj;
215             Comparator<AppEntry> comparatorObj;
216             switch (mLastFilterMode) {
217                 case FILTER_APPS_THIRD_PARTY:
218                     filterObj = ApplicationsState.THIRD_PARTY_FILTER;
219                     break;
220                 case FILTER_APPS_SDCARD:
221                     filterObj = ApplicationsState.ON_SD_CARD_FILTER;
222                     break;
223                 default:
224                     filterObj = null;
225                     break;
226             }
227             switch (mLastSortMode) {
228                 case SORT_ORDER_SIZE:
229                     comparatorObj = ApplicationsState.SIZE_COMPARATOR;
230                     break;
231                 default:
232                     comparatorObj = ApplicationsState.ALPHA_COMPARATOR;
233                     break;
234             }
235             ArrayList<ApplicationsState.AppEntry> entries
236                     = mState.rebuild(filterObj, comparatorObj);
237             if (entries == null && !eraseold) {
238                 // Don't have new list yet, but can continue using the old one.
239                 return;
240             }
241             mBaseEntries = entries;
242             if (mBaseEntries != null) {
243                 mEntries = applyPrefixFilter(mCurFilterPrefix, mBaseEntries);
244             } else {
245                 mEntries = null;
246             }
247             notifyDataSetChanged();
248
249             if (entries == null) {
250                 mWaitingForData = true;
251                 mListContainer.setVisibility(View.INVISIBLE);
252                 mLoadingContainer.setVisibility(View.VISIBLE);
253             } else {
254                 mListContainer.setVisibility(View.VISIBLE);
255                 mLoadingContainer.setVisibility(View.GONE);
256             }
257         }
258
259         ArrayList<ApplicationsState.AppEntry> applyPrefixFilter(CharSequence prefix,
260                 ArrayList<ApplicationsState.AppEntry> origEntries) {
261             if (prefix == null || prefix.length() == 0) {
262                 return origEntries;
263             } else {
264                 String prefixStr = ApplicationsState.normalize(prefix.toString());
265                 final String spacePrefixStr = " " + prefixStr;
266                 ArrayList<ApplicationsState.AppEntry> newEntries
267                         = new ArrayList<ApplicationsState.AppEntry>();
268                 for (int i=0; i<origEntries.size(); i++) {
269                     ApplicationsState.AppEntry entry = origEntries.get(i);
270                     String nlabel = entry.getNormalizedLabel();
271                     if (nlabel.startsWith(prefixStr) || nlabel.indexOf(spacePrefixStr) != -1) {
272                         newEntries.add(entry);
273                     }
274                 }
275                 return newEntries;
276             }
277         }
278
279         @Override
280         public void onRunningStateChanged(boolean running) {
281             setProgressBarIndeterminateVisibility(running);
282         }
283
284         @Override
285         public void onRebuildComplete(ArrayList<AppEntry> apps) {
286             mListContainer.setVisibility(View.VISIBLE);
287             mLoadingContainer.setVisibility(View.GONE);
288             mWaitingForData = false;
289             mBaseEntries = apps;
290             mEntries = applyPrefixFilter(mCurFilterPrefix, mBaseEntries);
291             notifyDataSetChanged();
292         }
293
294         @Override
295         public void onPackageListChanged() {
296             rebuild(false);
297         }
298
299         @Override
300         public void onPackageIconChanged() {
301             // We ensure icons are loaded when their item is displayed, so
302             // don't care about icons loaded in the background.
303         }
304
305         @Override
306         public void onPackageSizeChanged(String packageName) {
307             for (int i=0; i<mActive.size(); i++) {
308                 AppViewHolder holder = (AppViewHolder)mActive.get(i).getTag();
309                 if (holder.entry.info.packageName.equals(packageName)) {
310                     synchronized (holder.entry) {
311                         holder.updateSizeText(ManageApplications.this);
312                     }
313                     if (holder.entry.info.packageName.equals(mCurrentPkgName)
314                             && mLastSortMode == SORT_ORDER_SIZE) {
315                         // We got the size information for the last app the
316                         // user viewed, and are sorting by size...  they may
317                         // have cleared data, so we immediately want to resort
318                         // the list with the new size to reflect it to the user.
319                         rebuild(false);
320                     }
321                     return;
322                 }
323             }
324         }
325
326         @Override
327         public void onAllSizesComputed() {
328             if (mLastSortMode == SORT_ORDER_SIZE) {
329                 rebuild(false);
330             }
331         }
332         
333         public int getCount() {
334             return mEntries != null ? mEntries.size() : 0;
335         }
336         
337         public Object getItem(int position) {
338             return mEntries.get(position);
339         }
340         
341         public ApplicationsState.AppEntry getAppEntry(int position) {
342             return mEntries.get(position);
343         }
344
345         public long getItemId(int position) {
346             return mEntries.get(position).id;
347         }
348         
349         public View getView(int position, View convertView, ViewGroup parent) {
350             // A ViewHolder keeps references to children views to avoid unnecessary calls
351             // to findViewById() on each row.
352             AppViewHolder holder;
353
354             // When convertView is not null, we can reuse it directly, there is no need
355             // to reinflate it. We only inflate a new View when the convertView supplied
356             // by ListView is null.
357             if (convertView == null) {
358                 convertView = mInflater.inflate(R.layout.manage_applications_item, null);
359
360                 // Creates a ViewHolder and store references to the two children views
361                 // we want to bind data to.
362                 holder = new AppViewHolder();
363                 holder.appName = (TextView) convertView.findViewById(R.id.app_name);
364                 holder.appIcon = (ImageView) convertView.findViewById(R.id.app_icon);
365                 holder.appSize = (TextView) convertView.findViewById(R.id.app_size);
366                 holder.disabled = (TextView) convertView.findViewById(R.id.app_disabled);
367                 convertView.setTag(holder);
368             } else {
369                 // Get the ViewHolder back to get fast access to the TextView
370                 // and the ImageView.
371                 holder = (AppViewHolder) convertView.getTag();
372             }
373
374             // Bind the data efficiently with the holder
375             ApplicationsState.AppEntry entry = mEntries.get(position);
376             synchronized (entry) {
377                 holder.entry = entry;
378                 if (entry.label != null) {
379                     holder.appName.setText(entry.label);
380                     holder.appName.setTextColor(getResources().getColorStateList(
381                             entry.info.enabled ? android.R.color.primary_text_dark
382                                     : android.R.color.secondary_text_dark));
383                 }
384                 mState.ensureIcon(entry);
385                 if (entry.icon != null) {
386                     holder.appIcon.setImageDrawable(entry.icon);
387                 }
388                 holder.updateSizeText(ManageApplications.this);
389                 if (InstalledAppDetails.SUPPORT_DISABLE_APPS) {
390                     holder.disabled.setVisibility(entry.info.enabled ? View.GONE : View.VISIBLE);
391                 } else {
392                     holder.disabled.setVisibility(View.GONE);
393                 }
394             }
395             mActive.remove(convertView);
396             mActive.add(convertView);
397             return convertView;
398         }
399
400         @Override
401         public Filter getFilter() {
402             return mFilter;
403         }
404
405         @Override
406         public void onMovedToScrapHeap(View view) {
407             mActive.remove(view);
408         }
409     }
410     
411     static final String TAB_DOWNLOADED = "Downloaded";
412     static final String TAB_RUNNING = "Running";
413     static final String TAB_ALL = "All";
414     static final String TAB_SDCARD = "OnSdCard";
415     private View mRootView;
416     
417     @Override
418     protected void onCreate(Bundle savedInstanceState) {
419         super.onCreate(savedInstanceState);
420         mApplicationsState = ApplicationsState.getInstance(getApplication());
421         mApplicationsAdapter = new ApplicationsAdapter(mApplicationsState);
422         Intent intent = getIntent();
423         String action = intent.getAction();
424         String defaultTabTag = TAB_DOWNLOADED;
425         if (intent.getComponent().getClassName().equals(
426                 "com.android.settings.RunningServices")) {
427             defaultTabTag = TAB_RUNNING;
428         } else if (intent.getComponent().getClassName().equals(
429                 "com.android.settings.applications.StorageUse")
430                 || action.equals(Intent.ACTION_MANAGE_PACKAGE_STORAGE)) {
431             mSortOrder = SORT_ORDER_SIZE;
432             mFilterApps = FILTER_APPS_ALL;
433             defaultTabTag = TAB_ALL;
434         } else if (action.equals(Settings.ACTION_MANAGE_ALL_APPLICATIONS_SETTINGS)) {
435             // Select the all-apps tab, with the default sorting
436             defaultTabTag = TAB_ALL;
437         }
438         
439         if (savedInstanceState != null) {
440             mSortOrder = savedInstanceState.getInt("sortOrder", mSortOrder);
441             mFilterApps = savedInstanceState.getInt("filterApps", mFilterApps);
442             String tmp = savedInstanceState.getString("defaultTabTag");
443             if (tmp != null) defaultTabTag = tmp;
444         }
445         
446         mNonConfigInstance = getLastNonConfigurationInstance();
447         
448         // initialize some window features
449         requestWindowFeature(Window.FEATURE_RIGHT_ICON);
450         requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
451         mInvalidSizeStr = getText(R.string.invalid_size_value);
452         mComputingSizeStr = getText(R.string.computing_size);
453         // initialize the inflater
454         mInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
455         mRootView = mInflater.inflate(R.layout.manage_applications, null);
456         mLoadingContainer = mRootView.findViewById(R.id.loading_container);
457         mListContainer = mRootView.findViewById(R.id.list_container);
458         // Create adapter and list view here
459         ListView lv = (ListView) mListContainer.findViewById(android.R.id.list);
460         View emptyView = mListContainer.findViewById(com.android.internal.R.id.empty);
461         if (emptyView != null) {
462             lv.setEmptyView(emptyView);
463         }
464         lv.setOnItemClickListener(this);
465         lv.setSaveEnabled(true);
466         lv.setItemsCanFocus(true);
467         lv.setOnItemClickListener(this);
468         lv.setTextFilterEnabled(true);
469         mListView = lv;
470         lv.setRecyclerListener(mApplicationsAdapter);
471         mListView.setAdapter(mApplicationsAdapter);
472         mRunningProcessesView = (RunningProcessesView)mRootView.findViewById(
473                 R.id.running_processes);
474
475         final TabHost tabHost = getTabHost();
476         tabHost.addTab(tabHost.newTabSpec(TAB_DOWNLOADED)
477                 .setIndicator(getString(R.string.filter_apps_third_party),
478                         getResources().getDrawable(R.drawable.ic_tab_download))
479                 .setContent(this));
480         tabHost.addTab(tabHost.newTabSpec(TAB_ALL)
481                 .setIndicator(getString(R.string.filter_apps_all),
482                         getResources().getDrawable(R.drawable.ic_tab_all))
483                 .setContent(this));
484         tabHost.addTab(tabHost.newTabSpec(TAB_SDCARD)
485                 .setIndicator(getString(R.string.filter_apps_onsdcard),
486                         getResources().getDrawable(R.drawable.ic_tab_sdcard))
487                 .setContent(this));
488         tabHost.addTab(tabHost.newTabSpec(TAB_RUNNING)
489                 .setIndicator(getString(R.string.filter_apps_running),
490                         getResources().getDrawable(R.drawable.ic_tab_running))
491                 .setContent(this));
492         tabHost.setCurrentTabByTag(defaultTabTag);
493         tabHost.setOnTabChangedListener(this);
494     }
495     
496     @Override
497     public void onStart() {
498         super.onStart();
499     }
500
501     @Override
502     protected void onResume() {
503         super.onResume();
504         mActivityResumed = true;
505         showCurrentTab();
506     }
507
508     @Override
509     protected void onSaveInstanceState(Bundle outState) {
510         super.onSaveInstanceState(outState);
511         outState.putInt("sortOrder", mSortOrder);
512         outState.putInt("filterApps", mFilterApps);
513         outState.putString("defautTabTag", getTabHost().getCurrentTabTag());
514     }
515
516     @Override
517     public Object onRetainNonConfigurationInstance() {
518         return mRunningProcessesView.doRetainNonConfigurationInstance();
519     }
520     
521     @Override
522     protected void onPause() {
523         super.onPause();
524         mActivityResumed = false;
525         mApplicationsAdapter.pause();
526         if (mResumedRunning) {
527             mRunningProcessesView.doPause();
528             mResumedRunning = false;
529         }
530     }
531
532     @Override
533     protected void onActivityResult(int requestCode, int resultCode,
534             Intent data) {
535         if (requestCode == INSTALLED_APP_DETAILS && mCurrentPkgName != null) {
536             mApplicationsState.requestSize(mCurrentPkgName);
537         }
538     }
539     
540     // utility method used to start sub activity
541     private void startApplicationDetailsActivity() {
542         // Create intent to start new activity
543         Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
544                 Uri.fromParts("package", mCurrentPkgName, null));
545         // start new activity to display extended information
546         startActivityForResult(intent, INSTALLED_APP_DETAILS);
547     }
548     
549     @Override
550     public boolean onCreateOptionsMenu(Menu menu) {
551         menu.add(0, SORT_ORDER_ALPHA, 1, R.string.sort_order_alpha)
552                 .setIcon(android.R.drawable.ic_menu_sort_alphabetically);
553         menu.add(0, SORT_ORDER_SIZE, 2, R.string.sort_order_size)
554                 .setIcon(android.R.drawable.ic_menu_sort_by_size); 
555         return true;
556     }
557     
558     @Override
559     public boolean onPrepareOptionsMenu(Menu menu) {
560         menu.findItem(SORT_ORDER_ALPHA).setVisible(mSortOrder != SORT_ORDER_ALPHA);
561         menu.findItem(SORT_ORDER_SIZE).setVisible(mSortOrder != SORT_ORDER_SIZE);
562         return true;
563     }
564
565     @Override
566     public boolean onOptionsItemSelected(MenuItem item) {
567         int menuId = item.getItemId();
568         if ((menuId == SORT_ORDER_ALPHA) || (menuId == SORT_ORDER_SIZE)) {
569             mSortOrder = menuId;
570             mApplicationsAdapter.rebuild(mFilterApps, mSortOrder);
571         }
572         return true;
573     }
574
575     public void onItemClick(AdapterView<?> parent, View view, int position,
576             long id) {
577         ApplicationsState.AppEntry entry = mApplicationsAdapter.getAppEntry(position);
578         mCurrentPkgName = entry.info.packageName;
579         startApplicationDetailsActivity();
580     }
581     
582     // Finish the activity if the user presses the back button to cancel the activity
583     public void onCancel(DialogInterface dialog) {
584         finish();
585     }
586
587     public View createTabContent(String tag) {
588         return mRootView;
589     }
590
591     static final int VIEW_NOTHING = 0;
592     static final int VIEW_LIST = 1;
593     static final int VIEW_RUNNING = 2;
594
595     private void selectView(int which) {
596         if (which == VIEW_LIST) {
597             if (mResumedRunning) {
598                 mRunningProcessesView.doPause();
599                 mResumedRunning = false;
600             }
601             if (mCurView != which) {
602                 mRunningProcessesView.setVisibility(View.GONE);
603                 mListContainer.setVisibility(View.VISIBLE);
604                 mLoadingContainer.setVisibility(View.GONE);
605             }
606             if (mActivityResumed) {
607                 mApplicationsAdapter.resume(mFilterApps, mSortOrder);
608             }
609         } else if (which == VIEW_RUNNING) {
610             if (!mCreatedRunning) {
611                 mRunningProcessesView.doCreate(null, mNonConfigInstance);
612                 mCreatedRunning = true;
613             }
614             boolean haveData = true;
615             if (mActivityResumed && !mResumedRunning) {
616                 haveData = mRunningProcessesView.doResume(mRunningProcessesAvail);
617                 mResumedRunning = true;
618             }
619             mApplicationsAdapter.pause();
620             if (mCurView != which) {
621                 if (haveData) {
622                     mRunningProcessesView.setVisibility(View.VISIBLE);
623                 } else {
624                     mLoadingContainer.setVisibility(View.VISIBLE);
625                 }
626                 mListContainer.setVisibility(View.GONE);
627             }
628         }
629         mCurView = which;
630     }
631
632     void handleRunningProcessesAvail() {
633         if (mCurView == VIEW_RUNNING) {
634             mLoadingContainer.startAnimation(AnimationUtils.loadAnimation(
635                     this, android.R.anim.fade_out));
636             mRunningProcessesView.startAnimation(AnimationUtils.loadAnimation(
637                     this, android.R.anim.fade_in));
638             mRunningProcessesView.setVisibility(View.VISIBLE);
639             mLoadingContainer.setVisibility(View.GONE);
640         }
641     }
642
643     public void showCurrentTab() {
644         String tabId = getTabHost().getCurrentTabTag();
645         int newOption;
646         if (TAB_DOWNLOADED.equalsIgnoreCase(tabId)) {
647             newOption = FILTER_APPS_THIRD_PARTY;
648         } else if (TAB_ALL.equalsIgnoreCase(tabId)) {
649             newOption = FILTER_APPS_ALL;
650         } else if (TAB_SDCARD.equalsIgnoreCase(tabId)) {
651             newOption = FILTER_APPS_SDCARD;
652         } else if (TAB_RUNNING.equalsIgnoreCase(tabId)) {
653             selectView(VIEW_RUNNING);
654             return;
655         } else {
656             // Invalid option. Do nothing
657             return;
658         }
659         
660         mFilterApps = newOption;
661         selectView(VIEW_LIST);
662     }
663
664     public void onTabChanged(String tabId) {
665         showCurrentTab();
666     }
667 }