diff --git a/Android.mk b/Android.mk
index b9121ec..df85bbc 100644
--- a/Android.mk
+++ b/Android.mk
@@ -37,8 +37,8 @@
     ims-common
 
 LOCAL_STATIC_JAVA_LIBRARIES := \
-    apptoolkit-arch-core-runtime \
-    apptoolkit-lifecycle-extensions \
+    android-arch-lifecycle-runtime \
+    android-arch-lifecycle-extensions \
     jsr305 \
     settings-logtags \
 
diff --git a/res/layout/suggestion_tile_with_button_v2.xml b/res/layout/suggestion_tile_with_button_v2.xml
index bedc6da..7042341 100644
--- a/res/layout/suggestion_tile_with_button_v2.xml
+++ b/res/layout/suggestion_tile_with_button_v2.xml
@@ -80,6 +80,7 @@
         <Button
             android:id="@android:id/primary"
             style="@style/ActionPrimaryButton"
+            android:layout_gravity="center"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_marginTop="12dp"
diff --git a/src/com/android/settings/applications/InstalledAppDetails.java b/src/com/android/settings/applications/InstalledAppDetails.java
deleted file mode 100755
index f78459f..0000000
--- a/src/com/android/settings/applications/InstalledAppDetails.java
+++ /dev/null
@@ -1,1478 +0,0 @@
-/*
- * Copyright (C) 2007 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 com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
-
-import android.Manifest.permission;
-import android.app.Activity;
-import android.app.ActivityManager;
-import android.app.AlertDialog;
-import android.app.LoaderManager;
-import android.app.LoaderManager.LoaderCallbacks;
-import android.content.ActivityNotFoundException;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.Loader;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.ResolveInfo;
-import android.content.pm.UserInfo;
-import android.content.res.Resources;
-import android.icu.text.ListFormatter;
-import android.net.INetworkStatsService;
-import android.net.INetworkStatsSession;
-import android.net.NetworkTemplate;
-import android.net.TrafficStats;
-import android.net.Uri;
-import android.os.AsyncTask;
-import android.os.BatteryStats;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.support.annotation.VisibleForTesting;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.Preference.OnPreferenceClickListener;
-import android.support.v7.preference.PreferenceCategory;
-import android.support.v7.preference.PreferenceScreen;
-import android.text.BidiFormatter;
-import android.text.TextUtils;
-import android.text.format.DateUtils;
-import android.text.format.Formatter;
-import android.util.Log;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.webkit.IWebViewUpdateService;
-
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.internal.os.BatterySipper;
-import com.android.internal.os.BatteryStatsHelper;
-import com.android.settings.DeviceAdminAdd;
-import com.android.settings.R;
-import com.android.settings.SettingsActivity;
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.settings.Utils;
-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.PictureInPictureDetails;
-import com.android.settings.applications.appinfo.PictureInPictureSettings;
-import com.android.settings.applications.appinfo.WriteSettingsDetails;
-import com.android.settings.applications.defaultapps.DefaultBrowserPreferenceController;
-import com.android.settings.applications.defaultapps.DefaultEmergencyPreferenceController;
-import com.android.settings.applications.defaultapps.DefaultHomePreferenceController;
-import com.android.settings.applications.defaultapps.DefaultPhonePreferenceController;
-import com.android.settings.applications.defaultapps.DefaultSmsPreferenceController;
-import com.android.settings.applications.instantapps.InstantAppButtonsController;
-import com.android.settings.datausage.AppDataUsage;
-import com.android.settings.datausage.DataUsageList;
-import com.android.settings.datausage.DataUsageUtils;
-import com.android.settings.fuelgauge.AdvancedPowerUsageDetail;
-import com.android.settings.fuelgauge.BatteryEntry;
-import com.android.settings.fuelgauge.BatteryStatsHelperLoader;
-import com.android.settings.fuelgauge.BatteryUtils;
-import com.android.settings.notification.AppNotificationSettings;
-import com.android.settings.notification.NotificationBackend;
-import com.android.settings.notification.NotificationBackend.AppRow;
-import com.android.settings.widget.ActionButtonPreference;
-import com.android.settings.widget.EntityHeaderController;
-import com.android.settingslib.AppItem;
-import com.android.settingslib.RestrictedLockUtils;
-import com.android.settingslib.applications.AppUtils;
-import com.android.settingslib.applications.ApplicationsState;
-import com.android.settingslib.applications.ApplicationsState.AppEntry;
-import com.android.settingslib.applications.PermissionsSummaryHelper;
-import com.android.settingslib.applications.PermissionsSummaryHelper.PermissionsResultCallback;
-import com.android.settingslib.applications.StorageStatsSource;
-import com.android.settingslib.applications.StorageStatsSource.AppStorageStats;
-import com.android.settingslib.development.DevelopmentSettingsEnabler;
-import com.android.settingslib.net.ChartData;
-import com.android.settingslib.net.ChartDataLoader;
-import com.android.settingslib.wrapper.PackageManagerWrapper;
-
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-/**
- * Activity to display application information from Settings. This activity presents
- * extended information associated with a package like code, data, total size, permissions
- * used by the application and also the set of default launchable activities.
- * For system applications, an option to clear user data is displayed only if data size is > 0.
- * System applications that do not want clear user data do not have this option.
- * For non-system applications, there is no option to clear data. Instead there is an option to
- * uninstall the application.
- *
- * deprecated in favor of {@link AppInfoDashboardFragment}
- */
-@Deprecated
-public class InstalledAppDetails extends AppInfoBase
-        implements OnPreferenceClickListener, LoaderManager.LoaderCallbacks<AppStorageStats> {
-
-    private static final String LOG_TAG = "InstalledAppDetails";
-
-    // Menu identifiers
-    public static final int UNINSTALL_ALL_USERS_MENU = 1;
-    public static final int UNINSTALL_UPDATES = 2;
-
-    // Result code identifiers
-    public static final int REQUEST_UNINSTALL = 0;
-    private static final int REQUEST_REMOVE_DEVICE_ADMIN = 1;
-
-    private static final int SUB_INFO_FRAGMENT = 1;
-
-    private static final int LOADER_CHART_DATA = 2;
-    private static final int LOADER_STORAGE = 3;
-    @VisibleForTesting
-    static final int LOADER_BATTERY = 4;
-
-    private static final int DLG_FORCE_STOP = DLG_BASE + 1;
-    private static final int DLG_DISABLE = DLG_BASE + 2;
-    private static final int DLG_SPECIAL_DISABLE = DLG_BASE + 3;
-    private static final String EXTRA_HIDE_INFO_BUTTON = "hideInfoButton";
-    private static final String KEY_HEADER = "header_view";
-    private static final String KEY_INSTANT_APP_BUTTONS = "instant_app_buttons";
-    private static final String KEY_ACTION_BUTTONS = "action_buttons";
-    private static final String KEY_NOTIFICATION = "notification_settings";
-    private static final String KEY_STORAGE = "storage_settings";
-    private static final String KEY_PERMISSION = "permission_settings";
-    private static final String KEY_DATA = "data_settings";
-    private static final String KEY_LAUNCH = "preferred_settings";
-    private static final String KEY_BATTERY = "battery";
-    private static final String KEY_MEMORY = "memory";
-    private static final String KEY_VERSION = "app_version";
-    private static final String KEY_INSTANT_APP_SUPPORTED_LINKS =
-            "instant_app_launch_supported_domain_urls";
-
-    private final HashSet<String> mHomePackages = new HashSet<>();
-
-    private boolean mInitialized;
-    private boolean mShowUninstalled;
-    private LayoutPreference mHeader;
-    private boolean mUpdatedSysApp = false;
-    private Preference mNotificationPreference;
-    private Preference mStoragePreference;
-    private Preference mPermissionsPreference;
-    private Preference mLaunchPreference;
-    private Preference mDataPreference;
-    private Preference mMemoryPreference;
-    private Preference mVersionPreference;
-    private AppDomainsPreference mInstantAppDomainsPreference;
-    private boolean mDisableAfterUninstall;
-
-    // Used for updating notification preference.
-    private final NotificationBackend mBackend = new NotificationBackend();
-
-    private ChartData mChartData;
-    private INetworkStatsSession mStatsSession;
-
-    @VisibleForTesting
-    ActionButtonPreference mActionButtons;
-    @VisibleForTesting
-    Preference mBatteryPreference;
-    @VisibleForTesting
-    BatterySipper mSipper;
-    @VisibleForTesting
-    BatteryStatsHelper mBatteryHelper;
-    @VisibleForTesting
-    BatteryUtils mBatteryUtils;
-
-    protected ProcStatsData mStatsManager;
-    protected ProcStatsPackageEntry mStats;
-
-    private InstantAppButtonsController mInstantAppButtonsController;
-
-    private AppStorageStats mLastResult;
-    private String mBatteryPercent;
-
-    @VisibleForTesting
-    final LoaderCallbacks<BatteryStatsHelper> mBatteryCallbacks =
-            new LoaderCallbacks<BatteryStatsHelper>() {
-
-                @Override
-                public Loader<BatteryStatsHelper> onCreateLoader(int id, Bundle args) {
-                    return new BatteryStatsHelperLoader(getContext());
-                }
-
-                @Override
-                public void onLoadFinished(Loader<BatteryStatsHelper> loader,
-                        BatteryStatsHelper batteryHelper) {
-                    mBatteryHelper = batteryHelper;
-                    if (mPackageInfo != null) {
-                        mSipper = findTargetSipper(batteryHelper, mPackageInfo.applicationInfo.uid);
-                        if (getActivity() != null) {
-                            updateBattery();
-                        }
-                    }
-                }
-
-                @Override
-                public void onLoaderReset(Loader<BatteryStatsHelper> loader) {
-                }
-            };
-
-    @VisibleForTesting
-    boolean handleDisableable() {
-        boolean disableable = false;
-        // Try to prevent the user from bricking their phone
-        // by not allowing disabling of apps signed with the
-        // system cert and any launcher app in the system.
-        if (mHomePackages.contains(mAppEntry.info.packageName)
-                || Utils.isSystemPackage(getContext().getResources(), mPm, mPackageInfo)) {
-            // Disable button for core system applications.
-            mActionButtons
-                    .setButton1Text(R.string.disable_text)
-                    .setButton1Positive(false);
-        } else if (mAppEntry.info.enabled && !isDisabledUntilUsed()) {
-            mActionButtons
-                    .setButton1Text(R.string.disable_text)
-                    .setButton1Positive(false);
-            disableable = !mApplicationFeatureProvider.getKeepEnabledPackages()
-                    .contains(mAppEntry.info.packageName);
-        } else {
-            mActionButtons
-                    .setButton1Text(R.string.enable_text)
-                    .setButton1Positive(true);
-            disableable = true;
-        }
-
-        return disableable;
-    }
-
-    private boolean isDisabledUntilUsed() {
-        return mAppEntry.info.enabledSetting
-                == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
-    }
-
-    private void initUninstallButtons() {
-        final boolean isBundled = (mAppEntry.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
-        boolean enabled;
-        if (isBundled) {
-            enabled = handleDisableable();
-        } else {
-            enabled = initUninstallButtonForUserApp();
-        }
-        // If this is a device admin, it can't be uninstalled or disabled.
-        // We do this here so the text of the button is still set correctly.
-        if (isBundled && mDpm.packageHasActiveAdmins(mPackageInfo.packageName)) {
-            enabled = false;
-        }
-
-        // We don't allow uninstalling DO/PO on *any* users, because if it's a system app,
-        // "uninstall" is actually "downgrade to the system version + disable", and "downgrade"
-        // will clear data on all users.
-        if (Utils.isProfileOrDeviceOwner(mUserManager, mDpm, mPackageInfo.packageName)) {
-            enabled = false;
-        }
-
-        // Don't allow uninstalling the device provisioning package.
-        if (Utils.isDeviceProvisioningPackage(getResources(), mAppEntry.info.packageName)) {
-            enabled = false;
-        }
-
-        // If the uninstall intent is already queued, disable the uninstall button
-        if (mDpm.isUninstallInQueue(mPackageName)) {
-            enabled = false;
-        }
-
-        // Home apps need special handling.  Bundled ones we don't risk downgrading
-        // because that can interfere with home-key resolution.  Furthermore, we
-        // can't allow uninstallation of the only home app, and we don't want to
-        // allow uninstallation of an explicitly preferred one -- the user can go
-        // to Home settings and pick a different one, after which we'll permit
-        // uninstallation of the now-not-default one.
-        if (enabled && mHomePackages.contains(mPackageInfo.packageName)) {
-            if (isBundled) {
-                enabled = false;
-            } else {
-                ArrayList<ResolveInfo> homeActivities = new ArrayList<ResolveInfo>();
-                ComponentName currentDefaultHome  = mPm.getHomeActivities(homeActivities);
-                if (currentDefaultHome == null) {
-                    // No preferred default, so permit uninstall only when
-                    // there is more than one candidate
-                    enabled = (mHomePackages.size() > 1);
-                } else {
-                    // There is an explicit default home app -- forbid uninstall of
-                    // that one, but permit it for installed-but-inactive ones.
-                    enabled = !mPackageInfo.packageName.equals(currentDefaultHome.getPackageName());
-                }
-            }
-        }
-
-        if (mAppsControlDisallowedBySystem) {
-            enabled = false;
-        }
-
-        try {
-            IWebViewUpdateService webviewUpdateService =
-                IWebViewUpdateService.Stub.asInterface(ServiceManager.getService("webviewupdate"));
-            if (webviewUpdateService.isFallbackPackage(mAppEntry.info.packageName)) {
-                enabled = false;
-            }
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-
-        mActionButtons.setButton1Enabled(enabled);
-        if (enabled) {
-            // Register listener
-            mActionButtons.setButton1OnClickListener(v -> handleUninstallButtonClick());
-        }
-    }
-
-    @VisibleForTesting
-    boolean initUninstallButtonForUserApp() {
-        boolean enabled = true;
-        if ((mPackageInfo.applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED) == 0
-                && mUserManager.getUsers().size() >= 2) {
-            // When we have multiple users, there is a separate menu
-            // to uninstall for all users.
-            enabled = false;
-        } else if (AppUtils.isInstant(mPackageInfo.applicationInfo)) {
-            enabled = false;
-            mActionButtons.setButton1Visible(false);
-        }
-        mActionButtons.setButton1Text(R.string.uninstall_text).setButton1Positive(false);
-        return enabled;
-    }
-
-    /** Called when the activity is first created. */
-    @Override
-    public void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-        final Activity activity = getActivity();
-
-        if (!ensurePackageInfoAvailable(activity)) {
-            return;
-        }
-
-        setHasOptionsMenu(true);
-        addPreferencesFromResource(R.xml.installed_app_details);
-
-        addDynamicPrefs();
-        if (Utils.isBandwidthControlEnabled()) {
-            INetworkStatsService statsService = INetworkStatsService.Stub.asInterface(
-                    ServiceManager.getService(Context.NETWORK_STATS_SERVICE));
-            try {
-                mStatsSession = statsService.openSession();
-            } catch (RemoteException e) {
-                throw new RuntimeException(e);
-            }
-        } else {
-            removePreference(KEY_DATA);
-        }
-        mBatteryUtils = BatteryUtils.getInstance(getContext());
-    }
-
-    @Override
-    public int getMetricsCategory() {
-        return MetricsEvent.APPLICATIONS_INSTALLED_APP_DETAILS;
-    }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-        if (mFinishing) {
-            return;
-        }
-        AppItem app = new AppItem(mAppEntry.info.uid);
-        app.addUid(mAppEntry.info.uid);
-        if (mStatsSession != null) {
-            LoaderManager loaderManager = getLoaderManager();
-            loaderManager.restartLoader(LOADER_CHART_DATA,
-                    ChartDataLoader.buildArgs(getTemplate(getContext()), app),
-                    mDataCallbacks);
-            loaderManager.restartLoader(LOADER_STORAGE, Bundle.EMPTY, this);
-        }
-        restartBatteryStatsLoader();
-        if (DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(getContext())) {
-            new MemoryUpdater().execute();
-        }
-        updateDynamicPrefs();
-    }
-
-    @VisibleForTesting
-    public void restartBatteryStatsLoader() {
-        getLoaderManager().restartLoader(LOADER_BATTERY, Bundle.EMPTY, mBatteryCallbacks);
-    }
-
-    @Override
-    public void onPause() {
-        getLoaderManager().destroyLoader(LOADER_CHART_DATA);
-        super.onPause();
-    }
-
-    @Override
-    public void onDestroy() {
-        TrafficStats.closeQuietly(mStatsSession);
-        super.onDestroy();
-    }
-
-    public void onActivityCreated(Bundle savedInstanceState) {
-        super.onActivityCreated(savedInstanceState);
-        if (mFinishing) {
-            return;
-        }
-        final Activity activity = getActivity();
-        mHeader = (LayoutPreference) findPreference(KEY_HEADER);
-        mActionButtons = ((ActionButtonPreference) findPreference(KEY_ACTION_BUTTONS))
-                .setButton2Text(R.string.force_stop)
-                .setButton2Positive(false)
-                .setButton2Enabled(false);
-        EntityHeaderController.newInstance(activity, this, mHeader.findViewById(R.id.entity_header))
-                .setRecyclerView(getListView(), getLifecycle())
-                .setPackageName(mPackageName)
-                .setHasAppInfoLink(false)
-                .setButtonActions(EntityHeaderController.ActionType.ACTION_APP_PREFERENCE,
-                        EntityHeaderController.ActionType.ACTION_NONE)
-                .styleActionBar(activity)
-                .bindHeaderButtons();
-
-        mNotificationPreference = findPreference(KEY_NOTIFICATION);
-        mNotificationPreference.setOnPreferenceClickListener(this);
-        mStoragePreference = findPreference(KEY_STORAGE);
-        mStoragePreference.setOnPreferenceClickListener(this);
-        mPermissionsPreference = findPreference(KEY_PERMISSION);
-        mPermissionsPreference.setOnPreferenceClickListener(this);
-        mDataPreference = findPreference(KEY_DATA);
-        if (mDataPreference != null) {
-            mDataPreference.setOnPreferenceClickListener(this);
-        }
-        mBatteryPreference = findPreference(KEY_BATTERY);
-        mBatteryPreference.setEnabled(false);
-        mBatteryPreference.setOnPreferenceClickListener(this);
-        mMemoryPreference = findPreference(KEY_MEMORY);
-        mMemoryPreference.setOnPreferenceClickListener(this);
-        mMemoryPreference.setVisible(
-                DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(getContext()));
-        mVersionPreference = findPreference(KEY_VERSION);
-        mInstantAppDomainsPreference =
-                (AppDomainsPreference) findPreference(KEY_INSTANT_APP_SUPPORTED_LINKS);
-        mLaunchPreference = findPreference(KEY_LAUNCH);
-        if (mAppEntry != null && mAppEntry.info != null) {
-            if ((mAppEntry.info.flags&ApplicationInfo.FLAG_INSTALLED) == 0 ||
-                    !mAppEntry.info.enabled) {
-                mLaunchPreference.setEnabled(false);
-            } else {
-                mLaunchPreference.setOnPreferenceClickListener(this);
-            }
-        } else {
-            mLaunchPreference.setEnabled(false);
-        }
-    }
-
-    @Override
-    public void onPackageSizeChanged(String packageName) {
-        if (!TextUtils.equals(packageName, mPackageName)) {
-            Log.d(LOG_TAG, "Package change irrelevant, skipping");
-          return;
-        }
-        refreshUi();
-    }
-
-    /**
-     * Ensures the {@link PackageInfo} is available to proceed. If it's not available, the fragment
-     * will finish.
-     *
-     * @return true if packageInfo is available.
-     */
-    @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
-    boolean ensurePackageInfoAvailable(Activity activity) {
-        if (mPackageInfo == null) {
-            mFinishing = true;
-            Log.w(LOG_TAG, "Package info not available. Is this package already uninstalled?");
-            activity.finishAndRemoveTask();
-            return false;
-        }
-        return true;
-    }
-
-    @Override
-    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
-        super.onCreateOptionsMenu(menu, inflater);
-        menu.add(0, UNINSTALL_UPDATES, 0, R.string.app_factory_reset)
-                .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
-        menu.add(0, UNINSTALL_ALL_USERS_MENU, 1, R.string.uninstall_all_users_text)
-                .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
-    }
-
-    @Override
-    public void onPrepareOptionsMenu(Menu menu) {
-        if (mFinishing) {
-            return;
-        }
-        menu.findItem(UNINSTALL_ALL_USERS_MENU).setVisible(shouldShowUninstallForAll(mAppEntry));
-        mUpdatedSysApp = (mAppEntry.info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
-        MenuItem uninstallUpdatesItem = menu.findItem(UNINSTALL_UPDATES);
-        uninstallUpdatesItem.setVisible(mUpdatedSysApp && !mAppsControlDisallowedBySystem);
-        if (uninstallUpdatesItem.isVisible()) {
-            RestrictedLockUtils.setMenuItemAsDisabledByAdmin(getActivity(),
-                    uninstallUpdatesItem, mAppsControlDisallowedAdmin);
-        }
-    }
-
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-        switch (item.getItemId()) {
-            case UNINSTALL_ALL_USERS_MENU:
-                uninstallPkg(mAppEntry.info.packageName, true, false);
-                return true;
-            case UNINSTALL_UPDATES:
-                uninstallPkg(mAppEntry.info.packageName, false, false);
-                return true;
-        }
-        return false;
-    }
-
-    @Override
-    public void onActivityResult(int requestCode, int resultCode, Intent data) {
-        super.onActivityResult(requestCode, resultCode, data);
-        switch (requestCode) {
-            case REQUEST_UNINSTALL:
-                // Refresh option menu
-                getActivity().invalidateOptionsMenu();
-
-                if (mDisableAfterUninstall) {
-                    mDisableAfterUninstall = false;
-                    new DisableChanger(this, mAppEntry.info,
-                            PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER)
-                            .execute((Object)null);
-                }
-                // continue with following operations
-            case REQUEST_REMOVE_DEVICE_ADMIN:
-                if (!refreshUi()) {
-                    setIntentAndFinish(true, true);
-                } else {
-                    startListeningToPackageRemove();
-                }
-                break;
-        }
-    }
-
-    @Override
-    public Loader<AppStorageStats> onCreateLoader(int id, Bundle args) {
-        Context context = getContext();
-        return new FetchPackageStorageAsyncLoader(
-                context, new StorageStatsSource(context), mAppEntry.info, UserHandle.of(mUserId));
-    }
-
-    @Override
-    public void onLoadFinished(Loader<AppStorageStats> loader, AppStorageStats result) {
-        mLastResult = result;
-        refreshUi();
-    }
-
-    @Override
-    public void onLoaderReset(Loader<AppStorageStats> loader) {
-    }
-
-    /**
-     * Utility method to hide and show specific preferences based on whether the app being displayed
-     * is an Instant App or an installed app.
-     */
-    @VisibleForTesting
-    void prepareInstantAppPrefs() {
-        final boolean isInstant = AppUtils.isInstant(mPackageInfo.applicationInfo);
-        if (isInstant) {
-            Set<String> handledDomainSet = Utils.getHandledDomains(mPm, mPackageInfo.packageName);
-            String[] handledDomains = handledDomainSet.toArray(new String[handledDomainSet.size()]);
-            mInstantAppDomainsPreference.setTitles(handledDomains);
-            // Dummy values, unused in the implementation
-            mInstantAppDomainsPreference.setValues(new int[handledDomains.length]);
-            getPreferenceScreen().removePreference(mLaunchPreference);
-        } else {
-            getPreferenceScreen().removePreference(mInstantAppDomainsPreference);
-        }
-    }
-
-    // Utility method to set application label and icon.
-    private void setAppLabelAndIcon(PackageInfo pkgInfo) {
-        final View appSnippet = mHeader.findViewById(R.id.entity_header);
-        mState.ensureIcon(mAppEntry);
-        final Activity activity = getActivity();
-        final boolean isInstantApp = AppUtils.isInstant(mPackageInfo.applicationInfo);
-        final CharSequence summary =
-                isInstantApp ? null : getString(Utils.getInstallationStatus(mAppEntry.info));
-        EntityHeaderController.newInstance(activity, this, appSnippet)
-                .setLabel(mAppEntry)
-                .setIcon(mAppEntry)
-                .setSummary(summary)
-                .setIsInstantApp(isInstantApp)
-                .done(activity, false /* rebindActions */);
-        mVersionPreference.setSummary(getString(R.string.version_text,
-                BidiFormatter.getInstance().unicodeWrap(pkgInfo.versionName)));
-    }
-
-    @VisibleForTesting
-    boolean shouldShowUninstallForAll(ApplicationsState.AppEntry appEntry) {
-        boolean showIt = true;
-        if (mUpdatedSysApp) {
-            showIt = false;
-        } else if (appEntry == null) {
-            showIt = false;
-        } else if ((appEntry.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
-            showIt = false;
-        } else if (mPackageInfo == null || mDpm.packageHasActiveAdmins(mPackageInfo.packageName)) {
-            showIt = false;
-        } else if (UserHandle.myUserId() != 0) {
-            showIt = false;
-        } else if (mUserManager.getUsers().size() < 2) {
-            showIt = false;
-        } else if (PackageUtil.countPackageInUsers(mPm, mUserManager, mPackageName) < 2
-                && (appEntry.info.flags & ApplicationInfo.FLAG_INSTALLED) != 0) {
-            showIt = false;
-        } else if (AppUtils.isInstant(appEntry.info)) {
-            showIt = false;
-        }
-        return showIt;
-    }
-
-    @VisibleForTesting
-    BatterySipper findTargetSipper(BatteryStatsHelper batteryHelper, int uid) {
-        List<BatterySipper> usageList = batteryHelper.getUsageList();
-        for (int i = 0, size = usageList.size(); i < size; i++) {
-            BatterySipper sipper = usageList.get(i);
-            if (sipper.getUid() == uid) {
-                return sipper;
-            }
-        }
-
-        return null;
-    }
-
-    private boolean signaturesMatch(String pkg1, String pkg2) {
-        if (pkg1 != null && pkg2 != null) {
-            try {
-                final int match = mPm.checkSignatures(pkg1, pkg2);
-                if (match >= PackageManager.SIGNATURE_MATCH) {
-                    return true;
-                }
-            } catch (Exception e) {
-                // e.g. named alternate package not found during lookup;
-                // this is an expected case sometimes
-            }
-        }
-        return false;
-    }
-
-    @Override
-    protected boolean refreshUi() {
-        retrieveAppEntry();
-        if (mAppEntry == null) {
-            return false; // onCreate must have failed, make sure to exit
-        }
-
-        if (mPackageInfo == null) {
-            return false; // onCreate must have failed, make sure to exit
-        }
-
-        // Get list of "home" apps and trace through any meta-data references
-        List<ResolveInfo> homeActivities = new ArrayList<ResolveInfo>();
-        mPm.getHomeActivities(homeActivities);
-        mHomePackages.clear();
-        for (int i = 0; i< homeActivities.size(); i++) {
-            ResolveInfo ri = homeActivities.get(i);
-            final String activityPkg = ri.activityInfo.packageName;
-            mHomePackages.add(activityPkg);
-
-            // Also make sure to include anything proxying for the home app
-            final Bundle metadata = ri.activityInfo.metaData;
-            if (metadata != null) {
-                final String metaPkg = metadata.getString(ActivityManager.META_HOME_ALTERNATE);
-                if (signaturesMatch(metaPkg, activityPkg)) {
-                    mHomePackages.add(metaPkg);
-                }
-            }
-        }
-
-        checkForceStop();
-        setAppLabelAndIcon(mPackageInfo);
-        initUninstallButtons();
-        prepareInstantAppPrefs();
-
-        // Update the preference summaries.
-        Activity context = getActivity();
-        boolean isExternal = ((mAppEntry.info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0);
-        mStoragePreference.setSummary(getStorageSummary(context, mLastResult, isExternal));
-
-        PermissionsSummaryHelper.getPermissionSummary(getContext(),
-                mPackageName, mPermissionCallback);
-        mLaunchPreference.setSummary(AppUtils.getLaunchByDefaultSummary(mAppEntry, mUsbManager,
-                mPm, context));
-        mNotificationPreference.setSummary(getNotificationSummary(mAppEntry, context,
-                mBackend));
-        if (mDataPreference != null) {
-            mDataPreference.setSummary(getDataSummary());
-        }
-
-        if (!mInitialized) {
-            // First time init: are we displaying an uninstalled app?
-            mInitialized = true;
-            mShowUninstalled = (mAppEntry.info.flags&ApplicationInfo.FLAG_INSTALLED) == 0;
-        } else {
-            // All other times: if the app no longer exists then we want
-            // to go away.
-            try {
-                ApplicationInfo ainfo = context.getPackageManager().getApplicationInfo(
-                        mAppEntry.info.packageName,
-                        PackageManager.MATCH_DISABLED_COMPONENTS
-                        | PackageManager.MATCH_ANY_USER);
-                if (!mShowUninstalled) {
-                    // If we did not start out with the app uninstalled, then
-                    // it transitioning to the uninstalled state for the current
-                    // user means we should go away as well.
-                    return (ainfo.flags&ApplicationInfo.FLAG_INSTALLED) != 0;
-                }
-            } catch (NameNotFoundException e) {
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    @VisibleForTesting
-    void updateBattery() {
-        mBatteryPreference.setEnabled(true);
-        if (isBatteryStatsAvailable()) {
-            final int dischargeAmount = mBatteryHelper.getStats().getDischargeAmount(
-                    BatteryStats.STATS_SINCE_CHARGED);
-
-            final List<BatterySipper> usageList = new ArrayList<>(mBatteryHelper.getUsageList());
-            final double hiddenAmount = mBatteryUtils.removeHiddenBatterySippers(usageList);
-            final int percentOfMax = (int) mBatteryUtils.calculateBatteryPercent(
-                    mSipper.totalPowerMah, mBatteryHelper.getTotalPower(), hiddenAmount,
-                    dischargeAmount);
-            mBatteryPercent = Utils.formatPercentage(percentOfMax);
-            mBatteryPreference.setSummary(getString(R.string.battery_summary, mBatteryPercent));
-        } else {
-            mBatteryPreference.setSummary(getString(R.string.no_battery_summary));
-        }
-    }
-
-    private CharSequence getDataSummary() {
-        if (mChartData != null) {
-            long totalBytes = mChartData.detail.getTotalBytes();
-            if (totalBytes == 0) {
-                return getString(R.string.no_data_usage);
-            }
-            Context context = getActivity();
-            return getString(R.string.data_summary_format,
-                    Formatter.formatFileSize(context, totalBytes),
-                    DateUtils.formatDateTime(context, mChartData.detail.getStart(),
-                            DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_ABBREV_MONTH));
-        }
-        return getString(R.string.computing_size);
-    }
-
-    @VisibleForTesting
-    static CharSequence getStorageSummary(
-            Context context, AppStorageStats stats, boolean isExternal) {
-        if (stats == null) {
-            return context.getText(R.string.computing_size);
-        } else {
-            CharSequence storageType = context.getString(isExternal
-                    ? R.string.storage_type_external
-                    : R.string.storage_type_internal);
-            return context.getString(R.string.storage_summary_format,
-                    getSize(context, stats), storageType.toString().toLowerCase());
-        }
-    }
-
-    @VisibleForTesting
-    boolean isBatteryStatsAvailable() {
-        return mBatteryHelper != null && mSipper != null;
-    }
-
-    private static CharSequence getSize(Context context, AppStorageStats stats) {
-        return Formatter.formatFileSize(context, stats.getTotalBytes());
-    }
-
-
-    @Override
-    protected AlertDialog createDialog(int id, int errorCode) {
-        switch (id) {
-            case DLG_DISABLE:
-                return new AlertDialog.Builder(getActivity())
-                        .setMessage(getActivity().getText(R.string.app_disable_dlg_text))
-                        .setPositiveButton(R.string.app_disable_dlg_positive,
-                                new DialogInterface.OnClickListener() {
-                            public void onClick(DialogInterface dialog, int which) {
-                                // Disable the app
-                                mMetricsFeatureProvider.action(getContext(),
-                                        MetricsEvent.ACTION_SETTINGS_DISABLE_APP);
-                                new DisableChanger(InstalledAppDetails.this, mAppEntry.info,
-                                        PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER)
-                                .execute((Object)null);
-                            }
-                        })
-                        .setNegativeButton(R.string.dlg_cancel, null)
-                        .create();
-            case DLG_SPECIAL_DISABLE:
-                return new AlertDialog.Builder(getActivity())
-                        .setMessage(getActivity().getText(R.string.app_disable_dlg_text))
-                        .setPositiveButton(R.string.app_disable_dlg_positive,
-                                new DialogInterface.OnClickListener() {
-                            public void onClick(DialogInterface dialog, int which) {
-                                // Disable the app and ask for uninstall
-                                mMetricsFeatureProvider.action(getContext(),
-                                        MetricsEvent.ACTION_SETTINGS_DISABLE_APP);
-                                uninstallPkg(mAppEntry.info.packageName,
-                                        false, true);
-                            }
-                        })
-                        .setNegativeButton(R.string.dlg_cancel, null)
-                        .create();
-            case DLG_FORCE_STOP:
-                return new AlertDialog.Builder(getActivity())
-                        .setTitle(getActivity().getText(R.string.force_stop_dlg_title))
-                        .setMessage(getActivity().getText(R.string.force_stop_dlg_text))
-                        .setPositiveButton(R.string.dlg_ok, new DialogInterface.OnClickListener() {
-                            public void onClick(DialogInterface dialog, int which) {
-                                // Force stop
-                                forceStopPackage(mAppEntry.info.packageName);
-                            }
-                        })
-                        .setNegativeButton(R.string.dlg_cancel, null)
-                        .create();
-        }
-        if (mInstantAppButtonsController != null) {
-            return mInstantAppButtonsController.createDialog(id);
-        }
-        return null;
-    }
-
-    private void uninstallPkg(String packageName, boolean allUsers, boolean andDisable) {
-        stopListeningToPackageRemove();
-         // Create new intent to launch Uninstaller activity
-        Uri packageURI = Uri.parse("package:"+packageName);
-        Intent uninstallIntent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE, packageURI);
-        uninstallIntent.putExtra(Intent.EXTRA_UNINSTALL_ALL_USERS, allUsers);
-        mMetricsFeatureProvider.action(
-                getContext(), MetricsEvent.ACTION_SETTINGS_UNINSTALL_APP);
-        startActivityForResult(uninstallIntent, REQUEST_UNINSTALL);
-        mDisableAfterUninstall = andDisable;
-    }
-
-    private void forceStopPackage(String pkgName) {
-        mMetricsFeatureProvider.action(getContext(), MetricsEvent.ACTION_APP_FORCE_STOP, pkgName);
-        ActivityManager am = (ActivityManager) getActivity().getSystemService(
-                Context.ACTIVITY_SERVICE);
-        Log.d(LOG_TAG, "Stopping package " + pkgName);
-        am.forceStopPackage(pkgName);
-        int userId = UserHandle.getUserId(mAppEntry.info.uid);
-        mState.invalidatePackage(pkgName, userId);
-        ApplicationsState.AppEntry newEnt = mState.getEntry(pkgName, userId);
-        if (newEnt != null) {
-            mAppEntry = newEnt;
-        }
-        checkForceStop();
-    }
-
-    private void updateForceStopButton(boolean enabled) {
-        mActionButtons
-                .setButton2Enabled(mAppsControlDisallowedBySystem ? false : enabled)
-                .setButton2OnClickListener(mAppsControlDisallowedBySystem
-                        ? null : v -> handleForceStopButtonClick());
-    }
-
-    @VisibleForTesting
-    void checkForceStop() {
-        if (mDpm.packageHasActiveAdmins(mPackageInfo.packageName)) {
-            // User can't force stop device admin.
-            Log.w(LOG_TAG, "User can't force stop device admin");
-            updateForceStopButton(false);
-        } else if (AppUtils.isInstant(mPackageInfo.applicationInfo)) {
-            updateForceStopButton(false);
-            mActionButtons.setButton2Visible(false);
-        } else if ((mAppEntry.info.flags & ApplicationInfo.FLAG_STOPPED) == 0) {
-            // If the app isn't explicitly stopped, then always show the
-            // force stop button.
-            Log.w(LOG_TAG, "App is not explicitly stopped");
-            updateForceStopButton(true);
-        } else {
-            Intent intent = new Intent(Intent.ACTION_QUERY_PACKAGE_RESTART,
-                    Uri.fromParts("package", mAppEntry.info.packageName, null));
-            intent.putExtra(Intent.EXTRA_PACKAGES, new String[] { mAppEntry.info.packageName });
-            intent.putExtra(Intent.EXTRA_UID, mAppEntry.info.uid);
-            intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(mAppEntry.info.uid));
-            Log.d(LOG_TAG, "Sending broadcast to query restart status for "
-                    + mAppEntry.info.packageName);
-            getActivity().sendOrderedBroadcastAsUser(intent, UserHandle.CURRENT, null,
-                    mCheckKillProcessesReceiver, null, Activity.RESULT_CANCELED, null, null);
-        }
-    }
-
-    private void startManagePermissionsActivity() {
-        // start new activity to manage app permissions
-        Intent intent = new Intent(Intent.ACTION_MANAGE_APP_PERMISSIONS);
-        intent.putExtra(Intent.EXTRA_PACKAGE_NAME, mAppEntry.info.packageName);
-        intent.putExtra(EXTRA_HIDE_INFO_BUTTON, true);
-        try {
-            getActivity().startActivityForResult(intent, SUB_INFO_FRAGMENT);
-        } catch (ActivityNotFoundException e) {
-            Log.w(LOG_TAG, "No app can handle android.intent.action.MANAGE_APP_PERMISSIONS");
-        }
-    }
-
-    private void startAppInfoFragment(Class<?> fragment, int title) {
-        startAppInfoFragment(fragment, title, this, mAppEntry);
-    }
-
-    public static void startAppInfoFragment(Class<?> fragment, int title,
-            SettingsPreferenceFragment caller, AppEntry appEntry) {
-        // start new fragment to display extended information
-        Bundle args = new Bundle();
-        args.putString(ARG_PACKAGE_NAME, appEntry.info.packageName);
-        args.putInt(ARG_PACKAGE_UID, appEntry.info.uid);
-
-        SettingsActivity sa = (SettingsActivity) caller.getActivity();
-        sa.startPreferencePanel(caller, fragment.getName(), args, title, null, caller,
-                SUB_INFO_FRAGMENT);
-    }
-
-    private void handleUninstallButtonClick() {
-        if (mAppEntry == null) {
-            setIntentAndFinish(true, true);
-            return;
-        }
-        final String packageName = mAppEntry.info.packageName;
-        if (mDpm.packageHasActiveAdmins(mPackageInfo.packageName)) {
-            stopListeningToPackageRemove();
-            Activity activity = getActivity();
-            Intent uninstallDAIntent = new Intent(activity, DeviceAdminAdd.class);
-            uninstallDAIntent.putExtra(DeviceAdminAdd.EXTRA_DEVICE_ADMIN_PACKAGE_NAME,
-                    mPackageName);
-            mMetricsFeatureProvider.action(
-                    activity, MetricsEvent.ACTION_SETTINGS_UNINSTALL_DEVICE_ADMIN);
-            activity.startActivityForResult(uninstallDAIntent, REQUEST_REMOVE_DEVICE_ADMIN);
-            return;
-        }
-        EnforcedAdmin admin = RestrictedLockUtils.checkIfUninstallBlocked(getActivity(),
-                packageName, mUserId);
-        boolean uninstallBlockedBySystem = mAppsControlDisallowedBySystem ||
-                RestrictedLockUtils.hasBaseUserRestriction(getActivity(), packageName, mUserId);
-        if (admin != null && !uninstallBlockedBySystem) {
-            RestrictedLockUtils.sendShowAdminSupportDetailsIntent(getActivity(), admin);
-        } else if ((mAppEntry.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
-            if (mAppEntry.info.enabled && !isDisabledUntilUsed()) {
-                // If the system app has an update and this is the only user on the device,
-                // then offer to downgrade the app, otherwise only offer to disable the
-                // app for this user.
-                if (mUpdatedSysApp && isSingleUser()) {
-                    showDialogInner(DLG_SPECIAL_DISABLE, 0);
-                } else {
-                    showDialogInner(DLG_DISABLE, 0);
-                }
-            } else {
-                mMetricsFeatureProvider.action(
-                        getActivity(),
-                        MetricsEvent.ACTION_SETTINGS_ENABLE_APP);
-                new DisableChanger(this, mAppEntry.info,
-                        PackageManager.COMPONENT_ENABLED_STATE_ENABLED)
-                        .execute((Object) null);
-            }
-        } else if ((mAppEntry.info.flags & ApplicationInfo.FLAG_INSTALLED) == 0) {
-            uninstallPkg(packageName, true, false);
-        } else {
-            uninstallPkg(packageName, false, false);
-        }
-    }
-
-    private void handleForceStopButtonClick() {
-        if (mAppEntry == null) {
-            setIntentAndFinish(true, true);
-            return;
-        }
-        if (mAppsControlDisallowedAdmin != null && !mAppsControlDisallowedBySystem) {
-            RestrictedLockUtils.sendShowAdminSupportDetailsIntent(
-                    getActivity(), mAppsControlDisallowedAdmin);
-        } else {
-            showDialogInner(DLG_FORCE_STOP, 0);
-            //forceStopPackage(mAppInfo.packageName);
-        }
-    }
-
-    /** Returns whether there is only one user on this device, not including the system-only user */
-    private boolean isSingleUser() {
-        final int userCount = mUserManager.getUserCount();
-        return userCount == 1
-                || (mUserManager.isSplitSystemUser() && userCount == 2);
-    }
-
-    @Override
-    public boolean onPreferenceClick(Preference preference) {
-        if (preference == mStoragePreference) {
-            startAppInfoFragment(AppStorageSettings.class, R.string.storage_settings);
-        } else if (preference == mNotificationPreference) {
-            startAppInfoFragment(AppNotificationSettings.class, R.string.app_notifications_title);
-        } else if (preference == mPermissionsPreference) {
-            startManagePermissionsActivity();
-        } else if (preference == mLaunchPreference) {
-            startAppInfoFragment(AppLaunchSettings.class, R.string.launch_by_default);
-        } else if (preference == mMemoryPreference) {
-            ProcessStatsBase.launchMemoryDetail((SettingsActivity) getActivity(),
-                    mStatsManager.getMemInfo(), mStats, false);
-        } else if (preference == mDataPreference) {
-            startAppInfoFragment(AppDataUsage.class, R.string.app_data_usage);
-        } else if (preference == mBatteryPreference) {
-            if (isBatteryStatsAvailable()) {
-                BatteryEntry entry = new BatteryEntry(getContext(), null, mUserManager, mSipper);
-                entry.defaultPackageName = mPackageName;
-                AdvancedPowerUsageDetail.startBatteryDetailPage((SettingsActivity) getActivity(),
-                        this, mBatteryHelper, BatteryStats.STATS_SINCE_CHARGED, entry,
-                        mBatteryPercent, null /* mAnomalies */);
-            } else {
-                AdvancedPowerUsageDetail.startBatteryDetailPage((SettingsActivity) getActivity(),
-                        this, mPackageName);
-            }
-        } else {
-            return false;
-        }
-        return true;
-    }
-
-    private void addDynamicPrefs() {
-        if (UserManager.get(getContext()).isManagedProfile()) {
-            return;
-        }
-        final PreferenceScreen screen = getPreferenceScreen();
-        final Context context = getContext();
-        if (DefaultHomePreferenceController.hasHomePreference(mPackageName, context)) {
-            screen.addPreference(new ShortcutPreference(getPrefContext(),
-                    DefaultAppSettings.class, "default_home", R.string.home_app,
-                    R.string.configure_apps));
-        }
-        if (DefaultBrowserPreferenceController.hasBrowserPreference(mPackageName, context)) {
-            screen.addPreference(new ShortcutPreference(getPrefContext(),
-                    DefaultAppSettings.class, "default_browser", R.string.default_browser_title,
-                    R.string.configure_apps));
-        }
-        if (DefaultPhonePreferenceController.hasPhonePreference(mPackageName, context)) {
-            screen.addPreference(new ShortcutPreference(getPrefContext(),
-                    DefaultAppSettings.class, "default_phone_app", R.string.default_phone_title,
-                    R.string.configure_apps));
-        }
-        if (DefaultEmergencyPreferenceController.hasEmergencyPreference(mPackageName, context)) {
-            screen.addPreference(new ShortcutPreference(getPrefContext(),
-                    DefaultAppSettings.class, "default_emergency_app",
-                    R.string.default_emergency_app, R.string.configure_apps));
-        }
-        if (DefaultSmsPreferenceController.hasSmsPreference(mPackageName, context)) {
-            screen.addPreference(new ShortcutPreference(getPrefContext(),
-                    DefaultAppSettings.class, "default_sms_app", R.string.sms_application_title,
-                    R.string.configure_apps));
-        }
-
-        // Get the package info with the activities
-        PackageInfo packageInfoWithActivities = null;
-        try {
-            packageInfoWithActivities = mPm.getPackageInfoAsUser(mPackageName,
-                    PackageManager.GET_ACTIVITIES, UserHandle.myUserId());
-        } catch (NameNotFoundException e) {
-            Log.e(TAG, "Exception while retrieving the package info of " + mPackageName, e);
-        }
-
-        boolean hasDrawOverOtherApps = hasPermission(permission.SYSTEM_ALERT_WINDOW);
-        boolean hasWriteSettings = hasPermission(permission.WRITE_SETTINGS);
-        boolean hasPictureInPictureActivities = (packageInfoWithActivities != null) &&
-                PictureInPictureSettings.checkPackageHasPictureInPictureActivities(
-                        packageInfoWithActivities.packageName,
-                        packageInfoWithActivities.activities);
-        boolean isPotentialAppSource = isPotentialAppSource();
-        if (hasDrawOverOtherApps || hasWriteSettings || hasPictureInPictureActivities ||
-                isPotentialAppSource) {
-            PreferenceCategory category = new PreferenceCategory(getPrefContext());
-            category.setTitle(R.string.advanced_apps);
-            screen.addPreference(category);
-
-            if (hasDrawOverOtherApps) {
-                Preference pref = new Preference(getPrefContext());
-                pref.setTitle(R.string.draw_overlay);
-                pref.setKey("system_alert_window");
-                pref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
-                    @Override
-                    public boolean onPreferenceClick(Preference preference) {
-                        startAppInfoFragment(DrawOverlayDetails.class, R.string.draw_overlay);
-                        return true;
-                    }
-                });
-                category.addPreference(pref);
-            }
-            if (hasWriteSettings) {
-                Preference pref = new Preference(getPrefContext());
-                pref.setTitle(R.string.write_settings);
-                pref.setKey("write_settings_apps");
-                pref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
-                    @Override
-                    public boolean onPreferenceClick(Preference preference) {
-                        startAppInfoFragment(WriteSettingsDetails.class, R.string.write_settings);
-                        return true;
-                    }
-                });
-                category.addPreference(pref);
-            }
-            if (hasPictureInPictureActivities) {
-                Preference pref = new Preference(getPrefContext());
-                pref.setTitle(R.string.picture_in_picture_app_detail_title);
-                pref.setKey("picture_in_picture");
-                pref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
-                    @Override
-                    public boolean onPreferenceClick(Preference preference) {
-                        AppInfoBase.startAppInfoFragment(PictureInPictureDetails.class,
-                                R.string.picture_in_picture_app_detail_title, mPackageName,
-                                mPackageInfo.applicationInfo.uid, InstalledAppDetails.this,
-                                -1, getMetricsCategory());
-                        return true;
-                    }
-                });
-                category.addPreference(pref);
-            }
-            if (isPotentialAppSource) {
-                Preference pref = new Preference(getPrefContext());
-                pref.setTitle(R.string.install_other_apps);
-                pref.setKey("install_other_apps");
-                pref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
-                    @Override
-                    public boolean onPreferenceClick(Preference preference) {
-                        startAppInfoFragment(ExternalSourcesDetails.class,
-                                R.string.install_other_apps);
-                        return true;
-                    }
-                });
-                category.addPreference(pref);
-            }
-        }
-
-        addAppInstallerInfoPref(screen);
-        maybeAddInstantAppButtons();
-    }
-
-    private boolean isPotentialAppSource() {
-        AppStateInstallAppsBridge.InstallAppsState appState =
-                new AppStateInstallAppsBridge(getContext(), null, null)
-                        .createInstallAppsStateFor(mPackageName, mPackageInfo.applicationInfo.uid);
-        return appState.isPotentialAppSource();
-    }
-
-    private void addAppInstallerInfoPref(PreferenceScreen screen) {
-        String installerPackageName =
-                AppStoreUtil.getInstallerPackageName(getContext(), mPackageName);
-
-        final CharSequence installerLabel = Utils.getApplicationLabel(getContext(),
-                installerPackageName);
-        if (installerLabel == null) {
-            return;
-        }
-        final int detailsStringId = AppUtils.isInstant(mPackageInfo.applicationInfo)
-                ? R.string.instant_app_details_summary
-                : R.string.app_install_details_summary;
-        PreferenceCategory category = new PreferenceCategory(getPrefContext());
-        category.setTitle(R.string.app_install_details_group_title);
-        screen.addPreference(category);
-        Preference pref = new Preference(getPrefContext());
-        pref.setTitle(R.string.app_install_details_title);
-        pref.setKey("app_info_store");
-        pref.setSummary(getString(detailsStringId, installerLabel));
-
-        Intent intent =
-                AppStoreUtil.getAppStoreLink(getContext(), installerPackageName, mPackageName);
-        if (intent != null) {
-            pref.setIntent(intent);
-        } else {
-            pref.setEnabled(false);
-        }
-        category.addPreference(pref);
-    }
-
-    @VisibleForTesting
-    void maybeAddInstantAppButtons() {
-        if (AppUtils.isInstant(mPackageInfo.applicationInfo)) {
-            LayoutPreference buttons = (LayoutPreference) findPreference(KEY_INSTANT_APP_BUTTONS);
-            mInstantAppButtonsController = mApplicationFeatureProvider
-                    .newInstantAppButtonsController(this,
-                            buttons.findViewById(R.id.instant_app_button_container),
-                            id -> showDialogInner(id, 0))
-                    .setPackageName(mPackageName)
-                    .show();
-        }
-    }
-
-    private boolean hasPermission(String permission) {
-        if (mPackageInfo == null || mPackageInfo.requestedPermissions == null) {
-            return false;
-        }
-        for (int i = 0; i < mPackageInfo.requestedPermissions.length; i++) {
-            if (mPackageInfo.requestedPermissions[i].equals(permission)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private void updateDynamicPrefs() {
-        final Context context = getContext();
-        Preference pref = findPreference("default_home");
-
-        if (pref != null) {
-            pref.setSummary(DefaultHomePreferenceController.isHomeDefault(mPackageName,
-                    new PackageManagerWrapper(context.getPackageManager()))
-                    ? R.string.yes : R.string.no);
-        }
-        pref = findPreference("default_browser");
-        if (pref != null) {
-            pref.setSummary(new DefaultBrowserPreferenceController(context)
-                    .isBrowserDefault(mPackageName, mUserId)
-                    ? R.string.yes : R.string.no);
-        }
-        pref = findPreference("default_phone_app");
-        if (pref != null) {
-            pref.setSummary(
-                    DefaultPhonePreferenceController.isPhoneDefault(mPackageName, context)
-                    ? R.string.yes : R.string.no);
-        }
-        pref = findPreference("default_emergency_app");
-        if (pref != null) {
-            pref.setSummary(DefaultEmergencyPreferenceController.isEmergencyDefault(mPackageName,
-                    getContext()) ? R.string.yes : R.string.no);
-        }
-        pref = findPreference("default_sms_app");
-        if (pref != null) {
-            pref.setSummary(DefaultSmsPreferenceController.isSmsDefault(mPackageName, context)
-                    ? R.string.yes : R.string.no);
-        }
-        pref = findPreference("system_alert_window");
-        if (pref != null) {
-            pref.setSummary(DrawOverlayDetails.getSummary(getContext(), mAppEntry));
-        }
-        pref = findPreference("picture_in_picture");
-        if (pref != null) {
-            pref.setSummary(PictureInPictureDetails.getPreferenceSummary(getContext(),
-                    mPackageInfo.applicationInfo.uid, mPackageName));
-        }
-        pref = findPreference("write_settings_apps");
-        if (pref != null) {
-            pref.setSummary(WriteSettingsDetails.getSummary(getContext(), mAppEntry));
-        }
-        pref = findPreference("install_other_apps");
-        if (pref != null) {
-            pref.setSummary(ExternalSourcesDetails.getPreferenceSummary(getContext(), mAppEntry));
-        }
-    }
-
-    public static NetworkTemplate getTemplate(Context context) {
-        if (DataUsageList.hasReadyMobileRadio(context)) {
-            return NetworkTemplate.buildTemplateMobileWildcard();
-        }
-        if (DataUsageUtils.hasWifiRadio(context)) {
-            return NetworkTemplate.buildTemplateWifiWildcard();
-        }
-        return NetworkTemplate.buildTemplateEthernet();
-    }
-
-    public static CharSequence getNotificationSummary(AppEntry appEntry, Context context,
-            NotificationBackend backend) {
-        AppRow appRow = backend.loadAppRow(context, context.getPackageManager(), appEntry.info);
-        return getNotificationSummary(appRow, context);
-    }
-
-    public static CharSequence getNotificationSummary(AppRow appRow, Context context) {
-        // TODO: implement summary when it is known what it should say
-        return "";
-    }
-
-    @Override
-    protected void onPackageRemoved() {
-        getActivity().finishActivity(SUB_INFO_FRAGMENT);
-        super.onPackageRemoved();
-    }
-
-    private class MemoryUpdater extends AsyncTask<Void, Void, ProcStatsPackageEntry> {
-
-        @Override
-        protected ProcStatsPackageEntry doInBackground(Void... params) {
-            if (getActivity() == null) {
-                return null;
-            }
-            if (mPackageInfo == null) {
-                return null;
-            }
-            if (mStatsManager == null) {
-                mStatsManager = new ProcStatsData(getActivity(), false);
-                mStatsManager.setDuration(ProcessStatsBase.sDurations[0]);
-            }
-            mStatsManager.refreshStats(true);
-            for (ProcStatsPackageEntry pkgEntry : mStatsManager.getEntries()) {
-                for (ProcStatsEntry entry : pkgEntry.mEntries) {
-                    if (entry.mUid == mPackageInfo.applicationInfo.uid) {
-                        pkgEntry.updateMetrics();
-                        return pkgEntry;
-                    }
-                }
-            }
-            return null;
-        }
-
-        @Override
-        protected void onPostExecute(ProcStatsPackageEntry entry) {
-            if (getActivity() == null) {
-                return;
-            }
-            if (entry != null) {
-                mStats = entry;
-                mMemoryPreference.setEnabled(true);
-                double amount = Math.max(entry.mRunWeight, entry.mBgWeight)
-                        * mStatsManager.getMemInfo().weightToRam;
-                mMemoryPreference.setSummary(getString(R.string.memory_use_summary,
-                        Formatter.formatShortFileSize(getContext(), (long) amount)));
-            } else {
-                mMemoryPreference.setEnabled(false);
-                mMemoryPreference.setSummary(getString(R.string.no_memory_use_summary));
-            }
-        }
-
-    }
-
-    /**
-     * Elicit this class for testing. Test cannot be done in robolectric because it
-     * invokes the new API.
-     */
-    @VisibleForTesting
-    public static class PackageUtil {
-        /**
-         * Count how many users in device have installed package {@paramref packageName}
-         */
-        public static int countPackageInUsers(PackageManager packageManager, UserManager
-                userManager, String packageName) {
-            final List<UserInfo> userInfos = userManager.getUsers(true);
-            int count = 0;
-
-            for (final UserInfo userInfo : userInfos) {
-                try {
-                    // Use this API to check whether user has this package
-                    final ApplicationInfo info = packageManager.getApplicationInfoAsUser(
-                            packageName, PackageManager.GET_META_DATA, userInfo.id);
-                    if ((info.flags & ApplicationInfo.FLAG_INSTALLED) != 0) {
-                        count++;
-                    }
-                } catch(NameNotFoundException e) {
-                    Log.e(TAG, "Package: " + packageName + " not found for user: " + userInfo.id);
-                }
-            }
-
-            return count;
-        }
-    }
-
-    private static class DisableChanger extends AsyncTask<Object, Object, Object> {
-        final PackageManager mPm;
-        final WeakReference<InstalledAppDetails> mActivity;
-        final ApplicationInfo mInfo;
-        final int mState;
-
-        DisableChanger(InstalledAppDetails activity, ApplicationInfo info, int state) {
-            mPm = activity.mPm;
-            mActivity = new WeakReference<InstalledAppDetails>(activity);
-            mInfo = info;
-            mState = state;
-        }
-
-        @Override
-        protected Object doInBackground(Object... params) {
-            mPm.setApplicationEnabledSetting(mInfo.packageName, mState, 0);
-            return null;
-        }
-    }
-
-    private final LoaderCallbacks<ChartData> mDataCallbacks = new LoaderCallbacks<ChartData>() {
-
-        @Override
-        public Loader<ChartData> onCreateLoader(int id, Bundle args) {
-            return new ChartDataLoader(getActivity(), mStatsSession, args);
-        }
-
-        @Override
-        public void onLoadFinished(Loader<ChartData> loader, ChartData data) {
-            mChartData = data;
-            mDataPreference.setSummary(getDataSummary());
-        }
-
-        @Override
-        public void onLoaderReset(Loader<ChartData> loader) {
-            // Leave last result.
-        }
-    };
-
-    private final BroadcastReceiver mCheckKillProcessesReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            final boolean enabled = getResultCode() != Activity.RESULT_CANCELED;
-            Log.d(LOG_TAG, "Got broadcast response: Restart status for "
-                    + mAppEntry.info.packageName + " " + enabled);
-            updateForceStopButton(enabled);
-        }
-    };
-
-    private final PermissionsResultCallback mPermissionCallback
-            = new PermissionsResultCallback() {
-        @Override
-        public void onPermissionSummaryResult(int standardGrantedPermissionCount,
-                int requestedPermissionCount, int additionalGrantedPermissionCount,
-                List<CharSequence> grantedGroupLabels) {
-            if (getActivity() == null) {
-                return;
-            }
-            final Resources res = getResources();
-            CharSequence summary = null;
-
-            if (requestedPermissionCount == 0) {
-                summary = res.getString(
-                        R.string.runtime_permissions_summary_no_permissions_requested);
-                mPermissionsPreference.setOnPreferenceClickListener(null);
-                mPermissionsPreference.setEnabled(false);
-            } else {
-                final ArrayList<CharSequence> list = new ArrayList<>(grantedGroupLabels);
-                if (additionalGrantedPermissionCount > 0) {
-                    // N additional permissions.
-                    list.add(res.getQuantityString(
-                            R.plurals.runtime_permissions_additional_count,
-                            additionalGrantedPermissionCount, additionalGrantedPermissionCount));
-                }
-                if (list.size() == 0) {
-                    summary = res.getString(
-                            R.string.runtime_permissions_summary_no_permissions_granted);
-                } else {
-                    summary = ListFormatter.getInstance().format(list);
-                }
-                mPermissionsPreference.setOnPreferenceClickListener(InstalledAppDetails.this);
-                mPermissionsPreference.setEnabled(true);
-            }
-            mPermissionsPreference.setSummary(summary);
-        }
-    };
-}
diff --git a/src/com/android/settings/applications/InstalledAppDetailsTop.java b/src/com/android/settings/applications/InstalledAppDetailsTop.java
index 8090de0..2d9756a 100644
--- a/src/com/android/settings/applications/InstalledAppDetailsTop.java
+++ b/src/com/android/settings/applications/InstalledAppDetailsTop.java
@@ -17,30 +17,21 @@
 package com.android.settings.applications;
 
 import android.content.Intent;
