Merge "Rename LargeBitmap to BitmapRegionDecoder for having a better API." into gingerbread
diff --git a/api/current.xml b/api/current.xml
index 8ed7d93..b4fc949 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -15838,6 +15838,50 @@
  visibility="public"
 >
 </field>
+<field name="TextAppearance_StatusBar_EventContent"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16973927"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TextAppearance_StatusBar_EventContent_Title"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16973928"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TextAppearance_StatusBar_Icon"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16973926"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TextAppearance_StatusBar_Title"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16973925"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="TextAppearance_Theme"
  type="int"
  transient="false"
@@ -17059,50 +17103,6 @@
  visibility="public"
 >
 </field>
-<field name="kraken_resource_pad41"
- type="int"
- transient="false"
- volatile="false"
- value="16973928"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="kraken_resource_pad42"
- type="int"
- transient="false"
- volatile="false"
- value="16973927"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="kraken_resource_pad43"
- type="int"
- transient="false"
- volatile="false"
- value="16973926"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="kraken_resource_pad44"
- type="int"
- transient="false"
- volatile="false"
- value="16973925"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
 <field name="kraken_resource_pad5"
  type="int"
  transient="false"
diff --git a/cmds/installd/commands.c b/cmds/installd/commands.c
index 2e87394..f6f80d1 100644
--- a/cmds/installd/commands.c
+++ b/cmds/installd/commands.c
@@ -136,7 +136,7 @@
 /* TODO(oam): depending on use case (ecryptfs or dmcrypt)
  * change implementation
  */
-static int disk_free()
+static int64_t disk_free()
 {
     struct statfs sfs;
     if (statfs(PKG_DIR_PREFIX, &sfs) == 0) {
@@ -154,18 +154,18 @@
  * also require that apps constantly modify file metadata even
  * when just reading from the cache, which is pretty awful.
  */
-int free_cache(int free_size)
+int free_cache(int64_t free_size)
 {
     const char *name;
     int dfd, subfd;
     DIR *d;
     struct dirent *de;
-    int avail;
+    int64_t avail;
 
     avail = disk_free();
     if (avail < 0) return -1;
 
-    LOGI("free_cache(%d) avail %d\n", free_size, avail);
+    LOGI("free_cache(%" PRId64 ") avail %" PRId64 "\n", free_size, avail);
     if (avail >= free_size) return 0;
 
     /* First try encrypted dir */
@@ -327,10 +327,10 @@
     return 0;
 }
 
-static int stat_size(struct stat *s)
+static int64_t stat_size(struct stat *s)
 {
-    int blksize = s->st_blksize;
-    int size = s->st_size;
+    int64_t blksize = s->st_blksize;
+    int64_t size = s->st_size;
 
     if (blksize) {
             /* round up to filesystem block size */
@@ -340,9 +340,9 @@
     return size;
 }
 
-static int calculate_dir_size(int dfd)
+static int64_t calculate_dir_size(int dfd)
 {
-    int size = 0;
+    int64_t size = 0;
     struct stat s;
     DIR *d;
     struct dirent *de;
@@ -378,7 +378,7 @@
 
 int get_size(const char *pkgname, const char *apkpath,
              const char *fwdlock_apkpath,
-             int *_codesize, int *_datasize, int *_cachesize, int encrypted_fs_flag)
+             int64_t *_codesize, int64_t *_datasize, int64_t *_cachesize, int encrypted_fs_flag)
 {
     DIR *d;
     int dfd;
@@ -386,9 +386,9 @@
     struct stat s;
     char path[PKG_PATH_MAX];
 
-    int codesize = 0;
-    int datasize = 0;
-    int cachesize = 0;
+    int64_t codesize = 0;
+    int64_t datasize = 0;
+    int64_t cachesize = 0;
 
         /* count the source apk as code -- but only if it's not
          * on the /system partition and its not on the sdcard.
@@ -445,7 +445,7 @@
             }
             subfd = openat(dfd, name, O_RDONLY | O_DIRECTORY);
             if (subfd >= 0) {
-                int size = calculate_dir_size(subfd);
+                int64_t size = calculate_dir_size(subfd);
                 if (!strcmp(name,"lib")) {
                     codesize += size;
                 } else if(!strcmp(name,"cache")) {
diff --git a/cmds/installd/installd.c b/cmds/installd/installd.c
index 882c493..c991845 100644
--- a/cmds/installd/installd.c
+++ b/cmds/installd/installd.c
@@ -60,7 +60,7 @@
 
 static int do_free_cache(char **arg, char reply[REPLY_MAX]) /* TODO int:free_size */
 {
-    return free_cache(atoi(arg[0])); /* free_size */
+    return free_cache((int64_t)atoll(arg[0])); /* free_size */
 }
 
 static int do_rm_cache(char **arg, char reply[REPLY_MAX])
@@ -75,15 +75,19 @@
 
 static int do_get_size(char **arg, char reply[REPLY_MAX])
 {
-    int codesize = 0;
-    int datasize = 0;
-    int cachesize = 0;
+    int64_t codesize = 0;
+    int64_t datasize = 0;
+    int64_t cachesize = 0;
     int res = 0;
 
         /* pkgdir, apkpath */
     res = get_size(arg[0], arg[1], arg[2], &codesize, &datasize, &cachesize, atoi(arg[3]));
 
-    sprintf(reply,"%d %d %d", codesize, datasize, cachesize);
+    /*
+     * Each int64_t can take up 22 characters printed out. Make sure it
+     * doesn't go over REPLY_MAX in the future.
+     */
+    snprintf(reply, REPLY_MAX, "%" PRId64 " %" PRId64 " %" PRId64, codesize, datasize, cachesize);
     return res;
 }
 
diff --git a/cmds/installd/installd.h b/cmds/installd/installd.h
index 8e4adb1..479e4b2 100644
--- a/cmds/installd/installd.h
+++ b/cmds/installd/installd.h
@@ -19,6 +19,8 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <stdint.h>
+#include <inttypes.h>
 #include <sys/stat.h>
 #include <dirent.h>
 #include <unistd.h>
@@ -105,7 +107,7 @@
 int rm_dex(const char *path);
 int protect(char *pkgname, gid_t gid);
 int get_size(const char *pkgname, const char *apkpath, const char *fwdlock_apkpath,
-             int *codesize, int *datasize, int *cachesize, int encrypted_fs_flag);
-int free_cache(int free_size);
+             int64_t *codesize, int64_t *datasize, int64_t *cachesize, int encrypted_fs_flag);
+int free_cache(int64_t free_size);
 int dexopt(const char *apk_path, uid_t uid, int is_public);
 int movefiles();
diff --git a/core/java/android/app/NativeActivity.java b/core/java/android/app/NativeActivity.java
index 4dc88b3..d7a0412 100644
--- a/core/java/android/app/NativeActivity.java
+++ b/core/java/android/app/NativeActivity.java
@@ -3,8 +3,6 @@
 import com.android.internal.view.IInputMethodCallback;
 import com.android.internal.view.IInputMethodSession;
 
-import dalvik.system.PathClassLoader;
-
 import android.content.Context;
 import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
@@ -168,17 +166,14 @@
             // If the application does not have (Java) code, then no ClassLoader
             // has been set up for it.  We will need to do our own search for
             // the native code.
-            path = ai.applicationInfo.dataDir + "/lib/" + System.mapLibraryName(libname);
-            if (!(new File(path)).exists()) {
-                path = null;
+            File libraryFile = new File(ai.applicationInfo.nativeLibraryDir,
+                    System.mapLibraryName(libname));
+            if (libraryFile.exists()) {
+                path = libraryFile.getPath();
             }
         }
         
         if (path == null) {
-            path = ((PathClassLoader)getClassLoader()).findLibrary(libname);
-        }
-        
-        if (path == null) {
             throw new IllegalArgumentException("Unable to find native library: " + libname);
         }
         
diff --git a/core/java/android/app/backup/SharedPreferencesBackupHelper.java b/core/java/android/app/backup/SharedPreferencesBackupHelper.java
index 23b1703..213bd31 100644
--- a/core/java/android/app/backup/SharedPreferencesBackupHelper.java
+++ b/core/java/android/app/backup/SharedPreferencesBackupHelper.java
@@ -16,6 +16,7 @@
 
 package android.app.backup;
 
+import android.app.QueuedWork;
 import android.content.Context;
 import android.content.SharedPreferences;
 import android.os.ParcelFileDescriptor;
@@ -94,7 +95,11 @@
     public void performBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
             ParcelFileDescriptor newState) {
         Context context = mContext;
-        
+
+        // If a SharedPreference has an outstanding write in flight,
+        // wait for it to finish flushing to disk.
+        QueuedWork.waitToFinish();
+
         // make filenames for the prefGroups
         String[] prefGroups = mPrefGroups;
         final int N = prefGroups.length;
@@ -123,4 +128,3 @@
         }
     }
 }
