diff --git a/src/com/android/settings/InstrumentedFragment.java b/src/com/android/settings/InstrumentedFragment.java
index 883c67c..d239d4e 100644
--- a/src/com/android/settings/InstrumentedFragment.java
+++ b/src/com/android/settings/InstrumentedFragment.java
@@ -28,6 +28,7 @@
 
     public static final int VIEW_CATEGORY_DEFAULT_APPS = VIEW_CATEGORY_UNDECLARED + 1;
     public static final int VIEW_CATEGORY_STORAGE_APPS = VIEW_CATEGORY_UNDECLARED + 2;
+    public static final int VIEW_CATEGORY_USAGE_ACCESS_DETAIL = VIEW_CATEGORY_UNDECLARED + 3;
 
     /**
      * Declare the view of this category.
diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java
index e8be34a..caf2491 100644
--- a/src/com/android/settings/SettingsActivity.java
+++ b/src/com/android/settings/SettingsActivity.java
@@ -76,6 +76,7 @@
 import com.android.settings.applications.InstalledAppDetails;
 import com.android.settings.applications.ManageApplications;
 import com.android.settings.applications.ProcessStatsUi;
+import com.android.settings.applications.UsageAccessDetails;
 import com.android.settings.bluetooth.BluetoothSettings;
 import com.android.settings.dashboard.DashboardCategory;
 import com.android.settings.dashboard.DashboardSummary;
@@ -300,7 +301,7 @@
             NotificationStation.class.getName(),
             LocationSettings.class.getName(),
             SecuritySettings.class.getName(),
-            UsageAccessSettings.class.getName(),
+            UsageAccessDetails.class.getName(),
             PrivacySettings.class.getName(),
             DeviceAdminSettings.class.getName(),
             AccessibilitySettings.class.getName(),
diff --git a/src/com/android/settings/UsageAccessSettings.java b/src/com/android/settings/UsageAccessSettings.java
deleted file mode 100644
index 704c3c5..0000000
--- a/src/com/android/settings/UsageAccessSettings.java
+++ /dev/null
@@ -1,569 +0,0 @@
-/*
- * Copyright (C) 2014 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;
-
-import com.android.internal.content.PackageMonitor;
-import android.Manifest;
-import android.app.ActivityThread;
-import android.app.AlertDialog;
-import android.app.AppOpsManager;
-import android.app.Dialog;
-import android.app.DialogFragment;
-import android.app.Fragment;
-import android.app.FragmentTransaction;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.IPackageManager;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.os.Looper;
-import android.os.RemoteException;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.preference.Preference;
-import android.preference.PreferenceScreen;
-import android.preference.SwitchPreference;
-import android.util.ArrayMap;
-import android.util.Log;
-import android.util.SparseArray;
-import com.android.internal.logging.MetricsLogger;
-
-import java.util.List;
-import java.util.Collections;
-
-public class UsageAccessSettings extends SettingsPreferenceFragment implements
-        Preference.OnPreferenceChangeListener {
-
-    private static final String TAG = "UsageAccessSettings";
-    private static final String BUNDLE_KEY_PROFILEID = "profileId";
-
-    private static final String[] PM_USAGE_STATS_PERMISSION = new String[] {
-            Manifest.permission.PACKAGE_USAGE_STATS
-    };
-
-    private static final int[] APP_OPS_OP_CODES = new int[] {
-            AppOpsManager.OP_GET_USAGE_STATS
-    };
-
-    private static class PackageEntry implements Comparable<PackageEntry> {
-        public PackageEntry(String packageName, UserHandle userHandle) {
-            this.packageName = packageName;
-            this.appOpMode = AppOpsManager.MODE_DEFAULT;
-            this.userHandle = userHandle;
-        }
-
-        @Override
-        public int compareTo(PackageEntry another) {
-            return packageName.compareTo(another.packageName);
-        }
-
-        final String packageName;
-        PackageInfo packageInfo;
-        boolean permissionGranted;
-        int appOpMode;
-        UserHandle userHandle;
-
-        SwitchPreference preference;
-    }
-
-    /**
-     * Fetches the list of Apps that are requesting access to the UsageStats API and updates
-     * the PreferenceScreen with the results when complete.
-     */
-    private class AppsRequestingAccessFetcher extends
-            AsyncTask<Void, Void, SparseArray<ArrayMap<String, PackageEntry>>> {
-
-        private final Context mContext;
-        private final PackageManager mPackageManager;
-        private final IPackageManager mIPackageManager;
-        private final UserManager mUserManager;
-        private final List<UserHandle> mProfiles;
-
-        public AppsRequestingAccessFetcher(Context context) {
-            mContext = context;
-            mPackageManager = context.getPackageManager();
-            mIPackageManager = ActivityThread.getPackageManager();
-            mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
-            mProfiles = mUserManager.getUserProfiles();
-        }
-
-        @Override
-        protected SparseArray<ArrayMap<String, PackageEntry>> doInBackground(Void... params) {
-            final String[] packages;
-            SparseArray<ArrayMap<String, PackageEntry>> entries;
-            try {
-                packages = mIPackageManager.getAppOpPermissionPackages(
-                        Manifest.permission.PACKAGE_USAGE_STATS);
-
-                if (packages == null) {
-                    // No packages are requesting permission to use the UsageStats API.
-                    return null;
-                }
-
-                entries = new SparseArray<>();
-                for (final UserHandle profile : mProfiles) {
-                    final ArrayMap<String, PackageEntry> entriesForProfile = new ArrayMap<>();
-                    final int profileId = profile.getIdentifier();
-                    entries.put(profileId, entriesForProfile);
-                    for (final String packageName : packages) {
-                        final boolean isAvailable = mIPackageManager.isPackageAvailable(packageName,
-                                profileId);
-                        if (!shouldIgnorePackage(packageName) && isAvailable) {
-                            final PackageEntry newEntry = new PackageEntry(packageName, profile);
-                            entriesForProfile.put(packageName, newEntry);
-                        }
-                    }
-                }
-            } catch (RemoteException e) {
-                Log.w(TAG, "PackageManager is dead. Can't get list of packages requesting "
-                        + Manifest.permission.PACKAGE_USAGE_STATS);
-                return null;
-            }
-
-             // Load the packages that have been granted the PACKAGE_USAGE_STATS permission.
-            try {
-                for (final UserHandle profile : mProfiles) {
-                    final int profileId = profile.getIdentifier();
-                    final ArrayMap<String, PackageEntry> entriesForProfile = entries.get(profileId);
-                    if (entriesForProfile == null) {
-                        continue;
-                    }
-                    final List<PackageInfo> packageInfos = mIPackageManager
-                            .getPackagesHoldingPermissions(PM_USAGE_STATS_PERMISSION, 0, profileId)
-                            .getList();
-                    final int packageInfoCount = packageInfos != null ? packageInfos.size() : 0;
-                    for (int i = 0; i < packageInfoCount; i++) {
-                        final PackageInfo packageInfo = packageInfos.get(i);
-                        final PackageEntry pe = entriesForProfile.get(packageInfo.packageName);
-                        if (pe != null) {
-                            pe.packageInfo = packageInfo;
-                            pe.permissionGranted = true;
-                        }
-                    }
-                }
-            } catch (RemoteException e) {
-                Log.w(TAG, "PackageManager is dead. Can't get list of packages granted "
-                        + Manifest.permission.PACKAGE_USAGE_STATS);
-                return null;
-            }
-
-            // Load the remaining packages that have requested but don't have the
-            // PACKAGE_USAGE_STATS permission.
-            for (final UserHandle profile : mProfiles) {
-                final int profileId = profile.getIdentifier();
-                final ArrayMap<String, PackageEntry> entriesForProfile = entries.get(profileId);
-                if (entriesForProfile == null) {
-                    continue;
-                }
-                int packageCount = entriesForProfile.size();
-                for (int i = packageCount - 1; i >= 0; --i) {
-                    final PackageEntry pe = entriesForProfile.valueAt(i);
-                    if (pe.packageInfo == null) {
-                        try {
-                            pe.packageInfo = mIPackageManager.getPackageInfo(pe.packageName, 0,
-                                    profileId);
-                        } catch (RemoteException e) {
-                            // This package doesn't exist. This may occur when an app is
-                            // uninstalled for one user, but it is not removed from the system.
-                            entriesForProfile.removeAt(i);
-                        }
-                    }
-                }
-            }
-
-            // Find out which packages have been granted permission from AppOps.
-            final List<AppOpsManager.PackageOps> packageOps = mAppOpsManager.getPackagesForOps(
-                    APP_OPS_OP_CODES);
-            final int packageOpsCount = packageOps != null ? packageOps.size() : 0;
-            for (int i = 0; i < packageOpsCount; i++) {
-                final AppOpsManager.PackageOps packageOp = packageOps.get(i);
-                final int userId = UserHandle.getUserId(packageOp.getUid());
-                if (!isThisUserAProfileOfCurrentUser(userId)) {
-                    // This AppOp does not belong to any of this user's profiles.
-                    continue;
-                }
-
-                final ArrayMap<String, PackageEntry> entriesForProfile = entries.get(userId);
-                if (entriesForProfile == null) {
-                    continue;
-                }
-                final PackageEntry pe = entriesForProfile.get(packageOp.getPackageName());
-                if (pe == null) {
-                    Log.w(TAG, "AppOp permission exists for package " + packageOp.getPackageName()
-                            + " of user " + userId +
-                            " but package doesn't exist or did not request UsageStats access");
-                    continue;
-                }
-
-                if (packageOp.getOps().size() < 1) {
-                    Log.w(TAG, "No AppOps permission exists for package "
-                            + packageOp.getPackageName());
-                    continue;
-                }
-
-                pe.appOpMode = packageOp.getOps().get(0).getMode();
-            }
-
-            return entries;
-        }
-
-        @Override
-        protected void onPostExecute(SparseArray<ArrayMap<String, PackageEntry>> newEntries) {
-            mLastFetcherTask = null;
-
-            if (getActivity() == null) {
-                // We must have finished the Activity while we were processing in the background.
-                return;
-            }
-
-            if (newEntries == null) {
-                mPackageEntryMap.clear();
-                mPreferenceScreen.removeAll();
-                return;
-            }
-
-            // Find the deleted entries and remove them from the PreferenceScreen.
-            final int oldProfileCount = mPackageEntryMap.size();
-            for (int profileIndex = 0; profileIndex < oldProfileCount; ++profileIndex) {
-                final int profileId = mPackageEntryMap.keyAt(profileIndex);
-                final ArrayMap<String, PackageEntry> oldEntriesForProfile = mPackageEntryMap
-                        .valueAt(profileIndex);
-                final int oldPackageCount = oldEntriesForProfile.size();
-
-                final ArrayMap<String, PackageEntry> newEntriesForProfile = newEntries.get(
-                        profileId);
-
-                for (int i = 0; i < oldPackageCount; i++) {
-                    final PackageEntry oldPackageEntry = oldEntriesForProfile.valueAt(i);
-
-                    PackageEntry newPackageEntry = null;
-                    if (newEntriesForProfile != null) {
-                        newPackageEntry = newEntriesForProfile.get(oldPackageEntry.packageName);
-                    }
-                    if (newPackageEntry == null) {
-                        // This package has been removed.
-                        mPreferenceScreen.removePreference(oldPackageEntry.preference);
-                    } else {
-                        // This package already exists in the preference hierarchy, so reuse that
-                        // Preference.
-                        newPackageEntry.preference = oldPackageEntry.preference;
-                    }
-                }
-            }
-
-            // Now add new packages to the PreferenceScreen.
-            final int newProfileCount = newEntries.size();
-            for (int profileIndex = 0; profileIndex < newProfileCount; ++profileIndex) {
-                final int profileId = newEntries.keyAt(profileIndex);
-                final ArrayMap<String, PackageEntry> newEntriesForProfile = newEntries.get(
-                        profileId);
-                final int packageCount = newEntriesForProfile.size();
-                for (int i = 0; i < packageCount; i++) {
-                    final PackageEntry packageEntry = newEntriesForProfile.valueAt(i);
-                    if (packageEntry.preference == null) {
-                        packageEntry.preference = new SwitchPreference(mContext);
-                        packageEntry.preference.setPersistent(false);
-                        packageEntry.preference.setOnPreferenceChangeListener(
-                                UsageAccessSettings.this);
-                        mPreferenceScreen.addPreference(packageEntry.preference);
-                    }
-                    updatePreference(packageEntry);
-                }
-            }
-            mPackageEntryMap.clear();
-            mPackageEntryMap = newEntries;
-
-            // Add/remove headers if necessary. If there are package entries only for one user and
-            // that user is not the managed profile then do not show headers.
-            if (mPackageEntryMap.size() == 1 &&
-                    mPackageEntryMap.keyAt(0) == UserHandle.myUserId()) {
-                for (int i = 0; i < mCategoryHeaders.length; ++i) {
-                    if (mCategoryHeaders[i] != null) {
-                        mPreferenceScreen.removePreference(mCategoryHeaders[i]);
-                    }
-                    mCategoryHeaders[i] = null;
-                }
-            } else {
-                for (int i = 0; i < mCategoryHeaders.length; ++i) {
-                    if (mCategoryHeaders[i] == null) {
-                        final Preference preference = new Preference(mContext, null,
-                                com.android.internal.R.attr.preferenceCategoryStyle, 0);
-                        mCategoryHeaders[i] = preference;
-                        preference.setTitle(mCategoryHeaderTitleResIds[i]);
-                        preference.setEnabled(false);
-                        mPreferenceScreen.addPreference(preference);
-                    }
-                }
-            }
-
-            // Sort preferences alphabetically within categories
-            int order = 0;
-            final int profileCount = mProfiles.size();
-            for (int i = 0; i < profileCount; ++i) {
-                Preference header = mCategoryHeaders[i];
-                if (header != null) {
-                    header.setOrder(order++);
-                }
-                ArrayMap<String, PackageEntry> entriesForProfile =
-                        mPackageEntryMap.get(mProfiles.get(i).getIdentifier());
-                if (entriesForProfile != null) {
-                    List<PackageEntry> sortedEntries = Collections.list(
-                            Collections.enumeration(entriesForProfile.values()));
-                    Collections.sort(sortedEntries);
-                    for (PackageEntry pe : sortedEntries) {
-                        pe.preference.setOrder(order++);
-                    }
-                }
-            }
-        }
-
-        private void updatePreference(PackageEntry pe) {
-            final int profileId = pe.userHandle.getIdentifier();
-            // Set something as default
-            pe.preference.setEnabled(false);
-            pe.preference.setTitle(pe.packageName);
-            pe.preference.setIcon(mUserManager.getBadgedIconForUser(mPackageManager
-                    .getDefaultActivityIcon(), pe.userHandle));
-            try {
-                // Try setting real title and icon
-                final ApplicationInfo info = mIPackageManager.getApplicationInfo(pe.packageName,
-                        0 /* no flags */, profileId);
-                if (info != null) {
-                    pe.preference.setEnabled(true);
-                    pe.preference.setTitle(info.loadLabel(mPackageManager).toString());
-                    pe.preference.setIcon(mUserManager.getBadgedIconForUser(info.loadIcon(
-                            mPackageManager), pe.userHandle));
-                }
-            } catch (RemoteException e) {
-                Log.w(TAG, "PackageManager is dead. Can't get app info for package " +
-                        pe.packageName + " of user " + profileId);
-                // Keep going to update other parts of the preference
-            }
-
-            pe.preference.setKey(pe.packageName);
-            Bundle extra = pe.preference.getExtras();
-            extra.putInt(BUNDLE_KEY_PROFILEID, profileId);
-
-            boolean check = false;
-            if (pe.appOpMode == AppOpsManager.MODE_ALLOWED) {
-                check = true;
-            } else if (pe.appOpMode == AppOpsManager.MODE_DEFAULT) {
-                // If the default AppOps mode is set, then fall back to
-                // whether the app has been granted permission by PackageManager.
-                check = pe.permissionGranted;
-            }
-
-            if (check != pe.preference.isChecked()) {
-                pe.preference.setChecked(check);
-            }
-        }
-
-        private boolean isThisUserAProfileOfCurrentUser(final int userId) {
-            final int profilesMax = mProfiles.size();
-            for (int i = 0; i < profilesMax; ++i) {
-                if (mProfiles.get(i).getIdentifier() == userId) {
-                    return true;
-                }
-            }
-            return false;
-        }
-    }
-
-    static boolean shouldIgnorePackage(String packageName) {
-        return packageName.equals("android") || packageName.equals("com.android.settings");
-    }
-
-    private AppsRequestingAccessFetcher mLastFetcherTask;
-    SparseArray<ArrayMap<String, PackageEntry>> mPackageEntryMap = new SparseArray<>();
-    AppOpsManager mAppOpsManager;
-    PreferenceScreen mPreferenceScreen;
-    private Preference[] mCategoryHeaders = new Preference[2];
-    private static int[] mCategoryHeaderTitleResIds = new int[] {
-        R.string.category_personal,
-        R.string.category_work
-    };
-
-    @Override
-    protected int getMetricsCategory() {
-        return MetricsLogger.USAGE_ACCESS;
-    }
-
-    @Override
-    public void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-
-        addPreferencesFromResource(R.xml.usage_access_settings);
-        mPreferenceScreen = getPreferenceScreen();
-        mPreferenceScreen.setOrderingAsAdded(false);
-        mAppOpsManager = (AppOpsManager) getSystemService(Context.APP_OPS_SERVICE);
-    }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-
-        updateInterestedApps();
-        mPackageMonitor.register(getActivity(), Looper.getMainLooper(), false);
-    }
-
-    @Override
-    public void onPause() {
-        super.onPause();
-
-        mPackageMonitor.unregister();
-        if (mLastFetcherTask != null) {
-            mLastFetcherTask.cancel(true);
-            mLastFetcherTask = null;
-        }
-    }
-
-    private void updateInterestedApps() {
-        if (mLastFetcherTask != null) {
-            // Canceling can only fail for some obscure reason since mLastFetcherTask would be
-            // null if the task has already completed. So we ignore the result of cancel and
-            // spawn a new task to get fresh data. AsyncTask executes tasks serially anyways,
-            // so we are safe from running two tasks at the same time.
-            mLastFetcherTask.cancel(true);
-        }
-
-        mLastFetcherTask = new AppsRequestingAccessFetcher(getActivity());
-        mLastFetcherTask.execute();
-    }
-
-    @Override
-    public boolean onPreferenceChange(Preference preference, Object newValue) {
-        final String packageName = preference.getKey();
-        final int profileId = preference.getExtras().getInt(BUNDLE_KEY_PROFILEID);
-        final PackageEntry pe = getPackageEntry(packageName, profileId);
-        if (pe == null) {
-            Log.w(TAG, "Preference change event handling failed");
-            return false;
-        }
-
-        if (!(newValue instanceof Boolean)) {
-            Log.w(TAG, "Preference change event for package " + packageName + " of user " +
-                    profileId + " had non boolean value of type " + newValue.getClass().getName());
-            return false;
-        }
-
-        final int newMode = (Boolean) newValue ?
-                AppOpsManager.MODE_ALLOWED : AppOpsManager.MODE_IGNORED;
-
-        // Check if we need to do any work.
-        if (pe.appOpMode != newMode) {
-            if (newMode != AppOpsManager.MODE_ALLOWED) {
-                // Turning off the setting has no warning.
-                setNewMode(pe, newMode);
-                return true;
-            }
-
-            // Turning on the setting has a Warning.
-            FragmentTransaction ft = getChildFragmentManager().beginTransaction();
-            Fragment prev = getChildFragmentManager().findFragmentByTag("warning");
-            if (prev != null) {
-                ft.remove(prev);
-            }
-            WarningDialogFragment.newInstance(pe).show(ft, "warning");
-            return false;
-        }
-        return true;
-    }
-
-    void setNewMode(PackageEntry pe, int newMode) {
-        mAppOpsManager.setMode(AppOpsManager.OP_GET_USAGE_STATS,
-        pe.packageInfo.applicationInfo.uid, pe.packageName, newMode);
-        pe.appOpMode = newMode;
-    }
-
-    void allowAccess(String packageName, int profileId) {
-        final PackageEntry entry = getPackageEntry(packageName, profileId);
-        if (entry == null) {
-            Log.w(TAG, "Unable to give access");
-            return;
-        }
-
-        setNewMode(entry, AppOpsManager.MODE_ALLOWED);
-        entry.preference.setChecked(true);
-    }
-
-    private PackageEntry getPackageEntry(String packageName, int profileId) {
-        ArrayMap<String, PackageEntry> entriesForProfile = mPackageEntryMap.get(profileId);
-        if (entriesForProfile == null) {
-            Log.w(TAG, "getPackageEntry fails for package " + packageName + " of user " +
-                    profileId + ": user does not seem to be valid.");
-            return null;
-        }
-        final PackageEntry entry = entriesForProfile.get(packageName);
-        if (entry == null) {
-            Log.w(TAG, "getPackageEntry fails for package " + packageName + " of user " +
-                    profileId + ": package does not exist.");
-        }
-        return entry;
-    }
-
-    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
-        @Override
-        public void onPackageAdded(String packageName, int uid) {
-            updateInterestedApps();
-        }
-
-        @Override
-        public void onPackageRemoved(String packageName, int uid) {
-            updateInterestedApps();
-        }
-    };
-
-    public static class WarningDialogFragment extends DialogFragment
-            implements DialogInterface.OnClickListener {
-        private static final String ARG_PACKAGE_NAME = "package";
-        private static final String ARG_PROFILE_ID = "profileId";
-
-        public static WarningDialogFragment newInstance(PackageEntry pe) {
-            WarningDialogFragment dialog = new WarningDialogFragment();
-            Bundle args = new Bundle();
-            args.putString(ARG_PACKAGE_NAME, pe.packageName);
-            args.putInt(ARG_PROFILE_ID, pe.userHandle.getIdentifier());
-            dialog.setArguments(args);
-            return dialog;
-        }
-
-        @Override
-        public Dialog onCreateDialog(Bundle savedInstanceState) {
-            return new AlertDialog.Builder(getActivity())
-                    .setTitle(R.string.allow_usage_access_title)
-                    .setMessage(R.string.allow_usage_access_message)
-                    .setIconAttribute(android.R.attr.alertDialogIcon)
-                    .setNegativeButton(R.string.cancel, this)
-                    .setPositiveButton(android.R.string.ok, this)
-                    .create();
-        }
-
-        @Override
-        public void onClick(DialogInterface dialog, int which) {
-            if (which == DialogInterface.BUTTON_POSITIVE) {
-                ((UsageAccessSettings) getParentFragment()).allowAccess(
-                        getArguments().getString(ARG_PACKAGE_NAME),
-                        getArguments().getInt(ARG_PROFILE_ID));
-            } else {
-                dialog.cancel();
-            }
-        }
-    }
-}
diff --git a/src/com/android/settings/applications/AppInfoBase.java b/src/com/android/settings/applications/AppInfoBase.java
index a7dc500..56fe885 100644
--- a/src/com/android/settings/applications/AppInfoBase.java
+++ b/src/com/android/settings/applications/AppInfoBase.java
@@ -32,7 +32,6 @@
 import android.os.ServiceManager;
 import android.os.UserHandle;
 import android.os.UserManager;