-import android.util.FeatureFlagUtils;
 
 import com.android.settings.SettingsActivity;
 import com.android.settings.applications.appinfo.AppInfoDashboardFragment;
-import com.android.settings.core.FeatureFlags;
 
 public class InstalledAppDetailsTop extends SettingsActivity {
 
     @Override
     public Intent getIntent() {
         Intent modIntent = new Intent(super.getIntent());
-        if (FeatureFlagUtils.isEnabled(this, FeatureFlags.APP_INFO_V2)) {
-            modIntent.putExtra(EXTRA_SHOW_FRAGMENT, AppInfoDashboardFragment.class.getName());
-        } else {
-            modIntent.putExtra(EXTRA_SHOW_FRAGMENT, InstalledAppDetails.class.getName());
-        }
+        modIntent.putExtra(EXTRA_SHOW_FRAGMENT, AppInfoDashboardFragment.class.getName());
         return modIntent;
     }
 
     @Override
     protected boolean isValidFragment(String fragmentName) {
-        if (FeatureFlagUtils.isEnabled(this, FeatureFlags.APP_INFO_V2)) {
-            return AppInfoDashboardFragment.class.getName().equals(fragmentName);
-        }
-        return InstalledAppDetails.class.getName().equals(fragmentName);
+        return AppInfoDashboardFragment.class.getName().equals(fragmentName);
     }
 }