-
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 9fe6e01..a857e58 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -216,6 +216,11 @@
         public abstract Map<Integer, ? extends Sensor> getSensorStats();
 
         /**
+         * Returns a mapping containing active process data.
+         */
+        public abstract SparseArray<? extends Pid> getPidStats();
+        
+        /**
          * Returns a mapping containing process statistics.
          *
          * @return a Map from Strings to Uid.Proc objects.
@@ -286,6 +291,11 @@
             public abstract Timer getSensorTime();
         }
 
+        public class Pid {
+            public long mWakeSum;
+            public long mWakeStart;
+        }
+
         /**
          * The statistics associated with a particular process.
          */
@@ -521,6 +531,11 @@
     public abstract HistoryItem getHistory();
     
     /**
+     * Return the base time offset for the battery history.
+     */
+    public abstract long getHistoryBaseTime();
+    
+    /**
      * Returns the number of times the device has been started.
      */
     public abstract int getStartCount();
@@ -1673,6 +1688,7 @@
         HistoryItem rec = getHistory();
         if (rec != null) {
             pw.println("Battery History:");
+            long now = getHistoryBaseTime() + SystemClock.elapsedRealtime();
             int oldState = 0;
             int oldStatus = -1;
             int oldHealth = -1;
@@ -1681,7 +1697,7 @@
             int oldVolt = -1;
             while (rec != null) {
                 pw.print("  ");
-                pw.print(rec.time);
+                TimeUtils.formatDuration(rec.time-now, pw, TimeUtils.HUNDRED_DAY_FIELD_LEN);
                 pw.print(" ");
                 if (rec.cmd == HistoryItem.CMD_START) {
                     pw.println(" START");
@@ -1784,6 +1800,35 @@
                 oldState = rec.states;
                 rec = rec.next;
             }
+            pw.println("");
+        }
+        
+        SparseArray<? extends Uid> uidStats = getUidStats();
+        final int NU = uidStats.size();
+        boolean didPid = false;
+        long nowRealtime = SystemClock.elapsedRealtime();
+        StringBuilder sb = new StringBuilder(64);
+        for (int i=0; i<NU; i++) {
+            Uid uid = uidStats.valueAt(i);
+            SparseArray<? extends Uid.Pid> pids = uid.getPidStats();
+            if (pids != null) {
+                for (int j=0; j<pids.size(); j++) {
+                    Uid.Pid pid = pids.valueAt(j);
+                    if (!didPid) {
+                        pw.println("Per-PID Stats:");
+                        didPid = true;
+                    }
+                    long time = pid.mWakeSum + (pid.mWakeStart != 0
+                            ? (nowRealtime - pid.mWakeStart) : 0);
+                    pw.print("  PID "); pw.print(pids.keyAt(j));
+                            pw.print(" wake time: ");
+                            TimeUtils.formatDuration(time, pw);
+                            pw.println("");
+                }
+            }
+        }
+        if (didPid) {
+            pw.println("");
         }
         
         pw.println("Statistics since last charge:");
diff --git a/core/java/android/util/TimeUtils.java b/core/java/android/util/TimeUtils.java
index b01a71d..60ca384 100644
--- a/core/java/android/util/TimeUtils.java
+++ b/core/java/android/util/TimeUtils.java
@@ -132,20 +132,76 @@
         return ZoneInfoDB.getVersion();
     }
 
+    /** @hide Field length that can hold 999 days of time */
+    public static final int HUNDRED_DAY_FIELD_LEN = 19;
+    
     private static final int SECONDS_PER_MINUTE = 60;
     private static final int SECONDS_PER_HOUR = 60 * 60;
     private static final int SECONDS_PER_DAY = 24 * 60 * 60;
 
