import android.widget.Switch;
import com.android.internal.logging.MetricsLogger;
+import com.android.settings.DimmableIconPreference;
+import com.android.settings.PreferenceActivity;
import com.android.settings.R;
import com.android.settings.SettingsActivity;
import com.android.settings.Utils;
+import com.android.settings.applications.InstalledAppDetails;
import com.android.settings.widget.SwitchBar;
+import com.android.settingslib.location.RecentLocationApps;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
mCategoryRecentLocationRequests =
(PreferenceCategory) root.findPreference(KEY_RECENT_LOCATION_REQUESTS);
- RecentLocationApps recentApps = new RecentLocationApps(activity, getPrefContext());
- List<Preference> recentLocationRequests = recentApps.getAppList();
+ RecentLocationApps recentApps = new RecentLocationApps(activity);
+ List<RecentLocationApps.Request> recentLocationRequests = recentApps.getAppList();
+ List<Preference> recentLocationPrefs = new ArrayList<>(recentLocationRequests.size());
+ for (final RecentLocationApps.Request request : recentLocationRequests) {
+ DimmableIconPreference pref = new DimmableIconPreference(getPrefContext(),
+ request.contentDescription);
+ pref.setIcon(request.icon);
+ pref.setTitle(request.label);
+ if (request.isHighBattery) {
+ pref.setSummary(R.string.location_high_battery_use);
+ } else {
+ pref.setSummary(R.string.location_low_battery_use);
+ }
+ pref.setOnPreferenceClickListener(
+ new PackageEntryClickedListener(request.packageName, request.userHandle));
+ recentLocationPrefs.add(pref);
+
+ }
if (recentLocationRequests.size() > 0) {
- addPreferencesSorted(recentLocationRequests, mCategoryRecentLocationRequests);
+ addPreferencesSorted(recentLocationPrefs, mCategoryRecentLocationRequests);
} else {
// If there's no item to display, add a "No recent apps" item.
Preference banner = new Preference(getPrefContext());
setLocationMode(android.provider.Settings.Secure.LOCATION_MODE_OFF);
}
}
+
+ private class PackageEntryClickedListener
+ implements Preference.OnPreferenceClickListener {
+ private String mPackage;
+ private UserHandle mUserHandle;
+
+ public PackageEntryClickedListener(String packageName, UserHandle userHandle) {
+ mPackage = packageName;
+ mUserHandle = userHandle;
+ }
+
+ @Override
+ public boolean onPreferenceClick(Preference preference) {
+ // start new fragment to display extended information
+ Bundle args = new Bundle();
+ args.putString(InstalledAppDetails.ARG_PACKAGE_NAME, mPackage);
+ ((PreferenceActivity) getActivity()).startPreferencePanelAsUser(
+ InstalledAppDetails.class.getName(), args,
+ R.string.application_info_label, null, mUserHandle);
+ return true;
+ }
+ }
}
+++ /dev/null
-/*
- * Copyright (C) 2013 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.location;
-
-import android.app.AppGlobals;
-import android.app.AppOpsManager;
-import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.IPackageManager;
-import android.content.pm.PackageManager;
-import android.content.res.Resources;
-import android.graphics.drawable.Drawable;
-import android.os.Bundle;
-import android.os.Process;
-import android.os.RemoteException;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.support.v7.preference.Preference;
-import android.util.Log;
-
-import com.android.settings.DimmableIconPreference;
-import com.android.settings.R;
-import com.android.settings.SettingsActivity;
-import com.android.settings.applications.InstalledAppDetails;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Retrieves the information of applications which accessed location recently.
- */
-public class RecentLocationApps {
- private static final String TAG = RecentLocationApps.class.getSimpleName();
- private static final String ANDROID_SYSTEM_PACKAGE_NAME = "android";
-
- private static final int RECENT_TIME_INTERVAL_MILLIS = 15 * 60 * 1000;
-
- private final SettingsActivity mActivity;
- private final PackageManager mPackageManager;
- private final Context mContext;
-
- public RecentLocationApps(SettingsActivity activity, Context context) {
- mActivity = activity;
- mContext = context;
- mPackageManager = activity.getPackageManager();
- }
-
- private class PackageEntryClickedListener
- implements Preference.OnPreferenceClickListener {
- private String mPackage;
- private UserHandle mUserHandle;
-
- public PackageEntryClickedListener(String packageName, UserHandle userHandle) {
- mPackage = packageName;
- mUserHandle = userHandle;
- }
-
- @Override
- public boolean onPreferenceClick(Preference preference) {
- // start new fragment to display extended information
- Bundle args = new Bundle();
- args.putString(InstalledAppDetails.ARG_PACKAGE_NAME, mPackage);
- mActivity.startPreferencePanelAsUser(InstalledAppDetails.class.getName(), args,
- R.string.application_info_label, null, mUserHandle);
- return true;
- }
- }
-
- private DimmableIconPreference createRecentLocationEntry(
- Drawable icon,
- CharSequence label,
- boolean isHighBattery,
- CharSequence contentDescription,
- Preference.OnPreferenceClickListener listener) {
- DimmableIconPreference pref = new DimmableIconPreference(mContext, contentDescription);
- pref.setIcon(icon);
- pref.setTitle(label);
- if (isHighBattery) {
- pref.setSummary(R.string.location_high_battery_use);
- } else {
- pref.setSummary(R.string.location_low_battery_use);
- }
- pref.setOnPreferenceClickListener(listener);
- return pref;
- }
-
- /**
- * Fills a list of applications which queried location recently within specified time.
- */
- public List<Preference> getAppList() {
- // Retrieve a location usage list from AppOps
- AppOpsManager aoManager =
- (AppOpsManager) mActivity.getSystemService(Context.APP_OPS_SERVICE);
- List<AppOpsManager.PackageOps> appOps = aoManager.getPackagesForOps(new int[] {
- AppOpsManager.OP_MONITOR_LOCATION, AppOpsManager.OP_MONITOR_HIGH_POWER_LOCATION, });
-
- // Process the AppOps list and generate a preference list.
- ArrayList<Preference> prefs = new ArrayList<Preference>();
- final long now = System.currentTimeMillis();
- final UserManager um = (UserManager) mActivity.getSystemService(Context.USER_SERVICE);
- final List<UserHandle> profiles = um.getUserProfiles();
-
- final int appOpsN = appOps.size();
- for (int i = 0; i < appOpsN; ++i) {
- AppOpsManager.PackageOps ops = appOps.get(i);
- // Don't show the Android System in the list - it's not actionable for the user.
- // Also don't show apps belonging to background users except managed users.
- String packageName = ops.getPackageName();
- int uid = ops.getUid();
- int userId = UserHandle.getUserId(uid);
- boolean isAndroidOs =
- (uid == Process.SYSTEM_UID) && ANDROID_SYSTEM_PACKAGE_NAME.equals(packageName);
- if (isAndroidOs || !profiles.contains(new UserHandle(userId))) {
- continue;
- }
- Preference preference = getPreferenceFromOps(um, now, ops);
- if (preference != null) {
- prefs.add(preference);
- }
- }
-
- return prefs;
- }
-
- /**
- * Creates a Preference entry for the given PackageOps.
- *
- * This method examines the time interval of the PackageOps first. If the PackageOps is older
- * than the designated interval, this method ignores the PackageOps object and returns null.
- * When the PackageOps is fresh enough, this method returns a Preference pointing to the App
- * Info page for that package.
- */
- private Preference getPreferenceFromOps(final UserManager um, long now,
- AppOpsManager.PackageOps ops) {
- String packageName = ops.getPackageName();
- List<AppOpsManager.OpEntry> entries = ops.getOps();
- boolean highBattery = false;
- boolean normalBattery = false;
- // Earliest time for a location request to end and still be shown in list.
- long recentLocationCutoffTime = now - RECENT_TIME_INTERVAL_MILLIS;
- for (AppOpsManager.OpEntry entry : entries) {
- if (entry.isRunning() || entry.getTime() >= recentLocationCutoffTime) {
- switch (entry.getOp()) {
- case AppOpsManager.OP_MONITOR_LOCATION:
- normalBattery = true;
- break;
- case AppOpsManager.OP_MONITOR_HIGH_POWER_LOCATION:
- highBattery = true;
- break;
- default:
- break;
- }
- }
- }
-
- if (!highBattery && !normalBattery) {
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, packageName + " hadn't used location within the time interval.");
- }
- return null;
- }
-
- // The package is fresh enough, continue.
-
- int uid = ops.getUid();
- int userId = UserHandle.getUserId(uid);
-
- DimmableIconPreference preference = null;
- try {
- IPackageManager ipm = AppGlobals.getPackageManager();
- ApplicationInfo appInfo =
- ipm.getApplicationInfo(packageName, PackageManager.GET_META_DATA, userId);
- if (appInfo == null) {
- Log.w(TAG, "Null application info retrieved for package " + packageName
- + ", userId " + userId);
- return null;
- }
- Resources res = mActivity.getResources();
-
- final UserHandle userHandle = new UserHandle(userId);
- Drawable appIcon = mPackageManager.getApplicationIcon(appInfo);
- Drawable icon = mPackageManager.getUserBadgedIcon(appIcon, userHandle);
- CharSequence appLabel = mPackageManager.getApplicationLabel(appInfo);
- CharSequence badgedAppLabel = mPackageManager.getUserBadgedLabel(appLabel, userHandle);
- if (appLabel.toString().contentEquals(badgedAppLabel)) {
- // If badged label is not different from original then no need for it as
- // a separate content description.
- badgedAppLabel = null;
- }
- preference = createRecentLocationEntry(icon,
- appLabel, highBattery, badgedAppLabel,
- new PackageEntryClickedListener(packageName, userHandle));
- } catch (RemoteException e) {
- Log.w(TAG, "Error while retrieving application info for package " + packageName
- + ", userId " + userId, e);
- }
-
- return preference;
- }
-}