diff --git a/src/com/android/settings/applications/RecentAppsPreferenceController.java b/src/com/android/settings/applications/RecentAppsPreferenceController.java
index 3859081..e15671b 100644
--- a/src/com/android/settings/applications/RecentAppsPreferenceController.java
+++ b/src/com/android/settings/applications/RecentAppsPreferenceController.java
@@ -34,14 +34,12 @@
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.ArraySet;
-import android.util.FeatureFlagUtils;
 import android.util.IconDrawableFactory;
 import android.util.Log;
 
 import com.android.settings.R;
 import com.android.settings.Utils;
 import com.android.settings.applications.appinfo.AppInfoDashboardFragment;
-import com.android.settings.core.FeatureFlags;
 import com.android.settings.core.PreferenceControllerMixin;
 import com.android.settings.widget.AppPreference;
 import com.android.settingslib.applications.AppUtils;
@@ -245,17 +243,10 @@
                     System.currentTimeMillis() - stat.getLastTimeUsed(), false));
             pref.setOrder(i);
             pref.setOnPreferenceClickListener(preference -> {
-                if (FeatureFlagUtils.isEnabled(mContext, FeatureFlags.APP_INFO_V2)) {
-                    AppInfoBase.startAppInfoFragment(AppInfoDashboardFragment.class,
-                            R.string.application_info_label, pkgName, appEntry.info.uid, mHost,
-                            1001 /*RequestCode*/, SETTINGS_APP_NOTIF_CATEGORY);
-                    return true;
-                } else {
-                    AppInfoBase.startAppInfoFragment(InstalledAppDetails.class,
-                            R.string.application_info_label, pkgName, appEntry.info.uid, mHost,
-                            1001 /*RequestCode*/, SETTINGS_APP_NOTIF_CATEGORY);
-                    return true;
-                }
+                AppInfoBase.startAppInfoFragment(AppInfoDashboardFragment.class,
+                    R.string.application_info_label, pkgName, appEntry.info.uid, mHost,
+                    1001 /*RequestCode*/, SETTINGS_APP_NOTIF_CATEGORY);
+                return true;
             });
             if (!rebindPref) {
                 mCategory.addPreference(pref);
diff --git a/src/com/android/settings/applications/manageapplications/ManageApplications.java b/src/com/android/settings/applications/manageapplications/ManageApplications.java
index 09896dc..06ba86e 100644
--- a/src/com/android/settings/applications/manageapplications/ManageApplications.java
+++ b/src/com/android/settings/applications/manageapplications/ManageApplications.java
@@ -50,7 +50,6 @@
 import android.support.v7.widget.RecyclerView;
 import android.text.TextUtils;
 import android.util.ArraySet;
-import android.util.FeatureFlagUtils;
 import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.Menu;
@@ -91,15 +90,14 @@
 import com.android.settings.applications.AppStorageSettings;
 import com.android.settings.applications.DefaultAppSettings;
 import com.android.settings.applications.InstalledAppCounter;
-import com.android.settings.applications.InstalledAppDetails;
 import com.android.settings.applications.NotificationApps;
 import com.android.settings.applications.DirectoryAccessDetails;
 import com.android.settings.applications.UsageAccessDetails;
 import com.android.settings.applications.appinfo.AppInfoDashboardFragment;
+import com.android.settings.applications.appinfo.AppNotificationPreferenceController;
 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.FeatureFlags;
 import com.android.settings.core.InstrumentedPreferenceFragment;
 import com.android.settings.dashboard.SummaryLoader;
 import com.android.settings.fuelgauge.HighPowerDetail;
@@ -151,7 +149,7 @@
     private static final String EXTRA_HAS_ENTRIES = "hasEntries";
     private static final String EXTRA_HAS_BRIDGE = "hasBridge";
 
-    // attributes used as keys when passing values to InstalledAppDetails activity
+    // 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.
@@ -553,13 +551,8 @@
             // 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:
-                if (FeatureFlagUtils.isEnabled(getContext(), FeatureFlags.APP_INFO_V2)) {
-                    startAppInfoFragment(
-                            AppInfoDashboardFragment.class, R.string.application_info_label);
-                } else {
-                    startAppInfoFragment(
-                            InstalledAppDetails.class, R.string.application_info_label);
-                }
+                startAppInfoFragment(
+                    AppInfoDashboardFragment.class, R.string.application_info_label);
                 break;
         }
     }
