/*
 * Copyright (C) 2006 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.settings.applications;

import static android.net.NetworkPolicyManager.POLICY_NONE;
import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND;

import android.app.Activity;
import android.app.ActivityManager;
import android.app.AlertDialog;
import android.app.AppOpsManager;
import android.app.Fragment;
import android.app.INotificationManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.NetworkPolicyManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
import android.preference.PreferenceActivity;
import android.preference.PreferenceFrameLayout;
import android.provider.Settings;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.PagerTabStrip;
import android.support.v4.view.ViewPager;
import android.text.format.Formatter;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AnimationUtils;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ListView;
import android.widget.TextView;

import com.android.internal.app.IMediaContainerService;
import com.android.internal.content.PackageHelper;
import com.android.settings.R;
import com.android.settings.Settings.RunningServicesActivity;
import com.android.settings.Settings.StorageUseActivity;
import com.android.settings.applications.ApplicationsState.AppEntry;
import com.android.settings.deviceinfo.StorageMeasurement;
import com.android.settings.Utils;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

final class CanBeOnSdCardChecker {
    final IPackageManager mPm;
    int mInstallLocation;
    
    CanBeOnSdCardChecker() {
        mPm = IPackageManager.Stub.asInterface(
                ServiceManager.getService("package"));
    }
    
    void init() {
        try {
            mInstallLocation = mPm.getInstallLocation();
        } catch (RemoteException e) {
            Log.e("CanBeOnSdCardChecker", "Is Package Manager running?");
            return;
        }
    }
    
    boolean check(ApplicationInfo info) {
        boolean canBe = false;
        if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
            canBe = true;
        } else {
            if ((info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
                if (info.installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL ||
                        info.installLocation == PackageInfo.INSTALL_LOCATION_AUTO) {
                    canBe = true;
                } else if (info.installLocation
                        == PackageInfo.INSTALL_LOCATION_UNSPECIFIED) {
                    if (mInstallLocation == PackageHelper.APP_INSTALL_EXTERNAL) {
                        // For apps with no preference and the default value set
                        // to install on sdcard.
                        canBe = true;
                    }
                }
            }
        }
        return canBe;
    }
}

interface AppClickListener {
    void onItemClick(ManageApplications.TabInfo tab, AdapterView<?> parent,
            View view, int position, long id);
}

/**
 * Activity to pick an application that will be used to display installation information and
 * options to uninstall/delete user data for system applications. This activity
 * can be launched through Settings or via the ACTION_MANAGE_PACKAGE_STORAGE
 * intent.
 */