-import android.preference.PreferenceFragment;
 import android.util.Log;
 
 import com.android.settings.InstrumentedPreferenceFragment;
diff --git a/src/com/android/settings/applications/AppStateBaseBridge.java b/src/com/android/settings/applications/AppStateBaseBridge.java
new file mode 100644
index 0000000..04eb77b
--- /dev/null
+++ b/src/com/android/settings/applications/AppStateBaseBridge.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2015 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.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+
+import com.android.settings.applications.ApplicationsState.AppEntry;
+import com.android.settings.applications.ApplicationsState.Session;
+
+import java.util.ArrayList;
+
+/**
+ * Common base class for bridging information to ApplicationsState.
+ */
+public abstract class AppStateBaseBridge implements ApplicationsState.Callbacks {
+
+    protected final ApplicationsState mAppState;
+    protected final Session mAppSession;
+    protected final Callback mCallback;
+    protected final BackgroundHandler mHandler;
+    protected final MainHandler mMainHandler;
+
+    public AppStateBaseBridge(ApplicationsState appState, Callback callback) {
+        mAppState = appState;
+        mAppSession = mAppState != null ? mAppState.newSession(this) : null;
+        mCallback = callback;
+        // Running on the same background thread as the ApplicationsState lets
+        // us run in the background and make sure they aren't doing updates at
+        // the same time as us as well.
+        mHandler = new BackgroundHandler(mAppState.getBackgroundLooper());
+        mMainHandler = new MainHandler();
+    }
+
+    public void resume() {
+        mHandler.sendEmptyMessage(BackgroundHandler.MSG_LOAD_ALL);
+        mAppSession.resume();
+    }
+
+    public void pause() {
+        mAppSession.pause();
+    }
+
+    public void release() {
+        mAppSession.release();
+    }
+
+    public void forceUpdate(String pkg, int uid) {
+        mHandler.obtainMessage(BackgroundHandler.MSG_FORCE_LOAD_PKG, uid, 0, pkg).sendToTarget();
+    }
+
+    @Override
+    public void onPackageListChanged() {
+        mHandler.sendEmptyMessage(BackgroundHandler.MSG_LOAD_ALL);
+    }
+
+    @Override
+    public void onLoadEntriesCompleted() {
+        mHandler.sendEmptyMessage(BackgroundHandler.MSG_LOAD_ALL);
+    }
+
+    @Override
+    public void onRunningStateChanged(boolean running) {
+        // No op.
+    }
+
+    @Override
+    public void onRebuildComplete(ArrayList<AppEntry> apps) {
+        // No op.
+    }
+
+    @Override
+    public void onPackageIconChanged() {
+        // No op.
+    }
+
+    @Override
+    public void onPackageSizeChanged(String packageName) {
+        // No op.
+    }
+
+    @Override
+    public void onAllSizesComputed() {
+        // No op.
+    }
+
+    @Override
+    public void onLauncherInfoChanged() {
+        // No op.
+    }
+
+    protected abstract void loadAllExtraInfo();
+    protected abstract void updateExtraInfo(AppEntry app, String pkg, int uid);
+
+    private class MainHandler extends Handler {
+        private static final int MSG_INFO_UPDATED = 1;
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_INFO_UPDATED:
+                    mCallback.onExtraInfoUpdated();
+                    break;
+            }
+        }
+    }
+
+    private class BackgroundHandler extends Handler {
+        private static final int MSG_LOAD_ALL = 1;
+        private static final int MSG_FORCE_LOAD_PKG = 2;
+
+        public BackgroundHandler(Looper looper) {
+            super(looper);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_LOAD_ALL:
+                    loadAllExtraInfo();
+                    mMainHandler.sendEmptyMessage(MainHandler.MSG_INFO_UPDATED);
+                    break;
+                case MSG_FORCE_LOAD_PKG:
+                    ArrayList<AppEntry> apps = mAppSession.getAllApps();
+                    final int N = apps.size();
+                    String pkg = (String) msg.obj;
+                    int uid = msg.arg1;
+                    for (int i = 0; i < N; i++) {
+                        AppEntry app = apps.get(i);
+                        if (app.info.uid == uid && pkg.equals(app.info.packageName)) {
+                            updateExtraInfo(app, pkg, uid);
+                        }
+                    }
+                    mMainHandler.sendEmptyMessage(MainHandler.MSG_INFO_UPDATED);
+                    break;
+            }
+        }
+    }
+
+
+    public interface Callback {
+        void onExtraInfoUpdated();
+    }
+}
diff --git a/src/com/android/settings/applications/AppStateNotificationBridge.java b/src/com/android/settings/applications/AppStateNotificationBridge.java
index 0434c0e..1aa7ebf 100644
--- a/src/com/android/settings/applications/AppStateNotificationBridge.java
+++ b/src/com/android/settings/applications/AppStateNotificationBridge.java
@@ -16,156 +16,43 @@
 package com.android.settings.applications;
 
 import android.content.pm.PackageManager;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
 
 import com.android.settings.applications.ApplicationsState.AppEntry;
 import com.android.settings.applications.ApplicationsState.AppFilter;