@@ -1227,7 +1220,8 @@
             switch (mManageApplications.mListType) {
                 case LIST_TYPE_NOTIFICATION:
                     if (entry.extraInfo != null) {
-                        holder.setSummary(InstalledAppDetails.getNotificationSummary(
+                        holder.setSummary(
+                            AppNotificationPreferenceController.getNotificationSummary(
                                 (AppRow) entry.extraInfo, mContext));
                     } else {
                         holder.setSummary(null);
diff --git a/src/com/android/settings/core/FeatureFlags.java b/src/com/android/settings/core/FeatureFlags.java
index 7505876..687442e 100644
--- a/src/com/android/settings/core/FeatureFlags.java
+++ b/src/com/android/settings/core/FeatureFlags.java
@@ -20,7 +20,6 @@
  * This class keeps track of all feature flags in Settings.
  */
 public class FeatureFlags {
-    public static final String APP_INFO_V2 = "settings_app_info_v2";
     public static final String CONNECTED_DEVICE_V2 = "settings_connected_device_v2";
     public static final String BATTERY_SETTINGS_V2 = "settings_battery_v2";
     public static final String BATTERY_DISPLAY_APP_LIST = "settings_battery_display_app_list";
diff --git a/src/com/android/settings/core/gateway/SettingsGateway.java b/src/com/android/settings/core/gateway/SettingsGateway.java
index b07cf84..91fc108 100644
--- a/src/com/android/settings/core/gateway/SettingsGateway.java
+++ b/src/com/android/settings/core/gateway/SettingsGateway.java
@@ -39,7 +39,6 @@
 import com.android.settings.accounts.AccountDashboardFragment;
 import com.android.settings.applications.AppAndNotificationDashboardFragment;
 import com.android.settings.applications.DefaultAppSettings;
-import com.android.settings.applications.InstalledAppDetails;
 import com.android.settings.applications.ManageDomainUrls;
 import com.android.settings.applications.NotificationApps;
 import com.android.settings.applications.ProcessStatsSummary;
@@ -207,7 +206,6 @@
             ConfigureNotificationSettings.class.getName(),
             ChooseLockPassword.ChooseLockPasswordFragment.class.getName(),
             ChooseLockPattern.ChooseLockPatternFragment.class.getName(),
-            InstalledAppDetails.class.getName(),
             AppInfoDashboardFragment.class.getName(),
             BatterySaverSettings.class.getName(),
             AppNotificationSettings.class.getName(),
diff --git a/src/com/android/settings/dashboard/DashboardSummary.java b/src/com/android/settings/dashboard/DashboardSummary.java
index fc82d41..f86867b 100644
--- a/src/com/android/settings/dashboard/DashboardSummary.java
+++ b/src/com/android/settings/dashboard/DashboardSummary.java
@@ -39,6 +39,7 @@
 import com.android.settings.dashboard.conditional.FocusRecyclerView;
 import com.android.settings.dashboard.conditional.FocusRecyclerView.FocusListener;
 import com.android.settings.dashboard.suggestions.SuggestionDismissController;
+import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.widget.ActionBarShadowController;
 import com.android.settingslib.drawer.CategoryKey;
@@ -86,10 +87,14 @@
     public void onAttach(Context context) {
         super.onAttach(context);
         Log.d(TAG, "Creating SuggestionControllerMixin");
-        mSuggestionControllerMixin = new SuggestionControllerMixin(context, this /* host */,
-                getLifecycle(), FeatureFactory.getFactory(context)
-                                    .getSuggestionFeatureProvider(context)
-                                    .getSuggestionServiceComponent());
+        final SuggestionFeatureProvider suggestionFeatureProvider = FeatureFactory
+                .getFactory(context)
+                .getSuggestionFeatureProvider(context);
+        if (suggestionFeatureProvider.isSuggestionEnabled(context)) {
+            mSuggestionControllerMixin = new SuggestionControllerMixin(context, this /* host */,
+                    getLifecycle(), suggestionFeatureProvider
+                    .getSuggestionServiceComponent());
+        }
     }
 
     @Override
@@ -202,12 +207,12 @@
         mDashboard.setItemAnimator(new DashboardItemAnimator());
         if (mDashboardFeatureProvider.useSuggestionUiV2()) {
             mAdapterV2 = new DashboardAdapterV2(getContext(), bundle,
-                mConditionManager.getConditions(), mSuggestionControllerMixin, getLifecycle());
+                    mConditionManager.getConditions(), mSuggestionControllerMixin, getLifecycle());
             mDashboard.setAdapter(mAdapterV2);
             mSummaryLoader.setSummaryConsumer(mAdapterV2);
         } else {
             mAdapter = new DashboardAdapter(getContext(), bundle, mConditionManager.getConditions(),
-                mSuggestionControllerMixin, this /* SuggestionDismissController.Callback */);
+                    mSuggestionControllerMixin, this /* SuggestionDismissController.Callback */);
             mDashboard.setAdapter(mAdapter);
             mSummaryLoader.setSummaryConsumer(mAdapter);
         }
@@ -302,6 +307,9 @@
                 CategoryKey.CATEGORY_HOMEPAGE);
         mSummaryLoader.updateSummaryToCache(category);
         mStagingCategory = category;
+        if (mSuggestionControllerMixin == null) {
+            return;
+        }
         if (mSuggestionControllerMixin.isSuggestionLoaded()) {
             Log.d(TAG, "Suggestion has loaded, setting suggestion/category");
             ThreadUtils.postOnMainThread(() -> {
@@ -321,7 +329,7 @@
             Log.d(TAG, "Suggestion NOT loaded, delaying setCategory by " + MAX_WAIT_MILLIS + "ms");
             if (mDashboardFeatureProvider.useSuggestionUiV2()) {
                 mHandler.postDelayed(()
-                    -> mAdapterV2.setCategory(mStagingCategory), MAX_WAIT_MILLIS);
+                        -> mAdapterV2.setCategory(mStagingCategory), MAX_WAIT_MILLIS);
             } else {
                 mHandler.postDelayed(() -> mAdapter.setCategory(mStagingCategory), MAX_WAIT_MILLIS);
             }
diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProvider.java b/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProvider.java
index b700049..f913085 100644
--- a/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProvider.java
+++ b/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProvider.java
@@ -34,7 +34,7 @@
     /**
      * Whether or not the whole suggestion feature is enabled.
      */
-    boolean isSuggestionV2Enabled(Context context);
+    boolean isSuggestionEnabled(Context context);
 
     /**
      * Returns the component name for SuggestionService.
diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java b/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java
index 4e5f688..8523273 100644
--- a/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java
+++ b/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java
@@ -54,7 +54,7 @@
     private final MetricsFeatureProvider mMetricsFeatureProvider;
 
     @Override
-    public boolean isSuggestionV2Enabled(Context context) {
+    public boolean isSuggestionEnabled(Context context) {
         final ActivityManager am =
                 (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
         return !am.isLowRamDevice();
diff --git a/src/com/android/settings/datausage/UnrestrictedDataAccess.java b/src/com/android/settings/datausage/UnrestrictedDataAccess.java
index cff4a50..2e20406 100644
--- a/src/com/android/settings/datausage/UnrestrictedDataAccess.java
+++ b/src/com/android/settings/datausage/UnrestrictedDataAccess.java
@@ -22,7 +22,6 @@
 import android.os.UserHandle;
 import android.support.v7.preference.Preference;
 import android.support.v7.preference.PreferenceViewHolder;
-import android.util.FeatureFlagUtils;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
@@ -33,9 +32,7 @@
 import com.android.settings.R;
 import com.android.settings.SettingsPreferenceFragment;
 import com.android.settings.applications.AppStateBaseBridge;
-import com.android.settings.applications.InstalledAppDetails;
 import com.android.settings.applications.appinfo.AppInfoDashboardFragment;
-import com.android.settings.core.FeatureFlags;
 import com.android.settings.datausage.AppStateDataUsageBridge.DataUsageState;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.widget.AppSwitchPreference;
@@ -286,17 +283,10 @@
         protected void onClick() {
             if (mState.isDataSaverBlacklisted) {
                 // app is blacklisted, launch App Data Usage screen
-                if (FeatureFlagUtils.isEnabled(getContext(), FeatureFlags.APP_INFO_V2)) {
-                    AppInfoDashboardFragment.startAppInfoFragment(AppDataUsage.class,
-                            R.string.app_data_usage,
-                            UnrestrictedDataAccess.this,
-                            mEntry);
-                } else {
-                    InstalledAppDetails.startAppInfoFragment(AppDataUsage.class,
-                            R.string.app_data_usage,
-                            UnrestrictedDataAccess.this,
-                            mEntry);
-                }
+                AppInfoDashboardFragment.startAppInfoFragment(AppDataUsage.class,
+                    R.string.app_data_usage,
+                    UnrestrictedDataAccess.this,
+                    mEntry);
             } else {
                 // app is not blacklisted, let superclass handle toggle switch
                 super.onClick();
diff --git a/src/com/android/settings/display/BrightnessLevelPreferenceController.java b/src/com/android/settings/display/BrightnessLevelPreferenceController.java
index ee573eb..fc08511 100644
--- a/src/com/android/settings/display/BrightnessLevelPreferenceController.java
+++ b/src/com/android/settings/display/BrightnessLevelPreferenceController.java
@@ -45,7 +45,6 @@
 
     private static final String TAG = "BrightnessPrefCtrl";
     private static final String KEY_BRIGHTNESS = "brightness";
-    private static final Uri BRIGHTNESS_MODE_URI;
     private static final Uri BRIGHTNESS_URI;
     private static final Uri BRIGHTNESS_FOR_VR_URI;
     private static final Uri BRIGHTNESS_ADJ_URI;
@@ -59,7 +58,6 @@
     private Preference mPreference;
 
     static {
-        BRIGHTNESS_MODE_URI = System.getUriFor(System.SCREEN_BRIGHTNESS_MODE);
         BRIGHTNESS_URI = System.getUriFor(System.SCREEN_BRIGHTNESS);
         BRIGHTNESS_FOR_VR_URI = System.getUriFor(System.SCREEN_BRIGHTNESS_FOR_VR);
         BRIGHTNESS_ADJ_URI = System.getUriFor(System.SCREEN_AUTO_BRIGHTNESS_ADJ);
@@ -112,10 +110,8 @@
     public void updateState(Preference preference) {
         updatedSummary(preference);
     }
-
     @Override
     public void onStart() {
-        mContentResolver.registerContentObserver(BRIGHTNESS_MODE_URI, false, mBrightnessObserver);
         mContentResolver.registerContentObserver(BRIGHTNESS_URI, false, mBrightnessObserver);
         mContentResolver.registerContentObserver(BRIGHTNESS_FOR_VR_URI, false, mBrightnessObserver);
         mContentResolver.registerContentObserver(BRIGHTNESS_ADJ_URI, false, mBrightnessObserver);
@@ -137,18 +133,11 @@
             final double value = System.getInt(mContentResolver, System.SCREEN_BRIGHTNESS_FOR_VR,
                     mMaxBrightness);
             return getPercentage(value, mMinVrBrightness, mMaxVrBrightness);
+        } else {
+            final double value = Settings.System.getInt(mContentResolver, System.SCREEN_BRIGHTNESS,
+                    mMinBrightness);
+            return getPercentage(value, mMinBrightness, mMaxBrightness);
         }
-        final int brightnessMode = Settings.System.getInt(mContentResolver,
-                System.SCREEN_BRIGHTNESS_MODE, System.SCREEN_BRIGHTNESS_MODE_MANUAL);
-        if (brightnessMode == System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC) {
-            final float value = Settings.System.getFloat(mContentResolver,
-                    System.SCREEN_AUTO_BRIGHTNESS_ADJ, 0);
-            // auto brightness is between -1 and 1
-            return getPercentage(value, -1, 1);
-        }
-        final double value = Settings.System.getInt(mContentResolver, System.SCREEN_BRIGHTNESS,
-                mMinBrightness);
-        return getPercentage(value, mMinBrightness, mMaxBrightness);
     }
 
     private double getPercentage(double value, int min, int max) {
diff --git a/src/com/android/settings/fuelgauge/AppButtonsPreferenceController.java b/src/com/android/settings/fuelgauge/AppButtonsPreferenceController.java
index a52433b..7bd1b3d 100644
--- a/src/com/android/settings/fuelgauge/AppButtonsPreferenceController.java
+++ b/src/com/android/settings/fuelgauge/AppButtonsPreferenceController.java
@@ -74,7 +74,7 @@
  * An easy way to handle them is to delegate them to {@link #handleDialogClick(int)} and
  * {@link #handleActivityResult(int, int, Intent)} in this controller.
  */
-//TODO(b/35810915): Make InstalledAppDetails use this controller
+//TODO(b/35810915): Make AppInfoDashboardFragment use this controller
 public class AppButtonsPreferenceController extends AbstractPreferenceController implements
         PreferenceControllerMixin, LifecycleObserver, OnResume, OnDestroy,
         ApplicationsState.Callbacks {
diff --git a/src/com/android/settings/fuelgauge/PowerUsageSummary.java b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
index e0954e5..2a841f9 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageSummary.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
@@ -93,14 +93,10 @@
     private static final int MENU_STATS_TYPE = Menu.FIRST;
     @VisibleForTesting
     static final int MENU_HIGH_POWER_APPS = Menu.FIRST + 3;
-    @VisibleForTesting
-    static final int MENU_TOGGLE_APPS = Menu.FIRST + 4;
     private static final int MENU_HELP = Menu.FIRST + 5;
     public static final int DEBUG_INFO_LOADER = 3;
 
     @VisibleForTesting
-    boolean mShowAllApps = false;
-    @VisibleForTesting
     PowerGaugePreference mScreenUsagePref;
     @VisibleForTesting
     PowerGaugePreference mLastFullChargePref;
@@ -221,7 +217,6 @@
         mAnomalySparseArray = new SparseArray<>();
 
         restartBatteryInfoLoader();
-        restoreSavedInstance(icicle);
     }
 
     @Override
@@ -230,12 +225,6 @@
     }
 
     @Override
-    public void onSaveInstanceState(Bundle outState) {
-        super.onSaveInstanceState(outState);
-        outState.putBoolean(KEY_SHOW_ALL_APPS, mShowAllApps);
-    }
-
-    @Override
     public boolean onPreferenceTreeClick(Preference preference) {
         if (KEY_BATTERY_HEADER.equals(preference.getKey())) {
             performBatteryHeaderClick();
@@ -284,11 +273,6 @@
 
         menu.add(Menu.NONE, MENU_HIGH_POWER_APPS, Menu.NONE, R.string.high_power_apps);
 
-        if (mPowerFeatureProvider.isPowerAccountingToggleEnabled()) {
-            menu.add(Menu.NONE, MENU_TOGGLE_APPS, Menu.NONE,
-                    mShowAllApps ? R.string.hide_extra_apps : R.string.show_all_apps);
-        }
-
         super.onCreateOptionsMenu(menu, inflater);
     }
 
@@ -322,25 +306,11 @@
                 metricsFeatureProvider.action(context,
                         MetricsEvent.ACTION_SETTINGS_MENU_BATTERY_OPTIMIZATION);
                 return true;
-            case MENU_TOGGLE_APPS:
-                mShowAllApps = !mShowAllApps;
-                item.setTitle(mShowAllApps ? R.string.hide_extra_apps : R.string.show_all_apps);
-                metricsFeatureProvider.action(context,
-                        MetricsEvent.ACTION_SETTINGS_MENU_BATTERY_APPS_TOGGLE, mShowAllApps);
-                restartBatteryStatsLoader(false /* clearHeader */);
-                return true;
             default:
                 return super.onOptionsItemSelected(item);
         }
     }
 
-    @VisibleForTesting
-    void restoreSavedInstance(Bundle savedInstance) {
-        if (savedInstance != null) {
-            mShowAllApps = savedInstance.getBoolean(KEY_SHOW_ALL_APPS, false);
-        }
-    }
-
     private void performBatteryHeaderClick() {
         if (mPowerFeatureProvider.isAdvancedUiEnabled()) {
             Utils.startWithFragment(getContext(), PowerUsageAdvanced.class.getName(), null,
@@ -375,8 +345,8 @@
 
         final CharSequence timeSequence = Utils.formatRelativeTime(context, lastFullChargeTime,
                 false);
-        mBatteryAppListPreferenceController.refreshAppListGroup(mStatsHelper, mShowAllApps,
-                timeSequence);
+        mBatteryAppListPreferenceController.refreshAppListGroup(mStatsHelper,
+                false /* showAllApps */, timeSequence);
     }
 
     @VisibleForTesting
diff --git a/src/com/android/settings/location/RecentLocationRequestPreferenceController.java b/src/com/android/settings/location/RecentLocationRequestPreferenceController.java
index 8cbe95c..b17d19e 100644
--- a/src/com/android/settings/location/RecentLocationRequestPreferenceController.java
+++ b/src/com/android/settings/location/RecentLocationRequestPreferenceController.java
@@ -20,19 +20,15 @@
 import android.support.v7.preference.Preference;
 import android.support.v7.preference.PreferenceCategory;
 import android.support.v7.preference.PreferenceScreen;
-import android.util.FeatureFlagUtils;
 
 import com.android.settings.R;
 import com.android.settings.SettingsActivity;
-import com.android.settings.applications.InstalledAppDetails;
 import com.android.settings.applications.appinfo.AppInfoDashboardFragment;
-import com.android.settings.core.FeatureFlags;
 import com.android.settings.widget.AppPreference;
 import com.android.settingslib.core.lifecycle.Lifecycle;
 import com.android.settingslib.location.RecentLocationApps;
 
 import java.util.ArrayList;
-import java.util.Comparator;
 import java.util.List;
 
 public class RecentLocationRequestPreferenceController extends LocationBasePreferenceController {
@@ -60,19 +56,11 @@
         public boolean onPreferenceClick(Preference preference) {
             // start new fragment to display extended information
             final Bundle args = new Bundle();
-            if (FeatureFlagUtils.isEnabled(mFragment.getActivity(), FeatureFlags.APP_INFO_V2)) {
-                args.putString(AppInfoDashboardFragment.ARG_PACKAGE_NAME, mPackage);
-                ((SettingsActivity) mFragment.getActivity()).startPreferencePanelAsUser(
-                        mFragment,
-                        AppInfoDashboardFragment.class.getName(), args,
-                        R.string.application_info_label, null, mUserHandle);
-            } else {
-                args.putString(InstalledAppDetails.ARG_PACKAGE_NAME, mPackage);
-                ((SettingsActivity) mFragment.getActivity()).startPreferencePanelAsUser(
-                        mFragment,
-                        InstalledAppDetails.class.getName(), args,
-                        R.string.application_info_label, null, mUserHandle);
-            }
+            args.putString(AppInfoDashboardFragment.ARG_PACKAGE_NAME, mPackage);
+            ((SettingsActivity) mFragment.getActivity()).startPreferencePanelAsUser(
+                mFragment,
+                AppInfoDashboardFragment.class.getName(), args,
+                R.string.application_info_label, null, mUserHandle);
             return true;
         }
     }
diff --git a/src/com/android/settings/system/SystemDashboardFragment.java b/src/com/android/settings/system/SystemDashboardFragment.java
index 323a2d4..88cafb0 100644
--- a/src/com/android/settings/system/SystemDashboardFragment.java
+++ b/src/com/android/settings/system/SystemDashboardFragment.java
@@ -17,7 +17,6 @@
 
 import android.content.Context;
 import android.os.Bundle;
-import android.os.UserManager;
 import android.provider.SearchIndexableResource;
 import android.support.v7.preference.Preference;
 import android.support.v7.preference.PreferenceGroup;
diff --git a/src/com/android/settings/widget/EntityHeaderController.java b/src/com/android/settings/widget/EntityHeaderController.java
index 8607211..4ebc369 100644
--- a/src/com/android/settings/widget/EntityHeaderController.java
+++ b/src/com/android/settings/widget/EntityHeaderController.java
@@ -37,7 +37,6 @@
 import android.support.annotation.VisibleForTesting;
 import android.support.v7.widget.RecyclerView;
 import android.text.TextUtils;
-import android.util.FeatureFlagUtils;
 import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -48,10 +47,8 @@
 import com.android.settings.R;
 import com.android.settings.Utils;
 import com.android.settings.applications.AppInfoBase;
-import com.android.settings.applications.InstalledAppDetails;
 import com.android.settings.applications.LayoutPreference;
 import com.android.settings.applications.appinfo.AppInfoDashboardFragment;
-import com.android.settings.core.FeatureFlags;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settingslib.applications.ApplicationsState;
 import com.android.settingslib.core.lifecycle.Lifecycle;
@@ -285,17 +282,10 @@
         entityHeaderContent.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
-                if (FeatureFlagUtils.isEnabled(mAppContext, FeatureFlags.APP_INFO_V2)) {
-                    AppInfoBase.startAppInfoFragment(
-                            AppInfoDashboardFragment.class, R.string.application_info_label,
-                            mPackageName, mUid, mFragment, 0 /* request */,
-                            mMetricsCategory);
-                } else {
-                    AppInfoBase.startAppInfoFragment(
-                            InstalledAppDetails.class, R.string.application_info_label,
-                            mPackageName, mUid, mFragment, 0 /* request */,
-                            mMetricsCategory);
-                }
+                AppInfoBase.startAppInfoFragment(
+                    AppInfoDashboardFragment.class, R.string.application_info_label,
+                    mPackageName, mUid, mFragment, 0 /* request */,
+                    mMetricsCategory);
             }
         });
         return;
diff --git a/tests/robotests/assets/grandfather_not_implementing_indexable b/tests/robotests/assets/grandfather_not_implementing_indexable
index 9d593a0..ece35fb 100644
--- a/tests/robotests/assets/grandfather_not_implementing_indexable
+++ b/tests/robotests/assets/grandfather_not_implementing_indexable
@@ -43,7 +43,6 @@
 com.android.settings.applications.RunningServices
 com.android.settings.applications.ConfirmConvertToFbe
 com.android.settings.deviceinfo.PublicVolumeSettings
-com.android.settings.applications.InstalledAppDetails
 com.android.settings.accessibility.ToggleAccessibilityServicePreferenceFragment
 com.android.settings.print.PrintServiceSettingsFragment
 com.android.settings.deviceinfo.PrivateVolumeSettings
diff --git a/tests/robotests/src/com/android/settings/applications/InstalledAppDetailsTest.java b/tests/robotests/src/com/android/settings/applications/InstalledAppDetailsTest.java
deleted file mode 100644
index 21e7848..0000000
--- a/tests/robotests/src/com/android/settings/applications/InstalledAppDetailsTest.java
+++ /dev/null
@@ -1,591 +0,0 @@
-/*
- * Copyright (C) 2017 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 com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.nullable;
-import static org.mockito.Matchers.anyDouble;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.app.AlertDialog;
-import android.app.AppOpsManager;
-import android.app.Fragment;
-import android.app.LoaderManager;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.res.Resources;
-import android.os.BatteryStats;
-import android.os.Bundle;
-import android.os.UserManager;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceManager;
-import android.support.v7.preference.PreferenceScreen;
-import android.view.View;
-
-import com.android.internal.os.BatterySipper;
-import com.android.internal.os.BatteryStatsHelper;
-import com.android.settings.R;
-import com.android.settings.SettingsActivity;
-import com.android.settings.TestConfig;
-import com.android.settings.applications.instantapps.InstantAppButtonsController;
-import com.android.settings.applications.instantapps.InstantAppButtonsController.ShowDialogDelegate;
-import com.android.settings.fuelgauge.BatteryUtils;
-import com.android.settings.testutils.FakeFeatureFactory;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
-import com.android.settings.widget.ActionButtonPreferenceTest;
-import com.android.settings.wrapper.DevicePolicyManagerWrapper;
-import com.android.settingslib.Utils;
-import com.android.settingslib.applications.AppUtils;
-import com.android.settingslib.applications.ApplicationsState.AppEntry;
-import com.android.settingslib.applications.StorageStatsSource.AppStorageStats;
-import com.android.settingslib.applications.instantapps.InstantAppDataProvider;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Answers;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-import org.robolectric.annotation.Implementation;
-import org.robolectric.annotation.Implements;
-import org.robolectric.util.ReflectionHelpers;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-
-
-@RunWith(SettingsRobolectricTestRunner.class)
-@Config(
-        manifest = TestConfig.MANIFEST_PATH,
-        sdk = TestConfig.SDK_VERSION,
-        shadows = InstalledAppDetailsTest.ShadowUtils.class
-)
-public final class InstalledAppDetailsTest {
-
-    private static final String PACKAGE_NAME = "test_package_name";
-    private static final int TARGET_UID = 111;
-    private static final int OTHER_UID = 222;
-    private static final double BATTERY_LEVEL = 60;
-    private static final String BATTERY_LEVEL_STRING = "60%";
-
-    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
-    private Context mContext;
-    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
-    private UserManager mUserManager;
-    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
-    private SettingsActivity mActivity;
-    @Mock
-    private DevicePolicyManagerWrapper mDevicePolicyManager;
-    @Mock
-    private BatterySipper mBatterySipper;
-    @Mock
-    private BatterySipper mOtherBatterySipper;
-    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
-    private BatteryStatsHelper mBatteryStatsHelper;
-    @Mock
-    private BatteryStats.Uid mUid;
-    @Mock
-    private PackageManager mPackageManager;
-    @Mock
-    private BatteryUtils mBatteryUtils;
-    @Mock
-    private LoaderManager mLoaderManager;
-    @Mock
-    private AppOpsManager mAppOpsManager;
-
-    private FakeFeatureFactory mFeatureFactory;
-    private InstalledAppDetails mAppDetail;
-    private Context mShadowContext;
-    private Preference mBatteryPreference;
-
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        mFeatureFactory = FakeFeatureFactory.setupForTest();
-        mShadowContext = RuntimeEnvironment.application;
-        mAppDetail = spy(new InstalledAppDetails());
-        mAppDetail.mBatteryUtils = mBatteryUtils;
-
-        mBatteryPreference = new Preference(mShadowContext);
-        mAppDetail.mBatteryPreference = mBatteryPreference;
-        mAppDetail.mActionButtons = ActionButtonPreferenceTest.createMock();
-
-        mBatterySipper.drainType = BatterySipper.DrainType.IDLE;
-        mBatterySipper.uidObj = mUid;
-        doReturn(TARGET_UID).when(mBatterySipper).getUid();
-        doReturn(OTHER_UID).when(mOtherBatterySipper).getUid();
-        doReturn(mActivity).when(mAppDetail).getActivity();
-        doReturn(mShadowContext).when(mAppDetail).getContext();
-        doReturn(mPackageManager).when(mActivity).getPackageManager();
-        doReturn(mAppOpsManager).when(mActivity).getSystemService(Context.APP_OPS_SERVICE);
-
-        // Default to not considering any apps to be instant (individual tests can override this).
-        ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider",
-                (InstantAppDataProvider) (i -> false));
-    }
-
-    @Test
-    public void shouldShowUninstallForAll_installForOneOtherUserOnly_shouldReturnTrue() {
-        when(mDevicePolicyManager.packageHasActiveAdmins(nullable(String.class))).thenReturn(false);
-        when(mUserManager.getUsers().size()).thenReturn(2);
-        ReflectionHelpers.setField(mAppDetail, "mDpm", mDevicePolicyManager);
-        ReflectionHelpers.setField(mAppDetail, "mUserManager", mUserManager);
-        final ApplicationInfo info = new ApplicationInfo();
-        info.enabled = true;
-        final AppEntry appEntry = mock(AppEntry.class);
-        appEntry.info = info;
-        final PackageInfo packageInfo = mock(PackageInfo.class);
-        ReflectionHelpers.setField(mAppDetail, "mPackageInfo", packageInfo);
-
-        assertThat(mAppDetail.shouldShowUninstallForAll(appEntry)).isTrue();
-    }
-
-    @Test
-    public void shouldShowUninstallForAll_installForSelfOnly_shouldReturnFalse() {
-        when(mDevicePolicyManager.packageHasActiveAdmins(nullable(String.class))).thenReturn(false);
-        when(mUserManager.getUsers().size()).thenReturn(2);
-        ReflectionHelpers.setField(mAppDetail, "mDpm", mDevicePolicyManager);
-        ReflectionHelpers.setField(mAppDetail, "mUserManager", mUserManager);
-        final ApplicationInfo info = new ApplicationInfo();
-        info.flags = ApplicationInfo.FLAG_INSTALLED;
-        info.enabled = true;
-        final AppEntry appEntry = mock(AppEntry.class);
-        appEntry.info = info;
-        final PackageInfo packageInfo = mock(PackageInfo.class);
-        ReflectionHelpers.setField(mAppDetail, "mPackageInfo", packageInfo);
-
-        assertThat(mAppDetail.shouldShowUninstallForAll(appEntry)).isFalse();
-    }
-
-    @Test
-    public void getStorageSummary_shouldWorkForExternal() {
-        Context context = RuntimeEnvironment.application.getApplicationContext();
-        AppStorageStats stats = mock(AppStorageStats.class);
-        when(stats.getTotalBytes()).thenReturn(1L);
-
-        assertThat(InstalledAppDetails.getStorageSummary(context, stats, true))
-                .isEqualTo("1 B used in external storage");
-    }
-
-    @Test
-    public void getStorageSummary_shouldWorkForInternal() {
-        Context context = RuntimeEnvironment.application.getApplicationContext();
-        AppStorageStats stats = mock(AppStorageStats.class);
-        when(stats.getTotalBytes()).thenReturn(1L);
-
-        assertThat(InstalledAppDetails.getStorageSummary(context, stats, false))
-                .isEqualTo("1 B used in internal storage");
-    }
-
-    @Test
-    public void launchFragment_hasNoPackageInfo_shouldFinish() {
-        ReflectionHelpers.setField(mAppDetail, "mPackageInfo", null);
-
-        assertThat(mAppDetail.ensurePackageInfoAvailable(mActivity)).isFalse();
-        verify(mActivity).finishAndRemoveTask();
-    }
-
-    @Test
-    public void launchFragment_hasPackageInfo_shouldReturnTrue() {
-        final PackageInfo packageInfo = mock(PackageInfo.class);
-        ReflectionHelpers.setField(mAppDetail, "mPackageInfo", packageInfo);
-
-        assertThat(mAppDetail.ensurePackageInfoAvailable(mActivity)).isTrue();
-        verify(mActivity, never()).finishAndRemoveTask();
-    }
-
-    @Test
-    public void packageSizeChange_isOtherPackage_shouldNotRefreshUi() {
-        ReflectionHelpers.setField(mAppDetail, "mPackageName", PACKAGE_NAME);
-        mAppDetail.onPackageSizeChanged("Not_" + PACKAGE_NAME);
-
-        verify(mAppDetail, never()).refreshUi();
-    }
-
-    @Test
-    public void packageSizeChange_isOwnPackage_shouldRefreshUi() {
-        doReturn(Boolean.TRUE).when(mAppDetail).refreshUi();
-        ReflectionHelpers.setField(mAppDetail, "mPackageName", PACKAGE_NAME);
-
-        mAppDetail.onPackageSizeChanged(PACKAGE_NAME);
-
-        verify(mAppDetail).refreshUi();
-    }
-
-    @Test
-    public void launchPowerUsageDetailFragment_shouldNotCrash() {
-        mAppDetail.mBatteryPreference = mBatteryPreference;
-        mAppDetail.mSipper = mBatterySipper;
-        mAppDetail.mBatteryHelper = mBatteryStatsHelper;
-
-        // Should not crash
-        mAppDetail.onPreferenceClick(mBatteryPreference);
-    }
-
-    // Tests that we don't show the "uninstall for all users" button for instant apps.
-    @Test
-    public void instantApps_noUninstallForAllButton() {
-        // Make this app appear to be instant.
-        ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider",
-                (InstantAppDataProvider) (i -> true));
-        when(mDevicePolicyManager.packageHasActiveAdmins(nullable(String.class))).thenReturn(false);
-        when(mUserManager.getUsers().size()).thenReturn(2);
-
-        final ApplicationInfo info = new ApplicationInfo();
-        info.enabled = true;
-        final AppEntry appEntry = mock(AppEntry.class);
-        appEntry.info = info;
-        final PackageInfo packageInfo = mock(PackageInfo.class);
-
-        ReflectionHelpers.setField(mAppDetail, "mDpm", mDevicePolicyManager);
-        ReflectionHelpers.setField(mAppDetail, "mUserManager", mUserManager);
-        ReflectionHelpers.setField(mAppDetail, "mPackageInfo", packageInfo);
-
-        assertThat(mAppDetail.shouldShowUninstallForAll(appEntry)).isFalse();
-    }
-
-    // Tests that we don't show the uninstall button for instant apps"
-    @Test
-    public void instantApps_noUninstallButton() {
-        // Make this app appear to be instant.
-        ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider",
-                (InstantAppDataProvider) (i -> true));
-        final ApplicationInfo info = new ApplicationInfo();
-        info.flags = ApplicationInfo.FLAG_INSTALLED;
-        info.enabled = true;
-        final AppEntry appEntry = mock(AppEntry.class);
-        appEntry.info = info;
-        final PackageInfo packageInfo = mock(PackageInfo.class);
-        packageInfo.applicationInfo = info;
-
-        ReflectionHelpers.setField(mAppDetail, "mUserManager", mUserManager);
-        ReflectionHelpers.setField(mAppDetail, "mAppEntry", appEntry);
-        ReflectionHelpers.setField(mAppDetail, "mPackageInfo", packageInfo);
-
-        mAppDetail.initUninstallButtonForUserApp();
-        verify(mAppDetail.mActionButtons).setButton1Visible(false);
-    }
-
-    // Tests that we don't show the force stop button for instant apps (they aren't allowed to run
-    // when they aren't in the foreground).
-    @Test
-    public void instantApps_noForceStop() {
-        // Make this app appear to be instant.
-        ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider",
-                (InstantAppDataProvider) (i -> true));
-        final PackageInfo packageInfo = mock(PackageInfo.class);
-        final AppEntry appEntry = mock(AppEntry.class);
-        final ApplicationInfo info = new ApplicationInfo();
-        appEntry.info = info;
-
-        ReflectionHelpers.setField(mAppDetail, "mDpm", mDevicePolicyManager);
-        ReflectionHelpers.setField(mAppDetail, "mPackageInfo", packageInfo);
-        ReflectionHelpers.setField(mAppDetail, "mAppEntry", appEntry);
-
-        mAppDetail.checkForceStop();
-        verify(mAppDetail.mActionButtons).setButton2Visible(false);
-    }
-
-    @Test
-    public void instantApps_buttonControllerHandlesDialog() {
-        InstantAppButtonsController mockController = mock(InstantAppButtonsController.class);
-        ReflectionHelpers.setField(
-                mAppDetail, "mInstantAppButtonsController", mockController);
-        // Make sure first that button controller is not called for supported dialog id
-        AlertDialog mockDialog = mock(AlertDialog.class);
-        when(mockController.createDialog(InstantAppButtonsController.DLG_CLEAR_APP))
-                .thenReturn(mockDialog);
-        assertThat(mAppDetail.createDialog(InstantAppButtonsController.DLG_CLEAR_APP, 0))
-                .isEqualTo(mockDialog);
-        verify(mockController).createDialog(InstantAppButtonsController.DLG_CLEAR_APP);
-    }
-
-    // A helper class for testing the InstantAppButtonsController - it lets us look up the
-    // preference associated with a key for instant app buttons and get back a mock
-    // LayoutPreference (to avoid a null pointer exception).
-    public static class InstalledAppDetailsWithMockInstantButtons extends InstalledAppDetails {
-        @Mock
-        private LayoutPreference mInstantButtons;
-
-        public InstalledAppDetailsWithMockInstantButtons() {
-            super();
-            MockitoAnnotations.initMocks(this);
-        }
-
-        @Override
-        public Preference findPreference(CharSequence key) {
-            if (key == "instant_app_buttons") {
-                return mInstantButtons;
-            }
-            return super.findPreference(key);
-        }
-    }
-
-    @Test
-    public void instantApps_instantSpecificButtons() {
-        // Make this app appear to be instant.
-        ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider",
-                (InstantAppDataProvider) (i -> true));
-        final PackageInfo packageInfo = mock(PackageInfo.class);
-
-        final InstalledAppDetailsWithMockInstantButtons
-                fragment = new InstalledAppDetailsWithMockInstantButtons();
-        ReflectionHelpers.setField(fragment, "mPackageInfo", packageInfo);
-        ReflectionHelpers.setField(fragment, "mApplicationFeatureProvider",
-                mFeatureFactory.applicationFeatureProvider);
-
-        final InstantAppButtonsController buttonsController =
-                mock(InstantAppButtonsController.class);
-        when(buttonsController.setPackageName(nullable(String.class)))
-                .thenReturn(buttonsController);
-        when(mFeatureFactory.applicationFeatureProvider.newInstantAppButtonsController(
-                nullable(Fragment.class), nullable(View.class), nullable(ShowDialogDelegate.class)))
-                .thenReturn(buttonsController);
-
-        fragment.maybeAddInstantAppButtons();
-        verify(buttonsController).setPackageName(nullable(String.class));
-        verify(buttonsController).show();
-    }
-
-    @Test
-    public void instantApps_removeCorrectPref() {
-        PreferenceScreen mockPreferenceScreen = mock(PreferenceScreen.class);
-        PreferenceManager mockPreferenceManager = mock(PreferenceManager.class);
-        AppDomainsPreference mockAppDomainsPref = mock(AppDomainsPreference.class);
-        Preference mockLaunchPreference = mock(Preference.class);
-        PackageInfo mockPackageInfo = mock(PackageInfo.class);
-        PackageManager mockPackageManager = mock(PackageManager.class);
-        ReflectionHelpers.setField(
-                mAppDetail, "mLaunchPreference", mockLaunchPreference);
-        ReflectionHelpers.setField(
-                mAppDetail, "mInstantAppDomainsPreference", mockAppDomainsPref);
-        ReflectionHelpers.setField(
-                mAppDetail, "mPreferenceManager", mockPreferenceManager);
-        ReflectionHelpers.setField(
-                mAppDetail, "mPackageInfo", mockPackageInfo);
-        ReflectionHelpers.setField(
-                mAppDetail, "mPm", mockPackageManager);
-        when(mockPreferenceManager.getPreferenceScreen()).thenReturn(mockPreferenceScreen);
-
-        ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider",
-                (InstantAppDataProvider) (i -> false));
-        mAppDetail.prepareInstantAppPrefs();
-
-        // For the non instant case we remove the app domain pref, and leave the launch pref
-        verify(mockPreferenceScreen).removePreference(mockAppDomainsPref);
-        verify(mockPreferenceScreen, never()).removePreference(mockLaunchPreference);
-
-        // For the instant app case we remove the launch preff, and leave the app domain pref
-        ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider",
-                (InstantAppDataProvider) (i -> true));
-
-        mAppDetail.prepareInstantAppPrefs();
-        verify(mockPreferenceScreen).removePreference(mockLaunchPreference);
-        // Will be 1 still due to above call
-        verify(mockPreferenceScreen, times(1))
-                .removePreference(mockAppDomainsPref);
-    }
-
-    @Test
-    public void onActivityResult_uninstalledUpdates_shouldInvalidateOptionsMenu() {
-        doReturn(true).when(mAppDetail).refreshUi();
-
-        mAppDetail.onActivityResult(InstalledAppDetails.REQUEST_UNINSTALL, 0, mock(Intent.class));
-
-        verify(mActivity).invalidateOptionsMenu();
-    }
-
-    @Test
-    public void findTargetSipper_findCorrectSipper() {
-        List<BatterySipper> usageList = new ArrayList<>();
-        usageList.add(mBatterySipper);
-        usageList.add(mOtherBatterySipper);
-        doReturn(usageList).when(mBatteryStatsHelper).getUsageList();
-
-        assertThat(mAppDetail.findTargetSipper(mBatteryStatsHelper, TARGET_UID)).isEqualTo(
-                mBatterySipper);
-    }
-
-    @Test
-    public void updateBattery_noBatteryStats_summaryNo() {
-        doReturn(mShadowContext.getString(R.string.no_battery_summary)).when(mAppDetail).getString(
-                R.string.no_battery_summary);
-        mAppDetail.updateBattery();
-
-        assertThat(mBatteryPreference.getSummary()).isEqualTo(
-                "No battery use since last full charge");
-    }
-
-    @Test
-    public void updateBattery_hasBatteryStats_summaryPercent() {
-        mAppDetail.mBatteryHelper = mBatteryStatsHelper;
-        mAppDetail.mSipper = mBatterySipper;
-        doReturn(BATTERY_LEVEL).when(mBatteryUtils).calculateBatteryPercent(anyDouble(),
-                anyDouble(), anyDouble(), anyInt());
-        doReturn(mShadowContext.getString(R.string.battery_summary, BATTERY_LEVEL_STRING)).when(
-                mAppDetail).getString(R.string.battery_summary, BATTERY_LEVEL_STRING);
-        doReturn(new ArrayList<>()).when(mBatteryStatsHelper).getUsageList();
-
-        mAppDetail.updateBattery();
-
-        assertThat(mBatteryPreference.getSummary()).isEqualTo("60% use since last full charge");
-    }
-
-    @Test
-    public void isBatteryStatsAvailable_hasBatteryStatsHelperAndSipper_returnTrue() {
-        mAppDetail.mBatteryHelper = mBatteryStatsHelper;
-        mAppDetail.mSipper = mBatterySipper;
-
-        assertThat(mAppDetail.isBatteryStatsAvailable()).isTrue();
-    }
-
-    @Test
-    public void isBatteryStatsAvailable_parametersNull_returnFalse() {
-        assertThat(mAppDetail.isBatteryStatsAvailable()).isFalse();
-    }
-
-    @Test
-    public void handleDisableable_appIsHomeApp_buttonShouldNotWork() {
-        final ApplicationInfo info = new ApplicationInfo();
-        info.packageName = "pkg";
-        info.enabled = true;
-        final AppEntry appEntry = mock(AppEntry.class);
-        appEntry.info = info;
-        final HashSet<String> homePackages = new HashSet<>();
-        homePackages.add(info.packageName);
-
-        ReflectionHelpers.setField(mAppDetail, "mHomePackages", homePackages);
-        ReflectionHelpers.setField(mAppDetail, "mAppEntry", appEntry);
-
-        assertThat(mAppDetail.handleDisableable()).isFalse();
-        verify(mAppDetail.mActionButtons).setButton1Text(R.string.disable_text);
-    }
-
-    @Test
-    public void handleDisableable_appIsEnabled_buttonShouldWork() {
-        final ApplicationInfo info = new ApplicationInfo();
-        info.packageName = "pkg";
-        info.enabled = true;
-        info.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
-
-        final AppEntry appEntry = mock(AppEntry.class);
-        appEntry.info = info;
-        when(mFeatureFactory.applicationFeatureProvider.getKeepEnabledPackages()).thenReturn(
-                new HashSet<>());
-
-        ReflectionHelpers.setField(mAppDetail, "mApplicationFeatureProvider",
-                mFeatureFactory.applicationFeatureProvider);
-        ReflectionHelpers.setField(mAppDetail, "mAppEntry", appEntry);
-
-        assertThat(mAppDetail.handleDisableable()).isTrue();
-        verify(mAppDetail.mActionButtons).setButton1Text(R.string.disable_text);
-    }
-
-    @Test
-    @Config(shadows = ShadowUtils.class)
-    public void handleDisableable_appIsDisabled_buttonShouldShowEnable() {
-        final ApplicationInfo info = new ApplicationInfo();
-        info.packageName = "pkg";
-        info.enabled = false;
-        info.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
-
-        final AppEntry appEntry = mock(AppEntry.class);
-        appEntry.info = info;
-        when(mFeatureFactory.applicationFeatureProvider.getKeepEnabledPackages()).thenReturn(
-                new HashSet<>());
-
-        ReflectionHelpers.setField(mAppDetail, "mApplicationFeatureProvider",
-                mFeatureFactory.applicationFeatureProvider);
-        ReflectionHelpers.setField(mAppDetail, "mAppEntry", appEntry);
-
-        assertThat(mAppDetail.handleDisableable()).isTrue();
-        verify(mAppDetail.mActionButtons).setButton1Text(R.string.enable_text);
-        verify(mAppDetail.mActionButtons).setButton1Positive(true);
-    }
-
-    @Test
-    public void handleDisableable_appIsEnabledAndInKeepEnabledWhitelist_buttonShouldNotWork() {
-        final ApplicationInfo info = new ApplicationInfo();
-        info.packageName = "pkg";
-        info.enabled = true;
-        info.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
-
-        final AppEntry appEntry = mock(AppEntry.class);
-        appEntry.info = info;
-
-        final HashSet<String> packages = new HashSet<>();
-        packages.add(info.packageName);
-        when(mFeatureFactory.applicationFeatureProvider.getKeepEnabledPackages()).thenReturn(
-                packages);
-
-        ReflectionHelpers.setField(mAppDetail, "mApplicationFeatureProvider",
-                mFeatureFactory.applicationFeatureProvider);
-        ReflectionHelpers.setField(mAppDetail, "mAppEntry", appEntry);
-
-        assertThat(mAppDetail.handleDisableable()).isFalse();
-        verify(mAppDetail.mActionButtons).setButton1Text(R.string.disable_text);
-    }
-
-    @Test
-    public void testRestartBatteryStatsLoader() {
-        doReturn(mLoaderManager).when(mAppDetail).getLoaderManager();
-
-        mAppDetail.restartBatteryStatsLoader();
-
-        verify(mLoaderManager).restartLoader(InstalledAppDetails.LOADER_BATTERY, Bundle.EMPTY,
-                mAppDetail.mBatteryCallbacks);
-    }
-
-    @Test
-    public void initUninstallButtonForUserApp_shouldSetNegativeButton() {
-        final ApplicationInfo info = new ApplicationInfo();
-        info.flags = ApplicationInfo.FLAG_INSTALLED;
-        info.enabled = true;
-        final PackageInfo packageInfo = mock(PackageInfo.class);
-        packageInfo.applicationInfo = info;
-        ReflectionHelpers.setField(mAppDetail, "mUserManager", mUserManager);
-        ReflectionHelpers.setField(mAppDetail, "mPackageInfo", packageInfo);
-
-        mAppDetail.initUninstallButtonForUserApp();
-
-        verify(mAppDetail.mActionButtons).setButton1Positive(false);
-    }
-
-    @Implements(Utils.class)
-    public static class ShadowUtils {
-        @Implementation
-        public static boolean isSystemPackage(Resources resources, PackageManager pm,
-                PackageInfo pkg) {
-            return false;
-        }
-    }
-}
diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardSummaryTest.java b/tests/robotests/src/com/android/settings/dashboard/DashboardSummaryTest.java
index 59823ec..2a7b829 100644
--- a/tests/robotests/src/com/android/settings/dashboard/DashboardSummaryTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/DashboardSummaryTest.java
@@ -16,6 +16,7 @@
 
 package com.android.settings.dashboard;
 
+import static com.google.common.truth.Truth.assertThat;
 import static org.mockito.ArgumentMatchers.nullable;
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.doNothing;
@@ -34,9 +35,11 @@
 import com.android.settings.TestConfig;
 import com.android.settings.dashboard.conditional.ConditionManager;
 import com.android.settings.dashboard.conditional.FocusRecyclerView;
+import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settingslib.drawer.CategoryKey;
 import com.android.settingslib.drawer.DashboardCategory;
+import com.android.settingslib.suggestions.SuggestionControllerMixin;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -67,10 +70,12 @@
 
     private Context mContext;
     private DashboardSummary mSummary;
+    private FakeFeatureFactory mFeatureFactory;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
+        mFeatureFactory = FakeFeatureFactory.setupForTest();
         mContext = RuntimeEnvironment.application;
         mSummary = spy(new DashboardSummary());
         ReflectionHelpers.setField(mSummary, "mAdapter", mAdapter);
@@ -83,6 +88,28 @@
     }
 
     @Test
+    public void onAttach_suggestionDisabled_shouldNotStartSuggestionControllerMixin() {
+        when(mFeatureFactory.suggestionsFeatureProvider.isSuggestionEnabled(any(Context.class)))
+                .thenReturn(false);
+
+        mSummary.onAttach(mContext);
+        final SuggestionControllerMixin mixin = ReflectionHelpers
+                .getField(mSummary, "mSuggestionControllerMixin");
+        assertThat(mixin).isNull();
+    }
+
+    @Test
+    public void onAttach_suggestionEnabled_shouldStartSuggestionControllerMixin() {
+        when(mFeatureFactory.suggestionsFeatureProvider.isSuggestionEnabled(any(Context.class)))
+                .thenReturn(true);
+
+        mSummary.onAttach(mContext);
+        final SuggestionControllerMixin mixin = ReflectionHelpers
+                .getField(mSummary, "mSuggestionControllerMixin");
+        assertThat(mixin).isNotNull();
+    }
+
+    @Test
     public void updateCategory_shouldGetCategoryFromFeatureProvider() {
         doReturn(mock(Activity.class)).when(mSummary).getActivity();
         mSummary.onAttach(mContext);
diff --git a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImplTest.java
index 54af308..e9c8805 100644
--- a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImplTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImplTest.java
@@ -114,13 +114,13 @@
     public void isSuggestionEnabled_isLowMemoryDevice_shouldReturnFalse() {
         when(mActivityManager.isLowRamDevice()).thenReturn(true);
 
-        assertThat(mProvider.isSuggestionV2Enabled(mContext)).isFalse();
+        assertThat(mProvider.isSuggestionEnabled(mContext)).isFalse();
     }
 
     @Test
     public void isSuggestionV2Enabled_isNotLowMemoryDevice_shouldReturnTrue() {
         when(mActivityManager.isLowRamDevice()).thenReturn(false);
-        assertThat(mProvider.isSuggestionV2Enabled(mContext)).isTrue();
+        assertThat(mProvider.isSuggestionEnabled(mContext)).isTrue();
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/display/BrightnessLevelPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/BrightnessLevelPreferenceControllerTest.java
index 95144bd..f1cf79e 100644
--- a/tests/robotests/src/com/android/settings/display/BrightnessLevelPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/display/BrightnessLevelPreferenceControllerTest.java
@@ -90,8 +90,6 @@
         controller.onStart();
 
         assertThat(shadowContentResolver.getContentObservers(
-            System.getUriFor(System.SCREEN_BRIGHTNESS_MODE))).isNotEmpty();
-        assertThat(shadowContentResolver.getContentObservers(
             System.getUriFor(System.SCREEN_BRIGHTNESS))).isNotEmpty();
         assertThat(shadowContentResolver.getContentObservers(
             System.getUriFor(System.SCREEN_BRIGHTNESS_FOR_VR))).isNotEmpty();
@@ -111,8 +109,6 @@
         controller.onStop();
 
         assertThat(shadowContentResolver.getContentObservers(
-            System.getUriFor(System.SCREEN_BRIGHTNESS_MODE))).isEmpty();
-        assertThat(shadowContentResolver.getContentObservers(
             System.getUriFor(System.SCREEN_BRIGHTNESS))).isEmpty();
         assertThat(shadowContentResolver.getContentObservers(
             System.getUriFor(System.SCREEN_BRIGHTNESS_FOR_VR))).isEmpty();
@@ -136,11 +132,11 @@
         System.putInt(mContentResolver, System.SCREEN_BRIGHTNESS_MODE,
             System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
 
-        System.putFloat(mContentResolver, System.SCREEN_AUTO_BRIGHTNESS_ADJ, 0.0f);
+        System.putInt(mContentResolver, System.SCREEN_BRIGHTNESS, 31);
 
         mController.updateState(mPreference);
 
-        verify(mPreference).setSummary("50%");
+        verify(mPreference).setSummary("31%");
     }
 
     @Test
@@ -175,11 +171,11 @@
                 System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
 
         reset(mPreference);
-        System.putFloat(mContentResolver, System.SCREEN_AUTO_BRIGHTNESS_ADJ, 1.5f);
+        System.putInt(mContentResolver, System.SCREEN_BRIGHTNESS, 115);
         mController.updateState(mPreference);
         verify(mPreference).setSummary("100%");
 
-        System.putFloat(mContentResolver, System.SCREEN_AUTO_BRIGHTNESS_ADJ, -1.5f);
+        System.putInt(mContentResolver, System.SCREEN_BRIGHTNESS, -10);
         mController.updateState(mPreference);
         verify(mPreference).setSummary("0%");
 
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryLegacyTest.java b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryLegacyTest.java
index 45448a9..e707ede 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryLegacyTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryLegacyTest.java
@@ -15,8 +15,8 @@
  */
 package com.android.settings.fuelgauge;
 
-import static com.android.settings.fuelgauge.PowerUsageSummary.MENU_HIGH_POWER_APPS;
-import static com.android.settings.fuelgauge.PowerUsageSummary.MENU_TOGGLE_APPS;
+import static com.android.settings.fuelgauge.PowerUsageSummaryLegacy.MENU_HIGH_POWER_APPS;
+import static com.android.settings.fuelgauge.PowerUsageSummaryLegacy.MENU_TOGGLE_APPS;
 import static com.google.common.truth.Truth.assertThat;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyInt;
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java
index 6fecf3c..35af8bb 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java
@@ -16,7 +16,6 @@
 package com.android.settings.fuelgauge;
 
 import static com.android.settings.fuelgauge.PowerUsageSummary.MENU_HIGH_POWER_APPS;
-import static com.android.settings.fuelgauge.PowerUsageSummary.MENU_TOGGLE_APPS;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -170,7 +169,6 @@
         doReturn(mock(LoaderManager.class)).when(mFragment).getLoaderManager();
 
         when(mFragment.getActivity()).thenReturn(mSettingsActivity);
-        when(mToggleAppsMenu.getItemId()).thenReturn(MENU_TOGGLE_APPS);
         when(mHighPowerMenu.getItemId()).thenReturn(MENU_HIGH_POWER_APPS);
         when(mFeatureFactory.powerUsageFeatureProvider.getAdditionalBatteryInfoIntent())
                 .thenReturn(sAdditionalBatteryInfoIntent);
@@ -215,39 +213,6 @@
     }
 
     @Test
