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 — 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 — 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—including blind stupidity.</p>
-<p>—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>—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 — that is, not until you have a
-perfectly clear and unoptimized solution. </li>
-</ul>
-<p>—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 — 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>—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();