-    /** @hide Just for debugging; not internationalized. */
-    public static void formatDuration(long duration, StringBuilder builder) {
-        if (duration == 0) {
-            builder.append("0");
-            return;
+    private static final Object sFormatSync = new Object();
+    private static char[] sFormatStr = new char[HUNDRED_DAY_FIELD_LEN+5];
+    
+    static private int accumField(int amt, int suffix, boolean always, int zeropad) {
+        if (amt > 99 || (always && zeropad >= 3)) {
+            return 3+suffix;
         }
+        if (amt > 9 || (always && zeropad >= 2)) {
+            return 2+suffix;
+        }
+        if (always || amt > 0) {
+            return 1+suffix;
+        }
+        return 0;
+    }
+    
+    static private int printField(char[] formatStr, int amt, char suffix, int pos,
+            boolean always, int zeropad) {
+        if (always || amt > 0) {
+            if ((always && zeropad >= 3) || amt > 99) {
+                int dig = amt/100;
+                formatStr[pos] = (char)(dig + '0');
+                pos++;
+                always = true;
+                amt -= (dig*100);
+            }
+            if ((always && zeropad >= 2) || amt > 9) {
+                int dig = amt/10;
+                formatStr[pos] = (char)(dig + '0');
+                pos++;
+                always = true;
+                amt -= (dig*10);
+            }
+            formatStr[pos] = (char)(amt + '0');
+            pos++;
+            formatStr[pos] = suffix;
+            pos++;
+        }
+        return pos;
+    }
+    
+    private static int formatDurationLocked(long duration, int fieldLen) {
+        if (sFormatStr.length < fieldLen) {
+            sFormatStr = new char[fieldLen];
+        }
+        
+        char[] formatStr = sFormatStr;
+        
+        if (duration == 0) {
+            int pos = 0;
+            fieldLen -= 1;
+            while (pos < fieldLen) {
+                formatStr[pos] = ' ';
+            }
+            formatStr[pos] = '0';
+            return pos+1;
+        }
+        
+        char prefix;
         if (duration > 0) {
-            builder.append("+");
+            prefix = '+';
         } else {
-            builder.append("-");
+            prefix = '-';
             duration = -duration;
         }
 
@@ -166,93 +222,62 @@
             seconds -= minutes * SECONDS_PER_MINUTE;
         }
 
-        boolean doall = false;
-        if (days > 0) {
-            builder.append(days);
-            builder.append('d');
-            doall = true;
+        int pos = 0;
+        
+        if (fieldLen != 0) {
+            int myLen = accumField(days, 1, false, 0);
+            myLen += accumField(hours, 1, myLen > 0, 2);
+            myLen += accumField(minutes, 1, myLen > 0, 2);
+            myLen += accumField(seconds, 1, myLen > 0, 2);
+            myLen += accumField(millis, 2, true, myLen > 0 ? 3 : 0) + 1;
+            while (myLen < fieldLen) {
+                formatStr[pos] = ' ';
+                pos++;
+                myLen++;
+            }
         }
-        if (doall || hours > 0) {
-            builder.append(hours);
-            builder.append('h');
-            doall = true;
+        
+        formatStr[pos] = prefix;
+        pos++;
+        
+        int start = pos;
+        boolean zeropad = fieldLen != 0;
+        pos = printField(formatStr, days, 'd', pos, false, 0);
+        pos = printField(formatStr, hours, 'h', pos, pos != start, zeropad ? 2 : 0);
+        pos = printField(formatStr, minutes, 'm', pos, pos != start, zeropad ? 2 : 0);
+        pos = printField(formatStr, seconds, 's', pos, pos != start, zeropad ? 2 : 0);
+        pos = printField(formatStr, millis, 'm', pos, true, (zeropad && pos != start) ? 3 : 0);
+        formatStr[pos] = 's';
+        return pos + 1;
+    }
+    
+    /** @hide Just for debugging; not internationalized. */
+    public static void formatDuration(long duration, StringBuilder builder) {
+        synchronized (sFormatSync) {
+            int len = formatDurationLocked(duration, 0);
+            builder.append(sFormatStr, 0, len);
         }
-        if (doall || minutes > 0) {
-            builder.append(minutes);
-            builder.append('m');
-            doall = true;
+    }
+
+    /** @hide Just for debugging; not internationalized. */
+    public static void formatDuration(long duration, PrintWriter pw, int fieldLen) {
+        synchronized (sFormatSync) {
+            int len = formatDurationLocked(duration, fieldLen);
+            pw.print(new String(sFormatStr, 0, len));
         }
-        if (doall || seconds > 0) {
-            builder.append(seconds);
-            builder.append('s');
-            doall = true;
-        }
-        builder.append(millis);
-        builder.append("ms");
     }
 
     /** @hide Just for debugging; not internationalized. */
     public static void formatDuration(long duration, PrintWriter pw) {
-        if (duration == 0) {
-            pw.print("0");
-            return;
-        }
-        if (duration > 0) {
-            pw.print("+");
-        } else {
-            pw.print("-");
-            duration = -duration;
-        }
-
-        int millis = (int)(duration%1000);
-        int seconds = (int) Math.floor(duration / 1000);
-        int days = 0, hours = 0, minutes = 0;
-
-        if (seconds > SECONDS_PER_DAY) {
-            days = seconds / SECONDS_PER_DAY;
-            seconds -= days * SECONDS_PER_DAY;
-        }
-        if (seconds > SECONDS_PER_HOUR) {
-            hours = seconds / SECONDS_PER_HOUR;
-            seconds -= hours * SECONDS_PER_HOUR;
-        }
-        if (seconds > SECONDS_PER_MINUTE) {
-            minutes = seconds / SECONDS_PER_MINUTE;
-            seconds -= minutes * SECONDS_PER_MINUTE;
-        }
-
-        boolean doall = false;
-        if (days > 0) {
-            pw.print(days);
-            pw.print('d');
-            doall = true;
-        }
-        if (doall || hours > 0) {
-            pw.print(hours);
-            pw.print('h');
-            doall = true;
-        }
-        if (doall || minutes > 0) {
-            pw.print(minutes);
-            pw.print('m');
-            doall = true;
-        }
-        if (doall || seconds > 0) {
-            pw.print(seconds);
-            pw.print('s');
-            doall = true;
-        }
-        pw.print(millis);
-        pw.print("ms");
+        formatDuration(duration, pw, 0);
     }
-
-
+    
     /** @hide Just for debugging; not internationalized. */
     public static void formatDuration(long time, long now, PrintWriter pw) {
         if (time == 0) {
             pw.print("--");
             return;
         }
-        formatDuration(time-now, pw);
+        formatDuration(time-now, pw, 0);
     }
 }
diff --git a/core/java/android/widget/QuickContactBadge.java b/core/java/android/widget/QuickContactBadge.java
index 07c3e4b..4bbb540 100644
--- a/core/java/android/widget/QuickContactBadge.java
+++ b/core/java/android/widget/QuickContactBadge.java
@@ -236,6 +236,7 @@
                         trigger = true;
                         createUri = Uri.fromParts("tel", (String)cookie, null);
 
+                        //$FALL-THROUGH$
                     case TOKEN_PHONE_LOOKUP: {
                         if (cursor != null && cursor.moveToFirst()) {
                             long contactId = cursor.getLong(PHONE_ID_COLUMN_INDEX);
@@ -249,12 +250,14 @@
                         trigger = true;
                         createUri = Uri.fromParts("mailto", (String)cookie, null);
 
+                        //$FALL-THROUGH$
                     case TOKEN_EMAIL_LOOKUP: {
                         if (cursor != null && cursor.moveToFirst()) {
                             long contactId = cursor.getLong(EMAIL_ID_COLUMN_INDEX);
                             String lookupKey = cursor.getString(EMAIL_LOOKUP_STRING_COLUMN_INDEX);
                             lookupUri = Contacts.getLookupUri(contactId, lookupKey);
                         }
+                        break;
                     }
 
                     case TOKEN_CONTACT_LOOKUP_AND_TRIGGER: {
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index f4447ab..566ed29 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -3343,11 +3343,6 @@
             }
         }
 
-        public class Pid {
-            long mWakeSum;
-            long mWakeStart;
-        }
-
         /**
          * Retrieve the statistics object for a particular process, creating
          * if needed.
@@ -3362,6 +3357,10 @@
             return ps;
         }
 
+        public SparseArray<? extends Pid> getPidStats() {
+            return mPids;
+        }
+        
         public Pid getPidStatsLocked(int pid) {
             Pid p = mPids.get(pid);
             if (p == null) {
@@ -3586,6 +3585,11 @@
     }
     
     @Override
+    public long getHistoryBaseTime() {
+        return mHistoryBaseTime;
+    }
+    
+    @Override
     public int getStartCount() {
         return mStartCount;
     }
diff --git a/core/jni/android_app_NativeActivity.cpp b/core/jni/android_app_NativeActivity.cpp
index 0932473a..2517a8a 100644
--- a/core/jni/android_app_NativeActivity.cpp
+++ b/core/jni/android_app_NativeActivity.cpp
@@ -127,12 +127,13 @@
     close(mDispatchKeyWrite);
 }
 
-void AInputQueue::attachLooper(ALooper* looper, ALooper_callbackFunc* callback, void* data) {
+void AInputQueue::attachLooper(ALooper* looper, int ident,
+        ALooper_callbackFunc* callback, void* data) {
     mPollLoop = static_cast<android::PollLoop*>(looper);
     mPollLoop->setLooperCallback(mConsumer.getChannel()->getReceivePipeFd(),
-            POLLIN, callback, data);
+            ident, POLLIN, callback, data);
     mPollLoop->setLooperCallback(mDispatchKeyRead,
-            POLLIN, callback, data);
+            ident, POLLIN, callback, data);
 }
 
 void AInputQueue::detachLooper() {
diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp
index 7c99271..7dfb716 100644
--- a/core/jni/android_util_Process.cpp
+++ b/core/jni/android_util_Process.cpp
@@ -261,8 +261,7 @@
             continue;
         }
      
-        if (set_sched_policy(t_pid, (grp == ANDROID_TGROUP_BG_NONINTERACT) ?
-                                            SP_BACKGROUND : SP_FOREGROUND)) {
+        if (androidSetThreadSchedulingGroup(t_pid, grp) != NO_ERROR) {
             signalExceptionForGroupError(env, clazz, errno);
             break;
         }
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 7942c56..55d9b6c 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -703,8 +703,7 @@
     <string name="elapsed_time_short_format_mm_ss" msgid="4431555943828711473">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
     <string name="elapsed_time_short_format_h_mm_ss" msgid="1846071997616654124">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
     <string name="selectAll" msgid="6876518925844129331">"Vybrat vše"</string>
-    <!-- no translation found for selectText (4862359311088898878) -->
-    <skip />
+    <!-- outdated translation 3889149123626888637 -->     <string name="selectText" msgid="4862359311088898878">"Označit text"</string>
     <string name="cut" msgid="3092569408438626261">"Vyjmout"</string>
     <string name="copy" msgid="2681946229533511987">"Kopírovat"</string>
     <string name="paste" msgid="5629880836805036433">"Vložit"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index bab18f2..9e6865e 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -703,8 +703,7 @@
     <string name="elapsed_time_short_format_mm_ss" msgid="4431555943828711473">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
     <string name="elapsed_time_short_format_h_mm_ss" msgid="1846071997616654124">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
     <string name="selectAll" msgid="6876518925844129331">"Vælg alle"</string>
-    <!-- no translation found for selectText (4862359311088898878) -->
-    <skip />
+    <!-- outdated translation 3889149123626888637 -->     <string name="selectText" msgid="4862359311088898878">"Marker tekst"</string>
     <string name="cut" msgid="3092569408438626261">"Klip"</string>
     <string name="copy" msgid="2681946229533511987">"Kopier"</string>
     <string name="paste" msgid="5629880836805036433">"Indsæt"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index c20aa16..1e1556f 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -703,8 +703,7 @@
     <string name="elapsed_time_short_format_mm_ss" msgid="4431555943828711473">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
     <string name="elapsed_time_short_format_h_mm_ss" msgid="1846071997616654124">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
     <string name="selectAll" msgid="6876518925844129331">"Alles auswählen"</string>
-    <!-- no translation found for selectText (4862359311088898878) -->
-    <skip />
+    <!-- outdated translation 3889149123626888637 -->     <string name="selectText" msgid="4862359311088898878">"Text auswählen"</string>
     <string name="cut" msgid="3092569408438626261">"Ausschneiden"</string>
     <string name="copy" msgid="2681946229533511987">"Kopieren"</string>
     <string name="paste" msgid="5629880836805036433">"Einfügen"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index ab29601..a0bb65b 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -703,8 +703,7 @@
     <string name="elapsed_time_short_format_mm_ss" msgid="4431555943828711473">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
     <string name="elapsed_time_short_format_h_mm_ss" msgid="1846071997616654124">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
     <string name="selectAll" msgid="6876518925844129331">"Επιλογή όλων"</string>
-    <!-- no translation found for selectText (4862359311088898878) -->
-    <skip />
+    <!-- outdated translation 3889149123626888637 -->     <string name="selectText" msgid="4862359311088898878">"Επιλογή κειμένου"</string>
     <string name="cut" msgid="3092569408438626261">"Αποκοπή"</string>
     <string name="copy" msgid="2681946229533511987">"Αντιγραφή"</string>
     <string name="paste" msgid="5629880836805036433">"Επικόλληση"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index fce56cd..b07d79a 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -703,8 +703,7 @@
     <string name="elapsed_time_short_format_mm_ss" msgid="4431555943828711473">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
     <string name="elapsed_time_short_format_h_mm_ss" msgid="1846071997616654124">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
     <string name="selectAll" msgid="6876518925844129331">"Seleccionar todos"</string>
-    <!-- no translation found for selectText (4862359311088898878) -->
-    <skip />
+    <!-- outdated translation 3889149123626888637 -->     <string name="selectText" msgid="4862359311088898878">"Seleccionar texto"</string>
     <string name="cut" msgid="3092569408438626261">"Cortar"</string>
     <string name="copy" msgid="2681946229533511987">"Copiar"</string>
     <string name="paste" msgid="5629880836805036433">"Pegar"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 4fdaf3c..35e19a8 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -703,8 +703,7 @@
     <string name="elapsed_time_short_format_mm_ss" msgid="4431555943828711473">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
     <string name="elapsed_time_short_format_h_mm_ss" msgid="1846071997616654124">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
     <string name="selectAll" msgid="6876518925844129331">"Seleccionar todo"</string>
-    <!-- no translation found for selectText (4862359311088898878) -->
-    <skip />
+    <!-- outdated translation 3889149123626888637 -->     <string name="selectText" msgid="4862359311088898878">"Seleccionar texto"</string>
     <string name="cut" msgid="3092569408438626261">"Cortar"</string>
     <string name="copy" msgid="2681946229533511987">"Copiar"</string>
     <string name="paste" msgid="5629880836805036433">"Pegar"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 9f0fa0b..e826aba 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -703,8 +703,7 @@
     <string name="elapsed_time_short_format_mm_ss" msgid="4431555943828711473">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
     <string name="elapsed_time_short_format_h_mm_ss" msgid="1846071997616654124">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
     <string name="selectAll" msgid="6876518925844129331">"Tout sélectionner"</string>
-    <!-- no translation found for selectText (4862359311088898878) -->
-    <skip />
+    <!-- outdated translation 3889149123626888637 -->     <string name="selectText" msgid="4862359311088898878">"Sélectionner le texte"</string>
     <string name="cut" msgid="3092569408438626261">"Couper"</string>
     <string name="copy" msgid="2681946229533511987">"Copier"</string>
     <string name="paste" msgid="5629880836805036433">"Coller"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 4731f39..46b735e 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -703,8 +703,7 @@
     <string name="elapsed_time_short_format_mm_ss" msgid="4431555943828711473">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
     <string name="elapsed_time_short_format_h_mm_ss" msgid="1846071997616654124">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
     <string name="selectAll" msgid="6876518925844129331">"Seleziona tutto"</string>
-    <!-- no translation found for selectText (4862359311088898878) -->
-    <skip />
+    <!-- outdated translation 3889149123626888637 -->     <string name="selectText" msgid="4862359311088898878">"Seleziona testo"</string>
     <string name="cut" msgid="3092569408438626261">"Taglia"</string>
     <string name="copy" msgid="2681946229533511987">"Copia"</string>
     <string name="paste" msgid="5629880836805036433">"Incolla"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index a9613f4..802c6a3 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -703,8 +703,7 @@
     <string name="elapsed_time_short_format_mm_ss" msgid="4431555943828711473">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
     <string name="elapsed_time_short_format_h_mm_ss" msgid="1846071997616654124">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
     <string name="selectAll" msgid="6876518925844129331">"すべて選択"</string>
-    <!-- no translation found for selectText (4862359311088898878) -->
-    <skip />
+    <!-- outdated translation 3889149123626888637 -->     <string name="selectText" msgid="4862359311088898878">"テキストを選択"</string>
     <string name="cut" msgid="3092569408438626261">"切り取り"</string>
     <string name="copy" msgid="2681946229533511987">"コピー"</string>
     <string name="paste" msgid="5629880836805036433">"貼り付け"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index d6ab5ad..165c5e5 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -703,8 +703,7 @@
     <string name="elapsed_time_short_format_mm_ss" msgid="4431555943828711473">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
     <string name="elapsed_time_short_format_h_mm_ss" msgid="1846071997616654124">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
     <string name="selectAll" msgid="6876518925844129331">"모두 선택"</string>
-    <!-- no translation found for selectText (4862359311088898878) -->
-    <skip />
+    <!-- outdated translation 3889149123626888637 -->     <string name="selectText" msgid="4862359311088898878">"텍스트 선택"</string>
     <string name="cut" msgid="3092569408438626261">"잘라내기"</string>
     <string name="copy" msgid="2681946229533511987">"복사"</string>
     <string name="paste" msgid="5629880836805036433">"붙여넣기"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 021b20e..b4af7a6 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -703,8 +703,7 @@
     <string name="elapsed_time_short_format_mm_ss" msgid="4431555943828711473">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
     <string name="elapsed_time_short_format_h_mm_ss" msgid="1846071997616654124">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
     <string name="selectAll" msgid="6876518925844129331">"Merk alt"</string>
-    <!-- no translation found for selectText (4862359311088898878) -->
-    <skip />
+    <!-- outdated translation 3889149123626888637 -->     <string name="selectText" msgid="4862359311088898878">"Merk tekst"</string>
     <string name="cut" msgid="3092569408438626261">"Klipp ut"</string>
     <string name="copy" msgid="2681946229533511987">"Kopier"</string>
     <string name="paste" msgid="5629880836805036433">"Lim inn"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index a74db2b..8829f277 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -703,8 +703,7 @@
     <string name="elapsed_time_short_format_mm_ss" msgid="4431555943828711473">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
     <string name="elapsed_time_short_format_h_mm_ss" msgid="1846071997616654124">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
     <string name="selectAll" msgid="6876518925844129331">"Alles selecteren"</string>
-    <!-- no translation found for selectText (4862359311088898878) -->
-    <skip />
+    <!-- outdated translation 3889149123626888637 -->     <string name="selectText" msgid="4862359311088898878">"Tekst selecteren"</string>
     <string name="cut" msgid="3092569408438626261">"Knippen"</string>
     <string name="copy" msgid="2681946229533511987">"Kopiëren"</string>
     <string name="paste" msgid="5629880836805036433">"Plakken"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index f5ed50c..dd9747d 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -703,8 +703,7 @@
     <string name="elapsed_time_short_format_mm_ss" msgid="4431555943828711473">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
     <string name="elapsed_time_short_format_h_mm_ss" msgid="1846071997616654124">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
     <string name="selectAll" msgid="6876518925844129331">"Zaznacz wszystko"</string>
-    <!-- no translation found for selectText (4862359311088898878) -->
-    <skip />
+    <!-- outdated translation 3889149123626888637 -->     <string name="selectText" msgid="4862359311088898878">"Zaznacz tekst"</string>
     <string name="cut" msgid="3092569408438626261">"Wytnij"</string>
     <string name="copy" msgid="2681946229533511987">"Kopiuj"</string>
     <string name="paste" msgid="5629880836805036433">"Wklej"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 7914a3d..cce7ff9 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -703,8 +703,7 @@
     <string name="elapsed_time_short_format_mm_ss" msgid="4431555943828711473">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
     <string name="elapsed_time_short_format_h_mm_ss" msgid="1846071997616654124">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
     <string name="selectAll" msgid="6876518925844129331">"Seleccionar tudo"</string>
-    <!-- no translation found for selectText (4862359311088898878) -->
-    <skip />
+    <!-- outdated translation 3889149123626888637 -->     <string name="selectText" msgid="4862359311088898878">"Seleccionar texto"</string>
     <string name="cut" msgid="3092569408438626261">"Cortar"</string>
     <string name="copy" msgid="2681946229533511987">"Copiar"</string>
     <string name="paste" msgid="5629880836805036433">"Colar"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index c9c792e..7163fce 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -703,8 +703,7 @@
     <string name="elapsed_time_short_format_mm_ss" msgid="4431555943828711473">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
     <string name="elapsed_time_short_format_h_mm_ss" msgid="1846071997616654124">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
     <string name="selectAll" msgid="6876518925844129331">"Selecionar tudo"</string>
-    <!-- no translation found for selectText (4862359311088898878) -->
-    <skip />
+    <!-- outdated translation 3889149123626888637 -->     <string name="selectText" msgid="4862359311088898878">"Selecionar texto"</string>
     <string name="cut" msgid="3092569408438626261">"Recortar"</string>
     <string name="copy" msgid="2681946229533511987">"Copiar"</string>
     <string name="paste" msgid="5629880836805036433">"Colar"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 786571b..043e094 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -703,8 +703,7 @@
     <string name="elapsed_time_short_format_mm_ss" msgid="4431555943828711473">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
     <string name="elapsed_time_short_format_h_mm_ss" msgid="1846071997616654124">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
     <string name="selectAll" msgid="6876518925844129331">"Выбрать все"</string>
-    <!-- no translation found for selectText (4862359311088898878) -->
-    <skip />
+    <!-- outdated translation 3889149123626888637 -->     <string name="selectText" msgid="4862359311088898878">"Выбрать текст"</string>
     <string name="cut" msgid="3092569408438626261">"Вырезать"</string>
     <string name="copy" msgid="2681946229533511987">"Копировать"</string>
     <string name="paste" msgid="5629880836805036433">"Вставить"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 8a115697..e32746a 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -703,8 +703,7 @@
     <string name="elapsed_time_short_format_mm_ss" msgid="4431555943828711473">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
     <string name="elapsed_time_short_format_h_mm_ss" msgid="1846071997616654124">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
     <string name="selectAll" msgid="6876518925844129331">"Välj alla"</string>
-    <!-- no translation found for selectText (4862359311088898878) -->
-    <skip />
+    <!-- outdated translation 3889149123626888637 -->     <string name="selectText" msgid="4862359311088898878">"Markera text"</string>
     <string name="cut" msgid="3092569408438626261">"Klipp ut"</string>
     <string name="copy" msgid="2681946229533511987">"Kopiera"</string>
     <string name="paste" msgid="5629880836805036433">"Klistra in"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index b45d5bb..bd87446 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -703,8 +703,7 @@
     <string name="elapsed_time_short_format_mm_ss" msgid="4431555943828711473">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
     <string name="elapsed_time_short_format_h_mm_ss" msgid="1846071997616654124">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
     <string name="selectAll" msgid="6876518925844129331">"Tümünü seç"</string>
-    <!-- no translation found for selectText (4862359311088898878) -->
-    <skip />
+    <!-- outdated translation 3889149123626888637 -->     <string name="selectText" msgid="4862359311088898878">"Metin seç"</string>
     <string name="cut" msgid="3092569408438626261">"Kes"</string>
     <string name="copy" msgid="2681946229533511987">"Kopyala"</string>
     <string name="paste" msgid="5629880836805036433">"Yapıştır"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 88c38e5..aa1f93f 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -703,8 +703,7 @@
     <string name="elapsed_time_short_format_mm_ss" msgid="4431555943828711473">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
     <string name="elapsed_time_short_format_h_mm_ss" msgid="1846071997616654124">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
     <string name="selectAll" msgid="6876518925844129331">"全选"</string>
-    <!-- no translation found for selectText (4862359311088898878) -->
-    <skip />
+    <!-- outdated translation 3889149123626888637 -->     <string name="selectText" msgid="4862359311088898878">"选择文字"</string>
     <string name="cut" msgid="3092569408438626261">"剪切"</string>
     <string name="copy" msgid="2681946229533511987">"复制"</string>
     <string name="paste" msgid="5629880836805036433">"粘贴"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 7d3c27a..fdce813 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -703,8 +703,7 @@
     <string name="elapsed_time_short_format_mm_ss" msgid="4431555943828711473">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
     <string name="elapsed_time_short_format_h_mm_ss" msgid="1846071997616654124">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
     <string name="selectAll" msgid="6876518925844129331">"全部選取"</string>
-    <!-- no translation found for selectText (4862359311088898878) -->
-    <skip />
+    <!-- outdated translation 3889149123626888637 -->     <string name="selectText" msgid="4862359311088898878">"選取文字"</string>
     <string name="cut" msgid="3092569408438626261">"剪下"</string>
     <string name="copy" msgid="2681946229533511987">"複製"</string>
     <string name="paste" msgid="5629880836805036433">"貼上"</string>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index de419be..86e79c8 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1270,7 +1270,13 @@
 
   <public-padding type="drawable" name="kraken_resource_pad" end="0x01080100" />
   
+  <public type="style" name="TextAppearance.StatusBar.Title" id="0x01030065" />
+  <public type="style" name="TextAppearance.StatusBar.Icon" id="0x01030066" />
+  <public type="style" name="TextAppearance.StatusBar.EventContent" id="0x01030067" />
+  <public type="style" name="TextAppearance.StatusBar.EventContent.Title" id="0x01030068" />
+
   <public-padding type="style" name="kraken_resource_pad" end="0x01030090" />
+
   <public-padding type="string" name="kraken_resource_pad" end="0x01040020" />
   <public-padding type="integer" name="kraken_resource_pad" end="0x010e0010" />
   <public-padding type="layout" name="kraken_resource_pad" end="0x01090020" />
diff --git a/docs/html/guide/practices/design/performance.jd b/docs/html/guide/practices/design/performance.jd
index f22d2d3..56872a7 100644
--- a/docs/html/guide/practices/design/performance.jd
+++ b/docs/html/guide/practices/design/performance.jd
@@ -42,188 +42,39 @@
 
 <h2 id="optimize_judiciously">Optimize Judiciously</h2>
 
-<p>As you get started thinking about how to design your application, and as
-you write it, consider
-the cautionary points about optimization that Josh Bloch makes in his book
-<em>Effective Java</em>. Here's "Item 47: Optimize Judiciously", excerpted from
-the latest edition of the book with permission. Although Josh didn't have
-Android application development in mind when writing this section &mdash; for
-example, the <code style="color:black">java.awt.Component</code> class
-referenced is not available in Android, and Android uses the
-Dalvik VM, rather than a standard JVM &mdash; his points are still valid. </p>
+<p>This document is about Android-specific micro-optimization, so it assumes
+that you've already used profiling to work out exactly what code needs to be
+optimized, and that you already have a way to measure the effect (good or bad)
+of any changes you make. You only have so much engineering time to invest, so
+it's important to know you're spending it wisely.
 
-<blockquote>
+<p>(See <a href="#closing_notes">Closing Notes</a> for more on profiling and
+writing effective benchmarks.)
 
-<p>There are three aphorisms concerning optimization that everyone should know.
-They are perhaps beginning to suffer from overexposure, but in case you aren't
-yet familiar with them, here they are:</p>
+<p>This document also assumes that you made the best decisions about data
+structures and algorithms, and that you've also considered the future
+performance consequences of your API decisions. Using the right data
+structures and algorithms will make more difference than any of the advice
+here, and considering the performance consequences of your API decisions will
+make it easier to switch to better implementations later (this is more
+important for library code than for application code).
 
-<div style="padding-left:3em;padding-right:4em;">
+<p>(If you need that kind of advice, see Josh Bloch's <em>Effective Java</em>,
+item 47.)</p>
 
-<p style="margin-bottom:.5em;">More computing sins are committed in the name of
-efficiency (without necessarily achieving it) than for any other single
-reason&mdash;including blind stupidity.</p>
-<p>&mdash;William A. Wulf <span style="font-size:80%;"><sup>1</sup></span></p>
+<p>One of the trickiest problems you'll face when micro-optimizing an Android
+app is that your app is pretty much guaranteed to be running on multiple
+hardware platforms. Different versions of the VM running on different
+processors running at different speeds. It's not even generally the case
+that you can simply say "device X is a factor F faster/slower than device Y",
+and scale your results from one device to others. In particular, measurement
+on the emulator tells you very little about performance on any device. There
+are also huge differences between devices with and without a JIT: the "best"
+code for a device with a JIT is not always the best code for a device
+without.</p>
 
-<p style="margin-bottom:.5em;">We should forget about small efficiencies, say
-about 97% of the time: premature optimization is the root of all evil. </p>
-<p>&mdash;Donald E. Knuth <span style="font-size:80%;"><sup>2</sup></span></p>
-
-
-<p style="margin-bottom:.5em;">We follow two rules in the matter of optimization:</p>
-<ul style="margin-bottom:0">
-<li>Rule 1. Don't do it.</li>
-<li>Rule 2 (for experts only). Don't do it yet &mdash; that is, not until you have a
-perfectly clear and unoptimized solution. </li>
-</ul>
-<p>&mdash;M. A. Jackson <span style="font-size:80%;"><sup>3</sup></span></p>
-</div>
-
-<p>All of these aphorisms predate the Java programming language by two decades.
-They tell a deep truth about optimization: it is easy to do more harm than good,
-especially if you optimize prematurely. In the process, you may produce software
-that is neither fast nor correct and cannot easily be fixed.</p>
-
-<p>Don't sacrifice sound architectural principles for performance.
-<strong>Strive to write good programs rather than fast ones.</strong> If a good
-program is not fast enough, its architecture will allow it to be optimized. Good
-programs embody the principle of <em>information hiding</em>: where possible,
-they localize design decisions within individual modules, so individual
-decisions can be changed without affecting the remainder of the system (Item
-13).</p>
-
-<p>This does <em>not</em> mean that you can ignore performance concerns until
-your program is complete. Implementation problems can be fixed by later
-optimization, but pervasive architectural flaws that limit performance can be
-impossible to fix without rewriting the system. Changing a fundamental facet of
-your design after the fact can result in an ill-structured system that is
-difficult to maintain and evolve. Therefore you must think about performance
-during the design process.</p>
-
-<p><strong>Strive to avoid design decisions that limit performance.</strong> The
-components of a design that are most difficult to change after the fact are
-those specifying interactions between modules and with the outside world. Chief
-among these design components are APIs, wire-level protocols, and persistent
-data formats. Not only are these design components difficult or impossible to
-change after the fact, but all of them can place significant limitations on the
-performance that a system can ever achieve.</p>
-
-<p><strong>Consider the performance consequences of your API design
-decisions.</strong> Making a public type mutable may require a lot of needless
-defensive copying (Item 39). Similarly, using inheritance in a public class
-where composition would have been appropriate ties the class forever to its
-superclass, which can place artificial limits on the performance of the subclass
-(Item 16). As a final example, using an implementation type rather than an
-interface in an API ties you to a specific implementation, even though faster
-implementations may be written in the future (Item 52).</p>
-
-<p>The effects of API design on performance are very real. Consider the <code
-style="color:black">getSize</code> method in the <code
-style="color:black">java.awt.Component</code> class. The decision that this
-performance-critical method was to return a <code
-style="color:black">Dimension</code> instance, coupled with the decision that
-<code style="color:black">Dimension</code> instances are mutable, forces any
-implementation of this method to allocate a new <code
-style="color:black">Dimension</code> instance on every invocation. Even though
-allocating small objects is inexpensive on a modern VM, allocating millions of
-objects needlessly can do real harm to performance.</p>
-
-<p>In this case, several alternatives existed. Ideally, <code
-style="color:black">Dimension</code> should have been immutable (Item 15);
-alternatively, the <code style="color:black">getSize</code> method could have
-been replaced by two methods returning the individual primitive components of a
-<code style="color:black">Dimension</code> object. In fact, two such methods
-were added to the Component API in the 1.2 release for performance reasons.
-Preexisting client code, however, still uses the <code
-style="color:black">getSize</code> method and still suffers the performance
-consequences of the original API design decisions.</p>
-
-<p>Luckily, it is generally the case that good API design is consistent with
-good performance. <strong>It is a very bad idea to warp an API to achieve good
-performance.</strong> The performance issue that caused you to warp the API may
-go away in a future release of the platform or other underlying software, but
-the warped API and the support headaches that come with it will be with you for
-life.</p>
-
-<p>Once you've carefully designed your program and produced a clear, concise,
-and well-structured implementation, <em>then</em> it may be time to consider
-optimization, assuming you're not already satisfied with the performance of the
-program.</p>
-
-<p>Recall that Jackson's two rules of optimization were "Don't do it," and "(for
-experts only). Don't do it yet." He could have added one more: <strong>measure
-performance before and after each attempted optimization.</strong> You may be
-surprised by what you find. Often, attempted optimizations have no measurable
-effect on performance; sometimes, they make it worse. The main reason is that
-it's difficult to guess where your program is spending its time. The part of the
-program that you think is slow may not be at fault, in which case you'd be
-wasting your time trying to optimize it. Common wisdom says that programs spend
-80 percent of their time in 20 percent of their code.</p>
-
-<p>Profiling tools can help you decide where to focus your optimization efforts.
-Such tools give you runtime information, such as roughly how much time each
-method is consuming and how many times it is invoked. In addition to focusing
-your tuning efforts, this can alert you to the need for algorithmic changes. If
-a quadratic (or worse) algorithm lurks inside your program, no amount of tuning
-will fix the problem. You must replace the algorithm with one that is more
-efficient. The more code in the system, the more important it is to use a
-profiler. It's like looking for a needle in a haystack: the bigger the haystack,
-the more useful it is to have a metal detector. The JDK comes with a simple
-profiler and modern IDEs provide more sophisticated profiling tools.</p>
-
-<p>The need to measure the effects of attempted optimization is even greater on
-the Java platform than on more traditional platforms, because the Java
-programming language does not have a strong <em>performance model</em>. The
-relative costs of the various primitive operations are not well defined. The
-"semantic gap" between what the programmer writes and what the CPU executes is
-far greater than in traditional statically compiled languages, which makes it
-very difficult to reliably predict the performance consequences of any
-optimization. There are plenty of performance myths floating around that turn
-out to be half-truths or outright lies.</p>
-
-<p>Not only is Java's performance model ill-defined, but it varies from JVM
-implementation to JVM implementation, from release to release, and from
-processor to processor. If you will be running your program on multiple JVM
-implementations or multiple hardware platforms, it is important that you measure
-the effects of your optimization on each. Occasionally you may be forced to make
-trade-offs between performance on different JVM implementations or hardware
-platforms.</p>
-
-<p>To summarize, do not strive to write fast programs &mdash; strive to write
-good ones; speed will follow. Do think about performance issues while you're
-designing systems and especially while you're designing APIs, wire-level
-protocols, and persistent data formats. When you've finished building the
-system, measure its performance. If it's fast enough, you're done. If not,
-locate the source of the problems with the aid of a profiler, and go to work
-optimizing the relevant parts of the system. The first step is to examine your
-choice of algorithms: no amount of low-level optimization can make up for a poor
-choice of algorithm. Repeat this process as necessary, measuring the performance
-after every change, until you're satisfied.</p>
-
-<p>&mdash;Excerpted from Josh Bloch's <em>Effective Java</em>, Second Ed.
-(Addison-Wesley, 2008).</em></p>
-
-<p style="font-size:80%;margin-bottom:0;"><sup>1</sup> Wulf, W. A Case Against
-the GOTO. <em>Proceedings of the 25th ACM National
-Conference</em> 2 (1972): 791–797.</p>
-<p style="font-size:80%;margin-bottom:0;"><sup>2</sup> Knuth, Donald. Structured
-Programming with go to Statements. <em>Computing
-Surveys 6</em> (1974): 261–301.</p>
-<p style="font-size:80%"><sup>3</sup> Jackson, M. A. <em>Principles of Program
-Design</em>, Academic Press, London, 1975.
-ISBN: 0123790506.</p>
-
-</blockquote>
-
-<p>One of the trickiest problems you'll face when micro-optimizing Android
-apps is that the "if you will be running your program on ... multiple hardware
-platforms" clause above is always true. And it's not even generally the case
-that you can say "device X is a factor F faster/slower than device Y".
-This is especially true if one of the devices is the emulator, or one of the
-devices has a JIT. If you want to know how your app performs on a given device,
-you need to test it on that device. Drawing conclusions from the emulator is
-particularly dangerous, as is attempting to compare JIT versus non-JIT
-performance: the performance <em>profiles</em> can differ wildly.</p>
+<p>If you want to know how your app performs on a given device, you need to
+test on that device.</p>
 
 <a name="object_creation"></a>
 <h2>Avoid Creating Objects</h2>
@@ -566,3 +417,11 @@
 not measuring what you think you're measuring (because, say, the VM has
 managed to optimize all your code away). We highly recommend you use Caliper
 to run your own microbenchmarks.</p>
+
+<p>You may also find
+<a href="{@docRoot}guide/developing/tools/traceview.html">Traceview</a> useful
+for profiling, but it's important to realize that it currently disables the JIT,
+which may cause it to misattribute time to code that the JIT may be able to win
+back. It's especially important after making changes suggested by Traceview
+data to ensure that the resulting code actually runs faster when run without
+Traceview.
diff --git a/include/android_runtime/android_app_NativeActivity.h b/include/android_runtime/android_app_NativeActivity.h
index c388ba8..fdceb84 100644
--- a/include/android_runtime/android_app_NativeActivity.h
+++ b/include/android_runtime/android_app_NativeActivity.h
@@ -69,7 +69,7 @@
     /* Destroys the consumer and releases its input channel. */
     ~AInputQueue();
 
-    void attachLooper(ALooper* looper, ALooper_callbackFunc* callback, void* data);
+    void attachLooper(ALooper* looper, int ident, ALooper_callbackFunc* callback, void* data);
 
     void detachLooper();
 
diff --git a/include/utils/PollLoop.h b/include/utils/PollLoop.h
index 81230e8..bc616eb 100644
--- a/include/utils/PollLoop.h
+++ b/include/utils/PollLoop.h
@@ -111,12 +111,18 @@
      * This method can be called on any thread.
      * This method may block briefly if it needs to wake the poll loop.
      */
-    void setCallback(int fd, int events, Callback callback, void* data = NULL);
+    void setCallback(int fd, int ident, int events, Callback callback, void* data = NULL);
 
     /**
+     * Convenience for above setCallback when ident is not used.  In this case
+     * the ident is set to POLL_CALLBACK.
+     */
+    void setCallback(int fd, int events, Callback callback, void* data = NULL);
+    
+    /**
      * Like setCallback(), but for the NDK callback function.
      */
-    void setLooperCallback(int fd, int events, ALooper_callbackFunc* callback,
+    void setLooperCallback(int fd, int ident, int events, ALooper_callbackFunc* callback,
             void* data);
     
     /**
@@ -153,11 +159,13 @@
     struct RequestedCallback {
         Callback callback;
         ALooper_callbackFunc* looperCallback;
+        int ident;
         void* data;
     };
 
     struct PendingCallback {
         int fd;
+        int ident;
         int events;
         Callback callback;
         ALooper_callbackFunc* looperCallback;
@@ -185,7 +193,7 @@
     void openWakePipe();
     void closeWakePipe();
 
-    void setCallbackCommon(int fd, int events, Callback callback,
+    void setCallbackCommon(int fd, int ident, int events, Callback callback,
             ALooper_callbackFunc* looperCallback, void* data);
     ssize_t getRequestIndexLocked(int fd);
     void wakeAndLock();
diff --git a/libs/gui/SensorEventQueue.cpp b/libs/gui/SensorEventQueue.cpp
index 3396f25..7eb6da5 100644
--- a/libs/gui/SensorEventQueue.cpp
+++ b/libs/gui/SensorEventQueue.cpp
@@ -86,7 +86,7 @@
     Mutex::Autolock _l(mLock);
     if (mPollLoop == 0) {
         mPollLoop = new PollLoop(true);
-        mPollLoop->setCallback(getFd(), POLLIN, NULL, NULL);
+        mPollLoop->setCallback(getFd(), getFd(), POLLIN, NULL, NULL);
     }
     return mPollLoop;
 }
diff --git a/libs/utils/PollLoop.cpp b/libs/utils/PollLoop.cpp
index f740fa0..6d3eeee 100644
--- a/libs/utils/PollLoop.cpp
+++ b/libs/utils/PollLoop.cpp
@@ -95,6 +95,7 @@
     RequestedCallback requestedCallback;
     requestedCallback.callback = NULL;
     requestedCallback.looperCallback = NULL;
+    requestedCallback.ident = 0;
     requestedCallback.data = NULL;
     mRequestedCallbacks.insertAt(requestedCallback, 0);
 }
@@ -116,7 +117,7 @@
         mPendingFdsPos++;
         if (outEvents != NULL) *outEvents = pending.events;
         if (outData != NULL) *outData = pending.data;
-        return pending.fd;
+        return pending.ident;
     }
     
     mLock.lock();
@@ -182,6 +183,7 @@
             const RequestedCallback& requestedCallback = mRequestedCallbacks.itemAt(i);
             PendingCallback pending;
             pending.fd = requestedFd.fd;
+            pending.ident = requestedCallback.ident;
             pending.events = revents;
             pending.callback = requestedCallback.callback;
             pending.looperCallback = requestedCallback.looperCallback;
@@ -191,7 +193,7 @@
                 mPendingCallbacks.push(pending);
             } else if (pending.fd != mWakeReadPipeFd) {
                 if (result == POLL_CALLBACK) {
-                    result = pending.fd;
+                    result = pending.ident;
                     if (outEvents != NULL) *outEvents = pending.events;
                     if (outData != NULL) *outData = pending.data;
                 } else {
@@ -268,16 +270,20 @@
     return mAllowNonCallbacks;
 }
 
+void PollLoop::setCallback(int fd, int ident, int events, Callback callback, void* data) {
+    setCallbackCommon(fd, ident, events, callback, NULL, data);
+}
+
 void PollLoop::setCallback(int fd, int events, Callback callback, void* data) {
-    setCallbackCommon(fd, events, callback, NULL, data);
+    setCallbackCommon(fd, POLL_CALLBACK, events, callback, NULL, data);
 }
 
-void PollLoop::setLooperCallback(int fd, int events, ALooper_callbackFunc* callback,
+void PollLoop::setLooperCallback(int fd, int ident, int events, ALooper_callbackFunc* callback,
         void* data) {
-    setCallbackCommon(fd, events, NULL, callback, data);
+    setCallbackCommon(fd, ident, events, NULL, callback, data);
 }
 
-void PollLoop::setCallbackCommon(int fd, int events, Callback callback,
+void PollLoop::setCallbackCommon(int fd, int ident, int events, Callback callback,
         ALooper_callbackFunc* looperCallback, void* data) {
 
 #if DEBUG_CALLBACKS
@@ -305,6 +311,7 @@
     RequestedCallback requestedCallback;
     requestedCallback.callback = callback;
     requestedCallback.looperCallback = looperCallback;
+    requestedCallback.ident = ident;
     requestedCallback.data = data;
 
     ssize_t index = getRequestIndexLocked(fd);
diff --git a/libs/utils/Threads.cpp b/libs/utils/Threads.cpp
index 2b1f490..e5ece8e 100644
--- a/libs/utils/Threads.cpp
+++ b/libs/utils/Threads.cpp
@@ -21,6 +21,7 @@
 #include <utils/Log.h>
 
 #include <cutils/sched_policy.h>
+#include <cutils/properties.h>
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -57,7 +58,7 @@
 // ----------------------------------------------------------------------------
 
 /*
- * Create and run a new thead.
+ * Create and run a new thread.
  *
  * We create it "detached", so it cleans up after itself.
  */
@@ -280,6 +281,22 @@
 #endif
 }
 
+#if defined(HAVE_PTHREADS)
+static pthread_once_t gDoSchedulingGroupOnce = PTHREAD_ONCE_INIT;
+static bool gDoSchedulingGroup = true;
+
+static void checkDoSchedulingGroup(void) {
+    char buf[PROPERTY_VALUE_MAX];
+    int len = property_get("debug.sys.noschedgroups", buf, "");
+    if (len > 0) {
+        int temp;
+        if (sscanf(buf, "%d", &temp) == 1) {
+            gDoSchedulingGroup = temp == 0;
+        }
+    }
+}
+#endif
+
 int androidSetThreadSchedulingGroup(pid_t tid, int grp)
 {
     if (grp > ANDROID_TGROUP_MAX || grp < 0) { 
@@ -287,9 +304,12 @@
     }
 
 #if defined(HAVE_PTHREADS)
-    if (set_sched_policy(tid, (grp == ANDROID_TGROUP_BG_NONINTERACT) ?
-                                      SP_BACKGROUND : SP_FOREGROUND)) {
-        return PERMISSION_DENIED;
+    pthread_once(&gDoSchedulingGroupOnce, checkDoSchedulingGroup);
+    if (gDoSchedulingGroup) {
+        if (set_sched_policy(tid, (grp == ANDROID_TGROUP_BG_NONINTERACT) ?
+                                          SP_BACKGROUND : SP_FOREGROUND)) {
+            return PERMISSION_DENIED;
+        }
     }
 #endif
     
@@ -303,10 +323,13 @@
 #if defined(HAVE_PTHREADS)
     int lasterr = 0;
 
-    if (pri >= ANDROID_PRIORITY_BACKGROUND) {
-        rc = set_sched_policy(tid, SP_BACKGROUND);
-    } else if (getpriority(PRIO_PROCESS, tid) >= ANDROID_PRIORITY_BACKGROUND) {
-        rc = set_sched_policy(tid, SP_FOREGROUND);
+    pthread_once(&gDoSchedulingGroupOnce, checkDoSchedulingGroup);
+    if (gDoSchedulingGroup) {
+        if (pri >= ANDROID_PRIORITY_BACKGROUND) {
+            rc = set_sched_policy(tid, SP_BACKGROUND);
+        } else if (getpriority(PRIO_PROCESS, tid) >= ANDROID_PRIORITY_BACKGROUND) {
+            rc = set_sched_policy(tid, SP_FOREGROUND);
+        }
     }
 
     if (rc) {
diff --git a/native/android/input.cpp b/native/android/input.cpp
index 379960a..c79f913 100644
--- a/native/android/input.cpp
+++ b/native/android/input.cpp
@@ -246,8 +246,8 @@
 
 
 void AInputQueue_attachLooper(AInputQueue* queue, ALooper* looper,
-        ALooper_callbackFunc* callback, void* data) {
-    queue->attachLooper(looper, callback, data);
+        int ident, ALooper_callbackFunc* callback, void* data) {
+    queue->attachLooper(looper, ident, callback, data);
 }
 
 void AInputQueue_detachLooper(AInputQueue* queue) {
diff --git a/native/android/looper.cpp b/native/android/looper.cpp
index 1564c47..0aeed77 100644
--- a/native/android/looper.cpp
+++ b/native/android/looper.cpp
@@ -72,9 +72,9 @@
     static_cast<PollLoop*>(looper)->decStrong((void*)ALooper_acquire);
 }
 
-void ALooper_addFd(ALooper* looper, int fd, int events,
+void ALooper_addFd(ALooper* looper, int fd, int ident, int events,
         ALooper_callbackFunc* callback, void* data) {
-    static_cast<PollLoop*>(looper)->setLooperCallback(fd, events, callback, data);
+    static_cast<PollLoop*>(looper)->setLooperCallback(fd, ident, events, callback, data);
 }
 
 int32_t ALooper_removeFd(ALooper* looper, int fd) {
diff --git a/native/android/sensor.cpp b/native/android/sensor.cpp
index db534e0..cf7635d 100644
--- a/native/android/sensor.cpp
+++ b/native/android/sensor.cpp
@@ -60,12 +60,12 @@
 }
 
 ASensorEventQueue* ASensorManager_createEventQueue(ASensorManager* manager,
-        ALooper* looper, ALooper_callbackFunc* callback, void* data)
+        ALooper* looper, int ident, ALooper_callbackFunc* callback, void* data)
 {
     sp<SensorEventQueue> queue =
             static_cast<SensorManager*>(manager)->createEventQueue();
     if (queue != 0) {
-        ALooper_addFd(looper, queue->getFd(), POLLIN, callback, data);
+        ALooper_addFd(looper, queue->getFd(), ident, POLLIN, callback, data);
         queue->looper = looper;
         queue->incStrong(manager);
     }
diff --git a/native/include/android/input.h b/native/include/android/input.h
index 418f609..5b62da4 100644
--- a/native/include/android/input.h
+++ b/native/include/android/input.h
@@ -623,10 +623,10 @@
 
 /*
  * Add this input queue to a looper for processing.  See
- * ALooper_addFd() for information on the callback and data params.
+ * ALooper_addFd() for information on the ident, callback, and data params.
  */
 void AInputQueue_attachLooper(AInputQueue* queue, ALooper* looper,
-        ALooper_callbackFunc* callback, void* data);
+        int ident, ALooper_callbackFunc* callback, void* data);
 
 /*
  * Remove the input queue from the looper it is currently attached to.
diff --git a/native/include/android/looper.h b/native/include/android/looper.h
index 2917216..287bcd5 100644
--- a/native/include/android/looper.h
+++ b/native/include/android/looper.h
@@ -111,7 +111,7 @@
  *
  * Returns ALOPER_POLL_ERROR if an error occurred.
  *
- * Returns a value >= 0 containing a file descriptor if it has data
+ * Returns a value >= 0 containing an identifier if its file descriptor has data
  * and it has no callback function (requiring the caller here to handle it).
  * In this (and only this) case outEvents and outData will contain the poll
  * events and data associated with the fd.
@@ -145,10 +145,12 @@
  * descriptor was previously added, it is replaced.
  *
  * "fd" is the file descriptor to be added.
+ * "ident" is an identifier for this event, which is returned from
+ * ALooper_pollOnce().  Must be >= 0, or ALOOPER_POLL_CALLBACK if
+ * providing a non-NULL callback.
  * "events" are the poll events to wake up on.  Typically this is POLLIN.
  * "callback" is the function to call when there is an event on the file
  * descriptor.
- * "id" is an identifier to associated with this file descriptor, or 0.
  * "data" is a private data pointer to supply to the callback.
  *
  * There are two main uses of this function:
@@ -156,13 +158,13 @@
  * (1) If "callback" is non-NULL, then
  * this function will be called when there is data on the file descriptor.  It
  * should execute any events it has pending, appropriately reading from the
- * file descriptor.
+ * file descriptor.  The 'ident' is ignored in this case.
  *
- * (2) If "callback" is NULL, the fd will be returned by ALooper_pollOnce
- * when it has data available, requiring the caller to take care of processing
- * it.
+ * (2) If "callback" is NULL, the 'ident' will be returned by ALooper_pollOnce
+ * when its file descriptor has data available, requiring the caller to take
+ * care of processing it.
  */
-void ALooper_addFd(ALooper* looper, int fd, int events,
+void ALooper_addFd(ALooper* looper, int fd, int ident, int events,
         ALooper_callbackFunc* callback, void* data);
 
 /**
diff --git a/native/include/android/sensor.h b/native/include/android/sensor.h
index b4ce024..a102d43 100644
--- a/native/include/android/sensor.h
+++ b/native/include/android/sensor.h
@@ -166,7 +166,7 @@
  * Creates a new sensor event queue and associate it with a looper.
  */
 ASensorEventQueue* ASensorManager_createEventQueue(ASensorManager* manager,
-        ALooper* looper, ALooper_callbackFunc* callback, void* data);
+        ALooper* looper, int ident, ALooper_callbackFunc* callback, void* data);
 
 /*
  * Destroys the event queue and free all resources associated to it.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarService.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarService.java
index 8f2da7a..af736aa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarService.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarService.java
@@ -46,6 +46,7 @@
 import android.os.Message;
 import android.os.ServiceManager;
 import android.os.SystemClock;
+import android.text.TextUtils;
 import android.util.Slog;
 import android.util.Log;
 import android.view.Display;
@@ -462,7 +463,11 @@
         }
 
         // Restart the ticker if it's still running
-        tick(notification);
+        if (notification.notification.tickerText != null
+                && !TextUtils.equals(notification.notification.tickerText,
+                    oldEntry.notification.notification.tickerText)) {
+            tick(notification);
+        }
 
         // Recalculate the position of the sliding windows and the titles.
         setAreThereNotifications();