-    public void testOptionsMenu_menuAppToggle_metricEventInvoked() {
-        mFragment.onOptionsItemSelected(mToggleAppsMenu);
-        mFragment.mShowAllApps = false;
-
-        verify(mFeatureFactory.metricsFeatureProvider).action(mContext,
-                MetricsProto.MetricsEvent.ACTION_SETTINGS_MENU_BATTERY_APPS_TOGGLE, true);
-    }
-
-    @Test
-    public void testOptionsMenu_toggleAppsEnabled() {
-        when(mFeatureFactory.powerUsageFeatureProvider.isPowerAccountingToggleEnabled())
-                .thenReturn(true);
-        mFragment.mShowAllApps = false;
-
-        mFragment.onCreateOptionsMenu(mMenu, mMenuInflater);
-
-        verify(mMenu).add(Menu.NONE, MENU_TOGGLE_APPS, Menu.NONE, R.string.show_all_apps);
-    }
-
-    @Test
-    public void testOptionsMenu_clickToggleAppsMenu_dataChanged() {
-        testToggleAllApps(true);
-        testToggleAllApps(false);
-    }
-
-    private void testToggleAllApps(final boolean isShowApps) {
-        mFragment.mShowAllApps = isShowApps;
-
-        mFragment.onOptionsItemSelected(mToggleAppsMenu);
-        assertThat(mFragment.mShowAllApps).isEqualTo(!isShowApps);
-    }
-
-    @Test
     public void testUpdateLastFullChargePreference_showCorrectSummary() {
         doReturn(mRealContext).when(mFragment).getContext();
 
@@ -324,18 +289,6 @@
     }
 
     @Test
