Merge "adding Android Beam sample"
diff --git a/CleanSpec.mk b/CleanSpec.mk
index eb8471a..1c85279 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -114,6 +114,7 @@
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/fonts/Lohit_Hindi.ttf)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/media/audio/)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/fonts/DroidSans*)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/media/audio/)
 # ************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
 # ************************************************
diff --git a/api/14.txt b/api/14.txt
index 9f2a6df..e26311f 100644
--- a/api/14.txt
+++ b/api/14.txt
@@ -16583,10 +16583,6 @@
     field public static final java.lang.String PHOTO_FILE_ID = "data14";
   }
 
-  public static final class ContactsContract.Contacts.StreamItems implements android.provider.ContactsContract.StreamItemsColumns {
-    field public static final java.lang.String CONTENT_DIRECTORY = "stream_items";
-  }
-
   protected static abstract interface ContactsContract.ContactsColumns {
     field public static final java.lang.String DISPLAY_NAME = "display_name";
     field public static final java.lang.String HAS_PHONE_NUMBER = "has_phone_number";
@@ -16844,10 +16840,6 @@
     field public static final java.lang.String DATA_ID = "data_id";
   }
 
-  public static final class ContactsContract.RawContacts.StreamItems implements android.provider.BaseColumns android.provider.ContactsContract.StreamItemsColumns {
-    field public static final java.lang.String CONTENT_DIRECTORY = "stream_items";
-  }
-
   protected static abstract interface ContactsContract.RawContactsColumns {
     field public static final java.lang.String AGGREGATION_MODE = "aggregation_mode";
     field public static final java.lang.String CONTACT_ID = "contact_id";
@@ -16911,56 +16903,6 @@
     field public static final android.net.Uri PROFILE_CONTENT_URI;
   }
 
-  public static final class ContactsContract.StreamItemPhotos implements android.provider.BaseColumns android.provider.ContactsContract.StreamItemPhotosColumns {
-    field public static final java.lang.String PHOTO = "photo";
-  }
-
-  protected static abstract interface ContactsContract.StreamItemPhotosColumns {
-    field public static final java.lang.String PHOTO_FILE_ID = "photo_file_id";
-    field public static final java.lang.String PHOTO_URI = "photo_uri";
-    field public static final java.lang.String SORT_INDEX = "sort_index";
-    field public static final java.lang.String STREAM_ITEM_ID = "stream_item_id";
-    field public static final java.lang.String SYNC1 = "stream_item_photo_sync1";
-    field public static final java.lang.String SYNC2 = "stream_item_photo_sync2";
-    field public static final java.lang.String SYNC3 = "stream_item_photo_sync3";
-    field public static final java.lang.String SYNC4 = "stream_item_photo_sync4";
-  }
-
-  public static final class ContactsContract.StreamItems implements android.provider.BaseColumns android.provider.ContactsContract.StreamItemsColumns {
-    field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/stream_item";
-    field public static final android.net.Uri CONTENT_LIMIT_URI;
-    field public static final android.net.Uri CONTENT_PHOTO_URI;
-    field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/stream_item";
-    field public static final android.net.Uri CONTENT_URI;
-    field public static final java.lang.String MAX_ITEMS = "max_items";
-  }
-
-  public static final class ContactsContract.StreamItems.StreamItemPhotos implements android.provider.BaseColumns android.provider.ContactsContract.StreamItemPhotosColumns {
-    field public static final java.lang.String CONTENT_DIRECTORY = "photo";
-    field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/stream_item_photo";
-    field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/stream_item_photo";
-  }
-
-  protected static abstract interface ContactsContract.StreamItemsColumns {
-    field public static final java.lang.String ACCOUNT_NAME = "account_name";
-    field public static final java.lang.String ACCOUNT_TYPE = "account_type";
-    field public static final java.lang.String COMMENTS = "comments";
-    field public static final java.lang.String CONTACT_ID = "contact_id";
-    field public static final java.lang.String CONTACT_LOOKUP_KEY = "contact_lookup";
-    field public static final java.lang.String DATA_SET = "data_set";
-    field public static final java.lang.String RAW_CONTACT_ID = "raw_contact_id";
-    field public static final java.lang.String RAW_CONTACT_SOURCE_ID = "raw_contact_source_id";
-    field public static final java.lang.String RES_ICON = "icon";
-    field public static final java.lang.String RES_LABEL = "label";
-    field public static final java.lang.String RES_PACKAGE = "res_package";
-    field public static final java.lang.String SYNC1 = "stream_item_sync1";
-    field public static final java.lang.String SYNC2 = "stream_item_sync2";
-    field public static final java.lang.String SYNC3 = "stream_item_sync3";
-    field public static final java.lang.String SYNC4 = "stream_item_sync4";
-    field public static final java.lang.String TEXT = "text";
-    field public static final java.lang.String TIMESTAMP = "timestamp";
-  }
-
   protected static abstract interface ContactsContract.SyncColumns implements android.provider.ContactsContract.BaseSyncColumns {
     field public static final java.lang.String ACCOUNT_NAME = "account_name";
     field public static final java.lang.String ACCOUNT_TYPE = "account_type";
diff --git a/api/current.txt b/api/current.txt
index 9f2a6df..e26311f 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -16583,10 +16583,6 @@
     field public static final java.lang.String PHOTO_FILE_ID = "data14";
   }
 
-  public static final class ContactsContract.Contacts.StreamItems implements android.provider.ContactsContract.StreamItemsColumns {
-    field public static final java.lang.String CONTENT_DIRECTORY = "stream_items";
-  }
-
   protected static abstract interface ContactsContract.ContactsColumns {
     field public static final java.lang.String DISPLAY_NAME = "display_name";
     field public static final java.lang.String HAS_PHONE_NUMBER = "has_phone_number";
@@ -16844,10 +16840,6 @@
     field public static final java.lang.String DATA_ID = "data_id";
   }
 
-  public static final class ContactsContract.RawContacts.StreamItems implements android.provider.BaseColumns android.provider.ContactsContract.StreamItemsColumns {
-    field public static final java.lang.String CONTENT_DIRECTORY = "stream_items";
-  }
-
   protected static abstract interface ContactsContract.RawContactsColumns {
     field public static final java.lang.String AGGREGATION_MODE = "aggregation_mode";
     field public static final java.lang.String CONTACT_ID = "contact_id";
@@ -16911,56 +16903,6 @@
     field public static final android.net.Uri PROFILE_CONTENT_URI;
   }
 
