Merge "Improve View layoutDirection resolution"
diff --git a/api/current.txt b/api/current.txt
index edd56fe..327c98e 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -2744,6 +2744,7 @@
method public static boolean isUserAMonkey();
method public void killBackgroundProcesses(java.lang.String);
method public void moveTaskToFront(int, int);
+ method public void moveTaskToFront(int, int, android.os.Bundle);
method public deprecated void restartPackage(java.lang.String);
field public static final int MOVE_TASK_NO_USER_ACTION = 2; // 0x2
field public static final int MOVE_TASK_WITH_HOME = 1; // 0x1
@@ -2867,9 +2868,14 @@
public class ActivityOptions {
method public void join(android.app.ActivityOptions);
method public static android.app.ActivityOptions makeCustomAnimation(android.content.Context, int, int);
+ method public static android.app.ActivityOptions makeThumbnailScaleUpAnimation(android.view.View, android.graphics.Bitmap, int, int, android.app.ActivityOptions.OnAnimationStartedListener);
method public android.os.Bundle toBundle();
}
+ public static abstract interface ActivityOptions.OnAnimationStartedListener {
+ method public abstract void onAnimationStarted();
+ }
+
public class AlarmManager {
method public void cancel(android.app.PendingIntent);
method public void set(int, long, android.app.PendingIntent);
@@ -5204,6 +5210,7 @@
field public static final java.lang.String LAYOUT_INFLATER_SERVICE = "layout_inflater";
field public static final java.lang.String LOCATION_SERVICE = "location";
field public static final int MODE_APPEND = 32768; // 0x8000
+ field public static final int MODE_ENABLE_WRITE_AHEAD_LOGGING = 8; // 0x8
field public static final int MODE_MULTI_PROCESS = 4; // 0x4
field public static final int MODE_PRIVATE = 0; // 0x0
field public static final int MODE_WORLD_READABLE = 1; // 0x1
@@ -7334,6 +7341,7 @@
method public deprecated boolean isDbLockedByOtherThreads();
method public boolean isOpen();
method public boolean isReadOnly();
+ method public boolean isWriteAheadLoggingEnabled();
method public deprecated void markTableSyncable(java.lang.String, java.lang.String);
method public deprecated void markTableSyncable(java.lang.String, java.lang.String, java.lang.String);
method public boolean needUpgrade(int);
@@ -7356,6 +7364,7 @@
method public static int releaseMemory();
method public long replace(java.lang.String, java.lang.String, android.content.ContentValues);
method public long replaceOrThrow(java.lang.String, java.lang.String, android.content.ContentValues) throws android.database.SQLException;
+ method public void setForeignKeyConstraintsEnabled(boolean);
method public void setLocale(java.util.Locale);
method public deprecated void setLockingEnabled(boolean);
method public void setMaxSqlCacheSize(int);
@@ -7375,6 +7384,7 @@
field public static final int CONFLICT_REPLACE = 5; // 0x5
field public static final int CONFLICT_ROLLBACK = 1; // 0x1
field public static final int CREATE_IF_NECESSARY = 268435456; // 0x10000000
+ field public static final int ENABLE_WRITE_AHEAD_LOGGING = 536870912; // 0x20000000
field public static final int MAX_SQL_CACHE_SIZE = 100; // 0x64
field public static final int NO_LOCALIZED_COLLATORS = 16; // 0x10
field public static final int OPEN_READONLY = 1; // 0x1
@@ -7434,10 +7444,12 @@
method public java.lang.String getDatabaseName();
method public android.database.sqlite.SQLiteDatabase getReadableDatabase();
method public android.database.sqlite.SQLiteDatabase getWritableDatabase();
+ method public void onConfigure(android.database.sqlite.SQLiteDatabase);
method public abstract void onCreate(android.database.sqlite.SQLiteDatabase);
method public void onDowngrade(android.database.sqlite.SQLiteDatabase, int, int);
method public void onOpen(android.database.sqlite.SQLiteDatabase);
method public abstract void onUpgrade(android.database.sqlite.SQLiteDatabase, int, int);
+ method public void setWriteAheadLoggingEnabled(boolean);
}
public class SQLiteOutOfMemoryException extends android.database.sqlite.SQLiteException {
@@ -11912,8 +11924,10 @@
method public java.lang.String[] getDefaultCipherSuites();
method public static org.apache.http.conn.ssl.SSLSocketFactory getHttpSocketFactory(int, android.net.SSLSessionCache);
method public static javax.net.ssl.SSLSocketFactory getInsecure(int, android.net.SSLSessionCache);
+ method public byte[] getNpnSelectedProtocol(java.net.Socket);
method public java.lang.String[] getSupportedCipherSuites();
method public void setKeyManagers(javax.net.ssl.KeyManager[]);
+ method public void setNpnProtocols(byte[][]);
method public void setTrustManagers(javax.net.ssl.TrustManager[]);
}
@@ -27261,6 +27275,8 @@
method public void setShort(int, java.lang.String, short);
method public void setString(int, java.lang.String, java.lang.String);
method public void setTextColor(int, int);
+ method public void setTextViewCompoundDrawables(int, int, int, int, int);
+ method public void setTextViewCompoundDrawablesRelative(int, int, int, int, int);
method public void setTextViewText(int, java.lang.CharSequence);
method public void setUri(int, java.lang.String, android.net.Uri);
method public void setViewVisibility(int, int);
diff --git a/build/jarjar-rules.txt b/build/jarjar-rules.txt
deleted file mode 100644
index 5fdb022..0000000
--- a/build/jarjar-rules.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-rule org.apache.commons com.android.internal.apache.commons
-
diff --git a/build/phone-hdpi-512-dalvik-heap.mk b/build/phone-hdpi-512-dalvik-heap.mk
deleted file mode 100644
index 16e0505..0000000
--- a/build/phone-hdpi-512-dalvik-heap.mk
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# Copyright (C) 2010 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-# Provides overrides to configure the Dalvik heap for a standard high density
-# phone with around 512MB total RAM.
-
-PRODUCT_PROPERTY_OVERRIDES += \
- dalvik.vm.heapstartsize=5m \
- dalvik.vm.heapgrowthlimit=48m \
- dalvik.vm.heapsize=128m
diff --git a/build/phone-hdpi-dalvik-heap.mk b/build/phone-hdpi-dalvik-heap.mk
deleted file mode 100644
index ab33b96..0000000
--- a/build/phone-hdpi-dalvik-heap.mk
+++ /dev/null
@@ -1,21 +0,0 @@
-#
-# Copyright (C) 2010 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-# Provides overrides to configure the Dalvik heap for a standard high density phone.
-
-PRODUCT_PROPERTY_OVERRIDES += \
- dalvik.vm.heapstartsize=5m \
- dalvik.vm.heapsize=32m
diff --git a/build/phone-xhdpi-1024-dalvik-heap.mk b/build/phone-xhdpi-1024-dalvik-heap.mk
deleted file mode 100644
index f76535a..0000000
--- a/build/phone-xhdpi-1024-dalvik-heap.mk
+++ /dev/null
@@ -1,22 +0,0 @@
-#
-# Copyright (C) 2011 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-# Provides overrides to configure the Dalvik heap for a standard tablet device.
-
-PRODUCT_PROPERTY_OVERRIDES += \
- dalvik.vm.heapstartsize=8m \
- dalvik.vm.heapgrowthlimit=64m \
- dalvik.vm.heapsize=256m
diff --git a/build/tablet-dalvik-heap.mk b/build/tablet-dalvik-heap.mk
deleted file mode 100644
index 826a380..0000000
--- a/build/tablet-dalvik-heap.mk
+++ /dev/null
@@ -1,22 +0,0 @@
-#
-# Copyright (C) 2010 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-# Provides overrides to configure the Dalvik heap for a standard tablet device.
-
-PRODUCT_PROPERTY_OVERRIDES += \
- dalvik.vm.heapstartsize=5m \
- dalvik.vm.heapgrowthlimit=48m \
- dalvik.vm.heapsize=256m
diff --git a/cmds/dumpstate/Android.mk b/cmds/dumpstate/Android.mk
deleted file mode 100644
index d602500..0000000
--- a/cmds/dumpstate/Android.mk
+++ /dev/null
@@ -1,19 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-ifdef BOARD_WLAN_DEVICE
-LOCAL_CFLAGS := -DFWDUMP_$(BOARD_WLAN_DEVICE)
-endif
-
-LOCAL_SRC_FILES := dumpstate.c utils.c
-
-LOCAL_MODULE := dumpstate
-
-LOCAL_SHARED_LIBRARIES := libcutils
-
-ifdef BOARD_LIB_DUMPSTATE
-LOCAL_STATIC_LIBRARIES := $(BOARD_LIB_DUMPSTATE)
-LOCAL_CFLAGS += -DBOARD_HAS_DUMPSTATE
-endif
-
-include $(BUILD_EXECUTABLE)
diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c
deleted file mode 100644
index aa95b35..0000000
--- a/cmds/dumpstate/dumpstate.c
+++ /dev/null
@@ -1,452 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/resource.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#include <linux/capability.h>
-#include <linux/prctl.h>
-
-#include <cutils/properties.h>
-
-#include "private/android_filesystem_config.h"
-
-#define LOG_TAG "dumpstate"
-#include <utils/Log.h>
-
-#include "dumpstate.h"
-
-/* read before root is shed */
-static char cmdline_buf[16384] = "(unknown)";
-static const char *dump_traces_path = NULL;
-
-static char screenshot_path[PATH_MAX] = "";
-
-/* dumps the current system state to stdout */
-static void dumpstate() {
- time_t now = time(NULL);
- char build[PROPERTY_VALUE_MAX], fingerprint[PROPERTY_VALUE_MAX];
- char radio[PROPERTY_VALUE_MAX], bootloader[PROPERTY_VALUE_MAX];
- char network[PROPERTY_VALUE_MAX], date[80];
- char build_type[PROPERTY_VALUE_MAX];
-
- property_get("ro.build.display.id", build, "(unknown)");
- property_get("ro.build.fingerprint", fingerprint, "(unknown)");
- property_get("ro.build.type", build_type, "(unknown)");
- property_get("ro.baseband", radio, "(unknown)");
- property_get("ro.bootloader", bootloader, "(unknown)");
- property_get("gsm.operator.alpha", network, "(unknown)");
- strftime(date, sizeof(date), "%Y-%m-%d %H:%M:%S", localtime(&now));
-
- printf("========================================================\n");
- printf("== dumpstate: %s\n", date);
- printf("========================================================\n");
-
- printf("\n");
- printf("Build: %s\n", build);
- printf("Build fingerprint: '%s'\n", fingerprint); /* format is important for other tools */
- printf("Bootloader: %s\n", bootloader);
- printf("Radio: %s\n", radio);
- printf("Network: %s\n", network);
-
- printf("Kernel: ");
- dump_file(NULL, "/proc/version");
- printf("Command line: %s\n", strtok(cmdline_buf, "\n"));
- printf("\n");
-
- run_command("UPTIME", 10, "uptime", NULL);
- dump_file("MEMORY INFO", "/proc/meminfo");
- run_command("CPU INFO", 10, "top", "-n", "1", "-d", "1", "-m", "30", "-t", NULL);
- run_command("PROCRANK", 20, "procrank", NULL);
- dump_file("VIRTUAL MEMORY STATS", "/proc/vmstat");
- dump_file("VMALLOC INFO", "/proc/vmallocinfo");
- dump_file("SLAB INFO", "/proc/slabinfo");
- dump_file("ZONEINFO", "/proc/zoneinfo");
- dump_file("PAGETYPEINFO", "/proc/pagetypeinfo");
- dump_file("BUDDYINFO", "/proc/buddyinfo");
-
-
- dump_file("KERNEL WAKELOCKS", "/proc/wakelocks");
- dump_file("KERNEL CPUFREQ", "/sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state");
-
- run_command("PROCESSES", 10, "ps", "-P", NULL);
- run_command("PROCESSES AND THREADS", 10, "ps", "-t", "-p", "-P", NULL);
- run_command("LIBRANK", 10, "librank", NULL);
-
- do_dmesg();
-
- run_command("LIST OF OPEN FILES", 10, SU_PATH, "root", "lsof", NULL);
-
- for_each_pid(do_showmap, "SMAPS OF ALL PROCESSES");
- for_each_pid(show_wchan, "BLOCKED PROCESS WAIT-CHANNELS");
-
- // dump_file("EVENT LOG TAGS", "/etc/event-log-tags");
- run_command("SYSTEM LOG", 20, "logcat", "-v", "threadtime", "-d", "*:v", NULL);
- run_command("EVENT LOG", 20, "logcat", "-b", "events", "-v", "threadtime", "-d", "*:v", NULL);
- run_command("RADIO LOG", 20, "logcat", "-b", "radio", "-v", "threadtime", "-d", "*:v", NULL);
-
-
- /* show the traces we collected in main(), if that was done */
- if (dump_traces_path != NULL) {
- dump_file("VM TRACES JUST NOW", dump_traces_path);
- }
-
- /* only show ANR traces if they're less than 15 minutes old */
- struct stat st;
- char anr_traces_path[PATH_MAX];
- property_get("dalvik.vm.stack-trace-file", anr_traces_path, "");
- if (!anr_traces_path[0]) {
- printf("*** NO VM TRACES FILE DEFINED (dalvik.vm.stack-trace-file)\n\n");
- } else if (stat(anr_traces_path, &st)) {
- printf("*** NO ANR VM TRACES FILE (%s): %s\n\n", anr_traces_path, strerror(errno));
- } else {
- dump_file("VM TRACES AT LAST ANR", anr_traces_path);
- }
-
- /* slow traces for slow operations */
- if (anr_traces_path[0] != 0) {
- int tail = strlen(anr_traces_path)-1;
- while (tail > 0 && anr_traces_path[tail] != '/') {
- tail--;
- }
- int i = 0;
- while (1) {
- sprintf(anr_traces_path+tail+1, "slow%02d.txt", i);
- if (stat(anr_traces_path, &st)) {
- // No traces file at this index, done with the files.
- break;
- }
- dump_file("VM TRACES WHEN SLOW", anr_traces_path);
- i++;
- }
- }
-
- dump_file("NETWORK DEV INFO", "/proc/net/dev");
- dump_file("QTAGUID NETWORK INTERFACES INFO", "/proc/net/xt_qtaguid/iface_stat_all");
- dump_file("QTAGUID CTRL INFO", "/proc/net/xt_qtaguid/ctrl");
- dump_file("QTAGUID STATS INFO", "/proc/net/xt_qtaguid/stats");
-
- dump_file("NETWORK ROUTES", "/proc/net/route");
- dump_file("NETWORK ROUTES IPV6", "/proc/net/ipv6_route");
-
- /* TODO: Make last_kmsg CAP_SYSLOG protected. b/5555691 */
- dump_file("LAST KMSG", "/proc/last_kmsg");
- dump_file("LAST PANIC CONSOLE", "/data/dontpanic/apanic_console");
- dump_file("LAST PANIC THREADS", "/data/dontpanic/apanic_threads");
-
- if (screenshot_path[0]) {
- ALOGI("taking screenshot\n");
- run_command(NULL, 5, SU_PATH, "root", "screenshot", screenshot_path, NULL);
- ALOGI("wrote screenshot: %s\n", screenshot_path);
- }
-
- run_command("SYSTEM SETTINGS", 20, SU_PATH, "root", "sqlite3",
- "/data/data/com.android.providers.settings/databases/settings.db",
- "pragma user_version; select * from system; select * from secure;", NULL);
-
- /* The following have a tendency to get wedged when wifi drivers/fw goes belly-up. */
- run_command("NETWORK INTERFACES", 10, SU_PATH, "root", "netcfg", NULL);
- run_command("IP RULES", 10, "ip", "rule", "show", NULL);
- run_command("IP RULES v6", 10, "ip", "-6", "rule", "show", NULL);
- run_command("ROUTE TABLE 60", 10, "ip", "route", "show", "table", "60", NULL);
- run_command("ROUTE TABLE 61 v6", 10, "ip", "-6", "route", "show", "table", "60", NULL);
- run_command("ROUTE TABLE 61", 10, "ip", "route", "show", "table", "61", NULL);
- run_command("ROUTE TABLE 61 v6", 10, "ip", "-6", "route", "show", "table", "61", NULL);
- dump_file("ARP CACHE", "/proc/net/arp");
- run_command("IPTABLES", 10, SU_PATH, "root", "iptables", "-L", "-nvx", NULL);
- run_command("IP6TABLES", 10, SU_PATH, "root", "ip6tables", "-L", "-nvx", NULL);
- run_command("IPTABLE NAT", 10, SU_PATH, "root", "iptables", "-t", "nat", "-L", "-n", NULL);
- run_command("IPT6ABLE NAT", 10, SU_PATH, "root", "ip6tables", "-t", "nat", "-L", "-n", NULL);
-
- run_command("WIFI NETWORKS", 20,
- SU_PATH, "root", "wpa_cli", "list_networks", NULL);
-
- property_get("dhcp.wlan0.gateway", network, "");
- if (network[0])
- run_command("PING GATEWAY", 10, SU_PATH, "root", "ping", "-c", "3", "-i", ".5", network, NULL);
- property_get("dhcp.wlan0.dns1", network, "");
- if (network[0])
- run_command("PING DNS1", 10, SU_PATH, "root", "ping", "-c", "3", "-i", ".5", network, NULL);
- property_get("dhcp.wlan0.dns2", network, "");
- if (network[0])
- run_command("PING DNS2", 10, SU_PATH, "root", "ping", "-c", "3", "-i", ".5", network, NULL);
-#ifdef FWDUMP_bcm4329
- run_command("DUMP WIFI STATUS", 20,
- SU_PATH, "root", "dhdutil", "-i", "wlan0", "dump", NULL);
- run_command("DUMP WIFI INTERNAL COUNTERS", 20,
- SU_PATH, "root", "wlutil", "counters", NULL);
-#endif
-
- print_properties();
-
- run_command("VOLD DUMP", 10, "vdc", "dump", NULL);
- run_command("SECURE CONTAINERS", 10, "vdc", "asec", "list", NULL);
-
- run_command("FILESYSTEMS & FREE SPACE", 10, SU_PATH, "root", "df", NULL);
-
- dump_file("PACKAGE SETTINGS", "/data/system/packages.xml");
- dump_file("PACKAGE UID ERRORS", "/data/system/uiderrors.txt");
-
- run_command("LAST RADIO LOG", 10, "parse_radio_log", "/proc/last_radio_log", NULL);
-
- printf("------ BACKLIGHTS ------\n");
- printf("LCD brightness=");
- dump_file(NULL, "/sys/class/leds/lcd-backlight/brightness");
- printf("Button brightness=");
- dump_file(NULL, "/sys/class/leds/button-backlight/brightness");
- printf("Keyboard brightness=");
- dump_file(NULL, "/sys/class/leds/keyboard-backlight/brightness");
- printf("ALS mode=");
- dump_file(NULL, "/sys/class/leds/lcd-backlight/als");
- printf("LCD driver registers:\n");
- dump_file(NULL, "/sys/class/leds/lcd-backlight/registers");
- printf("\n");
-
- /* Binder state is expensive to look at as it uses a lot of memory. */
- dump_file("BINDER FAILED TRANSACTION LOG", "/sys/kernel/debug/binder/failed_transaction_log");
- dump_file("BINDER TRANSACTION LOG", "/sys/kernel/debug/binder/transaction_log");
- dump_file("BINDER TRANSACTIONS", "/sys/kernel/debug/binder/transactions");
- dump_file("BINDER STATS", "/sys/kernel/debug/binder/stats");
- dump_file("BINDER STATE", "/sys/kernel/debug/binder/state");
-
-#ifdef BOARD_HAS_DUMPSTATE
- printf("========================================================\n");
- printf("== Board\n");
- printf("========================================================\n");
-
- dumpstate_board();
- printf("\n");
-#endif
-
- /* Migrate the ril_dumpstate to a dumpstate_board()? */
- char ril_dumpstate_timeout[PROPERTY_VALUE_MAX] = {0};
- property_get("ril.dumpstate.timeout", ril_dumpstate_timeout, "30");
- if (strnlen(ril_dumpstate_timeout, PROPERTY_VALUE_MAX - 1) > 0) {
- if (0 == strncmp(build_type, "user", PROPERTY_VALUE_MAX - 1)) {
- // su does not exist on user builds, so try running without it.
- // This way any implementations of vril-dump that do not require
- // root can run on user builds.
- run_command("DUMP VENDOR RIL LOGS", atoi(ril_dumpstate_timeout),
- "vril-dump", NULL);
- } else {
- run_command("DUMP VENDOR RIL LOGS", atoi(ril_dumpstate_timeout),
- SU_PATH, "root", "vril-dump", NULL);
- }
- }
-
- printf("========================================================\n");
- printf("== Android Framework Services\n");
- printf("========================================================\n");
-
- /* the full dumpsys is starting to take a long time, so we need
- to increase its timeout. we really need to do the timeouts in
- dumpsys itself... */
- run_command("DUMPSYS", 60, "dumpsys", NULL);
-
- printf("========================================================\n");
- printf("== Running Application Activities\n");
- printf("========================================================\n");
-
- run_command("APP ACTIVITIES", 30, "dumpsys", "activity", "all", NULL);
-
- printf("========================================================\n");
- printf("== Running Application Services\n");
- printf("========================================================\n");
-
- run_command("APP SERVICES", 30, "dumpsys", "activity", "service", "all", NULL);
-
- printf("========================================================\n");
- printf("== Running Application Providers\n");
- printf("========================================================\n");
-
- run_command("APP SERVICES", 30, "dumpsys", "activity", "provider", "all", NULL);
-
-
- printf("========================================================\n");
- printf("== dumpstate: done\n");
- printf("========================================================\n");
-}
-
-static void usage() {
- fprintf(stderr, "usage: dumpstate [-b soundfile] [-e soundfile] [-o file [-d] [-p] [-z]] [-s]\n"
- " -o: write to file (instead of stdout)\n"
- " -d: append date to filename (requires -o)\n"
- " -z: gzip output (requires -o)\n"
- " -p: capture screenshot to filename.png (requires -o)\n"
- " -s: write output to control socket (for init)\n"
- " -b: play sound file instead of vibrate, at beginning of job\n"
- " -e: play sound file instead of vibrate, at end of job\n"
- );
-}
-
-int main(int argc, char *argv[]) {
- int do_add_date = 0;
- int do_compress = 0;
- char* use_outfile = 0;
- char* begin_sound = 0;
- char* end_sound = 0;
- int use_socket = 0;
- int do_fb = 0;
-
- ALOGI("begin\n");
-
- /* set as high priority, and protect from OOM killer */
- setpriority(PRIO_PROCESS, 0, -20);
- FILE *oom_adj = fopen("/proc/self/oom_adj", "w");
- if (oom_adj) {
- fputs("-17", oom_adj);
- fclose(oom_adj);
- }
-
- /* very first thing, collect VM traces from Dalvik (needs root) */
- dump_traces_path = dump_vm_traces();
-
- int c;
- while ((c = getopt(argc, argv, "b:de:ho:svzp")) != -1) {
- switch (c) {
- case 'b': begin_sound = optarg; break;
- case 'd': do_add_date = 1; break;
- case 'e': end_sound = optarg; break;
- case 'o': use_outfile = optarg; break;
- case 's': use_socket = 1; break;
- case 'v': break; // compatibility no-op
- case 'z': do_compress = 6; break;
- case 'p': do_fb = 1; break;
- case '?': printf("\n");
- case 'h':
- usage();
- exit(1);
- }
- }
-
- /* open the vibrator before dropping root */
- FILE *vibrator = fopen("/sys/class/timed_output/vibrator/enable", "w");
- if (vibrator) fcntl(fileno(vibrator), F_SETFD, FD_CLOEXEC);
-
- /* read /proc/cmdline before dropping root */
- FILE *cmdline = fopen("/proc/cmdline", "r");
- if (cmdline != NULL) {
- fgets(cmdline_buf, sizeof(cmdline_buf), cmdline);
- fclose(cmdline);
- }
-
- if (getuid() == 0) {
- if (prctl(PR_SET_KEEPCAPS, 1) < 0) {
- ALOGE("prctl(PR_SET_KEEPCAPS) failed: %s\n", strerror(errno));
- return -1;
- }
-
- /* switch to non-root user and group */
- gid_t groups[] = { AID_LOG, AID_SDCARD_RW, AID_MOUNT, AID_INET, AID_NET_BW_STATS };
- if (setgroups(sizeof(groups)/sizeof(groups[0]), groups) != 0) {
- ALOGE("Unable to setgroups, aborting: %s\n", strerror(errno));
- return -1;
- }
- if (setgid(AID_SHELL) != 0) {
- ALOGE("Unable to setgid, aborting: %s\n", strerror(errno));
- return -1;
- }
- if (setuid(AID_SHELL) != 0) {
- ALOGE("Unable to setuid, aborting: %s\n", strerror(errno));
- return -1;
- }
-
- struct __user_cap_header_struct capheader;
- struct __user_cap_data_struct capdata[2];
- memset(&capheader, 0, sizeof(capheader));
- memset(&capdata, 0, sizeof(capdata));
- capheader.version = _LINUX_CAPABILITY_VERSION_3;
- capheader.pid = 0;
-
- capdata[CAP_TO_INDEX(CAP_SYSLOG)].permitted = CAP_TO_MASK(CAP_SYSLOG);
- capdata[CAP_TO_INDEX(CAP_SYSLOG)].effective = CAP_TO_MASK(CAP_SYSLOG);
- capdata[0].inheritable = 0;
- capdata[1].inheritable = 0;
-
- if (capset(&capheader, &capdata[0]) < 0) {
- ALOGE("capset failed: %s\n", strerror(errno));
- return -1;
- }
- }
-
- char path[PATH_MAX], tmp_path[PATH_MAX];
- pid_t gzip_pid = -1;
-
- if (use_socket) {
- redirect_to_socket(stdout, "dumpstate");
- } else if (use_outfile) {
- strlcpy(path, use_outfile, sizeof(path));
- if (do_add_date) {
- char date[80];
- time_t now = time(NULL);
- strftime(date, sizeof(date), "-%Y-%m-%d-%H-%M-%S", localtime(&now));
- strlcat(path, date, sizeof(path));
- }
- if (do_fb) {
- strlcpy(screenshot_path, path, sizeof(screenshot_path));
- strlcat(screenshot_path, ".png", sizeof(screenshot_path));
- }
- strlcat(path, ".txt", sizeof(path));
- if (do_compress) strlcat(path, ".gz", sizeof(path));
- strlcpy(tmp_path, path, sizeof(tmp_path));
- strlcat(tmp_path, ".tmp", sizeof(tmp_path));
- gzip_pid = redirect_to_file(stdout, tmp_path, do_compress);
- }
-
- if (begin_sound) {
- play_sound(begin_sound);
- } else if (vibrator) {
- fputs("150", vibrator);
- fflush(vibrator);
- }
-
- dumpstate();
-
- if (end_sound) {
- play_sound(end_sound);
- } else if (vibrator) {
- int i;
- for (i = 0; i < 3; i++) {
- fputs("75\n", vibrator);
- fflush(vibrator);
- usleep((75 + 50) * 1000);
- }
- fclose(vibrator);
- }
-
- /* wait for gzip to finish, otherwise it might get killed when we exit */
- if (gzip_pid > 0) {
- fclose(stdout);
- waitpid(gzip_pid, NULL, 0);
- }
-
- /* rename the (now complete) .tmp file to its final location */
- if (use_outfile && rename(tmp_path, path)) {
- fprintf(stderr, "rename(%s, %s): %s\n", tmp_path, path, strerror(errno));
- }
-
- ALOGI("done\n");
-
- return 0;
-}
diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h
deleted file mode 100644
index c1c2ad8..0000000
--- a/cmds/dumpstate/dumpstate.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _DUMPSTATE_H_
-#define _DUMPSTATE_H_
-
-#include <time.h>
-#include <unistd.h>
-#include <stdio.h>
-
-#define SU_PATH "/system/xbin/su"
-
-/* prints the contents of a file */
-int dump_file(const char *title, const char* path);
-
-/* forks a command and waits for it to finish -- terminate args with NULL */
-int run_command(const char *title, int timeout_seconds, const char *command, ...);
-
-/* prints all the system properties */
-void print_properties();
-
-/* redirect output to a service control socket */
-void redirect_to_socket(FILE *redirect, const char *service);
-
-/* redirect output to a file, optionally gzipping; returns gzip pid */
-pid_t redirect_to_file(FILE *redirect, char *path, int gzip_level);
-
-/* dump Dalvik stack traces, return the trace file location (NULL if none) */
-const char *dump_vm_traces();
-
-/* for each process in the system, run the specified function */
-void for_each_pid(void (*func)(int, const char *), const char *header);
-
-/* Displays a blocked processes in-kernel wait channel */
-void show_wchan(int pid, const char *name);
-
-/* Runs "showmap" for a process */
-void do_showmap(int pid, const char *name);
-
-/* Gets the dmesg output for the kernel */
-void do_dmesg();
-
-/* Play a sound via Stagefright */
-void play_sound(const char* path);
-
-/* Implemented by libdumpstate_board to dump board-specific info */
-void dumpstate_board();
-
-#endif /* _DUMPSTATE_H_ */
diff --git a/cmds/dumpstate/utils.c b/cmds/dumpstate/utils.c
deleted file mode 100644
index 0d5ab90..0000000
--- a/cmds/dumpstate/utils.c
+++ /dev/null
@@ -1,470 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <poll.h>
-#include <signal.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/inotify.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <sys/wait.h>
-#include <sys/klog.h>
-#include <time.h>
-#include <unistd.h>
-
-#include <cutils/properties.h>
-#include <cutils/sockets.h>
-#include <private/android_filesystem_config.h>
-
-#include "dumpstate.h"
-
-void for_each_pid(void (*func)(int, const char *), const char *header) {
- DIR *d;
- struct dirent *de;
-
- if (!(d = opendir("/proc"))) {
- printf("Failed to open /proc (%s)\n", strerror(errno));
- return;
- }
-
- printf("\n------ %s ------\n", header);
- while ((de = readdir(d))) {
- int pid;
- int fd;
- char cmdpath[255];
- char cmdline[255];
-
- if (!(pid = atoi(de->d_name))) {
- continue;
- }
-
- sprintf(cmdpath,"/proc/%d/cmdline", pid);
- memset(cmdline, 0, sizeof(cmdline));
- if ((fd = open(cmdpath, O_RDONLY)) < 0) {
- strcpy(cmdline, "N/A");
- } else {
- read(fd, cmdline, sizeof(cmdline));
- close(fd);
- }
- func(pid, cmdline);
- }
-
- closedir(d);
-}
-
-void show_wchan(int pid, const char *name) {
- char path[255];
- char buffer[255];
- int fd;
-
- memset(buffer, 0, sizeof(buffer));
-
- sprintf(path, "/proc/%d/wchan", pid);
- if ((fd = open(path, O_RDONLY)) < 0) {
- printf("Failed to open '%s' (%s)\n", path, strerror(errno));
- return;
- }
-
- if (read(fd, buffer, sizeof(buffer)) < 0) {
- printf("Failed to read '%s' (%s)\n", path, strerror(errno));
- goto out_close;
- }
-
- printf("%-7d %-32s %s\n", pid, name, buffer);
-
-out_close:
- close(fd);
- return;
-}
-
-void do_dmesg() {
- printf("------ KERNEL LOG (dmesg) ------\n");
- int size = klogctl(10, NULL, 0); /* Get size of kernel buffer */
- if (size <= 0) {
- printf("Unexpected klogctl return value: %d\n\n", size);
- return;
- }
- char *buf = (char *) malloc(size + 1);
- if (buf == NULL) {
- printf("memory allocation failed\n\n");
- return;
- }
- int retval = klogctl(KLOG_READ_ALL, buf, size);
- if (retval < 0) {
- printf("klogctl failure\n\n");
- free(buf);
- return;
- }
- buf[retval] = '\0';
- printf("%s\n\n", buf);
- free(buf);
- return;
-}
-
-void do_showmap(int pid, const char *name) {
- char title[255];
- char arg[255];
-
- sprintf(title, "SHOW MAP %d (%s)", pid, name);
- sprintf(arg, "%d", pid);
- run_command(title, 10, SU_PATH, "root", "showmap", arg, NULL);
-}
-
-/* prints the contents of a file */
-int dump_file(const char *title, const char* path) {
- char buffer[32768];
- int fd = open(path, O_RDONLY);
- if (fd < 0) {
- int err = errno;
- if (title) printf("------ %s (%s) ------\n", title, path);
- printf("*** %s: %s\n", path, strerror(err));
- if (title) printf("\n");
- return -1;
- }
-
- if (title) printf("------ %s (%s", title, path);
-
- if (title) {
- struct stat st;
- if (memcmp(path, "/proc/", 6) && memcmp(path, "/sys/", 5) && !fstat(fd, &st)) {
- char stamp[80];
- time_t mtime = st.st_mtime;
- strftime(stamp, sizeof(stamp), "%Y-%m-%d %H:%M:%S", localtime(&mtime));
- printf(": %s", stamp);
- }
- printf(") ------\n");
- }
-
- int newline = 0;
- for (;;) {
- int ret = read(fd, buffer, sizeof(buffer));
- if (ret > 0) {
- newline = (buffer[ret - 1] == '\n');
- ret = fwrite(buffer, ret, 1, stdout);
- }
- if (ret <= 0) break;
- }
-
- close(fd);
- if (!newline) printf("\n");
- if (title) printf("\n");
- return 0;
-}
-
-/* forks a command and waits for it to finish */
-int run_command(const char *title, int timeout_seconds, const char *command, ...) {
- fflush(stdout);
- clock_t start = clock();
- pid_t pid = fork();
-
- /* handle error case */
- if (pid < 0) {
- printf("*** fork: %s\n", strerror(errno));
- return pid;
- }
-
- /* handle child case */
- if (pid == 0) {
- const char *args[1024] = {command};
- size_t arg;
-
- va_list ap;
- va_start(ap, command);
- if (title) printf("------ %s (%s", title, command);
- for (arg = 1; arg < sizeof(args) / sizeof(args[0]); ++arg) {
- args[arg] = va_arg(ap, const char *);
- if (args[arg] == NULL) break;
- if (title) printf(" %s", args[arg]);
- }
- if (title) printf(") ------\n");
- fflush(stdout);
-
- execvp(command, (char**) args);
- printf("*** exec(%s): %s\n", command, strerror(errno));
- fflush(stdout);
- _exit(-1);
- }
-
- /* handle parent case */
- for (;;) {
- int status;
- pid_t p = waitpid(pid, &status, WNOHANG);
- float elapsed = (float) (clock() - start) / CLOCKS_PER_SEC;
- if (p == pid) {
- if (WIFSIGNALED(status)) {
- printf("*** %s: Killed by signal %d\n", command, WTERMSIG(status));
- } else if (WIFEXITED(status) && WEXITSTATUS(status) > 0) {
- printf("*** %s: Exit code %d\n", command, WEXITSTATUS(status));
- }
- if (title) printf("[%s: %.1fs elapsed]\n\n", command, elapsed);
- return status;
- }
-
- if (timeout_seconds && elapsed > timeout_seconds) {
- printf("*** %s: Timed out after %.1fs (killing pid %d)\n", command, elapsed, pid);
- kill(pid, SIGTERM);
- return -1;
- }
-
- usleep(100000); // poll every 0.1 sec
- }
-}
-
-size_t num_props = 0;
-static char* props[2000];
-
-static void print_prop(const char *key, const char *name, void *user) {
- (void) user;
- if (num_props < sizeof(props) / sizeof(props[0])) {
- char buf[PROPERTY_KEY_MAX + PROPERTY_VALUE_MAX + 10];
- snprintf(buf, sizeof(buf), "[%s]: [%s]\n", key, name);
- props[num_props++] = strdup(buf);
- }
-}
-
-static int compare_prop(const void *a, const void *b) {
- return strcmp(*(char * const *) a, *(char * const *) b);
-}
-
-/* prints all the system properties */
-void print_properties() {
- size_t i;
- num_props = 0;
- property_list(print_prop, NULL);
- qsort(&props, num_props, sizeof(props[0]), compare_prop);
-
- printf("------ SYSTEM PROPERTIES ------\n");
- for (i = 0; i < num_props; ++i) {
- fputs(props[i], stdout);
- free(props[i]);
- }
- printf("\n");
-}
-
-/* redirect output to a service control socket */
-void redirect_to_socket(FILE *redirect, const char *service) {
- int s = android_get_control_socket(service);
- if (s < 0) {
- fprintf(stderr, "android_get_control_socket(%s): %s\n", service, strerror(errno));
- exit(1);
- }
- if (listen(s, 4) < 0) {
- fprintf(stderr, "listen(control socket): %s\n", strerror(errno));
- exit(1);
- }
-
- struct sockaddr addr;
- socklen_t alen = sizeof(addr);
- int fd = accept(s, &addr, &alen);
- if (fd < 0) {
- fprintf(stderr, "accept(control socket): %s\n", strerror(errno));
- exit(1);
- }
-
- fflush(redirect);
- dup2(fd, fileno(redirect));
- close(fd);
-}
-
-/* redirect output to a file, optionally gzipping; returns gzip pid (or -1) */
-pid_t redirect_to_file(FILE *redirect, char *path, int gzip_level) {
- char *chp = path;
-
- /* skip initial slash */
- if (chp[0] == '/')
- chp++;
-
- /* create leading directories, if necessary */
- while (chp && chp[0]) {
- chp = strchr(chp, '/');
- if (chp) {
- *chp = 0;
- mkdir(path, 0775); /* drwxrwxr-x */
- *chp++ = '/';
- }
- }
-
- int fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
- if (fd < 0) {
- fprintf(stderr, "%s: %s\n", path, strerror(errno));
- exit(1);
- }
-
- pid_t gzip_pid = -1;
- if (gzip_level > 0) {
- int fds[2];
- if (pipe(fds)) {
- fprintf(stderr, "pipe: %s\n", strerror(errno));
- exit(1);
- }
-
- fflush(redirect);
- fflush(stdout);
-
- gzip_pid = fork();
- if (gzip_pid < 0) {
- fprintf(stderr, "fork: %s\n", strerror(errno));
- exit(1);
- }
-
- if (gzip_pid == 0) {
- dup2(fds[0], STDIN_FILENO);
- dup2(fd, STDOUT_FILENO);
-
- close(fd);
- close(fds[0]);
- close(fds[1]);
-
- char level[10];
- snprintf(level, sizeof(level), "-%d", gzip_level);
- execlp("gzip", "gzip", level, NULL);
- fprintf(stderr, "exec(gzip): %s\n", strerror(errno));
- _exit(-1);
- }
-
- close(fd);
- close(fds[0]);
- fd = fds[1];
- }
-
- dup2(fd, fileno(redirect));
- close(fd);
- return gzip_pid;
-}
-
-/* dump Dalvik stack traces, return the trace file location (NULL if none) */
-const char *dump_vm_traces() {
- char traces_path[PROPERTY_VALUE_MAX] = "";
- property_get("dalvik.vm.stack-trace-file", traces_path, "");
- if (!traces_path[0]) return NULL;
-
- /* move the old traces.txt (if any) out of the way temporarily */
- char anr_traces_path[PATH_MAX];
- strlcpy(anr_traces_path, traces_path, sizeof(anr_traces_path));
- strlcat(anr_traces_path, ".anr", sizeof(anr_traces_path));
- if (rename(traces_path, anr_traces_path) && errno != ENOENT) {
- fprintf(stderr, "rename(%s, %s): %s\n", traces_path, anr_traces_path, strerror(errno));
- return NULL; // Can't rename old traces.txt -- no permission? -- leave it alone instead
- }
-
- /* make the directory if necessary */
- char anr_traces_dir[PATH_MAX];
- strlcpy(anr_traces_dir, traces_path, sizeof(anr_traces_dir));
- char *slash = strrchr(anr_traces_dir, '/');
- if (slash != NULL) {
- *slash = '\0';
- if (!mkdir(anr_traces_dir, 0775)) {
- chown(anr_traces_dir, AID_SYSTEM, AID_SYSTEM);
- } else if (errno != EEXIST) {
- fprintf(stderr, "mkdir(%s): %s\n", anr_traces_dir, strerror(errno));
- return NULL;
- }
- }
-
- /* create a new, empty traces.txt file to receive stack dumps */
- int fd = open(traces_path, O_CREAT | O_WRONLY | O_TRUNC, 0666); /* -rw-rw-rw- */
- if (fd < 0) {
- fprintf(stderr, "%s: %s\n", traces_path, strerror(errno));
- return NULL;
- }
- close(fd);
-
- /* walk /proc and kill -QUIT all Dalvik processes */
- DIR *proc = opendir("/proc");
- if (proc == NULL) {
- fprintf(stderr, "/proc: %s\n", strerror(errno));
- return NULL;
- }
-
- /* use inotify to find when processes are done dumping */
- int ifd = inotify_init();
- if (ifd < 0) {
- fprintf(stderr, "inotify_init: %s\n", strerror(errno));
- return NULL;
- }
-
- int wfd = inotify_add_watch(ifd, traces_path, IN_CLOSE_WRITE);
- if (wfd < 0) {
- fprintf(stderr, "inotify_add_watch(%s): %s\n", traces_path, strerror(errno));
- return NULL;
- }
-
- struct dirent *d;
- int dalvik_found = 0;
- while ((d = readdir(proc))) {
- int pid = atoi(d->d_name);
- if (pid <= 0) continue;
-
- /* identify Dalvik: /proc/(pid)/exe = /system/bin/app_process */
- char path[PATH_MAX], data[PATH_MAX];
- snprintf(path, sizeof(path), "/proc/%d/exe", pid);
- size_t len = readlink(path, data, sizeof(data) - 1);
- if (len <= 0 || memcmp(data, "/system/bin/app_process", 23)) continue;
-
- /* skip zygote -- it won't dump its stack anyway */
- snprintf(path, sizeof(path), "/proc/%d/cmdline", pid);
- int fd = open(path, O_RDONLY);
- len = read(fd, data, sizeof(data) - 1);
- close(fd);
- if (len <= 0 || !memcmp(data, "zygote", 6)) continue;
-
- ++dalvik_found;
- if (kill(pid, SIGQUIT)) {
- fprintf(stderr, "kill(%d, SIGQUIT): %s\n", pid, strerror(errno));
- continue;
- }
-
- /* wait for the writable-close notification from inotify */
- struct pollfd pfd = { ifd, POLLIN, 0 };
- int ret = poll(&pfd, 1, 200); /* 200 msec timeout */
- if (ret < 0) {
- fprintf(stderr, "poll: %s\n", strerror(errno));
- } else if (ret == 0) {
- fprintf(stderr, "warning: timed out dumping pid %d\n", pid);
- } else {
- struct inotify_event ie;
- read(ifd, &ie, sizeof(ie));
- }
- }
-
- close(ifd);
- if (dalvik_found == 0) {
- fprintf(stderr, "Warning: no Dalvik processes found to dump stacks\n");
- }
-
- static char dump_traces_path[PATH_MAX];
- strlcpy(dump_traces_path, traces_path, sizeof(dump_traces_path));
- strlcat(dump_traces_path, ".bugreport", sizeof(dump_traces_path));
- if (rename(traces_path, dump_traces_path)) {
- fprintf(stderr, "rename(%s, %s): %s\n", traces_path, dump_traces_path, strerror(errno));
- return NULL;
- }
-
- /* replace the saved [ANR] traces.txt file */
- rename(anr_traces_path, traces_path);
- return dump_traces_path;
-}
-
-void play_sound(const char* path) {
- run_command(NULL, 5, "/system/bin/stagefright", "-o", "-a", path, NULL);
-}
diff --git a/cmds/dumpsys/Android.mk b/cmds/dumpsys/Android.mk
deleted file mode 100644
index 42b1b73..0000000
--- a/cmds/dumpsys/Android.mk
+++ /dev/null
@@ -1,19 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
- dumpsys.cpp
-
-LOCAL_SHARED_LIBRARIES := \
- libutils \
- libbinder
-
-
-ifeq ($(TARGET_OS),linux)
- LOCAL_CFLAGS += -DXP_UNIX
- #LOCAL_SHARED_LIBRARIES += librt
-endif
-
-LOCAL_MODULE:= dumpsys
-
-include $(BUILD_EXECUTABLE)
diff --git a/cmds/dumpsys/MODULE_LICENSE_APACHE2 b/cmds/dumpsys/MODULE_LICENSE_APACHE2
deleted file mode 100644
index e69de29..0000000
--- a/cmds/dumpsys/MODULE_LICENSE_APACHE2
+++ /dev/null
diff --git a/cmds/dumpsys/NOTICE b/cmds/dumpsys/NOTICE
deleted file mode 100644
index c5b1efa..0000000
--- a/cmds/dumpsys/NOTICE
+++ /dev/null
@@ -1,190 +0,0 @@
-
- Copyright (c) 2005-2008, The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
diff --git a/cmds/dumpsys/dumpsys.cpp b/cmds/dumpsys/dumpsys.cpp
deleted file mode 100644
index 7dad6b6..0000000
--- a/cmds/dumpsys/dumpsys.cpp
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Command that dumps interesting system state to the log.
- *
- */
-
-#define LOG_TAG "dumpsys"
-
-#include <utils/Log.h>
-#include <binder/Parcel.h>
-#include <binder/ProcessState.h>
-#include <binder/IServiceManager.h>
-#include <utils/TextOutput.h>
-#include <utils/Vector.h>
-
-#include <getopt.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/time.h>
-
-using namespace android;
-
-static int sort_func(const String16* lhs, const String16* rhs)
-{
- return lhs->compare(*rhs);
-}
-
-int main(int argc, char* const argv[])
-{
- sp<IServiceManager> sm = defaultServiceManager();
- fflush(stdout);
- if (sm == NULL) {
- ALOGE("Unable to get default service manager!");
- aerr << "dumpsys: Unable to get default service manager!" << endl;
- return 20;
- }
-
- Vector<String16> services;
- Vector<String16> args;
- if (argc == 1) {
- services = sm->listServices();
- services.sort(sort_func);
- args.add(String16("-a"));
- } else {
- services.add(String16(argv[1]));
- for (int i=2; i<argc; i++) {
- args.add(String16(argv[i]));
- }
- }
-
- const size_t N = services.size();
-
- if (N > 1) {
- // first print a list of the current services
- aout << "Currently running services:" << endl;
-
- for (size_t i=0; i<N; i++) {
- sp<IBinder> service = sm->checkService(services[i]);
- if (service != NULL) {
- aout << " " << services[i] << endl;
- }
- }
- }
-
- for (size_t i=0; i<N; i++) {
- sp<IBinder> service = sm->checkService(services[i]);
- if (service != NULL) {
- if (N > 1) {
- aout << "------------------------------------------------------------"
- "-------------------" << endl;
- aout << "DUMP OF SERVICE " << services[i] << ":" << endl;
- }
- int err = service->dump(STDOUT_FILENO, args);
- if (err != 0) {
- aerr << "Error dumping service info: (" << strerror(err)
- << ") " << services[i] << endl;
- }
- } else {
- aerr << "Can't find service: " << services[i] << endl;
- }
- }
-
- return 0;
-}
diff --git a/cmds/installd/installd.c b/cmds/installd/installd.c
index 7f94a96..c2c749a 100644
--- a/cmds/installd/installd.c
+++ b/cmds/installd/installd.c
@@ -332,12 +332,15 @@
ret = 0;
// Make the /data/user directory if necessary
if (access(user_data_dir, R_OK) < 0) {
- if (mkdir(user_data_dir, 0755) < 0) {
+ if (mkdir(user_data_dir, 0711) < 0) {
return -1;
}
if (chown(user_data_dir, AID_SYSTEM, AID_SYSTEM) < 0) {
return -1;
}
+ if (chmod(user_data_dir, 0711) < 0) {
+ return -1;
+ }
}
// Make the /data/user/0 symlink to /data/data if necessary
if (access(primary_data_dir, R_OK) < 0) {
diff --git a/cmds/stagefright/Android.mk b/cmds/stagefright/Android.mk
index 30be7fa..52a9293 100644
--- a/cmds/stagefright/Android.mk
+++ b/cmds/stagefright/Android.mk
@@ -4,19 +4,18 @@
LOCAL_SRC_FILES:= \
stagefright.cpp \
+ jpeg.cpp \
SineSource.cpp
LOCAL_SHARED_LIBRARIES := \
libstagefright libmedia libmedia_native libutils libbinder libstagefright_foundation \
- libskia libgui
+ libjpeg libgui
LOCAL_C_INCLUDES:= \
- $(JNI_H_INCLUDE) \
frameworks/base/media/libstagefright \
frameworks/base/media/libstagefright/include \
$(TOP)/frameworks/native/include/media/openmax \
- external/skia/include/core \
- external/skia/include/images \
+ external/jpeg \
LOCAL_CFLAGS += -Wno-multichar
@@ -38,7 +37,6 @@
libstagefright liblog libutils libbinder libstagefright_foundation
LOCAL_C_INCLUDES:= \
- $(JNI_H_INCLUDE) \
frameworks/base/media/libstagefright \
$(TOP)/frameworks/native/include/media/openmax
@@ -62,7 +60,6 @@
libstagefright liblog libutils libbinder libstagefright_foundation
LOCAL_C_INCLUDES:= \
- $(JNI_H_INCLUDE) \
frameworks/base/media/libstagefright \
$(TOP)/frameworks/native/include/media/openmax
@@ -87,7 +84,6 @@
libstagefright liblog libutils libbinder libstagefright_foundation
LOCAL_C_INCLUDES:= \
- $(JNI_H_INCLUDE) \
frameworks/base/media/libstagefright \
$(TOP)/frameworks/native/include/media/openmax
@@ -111,7 +107,6 @@
libstagefright_foundation libmedia libmedia_native
LOCAL_C_INCLUDES:= \
- $(JNI_H_INCLUDE) \
frameworks/base/media/libstagefright \
$(TOP)/frameworks/native/include/media/openmax
@@ -135,7 +130,6 @@
libmedia libmedia_native libgui libcutils libui
LOCAL_C_INCLUDES:= \
- $(JNI_H_INCLUDE) \
frameworks/base/media/libstagefright \
$(TOP)/frameworks/native/include/media/openmax
@@ -160,7 +154,6 @@
libmedia libmedia_native libgui libcutils libui
LOCAL_C_INCLUDES:= \
- $(JNI_H_INCLUDE) \
frameworks/base/media/libstagefright \
$(TOP)/frameworks/native/include/media/openmax
diff --git a/cmds/stagefright/codec.cpp b/cmds/stagefright/codec.cpp
index fea62cc..cf2909e 100644
--- a/cmds/stagefright/codec.cpp
+++ b/cmds/stagefright/codec.cpp
@@ -28,6 +28,7 @@
#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/DataSource.h>
#include <media/stagefright/MediaCodec.h>
+#include <media/stagefright/MediaCodecList.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/NuMediaExtractor.h>
#include <gui/SurfaceComposerClient.h>
@@ -36,7 +37,9 @@
fprintf(stderr, "usage: %s [-a] use audio\n"
"\t\t[-v] use video\n"
"\t\t[-p] playback\n"
- "\t\t[-S] allocate buffers from a surface\n", me);
+ "\t\t[-S] allocate buffers from a surface\n"
+ "\t\t[-D] decrypt input buffers\n",
+ me);
exit(1);
}
@@ -63,7 +66,8 @@
const char *path,
bool useAudio,
bool useVideo,
- const android::sp<android::Surface> &surface) {
+ const android::sp<android::Surface> &surface,
+ bool decryptInputBuffers) {
using namespace android;
static int64_t kTimeout = 500ll;
@@ -109,13 +113,31 @@
state->mNumBuffersDecoded = 0;
state->mIsAudio = isAudio;
- state->mCodec = MediaCodec::CreateByType(
- looper, mime.c_str(), false /* encoder */);
+ if (decryptInputBuffers && !isAudio) {
+ static const MediaCodecList *list = MediaCodecList::getInstance();
+
+ ssize_t index =
+ list->findCodecByType(mime.c_str(), false /* encoder */);
+
+ CHECK_GE(index, 0);
+
+ const char *componentName = list->getCodecName(index);
+
+ AString fullName = componentName;
+ fullName.append(".secure");
+
+ state->mCodec = MediaCodec::CreateByComponentName(
+ looper, fullName.c_str());
+ } else {
+ state->mCodec = MediaCodec::CreateByType(
+ looper, mime.c_str(), false /* encoder */);
+ }
CHECK(state->mCodec != NULL);
err = state->mCodec->configure(
- format, isVideo ? surface : NULL, 0 /* flags */);
+ format, isVideo ? surface : NULL,
+ decryptInputBuffers ? MediaCodec::CONFIGURE_FLAG_SECURE : 0);
CHECK_EQ(err, (status_t)OK);
@@ -202,12 +224,24 @@
err = extractor->getSampleTime(&timeUs);
CHECK_EQ(err, (status_t)OK);
+ uint32_t bufferFlags = 0;
+
+ uint32_t sampleFlags;
+ err = extractor->getSampleFlags(&sampleFlags);
+ CHECK_EQ(err, (status_t)OK);
+
+ if (sampleFlags & NuMediaExtractor::SAMPLE_FLAG_ENCRYPTED) {
+ CHECK(decryptInputBuffers);
+
+ bufferFlags |= MediaCodec::BUFFER_FLAG_ENCRYPTED;
+ }
+
err = state->mCodec->queueInputBuffer(
index,
0 /* offset */,
buffer->size(),
timeUs,
- 0 /* flags */);
+ bufferFlags);
CHECK_EQ(err, (status_t)OK);
@@ -341,9 +375,10 @@
bool useVideo = false;
bool playback = false;
bool useSurface = false;
+ bool decryptInputBuffers = false;
int res;
- while ((res = getopt(argc, argv, "havpS")) >= 0) {
+ while ((res = getopt(argc, argv, "havpSD")) >= 0) {
switch (res) {
case 'a':
{
@@ -369,6 +404,12 @@
break;
}
+ case 'D':
+ {
+ decryptInputBuffers = true;
+ break;
+ }
+
case '?':
case 'h':
default:
@@ -440,7 +481,8 @@
player->stop();
player->reset();
} else {
- decode(looper, argv[0], useAudio, useVideo, surface);
+ decode(looper, argv[0],
+ useAudio, useVideo, surface, decryptInputBuffers);
}
if (playback || (useSurface && useVideo)) {
diff --git a/cmds/stagefright/jpeg.cpp b/cmds/stagefright/jpeg.cpp
new file mode 100644
index 0000000..7e859c3
--- /dev/null
+++ b/cmds/stagefright/jpeg.cpp
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <errno.h>
+#include <setjmp.h>
+#include <stdio.h>
+
+extern "C" {
+#include "jpeglib.h"
+}
+
+static inline uint8_t from565to8(uint16_t p, int start, int bits) {
+ uint8_t c = (p >> start) & ((1 << bits) - 1);
+ return (c << (8 - bits)) | (c >> (bits - (8 - bits)));
+}
+
+struct sf_jpeg_error_mgr {
+ struct jpeg_error_mgr jerr;
+ jmp_buf longjmp_buffer;
+};
+
+void sf_jpeg_error_exit(j_common_ptr cinfo) {
+ struct sf_jpeg_error_mgr *sf_err = (struct sf_jpeg_error_mgr *)cinfo->err;
+ longjmp(sf_err->longjmp_buffer, 0);
+}
+
+int writeJpegFile(const char *filename, uint8_t *frame, int width, int height) {
+ struct sf_jpeg_error_mgr sf_err;
+ struct jpeg_compress_struct cinfo;
+ uint8_t row_data[width * 3];
+ JSAMPROW row_pointer = row_data;
+ FILE *f;
+
+ f = fopen(filename, "w");
+ if (!f) {
+ return -errno;
+ }
+
+ cinfo.err = jpeg_std_error(&sf_err.jerr);
+ sf_err.jerr.error_exit = sf_jpeg_error_exit;
+ if (setjmp(sf_err.longjmp_buffer)) {
+ jpeg_destroy_compress(&cinfo);
+ fclose(f);
+ return -1;
+ }
+
+ jpeg_create_compress(&cinfo);
+ jpeg_stdio_dest(&cinfo, f);
+
+ cinfo.image_width = width;
+ cinfo.image_height = height;
+ cinfo.input_components = 3;
+ cinfo.in_color_space = JCS_RGB;
+
+ jpeg_set_defaults(&cinfo);
+ jpeg_set_quality(&cinfo, 80, TRUE);
+
+ jpeg_start_compress(&cinfo, TRUE);
+
+ for (int row = 0; row < height; row++) {
+ uint16_t *src = (uint16_t *)(frame + row * width * 2);
+ uint8_t *dst = row_data;
+ for (int col = 0; col < width; col++) {
+ dst[0] = from565to8(*src, 11, 5);
+ dst[1] = from565to8(*src, 5, 6);
+ dst[2] = from565to8(*src, 0, 5);
+ dst += 3;
+ src++;
+ }
+ jpeg_write_scanlines(&cinfo, &row_pointer, 1);
+ }
+
+ jpeg_finish_compress(&cinfo);
+ jpeg_destroy_compress(&cinfo);
+
+ fclose(f);
+ return 0;
+}
diff --git a/cmds/stagefright/jpeg.h b/cmds/stagefright/jpeg.h
new file mode 100644
index 0000000..ce86cf2
--- /dev/null
+++ b/cmds/stagefright/jpeg.h
@@ -0,0 +1,6 @@
+#ifndef _STAGEFRIGHT_JPEG_H_
+#define _STAGEFRIGHT_JPEG_H_
+
+int writeJpegFile(const char *filename, uint8_t *frame, int width, int height);
+
+#endif
diff --git a/cmds/stagefright/sf2.cpp b/cmds/stagefright/sf2.cpp
index 64df5d1..3bbfbdc 100644
--- a/cmds/stagefright/sf2.cpp
+++ b/cmds/stagefright/sf2.cpp
@@ -287,6 +287,11 @@
msg->setInt32("channel-count", numChannels);
msg->setInt32("sample-rate", sampleRate);
+
+ int32_t isADTS;
+ if (meta->findInt32(kKeyIsADTS, &isADTS) && isADTS != 0) {
+ msg->setInt32("is-adts", true);
+ }
}
uint32_t type;
diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp
index dab2e0f..d70c862 100644
--- a/cmds/stagefright/stagefright.cpp
+++ b/cmds/stagefright/stagefright.cpp
@@ -24,6 +24,7 @@
#include <string.h>
#include <unistd.h>
+#include "jpeg.h"
#include "SineSource.h"
#include <binder/IServiceManager.h>
@@ -49,8 +50,6 @@
#include <media/stagefright/MPEG4Writer.h>
#include <private/media/VideoFrame.h>
-#include <SkBitmap.h>
-#include <SkImageEncoder.h>
#include <fcntl.h>
@@ -787,16 +786,9 @@
VideoFrame *frame = (VideoFrame *)mem->pointer();
- SkBitmap bitmap;
- bitmap.setConfig(
- SkBitmap::kRGB_565_Config, frame->mWidth, frame->mHeight);
-
- bitmap.setPixels((uint8_t *)frame + sizeof(VideoFrame));
-
- CHECK(SkImageEncoder::EncodeFile(
- "/sdcard/out.jpg", bitmap,
- SkImageEncoder::kJPEG_Type,
- SkImageEncoder::kDefaultQuality));
+ CHECK_EQ(writeJpegFile("/sdcard/out.jpg",
+ (uint8_t *)frame + sizeof(VideoFrame),
+ frame->mWidth, frame->mHeight), 0);
}
{
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index ea32745..b277efb 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -3639,7 +3639,7 @@
*/
public void startActivityFromChild(Activity child, Intent intent,
int requestCode) {
- startActivityFromChild(child, intent, requestCode);
+ startActivityFromChild(child, intent, requestCode, null);
}
/**
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index d056b17..531a695 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -31,6 +31,7 @@
import android.graphics.Bitmap;
import android.graphics.Point;
import android.os.Binder;
+import android.os.Bundle;
import android.os.Debug;
import android.os.Handler;
import android.os.Parcel;
@@ -816,6 +817,19 @@
public static final int MOVE_TASK_NO_USER_ACTION = 0x00000002;
/**
+ * Equivalent to calling {@link #moveTaskToFront(int, int, Bundle)}
+ * with a null options argument.
+ *
+ * @param taskId The identifier of the task to be moved, as found in
+ * {@link RunningTaskInfo} or {@link RecentTaskInfo}.
+ * @param flags Additional operational flags, 0 or more of
+ * {@link #MOVE_TASK_WITH_HOME}.
+ */
+ public void moveTaskToFront(int taskId, int flags) {
+ moveTaskToFront(taskId, flags, null);
+ }
+
+ /**
* Ask that the task associated with a given task ID be moved to the
* front of the stack, so it is now visible to the user. Requires that
* the caller hold permission {@link android.Manifest.permission#REORDER_TASKS}
@@ -825,10 +839,13 @@
* {@link RunningTaskInfo} or {@link RecentTaskInfo}.
* @param flags Additional operational flags, 0 or more of
* {@link #MOVE_TASK_WITH_HOME}.
+ * @param options Additional options for the operation, either null or
+ * as per {@link Context#startActivity(Intent, android.os.Bundle)
+ * Context.startActivity(Intent, Bundle)}.
*/
- public void moveTaskToFront(int taskId, int flags) {
+ public void moveTaskToFront(int taskId, int flags, Bundle options) {
try {
- ActivityManagerNative.getDefault().moveTaskToFront(taskId, flags);
+ ActivityManagerNative.getDefault().moveTaskToFront(taskId, flags, options);
} catch (RemoteException e) {
// System dead, we will be dead too soon!
}
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index a3cc352..c402329 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -510,7 +510,9 @@
data.enforceInterface(IActivityManager.descriptor);
int task = data.readInt();
int fl = data.readInt();
- moveTaskToFront(task, fl);
+ Bundle options = data.readInt() != 0
+ ? Bundle.CREATOR.createFromParcel(data) : null;
+ moveTaskToFront(task, fl, options);
reply.writeNoException();
return true;
}
@@ -1055,6 +1057,15 @@
return true;
}
+ case KILL_PROCESSES_BELOW_FOREGROUND_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ String reason = data.readString();
+ boolean res = killProcessesBelowForeground(reason);
+ reply.writeNoException();
+ reply.writeInt(res ? 1 : 0);
+ return true;
+ }
+
case START_RUNNING_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
String pkg = data.readString();
@@ -2134,13 +2145,19 @@
reply.recycle();
return list;
}
- public void moveTaskToFront(int task, int flags) throws RemoteException
+ public void moveTaskToFront(int task, int flags, Bundle options) throws RemoteException
{
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeInt(task);
data.writeInt(flags);
+ if (options != null) {
+ data.writeInt(1);
+ options.writeToParcel(data, 0);
+ } else {
+ data.writeInt(0);
+ }
mRemote.transact(MOVE_TASK_TO_FRONT_TRANSACTION, data, reply, 0);
reply.readException();
data.recycle();
@@ -2902,6 +2919,18 @@
reply.recycle();
return res;
}
+ @Override
+ public boolean killProcessesBelowForeground(String reason) throws RemoteException {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ data.writeString(reason);
+ mRemote.transact(KILL_PROCESSES_BELOW_FOREGROUND_TRANSACTION, data, reply, 0);
+ boolean res = reply.readInt() != 0;
+ data.recycle();
+ reply.recycle();
+ return res;
+ }
public void startRunning(String pkg, String cls, String action,
String indata) throws RemoteException {
Parcel data = Parcel.obtain();
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index 03bc338..c637df0 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -17,7 +17,13 @@
package android.app;
import android.content.Context;
+import android.graphics.Bitmap;
import android.os.Bundle;
+import android.os.Handler;
+import android.os.IRemoteCallback;
+import android.os.Message;
+import android.os.RemoteException;
+import android.view.View;
/**
* Helper class for building an options Bundle that can be used with
@@ -32,6 +38,12 @@
public static final String KEY_PACKAGE_NAME = "android:packageName";
/**
+ * Type of animation that arguments specify.
+ * @hide
+ */
+ public static final String KEY_ANIM_TYPE = "android:animType";
+
+ /**
* Custom enter animation resource ID.
* @hide
*/
@@ -43,10 +55,45 @@
*/
public static final String KEY_ANIM_EXIT_RES_ID = "android:animExitRes";
+ /**
+ * Bitmap for thumbnail animation.
+ * @hide
+ */
+ public static final String KEY_ANIM_THUMBNAIL = "android:animThumbnail";
+
+ /**
+ * Start X position of thumbnail animation.
+ * @hide
+ */
+ public static final String KEY_ANIM_START_X = "android:animStartX";
+
+ /**
+ * Start Y position of thumbnail animation.
+ * @hide
+ */
+ public static final String KEY_ANIM_START_Y = "android:animStartY";
+
+ /**
+ * Callback for when animation is started.
+ * @hide
+ */
+ public static final String KEY_ANIM_START_LISTENER = "android:animStartListener";
+
+ /** @hide */
+ public static final int ANIM_NONE = 0;
+ /** @hide */
+ public static final int ANIM_CUSTOM = 1;
+ /** @hide */
+ public static final int ANIM_THUMBNAIL = 2;
+
private String mPackageName;
- private boolean mIsCustomAnimation;
+ private int mAnimationType = ANIM_NONE;
private int mCustomEnterResId;
private int mCustomExitResId;
+ private Bitmap mThumbnail;
+ private int mStartX;
+ private int mStartY;
+ private IRemoteCallback mAnimationStartedListener;
/**
* Create an ActivityOptions specifying a custom animation to run when
@@ -65,22 +112,79 @@
int enterResId, int exitResId) {
ActivityOptions opts = new ActivityOptions();
opts.mPackageName = context.getPackageName();
- opts.mIsCustomAnimation = true;
+ opts.mAnimationType = ANIM_CUSTOM;
opts.mCustomEnterResId = enterResId;
opts.mCustomExitResId = exitResId;
return opts;
}
+ /**
+ * Callback for use with {@link ActivityOptions#makeThumbnailScaleUpAnimation}
+ * to find out when the given animation has started running.
+ */
+ public interface OnAnimationStartedListener {
+ void onAnimationStarted();
+ }
+
+ /**
+ * Create an ActivityOptions specifying an animation where a thumbnail
+ * is scaled from a given position to the new activity window that is
+ * being started.
+ *
+ * @param source The View that this thumbnail is animating from. This
+ * defines the coordinate space for <var>startX</var> and <var>startY</var>.
+ * @param thumbnail The bitmap that will be shown as the initial thumbnail
+ * of the animation.
+ * @param startX The x starting location of the bitmap, in screen coordiantes.
+ * @param startY The y starting location of the bitmap, in screen coordinates.
+ * @param listener Optional OnAnimationStartedListener to find out when the
+ * requested animation has started running. If for some reason the animation
+ * is not executed, the callback will happen immediately.
+ * @return Returns a new ActivityOptions object that you can use to
+ * supply these options as the options Bundle when starting an activity.
+ */
+ public static ActivityOptions makeThumbnailScaleUpAnimation(View source,
+ Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener) {
+ ActivityOptions opts = new ActivityOptions();
+ opts.mPackageName = source.getContext().getPackageName();
+ opts.mAnimationType = ANIM_THUMBNAIL;
+ opts.mThumbnail = thumbnail;
+ int[] pts = new int[2];
+ source.getLocationOnScreen(pts);
+ opts.mStartX = pts[0] + startX;
+ opts.mStartY = pts[1] + startY;
+ if (listener != null) {
+ final Handler h = source.getHandler();
+ final OnAnimationStartedListener finalListener = listener;
+ opts.mAnimationStartedListener = new IRemoteCallback.Stub() {
+ @Override public void sendResult(Bundle data) throws RemoteException {
+ h.post(new Runnable() {
+ @Override public void run() {
+ finalListener.onAnimationStarted();
+ }
+ });
+ }
+ };
+ }
+ return opts;
+ }
+
private ActivityOptions() {
}
/** @hide */
public ActivityOptions(Bundle opts) {
mPackageName = opts.getString(KEY_PACKAGE_NAME);
- if (opts.containsKey(KEY_ANIM_ENTER_RES_ID)) {
- mIsCustomAnimation = true;
+ mAnimationType = opts.getInt(KEY_ANIM_TYPE);
+ if (mAnimationType == ANIM_CUSTOM) {
mCustomEnterResId = opts.getInt(KEY_ANIM_ENTER_RES_ID, 0);
mCustomExitResId = opts.getInt(KEY_ANIM_EXIT_RES_ID, 0);
+ } else if (mAnimationType == ANIM_THUMBNAIL) {
+ mThumbnail = (Bitmap)opts.getParcelable(KEY_ANIM_THUMBNAIL);
+ mStartX = opts.getInt(KEY_ANIM_START_X, 0);
+ mStartY = opts.getInt(KEY_ANIM_START_Y, 0);
+ mAnimationStartedListener = IRemoteCallback.Stub.asInterface(
+ opts.getIBinder(KEY_ANIM_START_LISTENER));
}
}
@@ -90,8 +194,8 @@
}
/** @hide */
- public boolean isCustomAnimation() {
- return mIsCustomAnimation;
+ public int getAnimationType() {
+ return mAnimationType;
}
/** @hide */
@@ -104,6 +208,43 @@
return mCustomExitResId;
}
+ /** @hide */
+ public Bitmap getThumbnail() {
+ return mThumbnail;
+ }
+
+ /** @hide */
+ public int getStartX() {
+ return mStartX;
+ }
+
+ /** @hide */
+ public int getStartY() {
+ return mStartY;
+ }
+
+ /** @hide */
+ public IRemoteCallback getOnAnimationStartListener() {
+ return mAnimationStartedListener;
+ }
+
+ /** @hide */
+ public void abort() {
+ if (mAnimationStartedListener != null) {
+ try {
+ mAnimationStartedListener.sendResult(null);
+ } catch (RemoteException e) {
+ }
+ }
+ }
+
+ /** @hide */
+ public static void abort(Bundle options) {
+ if (options != null) {
+ (new ActivityOptions(options)).abort();
+ }
+ }
+
/**
* Join the values in <var>otherOptions</var> in to this one. Any values
* defined in <var>otherOptions</var> replace those in the base options.
@@ -112,10 +253,27 @@
if (otherOptions.mPackageName != null) {
mPackageName = otherOptions.mPackageName;
}
- if (otherOptions.mIsCustomAnimation) {
- mIsCustomAnimation = true;
- mCustomEnterResId = otherOptions.mCustomEnterResId;
- mCustomExitResId = otherOptions.mCustomExitResId;
+ switch (otherOptions.mAnimationType) {
+ case ANIM_CUSTOM:
+ mAnimationType = otherOptions.mAnimationType;
+ mCustomEnterResId = otherOptions.mCustomEnterResId;
+ mCustomExitResId = otherOptions.mCustomExitResId;
+ mThumbnail = null;
+ mAnimationStartedListener = null;
+ break;
+ case ANIM_THUMBNAIL:
+ mAnimationType = otherOptions.mAnimationType;
+ mThumbnail = otherOptions.mThumbnail;
+ mStartX = otherOptions.mStartX;
+ mStartY = otherOptions.mStartY;
+ if (otherOptions.mAnimationStartedListener != null) {
+ try {
+ otherOptions.mAnimationStartedListener.sendResult(null);
+ } catch (RemoteException e) {
+ }
+ }
+ mAnimationStartedListener = otherOptions.mAnimationStartedListener;
+ break;
}
}
@@ -132,9 +290,19 @@
if (mPackageName != null) {
b.putString(KEY_PACKAGE_NAME, mPackageName);
}
- if (mIsCustomAnimation) {
- b.putInt(KEY_ANIM_ENTER_RES_ID, mCustomEnterResId);
- b.putInt(KEY_ANIM_EXIT_RES_ID, mCustomExitResId);
+ switch (mAnimationType) {
+ case ANIM_CUSTOM:
+ b.putInt(KEY_ANIM_TYPE, mAnimationType);
+ b.putInt(KEY_ANIM_ENTER_RES_ID, mCustomEnterResId);
+ b.putInt(KEY_ANIM_EXIT_RES_ID, mCustomExitResId);
+ break;
+ case ANIM_THUMBNAIL:
+ b.putInt(KEY_ANIM_TYPE, mAnimationType);
+ b.putParcelable(KEY_ANIM_THUMBNAIL, mThumbnail);
+ b.putInt(KEY_ANIM_START_X, mStartX);
+ b.putInt(KEY_ANIM_START_Y, mStartY);
+ b.putIBinder(KEY_ANIM_START_LISTENER, mAnimationStartedListener
+ != null ? mAnimationStartedListener.asBinder() : null);
}
return b;
}
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 0860890..ab4e73d 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -404,6 +404,7 @@
try {
fd.close();
} catch (IOException e) {
+ // Ignore
}
}
return;
@@ -412,6 +413,7 @@
try {
profileFd.close();
} catch (IOException e) {
+ // Ignore
}
}
profileFile = file;
@@ -843,14 +845,13 @@
FileOutputStream fout = new FileOutputStream(fd);
PrintWriter pw = new PrintWriter(fout);
try {
- return dumpMemInfo(pw, checkin, all, args);
+ return dumpMemInfo(pw, checkin, all);
} finally {
pw.flush();
}
}
- private Debug.MemoryInfo dumpMemInfo(PrintWriter pw, boolean checkin, boolean all,
- String[] args) {
+ private Debug.MemoryInfo dumpMemInfo(PrintWriter pw, boolean checkin, boolean all) {
long nativeMax = Debug.getNativeHeapSize() / 1024;
long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024;
long nativeFree = Debug.getNativeHeapFreeSize() / 1024;
@@ -1458,17 +1459,6 @@
return dm;
}
- static Configuration applyConfigCompat(Configuration config, CompatibilityInfo compat) {
- if (config == null) {
- return null;
- }
- if (compat != null && !compat.supportsScreen()) {
- config = new Configuration(config);
- compat.applyToConfiguration(config);
- }
- return config;
- }
-
private Configuration mMainThreadConfig = new Configuration();
Configuration applyConfigCompatMainThread(Configuration config, CompatibilityInfo compat) {
if (config == null) {
@@ -2509,7 +2499,7 @@
return r;
}
- final void cleanUpPendingRemoveWindows(ActivityClientRecord r) {
+ static final void cleanUpPendingRemoveWindows(ActivityClientRecord r) {
if (r.mPendingRemoveWindow != null) {
r.mPendingRemoveWindowManager.removeViewImmediate(r.mPendingRemoveWindow);
IBinder wtoken = r.mPendingRemoveWindow.getWindowToken();
@@ -3437,15 +3427,12 @@
= new ArrayList<ComponentCallbacks2>();
if (mActivities.size() > 0) {
- Iterator<ActivityClientRecord> it = mActivities.values().iterator();
- while (it.hasNext()) {
- ActivityClientRecord ar = it.next();
+ for (ActivityClientRecord ar : mActivities.values()) {
Activity a = ar.activity;
if (a != null) {
Configuration thisConfig = applyConfigCompatMainThread(newConfig,
ar.packageInfo.mCompatibilityInfo.getIfNeeded());
- if (!ar.activity.mFinished && (allActivities ||
- (a != null && !ar.paused))) {
+ if (!ar.activity.mFinished && (allActivities || !ar.paused)) {
// If the activity is currently resumed, its configuration
// needs to change right now.
callbacks.add(a);
@@ -3455,24 +3442,24 @@
// the activity manager may, before then, decide the
// activity needs to be destroyed to handle its new
// configuration.
- if (DEBUG_CONFIGURATION) Slog.v(TAG, "Setting activity "
- + ar.activityInfo.name + " newConfig=" + thisConfig);
+ if (DEBUG_CONFIGURATION) {
+ Slog.v(TAG, "Setting activity "
+ + ar.activityInfo.name + " newConfig=" + thisConfig);
+ }
ar.newConfig = thisConfig;
}
}
}
}
if (mServices.size() > 0) {
- Iterator<Service> it = mServices.values().iterator();
- while (it.hasNext()) {
- callbacks.add(it.next());
+ for (Service service : mServices.values()) {
+ callbacks.add(service);
}
}
synchronized (mProviderMap) {
if (mLocalProviders.size() > 0) {
- Iterator<ProviderClientRecord> it = mLocalProviders.values().iterator();
- while (it.hasNext()) {
- callbacks.add(it.next().mLocalProvider);
+ for (ProviderClientRecord providerClientRecord : mLocalProviders.values()) {
+ callbacks.add(providerClientRecord.mLocalProvider);
}
}
}
@@ -3484,8 +3471,7 @@
return callbacks;
}
- private final void performConfigurationChanged(
- ComponentCallbacks2 cb, Configuration config) {
+ private static void performConfigurationChanged(ComponentCallbacks2 cb, Configuration config) {
// Only for Activity objects, check that they actually call up to their
// superclass implementation. ComponentCallbacks2 is an interface, so
// we check the runtime type and act accordingly.
@@ -3692,7 +3678,7 @@
}
}
- final void handleDumpHeap(boolean managed, DumpHeapData dhd) {
+ static final void handleDumpHeap(boolean managed, DumpHeapData dhd) {
if (managed) {
try {
Debug.dumpHprofData(dhd.path, dhd.fd.getFileDescriptor());
@@ -3769,7 +3755,7 @@
}
final int N = callbacks.size();
- for (int i=0; i<N; i++) {
+ for (int i = 0; i < N; i++) {
callbacks.get(i).onTrimMemory(level);
}
WindowManagerImpl.getDefault().terminateEgl();
@@ -4057,9 +4043,7 @@
final ArrayList<IActivityManager.ContentProviderHolder> results =
new ArrayList<IActivityManager.ContentProviderHolder>();
- Iterator<ProviderInfo> i = providers.iterator();
- while (i.hasNext()) {
- ProviderInfo cpi = i.next();
+ for (ProviderInfo cpi : providers) {
StringBuilder buf = new StringBuilder(128);
buf.append("Pub ");
buf.append(cpi.authority);
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 7043a73..d758ecae 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -766,17 +766,18 @@
@Override
public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory) {
- File f = validateFilePath(name, true);
- SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(f, factory);
- setFilePermissionsFromMode(f.getPath(), mode, 0);
- return db;
+ return openOrCreateDatabase(name, mode, factory, null);
}
@Override
public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory,
DatabaseErrorHandler errorHandler) {
File f = validateFilePath(name, true);
- SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(f.getPath(), factory, errorHandler);
+ int flags = SQLiteDatabase.CREATE_IF_NECESSARY;
+ if ((mode & MODE_ENABLE_WRITE_AHEAD_LOGGING) != 0) {
+ flags |= SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING;
+ }
+ SQLiteDatabase db = SQLiteDatabase.openDatabase(f.getPath(), factory, flags, errorHandler);
setFilePermissionsFromMode(f.getPath(), mode, 0);
return db;
}
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 31066b5..1d994d8 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -105,7 +105,7 @@
public List getServices(int maxNum, int flags) throws RemoteException;
public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState()
throws RemoteException;
- public void moveTaskToFront(int task, int flags) throws RemoteException;
+ public void moveTaskToFront(int task, int flags, Bundle options) throws RemoteException;
public void moveTaskToBack(int task) throws RemoteException;
public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) throws RemoteException;
public void moveTaskBackwards(int task) throws RemoteException;
@@ -216,9 +216,10 @@
public void enterSafeMode() throws RemoteException;
public void noteWakeupAlarm(IIntentSender sender) throws RemoteException;
-
+
public boolean killPids(int[] pids, String reason, boolean secure) throws RemoteException;
-
+ public boolean killProcessesBelowForeground(String reason) throws RemoteException;
+
// Special low-level communication with activity manager.
public void startRunning(String pkg, String cls, String action,
String data) throws RemoteException;
@@ -573,4 +574,5 @@
int GET_CONTENT_PROVIDER_EXTERNAL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+140;
int REMOVE_CONTENT_PROVIDER_EXTERNAL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+141;
int GET_MY_MEMORY_STATE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+142;
+ int KILL_PROCESSES_BELOW_FOREGROUND_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+143;
}
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index 16299de..e4f7950 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -1381,6 +1381,7 @@
}
try {
intent.setAllowFds(false);
+ intent.migrateExtraStreamToClipData();
int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
@@ -1479,6 +1480,7 @@
}
try {
intent.setAllowFds(false);
+ intent.migrateExtraStreamToClipData();
int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 741a6e9..2902504 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -99,6 +99,16 @@
public static final int MODE_MULTI_PROCESS = 0x0004;
/**
+ * Database open flag: when set, the database is opened with write-ahead
+ * logging enabled by default.
+ *
+ * @see #openOrCreateDatabase(String, int, CursorFactory)
+ * @see #openOrCreateDatabase(String, int, CursorFactory, DatabaseErrorHandler)
+ * @see SQLiteDatabase#enableWriteAheadLogging
+ */
+ public static final int MODE_ENABLE_WRITE_AHEAD_LOGGING = 0x0008;
+
+ /**
* Flag for {@link #bindService}: automatically create the service as long
* as the binding exists. Note that while this will create the service,
* its {@link android.app.Service#onStartCommand}
@@ -691,6 +701,7 @@
* @param mode Operating mode. Use 0 or {@link #MODE_PRIVATE} for the
* default operation, {@link #MODE_WORLD_READABLE}
* and {@link #MODE_WORLD_WRITEABLE} to control permissions.
+ * Use {@link #MODE_ENABLE_WRITE_AHEAD_LOGGING} to enable write-ahead logging by default.
* @param factory An optional factory class that is called to instantiate a
* cursor when query is called.
*
@@ -700,6 +711,7 @@
* @see #MODE_PRIVATE
* @see #MODE_WORLD_READABLE
* @see #MODE_WORLD_WRITEABLE
+ * @see #MODE_ENABLE_WRITE_AHEAD_LOGGING
* @see #deleteDatabase
*/
public abstract SQLiteDatabase openOrCreateDatabase(String name,
@@ -716,6 +728,7 @@
* @param mode Operating mode. Use 0 or {@link #MODE_PRIVATE} for the
* default operation, {@link #MODE_WORLD_READABLE}
* and {@link #MODE_WORLD_WRITEABLE} to control permissions.
+ * Use {@link #MODE_ENABLE_WRITE_AHEAD_LOGGING} to enable write-ahead logging by default.
* @param factory An optional factory class that is called to instantiate a
* cursor when query is called.
* @param errorHandler the {@link DatabaseErrorHandler} to be used when sqlite reports database
@@ -726,6 +739,7 @@
* @see #MODE_PRIVATE
* @see #MODE_WORLD_READABLE
* @see #MODE_WORLD_WRITEABLE
+ * @see #MODE_ENABLE_WRITE_AHEAD_LOGGING
* @see #deleteDatabase
*/
public abstract SQLiteDatabase openOrCreateDatabase(String name,
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 6cf5b43..1c9ef38 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -6467,4 +6467,46 @@
}
return type;
}
+
+ /**
+ * Migrate any {@link #EXTRA_STREAM} in {@link #ACTION_SEND} and
+ * {@link #ACTION_SEND_MULTIPLE} to {@link ClipData}.
+ *
+ * @hide
+ */
+ public void migrateExtraStreamToClipData() {
+ // Refuse to touch if extras already parcelled
+ if (mExtras != null && mExtras.isParcelled()) return;
+
+ // Bail when someone already gave us ClipData
+ if (getClipData() != null) return;
+
+ final String action = getAction();
+ if (ACTION_SEND.equals(action)) {
+ final Uri stream = getParcelableExtra(EXTRA_STREAM);
+ if (stream != null) {
+ final ClipData clipData = new ClipData(
+ null, new String[] { getType() }, new ClipData.Item(stream));
+
+ setClipData(clipData);
+ addFlags(FLAG_GRANT_READ_URI_PERMISSION);
+ }
+
+ } else if (ACTION_SEND_MULTIPLE.equals(action)) {
+ final ArrayList<Uri> streams = getParcelableArrayListExtra(EXTRA_STREAM);
+ if (streams != null && streams.size() > 0) {
+ final Uri firstStream = streams.get(0);
+ final ClipData clipData = new ClipData(
+ null, new String[] { getType() }, new ClipData.Item(firstStream));
+
+ final int size = streams.size();
+ for (int i = 1; i < size; i++) {
+ clipData.addItem(new ClipData.Item(streams.get(i)));
+ }
+
+ setClipData(clipData);
+ addFlags(FLAG_GRANT_READ_URI_PERMISSION);
+ }
+ }
+ }
}
diff --git a/core/java/android/database/sqlite/SQLiteConnection.java b/core/java/android/database/sqlite/SQLiteConnection.java
index bf10bcb..254f652 100644
--- a/core/java/android/database/sqlite/SQLiteConnection.java
+++ b/core/java/android/database/sqlite/SQLiteConnection.java
@@ -211,6 +211,7 @@
SQLiteDebug.DEBUG_SQL_STATEMENTS, SQLiteDebug.DEBUG_SQL_TIME);
setPageSize();
+ setForeignKeyModeFromConfiguration();
setWalModeFromConfiguration();
setJournalSizeLimit();
setAutoCheckpointInterval();
@@ -267,9 +268,19 @@
}
}
+ private void setForeignKeyModeFromConfiguration() {
+ if (!mIsReadOnlyConnection) {
+ final long newValue = mConfiguration.foreignKeyConstraintsEnabled ? 1 : 0;
+ long value = executeForLong("PRAGMA foreign_keys", null, null);
+ if (value != newValue) {
+ execute("PRAGMA foreign_keys=" + newValue, null, null);
+ }
+ }
+ }
+
private void setWalModeFromConfiguration() {
if (!mConfiguration.isInMemoryDb() && !mIsReadOnlyConnection) {
- if (mConfiguration.walEnabled) {
+ if ((mConfiguration.openFlags & SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING) != 0) {
setJournalMode("WAL");
setSyncMode(SQLiteGlobal.getWALSyncMode());
} else {
@@ -389,7 +400,10 @@
}
// Remember what changed.
- boolean walModeChanged = configuration.walEnabled != mConfiguration.walEnabled;
+ boolean foreignKeyModeChanged = configuration.foreignKeyConstraintsEnabled
+ != mConfiguration.foreignKeyConstraintsEnabled;
+ boolean walModeChanged = ((configuration.openFlags ^ mConfiguration.openFlags)
+ & SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING) != 0;
boolean localeChanged = !configuration.locale.equals(mConfiguration.locale);
// Update configuration parameters.
@@ -398,6 +412,11 @@
// Update prepared statement cache size.
mPreparedStatementCache.resize(configuration.maxSqlCacheSize);
+ // Update foreign key mode.
+ if (foreignKeyModeChanged) {
+ setForeignKeyModeFromConfiguration();
+ }
+
// Update WAL.
if (walModeChanged) {
setWalModeFromConfiguration();
diff --git a/core/java/android/database/sqlite/SQLiteConnectionPool.java b/core/java/android/database/sqlite/SQLiteConnectionPool.java
index 27c9ee5..5c8e38bf 100644
--- a/core/java/android/database/sqlite/SQLiteConnectionPool.java
+++ b/core/java/android/database/sqlite/SQLiteConnectionPool.java
@@ -81,6 +81,7 @@
private final Object mLock = new Object();
private final AtomicBoolean mConnectionLeaked = new AtomicBoolean();
private final SQLiteDatabaseConfiguration mConfiguration;
+ private int mMaxConnectionPoolSize;
private boolean mIsOpen;
private int mNextConnectionId;
@@ -146,6 +147,7 @@
private SQLiteConnectionPool(SQLiteDatabaseConfiguration configuration) {
mConfiguration = new SQLiteDatabaseConfiguration(configuration);
+ setMaxConnectionPoolSizeLocked();
}
@Override
@@ -257,8 +259,9 @@
synchronized (mLock) {
throwIfClosedLocked();
- boolean restrictToOneConnection = false;
- if (mConfiguration.walEnabled != configuration.walEnabled) {
+ boolean walModeChanged = ((configuration.openFlags ^ mConfiguration.openFlags)
+ & SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING) != 0;
+ if (walModeChanged) {
// WAL mode can only be changed if there are no acquired connections
// because we need to close all but the primary connection first.
if (!mAcquiredConnections.isEmpty()) {
@@ -272,15 +275,27 @@
// because none of them are in use.
closeAvailableNonPrimaryConnectionsAndLogExceptionsLocked();
assert mAvailableNonPrimaryConnections.isEmpty();
+ }
- restrictToOneConnection = true;
+ boolean foreignKeyModeChanged = configuration.foreignKeyConstraintsEnabled
+ != mConfiguration.foreignKeyConstraintsEnabled;
+ if (foreignKeyModeChanged) {
+ // Foreign key constraints can only be changed if there are no transactions
+ // in progress. To make this clear, we throw an exception if there are
+ // any acquired connections.
+ if (!mAcquiredConnections.isEmpty()) {
+ throw new IllegalStateException("Foreign Key Constraints cannot "
+ + "be enabled or disabled while there are transactions in "
+ + "progress. Finish all transactions and release all active "
+ + "database connections first.");
+ }
}
if (mConfiguration.openFlags != configuration.openFlags) {
// If we are changing open flags and WAL mode at the same time, then
// we have no choice but to close the primary connection beforehand
// because there can only be one connection open when we change WAL mode.
- if (restrictToOneConnection) {
+ if (walModeChanged) {
closeAvailableConnectionsAndLogExceptionsLocked();
}
@@ -296,9 +311,11 @@
mAvailablePrimaryConnection = newPrimaryConnection;
mConfiguration.updateParametersFrom(configuration);
+ setMaxConnectionPoolSizeLocked();
} else {
// Reconfigure the database connections in place.
mConfiguration.updateParametersFrom(configuration);
+ setMaxConnectionPoolSizeLocked();
closeExcessConnectionsAndLogExceptionsLocked();
reconfigureAllConnectionsLocked();
@@ -360,8 +377,7 @@
mAvailablePrimaryConnection = connection;
}
wakeConnectionWaitersLocked();
- } else if (mAvailableNonPrimaryConnections.size() >=
- mConfiguration.maxConnectionPoolSize - 1) {
+ } else if (mAvailableNonPrimaryConnections.size() >= mMaxConnectionPoolSize - 1) {
closeConnectionAndLogExceptionsLocked(connection);
} else {
if (recycleConnectionLocked(connection, status)) {
@@ -499,7 +515,7 @@
// Can't throw.
private void closeExcessConnectionsAndLogExceptionsLocked() {
int availableCount = mAvailableNonPrimaryConnections.size();
- while (availableCount-- > mConfiguration.maxConnectionPoolSize - 1) {
+ while (availableCount-- > mMaxConnectionPoolSize - 1) {
SQLiteConnection connection =
mAvailableNonPrimaryConnections.remove(availableCount);
closeConnectionAndLogExceptionsLocked(connection);
@@ -874,7 +890,7 @@
if (mAvailablePrimaryConnection != null) {
openConnections += 1;
}
- if (openConnections >= mConfiguration.maxConnectionPoolSize) {
+ if (openConnections >= mMaxConnectionPoolSize) {
return null;
}
connection = openConnectionLocked(mConfiguration,
@@ -926,6 +942,18 @@
return (connectionFlags & CONNECTION_FLAG_INTERACTIVE) != 0 ? 1 : 0;
}
+ private void setMaxConnectionPoolSizeLocked() {
+ if ((mConfiguration.openFlags & SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING) != 0) {
+ mMaxConnectionPoolSize = SQLiteGlobal.getWALConnectionPoolSize();
+ } else {
+ // TODO: We don't actually need to restrict the connection pool size to 1
+ // for non-WAL databases. There might be reasons to use connection pooling
+ // with other journal modes. For now, enabling connection pooling and
+ // using WAL are the same thing in the API.
+ mMaxConnectionPoolSize = 1;
+ }
+ }
+
private void throwIfClosedLocked() {
if (!mIsOpen) {
throw new IllegalStateException("Cannot perform this operation "
@@ -972,7 +1000,7 @@
synchronized (mLock) {
printer.println("Connection pool for " + mConfiguration.path + ":");
printer.println(" Open: " + mIsOpen);
- printer.println(" Max connections: " + mConfiguration.maxConnectionPoolSize);
+ printer.println(" Max connections: " + mMaxConnectionPoolSize);
printer.println(" Available primary connection:");
if (mAvailablePrimaryConnection != null) {
diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java
index 0ecce4d..7bd0c8d 100644
--- a/core/java/android/database/sqlite/SQLiteDatabase.java
+++ b/core/java/android/database/sqlite/SQLiteDatabase.java
@@ -232,6 +232,18 @@
public static final int CREATE_IF_NECESSARY = 0x10000000; // update native code if changing
/**
+ * Open flag: Flag for {@link #openDatabase} to open the database file with
+ * write-ahead logging enabled by default. Using this flag is more efficient
+ * than calling {@link #enableWriteAheadLogging}.
+ *
+ * Write-ahead logging cannot be used with read-only databases so the value of
+ * this flag is ignored if the database is opened read-only.
+ *
+ * @see #enableWriteAheadLogging
+ */
+ public static final int ENABLE_WRITE_AHEAD_LOGGING = 0x20000000;
+
+ /**
* Absolute max value that can be set by {@link #setMaxSqlCacheSize(int)}.
*
* Each prepared-statement is between 1K - 6K, depending on the complexity of the
@@ -654,7 +666,7 @@
* @throws SQLiteException if the database cannot be opened
*/
public static SQLiteDatabase openDatabase(String path, CursorFactory factory, int flags) {
- return openDatabase(path, factory, flags, new DefaultDatabaseErrorHandler());
+ return openDatabase(path, factory, flags, null);
}
/**
@@ -694,7 +706,7 @@
* Equivalent to openDatabase(path, factory, CREATE_IF_NECESSARY).
*/
public static SQLiteDatabase openOrCreateDatabase(String path, CursorFactory factory) {
- return openDatabase(path, factory, CREATE_IF_NECESSARY);
+ return openDatabase(path, factory, CREATE_IF_NECESSARY, null);
}
/**
@@ -1781,56 +1793,131 @@
}
/**
- * This method enables parallel execution of queries from multiple threads on the same database.
- * It does this by opening multiple handles to the database and using a different
- * database handle for each query.
+ * Sets whether foreign key constraints are enabled for the database.
* <p>
- * If a transaction is in progress on one connection handle and say, a table is updated in the
- * transaction, then query on the same table on another connection handle will block for the
- * transaction to complete. But this method enables such queries to execute by having them
- * return old version of the data from the table. Most often it is the data that existed in the
- * table prior to the above transaction updates on that table.
- * <p>
- * Maximum number of simultaneous handles used to execute queries in parallel is
- * dependent upon the device memory and possibly other properties.
- * <p>
- * After calling this method, execution of queries in parallel is enabled as long as this
- * database handle is open. To disable execution of queries in parallel, database should
- * be closed and reopened.
- * <p>
- * If a query is part of a transaction, then it is executed on the same database handle the
- * transaction was begun.
- * <p>
- * If the database has any attached databases, then execution of queries in paralel is NOT
- * possible. In such cases, a message is printed to logcat and false is returned.
- * <p>
- * This feature is not available for :memory: databases. In such cases,
- * a message is printed to logcat and false is returned.
- * <p>
- * A typical way to use this method is the following:
- * <pre>
- * SQLiteDatabase db = SQLiteDatabase.openDatabase("db_filename", cursorFactory,
- * CREATE_IF_NECESSARY, myDatabaseErrorHandler);
- * db.enableWriteAheadLogging();
- * </pre>
- * <p>
- * Writers should use {@link #beginTransactionNonExclusive()} or
- * {@link #beginTransactionWithListenerNonExclusive(SQLiteTransactionListener)}
- * to start a trsnsaction.
- * Non-exclusive mode allows database file to be in readable by threads executing queries.
+ * By default, foreign key constraints are not enforced by the database.
+ * This method allows an application to enable foreign key constraints.
+ * It must be called each time the database is opened to ensure that foreign
+ * key constraints are enabled for the session.
+ * </p><p>
+ * A good time to call this method is right after calling {@link #openOrCreateDatabase}
+ * or in the {@link SQLiteOpenHelper#onConfigure} callback.
+ * </p><p>
+ * When foreign key constraints are disabled, the database does not check whether
+ * changes to the database will violate foreign key constraints. Likewise, when
+ * foreign key constraints are disabled, the database will not execute cascade
+ * delete or update triggers. As a result, it is possible for the database
+ * state to become inconsistent. To perform a database integrity check,
+ * call {@link #isDatabaseIntegrityOk}.
+ * </p><p>
+ * This method must not be called while a transaction is in progress.
+ * </p><p>
+ * See also <a href="http://sqlite.org/foreignkeys.html">SQLite Foreign Key Constraints</a>
+ * for more details about foreign key constraint support.
* </p>
*
- * @return true if write-ahead-logging is set. false otherwise
+ * @param enable True to enable foreign key constraints, false to disable them.
+ *
+ * @throws IllegalStateException if the are transactions is in progress
+ * when this method is called.
+ */
+ public void setForeignKeyConstraintsEnabled(boolean enable) {
+ synchronized (mLock) {
+ throwIfNotOpenLocked();
+
+ if (mConfigurationLocked.foreignKeyConstraintsEnabled == enable) {
+ return;
+ }
+
+ mConfigurationLocked.foreignKeyConstraintsEnabled = enable;
+ try {
+ mConnectionPoolLocked.reconfigure(mConfigurationLocked);
+ } catch (RuntimeException ex) {
+ mConfigurationLocked.foreignKeyConstraintsEnabled = !enable;
+ throw ex;
+ }
+ }
+ }
+
+ /**
+ * This method enables parallel execution of queries from multiple threads on the
+ * same database. It does this by opening multiple connections to the database
+ * and using a different database connection for each query. The database
+ * journal mode is also changed to enable writes to proceed concurrently with reads.
+ * <p>
+ * When write-ahead logging is not enabled (the default), it is not possible for
+ * reads and writes to occur on the database at the same time. Before modifying the
+ * database, the writer implicitly acquires an exclusive lock on the database which
+ * prevents readers from accessing the database until the write is completed.
+ * </p><p>
+ * In contrast, when write-ahead logging is enabled (by calling this method), write
+ * operations occur in a separate log file which allows reads to proceed concurrently.
+ * While a write is in progress, readers on other threads will perceive the state
+ * of the database as it was before the write began. When the write completes, readers
+ * on other threads will then perceive the new state of the database.
+ * </p><p>
+ * It is a good idea to enable write-ahead logging whenever a database will be
+ * concurrently accessed and modified by multiple threads at the same time.
+ * However, write-ahead logging uses significantly more memory than ordinary
+ * journaling because there are multiple connections to the same database.
+ * So if a database will only be used by a single thread, or if optimizing
+ * concurrency is not very important, then write-ahead logging should be disabled.
+ * </p><p>
+ * After calling this method, execution of queries in parallel is enabled as long as
+ * the database remains open. To disable execution of queries in parallel, either
+ * call {@link #disableWriteAheadLogging} or close the database and reopen it.
+ * </p><p>
+ * The maximum number of connections used to execute queries in parallel is
+ * dependent upon the device memory and possibly other properties.
+ * </p><p>
+ * If a query is part of a transaction, then it is executed on the same database handle the
+ * transaction was begun.
+ * </p><p>
+ * Writers should use {@link #beginTransactionNonExclusive()} or
+ * {@link #beginTransactionWithListenerNonExclusive(SQLiteTransactionListener)}
+ * to start a transaction. Non-exclusive mode allows database file to be in readable
+ * by other threads executing queries.
+ * </p><p>
+ * If the database has any attached databases, then execution of queries in parallel is NOT
+ * possible. Likewise, write-ahead logging is not supported for read-only databases
+ * or memory databases. In such cases, {@link #enableWriteAheadLogging} returns false.
+ * </p><p>
+ * The best way to enable write-ahead logging is to pass the
+ * {@link #ENABLE_WRITE_AHEAD_LOGGING} flag to {@link #openDatabase}. This is
+ * more efficient than calling {@link #enableWriteAheadLogging}.
+ * <code><pre>
+ * SQLiteDatabase db = SQLiteDatabase.openDatabase("db_filename", cursorFactory,
+ * SQLiteDatabase.CREATE_IF_NECESSARY | SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING,
+ * myDatabaseErrorHandler);
+ * db.enableWriteAheadLogging();
+ * </pre></code>
+ * </p><p>
+ * Another way to enable write-ahead logging is to call {@link #enableWriteAheadLogging}
+ * after opening the database.
+ * <code><pre>
+ * SQLiteDatabase db = SQLiteDatabase.openDatabase("db_filename", cursorFactory,
+ * SQLiteDatabase.CREATE_IF_NECESSARY, myDatabaseErrorHandler);
+ * db.enableWriteAheadLogging();
+ * </pre></code>
+ * </p><p>
+ * See also <a href="http://sqlite.org/wal.html">SQLite Write-Ahead Logging</a> for
+ * more details about how write-ahead logging works.
+ * </p>
+ *
+ * @return True if write-ahead logging is enabled.
*
* @throws IllegalStateException if there are transactions in progress at the
* time this method is called. WAL mode can only be changed when there are no
* transactions in progress.
+ *
+ * @see #ENABLE_WRITE_AHEAD_LOGGING
+ * @see #disableWriteAheadLogging
*/
public boolean enableWriteAheadLogging() {
synchronized (mLock) {
throwIfNotOpenLocked();
- if (mConfigurationLocked.walEnabled) {
+ if ((mConfigurationLocked.openFlags & ENABLE_WRITE_AHEAD_LOGGING) != 0) {
return true;
}
@@ -1855,14 +1942,11 @@
return false;
}
- final int oldMaxConnectionPoolSize = mConfigurationLocked.maxConnectionPoolSize;
- mConfigurationLocked.maxConnectionPoolSize = SQLiteGlobal.getWALConnectionPoolSize();
- mConfigurationLocked.walEnabled = true;
+ mConfigurationLocked.openFlags |= ENABLE_WRITE_AHEAD_LOGGING;
try {
mConnectionPoolLocked.reconfigure(mConfigurationLocked);
} catch (RuntimeException ex) {
- mConfigurationLocked.maxConnectionPoolSize = oldMaxConnectionPoolSize;
- mConfigurationLocked.walEnabled = false;
+ mConfigurationLocked.openFlags &= ~ENABLE_WRITE_AHEAD_LOGGING;
throw ex;
}
}
@@ -1875,29 +1959,44 @@
* @throws IllegalStateException if there are transactions in progress at the
* time this method is called. WAL mode can only be changed when there are no
* transactions in progress.
+ *
+ * @see #enableWriteAheadLogging
*/
public void disableWriteAheadLogging() {
synchronized (mLock) {
throwIfNotOpenLocked();
- if (!mConfigurationLocked.walEnabled) {
+ if ((mConfigurationLocked.openFlags & ENABLE_WRITE_AHEAD_LOGGING) == 0) {
return;
}
- final int oldMaxConnectionPoolSize = mConfigurationLocked.maxConnectionPoolSize;
- mConfigurationLocked.maxConnectionPoolSize = 1;
- mConfigurationLocked.walEnabled = false;
+ mConfigurationLocked.openFlags &= ~ENABLE_WRITE_AHEAD_LOGGING;
try {
mConnectionPoolLocked.reconfigure(mConfigurationLocked);
} catch (RuntimeException ex) {
- mConfigurationLocked.maxConnectionPoolSize = oldMaxConnectionPoolSize;
- mConfigurationLocked.walEnabled = true;
+ mConfigurationLocked.openFlags |= ENABLE_WRITE_AHEAD_LOGGING;
throw ex;
}
}
}
/**
+ * Returns true if write-ahead logging has been enabled for this database.
+ *
+ * @return True if write-ahead logging has been enabled for this database.
+ *
+ * @see #enableWriteAheadLogging
+ * @see #ENABLE_WRITE_AHEAD_LOGGING
+ */
+ public boolean isWriteAheadLoggingEnabled() {
+ synchronized (mLock) {
+ throwIfNotOpenLocked();
+
+ return (mConfigurationLocked.openFlags & ENABLE_WRITE_AHEAD_LOGGING) != 0;
+ }
+ }
+
+ /**
* Collect statistics about all open databases in the current process.
* Used by bug report.
*/
diff --git a/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java b/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java
index e06a5ee..549ab90 100644
--- a/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java
+++ b/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java
@@ -62,14 +62,6 @@
public int openFlags;
/**
- * The maximum number of connections to retain in the connection pool.
- * Must be at least 1.
- *
- * Default is 1.
- */
- public int maxConnectionPoolSize;
-
- /**
* The maximum size of the prepared statement cache for each database connection.
* Must be non-negative.
*
@@ -85,11 +77,11 @@
public Locale locale;
/**
- * True if WAL mode is enabled.
+ * True if foreign key constraints are enabled.
*
* Default is false.
*/
- public boolean walEnabled;
+ public boolean foreignKeyConstraintsEnabled;
/**
* The custom functions to register.
@@ -114,7 +106,6 @@
this.openFlags = openFlags;
// Set default values for optional parameters.
- maxConnectionPoolSize = 1;
maxSqlCacheSize = 25;
locale = Locale.getDefault();
}
@@ -150,10 +141,9 @@
}
openFlags = other.openFlags;
- maxConnectionPoolSize = other.maxConnectionPoolSize;
maxSqlCacheSize = other.maxSqlCacheSize;
locale = other.locale;
- walEnabled = other.walEnabled;
+ foreignKeyConstraintsEnabled = other.foreignKeyConstraintsEnabled;
customFunctions.clear();
customFunctions.addAll(other.customFunctions);
}
diff --git a/core/java/android/database/sqlite/SQLiteOpenHelper.java b/core/java/android/database/sqlite/SQLiteOpenHelper.java
index ffa4663..431eca2 100644
--- a/core/java/android/database/sqlite/SQLiteOpenHelper.java
+++ b/core/java/android/database/sqlite/SQLiteOpenHelper.java
@@ -58,6 +58,7 @@
private SQLiteDatabase mDatabase;
private boolean mIsInitializing;
+ private boolean mEnableWriteAheadLogging;
private final DatabaseErrorHandler mErrorHandler;
/**
@@ -74,7 +75,7 @@
* newer, {@link #onDowngrade} will be used to downgrade the database
*/
public SQLiteOpenHelper(Context context, String name, CursorFactory factory, int version) {
- this(context, name, factory, version, new DefaultDatabaseErrorHandler());
+ this(context, name, factory, version, null);
}
/**
@@ -92,14 +93,11 @@
* {@link #onUpgrade} will be used to upgrade the database; if the database is
* newer, {@link #onDowngrade} will be used to downgrade the database
* @param errorHandler the {@link DatabaseErrorHandler} to be used when sqlite reports database
- * corruption.
+ * corruption, or null to use the default error handler.
*/
public SQLiteOpenHelper(Context context, String name, CursorFactory factory, int version,
DatabaseErrorHandler errorHandler) {
if (version < 1) throw new IllegalArgumentException("Version must be >= 1, was " + version);
- if (errorHandler == null) {
- throw new IllegalArgumentException("DatabaseErrorHandler param value can't be null.");
- }
mContext = context;
mName = name;
@@ -117,6 +115,32 @@
}
/**
+ * Enables or disables the use of write-ahead logging for the database.
+ *
+ * Write-ahead logging cannot be used with read-only databases so the value of
+ * this flag is ignored if the database is opened read-only.
+ *
+ * @param enabled True if write-ahead logging should be enabled, false if it
+ * should be disabled.
+ *
+ * @see SQLiteDatabase#enableWriteAheadLogging()
+ */
+ public void setWriteAheadLoggingEnabled(boolean enabled) {
+ synchronized (this) {
+ if (mEnableWriteAheadLogging != enabled) {
+ if (mDatabase != null && mDatabase.isOpen() && !mDatabase.isReadOnly()) {
+ if (enabled) {
+ mDatabase.enableWriteAheadLogging();
+ } else {
+ mDatabase.disableWriteAheadLogging();
+ }
+ }
+ mEnableWriteAheadLogging = enabled;
+ }
+ }
+ }
+
+ /**
* Create and/or open a database that will be used for reading and writing.
* The first time this is called, the database will be opened and
* {@link #onCreate}, {@link #onUpgrade} and/or {@link #onOpen} will be
@@ -197,7 +221,9 @@
db = SQLiteDatabase.openDatabase(path, mFactory,
SQLiteDatabase.OPEN_READONLY, mErrorHandler);
} else {
- db = mContext.openOrCreateDatabase(mName, 0, mFactory, mErrorHandler);
+ db = mContext.openOrCreateDatabase(mName, mEnableWriteAheadLogging ?
+ Context.MODE_ENABLE_WRITE_AHEAD_LOGGING : 0,
+ mFactory, mErrorHandler);
}
} catch (SQLiteException ex) {
if (writable) {
@@ -211,6 +237,8 @@
}
}
+ onConfigure(db);
+
final int version = db.getVersion();
if (version != mNewVersion) {
if (db.isReadOnly()) {
@@ -235,6 +263,7 @@
db.endTransaction();
}
}
+
onOpen(db);
if (db.isReadOnly()) {
@@ -264,6 +293,25 @@
}
/**
+ * Called when the database connection is being configured, to enable features
+ * such as write-ahead logging or foreign key support.
+ * <p>
+ * This method is called before {@link #onCreate}, {@link #onUpgrade},
+ * {@link #onDowngrade}, or {@link #onOpen} are called. It should not modify
+ * the database except to configure the database connection as required.
+ * </p><p>
+ * This method should only call methods that configure the parameters of the
+ * database connection, such as {@link SQLiteDatabase#enableWriteAheadLogging}
+ * {@link SQLiteDatabase#setForeignKeyConstraintsEnabled},
+ * {@link SQLiteDatabase#setLocale}, {@link SQLiteDatabase#setMaximumSize},
+ * or executing PRAGMA statements.
+ * </p>
+ *
+ * @param db The database.
+ */
+ public void onConfigure(SQLiteDatabase db) {}
+
+ /**
* Called when the database is created for the first time. This is where the
* creation of tables and the initial population of the tables should happen.
*
@@ -276,11 +324,16 @@
* should use this method to drop tables, add tables, or do anything else it
* needs to upgrade to the new schema version.
*
- * <p>The SQLite ALTER TABLE documentation can be found
+ * <p>
+ * The SQLite ALTER TABLE documentation can be found
* <a href="http://sqlite.org/lang_altertable.html">here</a>. If you add new columns
* you can use ALTER TABLE to insert them into a live table. If you rename or remove columns
* you can use ALTER TABLE to rename the old table, then create the new table and then
* populate the new table with the contents of the old table.
+ * </p><p>
+ * This method executes within a transaction. If an exception is thrown, all changes
+ * will automatically be rolled back.
+ * </p>
*
* @param db The database.
* @param oldVersion The old database version.
@@ -290,11 +343,16 @@
/**
* Called when the database needs to be downgraded. This is strictly similar to
- * onUpgrade() method, but is called whenever current version is newer than requested one.
+ * {@link #onUpgrade} method, but is called whenever current version is newer than requested one.
* However, this method is not abstract, so it is not mandatory for a customer to
* implement it. If not overridden, default implementation will reject downgrade and
* throws SQLiteException
*
+ * <p>
+ * This method executes within a transaction. If an exception is thrown, all changes
+ * will automatically be rolled back.
+ * </p>
+ *
* @param db The database.
* @param oldVersion The old database version.
* @param newVersion The new database version.
@@ -308,6 +366,12 @@
* Called when the database has been opened. The implementation
* should check {@link SQLiteDatabase#isReadOnly} before updating the
* database.
+ * <p>
+ * This method is called after the database connection has been configured
+ * and after the database schema has been created, upgraded or downgraded as necessary.
+ * If the database connection must be configured in some way before the schema
+ * is created, upgraded, or downgraded, do it in {@link #onConfigure} instead.
+ * </p>
*
* @param db The database.
*/
diff --git a/core/java/android/net/SSLCertificateSocketFactory.java b/core/java/android/net/SSLCertificateSocketFactory.java
index 5c4b258..6a4f1f2 100644
--- a/core/java/android/net/SSLCertificateSocketFactory.java
+++ b/core/java/android/net/SSLCertificateSocketFactory.java
@@ -18,13 +18,11 @@
import android.os.SystemProperties;
import android.util.Log;
-
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.security.KeyManagementException;
import java.security.cert.X509Certificate;
-
import javax.net.SocketFactory;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
@@ -36,7 +34,6 @@
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
-
import org.apache.harmony.xnet.provider.jsse.OpenSSLContextImpl;
import org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl;
import org.apache.harmony.xnet.provider.jsse.SSLClientSessionCache;
@@ -89,6 +86,7 @@
private SSLSocketFactory mSecureFactory = null;
private TrustManager[] mTrustManagers = null;
private KeyManager[] mKeyManagers = null;
+ private byte[] mNpnProtocols = null;
private final int mHandshakeTimeoutMillis;
private final SSLClientSessionCache mSessionCache;
@@ -251,6 +249,60 @@
}
/**
+ * Sets the <a href="http://technotes.googlecode.com/git/nextprotoneg.html">Next
+ * Protocol Negotiation (NPN)</a> protocols that this peer is interested in.
+ *
+ * <p>For servers this is the sequence of protocols to advertise as
+ * supported, in order of preference. This list is sent unencrypted to
+ * all clients that support NPN.
+ *
+ * <p>For clients this is a list of supported protocols to match against the
+ * server's list. If there is no protocol supported by both client and
+ * server then the first protocol in the client's list will be selected.
+ * The order of the client's protocols is otherwise insignificant.
+ *
+ * @param npnProtocols a possibly-empty list of protocol byte arrays. All
+ * arrays must be non-empty and of length less than 256.
+ */
+ public void setNpnProtocols(byte[][] npnProtocols) {
+ this.mNpnProtocols = toNpnProtocolsList(npnProtocols);
+ }
+
+ /**
+ * Returns an array containing the concatenation of length-prefixed byte
+ * strings.
+ */
+ static byte[] toNpnProtocolsList(byte[]... npnProtocols) {
+ int totalLength = 0;
+ for (byte[] s : npnProtocols) {
+ if (s.length == 0 || s.length > 255) {
+ throw new IllegalArgumentException("s.length == 0 || s.length > 255: " + s.length);
+ }
+ totalLength += 1 + s.length;
+ }
+ byte[] result = new byte[totalLength];
+ int pos = 0;
+ for (byte[] s : npnProtocols) {
+ result[pos++] = (byte) s.length;
+ for (byte b : s) {
+ result[pos++] = b;
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Returns the <a href="http://technotes.googlecode.com/git/nextprotoneg.html">Next
+ * Protocol Negotiation (NPN)</a> protocol selected by client and server, or
+ * null if no protocol was negotiated.
+ *
+ * @param socket a socket created by this factory.
+ */
+ public byte[] getNpnSelectedProtocol(Socket socket) {
+ return ((OpenSSLSocketImpl) socket).getNpnSelectedProtocol();
+ }
+
+ /**
* Sets the {@link KeyManager}s to be used for connections made by this factory.
*/
public void setKeyManagers(KeyManager[] keyManagers) {
@@ -271,6 +323,7 @@
@Override
public Socket createSocket(Socket k, String host, int port, boolean close) throws IOException {
OpenSSLSocketImpl s = (OpenSSLSocketImpl) getDelegate().createSocket(k, host, port, close);
+ s.setNpnProtocols(mNpnProtocols);
s.setHandshakeTimeout(mHandshakeTimeoutMillis);
if (mSecure) {
verifyHostname(s, host);
@@ -289,6 +342,7 @@
@Override
public Socket createSocket() throws IOException {
OpenSSLSocketImpl s = (OpenSSLSocketImpl) getDelegate().createSocket();
+ s.setNpnProtocols(mNpnProtocols);
s.setHandshakeTimeout(mHandshakeTimeoutMillis);
return s;
}
@@ -305,6 +359,7 @@
throws IOException {
OpenSSLSocketImpl s = (OpenSSLSocketImpl) getDelegate().createSocket(
addr, port, localAddr, localPort);
+ s.setNpnProtocols(mNpnProtocols);
s.setHandshakeTimeout(mHandshakeTimeoutMillis);
return s;
}
@@ -319,6 +374,7 @@
@Override
public Socket createSocket(InetAddress addr, int port) throws IOException {
OpenSSLSocketImpl s = (OpenSSLSocketImpl) getDelegate().createSocket(addr, port);
+ s.setNpnProtocols(mNpnProtocols);
s.setHandshakeTimeout(mHandshakeTimeoutMillis);
return s;
}
@@ -334,6 +390,7 @@
throws IOException {
OpenSSLSocketImpl s = (OpenSSLSocketImpl) getDelegate().createSocket(
host, port, localAddr, localPort);
+ s.setNpnProtocols(mNpnProtocols);
s.setHandshakeTimeout(mHandshakeTimeoutMillis);
if (mSecure) {
verifyHostname(s, host);
@@ -350,6 +407,7 @@
@Override
public Socket createSocket(String host, int port) throws IOException {
OpenSSLSocketImpl s = (OpenSSLSocketImpl) getDelegate().createSocket(host, port);
+ s.setNpnProtocols(mNpnProtocols);
s.setHandshakeTimeout(mHandshakeTimeoutMillis);
if (mSecure) {
verifyHostname(s, host);
diff --git a/core/java/android/os/Bundle.java b/core/java/android/os/Bundle.java
index 28206b7..51cb91c8 100644
--- a/core/java/android/os/Bundle.java
+++ b/core/java/android/os/Bundle.java
@@ -226,6 +226,13 @@
}
/**
+ * @hide
+ */
+ public boolean isParcelled() {
+ return mParcelledData != null;
+ }
+
+ /**
* Returns the number of mappings contained in this Bundle.
*
* @return the number of mappings as an int.
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index 1f140e95..f98cfc0 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -1121,6 +1121,7 @@
GLES20Canvas.terminateCaches();
sEgl.eglDestroyContext(sEglDisplay, eglContext);
+ sEglContextStorage.set(null);
sEglContextStorage.remove();
sEgl.eglDestroySurface(sEglDisplay, sPbuffer);
@@ -1134,7 +1135,6 @@
sEglDisplay = null;
sEglConfig = null;
sPbuffer = null;
- sEglContextStorage.set(null);
}
}
}
@@ -1238,7 +1238,7 @@
}
private static void destroyHardwareLayer(View view) {
- view.destroyLayer();
+ view.destroyLayer(true);
if (view instanceof ViewGroup) {
ViewGroup group = (ViewGroup) view;
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index c54d09e..14cd48f 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -89,6 +89,8 @@
void prepareAppTransition(int transit, boolean alwaysKeepCurrent);
int getPendingAppTransition();
void overridePendingAppTransition(String packageName, int enterAnim, int exitAnim);
+ void overridePendingAppTransitionThumb(in Bitmap srcThumb, int startX, int startY,
+ IRemoteCallback startedCallback);
void executeAppTransition();
void setAppStartingWindow(IBinder token, String pkg, int theme,
in CompatibilityInfo compatInfo, CharSequence nonLocalizedLabel, int labelRes,
diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java
index fc02cc1..83999a1 100644
--- a/core/java/android/view/TextureView.java
+++ b/core/java/android/view/TextureView.java
@@ -299,7 +299,7 @@
}
@Override
- boolean destroyLayer() {
+ boolean destroyLayer(boolean valid) {
return false;
}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 8b6f775..f769e96 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -4933,9 +4933,8 @@
@RemotableViewMethod
public void setLayoutDirection(int layoutDirection) {
if (getLayoutDirection() != layoutDirection) {
- // Reset the current layout direction
+ // Reset the current layout direction and the resolved one
mPrivateFlags2 &= ~LAYOUT_DIRECTION_MASK;
- // Reset the current resolved layout direction
resetResolvedLayoutDirection();
// Set the new layout direction (filtered) and ask for a layout pass
mPrivateFlags2 |=
@@ -10041,7 +10040,7 @@
destroyDrawingCache();
- destroyLayer();
+ destroyLayer(false);
if (mAttachInfo != null) {
if (mDisplayList != null) {
@@ -10417,7 +10416,7 @@
// Destroy any previous software drawing cache if needed
switch (mLayerType) {
case LAYER_TYPE_HARDWARE:
- destroyLayer();
+ destroyLayer(false);
// fall through - non-accelerated views may use software layer mechanism instead
case LAYER_TYPE_SOFTWARE:
destroyDrawingCache();
@@ -10555,11 +10554,12 @@
* @see #setLayerType(int, android.graphics.Paint)
* @see #LAYER_TYPE_HARDWARE
*/
- boolean destroyLayer() {
+ boolean destroyLayer(boolean valid) {
if (mHardwareLayer != null) {
AttachInfo info = mAttachInfo;
if (info != null && info.mHardwareRenderer != null &&
- info.mHardwareRenderer.isEnabled() && info.mHardwareRenderer.validate()) {
+ info.mHardwareRenderer.isEnabled() &&
+ (valid || info.mHardwareRenderer.validate())) {
mHardwareLayer.destroy();
mHardwareLayer = null;
@@ -10583,7 +10583,7 @@
* @hide
*/
protected void destroyHardwareResources() {
- destroyLayer();
+ destroyLayer(true);
}
/**
@@ -14540,14 +14540,13 @@
*/
public void setTextDirection(int textDirection) {
if (getTextDirection() != textDirection) {
- // Reset the current text direction
+ // Reset the current text direction and the resolved one
mPrivateFlags2 &= ~TEXT_DIRECTION_MASK;
+ resetResolvedTextDirection();
// Set the new text direction
mPrivateFlags2 |= ((textDirection << TEXT_DIRECTION_MASK_SHIFT) & TEXT_DIRECTION_MASK);
- // Reset the current resolved text direction
- resetResolvedTextDirection();
- // Ask for a layout pass
requestLayout();
+ invalidate(true);
}
}
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index b8fbf17..6ccac78 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -1820,7 +1820,7 @@
* Resets the cancel next up flag.
* Returns true if the flag was previously set.
*/
- private boolean resetCancelNextUpFlag(View view) {
+ private static boolean resetCancelNextUpFlag(View view) {
if ((view.mPrivateFlags & CANCEL_NEXT_UP_EVENT) != 0) {
view.mPrivateFlags &= ~CANCEL_NEXT_UP_EVENT;
return true;
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 14b8084..befc1c6 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -1809,7 +1809,7 @@
*
* @return The measure spec to use to measure the root view.
*/
- private int getRootMeasureSpec(int windowSize, int rootDimension) {
+ private static int getRootMeasureSpec(int windowSize, int rootDimension) {
int measureSpec;
switch (rootDimension) {
@@ -2432,12 +2432,12 @@
mAccessibilityInteractionConnectionManager);
removeSendWindowContentChangedCallback();
+ destroyHardwareRenderer();
+
mView = null;
mAttachInfo.mRootView = null;
mAttachInfo.mSurface = null;
- destroyHardwareRenderer();
-
mSurface.release();
if (mInputQueueCallback != null && mInputQueue != null) {
@@ -2893,7 +2893,7 @@
* @param focused The currently focused view.
* @return An appropriate view, or null if no such view exists.
*/
- private ViewGroup findAncestorToTakeFocusInTouchMode(View focused) {
+ private static ViewGroup findAncestorToTakeFocusInTouchMode(View focused) {
ViewParent parent = focused.getParent();
while (parent instanceof ViewGroup) {
final ViewGroup vgParent = (ViewGroup) parent;
@@ -3763,7 +3763,7 @@
}
}
- private void getGfxInfo(View view, int[] info) {
+ private static void getGfxInfo(View view, int[] info) {
DisplayList displayList = view.mDisplayList;
info[0]++;
if (displayList != null) {
@@ -3784,6 +3784,7 @@
if (immediate) {
doDie();
} else {
+ destroyHardwareRenderer();
mHandler.sendEmptyMessage(MSG_DIE);
}
}
@@ -3826,10 +3827,18 @@
}
private void destroyHardwareRenderer() {
- if (mAttachInfo.mHardwareRenderer != null) {
- mAttachInfo.mHardwareRenderer.destroy(true);
- mAttachInfo.mHardwareRenderer = null;
- mAttachInfo.mHardwareAccelerated = false;
+ AttachInfo attachInfo = mAttachInfo;
+ HardwareRenderer hardwareRenderer = attachInfo.mHardwareRenderer;
+
+ if (hardwareRenderer != null) {
+ if (mView != null) {
+ hardwareRenderer.destroyHardwareResources(mView);
+ }
+ hardwareRenderer.destroy(true);
+ hardwareRenderer.setRequested(false);
+
+ attachInfo.mHardwareRenderer = null;
+ attachInfo.mHardwareAccelerated = false;
}
}
diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java
index 0e4a30f..f2ee9f9 100644
--- a/core/java/android/view/WindowManagerImpl.java
+++ b/core/java/android/view/WindowManagerImpl.java
@@ -354,7 +354,7 @@
View removeViewLocked(int index) {
ViewRootImpl root = mRoots[index];
View view = root.getView();
-
+
// Don't really remove until we have matched all calls to add().
root.mAddNesting--;
if (root.mAddNesting > 0) {
diff --git a/core/java/android/view/animation/Animation.java b/core/java/android/view/animation/Animation.java
index dc8c71b7..d92ebcd 100644
--- a/core/java/android/view/animation/Animation.java
+++ b/core/java/android/view/animation/Animation.java
@@ -875,7 +875,7 @@
* otherwise.
*
* @param currentTime Where we are in the animation. This is wall clock time.
- * @param outTransformation A tranformation object that is provided by the
+ * @param outTransformation A transformation object that is provided by the
* caller and will be filled in by the animation.
* @param scale Scaling factor to apply to any inputs to the transform operation, such
* pivot points being rotated or scaled around.
diff --git a/core/java/android/view/animation/Transformation.java b/core/java/android/view/animation/Transformation.java
index cf210c8..e8c1d23 100644
--- a/core/java/android/view/animation/Transformation.java
+++ b/core/java/android/view/animation/Transformation.java
@@ -112,6 +112,16 @@
}
/**
+ * Like {@link #compose(Transformation)} but does this.postConcat(t) of
+ * the transformation matrix.
+ * @hide
+ */
+ public void postCompose(Transformation t) {
+ mAlpha *= t.getAlpha();
+ mMatrix.postConcat(t.getMatrix());
+ }
+
+ /**
* @return The 3x3 Matrix representing the trnasformation to apply to the
* coordinates of the object being animated
*/
diff --git a/core/java/android/view/inputmethod/InputMethodSubtype.java b/core/java/android/view/inputmethod/InputMethodSubtype.java
index 18dec52..c22750e 100644
--- a/core/java/android/view/inputmethod/InputMethodSubtype.java
+++ b/core/java/android/view/inputmethod/InputMethodSubtype.java
@@ -27,6 +27,7 @@
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.IllegalFormatException;
import java.util.List;
import java.util.Locale;
@@ -45,6 +46,9 @@
private static final String TAG = InputMethodSubtype.class.getSimpleName();
private static final String EXTRA_VALUE_PAIR_SEPARATOR = ",";
private static final String EXTRA_VALUE_KEY_VALUE_SEPARATOR = "=";
+ // TODO: remove this
+ private static final String EXTRA_KEY_UNTRANSLATABLE_STRING_IN_SUBTYPE_NAME =
+ "UntranslatableReplacementStringInSubtypeName";
private final boolean mIsAuxiliary;
private final boolean mOverridesImplicitlyEnabledSubtype;
@@ -215,7 +219,17 @@
final CharSequence subtypeName = context.getPackageManager().getText(
packageName, mSubtypeNameResId, appInfo);
if (!TextUtils.isEmpty(subtypeName)) {
- return String.format(subtypeName.toString(), localeStr);
+ final String replacementString =
+ containsExtraValueKey(EXTRA_KEY_UNTRANSLATABLE_STRING_IN_SUBTYPE_NAME)
+ ? getExtraValueOf(EXTRA_KEY_UNTRANSLATABLE_STRING_IN_SUBTYPE_NAME)
+ : localeStr;
+ try {
+ return String.format(
+ subtypeName.toString(), replacementString != null ? replacementString : "");
+ } catch (IllegalFormatException e) {
+ Slog.w(TAG, "Found illegal format in subtype name("+ subtypeName + "): " + e);
+ return "";
+ }
} else {
return localeStr;
}
diff --git a/core/java/android/webkit/FindListener.java b/core/java/android/webkit/FindListener.java
deleted file mode 100644
index 124f737..0000000
--- a/core/java/android/webkit/FindListener.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.webkit;
-
-/**
- * @hide
- */
-public interface FindListener {
- /**
- * Notify the host application that a find result is available.
- *
- * @param numberOfMatches How many matches have been found
- * @param activeMatchOrdinal The ordinal of the currently selected match
- * @param isDoneCounting Whether we have finished counting matches
- */
- public void onFindResultReceived(int numberOfMatches,
- int activeMatchOrdinal, boolean isDoneCounting);
-}
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index dd373de..d225594 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -312,6 +312,24 @@
public static final String SCHEME_GEO = "geo:0,0?q=";
/**
+ * Interface to listen for find results.
+ * @hide
+ */
+ public interface FindListener {
+ /**
+ * Notify the listener about progress made by a find operation.
+ *
+ * @param numberOfMatches How many matches have been found.
+ * @param activeMatchOrdinal The zero-based ordinal of the currently selected match.
+ * @param isDoneCounting Whether the find operation has actually completed. The listener
+ * may be notified multiple times while the operation is underway, and the numberOfMatches
+ * value should not be considered final unless isDoneCounting is true.
+ */
+ public void onFindResultReceived(int numberOfMatches, int activeMatchOrdinal,
+ boolean isDoneCounting);
+ }
+
+ /**
* Interface to listen for new pictures as they change.
* @deprecated This interface is now obsolete.
*/
@@ -1228,10 +1246,10 @@
}
/**
- * Register the interface to be used when a find-on-page result has become
- * available. This will replace the current handler.
+ * Register the listener to be notified as find-on-page operations progress.
+ * This will replace the current listener.
*
- * @param listener An implementation of FindListener
+ * @param listener An implementation of {@link WebView#FindListener}.
* @hide
*/
public void setFindListener(FindListener listener) {
diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java
index 03329b8..ab2db22 100644
--- a/core/java/android/webkit/WebViewClassic.java
+++ b/core/java/android/webkit/WebViewClassic.java
@@ -1440,7 +1440,7 @@
private PictureListener mPictureListener;
// Used to notify listeners about find-on-page results.
- private FindListener mFindListener;
+ private WebView.FindListener mFindListener;
/**
* Refer to {@link WebView#requestFocusNodeHref(Message)} for more information
@@ -3620,12 +3620,10 @@
}
/**
- * Register the interface to be used when a find-on-page result has become
- * available. This will replace the current handler.
- *
- * @param listener An implementation of FindListener
+ * See {@link WebView#setFindListener(WebView.FindListener)}.
+ * @hide
*/
- public void setFindListener(FindListener listener) {
+ public void setFindListener(WebView.FindListener listener) {
mFindListener = listener;
}
diff --git a/core/java/android/webkit/WebViewProvider.java b/core/java/android/webkit/WebViewProvider.java
index 7d47e14..f049198 100644
--- a/core/java/android/webkit/WebViewProvider.java
+++ b/core/java/android/webkit/WebViewProvider.java
@@ -192,7 +192,7 @@
public WebBackForwardList copyBackForwardList();
- public void setFindListener(FindListener listener);
+ public void setFindListener(WebView.FindListener listener);
public void findNext(boolean forward);
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 55acb74..2f72e4a 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -965,6 +965,58 @@
}
/**
+ * Helper action to set compound drawables on a TextView. Supports relative
+ * (s/t/e/b) or cardinal (l/t/r/b) arrangement.
+ */
+ private class TextViewDrawableAction extends Action {
+ public TextViewDrawableAction(int viewId, boolean isRelative, int d1, int d2, int d3, int d4) {
+ this.viewId = viewId;
+ this.isRelative = isRelative;
+ this.d1 = d1;
+ this.d2 = d2;
+ this.d3 = d3;
+ this.d4 = d4;
+ }
+
+ public TextViewDrawableAction(Parcel parcel) {
+ viewId = parcel.readInt();
+ isRelative = (parcel.readInt() != 0);
+ d1 = parcel.readInt();
+ d2 = parcel.readInt();
+ d3 = parcel.readInt();
+ d4 = parcel.readInt();
+ }
+
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(TAG);
+ dest.writeInt(viewId);
+ dest.writeInt(isRelative ? 1 : 0);
+ dest.writeInt(d1);
+ dest.writeInt(d2);
+ dest.writeInt(d3);
+ dest.writeInt(d4);
+ }
+
+ @Override
+ public void apply(View root, ViewGroup rootParent) {
+ final Context context = root.getContext();
+ final TextView target = (TextView) root.findViewById(viewId);
+ if (target == null) return;
+ if (isRelative) {
+ target.setCompoundDrawablesRelativeWithIntrinsicBounds(d1, d2, d3, d4);
+ } else {
+ target.setCompoundDrawablesWithIntrinsicBounds(d1, d2, d3, d4);
+ }
+ }
+
+ int viewId;
+ boolean isRelative = false;
+ int d1, d2, d3, d4;
+
+ public final static int TAG = 11;
+ }
+
+ /**
* Simple class used to keep track of memory usage in a RemoteViews.
*
*/
@@ -1043,6 +1095,9 @@
case SetRemoteViewsAdapterIntent.TAG:
mActions.add(new SetRemoteViewsAdapterIntent(parcel));
break;
+ case TextViewDrawableAction.TAG:
+ mActions.add(new TextViewDrawableAction(parcel));
+ break;
default:
throw new ActionException("Tag " + tag + " not found");
}
@@ -1195,6 +1250,35 @@
}
/**
+ * Equivalent to calling
+ * {@link TextView#setCompoundDrawablesWithIntrinsicBounds(int, int, int, int)}.
+ *
+ * @param viewId The id of the view whose text should change
+ * @param left The id of a drawable to place to the left of the text, or 0
+ * @param top The id of a drawable to place above the text, or 0
+ * @param right The id of a drawable to place to the right of the text, or 0
+ * @param bottom The id of a drawable to place below the text, or 0
+ */
+ public void setTextViewCompoundDrawables(int viewId, int left, int top, int right, int bottom) {
+ addAction(new TextViewDrawableAction(viewId, false, left, top, right, bottom));
+ }
+
+ /**
+ * Equivalent to calling {@link
+ * TextView#setCompoundDrawablesRelativeWithIntrinsicBounds(int, int, int, int)}.
+ *
+ * @param viewId The id of the view whose text should change
+ * @param start The id of a drawable to place before the text (relative to the
+ * layout direction), or 0
+ * @param top The id of a drawable to place above the text, or 0
+ * @param end The id of a drawable to place after the text, or 0
+ * @param bottom The id of a drawable to place below the text, or 0
+ */
+ public void setTextViewCompoundDrawablesRelative(int viewId, int start, int top, int end, int bottom) {
+ addAction(new TextViewDrawableAction(viewId, true, start, top, end, bottom));
+ }
+
+ /**
* Equivalent to calling ImageView.setImageResource
*
* @param viewId The id of the view whose drawable should change
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 3c63b17..16d1b94 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -1798,6 +1798,7 @@
* @attr ref android.R.styleable#TextView_drawableRight
* @attr ref android.R.styleable#TextView_drawableBottom
*/
+ @android.view.RemotableViewMethod
public void setCompoundDrawablesWithIntrinsicBounds(int left, int top, int right, int bottom) {
final Resources resources = getContext().getResources();
setCompoundDrawablesWithIntrinsicBounds(left != 0 ? resources.getDrawable(left) : null,
@@ -1967,6 +1968,7 @@
* @attr ref android.R.styleable#TextView_drawableEnd
* @attr ref android.R.styleable#TextView_drawableBottom
*/
+ @android.view.RemotableViewMethod
public void setCompoundDrawablesRelativeWithIntrinsicBounds(int start, int top, int end,
int bottom) {
resetResolvedDrawables();
@@ -2042,6 +2044,7 @@
*
* @attr ref android.R.styleable#TextView_drawablePadding
*/
+ @android.view.RemotableViewMethod
public void setCompoundDrawablePadding(int pad) {
Drawables dr = mDrawables;
if (pad == 0) {
diff --git a/core/java/com/android/internal/app/HeavyWeightSwitcherActivity.java b/core/java/com/android/internal/app/HeavyWeightSwitcherActivity.java
index ef7e651..3d46cdd 100644
--- a/core/java/com/android/internal/app/HeavyWeightSwitcherActivity.java
+++ b/core/java/com/android/internal/app/HeavyWeightSwitcherActivity.java
@@ -123,7 +123,7 @@
private OnClickListener mSwitchOldListener = new OnClickListener() {
public void onClick(View v) {
try {
- ActivityManagerNative.getDefault().moveTaskToFront(mCurTask, 0);
+ ActivityManagerNative.getDefault().moveTaskToFront(mCurTask, 0, null);
} catch (RemoteException e) {
}
finish();
diff --git a/core/java/com/android/internal/backup/LocalTransport.java b/core/java/com/android/internal/backup/LocalTransport.java
index e7c3948..eed3e67 100644
--- a/core/java/com/android/internal/backup/LocalTransport.java
+++ b/core/java/com/android/internal/backup/LocalTransport.java
@@ -166,10 +166,13 @@
if (DEBUG) Log.v(TAG, "clearBackupData() pkg=" + packageInfo.packageName);
File packageDir = new File(mDataDir, packageInfo.packageName);
- for (File f : packageDir.listFiles()) {
- f.delete();
+ final File[] fileset = packageDir.listFiles();
+ if (fileset != null) {
+ for (File f : fileset) {
+ f.delete();
+ }
+ packageDir.delete();
}
- packageDir.delete();
return BackupConstants.TRANSPORT_OK;
}
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index fd32c8e..f020f5d 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -1168,6 +1168,7 @@
<string name="add_account_button_label" msgid="3611982894853435874">"Voeg rekening by"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Verhoging"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Verminder"</string>
+ <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> raak en hou."</string>
<string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Skuif op om by te tel en af om af te trek."</string>
<string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Tel \'n minuut by"</string>
<string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Trek \'n minuut af"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 50b6c67..f1379f7 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -1168,6 +1168,7 @@
<string name="add_account_button_label" msgid="3611982894853435874">"መለያ አክል"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"ጨምር"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"ቀንስ"</string>
+ <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> ንካ እና ያዝ።"</string>
<string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"ለመጨመር ወደላይ ለመቀነስ ወደታች አንሸራት"</string>
<string name="time_picker_increment_minute_button" msgid="2843066823236250329">"ደቂቃዎች ጨምር"</string>
<string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"ደቂቃ ቀንስ"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 9bd3ab2..a156e64 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -1168,6 +1168,7 @@
<string name="add_account_button_label" msgid="3611982894853435874">"إضافة حساب"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"زيادة"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"تناقص"</string>
+ <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> المس مع الاستمرار."</string>
<string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"مرر لأعلى للزيادة ولأسفل للإنقاص."</string>
<string name="time_picker_increment_minute_button" msgid="2843066823236250329">"زيادة دقيقة"</string>
<string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"إنقاص دقيقة"</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 2526bcd..0178764 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -1168,6 +1168,7 @@
<string name="add_account_button_label" msgid="3611982894853435874">"Дадаць уліковы запіс"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Інкрэмент"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Дэкрэмент"</string>
+ <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"Націсніце і ўтрымлівайце <xliff:g id="VALUE">%s</xliff:g>."</string>
<string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Перасуньце палец уверх, каб павялiчыць адрэзак, або ўніз, каб паменшыць."</string>
<string name="time_picker_increment_minute_button" msgid="2843066823236250329">"На хвiлiну больш"</string>
<string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"На хвiлiну менш"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index b34de19..479e118 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -1168,6 +1168,7 @@
<string name="add_account_button_label" msgid="3611982894853435874">"Добавяне на профил"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Увеличаване"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Намаляване"</string>
+ <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"Докоснете <xliff:g id="VALUE">%s</xliff:g> път/и и задръжте."</string>
<string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Плъзнете нагоре за увеличаване и надолу за намаляване."</string>
<string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Увеличаване на минутите"</string>
<string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Намаляване на минутите"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 675a4ba..64d0f87 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -1168,6 +1168,7 @@
<string name="add_account_button_label" msgid="3611982894853435874">"Afegeix un compte"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Incrementa"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Disminueix"</string>
+ <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"Mantén premut <xliff:g id="VALUE">%s</xliff:g>."</string>
<string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Fes lliscar el dit cap amunt per incrementar i cap avall per disminuir."</string>
<string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Incrementa els minuts"</string>
<string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Disminueix els minuts"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index b11f852..d2a4cc1 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -916,8 +916,8 @@
<string name="no" msgid="5141531044935541497">"Zrušit"</string>
<string name="dialog_alert_title" msgid="2049658708609043103">"Upozornění"</string>
<string name="loading" msgid="7933681260296021180">"Načítání..."</string>
- <string name="capital_on" msgid="1544682755514494298">"ZAPNUTO"</string>
- <string name="capital_off" msgid="6815870386972805832">"VYPNUTO"</string>
+ <string name="capital_on" msgid="1544682755514494298">"I"</string>
+ <string name="capital_off" msgid="6815870386972805832">"O"</string>
<string name="whichApplication" msgid="4533185947064773386">"Dokončit akci pomocí aplikace"</string>
<string name="alwaysUse" msgid="4583018368000610438">"Použít jako výchozí nastavení pro tuto činnost."</string>
<string name="clearDefaultHintMsg" msgid="3252584689512077257">"Výchozí nastavení vymažete v části Nastavení systému > Aplikace > Stažené."</string>
@@ -1168,6 +1168,7 @@
<string name="add_account_button_label" msgid="3611982894853435874">"Přidat účet"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Zvýšení"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Snížení"</string>
+ <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> dotkněte se a podržte."</string>
<string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Chcete-li přičítat, přejeďte prstem nahoru, chcete-li odečítat, přejeďte prstem dolů."</string>
<string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Přičíst minutu"</string>
<string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Odečíst minutu"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 89f3451..b139e5e 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -1168,6 +1168,7 @@
<string name="add_account_button_label" msgid="3611982894853435874">"Tilføj konto"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Optælling"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Nedtælling"</string>
+ <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"Tryk <xliff:g id="VALUE">%s</xliff:g> gange, og hold inde."</string>
<string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Glid op for at tilføje, og glid ned for at fjerne."</string>
<string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Tilføj minut"</string>
<string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Fjern minut"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 2de5212..baf3e40 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -1168,6 +1168,7 @@
<string name="add_account_button_label" msgid="3611982894853435874">"Konto hinzufügen"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Erhöhen"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Verringern"</string>
+ <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> berühren und gedrückt halten"</string>
<string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Zum Vorstellen nach oben und zum Zurückstellen nach unten ziehen"</string>
<string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Minute vorstellen"</string>
<string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Minute zurückstellen"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 4906812..ad840e3 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -1168,6 +1168,7 @@
<string name="add_account_button_label" msgid="3611982894853435874">"Προσθήκη λογαριασμού"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Αύξηση"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Μείωση"</string>
+ <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"Πατήστε παρατεταμένα το <xliff:g id="VALUE">%s</xliff:g>."</string>
<string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Πραγματοποιήστε κύλιση προς τα πάνω για αύξηση και προς τα κάτω για μείωση."</string>
<string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Αύξηση λεπτού"</string>
<string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Μείωση λεπτού"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index d8dac7c..de92665 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -1168,6 +1168,7 @@
<string name="add_account_button_label" msgid="3611982894853435874">"Add account"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Increment"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Decrement"</string>
+ <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> touch and hold."</string>
<string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Slide up to increment and down to decrease."</string>
<string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Increment minute"</string>
<string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Decrement minute"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 0071e0a..8761ca9 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -1168,6 +1168,7 @@
<string name="add_account_button_label" msgid="3611982894853435874">"Agregar una cuenta"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Incremento"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Decremento"</string>
+ <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"Mantén presionado <xliff:g id="VALUE">%s</xliff:g>."</string>
<string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Deslízate hacia arriba para aumentar y hacia abajo para disminuir."</string>
<string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Aumentar minutos"</string>
<string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Disminuir minutos"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 05b837d..9ede6a0 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -1168,6 +1168,7 @@
<string name="add_account_button_label" msgid="3611982894853435874">"Añadir cuenta"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Aumentar"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Disminuir"</string>
+ <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"Mantén pulsado <xliff:g id="VALUE">%s</xliff:g>."</string>
<string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Desliza el dedo hacia arriba para aumentar y hacia abajo para disminuir."</string>
<string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Aumentar minuto"</string>
<string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Disminuir minuto"</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 22de35d..b68944e 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -1168,6 +1168,7 @@
<string name="add_account_button_label" msgid="3611982894853435874">"Lisa konto"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Suurenda"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Vähenda"</string>
+ <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> puudutage ja hoidke."</string>
<string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Suurendamiseks lohistage üles, vähendamiseks alla."</string>
<string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Minutite arvu suurendamine"</string>
<string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Minutite arvu vähendamine"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index dd6a016..7ee47e7 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -1168,6 +1168,7 @@
<string name="add_account_button_label" msgid="3611982894853435874">"افزودن حساب"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"افزایش"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"کاهش"</string>
+ <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> لمس کرده و نگه دارید."</string>
<string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"برای افزایش به بالا و برای کاهش به پایین بلغزانید."</string>
<string name="time_picker_increment_minute_button" msgid="2843066823236250329">" افزایش دقیقه"</string>
<string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"کاهش دقیقه"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index c744479..b1009a5 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -1168,6 +1168,7 @@
<string name="add_account_button_label" msgid="3611982894853435874">"Lisää tili"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Lisää"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Vähennä"</string>
+ <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> kosketa pitkään."</string>
<string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Kasvata tai pienennä arvoa liu\'uttamalla ylös tai alas."</string>
<string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Kasvata minuuttia"</string>
<string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Pienennä minuuttia"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 62fe768..d044a70 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -1168,6 +1168,7 @@
<string name="add_account_button_label" msgid="3611982894853435874">"Ajouter un compte"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Augmenter"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Diminuer"</string>
+ <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> appuyez de manière prolongée."</string>
<string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Faire glisser vers le haut pour augmenter et vers le bas pour diminuer"</string>
<string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Minute suivante"</string>
<string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Minute précédente"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index bfc2f71..bd8863f 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -1168,6 +1168,7 @@
<string name="add_account_button_label" msgid="3611982894853435874">"खाता जोड़ें"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"वृद्धि"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"कमी"</string>
+ <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> को स्पर्श करके रखें."</string>
<string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"बढ़ते क्रम के लिए ऊपर और घटते क्रम के लिए नीचे की ओर स्लाइड करें."</string>
<string name="time_picker_increment_minute_button" msgid="2843066823236250329">"बढ़ते क्रम में मिनट"</string>
<string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"घटते क्रम में मिनट"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 77c5a10..749012b 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -1168,6 +1168,7 @@
<string name="add_account_button_label" msgid="3611982894853435874">"Dodaj račun"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Povećaj"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Smanji"</string>
+ <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> pritisnite i držite."</string>
<string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Klizite prema gore za pomak unaprijed, a prema dolje za pomak unatrag."</string>
<string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Pomak unaprijed za jednu minutu"</string>
<string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Pomak unatrag za jednu minutu"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 466cb3a..24a70d7 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -1168,6 +1168,7 @@
<string name="add_account_button_label" msgid="3611982894853435874">"Fiók hozzáadása"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Növelés"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Csökkentés"</string>
+ <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> érintse meg és tartsa lenyomva."</string>
<string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Csúsztassa fel a növeléshez és le a csökkentéshez."</string>
<string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Percek növelése"</string>
<string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Percek csökkentése"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 2ad73a4..8384b48 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -1168,6 +1168,7 @@
<string name="add_account_button_label" msgid="3611982894853435874">"Tambahkan akun"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Penambahan"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Pengurangan"</string>
+ <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> sentuh dan tahan."</string>
<string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Geser ke atas untuk menambah dan ke bawah untuk mengurangi."</string>
<string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Menit penambahan"</string>
<string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Menit pengurangan"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 1eb3be4..75ed4e8 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -1168,6 +1168,7 @@
<string name="add_account_button_label" msgid="3611982894853435874">"Aggiungi account"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Aumenta"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Diminuisci"</string>
+ <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"Tocca e tieni premuto il numero <xliff:g id="VALUE">%s</xliff:g>."</string>
<string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Scorri verso l\'alto per aumentare il valore e verso il basso per diminuirlo."</string>
<string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Aumenta minuto"</string>
<string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Diminuisci minuto"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 8edf115..f51f232 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -1168,6 +1168,7 @@
<string name="add_account_button_label" msgid="3611982894853435874">"הוסף חשבון"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"הגדל"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"הפחת"</string>
+ <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> גע והחזק."</string>
<string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"הסט מעלה כדי להוסיף ומטה כדי להפחית."</string>
<string name="time_picker_increment_minute_button" msgid="2843066823236250329">"הוסף דקה"</string>
<string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"הפחת דקה"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index fba0304..549c1e2 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -1168,6 +1168,7 @@
<string name="add_account_button_label" msgid="3611982894853435874">"アカウントを追加"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"増やす"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"減らす"</string>
+ <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g>回タップして押し続けます。"</string>
<string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"上にスライドで大きく、下にスライドで小さくなります。"</string>
<string name="time_picker_increment_minute_button" msgid="2843066823236250329">"1分進める"</string>
<string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"1分戻す"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 211c79c..fc8e7b1 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -1168,6 +1168,7 @@
<string name="add_account_button_label" msgid="3611982894853435874">"계정 추가"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"올리기"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"줄이기"</string>
+ <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> 길게 터치하세요."</string>
<string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"올리려면 위로 슬라이드하고 줄이려면 아래로 슬라이드합니다."</string>
<string name="time_picker_increment_minute_button" msgid="2843066823236250329">"\'분\'을 올립니다."</string>
<string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"\'분\'을 줄입니다."</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 9ceaa1d..5e9d3f4 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -1168,6 +1168,7 @@
<string name="add_account_button_label" msgid="3611982894853435874">"Pridėti paskyrą"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Padidinti"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Sumažinti"</string>
+ <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"Palieskite <xliff:g id="VALUE">%s</xliff:g> ir laikykite."</string>
<string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Slinkite aukštyn, kad būtų parodytas padidėjimas, ir žemyn, kad būtų parodytas sumažėjimas."</string>
<string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Padidėjimo minutė"</string>
<string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Sumažėjimo minutė"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 6ebc733..a568c3b 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -1168,6 +1168,7 @@
<string name="add_account_button_label" msgid="3611982894853435874">"Pievienot kontu"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Palielināt"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Samazināt"</string>
+ <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g>: pieskarieties un turiet nospiestu."</string>
<string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Bīdiet uz augšu, lai palielinātu vērtību, un uz leju, lai to samazinātu."</string>
<string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Palielināt minūtes vērtību"</string>
<string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Samazināt minūtes vērtību"</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 2b7fc36..363832d 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -1168,6 +1168,7 @@
<string name="add_account_button_label" msgid="3611982894853435874">"Tambah akaun"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Kenaikan"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Penyusutan"</string>
+ <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> sentuh terus."</string>
<string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Luncurkan ke atas untuk kenaikan dan ke bawah untuk penyusutan."</string>
<string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Minit kenaikan"</string>
<string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Minit penyusutan"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 580d30c..384fdac 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -1168,6 +1168,7 @@
<string name="add_account_button_label" msgid="3611982894853435874">"Legg til konto"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Øke"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Senke"</string>
+ <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> – trykk og hold inne."</string>
<string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Skyv opp for å øke og ned for å redusere."</string>
<string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Endre minutter (fremover)"</string>
<string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Endre minutter (bakover)"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 010a4d8..030222d 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -1168,6 +1168,7 @@
<string name="add_account_button_label" msgid="3611982894853435874">"Account toevoegen"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Hoger"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Lager"</string>
+ <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> blijven aanraken."</string>
<string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Schuif omhoog om te verhogen en omlaag om te verlagen."</string>
<string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Minuten verhogen"</string>
<string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Minuten verlagen"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 3d58076..9e4cbf3 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -1168,6 +1168,7 @@
<string name="add_account_button_label" msgid="3611982894853435874">"Dodaj konto"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Zwiększ"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Zmniejsz"</string>
+ <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> dotknij i przytrzymaj."</string>
<string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Przesuń w górę, aby zwiększyć wartość, lub w dół, aby ją zmniejszyć."</string>
<string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Następna minuta"</string>
<string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Poprzednia minuta"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 3e4c31b..abe1454 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -1168,6 +1168,7 @@
<string name="add_account_button_label" msgid="3611982894853435874">"Adicionar conta"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Aumentar"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Diminuir"</string>
+ <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"Toque sem soltar em <xliff:g id="VALUE">%s</xliff:g>."</string>
<string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Deslize lentamente para cima para aumentar e para baixo para diminuir."</string>
<string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Aumentar minuto"</string>
<string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Diminuir minuto"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 0af0052..3ae566c 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -1168,6 +1168,7 @@
<string name="add_account_button_label" msgid="3611982894853435874">"Adicionar conta"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Incremento"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Redução"</string>
+ <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> toque e mantenha pressionado."</string>
<string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Deslize para cima para aumentar e para baixo para diminuir."</string>
<string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Aumentar minuto"</string>
<string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Diminuir minuto"</string>
diff --git a/core/res/res/values-rm/strings.xml b/core/res/res/values-rm/strings.xml
index f14b247..fc6a510 100644
--- a/core/res/res/values-rm/strings.xml
+++ b/core/res/res/values-rm/strings.xml
@@ -1746,6 +1746,8 @@
<skip />
<!-- no translation found for number_picker_decrement_button (2576606679160067262) -->
<skip />
+ <!-- no translation found for number_picker_increment_scroll_mode (3073101067441638428) -->
+ <skip />
<!-- no translation found for number_picker_increment_scroll_action (4628981789985093179) -->
<skip />
<!-- no translation found for time_picker_increment_minute_button (2843066823236250329) -->
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 32d25c1..d443d1d 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -1168,6 +1168,7 @@
<string name="add_account_button_label" msgid="3611982894853435874">"Adăugaţi un cont"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Incrementaţi"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Decrementaţi"</string>
+ <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"Atingeţi şi ţineţi apăsat <xliff:g id="VALUE">%s</xliff:g>."</string>
<string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Glisaţi în sus pentru incrementare şi în jos pentru decrementare."</string>
<string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Incrementaţi valoarea pentru minut"</string>
<string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Decrementaţi valoarea pentru minut"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 989be4a..5ed4c2e 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -1168,6 +1168,7 @@
<string name="add_account_button_label" msgid="3611982894853435874">"Добавить аккаунт"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Увеличить"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Уменьшить"</string>
+ <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"Нажмите и удерживайте <xliff:g id="VALUE">%s</xliff:g>."</string>
<string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Проведите вверх, чтобы увеличить значение, и вниз, чтобы уменьшить его."</string>
<string name="time_picker_increment_minute_button" msgid="2843066823236250329">"На минуту вперед"</string>
<string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"На минуту назад"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 4a1fe20..2e97b82 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -1168,6 +1168,7 @@
<string name="add_account_button_label" msgid="3611982894853435874">"Pridať účet"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Zvýšenie"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Zníženie"</string>
+ <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"Dotknite sa a podržte <xliff:g id="VALUE">%s</xliff:g>."</string>
<string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Ak chcete pripočítať, potiahnite prst nahor. Ak chcete odpočítať, potiahnite prst nadol."</string>
<string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Pripočítať minútu"</string>
<string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Odpočítať minútu"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index e079147..f66cabb 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -1168,6 +1168,7 @@
<string name="add_account_button_label" msgid="3611982894853435874">"Dodaj račun"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Povečaj"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Zmanjšaj"</string>
+ <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"Dotaknite se vrednosti <xliff:g id="VALUE">%s</xliff:g> in jo pridržite."</string>
<string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Povlecite gor za povečanje in dol za zmanjšanje."</string>
<string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Povečaj minute"</string>
<string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Zmanjšaj minute"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 273a3ac..66c0561 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -1168,6 +1168,7 @@
<string name="add_account_button_label" msgid="3611982894853435874">"Додај налог"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Повећање"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Смањење"</string>
+ <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> додирните и задржите."</string>
<string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Превуците нагоре за повећање, а надоле за смањење."</string>
<string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Повећај минуте"</string>
<string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Смањи минуте"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 291f36b..6559fc5 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -743,8 +743,7 @@
<string name="double_tap_toast" msgid="4595046515400268881">"Tips! Dubbelknacka om du vill zooma in eller ut."</string>
<string name="autofill_this_form" msgid="4616758841157816676">"Autofyll"</string>
<string name="setup_autofill" msgid="7103495070180590814">"Ange Autofyll"</string>
- <!-- no translation found for autofill_address_name_separator (6350145154779706772) -->
- <skip />
+ <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
<string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
<string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
<string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
@@ -1169,6 +1168,7 @@
<string name="add_account_button_label" msgid="3611982894853435874">"Lägg till konto"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Öka"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Minska"</string>
+ <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> tryck länge."</string>
<string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Skjut uppåt för att öka och nedåt för att minska."</string>
<string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Öka minuter"</string>
<string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Minska minuter"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index dfdeb2f..39d2aba 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -1168,6 +1168,7 @@
<string name="add_account_button_label" msgid="3611982894853435874">"Ongeza akaunti"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Ongezeko"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Punguza"</string>
+ <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> gusa na ushikilie."</string>
<string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Nyiririsha juu kuongeza na chini kupunguza."</string>
<string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Dakika ya nyongeza"</string>
<string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Dakika pungufu"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index ebd2a31..4b59923 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -1168,6 +1168,7 @@
<string name="add_account_button_label" msgid="3611982894853435874">"เพิ่มบัญชี"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"การเพิ่ม"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"การลด"</string>
+ <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"แตะ <xliff:g id="VALUE">%s</xliff:g> ค้างไว้"</string>
<string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"เลื่อนขึ้นเพื่อเพิ่มและเลื่อนลงเพื่อลด"</string>
<string name="time_picker_increment_minute_button" msgid="2843066823236250329">"เพิ่มนาที"</string>
<string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"ลดนาที"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 0cc2b1f..dc22a08 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -1168,6 +1168,7 @@
<string name="add_account_button_label" msgid="3611982894853435874">"Magdagdag ng account"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Taasan"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Babaan"</string>
+ <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> pindutin nang matagal."</string>
<string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"I-slide pataas upang magdagdag at pababa upang magbawas."</string>
<string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Minuto ng pagdaragdag"</string>
<string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Minuto ng pagbawas"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index c4a5e83..419ae96 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -1168,6 +1168,7 @@
<string name="add_account_button_label" msgid="3611982894853435874">"Hesap ekle"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Artır"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Azalt"</string>
+ <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> rakamına dokunun ve basılı tutun."</string>
<string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Artırmak için yukarı, azaltmak için aşağı kaydırın."</string>
<string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Dakika değerini artır"</string>
<string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Dakika değerini azalt"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index ac04bc2..13311f1 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -1168,6 +1168,7 @@
<string name="add_account_button_label" msgid="3611982894853435874">"Додати облік. запис"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Додати"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Відняти"</string>
+ <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> – торкніться й утримуйте."</string>
<string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Перемістіть угору, щоб додати, і вниз, щоб відняти."</string>
<string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Додати хвилину"</string>
<string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Відняти хвилину"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 7fa924b..b94f104 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -1168,6 +1168,7 @@
<string name="add_account_button_label" msgid="3611982894853435874">"Thêm tài khoản"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Tăng dần"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Giảm dần"</string>
+ <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"Chạm và giữ <xliff:g id="VALUE">%s</xliff:g>."</string>
<string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Trượt lên để tăng và trượt xuống để giảm."</string>
<string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Phút tăng dần"</string>
<string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Phút giảm dần"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 53baaef..d7a1e43 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -145,7 +145,7 @@
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"您的手机会关机。"</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"您要关机吗?"</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"近期任务"</string>
- <string name="no_recent_tasks" msgid="8794906658732193473">"最近没有运行任何应用程序"</string>
+ <string name="no_recent_tasks" msgid="8794906658732193473">"最近没有运行任何应用"</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"平板电脑选项"</string>
<string name="global_actions" product="default" msgid="2406416831541615258">"手机选项"</string>
<string name="global_action_lock" msgid="2844945191792119712">"屏幕锁定"</string>
@@ -179,162 +179,162 @@
<string name="permgrouplab_systemTools" msgid="4652191644082714048">"系统工具"</string>
<string name="permgroupdesc_systemTools" msgid="8162102602190734305">"对系统进行低级访问和控制。"</string>
<string name="permgrouplab_developmentTools" msgid="3446164584710596513">"开发工具"</string>
- <string name="permgroupdesc_developmentTools" msgid="7058828032358142018">"只有应用程序开发人员才需要的功能。"</string>
+ <string name="permgroupdesc_developmentTools" msgid="7058828032358142018">"只有应用开发人员才需要的功能。"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"存储"</string>
<string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"访问 USB 存储设备。"</string>
<string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"访问 SD 卡。"</string>
<string name="permlab_statusBar" msgid="7417192629601890791">"停用或修改状态栏"</string>
- <string name="permdesc_statusBar" msgid="8434669549504290975">"允许应用程序停用状态栏或者增删系统图标。"</string>
+ <string name="permdesc_statusBar" msgid="8434669549504290975">"允许应用停用状态栏或者增删系统图标。"</string>
<string name="permlab_statusBarService" msgid="7247281911387931485">"状态栏"</string>
- <string name="permdesc_statusBarService" msgid="716113660795976060">"允许以状态栏形式显示应用程序。"</string>
+ <string name="permdesc_statusBarService" msgid="716113660795976060">"允许以状态栏形式显示应用。"</string>
<string name="permlab_expandStatusBar" msgid="1148198785937489264">"展开/收拢状态栏"</string>
- <string name="permdesc_expandStatusBar" msgid="6917549437129401132">"允许应用程序展开或折叠状态栏。"</string>
+ <string name="permdesc_expandStatusBar" msgid="6917549437129401132">"允许应用展开或折叠状态栏。"</string>
<string name="permlab_processOutgoingCalls" msgid="1136262550878335980">"拦截外拨电话"</string>
- <string name="permdesc_processOutgoingCalls" msgid="1152111671618301044">"允许应用程序处理外拨通话并更改要拨打的号码。恶意应用程序可能会监视、重定向或阻止外拨通话。"</string>
+ <string name="permdesc_processOutgoingCalls" msgid="1152111671618301044">"允许应用处理外拨通话并更改要拨打的号码。恶意应用可能会监视、重定向或阻止外拨通话。"</string>
<string name="permlab_receiveSms" msgid="2697628268086208535">"接收短信"</string>
- <string name="permdesc_receiveSms" msgid="8107887121893611793">"允许应用程序接收和处理短信。恶意应用程序可能会监视您的短信,或删除短信而不向您显示。"</string>
+ <string name="permdesc_receiveSms" msgid="8107887121893611793">"允许应用接收和处理短信。恶意应用可能会监视您的短信,或删除短信而不向您显示。"</string>
<string name="permlab_receiveMms" msgid="8894700916188083287">"接收彩信"</string>
- <string name="permdesc_receiveMms" msgid="1424805308566612086">"允许应用程序接收和处理彩信。恶意应用程序可能会监视您的短信,或删除短信而不向您显示。"</string>
+ <string name="permdesc_receiveMms" msgid="1424805308566612086">"允许应用接收和处理彩信。恶意应用可能会监视您的短信,或删除短信而不向您显示。"</string>
<string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"接收紧急广播"</string>
- <string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"允许应用程序接收和处理紧急广播消息。此权限仅适用于系统应用程序。"</string>
+ <string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"允许应用接收和处理紧急广播消息。此权限仅适用于系统应用。"</string>
<string name="permlab_sendSms" msgid="5600830612147671529">"发送短信"</string>
- <string name="permdesc_sendSms" msgid="906546667507626156">"允许应用程序发送短信。恶意应用程序可能会未经您的确认而发送短信,由此产生相关费用。"</string>
+ <string name="permdesc_sendSms" msgid="906546667507626156">"允许应用发送短信。恶意应用可能会未经您的确认而发送短信,由此产生相关费用。"</string>
<string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"不经确认直接发送短信"</string>
- <string name="permdesc_sendSmsNoConfirmation" msgid="3437759207020400204">"允许应用程序发送短信。恶意应用程序可能会未经您的确认而发送短信,由此产生相关费用。"</string>
+ <string name="permdesc_sendSmsNoConfirmation" msgid="3437759207020400204">"允许应用发送短信。恶意应用可能会未经您的确认而发送短信,由此产生相关费用。"</string>
<string name="permlab_readSms" msgid="4085333708122372256">"读取短信或彩信"</string>
- <string name="permdesc_readSms" product="tablet" msgid="2341692916884515613">"允许应用程序读取您的平板电脑或 SIM 卡上存储的短信。恶意应用程序可能会读取您的机密短信。"</string>
- <string name="permdesc_readSms" product="default" msgid="5653850482025875493">"允许应用程序读取您的手机或 SIM 卡上存储的短信。恶意应用程序可能借此读取您的机密短信。"</string>
+ <string name="permdesc_readSms" product="tablet" msgid="2341692916884515613">"允许应用读取您的平板电脑或 SIM 卡上存储的短信。恶意应用可能会读取您的机密短信。"</string>
+ <string name="permdesc_readSms" product="default" msgid="5653850482025875493">"允许应用读取您的手机或 SIM 卡上存储的短信。恶意应用可能借此读取您的机密短信。"</string>
<string name="permlab_writeSms" msgid="6881122575154940744">"编辑短信或彩信"</string>
- <string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"允许应用程序对平板电脑或 SIM 卡上存储的短信执行写入操作。恶意应用程序可能会删除您的短信。"</string>
- <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"允许应用程序对手机或 SIM 卡上存储的短信执行写入操作。恶意应用程序可能会删除您的短信。"</string>
+ <string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"允许应用对平板电脑或 SIM 卡上存储的短信执行写入操作。恶意应用可能会删除您的短信。"</string>
+ <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"允许应用对手机或 SIM 卡上存储的短信执行写入操作。恶意应用可能会删除您的短信。"</string>
<string name="permlab_receiveWapPush" msgid="8258226427716551388">"接收 WAP"</string>
- <string name="permdesc_receiveWapPush" msgid="7983455145335316872">"允许应用程序接收和处理 WAP 短信。恶意应用程序可能会监视您的短信,或删除短信而不向您显示。"</string>
- <string name="permlab_getTasks" msgid="6466095396623933906">"检索正在运行的应用程序"</string>
- <string name="permdesc_getTasks" msgid="6608159250520381359">"允许应用程序针对近期运行的和当前正在运行的任务检索相关信息。恶意应用程序可能会发现有关其他应用程序的私密信息。"</string>
- <string name="permlab_reorderTasks" msgid="2018575526934422779">"对正在运行的应用程序重新排序"</string>
- <string name="permdesc_reorderTasks" msgid="4175137612205663399">"允许应用程序将任务移动到前台和后台。恶意应用程序可能会不受您的控制,强行让自己处于前台。"</string>
- <string name="permlab_removeTasks" msgid="6821513401870377403">"停止正在运行的应用程序"</string>
- <string name="permdesc_removeTasks" msgid="1394714352062635493">"允许该应用程序删除任务并终止这些任务的应用程序。恶意应用程序可以籍此影响其他应用程序的行为。"</string>
+ <string name="permdesc_receiveWapPush" msgid="7983455145335316872">"允许应用接收和处理 WAP 短信。恶意应用可能会监视您的短信,或删除短信而不向您显示。"</string>
+ <string name="permlab_getTasks" msgid="6466095396623933906">"检索正在运行的应用"</string>
+ <string name="permdesc_getTasks" msgid="6608159250520381359">"允许应用针对近期运行的和当前正在运行的任务检索相关信息。恶意应用可能会发现有关其他应用的私密信息。"</string>
+ <string name="permlab_reorderTasks" msgid="2018575526934422779">"对正在运行的应用重新排序"</string>
+ <string name="permdesc_reorderTasks" msgid="4175137612205663399">"允许应用将任务移动到前台和后台。恶意应用可能会不受您的控制,强行让自己处于前台。"</string>
+ <string name="permlab_removeTasks" msgid="6821513401870377403">"停止正在运行的应用"</string>
+ <string name="permdesc_removeTasks" msgid="1394714352062635493">"允许该应用删除任务并终止这些任务的应用。恶意应用可以籍此影响其他应用的行为。"</string>
<string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"设置屏幕兼容性"</string>
- <string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"允许该应用程序控制其他应用程序的屏幕兼容模式。恶意应用程序可以籍此影响其他应用程序的行为。"</string>
- <string name="permlab_setDebugApp" msgid="3022107198686584052">"启用应用程序调试"</string>
- <string name="permdesc_setDebugApp" msgid="4474512416299013256">"允许该应用程序对其他应用程序启用调试。恶意应用程序可以籍此终止其他的应用程序。"</string>
+ <string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"允许该应用控制其他应用的屏幕兼容模式。恶意应用可以籍此影响其他应用的行为。"</string>
+ <string name="permlab_setDebugApp" msgid="3022107198686584052">"启用应用调试"</string>
+ <string name="permdesc_setDebugApp" msgid="4474512416299013256">"允许该应用对其他应用启用调试。恶意应用可以籍此终止其他的应用。"</string>
<string name="permlab_changeConfiguration" msgid="8214475779521218295">"更改用户界面设置"</string>
- <string name="permdesc_changeConfiguration" msgid="4372223873154296076">"允许该应用程序更改当前配置,例如语言区域或整体的字体大小。"</string>
+ <string name="permdesc_changeConfiguration" msgid="4372223873154296076">"允许该应用更改当前配置,例如语言区域或整体的字体大小。"</string>
<string name="permlab_enableCarMode" msgid="5684504058192921098">"启用车载模式"</string>
- <string name="permdesc_enableCarMode" msgid="4853187425751419467">"允许应用程序启用车载模式。"</string>
+ <string name="permdesc_enableCarMode" msgid="4853187425751419467">"允许应用启用车载模式。"</string>
<string name="permlab_killBackgroundProcesses" msgid="8373714752793061963">"结束后台进程"</string>
- <string name="permdesc_killBackgroundProcesses" msgid="931129103262126617">"允许应用程序在内存空间充足的情况下终止其他应用程序的后台进程。"</string>
- <string name="permlab_forceStopPackages" msgid="2329627428832067700">"强行停止其他应用程序"</string>
- <string name="permdesc_forceStopPackages" msgid="5253157296183940812">"允许应用程序强行停止其他应用程序。"</string>
- <string name="permlab_forceBack" msgid="652935204072584616">"强制应用程序关闭"</string>
- <string name="permdesc_forceBack" msgid="3892295830419513623">"允许应用程序强制关闭任何前台活动并返回。普通应用程序绝不需要此权限。"</string>
+ <string name="permdesc_killBackgroundProcesses" msgid="931129103262126617">"允许应用在内存空间充足的情况下终止其他应用的后台进程。"</string>
+ <string name="permlab_forceStopPackages" msgid="2329627428832067700">"强行停止其他应用"</string>
+ <string name="permdesc_forceStopPackages" msgid="5253157296183940812">"允许应用强行停止其他应用。"</string>
+ <string name="permlab_forceBack" msgid="652935204072584616">"强制应用关闭"</string>
+ <string name="permdesc_forceBack" msgid="3892295830419513623">"允许应用强制关闭任何前台活动并返回。普通应用绝不需要此权限。"</string>
<string name="permlab_dump" msgid="1681799862438954752">"检索系统内部状态"</string>
- <string name="permdesc_dump" msgid="1778299088692290329">"允许应用程序检索系统的内部状态。恶意应用程序可能会检索一般情况下绝不需要检索的多种私人信息和安全信息。"</string>
+ <string name="permdesc_dump" msgid="1778299088692290329">"允许应用检索系统的内部状态。恶意应用可能会检索一般情况下绝不需要检索的多种私人信息和安全信息。"</string>
<string name="permlab_retrieve_window_content" msgid="8022588608994589938">"检索屏幕内容"</string>
- <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"允许应用程序检索活动窗口的内容。恶意应用程序可能会检索整个窗口的内容,并检查其中除密码以外的所有文字。"</string>
+ <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"允许应用检索活动窗口的内容。恶意应用可能会检索整个窗口的内容,并检查其中除密码以外的所有文字。"</string>
<string name="permlab_shutdown" msgid="7185747824038909016">"部分关机"</string>
<string name="permdesc_shutdown" msgid="7046500838746291775">"使活动管理器进入关闭状态。不执行彻底关机。"</string>
- <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"禁止切换应用程序"</string>
- <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"阻止用户切换到其他应用程序。"</string>
- <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"监控所有应用程序的启动"</string>
- <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"允许应用程序监视和控制系统是如何启动活动的。恶意应用程序可能会完全破坏系统。此权限只有在进行开发时才需要,正常使用情况下绝不需要。"</string>
+ <string name="permlab_stopAppSwitches" msgid="4138608610717425573">"禁止切换应用"</string>
+ <string name="permdesc_stopAppSwitches" msgid="8262195802582255021">"阻止用户切换到其他应用。"</string>
+ <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"监控所有应用的启动"</string>
+ <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"允许应用监视和控制系统是如何启动活动的。恶意应用可能会完全破坏系统。此权限只有在进行开发时才需要,正常使用情况下绝不需要。"</string>
<string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"发送包删除的广播"</string>
- <string name="permdesc_broadcastPackageRemoved" msgid="6621901216207931089">"允许应用程序广播一条有关已删除了应用程序包的通知。恶意应用程序可能借此终止其他任何正在运行的应用程序。"</string>
+ <string name="permdesc_broadcastPackageRemoved" msgid="6621901216207931089">"允许应用广播一条有关已删除了应用包的通知。恶意应用可能借此终止其他任何正在运行的应用。"</string>
<string name="permlab_broadcastSmsReceived" msgid="5689095009030336593">"发送短信收到的广播"</string>
- <string name="permdesc_broadcastSmsReceived" msgid="4152037720034365492">"允许应用程序广播一条有关已收到短信的通知。恶意应用程序可能借此伪造接到的短信。"</string>
+ <string name="permdesc_broadcastSmsReceived" msgid="4152037720034365492">"允许应用广播一条有关已收到短信的通知。恶意应用可能借此伪造接到的短信。"</string>
<string name="permlab_broadcastWapPush" msgid="3145347413028582371">"发送 WAP-PUSH 收到的广播"</string>
- <string name="permdesc_broadcastWapPush" msgid="4783402525039442729">"允许应用程序广播一条有关已收到 WAP PUSH 短信的通知。恶意应用程序可能借此伪造短信接收,或在后台将任意网页的内容替换为恶意内容。"</string>
+ <string name="permdesc_broadcastWapPush" msgid="4783402525039442729">"允许应用广播一条有关已收到 WAP PUSH 短信的通知。恶意应用可能借此伪造短信接收,或在后台将任意网页的内容替换为恶意内容。"</string>
<string name="permlab_setProcessLimit" msgid="2451873664363662666">"限制运行的进程个数"</string>
- <string name="permdesc_setProcessLimit" msgid="7318061314040879542">"允许应用程序控制将运行的进程数上限。普通应用程序绝不需要此权限。"</string>
- <string name="permlab_setAlwaysFinish" msgid="238828158465736054">"关闭所有后台应用程序"</string>
- <string name="permdesc_setAlwaysFinish" msgid="7471310652868841499">"允许应用程序控制活动在转入后台后是否立即结束。普通应用程序绝不需要此权限。"</string>
+ <string name="permdesc_setProcessLimit" msgid="7318061314040879542">"允许应用控制将运行的进程数上限。普通应用绝不需要此权限。"</string>
+ <string name="permlab_setAlwaysFinish" msgid="238828158465736054">"关闭所有后台应用"</string>
+ <string name="permdesc_setAlwaysFinish" msgid="7471310652868841499">"允许应用控制活动在转入后台后是否立即结束。普通应用绝不需要此权限。"</string>
<string name="permlab_batteryStats" msgid="7863923071360031652">"修改电池统计信息"</string>
- <string name="permdesc_batteryStats" msgid="6835186932305744068">"允许应用程序修改收集到的电池统计信息。普通应用程序不能使用此权限。"</string>
+ <string name="permdesc_batteryStats" msgid="6835186932305744068">"允许应用修改收集到的电池统计信息。普通应用不能使用此权限。"</string>
<string name="permlab_backup" msgid="470013022865453920">"控制系统备份和还原"</string>
- <string name="permdesc_backup" msgid="6912230525140589891">"允许应用程序控制系统的备份和还原机制。普通应用程序不能使用此权限。"</string>
+ <string name="permdesc_backup" msgid="6912230525140589891">"允许应用控制系统的备份和还原机制。普通应用不能使用此权限。"</string>
<string name="permlab_confirm_full_backup" msgid="5557071325804469102">"确认完整备份或恢复操作"</string>
- <string name="permdesc_confirm_full_backup" msgid="1748762171637699562">"允许应用程序启动完整备份确认用户界面。不用于任何应用程序。"</string>
+ <string name="permdesc_confirm_full_backup" msgid="1748762171637699562">"允许应用启动完整备份确认用户界面。不用于任何应用。"</string>
<string name="permlab_internalSystemWindow" msgid="2148563628140193231">"显示未授权的窗口"</string>
- <string name="permdesc_internalSystemWindow" msgid="7458387759461466397">"允许该应用程序创建供内部系统用户界面使用的窗口。普通应用程序不应使用此权限。"</string>
+ <string name="permdesc_internalSystemWindow" msgid="7458387759461466397">"允许该应用创建供内部系统用户界面使用的窗口。普通应用不应使用此权限。"</string>
<string name="permlab_systemAlertWindow" msgid="3372321942941168324">"显示系统级警报"</string>
- <string name="permdesc_systemAlertWindow" msgid="8507863469978066409">"允许应用程序显示系统警告窗口。恶意应用程序可能会控制整个屏幕。"</string>
+ <string name="permdesc_systemAlertWindow" msgid="8507863469978066409">"允许应用显示系统警告窗口。恶意应用可能会控制整个屏幕。"</string>
<string name="permlab_setAnimationScale" msgid="2805103241153907174">"修改全局动画速度"</string>
- <string name="permdesc_setAnimationScale" msgid="7690063428924343571">"允许该应用程序随时更改全局动画速度(加快或减慢)。"</string>
- <string name="permlab_manageAppTokens" msgid="1286505717050121370">"管理应用程序令牌"</string>
- <string name="permdesc_manageAppTokens" msgid="8043431713014395671">"允许应用程序绕过其正常的 Z 排序创建和管理自己的令牌。普通应用程序绝不需要此权限。"</string>
+ <string name="permdesc_setAnimationScale" msgid="7690063428924343571">"允许该应用随时更改全局动画速度(加快或减慢)。"</string>
+ <string name="permlab_manageAppTokens" msgid="1286505717050121370">"管理应用令牌"</string>
+ <string name="permdesc_manageAppTokens" msgid="8043431713014395671">"允许应用绕过其正常的 Z 排序创建和管理自己的令牌。普通应用绝不需要此权限。"</string>
<string name="permlab_injectEvents" msgid="1378746584023586600">"按键和控制按钮"</string>
- <string name="permdesc_injectEvents" product="tablet" msgid="206352565599968632">"允许应用程序将自身的输入活动(例如按键操作等)提供给其他应用程序。恶意应用程序可能借此控制平板电脑。"</string>
- <string name="permdesc_injectEvents" product="default" msgid="653128057572326253">"允许应用程序将自身的输入活动(例如按键操作等)提供给其他应用程序。恶意应用程序可能借此控制手机。"</string>
+ <string name="permdesc_injectEvents" product="tablet" msgid="206352565599968632">"允许应用将自身的输入活动(例如按键操作等)提供给其他应用。恶意应用可能借此控制平板电脑。"</string>
+ <string name="permdesc_injectEvents" product="default" msgid="653128057572326253">"允许应用将自身的输入活动(例如按键操作等)提供给其他应用。恶意应用可能借此控制手机。"</string>
<string name="permlab_readInputState" msgid="469428900041249234">"记录您键入的内容和执行的操作"</string>
- <string name="permdesc_readInputState" msgid="8387754901688728043">"允许应用程序记录您所按的键,包括与其他应用程序进行交互(如输入密码)时按的键。普通应用程序绝不需要此权限。"</string>
+ <string name="permdesc_readInputState" msgid="8387754901688728043">"允许应用记录您所按的键,包括与其他应用进行交互(如输入密码)时按的键。普通应用绝不需要此权限。"</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"绑定至输入法"</string>
- <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"允许用户绑定至输入法的顶级接口。普通应用程序绝不需要此权限。"</string>
+ <string name="permdesc_bindInputMethod" msgid="3250440322807286331">"允许用户绑定至输入法的顶级接口。普通应用绝不需要此权限。"</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"绑定至文字服务"</string>
- <string name="permdesc_bindTextService" msgid="8151968910973998670">"允许用户绑定至文字服务(如 SpellCheckerService)的顶级接口。普通应用程序绝不需要此权限。"</string>
+ <string name="permdesc_bindTextService" msgid="8151968910973998670">"允许用户绑定至文字服务(如 SpellCheckerService)的顶级接口。普通应用绝不需要此权限。"</string>
<string name="permlab_bindVpnService" msgid="4708596021161473255">"绑定到 VPN 服务"</string>
- <string name="permdesc_bindVpnService" msgid="2067845564581693905">"允许用户绑定到 VPN 服务的顶级接口。普通应用程序从不需要此权限。"</string>
+ <string name="permdesc_bindVpnService" msgid="2067845564581693905">"允许用户绑定到 VPN 服务的顶级接口。普通应用从不需要此权限。"</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"绑定到壁纸"</string>
- <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"允许用户绑定到壁纸的顶级接口。普通应用程序绝不需要此权限。"</string>
+ <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"允许用户绑定到壁纸的顶级接口。普通应用绝不需要此权限。"</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"绑定到窗口小部件服务"</string>
- <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"允许用户绑定到窗口小部件服务的顶级接口。普通应用程序绝不需要此权限。"</string>
+ <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"允许用户绑定到窗口小部件服务的顶级接口。普通应用绝不需要此权限。"</string>
<string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"与设备管理器交互"</string>
- <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"允许用户将意向发送给设备管理员。普通应用程序绝不需要此权限。"</string>
+ <string name="permdesc_bindDeviceAdmin" msgid="569715419543907930">"允许用户将意向发送给设备管理员。普通应用绝不需要此权限。"</string>
<string name="permlab_setOrientation" msgid="3365947717163866844">"更改屏幕显示方向"</string>
- <string name="permdesc_setOrientation" msgid="3046126619316671476">"允许应用程序随时更改屏幕的旋转状态。普通应用程序绝不需要此权限。"</string>
+ <string name="permdesc_setOrientation" msgid="3046126619316671476">"允许应用随时更改屏幕的旋转状态。普通应用绝不需要此权限。"</string>
<string name="permlab_setPointerSpeed" msgid="9175371613322562934">"更改指针速度"</string>
- <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"允许应用程序随时更改鼠标或触控板指针速度。普通应用程序绝不需要此权限。"</string>
- <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"向应用程序发送 Linux 信号"</string>
- <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"允许应用程序请求将提供的信号发送给所有持续的进程。"</string>
- <string name="permlab_persistentActivity" msgid="8841113627955563938">"让应用程序始终运行"</string>
- <string name="permdesc_persistentActivity" msgid="4909910271316074418">"允许应用程序持续保留其自身的某些组件,这样系统就无法将其用于其他应用程序。"</string>
- <string name="permlab_deletePackages" msgid="184385129537705938">"删除应用程序"</string>
- <string name="permdesc_deletePackages" msgid="7411480275167205081">"允许应用程序删除 Android 程序包。恶意应用程序可能借此删除重要的应用程序。"</string>
- <string name="permlab_clearAppUserData" msgid="274109191845842756">"删除其他应用程序的数据"</string>
- <string name="permdesc_clearAppUserData" msgid="4625323684125459488">"允许应用程序清除用户数据。"</string>
- <string name="permlab_deleteCacheFiles" msgid="3128665571837408675">"删除其他应用程序的缓存"</string>
- <string name="permdesc_deleteCacheFiles" msgid="3812998599006730196">"允许应用程序删除缓存文件。"</string>
- <string name="permlab_getPackageSize" msgid="7472921768357981986">"计算应用程序存储空间"</string>
- <string name="permdesc_getPackageSize" msgid="3921068154420738296">"允许应用程序检索其代码、数据和缓存大小"</string>
- <string name="permlab_installPackages" msgid="2199128482820306924">"直接安装应用程序"</string>
- <string name="permdesc_installPackages" msgid="5628530972548071284">"允许应用程序安装新的或更新的 Android 程序包。恶意应用程序可能借此添加具有任意权限的新应用程序。"</string>
- <string name="permlab_clearAppCache" msgid="7487279391723526815">"删除所有应用程序缓存数据"</string>
- <string name="permdesc_clearAppCache" product="tablet" msgid="3523396284474042284">"允许应用程序删除应用程序缓存目录中的文件,从而释放平板电脑的存储空间。对系统进程的访问权限通常受到很大的限制。"</string>
- <string name="permdesc_clearAppCache" product="default" msgid="5067988373366292186">"允许应用程序删除应用程序缓存目录中的文件,从而释放手机的存储空间。对系统进程的访问权限通常受到很大的限制。"</string>
- <string name="permlab_movePackage" msgid="3289890271645921411">"移动应用程序资源"</string>
- <string name="permdesc_movePackage" msgid="319562217778244524">"允许应用程序在内部与外部媒体之间移动应用程序资源。"</string>
+ <string name="permdesc_setPointerSpeed" msgid="6866563234274104233">"允许应用随时更改鼠标或触控板指针速度。普通应用绝不需要此权限。"</string>
+ <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"向应用发送 Linux 信号"</string>
+ <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"允许应用请求将提供的信号发送给所有持续的进程。"</string>
+ <string name="permlab_persistentActivity" msgid="8841113627955563938">"让应用始终运行"</string>
+ <string name="permdesc_persistentActivity" msgid="4909910271316074418">"允许应用持续保留其自身的某些组件,这样系统就无法将其用于其他应用。"</string>
+ <string name="permlab_deletePackages" msgid="184385129537705938">"删除应用"</string>
+ <string name="permdesc_deletePackages" msgid="7411480275167205081">"允许应用删除 Android 程序包。恶意应用可能借此删除重要的应用。"</string>
+ <string name="permlab_clearAppUserData" msgid="274109191845842756">"删除其他应用的数据"</string>
+ <string name="permdesc_clearAppUserData" msgid="4625323684125459488">"允许应用清除用户数据。"</string>
+ <string name="permlab_deleteCacheFiles" msgid="3128665571837408675">"删除其他应用的缓存"</string>
+ <string name="permdesc_deleteCacheFiles" msgid="3812998599006730196">"允许应用删除缓存文件。"</string>
+ <string name="permlab_getPackageSize" msgid="7472921768357981986">"计算应用存储空间"</string>
+ <string name="permdesc_getPackageSize" msgid="3921068154420738296">"允许应用检索其代码、数据和缓存大小"</string>
+ <string name="permlab_installPackages" msgid="2199128482820306924">"直接安装应用"</string>
+ <string name="permdesc_installPackages" msgid="5628530972548071284">"允许应用安装新的或更新的 Android 程序包。恶意应用可能借此添加具有任意权限的新应用。"</string>
+ <string name="permlab_clearAppCache" msgid="7487279391723526815">"删除所有应用缓存数据"</string>
+ <string name="permdesc_clearAppCache" product="tablet" msgid="3523396284474042284">"允许应用删除应用缓存目录中的文件,从而释放平板电脑的存储空间。对系统进程的访问权限通常受到很大的限制。"</string>
+ <string name="permdesc_clearAppCache" product="default" msgid="5067988373366292186">"允许应用删除应用缓存目录中的文件,从而释放手机的存储空间。对系统进程的访问权限通常受到很大的限制。"</string>
+ <string name="permlab_movePackage" msgid="3289890271645921411">"移动应用资源"</string>
+ <string name="permdesc_movePackage" msgid="319562217778244524">"允许应用在内部与外部媒体之间移动应用资源。"</string>
<string name="permlab_readLogs" msgid="6615778543198967614">"查阅敏感日志数据"</string>
- <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"允许应用程序从系统的各种日志文件中读取信息。这样,应用程序就可以发现关于您平板电脑使用情况的一般信息,其中可能包含个人信息或隐私信息。"</string>
- <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"允许应用程序从系统的各个日志文件中读取信息。这样,应用程序就可以发现关于您手机使用情况的一般信息,其中可能包含个人信息或隐私信息。"</string>
+ <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"允许应用从系统的各种日志文件中读取信息。这样,应用就可以发现关于您平板电脑使用情况的一般信息,其中可能包含个人信息或隐私信息。"</string>
+ <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"允许应用从系统的各个日志文件中读取信息。这样,应用就可以发现关于您手机使用情况的一般信息,其中可能包含个人信息或隐私信息。"</string>
<string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"使用任何媒体解码器进行播放"</string>
- <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"允许该应用程序使用任何已安装的媒体解码器进行解码,以便播放媒体。"</string>
+ <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"允许该应用使用任何已安装的媒体解码器进行解码,以便播放媒体。"</string>
<string name="permlab_diagnostic" msgid="8076743953908000342">"读取/写入诊断所拥有的资源"</string>
- <string name="permdesc_diagnostic" msgid="6608295692002452283">"允许应用程序读取/写入诊断组拥有的所有资源(例如 /dev 中的文件)。这可能会影响系统的稳定性和安全性。此权限仅供制造商或运营商诊断硬件方面的问题时使用。"</string>
- <string name="permlab_changeComponentState" msgid="6335576775711095931">"启用或停用应用程序组件"</string>
- <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"允许应用程序启用或停用其他应用程序的组件。恶意应用程序可能借此停用重要的平板电脑功能。请务必谨慎使用此权限,因为这可能导致某些应用程序组件处于无法使用、不一致或不稳定的状态。"</string>
- <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"允许应用程序启用或停用其他应用程序的组件。恶意应用程序可能借此停用重要的手机功能。请务必谨慎使用此权限,因为这可能导致某些应用程序组件进入无法使用、不一致或不稳定的状态。"</string>
+ <string name="permdesc_diagnostic" msgid="6608295692002452283">"允许应用读取/写入诊断组拥有的所有资源(例如 /dev 中的文件)。这可能会影响系统的稳定性和安全性。此权限仅供制造商或运营商诊断硬件方面的问题时使用。"</string>
+ <string name="permlab_changeComponentState" msgid="6335576775711095931">"启用或停用应用组件"</string>
+ <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"允许应用启用或停用其他应用的组件。恶意应用可能借此停用重要的平板电脑功能。请务必谨慎使用此权限,因为这可能导致某些应用组件处于无法使用、不一致或不稳定的状态。"</string>
+ <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"允许应用启用或停用其他应用的组件。恶意应用可能借此停用重要的手机功能。请务必谨慎使用此权限,因为这可能导致某些应用组件进入无法使用、不一致或不稳定的状态。"</string>
<string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"授予或撤消权限"</string>
<string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"允许应用针对自身或其他应用授予或撤消特定权限。恶意应用可能会借此访问您未授权它们访问的功能。"</string>
- <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"设置首选应用程序"</string>
- <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"允许应用程序修改您的首选应用程序。恶意应用程序可能会在后台更改运行的应用程序,欺骗您现有的应用程序,以收集您的私人数据。"</string>
+ <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"设置首选应用"</string>
+ <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"允许应用修改您的首选应用。恶意应用可能会在后台更改运行的应用,欺骗您现有的应用,以收集您的私人数据。"</string>
<string name="permlab_writeSettings" msgid="1365523497395143704">"修改全局系统设置"</string>
- <string name="permdesc_writeSettings" msgid="7775723441558907181">"允许应用程序修改系统的设置数据。恶意应用程序可能会破坏您的系统配置。"</string>
+ <string name="permdesc_writeSettings" msgid="7775723441558907181">"允许应用修改系统的设置数据。恶意应用可能会破坏您的系统配置。"</string>
<string name="permlab_writeSecureSettings" msgid="204676251876718288">"修改安全系统设置"</string>
- <string name="permdesc_writeSecureSettings" msgid="8159535613020137391">"允许应用程序修改系统的安全设置数据。普通应用程序不能使用此权限。"</string>
+ <string name="permdesc_writeSecureSettings" msgid="8159535613020137391">"允许应用修改系统的安全设置数据。普通应用不能使用此权限。"</string>
<string name="permlab_writeGservices" msgid="2149426664226152185">"修改 Google 服务地图"</string>
- <string name="permdesc_writeGservices" msgid="1287309437638380229">"允许应用程序修改 Google 服务地图。普通应用程序不能使用此权限。"</string>
+ <string name="permdesc_writeGservices" msgid="1287309437638380229">"允许应用修改 Google 服务地图。普通应用不能使用此权限。"</string>
<string name="permlab_receiveBootCompleted" msgid="7776779842866993377">"开机时自动启动"</string>
- <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"允许应用程序在系统完成引导后立即自动启动。这样可能会延长平板电脑的启动时间,并允许应用程序始终运行,从而导致平板电脑总体运行速度减慢。"</string>
- <string name="permdesc_receiveBootCompleted" product="default" msgid="513950589102617504">"允许应用程序在系统完成引导后立即自动启动。这样可能会延长手机的启动时间,并允许应用程序始终运行,从而导致手机总体运行速度减慢。"</string>
+ <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"允许应用在系统完成引导后立即自动启动。这样可能会延长平板电脑的启动时间,并允许应用始终运行,从而导致平板电脑总体运行速度减慢。"</string>
+ <string name="permdesc_receiveBootCompleted" product="default" msgid="513950589102617504">"允许应用在系统完成引导后立即自动启动。这样可能会延长手机的启动时间,并允许应用始终运行,从而导致手机总体运行速度减慢。"</string>
<string name="permlab_broadcastSticky" msgid="7919126372606881614">"发送持久广播"</string>
- <string name="permdesc_broadcastSticky" product="tablet" msgid="1181582512022829259">"允许应用程序发送持久广播,此类广播在结束后仍会保留。恶意应用程序可能会导致平板电脑使用过多内存,从而使速度变慢或变得不稳定。"</string>
- <string name="permdesc_broadcastSticky" product="default" msgid="3287869131621514325">"允许应用程序发送持久广播,此类广播在结束后仍会保留。恶意应用程序可能会导致手机使用过多内存,从而使速度变慢或变得不稳定。"</string>
+ <string name="permdesc_broadcastSticky" product="tablet" msgid="1181582512022829259">"允许应用发送持久广播,此类广播在结束后仍会保留。恶意应用可能会导致平板电脑使用过多内存,从而使速度变慢或变得不稳定。"</string>
+ <string name="permdesc_broadcastSticky" product="default" msgid="3287869131621514325">"允许应用发送持久广播,此类广播在结束后仍会保留。恶意应用可能会导致手机使用过多内存,从而使速度变慢或变得不稳定。"</string>
<string name="permlab_readContacts" msgid="6219652189510218240">"读取联系人数据"</string>
- <string name="permdesc_readContacts" product="tablet" msgid="4028657556924039119">"允许应用程序读取您平板电脑上存储的所有联系人(地址)数据。恶意应用程序可能借此将您的数据发送给其他人。"</string>
- <string name="permdesc_readContacts" product="default" msgid="2032222056456498547">"允许应用程序读取您手机上存储的所有联系人(地址)数据。恶意应用程序可能借此将您的数据发送给其他人。"</string>
+ <string name="permdesc_readContacts" product="tablet" msgid="4028657556924039119">"允许应用读取您平板电脑上存储的所有联系人(地址)数据。恶意应用可能借此将您的数据发送给其他人。"</string>
+ <string name="permdesc_readContacts" product="default" msgid="2032222056456498547">"允许应用读取您手机上存储的所有联系人(地址)数据。恶意应用可能借此将您的数据发送给其他人。"</string>
<string name="permlab_writeContacts" msgid="644616215860933284">"写入联系数据"</string>
- <string name="permdesc_writeContacts" product="tablet" msgid="988969759110632978">"允许应用程序读取您平板电脑上存储的联系人(地址)数据。恶意应用程序可能借此清除或修改您的联系人数据。"</string>
- <string name="permdesc_writeContacts" product="default" msgid="5075164818647934067">"允许应用程序修改您手机上存储的联系人(地址)数据。恶意应用程序可能借此清除或修改您的联系人数据。"</string>
+ <string name="permdesc_writeContacts" product="tablet" msgid="988969759110632978">"允许应用读取您平板电脑上存储的联系人(地址)数据。恶意应用可能借此清除或修改您的联系人数据。"</string>
+ <string name="permdesc_writeContacts" product="default" msgid="5075164818647934067">"允许应用修改您手机上存储的联系人(地址)数据。恶意应用可能借此清除或修改您的联系人数据。"</string>
<string name="permlab_readCallLog" msgid="3478133184624102739">"读取通话记录"</string>
<string name="permdesc_readCallLog" product="tablet" msgid="3995157599976515002">"允许该应用读取平板电脑的通话记录,包括有关来电和外拨电话的数据。恶意应用可能会借此将您的数据发送给他人。"</string>
<string name="permdesc_readCallLog" product="default" msgid="3452017559804750758">"允许该应用读取手机的通话记录,包括有关来电和外拨电话的数据。恶意应用可能会借此将您的数据发送给他人。"</string>
@@ -342,189 +342,189 @@
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"允许该应用修改平板电脑的通话记录,包括有关来电和外拨电话的数据。恶意应用可能会借此清除或修改您的通话记录。"</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"允许该应用修改手机的通话记录,包括有关来电和外拨电话的数据。恶意应用可能会借此清除或修改您的通话记录。"</string>
<string name="permlab_readProfile" msgid="6824681438529842282">"读取您的个人资料数据"</string>
- <string name="permdesc_readProfile" product="default" msgid="94520753797630679">"允许应用程序读取您设备上存储的个人资料信息,例如您的姓名和联系信息。这意味着应用程序可以识别您的身份,并将您的个人资料信息发送给他人。"</string>
+ <string name="permdesc_readProfile" product="default" msgid="94520753797630679">"允许应用读取您设备上存储的个人资料信息,例如您的姓名和联系信息。这意味着应用可以识别您的身份,并将您的个人资料信息发送给他人。"</string>
<string name="permlab_writeProfile" msgid="4679878325177177400">"写入到您的个人资料数据"</string>
- <string name="permdesc_writeProfile" product="default" msgid="4637366723793045603">"允许应用程序更改或添加您设备上存储的个人资料信息,例如您的姓名和联系信息。这意味着其他应用程序可以识别您的身份,并将您的个人资料信息发送给他人。"</string>
+ <string name="permdesc_writeProfile" product="default" msgid="4637366723793045603">"允许应用更改或添加您设备上存储的个人资料信息,例如您的姓名和联系信息。这意味着其他应用可以识别您的身份,并将您的个人资料信息发送给他人。"</string>
<string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"读取您的社交视频流"</string>
- <string name="permdesc_readSocialStream" product="default" msgid="3419050808547335320">"允许应用程序访问并同步您和好友的社交最新动态。恶意应用程序可能借此读取您与社交网络上的好友之间的私人交流信息。"</string>
+ <string name="permdesc_readSocialStream" product="default" msgid="3419050808547335320">"允许应用访问并同步您和好友的社交最新动态。恶意应用可能借此读取您与社交网络上的好友之间的私人交流信息。"</string>
<string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"写入您的社交视频流"</string>
- <string name="permdesc_writeSocialStream" product="default" msgid="3496277176955721451">"允许应用程序显示好友的社交最新动态。恶意应用程序可能借此冒充您的某位好友,诱骗您泄露密码或其他机密信息。"</string>
+ <string name="permdesc_writeSocialStream" product="default" msgid="3496277176955721451">"允许应用显示好友的社交最新动态。恶意应用可能借此冒充您的某位好友,诱骗您泄露密码或其他机密信息。"</string>
<string name="permlab_readCalendar" msgid="5972727560257612398">"读取日历活动和机密信息"</string>
- <string name="permdesc_readCalendar" product="tablet" msgid="2338414551004122687">"允许应用程序读取您平板电脑上存储的所有日历活动,包括朋友或同事的活动。恶意应用程序可能会在所有者不知情的情况下,从这些日历活动中提取个人信息。"</string>
- <string name="permdesc_readCalendar" product="default" msgid="5693933067751827753">"允许应用程序读取您手机上存储的所有日历活动,包括朋友或同事的活动。恶意应用程序可能会在所有者不知情的情况下,从这些日历活动中提取个人信息。"</string>
+ <string name="permdesc_readCalendar" product="tablet" msgid="2338414551004122687">"允许应用读取您平板电脑上存储的所有日历活动,包括朋友或同事的活动。恶意应用可能会在所有者不知情的情况下,从这些日历活动中提取个人信息。"</string>
+ <string name="permdesc_readCalendar" product="default" msgid="5693933067751827753">"允许应用读取您手机上存储的所有日历活动,包括朋友或同事的活动。恶意应用可能会在所有者不知情的情况下,从这些日历活动中提取个人信息。"</string>
<string name="permlab_writeCalendar" msgid="8438874755193825647">"添加或修改日历活动,并在所有者不知情的情况下向邀请对象发送电子邮件"</string>
- <string name="permdesc_writeCalendar" msgid="2243771395254848873">"允许应用程序以日历所有者的身份发送活动邀请,并添加、删除和更改您可在自己设备上修改的活动,包括朋友或同事的活动。恶意应用程序可能会冒充日历所有者发送垃圾邮件,在所有者不知情的情况下修改活动,或者添加虚假活动。"</string>
+ <string name="permdesc_writeCalendar" msgid="2243771395254848873">"允许应用以日历所有者的身份发送活动邀请,并添加、删除和更改您可在自己设备上修改的活动,包括朋友或同事的活动。恶意应用可能会冒充日历所有者发送垃圾邮件,在所有者不知情的情况下修改活动,或者添加虚假活动。"</string>
<string name="permlab_accessMockLocation" msgid="8688334974036823330">"使用模拟地点来源进行测试"</string>
- <string name="permdesc_accessMockLocation" msgid="7577931556422993949">"允许应用程序创建模拟位置源以进行测试。恶意应用程序可能借此覆盖由真实位置源(如 GPS 或网络服务提供商)返回的位置和/或状态信息。"</string>
+ <string name="permdesc_accessMockLocation" msgid="7577931556422993949">"允许应用创建模拟位置源以进行测试。恶意应用可能借此覆盖由真实位置源(如 GPS 或网络服务提供商)返回的位置和/或状态信息。"</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"获取额外的位置信息提供程序命令"</string>
- <string name="permdesc_accessLocationExtraCommands" msgid="6737736970602176133">"允许应用程序访问额外的位置提供程序命令。恶意应用程序可能借此干扰 GPS 或其他位置源的运行。"</string>
+ <string name="permdesc_accessLocationExtraCommands" msgid="6737736970602176133">"允许应用访问额外的位置提供程序命令。恶意应用可能借此干扰 GPS 或其他位置源的运行。"</string>
<string name="permlab_installLocationProvider" msgid="6578101199825193873">"允许安装位置信息提供程序"</string>
- <string name="permdesc_installLocationProvider" msgid="1742577679350078373">"创建模拟位置源以进行测试。恶意应用程序可能借此覆盖由真实位置源(如 GPS 或网络服务提供商)返回的位置和/或状态信息,或者监视您的位置并将信息提供给外部源。"</string>
+ <string name="permdesc_installLocationProvider" msgid="1742577679350078373">"创建模拟位置源以进行测试。恶意应用可能借此覆盖由真实位置源(如 GPS 或网络服务提供商)返回的位置和/或状态信息,或者监视您的位置并将信息提供给外部源。"</string>
<string name="permlab_accessFineLocation" msgid="8116127007541369477">"精准的(GPS)位置"</string>
- <string name="permdesc_accessFineLocation" product="tablet" msgid="5326423948268164934">"访问精准的位置源,例如平板电脑上的全球定位系统(如果有)。恶意应用程序可能借此确定您所处的位置,并可能消耗额外的电池电量。"</string>
- <string name="permdesc_accessFineLocation" product="default" msgid="7130267914433890869">"访问手机上的精准位置源,例如全球定位系统(如果有)。恶意应用程序可能借此确定您所处的位置,并可能消耗额外的电池电量。"</string>
+ <string name="permdesc_accessFineLocation" product="tablet" msgid="5326423948268164934">"访问精准的位置源,例如平板电脑上的全球定位系统(如果有)。恶意应用可能借此确定您所处的位置,并可能消耗额外的电池电量。"</string>
+ <string name="permdesc_accessFineLocation" product="default" msgid="7130267914433890869">"访问手机上的精准位置源,例如全球定位系统(如果有)。恶意应用可能借此确定您所处的位置,并可能消耗额外的电池电量。"</string>
<string name="permlab_accessCoarseLocation" msgid="4642255009181975828">"(基于网络的)粗略位置"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="5460726396318105483">"访问粗略的位置源(例如蜂窝网络数据库)以确定平板电脑的大体位置(如果可以)。恶意应用程序可能借此确定您所处的大体位置。"</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="8900795778057579522">"访问粗略的位置源(例如蜂窝网络数据库)以确定手机的大体位置(如果可以)。恶意应用程序可能借此确定您所处的大体位置。"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="5460726396318105483">"访问粗略的位置源(例如蜂窝网络数据库)以确定平板电脑的大体位置(如果可以)。恶意应用可能借此确定您所处的大体位置。"</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="8900795778057579522">"访问粗略的位置源(例如蜂窝网络数据库)以确定手机的大体位置(如果可以)。恶意应用可能借此确定您所处的大体位置。"</string>
<string name="permlab_accessSurfaceFlinger" msgid="2363969641792388947">"访问 SurfaceFlinger"</string>
- <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"允许应用程序使用 SurfaceFlinger 低级功能。"</string>
+ <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"允许应用使用 SurfaceFlinger 低级功能。"</string>
<string name="permlab_readFrameBuffer" msgid="6690504248178498136">"读取帧缓冲区"</string>
- <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"允许应用程序读取帧缓冲区的内容。"</string>
+ <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"允许应用读取帧缓冲区的内容。"</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"更改您的音频设置"</string>
- <string name="permdesc_modifyAudioSettings" msgid="7343951185408396919">"允许应用程序修改全局音频设置,如音量和路由。"</string>
+ <string name="permdesc_modifyAudioSettings" msgid="7343951185408396919">"允许应用修改全局音频设置,如音量和路由。"</string>
<string name="permlab_recordAudio" msgid="3876049771427466323">"录音"</string>
- <string name="permdesc_recordAudio" msgid="2387462233976248635">"允许应用程序访问录音路径。"</string>
+ <string name="permdesc_recordAudio" msgid="2387462233976248635">"允许应用访问录音路径。"</string>
<string name="permlab_camera" msgid="3616391919559751192">"拍摄照片和视频"</string>
- <string name="permdesc_camera" msgid="1507407407002492176">"允许应用程序使用相机拍摄照片和视频。该权限可让应用程序随时收集相机的取景。"</string>
+ <string name="permdesc_camera" msgid="1507407407002492176">"允许应用使用相机拍摄照片和视频。该权限可让应用随时收集相机的取景。"</string>
<string name="permlab_brick" product="tablet" msgid="2961292205764488304">"永久停用平板电脑"</string>
<string name="permlab_brick" product="default" msgid="8337817093326370537">"永久停用手机"</string>
- <string name="permdesc_brick" product="tablet" msgid="4334818808001699530">"允许应用程序永久停用整个平板电脑,但这样非常危险。"</string>
- <string name="permdesc_brick" product="default" msgid="5788903297627283099">"允许应用程序永久停用整个手机,但这非常危险。"</string>
+ <string name="permdesc_brick" product="tablet" msgid="4334818808001699530">"允许应用永久停用整个平板电脑,但这样非常危险。"</string>
+ <string name="permdesc_brick" product="default" msgid="5788903297627283099">"允许应用永久停用整个手机,但这非常危险。"</string>
<string name="permlab_reboot" product="tablet" msgid="3436634972561795002">"强行重新启动平板电脑"</string>
<string name="permlab_reboot" product="default" msgid="2898560872462638242">"强行重新启动手机"</string>
- <string name="permdesc_reboot" product="tablet" msgid="8172056180063700741">"允许应用程序强行重新启动平板电脑。"</string>
- <string name="permdesc_reboot" product="default" msgid="5326008124289989969">"允许应用程序强行重新启动手机。"</string>
+ <string name="permdesc_reboot" product="tablet" msgid="8172056180063700741">"允许应用强行重新启动平板电脑。"</string>
+ <string name="permdesc_reboot" product="default" msgid="5326008124289989969">"允许应用强行重新启动手机。"</string>
<string name="permlab_mount_unmount_filesystems" msgid="1761023272170956541">"装载和卸载文件系统"</string>
- <string name="permdesc_mount_unmount_filesystems" msgid="1829290701658992347">"允许应用程序装载和卸载可移动存储设备的文件系统。"</string>
+ <string name="permdesc_mount_unmount_filesystems" msgid="1829290701658992347">"允许应用装载和卸载可移动存储设备的文件系统。"</string>
<string name="permlab_mount_format_filesystems" msgid="5523285143576718981">"格式化外部存储设备"</string>
- <string name="permdesc_mount_format_filesystems" msgid="8784268246779198627">"允许应用程序格式化可移动存储设备。"</string>
+ <string name="permdesc_mount_format_filesystems" msgid="8784268246779198627">"允许应用格式化可移动存储设备。"</string>
<string name="permlab_asec_access" msgid="3411338632002193846">"获取有关内部存储设备的信息"</string>
- <string name="permdesc_asec_access" msgid="3094563844593878548">"允许应用程序获取有关内存设备的信息。"</string>
+ <string name="permdesc_asec_access" msgid="3094563844593878548">"允许应用获取有关内存设备的信息。"</string>
<string name="permlab_asec_create" msgid="6414757234789336327">"创建内部存储设备"</string>
- <string name="permdesc_asec_create" msgid="4558869273585856876">"允许应用程序创建内存设备。"</string>
+ <string name="permdesc_asec_create" msgid="4558869273585856876">"允许应用创建内存设备。"</string>
<string name="permlab_asec_destroy" msgid="526928328301618022">"清除内部存储设备"</string>
- <string name="permdesc_asec_destroy" msgid="7218749286145526537">"允许应用程序清除内存设备。"</string>
+ <string name="permdesc_asec_destroy" msgid="7218749286145526537">"允许应用清除内存设备。"</string>
<string name="permlab_asec_mount_unmount" msgid="8877998101944999386">"装载/卸载内存设备"</string>
- <string name="permdesc_asec_mount_unmount" msgid="3451360114902490929">"允许应用程序装载/卸载内存设备。"</string>
+ <string name="permdesc_asec_mount_unmount" msgid="3451360114902490929">"允许应用装载/卸载内存设备。"</string>
<string name="permlab_asec_rename" msgid="7496633954080472417">"重命名内部存储设备"</string>
- <string name="permdesc_asec_rename" msgid="1794757588472127675">"允许应用程序重命名内存设备。"</string>
+ <string name="permdesc_asec_rename" msgid="1794757588472127675">"允许应用重命名内存设备。"</string>
<string name="permlab_vibrate" msgid="7768356019980849603">"控制振动器"</string>
- <string name="permdesc_vibrate" msgid="6284989245902300945">"允许应用程序控制振动器。"</string>
+ <string name="permdesc_vibrate" msgid="6284989245902300945">"允许应用控制振动器。"</string>
<string name="permlab_flashlight" msgid="2155920810121984215">"控制闪光灯"</string>
- <string name="permdesc_flashlight" msgid="6522284794568368310">"允许应用程序控制闪光灯。"</string>
+ <string name="permdesc_flashlight" msgid="6522284794568368310">"允许应用控制闪光灯。"</string>
<string name="permlab_manageUsb" msgid="1113453430645402723">"管理 USB 设备的偏好设置和权限"</string>
- <string name="permdesc_manageUsb" msgid="7776155430218239833">"允许应用程序管理针对 USB 设备的偏好设置和权限。"</string>
+ <string name="permdesc_manageUsb" msgid="7776155430218239833">"允许应用管理针对 USB 设备的偏好设置和权限。"</string>
<string name="permlab_accessMtp" msgid="4953468676795917042">"应用 MTP 协议"</string>
<string name="permdesc_accessMtp" msgid="6532961200486791570">"允许访问内核 MTP 驱动程序,以便应用 MTP USB 协议。"</string>
<string name="permlab_hardware_test" msgid="4148290860400659146">"测试硬件"</string>
- <string name="permdesc_hardware_test" msgid="6597964191208016605">"允许应用程序控制各种外围设备以进行硬件测试。"</string>
+ <string name="permdesc_hardware_test" msgid="6597964191208016605">"允许应用控制各种外围设备以进行硬件测试。"</string>
<string name="permlab_callPhone" msgid="3925836347681847954">"直接拨打电话号码"</string>
- <string name="permdesc_callPhone" msgid="6396463004110544744">"允许应用程序在没有您干预的情况下呼叫电话号码。恶意应用程序可能会产生意料之外的话费。请注意,此权限不允许应用程序呼叫紧急电话。"</string>
+ <string name="permdesc_callPhone" msgid="6396463004110544744">"允许应用在没有您干预的情况下呼叫电话号码。恶意应用可能会产生意料之外的话费。请注意,此权限不允许应用呼叫紧急电话。"</string>
<string name="permlab_callPrivileged" msgid="4198349211108497879">"直接呼叫任何电话号码"</string>
- <string name="permdesc_callPrivileged" msgid="1689024901509996810">"允许应用程序在没有您干预的情况下呼叫任何电话号码,包括紧急呼叫号码。恶意应用程序可能会向紧急服务进行多余以及非法呼叫。"</string>
+ <string name="permdesc_callPrivileged" msgid="1689024901509996810">"允许应用在没有您干预的情况下呼叫任何电话号码,包括紧急呼叫号码。恶意应用可能会向紧急服务进行多余以及非法呼叫。"</string>
<string name="permlab_performCdmaProvisioning" product="tablet" msgid="4842576994144604821">"直接启动 CDMA 平板电脑设置"</string>
<string name="permlab_performCdmaProvisioning" product="default" msgid="5604848095315421425">"直接启动 CDMA 电话设置"</string>
- <string name="permdesc_performCdmaProvisioning" msgid="1994193538802314186">"允许应用程序启动 CDMA 配置。恶意应用程序可能会无端启动 CDMA 配置。"</string>
+ <string name="permdesc_performCdmaProvisioning" msgid="1994193538802314186">"允许应用启动 CDMA 配置。恶意应用可能会无端启动 CDMA 配置。"</string>
<string name="permlab_locationUpdates" msgid="7785408253364335740">"控制位置更新通知"</string>
- <string name="permdesc_locationUpdates" msgid="1120741557891438876">"允许应用程序启用/停用来自无线装置的位置更新通知。普通应用程序不能使用此权限。"</string>
+ <string name="permdesc_locationUpdates" msgid="1120741557891438876">"允许应用启用/停用来自无线装置的位置更新通知。普通应用不能使用此权限。"</string>
<string name="permlab_checkinProperties" msgid="7855259461268734914">"访问检入属性"</string>
- <string name="permdesc_checkinProperties" msgid="4024526968630194128">"允许应用程序对登记服务上传的属性拥有读取/写入权限。普通应用程序不能使用此权限。"</string>
+ <string name="permdesc_checkinProperties" msgid="4024526968630194128">"允许应用对登记服务上传的属性拥有读取/写入权限。普通应用不能使用此权限。"</string>
<string name="permlab_bindGadget" msgid="776905339015863471">"选择窗口小部件"</string>
- <string name="permdesc_bindGadget" msgid="8261326938599049290">"允许应用程序告知系统哪些窗口小部件可供哪个应用程序使用。拥有此权限的应用程序可向其他应用程序授予对个人资料的访问权限。普通应用程序不能使用此权限。"</string>
+ <string name="permdesc_bindGadget" msgid="8261326938599049290">"允许应用告知系统哪些窗口小部件可供哪个应用使用。拥有此权限的应用可向其他应用授予对个人资料的访问权限。普通应用不能使用此权限。"</string>
<string name="permlab_modifyPhoneState" msgid="8423923777659292228">"修改手机状态"</string>
- <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"允许应用程序控制设备的电话功能。拥有此权限的应用程序可在不通知您的情况下执行切换网络、开关手机无线装置等此类操作。"</string>
+ <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"允许应用控制设备的电话功能。拥有此权限的应用可在不通知您的情况下执行切换网络、开关手机无线装置等此类操作。"</string>
<string name="permlab_readPhoneState" msgid="2326172951448691631">"读取手机状态和身份"</string>
- <string name="permdesc_readPhoneState" msgid="5127767618743602782">"允许应用程序访问设备的电话功能。拥有此权限的应用程序可以确定本机的电话号码和序列号、通话是否有效、呼叫的号码等。"</string>
+ <string name="permdesc_readPhoneState" msgid="5127767618743602782">"允许应用访问设备的电话功能。拥有此权限的应用可以确定本机的电话号码和序列号、通话是否有效、呼叫的号码等。"</string>
<string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"阻止平板电脑进入休眠状态"</string>
<string name="permlab_wakeLock" product="default" msgid="573480187941496130">"防止手机休眠"</string>
- <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"允许应用程序阻止平板电脑进入休眠状态。"</string>
- <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"允许应用程序阻止手机进入休眠状态。"</string>
+ <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"允许应用阻止平板电脑进入休眠状态。"</string>
+ <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"允许应用阻止手机进入休眠状态。"</string>
<string name="permlab_devicePower" product="tablet" msgid="2787034722616350417">"打开或关闭平板电脑"</string>
<string name="permlab_devicePower" product="default" msgid="4928622470980943206">"开机或关机"</string>
- <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"允许应用程序打开或关闭平板电脑。"</string>
- <string name="permdesc_devicePower" product="default" msgid="6037057348463131032">"允许应用程序打开或关闭手机。"</string>
+ <string name="permdesc_devicePower" product="tablet" msgid="6689862878984631831">"允许应用打开或关闭平板电脑。"</string>
+ <string name="permdesc_devicePower" product="default" msgid="6037057348463131032">"允许应用打开或关闭手机。"</string>
<string name="permlab_factoryTest" msgid="3715225492696416187">"在出厂测试模式下运行"</string>
<string name="permdesc_factoryTest" product="tablet" msgid="3952059318359653091">"作为低级制造商测试运行,从而允许对平板电脑硬件进行完全访问。此权限仅当平板电脑在制造商测试模式下运行时才可用。"</string>
<string name="permdesc_factoryTest" product="default" msgid="8136644990319244802">"作为一项低级制造商测试来运行,从而允许对手机硬件进行完全访问。此权限仅当手机在制造商测试模式下运行时才可用。。"</string>
<string name="permlab_setWallpaper" msgid="6627192333373465143">"设置壁纸"</string>
- <string name="permdesc_setWallpaper" msgid="7373447920977624745">"允许应用程序设置系统壁纸。"</string>
+ <string name="permdesc_setWallpaper" msgid="7373447920977624745">"允许应用设置系统壁纸。"</string>
<string name="permlab_setWallpaperHints" msgid="3600721069353106851">"设置有关壁纸大小的提示"</string>
- <string name="permdesc_setWallpaperHints" msgid="8235784384223730091">"允许应用程序设置有关系统壁纸大小的提示。"</string>
+ <string name="permdesc_setWallpaperHints" msgid="8235784384223730091">"允许应用设置有关系统壁纸大小的提示。"</string>
<string name="permlab_masterClear" msgid="2315750423139697397">"将系统恢复为出厂设置"</string>
- <string name="permdesc_masterClear" msgid="3665380492633910226">"允许应用程序将系统完全重置为其出厂设置,这会清除所有数据、配置和已安装的应用程序。"</string>
+ <string name="permdesc_masterClear" msgid="3665380492633910226">"允许应用将系统完全重置为其出厂设置,这会清除所有数据、配置和已安装的应用。"</string>
<string name="permlab_setTime" msgid="2021614829591775646">"设置时间"</string>
- <string name="permdesc_setTime" product="tablet" msgid="1896341438151152881">"允许应用程序更改平板电脑的时间。"</string>
- <string name="permdesc_setTime" product="default" msgid="1855702730738020">"允许应用程序更改手机的时间。"</string>
+ <string name="permdesc_setTime" product="tablet" msgid="1896341438151152881">"允许应用更改平板电脑的时间。"</string>
+ <string name="permdesc_setTime" product="default" msgid="1855702730738020">"允许应用更改手机的时间。"</string>
<string name="permlab_setTimeZone" msgid="2945079801013077340">"设置时区"</string>
- <string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"允许应用程序更改平板电脑的时区。"</string>
- <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"允许应用程序更改手机的时区。"</string>
+ <string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"允许应用更改平板电脑的时区。"</string>
+ <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"允许应用更改手机的时区。"</string>
<string name="permlab_accountManagerService" msgid="4829262349691386986">"作为 AccountManagerService"</string>
- <string name="permdesc_accountManagerService" msgid="1948455552333615954">"允许该应用程序调用 AccountAuthenticators。"</string>
+ <string name="permdesc_accountManagerService" msgid="1948455552333615954">"允许该应用调用 AccountAuthenticators。"</string>
<string name="permlab_getAccounts" msgid="4549918644233460103">"发现已知帐户"</string>
- <string name="permdesc_getAccounts" product="tablet" msgid="3238360555257773358">"允许应用程序获取平板电脑已知的帐户列表。"</string>
- <string name="permdesc_getAccounts" product="default" msgid="2735689364629830348">"允许应用程序获取手机已知的帐户列表。"</string>
+ <string name="permdesc_getAccounts" product="tablet" msgid="3238360555257773358">"允许应用获取平板电脑已知的帐户列表。"</string>
+ <string name="permdesc_getAccounts" product="default" msgid="2735689364629830348">"允许应用获取手机已知的帐户列表。"</string>
<string name="permlab_authenticateAccounts" msgid="3940505577982882450">"作为帐户身份验证程序"</string>
- <string name="permdesc_authenticateAccounts" msgid="5472124296908977260">"允许应用程序使用 AccountManager 的帐户身份验证程序功能,包括创建帐户以及获取和设置其密码。"</string>
+ <string name="permdesc_authenticateAccounts" msgid="5472124296908977260">"允许应用使用 AccountManager 的帐户身份验证程序功能,包括创建帐户以及获取和设置其密码。"</string>
<string name="permlab_manageAccounts" msgid="4440380488312204365">"管理帐户列表"</string>
- <string name="permdesc_manageAccounts" msgid="8698295625488292506">"允许应用程序执行添加帐户、删除帐户、删除帐户密码等操作。"</string>
+ <string name="permdesc_manageAccounts" msgid="8698295625488292506">"允许应用执行添加帐户、删除帐户、删除帐户密码等操作。"</string>
<string name="permlab_useCredentials" msgid="6401886092818819856">"使用帐户的身份验证凭据"</string>
- <string name="permdesc_useCredentials" msgid="7984227147403346422">"允许应用程序请求身份验证令牌。"</string>
+ <string name="permdesc_useCredentials" msgid="7984227147403346422">"允许应用请求身份验证令牌。"</string>
<string name="permlab_accessNetworkState" msgid="6865575199464405769">"查看网络状态"</string>
- <string name="permdesc_accessNetworkState" msgid="479772796952547198">"允许应用程序查看所有网络的状态。"</string>
+ <string name="permdesc_accessNetworkState" msgid="479772796952547198">"允许应用查看所有网络的状态。"</string>
<string name="permlab_createNetworkSockets" msgid="9121633680349549585">"完全的互联网访问权限"</string>
- <string name="permdesc_createNetworkSockets" msgid="5963922297444265950">"允许应用程序创建网络套接字。"</string>
+ <string name="permdesc_createNetworkSockets" msgid="5963922297444265950">"允许应用创建网络套接字。"</string>
<string name="permlab_writeApnSettings" msgid="505660159675751896">"更改/拦截网络设置和流量"</string>
- <string name="permdesc_writeApnSettings" msgid="5333798886412714193">"允许应用程序更改网络设置,并拦截和检查所有网络流量,例如更改任意 APN 的代理和端口。恶意应用程序可能会在您不知情的情况下监视、重定向或修改网络数据包。"</string>
+ <string name="permdesc_writeApnSettings" msgid="5333798886412714193">"允许应用更改网络设置,并拦截和检查所有网络流量,例如更改任意 APN 的代理和端口。恶意应用可能会在您不知情的情况下监视、重定向或修改网络数据包。"</string>
<string name="permlab_changeNetworkState" msgid="958884291454327309">"更改网络连接性"</string>
- <string name="permdesc_changeNetworkState" msgid="6789123912476416214">"允许应用程序更改网络连接的状态。"</string>
+ <string name="permdesc_changeNetworkState" msgid="6789123912476416214">"允许应用更改网络连接的状态。"</string>
<string name="permlab_changeTetherState" msgid="5952584964373017960">"更改网络共享连接"</string>
- <string name="permdesc_changeTetherState" msgid="1524441344412319780">"允许应用程序更改绑定网络连接的状态。"</string>
+ <string name="permdesc_changeTetherState" msgid="1524441344412319780">"允许应用更改绑定网络连接的状态。"</string>
<string name="permlab_changeBackgroundDataSetting" msgid="1400666012671648741">"更改后台数据使用设置"</string>
- <string name="permdesc_changeBackgroundDataSetting" msgid="5347729578468744379">"允许应用程序更改后台数据使用设置。"</string>
+ <string name="permdesc_changeBackgroundDataSetting" msgid="5347729578468744379">"允许应用更改后台数据使用设置。"</string>
<string name="permlab_accessWifiState" msgid="8100926650211034400">"查看 Wi-Fi 状态"</string>
- <string name="permdesc_accessWifiState" msgid="7770452658226256831">"允许应用程序查看有关 Wi-Fi 状态的信息。"</string>
+ <string name="permdesc_accessWifiState" msgid="7770452658226256831">"允许应用查看有关 Wi-Fi 状态的信息。"</string>
<string name="permlab_changeWifiState" msgid="7280632711057112137">"更改 Wi-Fi 状态"</string>
- <string name="permdesc_changeWifiState" msgid="7399961004537946240">"允许应用程序与 Wi-Fi 接入点建立和断开连接,并对配置的 Wi-Fi 网络进行更改。"</string>
+ <string name="permdesc_changeWifiState" msgid="7399961004537946240">"允许应用与 Wi-Fi 接入点建立和断开连接,并对配置的 Wi-Fi 网络进行更改。"</string>
<string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"允许接收 Wi-Fi 多播"</string>
- <string name="permdesc_changeWifiMulticastState" msgid="7633598524564320817">"允许应用程序接收并非直接发送至您设备的数据包。在查找附近提供的服务时,此权限很有用。这种操作所耗电量大于非多播模式。"</string>
+ <string name="permdesc_changeWifiMulticastState" msgid="7633598524564320817">"允许应用接收并非直接发送至您设备的数据包。在查找附近提供的服务时,此权限很有用。这种操作所耗电量大于非多播模式。"</string>
<string name="permlab_bluetoothAdmin" msgid="3606576270792236062">"蓝牙管理"</string>
- <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"允许应用程序配置本地蓝牙平板电脑,以及发现远程设备并进行配对。"</string>
- <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"允许应用程序配置本地蓝牙手机,以及发现远程设备并进行配对。"</string>
+ <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"允许应用配置本地蓝牙平板电脑,以及发现远程设备并进行配对。"</string>
+ <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"允许应用配置本地蓝牙手机,以及发现远程设备并进行配对。"</string>
<string name="permlab_accessWimaxState" msgid="1232061307208861588">"查看 WiMAX 状态"</string>
- <string name="permdesc_accessWimaxState" msgid="5914958077555177749">"允许该应用程序查看有关 WiMAX 状态的信息。"</string>
+ <string name="permdesc_accessWimaxState" msgid="5914958077555177749">"允许该应用查看有关 WiMAX 状态的信息。"</string>
<string name="permlab_changeWimaxState" msgid="2405042267131496579">"更改 WiMAX 状态"</string>
- <string name="permdesc_changeWimaxState" msgid="3328853825006455912">"允许该应用程序连接到 WiMAX 网络以及从 WiMAX 网络断开连接。"</string>
+ <string name="permdesc_changeWimaxState" msgid="3328853825006455912">"允许该应用连接到 WiMAX 网络以及从 WiMAX 网络断开连接。"</string>
<string name="permlab_bluetooth" msgid="8361038707857018732">"创建蓝牙连接"</string>
- <string name="permdesc_bluetooth" product="tablet" msgid="7007851048416363446">"允许应用程序查看本地蓝牙平板电脑的配置,以及建立和接受与配对设备的连接。"</string>
- <string name="permdesc_bluetooth" product="default" msgid="31846362767164948">"允许应用程序查看本地蓝牙手机的配置,以及建立和接受与配对设备的连接。"</string>
+ <string name="permdesc_bluetooth" product="tablet" msgid="7007851048416363446">"允许应用查看本地蓝牙平板电脑的配置,以及建立和接受与配对设备的连接。"</string>
+ <string name="permdesc_bluetooth" product="default" msgid="31846362767164948">"允许应用查看本地蓝牙手机的配置,以及建立和接受与配对设备的连接。"</string>
<string name="permlab_nfc" msgid="4423351274757876953">"控制近距离通信"</string>
- <string name="permdesc_nfc" msgid="7120611819401789907">"允许应用程序与近距离无线通信 (NFC) 标记、卡和阅读器进行通信。"</string>
+ <string name="permdesc_nfc" msgid="7120611819401789907">"允许应用与近距离无线通信 (NFC) 标记、卡和阅读器进行通信。"</string>
<string name="permlab_disableKeyguard" msgid="4977406164311535092">"停用键锁"</string>
- <string name="permdesc_disableKeyguard" msgid="6231611286892232626">"允许应用程序停用键锁和任何关联的密码安全设置。例如,在手机上接听电话时停用键锁,在通话结束后重新启用键锁。"</string>
+ <string name="permdesc_disableKeyguard" msgid="6231611286892232626">"允许应用停用键锁和任何关联的密码安全设置。例如,在手机上接听电话时停用键锁,在通话结束后重新启用键锁。"</string>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"读取同步设置"</string>
- <string name="permdesc_readSyncSettings" msgid="5464056785274229278">"允许应用程序读取同步设置,例如是否对“联系人”应用程序启用同步功能。"</string>
+ <string name="permdesc_readSyncSettings" msgid="5464056785274229278">"允许应用读取同步设置,例如是否对“联系人”应用启用同步功能。"</string>
<string name="permlab_writeSyncSettings" msgid="6297138566442486462">"写入同步设置"</string>
- <string name="permdesc_writeSyncSettings" msgid="1466056564502117130">"允许应用程序修改同步设置,例如是否对“联系人”应用程序启用同步功能。"</string>
+ <string name="permdesc_writeSyncSettings" msgid="1466056564502117130">"允许应用修改同步设置,例如是否对“联系人”应用启用同步功能。"</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"读取同步统计信息"</string>
- <string name="permdesc_readSyncStats" msgid="3801971839939951678">"允许应用程序读取同步统计信息;例如,已发生的同步历史记录。"</string>
+ <string name="permdesc_readSyncStats" msgid="3801971839939951678">"允许应用读取同步统计信息;例如,已发生的同步历史记录。"</string>
<string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"读取订阅的供稿"</string>
- <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"允许应用程序获取有关当前同步的 Feed 的详情。"</string>
+ <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"允许应用获取有关当前同步的 Feed 的详情。"</string>
<string name="permlab_subscribedFeedsWrite" msgid="9015246325408209296">"写入订阅的供稿"</string>
- <string name="permdesc_subscribedFeedsWrite" msgid="6928930188826089413">"允许应用程序修改您当前同步的 Feed。恶意应用程序可能会更改您的同步 Feed。"</string>
+ <string name="permdesc_subscribedFeedsWrite" msgid="6928930188826089413">"允许应用修改您当前同步的 Feed。恶意应用可能会更改您的同步 Feed。"</string>
<string name="permlab_readDictionary" msgid="8410247960433376352">"读取用户定义的词典"</string>
- <string name="permdesc_readDictionary" msgid="8977815988329283705">"允许应用程序读取用户可能在用户词典中已存储的任意私有字词、名称和短语。"</string>
+ <string name="permdesc_readDictionary" msgid="8977815988329283705">"允许应用读取用户可能在用户词典中已存储的任意私有字词、名称和短语。"</string>
<string name="permlab_writeDictionary" msgid="2296383164914812772">"写入用户定义的词典"</string>
- <string name="permdesc_writeDictionary" msgid="8185385716255065291">"允许应用程序向用户词典中写入新词。"</string>
+ <string name="permdesc_writeDictionary" msgid="8185385716255065291">"允许应用向用户词典中写入新词。"</string>
<string name="permlab_sdcardRead" product="nosdcard" msgid="4086221374639183281">"读取 USB 存储设备的内容"</string>
<string name="permlab_sdcardRead" product="default" msgid="8537875151845139539">"读取 SD 卡的内容"</string>
<string name="permdesc_sdcardRead" product="nosdcard" msgid="1055302898999352339">"允许应用读取 USB 存储设备的内容。"</string>
<string name="permdesc_sdcardRead" product="default" msgid="7947792373570683542">"允许应用读取 SD 卡的内容。"</string>
<string name="permlab_sdcardWrite" product="nosdcard" msgid="85430876310764752">"修改/删除 USB 存储设备内容"</string>
<string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"修改/删除 SD 卡中的内容"</string>
- <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"允许应用程序写入 USB 存储设备。"</string>
- <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"允许应用程序写入 SD 卡。"</string>
+ <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"允许应用写入 USB 存储设备。"</string>
+ <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"允许应用写入 SD 卡。"</string>
<string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"修改/删除内部媒体存储设备的内容"</string>
- <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"允许应用程序修改内部媒体存储设备的内容。"</string>
+ <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"允许应用修改内部媒体存储设备的内容。"</string>
<string name="permlab_cache_filesystem" msgid="5656487264819669824">"访问缓存文件系统"</string>
- <string name="permdesc_cache_filesystem" msgid="5578967642265550955">"允许应用程序读取和写入缓存文件系统。"</string>
+ <string name="permdesc_cache_filesystem" msgid="5578967642265550955">"允许应用读取和写入缓存文件系统。"</string>
<string name="permlab_use_sip" msgid="5986952362795870502">"拨打/接听互联网通话"</string>
- <string name="permdesc_use_sip" msgid="4717632000062674294">"允许应用程序使用 SIP 服务拨打/接听互联网电话。"</string>
+ <string name="permdesc_use_sip" msgid="4717632000062674294">"允许应用使用 SIP 服务拨打/接听互联网电话。"</string>
<string name="permlab_readNetworkUsageHistory" msgid="7862593283611493232">"读取网络使用情况历史记录"</string>
- <string name="permdesc_readNetworkUsageHistory" msgid="7689060749819126472">"允许应用程序读取特定网络和应用程序的网络使用情况历史记录。"</string>
+ <string name="permdesc_readNetworkUsageHistory" msgid="7689060749819126472">"允许应用读取特定网络和应用的网络使用情况历史记录。"</string>
<string name="permlab_manageNetworkPolicy" msgid="2562053592339859990">"管理网络政策"</string>
- <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"允许应用程序管理网络政策和定义专门针对应用程序的规则。"</string>
+ <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"允许应用管理网络政策和定义专门针对应用的规则。"</string>
<string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"修改网络使用情况记录方式"</string>
- <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"允许该应用程序修改对于各应用程序的网络使用情况的统计方式。普通应用程序不应使用此权限。"</string>
+ <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"允许该应用修改对于各应用的网络使用情况的统计方式。普通应用不应使用此权限。"</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"设置密码规则"</string>
<string name="policydesc_limitPassword" msgid="3252114203919510394">"控制屏幕解锁密码所允许的长度和字符。"</string>
<string name="policylab_watchLogin" msgid="914130646942199503">"监视屏幕解锁尝试次数"</string>
@@ -542,7 +542,7 @@
<string name="policylab_expirePassword" msgid="885279151847254056">"设置锁定屏幕密码的有效期"</string>
<string name="policydesc_expirePassword" msgid="1729725226314691591">"控制系统强制用户更改屏幕锁定密码的频率。"</string>
<string name="policylab_encryptedStorage" msgid="8901326199909132915">"设置存储设备加密"</string>
- <string name="policydesc_encryptedStorage" msgid="2637732115325316992">"要求对存储的应用程序数据进行加密。"</string>
+ <string name="policydesc_encryptedStorage" msgid="2637732115325316992">"要求对存储的应用数据进行加密。"</string>
<string name="policylab_disableCamera" msgid="6395301023152297826">"停用相机"</string>
<string name="policydesc_disableCamera" msgid="2306349042834754597">"禁止使用所有设备摄像头。"</string>
<string-array name="phoneTypes">
@@ -760,20 +760,20 @@
<string name="autofill_area" msgid="3547409050889952423">"区域"</string>
<string name="autofill_emirate" msgid="2893880978835698818">"酋长国"</string>
<string name="permlab_readHistoryBookmarks" msgid="1284843728203412135">"读取浏览器的历史记录和书签"</string>
- <string name="permdesc_readHistoryBookmarks" msgid="4577476392604595921">"允许应用程序读取“浏览器”访问过的所有网址,以及“浏览器”的所有书签。"</string>
+ <string name="permdesc_readHistoryBookmarks" msgid="4577476392604595921">"允许应用读取“浏览器”访问过的所有网址,以及“浏览器”的所有书签。"</string>
<string name="permlab_writeHistoryBookmarks" msgid="9009434109836280374">"写入浏览器的历史记录和书签"</string>
- <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="1757103804824209530">"允许应用程序修改“浏览器”存储在平板电脑上的历史记录或书签。恶意应用程序可能借此删除或修改“浏览器”的数据。"</string>
- <string name="permdesc_writeHistoryBookmarks" product="default" msgid="6693764355720719197">"允许应用程序修改“浏览器”存储在手机上的历史记录或书签。恶意应用程序可能借此删除或修改“浏览器”的数据。"</string>
+ <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="1757103804824209530">"允许应用修改“浏览器”存储在平板电脑上的历史记录或书签。恶意应用可能借此删除或修改“浏览器”的数据。"</string>
+ <string name="permdesc_writeHistoryBookmarks" product="default" msgid="6693764355720719197">"允许应用修改“浏览器”存储在手机上的历史记录或书签。恶意应用可能借此删除或修改“浏览器”的数据。"</string>
<string name="permlab_setAlarm" msgid="5924401328803615165">"在闹钟中设置警报"</string>
- <string name="permdesc_setAlarm" msgid="316392039157473848">"允许应用程序在已安装的闹钟应用程序中设置闹钟。有些闹钟应用程序可能无法实现此功能。"</string>
+ <string name="permdesc_setAlarm" msgid="316392039157473848">"允许应用在已安装的闹钟应用中设置闹钟。有些闹钟应用可能无法实现此功能。"</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"添加语音邮件"</string>
- <string name="permdesc_addVoicemail" msgid="6604508651428252437">"允许应用程序向您的语音信箱收件箱添加邮件。"</string>
+ <string name="permdesc_addVoicemail" msgid="6604508651428252437">"允许应用向您的语音信箱收件箱添加邮件。"</string>
<string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"修改“浏览器”地理位置的权限"</string>
- <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"允许应用程序修改“浏览器”的地理位置权限。恶意应用程序可能借此向任意网站发送位置信息。"</string>
+ <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"允许应用修改“浏览器”的地理位置权限。恶意应用可能借此向任意网站发送位置信息。"</string>
<string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"验证软件包"</string>
- <string name="permdesc_packageVerificationAgent" msgid="8437590190990843381">"允许应用程序验证程序包是否可以安装。"</string>
+ <string name="permdesc_packageVerificationAgent" msgid="8437590190990843381">"允许应用验证程序包是否可以安装。"</string>
<string name="permlab_bindPackageVerifier" msgid="4187786793360326654">"绑定到软件包验证程序"</string>
- <string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"允许用户请求使用程序包验证程序。普通应用程序绝不需要此权限。"</string>
+ <string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"允许用户请求使用程序包验证程序。普通应用绝不需要此权限。"</string>
<string name="permlab_serialPort" msgid="546083327654631076">"访问串行端口"</string>
<string name="permdesc_serialPort" msgid="2991639985224598193">"允许持有人使用 SerialManager API 访问串行端口。"</string>
<string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"从外部访问内容提供程序"</string>
@@ -918,12 +918,12 @@
<string name="loading" msgid="7933681260296021180">"正在加载..."</string>
<string name="capital_on" msgid="1544682755514494298">"打开"</string>
<string name="capital_off" msgid="6815870386972805832">"关闭"</string>
- <string name="whichApplication" msgid="4533185947064773386">"选择要使用的应用程序:"</string>
+ <string name="whichApplication" msgid="4533185947064773386">"选择要使用的应用:"</string>
<string name="alwaysUse" msgid="4583018368000610438">"设为默认选项。"</string>
- <string name="clearDefaultHintMsg" msgid="3252584689512077257">"在“系统设置”>“应用程序”>“已下载”中清除默认设置。"</string>
+ <string name="clearDefaultHintMsg" msgid="3252584689512077257">"在“系统设置”>“应用”>“已下载”中清除默认设置。"</string>
<string name="chooseActivity" msgid="7486876147751803333">"选择操作"</string>
- <string name="chooseUsbActivity" msgid="6894748416073583509">"为 USB 设备选择一个应用程序"</string>
- <string name="noApplications" msgid="2991814273936504689">"没有应用程序可执行此操作。"</string>
+ <string name="chooseUsbActivity" msgid="6894748416073583509">"为 USB 设备选择一个应用"</string>
+ <string name="noApplications" msgid="2991814273936504689">"没有应用可执行此操作。"</string>
<string name="aerr_title" msgid="1905800560317137752"></string>
<string name="aerr_application" msgid="932628488013092776">"很抱歉,“<xliff:g id="APPLICATION">%1$s</xliff:g>”已停止运行。"</string>
<string name="aerr_process" msgid="4507058997035697579">"抱歉,进程“<xliff:g id="PROCESS">%1$s</xliff:g>”已停止运行。"</string>
@@ -936,26 +936,26 @@
<string name="report" msgid="4060218260984795706">"报告"</string>
<string name="wait" msgid="7147118217226317732">"等待"</string>
<string name="webpage_unresponsive" msgid="3272758351138122503">"该网页已无响应。"\n\n"要将其关闭吗?"</string>
- <string name="launch_warning_title" msgid="1547997780506713581">"应用程序已重定向"</string>
+ <string name="launch_warning_title" msgid="1547997780506713581">"应用已重定向"</string>
<string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g>目前正在运行。"</string>
<string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g>已启动。"</string>
<string name="screen_compat_mode_scale" msgid="3202955667675944499">"缩放"</string>
<string name="screen_compat_mode_show" msgid="4013878876486655892">"始终显示"</string>
- <string name="screen_compat_mode_hint" msgid="1064524084543304459">"在“系统设置”>“应用程序”>“已下载”中重新启用此模式。"</string>
- <string name="smv_application" msgid="3307209192155442829">"“<xliff:g id="APPLICATION">%1$s</xliff:g>”应用程序(<xliff:g id="PROCESS">%2$s</xliff:g> 进程)违反了自我强制执行的严格模式 (StrictMode) 政策。"</string>
+ <string name="screen_compat_mode_hint" msgid="1064524084543304459">"在“系统设置”>“应用”>“已下载”中重新启用此模式。"</string>
+ <string name="smv_application" msgid="3307209192155442829">"“<xliff:g id="APPLICATION">%1$s</xliff:g>”应用(<xliff:g id="PROCESS">%2$s</xliff:g> 进程)违反了自我强制执行的严格模式 (StrictMode) 政策。"</string>
<string name="smv_process" msgid="5120397012047462446">"进程 <xliff:g id="PROCESS">%1$s</xliff:g> 违反了自我强制执行的严格模式 (StrictMode) 政策。"</string>
<string name="android_upgrading_title" msgid="1584192285441405746">"Android 正在升级..."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"正在优化第 <xliff:g id="NUMBER_0">%1$d</xliff:g> 个(共 <xliff:g id="NUMBER_1">%2$d</xliff:g> 个)。"</string>
- <string name="android_upgrading_starting_apps" msgid="451464516346926713">"正在启动应用程序。"</string>
+ <string name="android_upgrading_starting_apps" msgid="451464516346926713">"正在启动应用。"</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"即将完成启动。"</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g>正在运行"</string>
- <string name="heavy_weight_notification_detail" msgid="1721681741617898865">"触摸可切换至应用程序"</string>
- <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"切换应用程序吗?"</string>
- <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"已有一个应用程序正在运行,要启动新的应用程序,您必须先停止该应用程序。"</string>
+ <string name="heavy_weight_notification_detail" msgid="1721681741617898865">"触摸可切换至应用"</string>
+ <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"切换应用吗?"</string>
+ <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"已有一个应用正在运行,要启动新的应用,您必须先停止该应用。"</string>
<string name="old_app_action" msgid="493129172238566282">"返回至<xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
- <string name="old_app_description" msgid="2082094275580358049">"不启动新的应用程序。"</string>
+ <string name="old_app_description" msgid="2082094275580358049">"不启动新的应用。"</string>
<string name="new_app_action" msgid="5472756926945440706">"启动<xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
- <string name="new_app_description" msgid="1932143598371537340">"停止旧的应用程序,但不保存。"</string>
+ <string name="new_app_description" msgid="1932143598371537340">"停止旧的应用,但不保存。"</string>
<string name="sendText" msgid="5209874571959469142">"选择要对文字执行的操作"</string>
<string name="volume_ringtone" msgid="6885421406845734650">"铃声音量"</string>
<string name="volume_music" msgid="5421651157138628171">"媒体音量"</string>
@@ -1003,7 +1003,7 @@
<string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"键入所需的 PIN:"</string>
<string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN:"</string>
<string name="select_character" msgid="3365550120617701745">"插入字符"</string>
- <string name="sms_control_default_app_name" msgid="3058577482636640465">"未知应用程序"</string>
+ <string name="sms_control_default_app_name" msgid="3058577482636640465">"未知应用"</string>
<string name="sms_control_title" msgid="7296612781128917719">"正在发送短信"</string>
<string name="sms_control_message" msgid="4073755190243093924">"正在发送大量短信。触摸“确定”继续,或触摸“取消”停止发送。"</string>
<string name="sms_control_yes" msgid="2532062172402615953">"确定"</string>
@@ -1039,7 +1039,7 @@
<string name="usb_storage_stop_button_mount" msgid="7060218034900696029">"关闭 USB 存储设备"</string>
<string name="usb_storage_stop_error_message" msgid="1970374898263063836">"关闭 USB 存储设备时遇到问题。请检查您是否已卸载了 USB 主设备,然后重试。"</string>
<string name="dlg_confirm_kill_storage_users_title" msgid="963039033470478697">"打开 USB 存储设备"</string>
- <string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"如果您打开 USB 存储设备,您正在使用的某些应用程序将会停止,并且在您关闭 USB 存储设备前都将无法使用。"</string>
+ <string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"如果您打开 USB 存储设备,您正在使用的某些应用将会停止,并且在您关闭 USB 存储设备前都将无法使用。"</string>
<string name="dlg_error_title" msgid="7323658469626514207">"USB 操作失败"</string>
<string name="dlg_ok" msgid="7376953167039865701">"确定"</string>
<string name="usb_mtp_notification_title" msgid="3699913097391550394">"作为媒体设备连接"</string>
@@ -1084,9 +1084,9 @@
<string name="ext_media_nomedia_notification_message" product="default" msgid="3870120652983659641">"SD 卡已移除。请插入新的 SD 卡。"</string>
<string name="activity_list_empty" msgid="1675388330786841066">"未找到匹配的活动。"</string>
<string name="permlab_pkgUsageStats" msgid="8787352074326748892">"更新组件使用情况统计"</string>
- <string name="permdesc_pkgUsageStats" msgid="1106612424254277630">"允许应用程序修改收集到的组件使用情况统计信息。普通应用程序不能使用此权限。"</string>
+ <string name="permdesc_pkgUsageStats" msgid="1106612424254277630">"允许应用修改收集到的组件使用情况统计信息。普通应用不能使用此权限。"</string>
<string name="permlab_copyProtectedData" msgid="4341036311211406692">"复制内容"</string>
- <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"允许应用程序调用默认的容器服务,以便复制内容。普通应用程序不能使用此权限。"</string>
+ <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"允许应用调用默认的容器服务,以便复制内容。普通应用不能使用此权限。"</string>
<string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"触摸两次可进行缩放控制"</string>
<string name="gadget_host_error_inflating" msgid="4882004314906466162">"无法添加窗口小部件。"</string>
<string name="ime_action_go" msgid="8320845651737369027">"开始"</string>
@@ -1098,13 +1098,13 @@
<string name="ime_action_default" msgid="2840921885558045721">"执行"</string>
<string name="dial_number_using" msgid="5789176425167573586">"拨打电话"\n"<xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="create_contact_using" msgid="4947405226788104538">"创建电话号码为"\n"<xliff:g id="NUMBER">%s</xliff:g> 的联系人"</string>
- <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"以下一个或多个应用程序请求获得相应权限,以便在当前和以后访问您的帐户。"</string>
+ <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"以下一个或多个应用请求获得相应权限,以便在当前和以后访问您的帐户。"</string>
<string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"您是否同意此请求?"</string>
<string name="grant_permissions_header_text" msgid="6874497408201826708">"访问权限请求"</string>
<string name="allow" msgid="7225948811296386551">"允许"</string>
<string name="deny" msgid="2081879885755434506">"拒绝"</string>
<string name="permission_request_notification_title" msgid="6486759795926237907">"许可权限请求"</string>
- <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"应用程序对帐户 <xliff:g id="ACCOUNT">%s</xliff:g>"\n" 提出权限请求。"</string>
+ <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"应用对帐户 <xliff:g id="ACCOUNT">%s</xliff:g>"\n" 提出权限请求。"</string>
<string name="input_method_binding_label" msgid="1283557179944992649">"输入法"</string>
<string name="sync_binding_label" msgid="3687969138375092423">"同步"</string>
<string name="accessibility_binding_label" msgid="4148120742096474641">"辅助功能"</string>
@@ -1168,6 +1168,7 @@
<string name="add_account_button_label" msgid="3611982894853435874">"添加帐户"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"增加"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"减少"</string>
+ <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"触摸 <xliff:g id="VALUE">%s</xliff:g> 次并按住。"</string>
<string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"向上滑动可增加值,向下滑动可减少值。"</string>
<string name="time_picker_increment_minute_button" msgid="2843066823236250329">"增加分钟数"</string>
<string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"减少分钟数"</string>
@@ -1196,7 +1197,7 @@
<string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"模式更改"</string>
<string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
- <string name="activitychooserview_choose_application" msgid="2125168057199941199">"选择应用程序"</string>
+ <string name="activitychooserview_choose_application" msgid="2125168057199941199">"选择应用"</string>
<string name="shareactionprovider_share_with" msgid="806688056141131819">"共享对象"</string>
<string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"与“<xliff:g id="APPLICATION_NAME">%s</xliff:g>”共享"</string>
<string name="content_description_sliding_handle" msgid="415975056159262248">"滑动手柄。触摸并按住。"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index e5a15de..447af8a 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -743,8 +743,7 @@
<string name="double_tap_toast" msgid="4595046515400268881">"提示:輕按兩下即可縮放。"</string>
<string name="autofill_this_form" msgid="4616758841157816676">"自動填入功能"</string>
<string name="setup_autofill" msgid="7103495070180590814">"設定自動填入功能"</string>
- <!-- no translation found for autofill_address_name_separator (6350145154779706772) -->
- <skip />
+ <string name="autofill_address_name_separator" msgid="6350145154779706772">" //*** Empty segment here as a separator ***//"</string>
<string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
<string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
<string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
@@ -1169,6 +1168,7 @@
<string name="add_account_button_label" msgid="3611982894853435874">"新增帳戶"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"增加"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"減少"</string>
+ <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> 輕觸並按住。"</string>
<string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"向上滑動即可增加,向下滑動即可減少。"</string>
<string name="time_picker_increment_minute_button" msgid="2843066823236250329">"增加分鐘數"</string>
<string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"減少分鐘數"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index c50a1a8..f43835f 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -1168,6 +1168,7 @@
<string name="add_account_button_label" msgid="3611982894853435874">"Engeza i-akhawunti"</string>
<string name="number_picker_increment_button" msgid="4830170763103463443">"Nciphisa"</string>
<string name="number_picker_decrement_button" msgid="2576606679160067262">"Decrement"</string>
+ <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> thinta bese ucindezela."</string>
<string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Shishilizisa kwenyuke kuye ekwenyusweni kwehle kuye ekwehlisweni."</string>
<string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Iminithi wokwenyusa"</string>
<string name="time_picker_decrement_minute_button" msgid="4357907223628449595">"Iminithi yokwehlisa"</string>
diff --git a/core/tests/coretests/src/android/net/SSLTest.java b/core/tests/coretests/src/android/net/SSLTest.java
index 810ed0d..c573498 100644
--- a/core/tests/coretests/src/android/net/SSLTest.java
+++ b/core/tests/coretests/src/android/net/SSLTest.java
@@ -16,17 +16,16 @@
package android.net;
-import android.net.SSLCertificateSocketFactory;
import android.test.suitebuilder.annotation.Suppress;
-import junit.framework.TestCase;
-
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
+import java.util.Arrays;
+import junit.framework.TestCase;
-//This test relies on network resources.
-@Suppress
public class SSLTest extends TestCase {
+ //This test relies on network resources.
+ @Suppress
public void testCertificate() throws Exception {
// test www.fortify.net/sslcheck.html
Socket ssl = SSLCertificateSocketFactory.getDefault().createSocket("www.fortify.net",443);
@@ -49,4 +48,35 @@
// System.out.println(new String(b));
}
+
+ public void testStringsToNpnBytes() {
+ byte[] expected = {
+ 6, 's', 'p', 'd', 'y', '/', '2',
+ 8, 'h', 't', 't', 'p', '/', '1', '.', '1',
+ };
+ assertTrue(Arrays.equals(expected, SSLCertificateSocketFactory.toNpnProtocolsList(
+ new byte[] { 's', 'p', 'd', 'y', '/', '2' },
+ new byte[] { 'h', 't', 't', 'p', '/', '1', '.', '1' })));
+ }
+
+ public void testStringsToNpnBytesEmptyByteArray() {
+ try {
+ SSLCertificateSocketFactory.toNpnProtocolsList(new byte[0]);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ public void testStringsToNpnBytesEmptyArray() {
+ byte[] expected = {};
+ assertTrue(Arrays.equals(expected, SSLCertificateSocketFactory.toNpnProtocolsList()));
+ }
+
+ public void testStringsToNpnBytesOversizedInput() {
+ try {
+ SSLCertificateSocketFactory.toNpnProtocolsList(new byte[256]);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ }
}
diff --git a/data/fonts/vendor_fonts.xml b/data/fonts/vendor_fonts.xml
index c1116d0..5850f94 100644
--- a/data/fonts/vendor_fonts.xml
+++ b/data/fonts/vendor_fonts.xml
@@ -3,7 +3,12 @@
Vendor-provided fallback fonts
This file can be edited to add references to fonts that are not installed or referenced in the
- default system. The file should then be placed in /vendor/etc/fallback_fonts.xml.
+ default system. The file should then be placed in /vendor/etc/fallback_fonts.xml. Note
+ that in your makefile, this directory should be referenced as $(TARGET_COPY_OUT_VENDOR)/etc/:
+
+ PRODUCT_COPY_FILES += \
+ frameworks/base/data/fonts/vendor_fonts.xml:$(TARGET_COPY_OUT_VENDOR)/etc/fallback_fonts.xml \
+ frameworks/base/data/fonts/vendor_fonts-ja.xml:$(TARGET_COPY_OUT_VENDOR)/etc/fallback_fonts-ja.xml
For example, vendors might want to build configurations for locales that are
better served by fonts which either handle glyphs not supported in the default fonts or which
@@ -28,11 +33,31 @@
Han languages (Chinese, Japanese, and Korean) share a common range of unicode characters;
their ordering in the fallback or vendor files gives priority to the first in the list.
Locale-specific ordering can be configured by adding language and region codes to the end
- of the filename (e.g. /system/etc/fallback_fonts-ja.xml). When no region code is used,
+ of the filename (e.g. /vendor/etc/fallback_fonts-ja.xml). When no region code is used,
as with this example, all regions are matched. Use separate files for each supported locale.
The standard fallback file (fallback_fonts.xml) is used when a locale does not have its own
file. All fallback files must contain the same complete set of fonts; only their ordering
- can differ.
+ can differ. For example, on a device supporting Japanese, but with English as the default,
+ /vendor/etc/fallback_fonts.xml might contain:
+
+ <familyset>
+ <family>
+ <fileset>
+ <file>DroidSansJapanese.ttf</file>
+ </fileset>
+ </family>
+ </familyset>
+
+ placing the Japanese font at the end of the fallback sequence for English, with a corresponding
+ /system/vendor/etc/fallback_fonts-ja.xml, placing it at the front of the list.
+
+ <familyset>
+ <family order="0">
+ <fileset>
+ <file>DroidSansJapanese.ttf</file>
+ </fileset>
+ </family>
+ </familyset>
The sample configuration below is an example of how one might provide two families of fonts
that get inserted at the first and second (0 and 1) position in the overall fallback fonts.
diff --git a/graphics/java/android/renderscript/Allocation.java b/graphics/java/android/renderscript/Allocation.java
index 6539ff3..a76a628 100644
--- a/graphics/java/android/renderscript/Allocation.java
+++ b/graphics/java/android/renderscript/Allocation.java
@@ -131,22 +131,13 @@
public static final int USAGE_GRAPHICS_RENDER_TARGET = 0x0010;
/**
- * USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE The allocation
- * will be used as a SurfaceTexture graphics consumer. This
- * usage may only be used with USAGE_GRAPHICS_TEXTURE.
- *
- * @hide
- */
- public static final int USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE = 0x0020;
-
- /**
* USAGE_IO_INPUT The allocation will be used as SurfaceTexture
* consumer. This usage will cause the allocation to be created
* read only.
*
* @hide
*/
- public static final int USAGE_IO_INPUT = 0x0040;
+ public static final int USAGE_IO_INPUT = 0x0020;
/**
* USAGE_IO_OUTPUT The allocation will be used as a
@@ -155,7 +146,7 @@
*
* @hide
*/
- public static final int USAGE_IO_OUTPUT = 0x0080;
+ public static final int USAGE_IO_OUTPUT = 0x0040;
/**
* Controls mipmap behavior when using the bitmap creation and
@@ -197,6 +188,40 @@
return getID();
}
+
+ /**
+ * Get the element of the type of the Allocation.
+ *
+ * @hide
+ * @return Element
+ *
+ */
+ public Element getElement() {
+ return mType.getElement();
+ }
+
+ /**
+ * Get the usage flags of the Allocation.
+ *
+ * @hide
+ * @return usage
+ *
+ */
+ public int getUsage() {
+ return mUsage;
+ }
+
+ /**
+ * Get the size of the Allocation in bytes.
+ *
+ * @hide
+ * @return sizeInBytes
+ *
+ */
+ public int getSizeBytes() {
+ return mType.getCount() * mType.getElement().getSizeBytes();
+ }
+
private void updateCacheInfo(Type t) {
mCurrentDimX = t.getX();
mCurrentDimY = t.getY();
@@ -217,17 +242,15 @@
USAGE_GRAPHICS_VERTEX |
USAGE_GRAPHICS_CONSTANTS |
USAGE_GRAPHICS_RENDER_TARGET |
- USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE |
USAGE_IO_INPUT |
USAGE_IO_OUTPUT)) != 0) {
throw new RSIllegalArgumentException("Unknown usage specified.");
}
- if ((usage & (USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE | USAGE_IO_INPUT)) != 0) {
+ if ((usage & USAGE_IO_INPUT) != 0) {
mWriteAllowed = false;
- if ((usage & ~(USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE |
- USAGE_IO_INPUT |
+ if ((usage & ~(USAGE_IO_INPUT |
USAGE_GRAPHICS_TEXTURE |
USAGE_SCRIPT)) != 0) {
throw new RSIllegalArgumentException("Invalid usage combination.");
@@ -305,10 +328,21 @@
}
}
+ /**
+ * Get the type of the Allocation.
+ *
+ * @return Type
+ *
+ */
public Type getType() {
return mType;
}
+ /**
+ * Propagate changes from one usage of the allocation to the
+ * remaining usages of the allocation.
+ *
+ */
public void syncAll(int srcLocation) {
switch (srcLocation) {
case USAGE_SCRIPT:
@@ -348,12 +382,17 @@
public void ioGetInput() {
if ((mUsage & USAGE_IO_INPUT) == 0) {
throw new RSIllegalArgumentException(
- "Can only send buffer if IO_OUTPUT usage specified.");
+ "Can only receive if IO_INPUT usage specified.");
}
mRS.validate();
mRS.nAllocationIoReceive(getID());
}
+ /**
+ * Copy an array of RS objects to the allocation.
+ *
+ * @param d Source array.
+ */
public void copyFrom(BaseObj[] d) {
mRS.validate();
validateIsObject();
@@ -1134,13 +1173,15 @@
*
*/
public SurfaceTexture getSurfaceTexture() {
- if ((mUsage & USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE) == 0) {
+ if ((mUsage & USAGE_IO_INPUT) == 0) {
throw new RSInvalidStateException("Allocation is not a surface texture.");
}
int id = mRS.nAllocationGetSurfaceTextureID(getID());
- return new SurfaceTexture(id);
+ SurfaceTexture st = new SurfaceTexture(id);
+ mRS.nAllocationGetSurfaceTextureID2(getID(), st);
+ return st;
}
/**
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index 6921f37..ab6ba54 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -16,8 +16,8 @@
package android.renderscript;
-import java.lang.reflect.Field;
import java.io.File;
+import java.lang.reflect.Field;
import android.content.Context;
import android.content.pm.ApplicationInfo;
@@ -294,6 +294,11 @@
validate();
return rsnAllocationGetSurfaceTextureID(mContext, alloc);
}
+ native void rsnAllocationGetSurfaceTextureID2(int con, int alloc, SurfaceTexture st);
+ synchronized void nAllocationGetSurfaceTextureID2(int alloc, SurfaceTexture st) {
+ validate();
+ rsnAllocationGetSurfaceTextureID2(mContext, alloc, st);
+ }
native void rsnAllocationSetSurfaceTexture(int con, int alloc, SurfaceTexture sur);
synchronized void nAllocationSetSurfaceTexture(int alloc, SurfaceTexture sur) {
validate();
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index 9fc4fd4..9d4c64f 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -477,6 +477,15 @@
}
static void
+nAllocationGetSurfaceTextureID2(JNIEnv *_env, jobject _this, RsContext con, jint a, jobject jst)
+{
+ LOG_API("nAllocationGetSurfaceTextureID2, con(%p), a(%p)", con, (RsAllocation)a);
+ sp<SurfaceTexture> st = SurfaceTexture_getSurfaceTexture(_env, jst);
+
+ rsAllocationGetSurfaceTextureID2(con, (RsAllocation)a, st.get(), sizeof(SurfaceTexture *));
+}
+
+static void
nAllocationSetSurfaceTexture(JNIEnv *_env, jobject _this, RsContext con,
RsAllocation alloc, jobject sur)
{
@@ -1352,7 +1361,8 @@
{"rsnAllocationSyncAll", "(III)V", (void*)nAllocationSyncAll },
{"rsnAllocationGetSurfaceTextureID", "(II)I", (void*)nAllocationGetSurfaceTextureID },
-{"rsnAllocationSetSurfaceTexture", "(IILandroid/graphics/SurfaceTexture;)V", (void*)nAllocationSetSurfaceTexture },
+{"rsnAllocationGetSurfaceTextureID2","(IILandroid/graphics/SurfaceTexture;)V",(void*)nAllocationGetSurfaceTextureID2 },
+{"rsnAllocationSetSurfaceTexture", "(IILandroid/graphics/SurfaceTexture;)V",(void*)nAllocationSetSurfaceTexture },
{"rsnAllocationIoSend", "(II)V", (void*)nAllocationIoSend },
{"rsnAllocationIoReceive", "(II)V", (void*)nAllocationIoReceive },
{"rsnAllocationData1D", "(IIIII[II)V", (void*)nAllocationData1D_i },
diff --git a/include/cpustats/CentralTendencyStatistics.h b/include/cpustats/CentralTendencyStatistics.h
deleted file mode 100644
index 21b6981..0000000
--- a/include/cpustats/CentralTendencyStatistics.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _CENTRAL_TENDENCY_STATISTICS_H
-#define _CENTRAL_TENDENCY_STATISTICS_H
-
-#include <math.h>
-
-// Not multithread safe
-class CentralTendencyStatistics {
-
-public:
-
- CentralTendencyStatistics() :
- mMean(NAN), mMedian(NAN), mMinimum(INFINITY), mMaximum(-INFINITY), mN(0), mM2(0),
- mVariance(NAN), mVarianceKnownForN(0), mStddev(NAN), mStddevKnownForN(0) { }
-
- ~CentralTendencyStatistics() { }
-
- // add x to the set of samples
- void sample(double x);
-
- // return the arithmetic mean of all samples so far
- double mean() const { return mMean; }
-
- // return the minimum of all samples so far
- double minimum() const { return mMinimum; }
-
- // return the maximum of all samples so far
- double maximum() const { return mMaximum; }
-
- // return the variance of all samples so far
- double variance() const;
-
- // return the standard deviation of all samples so far
- double stddev() const;
-
- // return the number of samples added so far
- unsigned n() const { return mN; }
-
- // reset the set of samples to be empty
- void reset();
-
-private:
- double mMean;
- double mMedian;
- double mMinimum;
- double mMaximum;
- unsigned mN; // number of samples so far
- double mM2;
-
- // cached variance, and n at time of caching
- mutable double mVariance;
- mutable unsigned mVarianceKnownForN;
-
- // cached standard deviation, and n at time of caching
- mutable double mStddev;
- mutable unsigned mStddevKnownForN;
-
-};
-
-#endif // _CENTRAL_TENDENCY_STATISTICS_H
diff --git a/include/cpustats/README.txt b/include/cpustats/README.txt
deleted file mode 100644
index 14439f0..0000000
--- a/include/cpustats/README.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-This is a static library of CPU usage statistics, originally written
-for audio but most are not actually specific to audio.
-
-Requirements to be here:
- * should be related to CPU usage statistics
- * should be portable to host; avoid Android OS dependencies without a conditional
diff --git a/include/cpustats/ThreadCpuUsage.h b/include/cpustats/ThreadCpuUsage.h
deleted file mode 100644
index 9cd93d8..0000000
--- a/include/cpustats/ThreadCpuUsage.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _THREAD_CPU_USAGE_H
-#define _THREAD_CPU_USAGE_H
-
-#include <fcntl.h>
-#include <pthread.h>
-
-namespace android {
-
-// Track CPU usage for the current thread.
-// Units are in per-thread CPU ns, as reported by
-// clock_gettime(CLOCK_THREAD_CPUTIME_ID). Simple usage: for cyclic
-// threads where you want to measure the execution time of the whole
-// cycle, just call sampleAndEnable() at the start of each cycle.
-// For acyclic threads, or for cyclic threads where you want to measure/track
-// only part of each cycle, call enable(), disable(), and/or setEnabled()
-// to demarcate the region(s) of interest, and then call sample() periodically.
-// This class is not thread-safe for concurrent calls from multiple threads;
-// the methods of this class may only be called by the current thread
-// which constructed the object.
-
-class ThreadCpuUsage
-{
-
-public:
- ThreadCpuUsage() :
- mIsEnabled(false),
- mWasEverEnabled(false),
- mAccumulator(0),
- // mPreviousTs
- // mMonotonicTs
- mMonotonicKnown(false)
- {
- (void) pthread_once(&sOnceControl, &init);
- for (int i = 0; i < sKernelMax; ++i) {
- mCurrentkHz[i] = (uint32_t) ~0; // unknown
- }
- }
-
- ~ThreadCpuUsage() { }
-
- // Return whether currently tracking CPU usage by current thread
- bool isEnabled() const { return mIsEnabled; }
-
- // Enable tracking of CPU usage by current thread;
- // any CPU used from this point forward will be tracked.
- // Returns the previous enabled status.
- bool enable() { return setEnabled(true); }
-
- // Disable tracking of CPU usage by current thread;
- // any CPU used from this point forward will be ignored.
- // Returns the previous enabled status.
- bool disable() { return setEnabled(false); }
-
- // Set the enabled status and return the previous enabled status.
- // This method is intended to be used for safe nested enable/disabling.
- bool setEnabled(bool isEnabled);
-
- // Add a sample point, and also enable tracking if needed.
- // If tracking has never been enabled, then this call enables tracking but
- // does _not_ add a sample -- it is not possible to add a sample the
- // first time because there is no previous point to subtract from.
- // Otherwise, if tracking is enabled,
- // then adds a sample for tracked CPU ns since the previous
- // sample, or since the first call to sampleAndEnable(), enable(), or
- // setEnabled(true). If there was a previous sample but tracking is
- // now disabled, then adds a sample for the tracked CPU ns accumulated
- // up until the most recent disable(), resets this accumulator, and then
- // enables tracking. Calling this method rather than enable() followed
- // by sample() avoids a race condition for the first sample.
- // Returns true if the sample 'ns' is valid, or false if invalid.
- // Note that 'ns' is an output parameter passed by reference.
- // The caller does not need to initialize this variable.
- // The units are CPU nanoseconds consumed by current thread.
- bool sampleAndEnable(double& ns);
-
- // Add a sample point, but do not
- // change the tracking enabled status. If tracking has either never been
- // enabled, or has never been enabled since the last sample, then log a warning
- // and don't add sample. Otherwise, adds a sample for tracked CPU ns since
- // the previous sample or since the first call to sampleAndEnable(),
- // enable(), or setEnabled(true) if no previous sample.
- // Returns true if the sample is valid, or false if invalid.
- // Note that 'ns' is an output parameter passed by reference.
- // The caller does not need to initialize this variable.
- // The units are CPU nanoseconds consumed by current thread.
- bool sample(double& ns);
-
- // Return the elapsed delta wall clock ns since initial enable or reset,
- // as reported by clock_gettime(CLOCK_MONOTONIC).
- long long elapsed() const;
-
- // Reset elapsed wall clock. Has no effect on tracking or accumulator.
- void resetElapsed();
-
- // Return current clock frequency for specified CPU, in kHz.
- // You can get your CPU number using sched_getcpu(2). Note that, unless CPU affinity
- // has been configured appropriately, the CPU number can change.
- // Also note that, unless the CPU governor has been configured appropriately,
- // the CPU frequency can change. And even if the CPU frequency is locked down
- // to a particular value, that the frequency might still be adjusted
- // to prevent thermal overload. Therefore you should poll for your thread's
- // current CPU number and clock frequency periodically.
- uint32_t getCpukHz(int cpuNum);
-
-private:
- bool mIsEnabled; // whether tracking is currently enabled
- bool mWasEverEnabled; // whether tracking was ever enabled
- long long mAccumulator; // accumulated thread CPU time since last sample, in ns
- struct timespec mPreviousTs; // most recent thread CPU time, valid only if mIsEnabled is true
- struct timespec mMonotonicTs; // most recent monotonic time
- bool mMonotonicKnown; // whether mMonotonicTs has been set
-
- static const int MAX_CPU = 8;
- static int sScalingFds[MAX_CPU];// file descriptor per CPU for reading scaling_cur_freq
- uint32_t mCurrentkHz[MAX_CPU]; // current CPU frequency in kHz, not static to avoid a race
- static pthread_once_t sOnceControl;
- static int sKernelMax; // like MAX_CPU, but determined at runtime == cpu/kernel_max + 1
- static void init();
-};
-
-} // namespace android
-
-#endif // _THREAD_CPU_USAGE_H
diff --git a/include/media/AudioRecord.h b/include/media/AudioRecord.h
index 7df6668..5bfb65b 100644
--- a/include/media/AudioRecord.h
+++ b/include/media/AudioRecord.h
@@ -354,7 +354,6 @@
audio_format_t format,
uint32_t channelMask,
int frameCount,
- uint32_t flags,
audio_io_handle_t input);
audio_io_handle_t getInput_l();
status_t restoreRecord_l(audio_track_cblk_t*& cblk);
diff --git a/include/media/IAudioFlinger.h b/include/media/IAudioFlinger.h
index 0f39cf3..8239b0e 100644
--- a/include/media/IAudioFlinger.h
+++ b/include/media/IAudioFlinger.h
@@ -43,6 +43,14 @@
public:
DECLARE_META_INTERFACE(AudioFlinger);
+ // or-able bits shared by createTrack and openRecord, but not all combinations make sense
+ enum {
+ TRACK_DEFAULT = 0, // client requests a default AudioTrack
+ TRACK_TIMED = 1, // client requests a TimedAudioTrack
+ TRACK_FAST = 2, // client requests a fast AudioTrack
+ };
+ typedef uint32_t track_flags_t;
+
/* create an audio track and registers it with AudioFlinger.
* return null if the track cannot be created.
*/
@@ -53,10 +61,9 @@
audio_format_t format,
uint32_t channelMask,
int frameCount,
- uint32_t flags,
+ track_flags_t flags,
const sp<IMemory>& sharedBuffer,
audio_io_handle_t output,
- bool isTimed,
int *sessionId,
status_t *status) = 0;
@@ -67,7 +74,7 @@
audio_format_t format,
uint32_t channelMask,
int frameCount,
- uint32_t flags,
+ track_flags_t flags,
int *sessionId,
status_t *status) = 0;
diff --git a/include/media/ICrypto.h b/include/media/ICrypto.h
new file mode 100644
index 0000000..916abe0
--- /dev/null
+++ b/include/media/ICrypto.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <binder/IInterface.h>
+#include <media/stagefright/foundation/ABase.h>
+
+#ifndef ANDROID_ICRYPTO_H_
+
+#define ANDROID_ICRYPTO_H_
+
+namespace android {
+
+struct ICrypto : public IInterface {
+ DECLARE_META_INTERFACE(Crypto);
+
+ virtual status_t initialize() = 0;
+ virtual status_t terminate() = 0;
+
+ virtual status_t setEntitlementKey(
+ const void *key, size_t keyLength) = 0;
+
+ virtual status_t setEntitlementControlMessage(
+ const void *msg, size_t msgLength) = 0;
+
+ // "dstData" is in media_server's address space (but inaccessible).
+ virtual ssize_t decryptVideo(
+ const void *iv, size_t ivLength,
+ const void *srcData, size_t srcDataSize,
+ void *dstData, size_t dstDataOffset) = 0;
+
+ // "dstData" is in the calling process' address space.
+ virtual ssize_t decryptAudio(
+ const void *iv, size_t ivLength,
+ const void *srcData, size_t srcDataSize,
+ void *dstData, size_t dstDataSize) = 0;
+
+private:
+ DISALLOW_EVIL_CONSTRUCTORS(ICrypto);
+};
+
+struct BnCrypto : public BnInterface<ICrypto> {
+ virtual status_t onTransact(
+ uint32_t code, const Parcel &data, Parcel *reply,
+ uint32_t flags = 0);
+};
+
+} // namespace android
+
+#endif // ANDROID_ICRYPTO_H_
+
diff --git a/include/media/IMediaPlayerService.h b/include/media/IMediaPlayerService.h
index 4f46fcd..76c45a0 100644
--- a/include/media/IMediaPlayerService.h
+++ b/include/media/IMediaPlayerService.h
@@ -31,6 +31,7 @@
namespace android {
+struct ICrypto;
class IMediaRecorder;
class IOMX;
struct IStreamSource;
@@ -47,6 +48,7 @@
virtual sp<IMemory> decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, audio_format_t* pFormat) = 0;
virtual sp<IMemory> decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, audio_format_t* pFormat) = 0;
virtual sp<IOMX> getOMX() = 0;
+ virtual sp<ICrypto> makeCrypto() = 0;
// codecs and audio devices usage tracking for the battery app
enum BatteryDataBits {
diff --git a/include/media/IOMX.h b/include/media/IOMX.h
index a295e9a..be1b2fc 100644
--- a/include/media/IOMX.h
+++ b/include/media/IOMX.h
@@ -26,8 +26,6 @@
#include <OMX_Core.h>
#include <OMX_Video.h>
-#include "jni.h"
-
namespace android {
class IMemory;
diff --git a/include/media/JetPlayer.h b/include/media/JetPlayer.h
index 38a3e44..0616bf0 100644
--- a/include/media/JetPlayer.h
+++ b/include/media/JetPlayer.h
@@ -18,7 +18,6 @@
#define JETPLAYER_H_
#include <utils/threads.h>
-#include <nativehelper/jni.h>
#include <libsonivox/jet.h>
#include <libsonivox/eas_types.h>
@@ -40,7 +39,7 @@
static const int JET_NUMQUEUEDSEGMENT_UPDATE = 3;
static const int JET_PAUSE_UPDATE = 4;
- JetPlayer(jobject javaJetPlayer,
+ JetPlayer(void *javaJetPlayer,
int maxTracks = 32,
int trackBufferSize = 1200);
~JetPlayer();
@@ -75,7 +74,7 @@
jetevent_callback mEventCallback;
- jobject mJavaJetPlayerRef;
+ void* mJavaJetPlayerRef;
Mutex mMutex; // mutex to sync the render and playback thread with the JET calls
pid_t mTid;
Condition mCondition;
diff --git a/include/media/stagefright/ACodec.h b/include/media/stagefright/ACodec.h
index fa1a416..7d7af63 100644
--- a/include/media/stagefright/ACodec.h
+++ b/include/media/stagefright/ACodec.h
@@ -89,6 +89,10 @@
kPortIndexOutput = 1
};
+ enum {
+ kFlagIsSecure = 1,
+ };
+
struct BufferInfo {
enum Status {
OWNED_BY_US,
@@ -118,6 +122,7 @@
sp<FlushingState> mFlushingState;
AString mComponentName;
+ uint32_t mFlags;
uint32_t mQuirks;
sp<IOMX> mOMX;
IOMX::node_id mNode;
@@ -176,7 +181,8 @@
status_t setupAACCodec(
bool encoder,
- int32_t numChannels, int32_t sampleRate, int32_t bitRate);
+ int32_t numChannels, int32_t sampleRate, int32_t bitRate,
+ bool isADTS);
status_t selectAudioPortFormat(
OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat);
diff --git a/include/media/stagefright/MediaCodec.h b/include/media/stagefright/MediaCodec.h
index 72ac56a..0fc88e1 100644
--- a/include/media/stagefright/MediaCodec.h
+++ b/include/media/stagefright/MediaCodec.h
@@ -27,18 +27,21 @@
struct ABuffer;
struct ACodec;
struct AMessage;
+struct ICrypto;
struct SoftwareRenderer;
struct SurfaceTextureClient;
struct MediaCodec : public AHandler {
enum ConfigureFlags {
CONFIGURE_FLAG_ENCODE = 1,
+ CONFIGURE_FLAG_SECURE = 2,
};
enum BufferFlags {
BUFFER_FLAG_SYNCFRAME = 1,
BUFFER_FLAG_CODECCONFIG = 2,
BUFFER_FLAG_EOS = 4,
+ BUFFER_FLAG_ENCRYPTED = 8,
};
static sp<MediaCodec> CreateByType(
@@ -137,11 +140,13 @@
kFlagStickyError = 8,
kFlagDequeueInputPending = 16,
kFlagDequeueOutputPending = 32,
+ kFlagIsSecure = 64,
};
struct BufferInfo {
void *mBufferID;
sp<ABuffer> mData;
+ sp<ABuffer> mEncryptedData;
sp<AMessage> mNotify;
bool mOwnedByClient;
};
@@ -165,6 +170,8 @@
int32_t mDequeueOutputTimeoutGeneration;
uint32_t mDequeueOutputReplyID;
+ sp<ICrypto> mCrypto;
+
MediaCodec(const sp<ALooper> &looper);
static status_t PostAndAwaitResponse(
diff --git a/include/media/stagefright/MetaData.h b/include/media/stagefright/MetaData.h
index c3ccb56..639446e 100644
--- a/include/media/stagefright/MetaData.h
+++ b/include/media/stagefright/MetaData.h
@@ -128,6 +128,12 @@
kKeyTextFormatData = 'text', // raw data
kKeyRequiresSecureBuffers = 'secu', // bool (int32_t)
+
+ kKeyScrambling = 'scrm', // int32_t
+ kKeyEMM = 'emm ', // raw data
+ kKeyECM = 'ecm ', // raw data
+
+ kKeyIsADTS = 'adts', // bool (int32_t)
};
enum {
diff --git a/include/media/stagefright/NuMediaExtractor.h b/include/media/stagefright/NuMediaExtractor.h
index 96efdff..07c7be5 100644
--- a/include/media/stagefright/NuMediaExtractor.h
+++ b/include/media/stagefright/NuMediaExtractor.h
@@ -31,6 +31,11 @@
struct MediaSource;
struct NuMediaExtractor : public RefBase {
+ enum SampleFlags {
+ SAMPLE_FLAG_SYNC = 1,
+ SAMPLE_FLAG_ENCRYPTED = 2,
+ };
+
NuMediaExtractor();
status_t setDataSource(const char *path);
@@ -46,6 +51,7 @@
status_t readSampleData(const sp<ABuffer> &buffer);
status_t getSampleTrackIndex(size_t *trackIndex);
status_t getSampleTime(int64_t *sampleTimeUs);
+ status_t getSampleFlags(uint32_t *sampleFlags);
protected:
virtual ~NuMediaExtractor();
@@ -61,7 +67,9 @@
status_t mFinalResult;
MediaBuffer *mSample;
int64_t mSampleTimeUs;
- uint32_t mFlags; // bitmask of "TrackFlags"
+ uint32_t mSampleFlags;
+
+ uint32_t mTrackFlags; // bitmask of "TrackFlags"
};
sp<MediaExtractor> mImpl;
diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h
index 7c612ba..7d51dee 100644
--- a/include/media/stagefright/OMXCodec.h
+++ b/include/media/stagefright/OMXCodec.h
@@ -238,7 +238,11 @@
void setComponentRole();
void setAMRFormat(bool isWAMR, int32_t bitRate);
- status_t setAACFormat(int32_t numChannels, int32_t sampleRate, int32_t bitRate);
+
+ status_t setAACFormat(
+ int32_t numChannels, int32_t sampleRate, int32_t bitRate,
+ bool isADTS);
+
void setG711Format(int32_t numChannels);
status_t setVideoPortFormatType(
diff --git a/include/media/stagefright/SurfaceMediaSource.h b/include/media/stagefright/SurfaceMediaSource.h
index 54baab6..936b057 100644
--- a/include/media/stagefright/SurfaceMediaSource.h
+++ b/include/media/stagefright/SurfaceMediaSource.h
@@ -111,7 +111,7 @@
// Make sure this is called when the mutex is locked
virtual status_t onFrameReceivedLocked();
- virtual status_t setScalingMode(int mode) { } // no op for encoding
+ virtual status_t setScalingMode(int mode) { return OK; } // no op for encoding
virtual int query(int what, int* value);
// Just confirming to the ISurfaceTexture interface as of now
diff --git a/include/media/stagefright/foundation/AString.h b/include/media/stagefright/foundation/AString.h
index 55ade64..0f8f1e1 100644
--- a/include/media/stagefright/foundation/AString.h
+++ b/include/media/stagefright/foundation/AString.h
@@ -73,6 +73,7 @@
int compare(const AString &other) const;
bool startsWith(const char *prefix) const;
+ bool endsWith(const char *suffix) const;
void tolower();
diff --git a/libs/cpustats/Android.mk b/libs/cpustats/Android.mk
deleted file mode 100644
index 21bacbb..0000000
--- a/libs/cpustats/Android.mk
+++ /dev/null
@@ -1,21 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := \
- CentralTendencyStatistics.cpp \
- ThreadCpuUsage.cpp
-
-LOCAL_MODULE := libcpustats
-
-include $(BUILD_STATIC_LIBRARY)
-
-#include $(CLEAR_VARS)
-#
-#LOCAL_SRC_FILES := \
-# CentralTendencyStatistics.cpp \
-# ThreadCpuUsage.cpp
-#
-#LOCAL_MODULE := libcpustats
-#
-#include $(BUILD_HOST_STATIC_LIBRARY)
diff --git a/libs/cpustats/CentralTendencyStatistics.cpp b/libs/cpustats/CentralTendencyStatistics.cpp
deleted file mode 100644
index 42ab62b..0000000
--- a/libs/cpustats/CentralTendencyStatistics.cpp
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdlib.h>
-
-#include <cpustats/CentralTendencyStatistics.h>
-
-void CentralTendencyStatistics::sample(double x)
-{
- // update min and max
- if (x < mMinimum)
- mMinimum = x;
- if (x > mMaximum)
- mMaximum = x;
- // Knuth
- if (mN == 0) {
- mMean = 0;
- }
- ++mN;
- double delta = x - mMean;
- mMean += delta / mN;
- mM2 += delta * (x - mMean);
-}
-
-void CentralTendencyStatistics::reset()
-{
- mMean = NAN;
- mMedian = NAN;
- mMinimum = INFINITY;
- mMaximum = -INFINITY;
- mN = 0;
- mM2 = 0;
- mVariance = NAN;
- mVarianceKnownForN = 0;
- mStddev = NAN;
- mStddevKnownForN = 0;
-}
-
-double CentralTendencyStatistics::variance() const
-{
- double variance;
- if (mVarianceKnownForN != mN) {
- if (mN > 1) {
- // double variance_n = M2/n;
- variance = mM2 / (mN - 1);
- } else {
- variance = NAN;
- }
- mVariance = variance;
- mVarianceKnownForN = mN;
- } else {
- variance = mVariance;
- }
- return variance;
-}
-
-double CentralTendencyStatistics::stddev() const
-{
- double stddev;
- if (mStddevKnownForN != mN) {
- stddev = sqrt(variance());
- mStddev = stddev;
- mStddevKnownForN = mN;
- } else {
- stddev = mStddev;
- }
- return stddev;
-}
diff --git a/libs/cpustats/ThreadCpuUsage.cpp b/libs/cpustats/ThreadCpuUsage.cpp
deleted file mode 100644
index 99b4c8363..0000000
--- a/libs/cpustats/ThreadCpuUsage.cpp
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "ThreadCpuUsage"
-//#define LOG_NDEBUG 0
-
-#include <errno.h>
-#include <stdlib.h>
-#include <time.h>
-
-#include <utils/Debug.h>
-#include <utils/Log.h>
-
-#include <cpustats/ThreadCpuUsage.h>
-
-namespace android {
-
-bool ThreadCpuUsage::setEnabled(bool isEnabled)
-{
- bool wasEnabled = mIsEnabled;
- // only do something if there is a change
- if (isEnabled != wasEnabled) {
- ALOGV("setEnabled(%d)", isEnabled);
- int rc;
- // enabling
- if (isEnabled) {
- rc = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &mPreviousTs);
- if (rc) {
- ALOGE("clock_gettime(CLOCK_THREAD_CPUTIME_ID) errno=%d", errno);
- isEnabled = false;
- } else {
- mWasEverEnabled = true;
- // record wall clock time at first enable
- if (!mMonotonicKnown) {
- rc = clock_gettime(CLOCK_MONOTONIC, &mMonotonicTs);
- if (rc) {
- ALOGE("clock_gettime(CLOCK_MONOTONIC) errno=%d", errno);
- } else {
- mMonotonicKnown = true;
- }
- }
- }
- // disabling
- } else {
- struct timespec ts;
- rc = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts);
- if (rc) {
- ALOGE("clock_gettime(CLOCK_THREAD_CPUTIME_ID) errno=%d", errno);
- } else {
- long long delta = (ts.tv_sec - mPreviousTs.tv_sec) * 1000000000LL +
- (ts.tv_nsec - mPreviousTs.tv_nsec);
- mAccumulator += delta;
-#if 0
- mPreviousTs = ts;
-#endif
- }
- }
- mIsEnabled = isEnabled;
- }
- return wasEnabled;
-}
-
-bool ThreadCpuUsage::sampleAndEnable(double& ns)
-{
- bool ret;
- bool wasEverEnabled = mWasEverEnabled;
- if (enable()) {
- // already enabled, so add a new sample relative to previous
- return sample(ns);
- } else if (wasEverEnabled) {
- // was disabled, but add sample for accumulated time while enabled
- ns = (double) mAccumulator;
- mAccumulator = 0;
- ALOGV("sampleAndEnable %.0f", ns);
- return true;
- } else {
- // first time called
- ns = 0.0;
- ALOGV("sampleAndEnable false");
- return false;
- }
-}
-
-bool ThreadCpuUsage::sample(double &ns)
-{
- if (mWasEverEnabled) {
- if (mIsEnabled) {
- struct timespec ts;
- int rc;
- rc = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts);
- if (rc) {
- ALOGE("clock_gettime(CLOCK_THREAD_CPUTIME_ID) errno=%d", errno);
- ns = 0.0;
- return false;
- } else {
- long long delta = (ts.tv_sec - mPreviousTs.tv_sec) * 1000000000LL +
- (ts.tv_nsec - mPreviousTs.tv_nsec);
- mAccumulator += delta;
- mPreviousTs = ts;
- }
- } else {
- mWasEverEnabled = false;
- }
- ns = (double) mAccumulator;
- ALOGV("sample %.0f", ns);
- mAccumulator = 0;
- return true;
- } else {
- ALOGW("Can't add sample because measurements have never been enabled");
- ns = 0.0;
- return false;
- }
-}
-
-long long ThreadCpuUsage::elapsed() const
-{
- long long elapsed;
- if (mMonotonicKnown) {
- struct timespec ts;
- int rc;
- rc = clock_gettime(CLOCK_MONOTONIC, &ts);
- if (rc) {
- ALOGE("clock_gettime(CLOCK_MONOTONIC) errno=%d", errno);
- elapsed = 0;
- } else {
- // mMonotonicTs is updated only at first enable and resetStatistics
- elapsed = (ts.tv_sec - mMonotonicTs.tv_sec) * 1000000000LL +
- (ts.tv_nsec - mMonotonicTs.tv_nsec);
- }
- } else {
- ALOGW("Can't compute elapsed time because measurements have never been enabled");
- elapsed = 0;
- }
- ALOGV("elapsed %lld", elapsed);
- return elapsed;
-}
-
-void ThreadCpuUsage::resetElapsed()
-{
- ALOGV("resetElapsed");
- if (mMonotonicKnown) {
- int rc;
- rc = clock_gettime(CLOCK_MONOTONIC, &mMonotonicTs);
- if (rc) {
- ALOGE("clock_gettime(CLOCK_MONOTONIC) errno=%d", errno);
- mMonotonicKnown = false;
- }
- }
-}
-
-/*static*/
-int ThreadCpuUsage::sScalingFds[ThreadCpuUsage::MAX_CPU];
-pthread_once_t ThreadCpuUsage::sOnceControl = PTHREAD_ONCE_INIT;
-int ThreadCpuUsage::sKernelMax;
-
-/*static*/
-void ThreadCpuUsage::init()
-{
- // read the number of CPUs
- sKernelMax = 1;
- int fd = open("/sys/devices/system/cpu/kernel_max", O_RDONLY);
- if (fd >= 0) {
-#define KERNEL_MAX_SIZE 12
- char kernelMax[KERNEL_MAX_SIZE];
- ssize_t actual = read(fd, kernelMax, sizeof(kernelMax));
- if (actual >= 2 && kernelMax[actual-1] == '\n') {
- sKernelMax = atoi(kernelMax);
- if (sKernelMax >= MAX_CPU - 1) {
- ALOGW("kernel_max %d but MAX_CPU %d", sKernelMax, MAX_CPU);
- sKernelMax = MAX_CPU;
- } else if (sKernelMax < 0) {
- ALOGW("kernel_max invalid %d", sKernelMax);
- sKernelMax = 1;
- } else {
- ++sKernelMax;
- ALOGV("number of CPUs %d", sKernelMax);
- }
- } else {
- ALOGW("Can't read number of CPUs");
- }
- (void) close(fd);
- } else {
- ALOGW("Can't open number of CPUs");
- }
-
- // open fd to each frequency per CPU
-#define FREQ_SIZE 64
- char freq_path[FREQ_SIZE];
-#define FREQ_DIGIT 27
- COMPILE_TIME_ASSERT_FUNCTION_SCOPE(MAX_CPU <= 10);
- strlcpy(freq_path, "/sys/devices/system/cpu/cpu?/cpufreq/scaling_cur_freq", sizeof(freq_path));
- int i;
- for (i = 0; i < MAX_CPU; ++i) {
- sScalingFds[i] = -1;
- }
- for (i = 0; i < sKernelMax; ++i) {
- freq_path[FREQ_DIGIT] = i + '0';
- fd = open(freq_path, O_RDONLY);
- if (fd >= 0) {
- // keep this fd until process exit
- sScalingFds[i] = fd;
- } else {
- ALOGW("Can't open CPU %d", i);
- }
- }
-}
-
-uint32_t ThreadCpuUsage::getCpukHz(int cpuNum)
-{
- if (cpuNum < 0 || cpuNum >= MAX_CPU) {
- ALOGW("getCpukHz called with invalid CPU %d", cpuNum);
- return 0;
- }
- int fd = sScalingFds[cpuNum];
- if (fd < 0) {
- ALOGW("getCpukHz called for unopened CPU %d", cpuNum);
- return 0;
- }
-#define KHZ_SIZE 12
- char kHz[KHZ_SIZE]; // kHz base 10
- ssize_t actual = pread(fd, kHz, sizeof(kHz), (off_t) 0);
- uint32_t ret;
- if (actual >= 2 && kHz[actual-1] == '\n') {
- ret = atoi(kHz);
- } else {
- ret = 0;
- }
- if (ret != mCurrentkHz[cpuNum]) {
- if (ret > 0) {
- ALOGV("CPU %d frequency %u kHz", cpuNum, ret);
- } else {
- ALOGW("Can't read CPU %d frequency", cpuNum);
- }
- mCurrentkHz[cpuNum] = ret;
- }
- return ret;
-}
-
-} // namespace android
diff --git a/libs/rs/Allocation.cpp b/libs/rs/Allocation.cpp
index d69c55f..e37d5de 100644
--- a/libs/rs/Allocation.cpp
+++ b/libs/rs/Allocation.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008-2012 The Android Open Source Project
+ * Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -51,17 +51,14 @@
RS_ALLOCATION_USAGE_GRAPHICS_VERTEX |
RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS |
RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET |
- RS_ALLOCATION_USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE |
RS_ALLOCATION_USAGE_IO_INPUT |
RS_ALLOCATION_USAGE_IO_OUTPUT)) != 0) {
ALOGE("Unknown usage specified.");
}
- if ((usage & (RS_ALLOCATION_USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE |
- RS_ALLOCATION_USAGE_IO_INPUT)) != 0) {
+ if ((usage & RS_ALLOCATION_USAGE_IO_INPUT) != 0) {
mWriteAllowed = false;
- if ((usage & ~(RS_ALLOCATION_USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE |
- RS_ALLOCATION_USAGE_IO_INPUT |
+ if ((usage & ~(RS_ALLOCATION_USAGE_IO_INPUT |
RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE |
RS_ALLOCATION_USAGE_SCRIPT)) != 0) {
ALOGE("Invalid usage combination.");
diff --git a/libs/rs/driver/rsdAllocation.cpp b/libs/rs/driver/rsdAllocation.cpp
index fb93d82..f358f93 100644
--- a/libs/rs/driver/rsdAllocation.cpp
+++ b/libs/rs/driver/rsdAllocation.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 The Android Open Source Project
+ * Copyright (C) 2011-2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -27,6 +27,7 @@
#include "hardware/gralloc.h"
#include "ui/Rect.h"
#include "ui/GraphicBufferMapper.h"
+#include "gui/SurfaceTexture.h"
#include <GLES/gl.h>
#include <GLES2/gl2.h>
@@ -139,7 +140,7 @@
static void UploadToTexture(const Context *rsc, const Allocation *alloc) {
DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
- if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE) {
+ if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_INPUT) {
if (!drv->textureID) {
RSD_CALL_GL(glGenTextures, 1, &drv->textureID);
}
@@ -475,7 +476,8 @@
}
void rsdAllocationIoReceive(const Context *rsc, Allocation *alloc) {
- ALOGE("not implemented");
+ DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
+ alloc->mHal.state.surfaceTexture->updateTexImage();
}
diff --git a/libs/rs/driver/rsdCore.cpp b/libs/rs/driver/rsdCore.cpp
index 35a5c08..6a532e9 100644
--- a/libs/rs/driver/rsdCore.cpp
+++ b/libs/rs/driver/rsdCore.cpp
@@ -227,13 +227,13 @@
int cpu = sysconf(_SC_NPROCESSORS_ONLN);
- ALOGV("%p Launching thread(s), CPUs %i", rsc, cpu);
if(rsc->props.mDebugMaxThreads && (cpu > (int)rsc->props.mDebugMaxThreads)) {
cpu = rsc->props.mDebugMaxThreads;
}
if (cpu < 2) {
cpu = 0;
}
+ ALOGV("%p Launching thread(s), CPUs %i", rsc, cpu);
dc->mWorkers.mCount = (uint32_t)cpu;
dc->mWorkers.mThreadId = (pthread_t *) calloc(dc->mWorkers.mCount, sizeof(pthread_t));
diff --git a/libs/rs/driver/rsdProgram.cpp b/libs/rs/driver/rsdProgram.cpp
index fa4cb0f..30a4c5f 100644
--- a/libs/rs/driver/rsdProgram.cpp
+++ b/libs/rs/driver/rsdProgram.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 The Android Open Source Project
+ * Copyright (C) 2011-2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -41,7 +41,7 @@
textureNames, textureNamesCount, textureNamesLength);
pv->mHal.drv = drv;
- return drv->createShader();
+ return true;
}
static void SyncProgramConstants(const Context *rsc, const Program *p) {
@@ -88,7 +88,7 @@
textureNames, textureNamesCount, textureNamesLength);
pf->mHal.drv = drv;
- return drv->createShader();
+ return true;
}
void rsdProgramFragmentSetActive(const Context *rsc, const ProgramFragment *pf) {
diff --git a/libs/rs/driver/rsdShader.cpp b/libs/rs/driver/rsdShader.cpp
index 1e73b95..a386735 100644
--- a/libs/rs/driver/rsdShader.cpp
+++ b/libs/rs/driver/rsdShader.cpp
@@ -39,7 +39,10 @@
initMemberVars();
initAttribAndUniformArray();
init(textureNames, textureNamesCount, textureNamesLength);
- createTexturesString(textureNames, textureNamesCount, textureNamesLength);
+
+ for(size_t i=0; i < textureNamesCount; i++) {
+ mTextureNames.push(String8(textureNames[i], textureNamesLength[i]));
+ }
}
RsdShader::~RsdShader() {
@@ -138,37 +141,42 @@
}
}
-void RsdShader::createTexturesString(const char** textureNames, size_t textureNamesCount,
- const size_t *textureNamesLength) {
- mShaderTextures.setTo("");
+void RsdShader::appendTextures() {
+
+ // TODO: this does not yet handle cases where the texture changes between IO
+ // input and local
+ bool appendUsing = true;
for (uint32_t ct = 0; ct < mRSProgram->mHal.state.texturesCount; ct ++) {
if (mRSProgram->mHal.state.textureTargets[ct] == RS_TEXTURE_2D) {
Allocation *a = mRSProgram->mHal.state.textures[ct];
if (a && a->mHal.state.surfaceTextureID) {
- mShaderTextures.append("uniform samplerExternalOES UNI_");
+ if(appendUsing) {
+ mShader.append("#extension GL_OES_EGL_image_external : require\n");
+ appendUsing = false;
+ }
+ mShader.append("uniform samplerExternalOES UNI_");
+ mTextureTargets[ct] = GL_TEXTURE_EXTERNAL_OES;
} else {
- mShaderTextures.append("uniform sampler2D UNI_");
+ mShader.append("uniform sampler2D UNI_");
+ mTextureTargets[ct] = GL_TEXTURE_2D;
}
- mTextureTargets[ct] = GL_TEXTURE_2D;
} else {
- mShaderTextures.append("uniform samplerCube UNI_");
+ mShader.append("uniform samplerCube UNI_");
mTextureTargets[ct] = GL_TEXTURE_CUBE_MAP;
}
- mShaderTextures.append(textureNames[ct], textureNamesLength[ct]);
- mShaderTextures.append(";\n");
+ mShader.append(mTextureNames[ct]);
+ mShader.append(";\n");
}
}
bool RsdShader::createShader() {
-
if (mType == GL_FRAGMENT_SHADER) {
mShader.append("precision mediump float;\n");
}
appendUserConstants();
appendAttributes();
- mShader.append(mShaderTextures);
-
+ appendTextures();
mShader.append(mUserShader);
return true;
@@ -178,6 +186,10 @@
mShaderID = glCreateShader(mType);
rsAssert(mShaderID);
+ if(!mShader.length()) {
+ createShader();
+ }
+
if (rsc->props.mLogShaders) {
ALOGV("Loading shader type %x, ID %i", mType, mShaderID);
ALOGV("%s", mShader.string());
@@ -423,7 +435,9 @@
}
DrvAllocation *drvTex = (DrvAllocation *)mRSProgram->mHal.state.textures[ct]->mHal.drv;
- if (drvTex->glTarget != GL_TEXTURE_2D && drvTex->glTarget != GL_TEXTURE_CUBE_MAP) {
+ if (drvTex->glTarget != GL_TEXTURE_2D &&
+ drvTex->glTarget != GL_TEXTURE_CUBE_MAP &&
+ drvTex->glTarget != GL_TEXTURE_EXTERNAL_OES) {
ALOGE("Attempting to bind unknown texture to shader id %u, texture unit %u",
(uint)this, ct);
rsc->setError(RS_ERROR_BAD_SHADER, "Non-texture allocation bound to a shader");
diff --git a/libs/rs/driver/rsdShader.h b/libs/rs/driver/rsdShader.h
index e32145f..6c0b616 100644
--- a/libs/rs/driver/rsdShader.h
+++ b/libs/rs/driver/rsdShader.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 The Android Open Source Project
+ * Copyright (C) 2011-2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -81,15 +81,12 @@
void appendAttributes();
void appendTextures();
- void createTexturesString(const char** textureNames, size_t textureNamesCount,
- const size_t *textureNamesLength);
void initAttribAndUniformArray();
mutable bool mDirty;
android::String8 mShader;
android::String8 mUserShader;
- android::String8 mShaderTextures;
uint32_t mShaderID;
uint32_t mType;
@@ -101,6 +98,8 @@
android::String8 *mUniformNames;
uint32_t *mUniformArraySizes;
+ android::Vector<android::String8> mTextureNames;
+
int32_t mTextureUniformIndexStart;
void logUniform(const android::renderscript::Element *field,
diff --git a/libs/rs/driver/rsdShaderCache.cpp b/libs/rs/driver/rsdShaderCache.cpp
index 89d3c45..50cb9f9 100644
--- a/libs/rs/driver/rsdShaderCache.cpp
+++ b/libs/rs/driver/rsdShaderCache.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 The Android Open Source Project
+ * Copyright (C) 2011-2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -119,7 +119,6 @@
if (!vtx->getShaderID() || !frag->getShaderID()) {
return false;
}
- //ALOGV("rsdShaderCache lookup vtx %i, frag %i", vtx->getShaderID(), frag->getShaderID());
uint32_t entryCount = mEntries.size();
for (uint32_t ct = 0; ct < entryCount; ct ++) {
if ((mEntries[ct]->vtx == vtx->getShaderID()) &&
@@ -134,8 +133,6 @@
}
}
- //ALOGV("RsdShaderCache miss");
- //ALOGE("e0 %x", glGetError());
ProgramEntry *e = new ProgramEntry(vtx->getAttribCount(),
vtx->getUniformCount(),
frag->getUniformCount());
diff --git a/libs/rs/driver/rsdShaderCache.h b/libs/rs/driver/rsdShaderCache.h
index 0beecae..1192916 100644
--- a/libs/rs/driver/rsdShaderCache.h
+++ b/libs/rs/driver/rsdShaderCache.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 The Android Open Source Project
+ * Copyright (C) 2011-2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/libs/rs/rs.spec b/libs/rs/rs.spec
index cf4a391..b373056 100644
--- a/libs/rs/rs.spec
+++ b/libs/rs/rs.spec
@@ -69,6 +69,12 @@
ret int32_t
}
+AllocationGetSurfaceTextureID2 {
+ param RsAllocation alloc
+ param void *st
+ sync
+}
+
AllocationSetSurface {
param RsAllocation alloc
param RsNativeWindow sur
diff --git a/libs/rs/rsAllocation.cpp b/libs/rs/rsAllocation.cpp
index a404c49..cdff49c 100644
--- a/libs/rs/rsAllocation.cpp
+++ b/libs/rs/rsAllocation.cpp
@@ -20,6 +20,7 @@
#include "rs_hal.h"
#include "system/window.h"
+#include "gui/SurfaceTexture.h"
using namespace android;
using namespace android::renderscript;
@@ -64,6 +65,7 @@
Allocation::~Allocation() {
freeChildrenUnlocked();
+ setSurfaceTexture(mRSC, NULL);
mRSC->mHal.funcs.allocation.destroy(mRSC, this);
}
@@ -424,6 +426,18 @@
return id;
}
+void Allocation::setSurfaceTexture(const Context *rsc, SurfaceTexture *st) {
+ if(st != mHal.state.surfaceTexture) {
+ if(mHal.state.surfaceTexture != NULL) {
+ mHal.state.surfaceTexture->decStrong(NULL);
+ }
+ mHal.state.surfaceTexture = st;
+ if(mHal.state.surfaceTexture != NULL) {
+ mHal.state.surfaceTexture->incStrong(NULL);
+ }
+ }
+}
+
void Allocation::setSurface(const Context *rsc, RsNativeWindow sur) {
ANativeWindow *nw = (ANativeWindow *)sur;
ANativeWindow *old = mHal.state.wndSurface;
@@ -696,6 +710,11 @@
return alloc->getSurfaceTextureID(rsc);
}
+void rsi_AllocationGetSurfaceTextureID2(Context *rsc, RsAllocation valloc, void *vst, size_t len) {
+ Allocation *alloc = static_cast<Allocation *>(valloc);
+ alloc->setSurfaceTexture(rsc, static_cast<SurfaceTexture *>(vst));
+}
+
void rsi_AllocationSetSurface(Context *rsc, RsAllocation valloc, RsNativeWindow sur) {
Allocation *alloc = static_cast<Allocation *>(valloc);
alloc->setSurface(rsc, sur);
diff --git a/libs/rs/rsAllocation.h b/libs/rs/rsAllocation.h
index 58a6fca..e2783d2 100644
--- a/libs/rs/rsAllocation.h
+++ b/libs/rs/rsAllocation.h
@@ -23,6 +23,8 @@
// ---------------------------------------------------------------------------
namespace android {
+class SurfaceTexture;
+
namespace renderscript {
class Program;
@@ -60,6 +62,7 @@
void * usrPtr;
int32_t surfaceTextureID;
ANativeWindow *wndSurface;
+ SurfaceTexture *surfaceTexture;
};
State state;
@@ -130,6 +133,7 @@
}
int32_t getSurfaceTextureID(const Context *rsc);
+ void setSurfaceTexture(const Context *rsc, SurfaceTexture *st);
void setSurface(const Context *rsc, RsNativeWindow sur);
void ioSend(const Context *rsc);
void ioReceive(const Context *rsc);
diff --git a/libs/rs/rsDefines.h b/libs/rs/rsDefines.h
index 990ef26..0e0cd8d 100644
--- a/libs/rs/rsDefines.h
+++ b/libs/rs/rsDefines.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007 The Android Open Source Project
+ * Copyright (C) 2007-2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -100,9 +100,8 @@
RS_ALLOCATION_USAGE_GRAPHICS_VERTEX = 0x0004,
RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS = 0x0008,
RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET = 0x0010,
- RS_ALLOCATION_USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE = 0x0020,
- RS_ALLOCATION_USAGE_IO_INPUT = 0x0040,
- RS_ALLOCATION_USAGE_IO_OUTPUT = 0x0080,
+ RS_ALLOCATION_USAGE_IO_INPUT = 0x0020,
+ RS_ALLOCATION_USAGE_IO_OUTPUT = 0x0040,
RS_ALLOCATION_USAGE_ALL = 0x00FF
};
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index bccf1f9..d06e302 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -48,6 +48,7 @@
public static int FLAG_SYNCFRAME = 1;
public static int FLAG_CODECCONFIG = 2;
public static int FLAG_EOS = 4;
+ public static int FLAG_ENCRYPTED = 8;
/** Instantiate a codec component by mime type. For decoder components
this is the mime type of media that this decoder should be able to
@@ -82,6 +83,7 @@
public native final void release();
public static int CONFIGURE_FLAG_ENCODE = 1;
+ public static int CONFIGURE_FLAG_SECURE = 2;
/** Configures a component.
* @param format A map of string/value pairs describing the input format
diff --git a/media/java/android/media/MediaExtractor.java b/media/java/android/media/MediaExtractor.java
index 5732c72..9ea3d0e 100644
--- a/media/java/android/media/MediaExtractor.java
+++ b/media/java/android/media/MediaExtractor.java
@@ -65,6 +65,13 @@
// Returns the current sample's presentation time in microseconds.
public native long getSampleTime();
+ // Keep these in sync with their equivalents in NuMediaExtractor.h
+ public static final int SAMPLE_FLAG_SYNC = 1;
+ public static final int SAMPLE_FLAG_ENCRYPTED = 2;
+
+ // Returns the current sample's flags.
+ public native int getSampleFlags();
+
private static native final void native_init();
private native final void native_setup(String path);
private native final void native_finalize();
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index a08d6c3..a8144a7 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -1396,6 +1396,7 @@
}
mMtpObjectHandle = objectHandle;
+ Cursor fileList = null;
try {
if (MediaFile.isPlayListFileType(fileType)) {
// build file cache so we can look up tracks in the playlist
@@ -1403,7 +1404,9 @@
FileEntry entry = makeEntryFor(path);
if (entry != null) {
- processPlayList(entry);
+ fileList = mMediaProvider.query(mFilesUri, FILES_PRESCAN_PROJECTION,
+ null, null, null, null);
+ processPlayList(entry, fileList);
}
} else {
// MTP will create a file entry for us so we don't want to do it in prescan
@@ -1417,6 +1420,9 @@
Log.e(TAG, "RemoteException in MediaScanner.scanFile()", e);
} finally {
mMtpObjectHandle = 0;
+ if (fileList != null) {
+ fileList.close();
+ }
}
}
@@ -1479,7 +1485,7 @@
}
private boolean addPlayListEntry(String entry, String playListDirectory,
- Uri uri, ContentValues values, int index) {
+ Uri uri, ContentValues values, int index, Cursor fileList) {
// watch for trailing whitespace
int entryLength = entry.length();
@@ -1506,19 +1512,20 @@
// number of rightmost file/directory names for bestMatch
int bestMatchLength = 0;
- Cursor c = null;
- try {
- c = mMediaProvider.query(mFilesUri, FILES_PRESCAN_PROJECTION,
- null, null, null, null);
- } catch (RemoteException e1) {
- }
-
- if (c != null) {
- while (c.moveToNext()) {
- long rowId = c.getLong(FILES_PRESCAN_ID_COLUMN_INDEX);
- String path = c.getString(FILES_PRESCAN_PATH_COLUMN_INDEX);
- int format = c.getInt(FILES_PRESCAN_FORMAT_COLUMN_INDEX);
- long lastModified = c.getLong(FILES_PRESCAN_DATE_MODIFIED_COLUMN_INDEX);
+ if (fileList != null) {
+ int count = fileList.getCount();
+ // Backing up a little in the cursor helps when the files in the
+ // playlist are not in the same order as they are in the database
+ // but are still close.
+ fileList.move(-1000);
+ while(--count >= 0) {
+ if (!fileList.moveToNext()) {
+ fileList.moveToFirst();
+ }
+ long rowId = fileList.getLong(FILES_PRESCAN_ID_COLUMN_INDEX);
+ String path = fileList.getString(FILES_PRESCAN_PATH_COLUMN_INDEX);
+ int format = fileList.getInt(FILES_PRESCAN_FORMAT_COLUMN_INDEX);
+ long lastModified = fileList.getLong(FILES_PRESCAN_DATE_MODIFIED_COLUMN_INDEX);
if (path.equalsIgnoreCase(entry)) {
bestMatch = new FileEntry(rowId, path, lastModified, format);
@@ -1531,7 +1538,6 @@
bestMatchLength = matchLength;
}
}
- c.close();
}
if (bestMatch == null) {
@@ -1541,7 +1547,7 @@
try {
// check rowid is set. Rowid may be missing if it is inserted by bulkInsert().
if (bestMatch.mRowId == 0) {
- c = mMediaProvider.query(mAudioUri, ID_PROJECTION,
+ Cursor c = mMediaProvider.query(mAudioUri, ID_PROJECTION,
MediaStore.Files.FileColumns.DATA + "=?",
new String[] { bestMatch.mPath }, null, null);
if (c != null) {
@@ -1567,7 +1573,8 @@
return true;
}
- private void processM3uPlayList(String path, String playListDirectory, Uri uri, ContentValues values) {
+ private void processM3uPlayList(String path, String playListDirectory, Uri uri,
+ ContentValues values, Cursor fileList) {
BufferedReader reader = null;
try {
File f = new File(path);
@@ -1580,7 +1587,7 @@
// ignore comment lines, which begin with '#'
if (line.length() > 0 && line.charAt(0) != '#') {
values.clear();
- if (addPlayListEntry(line, playListDirectory, uri, values, index))
+ if (addPlayListEntry(line, playListDirectory, uri, values, index, fileList))
index++;
}
line = reader.readLine();
@@ -1598,7 +1605,8 @@
}
}
- private void processPlsPlayList(String path, String playListDirectory, Uri uri, ContentValues values) {
+ private void processPlsPlayList(String path, String playListDirectory, Uri uri,
+ ContentValues values, Cursor fileList) {
BufferedReader reader = null;
try {
File f = new File(path);
@@ -1613,7 +1621,8 @@
int equals = line.indexOf('=');
if (equals > 0) {
values.clear();
- if (addPlayListEntry(line.substring(equals + 1), playListDirectory, uri, values, index))
+ if (addPlayListEntry(line.substring(equals + 1), playListDirectory,
+ uri, values, index, fileList))
index++;
}
}
@@ -1637,12 +1646,14 @@
final ContentHandler handler;
String playListDirectory;
Uri uri;
+ Cursor fileList;
ContentValues values = new ContentValues();
int index = 0;
- public WplHandler(String playListDirectory, Uri uri) {
+ public WplHandler(String playListDirectory, Uri uri, Cursor fileList) {
this.playListDirectory = playListDirectory;
this.uri = uri;
+ this.fileList = fileList;
RootElement root = new RootElement("smil");
Element body = root.getChild("body");
@@ -1653,11 +1664,12 @@
this.handler = root.getContentHandler();
}
+ @Override
public void start(Attributes attributes) {
String path = attributes.getValue("", "src");
if (path != null) {
values.clear();
- if (addPlayListEntry(path, playListDirectory, uri, values, index)) {
+ if (addPlayListEntry(path, playListDirectory, uri, values, index, fileList)) {
index++;
}
}
@@ -1671,14 +1683,16 @@
}
}
- private void processWplPlayList(String path, String playListDirectory, Uri uri) {
+ private void processWplPlayList(String path, String playListDirectory, Uri uri,
+ Cursor fileList) {
FileInputStream fis = null;
try {
File f = new File(path);
if (f.exists()) {
fis = new FileInputStream(f);
- Xml.parse(fis, Xml.findEncodingByName("UTF-8"), new WplHandler(playListDirectory, uri).getContentHandler());
+ Xml.parse(fis, Xml.findEncodingByName("UTF-8"),
+ new WplHandler(playListDirectory, uri, fileList).getContentHandler());
}
} catch (SAXException e) {
e.printStackTrace();
@@ -1694,7 +1708,7 @@
}
}
- private void processPlayList(FileEntry entry) throws RemoteException {
+ private void processPlayList(FileEntry entry, Cursor fileList) throws RemoteException {
String path = entry.mPath;
ContentValues values = new ContentValues();
int lastSlash = path.lastIndexOf('/');
@@ -1736,21 +1750,31 @@
int fileType = (mediaFileType == null ? 0 : mediaFileType.fileType);
if (fileType == MediaFile.FILE_TYPE_M3U) {
- processM3uPlayList(path, playListDirectory, membersUri, values);
+ processM3uPlayList(path, playListDirectory, membersUri, values, fileList);
} else if (fileType == MediaFile.FILE_TYPE_PLS) {
- processPlsPlayList(path, playListDirectory, membersUri, values);
+ processPlsPlayList(path, playListDirectory, membersUri, values, fileList);
} else if (fileType == MediaFile.FILE_TYPE_WPL) {
- processWplPlayList(path, playListDirectory, membersUri);
+ processWplPlayList(path, playListDirectory, membersUri, fileList);
}
}
private void processPlayLists() throws RemoteException {
Iterator<FileEntry> iterator = mPlayLists.iterator();
- while (iterator.hasNext()) {
- FileEntry entry = iterator.next();
- // only process playlist files if they are new or have been modified since the last scan
- if (entry.mLastModifiedChanged) {
- processPlayList(entry);
+ Cursor fileList = null;
+ try {
+ fileList = mMediaProvider.query(mFilesUri, FILES_PRESCAN_PROJECTION,
+ null, null, null, null);
+ while (iterator.hasNext()) {
+ FileEntry entry = iterator.next();
+ // only process playlist files if they are new or have been modified since the last scan
+ if (entry.mLastModifiedChanged) {
+ processPlayList(entry, fileList);
+ }
+ }
+ } catch (RemoteException e1) {
+ } finally {
+ if (fileList != null) {
+ fileList.close();
}
}
}
diff --git a/media/jni/android_media_MediaExtractor.cpp b/media/jni/android_media_MediaExtractor.cpp
index 0c86fc2..8c661b7 100644
--- a/media/jni/android_media_MediaExtractor.cpp
+++ b/media/jni/android_media_MediaExtractor.cpp
@@ -160,6 +160,10 @@
return mImpl->getSampleTime(sampleTimeUs);
}
+status_t JMediaExtractor::getSampleFlags(uint32_t *sampleFlags) {
+ return mImpl->getSampleFlags(sampleFlags);
+}
+
} // namespace android
////////////////////////////////////////////////////////////////////////////////
@@ -343,6 +347,28 @@
return sampleTimeUs;
}
+static jint android_media_MediaExtractor_getSampleFlags(
+ JNIEnv *env, jobject thiz) {
+ sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
+
+ if (extractor == NULL) {
+ jniThrowException(env, "java/lang/IllegalStateException", NULL);
+ return -1ll;
+ }
+
+ uint32_t sampleFlags;
+ status_t err = extractor->getSampleFlags(&sampleFlags);
+
+ if (err == ERROR_END_OF_STREAM) {
+ return -1ll;
+ } else if (err != OK) {
+ jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
+ return false;
+ }
+
+ return sampleFlags;
+}
+
static void android_media_MediaExtractor_native_init(JNIEnv *env) {
jclass clazz = env->FindClass("android/media/MediaExtractor");
CHECK(clazz != NULL);
@@ -412,6 +438,9 @@
{ "getSampleTime", "()J",
(void *)android_media_MediaExtractor_getSampleTime },
+ { "getSampleFlags", "()I",
+ (void *)android_media_MediaExtractor_getSampleFlags },
+
{ "native_init", "()V", (void *)android_media_MediaExtractor_native_init },
{ "native_setup", "(Ljava/lang/String;)V",
diff --git a/media/jni/android_media_MediaExtractor.h b/media/jni/android_media_MediaExtractor.h
index 70e58c6..49a64d6 100644
--- a/media/jni/android_media_MediaExtractor.h
+++ b/media/jni/android_media_MediaExtractor.h
@@ -43,6 +43,7 @@
status_t readSampleData(jobject byteBuf, size_t offset, size_t *sampleSize);
status_t getSampleTrackIndex(size_t *trackIndex);
status_t getSampleTime(int64_t *sampleTimeUs);
+ status_t getSampleFlags(uint32_t *sampleFlags);
protected:
virtual ~JMediaExtractor();
diff --git a/media/jni/android_media_Utils.cpp b/media/jni/android_media_Utils.cpp
index 8b2321c..1190448 100644
--- a/media/jni/android_media_Utils.cpp
+++ b/media/jni/android_media_Utils.cpp
@@ -324,7 +324,7 @@
env->DeleteLocalRef(byteArray); byteArray = NULL;
}
- msg->setObject(key.c_str(), buffer);
+ msg->setBuffer(key.c_str(), buffer);
}
}
diff --git a/media/jni/mediaeditor/VideoEditorMain.h b/media/jni/mediaeditor/VideoEditorMain.h
deleted file mode 100755
index 4c3b517..0000000
--- a/media/jni/mediaeditor/VideoEditorMain.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef __VIDEO_EDITOR_API_H__
-#define __VIDEO_EDITOR_API_H__
-
-#include "M4OSA_Types.h"
-
-typedef enum
-{
- MSG_TYPE_PROGRESS_INDICATION, // Playback progress indication event
- MSG_TYPE_PLAYER_ERROR, // Playback error
- MSG_TYPE_PREVIEW_END, // Preview of clips is complete
- MSG_TYPE_OVERLAY_UPDATE, // update overlay during preview
- MSG_TYPE_OVERLAY_CLEAR, // clear the overlay
-} progress_callback_msg_type;
-
-typedef struct {
- int overlaySettingsIndex;
- int clipIndex;
-} VideoEditorCurretEditInfo;
-
-typedef struct
-{
- M4OSA_Void *pFile; /** PCM file path */
- M4OSA_Bool bRemoveOriginal; /** If true, the original audio track
- is not taken into account */
- M4OSA_UInt32 uiNbChannels; /** Number of channels (1=mono, 2=stereo) of BGM clip*/
- M4OSA_UInt32 uiSamplingFrequency; /** Sampling audio frequency (8000 for amr, 16000 or
- more for aac) of BGM clip*/
- M4OSA_UInt32 uiExtendedSamplingFrequency; /** Extended frequency for AAC+,
- eAAC+ streams of BGM clip*/
- M4OSA_UInt32 uiAddCts; /** Time, in milliseconds, at which the added
- audio track is inserted */
- M4OSA_UInt32 uiAddVolume; /** Volume, in percentage, of the added audio track */
- M4OSA_UInt32 beginCutMs;
- M4OSA_UInt32 endCutMs;
- M4OSA_Int32 fileType;
- M4OSA_Bool bLoop; /** Looping on/off **/
- /* Audio ducking */
- M4OSA_UInt32 uiInDucking_threshold; /** Threshold value at which
- background music shall duck */
- M4OSA_UInt32 uiInDucking_lowVolume; /** lower the background track to
- this factor of current level */
- M4OSA_Bool bInDucking_enable; /** enable ducking */
- M4OSA_UInt32 uiBTChannelCount; /** channel count for BT */
- M4OSA_Void *pPCMFilePath;
-} M4xVSS_AudioMixingSettings;
-
-typedef struct
-{
- M4OSA_Void *pBuffer; /* YUV420 buffer of frame to be rendered*/
- M4OSA_UInt32 timeMs; /* time stamp of the frame to be rendered*/
- M4OSA_UInt32 uiSurfaceWidth; /* Surface display width*/
- M4OSA_UInt32 uiSurfaceHeight; /* Surface display height*/
- M4OSA_UInt32 uiFrameWidth; /* Frame width*/
- M4OSA_UInt32 uiFrameHeight; /* Frame height*/
- M4OSA_Bool bApplyEffect; /* Apply video effects before render*/
- M4OSA_UInt32 clipBeginCutTime; /* Clip begin cut time relative to storyboard */
- M4OSA_UInt32 clipEndCutTime; /* Clip end cut time relative to storyboard */
- M4OSA_UInt32 videoRotationDegree; /* Video rotation degree */
-
-} VideoEditor_renderPreviewFrameStr;
-#endif /*__VIDEO_EDITOR_API_H__*/
diff --git a/media/jni/soundpool/Android.mk b/media/jni/soundpool/Android.mk
index 98d6449..70dbfb3 100644
--- a/media/jni/soundpool/Android.mk
+++ b/media/jni/soundpool/Android.mk
@@ -2,14 +2,14 @@
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
- android_media_SoundPool.cpp \
- SoundPool.cpp \
- SoundPoolThread.cpp
+ android_media_SoundPool.cpp
+
+LOCAL_C_INCLUDES := \
+ frameworks/base/media/libmedia
LOCAL_SHARED_LIBRARIES := \
libcutils \
libutils \
- libbinder \
libandroid_runtime \
libnativehelper \
libmedia \
diff --git a/media/jni/soundpool/android_media_SoundPool.cpp b/media/jni/soundpool/android_media_SoundPool.cpp
index da3af9d..c6dee06 100644
--- a/media/jni/soundpool/android_media_SoundPool.cpp
+++ b/media/jni/soundpool/android_media_SoundPool.cpp
@@ -23,7 +23,7 @@
#include <nativehelper/jni.h>
#include <nativehelper/JNIHelp.h>
#include <android_runtime/AndroidRuntime.h>
-#include "SoundPool.h"
+#include <SoundPool.h>
using namespace android;
diff --git a/media/libeffects/visualizer/EffectVisualizer.cpp b/media/libeffects/visualizer/EffectVisualizer.cpp
index 51c8b68..bdb1a1c 100644
--- a/media/libeffects/visualizer/EffectVisualizer.cpp
+++ b/media/libeffects/visualizer/EffectVisualizer.cpp
@@ -21,6 +21,7 @@
#include <stdlib.h>
#include <string.h>
#include <new>
+#include <time.h>
#include <audio_effects/effect_visualizer.h>
@@ -47,9 +48,9 @@
VISUALIZER_STATE_ACTIVE,
};
-// maximum number of reads from same buffer before resetting capture buffer. This means
+// maximum time since last capture buffer update before resetting capture buffer. This means
// that the framework has stopped playing audio and we must start returning silence
-#define MAX_STALL_COUNT 10
+#define MAX_STALL_TIME_MS 1000
struct VisualizerContext {
const struct effect_interface_s *mItfe;
@@ -59,7 +60,7 @@
uint8_t mState;
uint8_t mCurrentBuf;
uint8_t mLastBuf;
- uint8_t mStallCount;
+ struct timespec mBufferUpdateTime;
uint8_t mCaptureBuf[2][VISUALIZER_CAPTURE_SIZE_MAX];
};
@@ -72,7 +73,7 @@
pContext->mCaptureIdx = 0;
pContext->mCurrentBuf = 0;
pContext->mLastBuf = 1;
- pContext->mStallCount = 0;
+ pContext->mBufferUpdateTime.tv_sec = 0;
memset(pContext->mCaptureBuf[0], 0x80, VISUALIZER_CAPTURE_SIZE_MAX);
memset(pContext->mCaptureBuf[1], 0x80, VISUALIZER_CAPTURE_SIZE_MAX);
}
@@ -321,6 +322,11 @@
if (pContext->mCaptureIdx == pContext->mCaptureSize) {
pContext->mCurrentBuf ^= 1;
pContext->mCaptureIdx = 0;
+
+ // update last buffer update time stamp
+ if (clock_gettime(CLOCK_MONOTONIC, &pContext->mBufferUpdateTime) < 0) {
+ pContext->mBufferUpdateTime.tv_sec = 0;
+ }
}
if (inBuffer->raw != outBuffer->raw) {
@@ -453,16 +459,25 @@
pContext->mCaptureSize);
// if audio framework has stopped playing audio although the effect is still
// active we must clear the capture buffer to return silence
- if (pContext->mLastBuf == pContext->mCurrentBuf) {
- if (pContext->mStallCount < MAX_STALL_COUNT) {
- if (++pContext->mStallCount == MAX_STALL_COUNT) {
+ if ((pContext->mLastBuf == pContext->mCurrentBuf) &&
+ (pContext->mBufferUpdateTime.tv_sec != 0)) {
+ struct timespec ts;
+ if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) {
+ time_t secs = ts.tv_sec - pContext->mBufferUpdateTime.tv_sec;
+ long nsec = ts.tv_nsec - pContext->mBufferUpdateTime.tv_nsec;
+ if (nsec < 0) {
+ --secs;
+ nsec += 1000000000;
+ }
+ uint32_t deltaMs = secs * 1000 + nsec / 1000000;
+ if (deltaMs > MAX_STALL_TIME_MS) {
+ ALOGV("capture going to idle");
+ pContext->mBufferUpdateTime.tv_sec = 0;
memset(pContext->mCaptureBuf[pContext->mCurrentBuf ^ 1],
0x80,
pContext->mCaptureSize);
}
}
- } else {
- pContext->mStallCount = 0;
}
pContext->mLastBuf = pContext->mCurrentBuf;
} else {
diff --git a/media/libmedia/Android.mk b/media/libmedia/Android.mk
index 43008d4..c8e1dc7 100644
--- a/media/libmedia/Android.mk
+++ b/media/libmedia/Android.mk
@@ -3,26 +3,50 @@
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
+ AudioParameter.cpp
+LOCAL_MODULE:= libmedia_helper
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+ AudioTrack.cpp \
+ IAudioFlinger.cpp \
+ IAudioFlingerClient.cpp \
+ IAudioTrack.cpp \
+ IAudioRecord.cpp \
+ ICrypto.cpp \
+ AudioRecord.cpp \
+ AudioSystem.cpp \
+ mediaplayer.cpp \
+ IMediaPlayerService.cpp \
+ IMediaPlayerClient.cpp \
+ IMediaRecorderClient.cpp \
+ IMediaPlayer.cpp \
+ IMediaRecorder.cpp \
+ IStreamSource.cpp \
+ Metadata.cpp \
+ mediarecorder.cpp \
+ IMediaMetadataRetriever.cpp \
+ mediametadataretriever.cpp \
+ ToneGenerator.cpp \
+ JetPlayer.cpp \
+ IOMX.cpp \
+ IAudioPolicyService.cpp \
+ MediaScanner.cpp \
+ MediaScannerClient.cpp \
autodetect.cpp \
IMediaDeathNotifier.cpp \
- IMediaMetadataRetriever.cpp \
- IMediaPlayerClient.cpp \
- IMediaPlayer.cpp \
- IMediaPlayerService.cpp \
- IMediaRecorderClient.cpp \
- IMediaRecorder.cpp \
- IOMX.cpp \
- IStreamSource.cpp \
- JetPlayer.cpp \
- mediametadataretriever.cpp \
- mediaplayer.cpp \
MediaProfiles.cpp \
- mediarecorder.cpp \
- MediaScannerClient.cpp \
- MediaScanner.cpp \
+ IEffect.cpp \
+ IEffectClient.cpp \
+ AudioEffect.cpp \
+ Visualizer.cpp \
MemoryLeakTrackUtil.cpp \
- Metadata.cpp \
- Visualizer.cpp
+ SoundPool.cpp \
+ SoundPoolThread.cpp
LOCAL_SHARED_LIBRARIES := \
libui libcutils libutils libbinder libsonivox libicuuc libexpat \
@@ -34,7 +58,6 @@
LOCAL_MODULE:= libmedia
LOCAL_C_INCLUDES := \
- $(JNI_H_INCLUDE) \
$(call include-path-for, graphics corecg) \
$(TOP)/frameworks/native/include/media/openmax \
external/icu4c/common \
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index 05ade75..70ec593 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -201,7 +201,7 @@
// create the IAudioRecord
status = openRecord_l(sampleRate, format, channelMask,
- frameCount, flags, input);
+ frameCount, input);
if (status != NO_ERROR) {
return status;
}
@@ -458,7 +458,6 @@
audio_format_t format,
uint32_t channelMask,
int frameCount,
- uint32_t flags,
audio_io_handle_t input)
{
status_t status;
@@ -471,7 +470,7 @@
sampleRate, format,
channelMask,
frameCount,
- ((uint16_t)flags) << 16,
+ IAudioFlinger::TRACK_DEFAULT,
&mSessionId,
&status);
@@ -778,7 +777,7 @@
// following member variables: mAudioRecord, mCblkMemory and mCblk.
// It will also delete the strong references on previous IAudioRecord and IMemory
result = openRecord_l(cblk->sampleRate, mFormat, mChannelMask,
- mFrameCount, mFlags, getInput_l());
+ mFrameCount, getInput_l());
if (result == NO_ERROR) {
result = mAudioRecord->start(0); // callback thread hasn't changed
}
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index 50fbf36..bafde3a 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -803,16 +803,19 @@
}
}
+ IAudioFlinger::track_flags_t trackFlags = IAudioFlinger::TRACK_DEFAULT;
+ if (mIsTimed) {
+ trackFlags |= IAudioFlinger::TRACK_TIMED;
+ }
sp<IAudioTrack> track = audioFlinger->createTrack(getpid(),
streamType,
sampleRate,
format,
channelMask,
frameCount,
- ((uint16_t)flags) << 16,
+ trackFlags,
sharedBuffer,
output,
- mIsTimed,
&mSessionId,
&status);
diff --git a/media/libmedia/IAudioFlinger.cpp b/media/libmedia/IAudioFlinger.cpp
index 07b12e4..ce10c8e 100644
--- a/media/libmedia/IAudioFlinger.cpp
+++ b/media/libmedia/IAudioFlinger.cpp
@@ -87,10 +87,9 @@
audio_format_t format,
uint32_t channelMask,
int frameCount,
- uint32_t flags,
+ track_flags_t flags,
const sp<IMemory>& sharedBuffer,
audio_io_handle_t output,
- bool isTimed,
int *sessionId,
status_t *status)
{
@@ -103,10 +102,9 @@
data.writeInt32(format);
data.writeInt32(channelMask);
data.writeInt32(frameCount);
- data.writeInt32(flags);
+ data.writeInt32((int32_t) flags);
data.writeStrongBinder(sharedBuffer->asBinder());
data.writeInt32((int32_t) output);
- data.writeInt32(isTimed);
int lSessionId = 0;
if (sessionId != NULL) {
lSessionId = *sessionId;
@@ -136,7 +134,7 @@
audio_format_t format,
uint32_t channelMask,
int frameCount,
- uint32_t flags,
+ track_flags_t flags,
int *sessionId,
status_t *status)
{
@@ -688,15 +686,14 @@
audio_format_t format = (audio_format_t) data.readInt32();
int channelCount = data.readInt32();
size_t bufferCount = data.readInt32();
- uint32_t flags = data.readInt32();
+ track_flags_t flags = (track_flags_t) data.readInt32();
sp<IMemory> buffer = interface_cast<IMemory>(data.readStrongBinder());
audio_io_handle_t output = (audio_io_handle_t) data.readInt32();
- bool isTimed = data.readInt32();
int sessionId = data.readInt32();
status_t status;
sp<IAudioTrack> track = createTrack(pid,
(audio_stream_type_t) streamType, sampleRate, format,
- channelCount, bufferCount, flags, buffer, output, isTimed, &sessionId, &status);
+ channelCount, bufferCount, flags, buffer, output, &sessionId, &status);
reply->writeInt32(sessionId);
reply->writeInt32(status);
reply->writeStrongBinder(track->asBinder());
@@ -710,7 +707,7 @@
audio_format_t format = (audio_format_t) data.readInt32();
int channelCount = data.readInt32();
size_t bufferCount = data.readInt32();
- uint32_t flags = data.readInt32();
+ track_flags_t flags = (track_flags_t) data.readInt32();
int sessionId = data.readInt32();
status_t status;
sp<IAudioRecord> record = openRecord(pid, input,
diff --git a/media/libmedia/ICrypto.cpp b/media/libmedia/ICrypto.cpp
new file mode 100644
index 0000000..827d7af
--- /dev/null
+++ b/media/libmedia/ICrypto.cpp
@@ -0,0 +1,293 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "ICrypto"
+#include <utils/Log.h>
+
+#include <binder/Parcel.h>
+#include <media/ICrypto.h>
+#include <media/stagefright/foundation/ADebug.h>
+
+namespace android {
+
+enum {
+ INITIALIZE = IBinder::FIRST_CALL_TRANSACTION,
+ TERMINATE,
+ SET_ENTITLEMENT_KEY,
+ SET_ECM,
+ DECRYPT_VIDEO,
+ DECRYPT_AUDIO,
+};
+
+struct BpCrypto : public BpInterface<ICrypto> {
+ BpCrypto(const sp<IBinder> &impl)
+ : BpInterface<ICrypto>(impl) {
+ }
+
+ virtual status_t initialize() {
+ Parcel data, reply;
+ data.writeInterfaceToken(ICrypto::getInterfaceDescriptor());
+ remote()->transact(INITIALIZE, data, &reply);
+
+ return reply.readInt32();
+ }
+
+ virtual status_t terminate() {
+ Parcel data, reply;
+ data.writeInterfaceToken(ICrypto::getInterfaceDescriptor());
+ remote()->transact(TERMINATE, data, &reply);
+
+ return reply.readInt32();
+ }
+
+ virtual status_t setEntitlementKey(
+ const void *key, size_t keyLength) {
+ Parcel data, reply;
+ data.writeInterfaceToken(ICrypto::getInterfaceDescriptor());
+ data.writeInt32(keyLength);
+ data.write(key, keyLength);
+ remote()->transact(SET_ENTITLEMENT_KEY, data, &reply);
+
+ return reply.readInt32();
+ }
+
+ virtual status_t setEntitlementControlMessage(
+ const void *msg, size_t msgLength) {
+ Parcel data, reply;
+ data.writeInterfaceToken(ICrypto::getInterfaceDescriptor());
+ data.writeInt32(msgLength);
+ data.write(msg, msgLength);
+ remote()->transact(SET_ECM, data, &reply);
+
+ return reply.readInt32();
+ }
+
+ virtual ssize_t decryptVideo(
+ const void *iv, size_t ivLength,
+ const void *srcData, size_t srcDataSize,
+ void *dstData, size_t dstDataOffset) {
+ Parcel data, reply;
+ data.writeInterfaceToken(ICrypto::getInterfaceDescriptor());
+ if (iv == NULL) {
+ if (ivLength > 0) {
+ return -EINVAL;
+ }
+
+ data.writeInt32(-1);
+ } else {
+ data.writeInt32(ivLength);
+ data.write(iv, ivLength);
+ }
+
+ data.writeInt32(srcDataSize);
+ data.write(srcData, srcDataSize);
+
+ data.writeIntPtr((intptr_t)dstData);
+ data.writeInt32(dstDataOffset);
+
+ remote()->transact(DECRYPT_VIDEO, data, &reply);
+
+ return reply.readInt32();
+ }
+
+ virtual ssize_t decryptAudio(
+ const void *iv, size_t ivLength,
+ const void *srcData, size_t srcDataSize,
+ void *dstData, size_t dstDataSize) {
+ Parcel data, reply;
+ data.writeInterfaceToken(ICrypto::getInterfaceDescriptor());
+ if (iv == NULL) {
+ if (ivLength > 0) {
+ return -EINVAL;
+ }
+
+ data.writeInt32(-1);
+ } else {
+ data.writeInt32(ivLength);
+ data.write(iv, ivLength);
+ }
+
+ data.writeInt32(srcDataSize);
+ data.write(srcData, srcDataSize);
+ data.writeInt32(dstDataSize);
+
+ remote()->transact(DECRYPT_AUDIO, data, &reply);
+
+ ssize_t res = reply.readInt32();
+
+ if (res <= 0) {
+ return res;
+ }
+
+ reply.read(dstData, res);
+
+ return res;
+ }
+
+private:
+ DISALLOW_EVIL_CONSTRUCTORS(BpCrypto);
+};
+
+IMPLEMENT_META_INTERFACE(Crypto, "android.hardware.ICrypto");
+
+////////////////////////////////////////////////////////////////////////////////
+
+status_t BnCrypto::onTransact(
+ uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
+ switch (code) {
+ case INITIALIZE:
+ {
+ CHECK_INTERFACE(ICrypto, data, reply);
+ reply->writeInt32(initialize());
+
+ return OK;
+ }
+
+ case TERMINATE:
+ {
+ CHECK_INTERFACE(ICrypto, data, reply);
+ reply->writeInt32(terminate());
+
+ return OK;
+ }
+
+ case SET_ENTITLEMENT_KEY:
+ {
+ CHECK_INTERFACE(ICrypto, data, reply);
+
+ size_t keyLength = data.readInt32();
+ void *key = malloc(keyLength);
+ data.read(key, keyLength);
+
+ reply->writeInt32(setEntitlementKey(key, keyLength));
+
+ free(key);
+ key = NULL;
+
+ return OK;
+ }
+
+ case SET_ECM:
+ {
+ CHECK_INTERFACE(ICrypto, data, reply);
+
+ size_t msgLength = data.readInt32();
+ void *msg = malloc(msgLength);
+ data.read(msg, msgLength);
+
+ reply->writeInt32(setEntitlementControlMessage(msg, msgLength));
+
+ free(msg);
+ msg = NULL;
+
+ return OK;
+ }
+
+ case DECRYPT_VIDEO:
+ {
+ CHECK_INTERFACE(ICrypto, data, reply);
+
+ void *iv = NULL;
+
+ int32_t ivLength = data.readInt32();
+ if (ivLength >= 0) {
+ iv = malloc(ivLength);
+ data.read(iv, ivLength);
+ }
+
+ size_t srcDataSize = data.readInt32();
+ void *srcData = malloc(srcDataSize);
+ data.read(srcData, srcDataSize);
+
+ void *dstData = (void *)data.readIntPtr();
+ size_t dstDataOffset = data.readInt32();
+
+ reply->writeInt32(
+ decryptVideo(
+ iv,
+ ivLength < 0 ? 0 : ivLength,
+ srcData,
+ srcDataSize,
+ dstData,
+ dstDataOffset));
+
+ free(srcData);
+ srcData = NULL;
+
+ if (iv != NULL) {
+ free(iv);
+ iv = NULL;
+ }
+
+ return OK;
+ }
+
+ case DECRYPT_AUDIO:
+ {
+ CHECK_INTERFACE(ICrypto, data, reply);
+
+ void *iv = NULL;
+
+ int32_t ivLength = data.readInt32();
+ if (ivLength >= 0) {
+ iv = malloc(ivLength);
+ data.read(iv, ivLength);
+ }
+
+ size_t srcDataSize = data.readInt32();
+ void *srcData = malloc(srcDataSize);
+ data.read(srcData, srcDataSize);
+
+ size_t dstDataSize = data.readInt32();
+ void *dstData = malloc(dstDataSize);
+
+ ssize_t res =
+ decryptAudio(
+ iv,
+ ivLength < 0 ? 0 : ivLength,
+ srcData,
+ srcDataSize,
+ dstData,
+ dstDataSize);
+
+ reply->writeInt32(res);
+
+ if (res > 0) {
+ reply->write(dstData, res);
+ }
+
+ free(dstData);
+ dstData = NULL;
+
+ free(srcData);
+ srcData = NULL;
+
+ if (iv != NULL) {
+ free(iv);
+ iv = NULL;
+ }
+
+ return OK;
+ }
+
+ default:
+ return BBinder::onTransact(code, data, reply, flags);
+ }
+}
+
+} // namespace android
+
diff --git a/media/libmedia/IMediaMetadataRetriever.cpp b/media/libmedia/IMediaMetadataRetriever.cpp
index 9b8d7c3..7e6d54b 100644
--- a/media/libmedia/IMediaMetadataRetriever.cpp
+++ b/media/libmedia/IMediaMetadataRetriever.cpp
@@ -18,7 +18,6 @@
#include <stdint.h>
#include <sys/types.h>
#include <binder/Parcel.h>
-#include <SkBitmap.h>
#include <media/IMediaMetadataRetriever.h>
#include <utils/String8.h>
diff --git a/media/libmedia/IMediaPlayerService.cpp b/media/libmedia/IMediaPlayerService.cpp
index f5fccef..9120617 100644
--- a/media/libmedia/IMediaPlayerService.cpp
+++ b/media/libmedia/IMediaPlayerService.cpp
@@ -20,6 +20,7 @@
#include <binder/Parcel.h>
#include <binder/IMemory.h>
+#include <media/ICrypto.h>
#include <media/IMediaPlayerService.h>
#include <media/IMediaRecorder.h>
#include <media/IOMX.h>
@@ -36,6 +37,7 @@
CREATE_MEDIA_RECORDER,
CREATE_METADATA_RETRIEVER,
GET_OMX,
+ MAKE_CRYPTO,
ADD_BATTERY_DATA,
PULL_BATTERY_DATA
};
@@ -111,6 +113,13 @@
return interface_cast<IOMX>(reply.readStrongBinder());
}
+ virtual sp<ICrypto> makeCrypto() {
+ Parcel data, reply;
+ data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
+ remote()->transact(MAKE_CRYPTO, data, &reply);
+ return interface_cast<ICrypto>(reply.readStrongBinder());
+ }
+
virtual void addBatteryData(uint32_t params) {
Parcel data, reply;
data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
@@ -191,6 +200,12 @@
reply->writeStrongBinder(omx->asBinder());
return NO_ERROR;
} break;
+ case MAKE_CRYPTO: {
+ CHECK_INTERFACE(IMediaPlayerService, data, reply);
+ sp<ICrypto> crypto = makeCrypto();
+ reply->writeStrongBinder(crypto->asBinder());
+ return NO_ERROR;
+ } break;
case ADD_BATTERY_DATA: {
CHECK_INTERFACE(IMediaPlayerService, data, reply);
uint32_t params = data.readInt32();
diff --git a/media/libmedia/JetPlayer.cpp b/media/libmedia/JetPlayer.cpp
index 7fa6bb7..52aee49 100644
--- a/media/libmedia/JetPlayer.cpp
+++ b/media/libmedia/JetPlayer.cpp
@@ -30,7 +30,7 @@
static const S_EAS_LIB_CONFIG* pLibConfig = NULL;
//-------------------------------------------------------------------------------------------------
-JetPlayer::JetPlayer(jobject javaJetPlayer, int maxTracks, int trackBufferSize) :
+JetPlayer::JetPlayer(void *javaJetPlayer, int maxTracks, int trackBufferSize) :
mEventCallback(NULL),
mJavaJetPlayerRef(javaJetPlayer),
mTid(-1),
diff --git a/media/jni/soundpool/SoundPool.cpp b/media/libmedia/SoundPool.cpp
similarity index 99%
rename from media/jni/soundpool/SoundPool.cpp
rename to media/libmedia/SoundPool.cpp
index 5aed8a1..306c57d 100644
--- a/media/jni/soundpool/SoundPool.cpp
+++ b/media/libmedia/SoundPool.cpp
@@ -685,7 +685,7 @@
void SoundChannel::callback(int event, void* user, void *info)
{
SoundChannel* channel = static_cast<SoundChannel*>((void *)((unsigned long)user & ~1));
-
+
channel->process(event, info, (unsigned long)user & 1);
}
diff --git a/media/jni/soundpool/SoundPool.h b/media/libmedia/SoundPool.h
similarity index 100%
rename from media/jni/soundpool/SoundPool.h
rename to media/libmedia/SoundPool.h
diff --git a/media/jni/soundpool/SoundPoolThread.cpp b/media/libmedia/SoundPoolThread.cpp
similarity index 100%
rename from media/jni/soundpool/SoundPoolThread.cpp
rename to media/libmedia/SoundPoolThread.cpp
diff --git a/media/jni/soundpool/SoundPoolThread.h b/media/libmedia/SoundPoolThread.h
similarity index 100%
rename from media/jni/soundpool/SoundPoolThread.h
rename to media/libmedia/SoundPoolThread.h
diff --git a/media/libmedia_native/Android.mk b/media/libmedia_native/Android.mk
index 07f0978..065a90f 100644
--- a/media/libmedia_native/Android.mk
+++ b/media/libmedia_native/Android.mk
@@ -1,39 +1,11 @@
-# FIXME remove "/../libmedia" at same time as rename
-LOCAL_PATH := $(call my-dir)/../libmedia
+LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
-LOCAL_SRC_FILES:= \
- AudioParameter.cpp
-LOCAL_MODULE:= libmedia_helper
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_STATIC_LIBRARY)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := \
- AudioEffect.cpp \
- AudioRecord.cpp \
- AudioSystem.cpp \
- AudioTrack.cpp \
- IAudioFlingerClient.cpp \
- IAudioFlinger.cpp \
- IAudioPolicyService.cpp \
- IAudioRecord.cpp \
- IAudioTrack.cpp \
- IEffectClient.cpp \
- IEffect.cpp \
- ToneGenerator.cpp
-
-LOCAL_SHARED_LIBRARIES := \
- libaudioutils libbinder libcutils libutils
+LOCAL_SRC_FILES :=
LOCAL_MODULE:= libmedia_native
-LOCAL_C_INCLUDES := \
- $(call include-path-for, audio-utils)
-
LOCAL_MODULE_TAGS := optional
include $(BUILD_SHARED_LIBRARY)
diff --git a/media/libmediaplayerservice/Android.mk b/media/libmediaplayerservice/Android.mk
index ba5c776..675c563 100644
--- a/media/libmediaplayerservice/Android.mk
+++ b/media/libmediaplayerservice/Android.mk
@@ -7,6 +7,7 @@
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
+ Crypto.cpp \
MediaRecorderClient.cpp \
MediaPlayerService.cpp \
MetadataRetrieverClient.cpp \
@@ -38,12 +39,11 @@
libstagefright_rtsp \
LOCAL_C_INCLUDES := \
- $(JNI_H_INCLUDE) \
$(call include-path-for, graphics corecg) \
$(TOP)/frameworks/base/media/libstagefright/include \
$(TOP)/frameworks/base/media/libstagefright/rtsp \
$(TOP)/frameworks/native/include/media/openmax \
- $(TOP)/external/tremolo/Tremolo
+ $(TOP)/external/tremolo/Tremolo \
LOCAL_MODULE:= libmediaplayerservice
diff --git a/media/libmediaplayerservice/Crypto.cpp b/media/libmediaplayerservice/Crypto.cpp
new file mode 100644
index 0000000..e02035f
--- /dev/null
+++ b/media/libmediaplayerservice/Crypto.cpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "Crypto"
+#include <utils/Log.h>
+
+#include "Crypto.h"
+
+#include <media/stagefright/MediaErrors.h>
+
+namespace android {
+
+Crypto::Crypto() {
+}
+
+Crypto::~Crypto() {
+}
+
+status_t Crypto::initialize() {
+ return ERROR_UNSUPPORTED;
+}
+
+status_t Crypto::terminate() {
+ return ERROR_UNSUPPORTED;
+}
+
+status_t Crypto::setEntitlementKey(
+ const void *key, size_t keyLength) {
+ return ERROR_UNSUPPORTED;
+}
+
+status_t Crypto::setEntitlementControlMessage(
+ const void *msg, size_t msgLength) {
+ return ERROR_UNSUPPORTED;
+}
+
+ssize_t Crypto::decryptVideo(
+ const void *iv, size_t ivLength,
+ const void *srcData, size_t srcDataSize,
+ void *dstData, size_t dstDataOffset) {
+ return ERROR_UNSUPPORTED;
+}
+
+ssize_t Crypto::decryptAudio(
+ const void *iv, size_t ivLength,
+ const void *srcData, size_t srcDataSize,
+ void *dstData, size_t dstDataSize) {
+ return ERROR_UNSUPPORTED;
+}
+
+} // namespace android
diff --git a/media/libmediaplayerservice/Crypto.h b/media/libmediaplayerservice/Crypto.h
new file mode 100644
index 0000000..9855496
--- /dev/null
+++ b/media/libmediaplayerservice/Crypto.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef CRYPTO_H_
+
+#define CRYPTO_H_
+
+#include <media/ICrypto.h>
+#include <utils/threads.h>
+
+namespace android {
+
+struct Crypto : public BnCrypto {
+ Crypto();
+
+ virtual status_t initialize();
+ virtual status_t terminate();
+
+ virtual status_t setEntitlementKey(
+ const void *key, size_t keyLength);
+
+ virtual status_t setEntitlementControlMessage(
+ const void *msg, size_t msgLength);
+
+ virtual ssize_t decryptVideo(
+ const void *iv, size_t ivLength,
+ const void *srcData, size_t srcDataSize,
+ void *dstData, size_t dstDataOffset);
+
+ virtual ssize_t decryptAudio(
+ const void *iv, size_t ivLength,
+ const void *srcData, size_t srcDataSize,
+ void *dstData, size_t dstDataSize);
+
+protected:
+ virtual ~Crypto();
+
+private:
+ DISALLOW_EVIL_CONSTRUCTORS(Crypto);
+};
+
+} // namespace android
+
+#endif // CRYPTO_H_
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 840e475..123d07ff 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -70,6 +70,8 @@
#include <OMX.h>
+#include "Crypto.h"
+
namespace android {
sp<MediaPlayerBase> createAAH_TXPlayer();
sp<MediaPlayerBase> createAAH_RXPlayer();
@@ -292,6 +294,16 @@
return mOMX;
}
+sp<ICrypto> MediaPlayerService::makeCrypto() {
+ Mutex::Autolock autoLock(mLock);
+
+ if (mCrypto == NULL) {
+ mCrypto = new Crypto;
+ }
+
+ return mCrypto;
+}
+
status_t MediaPlayerService::AudioCache::dump(int fd, const Vector<String16>& args) const
{
const size_t SIZE = 256;
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index d4e0eb1..b08dd6c 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -240,6 +240,7 @@
virtual sp<IMemory> decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, audio_format_t* pFormat);
virtual sp<IMemory> decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, audio_format_t* pFormat);
virtual sp<IOMX> getOMX();
+ virtual sp<ICrypto> makeCrypto();
virtual status_t dump(int fd, const Vector<String16>& args);
@@ -419,6 +420,7 @@
SortedVector< wp<MediaRecorderClient> > mMediaRecorderClients;
int32_t mNextConnId;
sp<IOMX> mOMX;
+ sp<ICrypto> mCrypto;
};
// ----------------------------------------------------------------------------
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
index 1600141..5733229 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
@@ -125,6 +125,11 @@
msg->setInt32("channel-count", numChannels);
msg->setInt32("sample-rate", sampleRate);
+
+ int32_t isADTS;
+ if (meta->findInt32(kKeyIsADTS, &isADTS) && isADTS != 0) {
+ msg->setInt32("is-adts", true);
+ }
}
int32_t maxInputSize;
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index e5ad4b7..db2beda 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -427,24 +427,34 @@
sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
CHECK(mem.get() != NULL);
- IOMX::buffer_id buffer;
+ BufferInfo info;
+ info.mStatus = BufferInfo::OWNED_BY_US;
uint32_t requiresAllocateBufferBit =
(portIndex == kPortIndexInput)
? OMXCodec::kRequiresAllocateBufferOnInputPorts
: OMXCodec::kRequiresAllocateBufferOnOutputPorts;
- if (mQuirks & requiresAllocateBufferBit) {
+ if (portIndex == kPortIndexInput && (mFlags & kFlagIsSecure)) {
+ mem.clear();
+
+ void *ptr;
+ err = mOMX->allocateBuffer(
+ mNode, portIndex, def.nBufferSize, &info.mBufferID,
+ &ptr);
+
+ info.mData = new ABuffer(ptr, def.nBufferSize);
+ } else if (mQuirks & requiresAllocateBufferBit) {
err = mOMX->allocateBufferWithBackup(
- mNode, portIndex, mem, &buffer);
+ mNode, portIndex, mem, &info.mBufferID);
} else {
- err = mOMX->useBuffer(mNode, portIndex, mem, &buffer);
+ err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID);
}
- BufferInfo info;
- info.mBufferID = buffer;
- info.mStatus = BufferInfo::OWNED_BY_US;
- info.mData = new ABuffer(mem->pointer(), def.nBufferSize);
+ if (mem != NULL) {
+ info.mData = new ABuffer(mem->pointer(), def.nBufferSize);
+ }
+
mBuffers[portIndex].push(info);
}
}
@@ -840,7 +850,13 @@
|| !msg->findInt32("sample-rate", &sampleRate)) {
err = INVALID_OPERATION;
} else {
- err = setupAACCodec(encoder, numChannels, sampleRate, bitRate);
+ int32_t isADTS;
+ if (!msg->findInt32("is-adts", &isADTS)) {
+ isADTS = 0;
+ }
+
+ err = setupAACCodec(
+ encoder, numChannels, sampleRate, bitRate, isADTS != 0);
}
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
@@ -934,7 +950,11 @@
status_t ACodec::setupAACCodec(
bool encoder,
- int32_t numChannels, int32_t sampleRate, int32_t bitRate) {
+ int32_t numChannels, int32_t sampleRate, int32_t bitRate, bool isADTS) {
+ if (encoder && isADTS) {
+ return -EINVAL;
+ }
+
status_t err = setupRawAudioFormat(
encoder ? kPortIndexInput : kPortIndexOutput,
sampleRate,
@@ -1021,7 +1041,11 @@
profile.nChannels = numChannels;
profile.nSampleRate = sampleRate;
- profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4ADTS;
+
+ profile.eAACStreamFormat =
+ isADTS
+ ? OMX_AUDIO_AACStreamFormatMP4ADTS
+ : OMX_AUDIO_AACStreamFormatMP4FF;
return mOMX->setParameter(
mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
@@ -2653,6 +2677,12 @@
observer->setNotificationMessage(notify);
mCodec->mComponentName = componentName;
+ mCodec->mFlags = 0;
+
+ if (componentName.endsWith(".secure")) {
+ mCodec->mFlags |= kFlagIsSecure;
+ }
+
mCodec->mQuirks = quirks;
mCodec->mOMX = omx;
mCodec->mNode = node;
@@ -2701,6 +2731,7 @@
mCodec->mNode = NULL;
mCodec->mOMX.clear();
mCodec->mQuirks = 0;
+ mCodec->mFlags = 0;
mCodec->mComponentName.clear();
mCodec->changeState(mCodec->mUninitializedState);
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index 7d7bd7d..8948abb 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -57,7 +57,6 @@
avc_utils.cpp \
LOCAL_C_INCLUDES:= \
- $(JNI_H_INCLUDE) \
$(TOP)/frameworks/base/include/media/stagefright/timedtext \
$(TOP)/frameworks/native/include/media/hardware \
$(TOP)/frameworks/native/include/media/openmax \
@@ -69,7 +68,6 @@
LOCAL_SHARED_LIBRARIES := \
libbinder \
libcamera_client \
- libchromium_net \
libcrypto \
libcutils \
libdl \
@@ -102,14 +100,18 @@
libstagefright_httplive \
libstagefright_id3 \
libFLAC \
- libstagefright_chromium_http \
+
+ifneq ($(TARGET_BUILD_PDK), true)
+LOCAL_STATIC_LIBRARIES += \
+ libstagefright_chromium_http
+LOCAL_SHARED_LIBRARIES += \
+ libchromium_net
+LOCAL_CPPFLAGS += -DCHROMIUM_AVAILABLE=1
+endif
LOCAL_SHARED_LIBRARIES += libstlport
include external/stlport/libstlport.mk
-# TODO: Chromium is always available, so this flag can be removed.
-LOCAL_CPPFLAGS += -DCHROMIUM_AVAILABLE=1
-
LOCAL_SHARED_LIBRARIES += \
libstagefright_enc_common \
libstagefright_avc_common \
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index a9e7f360..42b5c7e 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -22,10 +22,14 @@
#include "include/SoftwareRenderer.h"
+#include <binder/IServiceManager.h>
#include <gui/SurfaceTextureClient.h>
+#include <media/ICrypto.h>
+#include <media/IMediaPlayerService.h>
#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AMessage.h>
+#include <media/stagefright/foundation/hexdump.h>
#include <media/stagefright/ACodec.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/MetaData.h>
@@ -528,6 +532,12 @@
info.mOwnedByClient = false;
CHECK(msg->findBuffer(name.c_str(), &info.mData));
+ if (portIndex == kPortIndexInput
+ && (mFlags & kFlagIsSecure)) {
+ info.mEncryptedData =
+ new ABuffer(info.mData->capacity());
+ }
+
buffers->push_back(info);
}
@@ -742,6 +752,59 @@
format->setInt32("encoder", true);
}
+ if (flags & CONFIGURE_FLAG_SECURE) {
+ mFlags |= kFlagIsSecure;
+
+ sp<IServiceManager> sm = defaultServiceManager();
+
+ sp<IBinder> binder =
+ sm->getService(String16("media.player"));
+
+ sp<IMediaPlayerService> service =
+ interface_cast<IMediaPlayerService>(binder);
+
+ CHECK(service != NULL);
+
+ mCrypto = service->makeCrypto();
+
+ status_t err = mCrypto->initialize();
+
+ if (err == OK) {
+ sp<ABuffer> emm;
+ if (format->findBuffer("emm", &emm)) {
+ err = mCrypto->setEntitlementKey(
+ emm->data(), emm->size());
+ }
+ }
+
+ if (err == OK) {
+ sp<ABuffer> ecm;
+ if (format->findBuffer("ecm", &ecm)) {
+ CHECK_EQ(ecm->size(), 80u);
+
+ // bytes 16..47 of the original ecm stream data.
+ err = mCrypto->setEntitlementControlMessage(
+ ecm->data() + 16, 32);
+ }
+ }
+
+ if (err != OK) {
+ ALOGE("failed to instantiate crypto service.");
+
+ mCrypto.clear();
+
+ setState(INITIALIZED);
+
+ sp<AMessage> response = new AMessage;
+ response->setInt32("err", UNKNOWN_ERROR);
+
+ response->postReply(mReplyID);
+ break;
+ }
+ } else {
+ mFlags &= ~kFlagIsSecure;
+ }
+
mCodec->initiateConfigureComponent(format);
break;
}
@@ -983,7 +1046,10 @@
for (size_t i = 0; i < srcBuffers.size(); ++i) {
const BufferInfo &info = srcBuffers.itemAt(i);
- dstBuffers->push_back(info.mData);
+ dstBuffers->push_back(
+ (portIndex == kPortIndexInput
+ && (mFlags & kFlagIsSecure))
+ ? info.mEncryptedData : info.mData);
}
(new AMessage)->postReply(replyID);
@@ -1037,10 +1103,15 @@
}
void MediaCodec::setState(State newState) {
- if (newState == UNINITIALIZED) {
+ if (newState == INITIALIZED) {
delete mSoftRenderer;
mSoftRenderer = NULL;
+ if (mCrypto != NULL) {
+ mCrypto->terminate();
+ mCrypto.clear();
+ }
+
mNativeWindow.clear();
mOutputFormat.clear();
@@ -1150,6 +1221,43 @@
info->mData->meta()->setInt32("csd", true);
}
+ if (mFlags & kFlagIsSecure) {
+ uint8_t iv[16];
+ memset(iv, 0, sizeof(iv));
+
+ ssize_t outLength;
+
+ if (mFlags & kFlagIsSoftwareCodec) {
+ outLength = mCrypto->decryptAudio(
+ (flags & BUFFER_FLAG_ENCRYPTED) ? iv : NULL,
+ (flags & BUFFER_FLAG_ENCRYPTED) ? sizeof(iv) : 0,
+ info->mEncryptedData->base() + offset,
+ size,
+ info->mData->base(),
+ info->mData->capacity());
+ } else {
+ outLength = mCrypto->decryptVideo(
+ (flags & BUFFER_FLAG_ENCRYPTED) ? iv : NULL,
+ (flags & BUFFER_FLAG_ENCRYPTED) ? sizeof(iv) : 0,
+ info->mEncryptedData->base() + offset,
+ size,
+ info->mData->base(),
+ 0 /* offset */);
+ }
+
+ if (outLength < 0) {
+ return outLength;
+ }
+
+ if ((size_t)outLength > info->mEncryptedData->capacity()) {
+ return -ERANGE;
+ }
+
+ info->mData->setRange(0, outLength);
+ } else if (flags & BUFFER_FLAG_ENCRYPTED) {
+ return -EINVAL;
+ }
+
reply->setBuffer("buffer", info->mData);
reply->post();
diff --git a/media/libstagefright/NuMediaExtractor.cpp b/media/libstagefright/NuMediaExtractor.cpp
index afd4763..224ec33 100644
--- a/media/libstagefright/NuMediaExtractor.cpp
+++ b/media/libstagefright/NuMediaExtractor.cpp
@@ -107,6 +107,11 @@
msg->setInt32("channel-count", numChannels);
msg->setInt32("sample-rate", sampleRate);
+
+ int32_t isADTS;
+ if (meta->findInt32(kKeyIsADTS, &isADTS)) {
+ msg->setInt32("is-adts", true);
+ }
}
int32_t maxInputSize;
@@ -232,6 +237,20 @@
msg->setBuffer("csd-1", buffer);
}
+ if (meta->findData(kKeyEMM, &type, &data, &size)) {
+ sp<ABuffer> emm = new ABuffer(size);
+ memcpy(emm->data(), data, size);
+
+ msg->setBuffer("emm", emm);
+ }
+
+ if (meta->findData(kKeyECM, &type, &data, &size)) {
+ sp<ABuffer> ecm = new ABuffer(size);
+ memcpy(ecm->data(), data, size);
+
+ msg->setBuffer("ecm", ecm);
+ }
+
*format = msg;
return OK;
@@ -267,13 +286,14 @@
info->mFinalResult = OK;
info->mSample = NULL;
info->mSampleTimeUs = -1ll;
- info->mFlags = 0;
+ info->mSampleFlags = 0;
+ info->mTrackFlags = 0;
const char *mime;
CHECK(source->getFormat()->findCString(kKeyMIMEType, &mime));
if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_VORBIS)) {
- info->mFlags |= kIsVorbis;
+ info->mTrackFlags |= kIsVorbis;
}
return OK;
@@ -288,6 +308,7 @@
info->mSample = NULL;
info->mSampleTimeUs = -1ll;
+ info->mSampleFlags = 0;
}
}
}
@@ -306,6 +327,7 @@
info->mSample->release();
info->mSample = NULL;
info->mSampleTimeUs = -1ll;
+ info->mSampleFlags = 0;
}
} else if (info->mFinalResult != OK) {
continue;
@@ -323,11 +345,25 @@
info->mFinalResult = err;
info->mSampleTimeUs = -1ll;
+ info->mSampleFlags = 0;
continue;
} else {
CHECK(info->mSample != NULL);
CHECK(info->mSample->meta_data()->findInt64(
kKeyTime, &info->mSampleTimeUs));
+
+ info->mSampleFlags = 0;
+
+ int32_t val;
+ if (info->mSample->meta_data()->findInt32(
+ kKeyIsSyncFrame, &val) && val != 0) {
+ info->mSampleFlags |= SAMPLE_FLAG_SYNC;
+ }
+
+ if (info->mSample->meta_data()->findInt32(
+ kKeyScrambling, &val) && val != 0) {
+ info->mSampleFlags |= SAMPLE_FLAG_ENCRYPTED;
+ }
}
}
@@ -371,7 +407,7 @@
size_t sampleSize = info->mSample->range_length();
- if (info->mFlags & kIsVorbis) {
+ if (info->mTrackFlags & kIsVorbis) {
// Each sample's data is suffixed by the number of page samples
// or -1 if not available.
sampleSize += sizeof(int32_t);
@@ -387,7 +423,7 @@
memcpy((uint8_t *)buffer->data(), src, info->mSample->range_length());
- if (info->mFlags & kIsVorbis) {
+ if (info->mTrackFlags & kIsVorbis) {
int32_t numPageSamples;
if (!info->mSample->meta_data()->findInt32(
kKeyValidSamples, &numPageSamples)) {
@@ -430,4 +466,17 @@
return OK;
}
+status_t NuMediaExtractor::getSampleFlags(uint32_t *sampleFlags) {
+ ssize_t minIndex = fetchTrackSamples();
+
+ if (minIndex < 0) {
+ return ERROR_END_OF_STREAM;
+ }
+
+ TrackInfo *info = &mSelectedTracks.editItemAt(minIndex);
+ *sampleFlags = info->mSampleFlags;
+
+ return OK;
+}
+
} // namespace android
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 8b6e9d5..9769f21 100755
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -515,7 +515,12 @@
CHECK(meta->findInt32(kKeyChannelCount, &numChannels));
CHECK(meta->findInt32(kKeySampleRate, &sampleRate));
- status_t err = setAACFormat(numChannels, sampleRate, bitRate);
+ int32_t isADTS;
+ if (!meta->findInt32(kKeyIsADTS, &isADTS)) {
+ isADTS = false;
+ }
+
+ status_t err = setAACFormat(numChannels, sampleRate, bitRate, isADTS);
if (err != OK) {
CODEC_LOGE("setAACFormat() failed (err = %d)", err);
return err;
@@ -3386,11 +3391,17 @@
}
}
-status_t OMXCodec::setAACFormat(int32_t numChannels, int32_t sampleRate, int32_t bitRate) {
- if (numChannels > 2)
+status_t OMXCodec::setAACFormat(
+ int32_t numChannels, int32_t sampleRate, int32_t bitRate, bool isADTS) {
+ if (numChannels > 2) {
ALOGW("Number of channels: (%d) \n", numChannels);
+ }
if (mIsEncoder) {
+ if (isADTS) {
+ return -EINVAL;
+ }
+
//////////////// input port ////////////////////
setRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
@@ -3445,7 +3456,9 @@
&profile, sizeof(profile));
if (err != OK) {
- CODEC_LOGE("setParameter('OMX_IndexParamAudioAac') failed (err = %d)", err);
+ CODEC_LOGE("setParameter('OMX_IndexParamAudioAac') failed "
+ "(err = %d)",
+ err);
return err;
}
} else {
@@ -3459,13 +3472,19 @@
profile.nChannels = numChannels;
profile.nSampleRate = sampleRate;
- profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4ADTS;
+
+ profile.eAACStreamFormat =
+ isADTS
+ ? OMX_AUDIO_AACStreamFormatMP4ADTS
+ : OMX_AUDIO_AACStreamFormatMP4FF;
err = mOMX->setParameter(
mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
if (err != OK) {
- CODEC_LOGE("setParameter('OMX_IndexParamAudioAac') failed (err = %d)", err);
+ CODEC_LOGE("setParameter('OMX_IndexParamAudioAac') failed "
+ "(err = %d)",
+ err);
return err;
}
}
diff --git a/media/libstagefright/TimedEventQueue.cpp b/media/libstagefright/TimedEventQueue.cpp
index 6d345bb..9df15eb 100644
--- a/media/libstagefright/TimedEventQueue.cpp
+++ b/media/libstagefright/TimedEventQueue.cpp
@@ -31,10 +31,6 @@
#include <media/stagefright/foundation/ADebug.h>
-#ifdef ANDROID_SIMULATOR
-#include <jni.h>
-#endif
-
namespace android {
TimedEventQueue::TimedEventQueue()
@@ -193,27 +189,10 @@
// static
void *TimedEventQueue::ThreadWrapper(void *me) {
-#ifdef ANDROID_SIMULATOR
- // The simulator runs everything as one process, so any
- // Binder calls happen on this thread instead of a thread
- // in another process. We therefore need to make sure that
- // this thread can do calls into interpreted code.
- // On the device this is not an issue because the remote
- // thread will already be set up correctly for this.
- JavaVM *vm;
- int numvms;
- JNI_GetCreatedJavaVMs(&vm, 1, &numvms);
- JNIEnv *env;
- vm->AttachCurrentThread(&env, NULL);
-#endif
-
androidSetThreadPriority(0, ANDROID_PRIORITY_FOREGROUND);
static_cast<TimedEventQueue *>(me)->threadEntry();
-#ifdef ANDROID_SIMULATOR
- vm->DetachCurrentThread();
-#endif
return NULL;
}
diff --git a/media/libstagefright/chromium_http/Android.mk b/media/libstagefright/chromium_http/Android.mk
index e37b4a8..d595686 100644
--- a/media/libstagefright/chromium_http/Android.mk
+++ b/media/libstagefright/chromium_http/Android.mk
@@ -1,5 +1,6 @@
LOCAL_PATH:= $(call my-dir)
+ifneq ($(TARGET_BUILD_PDK), true)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
@@ -8,7 +9,6 @@
support.cpp
LOCAL_C_INCLUDES:= \
- $(JNI_H_INCLUDE) \
frameworks/base/media/libstagefright \
$(TOP)/frameworks/native/include/media/openmax \
external/chromium \
@@ -22,3 +22,4 @@
LOCAL_MODULE:= libstagefright_chromium_http
include $(BUILD_STATIC_LIBRARY)
+endif
diff --git a/media/libstagefright/codecs/aacdec/SoftAAC.cpp b/media/libstagefright/codecs/aacdec/SoftAAC.cpp
index ea6c360..90f96c6 100644
--- a/media/libstagefright/codecs/aacdec/SoftAAC.cpp
+++ b/media/libstagefright/codecs/aacdec/SoftAAC.cpp
@@ -23,6 +23,7 @@
#include "pvmp4audiodecoder_api.h"
#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/hexdump.h>
namespace android {
@@ -42,6 +43,7 @@
OMX_COMPONENTTYPE **component)
: SimpleSoftOMXComponent(name, callbacks, appData, component),
mConfig(new tPVMP4AudioDecoderExternal),
+ mIsADTS(false),
mDecoderBuf(NULL),
mInputBufferCount(0),
mUpsamplingFactor(2),
@@ -140,7 +142,12 @@
aacParams->nAACtools = 0;
aacParams->nAACERtools = 0;
aacParams->eAACProfile = OMX_AUDIO_AACObjectMain;
- aacParams->eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
+
+ aacParams->eAACStreamFormat =
+ mIsADTS
+ ? OMX_AUDIO_AACStreamFormatMP4ADTS
+ : OMX_AUDIO_AACStreamFormatMP4FF;
+
aacParams->eChannelMode = OMX_AUDIO_ChannelModeStereo;
if (!isConfigured()) {
@@ -215,6 +222,15 @@
return OMX_ErrorUndefined;
}
+ if (aacParams->eAACStreamFormat == OMX_AUDIO_AACStreamFormatMP4FF) {
+ mIsADTS = false;
+ } else if (aacParams->eAACStreamFormat
+ == OMX_AUDIO_AACStreamFormatMP4ADTS) {
+ mIsADTS = true;
+ } else {
+ return OMX_ErrorUndefined;
+ }
+
return OMX_ErrorNone;
}
@@ -299,8 +315,35 @@
mNumSamplesOutput = 0;
}
- mConfig->pInputBuffer = inHeader->pBuffer + inHeader->nOffset;
- mConfig->inputBufferCurrentLength = inHeader->nFilledLen;
+ if (mIsADTS) {
+ // skip 30 bits, aac_frame_length follows.
+ // ssssssss ssssiiip ppffffPc ccohCCll llllllll lll?????
+
+ const uint8_t *adtsHeader = inHeader->pBuffer + inHeader->nOffset;
+
+ CHECK_GE(inHeader->nFilledLen, 7);
+
+ bool protectionAbsent = (adtsHeader[1] & 1);
+
+ unsigned aac_frame_length =
+ ((adtsHeader[3] & 3) << 11)
+ | (adtsHeader[4] << 3)
+ | (adtsHeader[5] >> 5);
+
+ CHECK_GE(inHeader->nFilledLen, aac_frame_length);
+
+ size_t headerSize = (protectionAbsent ? 7 : 9);
+
+ mConfig->pInputBuffer = (UChar *)adtsHeader + headerSize;
+ mConfig->inputBufferCurrentLength = aac_frame_length - headerSize;
+
+ inHeader->nOffset += headerSize;
+ inHeader->nFilledLen -= headerSize;
+ } else {
+ mConfig->pInputBuffer = inHeader->pBuffer + inHeader->nOffset;
+ mConfig->inputBufferCurrentLength = inHeader->nFilledLen;
+ }
+
mConfig->inputBufferMaxLength = 0;
mConfig->inputBufferUsedLength = 0;
mConfig->remainderBits = 0;
diff --git a/media/libstagefright/codecs/aacdec/SoftAAC.h b/media/libstagefright/codecs/aacdec/SoftAAC.h
index 963fd27..da0b8ed 100644
--- a/media/libstagefright/codecs/aacdec/SoftAAC.h
+++ b/media/libstagefright/codecs/aacdec/SoftAAC.h
@@ -49,6 +49,7 @@
};
tPVMP4AudioDecoderExternal *mConfig;
+ bool mIsADTS;
void *mDecoderBuf;
size_t mInputBufferCount;
diff --git a/media/libstagefright/foundation/AString.cpp b/media/libstagefright/foundation/AString.cpp
index 61b76cf..dee786d 100644
--- a/media/libstagefright/foundation/AString.cpp
+++ b/media/libstagefright/foundation/AString.cpp
@@ -310,6 +310,16 @@
return !strncmp(mData, prefix, strlen(prefix));
}
+bool AString::endsWith(const char *suffix) const {
+ size_t suffixLen = strlen(suffix);
+
+ if (mSize < suffixLen) {
+ return false;
+ }
+
+ return !strcmp(mData + mSize - suffixLen, suffix);
+}
+
AString StringPrintf(const char *format, ...) {
va_list ap;
va_start(ap, format);
diff --git a/media/libstagefright/httplive/Android.mk b/media/libstagefright/httplive/Android.mk
index a5990c3..90cb448 100644
--- a/media/libstagefright/httplive/Android.mk
+++ b/media/libstagefright/httplive/Android.mk
@@ -8,7 +8,6 @@
M3UParser.cpp \
LOCAL_C_INCLUDES:= \
- $(JNI_H_INCLUDE) \
$(TOP)/frameworks/base/media/libstagefright \
$(TOP)/frameworks/native/include/media/openmax \
$(TOP)/external/openssl/include
diff --git a/media/libstagefright/matroska/Android.mk b/media/libstagefright/matroska/Android.mk
index e67da4c..2cccb4f 100644
--- a/media/libstagefright/matroska/Android.mk
+++ b/media/libstagefright/matroska/Android.mk
@@ -5,7 +5,6 @@
MatroskaExtractor.cpp
LOCAL_C_INCLUDES:= \
- $(JNI_H_INCLUDE) \
$(TOP)/external/libvpx/mkvparser \
$(TOP)/frameworks/native/include/media/openmax \
diff --git a/media/libstagefright/mpeg2ts/Android.mk b/media/libstagefright/mpeg2ts/Android.mk
index ac4c2a1..eaa139d 100644
--- a/media/libstagefright/mpeg2ts/Android.mk
+++ b/media/libstagefright/mpeg2ts/Android.mk
@@ -10,7 +10,6 @@
MPEG2TSExtractor.cpp \
LOCAL_C_INCLUDES:= \
- $(JNI_H_INCLUDE) \
$(TOP)/frameworks/base/media/libstagefright \
$(TOP)/frameworks/native/include/media/openmax
diff --git a/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp b/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
index d708ba6..e1ac53c 100644
--- a/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
+++ b/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
@@ -117,6 +117,12 @@
mediaBuffer->meta_data()->setInt64(kKeyTime, timeUs);
+ int32_t scrambling;
+ if (buffer->meta()->findInt32("scrambling", &scrambling)
+ && scrambling != 0) {
+ mediaBuffer->meta_data()->setInt32(kKeyScrambling, scrambling);
+ }
+
*out = mediaBuffer;
return OK;
}
diff --git a/media/libstagefright/omx/Android.mk b/media/libstagefright/omx/Android.mk
index 083c7ef..d20ecb6 100644
--- a/media/libstagefright/omx/Android.mk
+++ b/media/libstagefright/omx/Android.mk
@@ -1,8 +1,6 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
-LOCAL_C_INCLUDES += $(JNI_H_INCLUDE)
-
LOCAL_SRC_FILES:= \
OMX.cpp \
OMXMaster.cpp \
diff --git a/media/libstagefright/omx/tests/Android.mk b/media/libstagefright/omx/tests/Android.mk
index 07d47a8..6aa7470 100644
--- a/media/libstagefright/omx/tests/Android.mk
+++ b/media/libstagefright/omx/tests/Android.mk
@@ -8,7 +8,6 @@
libstagefright libbinder libmedia libutils libstagefright_foundation
LOCAL_C_INCLUDES := \
- $(JNI_H_INCLUDE) \
frameworks/base/media/libstagefright \
$(TOP)/frameworks/native/include/media/openmax
diff --git a/media/libstagefright/rtsp/Android.mk b/media/libstagefright/rtsp/Android.mk
index b3bc37c..e0fe59b 100644
--- a/media/libstagefright/rtsp/Android.mk
+++ b/media/libstagefright/rtsp/Android.mk
@@ -18,7 +18,6 @@
ASessionDescription.cpp \
LOCAL_C_INCLUDES:= \
- $(JNI_H_INCLUDE) \
$(TOP)/frameworks/base/media/libstagefright/include \
$(TOP)/frameworks/native/include/media/openmax \
$(TOP)/external/openssl/include
@@ -45,7 +44,6 @@
libstagefright_rtsp
LOCAL_C_INCLUDES:= \
- $(JNI_H_INCLUDE) \
frameworks/base/media/libstagefright \
$(TOP)/frameworks/native/include/media/openmax
diff --git a/media/libstagefright/timedtext/Android.mk b/media/libstagefright/timedtext/Android.mk
index d2d5f7b..58ef9e3 100644
--- a/media/libstagefright/timedtext/Android.mk
+++ b/media/libstagefright/timedtext/Android.mk
@@ -11,7 +11,6 @@
LOCAL_CFLAGS += -Wno-multichar
LOCAL_C_INCLUDES:= \
- $(JNI_H_INCLUDE) \
$(TOP)/frameworks/base/include/media/stagefright/timedtext \
$(TOP)/frameworks/base/media/libstagefright
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java
index 4f6e7d2..db64b94 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java
@@ -101,6 +101,9 @@
protected void setUp() throws Exception {
super.setUp();
+ //Insert a 2 second before launching the test activity. This is
+ //the workaround for the race condition of requesting the updated surface.
+ Thread.sleep(2000);
getActivity();
if (MediaFrameworkPerfTestRunner.mGetNativeHeapDump)
MediaTestUtil.getNativeHeapDump(this.getName() + "_before");
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaPlayerStressTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaPlayerStressTest.java
index b2086d6..25b6e7f 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaPlayerStressTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaPlayerStressTest.java
@@ -43,13 +43,18 @@
/**
* Junit / Instrumentation test case for the media player
*/
-public class MediaPlayerStressTest extends InstrumentationTestCase {
+public class MediaPlayerStressTest extends ActivityInstrumentationTestCase2<MediaFrameworkTest> {
private String TAG = "MediaPlayerStressTest";
public MediaPlayerStressTest() {
+ super("com.android.mediaframeworktest", MediaFrameworkTest.class);
}
protected void setUp() throws Exception {
+ //Insert a 2 second before launching the test activity. This is
+ //the workaround for the race condition of requesting the updated surface.
+ Thread.sleep(2000);
+ getActivity();
super.setUp();
}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaRecorderStressTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaRecorderStressTest.java
index 5e649e0..e9bc6f0 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaRecorderStressTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaRecorderStressTest.java
@@ -88,7 +88,9 @@
if (! sem.tryAcquire(WAIT_TIMEOUT, TimeUnit.MILLISECONDS)) {
fail("Failed to start the looper.");
}
-
+ //Insert a 2 second before launching the test activity. This is
+ //the workaround for the race condition of requesting the updated surface.
+ Thread.sleep(2000);
getActivity();
super.setUp();
}
diff --git a/media/tests/omxjpegdecoder/Android.mk b/media/tests/omxjpegdecoder/Android.mk
index 3e09a5f..9dcc7ba 100644
--- a/media/tests/omxjpegdecoder/Android.mk
+++ b/media/tests/omxjpegdecoder/Android.mk
@@ -32,7 +32,6 @@
libjpeg
LOCAL_C_INCLUDES := \
- $(JNI_H_INCLUDE) \
$(TOP)/external/jpeg \
$(TOP)/external/skia/include/config \
$(TOP)/external/skia/include/core \
diff --git a/native/copy-to-ndk.sh b/native/copy-to-ndk.sh
index 6470892..90ff556 100644
--- a/native/copy-to-ndk.sh
+++ b/native/copy-to-ndk.sh
@@ -5,7 +5,7 @@
local CURR_PLATFORM=android-9
local ALL_PLATFORMS="$CURR_PLATFORM android-8 android-5 android-4 android-3"
- local SRC_HEADERS=$ANDROID_BUILD_TOP/frameworks/base/native/include/android
+ local SRC_HEADERS=$ANDROID_BUILD_TOP/frameworks/native/include/android
local NDK_PLATFORMS=$ANDROID_BUILD_TOP/development/ndk/platforms
local DST_HEADERS=$NDK_PLATFORMS/$CURR_PLATFORM
diff --git a/native/include/android/asset_manager.h b/native/include/android/asset_manager.h
deleted file mode 100644
index f5df46b..0000000
--- a/native/include/android/asset_manager.h
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-#ifndef ANDROID_ASSET_MANAGER_H
-#define ANDROID_ASSET_MANAGER_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct AAssetManager;
-typedef struct AAssetManager AAssetManager;
-
-struct AAssetDir;
-typedef struct AAssetDir AAssetDir;
-
-struct AAsset;
-typedef struct AAsset AAsset;
-
-/* Available modes for opening assets */
-enum {
- AASSET_MODE_UNKNOWN = 0,
- AASSET_MODE_RANDOM = 1,
- AASSET_MODE_STREAMING = 2,
- AASSET_MODE_BUFFER = 3
-};
-
-
-/**
- * Open the named directory within the asset hierarchy. The directory can then
- * be inspected with the AAssetDir functions. To open the top-level directory,
- * pass in "" as the dirName.
- *
- * The object returned here should be freed by calling AAssetDir_close().
- */
-AAssetDir* AAssetManager_openDir(AAssetManager* mgr, const char* dirName);
-
-/**
- * Open an asset.
- *
- * The object returned here should be freed by calling AAsset_close().
- */
-AAsset* AAssetManager_open(AAssetManager* mgr, const char* filename, int mode);
-
-/**
- * Iterate over the files in an asset directory. A NULL string is returned
- * when all the file names have been returned.
- *
- * The returned file name is suitable for passing to AAssetManager_open().
- *
- * The string returned here is owned by the AssetDir implementation and is not
- * guaranteed to remain valid if any other calls are made on this AAssetDir
- * instance.
- */
-const char* AAssetDir_getNextFileName(AAssetDir* assetDir);
-
-/**
- * Reset the iteration state of AAssetDir_getNextFileName() to the beginning.
- */
-void AAssetDir_rewind(AAssetDir* assetDir);
-
-/**
- * Close an opened AAssetDir, freeing any related resources.
- */
-void AAssetDir_close(AAssetDir* assetDir);
-
-/**
- * Attempt to read 'count' bytes of data from the current offset.
- *
- * Returns the number of bytes read, zero on EOF, or < 0 on error.
- */
-int AAsset_read(AAsset* asset, void* buf, size_t count);
-
-/**
- * Seek to the specified offset within the asset data. 'whence' uses the
- * same constants as lseek()/fseek().
- *
- * Returns the new position on success, or (off_t) -1 on error.
- */
-off_t AAsset_seek(AAsset* asset, off_t offset, int whence);
-
-/**
- * Seek to the specified offset within the asset data. 'whence' uses the
- * same constants as lseek()/fseek().
- *
- * Uses 64-bit data type for large files as opposed to the 32-bit type used
- * by AAsset_seek.
- *
- * Returns the new position on success, or (off64_t) -1 on error.
- */
-off64_t AAsset_seek64(AAsset* asset, off64_t offset, int whence);
-
-/**
- * Close the asset, freeing all associated resources.
- */
-void AAsset_close(AAsset* asset);
-
-/**
- * Get a pointer to a buffer holding the entire contents of the assset.
- *
- * Returns NULL on failure.
- */
-const void* AAsset_getBuffer(AAsset* asset);
-
-/**
- * Report the total size of the asset data.
- */
-off_t AAsset_getLength(AAsset* asset);
-
-/**
- * Report the total size of the asset data. Reports the size using a 64-bit
- * number insted of 32-bit as AAsset_getLength.
- */
-off64_t AAsset_getLength64(AAsset* asset);
-
-/**
- * Report the total amount of asset data that can be read from the current position.
- */
-off_t AAsset_getRemainingLength(AAsset* asset);
-
-/**
- * Report the total amount of asset data that can be read from the current position.
- *
- * Uses a 64-bit number instead of a 32-bit number as AAsset_getRemainingLength does.
- */
-off64_t AAsset_getRemainingLength64(AAsset* asset);
-
-/**
- * Open a new file descriptor that can be used to read the asset data. If the
- * start or length cannot be represented by a 32-bit number, it will be
- * truncated. If the file is large, use AAsset_openFileDescriptor64 instead.
- *
- * Returns < 0 if direct fd access is not possible (for example, if the asset is
- * compressed).
- */
-int AAsset_openFileDescriptor(AAsset* asset, off_t* outStart, off_t* outLength);
-
-/**
- * Open a new file descriptor that can be used to read the asset data.
- *
- * Uses a 64-bit number for the offset and length instead of 32-bit instead of
- * as AAsset_openFileDescriptor does.
- *
- * Returns < 0 if direct fd access is not possible (for example, if the asset is
- * compressed).
- */
-int AAsset_openFileDescriptor64(AAsset* asset, off64_t* outStart, off64_t* outLength);
-
-/**
- * Returns whether this asset's internal buffer is allocated in ordinary RAM (i.e. not
- * mmapped).
- */
-int AAsset_isAllocated(AAsset* asset);
-
-
-
-#ifdef __cplusplus
-};
-#endif
-
-#endif // ANDROID_ASSET_MANAGER_H
diff --git a/native/include/android/asset_manager_jni.h b/native/include/android/asset_manager_jni.h
deleted file mode 100644
index aec2d3c..0000000
--- a/native/include/android/asset_manager_jni.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-#ifndef ANDROID_ASSET_MANAGER_JNI_H
-#define ANDROID_ASSET_MANAGER_JNI_H
-
-#include <android/asset_manager.h>
-#include <jni.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * Given a Dalvik AssetManager object, obtain the corresponding native AAssetManager
- * object. Note that the caller is responsible for obtaining and holding a VM reference
- * to the jobject to prevent its being garbage collected while the native object is
- * in use.
- */
-AAssetManager* AAssetManager_fromJava(JNIEnv* env, jobject assetManager);
-
-#ifdef __cplusplus
-};
-#endif
-
-#endif // ANDROID_ASSET_MANAGER_JNI_H
diff --git a/native/include/android/bitmap.h b/native/include/android/bitmap.h
deleted file mode 100644
index 5078277..0000000
--- a/native/include/android/bitmap.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_BITMAP_H
-#define ANDROID_BITMAP_H
-
-#include <stdint.h>
-#include <jni.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define ANDROID_BITMAP_RESUT_SUCCESS 0
-#define ANDROID_BITMAP_RESULT_BAD_PARAMETER -1
-#define ANDROID_BITMAP_RESULT_JNI_EXCEPTION -2
-#define ANDROID_BITMAP_RESULT_ALLOCATION_FAILED -3
-
-enum AndroidBitmapFormat {
- ANDROID_BITMAP_FORMAT_NONE = 0,
- ANDROID_BITMAP_FORMAT_RGBA_8888 = 1,
- ANDROID_BITMAP_FORMAT_RGB_565 = 4,
- ANDROID_BITMAP_FORMAT_RGBA_4444 = 7,
- ANDROID_BITMAP_FORMAT_A_8 = 8,
-};
-
-typedef struct {
- uint32_t width;
- uint32_t height;
- uint32_t stride;
- int32_t format;
- uint32_t flags; // 0 for now
-} AndroidBitmapInfo;
-
-/**
- * Given a java bitmap object, fill out the AndroidBitmap struct for it.
- * If the call fails, the info parameter will be ignored
- */
-int AndroidBitmap_getInfo(JNIEnv* env, jobject jbitmap,
- AndroidBitmapInfo* info);
-
-/**
- * Given a java bitmap object, attempt to lock the pixel address.
- * Locking will ensure that the memory for the pixels will not move
- * until the unlockPixels call, and ensure that, if the pixels had been
- * previously purged, they will have been restored.
- *
- * If this call succeeds, it must be balanced by a call to
- * AndroidBitmap_unlockPixels, after which time the address of the pixels should
- * no longer be used.
- *
- * If this succeeds, *addrPtr will be set to the pixel address. If the call
- * fails, addrPtr will be ignored.
- */
-int AndroidBitmap_lockPixels(JNIEnv* env, jobject jbitmap, void** addrPtr);
-
-/**
- * Call this to balanace a successful call to AndroidBitmap_lockPixels
- */
-int AndroidBitmap_unlockPixels(JNIEnv* env, jobject jbitmap);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/native/include/android/configuration.h b/native/include/android/configuration.h
deleted file mode 100644
index 06cd3da..0000000
--- a/native/include/android/configuration.h
+++ /dev/null
@@ -1,364 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_CONFIGURATION_H
-#define ANDROID_CONFIGURATION_H
-
-#include <android/asset_manager.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct AConfiguration;
-typedef struct AConfiguration AConfiguration;
-
-enum {
- ACONFIGURATION_ORIENTATION_ANY = 0x0000,
- ACONFIGURATION_ORIENTATION_PORT = 0x0001,
- ACONFIGURATION_ORIENTATION_LAND = 0x0002,
- ACONFIGURATION_ORIENTATION_SQUARE = 0x0003,
-
- ACONFIGURATION_TOUCHSCREEN_ANY = 0x0000,
- ACONFIGURATION_TOUCHSCREEN_NOTOUCH = 0x0001,
- ACONFIGURATION_TOUCHSCREEN_STYLUS = 0x0002,
- ACONFIGURATION_TOUCHSCREEN_FINGER = 0x0003,
-
- ACONFIGURATION_DENSITY_DEFAULT = 0,
- ACONFIGURATION_DENSITY_LOW = 120,
- ACONFIGURATION_DENSITY_MEDIUM = 160,
- ACONFIGURATION_DENSITY_TV = 213,
- ACONFIGURATION_DENSITY_HIGH = 240,
- ACONFIGURATION_DENSITY_XHIGH = 320,
- ACONFIGURATION_DENSITY_XXHIGH = 480,
- ACONFIGURATION_DENSITY_NONE = 0xffff,
-
- ACONFIGURATION_KEYBOARD_ANY = 0x0000,
- ACONFIGURATION_KEYBOARD_NOKEYS = 0x0001,
- ACONFIGURATION_KEYBOARD_QWERTY = 0x0002,
- ACONFIGURATION_KEYBOARD_12KEY = 0x0003,
-
- ACONFIGURATION_NAVIGATION_ANY = 0x0000,
- ACONFIGURATION_NAVIGATION_NONAV = 0x0001,
- ACONFIGURATION_NAVIGATION_DPAD = 0x0002,
- ACONFIGURATION_NAVIGATION_TRACKBALL = 0x0003,
- ACONFIGURATION_NAVIGATION_WHEEL = 0x0004,
-
- ACONFIGURATION_KEYSHIDDEN_ANY = 0x0000,
- ACONFIGURATION_KEYSHIDDEN_NO = 0x0001,
- ACONFIGURATION_KEYSHIDDEN_YES = 0x0002,
- ACONFIGURATION_KEYSHIDDEN_SOFT = 0x0003,
-
- ACONFIGURATION_NAVHIDDEN_ANY = 0x0000,
- ACONFIGURATION_NAVHIDDEN_NO = 0x0001,
- ACONFIGURATION_NAVHIDDEN_YES = 0x0002,
-
- ACONFIGURATION_SCREENSIZE_ANY = 0x00,
- ACONFIGURATION_SCREENSIZE_SMALL = 0x01,
- ACONFIGURATION_SCREENSIZE_NORMAL = 0x02,
- ACONFIGURATION_SCREENSIZE_LARGE = 0x03,
- ACONFIGURATION_SCREENSIZE_XLARGE = 0x04,
-
- ACONFIGURATION_SCREENLONG_ANY = 0x00,
- ACONFIGURATION_SCREENLONG_NO = 0x1,
- ACONFIGURATION_SCREENLONG_YES = 0x2,
-
- ACONFIGURATION_UI_MODE_TYPE_ANY = 0x00,
- ACONFIGURATION_UI_MODE_TYPE_NORMAL = 0x01,
- ACONFIGURATION_UI_MODE_TYPE_DESK = 0x02,
- ACONFIGURATION_UI_MODE_TYPE_CAR = 0x03,
- ACONFIGURATION_UI_MODE_TYPE_TELEVISION = 0x04,
- ACONFIGURATION_UI_MODE_TYPE_APPLIANCE = 0x05,
-
- ACONFIGURATION_UI_MODE_NIGHT_ANY = 0x00,
- ACONFIGURATION_UI_MODE_NIGHT_NO = 0x1,
- ACONFIGURATION_UI_MODE_NIGHT_YES = 0x2,
-
- ACONFIGURATION_SCREEN_WIDTH_DP_ANY = 0x0000,
-
- ACONFIGURATION_SCREEN_HEIGHT_DP_ANY = 0x0000,
-
- ACONFIGURATION_SMALLEST_SCREEN_WIDTH_DP_ANY = 0x0000,
-
- ACONFIGURATION_MCC = 0x0001,
- ACONFIGURATION_MNC = 0x0002,
- ACONFIGURATION_LOCALE = 0x0004,
- ACONFIGURATION_TOUCHSCREEN = 0x0008,
- ACONFIGURATION_KEYBOARD = 0x0010,
- ACONFIGURATION_KEYBOARD_HIDDEN = 0x0020,
- ACONFIGURATION_NAVIGATION = 0x0040,
- ACONFIGURATION_ORIENTATION = 0x0080,
- ACONFIGURATION_DENSITY = 0x0100,
- ACONFIGURATION_SCREEN_SIZE = 0x0200,
- ACONFIGURATION_VERSION = 0x0400,
- ACONFIGURATION_SCREEN_LAYOUT = 0x0800,
- ACONFIGURATION_UI_MODE = 0x1000,
- ACONFIGURATION_SMALLEST_SCREEN_SIZE = 0x2000,
-};
-
-/**
- * Create a new AConfiguration, initialized with no values set.
- */
-AConfiguration* AConfiguration_new();
-
-/**
- * Free an AConfiguration that was previously created with
- * AConfiguration_new().
- */
-void AConfiguration_delete(AConfiguration* config);
-
-/**
- * Create and return a new AConfiguration based on the current configuration in
- * use in the given AssetManager.
- */
-void AConfiguration_fromAssetManager(AConfiguration* out, AAssetManager* am);
-
-/**
- * Copy the contents of 'src' to 'dest'.
- */
-void AConfiguration_copy(AConfiguration* dest, AConfiguration* src);
-
-/**
- * Return the current MCC set in the configuration. 0 if not set.
- */
-int32_t AConfiguration_getMcc(AConfiguration* config);
-
-/**
- * Set the current MCC in the configuration. 0 to clear.
- */
-void AConfiguration_setMcc(AConfiguration* config, int32_t mcc);
-
-/**
- * Return the current MNC set in the configuration. 0 if not set.
- */
-int32_t AConfiguration_getMnc(AConfiguration* config);
-
-/**
- * Set the current MNC in the configuration. 0 to clear.
- */
-void AConfiguration_setMnc(AConfiguration* config, int32_t mnc);
-
-/**
- * Return the current language code set in the configuration. The output will
- * be filled with an array of two characters. They are not 0-terminated. If
- * a language is not set, they will be 0.
- */
-void AConfiguration_getLanguage(AConfiguration* config, char* outLanguage);
-
-/**
- * Set the current language code in the configuration, from the first two
- * characters in the string.
- */
-void AConfiguration_setLanguage(AConfiguration* config, const char* language);
-
-/**
- * Return the current country code set in the configuration. The output will
- * be filled with an array of two characters. They are not 0-terminated. If
- * a country is not set, they will be 0.
- */
-void AConfiguration_getCountry(AConfiguration* config, char* outCountry);
-
-/**
- * Set the current country code in the configuration, from the first two
- * characters in the string.
- */
-void AConfiguration_setCountry(AConfiguration* config, const char* country);
-
-/**
- * Return the current ACONFIGURATION_ORIENTATION_* set in the configuration.
- */
-int32_t AConfiguration_getOrientation(AConfiguration* config);
-
-/**
- * Set the current orientation in the configuration.
- */
-void AConfiguration_setOrientation(AConfiguration* config, int32_t orientation);
-
-/**
- * Return the current ACONFIGURATION_TOUCHSCREEN_* set in the configuration.
- */
-int32_t AConfiguration_getTouchscreen(AConfiguration* config);
-
-/**
- * Set the current touchscreen in the configuration.
- */
-void AConfiguration_setTouchscreen(AConfiguration* config, int32_t touchscreen);
-
-/**
- * Return the current ACONFIGURATION_DENSITY_* set in the configuration.
- */
-int32_t AConfiguration_getDensity(AConfiguration* config);
-
-/**
- * Set the current density in the configuration.
- */
-void AConfiguration_setDensity(AConfiguration* config, int32_t density);
-
-/**
- * Return the current ACONFIGURATION_KEYBOARD_* set in the configuration.
- */
-int32_t AConfiguration_getKeyboard(AConfiguration* config);
-
-/**
- * Set the current keyboard in the configuration.
- */
-void AConfiguration_setKeyboard(AConfiguration* config, int32_t keyboard);
-
-/**
- * Return the current ACONFIGURATION_NAVIGATION_* set in the configuration.
- */
-int32_t AConfiguration_getNavigation(AConfiguration* config);
-
-/**
- * Set the current navigation in the configuration.
- */
-void AConfiguration_setNavigation(AConfiguration* config, int32_t navigation);
-
-/**
- * Return the current ACONFIGURATION_KEYSHIDDEN_* set in the configuration.
- */
-int32_t AConfiguration_getKeysHidden(AConfiguration* config);
-
-/**
- * Set the current keys hidden in the configuration.
- */
-void AConfiguration_setKeysHidden(AConfiguration* config, int32_t keysHidden);
-
-/**
- * Return the current ACONFIGURATION_NAVHIDDEN_* set in the configuration.
- */
-int32_t AConfiguration_getNavHidden(AConfiguration* config);
-
-/**
- * Set the current nav hidden in the configuration.
- */
-void AConfiguration_setNavHidden(AConfiguration* config, int32_t navHidden);
-
-/**
- * Return the current SDK (API) version set in the configuration.
- */
-int32_t AConfiguration_getSdkVersion(AConfiguration* config);
-
-/**
- * Set the current SDK version in the configuration.
- */
-void AConfiguration_setSdkVersion(AConfiguration* config, int32_t sdkVersion);
-
-/**
- * Return the current ACONFIGURATION_SCREENSIZE_* set in the configuration.
- */
-int32_t AConfiguration_getScreenSize(AConfiguration* config);
-
-/**
- * Set the current screen size in the configuration.
- */
-void AConfiguration_setScreenSize(AConfiguration* config, int32_t screenSize);
-
-/**
- * Return the current ACONFIGURATION_SCREENLONG_* set in the configuration.
- */
-int32_t AConfiguration_getScreenLong(AConfiguration* config);
-
-/**
- * Set the current screen long in the configuration.
- */
-void AConfiguration_setScreenLong(AConfiguration* config, int32_t screenLong);
-
-/**
- * Return the current ACONFIGURATION_UI_MODE_TYPE_* set in the configuration.
- */
-int32_t AConfiguration_getUiModeType(AConfiguration* config);
-
-/**
- * Set the current UI mode type in the configuration.
- */
-void AConfiguration_setUiModeType(AConfiguration* config, int32_t uiModeType);
-
-/**
- * Return the current ACONFIGURATION_UI_MODE_NIGHT_* set in the configuration.
- */
-int32_t AConfiguration_getUiModeNight(AConfiguration* config);
-
-/**
- * Set the current UI mode night in the configuration.
- */
-void AConfiguration_setUiModeNight(AConfiguration* config, int32_t uiModeNight);
-
-/**
- * Return the current configuration screen width in dp units, or
- * ACONFIGURATION_SCREEN_WIDTH_DP_ANY if not set.
- */
-int32_t AConfiguration_getScreenWidthDp(AConfiguration* config);
-
-/**
- * Set the configuration's current screen width in dp units.
- */
-void AConfiguration_setScreenWidthDp(AConfiguration* config, int32_t value);
-
-/**
- * Return the current configuration screen height in dp units, or
- * ACONFIGURATION_SCREEN_HEIGHT_DP_ANY if not set.
- */
-int32_t AConfiguration_getScreenHeightDp(AConfiguration* config);
-
-/**
- * Set the configuration's current screen width in dp units.
- */
-void AConfiguration_setScreenHeightDp(AConfiguration* config, int32_t value);
-
-/**
- * Return the configuration's smallest screen width in dp units, or
- * ACONFIGURATION_SMALLEST_SCREEN_WIDTH_DP_ANY if not set.
- */
-int32_t AConfiguration_getSmallestScreenWidthDp(AConfiguration* config);
-
-/**
- * Set the configuration's smallest screen width in dp units.
- */
-void AConfiguration_setSmallestScreenWidthDp(AConfiguration* config, int32_t value);
-
-/**
- * Perform a diff between two configurations. Returns a bit mask of
- * ACONFIGURATION_* constants, each bit set meaning that configuration element
- * is different between them.
- */
-int32_t AConfiguration_diff(AConfiguration* config1, AConfiguration* config2);
-
-/**
- * Determine whether 'base' is a valid configuration for use within the
- * environment 'requested'. Returns 0 if there are any values in 'base'
- * that conflict with 'requested'. Returns 1 if it does not conflict.
- */
-int32_t AConfiguration_match(AConfiguration* base, AConfiguration* requested);
-
-/**
- * Determine whether the configuration in 'test' is better than the existing
- * configuration in 'base'. If 'requested' is non-NULL, this decision is based
- * on the overall configuration given there. If it is NULL, this decision is
- * simply based on which configuration is more specific. Returns non-0 if
- * 'test' is better than 'base'.
- *
- * This assumes you have already filtered the configurations with
- * AConfiguration_match().
- */
-int32_t AConfiguration_isBetterThan(AConfiguration* base, AConfiguration* test,
- AConfiguration* requested);
-
-#ifdef __cplusplus
-};
-#endif
-
-#endif // ANDROID_CONFIGURATION_H
diff --git a/native/include/android/input.h b/native/include/android/input.h
deleted file mode 100644
index f2befa9e..0000000
--- a/native/include/android/input.h
+++ /dev/null
@@ -1,848 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _ANDROID_INPUT_H
-#define _ANDROID_INPUT_H
-
-/******************************************************************
- *
- * IMPORTANT NOTICE:
- *
- * This file is part of Android's set of stable system headers
- * exposed by the Android NDK (Native Development Kit).
- *
- * Third-party source AND binary code relies on the definitions
- * here to be FROZEN ON ALL UPCOMING PLATFORM RELEASES.
- *
- * - DO NOT MODIFY ENUMS (EXCEPT IF YOU ADD NEW 32-BIT VALUES)
- * - DO NOT MODIFY CONSTANTS OR FUNCTIONAL MACROS
- * - DO NOT CHANGE THE SIGNATURE OF FUNCTIONS IN ANY WAY
- * - DO NOT CHANGE THE LAYOUT OR SIZE OF STRUCTURES
- */
-
-/*
- * Structures and functions to receive and process input events in
- * native code.
- *
- * NOTE: These functions MUST be implemented by /system/lib/libui.so
- */
-
-#include <stdint.h>
-#include <sys/types.h>
-#include <android/keycodes.h>
-#include <android/looper.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Key states (may be returned by queries about the current state of a
- * particular key code, scan code or switch).
- */
-enum {
- /* The key state is unknown or the requested key itself is not supported. */
- AKEY_STATE_UNKNOWN = -1,
-
- /* The key is up. */
- AKEY_STATE_UP = 0,
-
- /* The key is down. */
- AKEY_STATE_DOWN = 1,
-
- /* The key is down but is a virtual key press that is being emulated by the system. */
- AKEY_STATE_VIRTUAL = 2
-};
-
-/*
- * Meta key / modifer state.
- */
-enum {
- /* No meta keys are pressed. */
- AMETA_NONE = 0,
-
- /* This mask is used to check whether one of the ALT meta keys is pressed. */
- AMETA_ALT_ON = 0x02,
-
- /* This mask is used to check whether the left ALT meta key is pressed. */
- AMETA_ALT_LEFT_ON = 0x10,
-
- /* This mask is used to check whether the right ALT meta key is pressed. */
- AMETA_ALT_RIGHT_ON = 0x20,
-
- /* This mask is used to check whether one of the SHIFT meta keys is pressed. */
- AMETA_SHIFT_ON = 0x01,
-
- /* This mask is used to check whether the left SHIFT meta key is pressed. */
- AMETA_SHIFT_LEFT_ON = 0x40,
-
- /* This mask is used to check whether the right SHIFT meta key is pressed. */
- AMETA_SHIFT_RIGHT_ON = 0x80,
-
- /* This mask is used to check whether the SYM meta key is pressed. */
- AMETA_SYM_ON = 0x04,
-
- /* This mask is used to check whether the FUNCTION meta key is pressed. */
- AMETA_FUNCTION_ON = 0x08,
-
- /* This mask is used to check whether one of the CTRL meta keys is pressed. */
- AMETA_CTRL_ON = 0x1000,
-
- /* This mask is used to check whether the left CTRL meta key is pressed. */
- AMETA_CTRL_LEFT_ON = 0x2000,
-
- /* This mask is used to check whether the right CTRL meta key is pressed. */
- AMETA_CTRL_RIGHT_ON = 0x4000,
-
- /* This mask is used to check whether one of the META meta keys is pressed. */
- AMETA_META_ON = 0x10000,
-
- /* This mask is used to check whether the left META meta key is pressed. */
- AMETA_META_LEFT_ON = 0x20000,
-
- /* This mask is used to check whether the right META meta key is pressed. */
- AMETA_META_RIGHT_ON = 0x40000,
-
- /* This mask is used to check whether the CAPS LOCK meta key is on. */
- AMETA_CAPS_LOCK_ON = 0x100000,
-
- /* This mask is used to check whether the NUM LOCK meta key is on. */
- AMETA_NUM_LOCK_ON = 0x200000,
-
- /* This mask is used to check whether the SCROLL LOCK meta key is on. */
- AMETA_SCROLL_LOCK_ON = 0x400000,
-};
-
-/*
- * Input events.
- *
- * Input events are opaque structures. Use the provided accessors functions to
- * read their properties.
- */
-struct AInputEvent;
-typedef struct AInputEvent AInputEvent;
-
-/*
- * Input event types.
- */
-enum {
- /* Indicates that the input event is a key event. */
- AINPUT_EVENT_TYPE_KEY = 1,
-
- /* Indicates that the input event is a motion event. */
- AINPUT_EVENT_TYPE_MOTION = 2
-};
-
-/*
- * Key event actions.
- */
-enum {
- /* The key has been pressed down. */
- AKEY_EVENT_ACTION_DOWN = 0,
-
- /* The key has been released. */
- AKEY_EVENT_ACTION_UP = 1,
-
- /* Multiple duplicate key events have occurred in a row, or a complex string is
- * being delivered. The repeat_count property of the key event contains the number
- * of times the given key code should be executed.
- */
- AKEY_EVENT_ACTION_MULTIPLE = 2
-};
-
-/*
- * Key event flags.
- */
-enum {
- /* This mask is set if the device woke because of this key event. */
- AKEY_EVENT_FLAG_WOKE_HERE = 0x1,
-
- /* This mask is set if the key event was generated by a software keyboard. */
- AKEY_EVENT_FLAG_SOFT_KEYBOARD = 0x2,
-
- /* This mask is set if we don't want the key event to cause us to leave touch mode. */
- AKEY_EVENT_FLAG_KEEP_TOUCH_MODE = 0x4,
-
- /* This mask is set if an event was known to come from a trusted part
- * of the system. That is, the event is known to come from the user,
- * and could not have been spoofed by a third party component. */
- AKEY_EVENT_FLAG_FROM_SYSTEM = 0x8,
-
- /* This mask is used for compatibility, to identify enter keys that are
- * coming from an IME whose enter key has been auto-labelled "next" or
- * "done". This allows TextView to dispatch these as normal enter keys
- * for old applications, but still do the appropriate action when
- * receiving them. */
- AKEY_EVENT_FLAG_EDITOR_ACTION = 0x10,
-
- /* When associated with up key events, this indicates that the key press
- * has been canceled. Typically this is used with virtual touch screen
- * keys, where the user can slide from the virtual key area on to the
- * display: in that case, the application will receive a canceled up
- * event and should not perform the action normally associated with the
- * key. Note that for this to work, the application can not perform an
- * action for a key until it receives an up or the long press timeout has
- * expired. */
- AKEY_EVENT_FLAG_CANCELED = 0x20,
-
- /* This key event was generated by a virtual (on-screen) hard key area.
- * Typically this is an area of the touchscreen, outside of the regular
- * display, dedicated to "hardware" buttons. */
- AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY = 0x40,
-
- /* This flag is set for the first key repeat that occurs after the
- * long press timeout. */
- AKEY_EVENT_FLAG_LONG_PRESS = 0x80,
-
- /* Set when a key event has AKEY_EVENT_FLAG_CANCELED set because a long
- * press action was executed while it was down. */
- AKEY_EVENT_FLAG_CANCELED_LONG_PRESS = 0x100,
-
- /* Set for AKEY_EVENT_ACTION_UP when this event's key code is still being
- * tracked from its initial down. That is, somebody requested that tracking
- * started on the key down and a long press has not caused
- * the tracking to be canceled. */
- AKEY_EVENT_FLAG_TRACKING = 0x200,
-
- /* Set when a key event has been synthesized to implement default behavior
- * for an event that the application did not handle.
- * Fallback key events are generated by unhandled trackball motions
- * (to emulate a directional keypad) and by certain unhandled key presses
- * that are declared in the key map (such as special function numeric keypad
- * keys when numlock is off). */
- AKEY_EVENT_FLAG_FALLBACK = 0x400,
-};
-
-/*
- * Motion event actions.
- */
-
-/* Bit shift for the action bits holding the pointer index as
- * defined by AMOTION_EVENT_ACTION_POINTER_INDEX_MASK.
- */
-#define AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT 8
-
-enum {
- /* Bit mask of the parts of the action code that are the action itself.
- */
- AMOTION_EVENT_ACTION_MASK = 0xff,
-
- /* Bits in the action code that represent a pointer index, used with
- * AMOTION_EVENT_ACTION_POINTER_DOWN and AMOTION_EVENT_ACTION_POINTER_UP. Shifting
- * down by AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT provides the actual pointer
- * index where the data for the pointer going up or down can be found.
- */
- AMOTION_EVENT_ACTION_POINTER_INDEX_MASK = 0xff00,
-
- /* A pressed gesture has started, the motion contains the initial starting location.
- */
- AMOTION_EVENT_ACTION_DOWN = 0,
-
- /* A pressed gesture has finished, the motion contains the final release location
- * as well as any intermediate points since the last down or move event.
- */
- AMOTION_EVENT_ACTION_UP = 1,
-
- /* A change has happened during a press gesture (between AMOTION_EVENT_ACTION_DOWN and
- * AMOTION_EVENT_ACTION_UP). The motion contains the most recent point, as well as
- * any intermediate points since the last down or move event.
- */
- AMOTION_EVENT_ACTION_MOVE = 2,
-
- /* The current gesture has been aborted.
- * You will not receive any more points in it. You should treat this as
- * an up event, but not perform any action that you normally would.
- */
- AMOTION_EVENT_ACTION_CANCEL = 3,
-
- /* A movement has happened outside of the normal bounds of the UI element.
- * This does not provide a full gesture, but only the initial location of the movement/touch.
- */
- AMOTION_EVENT_ACTION_OUTSIDE = 4,
-
- /* A non-primary pointer has gone down.
- * The bits in AMOTION_EVENT_ACTION_POINTER_INDEX_MASK indicate which pointer changed.
- */
- AMOTION_EVENT_ACTION_POINTER_DOWN = 5,
-
- /* A non-primary pointer has gone up.
- * The bits in AMOTION_EVENT_ACTION_POINTER_INDEX_MASK indicate which pointer changed.
- */
- AMOTION_EVENT_ACTION_POINTER_UP = 6,
-
- /* A change happened but the pointer is not down (unlike AMOTION_EVENT_ACTION_MOVE).
- * The motion contains the most recent point, as well as any intermediate points since
- * the last hover move event.
- */
- AMOTION_EVENT_ACTION_HOVER_MOVE = 7,
-
- /* The motion event contains relative vertical and/or horizontal scroll offsets.
- * Use getAxisValue to retrieve the information from AMOTION_EVENT_AXIS_VSCROLL
- * and AMOTION_EVENT_AXIS_HSCROLL.
- * The pointer may or may not be down when this event is dispatched.
- * This action is always delivered to the winder under the pointer, which
- * may not be the window currently touched.
- */
- AMOTION_EVENT_ACTION_SCROLL = 8,
-
- /* The pointer is not down but has entered the boundaries of a window or view.
- */
- AMOTION_EVENT_ACTION_HOVER_ENTER = 9,
-
- /* The pointer is not down but has exited the boundaries of a window or view.
- */
- AMOTION_EVENT_ACTION_HOVER_EXIT = 10,
-};
-
-/*
- * Motion event flags.
- */
-enum {
- /* This flag indicates that the window that received this motion event is partly
- * or wholly obscured by another visible window above it. This flag is set to true
- * even if the event did not directly pass through the obscured area.
- * A security sensitive application can check this flag to identify situations in which
- * a malicious application may have covered up part of its content for the purpose
- * of misleading the user or hijacking touches. An appropriate response might be
- * to drop the suspect touches or to take additional precautions to confirm the user's
- * actual intent.
- */
- AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED = 0x1,
-};
-
-/*
- * Motion event edge touch flags.
- */
-enum {
- /* No edges intersected */
- AMOTION_EVENT_EDGE_FLAG_NONE = 0,
-
- /* Flag indicating the motion event intersected the top edge of the screen. */
- AMOTION_EVENT_EDGE_FLAG_TOP = 0x01,
-
- /* Flag indicating the motion event intersected the bottom edge of the screen. */
- AMOTION_EVENT_EDGE_FLAG_BOTTOM = 0x02,
-
- /* Flag indicating the motion event intersected the left edge of the screen. */
- AMOTION_EVENT_EDGE_FLAG_LEFT = 0x04,
-
- /* Flag indicating the motion event intersected the right edge of the screen. */
- AMOTION_EVENT_EDGE_FLAG_RIGHT = 0x08
-};
-
-/*
- * Constants that identify each individual axis of a motion event.
- * Refer to the documentation on the MotionEvent class for descriptions of each axis.
- */
-enum {
- AMOTION_EVENT_AXIS_X = 0,
- AMOTION_EVENT_AXIS_Y = 1,
- AMOTION_EVENT_AXIS_PRESSURE = 2,
- AMOTION_EVENT_AXIS_SIZE = 3,
- AMOTION_EVENT_AXIS_TOUCH_MAJOR = 4,
- AMOTION_EVENT_AXIS_TOUCH_MINOR = 5,
- AMOTION_EVENT_AXIS_TOOL_MAJOR = 6,
- AMOTION_EVENT_AXIS_TOOL_MINOR = 7,
- AMOTION_EVENT_AXIS_ORIENTATION = 8,
- AMOTION_EVENT_AXIS_VSCROLL = 9,
- AMOTION_EVENT_AXIS_HSCROLL = 10,
- AMOTION_EVENT_AXIS_Z = 11,
- AMOTION_EVENT_AXIS_RX = 12,
- AMOTION_EVENT_AXIS_RY = 13,
- AMOTION_EVENT_AXIS_RZ = 14,
- AMOTION_EVENT_AXIS_HAT_X = 15,
- AMOTION_EVENT_AXIS_HAT_Y = 16,
- AMOTION_EVENT_AXIS_LTRIGGER = 17,
- AMOTION_EVENT_AXIS_RTRIGGER = 18,
- AMOTION_EVENT_AXIS_THROTTLE = 19,
- AMOTION_EVENT_AXIS_RUDDER = 20,
- AMOTION_EVENT_AXIS_WHEEL = 21,
- AMOTION_EVENT_AXIS_GAS = 22,
- AMOTION_EVENT_AXIS_BRAKE = 23,
- AMOTION_EVENT_AXIS_DISTANCE = 24,
- AMOTION_EVENT_AXIS_TILT = 25,
- AMOTION_EVENT_AXIS_GENERIC_1 = 32,
- AMOTION_EVENT_AXIS_GENERIC_2 = 33,
- AMOTION_EVENT_AXIS_GENERIC_3 = 34,
- AMOTION_EVENT_AXIS_GENERIC_4 = 35,
- AMOTION_EVENT_AXIS_GENERIC_5 = 36,
- AMOTION_EVENT_AXIS_GENERIC_6 = 37,
- AMOTION_EVENT_AXIS_GENERIC_7 = 38,
- AMOTION_EVENT_AXIS_GENERIC_8 = 39,
- AMOTION_EVENT_AXIS_GENERIC_9 = 40,
- AMOTION_EVENT_AXIS_GENERIC_10 = 41,
- AMOTION_EVENT_AXIS_GENERIC_11 = 42,
- AMOTION_EVENT_AXIS_GENERIC_12 = 43,
- AMOTION_EVENT_AXIS_GENERIC_13 = 44,
- AMOTION_EVENT_AXIS_GENERIC_14 = 45,
- AMOTION_EVENT_AXIS_GENERIC_15 = 46,
- AMOTION_EVENT_AXIS_GENERIC_16 = 47,
-
- // NOTE: If you add a new axis here you must also add it to several other files.
- // Refer to frameworks/base/core/java/android/view/MotionEvent.java for the full list.
-};
-
-/*
- * Constants that identify buttons that are associated with motion events.
- * Refer to the documentation on the MotionEvent class for descriptions of each button.
- */
-enum {
- AMOTION_EVENT_BUTTON_PRIMARY = 1 << 0,
- AMOTION_EVENT_BUTTON_SECONDARY = 1 << 1,
- AMOTION_EVENT_BUTTON_TERTIARY = 1 << 2,
- AMOTION_EVENT_BUTTON_BACK = 1 << 3,
- AMOTION_EVENT_BUTTON_FORWARD = 1 << 4,
-};
-
-/*
- * Constants that identify tool types.
- * Refer to the documentation on the MotionEvent class for descriptions of each tool type.
- */
-enum {
- AMOTION_EVENT_TOOL_TYPE_UNKNOWN = 0,
- AMOTION_EVENT_TOOL_TYPE_FINGER = 1,
- AMOTION_EVENT_TOOL_TYPE_STYLUS = 2,
- AMOTION_EVENT_TOOL_TYPE_MOUSE = 3,
- AMOTION_EVENT_TOOL_TYPE_ERASER = 4,
-};
-
-/*
- * Input sources.
- *
- * Refer to the documentation on android.view.InputDevice for more details about input sources
- * and their correct interpretation.
- */
-enum {
- AINPUT_SOURCE_CLASS_MASK = 0x000000ff,
-
- AINPUT_SOURCE_CLASS_BUTTON = 0x00000001,
- AINPUT_SOURCE_CLASS_POINTER = 0x00000002,
- AINPUT_SOURCE_CLASS_NAVIGATION = 0x00000004,
- AINPUT_SOURCE_CLASS_POSITION = 0x00000008,
- AINPUT_SOURCE_CLASS_JOYSTICK = 0x00000010,
-};
-
-enum {
- AINPUT_SOURCE_UNKNOWN = 0x00000000,
-
- AINPUT_SOURCE_KEYBOARD = 0x00000100 | AINPUT_SOURCE_CLASS_BUTTON,
- AINPUT_SOURCE_DPAD = 0x00000200 | AINPUT_SOURCE_CLASS_BUTTON,
- AINPUT_SOURCE_GAMEPAD = 0x00000400 | AINPUT_SOURCE_CLASS_BUTTON,
- AINPUT_SOURCE_TOUCHSCREEN = 0x00001000 | AINPUT_SOURCE_CLASS_POINTER,
- AINPUT_SOURCE_MOUSE = 0x00002000 | AINPUT_SOURCE_CLASS_POINTER,
- AINPUT_SOURCE_STYLUS = 0x00004000 | AINPUT_SOURCE_CLASS_POINTER,
- AINPUT_SOURCE_TRACKBALL = 0x00010000 | AINPUT_SOURCE_CLASS_NAVIGATION,
- AINPUT_SOURCE_TOUCHPAD = 0x00100000 | AINPUT_SOURCE_CLASS_POSITION,
- AINPUT_SOURCE_JOYSTICK = 0x01000000 | AINPUT_SOURCE_CLASS_JOYSTICK,
-
- AINPUT_SOURCE_ANY = 0xffffff00,
-};
-
-/*
- * Keyboard types.
- *
- * Refer to the documentation on android.view.InputDevice for more details.
- */
-enum {
- AINPUT_KEYBOARD_TYPE_NONE = 0,
- AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC = 1,
- AINPUT_KEYBOARD_TYPE_ALPHABETIC = 2,
-};
-
-/*
- * Constants used to retrieve information about the range of motion for a particular
- * coordinate of a motion event.
- *
- * Refer to the documentation on android.view.InputDevice for more details about input sources
- * and their correct interpretation.
- *
- * DEPRECATION NOTICE: These constants are deprecated. Use AMOTION_EVENT_AXIS_* constants instead.
- */
-enum {
- AINPUT_MOTION_RANGE_X = AMOTION_EVENT_AXIS_X,
- AINPUT_MOTION_RANGE_Y = AMOTION_EVENT_AXIS_Y,
- AINPUT_MOTION_RANGE_PRESSURE = AMOTION_EVENT_AXIS_PRESSURE,
- AINPUT_MOTION_RANGE_SIZE = AMOTION_EVENT_AXIS_SIZE,
- AINPUT_MOTION_RANGE_TOUCH_MAJOR = AMOTION_EVENT_AXIS_TOUCH_MAJOR,
- AINPUT_MOTION_RANGE_TOUCH_MINOR = AMOTION_EVENT_AXIS_TOUCH_MINOR,
- AINPUT_MOTION_RANGE_TOOL_MAJOR = AMOTION_EVENT_AXIS_TOOL_MAJOR,
- AINPUT_MOTION_RANGE_TOOL_MINOR = AMOTION_EVENT_AXIS_TOOL_MINOR,
- AINPUT_MOTION_RANGE_ORIENTATION = AMOTION_EVENT_AXIS_ORIENTATION,
-} __attribute__ ((deprecated));
-
-
-/*
- * Input event accessors.
- *
- * Note that most functions can only be used on input events that are of a given type.
- * Calling these functions on input events of other types will yield undefined behavior.
- */
-
-/*** Accessors for all input events. ***/
-
-/* Get the input event type. */
-int32_t AInputEvent_getType(const AInputEvent* event);
-
-/* Get the id for the device that an input event came from.
- *
- * Input events can be generated by multiple different input devices.
- * Use the input device id to obtain information about the input
- * device that was responsible for generating a particular event.
- *
- * An input device id of 0 indicates that the event didn't come from a physical device;
- * other numbers are arbitrary and you shouldn't depend on the values.
- * Use the provided input device query API to obtain information about input devices.
- */
-int32_t AInputEvent_getDeviceId(const AInputEvent* event);
-
-/* Get the input event source. */
-int32_t AInputEvent_getSource(const AInputEvent* event);
-
-/*** Accessors for key events only. ***/
-
-/* Get the key event action. */
-int32_t AKeyEvent_getAction(const AInputEvent* key_event);
-
-/* Get the key event flags. */
-int32_t AKeyEvent_getFlags(const AInputEvent* key_event);
-
-/* Get the key code of the key event.
- * This is the physical key that was pressed, not the Unicode character. */
-int32_t AKeyEvent_getKeyCode(const AInputEvent* key_event);
-
-/* Get the hardware key id of this key event.
- * These values are not reliable and vary from device to device. */
-int32_t AKeyEvent_getScanCode(const AInputEvent* key_event);
-
-/* Get the meta key state. */
-int32_t AKeyEvent_getMetaState(const AInputEvent* key_event);
-
-/* Get the repeat count of the event.
- * For both key up an key down events, this is the number of times the key has
- * repeated with the first down starting at 0 and counting up from there. For
- * multiple key events, this is the number of down/up pairs that have occurred. */
-int32_t AKeyEvent_getRepeatCount(const AInputEvent* key_event);
-
-/* Get the time of the most recent key down event, in the
- * java.lang.System.nanoTime() time base. If this is a down event,
- * this will be the same as eventTime.
- * Note that when chording keys, this value is the down time of the most recently
- * pressed key, which may not be the same physical key of this event. */
-int64_t AKeyEvent_getDownTime(const AInputEvent* key_event);
-
-/* Get the time this event occurred, in the
- * java.lang.System.nanoTime() time base. */
-int64_t AKeyEvent_getEventTime(const AInputEvent* key_event);
-
-/*** Accessors for motion events only. ***/
-
-/* Get the combined motion event action code and pointer index. */
-int32_t AMotionEvent_getAction(const AInputEvent* motion_event);
-
-/* Get the motion event flags. */
-int32_t AMotionEvent_getFlags(const AInputEvent* motion_event);
-
-/* Get the state of any meta / modifier keys that were in effect when the
- * event was generated. */
-int32_t AMotionEvent_getMetaState(const AInputEvent* motion_event);
-
-/* Get the button state of all buttons that are pressed. */
-int32_t AMotionEvent_getButtonState(const AInputEvent* motion_event);
-
-/* Get a bitfield indicating which edges, if any, were touched by this motion event.
- * For touch events, clients can use this to determine if the user's finger was
- * touching the edge of the display. */
-int32_t AMotionEvent_getEdgeFlags(const AInputEvent* motion_event);
-
-/* Get the time when the user originally pressed down to start a stream of
- * position events, in the java.lang.System.nanoTime() time base. */
-int64_t AMotionEvent_getDownTime(const AInputEvent* motion_event);
-
-/* Get the time when this specific event was generated,
- * in the java.lang.System.nanoTime() time base. */
-int64_t AMotionEvent_getEventTime(const AInputEvent* motion_event);
-
-/* Get the X coordinate offset.
- * For touch events on the screen, this is the delta that was added to the raw
- * screen coordinates to adjust for the absolute position of the containing windows
- * and views. */
-float AMotionEvent_getXOffset(const AInputEvent* motion_event);
-
-/* Get the precision of the Y coordinates being reported.
- * For touch events on the screen, this is the delta that was added to the raw
- * screen coordinates to adjust for the absolute position of the containing windows
- * and views. */
-float AMotionEvent_getYOffset(const AInputEvent* motion_event);
-
-/* Get the precision of the X coordinates being reported.
- * You can multiply this number with an X coordinate sample to find the
- * actual hardware value of the X coordinate. */
-float AMotionEvent_getXPrecision(const AInputEvent* motion_event);
-
-/* Get the precision of the Y coordinates being reported.
- * You can multiply this number with a Y coordinate sample to find the
- * actual hardware value of the Y coordinate. */
-float AMotionEvent_getYPrecision(const AInputEvent* motion_event);
-
-/* Get the number of pointers of data contained in this event.
- * Always >= 1. */
-size_t AMotionEvent_getPointerCount(const AInputEvent* motion_event);
-
-/* Get the pointer identifier associated with a particular pointer
- * data index in this event. The identifier tells you the actual pointer
- * number associated with the data, accounting for individual pointers
- * going up and down since the start of the current gesture. */
-int32_t AMotionEvent_getPointerId(const AInputEvent* motion_event, size_t pointer_index);
-
-/* Get the tool type of a pointer for the given pointer index.
- * The tool type indicates the type of tool used to make contact such as a
- * finger or stylus, if known. */
-int32_t AMotionEvent_getToolType(const AInputEvent* motion_event, size_t pointer_index);
-
-/* Get the original raw X coordinate of this event.
- * For touch events on the screen, this is the original location of the event
- * on the screen, before it had been adjusted for the containing window
- * and views. */
-float AMotionEvent_getRawX(const AInputEvent* motion_event, size_t pointer_index);
-
-/* Get the original raw X coordinate of this event.
- * For touch events on the screen, this is the original location of the event
- * on the screen, before it had been adjusted for the containing window
- * and views. */
-float AMotionEvent_getRawY(const AInputEvent* motion_event, size_t pointer_index);
-
-/* Get the current X coordinate of this event for the given pointer index.
- * Whole numbers are pixels; the value may have a fraction for input devices
- * that are sub-pixel precise. */
-float AMotionEvent_getX(const AInputEvent* motion_event, size_t pointer_index);
-
-/* Get the current Y coordinate of this event for the given pointer index.
- * Whole numbers are pixels; the value may have a fraction for input devices
- * that are sub-pixel precise. */
-float AMotionEvent_getY(const AInputEvent* motion_event, size_t pointer_index);
-
-/* Get the current pressure of this event for the given pointer index.
- * The pressure generally ranges from 0 (no pressure at all) to 1 (normal pressure),
- * although values higher than 1 may be generated depending on the calibration of
- * the input device. */
-float AMotionEvent_getPressure(const AInputEvent* motion_event, size_t pointer_index);
-
-/* Get the current scaled value of the approximate size for the given pointer index.
- * This represents some approximation of the area of the screen being
- * pressed; the actual value in pixels corresponding to the
- * touch is normalized with the device specific range of values
- * and scaled to a value between 0 and 1. The value of size can be used to
- * determine fat touch events. */
-float AMotionEvent_getSize(const AInputEvent* motion_event, size_t pointer_index);
-
-/* Get the current length of the major axis of an ellipse that describes the touch area
- * at the point of contact for the given pointer index. */
-float AMotionEvent_getTouchMajor(const AInputEvent* motion_event, size_t pointer_index);
-
-/* Get the current length of the minor axis of an ellipse that describes the touch area
- * at the point of contact for the given pointer index. */
-float AMotionEvent_getTouchMinor(const AInputEvent* motion_event, size_t pointer_index);
-
-/* Get the current length of the major axis of an ellipse that describes the size
- * of the approaching tool for the given pointer index.
- * The tool area represents the estimated size of the finger or pen that is
- * touching the device independent of its actual touch area at the point of contact. */
-float AMotionEvent_getToolMajor(const AInputEvent* motion_event, size_t pointer_index);
-
-/* Get the current length of the minor axis of an ellipse that describes the size
- * of the approaching tool for the given pointer index.
- * The tool area represents the estimated size of the finger or pen that is
- * touching the device independent of its actual touch area at the point of contact. */
-float AMotionEvent_getToolMinor(const AInputEvent* motion_event, size_t pointer_index);
-
-/* Get the current orientation of the touch area and tool area in radians clockwise from
- * vertical for the given pointer index.
- * An angle of 0 degrees indicates that the major axis of contact is oriented
- * upwards, is perfectly circular or is of unknown orientation. A positive angle
- * indicates that the major axis of contact is oriented to the right. A negative angle
- * indicates that the major axis of contact is oriented to the left.
- * The full range is from -PI/2 radians (finger pointing fully left) to PI/2 radians
- * (finger pointing fully right). */
-float AMotionEvent_getOrientation(const AInputEvent* motion_event, size_t pointer_index);
-
-/* Get the value of the request axis for the given pointer index. */
-float AMotionEvent_getAxisValue(const AInputEvent* motion_event,
- int32_t axis, size_t pointer_index);
-
-/* Get the number of historical points in this event. These are movements that
- * have occurred between this event and the previous event. This only applies
- * to AMOTION_EVENT_ACTION_MOVE events -- all other actions will have a size of 0.
- * Historical samples are indexed from oldest to newest. */
-size_t AMotionEvent_getHistorySize(const AInputEvent* motion_event);
-
-/* Get the time that a historical movement occurred between this event and
- * the previous event, in the java.lang.System.nanoTime() time base. */
-int64_t AMotionEvent_getHistoricalEventTime(AInputEvent* motion_event,
- size_t history_index);
-
-/* Get the historical raw X coordinate of this event for the given pointer index that
- * occurred between this event and the previous motion event.
- * For touch events on the screen, this is the original location of the event
- * on the screen, before it had been adjusted for the containing window
- * and views.
- * Whole numbers are pixels; the value may have a fraction for input devices
- * that are sub-pixel precise. */
-float AMotionEvent_getHistoricalRawX(const AInputEvent* motion_event, size_t pointer_index,
- size_t history_index);
-
-/* Get the historical raw Y coordinate of this event for the given pointer index that
- * occurred between this event and the previous motion event.
- * For touch events on the screen, this is the original location of the event
- * on the screen, before it had been adjusted for the containing window
- * and views.
- * Whole numbers are pixels; the value may have a fraction for input devices
- * that are sub-pixel precise. */
-float AMotionEvent_getHistoricalRawY(const AInputEvent* motion_event, size_t pointer_index,
- size_t history_index);
-
-/* Get the historical X coordinate of this event for the given pointer index that
- * occurred between this event and the previous motion event.
- * Whole numbers are pixels; the value may have a fraction for input devices
- * that are sub-pixel precise. */
-float AMotionEvent_getHistoricalX(AInputEvent* motion_event, size_t pointer_index,
- size_t history_index);
-
-/* Get the historical Y coordinate of this event for the given pointer index that
- * occurred between this event and the previous motion event.
- * Whole numbers are pixels; the value may have a fraction for input devices
- * that are sub-pixel precise. */
-float AMotionEvent_getHistoricalY(AInputEvent* motion_event, size_t pointer_index,
- size_t history_index);
-
-/* Get the historical pressure of this event for the given pointer index that
- * occurred between this event and the previous motion event.
- * The pressure generally ranges from 0 (no pressure at all) to 1 (normal pressure),
- * although values higher than 1 may be generated depending on the calibration of
- * the input device. */
-float AMotionEvent_getHistoricalPressure(AInputEvent* motion_event, size_t pointer_index,
- size_t history_index);
-
-/* Get the current scaled value of the approximate size for the given pointer index that
- * occurred between this event and the previous motion event.
- * This represents some approximation of the area of the screen being
- * pressed; the actual value in pixels corresponding to the
- * touch is normalized with the device specific range of values
- * and scaled to a value between 0 and 1. The value of size can be used to
- * determine fat touch events. */
-float AMotionEvent_getHistoricalSize(AInputEvent* motion_event, size_t pointer_index,
- size_t history_index);
-
-/* Get the historical length of the major axis of an ellipse that describes the touch area
- * at the point of contact for the given pointer index that
- * occurred between this event and the previous motion event. */
-float AMotionEvent_getHistoricalTouchMajor(const AInputEvent* motion_event, size_t pointer_index,
- size_t history_index);
-
-/* Get the historical length of the minor axis of an ellipse that describes the touch area
- * at the point of contact for the given pointer index that
- * occurred between this event and the previous motion event. */
-float AMotionEvent_getHistoricalTouchMinor(const AInputEvent* motion_event, size_t pointer_index,
- size_t history_index);
-
-/* Get the historical length of the major axis of an ellipse that describes the size
- * of the approaching tool for the given pointer index that
- * occurred between this event and the previous motion event.
- * The tool area represents the estimated size of the finger or pen that is
- * touching the device independent of its actual touch area at the point of contact. */
-float AMotionEvent_getHistoricalToolMajor(const AInputEvent* motion_event, size_t pointer_index,
- size_t history_index);
-
-/* Get the historical length of the minor axis of an ellipse that describes the size
- * of the approaching tool for the given pointer index that
- * occurred between this event and the previous motion event.
- * The tool area represents the estimated size of the finger or pen that is
- * touching the device independent of its actual touch area at the point of contact. */
-float AMotionEvent_getHistoricalToolMinor(const AInputEvent* motion_event, size_t pointer_index,
- size_t history_index);
-
-/* Get the historical orientation of the touch area and tool area in radians clockwise from
- * vertical for the given pointer index that
- * occurred between this event and the previous motion event.
- * An angle of 0 degrees indicates that the major axis of contact is oriented
- * upwards, is perfectly circular or is of unknown orientation. A positive angle
- * indicates that the major axis of contact is oriented to the right. A negative angle
- * indicates that the major axis of contact is oriented to the left.
- * The full range is from -PI/2 radians (finger pointing fully left) to PI/2 radians
- * (finger pointing fully right). */
-float AMotionEvent_getHistoricalOrientation(const AInputEvent* motion_event, size_t pointer_index,
- size_t history_index);
-
-/* Get the historical value of the request axis for the given pointer index
- * that occurred between this event and the previous motion event. */
-float AMotionEvent_getHistoricalAxisValue(const AInputEvent* motion_event,
- int32_t axis, size_t pointer_index, size_t history_index);
-
-
-/*
- * Input queue
- *
- * An input queue is the facility through which you retrieve input
- * events.
- */
-struct AInputQueue;
-typedef struct AInputQueue AInputQueue;
-
-/*
- * Add this input queue to a looper for processing. See
- * ALooper_addFd() for information on the ident, callback, and data params.
- */
-void AInputQueue_attachLooper(AInputQueue* queue, ALooper* looper,
- int ident, ALooper_callbackFunc callback, void* data);
-
-/*
- * Remove the input queue from the looper it is currently attached to.
- */
-void AInputQueue_detachLooper(AInputQueue* queue);
-
-/*
- * Returns true if there are one or more events available in the
- * input queue. Returns 1 if the queue has events; 0 if
- * it does not have events; and a negative value if there is an error.
- */
-int32_t AInputQueue_hasEvents(AInputQueue* queue);
-
-/*
- * Returns the next available event from the queue. Returns a negative
- * value if no events are available or an error has occurred.
- */
-int32_t AInputQueue_getEvent(AInputQueue* queue, AInputEvent** outEvent);
-
-/*
- * Sends the key for standard pre-dispatching -- that is, possibly deliver
- * it to the current IME to be consumed before the app. Returns 0 if it
- * was not pre-dispatched, meaning you can process it right now. If non-zero
- * is returned, you must abandon the current event processing and allow the
- * event to appear again in the event queue (if it does not get consumed during
- * pre-dispatching).
- */
-int32_t AInputQueue_preDispatchEvent(AInputQueue* queue, AInputEvent* event);
-
-/*
- * Report that dispatching has finished with the given event.
- * This must be called after receiving an event with AInputQueue_get_event().
- */
-void AInputQueue_finishEvent(AInputQueue* queue, AInputEvent* event, int handled);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // _ANDROID_INPUT_H
diff --git a/native/include/android/keycodes.h b/native/include/android/keycodes.h
deleted file mode 100644
index 8414ff6..0000000
--- a/native/include/android/keycodes.h
+++ /dev/null
@@ -1,266 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _ANDROID_KEYCODES_H
-#define _ANDROID_KEYCODES_H
-
-/******************************************************************
- *
- * IMPORTANT NOTICE:
- *
- * This file is part of Android's set of stable system headers
- * exposed by the Android NDK (Native Development Kit).
- *
- * Third-party source AND binary code relies on the definitions
- * here to be FROZEN ON ALL UPCOMING PLATFORM RELEASES.
- *
- * - DO NOT MODIFY ENUMS (EXCEPT IF YOU ADD NEW 32-BIT VALUES)
- * - DO NOT MODIFY CONSTANTS OR FUNCTIONAL MACROS
- * - DO NOT CHANGE THE SIGNATURE OF FUNCTIONS IN ANY WAY
- * - DO NOT CHANGE THE LAYOUT OR SIZE OF STRUCTURES
- */
-
-#include <sys/types.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Key codes.
- */
-enum {
- AKEYCODE_UNKNOWN = 0,
- AKEYCODE_SOFT_LEFT = 1,
- AKEYCODE_SOFT_RIGHT = 2,
- AKEYCODE_HOME = 3,
- AKEYCODE_BACK = 4,
- AKEYCODE_CALL = 5,
- AKEYCODE_ENDCALL = 6,
- AKEYCODE_0 = 7,
- AKEYCODE_1 = 8,
- AKEYCODE_2 = 9,
- AKEYCODE_3 = 10,
- AKEYCODE_4 = 11,
- AKEYCODE_5 = 12,
- AKEYCODE_6 = 13,
- AKEYCODE_7 = 14,
- AKEYCODE_8 = 15,
- AKEYCODE_9 = 16,
- AKEYCODE_STAR = 17,
- AKEYCODE_POUND = 18,
- AKEYCODE_DPAD_UP = 19,
- AKEYCODE_DPAD_DOWN = 20,
- AKEYCODE_DPAD_LEFT = 21,
- AKEYCODE_DPAD_RIGHT = 22,
- AKEYCODE_DPAD_CENTER = 23,
- AKEYCODE_VOLUME_UP = 24,
- AKEYCODE_VOLUME_DOWN = 25,
- AKEYCODE_POWER = 26,
- AKEYCODE_CAMERA = 27,
- AKEYCODE_CLEAR = 28,
- AKEYCODE_A = 29,
- AKEYCODE_B = 30,
- AKEYCODE_C = 31,
- AKEYCODE_D = 32,
- AKEYCODE_E = 33,
- AKEYCODE_F = 34,
- AKEYCODE_G = 35,
- AKEYCODE_H = 36,
- AKEYCODE_I = 37,
- AKEYCODE_J = 38,
- AKEYCODE_K = 39,
- AKEYCODE_L = 40,
- AKEYCODE_M = 41,
- AKEYCODE_N = 42,
- AKEYCODE_O = 43,
- AKEYCODE_P = 44,
- AKEYCODE_Q = 45,
- AKEYCODE_R = 46,
- AKEYCODE_S = 47,
- AKEYCODE_T = 48,
- AKEYCODE_U = 49,
- AKEYCODE_V = 50,
- AKEYCODE_W = 51,
- AKEYCODE_X = 52,
- AKEYCODE_Y = 53,
- AKEYCODE_Z = 54,
- AKEYCODE_COMMA = 55,
- AKEYCODE_PERIOD = 56,
- AKEYCODE_ALT_LEFT = 57,
- AKEYCODE_ALT_RIGHT = 58,
- AKEYCODE_SHIFT_LEFT = 59,
- AKEYCODE_SHIFT_RIGHT = 60,
- AKEYCODE_TAB = 61,
- AKEYCODE_SPACE = 62,
- AKEYCODE_SYM = 63,
- AKEYCODE_EXPLORER = 64,
- AKEYCODE_ENVELOPE = 65,
- AKEYCODE_ENTER = 66,
- AKEYCODE_DEL = 67,
- AKEYCODE_GRAVE = 68,
- AKEYCODE_MINUS = 69,
- AKEYCODE_EQUALS = 70,
- AKEYCODE_LEFT_BRACKET = 71,
- AKEYCODE_RIGHT_BRACKET = 72,
- AKEYCODE_BACKSLASH = 73,
- AKEYCODE_SEMICOLON = 74,
- AKEYCODE_APOSTROPHE = 75,
- AKEYCODE_SLASH = 76,
- AKEYCODE_AT = 77,
- AKEYCODE_NUM = 78,
- AKEYCODE_HEADSETHOOK = 79,
- AKEYCODE_FOCUS = 80, // *Camera* focus
- AKEYCODE_PLUS = 81,
- AKEYCODE_MENU = 82,
- AKEYCODE_NOTIFICATION = 83,
- AKEYCODE_SEARCH = 84,
- AKEYCODE_MEDIA_PLAY_PAUSE= 85,
- AKEYCODE_MEDIA_STOP = 86,
- AKEYCODE_MEDIA_NEXT = 87,
- AKEYCODE_MEDIA_PREVIOUS = 88,
- AKEYCODE_MEDIA_REWIND = 89,
- AKEYCODE_MEDIA_FAST_FORWARD = 90,
- AKEYCODE_MUTE = 91,
- AKEYCODE_PAGE_UP = 92,
- AKEYCODE_PAGE_DOWN = 93,
- AKEYCODE_PICTSYMBOLS = 94,
- AKEYCODE_SWITCH_CHARSET = 95,
- AKEYCODE_BUTTON_A = 96,
- AKEYCODE_BUTTON_B = 97,
- AKEYCODE_BUTTON_C = 98,
- AKEYCODE_BUTTON_X = 99,
- AKEYCODE_BUTTON_Y = 100,
- AKEYCODE_BUTTON_Z = 101,
- AKEYCODE_BUTTON_L1 = 102,
- AKEYCODE_BUTTON_R1 = 103,
- AKEYCODE_BUTTON_L2 = 104,
- AKEYCODE_BUTTON_R2 = 105,
- AKEYCODE_BUTTON_THUMBL = 106,
- AKEYCODE_BUTTON_THUMBR = 107,
- AKEYCODE_BUTTON_START = 108,
- AKEYCODE_BUTTON_SELECT = 109,
- AKEYCODE_BUTTON_MODE = 110,
- AKEYCODE_ESCAPE = 111,
- AKEYCODE_FORWARD_DEL = 112,
- AKEYCODE_CTRL_LEFT = 113,
- AKEYCODE_CTRL_RIGHT = 114,
- AKEYCODE_CAPS_LOCK = 115,
- AKEYCODE_SCROLL_LOCK = 116,
- AKEYCODE_META_LEFT = 117,
- AKEYCODE_META_RIGHT = 118,
- AKEYCODE_FUNCTION = 119,
- AKEYCODE_SYSRQ = 120,
- AKEYCODE_BREAK = 121,
- AKEYCODE_MOVE_HOME = 122,
- AKEYCODE_MOVE_END = 123,
- AKEYCODE_INSERT = 124,
- AKEYCODE_FORWARD = 125,
- AKEYCODE_MEDIA_PLAY = 126,
- AKEYCODE_MEDIA_PAUSE = 127,
- AKEYCODE_MEDIA_CLOSE = 128,
- AKEYCODE_MEDIA_EJECT = 129,
- AKEYCODE_MEDIA_RECORD = 130,
- AKEYCODE_F1 = 131,
- AKEYCODE_F2 = 132,
- AKEYCODE_F3 = 133,
- AKEYCODE_F4 = 134,
- AKEYCODE_F5 = 135,
- AKEYCODE_F6 = 136,
- AKEYCODE_F7 = 137,
- AKEYCODE_F8 = 138,
- AKEYCODE_F9 = 139,
- AKEYCODE_F10 = 140,
- AKEYCODE_F11 = 141,
- AKEYCODE_F12 = 142,
- AKEYCODE_NUM_LOCK = 143,
- AKEYCODE_NUMPAD_0 = 144,
- AKEYCODE_NUMPAD_1 = 145,
- AKEYCODE_NUMPAD_2 = 146,
- AKEYCODE_NUMPAD_3 = 147,
- AKEYCODE_NUMPAD_4 = 148,
- AKEYCODE_NUMPAD_5 = 149,
- AKEYCODE_NUMPAD_6 = 150,
- AKEYCODE_NUMPAD_7 = 151,
- AKEYCODE_NUMPAD_8 = 152,
- AKEYCODE_NUMPAD_9 = 153,
- AKEYCODE_NUMPAD_DIVIDE = 154,
- AKEYCODE_NUMPAD_MULTIPLY = 155,
- AKEYCODE_NUMPAD_SUBTRACT = 156,
- AKEYCODE_NUMPAD_ADD = 157,
- AKEYCODE_NUMPAD_DOT = 158,
- AKEYCODE_NUMPAD_COMMA = 159,
- AKEYCODE_NUMPAD_ENTER = 160,
- AKEYCODE_NUMPAD_EQUALS = 161,
- AKEYCODE_NUMPAD_LEFT_PAREN = 162,
- AKEYCODE_NUMPAD_RIGHT_PAREN = 163,
- AKEYCODE_VOLUME_MUTE = 164,
- AKEYCODE_INFO = 165,
- AKEYCODE_CHANNEL_UP = 166,
- AKEYCODE_CHANNEL_DOWN = 167,
- AKEYCODE_ZOOM_IN = 168,
- AKEYCODE_ZOOM_OUT = 169,
- AKEYCODE_TV = 170,
- AKEYCODE_WINDOW = 171,
- AKEYCODE_GUIDE = 172,
- AKEYCODE_DVR = 173,
- AKEYCODE_BOOKMARK = 174,
- AKEYCODE_CAPTIONS = 175,
- AKEYCODE_SETTINGS = 176,
- AKEYCODE_TV_POWER = 177,
- AKEYCODE_TV_INPUT = 178,
- AKEYCODE_STB_POWER = 179,
- AKEYCODE_STB_INPUT = 180,
- AKEYCODE_AVR_POWER = 181,
- AKEYCODE_AVR_INPUT = 182,
- AKEYCODE_PROG_RED = 183,
- AKEYCODE_PROG_GREEN = 184,
- AKEYCODE_PROG_YELLOW = 185,
- AKEYCODE_PROG_BLUE = 186,
- AKEYCODE_APP_SWITCH = 187,
- AKEYCODE_BUTTON_1 = 188,
- AKEYCODE_BUTTON_2 = 189,
- AKEYCODE_BUTTON_3 = 190,
- AKEYCODE_BUTTON_4 = 191,
- AKEYCODE_BUTTON_5 = 192,
- AKEYCODE_BUTTON_6 = 193,
- AKEYCODE_BUTTON_7 = 194,
- AKEYCODE_BUTTON_8 = 195,
- AKEYCODE_BUTTON_9 = 196,
- AKEYCODE_BUTTON_10 = 197,
- AKEYCODE_BUTTON_11 = 198,
- AKEYCODE_BUTTON_12 = 199,
- AKEYCODE_BUTTON_13 = 200,
- AKEYCODE_BUTTON_14 = 201,
- AKEYCODE_BUTTON_15 = 202,
- AKEYCODE_BUTTON_16 = 203,
- AKEYCODE_LANGUAGE_SWITCH = 204,
- AKEYCODE_MANNER_MODE = 205,
- AKEYCODE_3D_MODE = 206,
- AKEYCODE_CONTACTS = 207,
- AKEYCODE_CALENDAR = 208,
- AKEYCODE_MUSIC = 209,
- AKEYCODE_CALCULATOR = 210,
-
- // NOTE: If you add a new keycode here you must also add it to several other files.
- // Refer to frameworks/base/core/java/android/view/KeyEvent.java for the full list.
-};
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // _ANDROID_KEYCODES_H
diff --git a/native/include/android/looper.h b/native/include/android/looper.h
deleted file mode 100644
index 24e3967..0000000
--- a/native/include/android/looper.h
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-#ifndef ANDROID_LOOPER_H
-#define ANDROID_LOOPER_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * ALooper
- *
- * A looper is the state tracking an event loop for a thread.
- * Loopers do not define event structures or other such things; rather
- * they are a lower-level facility to attach one or more discrete objects
- * listening for an event. An "event" here is simply data available on
- * a file descriptor: each attached object has an associated file descriptor,
- * and waiting for "events" means (internally) polling on all of these file
- * descriptors until one or more of them have data available.
- *
- * A thread can have only one ALooper associated with it.
- */
-struct ALooper;
-typedef struct ALooper ALooper;
-
-/**
- * Returns the looper associated with the calling thread, or NULL if
- * there is not one.
- */
-ALooper* ALooper_forThread();
-
-enum {
- /**
- * Option for ALooper_prepare: this looper will accept calls to
- * ALooper_addFd() that do not have a callback (that is provide NULL
- * for the callback). In this case the caller of ALooper_pollOnce()
- * or ALooper_pollAll() MUST check the return from these functions to
- * discover when data is available on such fds and process it.
- */
- ALOOPER_PREPARE_ALLOW_NON_CALLBACKS = 1<<0
-};
-
-/**
- * Prepares a looper associated with the calling thread, and returns it.
- * If the thread already has a looper, it is returned. Otherwise, a new
- * one is created, associated with the thread, and returned.
- *
- * The opts may be ALOOPER_PREPARE_ALLOW_NON_CALLBACKS or 0.
- */
-ALooper* ALooper_prepare(int opts);
-
-enum {
- /**
- * Result from ALooper_pollOnce() and ALooper_pollAll():
- * The poll was awoken using wake() before the timeout expired
- * and no callbacks were executed and no other file descriptors were ready.
- */
- ALOOPER_POLL_WAKE = -1,
-
- /**
- * Result from ALooper_pollOnce() and ALooper_pollAll():
- * One or more callbacks were executed.
- */
- ALOOPER_POLL_CALLBACK = -2,
-
- /**
- * Result from ALooper_pollOnce() and ALooper_pollAll():
- * The timeout expired.
- */
- ALOOPER_POLL_TIMEOUT = -3,
-
- /**
- * Result from ALooper_pollOnce() and ALooper_pollAll():
- * An error occurred.
- */
- ALOOPER_POLL_ERROR = -4,
-};
-
-/**
- * Acquire a reference on the given ALooper object. This prevents the object
- * from being deleted until the reference is removed. This is only needed
- * to safely hand an ALooper from one thread to another.
- */
-void ALooper_acquire(ALooper* looper);
-
-/**
- * Remove a reference that was previously acquired with ALooper_acquire().
- */
-void ALooper_release(ALooper* looper);
-
-/**
- * Flags for file descriptor events that a looper can monitor.
- *
- * These flag bits can be combined to monitor multiple events at once.
- */
-enum {
- /**
- * The file descriptor is available for read operations.
- */
- ALOOPER_EVENT_INPUT = 1 << 0,
-
- /**
- * The file descriptor is available for write operations.
- */
- ALOOPER_EVENT_OUTPUT = 1 << 1,
-
- /**
- * The file descriptor has encountered an error condition.
- *
- * The looper always sends notifications about errors; it is not necessary
- * to specify this event flag in the requested event set.
- */
- ALOOPER_EVENT_ERROR = 1 << 2,
-
- /**
- * The file descriptor was hung up.
- * For example, indicates that the remote end of a pipe or socket was closed.
- *
- * The looper always sends notifications about hangups; it is not necessary
- * to specify this event flag in the requested event set.
- */
- ALOOPER_EVENT_HANGUP = 1 << 3,
-
- /**
- * The file descriptor is invalid.
- * For example, the file descriptor was closed prematurely.
- *
- * The looper always sends notifications about invalid file descriptors; it is not necessary
- * to specify this event flag in the requested event set.
- */
- ALOOPER_EVENT_INVALID = 1 << 4,
-};
-
-/**
- * For callback-based event loops, this is the prototype of the function
- * that is called when a file descriptor event occurs.
- * It is given the file descriptor it is associated with,
- * a bitmask of the poll events that were triggered (typically ALOOPER_EVENT_INPUT),
- * and the data pointer that was originally supplied.
- *
- * Implementations should return 1 to continue receiving callbacks, or 0
- * to have this file descriptor and callback unregistered from the looper.
- */
-typedef int (*ALooper_callbackFunc)(int fd, int events, void* data);
-
-/**
- * Waits for events to be available, with optional timeout in milliseconds.
- * Invokes callbacks for all file descriptors on which an event occurred.
- *
- * If the timeout is zero, returns immediately without blocking.
- * If the timeout is negative, waits indefinitely until an event appears.
- *
- * Returns ALOOPER_POLL_WAKE if the poll was awoken using wake() before
- * the timeout expired and no callbacks were invoked and no other file
- * descriptors were ready.
- *
- * Returns ALOOPER_POLL_CALLBACK if one or more callbacks were invoked.
- *
- * Returns ALOOPER_POLL_TIMEOUT if there was no data before the given
- * timeout expired.
- *
- * Returns ALOOPER_POLL_ERROR if an error occurred.
- *
- * 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 outFd, outEvents and outData will contain the poll
- * events and data associated with the fd, otherwise they will be set to NULL.
- *
- * This method does not return until it has finished invoking the appropriate callbacks
- * for all file descriptors that were signalled.
- */
-int ALooper_pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData);
-
-/**
- * Like ALooper_pollOnce(), but performs all pending callbacks until all
- * data has been consumed or a file descriptor is available with no callback.
- * This function will never return ALOOPER_POLL_CALLBACK.
- */
-int ALooper_pollAll(int timeoutMillis, int* outFd, int* outEvents, void** outData);
-
-/**
- * Wakes the poll asynchronously.
- *
- * This method can be called on any thread.
- * This method returns immediately.
- */
-void ALooper_wake(ALooper* looper);
-
-/**
- * Adds a new file descriptor to be polled by the looper.
- * If the same file 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().
- * The identifier 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 ALOOPER_EVENT_INPUT.
- * "callback" is the function to call when there is an event on the file descriptor.
- * "data" is a private data pointer to supply to the callback.
- *
- * There are two main uses of this function:
- *
- * (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. The 'ident' is ignored in this case.
- *
- * (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.
- *
- * Returns 1 if the file descriptor was added or -1 if an error occurred.
- *
- * This method can be called on any thread.
- * This method may block briefly if it needs to wake the poll.
- */
-int ALooper_addFd(ALooper* looper, int fd, int ident, int events,
- ALooper_callbackFunc callback, void* data);
-
-/**
- * Removes a previously added file descriptor from the looper.
- *
- * When this method returns, it is safe to close the file descriptor since the looper
- * will no longer have a reference to it. However, it is possible for the callback to
- * already be running or for it to run one last time if the file descriptor was already
- * signalled. Calling code is responsible for ensuring that this case is safely handled.
- * For example, if the callback takes care of removing itself during its own execution either
- * by returning 0 or by calling this method, then it can be guaranteed to not be invoked
- * again at any later time unless registered anew.
- *
- * Returns 1 if the file descriptor was removed, 0 if none was previously registered
- * or -1 if an error occurred.
- *
- * This method can be called on any thread.
- * This method may block briefly if it needs to wake the poll.
- */
-int ALooper_removeFd(ALooper* looper, int fd);
-
-#ifdef __cplusplus
-};
-#endif
-
-#endif // ANDROID_NATIVE_WINDOW_H
diff --git a/native/include/android/native_activity.h b/native/include/android/native_activity.h
deleted file mode 100644
index bc70f88..0000000
--- a/native/include/android/native_activity.h
+++ /dev/null
@@ -1,310 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-#ifndef ANDROID_NATIVE_ACTIVITY_H
-#define ANDROID_NATIVE_ACTIVITY_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <jni.h>
-
-#include <android/asset_manager.h>
-#include <android/input.h>
-#include <android/native_window.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct ANativeActivityCallbacks;
-
-/**
- * This structure defines the native side of an android.app.NativeActivity.
- * It is created by the framework, and handed to the application's native
- * code as it is being launched.
- */
-typedef struct ANativeActivity {
- /**
- * Pointer to the callback function table of the native application.
- * You can set the functions here to your own callbacks. The callbacks
- * pointer itself here should not be changed; it is allocated and managed
- * for you by the framework.
- */
- struct ANativeActivityCallbacks* callbacks;
-
- /**
- * The global handle on the process's Java VM.
- */
- JavaVM* vm;
-
- /**
- * JNI context for the main thread of the app. Note that this field
- * can ONLY be used from the main thread of the process; that is, the
- * thread that calls into the ANativeActivityCallbacks.
- */
- JNIEnv* env;
-
- /**
- * The NativeActivity object handle.
- *
- * IMPORTANT NOTE: This member is mis-named. It should really be named
- * 'activity' instead of 'clazz', since it's a reference to the
- * NativeActivity instance created by the system for you.
- *
- * We unfortunately cannot change this without breaking NDK
- * source-compatibility.
- */
- jobject clazz;
-
- /**
- * Path to this application's internal data directory.
- */
- const char* internalDataPath;
-
- /**
- * Path to this application's external (removable/mountable) data directory.
- */
- const char* externalDataPath;
-
- /**
- * The platform's SDK version code.
- */
- int32_t sdkVersion;
-
- /**
- * This is the native instance of the application. It is not used by
- * the framework, but can be set by the application to its own instance
- * state.
- */
- void* instance;
-
- /**
- * Pointer to the Asset Manager instance for the application. The application
- * uses this to access binary assets bundled inside its own .apk file.
- */
- AAssetManager* assetManager;
-
- /**
- * Available starting with Honeycomb: path to the directory containing
- * the application's OBB files (if any). If the app doesn't have any
- * OBB files, this directory may not exist.
- */
- const char* obbPath;
-} ANativeActivity;
-
-/**
- * These are the callbacks the framework makes into a native application.
- * All of these callbacks happen on the main thread of the application.
- * By default, all callbacks are NULL; set to a pointer to your own function
- * to have it called.
- */
-typedef struct ANativeActivityCallbacks {
- /**
- * NativeActivity has started. See Java documentation for Activity.onStart()
- * for more information.
- */
- void (*onStart)(ANativeActivity* activity);
-
- /**
- * NativeActivity has resumed. See Java documentation for Activity.onResume()
- * for more information.
- */
- void (*onResume)(ANativeActivity* activity);
-
- /**
- * Framework is asking NativeActivity to save its current instance state.
- * See Java documentation for Activity.onSaveInstanceState() for more
- * information. The returned pointer needs to be created with malloc();
- * the framework will call free() on it for you. You also must fill in
- * outSize with the number of bytes in the allocation. Note that the
- * saved state will be persisted, so it can not contain any active
- * entities (pointers to memory, file descriptors, etc).
- */
- void* (*onSaveInstanceState)(ANativeActivity* activity, size_t* outSize);
-
- /**
- * NativeActivity has paused. See Java documentation for Activity.onPause()
- * for more information.
- */
- void (*onPause)(ANativeActivity* activity);
-
- /**
- * NativeActivity has stopped. See Java documentation for Activity.onStop()
- * for more information.
- */
- void (*onStop)(ANativeActivity* activity);
-
- /**
- * NativeActivity is being destroyed. See Java documentation for Activity.onDestroy()
- * for more information.
- */
- void (*onDestroy)(ANativeActivity* activity);
-
- /**
- * Focus has changed in this NativeActivity's window. This is often used,
- * for example, to pause a game when it loses input focus.
- */
- void (*onWindowFocusChanged)(ANativeActivity* activity, int hasFocus);
-
- /**
- * The drawing window for this native activity has been created. You
- * can use the given native window object to start drawing.
- */
- void (*onNativeWindowCreated)(ANativeActivity* activity, ANativeWindow* window);
-
- /**
- * The drawing window for this native activity has been resized. You should
- * retrieve the new size from the window and ensure that your rendering in
- * it now matches.
- */
- void (*onNativeWindowResized)(ANativeActivity* activity, ANativeWindow* window);
-
- /**
- * The drawing window for this native activity needs to be redrawn. To avoid
- * transient artifacts during screen changes (such resizing after rotation),
- * applications should not return from this function until they have finished
- * drawing their window in its current state.
- */
- void (*onNativeWindowRedrawNeeded)(ANativeActivity* activity, ANativeWindow* window);
-
- /**
- * The drawing window for this native activity is going to be destroyed.
- * You MUST ensure that you do not touch the window object after returning
- * from this function: in the common case of drawing to the window from
- * another thread, that means the implementation of this callback must
- * properly synchronize with the other thread to stop its drawing before
- * returning from here.
- */
- void (*onNativeWindowDestroyed)(ANativeActivity* activity, ANativeWindow* window);
-
- /**
- * The input queue for this native activity's window has been created.
- * You can use the given input queue to start retrieving input events.
- */
- void (*onInputQueueCreated)(ANativeActivity* activity, AInputQueue* queue);
-
- /**
- * The input queue for this native activity's window is being destroyed.
- * You should no longer try to reference this object upon returning from this
- * function.
- */
- void (*onInputQueueDestroyed)(ANativeActivity* activity, AInputQueue* queue);
-
- /**
- * The rectangle in the window in which content should be placed has changed.
- */
- void (*onContentRectChanged)(ANativeActivity* activity, const ARect* rect);
-
- /**
- * The current device AConfiguration has changed. The new configuration can
- * be retrieved from assetManager.
- */
- void (*onConfigurationChanged)(ANativeActivity* activity);
-
- /**
- * The system is running low on memory. Use this callback to release
- * resources you do not need, to help the system avoid killing more
- * important processes.
- */
- void (*onLowMemory)(ANativeActivity* activity);
-} ANativeActivityCallbacks;
-
-/**
- * This is the function that must be in the native code to instantiate the
- * application's native activity. It is called with the activity instance (see
- * above); if the code is being instantiated from a previously saved instance,
- * the savedState will be non-NULL and point to the saved data. You must make
- * any copy of this data you need -- it will be released after you return from
- * this function.
- */
-typedef void ANativeActivity_createFunc(ANativeActivity* activity,
- void* savedState, size_t savedStateSize);
-
-/**
- * The name of the function that NativeInstance looks for when launching its
- * native code. This is the default function that is used, you can specify
- * "android.app.func_name" string meta-data in your manifest to use a different
- * function.
- */
-extern ANativeActivity_createFunc ANativeActivity_onCreate;
-
-/**
- * Finish the given activity. Its finish() method will be called, causing it
- * to be stopped and destroyed. Note that this method can be called from
- * *any* thread; it will send a message to the main thread of the process
- * where the Java finish call will take place.
- */
-void ANativeActivity_finish(ANativeActivity* activity);
-
-/**
- * Change the window format of the given activity. Calls getWindow().setFormat()
- * of the given activity. Note that this method can be called from
- * *any* thread; it will send a message to the main thread of the process
- * where the Java finish call will take place.
- */
-void ANativeActivity_setWindowFormat(ANativeActivity* activity, int32_t format);
-
-/**
- * Change the window flags of the given activity. Calls getWindow().setFlags()
- * of the given activity. Note that this method can be called from
- * *any* thread; it will send a message to the main thread of the process
- * where the Java finish call will take place. See window.h for flag constants.
- */
-void ANativeActivity_setWindowFlags(ANativeActivity* activity,
- uint32_t addFlags, uint32_t removeFlags);
-
-/**
- * Flags for ANativeActivity_showSoftInput; see the Java InputMethodManager
- * API for documentation.
- */
-enum {
- ANATIVEACTIVITY_SHOW_SOFT_INPUT_IMPLICIT = 0x0001,
- ANATIVEACTIVITY_SHOW_SOFT_INPUT_FORCED = 0x0002,
-};
-
-/**
- * Show the IME while in the given activity. Calls InputMethodManager.showSoftInput()
- * for the given activity. Note that this method can be called from
- * *any* thread; it will send a message to the main thread of the process
- * where the Java finish call will take place.
- */
-void ANativeActivity_showSoftInput(ANativeActivity* activity, uint32_t flags);
-
-/**
- * Flags for ANativeActivity_hideSoftInput; see the Java InputMethodManager
- * API for documentation.
- */
-enum {
- ANATIVEACTIVITY_HIDE_SOFT_INPUT_IMPLICIT_ONLY = 0x0001,
- ANATIVEACTIVITY_HIDE_SOFT_INPUT_NOT_ALWAYS = 0x0002,
-};
-
-/**
- * Hide the IME while in the given activity. Calls InputMethodManager.hideSoftInput()
- * for the given activity. Note that this method can be called from
- * *any* thread; it will send a message to the main thread of the process
- * where the Java finish call will take place.
- */
-void ANativeActivity_hideSoftInput(ANativeActivity* activity, uint32_t flags);
-
-#ifdef __cplusplus
-};
-#endif
-
-#endif // ANDROID_NATIVE_ACTIVITY_H
-
diff --git a/native/include/android/native_window.h b/native/include/android/native_window.h
deleted file mode 100644
index 2f4f2d3..0000000
--- a/native/include/android/native_window.h
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_NATIVE_WINDOW_H
-#define ANDROID_NATIVE_WINDOW_H
-
-#include <android/rect.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Pixel formats that a window can use.
- */
-enum {
- WINDOW_FORMAT_RGBA_8888 = 1,
- WINDOW_FORMAT_RGBX_8888 = 2,
- WINDOW_FORMAT_RGB_565 = 4,
-};
-
-struct ANativeWindow;
-typedef struct ANativeWindow ANativeWindow;
-
-typedef struct ANativeWindow_Buffer {
- // The number of pixels that are show horizontally.
- int32_t width;
-
- // The number of pixels that are shown vertically.
- int32_t height;
-
- // The number of *pixels* that a line in the buffer takes in
- // memory. This may be >= width.
- int32_t stride;
-
- // The format of the buffer. One of WINDOW_FORMAT_*
- int32_t format;
-
- // The actual bits.
- void* bits;
-
- // Do not touch.
- uint32_t reserved[6];
-} ANativeWindow_Buffer;
-
-/**
- * Acquire a reference on the given ANativeWindow object. This prevents the object
- * from being deleted until the reference is removed.
- */
-void ANativeWindow_acquire(ANativeWindow* window);
-
-/**
- * Remove a reference that was previously acquired with ANativeWindow_acquire().
- */
-void ANativeWindow_release(ANativeWindow* window);
-
-/*
- * Return the current width in pixels of the window surface. Returns a
- * negative value on error.
- */
-int32_t ANativeWindow_getWidth(ANativeWindow* window);
-
-/*
- * Return the current height in pixels of the window surface. Returns a
- * negative value on error.
- */
-int32_t ANativeWindow_getHeight(ANativeWindow* window);
-
-/*
- * Return the current pixel format of the window surface. Returns a
- * negative value on error.
- */
-int32_t ANativeWindow_getFormat(ANativeWindow* window);
-
-/*
- * Change the format and size of the window buffers.
- *
- * The width and height control the number of pixels in the buffers, not the
- * dimensions of the window on screen. If these are different than the
- * window's physical size, then it buffer will be scaled to match that size
- * when compositing it to the screen.
- *
- * For all of these parameters, if 0 is supplied then the window's base
- * value will come back in force.
- *
- * width and height must be either both zero or both non-zero.
- *
- */
-int32_t ANativeWindow_setBuffersGeometry(ANativeWindow* window,
- int32_t width, int32_t height, int32_t format);
-
-/**
- * Lock the window's next drawing surface for writing.
- * inOutDirtyBounds is used as an in/out parameter, upon entering the
- * function, it contains the dirty region, that is, the region the caller
- * intends to redraw. When the function returns, inOutDirtyBounds is updated
- * with the actual area the caller needs to redraw -- this region is often
- * extended by ANativeWindow_lock.
- */
-int32_t ANativeWindow_lock(ANativeWindow* window, ANativeWindow_Buffer* outBuffer,
- ARect* inOutDirtyBounds);
-
-/**
- * Unlock the window's drawing surface after previously locking it,
- * posting the new buffer to the display.
- */
-int32_t ANativeWindow_unlockAndPost(ANativeWindow* window);
-
-#ifdef __cplusplus
-};
-#endif
-
-#endif // ANDROID_NATIVE_WINDOW_H
diff --git a/native/include/android/native_window_jni.h b/native/include/android/native_window_jni.h
deleted file mode 100644
index b9e72ef..0000000
--- a/native/include/android/native_window_jni.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_NATIVE_WINDOW_JNI_H
-#define ANDROID_NATIVE_WINDOW_JNI_H
-
-#include <android/native_window.h>
-
-#include <jni.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * Return the ANativeWindow associated with a Java Surface object,
- * for interacting with it through native code. This acquires a reference
- * on the ANativeWindow that is returned; be sure to use ANativeWindow_release()
- * when done with it so that it doesn't leak.
- */
-ANativeWindow* ANativeWindow_fromSurface(JNIEnv* env, jobject surface);
-
-#ifdef __cplusplus
-};
-#endif
-
-#endif // ANDROID_NATIVE_WINDOW_H
diff --git a/native/include/android/obb.h b/native/include/android/obb.h
deleted file mode 100644
index 65e9b2a..0000000
--- a/native/include/android/obb.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-#ifndef ANDROID_OBB_H
-#define ANDROID_OBB_H
-
-#include <sys/types.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct AObbInfo;
-typedef struct AObbInfo AObbInfo;
-
-enum {
- AOBBINFO_OVERLAY = 0x0001,
-};
-
-/**
- * Scan an OBB and get information about it.
- */
-AObbInfo* AObbScanner_getObbInfo(const char* filename);
-
-/**
- * Destroy the AObbInfo object. You must call this when finished with the object.
- */
-void AObbInfo_delete(AObbInfo* obbInfo);
-
-/**
- * Get the package name for the OBB.
- */
-const char* AObbInfo_getPackageName(AObbInfo* obbInfo);
-
-/**
- * Get the version of an OBB file.
- */
-int32_t AObbInfo_getVersion(AObbInfo* obbInfo);
-
-/**
- * Get the flags of an OBB file.
- */
-int32_t AObbInfo_getFlags(AObbInfo* obbInfo);
-
-#ifdef __cplusplus
-};
-#endif
-
-#endif // ANDROID_OBB_H
diff --git a/native/include/android/rect.h b/native/include/android/rect.h
deleted file mode 100644
index 64d487d..0000000
--- a/native/include/android/rect.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-#ifndef ANDROID_RECT_H
-#define ANDROID_RECT_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct ARect {
-#ifdef __cplusplus
- typedef int32_t value_type;
-#endif
- int32_t left;
- int32_t top;
- int32_t right;
- int32_t bottom;
-} ARect;
-
-#ifdef __cplusplus
-};
-#endif
-
-#endif // ANDROID_RECT_H
diff --git a/native/include/android/sensor.h b/native/include/android/sensor.h
deleted file mode 100644
index f163f18..0000000
--- a/native/include/android/sensor.h
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-#ifndef ANDROID_SENSOR_H
-#define ANDROID_SENSOR_H
-
-/******************************************************************
- *
- * IMPORTANT NOTICE:
- *
- * This file is part of Android's set of stable system headers
- * exposed by the Android NDK (Native Development Kit).
- *
- * Third-party source AND binary code relies on the definitions
- * here to be FROZEN ON ALL UPCOMING PLATFORM RELEASES.
- *
- * - DO NOT MODIFY ENUMS (EXCEPT IF YOU ADD NEW 32-BIT VALUES)
- * - DO NOT MODIFY CONSTANTS OR FUNCTIONAL MACROS
- * - DO NOT CHANGE THE SIGNATURE OF FUNCTIONS IN ANY WAY
- * - DO NOT CHANGE THE LAYOUT OR SIZE OF STRUCTURES
- */
-
-/*
- * Structures and functions to receive and process sensor events in
- * native code.
- *
- */
-
-#include <sys/types.h>
-
-#include <android/looper.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/*
- * Sensor types
- * (keep in sync with hardware/sensor.h)
- */
-
-enum {
- ASENSOR_TYPE_ACCELEROMETER = 1,
- ASENSOR_TYPE_MAGNETIC_FIELD = 2,
- ASENSOR_TYPE_GYROSCOPE = 4,
- ASENSOR_TYPE_LIGHT = 5,
- ASENSOR_TYPE_PROXIMITY = 8
-};
-
-/*
- * Sensor accuracy measure
- */
-enum {
- ASENSOR_STATUS_UNRELIABLE = 0,
- ASENSOR_STATUS_ACCURACY_LOW = 1,
- ASENSOR_STATUS_ACCURACY_MEDIUM = 2,
- ASENSOR_STATUS_ACCURACY_HIGH = 3
-};
-
-/*
- * A few useful constants
- */
-
-/* Earth's gravity in m/s^2 */
-#define ASENSOR_STANDARD_GRAVITY (9.80665f)
-/* Maximum magnetic field on Earth's surface in uT */
-#define ASENSOR_MAGNETIC_FIELD_EARTH_MAX (60.0f)
-/* Minimum magnetic field on Earth's surface in uT*/
-#define ASENSOR_MAGNETIC_FIELD_EARTH_MIN (30.0f)
-
-/*
- * A sensor event.
- */
-
-/* NOTE: Must match hardware/sensors.h */
-typedef struct ASensorVector {
- union {
- float v[3];
- struct {
- float x;
- float y;
- float z;
- };
- struct {
- float azimuth;
- float pitch;
- float roll;
- };
- };
- int8_t status;
- uint8_t reserved[3];
-} ASensorVector;
-
-/* NOTE: Must match hardware/sensors.h */
-typedef struct ASensorEvent {
- int32_t version; /* sizeof(struct ASensorEvent) */
- int32_t sensor;
- int32_t type;
- int32_t reserved0;
- int64_t timestamp;
- union {
- float data[16];
- ASensorVector vector;
- ASensorVector acceleration;
- ASensorVector magnetic;
- float temperature;
- float distance;
- float light;
- float pressure;
- };
- int32_t reserved1[4];
-} ASensorEvent;
-
-
-struct ASensorManager;
-typedef struct ASensorManager ASensorManager;
-
-struct ASensorEventQueue;
-typedef struct ASensorEventQueue ASensorEventQueue;
-
-struct ASensor;
-typedef struct ASensor ASensor;
-typedef ASensor const* ASensorRef;
-typedef ASensorRef const* ASensorList;
-
-/*****************************************************************************/
-
-/*
- * Get a reference to the sensor manager. ASensorManager is a singleton.
- *
- * Example:
- *
- * ASensorManager* sensorManager = ASensorManager_getInstance();
- *
- */
-ASensorManager* ASensorManager_getInstance();
-
-
-/*
- * Returns the list of available sensors.
- */
-int ASensorManager_getSensorList(ASensorManager* manager, ASensorList* list);
-
-/*
- * Returns the default sensor for the given type, or NULL if no sensor
- * of that type exist.
- */
-ASensor const* ASensorManager_getDefaultSensor(ASensorManager* manager, int type);
-
-/*
- * Creates a new sensor event queue and associate it with a looper.
- */
-ASensorEventQueue* ASensorManager_createEventQueue(ASensorManager* manager,
- ALooper* looper, int ident, ALooper_callbackFunc callback, void* data);
-
-/*
- * Destroys the event queue and free all resources associated to it.
- */
-int ASensorManager_destroyEventQueue(ASensorManager* manager, ASensorEventQueue* queue);
-
-
-/*****************************************************************************/
-
-/*
- * Enable the selected sensor. Returns a negative error code on failure.
- */
-int ASensorEventQueue_enableSensor(ASensorEventQueue* queue, ASensor const* sensor);
-
-/*
- * Disable the selected sensor. Returns a negative error code on failure.
- */
-int ASensorEventQueue_disableSensor(ASensorEventQueue* queue, ASensor const* sensor);
-
-/*
- * Sets the delivery rate of events in microseconds for the given sensor.
- * Note that this is a hint only, generally event will arrive at a higher
- * rate. It is an error to set a rate inferior to the value returned by
- * ASensor_getMinDelay().
- * Returns a negative error code on failure.
- */
-int ASensorEventQueue_setEventRate(ASensorEventQueue* queue, ASensor const* sensor, int32_t usec);
-
-/*
- * Returns true if there are one or more events available in the
- * sensor queue. Returns 1 if the queue has events; 0 if
- * it does not have events; and a negative value if there is an error.
- */
-int ASensorEventQueue_hasEvents(ASensorEventQueue* queue);
-
-/*
- * Returns the next available events from the queue. Returns a negative
- * value if no events are available or an error has occurred, otherwise
- * the number of events returned.
- *
- * Examples:
- * ASensorEvent event;
- * ssize_t numEvent = ASensorEventQueue_getEvents(queue, &event, 1);
- *
- * ASensorEvent eventBuffer[8];
- * ssize_t numEvent = ASensorEventQueue_getEvents(queue, eventBuffer, 8);
- *
- */
-ssize_t ASensorEventQueue_getEvents(ASensorEventQueue* queue,
- ASensorEvent* events, size_t count);
-
-
-/*****************************************************************************/
-
-/*
- * Returns this sensor's name (non localized)
- */
-const char* ASensor_getName(ASensor const* sensor);
-
-/*
- * Returns this sensor's vendor's name (non localized)
- */
-const char* ASensor_getVendor(ASensor const* sensor);
-
-/*
- * Return this sensor's type
- */
-int ASensor_getType(ASensor const* sensor);
-
-/*
- * Returns this sensors's resolution
- */
-float ASensor_getResolution(ASensor const* sensor);
-
-/*
- * Returns the minimum delay allowed between events in microseconds.
- * A value of zero means that this sensor doesn't report events at a
- * constant rate, but rather only when a new data is available.
- */
-int ASensor_getMinDelay(ASensor const* sensor);
-
-
-#ifdef __cplusplus
-};
-#endif
-
-#endif // ANDROID_SENSOR_H
diff --git a/native/include/android/storage_manager.h b/native/include/android/storage_manager.h
deleted file mode 100644
index bad24913..0000000
--- a/native/include/android/storage_manager.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-#ifndef ANDROID_STORAGE_MANAGER_H
-#define ANDROID_STORAGE_MANAGER_H
-
-#include <stdint.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct AStorageManager;
-typedef struct AStorageManager AStorageManager;
-
-enum {
- /*
- * The OBB container is now mounted and ready for use. Can be returned
- * as the status for callbacks made during asynchronous OBB actions.
- */
- AOBB_STATE_MOUNTED = 1,
-
- /*
- * The OBB container is now unmounted and not usable. Can be returned
- * as the status for callbacks made during asynchronous OBB actions.
- */
- AOBB_STATE_UNMOUNTED = 2,
-
- /*
- * There was an internal system error encountered while trying to
- * mount the OBB. Can be returned as the status for callbacks made
- * during asynchronous OBB actions.
- */
- AOBB_STATE_ERROR_INTERNAL = 20,
-
- /*
- * The OBB could not be mounted by the system. Can be returned as the
- * status for callbacks made during asynchronous OBB actions.
- */
- AOBB_STATE_ERROR_COULD_NOT_MOUNT = 21,
-
- /*
- * The OBB could not be unmounted. This most likely indicates that a
- * file is in use on the OBB. Can be returned as the status for
- * callbacks made during asynchronous OBB actions.
- */
- AOBB_STATE_ERROR_COULD_NOT_UNMOUNT = 22,
-
- /*
- * A call was made to unmount the OBB when it was not mounted. Can be
- * returned as the status for callbacks made during asynchronous OBB
- * actions.
- */
- AOBB_STATE_ERROR_NOT_MOUNTED = 23,
-
- /*
- * The OBB has already been mounted. Can be returned as the status for
- * callbacks made during asynchronous OBB actions.
- */
- AOBB_STATE_ERROR_ALREADY_MOUNTED = 24,
-
- /*
- * The current application does not have permission to use this OBB.
- * This could be because the OBB indicates it's owned by a different
- * package. Can be returned as the status for callbacks made during
- * asynchronous OBB actions.
- */
- AOBB_STATE_ERROR_PERMISSION_DENIED = 25,
-};
-
-/**
- * Obtains a new instance of AStorageManager.
- */
-AStorageManager* AStorageManager_new();
-
-/**
- * Release AStorageManager instance.
- */
-void AStorageManager_delete(AStorageManager* mgr);
-
-/**
- * Callback function for asynchronous calls made on OBB files.
- */
-typedef void (*AStorageManager_obbCallbackFunc)(const char* filename, const int32_t state, void* data);
-
-/**
- * Attempts to mount an OBB file. This is an asynchronous operation.
- */
-void AStorageManager_mountObb(AStorageManager* mgr, const char* filename, const char* key,
- AStorageManager_obbCallbackFunc cb, void* data);
-
-/**
- * Attempts to unmount an OBB file. This is an asynchronous operation.
- */
-void AStorageManager_unmountObb(AStorageManager* mgr, const char* filename, const int force,
- AStorageManager_obbCallbackFunc cb, void* data);
-
-/**
- * Check whether an OBB is mounted.
- */
-int AStorageManager_isObbMounted(AStorageManager* mgr, const char* filename);
-
-/**
- * Get the mounted path for an OBB.
- */
-const char* AStorageManager_getMountedObbPath(AStorageManager* mgr, const char* filename);
-
-
-#ifdef __cplusplus
-};
-#endif
-
-#endif // ANDROID_STORAGE_MANAGER_H
diff --git a/native/include/android/window.h b/native/include/android/window.h
deleted file mode 100644
index 2ab192b..0000000
--- a/native/include/android/window.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-#ifndef ANDROID_WINDOW_H
-#define ANDROID_WINDOW_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * Window flags, as per the Java API at android.view.WindowManager.LayoutParams.
- */
-enum {
- AWINDOW_FLAG_ALLOW_LOCK_WHILE_SCREEN_ON = 0x00000001,
- AWINDOW_FLAG_DIM_BEHIND = 0x00000002,
- AWINDOW_FLAG_BLUR_BEHIND = 0x00000004,
- AWINDOW_FLAG_NOT_FOCUSABLE = 0x00000008,
- AWINDOW_FLAG_NOT_TOUCHABLE = 0x00000010,
- AWINDOW_FLAG_NOT_TOUCH_MODAL = 0x00000020,
- AWINDOW_FLAG_TOUCHABLE_WHEN_WAKING = 0x00000040,
- AWINDOW_FLAG_KEEP_SCREEN_ON = 0x00000080,
- AWINDOW_FLAG_LAYOUT_IN_SCREEN = 0x00000100,
- AWINDOW_FLAG_LAYOUT_NO_LIMITS = 0x00000200,
- AWINDOW_FLAG_FULLSCREEN = 0x00000400,
- AWINDOW_FLAG_FORCE_NOT_FULLSCREEN = 0x00000800,
- AWINDOW_FLAG_DITHER = 0x00001000,
- AWINDOW_FLAG_SECURE = 0x00002000,
- AWINDOW_FLAG_SCALED = 0x00004000,
- AWINDOW_FLAG_IGNORE_CHEEK_PRESSES = 0x00008000,
- AWINDOW_FLAG_LAYOUT_INSET_DECOR = 0x00010000,
- AWINDOW_FLAG_ALT_FOCUSABLE_IM = 0x00020000,
- AWINDOW_FLAG_WATCH_OUTSIDE_TOUCH = 0x00040000,
- AWINDOW_FLAG_SHOW_WHEN_LOCKED = 0x00080000,
- AWINDOW_FLAG_SHOW_WALLPAPER = 0x00100000,
- AWINDOW_FLAG_TURN_SCREEN_ON = 0x00200000,
- AWINDOW_FLAG_DISMISS_KEYGUARD = 0x00400000,
-};
-
-#ifdef __cplusplus
-};
-#endif
-
-#endif // ANDROID_WINDOW_H
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index 330a189..abf713b 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -84,6 +84,7 @@
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
mContext = context;
+ setWriteAheadLoggingEnabled(true);
}
public static boolean isValidTable(String name) {
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 95fd62d..1fa3695 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -260,7 +260,6 @@
// Watch for external modifications to the database file,
// keeping our cache in sync.
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- db.enableWriteAheadLogging();
sObserverInstance = new SettingsFileObserver(db.getPath());
sObserverInstance.startWatching();
startAsyncCachePopulation();
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 4d9b2cd..0f48f35 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -65,7 +65,7 @@
<string name="screenshot_saving_ticker" msgid="7403652894056693515">"Ukládání snímku obrazovky..."</string>
<string name="screenshot_saving_title" msgid="8242282144535555697">"Ukládání snímku obrazovky..."</string>
<string name="screenshot_saving_text" msgid="2419718443411738818">"Probíhá ukládání snímku obrazovky."</string>
- <string name="screenshot_saved_title" msgid="6461865960961414961">"Snímek obrazovky byl zachycen."</string>
+ <string name="screenshot_saved_title" msgid="6461865960961414961">"Snímek obrazovky zachycen."</string>
<string name="screenshot_saved_text" msgid="1152839647677558815">"Snímek obrazovky zobrazíte dotykem."</string>
<string name="screenshot_failed_title" msgid="705781116746922771">"Snímek obrazovky se nepodařilo zachytit."</string>
<string name="screenshot_failed_text" msgid="8134011269572415402">"Snímek obrazovky se nepodařilo uložit. Je možné, že je externí úložiště právě používáno."</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 7e0e3c4..1f9c959 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -24,12 +24,12 @@
<string name="status_bar_do_not_disturb_button" msgid="5812628897510997853">"请勿打扰"</string>
<string name="status_bar_please_disturb_button" msgid="3345398298841572813">"显示通知"</string>
<string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"从列表中删除"</string>
- <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"应用程序信息"</string>
- <string name="status_bar_no_recent_apps" msgid="6576392951053994640">"最近没有运行任何应用程序"</string>
- <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"关闭最近运行的应用程序"</string>
+ <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"应用信息"</string>
+ <string name="status_bar_no_recent_apps" msgid="6576392951053994640">"最近没有运行任何应用"</string>
+ <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"关闭最近运行的应用"</string>
<plurals name="status_bar_accessibility_recent_apps">
- <item quantity="one" msgid="5854176083865845541">"1 个最近运行的应用程序"</item>
- <item quantity="other" msgid="1040784359794890744">"%d 个最近运行的应用程序"</item>
+ <item quantity="one" msgid="5854176083865845541">"1 个最近运行的应用"</item>
+ <item quantity="other" msgid="1040784359794890744">"%d 个最近运行的应用"</item>
</plurals>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"无通知"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"正在进行的"</string>
@@ -49,11 +49,11 @@
<string name="bluetooth_tethered" msgid="7094101612161133267">"已通过蓝牙共享网络"</string>
<string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"设置输入法"</string>
<string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"使用物理键盘"</string>
- <string name="usb_device_permission_prompt" msgid="834698001271562057">"允许应用程序“<xliff:g id="APPLICATION">%1$s</xliff:g>”访问该 USB 设备吗?"</string>
- <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"允许应用程序“<xliff:g id="APPLICATION">%1$s</xliff:g>”访问该 USB 配件吗?"</string>
+ <string name="usb_device_permission_prompt" msgid="834698001271562057">"允许应用“<xliff:g id="APPLICATION">%1$s</xliff:g>”访问该 USB 设备吗?"</string>
+ <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"允许应用“<xliff:g id="APPLICATION">%1$s</xliff:g>”访问该 USB 配件吗?"</string>
<string name="usb_device_confirm_prompt" msgid="5161205258635253206">"要在连接此 USB 设备时打开<xliff:g id="ACTIVITY">%1$s</xliff:g>吗?"</string>
<string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"要在连接此 USB 配件时打开<xliff:g id="ACTIVITY">%1$s</xliff:g>吗?"</string>
- <string name="usb_accessory_uri_prompt" msgid="513450621413733343">"未安装此 USB 配件适用的应用程序。要了解此配件的详情,请访问:<xliff:g id="URL">%1$s</xliff:g>"</string>
+ <string name="usb_accessory_uri_prompt" msgid="513450621413733343">"未安装此 USB 配件适用的应用。要了解此配件的详情,请访问:<xliff:g id="URL">%1$s</xliff:g>"</string>
<string name="title_usb_accessory" msgid="4966265263465181372">"USB 配件"</string>
<string name="label_view" msgid="6304565553218192990">"查看"</string>
<string name="always_use_device" msgid="1450287437017315906">"默认情况下用于该 USB 设备"</string>
@@ -61,7 +61,7 @@
<string name="compat_mode_on" msgid="6623839244840638213">"缩放以填满屏幕"</string>
<string name="compat_mode_off" msgid="4434467572461327898">"拉伸以填满屏幕"</string>
<string name="compat_mode_help_header" msgid="7969493989397529910">"兼容性缩放"</string>
- <string name="compat_mode_help_body" msgid="4946726776359270040">"如果应用程序是针对较小屏幕设计的,则时钟旁会显示缩放控件。"</string>
+ <string name="compat_mode_help_body" msgid="4946726776359270040">"如果应用是针对较小屏幕设计的,则时钟旁会显示缩放控件。"</string>
<string name="screenshot_saving_ticker" msgid="7403652894056693515">"正在保存屏幕截图..."</string>
<string name="screenshot_saving_title" msgid="8242282144535555697">"正在保存屏幕截图..."</string>
<string name="screenshot_saving_text" msgid="2419718443411738818">"正在保存屏幕截图。"</string>
@@ -72,11 +72,11 @@
<string name="usb_preference_title" msgid="6551050377388882787">"USB 文件传输选项"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"作为媒体播放器 (MTP) 装载"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"作为摄像头 (PTP) 装载"</string>
- <string name="installer_cd_button_title" msgid="2312667578562201583">"安装适用于苹果机的“Android 文件传输”应用程序"</string>
+ <string name="installer_cd_button_title" msgid="2312667578562201583">"安装适用于苹果机的“Android 文件传输”应用"</string>
<string name="accessibility_back" msgid="567011538994429120">"返回"</string>
<string name="accessibility_home" msgid="8217216074895377641">"主屏幕"</string>
<string name="accessibility_menu" msgid="316839303324695949">"菜单"</string>
- <string name="accessibility_recent" msgid="8571350598987952883">"最近运行的应用程序"</string>
+ <string name="accessibility_recent" msgid="8571350598987952883">"最近运行的应用"</string>
<string name="accessibility_ime_switch_button" msgid="5032926134740456424">"输入法切换按钮。"</string>
<string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"兼容性缩放按钮。"</string>
<string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"将小屏幕的图片放大在较大屏幕上显示。"</string>
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
index 66cb32c..564b07b 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
@@ -19,6 +19,7 @@
import android.animation.Animator;
import android.animation.LayoutTransition;
import android.app.ActivityManager;
+import android.app.ActivityOptions;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
@@ -615,10 +616,11 @@
if (!mFirstScreenful && tasks.size() == 0) {
return;
}
- mNumItemsWaitingForThumbnailsAndIcons =
- mFirstScreenful ? tasks.size() : mRecentTaskDescriptions.size();
+ mNumItemsWaitingForThumbnailsAndIcons = mFirstScreenful
+ ? tasks.size() : mRecentTaskDescriptions == null
+ ? 0 : mRecentTaskDescriptions.size();
if (mRecentTaskDescriptions == null) {
- mRecentTaskDescriptions = new ArrayList(tasks);
+ mRecentTaskDescriptions = new ArrayList<TaskDescription>(tasks);
} else {
mRecentTaskDescriptions.addAll(tasks);
}
@@ -656,22 +658,33 @@
}
public void handleOnClick(View view) {
- TaskDescription ad = ((ViewHolder) view.getTag()).taskDescription;
+ ViewHolder holder = (ViewHolder)view.getTag();
+ TaskDescription ad = holder.taskDescription;
final Context context = view.getContext();
final ActivityManager am = (ActivityManager)
context.getSystemService(Context.ACTIVITY_SERVICE);
+ holder.thumbnailViewImage.setDrawingCacheEnabled(true);
+ Bitmap bm = holder.thumbnailViewImage.getDrawingCache();
+ ActivityOptions opts = ActivityOptions.makeThumbnailScaleUpAnimation(
+ holder.thumbnailViewImage, bm, 0, 0,
+ new ActivityOptions.OnAnimationStartedListener() {
+ @Override public void onAnimationStarted() {
+ hide(true);
+ }
+ });
if (ad.taskId >= 0) {
// This is an active task; it should just go to the foreground.
- am.moveTaskToFront(ad.taskId, ActivityManager.MOVE_TASK_WITH_HOME);
+ am.moveTaskToFront(ad.taskId, ActivityManager.MOVE_TASK_WITH_HOME,
+ opts.toBundle());
} else {
Intent intent = ad.intent;
intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
| Intent.FLAG_ACTIVITY_TASK_ON_HOME
| Intent.FLAG_ACTIVITY_NEW_TASK);
if (DEBUG) Log.v(TAG, "Starting activity " + intent);
- context.startActivity(intent);
+ context.startActivity(intent, opts.toBundle());
}
- hide(true);
+ holder.thumbnailViewImage.setDrawingCacheEnabled(false);
}
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
diff --git a/packages/VpnDialogs/res/values-zh-rCN/strings.xml b/packages/VpnDialogs/res/values-zh-rCN/strings.xml
index 7fdb368..ed844ad 100644
--- a/packages/VpnDialogs/res/values-zh-rCN/strings.xml
+++ b/packages/VpnDialogs/res/values-zh-rCN/strings.xml
@@ -17,8 +17,8 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="prompt" msgid="8359175999006833462">"“<xliff:g id="APP">%s</xliff:g>”尝试创建 VPN 连接。"</string>
- <string name="warning" msgid="5470743576660160079">"继续操作即表示您授予此应用程序拦截所有网络流量的权限。"<b>"除非您信任此应用程序,否则请勿接受此请求。"</b>"如果您在不信任该应用程序的情况下接受了此请求,则可能会面临数据遭到恶意软件盗用的风险。"</string>
- <string name="accept" msgid="2889226408765810173">"我信任此应用程序。"</string>
+ <string name="warning" msgid="5470743576660160079">"继续操作即表示您授予此应用拦截所有网络流量的权限。"<b>"除非您信任此应用,否则请勿接受此请求。"</b>"如果您在不信任该应用的情况下接受了此请求,则可能会面临数据遭到恶意软件盗用的风险。"</string>
+ <string name="accept" msgid="2889226408765810173">"我信任此应用。"</string>
<string name="legacy_title" msgid="192936250066580964">"已连接 VPN"</string>
<string name="configure" msgid="4905518375574791375">"配置"</string>
<string name="disconnect" msgid="971412338304200056">"断开连接"</string>
diff --git a/services/audioflinger/Android.mk b/services/audioflinger/Android.mk
index 69204d3..257f62c 100644
--- a/services/audioflinger/Android.mk
+++ b/services/audioflinger/Android.mk
@@ -22,6 +22,7 @@
libcutils \
libutils \
libbinder \
+ libmedia \
libmedia_native \
libhardware \
libhardware_legacy \
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index e92e69c..c5ad0f5 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -442,11 +442,9 @@
audio_format_t format,
uint32_t channelMask,
int frameCount,
- // FIXME dead, remove from IAudioFlinger
- uint32_t flags,
+ IAudioFlinger::track_flags_t flags,
const sp<IMemory>& sharedBuffer,
audio_io_handle_t output,
- bool isTimed,
int *sessionId,
status_t *status)
{
@@ -504,6 +502,7 @@
}
ALOGV("createTrack() lSessionId: %d", lSessionId);
+ bool isTimed = (flags & IAudioFlinger::TRACK_TIMED) != 0;
track = thread->createTrack_l(client, streamType, sampleRate, format,
channelMask, frameCount, sharedBuffer, lSessionId, isTimed, &lStatus);
@@ -4676,8 +4675,7 @@
audio_format_t format,
uint32_t channelMask,
int frameCount,
- // FIXME dead, remove from IAudioFlinger
- uint32_t flags,
+ IAudioFlinger::track_flags_t flags,
int *sessionId,
status_t *status)
{
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index d1950a3..795807d 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -87,10 +87,9 @@
audio_format_t format,
uint32_t channelMask,
int frameCount,
- uint32_t flags,
+ IAudioFlinger::track_flags_t flags,
const sp<IMemory>& sharedBuffer,
audio_io_handle_t output,
- bool isTimed,
int *sessionId,
status_t *status);
@@ -101,7 +100,7 @@
audio_format_t format,
uint32_t channelMask,
int frameCount,
- uint32_t flags,
+ IAudioFlinger::track_flags_t flags,
int *sessionId,
status_t *status);
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index a7b08f5..bd8ae17 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -1986,6 +1986,16 @@
try {
mCurrentPackage = mPackageManager.getPackageInfo(request.packageName,
PackageManager.GET_SIGNATURES);
+ if (mCurrentPackage.applicationInfo.backupAgentName == null) {
+ // The manifest has changed but we had a stale backup request pending.
+ // This won't happen again because the app won't be requesting further
+ // backups.
+ Slog.i(TAG, "Package " + request.packageName
+ + " no longer supports backup; skipping");
+ addBackupTrace("skipping - no agent, completion is noop");
+ executeNextState(BackupState.RUNNING_QUEUE);
+ return;
+ }
IBackupAgent agent = null;
try {
@@ -2547,6 +2557,8 @@
finalizeBackup(out);
} catch (RemoteException e) {
Slog.e(TAG, "App died during full backup");
+ } catch (Exception e) {
+ Slog.e(TAG, "Internal exception during full backup", e);
} finally {
tearDown(pkg);
try {
@@ -4681,6 +4693,8 @@
mTransport.clearBackupData(mPackage);
} catch (RemoteException e) {
// can't happen; the transport is local
+ } catch (Exception e) {
+ Slog.e(TAG, "Transport threw attempting to clear data for " + mPackage);
} finally {
try {
// TODO - need to handle failures
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index b422678..37a594e 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -34,6 +34,7 @@
import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManagerNative;
+import android.app.ActivityOptions;
import android.app.ActivityThread;
import android.app.AlertDialog;
import android.app.AppGlobals;
@@ -2353,10 +2354,12 @@
synchronized (this) {
ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
if (r == null) {
+ ActivityOptions.abort(options);
return false;
}
if (r.app == null || r.app.thread == null) {
// The caller is not running... d'oh!
+ ActivityOptions.abort(options);
return false;
}
intent = new Intent(intent);
@@ -2393,6 +2396,7 @@
if (aInfo == null) {
// Nobody who is next!
+ ActivityOptions.abort(options);
return false;
}
@@ -2422,8 +2426,6 @@
}
final long origId = Binder.clearCallingIdentity();
- // XXX we are not dealing with propagating grantedUriPermissions...
- // those are not yet exposed to user code, so there is no need.
int res = mMainStack.startActivityLocked(r.app.thread, intent,
r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
resultWho, requestCode, -1, r.launchedFromUid, 0,
@@ -3036,7 +3038,7 @@
}
final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
- if (IS_USER_BUILD) {
+ if (true || IS_USER_BUILD) {
return;
}
String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
@@ -3653,7 +3655,7 @@
}
lastTask = r.task;
if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
- null, "force-stop")) {
+ null, "force-stop", true)) {
i--;
}
}
@@ -5686,13 +5688,14 @@
/**
* TODO: Add mController hook
*/
- public void moveTaskToFront(int task, int flags) {
+ public void moveTaskToFront(int task, int flags, Bundle options) {
enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
"moveTaskToFront()");
synchronized(this) {
if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
Binder.getCallingUid(), "Task to front")) {
+ ActivityOptions.abort(options);
return;
}
final long origId = Binder.clearCallingIdentity();
@@ -5707,7 +5710,7 @@
// we'll just move the home task to the top first.
mMainStack.moveHomeToFrontLocked();
}
- mMainStack.moveTaskToFrontLocked(tr, null);
+ mMainStack.moveTaskToFrontLocked(tr, null, options);
return;
}
for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
@@ -5721,13 +5724,14 @@
// we'll just move the home task to the top first.
mMainStack.moveHomeToFrontLocked();
}
- mMainStack.moveTaskToFrontLocked(hr.task, null);
+ mMainStack.moveTaskToFrontLocked(hr.task, null, options);
return;
}
}
} finally {
Binder.restoreCallingIdentity(origId);
}
+ ActivityOptions.abort(options);
}
}
@@ -6993,7 +6997,43 @@
}
return killed;
}
-
+
+ @Override
+ public boolean killProcessesBelowForeground(String reason) {
+ if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+ throw new SecurityException("killProcessesBelowForeground() only available to system");
+ }
+
+ return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
+ }
+
+ private boolean killProcessesBelowAdj(int belowAdj, String reason) {
+ if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+ throw new SecurityException("killProcessesBelowAdj() only available to system");
+ }
+
+ boolean killed = false;
+ synchronized (mPidsSelfLocked) {
+ final int size = mPidsSelfLocked.size();
+ for (int i = 0; i < size; i++) {
+ final int pid = mPidsSelfLocked.keyAt(i);
+ final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
+ if (proc == null) continue;
+
+ final int adj = proc.setAdj;
+ if (adj > belowAdj && !proc.killedBackground) {
+ Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
+ EventLog.writeEvent(
+ EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason);
+ killed = true;
+ proc.killedBackground = true;
+ Process.killProcessQuiet(pid);
+ }
+ }
+ }
+ return killed;
+ }
+
public final void startRunning(String pkg, String cls, String action,
String data) {
synchronized(this) {
diff --git a/services/java/com/android/server/am/ActivityRecord.java b/services/java/com/android/server/am/ActivityRecord.java
index 53cb2b0..d60ff2b 100644
--- a/services/java/com/android/server/am/ActivityRecord.java
+++ b/services/java/com/android/server/am/ActivityRecord.java
@@ -26,7 +26,6 @@
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.res.CompatibilityInfo;
-import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.os.Build;
@@ -542,24 +541,38 @@
void updateOptionsLocked(Bundle options) {
if (options != null) {
+ if (pendingOptions != null) {
+ pendingOptions.abort();
+ }
pendingOptions = new ActivityOptions(options);
}
}
void applyOptionsLocked() {
if (pendingOptions != null) {
- if (pendingOptions.isCustomAnimation()) {
- service.mWindowManager.overridePendingAppTransition(
- pendingOptions.getPackageName(),
- pendingOptions.getCustomEnterResId(),
- pendingOptions.getCustomExitResId());
+ switch (pendingOptions.getAnimationType()) {
+ case ActivityOptions.ANIM_CUSTOM:
+ service.mWindowManager.overridePendingAppTransition(
+ pendingOptions.getPackageName(),
+ pendingOptions.getCustomEnterResId(),
+ pendingOptions.getCustomExitResId());
+ break;
+ case ActivityOptions.ANIM_THUMBNAIL:
+ service.mWindowManager.overridePendingAppTransitionThumb(
+ pendingOptions.getThumbnail(),
+ pendingOptions.getStartX(), pendingOptions.getStartY(),
+ pendingOptions.getOnAnimationStartListener());
+ break;
}
pendingOptions = null;
}
}
void clearOptionsLocked() {
- pendingOptions = null;
+ if (pendingOptions != null) {
+ pendingOptions.abort();
+ pendingOptions = null;
+ }
}
void removeUriPermissionsLocked() {
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index 48b4f4ff..a01ed25 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -1695,6 +1695,7 @@
if (VALIDATE_TOKENS) {
validateAppTokensLocked();
}
+ ActivityOptions.abort(options);
return;
}
break;
@@ -1797,6 +1798,7 @@
// because there is nothing for it to animate on top of.
mService.mWindowManager.addAppToken(addPos, r.appToken, r.task.taskId,
r.info.screenOrientation, r.fullscreen);
+ ActivityOptions.abort(options);
}
if (VALIDATE_TOKENS) {
validateAppTokensLocked();
@@ -2344,6 +2346,7 @@
// Transfer the result target from the source activity to the new
// one being started, including any failures.
if (requestCode >= 0) {
+ ActivityOptions.abort(options);
return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
}
resultRecord = sourceRecord.resultTo;
@@ -2375,6 +2378,7 @@
Activity.RESULT_CANCELED, null);
}
mDismissKeyguardOnNextActivity = false;
+ ActivityOptions.abort(options);
return err;
}
@@ -2425,6 +2429,7 @@
// We pretend to the caller that it was really started, but
// they will just get a cancel result.
mDismissKeyguardOnNextActivity = false;
+ ActivityOptions.abort(options);
return ActivityManager.START_SUCCESS;
}
}
@@ -2447,6 +2452,7 @@
pal.startFlags = startFlags;
mService.mPendingActivityLaunches.add(pal);
mDismissKeyguardOnNextActivity = false;
+ ActivityOptions.abort(options);
return ActivityManager.START_SWITCHES_CANCELED;
}
}
@@ -2601,8 +2607,7 @@
// We really do want to push this one into the
// user's face, right now.
moveHomeToFrontFromLaunchLocked(launchFlags);
- r.updateOptionsLocked(options);
- moveTaskToFrontLocked(taskTop.task, r);
+ moveTaskToFrontLocked(taskTop.task, r, options);
}
}
// If the caller has requested that the target task be
@@ -2618,6 +2623,7 @@
if (doResume) {
resumeTopActivityLocked(null);
}
+ ActivityOptions.abort(options);
return ActivityManager.START_RETURN_INTENT_TO_CALLER;
}
if ((launchFlags &
@@ -2705,6 +2711,7 @@
if (doResume) {
resumeTopActivityLocked(null);
}
+ ActivityOptions.abort(options);
return ActivityManager.START_TASK_TO_FRONT;
}
}
@@ -2734,6 +2741,7 @@
if (doResume) {
resumeTopActivityLocked(null);
}
+ ActivityOptions.abort(options);
if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
// We don't need to start a new activity, and
// the client said not to do anything if that
@@ -2753,6 +2761,7 @@
r.resultTo, r.resultWho, r.requestCode,
Activity.RESULT_CANCELED, null);
}
+ ActivityOptions.abort(options);
return ActivityManager.START_CLASS_NOT_FOUND;
}
@@ -2794,6 +2803,7 @@
if (doResume) {
resumeTopActivityLocked(null);
}
+ ActivityOptions.abort(options);
return ActivityManager.START_DELIVERED_TO_TOP;
}
} else if (!addingToTask &&
@@ -2948,6 +2958,7 @@
Slog.w(TAG, "Unable to find app for caller " + caller
+ " (pid=" + realCallingPid + ") when starting: "
+ intent.toString());
+ ActivityOptions.abort(options);
return ActivityManager.START_PERMISSION_DENIED;
}
}
@@ -3480,6 +3491,15 @@
*/
final boolean finishActivityLocked(ActivityRecord r, int index,
int resultCode, Intent resultData, String reason) {
+ return finishActivityLocked(r, index, resultCode, resultData, reason, false);
+ }
+
+ /**
+ * @return Returns true if this activity has been removed from the history
+ * list, or false if it is still in the list and will be removed later.
+ */
+ final boolean finishActivityLocked(ActivityRecord r, int index,
+ int resultCode, Intent resultData, String reason, boolean immediate) {
if (r.finishing) {
Slog.w(TAG, "Duplicate finish request for " + r);
return false;
@@ -3521,7 +3541,10 @@
mService.mCancelledThumbnails.add(r);
}
- if (mResumedActivity == r) {
+ if (immediate) {
+ return finishCurrentActivityLocked(r, index,
+ FINISH_IMMEDIATELY) == null;
+ } else if (mResumedActivity == r) {
boolean endTask = index <= 0
|| (mHistory.get(index-1)).task != r.task;
if (DEBUG_TRANSITION) Slog.v(TAG,
@@ -3887,12 +3910,12 @@
}
}
if (homeTask != null) {
- moveTaskToFrontLocked(homeTask, null);
+ moveTaskToFrontLocked(homeTask, null, null);
}
}
- final void moveTaskToFrontLocked(TaskRecord tr, ActivityRecord reason) {
+ final void moveTaskToFrontLocked(TaskRecord tr, ActivityRecord reason, Bundle options) {
if (DEBUG_SWITCH) Slog.v(TAG, "moveTaskToFront: " + tr);
final int task = tr.taskId;
@@ -3900,6 +3923,7 @@
if (top < 0 || (mHistory.get(top)).task.taskId == task) {
// nothing to do!
+ ActivityOptions.abort(options);
return;
}
@@ -3941,7 +3965,16 @@
if (r != null) {
mNoAnimActivities.add(r);
}
+ ActivityOptions.abort(options);
} else {
+ if (options != null) {
+ ActivityRecord r = topRunningActivityLocked(null);
+ if (r != null && r.state != ActivityState.RESUMED) {
+ r.updateOptionsLocked(options);
+ } else {
+ ActivityOptions.abort(options);
+ }
+ }
mService.mWindowManager.prepareAppTransition(
WindowManagerPolicy.TRANSIT_TASK_TO_FRONT, false);
}
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index 95666c0..067bf28 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -1587,7 +1587,16 @@
if (p != null) {
final PackageSetting ps = (PackageSetting)p.mExtras;
final SharedUserSetting suid = ps.sharedUser;
- return suid != null ? suid.gids : ps.gids;
+ int[] gids = suid != null ? suid.gids : ps.gids;
+
+ // include GIDs for any unenforced permissions
+ if (!isPermissionEnforcedLocked(READ_EXTERNAL_STORAGE)) {
+ final BasePermission basePerm = mSettings.mPermissions.get(
+ READ_EXTERNAL_STORAGE);
+ gids = appendInts(gids, basePerm.gids);
+ }
+
+ return gids;
}
}
// stupid thing to indicate an error.
@@ -8890,6 +8899,19 @@
if (mSettings.mReadExternalStorageEnforcement != enforcement) {
mSettings.mReadExternalStorageEnforcement = enforcement;
mSettings.writeLPr();
+
+ // kill any non-foreground processes so we restart them and
+ // grant/revoke the GID.
+ final IActivityManager am = ActivityManagerNative.getDefault();
+ if (am != null) {
+ final long token = Binder.clearCallingIdentity();
+ try {
+ am.killProcessesBelowForeground("setPermissionEnforcement");
+ } catch (RemoteException e) {
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
}
}
} else {
diff --git a/services/java/com/android/server/wm/AppWindowToken.java b/services/java/com/android/server/wm/AppWindowToken.java
index 0e110be..1442883 100644
--- a/services/java/com/android/server/wm/AppWindowToken.java
+++ b/services/java/com/android/server/wm/AppWindowToken.java
@@ -21,10 +21,12 @@
import com.android.server.wm.WindowManagerService.H;
import android.content.pm.ActivityInfo;
+import android.graphics.Matrix;
import android.os.Message;
import android.os.RemoteException;
import android.util.Slog;
import android.view.IApplicationToken;
+import android.view.Surface;
import android.view.View;
import android.view.WindowManager;
import android.view.WindowManagerPolicy;
@@ -90,6 +92,7 @@
boolean animating;
Animation animation;
+ boolean animInitialized;
boolean hasTransformation;
final Transformation transformation = new Transformation();
@@ -105,6 +108,15 @@
boolean startingMoved;
boolean firstWindowDrawn;
+ // Special surface for thumbnail animation.
+ Surface thumbnail;
+ int thumbnailTransactionSeq;
+ int thumbnailX;
+ int thumbnailY;
+ int thumbnailLayer;
+ Animation thumbnailAnimation;
+ final Transformation thumbnailTransformation = new Transformation();
+
// Input application handle used by the input dispatcher.
final InputApplicationHandle mInputApplicationHandle;
@@ -116,11 +128,12 @@
mInputApplicationHandle = new InputApplicationHandle(this);
}
- public void setAnimation(Animation anim) {
+ public void setAnimation(Animation anim, boolean initialized) {
if (WindowManagerService.localLOGV) Slog.v(
WindowManagerService.TAG, "Setting animation in " + this + ": " + anim);
animation = anim;
animating = false;
+ animInitialized = initialized;
anim.restrictDuration(WindowManagerService.MAX_ANIMATION_DURATION);
anim.scaleCurrentDuration(service.mTransitionAnimationScale);
int zorder = anim.getZAdjustment();
@@ -146,6 +159,7 @@
if (WindowManagerService.localLOGV) Slog.v(
WindowManagerService.TAG, "Setting dummy animation in " + this);
animation = WindowManagerService.sDummyAnimation;
+ animInitialized = false;
}
}
@@ -153,15 +167,28 @@
if (animation != null) {
animation = null;
animating = true;
+ animInitialized = false;
+ }
+ clearThumbnail();
+ }
+
+ public void clearThumbnail() {
+ if (thumbnail != null) {
+ thumbnail.destroy();
+ thumbnail = null;
}
}
void updateLayers() {
final int N = allAppWindows.size();
final int adj = animLayerAdjustment;
+ thumbnailLayer = -1;
for (int i=0; i<N; i++) {
WindowState w = allAppWindows.get(i);
w.mAnimLayer = w.mLayer + adj;
+ if (w.mAnimLayer > thumbnailLayer) {
+ thumbnailLayer = w.mAnimLayer;
+ }
if (WindowManagerService.DEBUG_LAYERS) Slog.v(WindowManagerService.TAG, "Updating layer " + w + ": "
+ w.mAnimLayer);
if (w == service.mInputMethodTarget && !service.mInputMethodTargetWaitingAnim) {
@@ -203,6 +230,38 @@
return isAnimating;
}
+ private void stepThumbnailAnimation(long currentTime) {
+ thumbnailTransformation.clear();
+ thumbnailAnimation.getTransformation(currentTime, thumbnailTransformation);
+ thumbnailTransformation.getMatrix().preTranslate(thumbnailX, thumbnailY);
+ final boolean screenAnimation = service.mAnimator.mScreenRotationAnimation != null
+ && service.mAnimator.mScreenRotationAnimation.isAnimating();
+ if (screenAnimation) {
+ thumbnailTransformation.postCompose(
+ service.mAnimator.mScreenRotationAnimation.getEnterTransformation());
+ }
+ // cache often used attributes locally
+ final float tmpFloats[] = service.mTmpFloats;
+ thumbnailTransformation.getMatrix().getValues(tmpFloats);
+ if (WindowManagerService.SHOW_TRANSACTIONS) service.logSurface(thumbnail,
+ "thumbnail", "POS " + tmpFloats[Matrix.MTRANS_X]
+ + ", " + tmpFloats[Matrix.MTRANS_Y], null);
+ thumbnail.setPosition(tmpFloats[Matrix.MTRANS_X], tmpFloats[Matrix.MTRANS_Y]);
+ if (WindowManagerService.SHOW_TRANSACTIONS) service.logSurface(thumbnail,
+ "thumbnail", "alpha=" + thumbnailTransformation.getAlpha()
+ + " layer=" + thumbnailLayer
+ + " matrix=[" + tmpFloats[Matrix.MSCALE_X]
+ + "," + tmpFloats[Matrix.MSKEW_Y]
+ + "][" + tmpFloats[Matrix.MSKEW_X]
+ + "," + tmpFloats[Matrix.MSCALE_Y] + "]", null);
+ thumbnail.setAlpha(thumbnailTransformation.getAlpha());
+ // The thumbnail is layered below the window immediately above this
+ // token's anim layer.
+ thumbnail.setLayer(thumbnailLayer + WindowManagerService.WINDOW_LAYER_MULTIPLIER
+ - WindowManagerService.LAYER_OFFSET_THUMBNAIL);
+ thumbnail.setMatrix(tmpFloats[Matrix.MSCALE_X], tmpFloats[Matrix.MSKEW_Y],
+ tmpFloats[Matrix.MSKEW_X], tmpFloats[Matrix.MSCALE_Y]);
+ }
private boolean stepAnimation(long currentTime) {
if (animation == null) {
@@ -215,6 +274,7 @@
": more=" + more + ", xform=" + transformation);
if (!more) {
animation = null;
+ clearThumbnail();
if (WindowManagerService.DEBUG_ANIM) Slog.v(
WindowManagerService.TAG, "Finished animation in " + this +
" @ " + currentTime);
@@ -243,12 +303,22 @@
" @ " + currentTime + ": dw=" + dw + " dh=" + dh
+ " scale=" + service.mTransitionAnimationScale
+ " allDrawn=" + allDrawn + " animating=" + animating);
- animation.initialize(dw, dh, dw, dh);
+ if (!animInitialized) {
+ animation.initialize(dw, dh, dw, dh);
+ }
animation.setStartTime(currentTime);
animating = true;
+ if (thumbnail != null) {
+ thumbnail.show();
+ thumbnailAnimation.setStartTime(currentTime);
+ }
}
if (stepAnimation(currentTime)) {
- // we're done!
+ // animation isn't over, step any thumbnail and that's
+ // it for now.
+ if (thumbnail != null) {
+ stepThumbnailAnimation(currentTime);
+ }
return true;
}
}
@@ -266,6 +336,10 @@
}
service.mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
+ if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
+ service.debugLayoutRepeats("AppWindowToken");
+ }
+
clearAnimation();
animating = false;
if (animLayerAdjustment != 0) {
@@ -440,6 +514,15 @@
pw.print(" startingDisplayed="); pw.print(startingDisplayed);
pw.print(" startingMoved"); pw.println(startingMoved);
}
+ if (thumbnail != null) {
+ pw.print(prefix); pw.print("thumbnail="); pw.print(thumbnail);
+ pw.print(" x="); pw.print(thumbnailX);
+ pw.print(" y="); pw.print(thumbnailY);
+ pw.print(" layer="); pw.println(thumbnailLayer);
+ pw.print(prefix); pw.print("thumbnailAnimation="); pw.println(thumbnailAnimation);
+ pw.print(prefix); pw.print("thumbnailTransformation=");
+ pw.println(thumbnailTransformation.toShortString());
+ }
}
@Override
diff --git a/services/java/com/android/server/wm/WindowAnimator.java b/services/java/com/android/server/wm/WindowAnimator.java
index b3dbee1..fbfd9ec 100644
--- a/services/java/com/android/server/wm/WindowAnimator.java
+++ b/services/java/com/android/server/wm/WindowAnimator.java
@@ -23,7 +23,7 @@
* on behalf of WindowManagerService.
*/
public class WindowAnimator {
- private static final String TAG = "WindowAnimations";
+ private static final String TAG = "WindowAnimator";
final WindowManagerService mService;
final Context mContext;
@@ -67,8 +67,32 @@
final int NAT = mService.mAppTokens.size();
for (i=0; i<NAT; i++) {
final AppWindowToken appToken = mService.mAppTokens.get(i);
+ final boolean wasAnimating = appToken.animation != null
+ && appToken.animation != WindowManagerService.sDummyAnimation;
if (appToken.stepAnimationLocked(mCurrentTime, mInnerDw, mInnerDh)) {
mAnimating = true;
+ } else if (wasAnimating) {
+ // stopped animating, do one more pass through the layout
+ mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
+ if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
+ mService.debugLayoutRepeats("appToken " + appToken + " done");
+ }
+ }
+ }
+
+ final int NEAT = mService.mExitingAppTokens.size();
+ for (i=0; i<NEAT; i++) {
+ final AppWindowToken appToken = mService.mExitingAppTokens.get(i);
+ final boolean wasAnimating = appToken.animation != null
+ && appToken.animation != WindowManagerService.sDummyAnimation;
+ if (appToken.stepAnimationLocked(mCurrentTime, mInnerDw, mInnerDh)) {
+ mAnimating = true;
+ } else if (wasAnimating) {
+ // stopped animating, do one more pass through the layout
+ mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
+ if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
+ mService.debugLayoutRepeats("exiting appToken " + appToken + " done");
+ }
}
}
@@ -103,6 +127,9 @@
"First draw done in potential wallpaper target " + w);
mService.mInnerFields.mWallpaperMayChange = true;
mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
+ if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
+ mService.debugLayoutRepeats("updateWindowsAndWallpaperLocked 1");
+ }
}
}
@@ -176,6 +203,9 @@
if (wasAnimating && !w.mAnimating && mService.mWallpaperTarget == w) {
mService.mInnerFields.mWallpaperMayChange = true;
mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
+ if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
+ mService.debugLayoutRepeats("updateWindowsAndWallpaperLocked 2");
+ }
}
if (mPolicy.doesForceHide(w, attrs)) {
@@ -185,6 +215,9 @@
+ w);
mService.mInnerFields.mWallpaperForceHidingChanged = true;
mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
+ if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
+ mService.debugLayoutRepeats("updateWindowsAndWallpaperLocked 3");
+ }
mService.mFocusMayChange = true;
} else if (w.isReadyForDisplay() && w.mAnimation == null) {
mForceHiding = true;
@@ -223,6 +256,9 @@
& WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) {
mService.mInnerFields.mWallpaperMayChange = true;
mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
+ if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
+ mService.debugLayoutRepeats("updateWindowsAndWallpaperLocked 4");
+ }
}
}
}
@@ -270,8 +306,21 @@
}
}
} else if (w.mReadyToShow) {
- w.performShowLocked();
- mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
+ if (w.performShowLocked()) {
+ mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
+ if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
+ mService.debugLayoutRepeats("updateWindowsAndWallpaperLocked 5");
+ }
+ }
+ }
+ if (atoken != null && atoken.thumbnail != null) {
+ if (atoken.thumbnailTransactionSeq != mTransactionSequence) {
+ atoken.thumbnailTransactionSeq = mTransactionSequence;
+ atoken.thumbnailLayer = 0;
+ }
+ if (atoken.thumbnailLayer < w.mAnimLayer) {
+ atoken.thumbnailLayer = w.mAnimLayer;
+ }
}
} // end forall windows
}
@@ -306,6 +355,9 @@
+ " drawn=" + wtoken.numDrawnWindows);
wtoken.allDrawn = true;
mPendingLayoutChanges |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
+ if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
+ mService.debugLayoutRepeats("testTokenMayBeDrawnLocked");
+ }
// We can now show all of the drawn windows!
if (!mService.mOpeningApps.contains(wtoken)) {
@@ -517,6 +569,7 @@
}
void animate() {
+ mPendingLayoutChanges = 0;
mCurrentTime = SystemClock.uptimeMillis();
// Update animations of all applications, including those
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 26367d2..e430529 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -89,6 +89,7 @@
import android.provider.Settings;
import android.util.DisplayMetrics;
import android.util.EventLog;
+import android.util.FloatMath;
import android.util.Log;
import android.util.Pair;
import android.util.Slog;
@@ -117,8 +118,12 @@
import android.view.WindowManagerPolicy;
import android.view.WindowManager.LayoutParams;
import android.view.WindowManagerPolicy.FakeWindow;
+import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
+import android.view.animation.AnimationSet;
import android.view.animation.AnimationUtils;
+import android.view.animation.Interpolator;
+import android.view.animation.ScaleAnimation;
import android.view.animation.Transformation;
import java.io.BufferedWriter;
@@ -166,10 +171,12 @@
static final boolean DEBUG_SCREEN_ON = false;
static final boolean DEBUG_SCREENSHOT = false;
static final boolean DEBUG_BOOT = false;
+ static final boolean DEBUG_LAYOUT_REPEATS = false;
static final boolean SHOW_SURFACE_ALLOC = false;
static final boolean SHOW_TRANSACTIONS = false;
static final boolean SHOW_LIGHT_TRANSACTIONS = false || SHOW_TRANSACTIONS;
static final boolean HIDE_STACK_CRAWLS = true;
+ static final int LAYOUT_REPEAT_THRESHOLD = 4;
static final boolean PROFILE_ORIENTATION = false;
static final boolean localLOGV = DEBUG;
@@ -194,6 +201,18 @@
static final int LAYER_OFFSET_DIM = 1;
/**
+ * Blur surface layer is immediately below dim layer.
+ */
+ static final int LAYER_OFFSET_BLUR = 2;
+
+ /**
+ * Animation thumbnail is as far as possible below the window above
+ * the thumbnail (or in other words as far as possible above the window
+ * below it).
+ */
+ static final int LAYER_OFFSET_THUMBNAIL = WINDOW_LAYER_MULTIPLIER-1;
+
+ /**
* Layer at which to put the rotation freeze snapshot.
*/
static final int FREEZE_LAYER = (TYPE_LAYER_MULTIPLIER * 200) + 1;
@@ -479,8 +498,12 @@
// made visible or hidden at the next transition.
int mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
String mNextAppTransitionPackage;
+ Bitmap mNextAppTransitionThumbnail;
+ IRemoteCallback mNextAppTransitionCallback;
int mNextAppTransitionEnter;
int mNextAppTransitionExit;
+ int mNextAppTransitionStartX;
+ int mNextAppTransitionStartY;
boolean mAppTransitionReady = false;
boolean mAppTransitionRunning = false;
boolean mAppTransitionTimeout = false;
@@ -588,6 +611,9 @@
}
LayoutAndSurfaceFields mInnerFields = new LayoutAndSurfaceFields();
+ /** Only do a maximum of 6 repeated layouts. After that quit */
+ private int mLayoutRepeatCount;
+
private final class AnimationRunnable implements Runnable {
@Override
public void run() {
@@ -1897,7 +1923,7 @@
rawChanged = true;
}
- if (rawChanged && (wallpaperWin.getAttrs().privateFlags &
+ if (rawChanged && (wallpaperWin.mAttrs.privateFlags &
WindowManager.LayoutParams.PRIVATE_FLAG_WANTS_OFFSET_NOTIFICATIONS) != 0) {
try {
if (DEBUG_WALLPAPER) Slog.v(TAG, "Report new wp offset "
@@ -2296,7 +2322,7 @@
if (wasVisible) {
int transit = WindowManagerPolicy.TRANSIT_EXIT;
- if (win.getAttrs().type == TYPE_APPLICATION_STARTING) {
+ if (win.mAttrs.type == TYPE_APPLICATION_STARTING) {
transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
}
// Try starting an animation.
@@ -2441,6 +2467,15 @@
Slog.i(TAG, str);
}
}
+
+ static void logSurface(Surface s, String title, String msg, RuntimeException where) {
+ String str = " SURFACE " + s + ": " + msg + " / " + title;
+ if (where != null) {
+ Slog.i(TAG, str, where);
+ } else {
+ Slog.i(TAG, str);
+ }
+ }
void setTransparentRegionWindow(Session session, IWindow client, Region region) {
long origId = Binder.clearCallingIdentity();
@@ -2761,7 +2796,7 @@
// Try starting an animation; if there isn't one, we
// can destroy the surface right away.
int transit = WindowManagerPolicy.TRANSIT_EXIT;
- if (win.getAttrs().type == TYPE_APPLICATION_STARTING) {
+ if (win.mAttrs.type == TYPE_APPLICATION_STARTING) {
transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
}
if (!win.mSurfacePendingDestroy && win.isWinVisibleLw() &&
@@ -3081,6 +3116,63 @@
return null;
}
+ private Animation createThumbnailAnimationLocked(int transit,
+ boolean enter, boolean thumb) {
+ Animation a;
+ final float thumbWidth = mNextAppTransitionThumbnail.getWidth();
+ final float thumbHeight = mNextAppTransitionThumbnail.getHeight();
+ // Pick the desired duration. If this is an inter-activity transition,
+ // it is the standard duration for that. Otherwise we use the longer
+ // task transition duration.
+ int duration;
+ switch (transit) {
+ case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
+ case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
+ duration = mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_shortAnimTime);
+ break;
+ default:
+ duration = 500;
+ break;
+
+ }
+ if (thumb) {
+ // Animation for zooming thumbnail from its initial size to
+ // filling the screen.
+ Animation scale = new ScaleAnimation(
+ 1, mAppDisplayWidth/thumbWidth,
+ 1, mAppDisplayHeight/thumbHeight,
+ mNextAppTransitionStartX + thumbWidth/2,
+ mNextAppTransitionStartY + thumbHeight/2);
+ AnimationSet set = new AnimationSet(true);
+ Animation alpha = new AlphaAnimation(1, 0);
+ scale.setDuration(duration);
+ set.addAnimation(scale);
+ alpha.setDuration(duration);
+ set.addAnimation(alpha);
+ a = set;
+ } else if (enter) {
+ // Entering app zooms out from the center of the thumbnail.
+ a = new ScaleAnimation(
+ thumbWidth/mAppDisplayWidth, 1,
+ thumbHeight/mAppDisplayHeight, 1,
+ mNextAppTransitionStartX + thumbWidth/2,
+ mNextAppTransitionStartY + thumbHeight/2);
+ a.setDuration(duration);
+ } else {
+ // Exiting app just holds in place.
+ a = new AlphaAnimation(1, 1);
+ a.setDuration(duration);
+ }
+ a.setFillAfter(true);
+ final Interpolator interpolator = AnimationUtils.loadInterpolator(mContext,
+ com.android.internal.R.interpolator.decelerate_quint);
+ a.setInterpolator(interpolator);
+ a.initialize(mAppDisplayWidth, mAppDisplayHeight,
+ mAppDisplayWidth, mAppDisplayHeight);
+ return a;
+ }
+
private boolean applyAnimationLocked(AppWindowToken wtoken,
WindowManager.LayoutParams lp, int transit, boolean enter) {
// Only apply an animation if the display isn't frozen. If it is
@@ -3089,7 +3181,11 @@
// is running.
if (okToDisplay()) {
Animation a;
- if (mNextAppTransitionPackage != null) {
+ boolean initialized = false;
+ if (mNextAppTransitionThumbnail != null) {
+ a = createThumbnailAnimationLocked(transit, enter, false);
+ initialized = true;
+ } else if (mNextAppTransitionPackage != null) {
a = loadAnimation(mNextAppTransitionPackage, enter ?
mNextAppTransitionEnter : mNextAppTransitionExit);
} else {
@@ -3161,7 +3257,7 @@
}
Slog.v(TAG, "Loaded animation " + a + " for " + wtoken, e);
}
- wtoken.setAnimation(a);
+ wtoken.setAnimation(a, initialized);
}
} else {
wtoken.clearAnimation();
@@ -3233,6 +3329,7 @@
return wtoken.appWindowToken;
}
+ @Override
public void addWindowToken(IBinder token, int type) {
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
"addWindowToken()")) {
@@ -3689,11 +3786,23 @@
int enterAnim, int exitAnim) {
if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
mNextAppTransitionPackage = packageName;
+ mNextAppTransitionThumbnail = null;
mNextAppTransitionEnter = enterAnim;
mNextAppTransitionExit = exitAnim;
}
}
+ public void overridePendingAppTransitionThumb(Bitmap srcThumb, int startX,
+ int startY, IRemoteCallback startedCallback) {
+ if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
+ mNextAppTransitionPackage = null;
+ mNextAppTransitionThumbnail = srcThumb;
+ mNextAppTransitionStartX = startX;
+ mNextAppTransitionStartY = startY;
+ mNextAppTransitionCallback = startedCallback;
+ }
+ }
+
public void executeAppTransition() {
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
"executeAppTransition()")) {
@@ -3837,6 +3946,19 @@
mH.sendMessageAtFrontOfQueue(m);
return;
}
+ if (ttoken.thumbnail != null) {
+ // The old token is animating with a thumbnail, transfer
+ // that to the new token.
+ if (wtoken.thumbnail != null) {
+ wtoken.thumbnail.destroy();
+ }
+ wtoken.thumbnail = ttoken.thumbnail;
+ wtoken.thumbnailX = ttoken.thumbnailX;
+ wtoken.thumbnailY = ttoken.thumbnailY;
+ wtoken.thumbnailLayer = ttoken.thumbnailLayer;
+ wtoken.thumbnailAnimation = ttoken.thumbnailAnimation;
+ ttoken.thumbnail = null;
+ }
}
}
@@ -4232,6 +4354,7 @@
// Make sure there is no animation running on this token,
// so any windows associated with it will be removed as
// soon as their animations are complete
+ wtoken.clearAnimation();
wtoken.animation = null;
wtoken.animating = false;
}
@@ -5139,8 +5262,8 @@
synchronized(mWindowMap) {
long ident = Binder.clearCallingIdentity();
- dw = mAppDisplayWidth;
- dh = mAppDisplayHeight;
+ dw = mCurDisplayWidth;
+ dh = mCurDisplayHeight;
int aboveAppLayer = mPolicy.windowTypeToLayerLw(
WindowManager.LayoutParams.TYPE_APPLICATION) * TYPE_LAYER_MULTIPLIER
@@ -5260,7 +5383,7 @@
Bitmap bm = Bitmap.createBitmap(width, height, rawss.getConfig());
Matrix matrix = new Matrix();
ScreenRotationAnimation.createRotationMatrix(rot, dw, dh, matrix);
- matrix.postTranslate(-(int)(frame.left*scale), -(int)(frame.top*scale));
+ matrix.postTranslate(-FloatMath.ceil(frame.left*scale), -FloatMath.ceil(frame.top*scale));
Canvas canvas = new Canvas(bm);
canvas.drawBitmap(rawss, matrix, null);
canvas.setBitmap(null);
@@ -7459,10 +7582,25 @@
} else {
mInLayout = false;
- if (mLayoutNeeded) {
- requestTraversalLocked();
- }
}
+
+ if (mLayoutNeeded) {
+ if (++mLayoutRepeatCount < 6) {
+ requestTraversalLocked();
+ } else {
+ Slog.e(TAG, "Performed 6 layouts in a row. Skipping");
+ mLayoutRepeatCount = 0;
+ }
+ } else {
+ mLayoutRepeatCount = 0;
+ }
+
+ if (mAnimator.mAnimating) {
+ // Do this even if requestTraversalLocked was called above so we get a frame drawn
+ // at the proper time as well as the one drawn early.
+ scheduleAnimationLocked();
+ }
+
if (mWindowsChanged && !mWindowChangeListeners.isEmpty()) {
mH.removeMessages(H.REPORT_WINDOWS_CHANGE);
mH.sendMessage(mH.obtainMessage(H.REPORT_WINDOWS_CHANGE));
@@ -7784,11 +7922,15 @@
animLp = null;
}
+ AppWindowToken topOpeningApp = null;
+ int topOpeningLayer = 0;
+
NN = mOpeningApps.size();
for (i=0; i<NN; i++) {
AppWindowToken wtoken = mOpeningApps.get(i);
if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
"Now opening app" + wtoken);
+ wtoken.clearThumbnail();
wtoken.reportedVisible = false;
wtoken.inPendingTransaction = false;
wtoken.animation = null;
@@ -7797,12 +7939,26 @@
wtoken.updateReportedVisibilityLocked();
wtoken.waitingToShow = false;
mAnimator.mAnimating |= wtoken.showAllWindowsLocked();
+ if (animLp != null) {
+ int layer = -1;
+ for (int j=0; j<wtoken.windows.size(); j++) {
+ WindowState win = wtoken.windows.get(j);
+ if (win.mAnimLayer > layer) {
+ layer = win.mAnimLayer;
+ }
+ }
+ if (topOpeningApp == null || layer > topOpeningLayer) {
+ topOpeningApp = wtoken;
+ topOpeningLayer = layer;
+ }
+ }
}
NN = mClosingApps.size();
for (i=0; i<NN; i++) {
AppWindowToken wtoken = mClosingApps.get(i);
if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
"Now closing app" + wtoken);
+ wtoken.clearThumbnail();
wtoken.inPendingTransaction = false;
wtoken.animation = null;
setTokenVisibilityLocked(wtoken, animLp, false,
@@ -7815,7 +7971,47 @@
wtoken.allDrawn = true;
}
+ if (mNextAppTransitionThumbnail != null && topOpeningApp != null
+ && topOpeningApp.animation != null) {
+ // This thumbnail animation is very special, we need to have
+ // an extra surface with the thumbnail included with the animation.
+ Rect dirty = new Rect(0, 0, mNextAppTransitionThumbnail.getWidth(),
+ mNextAppTransitionThumbnail.getHeight());
+ try {
+ Surface surface = new Surface(mFxSession, Process.myPid(),
+ "thumbnail anim", 0, dirty.width(), dirty.height(),
+ PixelFormat.TRANSLUCENT, Surface.HIDDEN);
+ topOpeningApp.thumbnail = surface;
+ if (SHOW_TRANSACTIONS) Slog.i(TAG, " THUMBNAIL "
+ + surface + ": CREATE");
+ Surface drawSurface = new Surface();
+ drawSurface.copyFrom(surface);
+ Canvas c = drawSurface.lockCanvas(dirty);
+ c.drawBitmap(mNextAppTransitionThumbnail, 0, 0, null);
+ drawSurface.unlockCanvasAndPost(c);
+ drawSurface.release();
+ topOpeningApp.thumbnailLayer = topOpeningLayer;
+ Animation anim = createThumbnailAnimationLocked(transit, true, true);
+ topOpeningApp.thumbnailAnimation = anim;
+ anim.restrictDuration(MAX_ANIMATION_DURATION);
+ anim.scaleCurrentDuration(mTransitionAnimationScale);
+ topOpeningApp.thumbnailX = mNextAppTransitionStartX;
+ topOpeningApp.thumbnailY = mNextAppTransitionStartY;
+ } catch (Surface.OutOfResourcesException e) {
+ Slog.e(TAG, "Can't allocate thumbnail surface w=" + dirty.width()
+ + " h=" + dirty.height(), e);
+ topOpeningApp.clearThumbnail();
+ }
+ }
+
mNextAppTransitionPackage = null;
+ mNextAppTransitionThumbnail = null;
+ if (mNextAppTransitionCallback != null) {
+ try {
+ mNextAppTransitionCallback.sendResult(null);
+ } catch (RemoteException e) {
+ }
+ }
mOpeningApps.clear();
mClosingApps.clear();
@@ -8186,12 +8382,15 @@
break;
}
+ if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("On entry to LockedInner");
+
if ((mPendingLayoutChanges & WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0) {
if ((adjustWallpaperWindowsLocked()&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
assignLayersLocked();
mLayoutNeeded = true;
}
}
+
if ((mPendingLayoutChanges & WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG) != 0) {
if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
if (updateOrientationFromAppTokensLocked(true)) {
@@ -8199,6 +8398,7 @@
mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
}
}
+
if ((mPendingLayoutChanges & WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT) != 0) {
mLayoutNeeded = true;
}
@@ -8213,6 +8413,7 @@
// FIRST AND ONE HALF LOOP: Make WindowManagerPolicy think
// it is animating.
mPendingLayoutChanges = 0;
+ if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("loop number " + mLayoutRepeatCount);
mPolicy.beginAnimationLw(dw, dh);
for (i = mWindows.size() - 1; i >= 0; i--) {
WindowState w = mWindows.get(i);
@@ -8221,7 +8422,7 @@
}
}
mPendingLayoutChanges |= mPolicy.finishAnimationLw();
-
+ if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after finishAnimationLw");
} while (mPendingLayoutChanges != 0);
final boolean someoneLosingFocus = !mLosingFocus.isEmpty();
@@ -8266,6 +8467,7 @@
// to go.
if (mAppTransitionReady) {
mPendingLayoutChanges |= handleAppTransitionReadyLocked();
+ if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after handleAppTransitionReadyLocked");
}
mInnerFields.mAdjResult = 0;
@@ -8278,6 +8480,7 @@
// be out of sync with it. So here we will just rebuild the
// entire app window list. Fun!
mPendingLayoutChanges |= handleAnimatingStoppedAndTransitionLocked();
+ if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after handleAnimStopAndXitionLock");
}
if (mInnerFields.mWallpaperForceHidingChanged && mPendingLayoutChanges == 0 &&
@@ -8289,12 +8492,15 @@
// hard -- the wallpaper now needs to be shown behind
// something that was hidden.
mPendingLayoutChanges |= animateAwayWallpaperLocked();
+ if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after animateAwayWallpaperLocked");
}
mPendingLayoutChanges |= testWallpaperAndBackgroundLocked();
+ if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after testWallpaperAndBackgroundLocked");
if (mLayoutNeeded) {
mPendingLayoutChanges |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
+ if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("mLayoutNeeded");
}
final int N = mWindows.size();
@@ -8308,6 +8514,7 @@
// associated with exiting/removed apps
mAnimator.animate();
mPendingLayoutChanges |= mAnimator.mPendingLayoutChanges;
+ if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after animate()");
if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
"<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces");
@@ -8400,6 +8607,7 @@
// Make sure there is no animation running on this token,
// so any windows associated with it will be removed as
// soon as their animations are complete
+ token.clearAnimation();
token.animation = null;
token.animating = false;
if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
@@ -8409,8 +8617,6 @@
}
}
- boolean needRelayout = false;
-
if (!mAnimator.mAnimating && mAppTransitionRunning) {
// We have finished the animation of an app transition. To do
// this, we have delayed a lot of operations like showing and
@@ -8419,7 +8625,7 @@
// be out of sync with it. So here we will just rebuild the
// entire app window list. Fun!
mAppTransitionRunning = false;
- needRelayout = true;
+ mLayoutNeeded = true;
rebuildAppWindowListLocked();
assignLayersLocked();
// Clear information about apps that were moving.
@@ -8430,19 +8636,10 @@
mH.sendEmptyMessage(H.REPORT_LOSING_FOCUS);
}
if (wallpaperDestroyed) {
- needRelayout = adjustWallpaperWindowsLocked() != 0;
+ mLayoutNeeded |= adjustWallpaperWindowsLocked() != 0;
}
- if ((mPendingLayoutChanges & (
- WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER |
- ADJUST_WALLPAPER_LAYERS_CHANGED |
- WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG |
- WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT)) != 0) {
- needRelayout = true;
- }
- if (needRelayout) {
- requestTraversalLocked();
- } else if (mAnimator.mAnimating) {
- scheduleAnimationLocked();
+ if (mPendingLayoutChanges != 0) {
+ mLayoutNeeded = true;
}
// Finally update all input windows now that the window changes have stabilized.
@@ -8485,7 +8682,7 @@
}
}
- if (mInnerFields.mOrientationChangeComplete && !needRelayout &&
+ if (mInnerFields.mOrientationChangeComplete && !mLayoutNeeded &&
!mInnerFields.mUpdateRotation) {
checkDrawnWindowsLocked();
}
@@ -8839,6 +9036,7 @@
if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
mNextAppTransition = WindowManagerPolicy.TRANSIT_UNSET;
mNextAppTransitionPackage = null;
+ mNextAppTransitionThumbnail = null;
mAppTransitionReady = true;
}
@@ -9399,6 +9597,12 @@
pw.print(" mNextAppTransitionExit=0x");
pw.print(Integer.toHexString(mNextAppTransitionExit));
}
+ if (mNextAppTransitionThumbnail != null) {
+ pw.print(" mNextAppTransitionThumbnail=");
+ pw.print(mNextAppTransitionThumbnail);
+ pw.print(" mNextAppTransitionStartX="); pw.print(mNextAppTransitionStartX);
+ pw.print(" mNextAppTransitionStartY="); pw.println(mNextAppTransitionStartY);
+ }
pw.print(" mStartingIconInTransition="); pw.print(mStartingIconInTransition);
pw.print(", mSkipAppTransitionAnimation="); pw.println(mSkipAppTransitionAnimation);
}
@@ -9566,4 +9770,11 @@
public interface OnHardKeyboardStatusChangeListener {
public void onHardKeyboardStatusChange(boolean available, boolean enabled);
}
+
+ void debugLayoutRepeats(final String msg) {
+ if (mLayoutRepeatCount >= LAYOUT_REPEAT_THRESHOLD) {
+ Slog.v(TAG, "Layouts looping: " + msg);
+ Slog.v(TAG, "mPendingLayoutChanges = 0x" + Integer.toHexString(mPendingLayoutChanges));
+ }
+ }
}
diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java
index cf61f7f..1146189 100644
--- a/services/java/com/android/server/wm/WindowState.java
+++ b/services/java/com/android/server/wm/WindowState.java
@@ -989,6 +989,8 @@
}
mAppToken.updateReportedVisibilityLocked();
}
+ } else {
+ return false;
}
return true;
}
@@ -1128,6 +1130,7 @@
finishExit();
mService.mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
+ if (WindowManagerService.DEBUG_LAYOUT_REPEATS) mService.debugLayoutRepeats("WindowState");
if (mAppToken != null) {
mAppToken.updateReportedVisibilityLocked();
diff --git a/tests/permission/src/com/android/framework/permission/tests/ActivityManagerPermissionTests.java b/tests/permission/src/com/android/framework/permission/tests/ActivityManagerPermissionTests.java
index 4cacbc4..cceed16 100644
--- a/tests/permission/src/com/android/framework/permission/tests/ActivityManagerPermissionTests.java
+++ b/tests/permission/src/com/android/framework/permission/tests/ActivityManagerPermissionTests.java
@@ -39,7 +39,7 @@
@SmallTest
public void testREORDER_TASKS() {
try {
- mAm.moveTaskToFront(0, 0);
+ mAm.moveTaskToFront(0, 0, null);
fail("IActivityManager.moveTaskToFront did not throw SecurityException as"
+ " expected");
} catch (SecurityException e) {
diff --git a/tools/layoutlib/bridge/src/android/graphics/BitmapFactory_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/BitmapFactory_Delegate.java
index 945b3cd7..5256b58 100644
--- a/tools/layoutlib/bridge/src/android/graphics/BitmapFactory_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/BitmapFactory_Delegate.java
@@ -85,15 +85,18 @@
// ------ Native Delegates ------
@LayoutlibDelegate
- /*package*/ static void nativeSetDefaultConfig(int nativeConfig) {
- // pass
+ /*package*/ static Bitmap nativeDecodeStream(InputStream is, byte[] storage,
+ Rect padding, Options opts) {
+ return nativeDecodeStream(is, storage, padding, opts, false, 1.f);
}
@LayoutlibDelegate
- /*package*/ static Bitmap nativeDecodeStream(InputStream is, byte[] storage,
- Rect padding, Options opts) {
+ /*package*/ static Bitmap nativeDecodeStream(InputStream is, byte[] storage,
+ Rect padding, Options opts, boolean applyScale, float scale) {
Bitmap bm = null;
+ //TODO support rescaling
+
Density density = Density.MEDIUM;
if (opts != null) {
density = Density.getEnum(opts.inDensity);
@@ -147,6 +150,13 @@
}
@LayoutlibDelegate
+ /*package*/ static Bitmap nativeDecodeAsset(int asset, Rect padding, Options opts,
+ boolean applyScale, float scale) {
+ opts.inBitmap = null;
+ return null;
+ }
+
+ @LayoutlibDelegate
/*package*/ static Bitmap nativeDecodeByteArray(byte[] data, int offset,
int length, Options opts) {
opts.inBitmap = null;
diff --git a/tools/layoutlib/bridge/src/android/view/ViewRootImpl_Delegate.java b/tools/layoutlib/bridge/src/android/view/ViewRootImpl_Delegate.java
new file mode 100644
index 0000000..14b84ef
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/view/ViewRootImpl_Delegate.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+/**
+ * Delegate used to provide new implementation of a select few methods of {@link ViewRootImpl}
+ *
+ * Through the layoutlib_create tool, the original methods of ViewRootImpl have been replaced
+ * by calls to methods of the same name in this delegate class.
+ *
+ */
+public class ViewRootImpl_Delegate {
+
+ @LayoutlibDelegate
+ /*package*/ static boolean isInTouchMode() {
+ return false; // this allows displaying selection.
+ }
+}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java
index bef2c95..8b1d41a 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java
@@ -340,6 +340,12 @@
}
@Override
+ public void overridePendingAppTransitionThumb(Bitmap srcThumb, int startX, int startY,
+ IRemoteCallback startedCallback) throws RemoteException {
+ // TODO Auto-generated method stub
+ }
+
+ @Override
public void pauseKeyDispatching(IBinder arg0) throws RemoteException {
// TODO Auto-generated method stub
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
index 170cd6a..79e02c8 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
@@ -114,6 +114,7 @@
"android.view.LayoutInflater#rInflate",
"android.view.LayoutInflater#parseInclude",
"android.view.View#isInEditMode",
+ "android.view.ViewRootImpl#isInTouchMode",
"android.view.inputmethod.InputMethodManager#getInstance",
"android.util.Log#println_native",
"com.android.internal.util.XmlUtils#convertValueToInt",