-    public void testSaveInstanceState_showAllAppsRestored() {
-        Bundle bundle = new Bundle();
-        mFragment.mShowAllApps = true;
-        doReturn(mPreferenceScreen).when(mFragment).getPreferenceScreen();
-
-        mFragment.onSaveInstanceState(bundle);
-        mFragment.restoreSavedInstance(bundle);
-
-        assertThat(mFragment.mShowAllApps).isTrue();
-    }
-
-    @Test
     public void testDebugMode() {
         doReturn(true).when(mFeatureFactory.powerUsageFeatureProvider).isEstimateDebugEnabled();
 
diff --git a/tests/robotests/src/com/android/settings/location/RecentLocationRequestPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/location/RecentLocationRequestPreferenceControllerTest.java
index f114ff3..7f495ab 100644
--- a/tests/robotests/src/com/android/settings/location/RecentLocationRequestPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/location/RecentLocationRequestPreferenceControllerTest.java
@@ -33,14 +33,11 @@
 import android.support.v7.preference.PreferenceCategory;
 import android.support.v7.preference.PreferenceScreen;
 import android.text.TextUtils;
-import android.util.FeatureFlagUtils;
 
 import com.android.settings.R;
 import com.android.settings.SettingsActivity;
 import com.android.settings.TestConfig;
-import com.android.settings.applications.InstalledAppDetails;
 import com.android.settings.applications.appinfo.AppInfoDashboardFragment;
-import com.android.settings.core.FeatureFlags;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.widget.AppPreference;
 import com.android.settingslib.core.lifecycle.Lifecycle;
@@ -179,15 +176,9 @@
 
         preference.performClick();
 
-        if (FeatureFlagUtils.isEnabled(mContext, FeatureFlags.APP_INFO_V2)) {
-            verify(activity).startPreferencePanelAsUser(any(),
-                    eq(AppInfoDashboardFragment.class.getName()),
-                    any(Bundle.class), anyInt(), any(), any());
-        } else {
-            verify(activity).startPreferencePanelAsUser(any(),
-                    eq(InstalledAppDetails.class.getName()),
-                    any(Bundle.class), anyInt(), any(), any());
-        }
+        verify(activity).startPreferencePanelAsUser(any(),
+            eq(AppInfoDashboardFragment.class.getName()),
+            any(Bundle.class), anyInt(), any(), any());
     }
 
     private static ArgumentMatcher<Preference> titleMatches(String expected) {
diff --git a/tests/uitests/src/com/android/settings/ui/BatterySettingsUITest.java b/tests/uitests/src/com/android/settings/ui/BatterySettingsUITest.java
new file mode 100644
index 0000000..8b34fff
--- /dev/null
+++ b/tests/uitests/src/com/android/settings/ui/BatterySettingsUITest.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2018 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.ui;
+
+import android.content.Intent;
+import android.os.RemoteException;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.test.uiautomator.UiDevice;
+import android.system.helpers.SettingsHelper;
+
+import com.android.settings.ui.testutils.SettingsTestUtils;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@MediumTest
+@RunWith(AndroidJUnit4.class)
+public class BatterySettingsUITest {
+    // Items we really want to always show
+    private static final String[] CATEGORIES = new String[] {
+            "Battery Saver",
+            "Battery percentage",
+            "Battery usage data is approximate and can change based on usage",
+    };
+
+    private UiDevice mDevice;
+    private SettingsHelper mHelper;
+
+    @Before
+    public void setUp() throws Exception {
+        mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+        mHelper = SettingsHelper.getInstance();
+        try {
+            mDevice.setOrientationNatural();
+        } catch (RemoteException e) {
+            throw new RuntimeException("failed to freeze device orientaion", e);
+        }
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        // Go back to home for next test.
+        mDevice.pressHome();
+    }
+
+    @Test
+    public void launchSecuritySettings() throws Exception {
+        // Launch Settings
+        SettingsHelper.launchSettingsPage(
+                InstrumentationRegistry.getTargetContext(), Intent.ACTION_POWER_USAGE_SUMMARY);
+        mHelper.scrollVert(false);
+        for (String category : CATEGORIES) {
+            SettingsTestUtils.assertTitleMatch(mDevice, category);
+        }
+    }
+}
diff --git a/tests/uitests/src/com/android/settings/ui/WirelessNetworkSettingsAdditionalTests.java b/tests/uitests/src/com/android/settings/ui/MoreWirelessSettingsTest2.java
similarity index 99%
rename from tests/uitests/src/com/android/settings/ui/WirelessNetworkSettingsAdditionalTests.java
rename to tests/uitests/src/com/android/settings/ui/MoreWirelessSettingsTest2.java
index 4ed2a1d..971c7d7 100644
--- a/tests/uitests/src/com/android/settings/ui/WirelessNetworkSettingsAdditionalTests.java
+++ b/tests/uitests/src/com/android/settings/ui/MoreWirelessSettingsTest2.java
@@ -38,7 +38,7 @@
 /**
  * Additional tests for Wifi Settings.
  */
-public class WirelessNetworkSettingsAdditionalTests extends InstrumentationTestCase {
+public class MoreWirelessSettingsTest2 extends InstrumentationTestCase {
     // These back button presses are performed in tearDown() to exit Wifi
     // Settings sub-menus that a test might finish in. This number should be
     // high enough to account for the deepest sub-menu a test might enter.
diff --git a/tests/uitests/src/com/android/settings/ui/StorageSettingsUITest.java b/tests/uitests/src/com/android/settings/ui/StorageSettingsUITest.java
new file mode 100644
index 0000000..a301cc3
--- /dev/null
+++ b/tests/uitests/src/com/android/settings/ui/StorageSettingsUITest.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2018 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.ui;
+
+import android.os.RemoteException;
+import android.provider.Settings;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.test.uiautomator.UiDevice;
+import android.system.helpers.SettingsHelper;
+import android.test.suitebuilder.annotation.MediumTest;
+
+import com.android.settings.ui.testutils.SettingsTestUtils;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@MediumTest
+public class StorageSettingsUITest {
+
+    private static final String[] TITLES = {
+            "Photos & videos",
+            "Music & audio",
+            "Games",
+            "Movie & TV apps",
+            "Other apps",
+            "Files",
+            "System",
+    };
+    private UiDevice mDevice;
+    private SettingsHelper mHelper;
+
+
+    @Before
+    public void setUp() throws Exception {
+        mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+        mHelper = SettingsHelper.getInstance();
+
+        try {
+            mDevice.setOrientationNatural();
+        } catch (RemoteException e) {
+            throw new RuntimeException("failed to freeze device orientation", e);
+        }
+    }
+
+    @After
+    public void tearDown() {
+        mDevice.pressHome();
+    }
+
+    @Test
+    public void launchStorageSettings() throws Exception {
+        // Launch Settings
+        SettingsHelper.launchSettingsPage(
+                InstrumentationRegistry.getTargetContext(),
+                Settings.ACTION_INTERNAL_STORAGE_SETTINGS);
+        mHelper.scrollVert(false);
+        for (String category : TITLES) {
+            SettingsTestUtils.assertTitleMatch(mDevice, category);
+        }
+    }
+}
diff --git a/tests/uitests/src/com/android/settings/ui/WirelessNetworkSettingsTests.java b/tests/uitests/src/com/android/settings/ui/WirelessNetworkSettingsTests.java
index 64fa5fd..dd700ac 100644
--- a/tests/uitests/src/com/android/settings/ui/WirelessNetworkSettingsTests.java
+++ b/tests/uitests/src/com/android/settings/ui/WirelessNetworkSettingsTests.java
@@ -61,7 +61,6 @@
 
     @Before
     public void setUp() throws Exception {
-
         mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
         try {
             mDevice.setOrientationNatural();
diff --git a/tests/unit/src/com/android/settings/applications/PackageUtilTest.java b/tests/unit/src/com/android/settings/applications/PackageUtilTest.java
deleted file mode 100644
index 0e3c402..0000000
--- a/tests/unit/src/com/android/settings/applications/PackageUtilTest.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2016 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 android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.UserInfo;
-import android.os.UserManager;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import static junit.framework.Assert.assertEquals;
-import static org.mockito.Mockito.when;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-@Deprecated
-public class PackageUtilTest {
-    private static final String ALL_USERS_APP_NAME = "com.google.allusers.app";
-    private static final String ONE_USER_APP_NAME = "com.google.oneuser.app";
-    private static final int USER1_ID = 1;
-    private static final int USER2_ID = 11;
-
-    @Mock
-    private PackageManager mMockPackageManager;
-    @Mock
-    private UserManager mMockUserManager;
-
-    private InstalledAppDetails.PackageUtil mPackageUtil;
-    private List<UserInfo> mUserInfos;
-
-    @Before
-    public void setUp() throws PackageManager.NameNotFoundException {
-        MockitoAnnotations.initMocks(this);
-
-        mUserInfos = new ArrayList<>();
-        mUserInfos.add(new UserInfo(USER1_ID, "lei", 0));
-        mUserInfos.add(new UserInfo(USER2_ID, "yue", 0));
-        when(mMockUserManager.getUsers(true)).thenReturn(mUserInfos);
-
-        ApplicationInfo usersApp = new ApplicationInfo();
-        usersApp.flags = ApplicationInfo.FLAG_INSTALLED;
-
-        when(mMockPackageManager.getApplicationInfoAsUser(
-                ALL_USERS_APP_NAME, PackageManager.GET_META_DATA, USER1_ID))
-                .thenReturn(usersApp);
-        when(mMockPackageManager.getApplicationInfoAsUser(
-                ALL_USERS_APP_NAME, PackageManager.GET_META_DATA, USER2_ID))
-                .thenReturn(usersApp);
-
-        when(mMockPackageManager.getApplicationInfoAsUser(
-                ONE_USER_APP_NAME, PackageManager.GET_META_DATA, USER1_ID))
-                .thenReturn(usersApp);
-
-        when(mMockPackageManager.getApplicationInfoAsUser(
-                ONE_USER_APP_NAME, PackageManager.GET_META_DATA, USER2_ID))
-                .thenThrow(new PackageManager.NameNotFoundException());
-
-        mPackageUtil = new InstalledAppDetails.PackageUtil();
-    }
-
-    @Test
-    public void testCountPackageInUsers_twoUsersInstalled_returnTwo() {
-        assertEquals(2, mPackageUtil.countPackageInUsers(
-                mMockPackageManager, mMockUserManager, ALL_USERS_APP_NAME));
-    }
-
-    @Test
-    public void testCountPackageInUsers_oneUsersInstalled_returnOne() {
-        assertEquals(1, mPackageUtil.countPackageInUsers(
-                mMockPackageManager, mMockUserManager, ONE_USER_APP_NAME));
-    }
-}
