Merge "Missing return statement if a print job is no longer present." into klp-dev
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 51ff2f2..ab31b8c 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -15,6 +15,7 @@
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
+ <uses-permission android:name="android.permission.BLUETOOTH_PRIVILEGED" />
<uses-permission android:name="android.permission.NFC" />
<uses-permission android:name="android.permission.HARDWARE_TEST" />
<uses-permission android:name="android.permission.CALL_PHONE" />
@@ -801,7 +802,8 @@
<activity android:name="Settings$AppOpsSummaryActivity"
android:label="@string/app_ops_settings"
android:taskAffinity=""
- android:excludeFromRecents="true">
+ android:excludeFromRecents="true"
+ android:enabled="false">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="android.settings.APP_OPS_SETTINGS" />
diff --git a/res/drawable-hdpi/ic_qs_certificate_info.png b/res/drawable-hdpi/ic_qs_certificate_info.png
deleted file mode 100644
index 1fdaaf9..0000000
--- a/res/drawable-hdpi/ic_qs_certificate_info.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_qs_certificate_info.png b/res/drawable-mdpi/ic_qs_certificate_info.png
deleted file mode 100644
index 3b49472..0000000
--- a/res/drawable-mdpi/ic_qs_certificate_info.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_qs_certificate_info.png b/res/drawable-xhdpi/ic_qs_certificate_info.png
deleted file mode 100644
index b3de2ce..0000000
--- a/res/drawable-xhdpi/ic_qs_certificate_info.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_qs_certificate_info.png b/res/drawable-xxhdpi/ic_qs_certificate_info.png
deleted file mode 100644
index 5d6f6c7..0000000
--- a/res/drawable-xxhdpi/ic_qs_certificate_info.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_settings_about.png b/res/drawable-xxhdpi/ic_settings_about.png
new file mode 100644
index 0000000..924d962
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_settings_about.png
Binary files differ
diff --git a/res/layout/empty_print_state.xml b/res/layout/empty_print_state.xml
index 135b3dd..e97bb85 100644
--- a/res/layout/empty_print_state.xml
+++ b/res/layout/empty_print_state.xml
@@ -15,7 +15,7 @@
-->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/empty_printers_list_service_disabled"
+ android:id="@+id/empty_print_state"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:visibility="gone">
@@ -28,11 +28,12 @@
android:orientation="vertical">
<ImageView
+ android:id="@+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="12dip"
android:src="@drawable/ic_grayedout_printer"
- android:contentDescription="@string/print_service_disabled">
+ android:contentDescription="@null">
</ImageView>
<TextView
diff --git a/res/menu/nfc_payment_settings.xml b/res/menu/nfc_payment_settings.xml
deleted file mode 100644
index f35374e..0000000
--- a/res/menu/nfc_payment_settings.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
- <item
- android:id="@+id/nfc_payment_menu_item_add_service"
- android:title="@string/nfc_payment_menu_item_add_service"
- android:showAsAction="ifRoom">
- </item>
-</menu>
diff --git a/res/menu/print_settings.xml b/res/menu/print_settings.xml
deleted file mode 100644
index 9df1181..0000000
--- a/res/menu/print_settings.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
- <item
- android:id="@+id/print_menu_item_add_service"
- android:title="@string/print_menu_item_add_service"
- android:showAsAction="ifRoom">
- </item>
-</menu>
diff --git a/res/values/donottranslate.xml b/res/values/donottranslate.xml
index f290f38..e6bd9a6 100644
--- a/res/values/donottranslate.xml
+++ b/res/values/donottranslate.xml
@@ -33,8 +33,4 @@
<item>@string/input_method_selector_always_show_value</item>
<item>@string/input_method_selector_always_hide_value</item>
</string-array>
- <!-- Default query string to search for a print service. -->
- <string name="download_print_service_query">market://search?q=print service</string>
- <!-- Default query string to search for a NFC payment service. -->
- <string name="download_nfc_payment_service_query">market://search?q=nfc payment</string>
</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 3c45bbc..9c5d039 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -2408,16 +2408,16 @@
<string name="location_mode_high_accuracy_title">High accuracy</string>
<!-- [CHAR LIMIT=30] Location settings screen, battery saving location mode -->
<string name="location_mode_battery_saving_title">Battery saving</string>
- <!-- [CHAR LIMIT=30] Location settings screen, device sensors only location mode -->
- <string name="location_mode_sensors_only_title">Device sensors</string>
+ <!-- [CHAR LIMIT=30] Location settings screen, device only location mode -->
+ <string name="location_mode_sensors_only_title">Device only</string>
<!-- [CHAR LIMIT=30] Location settings screen, location off mode -->
<string name="location_mode_location_off_title">Location off</string>
<!-- [CHAR LIMIT=30] Location settings screen, sub category for recent location requests -->
<string name="location_category_recent_location_requests">Recent location requests</string>
<!-- Location settings screen, displayed when there's no recent app accessing location -->
<string name="location_no_recent_apps">No apps have requested location recently</string>
- <!-- [CHAR LIMIT=30] Location settings screen, sub category for app settings -->
- <string name="location_category_app_settings">App settings</string>
+ <!-- [CHAR LIMIT=30] Location settings screen, sub category for location services -->
+ <string name="location_category_location_services">Location services</string>
<!-- [CHAR LIMIT=30] Location settings screen, recent location requests high battery use-->
<string name="location_high_battery_use">High battery use</string>
<!-- [CHAR LIMIT=30] Location settings screen, recent location requests low battery use-->
@@ -3430,6 +3430,9 @@
<!-- Title for the prompt shown as a placeholder if no print serivices are installed. [CHAR LIMIT=50] -->
<string name="print_no_services_installed">No services installed</string>
+ <!-- Title for the prompt shown as a placeholder if no printers are found while searching. [CHAR LIMIT=50] -->
+ <string name="print_no_printers_found">No printers found</string>
+
<!-- Title for print menu item to launch a settings activity. [CHAR LIMIT=25] -->
<string name="print_menu_item_settings">Settings</string>
@@ -4656,12 +4659,12 @@
<!-- Shows up when there is a user SSL CA Cert installed on the
device. Indicates to the user that SSL traffic can be intercepted. [CHAR LIMIT=NONE] -->
<string name="ssl_ca_cert_warning">Network may be monitored</string>
- <!-- Button to close the SSL CA cert warning dialog box. [CHAR LIMIT=NONE] -->
+ <!-- Button to close the SSL CA cert warning dialog box, meaning the user is done reading. [CHAR LIMIT=NONE] -->
<string name="done_button">Done</string>
<!-- Title of Dialog warning users of SSL monitoring. [CHAR LIMIT=NONE] -->
<string name="ssl_ca_cert_dialog_title">Network monitoring</string>
<!-- Text of message to show to users whose administrator has installed a SSL CA Cert. [CHAR LIMIT=NONE] -->
- <string name="ssl_ca_cert_info_message">This device is managed by: <xliff:g id="managing_domain">%s</xliff:g>.\n\nYour administrator is capable of monitoring your network activity, including emails, apps, and secure websites.\n\nFor more information, contact your administrator.</string>
+ <string name="ssl_ca_cert_info_message">This device is managed by:\n<xliff:g id="managing_domain">%s</xliff:g>\n\nYour administrator is capable of monitoring your network activity, including emails, apps, and secure websites.\n\nFor more information, contact your administrator.</string>
<!-- Text of warning to show to users that have a SSL CA Cert installed. [CHAR LIMIT=NONE] -->
<string name="ssl_ca_cert_warning_message">A third party is capable of monitoring your network\nactivity, including emails, apps, and secure websites.\n\nA trusted credential installed on your device is making this possible.</string>
<!-- Label on button that will take the user to the Trusted Credentials settings page. [CHAR LIMIT=NONE]-->
diff --git a/res/xml/location_settings.xml b/res/xml/location_settings.xml
index 5be6bd3..83b80b1 100644
--- a/res/xml/location_settings.xml
+++ b/res/xml/location_settings.xml
@@ -26,7 +26,7 @@
android:title="@string/location_category_recent_location_requests" />
<PreferenceCategory
- android:key="app_settings"
- android:title="@string/location_category_app_settings" />
+ android:key="location_services"
+ android:title="@string/location_category_location_services" />
</PreferenceScreen>
diff --git a/src/com/android/settings/CryptKeeper.java b/src/com/android/settings/CryptKeeper.java
index 94c793d..7057f1a 100644
--- a/src/com/android/settings/CryptKeeper.java
+++ b/src/com/android/settings/CryptKeeper.java
@@ -239,6 +239,7 @@
| StatusBarManager.DISABLE_NOTIFICATION_ALERTS
| StatusBarManager.DISABLE_SYSTEM_INFO
| StatusBarManager.DISABLE_HOME
+ | StatusBarManager.DISABLE_SEARCH
| StatusBarManager.DISABLE_RECENT;
/** @return whether or not this Activity was started for debugging the UI only. */
diff --git a/src/com/android/settings/SecuritySettings.java b/src/com/android/settings/SecuritySettings.java
index f365403..e002264 100644
--- a/src/com/android/settings/SecuritySettings.java
+++ b/src/com/android/settings/SecuritySettings.java
@@ -20,6 +20,7 @@
import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT;
import android.app.Activity;
+import android.app.ActivityManager;
import android.app.AlertDialog;
import android.app.admin.DevicePolicyManager;
import android.content.Context;
@@ -244,15 +245,25 @@
// Enable or disable keyguard widget checkbox based on DPM state
mEnableKeyguardWidgets = (CheckBoxPreference) root.findPreference(KEY_ENABLE_WIDGETS);
if (mEnableKeyguardWidgets != null) {
- final boolean disabled = (0 != (mDPM.getKeyguardDisabledFeatures(null)
- & DevicePolicyManager.KEYGUARD_DISABLE_WIDGETS_ALL));
- if (disabled) {
- mEnableKeyguardWidgets.setSummary(
- R.string.security_enable_widgets_disabled_summary);
+ if (ActivityManager.isLowRamDeviceStatic()) {
+ // Widgets take a lot of RAM, so disable them on low-memory devices
+ PreferenceGroup securityCategory
+ = (PreferenceGroup) root.findPreference(KEY_SECURITY_CATEGORY);
+ if (securityCategory != null) {
+ securityCategory.removePreference(root.findPreference(KEY_ENABLE_WIDGETS));
+ mEnableKeyguardWidgets = null;
+ }
} else {
- mEnableKeyguardWidgets.setSummary("");
+ final boolean disabled = (0 != (mDPM.getKeyguardDisabledFeatures(null)
+ & DevicePolicyManager.KEYGUARD_DISABLE_WIDGETS_ALL));
+ if (disabled) {
+ mEnableKeyguardWidgets.setSummary(
+ R.string.security_enable_widgets_disabled_summary);
+ } else {
+ mEnableKeyguardWidgets.setSummary("");
+ }
+ mEnableKeyguardWidgets.setEnabled(!disabled);
}
- mEnableKeyguardWidgets.setEnabled(!disabled);
}
// Show password
diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
index ac67a38..87d34c6 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -32,6 +32,7 @@
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.graphics.drawable.Drawable;
+import android.nfc.NfcAdapter;
import android.os.Bundle;
import android.os.INetworkManagementService;
import android.os.RemoteException;
@@ -574,8 +575,15 @@
target.remove(i);
}
} else if (id == R.id.nfc_payment_settings) {
- if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_NFC_HCE)) {
+ if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_NFC)) {
target.remove(i);
+ } else {
+ // Only show if NFC is on and we have the HCE feature
+ NfcAdapter adapter = NfcAdapter.getDefaultAdapter(this);
+ if (!adapter.isEnabled() || !getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_NFC_HOST_CARD_EMULATION)) {
+ target.remove(i);
+ }
}
} else if (id == R.id.development_settings) {
if (!showDev) {
@@ -871,7 +879,7 @@
holder.divider_.setVisibility(View.VISIBLE);
boolean isManaged = mDevicePolicyManager.getDeviceOwner() != null;
if (isManaged) {
- holder.button_.setImageResource(R.drawable.ic_qs_certificate_info);
+ holder.button_.setImageResource(R.drawable.ic_settings_about);
} else {
holder.button_.setImageResource(
android.R.drawable.stat_notify_error);
diff --git a/src/com/android/settings/applications/ProcStatsEntry.java b/src/com/android/settings/applications/ProcStatsEntry.java
index 8308784..0821ced 100644
--- a/src/com/android/settings/applications/ProcStatsEntry.java
+++ b/src/com/android/settings/applications/ProcStatsEntry.java
@@ -21,8 +21,8 @@
import android.content.pm.PackageManager;
import android.os.Parcel;
import android.os.Parcelable;
+import android.util.ArrayMap;
import android.util.Log;
-import android.util.SparseArray;
import com.android.internal.app.ProcessStats;
import java.util.ArrayList;
@@ -31,11 +31,12 @@
public final class ProcStatsEntry implements Parcelable {
private static final String TAG = "ProcStatsEntry";
+ private static boolean DEBUG = ProcessStatsUi.DEBUG;
final String mPackage;
final int mUid;
final String mName;
- final boolean mUnique;
+ final ArrayList<String> mPackages = new ArrayList<String>();
final long mDuration;
final long mAvgPss;
final long mMaxPss;
@@ -45,33 +46,35 @@
String mBestTargetPackage;
- ArrayList<Service> mServices = new ArrayList<Service>(2);
+ ArrayMap<String, ArrayList<Service>> mServices = new ArrayMap<String, ArrayList<Service>>(1);
public ApplicationInfo mUiTargetApp;
public String mUiLabel;
public String mUiBaseLabel;
public String mUiPackage;
- public ProcStatsEntry(ProcessStats.ProcessState proc,
+ public ProcStatsEntry(ProcessStats.ProcessState proc, String packageName,
ProcessStats.ProcessDataCollection tmpTotals, boolean useUss, boolean weightWithTime) {
ProcessStats.computeProcessData(proc, tmpTotals, 0);
mPackage = proc.mPackage;
mUid = proc.mUid;
mName = proc.mName;
- mUnique = proc.mCommonProcess == proc;
+ mPackages.add(packageName);
mDuration = tmpTotals.totalTime;
mAvgPss = tmpTotals.avgPss;
mMaxPss = tmpTotals.maxPss;
mAvgUss = tmpTotals.avgUss;
mMaxUss = tmpTotals.maxUss;
mWeight = (weightWithTime ? mDuration : 1) * (useUss ? mAvgUss : mAvgPss);
+ if (DEBUG) Log.d(TAG, "New proc entry " + proc.mName + ": dur=" + mDuration
+ + " avgpss=" + mAvgPss + " weight=" + mWeight);
}
public ProcStatsEntry(Parcel in) {
mPackage = in.readString();
mUid = in.readInt();
mName = in.readString();
- mUnique = in.readInt() != 0;
+ in.readStringList(mPackages);
mDuration = in.readLong();
mAvgPss = in.readLong();
mMaxPss = in.readLong();
@@ -79,40 +82,118 @@
mMaxUss = in.readLong();
mWeight = in.readLong();
mBestTargetPackage = in.readString();
- in.readTypedList(mServices, Service.CREATOR);
+ final int N = in.readInt();
+ if (N > 0) {
+ mServices.ensureCapacity(N);
+ for (int i=0; i<N; i++) {
+ String key = in.readString();
+ ArrayList<Service> value = new ArrayList<Service>();
+ in.readTypedList(value, Service.CREATOR);
+ mServices.append(key, value);
+ }
+ }
}
- public void evaluateTargetPackage(ProcessStats stats, ProcessStats.ProcessDataCollection totals,
- Comparator<ProcStatsEntry> compare, boolean useUss, boolean weightWithTime) {
+ public void addPackage(String packageName) {
+ mPackages.add(packageName);
+ }
+
+ public void evaluateTargetPackage(PackageManager pm, ProcessStats stats,
+ ProcessStats.ProcessDataCollection totals, Comparator<ProcStatsEntry> compare,
+ boolean useUss, boolean weightWithTime) {
mBestTargetPackage = null;
- if (mUnique) {
- mBestTargetPackage = mPackage;
+ if (mPackages.size() == 1) {
+ if (DEBUG) Log.d(TAG, "Eval pkg of " + mName + ": single pkg " + mPackages.get(0));
+ mBestTargetPackage = mPackages.get(0);
} else {
// See if there is one significant package that was running here.
ArrayList<ProcStatsEntry> subProcs = new ArrayList<ProcStatsEntry>();
- for (int ipkg=0, NPKG=stats.mPackages.getMap().size(); ipkg<NPKG; ipkg++) {
- SparseArray<ProcessStats.PackageState> uids
- = stats.mPackages.getMap().valueAt(ipkg);
- for (int iu=0, NU=uids.size(); iu<NU; iu++) {
- if (uids.keyAt(iu) != mUid) {
- continue;
- }
- ProcessStats.PackageState pkgState = uids.valueAt(iu);
- for (int iproc=0, NPROC=pkgState.mProcesses.size(); iproc<NPROC; iproc++) {
- ProcessStats.ProcessState subProc =
- pkgState.mProcesses.valueAt(iproc);
- if (subProc.mName.equals(mName)) {
- subProcs.add(new ProcStatsEntry(subProc, totals, useUss,
- weightWithTime));
- }
- }
+ for (int ipkg=0; ipkg<mPackages.size(); ipkg++) {
+ ProcessStats.PackageState pkgState = stats.mPackages.get(mPackages.get(ipkg), mUid);
+ if (DEBUG) Log.d(TAG, "Eval pkg of " + mName + ", pkg "
+ + mPackages.get(ipkg) + ":");
+ if (pkgState == null) {
+ Log.w(TAG, "No package state found for " + mPackages.get(ipkg) + "/"
+ + mUid + " in process " + mName);
+ continue;
}
+ ProcessStats.ProcessState pkgProc = pkgState.mProcesses.get(mName);
+ if (pkgProc == null) {
+ Log.w(TAG, "No process " + mName + " found in package state "
+ + mPackages.get(ipkg) + "/" + mUid);
+ continue;
+ }
+ subProcs.add(new ProcStatsEntry(pkgProc, pkgState.mPackageName, totals, useUss,
+ weightWithTime));
}
if (subProcs.size() > 1) {
Collections.sort(subProcs, compare);
if (subProcs.get(0).mWeight > (subProcs.get(1).mWeight*3)) {
+ if (DEBUG) Log.d(TAG, "Eval pkg of " + mName + ": best pkg "
+ + subProcs.get(0).mPackage + " weight " + subProcs.get(0).mWeight
+ + " better than " + subProcs.get(1).mPackage
+ + " weight " + subProcs.get(1).mWeight);
mBestTargetPackage = subProcs.get(0).mPackage;
+ return;
}
+ // Couldn't find one that is best by weight, let's decide on best another
+ // way: the one that has the longest running service, accounts for at least
+ // half of the maximum weight, and has specified an explicit app icon.
+ long maxWeight = subProcs.get(0).mWeight;
+ long bestRunTime = -1;
+ for (int i=0; i<subProcs.size(); i++) {
+ if (subProcs.get(i).mWeight < (maxWeight/2)) {
+ if (DEBUG) Log.d(TAG, "Eval pkg of " + mName + ": pkg "
+ + subProcs.get(i).mPackage + " weight " + subProcs.get(i).mWeight
+ + " too small");
+ continue;
+ }
+ try {
+ ApplicationInfo ai = pm.getApplicationInfo(subProcs.get(i).mPackage, 0);
+ if (ai.icon == 0) {
+ if (DEBUG) Log.d(TAG, "Eval pkg of " + mName + ": pkg "
+ + subProcs.get(i).mPackage + " has no icon");
+ continue;
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ if (DEBUG) Log.d(TAG, "Eval pkg of " + mName + ": pkg "
+ + subProcs.get(i).mPackage + " failed finding app info");
+ continue;
+ }
+ ArrayList<Service> subProcServices = null;
+ for (int isp=0, NSP=mServices.size(); isp<NSP; isp++) {
+ ArrayList<Service> subServices = mServices.valueAt(isp);
+ if (subServices.get(0).mPackage.equals(subProcs.get(i).mPackage)) {
+ subProcServices = subServices;
+ break;
+ }
+ }
+ long thisRunTime = 0;
+ if (subProcServices != null) {
+ for (int iss=0, NSS=subProcServices.size(); iss<NSS; iss++) {
+ Service service = subProcServices.get(iss);
+ if (service.mDuration > thisRunTime) {
+ if (DEBUG) Log.d(TAG, "Eval pkg of " + mName + ": pkg "
+ + subProcs.get(i).mPackage + " service " + service.mName
+ + " run time is " + service.mDuration);
+ thisRunTime = service.mDuration;
+ break;
+ }
+ }
+ }
+ if (thisRunTime > bestRunTime) {
+ if (DEBUG) Log.d(TAG, "Eval pkg of " + mName + ": pkg "
+ + subProcs.get(i).mPackage + " new best run time " + thisRunTime);
+ mBestTargetPackage = subProcs.get(i).mPackage;
+ bestRunTime = thisRunTime;
+ } else {
+ if (DEBUG) Log.d(TAG, "Eval pkg of " + mName + ": pkg "
+ + subProcs.get(i).mPackage + " run time " + thisRunTime
+ + " not as good as last " + bestRunTime);
+ }
+ }
+ } else if (subProcs.size() == 1) {
+ mBestTargetPackage = subProcs.get(0).mPackage;
}
}
}
@@ -178,7 +259,12 @@
}
public void addService(ProcessStats.ServiceState svc) {
- mServices.add(new Service(svc));
+ ArrayList<Service> services = mServices.get(svc.mPackage);
+ if (services == null) {
+ services = new ArrayList<Service>();
+ mServices.put(svc.mPackage, services);
+ }
+ services.add(new Service(svc));
}
@Override
@@ -191,7 +277,7 @@
dest.writeString(mPackage);
dest.writeInt(mUid);
dest.writeString(mName);
- dest.writeInt(mUnique ? 1 : 0);
+ dest.writeStringList(mPackages);
dest.writeLong(mDuration);
dest.writeLong(mAvgPss);
dest.writeLong(mMaxPss);
@@ -199,7 +285,12 @@
dest.writeLong(mMaxUss);
dest.writeLong(mWeight);
dest.writeString(mBestTargetPackage);
- dest.writeTypedList(mServices);
+ final int N = mServices.size();
+ dest.writeInt(N);
+ for (int i=0; i<N; i++) {
+ dest.writeString(mServices.keyAt(i));
+ dest.writeTypedList(mServices.valueAt(i));
+ }
}
public static final Parcelable.Creator<ProcStatsEntry> CREATOR
diff --git a/src/com/android/settings/applications/ProcessStatsDetail.java b/src/com/android/settings/applications/ProcessStatsDetail.java
index fad3745..a1885a7 100644
--- a/src/com/android/settings/applications/ProcessStatsDetail.java
+++ b/src/com/android/settings/applications/ProcessStatsDetail.java
@@ -168,6 +168,23 @@
}
}
+ private void addPackageHeaderItem(ViewGroup parent, String packageName) {
+ LayoutInflater inflater = getActivity().getLayoutInflater();
+ ViewGroup item = (ViewGroup) inflater.inflate(R.layout.running_processes_item,
+ null);
+ parent.addView(item);
+ final ImageView icon = (ImageView) item.findViewById(R.id.icon);
+ TextView nameView = (TextView) item.findViewById(R.id.name);
+ TextView descriptionView = (TextView) item.findViewById(R.id.description);
+ try {
+ ApplicationInfo ai = mPm.getApplicationInfo(packageName, 0);
+ icon.setImageDrawable(ai.loadIcon(mPm));
+ nameView.setText(ai.loadLabel(mPm));
+ } catch (PackageManager.NameNotFoundException e) {
+ }
+ descriptionView.setText(packageName);
+ }
+
private void addDetailsItem(ViewGroup parent, CharSequence label, CharSequence value) {
LayoutInflater inflater = getActivity().getLayoutInflater();
ViewGroup item = (ViewGroup) inflater.inflate(R.layout.power_usage_detail_item_text,
@@ -204,22 +221,31 @@
};
private void fillServicesSection() {
- LayoutInflater inflater = getActivity().getLayoutInflater();
if (mEntry.mServices.size() > 0) {
- ArrayList<ProcStatsEntry.Service> services =
- (ArrayList<ProcStatsEntry.Service>)mEntry.mServices.clone();
- Collections.sort(services, sServiceCompare);
- for (int i=0; i<services.size(); i++) {
- ProcStatsEntry.Service service = services.get(i);
- String label = service.mName;
- int tail = label.lastIndexOf('.');
- if (tail >= 0 && tail < (label.length()-1)) {
- label = label.substring(tail+1);
+ boolean addPackageSections = false;
+ if (mEntry.mServices.size() > 1
+ || !mEntry.mServices.valueAt(0).get(0).mPackage.equals(mEntry.mPackage)) {
+ addPackageSections = true;
+ }
+ for (int ip=0; ip<mEntry.mServices.size(); ip++) {
+ ArrayList<ProcStatsEntry.Service> services =
+ (ArrayList<ProcStatsEntry.Service>)mEntry.mServices.valueAt(ip).clone();
+ Collections.sort(services, sServiceCompare);
+ if (addPackageSections) {
+ addPackageHeaderItem(mServicesParent, services.get(0).mPackage);
}
- long duration = service.mDuration;
- final double percentOfTime = (((double)duration) / mTotalTime) * 100;
- addDetailsItem(mServicesParent, label, getActivity().getResources().getString(
- R.string.percentage, (int) Math.ceil(percentOfTime)));
+ for (int is=0; is<services.size(); is++) {
+ ProcStatsEntry.Service service = services.get(is);
+ String label = service.mName;
+ int tail = label.lastIndexOf('.');
+ if (tail >= 0 && tail < (label.length()-1)) {
+ label = label.substring(tail+1);
+ }
+ long duration = service.mDuration;
+ final double percentOfTime = (((double)duration) / mTotalTime) * 100;
+ addDetailsItem(mServicesParent, label, getActivity().getResources().getString(
+ R.string.percentage, (int) Math.ceil(percentOfTime)));
+ }
}
}
}
diff --git a/src/com/android/settings/applications/ProcessStatsPreference.java b/src/com/android/settings/applications/ProcessStatsPreference.java
index 2dea96a..bf2676d 100644
--- a/src/com/android/settings/applications/ProcessStatsPreference.java
+++ b/src/com/android/settings/applications/ProcessStatsPreference.java
@@ -45,7 +45,7 @@
public void setPercent(double percentOfWeight, double percentOfTime) {
mProgress = (int) Math.ceil(percentOfWeight);
mProgressText = getContext().getResources().getString(
- R.string.percentage, (int) Math.ceil(percentOfTime));
+ R.string.percentage, (int) Math.round(percentOfTime));
notifyChanged();
}
diff --git a/src/com/android/settings/applications/ProcessStatsUi.java b/src/com/android/settings/applications/ProcessStatsUi.java
index b7ffcef..0e27577 100644
--- a/src/com/android/settings/applications/ProcessStatsUi.java
+++ b/src/com/android/settings/applications/ProcessStatsUi.java
@@ -19,7 +19,6 @@
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Bundle;
-import android.os.Parcel;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -30,7 +29,6 @@
import android.preference.PreferenceFragment;
import android.preference.PreferenceGroup;
import android.preference.PreferenceScreen;
-import android.util.ArrayMap;
import android.util.Log;
import android.util.SparseArray;
import android.util.TimeUtils;
@@ -39,6 +37,7 @@
import android.view.MenuItem;
import android.view.SubMenu;
import com.android.internal.app.IProcessStats;
+import com.android.internal.app.ProcessMap;
import com.android.internal.app.ProcessStats;
import com.android.settings.R;
import com.android.settings.fuelgauge.Utils;
@@ -50,8 +49,8 @@
import java.util.Comparator;
public class ProcessStatsUi extends PreferenceFragment {
- private static final String TAG = "ProcessStatsUi";
- private static final boolean DEBUG = false;
+ static final String TAG = "ProcessStatsUi";
+ static final boolean DEBUG = false;
private static final String KEY_APP_LIST = "app_list";
private static final String KEY_MEM_STATUS = "mem_status";
@@ -76,6 +75,10 @@
return 1;
} else if (lhs.mWeight > rhs.mWeight) {
return -1;
+ } else if (lhs.mDuration < rhs.mDuration) {
+ return 1;
+ } else if (lhs.mDuration > rhs.mDuration) {
+ return -1;
}
return 0;
}
@@ -112,7 +115,7 @@
// batches of 3 hours so we want to allow the time we use to be slightly
// smaller than the actual time selected instead of bumping up to 3 hours
// beyond it.
- private static final long DURATION_QUANTUM = 3*60*60*1000;
+ private static final long DURATION_QUANTUM = ProcessStats.COMMIT_PERIOD;
private static long[] sDurations = new long[] {
3*60*60*1000 - DURATION_QUANTUM/2, 6*60*60*1000 - DURATION_QUANTUM/2,
12*60*60*1000 - DURATION_QUANTUM/2, 24*60*60*1000 - DURATION_QUANTUM/2
@@ -319,6 +322,12 @@
ProcessStats.STATE_CACHED_EMPTY
};
+ private String makeDuration(long time) {
+ StringBuilder sb = new StringBuilder(32);
+ TimeUtils.formatDuration(time, sb);
+ return sb.toString();
+ }
+
private void refreshStats() {
updateMenus();
@@ -378,6 +387,7 @@
mTotalTime = ProcessStats.dumpSingleTime(null, null, mStats.mMemFactorDurations,
mStats.mMemFactor, mStats.mStartTime, now);
+ if (DEBUG) Log.d(TAG, "Total time of stats: " + makeDuration(mTotalTime));
LinearColorPreference colors = new LinearColorPreference(getActivity());
colors.setOrder(-1);
@@ -396,7 +406,7 @@
+ memTimes[ProcessStats.ADJ_MEM_FACTOR_MODERATE]) / (float)mTotalTime,
memTimes[ProcessStats.ADJ_MEM_FACTOR_NORMAL] / (float)mTotalTime);
- ArrayList<ProcStatsEntry> procs = new ArrayList<ProcStatsEntry>();
+ ArrayList<ProcStatsEntry> entries = new ArrayList<ProcStatsEntry>();
/*
ArrayList<ProcessStats.ProcessState> rawProcs = mStats.collectProcessesLocked(
@@ -407,50 +417,43 @@
}
*/
- ArrayMap<String, ProcStatsEntry> processes = new ArrayMap<String, ProcStatsEntry>(
- mStats.mProcesses.getMap().size());
- for (int ip=0, N=mStats.mProcesses.getMap().size(); ip<N; ip++) {
- SparseArray<ProcessStats.ProcessState> uids = mStats.mProcesses.getMap().valueAt(ip);
- for (int iu=0; iu<uids.size(); iu++) {
- ProcStatsEntry ent = new ProcStatsEntry(uids.valueAt(iu), totals, mUseUss,
- mStatsType == MENU_TYPE_BACKGROUND);
- procs.add(ent);
- processes.put(ent.mName, ent);
+ if (DEBUG) Log.d(TAG, "-------------------- PULLING PROCESSES");
+
+ final ProcessMap<ProcStatsEntry> entriesMap = new ProcessMap<ProcStatsEntry>();
+ for (int ipkg=0, N=mStats.mPackages.getMap().size(); ipkg<N; ipkg++) {
+ final SparseArray<ProcessStats.PackageState> pkgUids
+ = mStats.mPackages.getMap().valueAt(ipkg);
+ for (int iu=0; iu<pkgUids.size(); iu++) {
+ final ProcessStats.PackageState st = pkgUids.valueAt(iu);
+ for (int iproc=0; iproc<st.mProcesses.size(); iproc++) {
+ final ProcessStats.ProcessState pkgProc = st.mProcesses.valueAt(iproc);
+ final ProcessStats.ProcessState proc = mStats.mProcesses.get(pkgProc.mName,
+ pkgProc.mUid);
+ if (proc == null) {
+ Log.w(TAG, "No process found for pkg " + st.mPackageName
+ + "/" + st.mUid + " proc name " + pkgProc.mName);
+ continue;
+ }
+ ProcStatsEntry ent = entriesMap.get(proc.mName, proc.mUid);
+ if (ent == null) {
+ ent = new ProcStatsEntry(proc, st.mPackageName, totals, mUseUss,
+ mStatsType == MENU_TYPE_BACKGROUND);
+ if (ent.mDuration > 0) {
+ if (DEBUG) Log.d(TAG, "Adding proc " + proc.mName + "/"
+ + proc.mUid + ": time=" + makeDuration(ent.mDuration) + " ("
+ + ((((double)ent.mDuration) / mTotalTime) * 100) + "%)"
+ + " pss=" + ent.mAvgPss);
+ entriesMap.put(proc.mName, proc.mUid, ent);
+ entries.add(ent);
+ }
+ } else {
+ ent.addPackage(st.mPackageName);
+ }
+ }
}
}
- Collections.sort(procs, sEntryCompare);
- while (procs.size() > MAX_ITEMS_TO_LIST) {
- procs.remove(procs.size()-1);
- }
-
- long maxWeight = 0;
- for (int i=0, N=(procs != null ? procs.size() : 0); i<N; i++) {
- ProcStatsEntry proc = procs.get(i);
- if (maxWeight < proc.mWeight) {
- maxWeight = proc.mWeight;
- }
- }
- mMaxWeight = maxWeight;
-
- for (int i=0, N=(procs != null ? procs.size() : 0); i<N; i++) {
- ProcStatsEntry proc = procs.get(i);
- final double percentOfWeight = (((double)proc.mWeight) / maxWeight) * 100;
- final double percentOfTime = (((double)proc.mDuration) / mTotalTime) * 100;
- if (percentOfWeight < 1) break;
- ProcessStatsPreference pref = new ProcessStatsPreference(getActivity(), null, proc);
- proc.evaluateTargetPackage(mStats, totals, sEntryCompare, mUseUss,
- mStatsType == MENU_TYPE_BACKGROUND);
- proc.retrieveUiData(pm);
- pref.setTitle(proc.mUiLabel);
- if (proc.mUiTargetApp != null) {
- pref.setIcon(proc.mUiTargetApp.loadIcon(pm));
- }
- pref.setOrder(i);
- pref.setPercent(percentOfWeight, percentOfTime);
- mAppListGroup.addPreference(pref);
- if (mAppListGroup.getPreferenceCount() > (MAX_ITEMS_TO_LIST+1)) break;
- }
+ if (DEBUG) Log.d(TAG, "-------------------- MAPPING SERVICES");
// Add in service info.
if (mStatsType == MENU_TYPE_BACKGROUND) {
@@ -461,13 +464,85 @@
for (int is=0, NS=ps.mServices.size(); is<NS; is++) {
ProcessStats.ServiceState ss = ps.mServices.valueAt(is);
if (ss.mProcessName != null) {
- ProcStatsEntry ent = processes.get(ss.mProcessName);
- ent.addService(ss);
+ ProcStatsEntry ent = entriesMap.get(ss.mProcessName, uids.keyAt(iu));
+ if (ent != null) {
+ if (DEBUG) Log.d(TAG, "Adding service " + ps.mPackageName
+ + "/" + ss.mName + "/" + uids.keyAt(iu) + " to proc "
+ + ss.mProcessName);
+ ent.addService(ss);
+ } else {
+ Log.w(TAG, "No process " + ss.mProcessName + "/" + uids.keyAt(iu)
+ + " for service " + ss.mName);
+ }
}
}
}
}
}
+
+ /*
+ SparseArray<ArrayMap<String, ProcStatsEntry>> processes
+ = new SparseArray<ArrayMap<String, ProcStatsEntry>>();
+ for (int ip=0, N=mStats.mProcesses.getMap().size(); ip<N; ip++) {
+ SparseArray<ProcessStats.ProcessState> uids = mStats.mProcesses.getMap().valueAt(ip);
+ for (int iu=0; iu<uids.size(); iu++) {
+ ProcessStats.ProcessState st = uids.valueAt(iu);
+ ProcStatsEntry ent = new ProcStatsEntry(st, totals, mUseUss,
+ mStatsType == MENU_TYPE_BACKGROUND);
+ if (ent.mDuration > 0) {
+ if (DEBUG) Log.d(TAG, "Adding proc " + st.mName + "/" + st.mUid + ": time="
+ + makeDuration(ent.mDuration) + " ("
+ + ((((double)ent.mDuration) / mTotalTime) * 100) + "%)");
+ procs.add(ent);
+ ArrayMap<String, ProcStatsEntry> uidProcs = processes.get(ent.mUid);
+ if (uidProcs == null) {
+ uidProcs = new ArrayMap<String, ProcStatsEntry>();
+ processes.put(ent.mUid, uidProcs);
+ }
+ uidProcs.put(ent.mName, ent);
+ }
+ }
+ }
+ */
+
+ Collections.sort(entries, sEntryCompare);
+
+ long maxWeight = 1;
+ for (int i=0, N=(entries != null ? entries.size() : 0); i<N; i++) {
+ ProcStatsEntry proc = entries.get(i);
+ if (maxWeight < proc.mWeight) {
+ maxWeight = proc.mWeight;
+ }
+ }
+ mMaxWeight = maxWeight;
+
+ if (DEBUG) Log.d(TAG, "-------------------- BUILDING UI");
+
+ for (int i=0, N=(entries != null ? entries.size() : 0); i<N; i++) {
+ ProcStatsEntry proc = entries.get(i);
+ final double percentOfWeight = (((double)proc.mWeight) / maxWeight) * 100;
+ final double percentOfTime = (((double)proc.mDuration) / mTotalTime) * 100;
+ if (percentOfWeight < 1 && percentOfTime < 33) {
+ if (DEBUG) Log.d(TAG, "Skipping " + proc.mName + " weight=" + percentOfWeight
+ + " time=" + percentOfTime);
+ continue;
+ }
+ ProcessStatsPreference pref = new ProcessStatsPreference(getActivity(), null, proc);
+ proc.evaluateTargetPackage(pm, mStats, totals, sEntryCompare, mUseUss,
+ mStatsType == MENU_TYPE_BACKGROUND);
+ proc.retrieveUiData(pm);
+ pref.setTitle(proc.mUiLabel);
+ if (proc.mUiTargetApp != null) {
+ pref.setIcon(proc.mUiTargetApp.loadIcon(pm));
+ }
+ pref.setOrder(i);
+ pref.setPercent(percentOfWeight, percentOfTime);
+ mAppListGroup.addPreference(pref);
+ if (mAppListGroup.getPreferenceCount() > (MAX_ITEMS_TO_LIST+1)) {
+ if (DEBUG) Log.d(TAG, "Done with UI, hit item limit!");
+ break;
+ }
+ }
}
private void load() {
diff --git a/src/com/android/settings/location/LocationMode.java b/src/com/android/settings/location/LocationMode.java
index 63ba6ea..233b010 100644
--- a/src/com/android/settings/location/LocationMode.java
+++ b/src/com/android/settings/location/LocationMode.java
@@ -45,12 +45,6 @@
private RadioButtonPreference mSensorsOnly;
@Override
- public void onActivityResult(int requestCode, int resultCode, Intent data) {
- super.onActivityResult(requestCode, resultCode, data);
- createPreferenceHierarchy();
- }
-
- @Override
public void onResume() {
super.onResume();
createPreferenceHierarchy();
diff --git a/src/com/android/settings/location/LocationSettings.java b/src/com/android/settings/location/LocationSettings.java
index add82c6..06a6650 100644
--- a/src/com/android/settings/location/LocationSettings.java
+++ b/src/com/android/settings/location/LocationSettings.java
@@ -37,7 +37,6 @@
import android.widget.Switch;
import com.android.settings.R;
-import com.android.settings.fuelgauge.BatteryStatsHelper;
import java.util.Collections;
import java.util.Comparator;
@@ -56,13 +55,12 @@
/** Key for preference category "Recent location requests" */
private static final String KEY_RECENT_LOCATION_REQUESTS = "recent_location_requests";
/** Key for preference category "Location services" */
- private static final String KEY_APP_SETTINGS = "app_settings";
+ private static final String KEY_LOCATION_SERVICES = "location_services";
private Switch mSwitch;
private boolean mValidListener;
private Preference mLocationMode;
private PreferenceCategory mCategoryRecentLocationRequests;
- private BatteryStatsHelper mStatsHelper;
/** Receives UPDATE_INTENT */
private BroadcastReceiver mReceiver;
@@ -71,24 +69,6 @@
}
@Override
- public void onActivityResult(int requestCode, int resultCode, Intent data) {
- super.onActivityResult(requestCode, resultCode, data);
- createPreferenceHierarchy();
- }
-
- @Override
- public void onAttach(Activity activity) {
- super.onAttach(activity);
- mStatsHelper = new BatteryStatsHelper(activity, null);
- }
-
- @Override
- public void onCreate(Bundle icicle) {
- super.onCreate(icicle);
- mStatsHelper.create(icicle);
- }
-
- @Override
public void onResume() {
super.onResume();
mSwitch = new Switch(getActivity());
@@ -107,13 +87,6 @@
super.onPause();
mValidListener = false;
mSwitch.setOnCheckedChangeListener(null);
- mStatsHelper.pause();
- }
-
- @Override
- public void onDestroy() {
- super.onDestroy();
- mStatsHelper.destroy();
}
private void addPreferencesSorted(List<Preference> prefs, PreferenceGroup container) {
@@ -153,7 +126,7 @@
mCategoryRecentLocationRequests =
(PreferenceCategory) root.findPreference(KEY_RECENT_LOCATION_REQUESTS);
- RecentLocationApps recentApps = new RecentLocationApps(activity, mStatsHelper);
+ RecentLocationApps recentApps = new RecentLocationApps(activity);
List<Preference> recentLocationRequests = recentApps.getAppList();
if (recentLocationRequests.size() > 0) {
addPreferencesSorted(recentLocationRequests, mCategoryRecentLocationRequests);
@@ -166,7 +139,7 @@
mCategoryRecentLocationRequests.addPreference(banner);
}
- addAppSettings(activity, root);
+ addLocationServices(activity, root);
// Only show the master switch when we're not in multi-pane mode, and not being used as
// Setup Wizard.
@@ -198,11 +171,11 @@
* up-to-date after mode changes even if an affected app doesn't send the setting changed
* broadcast.
*/
- private void addAppSettings(Context context, PreferenceScreen root) {
- PreferenceCategory categoryAppSettings =
- (PreferenceCategory) root.findPreference(KEY_APP_SETTINGS);
+ private void addLocationServices(Context context, PreferenceScreen root) {
+ PreferenceCategory categoryLocationServices =
+ (PreferenceCategory) root.findPreference(KEY_LOCATION_SERVICES);
final SettingsInjector injector = new SettingsInjector(context);
- List<Preference> appSettings = injector.getInjectedSettings();
+ List<Preference> locationServices = injector.getInjectedSettings();
mReceiver = new BroadcastReceiver() {
@Override
@@ -219,11 +192,11 @@
filter.addAction(LocationManager.MODE_CHANGED_ACTION);
context.registerReceiver(mReceiver, filter);
- if (appSettings.size() > 0) {
- addPreferencesSorted(appSettings, categoryAppSettings);
+ if (locationServices.size() > 0) {
+ addPreferencesSorted(locationServices, categoryLocationServices);
} else {
// If there's no item to display, remove the whole category.
- root.removePreference(categoryAppSettings);
+ root.removePreference(categoryLocationServices);
}
}
diff --git a/src/com/android/settings/location/RecentLocationApps.java b/src/com/android/settings/location/RecentLocationApps.java
index 9488db7..5708434 100644
--- a/src/com/android/settings/location/RecentLocationApps.java
+++ b/src/com/android/settings/location/RecentLocationApps.java
@@ -20,7 +20,6 @@
import android.app.AppOpsManager;
import android.content.Context;
import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
@@ -32,11 +31,8 @@
import com.android.settings.R;
import com.android.settings.applications.InstalledAppDetails;
-import com.android.settings.fuelgauge.BatterySipper;
-import com.android.settings.fuelgauge.BatteryStatsHelper;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.List;
/**
@@ -45,51 +41,15 @@
public class RecentLocationApps {
private static final String TAG = RecentLocationApps.class.getSimpleName();
private static final String ANDROID_SYSTEM_PACKAGE_NAME = "android";
- private static final String GOOGLE_SERVICES_SHARED_UID = "com.google.uid.shared";
- private static final String GCORE_PACKAGE_NAME = "com.google.android.gms";
private static final int RECENT_TIME_INTERVAL_MILLIS = 15 * 60 * 1000;
private final PreferenceActivity mActivity;
- private final BatteryStatsHelper mStatsHelper;
private final PackageManager mPackageManager;
- private final Drawable mGCoreIcon;
- // Stores all the packages that requested location within the designated interval
- // key - package name of the app
- // value - whether the app has requested high power location
-
- public RecentLocationApps(PreferenceActivity activity, BatteryStatsHelper sipperUtil) {
+ public RecentLocationApps(PreferenceActivity activity) {
mActivity = activity;
mPackageManager = activity.getPackageManager();
- mStatsHelper = sipperUtil;
- Drawable icon = null;
- try {
- ApplicationInfo appInfo = mPackageManager.getApplicationInfo(
- GCORE_PACKAGE_NAME, PackageManager.GET_META_DATA);
- icon = mPackageManager.getApplicationIcon(appInfo);
- } catch (PackageManager.NameNotFoundException e) {
- if (Log.isLoggable(TAG, Log.INFO)) {
- Log.i(TAG, "GCore not installed");
- }
- icon = null;
- }
- mGCoreIcon = icon;
- }
-
- private class UidEntryClickedListener
- implements Preference.OnPreferenceClickListener {
- private BatterySipper mSipper;
-
- public UidEntryClickedListener(BatterySipper sipper) {
- mSipper = sipper;
- }
-
- @Override
- public boolean onPreferenceClick(Preference preference) {
- mStatsHelper.startBatteryDetailPage(mActivity, mSipper, false);
- return true;
- }
}
private class PackageEntryClickedListener
@@ -129,49 +89,10 @@
}
/**
- * Stores a BatterySipper object and records whether the sipper has been used.
- */
- private static final class BatterySipperWrapper {
- private BatterySipper mSipper;
- private boolean mUsed;
-
- public BatterySipperWrapper(BatterySipper sipper) {
- mSipper = sipper;
- mUsed = false;
- }
-
- public BatterySipper batterySipper() {
- return mSipper;
- }
-
- public boolean used() {
- return mUsed;
- }
-
- public void setUsed() {
- mUsed = true;
- }
- }
-
- /**
* Fills a list of applications which queried location recently within
* specified time.
*/
public List<Preference> getAppList() {
- // Retrieve Uid-based battery blaming info and generate a package to BatterySipper HashMap
- // for later faster looking up.
- mStatsHelper.refreshStats(true);
- List<BatterySipper> usageList = mStatsHelper.getUsageList();
- // Key: package Uid. Value: BatterySipperWrapper.
- HashMap<Integer, BatterySipperWrapper> sipperMap =
- new HashMap<Integer, BatterySipperWrapper>(usageList.size());
- for (BatterySipper sipper: usageList) {
- int uid = sipper.getUid();
- if (uid != 0) {
- sipperMap.put(uid, new BatterySipperWrapper(sipper));
- }
- }
-
// Retrieve a location usage list from AppOps
AppOpsManager aoManager =
(AppOpsManager) mActivity.getSystemService(Context.APP_OPS_SERVICE);
@@ -191,8 +112,7 @@
boolean isAndroidOs = (uid == Process.SYSTEM_UID)
&& ANDROID_SYSTEM_PACKAGE_NAME.equals(ops.getPackageName());
if (!isAndroidOs && ActivityManager.getCurrentUser() == UserHandle.getUserId(uid)) {
- BatterySipperWrapper wrapper = sipperMap.get(uid);
- Preference pref = getPreferenceFromOps(now, ops, wrapper);
+ Preference pref = getPreferenceFromOps(now, ops);
if (pref != null) {
prefs.add(pref);
}
@@ -203,56 +123,14 @@
}
/**
- * Retrieves the icon for given BatterySipper object.
- *
- * The icons on location blaming page are actually Uid-based rather than package based. For
- * those packages that share the same Uid, BatteryStatsHelper picks the one with the most CPU
- * usage. Both "Contact Sync" and GCore belong to "Google Services" and they share the same Uid.
- * As a result, sometimes Contact icon may be chosen to represent "Google Services" by
- * BatteryStatsHelper.
- *
- * In order to avoid displaying Contact icon for "Google Services", we hack this method to
- * always return Puzzle icon for all packages that share the Uid of "Google Services".
- */
- private Drawable getIcon(BatterySipper sipper, AppOpsManager.PackageOps ops) {
- Drawable icon = null;
- if (mGCoreIcon != null) {
- try {
- PackageInfo info = mPackageManager.getPackageInfo(
- ops.getPackageName(), PackageManager.GET_META_DATA);
- if (info != null && GOOGLE_SERVICES_SHARED_UID.equals(info.sharedUserId)) {
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "shareUserId matches GCore, force using puzzle icon");
- }
- icon = mGCoreIcon;
- }
- } catch (PackageManager.NameNotFoundException e) {
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, e.toString());
- }
- }
- }
- if (icon == null) {
- icon = sipper.getIcon();
- }
- return icon;
- }
-
- /**
* 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, if the package has a corresponding battery blaming entry
- * in the Uid-based battery sipper list, this method returns a Preference pointing to the Uid
- * battery blaming page. If the package doesn't have a battery sipper entry (typically shouldn't
- * happen), this method returns a Preference pointing to the App Info page for that package.
+ * When the PackageOps is fresh enough, this method returns a Preference pointing to the App
+ * Info page for that package.
*/
- private Preference getPreferenceFromOps(
- long now,
- AppOpsManager.PackageOps ops,
- BatterySipperWrapper wrapper) {
+ private Preference getPreferenceFromOps(long now, AppOpsManager.PackageOps ops) {
String packageName = ops.getPackageName();
List<AppOpsManager.OpEntry> entries = ops.getOps();
boolean highBattery = false;
@@ -284,48 +162,27 @@
// The package is fresh enough, continue.
Preference pref = null;
- if (wrapper != null) {
- // Contains sipper. Link to Battery Blaming page.
-
- // We're listing by UID rather than package. Check whether the entry has been used
- // before to prevent the same UID from showing up twice.
- if (!wrapper.used()) {
- BatterySipper sipper = wrapper.batterySipper();
- sipper.loadNameAndIcon();
- pref = createRecentLocationEntry(
- getIcon(sipper, ops),
- sipper.getLabel(),
- highBattery,
- new UidEntryClickedListener(sipper));
- wrapper.setUsed();
- }
- } else {
- // No corresponding sipper. Link to App Info page.
-
- // This is grouped by package rather than UID, but that's OK because this branch
- // shouldn't happen in practice.
- try {
- ApplicationInfo appInfo = mPackageManager.getApplicationInfo(
- packageName, PackageManager.GET_META_DATA);
- // Multiple users can install the same package. Each user gets a different Uid for
- // the same package.
- //
- // Here we retrieve the Uid with package name, that will be the Uid for that package
- // associated with the current active user. If the Uid differs from the Uid in ops,
- // that means this entry belongs to another inactive user and we should ignore that.
- if (appInfo.uid == ops.getUid()) {
- pref = createRecentLocationEntry(
- mPackageManager.getApplicationIcon(appInfo),
- mPackageManager.getApplicationLabel(appInfo),
- highBattery,
- new PackageEntryClickedListener(packageName));
- } else if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "package " + packageName + " with Uid " + ops.getUid() +
- " belongs to another inactive account, ignored.");
- }
- } catch (PackageManager.NameNotFoundException e) {
- Log.wtf(TAG, "Package not found: " + packageName, e);
- }
+ try {
+ ApplicationInfo appInfo = mPackageManager.getApplicationInfo(
+ packageName, PackageManager.GET_META_DATA);
+ // Multiple users can install the same package. Each user gets a different Uid for
+ // the same package.
+ //
+ // Here we retrieve the Uid with package name, that will be the Uid for that package
+ // associated with the current active user. If the Uid differs from the Uid in ops,
+ // that means this entry belongs to another inactive user and we should ignore that.
+ if (appInfo.uid == ops.getUid()) {
+ pref = createRecentLocationEntry(
+ mPackageManager.getApplicationIcon(appInfo),
+ mPackageManager.getApplicationLabel(appInfo),
+ highBattery,
+ new PackageEntryClickedListener(packageName));
+ } else if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ Log.v(TAG, "package " + packageName + " with Uid " + ops.getUid() +
+ " belongs to another inactive account, ignored.");
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.wtf(TAG, "Package not found: " + packageName, e);
}
return pref;
diff --git a/src/com/android/settings/nfc/PaymentSettings.java b/src/com/android/settings/nfc/PaymentSettings.java
index 06697a4..7548c50 100644
--- a/src/com/android/settings/nfc/PaymentSettings.java
+++ b/src/com/android/settings/nfc/PaymentSettings.java
@@ -25,6 +25,7 @@
import android.preference.Preference;
import android.preference.PreferenceManager;
import android.preference.PreferenceScreen;
+import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
@@ -152,10 +153,13 @@
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
- inflater.inflate(R.menu.nfc_payment_settings, menu);
- MenuItem menuItem = menu.findItem(R.id.nfc_payment_menu_item_add_service);
- menuItem.setIntent(new Intent(Intent.ACTION_VIEW,
- Uri.parse(getString(R.string.download_nfc_payment_service_query))));
+ String searchUri = Settings.Secure.getString(getContentResolver(),
+ Settings.Secure.PAYMENT_SERVICE_SEARCH_URI);
+ if (!TextUtils.isEmpty(searchUri)) {
+ MenuItem menuItem = menu.add(R.string.nfc_payment_menu_item_add_service);
+ menuItem.setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_IF_ROOM);
+ menuItem.setIntent(new Intent(Intent.ACTION_VIEW,Uri.parse(searchUri)));
+ }
}
private final Handler mHandler = new Handler() {
diff --git a/src/com/android/settings/print/PrintServiceSettingsFragment.java b/src/com/android/settings/print/PrintServiceSettingsFragment.java
index 9db2dec..044d86e 100644
--- a/src/com/android/settings/print/PrintServiceSettingsFragment.java
+++ b/src/com/android/settings/print/PrintServiceSettingsFragment.java
@@ -95,6 +95,7 @@
@Override
public void onChanged() {
invalidateOptionsMenuIfNeeded();
+ updateEmptyView();
}
@Override
@@ -227,14 +228,15 @@
ViewGroup contentRoot = (ViewGroup) listView.getParent();
View emptyView = listView.getEmptyView();
if (!mToggleSwitch.isChecked()) {
- if (emptyView != null
- && emptyView.getId() != R.id.empty_printers_list_service_disabled) {
+ if (emptyView != null && emptyView.getId() != R.id.empty_print_state) {
contentRoot.removeView(emptyView);
emptyView = null;
}
if (emptyView == null) {
emptyView = getActivity().getLayoutInflater().inflate(
R.layout.empty_print_state, contentRoot, false);
+ ImageView iconView = (ImageView) emptyView.findViewById(R.id.icon);
+ iconView.setContentDescription(getString(R.string.print_service_disabled));
TextView textView = (TextView) emptyView.findViewById(R.id.message);
textView.setText(R.string.print_service_disabled);
contentRoot.addView(emptyView);
@@ -252,6 +254,21 @@
contentRoot.addView(emptyView);
listView.setEmptyView(emptyView);
}
+ } else if (mPrintersAdapter.getCount() <= 0) {
+ if (emptyView != null && emptyView.getId() != R.id.empty_print_state) {
+ contentRoot.removeView(emptyView);
+ emptyView = null;
+ }
+ if (emptyView == null) {
+ emptyView = getActivity().getLayoutInflater().inflate(
+ R.layout.empty_print_state, contentRoot, false);
+ ImageView iconView = (ImageView) emptyView.findViewById(R.id.icon);
+ iconView.setContentDescription(getString(R.string.print_no_printers_found));
+ TextView textView = (TextView) emptyView.findViewById(R.id.message);
+ textView.setText(R.string.print_no_printers_found);
+ contentRoot.addView(emptyView);
+ listView.setEmptyView(emptyView);
+ }
}
}
diff --git a/src/com/android/settings/print/PrintSettingsFragment.java b/src/com/android/settings/print/PrintSettingsFragment.java
index 84865c3..8d080ce 100644
--- a/src/com/android/settings/print/PrintSettingsFragment.java
+++ b/src/com/android/settings/print/PrintSettingsFragment.java
@@ -150,10 +150,13 @@
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
- inflater.inflate(R.menu.print_settings, menu);
- MenuItem menuItem = menu.findItem(R.id.print_menu_item_add_service);
- menuItem.setIntent(new Intent(Intent.ACTION_VIEW,
- Uri.parse(getString(R.string.download_print_service_query))));
+ String searchUri = Settings.Secure.getString(getContentResolver(),
+ Settings.Secure.PRINT_SERVICE_SEARCH_URI);
+ if (!TextUtils.isEmpty(searchUri)) {
+ MenuItem menuItem = menu.add(R.string.print_menu_item_add_service);
+ menuItem.setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_IF_ROOM);
+ menuItem.setIntent(new Intent(Intent.ACTION_VIEW,Uri.parse(searchUri)));
+ }
}
@Override