public class ManageApplications extends Fragment implements
        AppClickListener, DialogInterface.OnClickListener,
        DialogInterface.OnDismissListener {

    static final String TAG = "ManageApplications";
    static final boolean DEBUG = false;

    private static final String EXTRA_SORT_ORDER = "sortOrder";
    private static final String EXTRA_SHOW_BACKGROUND = "showBackground";
    private static final String EXTRA_DEFAULT_LIST_TYPE = "defaultListType";
    private static final String EXTRA_RESET_DIALOG = "resetDialog";

    // attributes used as keys when passing values to InstalledAppDetails activity
    public static final String APP_CHG = "chg";

    // constant value that can be used to check return code from sub activity.
    private static final int INSTALLED_APP_DETAILS = 1;

    public static final int SIZE_TOTAL = 0;
    public static final int SIZE_INTERNAL = 1;
    public static final int SIZE_EXTERNAL = 2;

    // sort order that can be changed through the menu can be sorted alphabetically
    // or size(descending)
    private static final int MENU_OPTIONS_BASE = 0;
    // Filter options used for displayed list of applications
    public static final int FILTER_APPS_ALL = MENU_OPTIONS_BASE + 0;
    public static final int FILTER_APPS_THIRD_PARTY = MENU_OPTIONS_BASE + 1;
    public static final int FILTER_APPS_SDCARD = MENU_OPTIONS_BASE + 2;
    public static final int FILTER_APPS_DISABLED = MENU_OPTIONS_BASE + 3;

    public static final int SORT_ORDER_ALPHA = MENU_OPTIONS_BASE + 4;
    public static final int SORT_ORDER_SIZE = MENU_OPTIONS_BASE + 5;
    public static final int SHOW_RUNNING_SERVICES = MENU_OPTIONS_BASE + 6;
    public static final int SHOW_BACKGROUND_PROCESSES = MENU_OPTIONS_BASE + 7;
    public static final int RESET_APP_PREFERENCES = MENU_OPTIONS_BASE + 8;
    // sort order
    private int mSortOrder = SORT_ORDER_ALPHA;
    
    private ApplicationsState mApplicationsState;

    public static class TabInfo implements OnItemClickListener {
        public final ManageApplications mOwner;
        public final ApplicationsState mApplicationsState;
        public final CharSequence mLabel;
        public final int mListType;
        public final int mFilter;
        public final AppClickListener mClickListener;
        public final CharSequence mInvalidSizeStr;
        public final CharSequence mComputingSizeStr;
        private final Bundle mSavedInstanceState;

        public ApplicationsAdapter mApplications;
        public LayoutInflater mInflater;
        public View mRootView;

        private IMediaContainerService mContainerService;

        private View mLoadingContainer;

        private View mListContainer;

        // ListView used to display list
        private ListView mListView;
        // Custom view used to display running processes
        private RunningProcessesView mRunningProcessesView;
        
        private LinearColorBar mColorBar;
        private TextView mStorageChartLabel;
        private TextView mUsedStorageText;
        private TextView mFreeStorageText;
        private long mFreeStorage = 0, mAppStorage = 0, mTotalStorage = 0;
        private long mLastUsedStorage, mLastAppStorage, mLastFreeStorage;

        final Runnable mRunningProcessesAvail = new Runnable() {
            public void run() {
                handleRunningProcessesAvail();
            }
        };

        public TabInfo(ManageApplications owner, ApplicationsState apps,
                CharSequence label, int listType, AppClickListener clickListener,
                Bundle savedInstanceState) {
            mOwner = owner;
            mApplicationsState = apps;
            mLabel = label;
            mListType = listType;
            switch (listType) {
                case LIST_TYPE_DOWNLOADED: mFilter = FILTER_APPS_THIRD_PARTY; break;
                case LIST_TYPE_SDCARD: mFilter = FILTER_APPS_SDCARD; break;
                case LIST_TYPE_DISABLED: mFilter = FILTER_APPS_DISABLED; break;
                default: mFilter = FILTER_APPS_ALL; break;
            }
            mClickListener = clickListener;
            mInvalidSizeStr = owner.getActivity().getText(R.string.invalid_size_value);
            mComputingSizeStr = owner.getActivity().getText(R.string.computing_size);
            mSavedInstanceState = savedInstanceState;
        }

        public void setContainerService(IMediaContainerService containerService) {
            mContainerService = containerService;
            updateStorageUsage();
        }

        public View build(LayoutInflater inflater, ViewGroup contentParent, View contentChild) {
            if (mRootView != null) {
                return mRootView;
            }

            mInflater = inflater;
            mRootView = inflater.inflate(mListType == LIST_TYPE_RUNNING
                    ? R.layout.manage_applications_running
                    : R.layout.manage_applications_apps, null);
            mLoadingContainer = mRootView.findViewById(R.id.loading_container);
            mLoadingContainer.setVisibility(View.VISIBLE);
            mListContainer = mRootView.findViewById(R.id.list_container);
            if (mListContainer != null) {
                // Create adapter and list view here
                View emptyView = mListContainer.findViewById(com.android.internal.R.id.empty);
                ListView lv = (ListView) mListContainer.findViewById(android.R.id.list);
                if (emptyView != null) {
                    lv.setEmptyView(emptyView);
                }
                lv.setOnItemClickListener(this);
                lv.setSaveEnabled(true);
                lv.setItemsCanFocus(true);
                lv.setTextFilterEnabled(true);
                mListView = lv;
                mApplications = new ApplicationsAdapter(mApplicationsState, this, mFilter);
                mListView.setAdapter(mApplications);
                mListView.setRecyclerListener(mApplications);
                mColorBar = (LinearColorBar)mListContainer.findViewById(R.id.storage_color_bar);
                mStorageChartLabel = (TextView)mListContainer.findViewById(R.id.storageChartLabel);
                mUsedStorageText = (TextView)mListContainer.findViewById(R.id.usedStorageText);
                mFreeStorageText = (TextView)mListContainer.findViewById(R.id.freeStorageText);
                Utils.prepareCustomPreferencesList(contentParent, contentChild, mListView, false);
                if (mFilter == FILTER_APPS_SDCARD) {
                    mStorageChartLabel.setText(mOwner.getActivity().getText(
                            R.string.sd_card_storage));
                } else {
                    mStorageChartLabel.setText(mOwner.getActivity().getText(
                            R.string.internal_storage));
                }
                applyCurrentStorage();
            }
            mRunningProcessesView = (RunningProcessesView)mRootView.findViewById(
                    R.id.running_processes);
            if (mRunningProcessesView != null) {
                mRunningProcessesView.doCreate(mSavedInstanceState);
            }

            return mRootView;
        }

        public void detachView() {
            if (mRootView != null) {
                ViewGroup group = (ViewGroup)mRootView.getParent();
                if (group != null) {
                    group.removeView(mRootView);
                }
            }
        }

        public void resume(int sortOrder) {
            if (mApplications != null) {
                mApplications.resume(sortOrder);
            }
            if (mRunningProcessesView != null) {
                boolean haveData = mRunningProcessesView.doResume(mOwner, mRunningProcessesAvail);
                if (haveData) {
                    mRunningProcessesView.setVisibility(View.VISIBLE);
                    mLoadingContainer.setVisibility(View.INVISIBLE);
                } else {
                    mLoadingContainer.setVisibility(View.VISIBLE);
                }
            }
        }

        public void pause() {
            if (mApplications != null) {
                mApplications.pause();
            }
            if (mRunningProcessesView != null) {
                mRunningProcessesView.doPause();
            }
        }

        void updateStorageUsage() {
            // Make sure a callback didn't come at an inopportune time.
            if (mOwner.getActivity() == null) return;
            // Doesn't make sense for stuff that is not an app list.
            if (mApplications == null) return;

            mFreeStorage = 0;
            mAppStorage = 0;
            mTotalStorage = 0;

            if (mFilter == FILTER_APPS_SDCARD) {
                if (mContainerService != null) {
                    try {
                        final long[] stats = mContainerService.getFileSystemStats(
                                Environment.getExternalStorageDirectory().getPath());
                        mTotalStorage = stats[0];
                        mFreeStorage = stats[1];
                    } catch (RemoteException e) {
                        Log.w(TAG, "Problem in container service", e);
                    }
                }

                if (mApplications != null) {
                    final int N = mApplications.getCount();
                    for (int i=0; i<N; i++) {
                        ApplicationsState.AppEntry ae = mApplications.getAppEntry(i);
                        mAppStorage += ae.externalCodeSize + ae.externalDataSize
                                + ae.externalCacheSize;
                    }
                }
            } else {
                if (mContainerService != null) {
                    try {
                        final long[] stats = mContainerService.getFileSystemStats(
                                Environment.getDataDirectory().getPath());
                        mTotalStorage = stats[0];
                        mFreeStorage = stats[1];
                    } catch (RemoteException e) {
                        Log.w(TAG, "Problem in container service", e);
                    }
                }

                final boolean emulatedStorage = Environment.isExternalStorageEmulated();
                if (mApplications != null) {
                    final int N = mApplications.getCount();
                    for (int i=0; i<N; i++) {
                        ApplicationsState.AppEntry ae = mApplications.getAppEntry(i);
                        mAppStorage += ae.codeSize + ae.dataSize;
                        if (emulatedStorage) {
                            mAppStorage += ae.externalCodeSize + ae.externalDataSize;
                        }
                    }
                }
                mFreeStorage += mApplicationsState.sumCacheSizes();
            }

            applyCurrentStorage();
        }

        void applyCurrentStorage() {
            // If view hierarchy is not yet created, no views to update.
            if (mRootView == null) {
                return;
            }
            if (mTotalStorage > 0) {
                mColorBar.setRatios((mTotalStorage-mFreeStorage-mAppStorage)/(float)mTotalStorage,
                        mAppStorage/(float)mTotalStorage, mFreeStorage/(float)mTotalStorage);
                long usedStorage = mTotalStorage - mFreeStorage;
                if (mLastUsedStorage != usedStorage) {
                    mLastUsedStorage = usedStorage;
                    String sizeStr = Formatter.formatShortFileSize(
                            mOwner.getActivity(), usedStorage);
                    mUsedStorageText.setText(mOwner.getActivity().getResources().getString(
                            R.string.service_foreground_processes, sizeStr));
                }
                if (mLastFreeStorage != mFreeStorage) {
                    mLastFreeStorage = mFreeStorage;
                    String sizeStr = Formatter.formatShortFileSize(
                            mOwner.getActivity(), mFreeStorage);
                    mFreeStorageText.setText(mOwner.getActivity().getResources().getString(
                            R.string.service_background_processes, sizeStr));
                }
            } else {
                mColorBar.setRatios(0, 0, 0);
                if (mLastUsedStorage != -1) {
                    mLastUsedStorage = -1;
                    mUsedStorageText.setText("");
                }
                if (mLastFreeStorage != -1) {
                    mLastFreeStorage = -1;
                    mFreeStorageText.setText("");
                }
            }
        }

        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            mClickListener.onItemClick(this, parent, view, position, id);
        }

        void handleRunningProcessesAvail() {
            mLoadingContainer.startAnimation(AnimationUtils.loadAnimation(
                    mOwner.getActivity(), android.R.anim.fade_out));
            mRunningProcessesView.startAnimation(AnimationUtils.loadAnimation(
                    mOwner.getActivity(), android.R.anim.fade_in));
            mRunningProcessesView.setVisibility(View.VISIBLE);
            mLoadingContainer.setVisibility(View.GONE);
        }
    }
    private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
    private int mNumTabs;
    TabInfo mCurTab = null;

    // Size resource used for packages whose size computation failed for some reason
    CharSequence mInvalidSizeStr;
    private CharSequence mComputingSizeStr;
    
    // layout inflater object used to inflate views
    private LayoutInflater mInflater;
    
    private String mCurrentPkgName;
    
    private Menu mOptionsMenu;

    // These are for keeping track of activity and spinner switch state.
    private boolean mActivityResumed;
    
    static final int LIST_TYPE_DOWNLOADED = 0;
    static final int LIST_TYPE_RUNNING = 1;
    static final int LIST_TYPE_SDCARD = 2;
    static final int LIST_TYPE_ALL = 3;
    static final int LIST_TYPE_DISABLED = 4;

    private boolean mShowBackground = false;
    
    private int mDefaultListType = -1;

    private ViewGroup mContentContainer;
    private View mRootView;
    private ViewPager mViewPager;

    AlertDialog mResetDialog;

    class MyPagerAdapter extends PagerAdapter
            implements ViewPager.OnPageChangeListener {
        int mCurPos = 0;

        @Override
        public int getCount() {
            return mNumTabs;
        }
        
        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            TabInfo tab = mTabs.get(position);
            View root = tab.build(mInflater, mContentContainer, mRootView);
            container.addView(root);
            root.setTag(R.id.name, tab);
            return root;
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            container.removeView((View)object);
        }

        @Override
        public boolean isViewFromObject(View view, Object object) {
            return view == object;
        }

        @Override
        public int getItemPosition(Object object) {
            return super.getItemPosition(object);
            //return ((TabInfo)((View)object).getTag(R.id.name)).mListType;
        }

        @Override
        public CharSequence getPageTitle(int position) {
            return mTabs.get(position).mLabel;
        }

        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        }

        @Override
        public void onPageSelected(int position) {
            mCurPos = position;
        }

        @Override
        public void onPageScrollStateChanged(int state) {
            if (state == ViewPager.SCROLL_STATE_IDLE) {
                updateCurrentTab(mCurPos);
            }
        }
    }

    /*
     * Custom adapter implementation for the ListView
     * This adapter maintains a map for each displayed application and its properties
     * An index value on each AppInfo object indicates the correct position or index
     * in the list. If the list gets updated dynamically when the user is viewing the list of
     * applications, we need to return the correct index of position. This is done by mapping
     * the getId methods via the package name into the internal maps and indices.
     * The order of applications in the list is mirrored in mAppLocalList
     */
    static class ApplicationsAdapter extends BaseAdapter implements Filterable,
            ApplicationsState.Callbacks, AbsListView.RecyclerListener {
        private final ApplicationsState mState;
        private final ApplicationsState.Session mSession;
        private final TabInfo mTab;
        private final Context mContext;
        private final ArrayList<View> mActive = new ArrayList<View>();
        private final int mFilterMode;
        private ArrayList<ApplicationsState.AppEntry> mBaseEntries;
        private ArrayList<ApplicationsState.AppEntry> mEntries;
        private boolean mResumed;
        private int mLastSortMode=-1;
        private boolean mWaitingForData;
        private int mWhichSize = SIZE_TOTAL;
        CharSequence mCurFilterPrefix;

        private Filter mFilter = new Filter() {
            @Override
            protected FilterResults performFiltering(CharSequence constraint) {
                ArrayList<ApplicationsState.AppEntry> entries
                        = applyPrefixFilter(constraint, mBaseEntries);
                FilterResults fr = new FilterResults();
                fr.values = entries;
                fr.count = entries.size();
                return fr;
            }

            @Override
            protected void publishResults(CharSequence constraint, FilterResults results) {
                mCurFilterPrefix = constraint;
                mEntries = (ArrayList<ApplicationsState.AppEntry>)results.values;
                notifyDataSetChanged();
                mTab.updateStorageUsage();
            }
        };

        public ApplicationsAdapter(ApplicationsState state, TabInfo tab, int filterMode) {
            mState = state;
            mSession = state.newSession(this);
            mTab = tab;
            mContext = tab.mOwner.getActivity();
            mFilterMode = filterMode;
        }

        public void resume(int sort) {
            if (DEBUG) Log.i(TAG, "Resume!  mResumed=" + mResumed);
            if (!mResumed) {
                mResumed = true;
                mSession.resume();
                mLastSortMode = sort;
                rebuild(true);
            } else {
                rebuild(sort);
            }
        }

        public void pause() {
            if (mResumed) {
                mResumed = false;
                mSession.pause();
            }
        }

        public void rebuild(int sort) {
            if (sort == mLastSortMode) {
                return;
            }
            mLastSortMode = sort;
            rebuild(true);
        }
        
        public void rebuild(boolean eraseold) {
            if (DEBUG) Log.i(TAG, "Rebuilding app list...");
            ApplicationsState.AppFilter filterObj;
            Comparator<AppEntry> comparatorObj;
            boolean emulated = Environment.isExternalStorageEmulated();
            if (emulated) {
                mWhichSize = SIZE_TOTAL;
            } else {
                mWhichSize = SIZE_INTERNAL;
            }
            switch (mFilterMode) {
                case FILTER_APPS_THIRD_PARTY:
                    filterObj = ApplicationsState.THIRD_PARTY_FILTER;
                    break;
                case FILTER_APPS_SDCARD:
                    filterObj = ApplicationsState.ON_SD_CARD_FILTER;
                    if (!emulated) {
                        mWhichSize = SIZE_EXTERNAL;
                    }
                    break;
                case FILTER_APPS_DISABLED:
                    filterObj = ApplicationsState.DISABLED_FILTER;
                    break;
                default:
                    filterObj = ApplicationsState.ALL_ENABLED_FILTER;
                    break;
            }
            switch (mLastSortMode) {
                case SORT_ORDER_SIZE:
                    switch (mWhichSize) {
                        case SIZE_INTERNAL:
                            comparatorObj = ApplicationsState.INTERNAL_SIZE_COMPARATOR;
                            break;
                        case SIZE_EXTERNAL:
                            comparatorObj = ApplicationsState.EXTERNAL_SIZE_COMPARATOR;
                            break;
                        default:
                            comparatorObj = ApplicationsState.SIZE_COMPARATOR;
                            break;
                    }
                    break;
                default:
                    comparatorObj = ApplicationsState.ALPHA_COMPARATOR;
                    break;
            }
            ArrayList<ApplicationsState.AppEntry> entries
                    = mSession.rebuild(filterObj, comparatorObj);
            if (entries == null && !eraseold) {
                // Don't have new list yet, but can continue using the old one.
                return;
            }
            mBaseEntries = entries;
            if (mBaseEntries != null) {
                mEntries = applyPrefixFilter(mCurFilterPrefix, mBaseEntries);
            } else {
                mEntries = null;
            }
            notifyDataSetChanged();
            mTab.updateStorageUsage();

            if (entries == null) {
                mWaitingForData = true;
                mTab.mListContainer.setVisibility(View.INVISIBLE);
                mTab.mLoadingContainer.setVisibility(View.VISIBLE);
            } else {
                mTab.mListContainer.setVisibility(View.VISIBLE);
                mTab.mLoadingContainer.setVisibility(View.GONE);
            }
        }

        ArrayList<ApplicationsState.AppEntry> applyPrefixFilter(CharSequence prefix,
                ArrayList<ApplicationsState.AppEntry> origEntries) {
            if (prefix == null || prefix.length() == 0) {
                return origEntries;
            } else {
                String prefixStr = ApplicationsState.normalize(prefix.toString());
                final String spacePrefixStr = " " + prefixStr;
                ArrayList<ApplicationsState.AppEntry> newEntries
                        = new ArrayList<ApplicationsState.AppEntry>();
                for (int i=0; i<origEntries.size(); i++) {
                    ApplicationsState.AppEntry entry = origEntries.get(i);
                    String nlabel = entry.getNormalizedLabel();
                    if (nlabel.startsWith(prefixStr) || nlabel.indexOf(spacePrefixStr) != -1) {
                        newEntries.add(entry);
                    }
                }
                return newEntries;
            }
        }

        @Override
        public void onRunningStateChanged(boolean running) {
            mTab.mOwner.getActivity().setProgressBarIndeterminateVisibility(running);
        }

        @Override
        public void onRebuildComplete(ArrayList<AppEntry> apps) {
            if (mTab.mLoadingContainer.getVisibility() == View.VISIBLE) {
                mTab.mLoadingContainer.startAnimation(AnimationUtils.loadAnimation(
                        mContext, android.R.anim.fade_out));
                mTab.mListContainer.startAnimation(AnimationUtils.loadAnimation(
                        mContext, android.R.anim.fade_in));
            }
            mTab.mListContainer.setVisibility(View.VISIBLE);
            mTab.mLoadingContainer.setVisibility(View.GONE);
            mWaitingForData = false;
            mBaseEntries = apps;
            mEntries = applyPrefixFilter(mCurFilterPrefix, mBaseEntries);
            notifyDataSetChanged();
            mTab.updateStorageUsage();
        }

        @Override
        public void onPackageListChanged() {
            rebuild(false);
        }

        @Override
        public void onPackageIconChanged() {
            // We ensure icons are loaded when their item is displayed, so
            // don't care about icons loaded in the background.
        }

        @Override
        public void onPackageSizeChanged(String packageName) {
            for (int i=0; i<mActive.size(); i++) {
                AppViewHolder holder = (AppViewHolder)mActive.get(i).getTag();
                if (holder.entry.info.packageName.equals(packageName)) {
                    synchronized (holder.entry) {
                        holder.updateSizeText(mTab.mInvalidSizeStr, mWhichSize);
                    }
                    if (holder.entry.info.packageName.equals(mTab.mOwner.mCurrentPkgName)
                            && mLastSortMode == SORT_ORDER_SIZE) {
                        // We got the size information for the last app the
                        // user viewed, and are sorting by size...  they may
                        // have cleared data, so we immediately want to resort
                        // the list with the new size to reflect it to the user.
                        rebuild(false);
                    }
                    mTab.updateStorageUsage();
                    return;
                }
            }
        }

        @Override
        public void onAllSizesComputed() {
            if (mLastSortMode == SORT_ORDER_SIZE) {
                rebuild(false);
            }
            mTab.updateStorageUsage();
        }
        
        public int getCount() {
            return mEntries != null ? mEntries.size() : 0;
        }
        
        public Object getItem(int position) {
            return mEntries.get(position);
        }
        
        public ApplicationsState.AppEntry getAppEntry(int position) {
            return mEntries.get(position);
        }

        public long getItemId(int position) {
            return mEntries.get(position).id;
        }
        
        public View getView(int position, View convertView, ViewGroup parent) {
            // A ViewHolder keeps references to children views to avoid unnecessary calls
            // to findViewById() on each row.
            AppViewHolder holder = AppViewHolder.createOrRecycle(mTab.mInflater, convertView);
            convertView = holder.rootView;

            // Bind the data efficiently with the holder
            ApplicationsState.AppEntry entry = mEntries.get(position);
            synchronized (entry) {
                holder.entry = entry;
                if (entry.label != null) {
                    holder.appName.setText(entry.label);
                }
                mState.ensureIcon(entry);
                if (entry.icon != null) {
                    holder.appIcon.setImageDrawable(entry.icon);
                }
                holder.updateSizeText(mTab.mInvalidSizeStr, mWhichSize);
                if ((entry.info.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
                    holder.disabled.setVisibility(View.VISIBLE);
                    holder.disabled.setText(R.string.not_installed);
                } else if (!entry.info.enabled) {
                    holder.disabled.setVisibility(View.VISIBLE);
                    holder.disabled.setText(R.string.disabled);
                } else {
                    holder.disabled.setVisibility(View.GONE);
                }
                if (mFilterMode == FILTER_APPS_SDCARD) {
                    holder.checkBox.setVisibility(View.VISIBLE);
                    holder.checkBox.setChecked((entry.info.flags
                            & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0);
                } else {
                    holder.checkBox.setVisibility(View.GONE);
                }
            }
            mActive.remove(convertView);
            mActive.add(convertView);
            return convertView;
        }

        @Override
        public Filter getFilter() {
            return mFilter;
        }

        @Override
        public void onMovedToScrapHeap(View view) {
            mActive.remove(view);
        }
    }
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setHasOptionsMenu(true);

        mApplicationsState = ApplicationsState.getInstance(getActivity().getApplication());
        Intent intent = getActivity().getIntent();
        String action = intent.getAction();
        int defaultListType = LIST_TYPE_DOWNLOADED;
        String className = getArguments() != null
                ? getArguments().getString("classname") : null;
        if (className == null) {
            className = intent.getComponent().getClassName();
        }
        if (className.equals(RunningServicesActivity.class.getName())
                || className.endsWith(".RunningServices")) {
            defaultListType = LIST_TYPE_RUNNING;
        } else if (className.equals(StorageUseActivity.class.getName())
                || Intent.ACTION_MANAGE_PACKAGE_STORAGE.equals(action)
                || className.endsWith(".StorageUse")) {
            mSortOrder = SORT_ORDER_SIZE;
            defaultListType = LIST_TYPE_ALL;
        } else if (Settings.ACTION_MANAGE_ALL_APPLICATIONS_SETTINGS.equals(action)) {
            // Select the all-apps list, with the default sorting
            defaultListType = LIST_TYPE_ALL;
        }

        if (savedInstanceState != null) {
            mSortOrder = savedInstanceState.getInt(EXTRA_SORT_ORDER, mSortOrder);
            int tmp = savedInstanceState.getInt(EXTRA_DEFAULT_LIST_TYPE, -1);
            if (tmp != -1) defaultListType = tmp;
            mShowBackground = savedInstanceState.getBoolean(EXTRA_SHOW_BACKGROUND, false);
        }

        mDefaultListType = defaultListType;

        final Intent containerIntent = new Intent().setComponent(
                StorageMeasurement.DEFAULT_CONTAINER_COMPONENT);
        getActivity().bindService(containerIntent, mContainerConnection, Context.BIND_AUTO_CREATE);

        mInvalidSizeStr = getActivity().getText(R.string.invalid_size_value);
        mComputingSizeStr = getActivity().getText(R.string.computing_size);

        TabInfo tab = new TabInfo(this, mApplicationsState,
                getActivity().getString(R.string.filter_apps_third_party),
                LIST_TYPE_DOWNLOADED, this, savedInstanceState);
        mTabs.add(tab);

        if (!Environment.isExternalStorageEmulated()) {
            tab = new TabInfo(this, mApplicationsState,
                    getActivity().getString(R.string.filter_apps_onsdcard),
                    LIST_TYPE_SDCARD, this, savedInstanceState);
            mTabs.add(tab);
        }

        tab = new TabInfo(this, mApplicationsState,
                getActivity().getString(R.string.filter_apps_running),
                LIST_TYPE_RUNNING, this, savedInstanceState);
        mTabs.add(tab);

        tab = new TabInfo(this, mApplicationsState,
                getActivity().getString(R.string.filter_apps_all),
                LIST_TYPE_ALL, this, savedInstanceState);
        mTabs.add(tab);

        tab = new TabInfo(this, mApplicationsState,
                getActivity().getString(R.string.filter_apps_disabled),
                LIST_TYPE_DISABLED, this, savedInstanceState);
        mTabs.add(tab);

        mNumTabs = mTabs.size();
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        // initialize the inflater
        mInflater = inflater;

        View rootView = mInflater.inflate(R.layout.manage_applications_content,
                container, false);
        mContentContainer = container;
        mRootView = rootView;

        mViewPager = (ViewPager) rootView.findViewById(R.id.pager);
        MyPagerAdapter adapter = new MyPagerAdapter();
        mViewPager.setAdapter(adapter);
        mViewPager.setOnPageChangeListener(adapter);
        PagerTabStrip tabs = (PagerTabStrip) rootView.findViewById(R.id.tabs);
        tabs.setTabIndicatorColorResource(android.R.color.holo_blue_light);

        // We have to do this now because PreferenceFrameLayout looks at it
        // only when the view is added.
        if (container instanceof PreferenceFrameLayout) {
            ((PreferenceFrameLayout.LayoutParams) rootView.getLayoutParams()).removeBorders = true;
        }

        if (savedInstanceState != null && savedInstanceState.getBoolean(EXTRA_RESET_DIALOG)) {
            buildResetDialog();
        }

        if (savedInstanceState == null) {
            // First time init: make sure view pager is showing the correct tab.
            for (int i = 0; i < mTabs.size(); i++) {
                TabInfo tab = mTabs.get(i);
                if (tab.mListType == mDefaultListType) {
                    mViewPager.setCurrentItem(i);
                    break;
                }
            }
        }

        return rootView;
    }

    @Override
    public void onStart() {
        super.onStart();
    }

    @Override
    public void onResume() {
        super.onResume();
        mActivityResumed = true;
        updateCurrentTab(mViewPager.getCurrentItem());
        updateNumTabs();
        updateOptionsMenu();
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putInt(EXTRA_SORT_ORDER, mSortOrder);
        if (mDefaultListType != -1) {
            outState.putInt(EXTRA_DEFAULT_LIST_TYPE, mDefaultListType);
        }
        outState.putBoolean(EXTRA_SHOW_BACKGROUND, mShowBackground);
        if (mResetDialog != null) {
            outState.putBoolean(EXTRA_RESET_DIALOG, true);
        }
    }

    @Override
    public void onPause() {
        super.onPause();
        mActivityResumed = false;
        for (int i=0; i<mTabs.size(); i++) {
            mTabs.get(i).pause();
        }
    }

    @Override
    public void onStop() {
        super.onStop();
        if (mResetDialog != null) {
            mResetDialog.dismiss();
            mResetDialog = null;
        }
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();

        // We are going to keep the tab data structures around, but they
        // are no longer attached to their view hierarchy.
        for (int i=0; i<mTabs.size(); i++) {
            mTabs.get(i).detachView();
        }
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == INSTALLED_APP_DETAILS && mCurrentPkgName != null) {
            mApplicationsState.requestSize(mCurrentPkgName);
        }
    }

    private void updateNumTabs() {
        int newNum = mApplicationsState.haveDisabledApps() ? mTabs.size() : (mTabs.size()-1);
        if (newNum != mNumTabs) {
            mNumTabs = newNum;
            if (mViewPager != null) {
                mViewPager.getAdapter().notifyDataSetChanged();
            }
        }
    }

    TabInfo tabForType(int type) {
        for (int i = 0; i < mTabs.size(); i++) {
            TabInfo tab = mTabs.get(i);
            if (tab.mListType == type) {
                return tab;
            }
        }
        return null;
    }

    // utility method used to start sub activity
    private void startApplicationDetailsActivity() {
        // start new fragment to display extended information
        Bundle args = new Bundle();
        args.putString(InstalledAppDetails.ARG_PACKAGE_NAME, mCurrentPkgName);

        PreferenceActivity pa = (PreferenceActivity)getActivity();
        pa.startPreferencePanel(InstalledAppDetails.class.getName(), args,
                R.string.application_info_label, null, this, INSTALLED_APP_DETAILS);
    }
    
    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        mOptionsMenu = menu;
        // note: icons removed for now because the cause the new action
        // bar UI to be very confusing.
        menu.add(0, SORT_ORDER_ALPHA, 1, R.string.sort_order_alpha)
                //.setIcon(android.R.drawable.ic_menu_sort_alphabetically)
                .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
        menu.add(0, SORT_ORDER_SIZE, 2, R.string.sort_order_size)
                //.setIcon(android.R.drawable.ic_menu_sort_by_size)
                .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
        menu.add(0, SHOW_RUNNING_SERVICES, 3, R.string.show_running_services)
                .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
        menu.add(0, SHOW_BACKGROUND_PROCESSES, 3, R.string.show_background_processes)
                .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
        menu.add(0, RESET_APP_PREFERENCES, 4, R.string.reset_app_preferences)
                .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
        updateOptionsMenu();
    }
    
    @Override
    public void onPrepareOptionsMenu(Menu menu) {
        updateOptionsMenu();
    }
    
    @Override
    public void onDestroyOptionsMenu() {
        mOptionsMenu = null;
    }

    @Override
    public void onDestroy() {
        getActivity().unbindService(mContainerConnection);
        super.onDestroy();
    }

    void updateOptionsMenu() {
        if (mOptionsMenu == null) {
            return;
        }
        
        /*
         * The running processes screen doesn't use the mApplicationsAdapter
         * so bringing up this menu in that case doesn't make any sense.
         */
        if (mCurTab != null && mCurTab.mListType == LIST_TYPE_RUNNING) {
            TabInfo tab = tabForType(LIST_TYPE_RUNNING);
            boolean showingBackground = tab != null && tab.mRunningProcessesView != null
                    ? tab.mRunningProcessesView.mAdapter.getShowBackground() : false;
            mOptionsMenu.findItem(SORT_ORDER_ALPHA).setVisible(false);
            mOptionsMenu.findItem(SORT_ORDER_SIZE).setVisible(false);
            mOptionsMenu.findItem(SHOW_RUNNING_SERVICES).setVisible(showingBackground);
            mOptionsMenu.findItem(SHOW_BACKGROUND_PROCESSES).setVisible(!showingBackground);
            mOptionsMenu.findItem(RESET_APP_PREFERENCES).setVisible(false);
        } else {
            mOptionsMenu.findItem(SORT_ORDER_ALPHA).setVisible(mSortOrder != SORT_ORDER_ALPHA);
            mOptionsMenu.findItem(SORT_ORDER_SIZE).setVisible(mSortOrder != SORT_ORDER_SIZE);
            mOptionsMenu.findItem(SHOW_RUNNING_SERVICES).setVisible(false);
            mOptionsMenu.findItem(SHOW_BACKGROUND_PROCESSES).setVisible(false);
            mOptionsMenu.findItem(RESET_APP_PREFERENCES).setVisible(true);
        }
    }

    void buildResetDialog() {
        if (mResetDialog == null) {
            AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
            builder.setTitle(R.string.reset_app_preferences_title);
            builder.setMessage(R.string.reset_app_preferences_desc);
            builder.setPositiveButton(R.string.reset_app_preferences_button, this);
            builder.setNegativeButton(R.string.cancel, null);
            mResetDialog = builder.show();
            mResetDialog.setOnDismissListener(this);
        }
    }

    @Override
    public void onDismiss(DialogInterface dialog) {
        if (mResetDialog == dialog) {
            mResetDialog = null;
        }
    }


    @Override
    public void onClick(DialogInterface dialog, int which) {
        if (mResetDialog == dialog) {
            final PackageManager pm = getActivity().getPackageManager();
            final IPackageManager mIPm = IPackageManager.Stub.asInterface(
                    ServiceManager.getService("package"));
            final INotificationManager nm = INotificationManager.Stub.asInterface(
                    ServiceManager.getService(Context.NOTIFICATION_SERVICE));
            final NetworkPolicyManager npm = NetworkPolicyManager.from(getActivity());
            final AppOpsManager aom = (AppOpsManager)getActivity().getSystemService(
                    Context.APP_OPS_SERVICE);
            final Handler handler = new Handler(getActivity().getMainLooper());
            (new AsyncTask<Void, Void, Void>() {
                @Override protected Void doInBackground(Void... params) {
                    List<ApplicationInfo> apps = pm.getInstalledApplications(
                            PackageManager.GET_DISABLED_COMPONENTS);
                    for (int i=0; i<apps.size(); i++) {
                        ApplicationInfo app = apps.get(i);
                        try {
                            if (DEBUG) Log.v(TAG, "Enabling notifications: " + app.packageName);
                            nm.setNotificationsEnabledForPackage(app.packageName, app.uid, true);
                        } catch (android.os.RemoteException ex) {
                        }
                        if (!app.enabled) {
                            if (DEBUG) Log.v(TAG, "Enabling app: " + app.packageName);
                            if (pm.getApplicationEnabledSetting(app.packageName)
                                    == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) {
                                pm.setApplicationEnabledSetting(app.packageName,
                                        PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
                                        PackageManager.DONT_KILL_APP);
                            }
                        }
                    }
                    try {
                        mIPm.resetPreferredActivities(UserHandle.myUserId());
                    } catch (RemoteException e) {
                    }
                    aom.resetAllModes();
                    final int[] restrictedUids = npm.getUidsWithPolicy(
                            POLICY_REJECT_METERED_BACKGROUND);
                    final int currentUserId = ActivityManager.getCurrentUser();
                    for (int uid : restrictedUids) {
                        // Only reset for current user
                        if (UserHandle.getUserId(uid) == currentUserId) {
                            if (DEBUG) Log.v(TAG, "Clearing data policy: " + uid);
                            npm.setUidPolicy(uid, POLICY_NONE);
                        }
                    }
                    handler.post(new Runnable() {
                        @Override public void run() {
                            if (DEBUG) Log.v(TAG, "Done clearing");
                            if (getActivity() != null && mActivityResumed) {
                                if (DEBUG) Log.v(TAG, "Updating UI!");
                                for (int i=0; i<mTabs.size(); i++) {
                                    TabInfo tab = mTabs.get(i);
                                    if (tab.mApplications != null) {
                                        tab.mApplications.pause();
                                    }
                                }
                                if (mCurTab != null) {
                                    mCurTab.resume(mSortOrder);
                                }
                            }
                        }
                    });
                    return null;
                }
            }).execute();
        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int menuId = item.getItemId();
        if ((menuId == SORT_ORDER_ALPHA) || (menuId == SORT_ORDER_SIZE)) {
            mSortOrder = menuId;
            if (mCurTab != null && mCurTab.mApplications != null) {
                mCurTab.mApplications.rebuild(mSortOrder);
            }
        } else if (menuId == SHOW_RUNNING_SERVICES) {
            mShowBackground = false;
            if (mCurTab != null && mCurTab.mRunningProcessesView != null) {
                mCurTab.mRunningProcessesView.mAdapter.setShowBackground(false);
            }
        } else if (menuId == SHOW_BACKGROUND_PROCESSES) {
            mShowBackground = true;
            if (mCurTab != null && mCurTab.mRunningProcessesView != null) {
                mCurTab.mRunningProcessesView.mAdapter.setShowBackground(true);
            }
        } else if (menuId == RESET_APP_PREFERENCES) {
            buildResetDialog();
        } else {
            // Handle the home button
            return false;
        }
        updateOptionsMenu();
        return true;
    }
    
    public void onItemClick(TabInfo tab, AdapterView<?> parent, View view, int position,
            long id) {
        if (tab.mApplications != null && tab.mApplications.getCount() > position) {
            ApplicationsState.AppEntry entry = tab.mApplications.getAppEntry(position);
            mCurrentPkgName = entry.info.packageName;
            startApplicationDetailsActivity();
        }
    }

    public void updateCurrentTab(int position) {
        TabInfo tab = mTabs.get(position);
        mCurTab = tab;

        // Put things in the correct paused/resumed state.
        if (mActivityResumed) {
            mCurTab.build(mInflater, mContentContainer, mRootView);
            mCurTab.resume(mSortOrder);
        } else {
            mCurTab.pause();
        }
        for (int i=0; i<mTabs.size(); i++) {
            TabInfo t = mTabs.get(i);
            if (t != mCurTab) {
                t.pause();
            }
        }

        mCurTab.updateStorageUsage();
        updateOptionsMenu();
        final Activity host = getActivity();
        if (host != null) {
            host.invalidateOptionsMenu();
        }
    }

    private volatile IMediaContainerService mContainerService;

    private final ServiceConnection mContainerConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mContainerService = IMediaContainerService.Stub.asInterface(service);
            for (int i=0; i<mTabs.size(); i++) {
                mTabs.get(i).setContainerService(mContainerService);
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            mContainerService = null;
        }
    };
}