-import com.android.settings.applications.ApplicationsState.Session;
 import com.android.settings.notification.NotificationBackend;
 import com.android.settings.notification.NotificationBackend.AppRow;
 
 import java.util.ArrayList;
-import java.util.List;
 
 /**
  * Connects the info provided by ApplicationsState and the NotificationBackend.
  * Also provides app filters that can use the notification data.
  */
-public class AppStateNotificationBridge implements ApplicationsState.Callbacks {
+public class AppStateNotificationBridge extends AppStateBaseBridge {
 
-    private final ApplicationsState mAppState;
     private final NotificationBackend mNotifBackend;
-    private final Session mAppSession;
-    private final Callback mCallback;
-    private final BackgroundHandler mHandler;
-    private final MainHandler mMainHandler;
     private final PackageManager mPm;
 
     public AppStateNotificationBridge(PackageManager pm, ApplicationsState appState,
-            NotificationBackend notifBackend, Callback callback) {
-        mAppState = appState;
+            Callback callback, NotificationBackend notifBackend) {
+        super(appState, callback);
         mPm = pm;
-        mAppSession = mAppState.newSession(this);
         mNotifBackend = notifBackend;
-        mCallback = callback;
-        // Running on the same background thread as the ApplicationsState lets
-        // us run in the background and make sure they aren't doing updates at
-        // the same time as us as well.
-        mHandler = new BackgroundHandler(mAppState.getBackgroundLooper());
-        mMainHandler = new MainHandler();
-        mHandler.sendEmptyMessage(BackgroundHandler.MSG_LOAD_ALL);
-    }
-
-    public void resume() {
-        mHandler.sendEmptyMessage(BackgroundHandler.MSG_LOAD_ALL);
-        mAppSession.resume();
-    }
-
-    public void pause() {
-        mAppSession.pause();
-    }
-
-    public void release() {
-        mAppSession.release();
-    }
-
-    public void forceUpdate(String pkg, int uid) {
-        mHandler.obtainMessage(BackgroundHandler.MSG_FORCE_LOAD_PKG, uid, 0, pkg).sendToTarget();
     }
 
     @Override
-    public void onPackageListChanged() {
-        mHandler.sendEmptyMessage(BackgroundHandler.MSG_LOAD_ALL);
-    }
-
-    @Override
-    public void onLoadEntriesCompleted() {
-        mHandler.sendEmptyMessage(BackgroundHandler.MSG_LOAD_ALL);
-    }
-
-    @Override
-    public void onRunningStateChanged(boolean running) {
-        // No op.
-    }
-
-    @Override
-    public void onRebuildComplete(ArrayList<AppEntry> apps) {
-        // No op.
-    }
-
-    @Override
-    public void onPackageIconChanged() {
-        // No op.
-    }
-
-    @Override
-    public void onPackageSizeChanged(String packageName) {
-        // No op.
-    }
-
-    @Override
-    public void onAllSizesComputed() {
-        // No op.
-    }
-
-    @Override
-    public void onLauncherInfoChanged() {
-        // No op.
-    }
-
-    private class MainHandler extends Handler {
-        private static final int MSG_NOTIF_UPDATED = 1;
-
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case MSG_NOTIF_UPDATED:
-                    mCallback.onNotificationInfoUpdated();
-                    break;
-            }
+    protected void loadAllExtraInfo() {
+        ArrayList<AppEntry> apps = mAppSession.getAllApps();
+        final int N = apps.size();
+        for (int i = 0; i < N; i++) {
+            AppEntry app = apps.get(i);
+            app.extraInfo = mNotifBackend.loadAppRow(mPm, app.info);
         }
     }
 
-    private class BackgroundHandler extends Handler {
-        private static final int MSG_LOAD_ALL = 1;
-        private static final int MSG_FORCE_LOAD_PKG = 2;
-
-        public BackgroundHandler(Looper looper) {
-            super(looper);
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            List<AppEntry> apps = mAppSession.getAllApps();
-            final int N = apps.size();
-            switch (msg.what) {
-                case MSG_LOAD_ALL:
-                    for (int i = 0; i < N; i++) {
-                        AppEntry app = apps.get(i);
-                        app.extraInfo = mNotifBackend.loadAppRow(mPm, app.info);
-                    }
-                    mMainHandler.sendEmptyMessage(MainHandler.MSG_NOTIF_UPDATED);
-                    break;
-                case MSG_FORCE_LOAD_PKG:
-                    String pkg = (String) msg.obj;
-                    int uid = msg.arg1;
-                    for (int i = 0; i < N; i++) {
-                        AppEntry app = apps.get(i);
-                        if (app.info.uid == uid && pkg.equals(app.info.packageName)) {
-                            app.extraInfo = mNotifBackend.loadAppRow(mPm, app.info);
-                            break;
-                        }
-                    }
-                    mMainHandler.sendEmptyMessage(MainHandler.MSG_NOTIF_UPDATED);
-                    break;
-            }
-        }
-    }
-
-    public interface Callback {
-        void onNotificationInfoUpdated();
+    @Override
+    protected void updateExtraInfo(AppEntry app, String pkg, int uid) {
+        app.extraInfo = mNotifBackend.loadAppRow(mPm, app.info);
     }
 
     public static final AppFilter FILTER_APP_NOTIFICATION_BLOCKED = new AppFilter() {
diff --git a/src/com/android/settings/applications/AppStateUsageBridge.java b/src/com/android/settings/applications/AppStateUsageBridge.java
new file mode 100644
index 0000000..22f19b2
--- /dev/null
+++ b/src/com/android/settings/applications/AppStateUsageBridge.java
@@ -0,0 +1,265 @@
+/*
+ * Copyright (C) 2015 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.Manifest;
+import android.app.AppGlobals;
+import android.app.AppOpsManager;
+import android.app.AppOpsManager.PackageOps;
+import android.content.Context;
+import android.content.pm.IPackageManager;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.util.ArrayMap;
+import android.util.Log;
+import android.util.SparseArray;
+
+import com.android.settings.applications.ApplicationsState.AppEntry;
+import com.android.settings.applications.ApplicationsState.AppFilter;
+
+import java.util.List;
+
+/*
+ * Connects app usage info to the ApplicationsState.
+ * Also provides app filters that can use the info.
+ */
+public class AppStateUsageBridge extends AppStateBaseBridge {
+
+    private static final String TAG = "AppStateUsageBridge";
+
+    private static final String[] PM_USAGE_STATS_PERMISSION = {
+            Manifest.permission.PACKAGE_USAGE_STATS
+    };
+
+    private static final int[] APP_OPS_OP_CODES = {
+            AppOpsManager.OP_GET_USAGE_STATS
+    };
+
+    private final IPackageManager mIPackageManager;
+    private final UserManager mUserManager;
+    private final List<UserHandle> mProfiles;
+    private final AppOpsManager mAppOpsManager;
+    private final Context mContext;
+
+    public AppStateUsageBridge(Context context, ApplicationsState appState, Callback callback) {
+        super(appState, callback);
+        mContext = context;
+        mIPackageManager = AppGlobals.getPackageManager();
+        mUserManager = UserManager.get(context);
+        mProfiles = mUserManager.getUserProfiles();
+        mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
+    }
+
+    private boolean isThisUserAProfileOfCurrentUser(final int userId) {
+        final int profilesMax = mProfiles.size();
+        for (int i = 0; i < profilesMax; i++) {
+            if (mProfiles.get(i).getIdentifier() == userId) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    protected void updateExtraInfo(AppEntry app, String pkg, int uid) {
+        app.extraInfo = getUsageInfo(pkg, uid);
+    }
+
+    public UsageState getUsageInfo(String pkg, int uid) {
+        UsageState usageState = new UsageState(pkg, new UserHandle(UserHandle.getUserId(uid)));
+        try {
+            usageState.packageInfo = mIPackageManager.getPackageInfo(pkg,
+                    PackageManager.GET_PERMISSIONS, usageState.userHandle.getIdentifier());
+            // Check permission state.
+            String[] requestedPermissions = usageState.packageInfo.requestedPermissions;
+            int[] permissionFlags = usageState.packageInfo.requestedPermissionsFlags;
+            if (requestedPermissions != null) {
+                for (int i = 0; i < requestedPermissions.length; i++) {
+                    if (Manifest.permission.PACKAGE_USAGE_STATS.equals(requestedPermissions[i])
+                            && (permissionFlags[i] & PackageInfo.REQUESTED_PERMISSION_GRANTED)
+                            != 0) {
+                        usageState.permissionGranted = true;
+                        break;
+                    }
+                }
+            }
+            // Check app op state.
+            List<PackageOps> ops = mAppOpsManager.getOpsForPackage(uid, pkg, APP_OPS_OP_CODES);
+            if (ops != null && ops.size() > 0 && ops.get(0).getOps().size() > 0) {
+                usageState.appOpMode = ops.get(0).getOps().get(0).getMode();
+            }
+        } catch (RemoteException e) {
+            Log.w(TAG, "PackageManager is dead. Can't get package info " + pkg, e);
+        }
+        return usageState;
+    }
+
+    @Override
+    protected void loadAllExtraInfo() {
+        SparseArray<ArrayMap<String, UsageState>> entries = getEntries();
+
+        // Load state info.
+        loadPermissionsStates(entries);
+        loadAppOpsStates(entries);
+
+        // Map states to application info.
+        List<AppEntry> apps = mAppSession.getAllApps();
+        final int N = apps.size();
+        for (int i = 0; i < N; i++) {
+            AppEntry app = apps.get(i);
+            int userId = UserHandle.getUserId(app.info.uid);
+            ArrayMap<String, UsageState> userMap = entries.get(userId);
+            app.extraInfo = userMap != null ? userMap.get(app.info.packageName) : null;
+        }
+    }
+
+    private SparseArray<ArrayMap<String, UsageState>> getEntries() {
+        try {
+            final String[] packages = mIPackageManager.getAppOpPermissionPackages(
+                    Manifest.permission.PACKAGE_USAGE_STATS);
+
+            if (packages == null) {
+                // No packages are requesting permission to use the UsageStats API.
+                return null;
+            }
+
+            SparseArray<ArrayMap<String, UsageState>> entries = new SparseArray<>();
+            for (final UserHandle profile : mProfiles) {
+                final ArrayMap<String, UsageState> entriesForProfile = new ArrayMap<>();
+                final int profileId = profile.getIdentifier();
+                entries.put(profileId, entriesForProfile);
+                for (final String packageName : packages) {
+                    final boolean isAvailable = mIPackageManager.isPackageAvailable(packageName,
+                            profileId);
+                    if (!shouldIgnorePackage(packageName) && isAvailable) {
+                        final UsageState newEntry = new UsageState(packageName, profile);
+                        entriesForProfile.put(packageName, newEntry);
+                    }
+                }
+            }
+
+            return entries;
+        } catch (RemoteException e) {
+            Log.w(TAG, "PackageManager is dead. Can't get list of packages requesting "
+                    + Manifest.permission.PACKAGE_USAGE_STATS, e);
+            return null;
+        }
+    }
+
+    private void loadPermissionsStates(SparseArray<ArrayMap<String, UsageState>> entries) {
+         // Load the packages that have been granted the PACKAGE_USAGE_STATS permission.
+        try {
+            for (final UserHandle profile : mProfiles) {
+                final int profileId = profile.getIdentifier();
+                final ArrayMap<String, UsageState> entriesForProfile = entries.get(profileId);
+                if (entriesForProfile == null) {
+                    continue;
+                }
+                @SuppressWarnings("unchecked")
+                final List<PackageInfo> packageInfos = mIPackageManager
+                        .getPackagesHoldingPermissions(PM_USAGE_STATS_PERMISSION, 0, profileId)
+                        .getList();
+                final int packageInfoCount = packageInfos != null ? packageInfos.size() : 0;
+                for (int i = 0; i < packageInfoCount; i++) {
+                    final PackageInfo packageInfo = packageInfos.get(i);
+                    final UsageState pe = entriesForProfile.get(packageInfo.packageName);
+                    if (pe != null) {
+                        pe.packageInfo = packageInfo;
+                        pe.permissionGranted = true;
+                    }
+                }
+            }
+        } catch (RemoteException e) {
+            Log.w(TAG, "PackageManager is dead. Can't get list of packages granted "
+                    + Manifest.permission.PACKAGE_USAGE_STATS, e);
+            return;
+        }
+    }
+
+    private void loadAppOpsStates(SparseArray<ArrayMap<String, UsageState>> entries) {
+        // Find out which packages have been granted permission from AppOps.
+        final List<AppOpsManager.PackageOps> packageOps = mAppOpsManager.getPackagesForOps(
+                APP_OPS_OP_CODES);
+        final int packageOpsCount = packageOps != null ? packageOps.size() : 0;
+        for (int i = 0; i < packageOpsCount; i++) {
+            final AppOpsManager.PackageOps packageOp = packageOps.get(i);
+            final int userId = UserHandle.getUserId(packageOp.getUid());
+            if (!isThisUserAProfileOfCurrentUser(userId)) {
+                // This AppOp does not belong to any of this user's profiles.
+                continue;
+            }
+
+            final ArrayMap<String, UsageState> entriesForProfile = entries.get(userId);
+            if (entriesForProfile == null) {
+                continue;
+            }
+            final UsageState pe = entriesForProfile.get(packageOp.getPackageName());
+            if (pe == null) {
+                Log.w(TAG, "AppOp permission exists for package " + packageOp.getPackageName()
+                        + " of user " + userId +
+                        " but package doesn't exist or did not request UsageStats access");
+                continue;
+            }
+
+            if (packageOp.getOps().size() < 1) {
+                Log.w(TAG, "No AppOps permission exists for package "
+                        + packageOp.getPackageName());
+                continue;
+            }
+
+            pe.appOpMode = packageOp.getOps().get(0).getMode();
+        }
+    }
+
+    private boolean shouldIgnorePackage(String packageName) {
+        return packageName.equals("android") || packageName.equals(mContext.getPackageName());
+    }
+
+    public static class UsageState {
+        public final String packageName;
+        public final UserHandle userHandle;
+        public PackageInfo packageInfo;
+        public boolean permissionGranted;
+        public int appOpMode;
+
+        public UsageState(String packageName, UserHandle userHandle) {
+            this.packageName = packageName;
+            this.appOpMode = AppOpsManager.MODE_DEFAULT;
+            this.userHandle = userHandle;
+        }
+
+        public boolean hasAccess() {
+            if (appOpMode == AppOpsManager.MODE_DEFAULT) {
+                return permissionGranted;
+            }
+            return appOpMode == AppOpsManager.MODE_ALLOWED;
+        }
+    }
+
+    public static final AppFilter FILTER_APP_USAGE = new AppFilter() {
+        @Override
+        public void init() {
+        }
+
+        @Override
+        public boolean filterApp(AppEntry info) {
+            return info.extraInfo != null;
+        }
+    };
+}
diff --git a/src/com/android/settings/applications/ManageApplications.java b/src/com/android/settings/applications/ManageApplications.java
index 1502173..273bcfe 100644
--- a/src/com/android/settings/applications/ManageApplications.java
+++ b/src/com/android/settings/applications/ManageApplications.java
@@ -58,8 +58,10 @@
 import com.android.settings.Settings.DomainsURLsAppListActivity;
 import com.android.settings.Settings.NotificationAppListActivity;
 import com.android.settings.Settings.StorageUseActivity;
+import com.android.settings.Settings.UsageAccessSettingsActivity;
 import com.android.settings.SettingsActivity;
 import com.android.settings.Utils;
+import com.android.settings.applications.AppStateUsageBridge.UsageState;
 import com.android.settings.applications.ApplicationsState.AppEntry;
 import com.android.settings.applications.ApplicationsState.AppFilter;
 import com.android.settings.applications.ApplicationsState.CompoundFilter;
@@ -117,6 +119,7 @@
     public static final int FILTER_APPS_PERSONAL                = 9;
     public static final int FILTER_APPS_WORK                    = 10;
     public static final int FILTER_APPS_WITH_DOMAIN_URLS        = 11;
+    public static final int FILTER_APPS_USAGE_ACCESS            = 12;
 
     // This is the string labels for the filter modes above, the order must be kept in sync.
     public static final int[] FILTER_LABELS = new int[] {
@@ -132,6 +135,7 @@
         R.string.filter_personal_apps, // Personal
         R.string.filter_work_apps,     // Work
         R.string.filter_with_domain_urls_apps,     // Domain URLs
+        R.string.filter_all_apps,      // Usage access screen, never displayed
     };
     // This is the actual mapping to filters from FILTER_ constants above, the order must
     // be kept in sync.
@@ -152,6 +156,7 @@
         ApplicationsState.FILTER_PERSONAL,    // Personal
         ApplicationsState.FILTER_WORK,        // Work
         ApplicationsState.FILTER_WITH_DOMAIN_URLS,   // Apps with Domain URLs
+        AppStateUsageBridge.FILTER_APP_USAGE, // Apps with Domain URLs
     };
 
     // sort order
@@ -190,6 +195,7 @@
     public static final int LIST_TYPE_NOTIFICATION = 1;
     public static final int LIST_TYPE_DOMAINS_URLS = 2;
     public static final int LIST_TYPE_STORAGE = 3;
+    public static final int LIST_TYPE_USAGE_ACCESS = 4;
 
     private View mRootView;
 
@@ -230,6 +236,9 @@
                 mListType = LIST_TYPE_MAIN;
                 mSortOrder = R.id.sort_order_size;
             }
+        } else if (className.equals(UsageAccessSettingsActivity.class.getName())) {
+            mListType = LIST_TYPE_USAGE_ACCESS;
+            getActivity().getActionBar().setTitle(R.string.usage_access_title);
         } else {
             mListType = LIST_TYPE_MAIN;
         }
@@ -300,7 +309,7 @@
         contentParent.addView(mSpinnerHeader, 0);
 
         mFilterAdapter.enableFilter(getDefaultFilter());
-        if (mListType != LIST_TYPE_STORAGE) {
+        if (mListType == LIST_TYPE_MAIN || mListType == LIST_TYPE_NOTIFICATION) {
             if (UserManager.get(getActivity()).getUserProfiles().size() > 1) {
                 mFilterAdapter.enableFilter(FILTER_APPS_PERSONAL);
                 mFilterAdapter.enableFilter(FILTER_APPS_WORK);
@@ -331,6 +340,8 @@
                 return mShowSystem ? FILTER_APPS_ALL : FILTER_APPS_DOWNLOADED_AND_LAUNCHER;
             case LIST_TYPE_DOMAINS_URLS:
                 return FILTER_APPS_WITH_DOMAIN_URLS;
+            case LIST_TYPE_USAGE_ACCESS:
+                return FILTER_APPS_USAGE_ACCESS;
             default:
                 return FILTER_APPS_ALL;
         }
@@ -347,6 +358,8 @@
                 return MetricsLogger.MANAGE_DOMAIN_URLS;
             case LIST_TYPE_STORAGE:
                 return InstrumentedFragment.VIEW_CATEGORY_STORAGE_APPS;
+            case LIST_TYPE_USAGE_ACCESS:
+                return MetricsLogger.USAGE_ACCESS;
             default:
                 return MetricsLogger.VIEW_UNKNOWN;
         }
@@ -398,7 +411,7 @@
     public void onActivityResult(int requestCode, int resultCode, Intent data) {
         if (requestCode == INSTALLED_APP_DETAILS && mCurrentPkgName != null) {
             if (mListType == LIST_TYPE_NOTIFICATION) {
-                mApplications.mNotifBridge.forceUpdate(mCurrentPkgName, mCurrentUid);
+                mApplications.mExtraInfoBridge.forceUpdate(mCurrentPkgName, mCurrentUid);
             } else {
                 mApplicationsState.requestSize(mCurrentPkgName, UserHandle.getUserId(mCurrentUid));
             }
@@ -408,30 +421,39 @@
     // utility method used to start sub activity
     private void startApplicationDetailsActivity() {
         Activity activity = getActivity();
-        if (mListType == LIST_TYPE_NOTIFICATION) {
-            activity.startActivity(new Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS)
-                    .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
-                    .putExtra(Settings.EXTRA_APP_PACKAGE, mCurrentPkgName)
-                    .putExtra(Settings.EXTRA_APP_UID, mCurrentUid));
-        } else if (mListType == LIST_TYPE_DOMAINS_URLS) {
-            final String title = getString(R.string.auto_launch_label);
-            startAppInfoFragment(AppLaunchSettings.class, title);
-        } else {
+        switch (mListType) {
+            case LIST_TYPE_NOTIFICATION:
+                activity.startActivity(new Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS)
+                        .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
+                        .putExtra(Settings.EXTRA_APP_PACKAGE, mCurrentPkgName)
+                        .putExtra(Settings.EXTRA_APP_UID, mCurrentUid));
+                break;
+            case LIST_TYPE_DOMAINS_URLS:
+                startAppInfoFragment(AppLaunchSettings.class, R.string.auto_launch_label);
+                break;
+            case LIST_TYPE_USAGE_ACCESS:
+                startAppInfoFragment(UsageAccessDetails.class, R.string.usage_access);
+                break;
+            case LIST_TYPE_STORAGE:
+                startAppInfoFragment(AppStorageSettings.class, R.string.storage_settings);
+                break;
             // TODO: Figure out if there is a way where we can spin up the profile's settings
             // process ahead of time, to avoid a long load of data when user clicks on a managed app.
             // Maybe when they load the list of apps that contains managed profile apps.
-            Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
-            intent.setData(Uri.fromParts("package", mCurrentPkgName, null));
-            activity.startActivityAsUser(intent, new UserHandle(UserHandle.getUserId(mCurrentUid)));
+            default:
+                startAppInfoFragment(InstalledAppDetails.class, R.string.application_info_label);
+                break;
         }
     }
 
-    private void startAppInfoFragment(Class<? extends AppInfoBase> fragment, CharSequence title) {
+    private void startAppInfoFragment(Class<? extends AppInfoBase> fragment, int titleRes) {
         Bundle args = new Bundle();
-        args.putString("package", mCurrentPkgName);
+        args.putString(AppInfoBase.ARG_PACKAGE_NAME, mCurrentPkgName);
 
-        SettingsActivity sa = (SettingsActivity) getActivity();
-        sa.startPreferencePanel(fragment.getName(), args, -1, title, this, 0);
+        Intent intent = Utils.onBuildStartFragmentIntent(getActivity(), fragment.getName(), args,
+                null, titleRes, null, false);
+        getActivity().startActivityForResultAsUser(intent, INSTALLED_APP_DETAILS,
+                new UserHandle(UserHandle.getUserId(mCurrentUid)));
     }
 
     @Override
@@ -653,14 +675,14 @@
      * The order of applications in the list is mirrored in mAppLocalList
      */
     static class ApplicationsAdapter extends BaseAdapter implements Filterable,
-            ApplicationsState.Callbacks, AppStateNotificationBridge.Callback,
+            ApplicationsState.Callbacks, AppStateBaseBridge.Callback,
             AbsListView.RecyclerListener {
         private final ApplicationsState mState;
         private final ApplicationsState.Session mSession;
         private final ManageApplications mManageApplications;
         private final Context mContext;
         private final ArrayList<View> mActive = new ArrayList<View>();
-        private final AppStateNotificationBridge mNotifBridge;
+        private final AppStateBaseBridge mExtraInfoBridge;
         private int mFilterMode;
         private ArrayList<ApplicationsState.AppEntry> mBaseEntries;
         private ArrayList<ApplicationsState.AppEntry> mEntries;
@@ -700,11 +722,12 @@
             mPm = mContext.getPackageManager();
             mFilterMode = filterMode;
             if (mManageApplications.mListType == LIST_TYPE_NOTIFICATION) {
-                mNotifBridge = new AppStateNotificationBridge(
-                        mContext.getPackageManager(), mState,
-                        manageApplications.mNotifBackend, this);
+                mExtraInfoBridge = new AppStateNotificationBridge(mContext.getPackageManager(),
+                        mState, this, manageApplications.mNotifBackend);
+            } else if (mManageApplications.mListType == LIST_TYPE_USAGE_ACCESS) {
+                mExtraInfoBridge = new AppStateUsageBridge(mContext, mState, this);
             } else {
-                mNotifBridge = null;
+                mExtraInfoBridge = null;
             }
         }
 
@@ -724,8 +747,8 @@
                 mResumed = true;
                 mSession.resume();
                 mLastSortMode = sort;
-                if (mNotifBridge != null) {
-                    mNotifBridge.resume();
+                if (mExtraInfoBridge != null) {
+                    mExtraInfoBridge.resume();
                 }
                 rebuild(true);
             } else {
@@ -737,16 +760,16 @@
             if (mResumed) {
                 mResumed = false;
                 mSession.pause();
-                if (mNotifBridge != null) {
-                    mNotifBridge.pause();
+                if (mExtraInfoBridge != null) {
+                    mExtraInfoBridge.pause();
                 }
             }
         }
 
         public void release() {
             mSession.release();
-            if (mNotifBridge != null) {
-                mNotifBridge.release();
+            if (mExtraInfoBridge != null) {
+                mExtraInfoBridge.release();
             }
         }
 
@@ -809,6 +832,10 @@
                 Utils.handleLoadingContainer(mManageApplications.mLoadingContainer,
                         mManageApplications.mListContainer, true, true);
             }
+            if (mManageApplications.mListType == LIST_TYPE_USAGE_ACCESS) {
+                // No enabled or disabled filters for usage access.
+                return;
+            }
 
             mManageApplications.setHasDisabled(hasDisabledApps());
         }
@@ -849,10 +876,8 @@
         }
 
         @Override
-        public void onNotificationInfoUpdated() {
-            if (mFilterMode != mManageApplications.getDefaultFilter()) {
-                rebuild(false);
-            }
+        public void onExtraInfoUpdated() {
+            rebuild(false);
         }
 
         @Override
@@ -897,9 +922,7 @@
                 AppViewHolder holder = (AppViewHolder)mActive.get(i).getTag();
                 if (holder.entry.info.packageName.equals(packageName)) {
                     synchronized (holder.entry) {
-                        if (mManageApplications.mListType != LIST_TYPE_NOTIFICATION) {
-                            holder.updateSizeText(mManageApplications.mInvalidSizeStr, mWhichSize);
-                        }
+                        updateSummary(holder);
                     }
                     if (holder.entry.info.packageName.equals(mManageApplications.mCurrentPkgName)
                             && mLastSortMode == R.id.sort_order_size) {
@@ -967,24 +990,7 @@
                 if (entry.icon != null) {
                     holder.appIcon.setImageDrawable(entry.icon);
                 }
-                switch (mManageApplications.mListType) {
-                    case LIST_TYPE_NOTIFICATION:
-                        if (entry.extraInfo != null) {
-                            holder.summary.setText(InstalledAppDetails.getNotificationSummary(
-                                    (AppRow) entry.extraInfo, mContext));
-                        } else {
-                            holder.summary.setText("");
-                        }
-                        break;
-
-                    case LIST_TYPE_DOMAINS_URLS:
-                        holder.summary.setText(getDomainsSummary(entry.info.packageName));
-                        break;
-
-                    default:
-                        holder.updateSizeText(mManageApplications.mInvalidSizeStr, mWhichSize);
-                        break;
-                }
+                updateSummary(holder);
                 convertView.setEnabled(isAppEntryViewEnabled(entry));
                 if ((entry.info.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
                     holder.disabled.setVisibility(View.VISIBLE);
@@ -1002,6 +1008,36 @@
             return convertView;
         }
 
+        private void updateSummary(AppViewHolder holder) {
+            switch (mManageApplications.mListType) {
+                case LIST_TYPE_NOTIFICATION:
+                    if (holder.entry.extraInfo != null) {
+                        holder.summary.setText(InstalledAppDetails.getNotificationSummary(
+                                (AppRow) holder.entry.extraInfo, mContext));
+                    } else {
+                        holder.summary.setText(null);
+                    }
+                    break;
+
+                case LIST_TYPE_DOMAINS_URLS:
+                    holder.summary.setText(getDomainsSummary(holder.entry.info.packageName));
+                    break;
+
+                case LIST_TYPE_USAGE_ACCESS:
+                    if (holder.entry.extraInfo != null) {
+                        holder.summary.setText(((UsageState) holder.entry.extraInfo).hasAccess() ?
+                                R.string.switch_on_text : R.string.switch_off_text);
+                    } else {
+                        holder.summary.setText(null);
+                    }
+                    break;
+
+                default:
+                    holder.updateSizeText(mManageApplications.mInvalidSizeStr, mWhichSize);
+                    break;
+            }
+        }
+
         @Override
         public Filter getFilter() {
             return mFilter;
diff --git a/src/com/android/settings/applications/UsageAccessDetails.java b/src/com/android/settings/applications/UsageAccessDetails.java
new file mode 100644
index 0000000..a11d7a7
--- /dev/null
+++ b/src/com/android/settings/applications/UsageAccessDetails.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2015 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.app.AlertDialog;
+import android.app.AppOpsManager;
+import android.content.ActivityNotFoundException;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.os.Bundle;
+import android.os.UserHandle;
+import android.preference.Preference;
+import android.preference.Preference.OnPreferenceChangeListener;
+import android.preference.Preference.OnPreferenceClickListener;
+import android.preference.SwitchPreference;
+import android.provider.Settings;
+import android.util.Log;
+
+import com.android.settings.InstrumentedFragment;
+import com.android.settings.R;
+import com.android.settings.applications.AppStateUsageBridge.UsageState;
+
+public class UsageAccessDetails extends AppInfoWithHeader implements OnPreferenceChangeListener,
+        OnPreferenceClickListener {
+
+    private static final String KEY_USAGE_SWITCH = "usage_switch";
+    private static final String KEY_USAGE_PREFS = "app_usage_preference";
+
+    // Use a bridge to get the usage stats but don't initialize it to connect with all state.
+    // TODO: Break out this functionality into its own class.
+    private AppStateUsageBridge mUsageBridge;
+    private AppOpsManager mAppOpsManager;
+    private SwitchPreference mSwitchPref;
+    private Preference mUsagePrefs;
+    private Intent mSettingsIntent;
+    private UsageState mUsageState;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        Context context = getActivity();
+        mUsageBridge = new AppStateUsageBridge(context, mState, null);
+        mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
+
+        addPreferencesFromResource(R.xml.usage_access_details);
+        mSwitchPref = (SwitchPreference) findPreference(KEY_USAGE_SWITCH);
+        mUsagePrefs = findPreference(KEY_USAGE_PREFS);
+
+        mSwitchPref.setOnPreferenceChangeListener(this);
+        mUsagePrefs.setOnPreferenceClickListener(this);
+
+        mSettingsIntent = new Intent(Intent.ACTION_MAIN)
+                .addCategory(Settings.INTENT_CATEGORY_USAGE_ACCESS_CONFIG)
+                .setPackage(mPackageName);
+    }
+
+    @Override
+    public boolean onPreferenceClick(Preference preference) {
+        if (preference == mUsagePrefs) {
+            if (mSettingsIntent != null) {
+                try {
+                    getActivity().startActivityAsUser(mSettingsIntent, new UserHandle(mUserId));
+                } catch (ActivityNotFoundException e) {
+                    Log.w(TAG, "Unable to launch app usage access settings " + mSettingsIntent, e);
+                }
+            }
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public boolean onPreferenceChange(Preference preference, Object newValue) {
+        if (preference == mSwitchPref) {
+            if (mUsageState != null && (Boolean) newValue != mUsageState.hasAccess()) {
+                setHasAccess(!mUsageState.hasAccess());
+                refreshUi();
+            }
+            return true;
+        }
+        return false;
+    }
+
+    private void setHasAccess(boolean newState) {
+        mAppOpsManager.setMode(AppOpsManager.OP_GET_USAGE_STATS, mPackageInfo.applicationInfo.uid,
+                mPackageName, newState ? AppOpsManager.MODE_ALLOWED : AppOpsManager.MODE_IGNORED);
+    }
+
+    @Override
+    protected boolean refreshUi() {
+        mUsageState = mUsageBridge.getUsageInfo(mPackageName,
+                mPackageInfo.applicationInfo.uid);
+
+        boolean hasAccess = mUsageState.hasAccess();
+        mSwitchPref.setChecked(hasAccess);
+        mUsagePrefs.setEnabled(hasAccess);
+
+        ResolveInfo resolveInfo = mPm.resolveActivityAsUser(mSettingsIntent,
+                PackageManager.GET_META_DATA, mUserId);
+        if (resolveInfo != null) {
+            if (findPreference(KEY_USAGE_PREFS) == null) {
+                getPreferenceScreen().addPreference(mUsagePrefs);
+            }
+            Bundle metaData = resolveInfo.activityInfo.metaData;
+            mSettingsIntent.setComponent(new ComponentName(resolveInfo.activityInfo.packageName,
+                    resolveInfo.activityInfo.name));
+            if (metaData != null
+                    && metaData.containsKey(Settings.METADATA_USAGE_ACCESS_REASON)) {
+                mSwitchPref.setSummary(
+                        metaData.getString(Settings.METADATA_USAGE_ACCESS_REASON));
+            }
+        } else {
+            if (findPreference(KEY_USAGE_PREFS) != null) {
+                getPreferenceScreen().removePreference(mUsagePrefs);
+            }
+        }
+
+        return true;
+    }
+
+    @Override
+    protected AlertDialog createDialog(int id, int errorCode) {
+        return null;
+    }
+
+    @Override
+    protected int getMetricsCategory() {
+        return InstrumentedFragment.VIEW_CATEGORY_USAGE_ACCESS_DETAIL;
+    }
+
+}
