/*
 * 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.manageapplications;

import static androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_IDLE;
import static com.android.settings.applications.manageapplications.AppFilterRegistry
        .FILTER_APPS_ALL;
import static com.android.settings.applications.manageapplications.AppFilterRegistry
        .FILTER_APPS_DISABLED;
import static com.android.settings.applications.manageapplications.AppFilterRegistry
        .FILTER_APPS_ENABLED;
import static com.android.settings.applications.manageapplications.AppFilterRegistry
        .FILTER_APPS_FREQUENT;
import static com.android.settings.applications.manageapplications.AppFilterRegistry
        .FILTER_APPS_INSTANT;
import static com.android.settings.applications.manageapplications.AppFilterRegistry
        .FILTER_APPS_PERSONAL;
import static com.android.settings.applications.manageapplications.AppFilterRegistry
        .FILTER_APPS_POWER_WHITELIST;
import static com.android.settings.applications.manageapplications.AppFilterRegistry
        .FILTER_APPS_POWER_WHITELIST_ALL;
import static com.android.settings.applications.manageapplications.AppFilterRegistry
        .FILTER_APPS_RECENT;
import static com.android.settings.applications.manageapplications.AppFilterRegistry
        .FILTER_APPS_WORK;

import android.annotation.Nullable;
import android.annotation.StringRes;
import android.app.Activity;
import android.app.usage.IUsageStatsManager;
import android.app.usage.UsageStatsManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageItemInfo;
import android.os.Bundle;
import android.os.Environment;
import android.os.ServiceManager;
import android.os.UserHandle;
import android.os.UserManager;
import android.preference.PreferenceFrameLayout;
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.text.TextUtils;
import android.util.ArraySet;
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.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.FrameLayout;
import android.widget.Spinner;

import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.Settings;
import com.android.settings.Settings.GamesStorageActivity;
import com.android.settings.Settings.HighPowerApplicationsActivity;
import com.android.settings.Settings.ManageExternalSourcesActivity;
import com.android.settings.Settings.MoviesStorageActivity;
import com.android.settings.Settings.OverlaySettingsActivity;
import com.android.settings.Settings.StorageUseActivity;
import com.android.settings.Settings.UsageAccessSettingsActivity;
import com.android.settings.Settings.WriteSettingsActivity;
import com.android.settings.SettingsActivity;
import com.android.settings.applications.AppInfoBase;
import com.android.settings.applications.AppStateAppOpsBridge.PermissionState;
import com.android.settings.applications.AppStateBaseBridge;
import com.android.settings.applications.AppStateDirectoryAccessBridge;
import com.android.settings.applications.AppStateInstallAppsBridge;
import com.android.settings.applications.AppStateNotificationBridge;
import com.android.settings.applications.AppStateNotificationBridge.NotificationsSentState;
import com.android.settings.applications.AppStateOverlayBridge;
import com.android.settings.applications.AppStatePowerBridge;
import com.android.settings.applications.AppStateUsageBridge;
import com.android.settings.applications.AppStateUsageBridge.UsageState;
import com.android.settings.applications.AppStateWriteSettingsBridge;
import com.android.settings.applications.AppStorageSettings;
import com.android.settings.applications.DefaultAppSettings;
import com.android.settings.applications.DirectoryAccessDetails;
import com.android.settings.applications.InstalledAppCounter;
import com.android.settings.applications.UsageAccessDetails;
import com.android.settings.applications.appinfo.AppInfoDashboardFragment;
import com.android.settings.applications.appinfo.DrawOverlayDetails;
import com.android.settings.applications.appinfo.ExternalSourcesDetails;
import com.android.settings.applications.appinfo.WriteSettingsDetails;
import com.android.settings.core.InstrumentedFragment;
import com.android.settings.core.SubSettingLauncher;
import com.android.settings.dashboard.SummaryLoader;
import com.android.settings.fuelgauge.HighPowerDetail;
import com.android.settings.notification.AppNotificationSettings;
import com.android.settings.notification.ConfigureNotificationSettings;
import com.android.settings.notification.NotificationBackend;
import com.android.settings.widget.LoadingViewController;
import com.android.settings.wifi.AppStateChangeWifiStateBridge;
import com.android.settings.wifi.ChangeWifiStateDetails;
import com.android.settingslib.HelpUtils;
import com.android.settingslib.applications.ApplicationsState;
import com.android.settingslib.applications.ApplicationsState.AppEntry;
import com.android.settingslib.applications.ApplicationsState.AppFilter;
import com.android.settingslib.applications.ApplicationsState.CompoundFilter;
import com.android.settingslib.applications.ApplicationsState.VolumeFilter;
import com.android.settingslib.applications.StorageStatsSource;
import com.android.settingslib.fuelgauge.PowerWhitelistBackend;
import com.android.settingslib.utils.ThreadUtils;
import com.android.settingslib.wrapper.PackageManagerWrapper;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Set;

/**
 * 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 InstrumentedFragment
        implements View.OnClickListener, OnItemSelectedListener {

    static final String TAG = "ManageApplications";
    static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);

    // Intent extras.
    public static final String EXTRA_CLASSNAME = "classname";
    // Used for storage only.
    public static final String EXTRA_VOLUME_UUID = "volumeUuid";
    public static final String EXTRA_VOLUME_NAME = "volumeName";
    public static final String EXTRA_STORAGE_TYPE = "storageType";
    public static final String EXTRA_WORK_ONLY = "workProfileOnly";
    public static final String EXTRA_WORK_ID = "workId";

    private static final String EXTRA_SORT_ORDER = "sortOrder";
    private static final String EXTRA_SHOW_SYSTEM = "showSystem";
    private static final String EXTRA_HAS_ENTRIES = "hasEntries";
    private static final String EXTRA_HAS_BRIDGE = "hasBridge";

    // attributes used as keys when passing values to AppInfoDashboardFragment 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;
    private static final int ADVANCED_SETTINGS = 2;

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

    // Storage types. Used to determine what the extra item in the list of preferences is.
    public static final int STORAGE_TYPE_DEFAULT = 0; // Show all apps that are not categorized.
    public static final int STORAGE_TYPE_MUSIC = 1;
    public static final int STORAGE_TYPE_LEGACY = 2; // Show apps even if they can be categorized.
    public static final int STORAGE_TYPE_PHOTOS_VIDEOS = 3;

    private static final int NO_USER_SPECIFIED = -1;

    // sort order
    @VisibleForTesting
    int mSortOrder = R.id.sort_order_alpha;

    // whether showing system apps.
    private boolean mShowSystem;

    private ApplicationsState mApplicationsState;

    public int mListType;
    private AppFilterItem mFilter;
    private ApplicationsAdapter mApplications;

    private View mLoadingContainer;

    private View mListContainer;
    private RecyclerView mRecyclerView;

    // Size resource used for packages whose size computation failed for some reason
    CharSequence mInvalidSizeStr;

    private String mCurrentPkgName;
    private int mCurrentUid;

    private Menu mOptionsMenu;

    public static final int LIST_TYPE_MAIN = 0;
    public static final int LIST_TYPE_NOTIFICATION = 1;
    public static final int LIST_TYPE_STORAGE = 3;
    public static final int LIST_TYPE_USAGE_ACCESS = 4;
    public static final int LIST_TYPE_HIGH_POWER = 5;
    public static final int LIST_TYPE_OVERLAY = 6;
    public static final int LIST_TYPE_WRITE_SETTINGS = 7;
    public static final int LIST_TYPE_MANAGE_SOURCES = 8;
    public static final int LIST_TYPE_GAMES = 9;
    public static final int LIST_TYPE_MOVIES = 10;
    public static final int LIST_TYPE_PHOTOGRAPHY = 11;
    public static final int LIST_TYPE_DIRECTORY_ACCESS = 12;
    public static final int LIST_TYPE_WIFI_ACCESS = 13;

    // List types that should show instant apps.
    public static final Set<Integer> LIST_TYPES_WITH_INSTANT = new ArraySet<>(Arrays.asList(
            LIST_TYPE_MAIN,
            LIST_TYPE_STORAGE));

    private View mRootView;
    private View mSpinnerHeader;
    private Spinner mFilterSpinner;
    private FilterSpinnerAdapter mFilterAdapter;
    private IUsageStatsManager mUsageStatsManager;
    private UserManager mUserManager;
    private NotificationBackend mNotificationBackend;
    private ResetAppsHelper mResetAppsHelper;
    private String mVolumeUuid;
    private int mStorageType;
    private boolean mIsWorkOnly;
    private int mWorkUserId;
    private View mEmptyView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setHasOptionsMenu(true);
        final Activity activity = getActivity();
        mApplicationsState = ApplicationsState.getInstance(activity.getApplication());

        Intent intent = activity.getIntent();
        Bundle args = getArguments();
        int screenTitle = intent.getIntExtra(
                SettingsActivity.EXTRA_SHOW_FRAGMENT_TITLE_RESID, R.string.application_info_label);
        String className = args != null ? args.getString(EXTRA_CLASSNAME) : null;
        if (className == null) {
            className = intent.getComponent().getClassName();
        }
        if (className.equals(StorageUseActivity.class.getName())) {
            if (args != null && args.containsKey(EXTRA_VOLUME_UUID)) {
                mVolumeUuid = args.getString(EXTRA_VOLUME_UUID);
                mStorageType = args.getInt(EXTRA_STORAGE_TYPE, STORAGE_TYPE_DEFAULT);
                mListType = LIST_TYPE_STORAGE;
            } else {
                // No volume selected, display a normal list, sorted by size.
                mListType = LIST_TYPE_MAIN;
            }
            mSortOrder = R.id.sort_order_size;
        } else if (className.equals(UsageAccessSettingsActivity.class.getName())) {
            mListType = LIST_TYPE_USAGE_ACCESS;
            screenTitle = R.string.usage_access;
        } else if (className.equals(HighPowerApplicationsActivity.class.getName())) {
            mListType = LIST_TYPE_HIGH_POWER;
            // Default to showing system.
            mShowSystem = true;
            screenTitle = R.string.high_power_apps;
        } else if (className.equals(OverlaySettingsActivity.class.getName())) {
            mListType = LIST_TYPE_OVERLAY;
            screenTitle = R.string.system_alert_window_settings;
        } else if (className.equals(WriteSettingsActivity.class.getName())) {
            mListType = LIST_TYPE_WRITE_SETTINGS;
            screenTitle = R.string.write_settings;
        } else if (className.equals(ManageExternalSourcesActivity.class.getName())) {
            mListType = LIST_TYPE_MANAGE_SOURCES;
            screenTitle = R.string.install_other_apps;
        } else if (className.equals(GamesStorageActivity.class.getName())) {
            mListType = LIST_TYPE_GAMES;
            mSortOrder = R.id.sort_order_size;
        } else if (className.equals(MoviesStorageActivity.class.getName())) {
            mListType = LIST_TYPE_MOVIES;
            mSortOrder = R.id.sort_order_size;
        } else if (className.equals(Settings.PhotosStorageActivity.class.getName())) {
            mListType = LIST_TYPE_PHOTOGRAPHY;
            mSortOrder = R.id.sort_order_size;
            mStorageType = args.getInt(EXTRA_STORAGE_TYPE, STORAGE_TYPE_DEFAULT);
        } else if (className.equals(Settings.DirectoryAccessSettingsActivity.class.getName())) {
            mListType = LIST_TYPE_DIRECTORY_ACCESS;
            screenTitle = R.string.directory_access;
        } else if (className.equals(Settings.ChangeWifiStateActivity.class.getName())) {
            mListType = LIST_TYPE_WIFI_ACCESS;
            screenTitle = R.string.change_wifi_state_title;
        } else if (className.equals(Settings.NotificationAppListActivity.class.getName())) {
            mListType = LIST_TYPE_NOTIFICATION;
            mUsageStatsManager = IUsageStatsManager.Stub.asInterface(
                    ServiceManager.getService(Context.USAGE_STATS_SERVICE));
            mUserManager = UserManager.get(getContext());
            mNotificationBackend = new NotificationBackend();
            mSortOrder = R.id.sort_order_recent_notification;
            screenTitle = R.string.app_notifications_title;
        } else {
            if (screenTitle == -1) {
                screenTitle = R.string.application_info_label;
            }
            mListType = LIST_TYPE_MAIN;
        }
        final AppFilterRegistry appFilterRegistry = AppFilterRegistry.getInstance();
        mFilter = appFilterRegistry.get(appFilterRegistry.getDefaultFilterType(mListType));
        mIsWorkOnly = args != null ? args.getBoolean(EXTRA_WORK_ONLY) : false;
        mWorkUserId = args != null ? args.getInt(EXTRA_WORK_ID) : NO_USER_SPECIFIED;

        if (savedInstanceState != null) {
            mSortOrder = savedInstanceState.getInt(EXTRA_SORT_ORDER, mSortOrder);
            mShowSystem = savedInstanceState.getBoolean(EXTRA_SHOW_SYSTEM, mShowSystem);
        }

        mInvalidSizeStr = activity.getText(R.string.invalid_size_value);

        mResetAppsHelper = new ResetAppsHelper(activity);

        if (screenTitle > 0) {
            activity.setTitle(screenTitle);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        mRootView = inflater.inflate(R.layout.manage_applications_apps, null);
        mLoadingContainer = mRootView.findViewById(R.id.loading_container);
        mListContainer = mRootView.findViewById(R.id.list_container);
        if (mListContainer != null) {
            // Create adapter and list view here
            mEmptyView = mListContainer.findViewById(android.R.id.empty);
            mApplications = new ApplicationsAdapter(mApplicationsState, this, mFilter,
                    savedInstanceState);
            if (savedInstanceState != null) {
                mApplications.mHasReceivedLoadEntries =
                        savedInstanceState.getBoolean(EXTRA_HAS_ENTRIES, false);
                mApplications.mHasReceivedBridgeCallback =
                        savedInstanceState.getBoolean(EXTRA_HAS_BRIDGE, false);
            }
            int userId = mIsWorkOnly ? mWorkUserId : UserHandle.getUserId(mCurrentUid);
            if (mStorageType == STORAGE_TYPE_MUSIC) {
                Context context = getContext();
                mApplications.setExtraViewController(
                        new MusicViewHolderController(
                                context,
                                new StorageStatsSource(context),
                                mVolumeUuid,
                                UserHandle.of(userId)));
            } else if (mStorageType == STORAGE_TYPE_PHOTOS_VIDEOS) {
                Context context = getContext();
                mApplications.setExtraViewController(
                        new PhotosViewHolderController(
                                context,
                                new StorageStatsSource(context),
                                mVolumeUuid,
                                UserHandle.of(userId)));
            }
            mRecyclerView = mListContainer.findViewById(R.id.apps_list);
            mRecyclerView.setLayoutManager(new LinearLayoutManager(
                    getContext(), RecyclerView.VERTICAL, false /* reverseLayout */));
            mRecyclerView.setAdapter(mApplications);
        }

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

        createHeader();

        mResetAppsHelper.onRestoreInstanceState(savedInstanceState);

        return mRootView;
    }

    @VisibleForTesting
    void createHeader() {
        final Activity activity = getActivity();
        final FrameLayout pinnedHeader = mRootView.findViewById(R.id.pinned_header);
        mSpinnerHeader = activity.getLayoutInflater()
                .inflate(R.layout.apps_filter_spinner, pinnedHeader, false);
        mFilterSpinner = mSpinnerHeader.findViewById(R.id.filter_spinner);
        mFilterAdapter = new FilterSpinnerAdapter(this);
        mFilterSpinner.setAdapter(mFilterAdapter);
        mFilterSpinner.setOnItemSelectedListener(this);
        pinnedHeader.addView(mSpinnerHeader, 0);

        final AppFilterRegistry appFilterRegistry = AppFilterRegistry.getInstance();
        mFilterAdapter.enableFilter(appFilterRegistry.getDefaultFilterType(mListType));
        if (mListType == LIST_TYPE_MAIN) {
            if (UserManager.get(getActivity()).getUserProfiles().size() > 1) {
                mFilterAdapter.enableFilter(FILTER_APPS_PERSONAL);
                mFilterAdapter.enableFilter(FILTER_APPS_WORK);
            }
        }
        if (mListType == LIST_TYPE_NOTIFICATION) {
            mFilterAdapter.enableFilter(FILTER_APPS_RECENT);
            mFilterAdapter.enableFilter(FILTER_APPS_FREQUENT);
            mFilterAdapter.disableFilter(FILTER_APPS_ALL);
        }
        if (mListType == LIST_TYPE_HIGH_POWER) {
            mFilterAdapter.enableFilter(FILTER_APPS_POWER_WHITELIST_ALL);
        }

        AppFilter compositeFilter = getCompositeFilter(mListType, mStorageType, mVolumeUuid);
        if (mIsWorkOnly) {
            final AppFilter workFilter = appFilterRegistry.get(FILTER_APPS_WORK).getFilter();
            compositeFilter = new CompoundFilter(compositeFilter, workFilter);
        }
        if (compositeFilter != null) {
            mApplications.setCompositeFilter(compositeFilter);
        }
    }

    @VisibleForTesting
    @Nullable
    static AppFilter getCompositeFilter(int listType, int storageType, String volumeUuid) {
        AppFilter filter = new VolumeFilter(volumeUuid);
        if (listType == LIST_TYPE_STORAGE) {
            if (storageType == STORAGE_TYPE_MUSIC) {
                filter = new CompoundFilter(ApplicationsState.FILTER_AUDIO, filter);
            } else if (storageType == STORAGE_TYPE_DEFAULT) {
                filter = new CompoundFilter(ApplicationsState.FILTER_OTHER_APPS, filter);
            }
            return filter;
        }
        if (listType == LIST_TYPE_GAMES) {
            return new CompoundFilter(ApplicationsState.FILTER_GAMES, filter);
        } else if (listType == LIST_TYPE_MOVIES) {
            return new CompoundFilter(ApplicationsState.FILTER_MOVIES, filter);
        } else if (listType == LIST_TYPE_PHOTOGRAPHY) {
            return new CompoundFilter(ApplicationsState.FILTER_PHOTOS, filter);
        }

        return null;
    }

    @Override
    public int getMetricsCategory() {
        switch (mListType) {
            case LIST_TYPE_MAIN:
                return MetricsEvent.MANAGE_APPLICATIONS;
            case LIST_TYPE_NOTIFICATION:
                return MetricsEvent.MANAGE_APPLICATIONS_NOTIFICATIONS;
            case LIST_TYPE_STORAGE:
                if (mStorageType == STORAGE_TYPE_MUSIC) {
                    return MetricsEvent.APPLICATIONS_STORAGE_MUSIC;
                }
                return MetricsEvent.APPLICATIONS_STORAGE_APPS;
            case LIST_TYPE_GAMES:
                return MetricsEvent.APPLICATIONS_STORAGE_GAMES;
            case LIST_TYPE_MOVIES:
                return MetricsEvent.APPLICATIONS_STORAGE_MOVIES;
            case LIST_TYPE_PHOTOGRAPHY:
                return MetricsEvent.APPLICATIONS_STORAGE_PHOTOS;
            case LIST_TYPE_USAGE_ACCESS:
                return MetricsEvent.USAGE_ACCESS;
            case LIST_TYPE_HIGH_POWER:
                return MetricsEvent.APPLICATIONS_HIGH_POWER_APPS;
            case LIST_TYPE_OVERLAY:
                return MetricsEvent.SYSTEM_ALERT_WINDOW_APPS;
            case LIST_TYPE_WRITE_SETTINGS:
                return MetricsEvent.SYSTEM_ALERT_WINDOW_APPS;
            case LIST_TYPE_MANAGE_SOURCES:
                return MetricsEvent.MANAGE_EXTERNAL_SOURCES;
            case LIST_TYPE_DIRECTORY_ACCESS:
                return MetricsEvent.DIRECTORY_ACCESS;
            case LIST_TYPE_WIFI_ACCESS:
                return MetricsEvent.CONFIGURE_WIFI;
            default:
                return MetricsEvent.VIEW_UNKNOWN;
        }
    }

    @Override
    public void onStart() {
        super.onStart();
        updateView();
        if (mApplications != null) {
            mApplications.resume(mSortOrder);
            mApplications.updateLoading();
        }
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        mResetAppsHelper.onSaveInstanceState(outState);
        outState.putInt(EXTRA_SORT_ORDER, mSortOrder);
        outState.putBoolean(EXTRA_SHOW_SYSTEM, mShowSystem);
        outState.putBoolean(EXTRA_HAS_ENTRIES, mApplications.mHasReceivedLoadEntries);
        outState.putBoolean(EXTRA_HAS_BRIDGE, mApplications.mHasReceivedBridgeCallback);
        if (mApplications != null) {
            mApplications.onSaveInstanceState(outState);
        }
    }

    @Override
    public void onStop() {
        super.onStop();
        if (mApplications != null) {
            mApplications.pause();
        }
        mResetAppsHelper.stop();
    }

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

        if (mApplications != null) {
            mApplications.release();
        }
        mRootView = null;
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == INSTALLED_APP_DETAILS && mCurrentPkgName != null) {
            if (mListType == LIST_TYPE_NOTIFICATION) {
                mApplications.mExtraInfoBridge.forceUpdate(mCurrentPkgName, mCurrentUid);
            } else if (mListType == LIST_TYPE_HIGH_POWER || mListType == LIST_TYPE_OVERLAY
                    || mListType == LIST_TYPE_WRITE_SETTINGS) {
                mApplications.mExtraInfoBridge.forceUpdate(mCurrentPkgName, mCurrentUid);
            } else {
                mApplicationsState.requestSize(mCurrentPkgName, UserHandle.getUserId(mCurrentUid));
            }
        }
    }

    // utility method used to start sub activity
    private void startApplicationDetailsActivity() {
        switch (mListType) {
            case LIST_TYPE_NOTIFICATION:
                startAppInfoFragment(AppNotificationSettings.class, R.string.notifications_title);
                break;
            case LIST_TYPE_USAGE_ACCESS:
                startAppInfoFragment(UsageAccessDetails.class, R.string.usage_access);
                break;
            case LIST_TYPE_STORAGE:
                startAppInfoFragment(AppStorageSettings.class, R.string.storage_settings);
                break;
            case LIST_TYPE_HIGH_POWER:
                HighPowerDetail.show(this, mCurrentUid, mCurrentPkgName, INSTALLED_APP_DETAILS);
                break;
            case LIST_TYPE_OVERLAY:
                startAppInfoFragment(DrawOverlayDetails.class, R.string.overlay_settings);
                break;
            case LIST_TYPE_WRITE_SETTINGS:
                startAppInfoFragment(WriteSettingsDetails.class, R.string.write_system_settings);
                break;
            case LIST_TYPE_MANAGE_SOURCES:
                startAppInfoFragment(ExternalSourcesDetails.class, R.string.install_other_apps);
                break;
            case LIST_TYPE_GAMES:
                startAppInfoFragment(AppStorageSettings.class, R.string.game_storage_settings);
                break;
            case LIST_TYPE_MOVIES:
                startAppInfoFragment(AppStorageSettings.class, R.string.storage_movies_tv);
                break;
            case LIST_TYPE_PHOTOGRAPHY:
                startAppInfoFragment(AppStorageSettings.class, R.string.storage_photos_videos);
                break;
            case LIST_TYPE_DIRECTORY_ACCESS:
                startAppInfoFragment(DirectoryAccessDetails.class, R.string.directory_access);
                break;
            case LIST_TYPE_WIFI_ACCESS:
                startAppInfoFragment(ChangeWifiStateDetails.class,
                        R.string.change_wifi_state_title);
                break;
            // TODO: Figure out if there is a way where we can spin up the profile's settings
            // process ahead of time, to avoid a long load of data when user clicks on a managed
            // app. Maybe when they load the list of apps that contains managed profile apps.
            default:
                startAppInfoFragment(
                        AppInfoDashboardFragment.class, R.string.application_info_label);
                break;
        }
    }

    private void startAppInfoFragment(Class<?> fragment, int titleRes) {
        AppInfoBase.startAppInfoFragment(fragment, titleRes, mCurrentPkgName, mCurrentUid, this,
                INSTALLED_APP_DETAILS, getMetricsCategory());
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        final Activity activity = getActivity();
        if (activity == null) {
            return;
        }
        HelpUtils.prepareHelpMenuItem(activity, menu, getHelpResource(), getClass().getName());
        mOptionsMenu = menu;
        inflater.inflate(R.menu.manage_apps, menu);

        updateOptionsMenu();
    }

    @Override
    public void onPrepareOptionsMenu(Menu menu) {
        updateOptionsMenu();
    }

    @Override
    public void onDestroyOptionsMenu() {
        mOptionsMenu = null;
    }

    @StringRes
    int getHelpResource() {
        if (mListType == LIST_TYPE_MAIN) {
            return R.string.help_uri_apps;
        } else if (mListType == LIST_TYPE_USAGE_ACCESS) {
            return R.string.help_url_usage_access;
        } else {
            return R.string.help_uri_notifications;
        }
    }

    void updateOptionsMenu() {
        if (mOptionsMenu == null) {
            return;
        }
        mOptionsMenu.findItem(R.id.advanced).setVisible(false);

        mOptionsMenu.findItem(R.id.sort_order_alpha).setVisible(mListType == LIST_TYPE_STORAGE
                && mSortOrder != R.id.sort_order_alpha);
        mOptionsMenu.findItem(R.id.sort_order_size).setVisible(mListType == LIST_TYPE_STORAGE
                && mSortOrder != R.id.sort_order_size);

        mOptionsMenu.findItem(R.id.show_system).setVisible(!mShowSystem
                && mListType != LIST_TYPE_HIGH_POWER);
        mOptionsMenu.findItem(R.id.hide_system).setVisible(mShowSystem
                && mListType != LIST_TYPE_HIGH_POWER);

        mOptionsMenu.findItem(R.id.reset_app_preferences).setVisible(mListType == LIST_TYPE_MAIN);

        // Hide notification menu items, because sorting happens when filtering
        mOptionsMenu.findItem(R.id.sort_order_recent_notification).setVisible(false);
        mOptionsMenu.findItem(R.id.sort_order_frequent_notification).setVisible(false);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int menuId = item.getItemId();
        switch (item.getItemId()) {
            case R.id.sort_order_alpha:
            case R.id.sort_order_size:
                if (mApplications != null) {
                    mApplications.rebuild(menuId);
                }
                break;
            case R.id.show_system:
            case R.id.hide_system:
                mShowSystem = !mShowSystem;
                mApplications.rebuild();
                break;
            case R.id.reset_app_preferences:
                mResetAppsHelper.buildResetDialog();
                return true;
            case R.id.advanced:
                if (mListType == LIST_TYPE_NOTIFICATION) {
                    new SubSettingLauncher(getContext())
                            .setDestination(ConfigureNotificationSettings.class.getName())
                            .setTitle(R.string.configure_notification_settings)
                            .setSourceMetricsCategory(getMetricsCategory())
                            .setResultListener(this, ADVANCED_SETTINGS)
                            .launch();
                } else {
                    new SubSettingLauncher(getContext())
                            .setDestination(DefaultAppSettings.class.getName())
                            .setTitle(R.string.configure_apps)
                            .setSourceMetricsCategory(getMetricsCategory())
                            .setResultListener(this, ADVANCED_SETTINGS)
                            .launch();
                }
                return true;
            default:
                // Handle the home button
                return false;
        }
        updateOptionsMenu();
        return true;
    }

    @Override
    public void onClick(View view) {
        if (mApplications == null) {
            return;
        }
        final int position = mRecyclerView.getChildAdapterPosition(view);

        if (position == RecyclerView.NO_POSITION) {
            Log.w(TAG, "Cannot find position for child, skipping onClick handling");
            return;
        }
        if (mApplications.getApplicationCount() > position) {
            ApplicationsState.AppEntry entry = mApplications.getAppEntry(position);
            mCurrentPkgName = entry.info.packageName;
            mCurrentUid = entry.info.uid;
            startApplicationDetailsActivity();
        } else {
            mApplications.mExtraViewController.onClick(this);
        }
    }

    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
        mFilter = mFilterAdapter.getFilter(position);
        mApplications.setFilter(mFilter);

        if (DEBUG) Log.d(TAG, "Selecting filter " + mFilter);
    }

    @Override
    public void onNothingSelected(AdapterView<?> parent) {
    }

    public void updateView() {
        updateOptionsMenu();
        final Activity host = getActivity();
        if (host != null) {
            host.invalidateOptionsMenu();
        }
    }

    public void setHasDisabled(boolean hasDisabledApps) {
        if (mListType != LIST_TYPE_MAIN) {
            return;
        }
        mFilterAdapter.setFilterEnabled(FILTER_APPS_ENABLED, hasDisabledApps);
        mFilterAdapter.setFilterEnabled(FILTER_APPS_DISABLED, hasDisabledApps);
    }

    public void setHasInstant(boolean haveInstantApps) {
        if (LIST_TYPES_WITH_INSTANT.contains(mListType)) {
            mFilterAdapter.setFilterEnabled(FILTER_APPS_INSTANT, haveInstantApps);
        }
    }

    static class FilterSpinnerAdapter extends ArrayAdapter<CharSequence> {

        private final ManageApplications mManageApplications;
        private final Context mContext;

        // Use ArrayAdapter for view logic, but have our own list for managing
        // the options available.
        private final ArrayList<AppFilterItem> mFilterOptions = new ArrayList<>();

        public FilterSpinnerAdapter(ManageApplications manageApplications) {
            super(manageApplications.getContext(), R.layout.filter_spinner_item);
            mContext = manageApplications.getContext();
            mManageApplications = manageApplications;
            setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        }

        public AppFilterItem getFilter(int position) {
            return mFilterOptions.get(position);
        }

        public void setFilterEnabled(@AppFilterRegistry.FilterType int filter, boolean enabled) {
            if (enabled) {
                enableFilter(filter);
            } else {
                disableFilter(filter);
            }
        }

        public void enableFilter(@AppFilterRegistry.FilterType int filterType) {
            final AppFilterItem filter = AppFilterRegistry.getInstance().get(filterType);
            if (mFilterOptions.contains(filter)) {
                return;
            }
            if (DEBUG) {
                Log.d(TAG, "Enabling filter " + filter);
            }
            mFilterOptions.add(filter);
            Collections.sort(mFilterOptions);
            mManageApplications.mSpinnerHeader.setVisibility(
                    mFilterOptions.size() > 1 ? View.VISIBLE : View.GONE);
            notifyDataSetChanged();
            if (mFilterOptions.size() == 1) {
                if (DEBUG) {
                    Log.d(TAG, "Auto selecting filter " + filter);
                }
                mManageApplications.mFilterSpinner.setSelection(0);
                mManageApplications.onItemSelected(null, null, 0, 0);
            }
        }

        public void disableFilter(@AppFilterRegistry.FilterType int filterType) {
            final AppFilterItem filter = AppFilterRegistry.getInstance().get(filterType);
            if (!mFilterOptions.remove(filter)) {
                return;
            }
            if (DEBUG) {
                Log.d(TAG, "Disabling filter " + filter);
            }
            Collections.sort(mFilterOptions);
            mManageApplications.mSpinnerHeader.setVisibility(
                    mFilterOptions.size() > 1 ? View.VISIBLE : View.GONE);
            notifyDataSetChanged();
            if (mManageApplications.mFilter == filter) {
                if (mFilterOptions.size() > 0) {
                    if (DEBUG) {
                        Log.d(TAG, "Auto selecting filter " + mFilterOptions.get(0));
                    }
                    mManageApplications.mFilterSpinner.setSelection(0);
                    mManageApplications.onItemSelected(null, null, 0, 0);
                }
            }
        }

        @Override
        public int getCount() {
            return mFilterOptions.size();
        }

        @Override
        public CharSequence getItem(int position) {
            return mContext.getText(mFilterOptions.get(position).getTitle());
        }
    }

    static class ApplicationsAdapter extends RecyclerView.Adapter<ApplicationViewHolder>
            implements ApplicationsState.Callbacks, AppStateBaseBridge.Callback {

        private static final String STATE_LAST_SCROLL_INDEX = "state_last_scroll_index";
        private static final int VIEW_TYPE_APP = 0;
        private static final int VIEW_TYPE_EXTRA_VIEW = 1;

        private final ApplicationsState mState;
        private final ApplicationsState.Session mSession;
        private final ManageApplications mManageApplications;
        private final Context mContext;
        private final AppStateBaseBridge mExtraInfoBridge;
        private final LoadingViewController mLoadingViewController;

        private AppFilterItem mAppFilter;
        private ArrayList<ApplicationsState.AppEntry> mEntries;
        private boolean mResumed;
        private int mLastSortMode = -1;
        private int mWhichSize = SIZE_TOTAL;
        private AppFilter mCompositeFilter;
        private boolean mHasReceivedLoadEntries;
        private boolean mHasReceivedBridgeCallback;
        private FileViewHolderController mExtraViewController;

        // This is to remember and restore the last scroll position when this
        // fragment is paused. We need this special handling because app entries are added gradually
        // when we rebuild the list after the user made some changes, like uninstalling an app.
        private int mLastIndex = -1;

        @VisibleForTesting
        OnScrollListener mOnScrollListener;
        private RecyclerView mRecyclerView;


        public ApplicationsAdapter(ApplicationsState state, ManageApplications manageApplications,
                AppFilterItem appFilter, Bundle savedInstanceState) {
            setHasStableIds(true);
            mState = state;
            mSession = state.newSession(this);
            mManageApplications = manageApplications;
            mLoadingViewController = new LoadingViewController(
                    mManageApplications.mLoadingContainer,
                    mManageApplications.mListContainer
            );
            mContext = manageApplications.getActivity();
            mAppFilter = appFilter;
            if (mManageApplications.mListType == LIST_TYPE_NOTIFICATION) {
                mExtraInfoBridge = new AppStateNotificationBridge(mContext, mState, this,
                        manageApplications.mUsageStatsManager,
                        manageApplications.mUserManager,
                        manageApplications.mNotificationBackend);
            } else if (mManageApplications.mListType == LIST_TYPE_USAGE_ACCESS) {
                mExtraInfoBridge = new AppStateUsageBridge(mContext, mState, this);
            } else if (mManageApplications.mListType == LIST_TYPE_HIGH_POWER) {
                mExtraInfoBridge = new AppStatePowerBridge(mContext, mState, this);
            } else if (mManageApplications.mListType == LIST_TYPE_OVERLAY) {
                mExtraInfoBridge = new AppStateOverlayBridge(mContext, mState, this);
            } else if (mManageApplications.mListType == LIST_TYPE_WRITE_SETTINGS) {
                mExtraInfoBridge = new AppStateWriteSettingsBridge(mContext, mState, this);
            } else if (mManageApplications.mListType == LIST_TYPE_MANAGE_SOURCES) {
                mExtraInfoBridge = new AppStateInstallAppsBridge(mContext, mState, this);
            } else if (mManageApplications.mListType == LIST_TYPE_DIRECTORY_ACCESS) {
                mExtraInfoBridge = new AppStateDirectoryAccessBridge(mState, this);
            } else if (mManageApplications.mListType == LIST_TYPE_WIFI_ACCESS) {
                mExtraInfoBridge = new AppStateChangeWifiStateBridge(mContext, mState, this);
            } else {
                mExtraInfoBridge = null;
            }
            if (savedInstanceState != null) {
                mLastIndex = savedInstanceState.getInt(STATE_LAST_SCROLL_INDEX);
            }
        }

        @Override
        public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
            super.onAttachedToRecyclerView(recyclerView);
            mRecyclerView = recyclerView;
            mOnScrollListener = new OnScrollListener(this);
            mRecyclerView.addOnScrollListener(mOnScrollListener);
        }

        @Override
        public void onDetachedFromRecyclerView(@NonNull RecyclerView recyclerView) {
            super.onDetachedFromRecyclerView(recyclerView);
            mRecyclerView.removeOnScrollListener(mOnScrollListener);
            mOnScrollListener = null;
            mRecyclerView = null;
        }

        public void setCompositeFilter(AppFilter compositeFilter) {
            mCompositeFilter = compositeFilter;
            rebuild();
        }

        public void setFilter(AppFilterItem appFilter) {
            mAppFilter = appFilter;

            // Notification filters require resorting the list
            if (FILTER_APPS_FREQUENT == appFilter.getFilterType()) {
                rebuild(R.id.sort_order_frequent_notification);
            } else if (FILTER_APPS_RECENT == appFilter.getFilterType()) {
                rebuild(R.id.sort_order_recent_notification);
            } else {
                rebuild();
            }
        }

        public void setExtraViewController(FileViewHolderController extraViewController) {
            mExtraViewController = extraViewController;
            // Start to query extra view's stats on background, and once done post result to main
            // thread.
            ThreadUtils.postOnBackgroundThread(() -> {
                mExtraViewController.queryStats();
                ThreadUtils.postOnMainThread(() -> {
                    onExtraViewCompleted();
                });
            });
        }

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

        public void pause() {
            if (mResumed) {
                mResumed = false;
                mSession.onPause();
                if (mExtraInfoBridge != null) {
                    mExtraInfoBridge.pause();
                }
            }
        }

        public void onSaveInstanceState(Bundle outState) {
            // Record the current scroll position before pausing.
            final LinearLayoutManager layoutManager =
                    (LinearLayoutManager) mManageApplications.mRecyclerView.getLayoutManager();
            outState.putInt(STATE_LAST_SCROLL_INDEX, layoutManager.findFirstVisibleItemPosition());
        }

        public void release() {
            mSession.onDestroy();
            if (mExtraInfoBridge != null) {
                mExtraInfoBridge.release();
            }
        }

        public void rebuild(int sort) {
            if (sort == mLastSortMode) {
                return;
            }
            mManageApplications.mSortOrder = sort;
            mLastSortMode = sort;
            rebuild();
        }

        @Override
        public ApplicationViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View view;
            if (mManageApplications.mListType == LIST_TYPE_NOTIFICATION) {
                view = ApplicationViewHolder.newView(parent, true /* twoTarget */);
            } else {
                view = ApplicationViewHolder.newView(parent, false /* twoTarget */);
            }
            return new ApplicationViewHolder(view,
                    shouldUseStableItemHeight(mManageApplications.mListType));
        }

        @Override
        public int getItemViewType(int position) {
            boolean isLastItem = (getItemCount() - 1) == position;
            return hasExtraView() && isLastItem
                    ? VIEW_TYPE_EXTRA_VIEW
                    : VIEW_TYPE_APP;
        }

        public void rebuild() {
            if (!mHasReceivedLoadEntries
                    || (mExtraInfoBridge != null && !mHasReceivedBridgeCallback)) {
                // Don't rebuild the list until all the app entries are loaded.
                return;
            }
            ApplicationsState.AppFilter filterObj;
            Comparator<AppEntry> comparatorObj;
            boolean emulated = Environment.isExternalStorageEmulated();
            if (emulated) {
                mWhichSize = SIZE_TOTAL;
            } else {
                mWhichSize = SIZE_INTERNAL;
            }
            filterObj = mAppFilter.getFilter();
            if (mCompositeFilter != null) {
                filterObj = new CompoundFilter(filterObj, mCompositeFilter);
            }
            if (!mManageApplications.mShowSystem) {
                if (LIST_TYPES_WITH_INSTANT.contains(mManageApplications.mListType)) {
                    filterObj = new CompoundFilter(filterObj,
                            ApplicationsState.FILTER_DOWNLOADED_AND_LAUNCHER_AND_INSTANT);
                } else {
                    filterObj = new CompoundFilter(filterObj,
                            ApplicationsState.FILTER_DOWNLOADED_AND_LAUNCHER);
                }
            }
            switch (mLastSortMode) {
                case R.id.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;
                case R.id.sort_order_recent_notification:
                    comparatorObj = AppStateNotificationBridge.RECENT_NOTIFICATION_COMPARATOR;
                    break;
                case R.id.sort_order_frequent_notification:
                    comparatorObj = AppStateNotificationBridge.FREQUENCY_NOTIFICATION_COMPARATOR;
                    break;
                default:
                    comparatorObj = ApplicationsState.ALPHA_COMPARATOR;
                    break;
            }

            filterObj = new CompoundFilter(filterObj, ApplicationsState.FILTER_NOT_HIDE);
            AppFilter finalFilterObj = filterObj;
            ThreadUtils.postOnBackgroundThread(() -> {
                final ArrayList<AppEntry> entries = mSession.rebuild(finalFilterObj,
                        comparatorObj, false);
                if (entries != null) {
                    ThreadUtils.postOnMainThread(() -> onRebuildComplete(entries));
                }
            });
        }

        @VisibleForTesting
        static boolean shouldUseStableItemHeight(int listType) {
            switch (listType) {
                case LIST_TYPE_NOTIFICATION:
                    // Most entries in notification type has no summary. Don't use stable height
                    // so height is short for most entries.
                    return false;
                default:
                    // Other types have non-empty summary, so keep the height as we expect summary
                    // to fill in.
                    return true;
            }
        }

        private static boolean packageNameEquals(PackageItemInfo info1, PackageItemInfo info2) {
            if (info1 == null || info2 == null) {
                return false;
            }
            if (info1.packageName == null || info2.packageName == null) {
                return false;
            }
            return info1.packageName.equals(info2.packageName);
        }

        private ArrayList<ApplicationsState.AppEntry> removeDuplicateIgnoringUser(
                ArrayList<ApplicationsState.AppEntry> entries) {
            int size = entries.size();
            // returnList will not have more entries than entries
            ArrayList<ApplicationsState.AppEntry> returnEntries = new ArrayList<>(size);

            // assume appinfo of same package but different users are grouped together
            PackageItemInfo lastInfo = null;
            for (int i = 0; i < size; i++) {
                AppEntry appEntry = entries.get(i);
                PackageItemInfo info = appEntry.info;
                if (!packageNameEquals(lastInfo, appEntry.info)) {
                    returnEntries.add(appEntry);
                }
                lastInfo = info;
            }
            returnEntries.trimToSize();
            return returnEntries;
        }

        @Override
        public void onRebuildComplete(ArrayList<AppEntry> entries) {
            final int filterType = mAppFilter.getFilterType();
            if (filterType == FILTER_APPS_POWER_WHITELIST ||
                    filterType == FILTER_APPS_POWER_WHITELIST_ALL) {
                entries = removeDuplicateIgnoringUser(entries);
            }
            mEntries = entries;
            notifyDataSetChanged();
            if (getItemCount() == 0) {
                mManageApplications.mRecyclerView.setVisibility(View.GONE);
                mManageApplications.mEmptyView.setVisibility(View.VISIBLE);
            } else {
                mManageApplications.mEmptyView.setVisibility(View.GONE);
                mManageApplications.mRecyclerView.setVisibility(View.VISIBLE);
            }
            // Restore the last scroll position if the number of entries added so far is bigger than
            // it.
            if (mLastIndex != -1 && getItemCount() > mLastIndex) {
                mManageApplications.mRecyclerView.getLayoutManager().scrollToPosition(mLastIndex);
                mLastIndex = -1;
            }

            if (mSession.getAllApps().size() != 0
                    && mManageApplications.mListContainer.getVisibility() != View.VISIBLE) {
                mLoadingViewController.showContent(true /* animate */);
            }
            if (mManageApplications.mListType == LIST_TYPE_USAGE_ACCESS) {
                // No enabled or disabled filters for usage access.
                return;
            }

            mManageApplications.setHasDisabled(mState.haveDisabledApps());
            mManageApplications.setHasInstant(mState.haveInstantApps());
        }

        @VisibleForTesting
        void updateLoading() {
            final boolean appLoaded = mHasReceivedLoadEntries && mSession.getAllApps().size() != 0;
            if (appLoaded) {
                mLoadingViewController.showContent(false /* animate */);
            } else {
                mLoadingViewController.showLoadingViewDelayed();
            }
        }

        @Override
        public void onExtraInfoUpdated() {
            mHasReceivedBridgeCallback = true;
            rebuild();
        }

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

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

        @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 onLoadEntriesCompleted() {
            mHasReceivedLoadEntries = true;
            // We may have been skipping rebuilds until this came in, trigger one now.
            rebuild();
        }

        @Override
        public void onPackageSizeChanged(String packageName) {
            if (mEntries == null) {
                return;
            }
            final int size = mEntries.size();
            for (int i = 0; i < size; i++) {
                final AppEntry entry = mEntries.get(i);
                final ApplicationInfo info = entry.info;
                if (info == null && !TextUtils.equals(packageName, info.packageName)) {
                    continue;
                }
                if (TextUtils.equals(mManageApplications.mCurrentPkgName, info.packageName)) {
                    // 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();
                    return;
                } else {
                    mOnScrollListener.postNotifyItemChange(i);
                }
            }
        }

        @Override
        public void onLauncherInfoChanged() {
            if (!mManageApplications.mShowSystem) {
                rebuild();
            }
        }

        @Override
        public void onAllSizesComputed() {
            if (mLastSortMode == R.id.sort_order_size) {
                rebuild();
            }
        }

        public void onExtraViewCompleted() {
            if (!hasExtraView()) {
                return;
            }
            // Update last item - this is assumed to be the extra view.
            notifyItemChanged(getItemCount() - 1);
        }

        @Override
        public int getItemCount() {
            if (mEntries == null) {
                return 0;
            }
            return mEntries.size() + (hasExtraView() ? 1 : 0);
        }

        public int getApplicationCount() {
            return mEntries != null ? mEntries.size() : 0;
        }

        public AppEntry getAppEntry(int position) {
            return mEntries.get(position);
        }

        @Override
        public long getItemId(int position) {
            if (position == mEntries.size()) {
                return -1;
            }
            return mEntries.get(position).id;
        }

        public boolean isEnabled(int position) {
            if (getItemViewType(position) == VIEW_TYPE_EXTRA_VIEW
                    || mManageApplications.mListType != LIST_TYPE_HIGH_POWER) {
                return true;
            }
            ApplicationsState.AppEntry entry = mEntries.get(position);
            return !PowerWhitelistBackend.getInstance(mContext)
                    .isSysWhitelisted(entry.info.packageName);
        }

        @Override
        public void onBindViewHolder(ApplicationViewHolder holder, int position) {
            if (mEntries != null && mExtraViewController != null && position == mEntries.size()) {
                // set up view for extra view controller
                mExtraViewController.setupView(holder);
            } else {
                // Bind the data efficiently with the holder
                ApplicationsState.AppEntry entry = mEntries.get(position);
                synchronized (entry) {
                    holder.setTitle(entry.label);
                    mState.ensureIcon(entry);
                    holder.setIcon(entry.icon);
                    updateSummary(holder, entry);
                    updateSwitch(holder, entry);
                    holder.updateDisableView(entry.info);
                }
                holder.setEnabled(isEnabled(position));
            }
            holder.itemView.setOnClickListener(mManageApplications);
        }

        private void updateSummary(ApplicationViewHolder holder, AppEntry entry) {
            switch (mManageApplications.mListType) {
                case LIST_TYPE_NOTIFICATION:
                    if (entry.extraInfo != null) {
                        holder.setSummary(AppStateNotificationBridge.getSummary(mContext,
                                (NotificationsSentState) entry.extraInfo,
                                (mLastSortMode == R.id.sort_order_recent_notification)));
                    } else {
                        holder.setSummary(null);
                    }
                    break;
                case LIST_TYPE_USAGE_ACCESS:
                    if (entry.extraInfo != null) {
                        holder.setSummary(
                                (new UsageState((PermissionState) entry.extraInfo)).isPermissible()
                                        ? R.string.app_permission_summary_allowed
                                        : R.string.app_permission_summary_not_allowed);
                    } else {
                        holder.setSummary(null);
                    }
                    break;
                case LIST_TYPE_HIGH_POWER:
                    holder.setSummary(HighPowerDetail.getSummary(mContext, entry));
                    break;
                case LIST_TYPE_OVERLAY:
                    holder.setSummary(DrawOverlayDetails.getSummary(mContext, entry));
                    break;
                case LIST_TYPE_WRITE_SETTINGS:
                    holder.setSummary(WriteSettingsDetails.getSummary(mContext, entry));
                    break;
                case LIST_TYPE_MANAGE_SOURCES:
                    holder.setSummary(ExternalSourcesDetails.getPreferenceSummary(mContext, entry));
                    break;
                case LIST_TYPE_DIRECTORY_ACCESS:
                    holder.setSummary(null);
                    break;
                case LIST_TYPE_WIFI_ACCESS:
                    holder.setSummary(ChangeWifiStateDetails.getSummary(mContext, entry));
                    break;
                default:
                    holder.updateSizeText(entry, mManageApplications.mInvalidSizeStr, mWhichSize);
                    break;
            }
        }

        private void updateSwitch(ApplicationViewHolder holder, AppEntry entry) {
            switch (mManageApplications.mListType) {
                case LIST_TYPE_NOTIFICATION:
                    holder.updateSwitch(((AppStateNotificationBridge) mExtraInfoBridge)
                                    .getSwitchOnClickListener(entry),
                            AppStateNotificationBridge.enableSwitch(entry),
                            AppStateNotificationBridge.checkSwitch(entry));
                    if (entry.extraInfo != null) {
                        holder.setSummary(AppStateNotificationBridge.getSummary(mContext,
                                (NotificationsSentState) entry.extraInfo,
                                (mLastSortMode == R.id.sort_order_recent_notification)));
                    } else {
                        holder.setSummary(null);
                    }
                    break;
            }
        }

        private boolean hasExtraView() {
            return mExtraViewController != null
                    && mExtraViewController.shouldShow();
        }

        public static class OnScrollListener extends RecyclerView.OnScrollListener {
            private int mScrollState = SCROLL_STATE_IDLE;
            private boolean mDelayNotifyDataChange;
            private ApplicationsAdapter mAdapter;

            public OnScrollListener(ApplicationsAdapter adapter) {
                mAdapter = adapter;
            }

            @Override
            public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
                mScrollState = newState;
                if (mScrollState == SCROLL_STATE_IDLE && mDelayNotifyDataChange) {
                    mDelayNotifyDataChange = false;
                    mAdapter.notifyDataSetChanged();
                }
            }

            public void postNotifyItemChange(int index) {
                if (mScrollState == SCROLL_STATE_IDLE) {
                    mAdapter.notifyItemChanged(index);
                } else {
                    mDelayNotifyDataChange = true;
                }
            }
        }
    }

    private static class SummaryProvider implements SummaryLoader.SummaryProvider {

        private final Context mContext;
        private final SummaryLoader mLoader;

        private SummaryProvider(Context context, SummaryLoader loader) {
            mContext = context;
            mLoader = loader;
        }

        @Override
        public void setListening(boolean listening) {
            if (listening) {
                new InstalledAppCounter(mContext, InstalledAppCounter.IGNORE_INSTALL_REASON,
                        new PackageManagerWrapper(mContext.getPackageManager())) {
                    @Override
                    protected void onCountComplete(int num) {
                        mLoader.setSummary(SummaryProvider.this,
                                mContext.getString(R.string.apps_summary, num));
                    }
                }.execute();
            }
        }
    }

    public static final SummaryLoader.SummaryProviderFactory SUMMARY_PROVIDER_FACTORY
            = new SummaryLoader.SummaryProviderFactory() {
        @Override
        public SummaryLoader.SummaryProvider createSummaryProvider(Activity activity,
                SummaryLoader summaryLoader) {
            return new SummaryProvider(activity, summaryLoader);
        }
    };
}
