Merge "Fix issue #10948509: Crash in procstats when there is no data" into klp-dev
diff --git a/res/layout/nfc_payment.xml b/res/layout/nfc_payment.xml
index 54ac403..d6f9fa4 100644
--- a/res/layout/nfc_payment.xml
+++ b/res/layout/nfc_payment.xml
@@ -23,6 +23,18 @@
android:visibility="gone"
android:paddingTop="16dp"
android:text="@string/nfc_payment_no_apps"/>
+ <TextView
+ android:id="@+id/nfc_payment_learn_more"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:clickable="true"
+ android:textSize="20sp"
+ android:textStyle="italic"
+ android:visibility="gone"
+ android:textColor="@android:color/holo_blue_light"
+ android:paddingTop="16dp"
+ android:text="@string/nfc_payment_learn_more"/>
</LinearLayout>
<ListView
android:id="@android:id/list"
diff --git a/res/layout/printer_dropdown_item.xml b/res/layout/printer_dropdown_item.xml
new file mode 100644
index 0000000..ad393b8
--- /dev/null
+++ b/res/layout/printer_dropdown_item.xml
@@ -0,0 +1,67 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="48dip"
+ android:gravity="center_vertical"
+ android:paddingStart="@*android:dimen/preference_item_padding_side"
+ android:paddingEnd="?android:attr/scrollbarSize"
+ android:background="?android:attr/selectableItemBackground">
+
+ <ImageView
+ android:id="@+id/icon"
+ android:layout_width="32dip"
+ android:layout_height="32dip"
+ android:layout_gravity="center_vertical"
+ android:layout_marginEnd="8dip"
+ android:duplicateParentState="true"
+ android:contentDescription="@null"
+ android:visibility="gone">
+ </ImageView>
+
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <TextView
+ android:id="@+id/title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:singleLine="true"
+ android:ellipsize="marquee"
+ android:fadingEdge="horizontal"
+ android:textIsSelectable="false">
+ </TextView>
+
+ <TextView
+ android:id="@+id/subtitle"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:singleLine="true"
+ android:ellipsize="end"
+ android:textIsSelectable="false"
+ android:visibility="gone"
+ android:textColor="?android:attr/textColorSecondary">
+ </TextView>
+
+ </LinearLayout>
+
+</LinearLayout>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index bd385f6..40098f5 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -35,7 +35,8 @@
<color name="divider_color">#20ffffff</color>
<color name="title_color">@android:color/holo_blue_light</color>
- <color name="setup_divider_color">#333333</color>
+ <color name="setup_divider_color_dark">#33ffffff</color>
+ <color name="setup_divider_color_light">#33000000</color>
<color name="circle_avatar_frame_color">#ffffffff</color>
<color name="circle_avatar_frame_shadow_color">#80000000</color>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 79a4c92..3c45bbc 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -4778,7 +4778,10 @@
<!-- NFC payment settings --><skip/>
<string name="nfc_payment_settings_title">Tap & pay</string>
<!-- String shown when there are no NFC payment applications installed -->
- <string name="nfc_payment_no_apps">You have no apps configured for tap & pay with NFC.</string>
+ <string name="nfc_payment_no_apps">Pay with just a tap</string>
+ <!-- String shown when there are no NFC payment applications installed, clickable, pointing to
+ a website to learn more-->
+ <string name="nfc_payment_learn_more">Learn more</string>
<string name="nfc_payment_menu_item_add_service">Find apps</string>
<!-- Label for the dialog that is shown when the user is asked to set a
preferred payment application -->
@@ -4830,6 +4833,8 @@
<string name="help_url_location_access" translatable="false"></string>
<!-- Help URL, Security settings [DO NOT TRANSLATE] -->
<string name="help_url_security" translatable="false"></string>
+ <!-- Help URL, Tap & pay [DO NOT TRANSLATE] -->
+ <string name="help_url_nfc_payment" translatable="false"></string>
<!-- User account title [CHAR LIMIT=30] -->
<string name="user_account_title">Account for content</string>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 4805cb6..eee2cd9 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -130,7 +130,7 @@
<style name="TopDivider">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">@dimen/divider_height</item>
- <item name="android:background">@color/setup_divider_color</item>
+ <item name="android:background">?attr/setup_divider_color</item>
<item name="android:focusable">false</item>
<item name="android:clickable">false</item>
<item name="android:layout_marginTop">@dimen/divider_margin_top</item>
diff --git a/res/values/themes.xml b/res/values/themes.xml
index 19d1e91..a87ad33 100644
--- a/res/values/themes.xml
+++ b/res/values/themes.xml
@@ -18,6 +18,7 @@
<attr name="ic_menu_add" format="reference" />
<attr name="ic_menu_moreoverflow" format="reference" />
<attr name="ic_wps" format="reference" />
+ <attr name="setup_divider_color" format="reference" />
<attr name="wifi_signal" format="reference" />
<style name="SetupWizardWifiTheme" parent="android:Theme.Holo.NoActionBar">
@@ -27,6 +28,7 @@
<item name="ic_menu_add">@drawable/ic_menu_add_dark</item>
<item name="ic_menu_moreoverflow">@*android:drawable/ic_menu_moreoverflow_holo_dark</item>
<item name="ic_wps">@drawable/ic_wps_dark</item>
+ <item name="setup_divider_color">@color/setup_divider_color_dark</item>
<item name="wifi_signal">@drawable/wifi_signal_dark</item>
</style>
@@ -37,6 +39,7 @@
<item name="ic_menu_add">@drawable/ic_menu_add_light</item>
<item name="ic_menu_moreoverflow">@*android:drawable/ic_menu_moreoverflow_holo_light</item>
<item name="ic_wps">@drawable/ic_wps_light</item>
+ <item name="setup_divider_color">@color/setup_divider_color_light</item>
<item name="wifi_signal">@drawable/wifi_signal_light</item>
</style>
diff --git a/src/com/android/settings/HelpUtils.java b/src/com/android/settings/HelpUtils.java
index 6cd5eb6..22e2f76 100644
--- a/src/com/android/settings/HelpUtils.java
+++ b/src/com/android/settings/HelpUtils.java
@@ -16,6 +16,7 @@
package com.android.settings;
+import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
@@ -95,9 +96,15 @@
// Set the intent to the help menu item, show the help menu item in the overflow
// menu, and make it visible.
- helpMenuItem.setIntent(intent);
- helpMenuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
- helpMenuItem.setVisible(true);
+ ComponentName component = intent.resolveActivity(context.getPackageManager());
+ if (component != null) {
+ helpMenuItem.setIntent(intent);
+ helpMenuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
+ helpMenuItem.setVisible(true);
+ } else {
+ helpMenuItem.setVisible(false);
+ return false;
+ }
// return that the help menu item is visible (i.e., true)
return true;
@@ -109,7 +116,7 @@
* of the app's package as gotten via the context.
* @return the uri with added query parameters
*/
- private static Uri uriWithAddedParameters(Context context, Uri baseUri) {
+ public static Uri uriWithAddedParameters(Context context, Uri baseUri) {
Uri.Builder builder = baseUri.buildUpon();
// Add in the preferred language
diff --git a/src/com/android/settings/accessibility/ToggleCaptioningPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleCaptioningPreferenceFragment.java
index 3934646..f3c8b1c 100644
--- a/src/com/android/settings/accessibility/ToggleCaptioningPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleCaptioningPreferenceFragment.java
@@ -92,6 +92,8 @@
final CharSequence localizedText = AccessibilityUtils.getTextForLocale(
activity, locale, R.string.captioning_preview_text);
preview.setText(localizedText);
+ } else {
+ preview.setText(R.string.captioning_preview_text);
}
}
}
@@ -110,6 +112,8 @@
final CharSequence localizedText = AccessibilityUtils.getTextForLocale(
context, locale, R.string.captioning_preview_characters);
previewText.setText(localizedText);
+ } else {
+ previewText.setText(R.string.captioning_preview_characters);
}
}
diff --git a/src/com/android/settings/location/RecentLocationApps.java b/src/com/android/settings/location/RecentLocationApps.java
index 3cd5406..9488db7 100644
--- a/src/com/android/settings/location/RecentLocationApps.java
+++ b/src/com/android/settings/location/RecentLocationApps.java
@@ -20,6 +20,7 @@
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;
@@ -44,12 +45,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
@@ -59,6 +63,18 @@
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
@@ -187,6 +203,42 @@
}
/**
+ * 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
@@ -241,7 +293,7 @@
BatterySipper sipper = wrapper.batterySipper();
sipper.loadNameAndIcon();
pref = createRecentLocationEntry(
- sipper.getIcon(),
+ getIcon(sipper, ops),
sipper.getLabel(),
highBattery,
new UidEntryClickedListener(sipper));
diff --git a/src/com/android/settings/nfc/PaymentSettings.java b/src/com/android/settings/nfc/PaymentSettings.java
index f839b24..06697a4 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.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
@@ -38,6 +39,7 @@
import android.widget.TextView;
import com.android.internal.content.PackageMonitor;
+import com.android.settings.HelpUtils;
import com.android.settings.R;
import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.nfc.PaymentBackend.PaymentAppInfo;
@@ -49,7 +51,6 @@
public static final String TAG = "PaymentSettings";
private LayoutInflater mInflater;
private PaymentBackend mPaymentBackend;
-
private final PackageMonitor mSettingsPackageMonitor = new SettingsPackageMonitor();
@@ -57,7 +58,6 @@
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
- setHasOptionsMenu(false);
mPaymentBackend = new PaymentBackend(getActivity());
mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
setHasOptionsMenu(true);
@@ -83,13 +83,18 @@
}
}
TextView emptyText = (TextView) getView().findViewById(R.id.nfc_payment_empty_text);
+ TextView learnMore = (TextView) getView().findViewById(R.id.nfc_payment_learn_more);
ImageView emptyImage = (ImageView) getView().findViewById(R.id.nfc_payment_tap_image);
if (screen.getPreferenceCount() == 0) {
emptyText.setVisibility(View.VISIBLE);
+ learnMore.setVisibility(View.VISIBLE);
emptyImage.setVisibility(View.VISIBLE);
+ getListView().setVisibility(View.GONE);
} else {
emptyText.setVisibility(View.GONE);
+ learnMore.setVisibility(View.GONE);
emptyImage.setVisibility(View.GONE);
+ getListView().setVisibility(View.VISIBLE);
}
setPreferenceScreen(screen);
}
@@ -99,6 +104,24 @@
Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
View v = mInflater.inflate(R.layout.nfc_payment, container, false);
+ TextView learnMore = (TextView) v.findViewById(R.id.nfc_payment_learn_more);
+ learnMore.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ String helpUrl;
+ if (!TextUtils.isEmpty(helpUrl = getResources().getString(
+ R.string.help_url_nfc_payment))) {
+ final Uri fullUri = HelpUtils.uriWithAddedParameters(
+ PaymentSettings.this.getActivity(), Uri.parse(helpUrl));
+ Intent intent = new Intent(Intent.ACTION_VIEW, fullUri);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+ | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
+ startActivity(intent);
+ } else {
+ Log.e(TAG, "Help url not set.");
+ }
+ }
+ });
return v;
}
@@ -190,4 +213,4 @@
banner.setImageDrawable(appInfo.banner);
}
}
-}
\ No newline at end of file
+}
diff --git a/src/com/android/settings/print/PrintServiceSettingsFragment.java b/src/com/android/settings/print/PrintServiceSettingsFragment.java
index d2d8525..9db2dec 100644
--- a/src/com/android/settings/print/PrintServiceSettingsFragment.java
+++ b/src/com/android/settings/print/PrintServiceSettingsFragment.java
@@ -32,6 +32,9 @@
import android.content.pm.ResolveInfo;
import android.database.ContentObserver;
import android.database.DataSetObserver;
+import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
@@ -54,6 +57,7 @@
import android.widget.CompoundButton;
import android.widget.Filter;
import android.widget.Filterable;
+import android.widget.ImageView;
import android.widget.ListView;
import android.widget.SearchView;
import android.widget.TextView;
@@ -293,7 +297,7 @@
}
});
- getListView().setEnabled(false);
+ getListView().setSelector(new ColorDrawable(Color.TRANSPARENT));
getListView().setAdapter(mPrintersAdapter);
}
@@ -531,24 +535,26 @@
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = getActivity().getLayoutInflater().inflate(
- R.layout.preference, parent, false);
+ R.layout.printer_dropdown_item, parent, false);
}
PrinterInfo printer = (PrinterInfo) getItem(position);
CharSequence title = printer.getName();
CharSequence subtitle = null;
+ Drawable icon = null;
try {
PackageInfo packageInfo = getPackageManager().getPackageInfo(
printer.getId().getServiceName().getPackageName(), 0);
subtitle = packageInfo.applicationInfo.loadLabel(getPackageManager());
+ icon = packageInfo.applicationInfo.loadIcon(getPackageManager());
} catch (NameNotFoundException nnfe) {
/* ignore */
}
- TextView titleView = (TextView) convertView.findViewById(android.R.id.title);
+ TextView titleView = (TextView) convertView.findViewById(R.id.title);
titleView.setText(title);
- TextView subtitleView = (TextView) convertView.findViewById(android.R.id.summary);
+ TextView subtitleView = (TextView) convertView.findViewById(R.id.subtitle);
if (!TextUtils.isEmpty(subtitle)) {
subtitleView.setText(subtitle);
subtitleView.setVisibility(View.VISIBLE);
@@ -557,6 +563,14 @@
subtitleView.setVisibility(View.GONE);
}
+ ImageView iconView = (ImageView) convertView.findViewById(R.id.icon);
+ if (icon != null) {
+ iconView.setImageDrawable(icon);
+ iconView.setVisibility(View.VISIBLE);
+ } else {
+ iconView.setVisibility(View.GONE);
+ }
+
return convertView;
}