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/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/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/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));
-    }
-}