-  public static final class ContactsContract.StreamItemPhotos implements android.provider.BaseColumns android.provider.ContactsContract.StreamItemPhotosColumns {
-    field public static final java.lang.String PHOTO = "photo";
-  }
-
-  protected static abstract interface ContactsContract.StreamItemPhotosColumns {
-    field public static final java.lang.String PHOTO_FILE_ID = "photo_file_id";
-    field public static final java.lang.String PHOTO_URI = "photo_uri";
-    field public static final java.lang.String SORT_INDEX = "sort_index";
-    field public static final java.lang.String STREAM_ITEM_ID = "stream_item_id";
-    field public static final java.lang.String SYNC1 = "stream_item_photo_sync1";
-    field public static final java.lang.String SYNC2 = "stream_item_photo_sync2";
-    field public static final java.lang.String SYNC3 = "stream_item_photo_sync3";
-    field public static final java.lang.String SYNC4 = "stream_item_photo_sync4";
-  }
-
-  public static final class ContactsContract.StreamItems implements android.provider.BaseColumns android.provider.ContactsContract.StreamItemsColumns {
-    field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/stream_item";
-    field public static final android.net.Uri CONTENT_LIMIT_URI;
-    field public static final android.net.Uri CONTENT_PHOTO_URI;
-    field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/stream_item";
-    field public static final android.net.Uri CONTENT_URI;
-    field public static final java.lang.String MAX_ITEMS = "max_items";
-  }
-
-  public static final class ContactsContract.StreamItems.StreamItemPhotos implements android.provider.BaseColumns android.provider.ContactsContract.StreamItemPhotosColumns {
-    field public static final java.lang.String CONTENT_DIRECTORY = "photo";
-    field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/stream_item_photo";
-    field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/stream_item_photo";
-  }
-
-  protected static abstract interface ContactsContract.StreamItemsColumns {
-    field public static final java.lang.String ACCOUNT_NAME = "account_name";
-    field public static final java.lang.String ACCOUNT_TYPE = "account_type";
-    field public static final java.lang.String COMMENTS = "comments";
-    field public static final java.lang.String CONTACT_ID = "contact_id";
-    field public static final java.lang.String CONTACT_LOOKUP_KEY = "contact_lookup";
-    field public static final java.lang.String DATA_SET = "data_set";
-    field public static final java.lang.String RAW_CONTACT_ID = "raw_contact_id";
-    field public static final java.lang.String RAW_CONTACT_SOURCE_ID = "raw_contact_source_id";
-    field public static final java.lang.String RES_ICON = "icon";
-    field public static final java.lang.String RES_LABEL = "label";
-    field public static final java.lang.String RES_PACKAGE = "res_package";
-    field public static final java.lang.String SYNC1 = "stream_item_sync1";
-    field public static final java.lang.String SYNC2 = "stream_item_sync2";
-    field public static final java.lang.String SYNC3 = "stream_item_sync3";
-    field public static final java.lang.String SYNC4 = "stream_item_sync4";
-    field public static final java.lang.String TEXT = "text";
-    field public static final java.lang.String TIMESTAMP = "timestamp";
-  }
-
   protected static abstract interface ContactsContract.SyncColumns implements android.provider.ContactsContract.BaseSyncColumns {
     field public static final java.lang.String ACCOUNT_NAME = "account_name";
     field public static final java.lang.String ACCOUNT_TYPE = "account_type";
diff --git a/cmds/bu/src/com/android/commands/bu/Backup.java b/cmds/bu/src/com/android/commands/bu/Backup.java
index 4c4bf98..046ccca 100644
--- a/cmds/bu/src/com/android/commands/bu/Backup.java
+++ b/cmds/bu/src/com/android/commands/bu/Backup.java
@@ -66,6 +66,7 @@
         boolean saveApks = false;
         boolean saveShared = false;
         boolean doEverything = false;
+        boolean allIncludesSystem = true;
 
         String arg;
         while ((arg = nextArg()) != null) {
@@ -78,6 +79,10 @@
                     saveShared = true;
                 } else if ("-noshared".equals(arg)) {
                     saveShared = false;
+                } else if ("-system".equals(arg)) {
+                    allIncludesSystem = true;
+                } else if ("-nosystem".equals(arg)) {
+                    allIncludesSystem = false;
                 } else if ("-all".equals(arg)) {
                     doEverything = true;
                 } else {
@@ -102,7 +107,7 @@
         try {
             ParcelFileDescriptor fd = ParcelFileDescriptor.adoptFd(socketFd);
             String[] packArray = new String[packages.size()];
-            mBackupManager.fullBackup(fd, saveApks, saveShared, doEverything,
+            mBackupManager.fullBackup(fd, saveApks, saveShared, doEverything, allIncludesSystem,
                     packages.toArray(packArray));
         } catch (RemoteException e) {
             Log.e(TAG, "Unable to invoke backup manager for backup");
diff --git a/core/java/android/app/ActionBar.java b/core/java/android/app/ActionBar.java
index 51c6f3a..24d3a6b 100644
--- a/core/java/android/app/ActionBar.java
+++ b/core/java/android/app/ActionBar.java
@@ -43,15 +43,18 @@
  * modify various characteristics of the action bar or remove it completely.</p>
  * <p>From your activity, you can retrieve an instance of {@link ActionBar} by calling {@link
  * android.app.Activity#getActionBar getActionBar()}.</p>
- * <p>For information about how to use the action bar, including how to add action items, navigation
- * modes and more, read the <a href="{@docRoot}guide/topics/ui/actionbar.html">Action
- * Bar</a> developer guide.</p>
  * <p>In some cases, the action bar may be overlayed by another bar that enables contextual actions,
  * using an {@link android.view.ActionMode}. For example, when the user selects one or more items in
  * your activity, you can enable an action mode that offers actions specific to the selected
  * items, with a UI that temporarily replaces the action bar. Although the UI may occupy the
  * same space, the {@link android.view.ActionMode} APIs are distinct and independent from those for
  * {@link ActionBar}.
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For information about how to use the action bar, including how to add action items, navigation
+ * modes and more, read the <a href="{@docRoot}guide/topics/ui/actionbar.html">Action
+ * Bar</a> developer guide.</p>
+ * </div>
  */
 public abstract class ActionBar {
     /**
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 034e3c7..8e8d37d 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -111,18 +111,6 @@
  * {@link android.R.styleable#AndroidManifestActivity &lt;activity&gt;}
  * declaration in their package's <code>AndroidManifest.xml</code>.</p>
  * 
- * <p>The Activity class is an important part of an application's overall lifecycle,
- * and the way activities are launched and put together is a fundamental
- * part of the platform's application model. For a detailed perspective on the structure of an
- * Android application and how activities behave, please read the
- * <a href="{@docRoot}guide/topics/fundamentals.html">Application Fundamentals</a> and
- * <a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and Back Stack</a>
- * documents.</p>
- *
- * <p>You can also find a detailed discussion about how to create activities in the
- * <a href="{@docRoot}guide/topics/fundamentals/activities.html">Activities</a>
- * document.</p>
- * 
  * <p>Topics covered here:
  * <ol>
  * <li><a href="#Fragments">Fragments</a>
@@ -133,7 +121,22 @@
  * <li><a href="#Permissions">Permissions</a>
  * <li><a href="#ProcessLifecycle">Process Lifecycle</a>
  * </ol>
- * 
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>The Activity class is an important part of an application's overall lifecycle,
+ * and the way activities are launched and put together is a fundamental
+ * part of the platform's application model. For a detailed perspective on the structure of an
+ * Android application and how activities behave, please read the
+ * <a href="{@docRoot}guide/topics/fundamentals.html">Application Fundamentals</a> and
+ * <a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and Back Stack</a>
+ * developer guides.</p>
+ *
+ * <p>You can also find a detailed discussion about how to create activities in the
+ * <a href="{@docRoot}guide/topics/fundamentals/activities.html">Activities</a>
+ * developer guide.</p>
+ * </div>
+ *
  * <a name="Fragments"></a>
  * <h3>Fragments</h3>
  *
@@ -3246,6 +3249,7 @@
         try {
             String resolvedType = null;
             if (fillInIntent != null) {
+                fillInIntent.setAllowFds(false);
                 resolvedType = fillInIntent.resolveTypeIfNeeded(getContentResolver());
             }
             int result = ActivityManagerNative.getDefault()
@@ -3370,6 +3374,7 @@
         if (mParent == null) {
             int result = IActivityManager.START_RETURN_INTENT_TO_CALLER;
             try {
+                intent.setAllowFds(false);
                 result = ActivityManagerNative.getDefault()
                     .startActivity(mMainThread.getApplicationThread(),
                             intent, intent.resolveTypeIfNeeded(
@@ -3419,6 +3424,7 @@
     public boolean startNextMatchingActivity(Intent intent) {
         if (mParent == null) {
             try {
+                intent.setAllowFds(false);
                 return ActivityManagerNative.getDefault()
                     .startNextMatchingActivity(mToken, intent);
             } catch (RemoteException e) {
@@ -3692,6 +3698,9 @@
             }
             if (false) Log.v(TAG, "Finishing self: token=" + mToken);
             try {
+                if (resultData != null) {
+                    resultData.setAllowFds(false);
+                }
                 if (ActivityManagerNative.getDefault()
                     .finishActivity(mToken, resultCode, resultData)) {
                     mFinished = true;
@@ -3812,6 +3821,7 @@
             int flags) {
         String packageName = getPackageName();
         try {
+            data.setAllowFds(false);
             IIntentSender target =
                 ActivityManagerNative.getDefault().getIntentSender(
                         IActivityManager.INTENT_SENDER_ACTIVITY_RESULT, packageName,
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 0776e10..99aae37 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -2674,6 +2674,7 @@
             // Next have the activity save its current state and managed dialogs...
             if (!r.activity.mFinished && saveState) {
                 state = new Bundle();
+                state.setAllowFds(false);
                 mInstrumentation.callActivityOnSaveInstanceState(r.activity, state);
                 r.state = state;
             }
@@ -2775,6 +2776,7 @@
             if (!r.activity.mFinished && saveState) {
                 if (r.state == null) {
                     state = new Bundle();
+                    state.setAllowFds(false);
                     mInstrumentation.callActivityOnSaveInstanceState(r.activity, state);
                     r.state = state;
                 } else {
@@ -3306,6 +3308,7 @@
         }
         if (r.state == null && !r.stopped && !r.isPreHoneycomb()) {
             r.state = new Bundle();
+            r.state.setAllowFds(false);
             mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state);
         }
 
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 2139704..2bf1fb7 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -874,6 +874,7 @@
         try {
             String resolvedType = null;
             if (fillInIntent != null) {
+                fillInIntent.setAllowFds(false);
                 resolvedType = fillInIntent.resolveTypeIfNeeded(getContentResolver());
             }
             int result = ActivityManagerNative.getDefault()
@@ -892,6 +893,7 @@
     public void sendBroadcast(Intent intent) {
         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
         try {
+            intent.setAllowFds(false);
             ActivityManagerNative.getDefault().broadcastIntent(
                 mMainThread.getApplicationThread(), intent, resolvedType, null,
                 Activity.RESULT_OK, null, null, null, false, false);
@@ -903,6 +905,7 @@
     public void sendBroadcast(Intent intent, String receiverPermission) {
         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
         try {
+            intent.setAllowFds(false);
             ActivityManagerNative.getDefault().broadcastIntent(
                 mMainThread.getApplicationThread(), intent, resolvedType, null,
                 Activity.RESULT_OK, null, null, receiverPermission, false, false);
@@ -915,6 +918,7 @@
             String receiverPermission) {
         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
         try {
+            intent.setAllowFds(false);
             ActivityManagerNative.getDefault().broadcastIntent(
                 mMainThread.getApplicationThread(), intent, resolvedType, null,
                 Activity.RESULT_OK, null, null, receiverPermission, true, false);
@@ -946,6 +950,7 @@
         }
         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
         try {
+            intent.setAllowFds(false);
             ActivityManagerNative.getDefault().broadcastIntent(
                 mMainThread.getApplicationThread(), intent, resolvedType, rd,
                 initialCode, initialData, initialExtras, receiverPermission,
@@ -958,6 +963,7 @@
     public void sendStickyBroadcast(Intent intent) {
         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
         try {
+            intent.setAllowFds(false);
             ActivityManagerNative.getDefault().broadcastIntent(
                 mMainThread.getApplicationThread(), intent, resolvedType, null,
                 Activity.RESULT_OK, null, null, null, false, true);
@@ -989,6 +995,7 @@
         }
         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
         try {
+            intent.setAllowFds(false);
             ActivityManagerNative.getDefault().broadcastIntent(
                 mMainThread.getApplicationThread(), intent, resolvedType, rd,
                 initialCode, initialData, initialExtras, null,
@@ -1005,6 +1012,7 @@
             intent.setDataAndType(intent.getData(), resolvedType);
         }
         try {
+            intent.setAllowFds(false);
             ActivityManagerNative.getDefault().unbroadcastIntent(
                 mMainThread.getApplicationThread(), intent);
         } catch (RemoteException e) {
@@ -1069,6 +1077,7 @@
     @Override
     public ComponentName startService(Intent service) {
         try {
+            service.setAllowFds(false);
             ComponentName cn = ActivityManagerNative.getDefault().startService(
                 mMainThread.getApplicationThread(), service,
                 service.resolveTypeIfNeeded(getContentResolver()));
@@ -1086,6 +1095,7 @@
     @Override
     public boolean stopService(Intent service) {
         try {
+            service.setAllowFds(false);
             int res = ActivityManagerNative.getDefault().stopService(
                 mMainThread.getApplicationThread(), service,
                 service.resolveTypeIfNeeded(getContentResolver()));
@@ -1116,6 +1126,7 @@
                     < android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
                 flags |= BIND_WAIVE_PRIORITY;
             }
+            service.setAllowFds(false);
             int res = ActivityManagerNative.getDefault().bindService(
                 mMainThread.getApplicationThread(), getActivityToken(),
                 service, service.resolveTypeIfNeeded(getContentResolver()),
@@ -1148,6 +1159,9 @@
     public boolean startInstrumentation(ComponentName className,
             String profileFile, Bundle arguments) {
         try {
+            if (arguments != null) {
+                arguments.setAllowFds(false);
+            }
             return ActivityManagerNative.getDefault().startInstrumentation(
                     className, profileFile, 0, arguments, null);
         } catch (RemoteException e) {
diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java
index 3a08e6d..d423d98 100644
--- a/core/java/android/app/Fragment.java
+++ b/core/java/android/app/Fragment.java
@@ -162,9 +162,6 @@
  * constructor to instantiate it.  If the empty constructor is not available,
  * a runtime exception will occur in some cases during state restore.
  *
- * <p>For more documentation, also see the <a
- * href="{@docRoot}guide/topics/fundamentals/fragments.html">Fragments</a> developer guide.</p>
- *
  * <p>Topics covered here:
  * <ol>
  * <li><a href="#OlderPlatforms">Older Platforms</a>
@@ -173,6 +170,12 @@
  * <li><a href="#BackStack">Back Stack</a>
  * </ol>
  *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For more information about using fragments, read the
+ * <a href="{@docRoot}guide/topics/fundamentals/fragments.html">Fragments</a> developer guide.</p>
+ * </div>
+ *
  * <a name="OlderPlatforms"></a>
  * <h3>Older Platforms</h3>
  *
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index 7a6759f..3da4f29 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -45,6 +45,12 @@
 /**
  * Interface for interacting with {@link Fragment} objects inside of an
  * {@link Activity}
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For more information about using fragments, read the
+ * <a href="{@docRoot}guide/topics/fundamentals/fragments.html">Fragments</a> developer guide.</p>
+ * </div>
  */
 public abstract class FragmentManager {
     /**
diff --git a/core/java/android/app/FragmentTransaction.java b/core/java/android/app/FragmentTransaction.java
index c1f3cd6..6e99899 100644
--- a/core/java/android/app/FragmentTransaction.java
+++ b/core/java/android/app/FragmentTransaction.java
@@ -2,6 +2,12 @@
 
 /**
  * API for performing a set of Fragment operations.
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For more information about using fragments, read the
+ * <a href="{@docRoot}guide/topics/fundamentals/fragments.html">Fragments</a> developer guide.</p>
+ * </div>
  */
 public abstract class FragmentTransaction {
     /**
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index f3bc495..d7f5c55 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -1375,6 +1375,7 @@
             }
         }
         try {
+            intent.setAllowFds(false);
             int result = ActivityManagerNative.getDefault()
                 .startActivity(whoThread, intent,
                         intent.resolveTypeIfNeeded(who.getContentResolver()),
@@ -1415,6 +1416,7 @@
         try {
             String[] resolvedTypes = new String[intents.length];
             for (int i=0; i<intents.length; i++) {
+                intents[i].setAllowFds(false);
                 resolvedTypes[i] = intents[i].resolveTypeIfNeeded(who.getContentResolver());
             }
             int result = ActivityManagerNative.getDefault()
@@ -1471,6 +1473,7 @@
             }
         }
         try {
+            intent.setAllowFds(false);
             int result = ActivityManagerNative.getDefault()
                 .startActivity(whoThread, intent,
                         intent.resolveTypeIfNeeded(who.getContentResolver()),
diff --git a/core/java/android/app/IntentService.java b/core/java/android/app/IntentService.java
index 57a2695..96767ae 100644
--- a/core/java/android/app/IntentService.java
+++ b/core/java/android/app/IntentService.java
@@ -41,6 +41,12 @@
  * long as necessary (and will not block the application's main loop), but
  * only one request will be processed at a time.
  *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For a detailed discussion about how to create services, read the
+ * <a href="{@docRoot}guide/topics/fundamentals/services.html">Services</a> developer guide.</p>
+ * </div>
+ *
  * @see android.os.AsyncTask
  */
 public abstract class IntentService extends Service {
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index 2549c84..522f477 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -661,6 +661,9 @@
                             "Finishing broadcast to unregistered receiver");
                     IActivityManager mgr = ActivityManagerNative.getDefault();
                     try {
+                        if (extras != null) {
+                            extras.setAllowFds(false);
+                        }
                         mgr.finishReceiver(this, resultCode, data, extras, false);
                     } catch (RemoteException e) {
                         Slog.w(ActivityThread.TAG, "Couldn't finish broadcast to unregistered receiver");
diff --git a/core/java/android/app/LoaderManager.java b/core/java/android/app/LoaderManager.java
index 46a008d..89e9ddd 100644
--- a/core/java/android/app/LoaderManager.java
+++ b/core/java/android/app/LoaderManager.java
@@ -47,6 +47,12 @@
  *
  * {@sample development/samples/ApiDemos/src/com/example/android/apis/app/LoaderCursor.java
  *      fragment_cursor}
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For more information about using loaders, read the
+ * <a href="{@docRoot}guide/topics/fundamentals/loaders.html">Loaders</a> developer guide.</p>
+ * </div>
  */
 public abstract class LoaderManager {
     /**
diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java
index b4827cb..b0637a7 100644
--- a/core/java/android/app/PendingIntent.java
+++ b/core/java/android/app/PendingIntent.java
@@ -192,6 +192,7 @@
         String resolvedType = intent != null ? intent.resolveTypeIfNeeded(
                 context.getContentResolver()) : null;
         try {
+            intent.setAllowFds(false);
             IIntentSender target =
                 ActivityManagerNative.getDefault().getIntentSender(
                     IActivityManager.INTENT_SENDER_ACTIVITY, packageName,
@@ -249,6 +250,7 @@
         String packageName = context.getPackageName();
         String[] resolvedTypes = new String[intents.length];
         for (int i=0; i<intents.length; i++) {
+            intents[i].setAllowFds(false);
             resolvedTypes[i] = intents[i].resolveTypeIfNeeded(context.getContentResolver());
         }
         try {
@@ -287,6 +289,7 @@
         String resolvedType = intent != null ? intent.resolveTypeIfNeeded(
                 context.getContentResolver()) : null;
         try {
+            intent.setAllowFds(false);
             IIntentSender target =
                 ActivityManagerNative.getDefault().getIntentSender(
                     IActivityManager.INTENT_SENDER_BROADCAST, packageName,
@@ -324,6 +327,7 @@
         String resolvedType = intent != null ? intent.resolveTypeIfNeeded(
                 context.getContentResolver()) : null;
         try {
+            intent.setAllowFds(false);
             IIntentSender target =
                 ActivityManagerNative.getDefault().getIntentSender(
                     IActivityManager.INTENT_SENDER_SERVICE, packageName,
diff --git a/core/java/android/app/Service.java b/core/java/android/app/Service.java
index ebde6e0..35bd8c0 100644
--- a/core/java/android/app/Service.java
+++ b/core/java/android/app/Service.java
@@ -50,10 +50,6 @@
  * Threads</a>.  The {@link IntentService} class is available
  * as a standard implementation of Service that has its own thread where it
  * schedules its work to be done.</p>
- *
- * <p>You can find a detailed discussion about how to create services in the 
- * <a href="{@docRoot}guide/topics/fundamentals/services.html">Services</a>
- * document.</p>
  * 
  * <p>Topics covered here:
  * <ol>
@@ -64,7 +60,13 @@
  * <li><a href="#LocalServiceSample">Local Service Sample</a>
  * <li><a href="#RemoteMessengerServiceSample">Remote Messenger Service Sample</a>
  * </ol>
- * 
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For a detailed discussion about how to create services, read the
+ * <a href="{@docRoot}guide/topics/fundamentals/services.html">Services</a> developer guide.</p>
+ * </div>
+ *
  * <a name="WhatIsAService"></a>
  * <h3>What is a Service?</h3>
  * 
diff --git a/core/java/android/app/backup/IBackupManager.aidl b/core/java/android/app/backup/IBackupManager.aidl
index c154296..acdd0b5 100644
--- a/core/java/android/app/backup/IBackupManager.aidl
+++ b/core/java/android/app/backup/IBackupManager.aidl
@@ -157,11 +157,15 @@
      * @param allApps If <code>true</code>, the resulting tar stream will include all
      *     installed applications' data, not just those named in the <code>packageNames</code>
      *     parameter.
+     * @param allIncludesSystem If {@code true}, then {@code allApps} will be interpreted
+     *     as including packages pre-installed as part of the system. If {@code false},
+     *     then setting {@code allApps} to {@code true} will mean only that all 3rd-party
+     *     applications will be included in the dataset.
      * @param packageNames The package names of the apps whose data (and optionally .apk files)
      *     are to be backed up.  The <code>allApps</code> parameter supersedes this.
      */
     void fullBackup(in ParcelFileDescriptor fd, boolean includeApks, boolean includeShared,
-            boolean allApps, in String[] packageNames);
+            boolean allApps, boolean allIncludesSystem, in String[] packageNames);
 
     /**
      * Restore device content from the data stream passed through the given socket.  The
diff --git a/core/java/android/content/BroadcastReceiver.java b/core/java/android/content/BroadcastReceiver.java
index 028149b..d71a8d6 100644
--- a/core/java/android/content/BroadcastReceiver.java
+++ b/core/java/android/content/BroadcastReceiver.java
@@ -90,7 +90,14 @@
  * <li><a href="#Permissions">Permissions</a>
  * <li><a href="#ProcessLifecycle">Process Lifecycle</a>
  * </ol>
- * 
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For information about how to use this class to receive and resolve intents, read the
+ * <a href="{@docRoot}guide/topics/intents/intents-filters.html">Intents and Intent Filters</a>
+ * developer guide.</p>
+ * </div>
+ *
  * <a name="ReceiverLifecycle"></a>
  * <h3>Receiver Lifecycle</h3>
  * 
@@ -366,6 +373,9 @@
                 mFinished = true;
             
                 try {
+                    if (mResultExtras != null) {
+                        mResultExtras.setAllowFds(false);
+                    }
                     if (mOrderedHint) {
                         am.finishReceiver(mToken, mResultCode, mResultData, mResultExtras,
                                 mAbortBroadcast);
@@ -462,6 +472,7 @@
         IActivityManager am = ActivityManagerNative.getDefault();
         IBinder binder = null;
         try {
+            service.setAllowFds(false);
             binder = am.peekService(service, service.resolveTypeIfNeeded(
                     myContext.getContentResolver()));
         } catch (RemoteException e) {
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index f44d038..2be5153 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -55,13 +55,21 @@
  * {@link android.content.Context#bindService} to communicate with a
  * background {@link android.app.Service}.
  *
- * <p>An Intent provides a facility for performing late runtime binding between
- * the code in different applications.  Its most significant use is in the
- * launching of activities, where it can be thought of as the glue between
- * activities. It is
- * basically a passive data structure holding an abstract description of an
- * action to be performed. The primary pieces of information in an intent
- * are:</p>
+ * <p>An Intent provides a facility for performing late runtime binding between the code in
+ * different applications. Its most significant use is in the launching of activities, where it
+ * can be thought of as the glue between activities. It is basically a passive data structure 
+ * holding an abstract description of an action to be performed.</p> 
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For information about how to create and resolve intents, read the
+ * <a href="{@docRoot}guide/topics/intents/intents-filters.html">Intents and Intent Filters</a>
+ * developer guide.</p>
+ * </div>
+ *
+ * <a name="IntentStructure"></a>
+ * <h3>Intent Structure</h3>
+ * <p>The primary pieces of information in an intent are:</p>
  *
  * <ul>
  *   <li> <p><b>action</b> -- The general action to be performed, such as
@@ -3568,6 +3576,13 @@
         return mExtras != null && mExtras.hasFileDescriptors();
     }
 
+    /** @hide */
+    public void setAllowFds(boolean allowFds) {
+        if (mExtras != null) {
+            mExtras.setAllowFds(allowFds);
+        }
+    }
+
     /**
      * Retrieve extended data from the intent.
      *
diff --git a/core/java/android/content/IntentFilter.java b/core/java/android/content/IntentFilter.java
index f9b3fd5..3b0d846 100644
--- a/core/java/android/content/IntentFilter.java
+++ b/core/java/android/content/IntentFilter.java
@@ -71,6 +71,14 @@
  * To specify a path, you also must specify both one or more authorities and
  * one or more schemes it is associated with.
  *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For information about how to create and resolve intents, read the
+ * <a href="{@docRoot}guide/topics/intents/intents-filters.html">Intents and Intent Filters</a>
+ * developer guide.</p>
+ * </div>
+ *
+ * <h3>Filter Rules</h3>
  * <p>A match is based on the following rules.  Note that
  * for an IntentFilter to match an Intent, three conditions must hold:
  * the <strong>action</strong> and <strong>category</strong> must match, and
diff --git a/core/java/android/content/Loader.java b/core/java/android/content/Loader.java
index 368c33e..b962800 100644
--- a/core/java/android/content/Loader.java
+++ b/core/java/android/content/Loader.java
@@ -40,8 +40,12 @@
  *
  * <p>Most implementations should not derive directly from this class, but
  * instead inherit from {@link AsyncTaskLoader}.</p>
- * <p>For more information, see the <a
- * href="{@docRoot}guide/topics/fundamentals/loaders.html">Loaders</a> developer guide.</p>
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For more information about using loaders, read the
+ * <a href="{@docRoot}guide/topics/fundamentals/loaders.html">Loaders</a> developer guide.</p>
+ * </div>
  *
  * @param <D> The result returned when the load is complete
  */
diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java
index 127efa2..4225393 100644
--- a/core/java/android/content/SyncManager.java
+++ b/core/java/android/content/SyncManager.java
@@ -1301,7 +1301,7 @@
 
                 elapsedTime = authoritySyncStats.elapsedTime;
                 times = authoritySyncStats.times;
-                timeStr = String.format("%d/%d%%",
+                timeStr = String.format("%ds/%d%%",
                         elapsedTime / 1000,
                         elapsedTime * 100 / totalElapsedTime);
                 timesStr = String.format("%d/%d%%",
@@ -1309,32 +1309,30 @@
                         times * 100 / totalTimes);
                 pw.printf(authorityFormat, name, timesStr, timeStr);
 
-                if (authoritySyncStats.accountMap.size() > 1) {
-                    final List<AccountSyncStats> sortedAccounts =
-                            new ArrayList<AccountSyncStats>(
-                                    authoritySyncStats.accountMap.values());
-                    Collections.sort(sortedAccounts, new Comparator<AccountSyncStats>() {
-                        @Override
-                        public int compare(AccountSyncStats lhs, AccountSyncStats rhs) {
-                            // reverse order
-                            int compare = Integer.compare(rhs.times, lhs.times);
-                            if (compare == 0) {
-                                compare = Long.compare(rhs.elapsedTime, lhs.elapsedTime);
-                            }
-                            return compare;
+                final List<AccountSyncStats> sortedAccounts =
+                        new ArrayList<AccountSyncStats>(
+                                authoritySyncStats.accountMap.values());
+                Collections.sort(sortedAccounts, new Comparator<AccountSyncStats>() {
+                    @Override
+                    public int compare(AccountSyncStats lhs, AccountSyncStats rhs) {
+                        // reverse order
+                        int compare = Integer.compare(rhs.times, lhs.times);
+                        if (compare == 0) {
+                            compare = Long.compare(rhs.elapsedTime, lhs.elapsedTime);
                         }
-                    });
-                    for (AccountSyncStats stats: sortedAccounts) {
-                        elapsedTime = stats.elapsedTime;
-                        times = stats.times;
-                        timeStr = String.format("%d/%d%%",
-                                elapsedTime / 1000,
-                                elapsedTime * 100 / totalElapsedTime);
-                        timesStr = String.format("%d/%d%%",
-                                times,
-                                times * 100 / totalTimes);
-                        pw.printf(accountFormat, stats.name, timesStr, timeStr);
+                        return compare;
                     }
+                });
+                for (AccountSyncStats stats: sortedAccounts) {
+                    elapsedTime = stats.elapsedTime;
+                    times = stats.times;
+                    timeStr = String.format("%ds/%d%%",
+                            elapsedTime / 1000,
+                            elapsedTime * 100 / totalElapsedTime);
+                    timesStr = String.format("%d/%d%%",
+                            times,
+                            times * 100 / totalTimes);
+                    pw.printf(accountFormat, stats.name, timesStr, timeStr);
                 }
                 pw.println(separator);
             }
@@ -1342,9 +1340,8 @@
             pw.println();
             pw.println("Recent Sync History");
             final String format = "  %-" + maxAccount + "s  %s\n";
-            String lastAuthorityName = null;
-            String lastAccountKey = null;
-            long lastEventTime = 0;
+            final Map<String, Long> lastTimeMap = Maps.newHashMap();
+
             for (int i = 0; i < N; i++) {
                 SyncStorageEngine.SyncHistoryItem item = items.get(i);
                 SyncStorageEngine.AuthorityInfo authority
@@ -1363,21 +1360,32 @@
                 final long eventTime = item.eventTime;
                 time.set(eventTime);
 
-                pw.printf("  #%-3d: %s %8s  %5.1fs",
+                final String key = authorityName + "/" + accountKey;
+                final Long lastEventTime = lastTimeMap.get(key);
+                final String diffString;
+                if (lastEventTime == null) {
+                    diffString = "";
+                } else {
+                    final long diff = (lastEventTime - eventTime) / 1000;
+                    if (diff < 60) {
+                        diffString = String.valueOf(diff);
+                    } else if (diff < 3600) {
+                        diffString = String.format("%02d:%02d", diff / 60, diff % 60);
+                    } else {
+                        final long sec = diff % 3600;
+                        diffString = String.format("%02d:%02d:%02d",
+                                diff / 3600, sec / 60, sec % 60);
+                    }
+                }
+                lastTimeMap.put(key, eventTime);
+
+                pw.printf("  #%-3d: %s %8s  %5.1fs  %8s",
                         i + 1,
                         formatTime(eventTime),
                         SyncStorageEngine.SOURCES[item.source],
-                        ((float) elapsedTime) / 1000);
-                if (authorityName.equals(lastAuthorityName) && accountKey.equals(lastAccountKey)) {
-                    final long span = (lastEventTime - eventTime) / 1000;
-                    pw.printf("  %02d:%02d\n", span / 60, span % 60);
-                } else {
-                    pw.printf(format, accountKey, authorityName);
-                }
-
-                lastAuthorityName = authorityName;
-                lastAccountKey = accountKey;
-                lastEventTime = eventTime;
+                        ((float) elapsedTime) / 1000,
+                        diffString);
+                pw.printf(format, accountKey, authorityName);
 
                 if (item.event != SyncStorageEngine.EVENT_STOP
                         || item.upstreamActivity != 0
diff --git a/core/java/android/net/DhcpStateMachine.java b/core/java/android/net/DhcpStateMachine.java
index 79c9395..fc6a44a 100644
--- a/core/java/android/net/DhcpStateMachine.java
+++ b/core/java/android/net/DhcpStateMachine.java
@@ -336,17 +336,17 @@
         DhcpInfoInternal dhcpInfoInternal = new DhcpInfoInternal();
 
         if (dhcpAction == DhcpAction.START) {
-            Log.d(TAG, "DHCP request on " + mInterfaceName);
+            if (DBG) Log.d(TAG, "DHCP request on " + mInterfaceName);
             success = NetworkUtils.runDhcp(mInterfaceName, dhcpInfoInternal);
             mDhcpInfo = dhcpInfoInternal;
         } else if (dhcpAction == DhcpAction.RENEW) {
-            Log.d(TAG, "DHCP renewal on " + mInterfaceName);
+            if (DBG) Log.d(TAG, "DHCP renewal on " + mInterfaceName);
             success = NetworkUtils.runDhcpRenew(mInterfaceName, dhcpInfoInternal);
             dhcpInfoInternal.updateFromDhcpRequest(mDhcpInfo);
         }
 
         if (success) {
-            Log.d(TAG, "DHCP succeeded on " + mInterfaceName);
+            if (DBG) Log.d(TAG, "DHCP succeeded on " + mInterfaceName);
            long leaseDuration = dhcpInfoInternal.leaseDuration; //int to long conversion
 
            //Sanity check for renewal
@@ -366,7 +366,7 @@
             mController.obtainMessage(CMD_POST_DHCP_ACTION, DHCP_SUCCESS, 0, dhcpInfoInternal)
                 .sendToTarget();
         } else {
-            Log.d(TAG, "DHCP failed on " + mInterfaceName + ": " +
+            Log.e(TAG, "DHCP failed on " + mInterfaceName + ": " +
                     NetworkUtils.getDhcpError());
             NetworkUtils.stopDhcp(mInterfaceName);
             mController.obtainMessage(CMD_POST_DHCP_ACTION, DHCP_FAILURE, 0)
diff --git a/core/java/android/net/DnsPinger.java b/core/java/android/net/DnsPinger.java
index 3291e6b..11acabe 100644
--- a/core/java/android/net/DnsPinger.java
+++ b/core/java/android/net/DnsPinger.java
@@ -22,7 +22,7 @@
 import android.os.Message;
 import android.os.SystemClock;
 import android.provider.Settings;
-import android.util.Slog;
+import android.util.Log;
 
 import com.android.internal.util.Protocol;
 
@@ -51,7 +51,7 @@
  * @hide
  */
 public final class DnsPinger extends Handler {
-    private static final boolean V = true;
+    private static final boolean DBG = false;
 
     private static final int RECEIVE_POLL_INTERVAL_MS = 200;
     private static final int DNS_PORT = 53;
@@ -154,7 +154,7 @@
                         newActivePing.socket.setNetworkInterface(NetworkInterface.getByName(
                                 getCurrentLinkProperties().getInterfaceName()));
                     } catch (Exception e) {
-                        Slog.w(TAG,"sendDnsPing::Error binding to socket", e);
+                        loge("sendDnsPing::Error binding to socket " + e);
                     }
 
                     newActivePing.packetId = (short) sRandom.nextInt();
@@ -165,8 +165,8 @@
                     // Send the DNS query
                     DatagramPacket packet = new DatagramPacket(buf,
                             buf.length, dnsAddress, DNS_PORT);
-                    if (V) {
-                        Slog.v(TAG, "Sending a ping " + newActivePing.internalId +
+                    if (DBG) {
+                        log("Sending a ping " + newActivePing.internalId +
                                 " to " + dnsAddress.getHostAddress()
                                 + " with packetId " + newActivePing.packetId + ".");
                     }
@@ -196,15 +196,15 @@
                             curPing.result =
                                     (int) (SystemClock.elapsedRealtime() - curPing.start);
                         } else {
-                            if (V) {
-                                Slog.v(TAG, "response ID didn't match, ignoring packet");
+                            if (DBG) {
+                                log("response ID didn't match, ignoring packet");
                             }
                         }
                     } catch (SocketTimeoutException e) {
                         // A timeout here doesn't mean anything - squelsh this exception
                     } catch (Exception e) {
-                        if (V) {
-                            Slog.v(TAG, "DnsPinger.pingDns got socket exception: ", e);
+                        if (DBG) {
+                            log("DnsPinger.pingDns got socket exception: " + e);
                         }
                         curPing.result = SOCKET_EXCEPTION;
                     }
@@ -244,13 +244,13 @@
     public List<InetAddress> getDnsList() {
         LinkProperties curLinkProps = getCurrentLinkProperties();
         if (curLinkProps == null) {
-            Slog.e(TAG, "getCurLinkProperties:: LP for type" + mConnectionType + " is null!");
+            loge("getCurLinkProperties:: LP for type" + mConnectionType + " is null!");
             return mDefaultDns;
         }
 
         Collection<InetAddress> dnses = curLinkProps.getDnses();
         if (dnses == null || dnses.size() == 0) {
-            Slog.v(TAG, "getDns::LinkProps has null dns - returning default");
+            loge("getDns::LinkProps has null dns - returning default");
             return mDefaultDns;
         }
 
@@ -277,8 +277,8 @@
     }
 
     private void sendResponse(int internalId, int externalId, int responseVal) {
-        if(V) {
-            Slog.d(TAG, "Responding to packet " + internalId +
+        if(DBG) {
+            log("Responding to packet " + internalId +
                     " externalId " + externalId +
                     " and val " + responseVal);
         }
@@ -304,7 +304,7 @@
         try {
             return NetworkUtils.numericToInetAddress(dns);
         } catch (IllegalArgumentException e) {
-            Slog.w(TAG, "getDefaultDns::malformed default dns address");
+            loge("getDefaultDns::malformed default dns address");
             return null;
         }
     }
@@ -323,4 +323,12 @@
         0, 1, // QTYPE, set to 1 = A (host address)
         0, 1  // QCLASS, set to 1 = IN (internet)
     };
+
+    private void log(String s) {
+        Log.d(TAG, s);
+    }
+
+    private void loge(String s) {
+        Log.e(TAG, s);
+    }
 }
diff --git a/core/java/android/net/NetworkStats.java b/core/java/android/net/NetworkStats.java
index f3be39c..e554975 100644
--- a/core/java/android/net/NetworkStats.java
+++ b/core/java/android/net/NetworkStats.java
@@ -272,6 +272,17 @@
     }
 
     /**
+     * Combine all values from another {@link NetworkStats} into this object.
+     */
+    public void combineAllValues(NetworkStats another) {
+        NetworkStats.Entry entry = null;
+        for (int i = 0; i < another.size; i++) {
+            entry = another.getValues(i, entry);
+            combineValues(entry);
+        }
+    }
+
+    /**
      * Find first stats index that matches the requested parameters.
      */
     public int findIndex(String iface, int uid, int set, int tag) {
@@ -456,6 +467,34 @@
         return result;
     }
 
+    /**
+     * Return total statistics grouped by {@link #iface}; doesn't mutate the
+     * original structure.
+     */
+    public NetworkStats groupedByIface() {
+        final NetworkStats stats = new NetworkStats(elapsedRealtime, 10);
+
+        final Entry entry = new Entry();
+        entry.uid = UID_ALL;
+        entry.set = SET_ALL;
+        entry.tag = TAG_NONE;
+        entry.operations = 0L;
+
+        for (int i = 0; i < size; i++) {
+            // skip specific tags, since already counted in TAG_NONE
+            if (tag[i] != TAG_NONE) continue;
+
+            entry.iface = iface[i];
+            entry.rxBytes = rxBytes[i];
+            entry.rxPackets = rxPackets[i];
+            entry.txBytes = txBytes[i];
+            entry.txPackets = txPackets[i];
+            stats.combineValues(entry);
+        }
+
+        return stats;
+    }
+
     public void dump(String prefix, PrintWriter pw) {
         pw.print(prefix);
         pw.print("NetworkStats: elapsedRealtime="); pw.println(elapsedRealtime);
diff --git a/core/java/android/os/AsyncTask.java b/core/java/android/os/AsyncTask.java
index 64bba54..9dea4c4 100644
--- a/core/java/android/os/AsyncTask.java
+++ b/core/java/android/os/AsyncTask.java
@@ -42,6 +42,13 @@
  * and 4 steps, called <code>onPreExecute</code>, <code>doInBackground</code>,
  * <code>onProgressUpdate</code> and <code>onPostExecute</code>.</p>
  *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For more information about using tasks and threads, read the
+ * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html">Processes and
+ * Threads</a> developer guide.</p>
+ * </div>
+ *
  * <h2>Usage</h2>
  * <p>AsyncTask must be subclassed to be used. The subclass will override at least
  * one method ({@link #doInBackground}), and most often will override a
diff --git a/core/java/android/os/Bundle.java b/core/java/android/os/Bundle.java
index c288f8a..28206b7 100644
--- a/core/java/android/os/Bundle.java
+++ b/core/java/android/os/Bundle.java
@@ -54,6 +54,7 @@
 
     private boolean mHasFds = false;
     private boolean mFdsKnown = true;
+    private boolean mAllowFds = true;
 
     /**
      * The ClassLoader used when unparcelling data from mParcelledData.
@@ -186,7 +187,14 @@
     public ClassLoader getClassLoader() {
         return mClassLoader;
     }
-    
+
+    /** @hide */
+    public boolean setAllowFds(boolean allowFds) {
+        boolean orig = mAllowFds;
+        mAllowFds = allowFds;
+        return orig;
+    }
+
     /**
      * Clones the current Bundle. The internal map is cloned, but the keys and
      * values to which it refers are copied by reference.
@@ -1589,24 +1597,29 @@
      * @param parcel The parcel to copy this bundle to.
      */
     public void writeToParcel(Parcel parcel, int flags) {
-        if (mParcelledData != null) {
-            int length = mParcelledData.dataSize();
-            parcel.writeInt(length);
-            parcel.writeInt(0x4C444E42); // 'B' 'N' 'D' 'L'
-            parcel.appendFrom(mParcelledData, 0, length);
-        } else {
-            parcel.writeInt(-1); // dummy, will hold length
-            parcel.writeInt(0x4C444E42); // 'B' 'N' 'D' 'L'
-
-            int oldPos = parcel.dataPosition();
-            parcel.writeMapInternal(mMap);
-            int newPos = parcel.dataPosition();
-
-            // Backpatch length
-            parcel.setDataPosition(oldPos - 8);
-            int length = newPos - oldPos;
-            parcel.writeInt(length);
-            parcel.setDataPosition(newPos);
+        final boolean oldAllowFds = parcel.pushAllowFds(mAllowFds);
+        try {
+            if (mParcelledData != null) {
+                int length = mParcelledData.dataSize();
+                parcel.writeInt(length);
+                parcel.writeInt(0x4C444E42); // 'B' 'N' 'D' 'L'
+                parcel.appendFrom(mParcelledData, 0, length);
+            } else {
+                parcel.writeInt(-1); // dummy, will hold length
+                parcel.writeInt(0x4C444E42); // 'B' 'N' 'D' 'L'
+    
+                int oldPos = parcel.dataPosition();
+                parcel.writeMapInternal(mMap);
+                int newPos = parcel.dataPosition();
+    
+                // Backpatch length
+                parcel.setDataPosition(oldPos - 8);
+                int length = newPos - oldPos;
+                parcel.writeInt(length);
+                parcel.setDataPosition(newPos);
+            }
+        } finally {
+            parcel.restoreAllowFds(oldAllowFds);
         }
     }
 
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index e9ed676..15e3af4 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -323,6 +323,12 @@
      */
     public final native void setDataCapacity(int size);
 
+    /** @hide */
+    public final native boolean pushAllowFds(boolean allowFds);
+
+    /** @hide */
+    public final native void restoreAllowFds(boolean lastValue);
+
     /**
      * Returns the raw bytes of the parcel.
      *
diff --git a/core/java/android/provider/CallLog.java b/core/java/android/provider/CallLog.java
index 886edaf..6d14dfc 100644
--- a/core/java/android/provider/CallLog.java
+++ b/core/java/android/provider/CallLog.java
@@ -238,6 +238,14 @@
         public static final String CACHED_PHOTO_ID = "photo_id";
 
         /**
+         * The cached formatted phone number.
+         * This value is not guaranteed to be present.
+         * <P>Type: TEXT</P>
+         * @hide
+         */
+        public static final String CACHED_FORMATTED_NUMBER = "formatted_number";
+
+        /**
          * Adds a call to the call log.
          *
          * @param ci the CallerInfo object to get the target contact from.  Can be null
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index fb119b3..8483b4f 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -1611,9 +1611,16 @@
         }
 
         /**
+         * <p>
          * A sub-directory of a single contact that contains all of the constituent raw contact
          * {@link ContactsContract.StreamItems} rows.  This directory can be used either
          * with a {@link #CONTENT_URI} or {@link #CONTENT_LOOKUP_URI}.
+         * </p>
+         * <p>
+         * Querying for social stream data requires android.permission.READ_SOCIAL_STREAM
+         * permission.
+         * </p>
+         * @hide
          */
         public static final class StreamItems implements StreamItemsColumns {
             /**
@@ -2669,6 +2676,14 @@
          * {@link ContactsContract.StreamItems} for a stand-alone table containing the
          * same data.
          * </p>
+         * <p>
+         * Access to the social stream through this sub-directory requires additional permissions
+         * beyond the read/write contact permissions required by the provider.  Querying for
+         * social stream data requires android.permission.READ_SOCIAL_STREAM permission, and
+         * inserting or updating social stream items requires android.permission.WRITE_SOCIAL_STREAM
+         * permission.
+         * </p>
+         * @hide
          */
         public static final class StreamItems implements BaseColumns, StreamItemsColumns {
             /**
@@ -2963,6 +2978,12 @@
      * transaction correspondingly.  Insertion of more items beyond the limit will
      * automatically lead to deletion of the oldest items, by {@link StreamItems#TIMESTAMP}.
      * </p>
+     * <p>
+     * Access to the social stream through these URIs requires additional permissions beyond the
+     * read/write contact permissions required by the provider.  Querying for social stream data
+     * requires android.permission.READ_SOCIAL_STREAM permission, and inserting or updating social
+     * stream items requires android.permission.WRITE_SOCIAL_STREAM permission.
+     * </p>
      * <h3>Operations</h3>
      * <dl>
      * <dt><b>Insert</b></dt>
@@ -3075,6 +3096,7 @@
      * </pre>
      * </dd>
      * </dl>
+     * @hide
      */
     public static final class StreamItems implements BaseColumns, StreamItemsColumns {
         /**
@@ -3135,6 +3157,12 @@
          * directory append {@link StreamItems.StreamItemPhotos#CONTENT_DIRECTORY} to
          * an individual stream item URI.
          * </p>
+         * <p>
+         * Access to social stream photos requires additional permissions beyond the read/write
+         * contact permissions required by the provider.  Querying for social stream photos
+         * requires android.permission.READ_SOCIAL_STREAM permission, and inserting or updating
+         * social stream photos requires android.permission.WRITE_SOCIAL_STREAM permission.
+         * </p>
          */
         public static final class StreamItemPhotos
                 implements BaseColumns, StreamItemPhotosColumns {
@@ -3166,6 +3194,7 @@
      * Columns in the StreamItems table.
      *
      * @see ContactsContract.StreamItems
+     * @hide
      */
     protected interface StreamItemsColumns {
         /**
@@ -3312,6 +3341,12 @@
      * Constants for the stream_item_photos table, which contains photos associated with
      * social stream updates.
      * </p>
+     * <p>
+     * Access to social stream photos requires additional permissions beyond the read/write
+     * contact permissions required by the provider.  Querying for social stream photos
+     * requires android.permission.READ_SOCIAL_STREAM permission, and inserting or updating
+     * social stream photos requires android.permission.WRITE_SOCIAL_STREAM permission.
+     * </p>
      * <h3>Operations</h3>
      * <dl>
      * <dt><b>Insert</b></dt>
@@ -3450,6 +3485,7 @@
      * <pre>
      * </dd>
      * </dl>
+     * @hide
      */
     public static final class StreamItemPhotos implements BaseColumns, StreamItemPhotosColumns {
         /**
@@ -3477,6 +3513,7 @@
      * Columns in the StreamItemPhotos table.
      *
      * @see ContactsContract.StreamItemPhotos
+     * @hide
      */
     protected interface StreamItemPhotosColumns {
         /**
diff --git a/core/java/android/server/BluetoothAdapterStateMachine.java b/core/java/android/server/BluetoothAdapterStateMachine.java
index d26364e..da7c489 100644
--- a/core/java/android/server/BluetoothAdapterStateMachine.java
+++ b/core/java/android/server/BluetoothAdapterStateMachine.java
@@ -77,6 +77,12 @@
     static final int PER_PROCESS_TURN_ON = 3;
     static final int PER_PROCESS_TURN_OFF = 4;
 
+    // Turn on Bluetooth Module, Load firmware, and do all the preparation
+    // needed to get the Bluetooth Module ready but keep it not discoverable
+    // and not connectable. This way the Bluetooth Module can be quickly
+    // switched on if needed
+    static final int TURN_HOT = 5;
+
     // Message(what) to report a event that the state machine need to respond to
     //
     // Event indicates sevice records have been loaded
@@ -94,23 +100,18 @@
 
     // private internal messages
     //
-    // Turn on Bluetooth Module, Load firmware, and do all the preparation
-    // needed to get the Bluetooth Module ready but keep it not discoverable
-    // and not connectable. This way the Bluetooth Module can be quickly
-    // switched on if needed
-    private static final int TURN_HOT = 101;
     // USER_TURN_ON is changed to TURN_ON_CONTINUE after we broadcast the
     // state change intent so that we will not broadcast the intent again in
     // other state
-    private static final int TURN_ON_CONTINUE = 102;
+    private static final int TURN_ON_CONTINUE = 101;
     // Unload firmware, turning off Bluetooth module power
-    private static final int TURN_COLD = 103;
+    private static final int TURN_COLD = 102;
     // Device disconnecting timeout happens
-    private static final int DEVICES_DISCONNECT_TIMEOUT = 104;
+    private static final int DEVICES_DISCONNECT_TIMEOUT = 103;
     // Prepare Bluetooth timeout happens
-    private static final int PREPARE_BLUETOOTH_TIMEOUT = 105;
+    private static final int PREPARE_BLUETOOTH_TIMEOUT = 104;
     // Bluetooth Powerdown timeout happens
-    private static final int POWER_DOWN_TIMEOUT = 106;
+    private static final int POWER_DOWN_TIMEOUT = 105;
 
     private Context mContext;
     private BluetoothService mBluetoothService;
@@ -156,11 +157,6 @@
 
         setInitialState(mPowerOff);
         mPublicState = BluetoothAdapter.STATE_OFF;
-
-        if (mContext.getResources().getBoolean
-            (com.android.internal.R.bool.config_bluetooth_adapter_quick_switch)) {
-            sendMessage(TURN_HOT);
-        }
     }
 
     /**
diff --git a/core/java/android/server/BluetoothService.java b/core/java/android/server/BluetoothService.java
index 63da926..9ca5847 100755
--- a/core/java/android/server/BluetoothService.java
+++ b/core/java/android/server/BluetoothService.java
@@ -313,6 +313,10 @@
         mAdapter = BluetoothAdapter.getDefaultAdapter();
         mBluetoothState = new BluetoothAdapterStateMachine(mContext, this, mAdapter);
         mBluetoothState.start();
+        if (mContext.getResources().getBoolean
+            (com.android.internal.R.bool.config_bluetooth_adapter_quick_switch)) {
+            mBluetoothState.sendMessage(BluetoothAdapterStateMachine.TURN_HOT);
+        }
         mEventLoop = mBluetoothState.getBluetoothEventLoop();
     }
 
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index d193d6e..8e5aefd 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -94,20 +94,10 @@
  * their layout properties.
  * </p>
  *
- * <div class="special">
- * <p>For an introduction to using this class to develop your
- * application's user interface, read the Developer Guide documentation on
- * <strong><a href="{@docRoot}guide/topics/ui/index.html">User Interface</a></strong>. Special topics
- * include:
- * <br/><a href="{@docRoot}guide/topics/ui/declaring-layout.html">Declaring Layout</a>
- * <br/><a href="{@docRoot}guide/topics/ui/menus.html">Creating Menus</a>
- * <br/><a href="{@docRoot}guide/topics/ui/layout-objects.html">Common Layout Objects</a>
- * <br/><a href="{@docRoot}guide/topics/ui/binding.html">Binding to Data with AdapterView</a>
- * <br/><a href="{@docRoot}guide/topics/ui/ui-events.html">Handling UI Events</a>
- * <br/><a href="{@docRoot}guide/topics/ui/themes.html">Applying Styles and Themes</a>
- * <br/><a href="{@docRoot}guide/topics/ui/custom-components.html">Building Custom Components</a>
- * <br/><a href="{@docRoot}guide/topics/ui/how-android-draws.html">How Android Draws Views</a>.
- * </p>
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For information about using this class to develop your application's user interface,
+ * read the <a href="{@docRoot}guide/topics/ui/index.html">User Interface</a> developer guide.
  * </div>
  *
  * <a name="Using"></a>
@@ -1487,6 +1477,18 @@
     }
 
     /**
+     * Accessibility event types that are dispatched for text population.
+     */
+    private static final int POPULATING_ACCESSIBILITY_EVENT_TYPES =
+            AccessibilityEvent.TYPE_VIEW_CLICKED
+            | AccessibilityEvent.TYPE_VIEW_LONG_CLICKED
+            | AccessibilityEvent.TYPE_VIEW_SELECTED
+            | AccessibilityEvent.TYPE_VIEW_FOCUSED
+            | AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED
+            | AccessibilityEvent.TYPE_VIEW_HOVER_ENTER
+            | AccessibilityEvent.TYPE_VIEW_HOVER_EXIT;
+
+    /**
      * Temporary Rect currently for use in setBackground().  This will probably
      * be extended in the future to hold our own class with more than just
      * a Rect. :)
@@ -3855,7 +3857,10 @@
             return;
         }
         onInitializeAccessibilityEvent(event);
-        dispatchPopulateAccessibilityEvent(event);
+        // Only a subset of accessibility events populates text content.
+        if ((event.getEventType() & POPULATING_ACCESSIBILITY_EVENT_TYPES) != 0) {
+            dispatchPopulateAccessibilityEvent(event);
+        }
         // In the beginning we called #isShown(), so we know that getParent() is not null.
         getParent().requestSendAccessibilityEvent(this, event);
     }
@@ -3876,6 +3881,10 @@
      * {@link AccessibilityDelegate#dispatchPopulateAccessibilityEvent(View, AccessibilityEvent)}
      * is responsible for handling this call.
      * </p>
+     * <p>
+     * <em>Note:</em> Accessibility events of certain types are not dispatched for
+     * populating the event text via this method. For details refer to {@link AccessibilityEvent}.
+     * </p>
      *
      * @param event The event.
      *
@@ -3895,12 +3904,6 @@
      * Note: Called from the default {@link AccessibilityDelegate}.
      */
     boolean dispatchPopulateAccessibilityEventInternal(AccessibilityEvent event) {
-        // Do not populate text to scroll events. They describe position change
-        // and usually come from container with a lot of text which is not very
-        // informative for accessibility purposes. Also they are fired frequently.
-        if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_SCROLLED) {
-            return true;
-        }
         onPopulateAccessibilityEvent(event);
         return false;
     }
@@ -12093,6 +12096,39 @@
     }
 
     /**
+     * Finds a view by its unuque and stable accessibility id.
+     *
+     * @param accessibilityId The searched accessibility id.
+     * @return The found view.
+     */
+    final View findViewByAccessibilityId(int accessibilityId) {
+        if (accessibilityId < 0) {
+            return null;
+        }
+        return findViewByAccessibilityIdTraversal(accessibilityId);
+    }
+
+    /**
+     * Performs the traversal to find a view by its unuque and stable accessibility id.
+     *
+     * <strong>Note:</strong>This method does not stop at the root namespace
+     * boundary since the user can touch the screen at an arbitrary location
+     * potentially crossing the root namespace bounday which will send an
+     * accessibility event to accessibility services and they should be able
+     * to obtain the event source. Also accessibility ids are guaranteed to be
+     * unique in the window.
+     *
+     * @param accessibilityId The accessibility id.
+     * @return The found view.
+     */
+    View findViewByAccessibilityIdTraversal(int accessibilityId) {
+        if (getAccessibilityViewId() == accessibilityId) {
+            return this;
+        }
+        return null;
+    }
+
+    /**
      * Look for a child view with the given tag.  If this view has the given
      * tag, return this view.
      *
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index fb0d80a..5b4a6f8 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -821,6 +821,24 @@
         }
     }
 
+    @Override
+    View findViewByAccessibilityIdTraversal(int accessibilityId) {
+        View foundView = super.findViewByAccessibilityIdTraversal(accessibilityId);
+        if (foundView != null) {
+            return foundView;
+        }
+        final int childrenCount = mChildrenCount;
+        final View[] children = mChildren;
+        for (int i = 0; i < childrenCount; i++) {
+            View child = children[i];
+            foundView = child.findViewByAccessibilityIdTraversal(accessibilityId);
+            if (foundView != null) {
+                return foundView;
+            }
+        }
+        return null;
+    }
+
     /**
      * {@inheritDoc}
      */
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 9cb4e5e..e7c91f9 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -74,7 +74,6 @@
 import android.widget.Scroller;
 
 import com.android.internal.policy.PolicyManager;
-import com.android.internal.util.Predicate;
 import com.android.internal.view.BaseSurfaceHolder;
 import com.android.internal.view.IInputMethodCallback;
 import com.android.internal.view.IInputMethodSession;
@@ -4462,9 +4461,6 @@
     final class AccessibilityInteractionController {
         private static final int POOL_SIZE = 5;
 
-        private FindByAccessibilitytIdPredicate mFindByAccessibilityIdPredicate =
-            new FindByAccessibilitytIdPredicate();
-
         private ArrayList<AccessibilityNodeInfo> mTempAccessibilityNodeInfoList =
             new ArrayList<AccessibilityNodeInfo>();
 
@@ -4551,11 +4547,8 @@
 
             AccessibilityNodeInfo info = null;
             try {
-                FindByAccessibilitytIdPredicate predicate = mFindByAccessibilityIdPredicate;
-                predicate.init(accessibilityId);
-                View root = ViewRootImpl.this.mView;
-                View target = root.findViewByPredicate(predicate);
-                if (target != null && target.getVisibility() == View.VISIBLE) {
+                View target = findViewByAccessibilityId(accessibilityId);
+                if (target != null) {
                     info = target.createAccessibilityNodeInfo();
                 }
             } finally {
@@ -4794,25 +4787,12 @@
             if (root == null) {
                 return null;
             }
-            mFindByAccessibilityIdPredicate.init(accessibilityId);
-            View foundView = root.findViewByPredicate(mFindByAccessibilityIdPredicate);
-            if (foundView == null || foundView.getVisibility() != View.VISIBLE) {
+            View foundView = root.findViewByAccessibilityId(accessibilityId);
+            if (foundView != null && foundView.getVisibility() != View.VISIBLE) {
                 return null;
             }
             return foundView;
         }
-
-        private final class FindByAccessibilitytIdPredicate implements Predicate<View> {
-            public int mSearchedId;
-
-            public void init(int searchedId) {
-                mSearchedId = searchedId;
-            }
-
-            public boolean apply(View view) {
-                return (view.getAccessibilityViewId() == mSearchedId);
-            }
-        }
     }
 
     private class SendWindowContentChangedAccessibilityEvent implements Runnable {
@@ -4820,18 +4800,7 @@
 
         public void run() {
             if (mView != null) {
-                // Check again for accessibility state since this is executed delayed.
-                AccessibilityManager accessibilityManager =
-                    AccessibilityManager.getInstance(mView.mContext);
-                if (accessibilityManager.isEnabled()) {
-                    // Send the event directly since we do not want to append the
-                    // source text because this is the text for the entire window
-                    // and we just want to notify that the content has changed.
-                    AccessibilityEvent event = AccessibilityEvent.obtain(
-                            AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
-                    mView.onInitializeAccessibilityEvent(event);
-                    accessibilityManager.sendAccessibilityEvent(event);
-                }
+                mView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
                 mIsPending = false;
             }
         }
diff --git a/core/java/android/view/accessibility/AccessibilityEvent.java b/core/java/android/view/accessibility/AccessibilityEvent.java
index c93b564..91fbb0e 100644
--- a/core/java/android/view/accessibility/AccessibilityEvent.java
+++ b/core/java/android/view/accessibility/AccessibilityEvent.java
@@ -69,14 +69,16 @@
  * <em>Type:</em>{@link #TYPE_VIEW_CLICKED}</br>
  * <em>Properties:</em></br>
  * <ul>
+ *   <li>{@link #getEventType()} - The type of the event.</li>
  *   <li>{@link #getSource()} - The source info (for registered clients).</li>
  *   <li>{@link #getClassName()} - The class name of the source.</li>
  *   <li>{@link #getPackageName()} - The package name of the source.</li>
  *   <li>{@link #getEventTime()}  - The event time.</li>
- *   <li>{@link #getText()} - The text of the source.</li>
+ *   <li>{@link #getText()} - The text of the source's sub-tree.</li>
  *   <li>{@link #isEnabled()} - Whether the source is enabled.</li>
  *   <li>{@link #isPassword()} - Whether the source is password.</li>
  *   <li>{@link #isChecked()} - Whether the source is checked.</li>
+ *   <li>{@link #getContentDescription()} - The content description of the source.</li>
  * </ul>
  * </p>
  * <p>
@@ -85,14 +87,16 @@
  * <em>Type:</em>{@link #TYPE_VIEW_LONG_CLICKED}</br>
  * <em>Properties:</em></br>
  * <ul>
+ *   <li>{@link #getEventType()} - The type of the event.</li>
  *   <li>{@link #getSource()} - The source info (for registered clients).</li>
  *   <li>{@link #getClassName()} - The class name of the source.</li>
  *   <li>{@link #getPackageName()} - The package name of the source.</li>
  *   <li>{@link #getEventTime()}  - The event time.</li>
- *   <li>{@link #getText()} - The text of the source.</li>
+ *   <li>{@link #getText()} - The text of the source's sub-tree.</li>
  *   <li>{@link #isEnabled()} - Whether the source is enabled.</li>
  *   <li>{@link #isPassword()} - Whether the source is password.</li>
  *   <li>{@link #isChecked()} - Whether the source is checked.</li>
+ *   <li>{@link #getContentDescription()} - The content description of the source.</li>
  * </ul>
  * </p>
  * <p>
@@ -101,16 +105,18 @@
  * <em>Type:</em> {@link #TYPE_VIEW_SELECTED}</br>
  * <em>Properties:</em></br>
  * <ul>
+ *   <li>{@link #getEventType()} - The type of the event.</li>
  *   <li>{@link #getSource()} - The source info (for registered clients).</li>
  *   <li>{@link #getClassName()} - The class name of the source.</li>
  *   <li>{@link #getPackageName()} - The package name of the source.</li>
  *   <li>{@link #getEventTime()}  - The event time.</li>
- *   <li>{@link #getText()} - The text of the source.</li>
+ *   <li>{@link #getText()} - The text of the source's sub-tree.</li>
  *   <li>{@link #isEnabled()} - Whether the source is enabled.</li>
  *   <li>{@link #isPassword()} - Whether the source is password.</li>
  *   <li>{@link #isChecked()} - Whether the source is checked.</li>
  *   <li>{@link #getItemCount()} - The number of selectable items of the source.</li>
  *   <li>{@link #getCurrentItemIndex()} - The currently selected item index.</li>
+ *   <li>{@link #getContentDescription()} - The content description of the source.</li>
  * </ul>
  * </p>
  * <p>
@@ -119,16 +125,18 @@
  * <em>Type:</em> {@link #TYPE_VIEW_FOCUSED}</br>
  * <em>Properties:</em></br>
  * <ul>
+ *   <li>{@link #getEventType()} - The type of the event.</li>
  *   <li>{@link #getSource()} - The source info (for registered clients).</li>
  *   <li>{@link #getClassName()} - The class name of the source.</li>
  *   <li>{@link #getPackageName()} - The package name of the source.</li>
  *   <li>{@link #getEventTime()}  - The event time.</li>
- *   <li>{@link #getText()} - The text of the source.</li>
+ *   <li>{@link #getText()} - The text of the source's sub-tree.</li>
  *   <li>{@link #isEnabled()} - Whether the source is enabled.</li>
  *   <li>{@link #isPassword()} - Whether the source is password.</li>
  *   <li>{@link #isChecked()} - Whether the source is checked.</li>
  *   <li>{@link #getItemCount()} - The number of focusable items on the screen.</li>
  *   <li>{@link #getCurrentItemIndex()} - The currently focused item index.</li>
+ *   <li>{@link #getContentDescription()} - The content description of the source.</li>
  * </ul>
  * </p>
  * <p>
@@ -137,6 +145,7 @@
  * <em>Type:</em> {@link #TYPE_VIEW_TEXT_CHANGED}</br>
  * <em>Properties:</em></br>
  * <ul>
+ *   <li>{@link #getEventType()} - The type of the event.</li>
  *   <li>{@link #getSource()} - The source info (for registered clients).</li>
  *   <li>{@link #getClassName()} - The class name of the source.</li>
  *   <li>{@link #getPackageName()} - The package name of the source.</li>
@@ -149,7 +158,17 @@
  *   <li>{@link #getAddedCount()} - The number of added characters.</li>
  *   <li>{@link #getRemovedCount()} - The number of removed characters.</li>
  *   <li>{@link #getBeforeText()} - The text of the source before the change.</li>
+ *   <li>{@link #getContentDescription()} - The content description of the source.</li>
  * </ul>
+ * <em>Note:</em> This event type is not dispatched to descendants though
+ * {@link android.view.View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)
+ * View.dispatchPopulateAccessibilityEvent(AccessibilityEvent)}, hence the event
+ * source {@link android.view.View} and the sub-tree rooted at it will not receive
+ * calls to {@link android.view.View#onPopulateAccessibilityEvent(AccessibilityEvent)
+ * View.onPopulateAccessibilityEvent(AccessibilityEvent)}. The preferred way to add
+ * text content to such events is by setting the
+ * {@link android.R.styleable#View_contentDescription contentDescription} of the source
+ * view.</br>
  * </p>
  * <p>
  * <b>View text selection changed</b> - represents the event of changing the text
@@ -157,35 +176,47 @@
  * <em>Type:</em> {@link #TYPE_VIEW_TEXT_SELECTION_CHANGED} </br>
  * <em>Properties:</em></br>
  * <ul>
+ *   <li>{@link #getEventType()} - The type of the event.</li>
  *   <li>{@link #getSource()} - The source info (for registered clients).</li>
  *   <li>{@link #getClassName()} - The class name of the source.</li>
  *   <li>{@link #getPackageName()} - The package name of the source.</li>
  *   <li>{@link #getEventTime()}  - The event time.</li>
  *   <li>{@link #getText()} - The text of the source.</li>
- *   <li>{@link #isEnabled()} - Whether the source is enabled.</li>
  *   <li>{@link #isPassword()} - Whether the source is password.</li>
  *   <li>{@link #getFromIndex()} - The selection start index.</li>
  *   <li>{@link #getToIndex()} - The selection end index.</li>
  *   <li>{@link #getItemCount()} - The length of the source text.</li>
+ *   <li>{@link #isEnabled()} - Whether the source is enabled.</li>
+ *   <li>{@link #getContentDescription()} - The content description of the source.</li>
  * </ul>
+ * <em>Note:</em> This event type is not dispatched to descendants though
+ * {@link android.view.View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)
+ * View.dispatchPopulateAccessibilityEvent(AccessibilityEvent)}, hence the event
+ * source {@link android.view.View} and the sub-tree rooted at it will not receive
+ * calls to {@link android.view.View#onPopulateAccessibilityEvent(AccessibilityEvent)
+ * View.onPopulateAccessibilityEvent(AccessibilityEvent)}. The preferred way to add
+ * text content to such events is by setting the
+ * {@link android.R.styleable#View_contentDescription contentDescription} of the source
+ * view.</br>
  * </p>
  * <p>
  * <b>View scrolled</b> - represents the event of scrolling a view. If
  * the source is a descendant of {@link android.widget.AdapterView} the
  * scroll is reported in terms of visible items - the first visible item,
  * the last visible item, and the total items - because the the source
- * is unaware if its pixel size since its adapter is responsible for
+ * is unaware of its pixel size since its adapter is responsible for
  * creating views. In all other cases the scroll is reported as the current
  * scroll on the X and Y axis respectively plus the height of the source in
  * pixels.</br>
  * <em>Type:</em> {@link #TYPE_VIEW_SCROLLED}</br>
  * <em>Properties:</em></br>
  * <ul>
+ *   <li>{@link #getEventType()} - The type of the event.</li>
  *   <li>{@link #getSource()} - The source info (for registered clients).</li>
  *   <li>{@link #getClassName()} - The class name of the source.</li>
  *   <li>{@link #getPackageName()} - The package name of the source.</li>
  *   <li>{@link #getEventTime()}  - The event time.</li>
- *   <li>{@link #getText()} - The text of the source.</li>
+ *   <li>{@link #getText()} - The text of the source's sub-tree.</li>
  *   <li>{@link #isEnabled()} - Whether the source is enabled.</li>
  *   <li>{@link #getScrollX()} - The horizontal offset of the source
  *                                (without descendants of AdapterView)).</li>
@@ -197,56 +228,165 @@
  *                               (for descendants of AdapterView).</li>
  *   <li>{@link #getItemCount()} - The total items of the source (for descendants of AdapterView)
  *                                 or the height of the source in pixels (all other cases).</li>
+ *   <li>{@link #getText()} - Text for providing more context.</li>
+ *   <li>{@link #getContentDescription()} - The content description of the source.</li>
  * </ul>
+ * <em>Note:</em> This event type is not dispatched to descendants though
+ * {@link android.view.View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)
+ * View.dispatchPopulateAccessibilityEvent(AccessibilityEvent)}, hence the event
+ * source {@link android.view.View} and the sub-tree rooted at it will not receive
+ * calls to {@link android.view.View#onPopulateAccessibilityEvent(AccessibilityEvent)
+ * View.onPopulateAccessibilityEvent(AccessibilityEvent)}. The preferred way to add
+ * text content to such events is by setting the
+ * {@link android.R.styleable#View_contentDescription contentDescription} of the source
+ * view.</br>
  * </p>
  * <p>
  * <b>TRANSITION TYPES</b></br>
  * </p>
+ * <p>
  * <b>Window state changed</b> - represents the event of opening a
  * {@link android.widget.PopupWindow}, {@link android.view.Menu},
  * {@link android.app.Dialog}, etc.</br>
  * <em>Type:</em> {@link #TYPE_WINDOW_STATE_CHANGED}</br>
  * <em>Properties:</em></br>
  * <ul>
+ *   <li>{@link #getEventType()} - The type of the event.</li>
  *   <li>{@link #getSource()} - The source info (for registered clients).</li>
  *   <li>{@link #getClassName()} - The class name of the source.</li>
  *   <li>{@link #getPackageName()} - The package name of the source.</li>
  *   <li>{@link #getEventTime()}  - The event time.</li>
- *   <li>{@link #getText()} - The text of the source.</li>
+ *   <li>{@link #getText()} - The text of the source's sub-tree.</li>
+ *   <li>{@link #isEnabled()} - Whether the source is enabled.</li>
  * </ul>
  * </p>
  * <p>
  * <b>Window content changed</b> - represents the event of change in the
  * content of a window. This change can be adding/removing view, changing
  * a view size, etc.</br>
+ * </p>
  * <p>
  * <strong>Note:</strong> This event is fired only for the window source of the
- * last accessibility event different from {@link #TYPE_NOTIFICATION_STATE_CHANGED})
+ * last accessibility event different from {@link #TYPE_NOTIFICATION_STATE_CHANGED}
  * and its purpose is to notify clients that the content of the user interaction
- * window has changed.
- * </p>
+ * window has changed.</br>
  * <em>Type:</em> {@link #TYPE_WINDOW_CONTENT_CHANGED}</br>
  * <em>Properties:</em></br>
  * <ul>
+ *   <li>{@link #getEventType()} - The type of the event.</li>
  *   <li>{@link #getSource()} - The source info (for registered clients).</li>
  *   <li>{@link #getClassName()} - The class name of the source.</li>
  *   <li>{@link #getPackageName()} - The package name of the source.</li>
  *   <li>{@link #getEventTime()}  - The event time.</li>
  * </ul>
+ * <em>Note:</em> This event type is not dispatched to descendants though
+ * {@link android.view.View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)
+ * View.dispatchPopulateAccessibilityEvent(AccessibilityEvent)}, hence the event
+ * source {@link android.view.View} and the sub-tree rooted at it will not receive
+ * calls to {@link android.view.View#onPopulateAccessibilityEvent(AccessibilityEvent)
+ * View.onPopulateAccessibilityEvent(AccessibilityEvent)}. The preferred way to add
+ * text content to such events is by setting the
+ * {@link android.R.styleable#View_contentDescription contentDescription} of the source
+ * view.</br>
+ * </p>
  * <p>
  * <b>NOTIFICATION TYPES</b></br>
+ * </p>
  * <p>
  * <b>Notification state changed</b> - represents the event showing
- * {@link android.app.Notification}.
+ * {@link android.app.Notification}.</br>
  * <em>Type:</em> {@link #TYPE_NOTIFICATION_STATE_CHANGED}</br>
  * <em>Properties:</em></br>
  * <ul>
+ *   <li>{@link #getEventType()} - The type of the event.</li>
  *   <li>{@link #getClassName()} - The class name of the source.</li>
  *   <li>{@link #getPackageName()} - The package name of the source.</li>
  *   <li>{@link #getEventTime()}  - The event time.</li>
- *   <li>{@link #getText()} - The text of the source.</li>
+ *   <li>{@link #getText()} - The text of the source's sub-tree.</li>
  *   <li>{@link #getParcelableData()} - The posted {@link android.app.Notification}.</li>
+ *   <li>{@link #getText()} - Text for providing more context.</li>
  * </ul>
+ * <em>Note:</em> This event type is not dispatched to descendants though
+ * {@link android.view.View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)
+ * View.dispatchPopulateAccessibilityEvent(AccessibilityEvent)}, hence the event
+ * source {@link android.view.View} and the sub-tree rooted at it will not receive
+ * calls to {@link android.view.View#onPopulateAccessibilityEvent(AccessibilityEvent)
+ * View.onPopulateAccessibilityEvent(AccessibilityEvent)}. The preferred way to add
+ * text content to such events is by setting the
+ * {@link android.R.styleable#View_contentDescription contentDescription} of the source
+ * view.</br>
+ * </p>
+ * <p>
+ * <b>EXPLORATION TYPES</b></br>
+ * </p>
+ * <p>
+ * <b>View hover enter</b> - represents the event of beginning to hover
+ * over a {@link android.view.View}. The hover may be generated via
+ * exploring the screen by touch or via a pointing device.</br>
+ * <em>Type:</em> {@link #TYPE_VIEW_HOVER_ENTER}</br>
+ * <em>Properties:</em></br>
+ * <ul>
+ *   <li>{@link #getEventType()} - The type of the event.</li>
+ *   <li>{@link #getSource()} - The source info (for registered clients).</li>
+ *   <li>{@link #getClassName()} - The class name of the source.</li>
+ *   <li>{@link #getPackageName()} - The package name of the source.</li>
+ *   <li>{@link #getEventTime()}  - The event time.</li>
+ *   <li>{@link #getText()} - The text of the source's sub-tree.</li>
+ *   <li>{@link #isEnabled()} - Whether the source is enabled.</li>
+ *   <li>{@link #getContentDescription()} - The content description of the source.</li>
+ * </ul>
+ * </p>
+ * <b>View hover exit</b> - represents the event of stopping to hover
+ * over a {@link android.view.View}. The hover may be generated via
+ * exploring the screen by touch or via a pointing device.</br>
+ * <em>Type:</em> {@link #TYPE_VIEW_HOVER_EXIT}</br>
+ * <em>Properties:</em></br>
+ * <ul>
+ *   <li>{@link #getEventType()} - The type of the event.</li>
+ *   <li>{@link #getSource()} - The source info (for registered clients).</li>
+ *   <li>{@link #getClassName()} - The class name of the source.</li>
+ *   <li>{@link #getPackageName()} - The package name of the source.</li>
+ *   <li>{@link #getEventTime()}  - The event time.</li>
+ *   <li>{@link #getText()} - The text of the source's sub-tree.</li>
+ *   <li>{@link #isEnabled()} - Whether the source is enabled.</li>
+ *   <li>{@link #getContentDescription()} - The content description of the source.</li>
+ * </ul>
+ * </p>
+ * <p>
+ * <b>Touch exploration gesture start</b> - represents the event of starting a touch
+ * exploring gesture.</br>
+ * <em>Type:</em> {@link #TYPE_TOUCH_EXPLORATION_GESTURE_START}</br>
+ * <em>Properties:</em></br>
+ * <ul>
+ *   <li>{@link #getEventType()} - The type of the event.</li>
+ * </ul>
+ * <em>Note:</em> This event type is not dispatched to descendants though
+ * {@link android.view.View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)
+ * View.dispatchPopulateAccessibilityEvent(AccessibilityEvent)}, hence the event
+ * source {@link android.view.View} and the sub-tree rooted at it will not receive
+ * calls to {@link android.view.View#onPopulateAccessibilityEvent(AccessibilityEvent)
+ * View.onPopulateAccessibilityEvent(AccessibilityEvent)}. The preferred way to add
+ * text content to such events is by setting the
+ * {@link android.R.styleable#View_contentDescription contentDescription} of the source
+ * view.</br>
+ * </p>
+ * <p>
+ * <b>Touch exploration gesture end</b> - represents the event of ending a touch
+ * exploring gesture.</br>
+ * <em>Type:</em> {@link #TYPE_TOUCH_EXPLORATION_GESTURE_END}</br>
+ * <em>Properties:</em></br>
+ * <ul>
+ *   <li>{@link #getEventType()} - The type of the event.</li>
+ * </ul>
+ * <em>Note:</em> This event type is not dispatched to descendants though
+ * {@link android.view.View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)
+ * View.dispatchPopulateAccessibilityEvent(AccessibilityEvent)}, hence the event
+ * source {@link android.view.View} and the sub-tree rooted at it will not receive
+ * calls to {@link android.view.View#onPopulateAccessibilityEvent(AccessibilityEvent)
+ * View.onPopulateAccessibilityEvent(AccessibilityEvent)}. The preferred way to add
+ * text content to such events is by setting the
+ * {@link android.R.styleable#View_contentDescription contentDescription} of the source
+ * view.</br>
  * </p>
  * <p>
  * <b>Security note</b>
@@ -254,6 +394,7 @@
  * Since an event contains the text of its source privacy can be compromised by leaking
  * sensitive information such as passwords. To address this issue any event fired in response
  * to manipulation of a PASSWORD field does NOT CONTAIN the text of the password.
+ * </p>
  *
  * @see android.view.accessibility.AccessibilityManager
  * @see android.accessibilityservice.AccessibilityService
diff --git a/core/java/android/widget/AdapterView.java b/core/java/android/widget/AdapterView.java
index a4b4e78..61c5dd4 100644
--- a/core/java/android/widget/AdapterView.java
+++ b/core/java/android/widget/AdapterView.java
@@ -881,20 +881,14 @@
 
     @Override
     public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
-        final int eventType = event.getEventType();
-        switch (eventType) {
-            case AccessibilityEvent.TYPE_VIEW_SCROLLED:
-                // Do not populate the text of scroll events.
-                return true;
-            case AccessibilityEvent.TYPE_VIEW_FOCUSED:
-                // This is an exceptional case which occurs when a window gets the
-                // focus and sends a focus event via its focused child to announce
-                // current focus/selection. AdapterView fires selection but not focus
-                // events so we change the event type here.
-                if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_FOCUSED) {
-                    event.setEventType(AccessibilityEvent.TYPE_VIEW_SELECTED);
-                }
-                break;
+        if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_FOCUSED) {
+            // This is an exceptional case which occurs when a window gets the
+            // focus and sends a focus event via its focused child to announce
+            // current focus/selection. AdapterView fires selection but not focus
+            // events so we change the event type here.
+            if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_FOCUSED) {
+                event.setEventType(AccessibilityEvent.TYPE_VIEW_SELECTED);
+            }
         }
 
         View selectedView = getSelectedView();
diff --git a/core/java/android/widget/AnalogClock.java b/core/java/android/widget/AnalogClock.java
index 84ebec3..63a0870 100644
--- a/core/java/android/widget/AnalogClock.java
+++ b/core/java/android/widget/AnalogClock.java
@@ -25,6 +25,7 @@
 import android.graphics.Canvas;
 import android.graphics.drawable.Drawable;
 import android.os.Handler;
+import android.text.format.DateUtils;
 import android.text.format.Time;
 import android.util.AttributeSet;
 import android.view.View;
@@ -228,6 +229,8 @@
         mMinutes = minute + second / 60.0f;
         mHour = hour + mMinutes / 60.0f;
         mChanged = true;
+
+        updateContentDescription(mCalendar);
     }
 
     private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
@@ -243,4 +246,11 @@
             invalidate();
         }
     };
+
+    private void updateContentDescription(Time time) {
+        final int flags = DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_24HOUR;
+        String contentDescription = DateUtils.formatDateTime(mContext,
+                time.toMillis(false), flags);
+        setContentDescription(contentDescription);
+    }
 }
diff --git a/core/java/android/widget/Gallery.java b/core/java/android/widget/Gallery.java
index 3f5b571c..a0eba9a 100644
--- a/core/java/android/widget/Gallery.java
+++ b/core/java/android/widget/Gallery.java
@@ -371,16 +371,6 @@
         }
     }
 
-    @Override
-    public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
-        // Do not append text content to scroll events they are fired frequently
-        // and the client has already received another event type with the text.
-        if (event.getEventType() != AccessibilityEvent.TYPE_VIEW_SCROLLED) {
-            super.dispatchPopulateAccessibilityEvent(event);
-        }
-        return false;
-    }
-
     /**
      * Tracks a motion scroll. In reality, this is used to do just about any
      * movement to items (touch scroll, arrow-key scroll, set an item as selected).
diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java
index 1bbc501..324dfd7 100644
--- a/core/java/android/widget/HorizontalScrollView.java
+++ b/core/java/android/widget/HorizontalScrollView.java
@@ -725,16 +725,6 @@
         event.setScrollable(true);
     }
 
-    @Override
-    public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
-        // Do not append text content to scroll events they are fired frequently
-        // and the client has already received another event type with the text.
-        if (event.getEventType() != AccessibilityEvent.TYPE_VIEW_SCROLLED) {
-            super.dispatchPopulateAccessibilityEvent(event);
-        }
-        return false;
-    }
-
     private int getScrollRange() {
         int scrollRange = 0;
         if (getChildCount() > 0) {
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index 61ea5c9..3ac4e80 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -730,16 +730,6 @@
         event.setScrollable(true);
     }
 
-    @Override
-    public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
-        // Do not append text content to scroll events they are fired frequently
-        // and the client has already received another event type with the text.
-        if (event.getEventType() != AccessibilityEvent.TYPE_VIEW_SCROLLED) {
-            super.dispatchPopulateAccessibilityEvent(event);
-        }
-        return false;
-    }
-
     private int getScrollRange() {
         int scrollRange = 0;
         if (getChildCount() > 0) {
diff --git a/core/java/android/widget/SpellChecker.java b/core/java/android/widget/SpellChecker.java
index 772c129..ce17184 100644
--- a/core/java/android/widget/SpellChecker.java
+++ b/core/java/android/widget/SpellChecker.java
@@ -165,6 +165,7 @@
 
     @Override
     public void onGetSuggestions(SuggestionsInfo[] results) {
+        final Editable editable = (Editable) mTextView.getText();
         for (int i = 0; i < results.length; i++) {
             SuggestionsInfo suggestionsInfo = results[i];
             if (suggestionsInfo.getCookie() != mCookie) continue;
@@ -178,18 +179,19 @@
                     boolean looksLikeTypo =
                             ((attributes & SuggestionsInfo.RESULT_ATTR_LOOKS_LIKE_TYPO) > 0);
 
+                    SpellCheckSpan spellCheckSpan = mSpellCheckSpans[j];
                     if (!isInDictionary && looksLikeTypo) {
-                        createMisspelledSuggestionSpan(suggestionsInfo, mSpellCheckSpans[j]);
+                        createMisspelledSuggestionSpan(editable, suggestionsInfo, spellCheckSpan);
                     }
+                    editable.removeSpan(spellCheckSpan);
                     break;
                 }
             }
         }
     }
 
-    private void createMisspelledSuggestionSpan(SuggestionsInfo suggestionsInfo,
+    private void createMisspelledSuggestionSpan(Editable editable, SuggestionsInfo suggestionsInfo,
             SpellCheckSpan spellCheckSpan) {
-        final Editable editable = (Editable) mTextView.getText();
         final int start = editable.getSpanStart(spellCheckSpan);
         final int end = editable.getSpanEnd(spellCheckSpan);
 
@@ -251,6 +253,5 @@
 
         // TODO limit to the word rectangle region
         mTextView.invalidate();
-        editable.removeSpan(spellCheckSpan);
     }
 }
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 5edb47c..17f0e05 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -7780,7 +7780,7 @@
 
         // Iterate over the newly added text and schedule new SpellCheckSpans
         while (wordStart <= shiftedEnd) {
-            if (wordEnd >= shiftedStart) {
+            if (wordEnd >= shiftedStart && wordEnd > wordStart) {
                 // A new word has been created across the interval boundaries. Remove previous spans
                 if (wordStart < shiftedStart && wordEnd > shiftedStart) {
                     removeSpansAt(start, spellCheckSpans, text);
@@ -8925,10 +8925,10 @@
 
         // If a URLSpan (web address, email, phone...) is found at that position, select it.
         URLSpan[] urlSpans = ((Spanned) mText).getSpans(minOffset, maxOffset, URLSpan.class);
-        if (urlSpans.length == 1) {
-            URLSpan url = urlSpans[0];
-            selectionStart = ((Spanned) mText).getSpanStart(url);
-            selectionEnd = ((Spanned) mText).getSpanEnd(url);
+        if (urlSpans.length >= 1) {
+            URLSpan urlSpan = urlSpans[0];
+            selectionStart = ((Spanned) mText).getSpanStart(urlSpan);
+            selectionEnd = ((Spanned) mText).getSpanEnd(urlSpan);
         } else {
             final int shift = prepareWordIterator(minOffset, maxOffset);
 
@@ -8939,10 +8939,42 @@
             selectionEnd = mWordIterator.getEnd(maxOffset - shift);
             if (selectionEnd == BreakIterator.DONE) return false;
             selectionEnd += shift;
+
+            if (selectionStart == selectionEnd) {
+                // Possible when the word iterator does not properly handle the text's language
+                long range = getCharRange(selectionStart);
+                selectionStart = extractRangeStartFromLong(range);
+                selectionEnd = extractRangeEndFromLong(range);
+            }
         }
 
         Selection.setSelection((Spannable) mText, selectionStart, selectionEnd);
-        return true;
+        return selectionEnd > selectionStart;
+    }
+
+    private long getCharRange(int offset) {
+        final int textLength = mText.length();
+        if (offset + 1 < textLength) {
+            final char currentChar = mText.charAt(offset);
+            final char nextChar = mText.charAt(offset + 1);
+            if (Character.isSurrogatePair(currentChar, nextChar)) {
+                return packRangeInLong(offset,  offset + 2);
+            }
+        }
+        if (offset < textLength) {
+            return packRangeInLong(offset,  offset + 1);
+        }
+        if (offset - 2 >= 0) {
+            final char previousChar = mText.charAt(offset - 1);
+            final char previousPreviousChar = mText.charAt(offset - 2);
+            if (Character.isSurrogatePair(previousPreviousChar, previousChar)) {
+                return packRangeInLong(offset - 2,  offset);
+            }
+        }
+        if (offset - 1 >= 0) {
+            return packRangeInLong(offset - 1,  offset);
+        }
+        return packRangeInLong(offset,  offset);
     }
 
     int prepareWordIterator(int start, int end) {
@@ -9330,7 +9362,7 @@
 
         // Start a new selection
         if (!handled) {
-            handled = startSelectionActionMode();
+            vibrate = handled = startSelectionActionMode();
         }
 
         if (vibrate) {
@@ -9946,8 +9978,8 @@
                     suggestionInfo.text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
 
             // Add the text before and after the span.
-            suggestionInfo.text.insert(0, mText.subSequence(unionStart, spanStart).toString());
-            suggestionInfo.text.append(mText.subSequence(spanEnd, unionEnd).toString());
+            suggestionInfo.text.insert(0, mText.toString().substring(unionStart, spanStart));
+            suggestionInfo.text.append(mText.toString().substring(spanEnd, unionEnd));
         }
 
         @Override
@@ -9979,7 +10011,7 @@
                 hide();
                 return;
             }
-            final String originalText = mText.subSequence(spanStart, spanEnd).toString();
+            final String originalText = mText.toString().substring(spanStart, spanEnd);
 
             if (suggestionInfo.suggestionIndex == ADD_TO_DICTIONARY) {
                 Intent intent = new Intent(Settings.ACTION_USER_DICTIONARY_INSERT);
@@ -10016,8 +10048,10 @@
                 if (!TextUtils.isEmpty(
                         suggestionInfo.suggestionSpan.getNotificationTargetClassName())) {
                     InputMethodManager imm = InputMethodManager.peekInstance();
-                    imm.notifySuggestionPicked(suggestionInfo.suggestionSpan, originalText,
-                            suggestionInfo.suggestionIndex);
+                    if (imm != null) {
+                        imm.notifySuggestionPicked(suggestionInfo.suggestionSpan, originalText,
+                                suggestionInfo.suggestionIndex);
+                    }
                 }
 
                 // Swap text content between actual text and Suggestion span
@@ -10037,7 +10071,7 @@
                     }
                 }
 
-                // Move cursor at the end of the replacement word
+                // Move cursor at the end of the replaced word
                 Selection.setSelection(editable, spanEnd + lengthDifference);
             }
 
@@ -10166,8 +10200,7 @@
 
         if (!hasSelection()) {
             // There may already be a selection on device rotation
-            boolean currentWordSelected = selectCurrentWord();
-            if (!currentWordSelected) {
+            if (!selectCurrentWord()) {
                 // No word found under cursor or text selection not permitted.
                 return false;
             }
@@ -10248,7 +10281,8 @@
 
         @Override
         public boolean onCreateActionMode(ActionMode mode, Menu menu) {
-            TypedArray styledAttributes = mContext.obtainStyledAttributes(R.styleable.Theme);
+            TypedArray styledAttributes = mContext.obtainStyledAttributes(
+                    com.android.internal.R.styleable.SelectionModeDrawables);
 
             boolean allowText = getContext().getResources().getBoolean(
                     com.android.internal.R.bool.config_allowActionMenuItemTextWithIcon);
@@ -10261,7 +10295,7 @@
             if (!allowText) {
                 // Provide an icon, text will not be displayed on smaller screens.
                 selectAllIconId = styledAttributes.getResourceId(
-                        R.styleable.Theme_actionModeSelectAllDrawable, 0);
+                        R.styleable.SelectionModeDrawables_actionModeSelectAllDrawable, 0);
             }
 
             menu.add(0, ID_SELECT_ALL, 0, com.android.internal.R.string.selectAll).
@@ -10273,7 +10307,7 @@
             if (canCut()) {
                 menu.add(0, ID_CUT, 0, com.android.internal.R.string.cut).
                     setIcon(styledAttributes.getResourceId(
-                            R.styleable.Theme_actionModeCutDrawable, 0)).
+                            R.styleable.SelectionModeDrawables_actionModeCutDrawable, 0)).
                     setAlphabeticShortcut('x').
                     setShowAsAction(
                             MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
@@ -10282,7 +10316,7 @@
             if (canCopy()) {
                 menu.add(0, ID_COPY, 0, com.android.internal.R.string.copy).
                     setIcon(styledAttributes.getResourceId(
-                            R.styleable.Theme_actionModeCopyDrawable, 0)).
+                            R.styleable.SelectionModeDrawables_actionModeCopyDrawable, 0)).
                     setAlphabeticShortcut('c').
                     setShowAsAction(
                             MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
@@ -10291,7 +10325,7 @@
             if (canPaste()) {
                 menu.add(0, ID_PASTE, 0, com.android.internal.R.string.paste).
                         setIcon(styledAttributes.getResourceId(
-                                R.styleable.Theme_actionModePasteDrawable, 0)).
+                                R.styleable.SelectionModeDrawables_actionModePasteDrawable, 0)).
                         setAlphabeticShortcut('v').
                         setShowAsAction(
                                 MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
diff --git a/core/java/android/widget/TimePicker.java b/core/java/android/widget/TimePicker.java
index 7444d46..f52e773 100644
--- a/core/java/android/widget/TimePicker.java
+++ b/core/java/android/widget/TimePicker.java
@@ -237,9 +237,7 @@
         }
 
         // set the content descriptions
-        if (AccessibilityManager.getInstance(mContext).isEnabled()) {
-            setContentDescriptions();
-        }
+        setContentDescriptions();
     }
 
     @Override
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 4a38775..2694aa2 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -24,11 +24,15 @@
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.hardware.Camera;
+import android.hardware.Camera.CameraInfo;
 import android.os.FileObserver;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.SystemClock;
+import android.os.SystemProperties;
 import android.os.storage.IMountService;
 import android.provider.Settings;
 import android.security.KeyStore;
@@ -55,6 +59,8 @@
  */
 public class LockPatternUtils {
 
+    private static final String OPTION_ENABLE_FACELOCK = "enable_facelock";
+
     private static final String TAG = "LockPatternUtils";
 
     private static final String SYSTEM_DIRECTORY = "/system/";
@@ -110,6 +116,7 @@
     public static final String PASSWORD_TYPE_ALTERNATE_KEY = "lockscreen.password_type_alternate";
     private final static String LOCK_PASSWORD_SALT_KEY = "lockscreen.password_salt";
     private final static String DISABLE_LOCKSCREEN_KEY = "lockscreen.disabled";
+    private final static String LOCKSCREEN_OPTIONS = "lockscreen.options";
     public final static String LOCKSCREEN_BIOMETRIC_WEAK_FALLBACK
             = "lockscreen.biometric_weak_fallback";
 
@@ -339,12 +346,21 @@
      */
     public int getActivePasswordQuality() {
         int activePasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
-        switch (getKeyguardStoredPasswordQuality()) {
+        // Note we don't want to use getKeyguardStoredPasswordQuality() because we want this to
+        // return biometric_weak if that is being used instead of the backup
+        int quality =
+                (int) getLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
+        switch (quality) {
             case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
                 if (isLockPatternEnabled()) {
                     activePasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
                 }
                 break;
+            case DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK:
+                if (isBiometricWeakInstalled()) {
+                    activePasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK;
+                }
+                break;
             case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
                 if (isLockPasswordEnabled()) {
                     activePasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_NUMERIC;
@@ -366,6 +382,7 @@
                 }
                 break;
         }
+
         return activePasswordQuality;
     }
 
@@ -434,7 +451,7 @@
      * Calls back SetupFaceLock to delete the gallery file when the lock type is changed
     */
     void deleteGallery() {
-        if(isBiometricEnabled()) {
+        if(usingBiometricWeak()) {
             Intent intent = new Intent().setClassName("com.android.facelock",
                     "com.android.facelock.SetupFaceLock");
             intent.putExtra("deleteGallery", true);
@@ -677,6 +694,9 @@
         return quality;
     }
 
+    /**
+     * @return true if the lockscreen method is set to biometric weak
+     */
     public boolean usingBiometricWeak() {
         int quality =
                 (int) getLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
@@ -810,7 +830,7 @@
                 || backupMode == DevicePolicyManager.PASSWORD_QUALITY_COMPLEX;
 
         return savedPasswordExists() && (passwordEnabled ||
-                (isBiometricEnabled() && backupEnabled));
+                (usingBiometricWeak() && backupEnabled));
     }
 
     /**
@@ -824,16 +844,36 @@
         return getBoolean(Settings.Secure.LOCK_PATTERN_ENABLED)
                 && (getLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING)
                         == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING ||
-                        (isBiometricEnabled() && backupEnabled));
+                        (usingBiometricWeak() && backupEnabled));
     }
 
     /**
-     * @return Whether biometric weak lock is enabled.
+     * @return Whether biometric weak lock is installed and that the front facing camera exists
      */
-    public boolean isBiometricEnabled() {
-        // TODO: check if it's installed
-        return getLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING)
-                == DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK;
+    public boolean isBiometricWeakInstalled() {
+        // Check that the system flag was set
+        if (!OPTION_ENABLE_FACELOCK.equals(getString(LOCKSCREEN_OPTIONS))) {
+            return false;
+        }
+
+        // Check that it's installed
+        PackageManager pm = mContext.getPackageManager();
+        try {
+            pm.getPackageInfo("com.android.facelock", PackageManager.GET_ACTIVITIES);
+        } catch (PackageManager.NameNotFoundException e) {
+            return false;
+        }
+
+        // Check that the camera is enabled
+        if (!pm.hasSystemFeature(PackageManager.FEATURE_CAMERA_FRONT)) {
+            return false;
+        }
+        if (getDevicePolicyManager().getCameraDisabled(null)) {
+            return false;
+        }
+
+
+        return true;
     }
 
     /**
diff --git a/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java b/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java
index 366b983..01df48a 100644
--- a/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java
+++ b/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java
@@ -48,11 +48,11 @@
     private PasswordEntryKeyboard mSymbolsKeyboard;
     private PasswordEntryKeyboard mSymbolsKeyboardShifted;
     private PasswordEntryKeyboard mNumericKeyboard;
-    private Context mContext;
-    private View mTargetView;
-    private KeyboardView mKeyboardView;
+    private final Context mContext;
+    private final View mTargetView;
+    private final KeyboardView mKeyboardView;
     private long[] mVibratePattern;
-    private Vibrator mVibrator;
+    private final Vibrator mVibrator;
 
     public PasswordEntryKeyboardHelper(Context context, KeyboardView keyboardView, View targetView) {
         this(context, keyboardView, targetView, true);
@@ -228,7 +228,7 @@
         }
     }
 
-    private void handleBackspace() {
+    public void handleBackspace() {
         sendDownUpKeyEvents(KeyEvent.KEYCODE_DEL);
     }
 
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index 18bd754..da055fc 100644
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -392,10 +392,20 @@
     SkSafeUnref(ctable);

 

     size_t size = bitmap->getSize();

+

+    android::Parcel::ReadableBlob blob;

+    android::status_t status = p->readBlob(size, &blob);

+    if (status) {

+        doThrowRE(env, "Could not read bitmap from parcel blob.");

+        delete bitmap;

+        return NULL;

+    }

+

     bitmap->lockPixels();

-    memcpy(bitmap->getPixels(), p->readInplace(size), size);

+    memcpy(bitmap->getPixels(), blob.data(), size);

     bitmap->unlockPixels();

 

+    blob.release();

     return GraphicsJNI::createBitmap(env, bitmap, buffer, isMutable, NULL, density);

 }

 

@@ -431,17 +441,24 @@
     }

 

     size_t size = bitmap->getSize();

+

+    android::Parcel::WritableBlob blob;

+    android::status_t status = p->writeBlob(size, &blob);

+    if (status) {

+        doThrowRE(env, "Could not write bitmap to parcel blob.");

+        return false;

+    }

+

     bitmap->lockPixels();

-    void* pDst = p->writeInplace(size);

-

     const void* pSrc =  bitmap->getPixels();

-

     if (pSrc == NULL) {

-        memset(pDst, 0, size);

+        memset(blob.data(), 0, size);

     } else {

-        memcpy(pDst, pSrc, size);

+        memcpy(blob.data(), pSrc, size);

     }

     bitmap->unlockPixels();

+

+    blob.release();

     return true;

 }

 

diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index 494a2b3..1718e74 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -697,6 +697,10 @@
             LOGE("!!! FAILED BINDER TRANSACTION !!!");
             //jniThrowException(env, "java/lang/OutOfMemoryError", "Binder transaction too large");
             break;
+        case FDS_NOT_ALLOWED:
+            jniThrowException(env, "java/lang/RuntimeException",
+                    "Not allowed to write file descriptors here");
+            break;
         default:
             LOGE("Unknown binder error code. 0x%x", err);
     }
@@ -1275,7 +1279,7 @@
     if (parcel != NULL) {
         const status_t err = parcel->setDataSize(size);
         if (err != NO_ERROR) {
-            jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
+            signalExceptionForError(env, clazz, err);
         }
     }
 }
@@ -1294,11 +1298,29 @@
     if (parcel != NULL) {
         const status_t err = parcel->setDataCapacity(size);
         if (err != NO_ERROR) {
-            jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
+            signalExceptionForError(env, clazz, err);
         }
     }
 }
 
+static jboolean android_os_Parcel_pushAllowFds(JNIEnv* env, jobject clazz, jboolean allowFds)
+{
+    Parcel* parcel = parcelForJavaObject(env, clazz);
+    jboolean ret = JNI_TRUE;
+    if (parcel != NULL) {
+        ret = (jboolean)parcel->pushAllowFds(allowFds);
+    }
+    return ret;
+}
+
+static void android_os_Parcel_restoreAllowFds(JNIEnv* env, jobject clazz, jboolean lastValue)
+{
+    Parcel* parcel = parcelForJavaObject(env, clazz);
+    if (parcel != NULL) {
+        parcel->restoreAllowFds((bool)lastValue);
+    }
+}
+
 static void android_os_Parcel_writeNative(JNIEnv* env, jobject clazz,
                                           jobject data, jint offset,
                                           jint length)
@@ -1310,12 +1332,13 @@
 
     const status_t err = parcel->writeInt32(length);
     if (err != NO_ERROR) {
-        jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
+        signalExceptionForError(env, clazz, err);
+        return;
     }
 
     void* dest = parcel->writeInplace(length);
     if (dest == NULL) {
-        jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
+        signalExceptionForError(env, clazz, NO_MEMORY);
         return;
     }
 
@@ -1333,7 +1356,7 @@
     if (parcel != NULL) {
         const status_t err = parcel->writeInt32(val);
         if (err != NO_ERROR) {
-            jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
+            signalExceptionForError(env, clazz, err);
         }
     }
 }
@@ -1344,7 +1367,7 @@
     if (parcel != NULL) {
         const status_t err = parcel->writeInt64(val);
         if (err != NO_ERROR) {
-            jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
+            signalExceptionForError(env, clazz, err);
         }
     }
 }
@@ -1355,7 +1378,7 @@
     if (parcel != NULL) {
         const status_t err = parcel->writeFloat(val);
         if (err != NO_ERROR) {
-            jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
+            signalExceptionForError(env, clazz, err);
         }
     }
 }
@@ -1366,7 +1389,7 @@
     if (parcel != NULL) {
         const status_t err = parcel->writeDouble(val);
         if (err != NO_ERROR) {
-            jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
+            signalExceptionForError(env, clazz, err);
         }
     }
 }
@@ -1386,7 +1409,7 @@
             err = parcel->writeString16(NULL, 0);
         }
         if (err != NO_ERROR) {
-            jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
+            signalExceptionForError(env, clazz, err);
         }
     }
 }
@@ -1397,7 +1420,7 @@
     if (parcel != NULL) {
         const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object));
         if (err != NO_ERROR) {
-            jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
+            signalExceptionForError(env, clazz, err);
         }
     }
 }
@@ -1409,7 +1432,7 @@
         const status_t err =
                 parcel->writeDupFileDescriptor(jniGetFDFromFileDescriptor(env, object));
         if (err != NO_ERROR) {
-            jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
+            signalExceptionForError(env, clazz, err);
         }
     }
 }
@@ -1717,7 +1740,10 @@
        return;
     }
 
-    (void) thisParcel->appendFrom(otherParcel, offset, length);
+    status_t err = thisParcel->appendFrom(otherParcel, offset, length);
+    if (err != NO_ERROR) {
+        signalExceptionForError(env, clazz, err);
+    }
 }
 
 static jboolean android_os_Parcel_hasFileDescriptors(JNIEnv* env, jobject clazz)
@@ -1792,6 +1818,8 @@
     {"setDataSize",         "(I)V", (void*)android_os_Parcel_setDataSize},
     {"setDataPosition",     "(I)V", (void*)android_os_Parcel_setDataPosition},
     {"setDataCapacity",     "(I)V", (void*)android_os_Parcel_setDataCapacity},
+    {"pushAllowFds",        "(Z)Z", (void*)android_os_Parcel_pushAllowFds},
+    {"restoreAllowFds",     "(Z)V", (void*)android_os_Parcel_restoreAllowFds},
     {"writeNative",         "([BII)V", (void*)android_os_Parcel_writeNative},
     {"writeInt",            "(I)V", (void*)android_os_Parcel_writeInt},
     {"writeLong",           "(J)V", (void*)android_os_Parcel_writeLong},
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 9755f22..18194ee 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -263,6 +263,23 @@
         android:label="@string/permlab_writeProfile"
         android:description="@string/permdesc_writeProfile" />
 
+    <!-- Allows an application to read from the user's social stream.
+         @hide -->
+    <permission android:name="android.permission.READ_SOCIAL_STREAM"
+        android:permissionGroup="android.permission-group.PERSONAL_INFO"
+        android:protectionLevel="dangerous"
+        android:label="@string/permlab_readSocialStream"
+        android:description="@string/permdesc_readSocialStream" />
+
+    <!-- Allows an application to write (but not read) the user's
+         social stream data.
+         @hide -->
+    <permission android:name="android.permission.WRITE_SOCIAL_STREAM"
+        android:permissionGroup="android.permission-group.PERSONAL_INFO"
+        android:protectionLevel="dangerous"
+        android:label="@string/permlab_writeSocialStream"
+        android:description="@string/permdesc_writeSocialStream" />
+
     <!-- Allows an application to read the user's calendar data. -->
     <permission android:name="android.permission.READ_CALENDAR"
         android:permissionGroup="android.permission-group.PERSONAL_INFO"
diff --git a/core/res/res/layout/keyguard_screen_password_landscape.xml b/core/res/res/layout/keyguard_screen_password_landscape.xml
index 8bc5f34..e34822d 100644
--- a/core/res/res/layout/keyguard_screen_password_landscape.xml
+++ b/core/res/res/layout/keyguard_screen_password_landscape.xml
@@ -135,7 +135,8 @@
     <LinearLayout
         android:orientation="horizontal"
         android:layout_width="270dip"
-        android:layout_gravity="center_vertical">
+        android:layout_gravity="center_vertical"
+        android:background="@drawable/lockscreen_password_field_dark">
 
         <EditText android:id="@+id/passwordEntry"
             android:layout_height="wrap_content"
@@ -148,11 +149,23 @@
             android:textSize="24sp"
             android:minEms="8"
             android:textAppearance="?android:attr/textAppearanceMedium"
-            android:background="@drawable/lockscreen_password_field_dark"
+            android:background="@null"
             android:textColor="?android:attr/textColorPrimary"
             android:imeOptions="flagNoFullscreen|actionDone"
             />
 
+        <!-- This delete button is only visible for numeric PIN entry -->
+        <ImageButton android:id="@+id/pinDel"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:src="@android:drawable/ic_input_delete"
+            android:clickable="true"
+            android:padding="8dip"
+            android:layout_gravity="center"
+            android:background="?android:attr/selectableItemBackground"
+            android:visibility="gone"
+            />
+
         <ImageView android:id="@+id/switch_ime_button"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
diff --git a/core/res/res/layout/keyguard_screen_password_portrait.xml b/core/res/res/layout/keyguard_screen_password_portrait.xml
index 2a66d7d..e1280ba 100644
--- a/core/res/res/layout/keyguard_screen_password_portrait.xml
+++ b/core/res/res/layout/keyguard_screen_password_portrait.xml
@@ -95,9 +95,12 @@
         />
 
     <!-- Password entry field -->
+    <!-- Note: the entire container is styled to look like the edit field,
+         since the backspace/IME switcher looks better inside -->
     <LinearLayout
         android:layout_gravity="center_vertical|fill_horizontal"
         android:orientation="horizontal"
+        android:background="@drawable/lockscreen_password_field_dark"
         android:layout_marginLeft="16dip"
         android:layout_marginRight="16dip">
 
@@ -110,12 +113,24 @@
             android:textStyle="normal"
             android:inputType="textPassword"
             android:textSize="36sp"
-            android:background="@drawable/lockscreen_password_field_dark"
+            android:background="@null"
             android:textAppearance="?android:attr/textAppearanceMedium"
             android:textColor="#ffffffff"
             android:imeOptions="actionDone"
             />
 
+        <!-- This delete button is only visible for numeric PIN entry -->
+        <ImageButton android:id="@+id/pinDel"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:src="@android:drawable/ic_input_delete"
+            android:clickable="true"
+            android:padding="8dip"
+            android:layout_gravity="center_vertical"
+            android:background="?android:attr/selectableItemBackground"
+            android:visibility="gone"
+            />
+
         <ImageView android:id="@+id/switch_ime_button"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index c990125..a27abb3 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -3181,6 +3181,12 @@
         <!-- Base text color, typeface, size, and style. -->
         <attr name="textAppearance" />
     </declare-styleable>
+    <declare-styleable name="SelectionModeDrawables">
+        <attr name="actionModeSelectAllDrawable" />
+        <attr name="actionModeCutDrawable" />
+        <attr name="actionModeCopyDrawable" />
+        <attr name="actionModePasteDrawable" />
+    </declare-styleable>
     <declare-styleable name="SuggestionSpan">
         <attr name="textUnderlineColor" />
         <attr name="textUnderlineThickness" />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 1e0151a..9208efe 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -941,6 +941,19 @@
         information.  This means other applications can identify you and send your profile
         information to others.</string>
 
+    <!-- Title of the read social stream permission, listed so the user can decide whether to allow the application to read information from the user's social stream. [CHAR LIMIT=30] -->
+    <string name="permlab_readSocialStream" product="default">read your social stream</string>
+    <string name="permdesc_readSocialStream" product="default">Allows the application to access
+        and sync social updates from you and your friends. Malicious apps can use this to read
+        private communications between you and your friends on social networks.</string>
+
+    <!-- Title of the write social stream permission, listed so the user can decide whether to allow the application to write information to the user's social stream. [CHAR LIMIT=30] -->
+    <string name="permlab_writeSocialStream" product="default">write to your social stream</string>
+    <string name="permdesc_writeSocialStream" product="default">Allows the application to display
+        social updates from your friends. Malicious apps can use this to pretend to be a friend
+        and trick you into revealing passwords or other confidential information.</string>
+
+    
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_readCalendar">read calendar events plus confidential information</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
@@ -3316,4 +3329,4 @@
     <!-- Delimeter used between each item in a textual list; for example "Alpha, Beta". [CHAR LIMIT=3] -->
     <string name="list_delimeter">", "</string>
 
-</resources>
\ No newline at end of file
+</resources>
diff --git a/core/res/res/xml/password_kbd_numeric.xml b/core/res/res/xml/password_kbd_numeric.xml
index 2fd5aa0..560f867 100755
--- a/core/res/res/xml/password_kbd_numeric.xml
+++ b/core/res/res/xml/password_kbd_numeric.xml
@@ -49,12 +49,10 @@
     </Row>
 
     <Row android:rowEdgeFlags="bottom">
+        <Key android:codes="48" android:keyIcon="@drawable/sym_keyboard_num0_no_plus"
+             android:keyWidth="66.66%p" android:keyEdgeFlags="left"/>
         <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_ok"
-             android:keyEdgeFlags="left"/>
-        <Key android:codes="48" android:keyIcon="@drawable/sym_keyboard_num0_no_plus"/>
-        <Key android:codes="-5" android:keyIcon="@drawable/sym_keyboard_delete"
-             android:iconPreview="@drawable/sym_keyboard_feedback_delete"
-             android:isRepeatable="true" android:keyEdgeFlags="right"/>
+             android:keyEdgeFlags="right"/>
     </Row>
 
 </Keyboard>
diff --git a/core/tests/coretests/src/android/net/NetworkStatsTest.java b/core/tests/coretests/src/android/net/NetworkStatsTest.java
index c36685d..d78d2ef 100644
--- a/core/tests/coretests/src/android/net/NetworkStatsTest.java
+++ b/core/tests/coretests/src/android/net/NetworkStatsTest.java
@@ -18,6 +18,8 @@
 
 import static android.net.NetworkStats.SET_DEFAULT;
 import static android.net.NetworkStats.SET_FOREGROUND;
+import static android.net.NetworkStats.SET_ALL;
+import static android.net.NetworkStats.IFACE_ALL;
 import static android.net.NetworkStats.TAG_NONE;
 import static android.net.NetworkStats.UID_ALL;
 
@@ -176,8 +178,63 @@
         assertEquals(64L, uidTag.getTotalBytes());
     }
 
+    public void testGroupedByIfaceEmpty() throws Exception {
+        final NetworkStats uidStats = new NetworkStats(TEST_START, 3);
+        final NetworkStats grouped = uidStats.groupedByIface();
+
+        assertEquals(0, uidStats.size());
+        assertEquals(0, grouped.size());
+    }
+
+    public void testGroupedByIfaceAll() throws Exception {
+        final NetworkStats uidStats = new NetworkStats(TEST_START, 3)
+                .addValues(IFACE_ALL, 100, SET_ALL, TAG_NONE, 128L, 8L, 0L, 2L, 20L)
+                .addValues(IFACE_ALL, 101, SET_FOREGROUND, TAG_NONE, 128L, 8L, 0L, 2L, 20L);
+        final NetworkStats grouped = uidStats.groupedByIface();
+
+        assertEquals(2, uidStats.size());
+        assertEquals(1, grouped.size());
+
+        assertValues(grouped, 0, IFACE_ALL, UID_ALL, SET_ALL, TAG_NONE, 256L, 16L, 0L, 4L, 0L);
+    }
+
+    public void testGroupedByIface() throws Exception {
+        final NetworkStats uidStats = new NetworkStats(TEST_START, 3)
+                .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 2L, 20L)
+                .addValues(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, 512L, 32L, 0L, 0L, 0L)
+                .addValues(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, 64L, 4L, 0L, 0L, 0L)
+                .addValues(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, 512L, 32L, 0L, 0L, 0L)
+                .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 0L, 0L)
+                .addValues(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, 128L, 8L, 0L, 0L, 0L);
+
+        final NetworkStats grouped = uidStats.groupedByIface();
+
+        assertEquals(6, uidStats.size());
+
+        assertEquals(2, grouped.size());
+        assertValues(grouped, 0, TEST_IFACE, UID_ALL, SET_ALL, TAG_NONE, 256L, 16L, 0L, 2L, 0L);
+        assertValues(grouped, 1, TEST_IFACE2, UID_ALL, SET_ALL, TAG_NONE, 1024L, 64L, 0L, 0L, 0L);
+    }
+
+    public void testAddAllValues() {
+        final NetworkStats first = new NetworkStats(TEST_START, 5)
+                .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 32L, 0L, 0L, 0L, 0L)
+                .addValues(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, 32L, 0L, 0L, 0L, 0L);
+
+        final NetworkStats second = new NetworkStats(TEST_START, 2)
+                .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 32L, 0L, 0L, 0L, 0L)
+                .addValues(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, 32L, 0L, 0L, 0L, 0L);
+
+        first.combineAllValues(second);
+
+        assertEquals(3, first.size());
+        assertValues(first, 0, TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 64L, 0L, 0L, 0L, 0L);
+        assertValues(first, 1, TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, 32L, 0L, 0L, 0L, 0L);
+        assertValues(first, 2, TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, 32L, 0L, 0L, 0L, 0L);
+    }
+
     private static void assertValues(NetworkStats stats, int index, String iface, int uid, int set,
-            int tag, long rxBytes, long rxPackets, long txBytes, long txPackets, int operations) {
+            int tag, long rxBytes, long rxPackets, long txBytes, long txPackets, long operations) {
         final NetworkStats.Entry entry = stats.getValues(index, null);
         assertEquals(iface, entry.iface);
         assertEquals(uid, entry.uid);
diff --git a/data/sounds/AudioPackage7.mk b/data/sounds/AudioPackage7.mk
index 16171dc..9983f38 100755
--- a/data/sounds/AudioPackage7.mk
+++ b/data/sounds/AudioPackage7.mk
@@ -27,17 +27,24 @@
 	$(LOCAL_PATH)/effects/ogg/Lock.ogg:system/media/audio/ui/Lock.ogg \
 	$(LOCAL_PATH)/effects/ogg/Unlock.ogg:system/media/audio/ui/Unlock.ogg \
 	$(LOCAL_PATH)/notifications/ogg/Altair.ogg:system/media/audio/notifications/Altair.ogg \
-	$(LOCAL_PATH)/notifications/ogg/Antares.ogg:system/media/audio/notifications/Antares.ogg \
-	$(LOCAL_PATH)/notifications/ogg/Deneb.ogg:system/media/audio/notifications/Deneb.ogg \
-	$(LOCAL_PATH)/notifications/ogg/Lalande.ogg:system/media/audio/notifications/Lalande.ogg \
-	$(LOCAL_PATH)/notifications/ogg/Hojus.ogg:system/media/audio/notifications/Hojus.ogg \
-	$(LOCAL_PATH)/notifications/ogg/Proxima.ogg:system/media/audio/notifications/Proxima.ogg \
+	$(LOCAL_PATH)/notifications/ogg/Arcturus.ogg:system/media/audio/notifications/Arcturus.ogg \
 	$(LOCAL_PATH)/notifications/ogg/Betelgeuse.ogg:system/media/audio/notifications/Betelgeuse.ogg \
+	$(LOCAL_PATH)/notifications/ogg/Capella.ogg:system/media/audio/notifications/Capella.ogg \
+	$(LOCAL_PATH)/notifications/ogg/CetiAlpha.ogg:system/media/audio/notifications/CetiAlpha.ogg \
+	$(LOCAL_PATH)/notifications/ogg/Deneb.ogg:system/media/audio/notifications/Deneb.ogg \
+	$(LOCAL_PATH)/notifications/ogg/Hojus.ogg:system/media/audio/notifications/Hojus.ogg \
+	$(LOCAL_PATH)/notifications/ogg/Lalande.ogg:system/media/audio/notifications/Lalande.ogg \
 	$(LOCAL_PATH)/notifications/ogg/Mira.ogg:system/media/audio/notifications/Mira.ogg \
+	$(LOCAL_PATH)/notifications/ogg/Polaris.ogg:system/media/audio/notifications/Polaris.ogg \
+	$(LOCAL_PATH)/notifications/ogg/Procyon.ogg:system/media/audio/notifications/Procyon.ogg \
+	$(LOCAL_PATH)/notifications/ogg/Proxima.ogg:system/media/audio/notifications/Proxima.ogg \
 	$(LOCAL_PATH)/notifications/ogg/Upsilon.ogg:system/media/audio/notifications/Upsilon.ogg \
+	$(LOCAL_PATH)/notifications/ogg/Vega.ogg:system/media/audio/notifications/Vega.ogg \
+	$(LOCAL_PATH)/ringtones/ogg/Acheron.ogg:system/media/audio/ringtones/Acheron.ogg \
 	$(LOCAL_PATH)/ringtones/ogg/Andromeda.ogg:system/media/audio/ringtones/Andromeda.ogg \
 	$(LOCAL_PATH)/ringtones/ogg/Aquila.ogg:system/media/audio/ringtones/Aquila.ogg \
 	$(LOCAL_PATH)/ringtones/ogg/ArgoNavis.ogg:system/media/audio/ringtones/ArgoNavis.ogg \
+	$(LOCAL_PATH)/ringtones/ogg/CanisMajor.ogg:system/media/audio/ringtones/CanisMajor.ogg \
 	$(LOCAL_PATH)/ringtones/ogg/Carina.ogg:system/media/audio/ringtones/Carina.ogg \
 	$(LOCAL_PATH)/ringtones/ogg/Cassiopeia.ogg:system/media/audio/ringtones/Cassiopeia.ogg \
 	$(LOCAL_PATH)/ringtones/ogg/Centaurus.ogg:system/media/audio/ringtones/Centaurus.ogg \
@@ -45,8 +52,10 @@
 	$(LOCAL_PATH)/ringtones/ogg/Draco.ogg:system/media/audio/ringtones/Draco.ogg \
 	$(LOCAL_PATH)/ringtones/ogg/Hydra.ogg:system/media/audio/ringtones/Hydra.ogg \
 	$(LOCAL_PATH)/ringtones/ogg/Machina.ogg:system/media/audio/ringtones/Machina.ogg \
+	$(LOCAL_PATH)/ringtones/ogg/Nasqueron.ogg:system/media/audio/ringtones/Nasqueron.ogg \
 	$(LOCAL_PATH)/ringtones/ogg/Orion.ogg:system/media/audio/ringtones/Orion.ogg \
 	$(LOCAL_PATH)/ringtones/ogg/Pegasus.ogg:system/media/audio/ringtones/Pegasus.ogg \
+	$(LOCAL_PATH)/ringtones/ogg/Perseus.ogg:system/media/audio/ringtones/Perseus.ogg \
 	$(LOCAL_PATH)/ringtones/ogg/Pyxis.ogg:system/media/audio/ringtones/Pyxis.ogg \
 	$(LOCAL_PATH)/ringtones/ogg/Rigel.ogg:system/media/audio/ringtones/Rigel.ogg \
 	$(LOCAL_PATH)/ringtones/ogg/Scarabaeus.ogg:system/media/audio/ringtones/Scarabaeus.ogg \
diff --git a/data/sounds/notifications/ogg/Arcturus.ogg b/data/sounds/notifications/ogg/Arcturus.ogg
new file mode 100644
index 0000000..8b83285
--- /dev/null
+++ b/data/sounds/notifications/ogg/Arcturus.ogg
Binary files differ
diff --git a/data/sounds/notifications/ogg/Capella.ogg b/data/sounds/notifications/ogg/Capella.ogg
new file mode 100755
index 0000000..88a955d
--- /dev/null
+++ b/data/sounds/notifications/ogg/Capella.ogg
Binary files differ
diff --git a/data/sounds/notifications/ogg/CetiAlpha.ogg b/data/sounds/notifications/ogg/CetiAlpha.ogg
new file mode 100644
index 0000000..cd09526
--- /dev/null
+++ b/data/sounds/notifications/ogg/CetiAlpha.ogg
Binary files differ
diff --git a/data/sounds/notifications/ogg/Polaris.ogg b/data/sounds/notifications/ogg/Polaris.ogg
new file mode 100755
index 0000000..0f63a65
--- /dev/null
+++ b/data/sounds/notifications/ogg/Polaris.ogg
Binary files differ
diff --git a/data/sounds/notifications/ogg/Procyon.ogg b/data/sounds/notifications/ogg/Procyon.ogg
new file mode 100755
index 0000000..e5ffcdb
--- /dev/null
+++ b/data/sounds/notifications/ogg/Procyon.ogg
Binary files differ
diff --git a/data/sounds/notifications/ogg/Vega.ogg b/data/sounds/notifications/ogg/Vega.ogg
new file mode 100644
index 0000000..7cdbf21
--- /dev/null
+++ b/data/sounds/notifications/ogg/Vega.ogg
Binary files differ
diff --git a/data/sounds/ringtones/ogg/Acheron.ogg b/data/sounds/ringtones/ogg/Acheron.ogg
new file mode 100644
index 0000000..67d7388
--- /dev/null
+++ b/data/sounds/ringtones/ogg/Acheron.ogg
Binary files differ
diff --git a/data/sounds/ringtones/ogg/Nasqueron.ogg b/data/sounds/ringtones/ogg/Nasqueron.ogg
new file mode 100644
index 0000000..ae1a725
--- /dev/null
+++ b/data/sounds/ringtones/ogg/Nasqueron.ogg
Binary files differ
diff --git a/include/binder/Parcel.h b/include/binder/Parcel.h
index bfe13f0..3fa2acb 100644
--- a/include/binder/Parcel.h
+++ b/include/binder/Parcel.h
@@ -38,6 +38,9 @@
 class Parcel
 {
 public:
+    class ReadableBlob;
+    class WritableBlob;
+
                         Parcel();
                         ~Parcel();
     
@@ -46,7 +49,7 @@
     size_t              dataAvail() const;
     size_t              dataPosition() const;
     size_t              dataCapacity() const;
-    
+
     status_t            setDataSize(size_t size);
     void                setDataPosition(size_t pos) const;
     status_t            setDataCapacity(size_t size);
@@ -56,6 +59,9 @@
     status_t            appendFrom(const Parcel *parcel,
                                    size_t start, size_t len);
 
+    bool                pushAllowFds(bool allowFds);
+    void                restoreAllowFds(bool lastValue);
+
     bool                hasFileDescriptors() const;
 
     // Writes the RPC header.
@@ -109,7 +115,13 @@
     // Place a file descriptor into the parcel.  A dup of the fd is made, which
     // will be closed once the parcel is destroyed.
     status_t            writeDupFileDescriptor(int fd);
-    
+
+    // Writes a blob to the parcel.
+    // If the blob is small, then it is stored in-place, otherwise it is
+    // transferred by way of an anonymous shared memory region.
+    // The caller should call release() on the blob after writing its contents.
+    status_t            writeBlob(size_t len, WritableBlob* outBlob);
+
     status_t            writeObject(const flat_binder_object& val, bool nullMetaData);
 
     // Like Parcel.java's writeNoException().  Just writes a zero int32.
@@ -157,7 +169,11 @@
     // Retrieve a file descriptor from the parcel.  This returns the raw fd
     // in the parcel, which you do not own -- use dup() to get your own copy.
     int                 readFileDescriptor() const;
-    
+
+    // Reads a blob from the parcel.
+    // The caller should call release() on the blob after reading its contents.
+    status_t            readBlob(size_t len, ReadableBlob* outBlob) const;
+
     const flat_binder_object* readObject(bool nullMetaData) const;
 
     // Explicitly close all file descriptors in the parcel.
@@ -177,7 +193,7 @@
                                             release_func relFunc, void* relCookie);
     
     void                print(TextOutput& to, uint32_t flags = 0) const;
-        
+
 private:
                         Parcel(const Parcel& o);
     Parcel&             operator=(const Parcel& o);
@@ -212,9 +228,40 @@
 
     mutable bool        mFdsKnown;
     mutable bool        mHasFds;
+    bool                mAllowFds;
     
     release_func        mOwner;
     void*               mOwnerCookie;
+
+    class Blob {
+    public:
+        Blob();
+        ~Blob();
+
+        void release();
+        inline size_t size() const { return mSize; }
+
+    protected:
+        void init(bool mapped, void* data, size_t size);
+        void clear();
+
+        bool mMapped;
+        void* mData;
+        size_t mSize;
+    };
+
+public:
+    class ReadableBlob : public Blob {
+        friend class Parcel;
+    public:
+        inline const void* data() const { return mData; }
+    };
+
+    class WritableBlob : public Blob {
+        friend class Parcel;
+    public:
+        inline void* data() { return mData; }
+    };
 };
 
 // ---------------------------------------------------------------------------
diff --git a/include/utils/Errors.h b/include/utils/Errors.h
index 81f818b..0b75b19 100644
--- a/include/utils/Errors.h
+++ b/include/utils/Errors.h
@@ -72,6 +72,7 @@
     TIMED_OUT           = 0x80000005,
     UNKNOWN_TRANSACTION = 0x80000006,
 #endif    
+    FDS_NOT_ALLOWED     = 0x80000007,
 };
 
 // Restore define; enumeration is in "android" namespace, so the value defined
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index a0fc4d0..608877e 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -30,12 +30,14 @@
 #include <utils/TextOutput.h>
 #include <utils/misc.h>
 #include <utils/Flattenable.h>
+#include <cutils/ashmem.h>
 
 #include <private/binder/binder_module.h>
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdint.h>
+#include <sys/mman.h>
 
 #ifndef INT32_MAX
 #define INT32_MAX ((int32_t)(2147483647))
@@ -54,6 +56,9 @@
 // Note: must be kept in sync with android/os/Parcel.java's EX_HAS_REPLY_HEADER
 #define EX_HAS_REPLY_HEADER -128
 
+// Maximum size of a blob to transfer in-place.
+static const size_t IN_PLACE_BLOB_LIMIT = 40 * 1024;
+
 // XXX This can be made public if we want to provide
 // support for typed data.
 struct small_flat_data
@@ -399,6 +404,8 @@
     mDataPos += len;
     mDataSize += len;
 
+    err = NO_ERROR;
+
     if (numObjects > 0) {
         // grow objects
         if (mObjectsCapacity < mObjectsSize + numObjects) {
@@ -430,11 +437,28 @@
                 flat->handle = dup(flat->handle);
                 flat->cookie = (void*)1;
                 mHasFds = mFdsKnown = true;
+                if (!mAllowFds) {
+                    err = FDS_NOT_ALLOWED;
+                }
             }
         }
     }
 
-    return NO_ERROR;
+    return err;
+}
+
+bool Parcel::pushAllowFds(bool allowFds)
+{
+    const bool origValue = mAllowFds;
+    if (!allowFds) {
+        mAllowFds = false;
+    }
+    return origValue;
+}
+
+void Parcel::restoreAllowFds(bool lastValue)
+{
+    mAllowFds = lastValue;
 }
 
 bool Parcel::hasFileDescriptors() const
@@ -706,6 +730,54 @@
     return writeObject(obj, true);
 }
 
+status_t Parcel::writeBlob(size_t len, WritableBlob* outBlob)
+{
+    status_t status;
+
+    if (!mAllowFds || len <= IN_PLACE_BLOB_LIMIT) {
+        LOGV("writeBlob: write in place");
+        status = writeInt32(0);
+        if (status) return status;
+
+        void* ptr = writeInplace(len);
+        if (!ptr) return NO_MEMORY;
+
+        outBlob->init(false /*mapped*/, ptr, len);
+        return NO_ERROR;
+    }
+
+    LOGV("writeBlob: write to ashmem");
+    int fd = ashmem_create_region("Parcel Blob", len);
+    if (fd < 0) return NO_MEMORY;
+
+    int result = ashmem_set_prot_region(fd, PROT_READ | PROT_WRITE);
+    if (result < 0) {
+        status = -result;
+    } else {
+        void* ptr = ::mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+        if (ptr == MAP_FAILED) {
+            status = -errno;
+        } else {
+            result = ashmem_set_prot_region(fd, PROT_READ);
+            if (result < 0) {
+                status = -result;
+            } else {
+                status = writeInt32(1);
+                if (!status) {
+                    status = writeFileDescriptor(fd);
+                    if (!status) {
+                        outBlob->init(true /*mapped*/, ptr, len);
+                        return NO_ERROR;
+                    }
+                }
+            }
+        }
+        ::munmap(ptr, len);
+    }
+    ::close(fd);
+    return status;
+}
+
 status_t Parcel::write(const Flattenable& val)
 {
     status_t err;
@@ -759,6 +831,9 @@
         
         // remember if it's a file descriptor
         if (val.type == BINDER_TYPE_FD) {
+            if (!mAllowFds) {
+                return FDS_NOT_ALLOWED;
+            }
             mHasFds = mFdsKnown = true;
         }
 
@@ -1025,6 +1100,32 @@
     return BAD_TYPE;
 }
 
+status_t Parcel::readBlob(size_t len, ReadableBlob* outBlob) const
+{
+    int32_t useAshmem;
+    status_t status = readInt32(&useAshmem);
+    if (status) return status;
+
+    if (!useAshmem) {
+        LOGV("readBlob: read in place");
+        const void* ptr = readInplace(len);
+        if (!ptr) return BAD_VALUE;
+
+        outBlob->init(false /*mapped*/, const_cast<void*>(ptr), len);
+        return NO_ERROR;
+    }
+
+    LOGV("readBlob: read from ashmem");
+    int fd = readFileDescriptor();
+    if (fd == int(BAD_TYPE)) return BAD_VALUE;
+
+    void* ptr = ::mmap(NULL, len, PROT_READ, MAP_SHARED, fd, 0);
+    if (!ptr) return NO_MEMORY;
+
+    outBlob->init(true /*mapped*/, ptr, len);
+    return NO_ERROR;
+}
+
 status_t Parcel::read(Flattenable& val) const
 {
     // size
@@ -1283,6 +1384,7 @@
     mNextObjectHint = 0;
     mHasFds = false;
     mFdsKnown = true;
+    mAllowFds = true;
     
     return NO_ERROR;
 }
@@ -1434,6 +1536,7 @@
     mNextObjectHint = 0;
     mHasFds = false;
     mFdsKnown = true;
+    mAllowFds = true;
     mOwner = NULL;
 }
 
@@ -1452,4 +1555,33 @@
     mFdsKnown = true;
 }
 
+// --- Parcel::Blob ---
+
+Parcel::Blob::Blob() :
+        mMapped(false), mData(NULL), mSize(0) {
+}
+
+Parcel::Blob::~Blob() {
+    release();
+}
+
+void Parcel::Blob::release() {
+    if (mMapped && mData) {
+        ::munmap(mData, mSize);
+    }
+    clear();
+}
+
+void Parcel::Blob::init(bool mapped, void* data, size_t size) {
+    mMapped = mapped;
+    mData = data;
+    mSize = size;
+}
+
+void Parcel::Blob::clear() {
+    mMapped = false;
+    mData = NULL;
+    mSize = 0;
+}
+
 }; // namespace android
diff --git a/libs/rs/driver/rsdBcc.cpp b/libs/rs/driver/rsdBcc.cpp
index 0755fb7..5fd5c35 100644
--- a/libs/rs/driver/rsdBcc.cpp
+++ b/libs/rs/driver/rsdBcc.cpp
@@ -302,7 +302,10 @@
     DrvScript *drv = (DrvScript *)s->mHal.drv;
     // We only support slot 0 (root) at this point in time.
     rsAssert(slot == 0);
-    mtls.sig = drv->mExportForEachSignatureList[slot];
+    mtls.sig = 0x1f;  // temp fix for old apps, full table in slang_rs_export_foreach.cpp
+    if (drv->mExportForEachSignatureList) {
+        mtls.sig = drv->mExportForEachSignatureList[slot];
+    }
     if (ain) {
         mtls.dimX = ain->getType()->getDimX();
         mtls.dimY = ain->getType()->getDimY();
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index d0ece6c..830506c 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -30,7 +30,7 @@
 
     <!-- Size of application thumbnail -->
     <dimen name="status_bar_recents_thumbnail_width">164dp</dimen>
-    <dimen name="status_bar_recents_thumbnail_height">164dp</dimen>
+    <dimen name="status_bar_recents_thumbnail_height">145dp</dimen>
 
     <!-- Size of application label text -->
     <dimen name="status_bar_recents_app_label_text_size">16dip</dimen>
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
index ca9e273..e3f5cdb 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
@@ -60,6 +60,7 @@
 import android.widget.ScrollView;
 import android.widget.TextView;
 import android.widget.AdapterView.OnItemClickListener;
+import android.widget.ImageView.ScaleType;
 
 import com.android.systemui.R;
 import com.android.systemui.statusbar.StatusBar;
@@ -556,7 +557,7 @@
                     if (v.getTag() instanceof ViewHolder) {
                         ViewHolder h = (ViewHolder)v.getTag();
                         if (h.activityDescription == ad) {
-                            if (DEBUG) Log.v(TAG, "Updatating thumbnail #" + index + " in "
+                            if (DEBUG) Log.v(TAG, "Updating thumbnail #" + index + " in "
                                     + h.activityDescription
                                     + ": " + ad.getThumbnail());
                             h.iconView.setImageDrawable(ad.getIcon());
@@ -578,6 +579,15 @@
                                 // that this now covers, to improve scrolling speed.
                                 // That can't be done until the anim is complete though.
                                 h.thumbnailViewImage.setImageBitmap(thumbnail);
+
+                                // scale to fill up the full width
+                                Matrix scaleMatrix = new Matrix();
+                                float thumbnailViewWidth = h.thumbnailViewImage.getWidth();
+                                float scale = thumbnailViewWidth / thumbnail.getWidth();
+                                scaleMatrix.setScale(scale, scale);
+                                h.thumbnailViewImage.setScaleType(ScaleType.MATRIX);
+                                h.thumbnailViewImage.setImageMatrix(scaleMatrix);
+
                                 if (anim) {
                                     h.thumbnailViewImage.setAnimation(AnimationUtils.loadAnimation(
                                             mContext, R.anim.recent_appear));
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
index 886997c..c25e3ca 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
@@ -147,8 +147,16 @@
      */
     private static final boolean ENABLE_INSECURE_STATUS_BAR_EXPAND = true;
 
+    /** The stream type that the lock sounds are tied to. */
+    private static final int MASTER_STREAM_TYPE = AudioManager.STREAM_RING;
+    /** Minimum volume for lock sounds, as a ratio of max MASTER_STREAM_TYPE */
+    final float MIN_LOCK_VOLUME = 0.05f;
+    /** Maximum volume for lock sounds, as a ratio of max MASTER_STREAM_TYPE */
+    final float MAX_LOCK_VOLUME = 0.4f;
+
     private Context mContext;
     private AlarmManager mAlarmManager;
+    private AudioManager mAudioManager;
     private StatusBarManager mStatusBarManager;
     private boolean mShowLockIcon;
     private boolean mShowingLockIcon;
@@ -255,6 +263,7 @@
     private int mLockSoundId;
     private int mUnlockSoundId;
     private int mLockSoundStreamId;
+    private int mMasterStreamMaxVolume;
 
     public KeyguardViewMediator(Context context, PhoneWindowManager callback,
             LocalPowerManager powerManager) {
@@ -1061,13 +1070,33 @@
         }
 
         final ContentResolver cr = mContext.getContentResolver();
-        if (Settings.System.getInt(cr, Settings.System.LOCKSCREEN_SOUNDS_ENABLED, 1) == 1)
-        {
+        if (Settings.System.getInt(cr, Settings.System.LOCKSCREEN_SOUNDS_ENABLED, 1) == 1) {
             final int whichSound = locked
                 ? mLockSoundId
                 : mUnlockSoundId;
             mLockSounds.stop(mLockSoundStreamId);
-            mLockSoundStreamId = mLockSounds.play(whichSound, 1.0f, 1.0f, 1, 0, 1.0f);
+            // Init mAudioManager
+            if (mAudioManager == null) {
+                mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
+                if (mAudioManager == null) return;
+                mMasterStreamMaxVolume = mAudioManager.getStreamMaxVolume(MASTER_STREAM_TYPE);
+            }
+            // If the stream is muted, don't play the sound
+            if (mAudioManager.isStreamMute(MASTER_STREAM_TYPE)) return;
+
+            // Adjust the lock sound volume from a minimum of MIN_LOCK_VOLUME to a maximum
+            // of MAX_LOCK_VOLUME, relative to the maximum level of the MASTER_STREAM_TYPE volume.
+            float lockSoundVolume;
+            int masterStreamVolume = mAudioManager.getStreamVolume(MASTER_STREAM_TYPE);
+            if (masterStreamVolume == 0) {
+                return;
+            } else {
+                lockSoundVolume = MIN_LOCK_VOLUME + (MAX_LOCK_VOLUME - MIN_LOCK_VOLUME)
+                        * ((float) masterStreamVolume / mMasterStreamMaxVolume);
+            }
+
+            mLockSoundStreamId = mLockSounds.play(whichSound, lockSoundVolume, lockSoundVolume, 1,
+                    0, 1.0f);
         }
     }
 
diff --git a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
index f970ff3..ca5d274 100644
--- a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
+++ b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
@@ -531,7 +531,8 @@
             ((KeyguardScreen) mUnlockScreen).onResume();
         }
 
-        if (mLockPatternUtils.usingBiometricWeak()) {
+        if (mLockPatternUtils.usingBiometricWeak() &&
+                mLockPatternUtils.isBiometricWeakInstalled()) {
             mHandler.sendEmptyMessage(MSG_SHOW_FACELOCK_AREA_VIEW);
         } else {
             mHandler.sendEmptyMessage(MSG_HIDE_FACELOCK_AREA_VIEW);
@@ -1014,7 +1015,8 @@
 
     // Binds to FaceLock service, but does not tell it to start
     public void bindToFaceLock() {
-        if (mLockPatternUtils.usingBiometricWeak()) {
+        if (mLockPatternUtils.usingBiometricWeak() &&
+                mLockPatternUtils.isBiometricWeakInstalled()) {
             if (!mBoundToFaceLockService) {
                 if (DEBUG) Log.d(TAG, "before bind to FaceLock service");
                 mContext.bindService(new Intent(IFaceLockInterface.class.getName()),
@@ -1030,7 +1032,8 @@
 
     // Tells FaceLock to stop and then unbinds from the FaceLock service
     public void stopAndUnbindFromFaceLock() {
-        if (mLockPatternUtils.usingBiometricWeak()) {
+        if (mLockPatternUtils.usingBiometricWeak() &&
+                mLockPatternUtils.isBiometricWeakInstalled()) {
             stopFaceLock();
 
             if (mBoundToFaceLockService) {
@@ -1079,7 +1082,8 @@
     // Tells the FaceLock service to start displaying its UI and perform recognition
     public void startFaceLock(IBinder windowToken, int x, int y, int h, int w)
     {
-        if (mLockPatternUtils.usingBiometricWeak()) {
+        if (mLockPatternUtils.usingBiometricWeak() &&
+                mLockPatternUtils.isBiometricWeakInstalled()) {
             synchronized (mFaceLockServiceRunningLock) {
                 if (!mFaceLockServiceRunning) {
                     if (DEBUG) Log.d(TAG, "Starting FaceLock");
@@ -1099,7 +1103,8 @@
     // Tells the FaceLock service to stop displaying its UI and stop recognition
     public void stopFaceLock()
     {
-        if (mLockPatternUtils.usingBiometricWeak()) {
+        if (mLockPatternUtils.usingBiometricWeak() &&
+                mLockPatternUtils.isBiometricWeakInstalled()) {
             // Note that attempting to stop FaceLock when it's not running is not an issue.
             // FaceLock can return, which stops it and then we try to stop it when the
             // screen is turned off.  That's why we check.
diff --git a/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java b/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java
index 6d2f2f2..ec0072c 100644
--- a/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java
+++ b/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java
@@ -60,19 +60,18 @@
     private final KeyguardUpdateMonitor mUpdateMonitor;
     private final KeyguardScreenCallback mCallback;
 
-    private boolean mIsAlpha;
+    private final boolean mIsAlpha;
 
-    private EditText mPasswordEntry;
-    private LockPatternUtils mLockPatternUtils;
-    private PasswordEntryKeyboardView mKeyboardView;
-    private PasswordEntryKeyboardHelper mKeyboardHelper;
+    private final EditText mPasswordEntry;
+    private final LockPatternUtils mLockPatternUtils;
+    private final PasswordEntryKeyboardView mKeyboardView;
+    private final PasswordEntryKeyboardHelper mKeyboardHelper;
 
-    private int mCreationOrientation;
-    private int mCreationHardKeyboardHidden;
-    private CountDownTimer mCountdownTimer;
+    private final int mCreationOrientation;
+    private final int mCreationHardKeyboardHidden;
 
-    private KeyguardStatusViewManager mStatusViewManager;
-    private boolean mUseSystemIME = true; // TODO: Make configurable
+    private final KeyguardStatusViewManager mStatusViewManager;
+    private final boolean mUseSystemIME = true; // TODO: Make configurable
     private boolean mResuming; // used to prevent poking the wakelock during onResume()
 
     // To avoid accidental lockout due to events while the device in in the pocket, ignore
@@ -119,6 +118,19 @@
             mKeyboardHelper.setKeyboardMode(PasswordEntryKeyboardHelper.KEYBOARD_MODE_NUMERIC);
             mKeyboardView.setVisibility(mCreationHardKeyboardHidden
                     == Configuration.HARDKEYBOARDHIDDEN_NO ? View.INVISIBLE : View.VISIBLE);
+
+            // The delete button is of the PIN keyboard itself in some (e.g. tablet) layouts,
+            // not a separate view
+            View pinDelete = findViewById(R.id.pinDel);
+            if (pinDelete != null) {
+                pinDelete.setVisibility(View.VISIBLE);
+                pinDelete.setOnClickListener(new OnClickListener() {
+                    @Override
+                    public void onClick(View v) {
+                        mKeyboardHelper.handleBackspace();
+                    }
+                });
+            }
         }
 
         mPasswordEntry.requestFocus();
@@ -293,7 +305,7 @@
         mPasswordEntry.setEnabled(false);
         mKeyboardView.setEnabled(false);
         long elapsedRealtime = SystemClock.elapsedRealtime();
-        mCountdownTimer = new CountDownTimer(elapsedRealtimeDeadline - elapsedRealtime, 1000) {
+        new CountDownTimer(elapsedRealtimeDeadline - elapsedRealtime, 1000) {
 
             @Override
             public void onTick(long millisUntilFinished) {
@@ -309,7 +321,6 @@
                 mPasswordEntry.setEnabled(true);
                 mKeyboardView.setEnabled(true);
                 mStatusViewManager.resetStatusInfo();
-                mCountdownTimer = null;
             }
         }.start();
     }
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index fe49cd2..7b8657a 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -325,14 +325,16 @@
         public boolean includeApks;
         public boolean includeShared;
         public boolean allApps;
+        public boolean includeSystem;
         public String[] packages;
 
         FullBackupParams(ParcelFileDescriptor output, boolean saveApks, boolean saveShared,
-                boolean doAllApps, String[] pkgList) {
+                boolean doAllApps, boolean doSystem, String[] pkgList) {
             fd = output;
             includeApks = saveApks;
             includeShared = saveShared;
             allApps = doAllApps;
+            includeSystem = doSystem;
             packages = pkgList;
         }
     }
@@ -504,7 +506,7 @@
                 PerformFullBackupTask task = new PerformFullBackupTask(params.fd,
                         params.observer, params.includeApks,
                         params.includeShared, params.curPassword, params.encryptPassword,
-                        params.allApps, params.packages, params.latch);
+                        params.allApps, params.includeSystem, params.packages, params.latch);
                 (new Thread(task)).start();
                 break;
             }
@@ -2161,6 +2163,7 @@
         boolean mIncludeApks;
         boolean mIncludeShared;
         boolean mAllApps;
+        final boolean mIncludeSystem;
         String[] mPackages;
         String mCurrentPassword;
         String mEncryptPassword;
@@ -2219,13 +2222,14 @@
 
         PerformFullBackupTask(ParcelFileDescriptor fd, IFullBackupRestoreObserver observer, 
                 boolean includeApks, boolean includeShared, String curPassword,
-                String encryptPassword, boolean doAllApps, String[] packages,
+                String encryptPassword, boolean doAllApps, boolean doSystem, String[] packages,
                 AtomicBoolean latch) {
             mOutputFile = fd;
             mObserver = observer;
             mIncludeApks = includeApks;
             mIncludeShared = includeShared;
             mAllApps = doAllApps;
+            mIncludeSystem = doSystem;
             mPackages = packages;
             mCurrentPassword = curPassword;
             // when backing up, if there is a current backup password, we require that
@@ -2245,7 +2249,7 @@
 
         @Override
         public void run() {
-            final List<PackageInfo> packagesToBackup;
+            List<PackageInfo> packagesToBackup = new ArrayList<PackageInfo>();
 
             Slog.i(TAG, "--- Performing full-dataset backup ---");
             sendStartBackup();
@@ -2254,8 +2258,23 @@
             if (mAllApps) {
                 packagesToBackup = mPackageManager.getInstalledPackages(
                         PackageManager.GET_SIGNATURES);
-            } else {
-                packagesToBackup = new ArrayList<PackageInfo>();
+                // Exclude system apps if we've been asked to do so
+                if (mIncludeSystem == false) {
+                    for (int i = 0; i < packagesToBackup.size(); ) {
+                        PackageInfo pkg = packagesToBackup.get(i);
+                        if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
+                            packagesToBackup.remove(i);
+                        } else {
+                            i++;
+                        }
+                    }
+                }
+            }
+
+            // Now process the command line argument packages, if any. Note that explicitly-
+            // named system-partition packages will be included even if includeSystem was
+            // set to false.
+            if (mPackages != null) {
                 for (String pkgName : mPackages) {
                     try {
                         packagesToBackup.add(mPackageManager.getPackageInfo(pkgName,
@@ -2268,8 +2287,8 @@
 
             // Cull any packages that have indicated that backups are not permitted.
             for (int i = 0; i < packagesToBackup.size(); ) {
-                PackageInfo info = packagesToBackup.get(i);
-                if ((info.applicationInfo.flags & ApplicationInfo.FLAG_ALLOW_BACKUP) == 0) {
+                PackageInfo pkg = packagesToBackup.get(i);
+                if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_ALLOW_BACKUP) == 0) {
                     packagesToBackup.remove(i);
                 } else {
                     i++;
@@ -4781,7 +4800,7 @@
     // to the supplied file descriptor.  This method is synchronous and does not return
     // to the caller until the backup has been completed.
     public void fullBackup(ParcelFileDescriptor fd, boolean includeApks, boolean includeShared,
-            boolean doAllApps, String[] pkgList) {
+            boolean doAllApps, boolean includeSystem, String[] pkgList) {
         mContext.enforceCallingPermission(android.Manifest.permission.BACKUP, "fullBackup");
 
         // Validate
@@ -4811,7 +4830,7 @@
             Slog.i(TAG, "Beginning full backup...");
 
             FullBackupParams params = new FullBackupParams(fd, includeApks, includeShared,
-                    doAllApps, pkgList);
+                    doAllApps, includeSystem, pkgList);
             final int token = generateToken();
             synchronized (mFullConfirmations) {
                 mFullConfirmations.put(token, params);
diff --git a/services/java/com/android/server/EventLogTags.logtags b/services/java/com/android/server/EventLogTags.logtags
index 99f6b8e..a7eff93 100644
--- a/services/java/com/android/server/EventLogTags.logtags
+++ b/services/java/com/android/server/EventLogTags.logtags
@@ -142,5 +142,5 @@
 # ---------------------------
 # NetworkStatsService.java
 # ---------------------------
-51100 netstats_mobile_sample (iface_rx_bytes|2|2),(iface_tx_bytes|2|2),(iface_rx_pkts|2|1),(iface_tx_pkts|2|1),(uid_rx_bytes|2|2),(uid_tx_bytes|2|2),(uid_rx_pkts|2|1),(uid_tx_pkts|2|1)
-51101 netstats_wifi_sample (iface_rx_bytes|2|2),(iface_tx_bytes|2|2),(iface_rx_pkts|2|1),(iface_tx_pkts|2|1),(uid_rx_bytes|2|2),(uid_tx_bytes|2|2),(uid_rx_pkts|2|1),(uid_tx_pkts|2|1)
+51100 netstats_mobile_sample (dev_rx_bytes|2|2),(dev_tx_bytes|2|2),(dev_rx_pkts|2|1),(dev_tx_pkts|2|1),(xt_rx_bytes|2|2),(xt_tx_bytes|2|2),(xt_rx_pkts|2|1),(xt_tx_pkts|2|1),(uid_rx_bytes|2|2),(uid_tx_bytes|2|2),(uid_rx_pkts|2|1),(uid_tx_pkts|2|1),(trusted_time|2|3)
+51101 netstats_wifi_sample (dev_rx_bytes|2|2),(dev_tx_bytes|2|2),(dev_rx_pkts|2|1),(dev_tx_pkts|2|1),(xt_rx_bytes|2|2),(xt_tx_bytes|2|2),(xt_rx_pkts|2|1),(xt_tx_pkts|2|1),(uid_rx_bytes|2|2),(uid_tx_bytes|2|2),(uid_rx_pkts|2|1),(uid_tx_pkts|2|1),(trusted_time|2|3)
diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java
index aacaa6a..f1a404a 100644
--- a/services/java/com/android/server/NetworkManagementService.java
+++ b/services/java/com/android/server/NetworkManagementService.java
@@ -22,6 +22,7 @@
 import static android.net.NetworkStats.SET_DEFAULT;
 import static android.net.NetworkStats.TAG_NONE;
 import static android.net.NetworkStats.UID_ALL;
+import static android.net.TrafficStats.UID_TETHERING;
 import static android.provider.Settings.Secure.NETSTATS_ENABLED;
 import static com.android.server.NetworkManagementSocketTagger.PROP_QTAGUID_ENABLED;
 import static com.android.server.NetworkManagementSocketTagger.kernelToTag;
@@ -85,11 +86,15 @@
     @Deprecated
     private final File mStatsUid;
     /** Path to {@code /proc/net/dev}. */
+    @Deprecated
     private final File mStatsIface;
+    /** Path to {@code /proc/net/xt_qtaguid/iface_stat}. */
+    @Deprecated
+    private final File mStatsXtIface;
+    /** Path to {@code /proc/net/xt_qtaguid/iface_stat_all}. */
+    private final File mStatsXtIfaceAll;
     /** Path to {@code /proc/net/xt_qtaguid/stats}. */
     private final File mStatsXtUid;
-    /** Path to {@code /proc/net/xt_qtaguid/iface_stat}. */
-    private final File mStatsXtIface;
 
     /**
      * Name representing {@link #setGlobalAlert(long)} limit when delivered to
@@ -97,12 +102,17 @@
      */
     public static final String LIMIT_GLOBAL_ALERT = "globalAlert";
 
-    /** {@link #mStatsXtUid} headers. */
+    /** {@link #mStatsXtUid} and {@link #mStatsXtIfaceAll} headers. */
     private static final String KEY_IDX = "idx";
     private static final String KEY_IFACE = "iface";
+    private static final String KEY_ACTIVE = "active";
     private static final String KEY_UID = "uid_tag_int";
     private static final String KEY_COUNTER_SET = "cnt_set";
     private static final String KEY_TAG_HEX = "acct_tag_hex";
+    private static final String KEY_SNAP_RX_BYTES = "snap_rx_bytes";
+    private static final String KEY_SNAP_RX_PACKETS = "snap_rx_packets";
+    private static final String KEY_SNAP_TX_BYTES = "snap_tx_bytes";
+    private static final String KEY_SNAP_TX_PACKETS = "snap_tx_packets";
     private static final String KEY_RX_BYTES = "rx_bytes";
     private static final String KEY_RX_PACKETS = "rx_packets";
     private static final String KEY_TX_BYTES = "tx_bytes";
@@ -169,6 +179,7 @@
         mStatsIface = new File(procRoot, "net/dev");
         mStatsXtUid = new File(procRoot, "net/xt_qtaguid/stats");
         mStatsXtIface = new File(procRoot, "net/xt_qtaguid/iface_stat");
+        mStatsXtIfaceAll = new File(procRoot, "net/xt_qtaguid/iface_stat_all");
 
         if ("simulator".equals(SystemProperties.get("ro.product.device"))) {
             return;
@@ -1071,6 +1082,15 @@
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService");
 
+        if (mBandwidthControlEnabled && mStatsXtIfaceAll.exists()) {
+            return getNetworkStatsSummarySingleFile();
+        } else {
+            return getNetworkStatsSummaryMultipleFiles();
+        }
+    }
+
+    @Deprecated
+    private NetworkStats getNetworkStatsSummaryMultipleFiles() {
         final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 6);
         final NetworkStats.Entry entry = new NetworkStats.Entry();
 
@@ -1155,6 +1175,61 @@
         return stats;
     }
 
+    private NetworkStats getNetworkStatsSummarySingleFile() {
+        final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 6);
+        final NetworkStats.Entry entry = new NetworkStats.Entry();
+
+        // TODO: read directly from proc once headers are added
+        final ArrayList<String> keys = Lists.newArrayList(KEY_IFACE, KEY_ACTIVE, KEY_SNAP_RX_BYTES,
+                KEY_SNAP_RX_PACKETS, KEY_SNAP_TX_BYTES, KEY_SNAP_TX_PACKETS, KEY_RX_BYTES,
+                KEY_RX_PACKETS, KEY_TX_BYTES, KEY_TX_PACKETS);
+        final ArrayList<String> values = Lists.newArrayList();
+        final HashMap<String, String> parsed = Maps.newHashMap();
+
+        BufferedReader reader = null;
+        try {
+            reader = new BufferedReader(new FileReader(mStatsXtIfaceAll));
+
+            String line;
+            while ((line = reader.readLine()) != null) {
+                splitLine(line, values);
+                parseLine(keys, values, parsed);
+
+                entry.iface = parsed.get(KEY_IFACE);
+                entry.uid = UID_ALL;
+                entry.set = SET_DEFAULT;
+                entry.tag = TAG_NONE;
+
+                // always include snapshot values
+                entry.rxBytes = getParsedLong(parsed, KEY_SNAP_RX_BYTES);
+                entry.rxPackets = getParsedLong(parsed, KEY_SNAP_RX_PACKETS);
+                entry.txBytes = getParsedLong(parsed, KEY_SNAP_TX_BYTES);
+                entry.txPackets = getParsedLong(parsed, KEY_SNAP_TX_PACKETS);
+
+                // fold in active numbers, but only when active
+                final boolean active = getParsedInt(parsed, KEY_ACTIVE) != 0;
+                if (active) {
+                    entry.rxBytes += getParsedLong(parsed, KEY_RX_BYTES);
+                    entry.rxPackets += getParsedLong(parsed, KEY_RX_PACKETS);
+                    entry.txBytes += getParsedLong(parsed, KEY_TX_BYTES);
+                    entry.txPackets += getParsedLong(parsed, KEY_TX_PACKETS);
+                }
+
+                stats.addValues(entry);
+            }
+        } catch (NullPointerException e) {
+            throw new IllegalStateException("problem parsing stats: " + e);
+        } catch (NumberFormatException e) {
+            throw new IllegalStateException("problem parsing stats: " + e);
+        } catch (IOException e) {
+            throw new IllegalStateException("problem parsing stats: " + e);
+        } finally {
+            IoUtils.closeQuietly(reader);
+        }
+
+        return stats;
+    }
+
     @Override
     public NetworkStats getNetworkStatsDetail() {
         mContext.enforceCallingOrSelfPermission(
@@ -1522,7 +1597,7 @@
         try {
             final NetworkStats.Entry entry = new NetworkStats.Entry();
             entry.iface = ifaceIn;
-            entry.uid = UID_ALL;
+            entry.uid = UID_TETHERING;
             entry.set = SET_DEFAULT;
             entry.tag = TAG_NONE;
             entry.rxBytes = Long.parseLong(tok[3]);
diff --git a/services/java/com/android/server/net/NetworkStatsService.java b/services/java/com/android/server/net/NetworkStatsService.java
index aa46795..e5f0a77 100644
--- a/services/java/com/android/server/net/NetworkStatsService.java
+++ b/services/java/com/android/server/net/NetworkStatsService.java
@@ -35,7 +35,6 @@
 import static android.net.NetworkTemplate.buildTemplateMobileAll;
 import static android.net.NetworkTemplate.buildTemplateWifi;
 import static android.net.TrafficStats.UID_REMOVED;
-import static android.net.TrafficStats.UID_TETHERING;
 import static android.provider.Settings.Secure.NETSTATS_NETWORK_BUCKET_DURATION;
 import static android.provider.Settings.Secure.NETSTATS_NETWORK_MAX_HISTORY;
 import static android.provider.Settings.Secure.NETSTATS_PERSIST_THRESHOLD;
@@ -72,7 +71,6 @@
 import android.net.NetworkStats;
 import android.net.NetworkStatsHistory;
 import android.net.NetworkTemplate;
-import android.net.TrafficStats;
 import android.os.Binder;
 import android.os.Environment;
 import android.os.Handler;
@@ -140,11 +138,14 @@
     private static final int MSG_UPDATE_IFACES = 2;
 
     /** Flags to control detail level of poll event. */
-    private static final int FLAG_PERSIST_NETWORK = 0x10;
-    private static final int FLAG_PERSIST_UID = 0x20;
+    private static final int FLAG_PERSIST_NETWORK = 0x1;
+    private static final int FLAG_PERSIST_UID = 0x2;
     private static final int FLAG_PERSIST_ALL = FLAG_PERSIST_NETWORK | FLAG_PERSIST_UID;
     private static final int FLAG_PERSIST_FORCE = 0x100;
 
+    /** Sample recent usage after each poll event. */
+    private static final boolean ENABLE_SAMPLE_AFTER_POLL = true;
+
     private final Context mContext;
     private final INetworkManagementService mNetworkManager;
     private final IAlarmManager mAlarmManager;
@@ -188,20 +189,23 @@
 
     /** Set of currently active ifaces. */
     private HashMap<String, NetworkIdentitySet> mActiveIfaces = Maps.newHashMap();
-    /** Set of historical network layer stats for known networks. */
-    private HashMap<NetworkIdentitySet, NetworkStatsHistory> mNetworkStats = Maps.newHashMap();
-    /** Set of historical network layer stats for known UIDs. */
+    /** Set of historical {@code dev} stats for known networks. */
+    private HashMap<NetworkIdentitySet, NetworkStatsHistory> mNetworkDevStats = Maps.newHashMap();
+    /** Set of historical {@code xtables} stats for known networks. */
+    private HashMap<NetworkIdentitySet, NetworkStatsHistory> mNetworkXtStats = Maps.newHashMap();
+    /** Set of historical {@code xtables} stats for known UIDs. */
     private HashMap<UidStatsKey, NetworkStatsHistory> mUidStats = Maps.newHashMap();
 
     /** Flag if {@link #mUidStats} have been loaded from disk. */
     private boolean mUidStatsLoaded = false;
 
-    private NetworkStats mLastPollNetworkSnapshot;
+    private NetworkStats mLastPollNetworkDevSnapshot;
+    private NetworkStats mLastPollNetworkXtSnapshot;
     private NetworkStats mLastPollUidSnapshot;
     private NetworkStats mLastPollOperationsSnapshot;
-    private NetworkStats mLastPollTetherSnapshot;
 
-    private NetworkStats mLastPersistNetworkSnapshot;
+    private NetworkStats mLastPersistNetworkDevSnapshot;
+    private NetworkStats mLastPersistNetworkXtSnapshot;
     private NetworkStats mLastPersistUidSnapshot;
 
     /** Current counter sets for each UID. */
@@ -213,7 +217,8 @@
     private final HandlerThread mHandlerThread;
     private final Handler mHandler;
 
-    private final AtomicFile mNetworkFile;
+    private final AtomicFile mNetworkDevFile;
+    private final AtomicFile mNetworkXtFile;
     private final AtomicFile mUidFile;
 
     public NetworkStatsService(
@@ -244,7 +249,8 @@
         mHandlerThread.start();
         mHandler = new Handler(mHandlerThread.getLooper(), mHandlerCallback);
 
-        mNetworkFile = new AtomicFile(new File(systemDir, "netstats.bin"));
+        mNetworkDevFile = new AtomicFile(new File(systemDir, "netstats.bin"));
+        mNetworkXtFile = new AtomicFile(new File(systemDir, "netstats_xt.bin"));
         mUidFile = new AtomicFile(new File(systemDir, "netstats_uid.bin"));
     }
 
@@ -257,7 +263,8 @@
             // read historical network stats from disk, since policy service
             // might need them right away. we delay loading detailed UID stats
             // until actually needed.
-            readNetworkStatsLocked();
+            readNetworkDevStatsLocked();
+            readNetworkXtStatsLocked();
         }
 
         // watch for network interfaces to be claimed
@@ -306,11 +313,13 @@
 
         mTeleManager.listen(mPhoneListener, LISTEN_NONE);
 
-        writeNetworkStatsLocked();
+        writeNetworkDevStatsLocked();
+        writeNetworkXtStatsLocked();
         if (mUidStatsLoaded) {
             writeUidStatsLocked();
         }
-        mNetworkStats.clear();
+        mNetworkDevStats.clear();
+        mNetworkXtStats.clear();
         mUidStats.clear();
         mUidStatsLoaded = false;
     }
@@ -355,14 +364,26 @@
     @Override
     public NetworkStatsHistory getHistoryForNetwork(NetworkTemplate template, int fields) {
         mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
+        return getHistoryForNetworkDev(template, fields);
+    }
 
+    private NetworkStatsHistory getHistoryForNetworkDev(NetworkTemplate template, int fields) {
+        return getHistoryForNetwork(template, fields, mNetworkDevStats);
+    }
+
+    private NetworkStatsHistory getHistoryForNetworkXt(NetworkTemplate template, int fields) {
+        return getHistoryForNetwork(template, fields, mNetworkXtStats);
+    }
+
+    private NetworkStatsHistory getHistoryForNetwork(NetworkTemplate template, int fields,
+            HashMap<NetworkIdentitySet, NetworkStatsHistory> source) {
         synchronized (mStatsLock) {
             // combine all interfaces that match template
             final NetworkStatsHistory combined = new NetworkStatsHistory(
                     mSettings.getNetworkBucketDuration(), estimateNetworkBuckets(), fields);
-            for (NetworkIdentitySet ident : mNetworkStats.keySet()) {
+            for (NetworkIdentitySet ident : source.keySet()) {
                 if (templateMatches(template, ident)) {
-                    final NetworkStatsHistory history = mNetworkStats.get(ident);
+                    final NetworkStatsHistory history = source.get(ident);
                     if (history != null) {
                         combined.recordEntireHistory(history);
                     }
@@ -399,7 +420,19 @@
     @Override
     public NetworkStats getSummaryForNetwork(NetworkTemplate template, long start, long end) {
         mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
+        return getSummaryForNetworkDev(template, start, end);
+    }
 
+    private NetworkStats getSummaryForNetworkDev(NetworkTemplate template, long start, long end) {
+        return getSummaryForNetwork(template, start, end, mNetworkDevStats);
+    }
+
+    private NetworkStats getSummaryForNetworkXt(NetworkTemplate template, long start, long end) {
+        return getSummaryForNetwork(template, start, end, mNetworkXtStats);
+    }
+
+    private NetworkStats getSummaryForNetwork(NetworkTemplate template, long start, long end,
+            HashMap<NetworkIdentitySet, NetworkStatsHistory> source) {
         synchronized (mStatsLock) {
             // use system clock to be externally consistent
             final long now = System.currentTimeMillis();
@@ -409,9 +442,9 @@
             NetworkStatsHistory.Entry historyEntry = null;
 
             // combine total from all interfaces that match template
-            for (NetworkIdentitySet ident : mNetworkStats.keySet()) {
+            for (NetworkIdentitySet ident : source.keySet()) {
                 if (templateMatches(template, ident)) {
-                    final NetworkStatsHistory history = mNetworkStats.get(ident);
+                    final NetworkStatsHistory history = source.get(ident);
                     historyEntry = history.getValues(start, end, now, historyEntry);
 
                     entry.iface = IFACE_ALL;
@@ -716,8 +749,9 @@
      */
     private void bootstrapStats() {
         try {
-            mLastPollNetworkSnapshot = mNetworkManager.getNetworkStatsSummary();
             mLastPollUidSnapshot = mNetworkManager.getNetworkStatsUidDetail(UID_ALL);
+            mLastPollNetworkDevSnapshot = mNetworkManager.getNetworkStatsSummary();
+            mLastPollNetworkXtSnapshot = computeNetworkXtSnapshotFromUid(mLastPollUidSnapshot);
             mLastPollOperationsSnapshot = new NetworkStats(0L, 0);
         } catch (IllegalStateException e) {
             Slog.w(TAG, "problem reading network stats: " + e);
@@ -759,42 +793,56 @@
                 : System.currentTimeMillis();
         final long threshold = mSettings.getPersistThreshold();
 
+        final NetworkStats uidSnapshot;
+        final NetworkStats networkXtSnapshot;
+        final NetworkStats networkDevSnapshot;
         try {
-            // record tethering stats; persisted during normal UID cycle below
-            final String[] ifacePairs = mConnManager.getTetheredIfacePairs();
+            // collect any tethering stats
+            final String[] tetheredIfacePairs = mConnManager.getTetheredIfacePairs();
             final NetworkStats tetherSnapshot = mNetworkManager.getNetworkStatsTethering(
-                    ifacePairs);
-            performTetherPollLocked(tetherSnapshot, currentTime);
+                    tetheredIfacePairs);
 
-            // record uid stats
-            final NetworkStats uidSnapshot = mNetworkManager.getNetworkStatsUidDetail(UID_ALL);
+            // record uid stats, folding in tethering stats
+            uidSnapshot = mNetworkManager.getNetworkStatsUidDetail(UID_ALL);
+            uidSnapshot.combineAllValues(tetherSnapshot);
             performUidPollLocked(uidSnapshot, currentTime);
 
-            // persist when enough network data has occurred
-            final NetworkStats persistUidDelta = computeStatsDelta(
-                    mLastPersistUidSnapshot, uidSnapshot, true);
-            final boolean uidPastThreshold = persistUidDelta.getTotalBytes() > threshold;
-            if (persistForce || (persistUid && uidPastThreshold)) {
-                writeUidStatsLocked();
-                mLastPersistUidSnapshot = uidSnapshot;
-            }
+            // record dev network stats
+            networkDevSnapshot = mNetworkManager.getNetworkStatsSummary();
+            performNetworkDevPollLocked(networkDevSnapshot, currentTime);
 
-            // record network stats
-            final NetworkStats networkSnapshot = mNetworkManager.getNetworkStatsSummary();
-            performNetworkPollLocked(networkSnapshot, currentTime);
+            // record xt network stats
+            networkXtSnapshot = computeNetworkXtSnapshotFromUid(uidSnapshot);
+            performNetworkXtPollLocked(networkXtSnapshot, currentTime);
 
-            // persist when enough network data has occurred
-            final NetworkStats persistNetworkDelta = computeStatsDelta(
-                    mLastPersistNetworkSnapshot, networkSnapshot, true);
-            final boolean networkPastThreshold = persistNetworkDelta.getTotalBytes() > threshold;
-            if (persistForce || (persistNetwork && networkPastThreshold)) {
-                writeNetworkStatsLocked();
-                mLastPersistNetworkSnapshot = networkSnapshot;
-            }
         } catch (IllegalStateException e) {
             Log.wtf(TAG, "problem reading network stats", e);
+            return;
         } catch (RemoteException e) {
             // ignored; service lives in system_server
+            return;
+        }
+
+        // persist when enough network data has occurred
+        final long persistNetworkDevDelta = computeStatsDelta(
+                mLastPersistNetworkDevSnapshot, networkDevSnapshot, true).getTotalBytes();
+        final long persistNetworkXtDelta = computeStatsDelta(
+                mLastPersistNetworkXtSnapshot, networkXtSnapshot, true).getTotalBytes();
+        final boolean networkOverThreshold = persistNetworkDevDelta > threshold
+                || persistNetworkXtDelta > threshold;
+        if (persistForce || (persistNetwork && networkOverThreshold)) {
+            writeNetworkDevStatsLocked();
+            writeNetworkXtStatsLocked();
+            mLastPersistNetworkDevSnapshot = networkDevSnapshot;
+            mLastPersistNetworkXtSnapshot = networkXtSnapshot;
+        }
+
+        // persist when enough uid data has occurred
+        final long persistUidDelta = computeStatsDelta(mLastPersistUidSnapshot, uidSnapshot, true)
+                .getTotalBytes();
+        if (persistForce || (persistUid && persistUidDelta > threshold)) {
+            writeUidStatsLocked();
+            mLastPersistUidSnapshot = uidSnapshot;
         }
 
         if (LOGV) {
@@ -802,8 +850,10 @@
             Slog.v(TAG, "performPollLocked() took " + duration + "ms");
         }
 
-        // sample stats after each full poll
-        performSample();
+        if (ENABLE_SAMPLE_AFTER_POLL) {
+            // sample stats after each full poll
+            performSample();
+        }
 
         // finally, dispatch updated event to any listeners
         final Intent updatedIntent = new Intent(ACTION_NETWORK_STATS_UPDATED);
@@ -812,12 +862,13 @@
     }
 
     /**
-     * Update {@link #mNetworkStats} historical usage.
+     * Update {@link #mNetworkDevStats} historical usage.
      */
-    private void performNetworkPollLocked(NetworkStats networkSnapshot, long currentTime) {
+    private void performNetworkDevPollLocked(NetworkStats networkDevSnapshot, long currentTime) {
         final HashSet<String> unknownIface = Sets.newHashSet();
 
-        final NetworkStats delta = computeStatsDelta(mLastPollNetworkSnapshot, networkSnapshot, false);
+        final NetworkStats delta = computeStatsDelta(
+                mLastPollNetworkDevSnapshot, networkDevSnapshot, false);
         final long timeStart = currentTime - delta.getElapsedRealtime();
 
         NetworkStats.Entry entry = null;
@@ -829,14 +880,44 @@
                 continue;
             }
 
-            final NetworkStatsHistory history = findOrCreateNetworkStatsLocked(ident);
+            final NetworkStatsHistory history = findOrCreateNetworkDevStatsLocked(ident);
             history.recordData(timeStart, currentTime, entry);
         }
 
-        mLastPollNetworkSnapshot = networkSnapshot;
+        mLastPollNetworkDevSnapshot = networkDevSnapshot;
 
         if (LOGD && unknownIface.size() > 0) {
-            Slog.w(TAG, "unknown interfaces " + unknownIface.toString() + ", ignoring those stats");
+            Slog.w(TAG, "unknown dev interfaces " + unknownIface + ", ignoring those stats");
+        }
+    }
+
+    /**
+     * Update {@link #mNetworkXtStats} historical usage.
+     */
+    private void performNetworkXtPollLocked(NetworkStats networkXtSnapshot, long currentTime) {
+        final HashSet<String> unknownIface = Sets.newHashSet();
+
+        final NetworkStats delta = computeStatsDelta(
+                mLastPollNetworkXtSnapshot, networkXtSnapshot, false);
+        final long timeStart = currentTime - delta.getElapsedRealtime();
+
+        NetworkStats.Entry entry = null;
+        for (int i = 0; i < delta.size(); i++) {
+            entry = delta.getValues(i, entry);
+            final NetworkIdentitySet ident = mActiveIfaces.get(entry.iface);
+            if (ident == null) {
+                unknownIface.add(entry.iface);
+                continue;
+            }
+
+            final NetworkStatsHistory history = findOrCreateNetworkXtStatsLocked(ident);
+            history.recordData(timeStart, currentTime, entry);
+        }
+
+        mLastPollNetworkXtSnapshot = networkXtSnapshot;
+
+        if (LOGD && unknownIface.size() > 0) {
+            Slog.w(TAG, "unknown xt interfaces " + unknownIface + ", ignoring those stats");
         }
     }
 
@@ -882,38 +963,6 @@
     }
 
     /**
-     * Update {@link #mUidStats} historical usage for
-     * {@link TrafficStats#UID_TETHERING} based on tethering statistics.
-     */
-    private void performTetherPollLocked(NetworkStats tetherSnapshot, long currentTime) {
-        ensureUidStatsLoadedLocked();
-
-        final NetworkStats delta = computeStatsDelta(
-                mLastPollTetherSnapshot, tetherSnapshot, false);
-        final long timeStart = currentTime - delta.getElapsedRealtime();
-
-        NetworkStats.Entry entry = null;
-        for (int i = 0; i < delta.size(); i++) {
-            entry = delta.getValues(i, entry);
-            final NetworkIdentitySet ident = mActiveIfaces.get(entry.iface);
-            if (ident == null) {
-                if (entry.rxBytes > 0 || entry.rxPackets > 0 || entry.txBytes > 0
-                        || entry.txPackets > 0) {
-                    Log.w(TAG, "dropping tether delta from unknown iface: " + entry);
-                }
-                continue;
-            }
-
-            final NetworkStatsHistory history = findOrCreateUidStatsLocked(
-                    ident, UID_TETHERING, SET_DEFAULT, TAG_NONE);
-            history.recordData(timeStart, currentTime, entry);
-        }
-
-        // normal UID poll will trim any history beyond max
-        mLastPollTetherSnapshot = tetherSnapshot;
-    }
-
-    /**
      * Sample recent statistics summary into {@link EventLog}.
      */
     private void performSample() {
@@ -925,25 +974,34 @@
         final long end = now - (now % largestBucketSize) + largestBucketSize;
         final long start = end - largestBucketSize;
 
+        final long trustedTime = mTime.hasCache() ? mTime.currentTimeMillis() : -1;
+
         NetworkTemplate template = null;
-        NetworkStats.Entry ifaceTotal = null;
+        NetworkStats.Entry devTotal = null;
+        NetworkStats.Entry xtTotal = null;
         NetworkStats.Entry uidTotal = null;
 
         // collect mobile sample
         template = buildTemplateMobileAll(getActiveSubscriberId(mContext));
-        ifaceTotal = getSummaryForNetwork(template, start, end).getTotal(ifaceTotal);
+        devTotal = getSummaryForNetworkDev(template, start, end).getTotal(devTotal);
+        xtTotal = getSummaryForNetworkXt(template, start, end).getTotal(xtTotal);
         uidTotal = getSummaryForAllUid(template, start, end, false).getTotal(uidTotal);
-        EventLogTags.writeNetstatsMobileSample(ifaceTotal.rxBytes, ifaceTotal.rxPackets,
-                ifaceTotal.txBytes, ifaceTotal.txPackets, uidTotal.rxBytes, uidTotal.rxPackets,
-                uidTotal.txBytes, uidTotal.txPackets);
+        EventLogTags.writeNetstatsMobileSample(
+                devTotal.rxBytes, devTotal.rxPackets, devTotal.txBytes, devTotal.txPackets,
+                xtTotal.rxBytes, xtTotal.rxPackets, xtTotal.txBytes, xtTotal.txPackets,
+                uidTotal.rxBytes, uidTotal.rxPackets, uidTotal.txBytes, uidTotal.txPackets,
+                trustedTime);
 
         // collect wifi sample
         template = buildTemplateWifi();
-        ifaceTotal = getSummaryForNetwork(template, start, end).getTotal(ifaceTotal);
+        devTotal = getSummaryForNetworkDev(template, start, end).getTotal(devTotal);
+        xtTotal = getSummaryForNetworkXt(template, start, end).getTotal(xtTotal);
         uidTotal = getSummaryForAllUid(template, start, end, false).getTotal(uidTotal);
-        EventLogTags.writeNetstatsWifiSample(ifaceTotal.rxBytes, ifaceTotal.rxPackets,
-                ifaceTotal.txBytes, ifaceTotal.txPackets, uidTotal.rxBytes, uidTotal.rxPackets,
-                uidTotal.txBytes, uidTotal.txPackets);
+        EventLogTags.writeNetstatsWifiSample(
+                devTotal.rxBytes, devTotal.rxPackets, devTotal.txBytes, devTotal.txPackets,
+                xtTotal.rxBytes, xtTotal.rxPackets, xtTotal.txBytes, xtTotal.txPackets,
+                uidTotal.rxBytes, uidTotal.rxPackets, uidTotal.txBytes, uidTotal.txPackets,
+                trustedTime);
     }
 
     /**
@@ -976,8 +1034,17 @@
         writeUidStatsLocked();
     }
 
-    private NetworkStatsHistory findOrCreateNetworkStatsLocked(NetworkIdentitySet ident) {
-        final NetworkStatsHistory existing = mNetworkStats.get(ident);
+    private NetworkStatsHistory findOrCreateNetworkXtStatsLocked(NetworkIdentitySet ident) {
+        return findOrCreateNetworkStatsLocked(ident, mNetworkXtStats);
+    }
+
+    private NetworkStatsHistory findOrCreateNetworkDevStatsLocked(NetworkIdentitySet ident) {
+        return findOrCreateNetworkStatsLocked(ident, mNetworkDevStats);
+    }
+
+    private NetworkStatsHistory findOrCreateNetworkStatsLocked(
+            NetworkIdentitySet ident, HashMap<NetworkIdentitySet, NetworkStatsHistory> source) {
+        final NetworkStatsHistory existing = source.get(ident);
 
         // update when no existing, or when bucket duration changed
         final long bucketDuration = mSettings.getNetworkBucketDuration();
@@ -991,7 +1058,7 @@
         }
 
         if (updated != null) {
-            mNetworkStats.put(ident, updated);
+            source.put(ident, updated);
             return updated;
         } else {
             return existing;
@@ -1024,15 +1091,24 @@
         }
     }
 
-    private void readNetworkStatsLocked() {
-        if (LOGV) Slog.v(TAG, "readNetworkStatsLocked()");
+    private void readNetworkDevStatsLocked() {
+        if (LOGV) Slog.v(TAG, "readNetworkDevStatsLocked()");
+        readNetworkStats(mNetworkDevFile, mNetworkDevStats);
+    }
 
+    private void readNetworkXtStatsLocked() {
+        if (LOGV) Slog.v(TAG, "readNetworkXtStatsLocked()");
+        readNetworkStats(mNetworkXtFile, mNetworkXtStats);
+    }
+
+    private static void readNetworkStats(
+            AtomicFile inputFile, HashMap<NetworkIdentitySet, NetworkStatsHistory> output) {
         // clear any existing stats and read from disk
-        mNetworkStats.clear();
+        output.clear();
 
         DataInputStream in = null;
         try {
-            in = new DataInputStream(new BufferedInputStream(mNetworkFile.openRead()));
+            in = new DataInputStream(new BufferedInputStream(inputFile.openRead()));
 
             // verify file magic header intact
             final int magic = in.readInt();
@@ -1048,7 +1124,7 @@
                     for (int i = 0; i < size; i++) {
                         final NetworkIdentitySet ident = new NetworkIdentitySet(in);
                         final NetworkStatsHistory history = new NetworkStatsHistory(in);
-                        mNetworkStats.put(ident, history);
+                        output.put(ident, history);
                     }
                     break;
                 }
@@ -1138,41 +1214,50 @@
         }
     }
 
-    private void writeNetworkStatsLocked() {
-        if (LOGV) Slog.v(TAG, "writeNetworkStatsLocked()");
+    private void writeNetworkDevStatsLocked() {
+        if (LOGV) Slog.v(TAG, "writeNetworkDevStatsLocked()");
+        writeNetworkStats(mNetworkDevStats, mNetworkDevFile);
+    }
 
+    private void writeNetworkXtStatsLocked() {
+        if (LOGV) Slog.v(TAG, "writeNetworkXtStatsLocked()");
+        writeNetworkStats(mNetworkXtStats, mNetworkXtFile);
+    }
+
+    private void writeNetworkStats(
+            HashMap<NetworkIdentitySet, NetworkStatsHistory> input, AtomicFile outputFile) {
         // TODO: consider duplicating stats and releasing lock while writing
 
         // trim any history beyond max
         if (mTime.hasCache()) {
             final long currentTime = mTime.currentTimeMillis();
             final long maxHistory = mSettings.getNetworkMaxHistory();
-            for (NetworkStatsHistory history : mNetworkStats.values()) {
+            for (NetworkStatsHistory history : input.values()) {
                 history.removeBucketsBefore(currentTime - maxHistory);
             }
         }
 
         FileOutputStream fos = null;
         try {
-            fos = mNetworkFile.startWrite();
+            fos = outputFile.startWrite();
             final DataOutputStream out = new DataOutputStream(new BufferedOutputStream(fos));
 
             out.writeInt(FILE_MAGIC);
             out.writeInt(VERSION_NETWORK_INIT);
 
-            out.writeInt(mNetworkStats.size());
-            for (NetworkIdentitySet ident : mNetworkStats.keySet()) {
-                final NetworkStatsHistory history = mNetworkStats.get(ident);
+            out.writeInt(input.size());
+            for (NetworkIdentitySet ident : input.keySet()) {
+                final NetworkStatsHistory history = input.get(ident);
                 ident.writeToStream(out);
                 history.writeToStream(out);
             }
 
             out.flush();
-            mNetworkFile.finishWrite(fos);
+            outputFile.finishWrite(fos);
         } catch (IOException e) {
             Log.wtf(TAG, "problem writing stats", e);
             if (fos != null) {
-                mNetworkFile.failWrite(fos);
+                outputFile.failWrite(fos);
             }
         }
     }
@@ -1280,9 +1365,16 @@
                 pw.print(" ident="); pw.println(ident.toString());
             }
 
-            pw.println("Known historical stats:");
-            for (NetworkIdentitySet ident : mNetworkStats.keySet()) {
-                final NetworkStatsHistory history = mNetworkStats.get(ident);
+            pw.println("Known historical dev stats:");
+            for (NetworkIdentitySet ident : mNetworkDevStats.keySet()) {
+                final NetworkStatsHistory history = mNetworkDevStats.get(ident);
+                pw.print("  ident="); pw.println(ident.toString());
+                history.dump("  ", pw, fullHistory);
+            }
+
+            pw.println("Known historical xt stats:");
+            for (NetworkIdentitySet ident : mNetworkXtStats.keySet()) {
+                final NetworkStatsHistory history = mNetworkXtStats.get(ident);
                 pw.print("  ident="); pw.println(ident.toString());
                 history.dump("  ", pw, fullHistory);
             }
@@ -1333,10 +1425,13 @@
         final List<ApplicationInfo> installedApps = mContext
                 .getPackageManager().getInstalledApplications(0);
 
-        mNetworkStats.clear();
+        mNetworkDevStats.clear();
+        mNetworkXtStats.clear();
         mUidStats.clear();
         for (NetworkIdentitySet ident : mActiveIfaces.values()) {
-            findOrCreateNetworkStatsLocked(ident).generateRandom(NET_START, NET_END, NET_RX_BYTES,
+            findOrCreateNetworkDevStatsLocked(ident).generateRandom(NET_START, NET_END,
+                    NET_RX_BYTES, NET_RX_PACKETS, NET_TX_BYTES, NET_TX_PACKETS, 0L);
+            findOrCreateNetworkXtStatsLocked(ident).generateRandom(NET_START, NET_END, NET_RX_BYTES,
                     NET_RX_PACKETS, NET_TX_BYTES, NET_TX_PACKETS, 0L);
 
             for (ApplicationInfo info : installedApps) {
@@ -1369,6 +1464,10 @@
         }
     }
 
+    private static NetworkStats computeNetworkXtSnapshotFromUid(NetworkStats uidSnapshot) {
+        return uidSnapshot.groupedByIface();
+    }
+
     private int estimateNetworkBuckets() {
         return (int) (mSettings.getNetworkMaxHistory() / mSettings.getNetworkBucketDuration());
     }
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index eb135b7..19dd606 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -753,7 +753,7 @@
 
                     if (state != null) {
                         final InstallArgs args = state.getInstallArgs();
-                        Slog.i(TAG, "Validation timed out for " + args.packageURI.toString());
+                        Slog.i(TAG, "Verification timed out for " + args.packageURI.toString());
                         mPendingVerification.remove(verificationId);
 
                         int ret = PackageManager.INSTALL_FAILED_VERIFICATION_TIMEOUT;
@@ -769,7 +769,7 @@
 
                     final PackageVerificationState state = mPendingVerification.get(verificationId);
                     if (state == null) {
-                        Slog.w(TAG, "Invalid validation token " + verificationId + " received");
+                        Slog.w(TAG, "Invalid verification token " + verificationId + " received");
                         break;
                     }
 
@@ -5464,8 +5464,8 @@
                 final int requiredUid = mRequiredVerifierPackage == null ? -1
                         : getPackageUid(mRequiredVerifierPackage);
                 if (requiredUid != -1 && isVerificationEnabled()) {
-                    final Intent verification = new Intent(
-                            Intent.ACTION_PACKAGE_NEEDS_VERIFICATION, packageURI);
+                    final Intent verification = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
+                    verification.setDataAndType(packageURI, PACKAGE_MIME_TYPE);
                     verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
 
                     final List<ResolveInfo> receivers = queryIntentReceivers(verification, null,
diff --git a/services/tests/servicestests/res/raw/xt_qtaguid_iface_typical b/services/tests/servicestests/res/raw/xt_qtaguid_iface_typical
new file mode 100644
index 0000000..efa4cd5
--- /dev/null
+++ b/services/tests/servicestests/res/raw/xt_qtaguid_iface_typical
@@ -0,0 +1,6 @@
+rmnet3 1 0 0 0 0 20822 501 1149991 815

+rmnet2 1 0 0 0 0 1594 15 1313 15

+rmnet1 1 0 0 0 0 207398 458 166918 565

+rmnet0 1 0 0 0 0 2112 24 700 10

+test1 1 1 2 3 4 5 6 7 8

+test2 0 1 2 3 4 5 6 7 8

diff --git a/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java
index ab1597c..40640e0 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java
@@ -159,6 +159,16 @@
         assertStatsEntry(stats, "rmnet0", 1000, SET_FOREGROUND, 0, 26033L, 30L, 1401L, 26L);
     }
 
+    public void testNetworkStatsSingle() throws Exception {
+        stageFile(R.raw.xt_qtaguid_iface_typical, new File(mTestProc, "net/xt_qtaguid/iface_stat_all"));
+
+        final NetworkStats stats = mService.getNetworkStatsSummary();
+        assertEquals(6, stats.size());
+        assertStatsEntry(stats, "rmnet0", UID_ALL, SET_DEFAULT, TAG_NONE, 2112L, 24L, 700L, 10L);
+        assertStatsEntry(stats, "test1", UID_ALL, SET_DEFAULT, TAG_NONE, 6L, 8L, 10L, 12L);
+        assertStatsEntry(stats, "test2", UID_ALL, SET_DEFAULT, TAG_NONE, 1L, 2L, 3L, 4L);
+    }
+
     /**
      * Copy a {@link Resources#openRawResource(int)} into {@link File} for
      * testing purposes.
diff --git a/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java
index 2ead254..f7dff23 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java
@@ -32,6 +32,7 @@
 import static android.net.NetworkTemplate.buildTemplateMobileAll;
 import static android.net.NetworkTemplate.buildTemplateWifi;
 import static android.net.TrafficStats.UID_REMOVED;
+import static android.net.TrafficStats.UID_TETHERING;
 import static android.text.format.DateUtils.DAY_IN_MILLIS;
 import static android.text.format.DateUtils.HOUR_IN_MILLIS;
 import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
@@ -179,6 +180,7 @@
         expectNetworkState(buildWifiState());
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(buildEmptyStats());
+        expectNetworkStatsPoll();
 
         replay();
         mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
@@ -232,6 +234,7 @@
         expectNetworkState(buildWifiState());
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(buildEmptyStats());
+        expectNetworkStatsPoll();
 
         replay();
         mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
@@ -327,6 +330,7 @@
         expectNetworkState(buildWifiState());
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(buildEmptyStats());
+        expectNetworkStatsPoll();
 
         replay();
         mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
@@ -378,6 +382,7 @@
         expectNetworkState(buildMobile3gState(IMSI_1));
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(buildEmptyStats());
+        expectNetworkStatsPoll();
 
         replay();
         mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
@@ -459,6 +464,7 @@
         expectNetworkState(buildWifiState());
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(buildEmptyStats());
+        expectNetworkStatsPoll();
 
         replay();
         mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
@@ -518,6 +524,7 @@
         expectNetworkState(buildMobile3gState(IMSI_1));
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(buildEmptyStats());
+        expectNetworkStatsPoll();
 
         replay();
         mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
@@ -585,6 +592,7 @@
         expectNetworkState(buildWifiState());
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(buildEmptyStats());
+        expectNetworkStatsPoll();
 
         replay();
         mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
@@ -648,6 +656,7 @@
         expectNetworkState(buildWifiState());
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(buildEmptyStats());
+        expectNetworkStatsPoll();
 
         replay();
         mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
@@ -705,6 +714,42 @@
         verifyAndReset();
     }
 
+    public void testTethering() throws Exception {
+        // pretend first mobile network comes online
+        expectCurrentTime();
+        expectDefaultSettings();
+        expectNetworkState(buildMobile3gState(IMSI_1));
+        expectNetworkStatsSummary(buildEmptyStats());
+        expectNetworkStatsUidDetail(buildEmptyStats());
+        expectNetworkStatsPoll();
+
+        replay();
+        mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
+        verifyAndReset();
+
+        // create some tethering traffic
+        incrementCurrentTime(HOUR_IN_MILLIS);
+        expectCurrentTime();
+        expectDefaultSettings();
+        expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
+                .addIfaceValues(TEST_IFACE, 2048L, 16L, 512L, 4L));
+        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
+                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L));
+        final String[] tetherIfacePairs = new String[] { TEST_IFACE, "wlan0" };
+        expectNetworkStatsPoll(tetherIfacePairs, new NetworkStats(getElapsedRealtime(), 1)
+                .addValues(TEST_IFACE, UID_TETHERING, SET_DEFAULT, TAG_NONE, 1920L, 14L, 384L, 2L, 0L));
+
+        replay();
+        mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
+
+        // verify service recorded history
+        assertNetworkTotal(sTemplateImsi1, 2048L, 16L, 512L, 4L, 0);
+        assertUidTotal(sTemplateImsi1, UID_RED, 128L, 2L, 128L, 2L, 0);
+        assertUidTotal(sTemplateImsi1, UID_TETHERING, 1920L, 14L, 384L, 2L, 0);
+        verifyAndReset();
+
+    }
+
     private void assertNetworkTotal(NetworkTemplate template, long rxBytes, long rxPackets,
             long txBytes, long txPackets, int operations) {
         final NetworkStatsHistory history = mService.getHistoryForNetwork(template, FIELD_ALL);
@@ -774,9 +819,16 @@
     }
 
     private void expectNetworkStatsPoll() throws Exception {
+        expectNetworkStatsPoll(new String[0], new NetworkStats(getElapsedRealtime(), 0));
+    }
+
+    private void expectNetworkStatsPoll(String[] tetherIfacePairs, NetworkStats tetherStats)
+            throws Exception {
         mNetManager.setGlobalAlert(anyLong());
         expectLastCall().anyTimes();
-        expect(mConnManager.getTetheredIfacePairs()).andReturn(null).anyTimes();
+        expect(mConnManager.getTetheredIfacePairs()).andReturn(tetherIfacePairs).anyTimes();
+        expect(mNetManager.getNetworkStatsTethering(eq(tetherIfacePairs)))
+                .andReturn(tetherStats).anyTimes();
     }
 
     private void assertStatsFilesExist(boolean exist) {
diff --git a/wifi/java/android/net/wifi/WifiConfigStore.java b/wifi/java/android/net/wifi/WifiConfigStore.java
index 18d6eaa..568a485 100644
--- a/wifi/java/android/net/wifi/WifiConfigStore.java
+++ b/wifi/java/android/net/wifi/WifiConfigStore.java
@@ -100,6 +100,7 @@
 
     private static Context sContext;
     private static final String TAG = "WifiConfigStore";
+    private static final boolean DBG = false;
 
     /* configured networks with network id as the key */
     private static HashMap<Integer, WifiConfiguration> sConfiguredNetworks =
@@ -140,7 +141,7 @@
      * and enable all stored networks in supplicant.
      */
     static void initialize(Context context) {
-        Log.d(TAG, "Loading config and enabling all networks");
+        if (DBG) log("Loading config and enabling all networks");
         sContext = context;
         loadConfiguredNetworks();
         enableAllNetworks();
@@ -173,7 +174,7 @@
                         networkEnabledStateChanged = true;
                         config.status = Status.ENABLED;
                     } else {
-                        Log.e(TAG, "Enable network failed on " + config.networkId);
+                        loge("Enable network failed on " + config.networkId);
                     }
                 }
             }
@@ -204,7 +205,7 @@
             if (netId != INVALID_NETWORK_ID) {
                 selectNetwork(netId);
             } else {
-                Log.e(TAG, "Failed to update network " + config);
+                loge("Failed to update network " + config);
             }
             return netId;
         }
@@ -290,7 +291,7 @@
             writeIpAndProxyConfigurations();
             sendConfiguredNetworksChangedBroadcast();
         } else {
-            Log.e(TAG, "Failed to remove network " + netId);
+            loge("Failed to remove network " + netId);
         }
     }
 
@@ -404,7 +405,7 @@
             markAllNetworksDisabled();
             result.status = WpsResult.Status.SUCCESS;
         } else {
-            Log.e(TAG, "Failed to start WPS pin method configuration");
+            loge("Failed to start WPS pin method configuration");
             result.status = WpsResult.Status.FAILURE;
         }
         return result;
@@ -423,7 +424,7 @@
             markAllNetworksDisabled();
             result.status = WpsResult.Status.SUCCESS;
         } else {
-            Log.e(TAG, "Failed to start WPS pin method configuration");
+            loge("Failed to start WPS pin method configuration");
             result.status = WpsResult.Status.FAILURE;
         }
         return result;
@@ -439,7 +440,7 @@
             markAllNetworksDisabled();
             result.status = WpsResult.Status.SUCCESS;
         } else {
-            Log.e(TAG, "Failed to start WPS push button configuration");
+            loge("Failed to start WPS push button configuration");
             result.status = WpsResult.Status.FAILURE;
         }
         return result;
@@ -680,7 +681,7 @@
                                 /* Ignore */
                                 break;
                             default:
-                                Log.e(TAG, "Ignore invalid ip assignment while writing");
+                                loge("Ignore invalid ip assignment while writing");
                                 break;
                         }
 
@@ -707,7 +708,7 @@
                                 /* Ignore */
                                 break;
                             default:
-                                Log.e(TAG, "Ignore invalid proxy settings while writing");
+                                loge("Ignore invalid proxy settings while writing");
                                 break;
                         }
                         if (writeToFile) {
@@ -715,14 +716,14 @@
                             out.writeInt(configKey(config));
                         }
                     } catch (NullPointerException e) {
-                        Log.e(TAG, "Failure in writing " + config.linkProperties + e);
+                        loge("Failure in writing " + config.linkProperties + e);
                     }
                     out.writeUTF(EOS);
                 }
             }
 
         } catch (IOException e) {
-            Log.e(TAG, "Error writing data file");
+            loge("Error writing data file");
         } finally {
             if (out != null) {
                 try {
@@ -741,7 +742,7 @@
 
             int version = in.readInt();
             if (version != 2 && version != 1) {
-                Log.e(TAG, "Bad version on IP configuration file, ignore read");
+                loge("Bad version on IP configuration file, ignore read");
                 return;
             }
 
@@ -797,10 +798,10 @@
                         } else if (key.equals(EOS)) {
                             break;
                         } else {
-                            Log.e(TAG, "Ignore unknown key " + key + "while reading");
+                            loge("Ignore unknown key " + key + "while reading");
                         }
                     } catch (IllegalArgumentException e) {
-                        Log.e(TAG, "Ignore invalid address while reading" + e);
+                        loge("Ignore invalid address while reading" + e);
                     }
                 } while (true);
 
@@ -810,7 +811,7 @@
                                 sNetworkIds.get(id));
 
                         if (config == null) {
-                            Log.e(TAG, "configuration found for missing network, ignored");
+                            loge("configuration found for missing network, ignored");
                         } else {
                             config.linkProperties = linkProperties;
                             switch (ipAssignment) {
@@ -822,7 +823,7 @@
                                     //Ignore
                                     break;
                                 default:
-                                    Log.e(TAG, "Ignore invalid ip assignment while reading");
+                                    loge("Ignore invalid ip assignment while reading");
                                     break;
                             }
 
@@ -840,18 +841,18 @@
                                     //Ignore
                                     break;
                                 default:
-                                    Log.e(TAG, "Ignore invalid proxy settings while reading");
+                                    loge("Ignore invalid proxy settings while reading");
                                     break;
                             }
                         }
                     }
                 } else {
-                    Log.e(TAG, "Missing id while parsing configuration");
+                    loge("Missing id while parsing configuration");
                 }
             }
         } catch (EOFException ignore) {
         } catch (IOException e) {
-            Log.e(TAG, "Error parsing configuration" + e);
+            loge("Error parsing configuration" + e);
         } finally {
             if (in != null) {
                 try {
@@ -878,7 +879,7 @@
                 newNetwork = true;
                 netId = WifiNative.addNetworkCommand();
                 if (netId < 0) {
-                    Log.e(TAG, "Failed to add a network!");
+                    loge("Failed to add a network!");
                     return new NetworkUpdateResult(INVALID_NETWORK_ID);
                 }
             }
@@ -893,7 +894,7 @@
                         netId,
                         WifiConfiguration.ssidVarName,
                         config.SSID)) {
-                Log.d(TAG, "failed to set SSID: "+config.SSID);
+                loge("failed to set SSID: "+config.SSID);
                 break setVariables;
             }
 
@@ -902,7 +903,7 @@
                         netId,
                         WifiConfiguration.bssidVarName,
                         config.BSSID)) {
-                Log.d(TAG, "failed to set BSSID: "+config.BSSID);
+                loge("failed to set BSSID: "+config.BSSID);
                 break setVariables;
             }
 
@@ -913,7 +914,7 @@
                         netId,
                         WifiConfiguration.KeyMgmt.varName,
                         allowedKeyManagementString)) {
-                Log.d(TAG, "failed to set key_mgmt: "+
+                loge("failed to set key_mgmt: "+
                         allowedKeyManagementString);
                 break setVariables;
             }
@@ -925,7 +926,7 @@
                         netId,
                         WifiConfiguration.Protocol.varName,
                         allowedProtocolsString)) {
-                Log.d(TAG, "failed to set proto: "+
+                loge("failed to set proto: "+
                         allowedProtocolsString);
                 break setVariables;
             }
@@ -937,7 +938,7 @@
                         netId,
                         WifiConfiguration.AuthAlgorithm.varName,
                         allowedAuthAlgorithmsString)) {
-                Log.d(TAG, "failed to set auth_alg: "+
+                loge("failed to set auth_alg: "+
                         allowedAuthAlgorithmsString);
                 break setVariables;
             }
@@ -950,7 +951,7 @@
                         netId,
                         WifiConfiguration.PairwiseCipher.varName,
                         allowedPairwiseCiphersString)) {
-                Log.d(TAG, "failed to set pairwise: "+
+                loge("failed to set pairwise: "+
                         allowedPairwiseCiphersString);
                 break setVariables;
             }
@@ -962,7 +963,7 @@
                         netId,
                         WifiConfiguration.GroupCipher.varName,
                         allowedGroupCiphersString)) {
-                Log.d(TAG, "failed to set group: "+
+                loge("failed to set group: "+
                         allowedGroupCiphersString);
                 break setVariables;
             }
@@ -974,7 +975,7 @@
                         netId,
                         WifiConfiguration.pskVarName,
                         config.preSharedKey)) {
-                Log.d(TAG, "failed to set psk");
+                loge("failed to set psk");
                 break setVariables;
             }
 
@@ -988,9 +989,7 @@
                                     netId,
                                     WifiConfiguration.wepKeyVarNames[i],
                                     config.wepKeys[i])) {
-                            Log.d(TAG,
-                                    "failed to set wep_key"+i+": " +
-                                    config.wepKeys[i]);
+                            loge("failed to set wep_key" + i + ": " + config.wepKeys[i]);
                             break setVariables;
                         }
                         hasSetKey = true;
@@ -1003,9 +1002,7 @@
                             netId,
                             WifiConfiguration.wepTxKeyIdxVarName,
                             Integer.toString(config.wepTxKeyIndex))) {
-                    Log.d(TAG,
-                            "failed to set wep_tx_keyidx: "+
-                            config.wepTxKeyIndex);
+                    loge("failed to set wep_tx_keyidx: " + config.wepTxKeyIndex);
                     break setVariables;
                 }
             }
@@ -1014,7 +1011,7 @@
                         netId,
                         WifiConfiguration.priorityVarName,
                         Integer.toString(config.priority))) {
-                Log.d(TAG, config.SSID + ": failed to set priority: "
+                loge(config.SSID + ": failed to set priority: "
                         +config.priority);
                 break setVariables;
             }
@@ -1023,7 +1020,7 @@
                         netId,
                         WifiConfiguration.hiddenSSIDVarName,
                         Integer.toString(config.hiddenSSID ? 1 : 0))) {
-                Log.d(TAG, config.SSID + ": failed to set hiddenSSID: "+
+                loge(config.SSID + ": failed to set hiddenSSID: "+
                         config.hiddenSSID);
                 break setVariables;
             }
@@ -1040,7 +1037,7 @@
                                 netId,
                                 varName,
                                 value)) {
-                        Log.d(TAG, config.SSID + ": failed to set " + varName +
+                        loge(config.SSID + ": failed to set " + varName +
                                 ": " + value);
                         break setVariables;
                     }
@@ -1052,9 +1049,7 @@
         if (updateFailed) {
             if (newNetwork) {
                 WifiNative.removeNetworkCommand(netId);
-                Log.d(TAG,
-                        "Failed to set a network variable, removed network: "
-                        + netId);
+                loge("Failed to set a network variable, removed network: " + netId);
             }
             return new NetworkUpdateResult(INVALID_NETWORK_ID);
         }
@@ -1130,7 +1125,7 @@
                 /* Ignore */
                 break;
             default:
-                Log.e(TAG, "Ignore invalid ip assignment during write");
+                loge("Ignore invalid ip assignment during write");
                 break;
         }
 
@@ -1154,7 +1149,7 @@
                 /* Ignore */
                 break;
             default:
-                Log.e(TAG, "Ignore invalid proxy configuration during write");
+                loge("Ignore invalid proxy configuration during write");
                 break;
         }
 
@@ -1163,7 +1158,7 @@
         } else {
             currentConfig.ipAssignment = newConfig.ipAssignment;
             addIpSettingsFromConfig(linkProperties, newConfig);
-            Log.d(TAG, "IP config changed SSID = " + currentConfig.SSID + " linkProperties: " +
+            log("IP config changed SSID = " + currentConfig.SSID + " linkProperties: " +
                     linkProperties.toString());
         }
 
@@ -1173,9 +1168,9 @@
         } else {
             currentConfig.proxySettings = newConfig.proxySettings;
             linkProperties.setHttpProxy(newConfig.linkProperties.getHttpProxy());
-            Log.d(TAG, "proxy changed SSID = " + currentConfig.SSID);
+            log("proxy changed SSID = " + currentConfig.SSID);
             if (linkProperties.getHttpProxy() != null) {
-                Log.d(TAG, " proxyProperties: " + linkProperties.getHttpProxy().toString());
+                log(" proxyProperties: " + linkProperties.getHttpProxy().toString());
             }
         }
 
@@ -1394,7 +1389,7 @@
         // if we ever get here, we should probably add the
         // value to WifiConfiguration to reflect that it's
         // supported by the WPA supplicant
-        Log.w(TAG, "Failed to look-up a string: " + string);
+        loge("Failed to look-up a string: " + string);
 
         return -1;
     }
@@ -1431,4 +1426,12 @@
     public static String getConfigFile() {
         return ipConfigFile;
     }
+
+    private static void loge(String s) {
+        Log.e(TAG, s);
+    }
+
+    private static void log(String s) {
+        Log.d(TAG, s);
+    }
 }
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index d1522fb..5ca7aff 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -75,7 +75,6 @@
 import android.util.EventLog;
 import android.util.Log;
 import android.util.LruCache;
-import android.util.Slog;
 
 import com.android.internal.app.IBatteryStats;
 import com.android.internal.util.AsyncChannel;
@@ -1104,12 +1103,12 @@
                             mNwService.setInterfaceConfig(intf, ifcg);
                         }
                     } catch (Exception e) {
-                        Log.e(TAG, "Error configuring interface " + intf + ", :" + e);
+                        loge("Error configuring interface " + intf + ", :" + e);
                         return false;
                     }
 
                     if(mCm.tether(intf) != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
-                        Log.e(TAG, "Error tethering on " + intf);
+                        loge("Error tethering on " + intf);
                         return false;
                     }
                     return true;
@@ -1135,11 +1134,11 @@
                 mNwService.setInterfaceConfig(mInterfaceName, ifcg);
             }
         } catch (Exception e) {
-            Log.e(TAG, "Error resetting interface " + mInterfaceName + ", :" + e);
+            loge("Error resetting interface " + mInterfaceName + ", :" + e);
         }
 
         if (mCm.untether(mInterfaceName) != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
-            Log.e(TAG, "Untether initiate failed!");
+            loge("Untether initiate failed!");
         }
     }
 
@@ -1175,12 +1174,12 @@
                 mBatteryStats.noteWifiOff();
             }
         } catch (RemoteException e) {
-            Log.e(TAG, "Failed to note battery stats in wifi");
+            loge("Failed to note battery stats in wifi");
         }
 
         mWifiState.set(wifiState);
 
-        if (DBG) Log.d(TAG, "setWifiState: " + syncGetWifiStateByName());
+        if (DBG) log("setWifiState: " + syncGetWifiStateByName());
 
         final Intent intent = new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION);
         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
@@ -1199,13 +1198,13 @@
                 mBatteryStats.noteWifiOff();
             }
         } catch (RemoteException e) {
-            Log.d(TAG, "Failed to note battery stats in wifi");
+            loge("Failed to note battery stats in wifi");
         }
 
         // Update state
         mWifiApState.set(wifiApState);
 
-        if (DBG) Log.d(TAG, "setWifiApState: " + syncGetWifiApStateByName());
+        if (DBG) log("setWifiApState: " + syncGetWifiApStateByName());
 
         final Intent intent = new Intent(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
@@ -1291,7 +1290,7 @@
                         }
                     }
                 } else {
-                    Log.w(TAG, "Misformatted scan result text with " +
+                    loge("Misformatted scan result text with " +
                           result.length + " fields: " + line);
                 }
             }
@@ -1419,15 +1418,15 @@
 
     private void setHighPerfModeEnabledNative(boolean enable) {
         if(!WifiNative.setSuspendOptimizationsCommand(!enable)) {
-            Log.e(TAG, "set suspend optimizations failed!");
+            loge("set suspend optimizations failed!");
         }
         if (enable) {
             if (!WifiNative.setPowerModeCommand(POWER_MODE_ACTIVE)) {
-                Log.e(TAG, "set power mode active failed!");
+                loge("set power mode active failed!");
             }
         } else {
             if (!WifiNative.setPowerModeCommand(POWER_MODE_AUTO)) {
-                Log.e(TAG, "set power mode auto failed!");
+                loge("set power mode auto failed!");
             }
         }
     }
@@ -1442,7 +1441,10 @@
             mLinkProperties.setHttpProxy(WifiConfigStore.getProxyProperties(mLastNetworkId));
         }
         mLinkProperties.setInterfaceName(mInterfaceName);
-        Log.d(TAG, "netId=" + mLastNetworkId  + " Link configured: " + mLinkProperties.toString());
+        if (DBG) {
+            log("netId=" + mLastNetworkId  + " Link configured: " +
+                    mLinkProperties.toString());
+        }
     }
 
     private int getMaxDhcpRetries() {
@@ -1503,8 +1505,11 @@
      * @param state the new @{code DetailedState}
      */
     private void setNetworkDetailedState(NetworkInfo.DetailedState state) {
-        Log.d(TAG, "setDetailed state, old ="
-                + mNetworkInfo.getDetailedState() + " and new state=" + state);
+        if (DBG) {
+            log("setDetailed state, old ="
+                    + mNetworkInfo.getDetailedState() + " and new state=" + state);
+        }
+
         if (state != mNetworkInfo.getDetailedState()) {
             mNetworkInfo.setDetailedState(state, null, null);
         }
@@ -1547,7 +1552,7 @@
      * using the interface, stopping DHCP & disabling interface
      */
     private void handleNetworkDisconnect() {
-        Log.d(TAG, "Stopping DHCP and clearing IP");
+        if (DBG) log("Stopping DHCP and clearing IP");
 
         /*
          * stop DHCP
@@ -1562,7 +1567,7 @@
             mNwService.clearInterfaceAddresses(mInterfaceName);
             mNwService.disableIpv6(mInterfaceName);
         } catch (Exception e) {
-            Log.e(TAG, "Failed to clear addresses or disable ipv6" + e);
+            loge("Failed to clear addresses or disable ipv6" + e);
         }
 
         /* Reset data structures */
@@ -1647,8 +1652,10 @@
             linkProperties.setHttpProxy(WifiConfigStore.getProxyProperties(mLastNetworkId));
             linkProperties.setInterfaceName(mInterfaceName);
             if (!linkProperties.equals(mLinkProperties)) {
-                Log.d(TAG, "Link configuration changed for netId: " + mLastNetworkId
-                    + " old: " + mLinkProperties + "new: " + linkProperties);
+                if (DBG) {
+                    log("Link configuration changed for netId: " + mLastNetworkId
+                            + " old: " + mLinkProperties + "new: " + linkProperties);
+                }
                 mLinkProperties = linkProperties;
                 sendLinkConfigurationChangedBroadcast();
             }
@@ -1660,7 +1667,7 @@
     }
 
     private void handleFailedIpConfiguration() {
-        Log.e(TAG, "IP configuration failed");
+        loge("IP configuration failed");
 
         mWifiInfo.setInetAddress(null);
         /**
@@ -1668,7 +1675,7 @@
          * to a given network, disable the network
          */
         if (++mReconnectCount > getMaxDhcpRetries()) {
-            Log.e(TAG, "Failed " +
+            loge("Failed " +
                     mReconnectCount + " times, Disabling " + mLastNetworkId);
             WifiConfigStore.disableNetwork(mLastNetworkId,
                     WifiConfiguration.DISABLED_DHCP_FAILURE);
@@ -1697,12 +1704,12 @@
         try {
             mNwService.startAccessPoint(config, mInterfaceName, SOFTAP_IFACE);
         } catch (Exception e) {
-            Log.e(TAG, "Exception in softap start " + e);
+            loge("Exception in softap start " + e);
             try {
                 mNwService.stopAccessPoint(mInterfaceName);
                 mNwService.startAccessPoint(config, mInterfaceName, SOFTAP_IFACE);
             } catch (Exception e1) {
-                Log.e(TAG, "Exception in softap re-start " + e1);
+                loge("Exception in softap re-start " + e1);
                 return false;
             }
         }
@@ -1716,17 +1723,17 @@
     class DefaultState extends State {
         @Override
         public boolean processMessage(Message message) {
-            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+            if (DBG) log(getName() + message.toString() + "\n");
             switch (message.what) {
                 case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
                     if (message.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
                         mWifiP2pChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION);
                     } else {
-                        Log.e(TAG, "WifiP2pService connection failure, error=" + message.arg1);
+                        loge("WifiP2pService connection failure, error=" + message.arg1);
                     }
                     break;
                 case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
-                    Log.e(TAG, "WifiP2pService channel lost, message.arg1 =" + message.arg1);
+                    loge("WifiP2pService channel lost, message.arg1 =" + message.arg1);
                     //TODO: Re-establish connection to state machine after a delay
                     //mWifiP2pChannel.connect(mContext, getHandler(), mWifiP2pManager.getMessenger());
                     break;
@@ -1812,7 +1819,7 @@
                     deferMessage(message);
                     break;
                 default:
-                    Log.e(TAG, "Error! unhandled message" + message);
+                    loge("Error! unhandled message" + message);
                     break;
             }
             return HANDLED;
@@ -1823,7 +1830,7 @@
         @Override
         //TODO: could move logging into a common class
         public void enter() {
-            if (DBG) Log.d(TAG, getName() + "\n");
+            if (DBG) log(getName() + "\n");
             // [31-8] Reserved for future use
             // [7 - 0] HSM state change
             // 50021 wifi_state_changed (custom|1|5)
@@ -1853,9 +1860,9 @@
             try {
                 mNwService.disableIpv6(mInterfaceName);
             } catch (RemoteException re) {
-                Log.e(TAG, "Failed to disable IPv6: " + re);
+                loge("Failed to disable IPv6: " + re);
             } catch (IllegalStateException e) {
-                Log.e(TAG, "Failed to disable IPv6: " + e);
+                loge("Failed to disable IPv6: " + e);
             }
         }
     }
@@ -1863,7 +1870,7 @@
     class DriverLoadingState extends State {
         @Override
         public void enter() {
-            if (DBG) Log.d(TAG, getName() + "\n");
+            if (DBG) log(getName() + "\n");
             EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
 
             final Message message = new Message();
@@ -1885,10 +1892,10 @@
                     }
 
                     if(WifiNative.loadDriver()) {
-                        Log.d(TAG, "Driver load successful");
+                        if (DBG) log("Driver load successful");
                         sendMessage(CMD_LOAD_DRIVER_SUCCESS);
                     } else {
-                        Log.e(TAG, "Failed to load driver!");
+                        loge("Failed to load driver!");
                         switch(message.arg1) {
                             case WIFI_STATE_ENABLING:
                                 setWifiState(WIFI_STATE_UNKNOWN);
@@ -1906,7 +1913,7 @@
 
         @Override
         public boolean processMessage(Message message) {
-            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+            if (DBG) log(getName() + message.toString() + "\n");
             switch (message.what) {
                 case CMD_LOAD_DRIVER_SUCCESS:
                     transitionTo(mDriverLoadedState);
@@ -1942,12 +1949,12 @@
     class DriverLoadedState extends State {
         @Override
         public void enter() {
-            if (DBG) Log.d(TAG, getName() + "\n");
+            if (DBG) log(getName() + "\n");
             EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
         }
         @Override
         public boolean processMessage(Message message) {
-            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+            if (DBG) log(getName() + message.toString() + "\n");
             switch(message.what) {
                 case CMD_UNLOAD_DRIVER:
                     transitionTo(mDriverUnloadingState);
@@ -1956,7 +1963,7 @@
                     try {
                         mNwService.wifiFirmwareReload(mInterfaceName, "STA");
                     } catch (Exception e) {
-                        Log.e(TAG, "Failed to reload STA firmware " + e);
+                        loge("Failed to reload STA firmware " + e);
                         // continue
                     }
                    try {
@@ -1967,17 +1974,17 @@
                         //Set privacy extensions
                         mNwService.setInterfaceIpv6PrivacyExtensions(mInterfaceName, true);
                     } catch (RemoteException re) {
-                        if (DBG) Log.w(TAG, "Unable to change interface settings: " + re);
+                        loge("Unable to change interface settings: " + re);
                     } catch (IllegalStateException ie) {
-                        if (DBG) Log.w(TAG, "Unable to change interface settings: " + ie);
+                        loge("Unable to change interface settings: " + ie);
                     }
 
                     if(WifiNative.startSupplicant()) {
-                        Log.d(TAG, "Supplicant start successful");
+                        if (DBG) log("Supplicant start successful");
                         mWifiMonitor.startMonitoring();
                         transitionTo(mSupplicantStartingState);
                     } else {
-                        Log.e(TAG, "Failed to start supplicant!");
+                        loge("Failed to start supplicant!");
                         sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_STATE_UNKNOWN, 0));
                     }
                     break;
@@ -1995,17 +2002,17 @@
     class DriverUnloadingState extends State {
         @Override
         public void enter() {
-            if (DBG) Log.d(TAG, getName() + "\n");
+            if (DBG) log(getName() + "\n");
             EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
 
             final Message message = new Message();
             message.copyFrom(getCurrentMessage());
             new Thread(new Runnable() {
                 public void run() {
-                    if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+                    if (DBG) log(getName() + message.toString() + "\n");
                     mWakeLock.acquire();
                     if(WifiNative.unloadDriver()) {
-                        Log.d(TAG, "Driver unload successful");
+                        if (DBG) log("Driver unload successful");
                         sendMessage(CMD_UNLOAD_DRIVER_SUCCESS);
 
                         switch(message.arg1) {
@@ -2019,7 +2026,7 @@
                                 break;
                         }
                     } else {
-                        Log.e(TAG, "Failed to unload driver!");
+                        loge("Failed to unload driver!");
                         sendMessage(CMD_UNLOAD_DRIVER_FAILURE);
 
                         switch(message.arg1) {
@@ -2040,7 +2047,7 @@
 
         @Override
         public boolean processMessage(Message message) {
-            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+            if (DBG) log(getName() + message.toString() + "\n");
             switch (message.what) {
                 case CMD_UNLOAD_DRIVER_SUCCESS:
                     transitionTo(mDriverUnloadedState);
@@ -2076,12 +2083,12 @@
     class DriverUnloadedState extends State {
         @Override
         public void enter() {
-            if (DBG) Log.d(TAG, getName() + "\n");
+            if (DBG) log(getName() + "\n");
             EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
         }
         @Override
         public boolean processMessage(Message message) {
-            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+            if (DBG) log(getName() + message.toString() + "\n");
             switch (message.what) {
                 case CMD_LOAD_DRIVER:
                     mWifiP2pChannel.sendMessage(WIFI_ENABLE_PENDING);
@@ -2101,12 +2108,12 @@
     class DriverFailedState extends State {
         @Override
         public void enter() {
-            Log.e(TAG, getName() + "\n");
+            loge(getName() + "\n");
             EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
         }
         @Override
         public boolean processMessage(Message message) {
-            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+            if (DBG) log(getName() + message.toString() + "\n");
             return NOT_HANDLED;
         }
     }
@@ -2115,15 +2122,15 @@
     class SupplicantStartingState extends State {
         @Override
         public void enter() {
-            if (DBG) Log.d(TAG, getName() + "\n");
+            if (DBG) log(getName() + "\n");
             EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
         }
         @Override
         public boolean processMessage(Message message) {
-            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+            if (DBG) log(getName() + message.toString() + "\n");
             switch(message.what) {
                 case WifiMonitor.SUP_CONNECTION_EVENT:
-                    Log.d(TAG, "Supplicant connection established");
+                    if (DBG) log("Supplicant connection established");
                     setWifiState(WIFI_STATE_ENABLED);
                     mSupplicantRestartCount = 0;
                     /* Reset the supplicant state to indicate the supplicant
@@ -2144,12 +2151,12 @@
                     break;
                 case WifiMonitor.SUP_DISCONNECTION_EVENT:
                     if (++mSupplicantRestartCount <= SUPPLICANT_RESTART_TRIES) {
-                        Log.e(TAG, "Failed to setup control channel, restart supplicant");
+                        loge("Failed to setup control channel, restart supplicant");
                         WifiNative.killSupplicant();
                         transitionTo(mDriverLoadedState);
                         sendMessageDelayed(CMD_START_SUPPLICANT, SUPPLICANT_RESTART_INTERVAL_MSECS);
                     } else {
-                        Log.e(TAG, "Failed " + mSupplicantRestartCount +
+                        loge("Failed " + mSupplicantRestartCount +
                                 " times to start supplicant, unload driver");
                         mSupplicantRestartCount = 0;
                         transitionTo(mDriverLoadedState);
@@ -2184,7 +2191,7 @@
     class SupplicantStartedState extends State {
         @Override
         public void enter() {
-            if (DBG) Log.d(TAG, getName() + "\n");
+            if (DBG) log(getName() + "\n");
             EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
             /* Initialize for connect mode operation at start */
             mIsScanMode = false;
@@ -2198,7 +2205,7 @@
         }
         @Override
         public boolean processMessage(Message message) {
-            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+            if (DBG) log(getName() + message.toString() + "\n");
             WifiConfiguration config;
             boolean eventLoggingEnabled = true;
             switch(message.what) {
@@ -2206,7 +2213,7 @@
                     transitionTo(mSupplicantStoppingState);
                     break;
                 case WifiMonitor.SUP_DISCONNECTION_EVENT:  /* Supplicant connection lost */
-                    Log.e(TAG, "Connection lost, restart supplicant");
+                    loge("Connection lost, restart supplicant");
                     WifiNative.killSupplicant();
                     WifiNative.closeSupplicantConnection();
                     mNetworkInfo.setIsAvailable(false);
@@ -2270,7 +2277,7 @@
                     break;
                     /* Cannot start soft AP while in client mode */
                 case CMD_START_AP:
-                    Log.d(TAG, "Failed to start soft AP with a running supplicant");
+                    loge("Failed to start soft AP with a running supplicant");
                     setWifiApState(WIFI_AP_STATE_FAILED);
                     break;
                 case CMD_SET_SCAN_MODE:
@@ -2301,11 +2308,11 @@
     class SupplicantStoppingState extends State {
         @Override
         public void enter() {
-            if (DBG) Log.d(TAG, getName() + "\n");
+            if (DBG) log(getName() + "\n");
             EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
-            Log.d(TAG, "stopping supplicant");
+            if (DBG) log("stopping supplicant");
             if (!WifiNative.stopSupplicant()) {
-                Log.e(TAG, "Failed to stop supplicant");
+                loge("Failed to stop supplicant");
             }
 
             /* Send ourselves a delayed message to indicate failure after a wait time */
@@ -2321,13 +2328,13 @@
         }
         @Override
         public boolean processMessage(Message message) {
-            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+            if (DBG) log(getName() + message.toString() + "\n");
             switch(message.what) {
                 case WifiMonitor.SUP_CONNECTION_EVENT:
-                    Log.e(TAG, "Supplicant connection received while stopping");
+                    loge("Supplicant connection received while stopping");
                     break;
                 case WifiMonitor.SUP_DISCONNECTION_EVENT:
-                    Log.d(TAG, "Supplicant connection lost");
+                    if (DBG) log("Supplicant connection lost");
                     /* Socket connection can be lost when we do a graceful shutdown
                      * or when the driver is hung. Ensure supplicant is stopped here.
                      */
@@ -2337,7 +2344,7 @@
                     break;
                 case CMD_STOP_SUPPLICANT_FAILED:
                     if (message.arg1 == mSupplicantStopFailureToken) {
-                        Log.e(TAG, "Timed out on a supplicant stop, kill and proceed");
+                        loge("Timed out on a supplicant stop, kill and proceed");
                         WifiNative.killSupplicant();
                         WifiNative.closeSupplicantConnection();
                         transitionTo(mDriverLoadedState);
@@ -2371,12 +2378,12 @@
     class DriverStartingState extends State {
         @Override
         public void enter() {
-            if (DBG) Log.d(TAG, getName() + "\n");
+            if (DBG) log(getName() + "\n");
             EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
         }
         @Override
         public boolean processMessage(Message message) {
-            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+            if (DBG) log(getName() + message.toString() + "\n");
             switch(message.what) {
                case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
                     SupplicantState state = handleSupplicantStateChange(message);
@@ -2418,7 +2425,7 @@
     class DriverStartedState extends State {
         @Override
         public void enter() {
-            if (DBG) Log.d(TAG, getName() + "\n");
+            if (DBG) log(getName() + "\n");
             EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
 
             mIsRunning = true;
@@ -2459,7 +2466,7 @@
         }
         @Override
         public boolean processMessage(Message message) {
-            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+            if (DBG) log(getName() + message.toString() + "\n");
             boolean eventLoggingEnabled = true;
             switch(message.what) {
                 case CMD_SET_SCAN_TYPE:
@@ -2479,20 +2486,20 @@
                     break;
                 case CMD_SET_COUNTRY_CODE:
                     String country = (String) message.obj;
-                    Log.d(TAG, "set country code " + country);
+                    if (DBG) log("set country code " + country);
                     if (!WifiNative.setCountryCodeCommand(country.toUpperCase())) {
-                        Log.e(TAG, "Failed to set country code " + country);
+                        loge("Failed to set country code " + country);
                     }
                     break;
                 case CMD_SET_FREQUENCY_BAND:
                     int band =  message.arg1;
-                    Log.d(TAG, "set frequency band " + band);
+                    if (DBG) log("set frequency band " + band);
                     if (WifiNative.setBandCommand(band)) {
                         mFrequencyBand.set(band);
                         //Fetch the latest scan results when frequency band is set
                         startScan(true);
                     } else {
-                        Log.e(TAG, "Failed to set frequency band " + band);
+                        loge("Failed to set frequency band " + band);
                     }
                     break;
                 case CMD_BLUETOOTH_ADAPTER_STATE_CHANGE:
@@ -2512,7 +2519,7 @@
                     } else if (message.arg1 == MULTICAST_V4) {
                         WifiNative.startFilteringMulticastV4Packets();
                     } else {
-                        Log.e(TAG, "Illegal arugments to CMD_START_PACKET_FILTERING");
+                        loge("Illegal arugments to CMD_START_PACKET_FILTERING");
                     }
                     break;
                 case CMD_STOP_PACKET_FILTERING:
@@ -2521,7 +2528,7 @@
                     } else if (message.arg1 == MULTICAST_V4) {
                         WifiNative.stopFilteringMulticastV4Packets();
                     } else {
-                        Log.e(TAG, "Illegal arugments to CMD_STOP_PACKET_FILTERING");
+                        loge("Illegal arugments to CMD_STOP_PACKET_FILTERING");
                     }
                     break;
                 default:
@@ -2534,7 +2541,7 @@
         }
         @Override
         public void exit() {
-            if (DBG) Log.d(TAG, getName() + "\n");
+            if (DBG) log(getName() + "\n");
             mIsRunning = false;
             updateBatteryWorkSource(null);
             mScanResults = null;
@@ -2544,12 +2551,12 @@
     class DriverStoppingState extends State {
         @Override
         public void enter() {
-            if (DBG) Log.d(TAG, getName() + "\n");
+            if (DBG) log(getName() + "\n");
             EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
         }
         @Override
         public boolean processMessage(Message message) {
-            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+            if (DBG) log(getName() + message.toString() + "\n");
             switch(message.what) {
                 case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
                     SupplicantState state = handleSupplicantStateChange(message);
@@ -2583,12 +2590,12 @@
     class DriverStoppedState extends State {
         @Override
         public void enter() {
-            if (DBG) Log.d(TAG, getName() + "\n");
+            if (DBG) log(getName() + "\n");
             EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
         }
         @Override
         public boolean processMessage(Message message) {
-            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+            if (DBG) log(getName() + message.toString() + "\n");
             switch (message.what) {
                 case CMD_START_DRIVER:
                     mWakeLock.acquire();
@@ -2607,12 +2614,12 @@
     class ScanModeState extends State {
         @Override
         public void enter() {
-            if (DBG) Log.d(TAG, getName() + "\n");
+            if (DBG) log(getName() + "\n");
             EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
         }
         @Override
         public boolean processMessage(Message message) {
-            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+            if (DBG) log(getName() + message.toString() + "\n");
             switch(message.what) {
                 case CMD_SET_SCAN_MODE:
                     if (message.arg1 == SCAN_ONLY_MODE) {
@@ -2644,12 +2651,12 @@
     class ConnectModeState extends State {
         @Override
         public void enter() {
-            if (DBG) Log.d(TAG, getName() + "\n");
+            if (DBG) log(getName() + "\n");
             EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
         }
         @Override
         public boolean processMessage(Message message) {
-            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+            if (DBG) log(getName() + message.toString() + "\n");
             StateChangeResult stateChangeResult;
             switch(message.what) {
                 case WifiMonitor.AUTHENTICATION_FAILURE_EVENT:
@@ -2696,7 +2703,7 @@
                     mLastExplicitNetworkId = netId;
                     mLastNetworkChoiceTime  = SystemClock.elapsedRealtime();
                     mNextWifiActionExplicit = true;
-                    Slog.d(TAG, "Setting wifi connect explicit for netid " + netId);
+                    if (DBG) log("Setting wifi connect explicit for netid " + netId);
                     /* Expect a disconnection from the old connection */
                     transitionTo(mDisconnectingState);
                     break;
@@ -2710,7 +2717,7 @@
                     /* Handle scan results */
                     return NOT_HANDLED;
                 case WifiMonitor.NETWORK_CONNECTION_EVENT:
-                    Log.d(TAG,"Network connection established");
+                    if (DBG) log("Network connection established");
                     mLastNetworkId = message.arg1;
                     mLastBssid = (String) message.obj;
 
@@ -2731,7 +2738,7 @@
                     transitionTo(mConnectingState);
                     break;
                 case WifiMonitor.NETWORK_DISCONNECTION_EVENT:
-                    Log.d(TAG,"Network connection lost");
+                    if (DBG) log("Network connection lost");
                     handleNetworkDisconnect();
                     transitionTo(mDisconnectedState);
                     break;
@@ -2747,15 +2754,15 @@
 
         @Override
         public void enter() {
-            if (DBG) Log.d(TAG, getName() + "\n");
+            if (DBG) log(getName() + "\n");
             EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
 
             try {
                 mNwService.enableIpv6(mInterfaceName);
             } catch (RemoteException re) {
-                Log.e(TAG, "Failed to enable IPv6: " + re);
+                loge("Failed to enable IPv6: " + re);
             } catch (IllegalStateException e) {
-                Log.e(TAG, "Failed to enable IPv6: " + e);
+                loge("Failed to enable IPv6: " + e);
             }
 
             if (!WifiConfigStore.isUsingStaticIp(mLastNetworkId)) {
@@ -2772,20 +2779,20 @@
                 ifcg.interfaceFlags = "[up]";
                 try {
                     mNwService.setInterfaceConfig(mInterfaceName, ifcg);
-                    Log.v(TAG, "Static IP configuration succeeded");
+                    if (DBG) log("Static IP configuration succeeded");
                     sendMessage(CMD_STATIC_IP_SUCCESS, dhcpInfoInternal);
                 } catch (RemoteException re) {
-                    Log.v(TAG, "Static IP configuration failed: " + re);
+                    loge("Static IP configuration failed: " + re);
                     sendMessage(CMD_STATIC_IP_FAILURE);
                 } catch (IllegalStateException e) {
-                    Log.v(TAG, "Static IP configuration failed: " + e);
+                    loge("Static IP configuration failed: " + e);
                     sendMessage(CMD_STATIC_IP_FAILURE);
                 }
             }
         }
       @Override
       public boolean processMessage(Message message) {
-          if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+          if (DBG) log(getName() + message.toString() + "\n");
 
           switch(message.what) {
               case DhcpStateMachine.CMD_PRE_DHCP_ACTION:
@@ -2856,7 +2863,7 @@
     class ConnectedState extends State {
         @Override
         public void enter() {
-            if (DBG) Log.d(TAG, getName() + "\n");
+            if (DBG) log(getName() + "\n");
             EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
             mRssiPollToken++;
             if (mEnableRssiPolling) {
@@ -2865,7 +2872,7 @@
         }
         @Override
         public boolean processMessage(Message message) {
-            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+            if (DBG) log(getName() + message.toString() + "\n");
             boolean eventLoggingEnabled = true;
             switch (message.what) {
               case DhcpStateMachine.CMD_PRE_DHCP_ACTION:
@@ -2921,11 +2928,11 @@
                     NetworkUpdateResult result = WifiConfigStore.saveNetwork(config);
                     if (mWifiInfo.getNetworkId() == result.getNetworkId()) {
                         if (result.hasIpChanged()) {
-                            Log.d(TAG,"Reconfiguring IP on connection");
+                            log("Reconfiguring IP on connection");
                             transitionTo(mConnectingState);
                         }
                         if (result.hasProxyChanged()) {
-                            Log.d(TAG,"Reconfiguring proxy on connection");
+                            log("Reconfiguring proxy on connection");
                             configureLinkProperties();
                             sendLinkConfigurationChangedBroadcast();
                         }
@@ -2977,12 +2984,12 @@
     class DisconnectingState extends State {
         @Override
         public void enter() {
-            if (DBG) Log.d(TAG, getName() + "\n");
+            if (DBG) log(getName() + "\n");
             EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
         }
         @Override
         public boolean processMessage(Message message) {
-            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+            if (DBG) log(getName() + message.toString() + "\n");
             switch (message.what) {
                 case CMD_STOP_DRIVER: /* Stop driver only after disconnect handled */
                     deferMessage(message);
@@ -3029,7 +3036,7 @@
 
         @Override
         public void enter() {
-            if (DBG) Log.d(TAG, getName() + "\n");
+            if (DBG) log(getName() + "\n");
             EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
 
             mFrameworkScanIntervalMs = Settings.Secure.getLong(mContext.getContentResolver(),
@@ -3056,7 +3063,7 @@
         }
         @Override
         public boolean processMessage(Message message) {
-            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+            if (DBG) log(getName() + message.toString() + "\n");
             switch (message.what) {
                 case CMD_SET_SCAN_MODE:
                     if (message.arg1 == SCAN_ONLY_MODE) {
@@ -3119,12 +3126,12 @@
     class WaitForWpsCompletionState extends State {
         @Override
         public void enter() {
-            if (DBG) Log.d(TAG, getName() + "\n");
+            if (DBG) log(getName() + "\n");
             EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
         }
         @Override
         public boolean processMessage(Message message) {
-            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+            if (DBG) log(getName() + message.toString() + "\n");
             switch (message.what) {
                 /* Defer all commands that can cause connections to a different network
                  * or put the state machine out of connect mode
@@ -3139,7 +3146,7 @@
                     deferMessage(message);
                     break;
                 case WifiMonitor.NETWORK_DISCONNECTION_EVENT:
-                    Log.d(TAG,"Network connection lost");
+                    if (DBG) log("Network connection lost");
                     handleNetworkDisconnect();
                     break;
                 case WPS_COMPLETED_EVENT:
@@ -3158,7 +3165,7 @@
     class SoftApStartingState extends State {
         @Override
         public void enter() {
-            if (DBG) Log.d(TAG, getName() + "\n");
+            if (DBG) log(getName() + "\n");
             EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
 
             final Message message = Message.obtain(getCurrentMessage());
@@ -3168,10 +3175,10 @@
             new Thread(new Runnable() {
                 public void run() {
                     if (startSoftApWithConfig(config)) {
-                        Log.d(TAG, "Soft AP start successful");
+                        if (DBG) log("Soft AP start successful");
                         sendMessage(CMD_START_AP_SUCCESS);
                     } else {
-                        Log.d(TAG, "Soft AP start failed");
+                        loge("Soft AP start failed");
                         sendMessage(CMD_START_AP_FAILURE);
                     }
                 }
@@ -3179,7 +3186,7 @@
         }
         @Override
         public boolean processMessage(Message message) {
-            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+            if (DBG) log(getName() + message.toString() + "\n");
             switch(message.what) {
                 case CMD_LOAD_DRIVER:
                 case CMD_UNLOAD_DRIVER:
@@ -3219,21 +3226,21 @@
     class SoftApStartedState extends State {
         @Override
         public void enter() {
-            if (DBG) Log.d(TAG, getName() + "\n");
+            if (DBG) log(getName() + "\n");
             EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
         }
         @Override
         public boolean processMessage(Message message) {
-            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+            if (DBG) log(getName() + message.toString() + "\n");
             switch(message.what) {
                 case CMD_STOP_AP:
-                    Log.d(TAG,"Stopping Soft AP");
+                    if (DBG) log("Stopping Soft AP");
                     setWifiApState(WIFI_AP_STATE_DISABLING);
                     stopTethering();
                     try {
                         mNwService.stopAccessPoint(mInterfaceName);
                     } catch(Exception e) {
-                        Log.e(TAG, "Exception in stopAccessPoint()");
+                        loge("Exception in stopAccessPoint()");
                     }
                     transitionTo(mDriverLoadedState);
                     break;
@@ -3242,7 +3249,7 @@
                     break;
                     /* Fail client mode operation when soft AP is enabled */
                 case CMD_START_SUPPLICANT:
-                    Log.e(TAG,"Cannot start supplicant with a running soft AP");
+                   loge("Cannot start supplicant with a running soft AP");
                     setWifiState(WIFI_STATE_UNKNOWN);
                     break;
                 case CMD_TETHER_INTERFACE:
@@ -3268,7 +3275,7 @@
         private int mSavedArg;
         @Override
         public void enter() {
-            if (DBG) Log.d(TAG, getName() + "\n");
+            if (DBG) log(getName() + "\n");
             EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
 
             //Preserve the argument arg1 that has information used in DriverLoadingState
@@ -3276,7 +3283,7 @@
         }
         @Override
         public boolean processMessage(Message message) {
-            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+            if (DBG) log(getName() + message.toString() + "\n");
             switch(message.what) {
                 case WifiP2pService.WIFI_ENABLE_PROCEED:
                     //restore argument from original message (CMD_LOAD_DRIVER)
@@ -3311,12 +3318,12 @@
     class TetheredState extends State {
         @Override
         public void enter() {
-            if (DBG) Log.d(TAG, getName() + "\n");
+            if (DBG) log(getName() + "\n");
             EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
         }
         @Override
         public boolean processMessage(Message message) {
-            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+            if (DBG) log(getName() + message.toString() + "\n");
             switch(message.what) {
                case CMD_TETHER_INTERFACE:
                     // Ignore any duplicate interface available notifications
@@ -3327,4 +3334,12 @@
             }
         }
     }
+
+    private void log(String s) {
+        Log.d(TAG, s);
+    }
+
+    private void loge(String s) {
+        Log.e(TAG, s);
+    }
 }
diff --git a/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java b/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
index af8c486..5d5b9ef 100644
--- a/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
@@ -35,7 +35,6 @@
 import android.os.SystemProperties;
 import android.provider.Settings;
 import android.provider.Settings.Secure;
-import android.util.Slog;
 import android.util.Log;
 
 import com.android.internal.util.Protocol;
@@ -67,10 +66,8 @@
  */
 public class WifiWatchdogStateMachine extends StateMachine {
 
-
-    private static final boolean VDBG = false;
-    private static final boolean DBG = true;
-    private static final String WWSM_TAG = "WifiWatchdogStateMachine";
+    private static final boolean DBG = false;
+    private static final String TAG = "WifiWatchdogStateMachine";
     private static final String WATCHDOG_NOTIFICATION_ID = "Android.System.WifiWatchdog";
 
     private static final int WIFI_SIGNAL_LEVELS = 4;
@@ -192,7 +189,7 @@
      *               (all other states)
      */
     private WifiWatchdogStateMachine(Context context) {
-        super(WWSM_TAG);
+        super(TAG);
         mContext = context;
         mContentResolver = context.getContentResolver();
         mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
@@ -351,7 +348,7 @@
             return urlConnection.getResponseCode() != 204;
         } catch (IOException e) {
             if (DBG) {
-                Slog.d(WWSM_TAG, "Walled garden check - probably not a portal: exception ", e);
+                log("Walled garden check - probably not a portal: exception " + e);
             }
             return false;
         } finally {
@@ -443,7 +440,7 @@
 
         if (results == null) {
             if (DBG) {
-                Slog.d(WWSM_TAG, "updateBssids: Got null scan results!");
+                log("updateBssids: Got null scan results!");
             }
             return;
         }
@@ -451,7 +448,7 @@
         for (ScanResult result : results) {
             if (result == null || result.SSID == null) {
                 if (DBG) {
-                    Slog.d(WWSM_TAG, "Received invalid scan result: " + result);
+                    log("Received invalid scan result: " + result);
                 }
                 continue;
             }
@@ -461,8 +458,8 @@
     }
 
     private void resetWatchdogState() {
-        if (VDBG) {
-            Slog.v(WWSM_TAG, "Resetting watchdog state...");
+        if (DBG) {
+            log("Resetting watchdog state...");
         }
         mConnectionInfo = null;
         mDisableAPNextFailure = false;
@@ -522,13 +519,13 @@
             switch (msg.what) {
                 case EVENT_WATCHDOG_SETTINGS_CHANGE:
                     updateSettings();
-                    if (VDBG) {
-                        Slog.d(WWSM_TAG, "Updating wifi-watchdog secure settings");
+                    if (DBG) {
+                        log("Updating wifi-watchdog secure settings");
                     }
                     return HANDLED;
             }
-            if (VDBG) {
-                Slog.v(WWSM_TAG, "Caught message " + msg.what + " in state " +
+            if (DBG) {
+                log("Caught message " + msg.what + " in state " +
                         getCurrentState().getName());
             }
             return HANDLED;
@@ -553,7 +550,7 @@
         public void enter() {
             resetWatchdogState();
             mContext.registerReceiver(mBroadcastReceiver, mIntentFilter);
-            Slog.i(WWSM_TAG, "WifiWatchdogService enabled");
+            if (DBG) log("WifiWatchdogService enabled");
         }
 
         @Override
@@ -574,12 +571,12 @@
                             WifiInfo wifiInfo = (WifiInfo)
                                 stateChangeIntent.getParcelableExtra(WifiManager.EXTRA_WIFI_INFO);
                             if (wifiInfo == null) {
-                                Slog.e(WWSM_TAG, "Connected --> WifiInfo object null!");
+                                loge("Connected --> WifiInfo object null!");
                                 return HANDLED;
                             }
 
                             if (wifiInfo.getSSID() == null || wifiInfo.getBSSID() == null) {
-                                Slog.e(WWSM_TAG, "Received wifiInfo object with null elts: "
+                                loge("Received wifiInfo object with null elts: "
                                         + wifiInfoToStr(wifiInfo));
                                 return HANDLED;
                             }
@@ -598,7 +595,7 @@
                     return HANDLED;
                 case EVENT_WIFI_RADIO_STATE_CHANGE:
                     if ((Integer) msg.obj == WifiManager.WIFI_STATE_DISABLING) {
-                        Slog.i(WWSM_TAG, "WifiStateDisabling -- Resetting WatchdogState");
+                        if (DBG) log("WifiStateDisabling -- Resetting WatchdogState");
                         resetWatchdogState();
                         mNetEventCounter++;
                         transitionTo(mNotConnectedState);
@@ -613,8 +610,8 @@
          * @param wifiInfo Info object with non-null ssid and bssid
          */
         private void initConnection(WifiInfo wifiInfo) {
-            if (VDBG) {
-                Slog.v(WWSM_TAG, "Connected:: old " + wifiInfoToStr(mConnectionInfo) +
+            if (DBG) {
+                log("Connected:: old " + wifiInfoToStr(mConnectionInfo) +
                         " ==> new " + wifiInfoToStr(wifiInfo));
             }
 
@@ -628,7 +625,7 @@
         @Override
         public void exit() {
             mContext.unregisterReceiver(mBroadcastReceiver);
-            Slog.i(WWSM_TAG, "WifiWatchdogService disabled");
+            if (DBG) log("WifiWatchdogService disabled");
         }
     }
 
@@ -671,7 +668,7 @@
             if (DBG) {
                 dnsCheckLogStr = String.format("Pinging %s on ssid [%s]: ",
                         mDnsList, mConnectionInfo.getSSID());
-                Slog.d(WWSM_TAG, dnsCheckLogStr);
+                log(dnsCheckLogStr);
             }
 
             idDnsMap.clear();
@@ -694,7 +691,7 @@
 
             Integer dnsServerId = idDnsMap.get(pingID);
             if (dnsServerId == null) {
-                Slog.w(WWSM_TAG, "Received a Dns response with unknown ID!");
+                loge("Received a Dns response with unknown ID!");
                 return HANDLED;
             }
 
@@ -722,7 +719,7 @@
             if (dnsCheckSuccesses[dnsServerId] >= mMinDnsResponses) {
                 // DNS CHECKS OK, NOW WALLED GARDEN
                 if (DBG) {
-                    Slog.d(WWSM_TAG, makeLogString() + "  SUCCESS");
+                    log(makeLogString() + "  SUCCESS");
                 }
 
                 if (!shouldCheckWalledGarden()) {
@@ -732,13 +729,10 @@
 
                 mLastWalledGardenCheckTime = SystemClock.elapsedRealtime();
                 if (isWalledGardenConnection()) {
-                    if (DBG)
-                        Slog.d(WWSM_TAG,
-                                "Walled garden test complete - walled garden detected");
+                    if (DBG) log("Walled garden test complete - walled garden detected");
                     transitionTo(mWalledGardenState);
                 } else {
-                    if (DBG)
-                        Slog.d(WWSM_TAG, "Walled garden test complete - online");
+                    if (DBG) log("Walled garden test complete - online");
                     transitionTo(mOnlineWatchState);
                 }
                 return HANDLED;
@@ -746,7 +740,7 @@
 
             if (idDnsMap.isEmpty()) {
                 if (DBG) {
-                    Slog.d(WWSM_TAG, makeLogString() + "  FAILURE");
+                    log(makeLogString() + "  FAILURE");
                 }
                 transitionTo(mDnsCheckFailureState);
                 return HANDLED;
@@ -769,15 +763,15 @@
 
         private boolean shouldCheckWalledGarden() {
             if (!mWalledGardenTestEnabled) {
-                if (VDBG)
-                    Slog.v(WWSM_TAG, "Skipping walled garden check - disabled");
+                if (DBG)
+                    log("Skipping walled garden check - disabled");
                 return false;
             }
             long waitTime = waitTime(mWalledGardenIntervalMs,
                     mLastWalledGardenCheckTime);
             if (waitTime > 0) {
                 if (DBG) {
-                    Slog.d(WWSM_TAG, "Skipping walled garden check - wait " +
+                    log("Skipping walled garden check - wait " +
                             waitTime + " ms.");
                 }
                 return false;
@@ -825,28 +819,28 @@
                 case EVENT_RSSI_CHANGE:
                     if (msg.arg1 != mNetEventCounter) {
                         if (DBG) {
-                            Slog.d(WWSM_TAG, "Rssi change message out of sync, ignoring");
+                            log("Rssi change message out of sync, ignoring");
                         }
                         return HANDLED;
                     }
                     int newRssi = msg.arg2;
                     signalUnstable = !rssiStrengthAboveCutoff(newRssi);
-                    if (VDBG) {
-                        Slog.v(WWSM_TAG, "OnlineWatchState:: new rssi " + newRssi + " --> level " +
+                    if (DBG) {
+                        log("OnlineWatchState:: new rssi " + newRssi + " --> level " +
                                 WifiManager.calculateSignalLevel(newRssi, WIFI_SIGNAL_LEVELS));
                     }
 
                     if (signalUnstable && !unstableSignalChecks) {
-                        if (VDBG) {
-                            Slog.v(WWSM_TAG, "Sending triggered check msg");
+                        if (DBG) {
+                            log("Sending triggered check msg");
                         }
                         triggerSingleDnsCheck();
                     }
                     return HANDLED;
                 case MESSAGE_SINGLE_DNS_CHECK:
                     if (msg.arg1 != checkGuard) {
-                        if (VDBG) {
-                            Slog.v(WWSM_TAG, "Single check msg out of sync, ignoring.");
+                        if (DBG) {
+                            log("Single check msg out of sync, ignoring.");
                         }
                         return HANDLED;
                     }
@@ -865,8 +859,8 @@
                     pingInfoMap.remove(msg.arg1);
                     int responseTime = msg.arg2;
                     if (responseTime >= 0) {
-                        if (VDBG) {
-                            Slog.v(WWSM_TAG, "Single DNS ping OK. Response time: "
+                        if (DBG) {
+                            log("Single DNS ping OK. Response time: "
                                     + responseTime + " from DNS " + curDnsServer);
                         }
                         pingInfoMap.clear();
@@ -877,7 +871,7 @@
                     } else {
                         if (pingInfoMap.isEmpty()) {
                             if (DBG) {
-                                Slog.d(WWSM_TAG, "Single dns ping failure. All dns servers failed, "
+                                log("Single dns ping failure. All dns servers failed, "
                                         + "starting full checks.");
                             }
                             transitionTo(mDnsCheckingState);
@@ -924,8 +918,8 @@
             }
 
             if (msg.arg1 != mNetEventCounter) {
-                if (VDBG) {
-                    Slog.v(WWSM_TAG, "Msg out of sync, ignoring...");
+                if (DBG) {
+                    log("Msg out of sync, ignoring...");
                 }
                 return HANDLED;
             }
@@ -933,7 +927,7 @@
             if (mDisableAPNextFailure || mNumCheckFailures >= mBssids.size()
                     || mNumCheckFailures >= mMaxSsidBlacklists) {
                 if (sWifiOnly) {
-                    Slog.w(WWSM_TAG, "Would disable bad network, but device has no mobile data!" +
+                    log("Would disable bad network, but device has no mobile data!" +
                             "  Going idle...");
                     // This state should be called idle -- will be changing flow.
                     transitionTo(mNotConnectedState);
@@ -941,7 +935,7 @@
                 }
 
                 // TODO : Unban networks if they had low signal ?
-                Slog.i(WWSM_TAG, "Disabling current SSID " + wifiInfoToStr(mConnectionInfo)
+                log("Disabling current SSID " + wifiInfoToStr(mConnectionInfo)
                         + ".  " + "numCheckFailures " + mNumCheckFailures
                         + ", numAPs " + mBssids.size());
                 int networkId = mConnectionInfo.getNetworkId();
@@ -955,7 +949,7 @@
                 }
                 transitionTo(mNotConnectedState);
             } else {
-                Slog.i(WWSM_TAG, "Blacklisting current BSSID.  " + wifiInfoToStr(mConnectionInfo)
+                log("Blacklisting current BSSID.  " + wifiInfoToStr(mConnectionInfo)
                        + "numCheckFailures " + mNumCheckFailures + ", numAPs " + mBssids.size());
 
                 mWifiManager.addToBlacklist(mConnectionInfo.getBSSID());
@@ -979,8 +973,8 @@
             }
 
             if (msg.arg1 != mNetEventCounter) {
-                if (VDBG) {
-                    Slog.v(WWSM_TAG, "WalledGardenState::Msg out of sync, ignoring...");
+                if (DBG) {
+                    log("WalledGardenState::Msg out of sync, ignoring...");
                 }
                 return HANDLED;
             }
@@ -1005,8 +999,8 @@
             }
 
             if (msg.arg1 != mNetEventCounter) {
-                if (VDBG) {
-                    Slog.v(WWSM_TAG, "BlacklistedApState::Msg out of sync, ignoring...");
+                if (DBG) {
+                    log("BlacklistedApState::Msg out of sync, ignoring...");
                 }
                 return HANDLED;
             }
@@ -1067,5 +1061,11 @@
         return Settings.Secure.putInt(cr, name, value ? 1 : 0);
     }
 
+    private void log(String s) {
+        Log.d(TAG, s);
+    }
 
+    private void loge(String s) {
+        Log.e(TAG, s);
+    }
 }