summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/current.xml44
-rw-r--r--cmds/dumpstate/Android.mk11
-rw-r--r--cmds/dumpstate/dumpstate.c501
-rw-r--r--cmds/dumpstate/dumpstate.h153
-rw-r--r--cmds/dumpstate/utils.c412
-rw-r--r--core/java/android/inputmethodservice/InputMethodService.java9
-rw-r--r--core/java/android/net/ConnectivityManager.java14
-rw-r--r--core/java/android/os/IMountService.aidl9
-rw-r--r--core/java/android/os/Power.java18
-rw-r--r--core/java/android/pim/vcard/VCardParser_V21.java4
-rw-r--r--core/java/android/provider/Calendar.java4
-rw-r--r--core/java/android/view/TransformGestureDetector.java316
-rw-r--r--core/java/android/view/VelocityTracker.java139
-rw-r--r--core/java/android/view/inputmethod/EditorInfo.java10
-rw-r--r--core/java/android/webkit/MimeTypeMap.java6
-rw-r--r--core/java/android/webkit/WebTextView.java13
-rw-r--r--core/java/com/android/internal/app/ExternalMediaFormatActivity.java2
-rw-r--r--core/jni/android_os_Power.cpp2
-rw-r--r--graphics/java/android/renderscript/Allocation.java4
-rw-r--r--graphics/java/android/renderscript/Program.java5
-rw-r--r--include/media/stagefright/MetaData.h3
-rw-r--r--libs/rs/rsProgram.cpp16
-rw-r--r--libs/rs/rsProgram.h4
-rw-r--r--libs/rs/rsProgramVertex.cpp130
-rw-r--r--libs/rs/rsProgramVertex.h2
-rw-r--r--libs/rs/rsScriptC_Lib.cpp10
-rw-r--r--libs/rs/rsShaderCache.cpp2
-rw-r--r--media/libmediaplayerservice/MediaPlayerService.cpp127
-rw-r--r--media/libmediaplayerservice/MediaPlayerService.h1
-rw-r--r--media/libstagefright/MP3Extractor.cpp4
-rw-r--r--media/libstagefright/MPEG4Extractor.cpp63
-rw-r--r--media/libstagefright/StagefrightMetadataRetriever.cpp13
-rw-r--r--media/libstagefright/codecs/mp3dec/MP3Decoder.cpp3
-rw-r--r--services/java/com/android/server/INativeDaemonConnectorCallbacks.java (renamed from tests/AndroidTests/src/com/android/unit_tests/vcard/VCardTestSuite.java)21
-rw-r--r--services/java/com/android/server/MountListener.java377
-rw-r--r--services/java/com/android/server/MountService.java218
-rw-r--r--services/java/com/android/server/NativeDaemonConnector.java239
-rw-r--r--services/java/com/android/server/WifiService.java11
-rw-r--r--telephony/java/com/android/internal/telephony/Call.java17
-rw-r--r--telephony/java/com/android/internal/telephony/ServiceStateTracker.java7
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java66
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java2
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java49
-rw-r--r--tests/AndroidTests/src/com/android/unit_tests/AndroidTests.java32
-rw-r--r--tests/AndroidTests/src/com/android/unit_tests/DatabaseCursorTest.java626
-rw-r--r--tests/AndroidTests/src/com/android/unit_tests/DatabaseStatementTest.java320
-rw-r--r--tests/AndroidTests/src/com/android/unit_tests/DatabaseTests.java2
-rw-r--r--tests/AndroidTests/src/com/android/unit_tests/NeighboringCellInfoTest.java79
-rw-r--r--tests/AndroidTests/src/com/android/unit_tests/content/ArrayTest.java77
-rw-r--r--tests/AndroidTests/src/com/android/unit_tests/content/ConfigTest.java540
-rw-r--r--tests/AndroidTests/src/com/android/unit_tests/content/ContentTests.java4
-rw-r--r--tests/AndroidTests/src/com/android/unit_tests/content/FractionTest.java92
-rw-r--r--tests/AndroidTests/src/com/android/unit_tests/content/IntentFilterTest.java570
-rw-r--r--tests/AndroidTests/src/com/android/unit_tests/content/PluralResourcesTest.java97
-rw-r--r--tests/AndroidTests/src/com/android/unit_tests/content/PrimitiveTest.java141
-rw-r--r--tests/AndroidTests/src/com/android/unit_tests/content/RawResourceTest.java40
-rw-r--r--tests/AndroidTests/src/com/android/unit_tests/content/ResourceNameTest.java61
-rw-r--r--tests/AndroidTests/src/com/android/unit_tests/content/ResourceTests.java33
-rw-r--r--tests/CoreTests/android/core/CoreTests.java1
-rw-r--r--tests/CoreTests/android/webkit/CookieTest.java193
-rw-r--r--tests/FrameworkTest/tests/src/com/android/frameworktest/expandablelistview/ExpandableListWithHeadersTest.java66
-rw-r--r--tests/FrameworkTest/tests/src/com/android/frameworktest/view/RemoteViewsActivityTest.java126
-rw-r--r--tests/TransformTest/Android.mk10
-rw-r--r--tests/TransformTest/AndroidManifest.xml28
-rw-r--r--tests/TransformTest/res/drawable/logo.pngbin0 -> 13388 bytes
-rw-r--r--tests/TransformTest/res/values/strings.xml19
-rw-r--r--tests/TransformTest/src/com/google/android/test/transform/TransformTestActivity.java171
-rw-r--r--tools/aapt/Resource.cpp48
68 files changed, 2041 insertions, 4396 deletions
diff --git a/api/current.xml b/api/current.xml
index 92540b1f9715..f3e614a11db6 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -83874,6 +83874,50 @@
visibility="public"
>
</field>
+<field name="TYPE_MOBILE_DUN"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="4"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TYPE_MOBILE_HIPRI"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="5"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TYPE_MOBILE_MMS"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TYPE_MOBILE_SUPL"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="3"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="TYPE_WIFI"
type="int"
transient="false"
diff --git a/cmds/dumpstate/Android.mk b/cmds/dumpstate/Android.mk
index 27891ecf6fd1..431a55658b48 100644
--- a/cmds/dumpstate/Android.mk
+++ b/cmds/dumpstate/Android.mk
@@ -15,15 +15,4 @@ LOCAL_SHARED_LIBRARIES := libcutils
include $(BUILD_EXECUTABLE)
-COMMANDS = dumpcrash
-SYMLINKS := $(addprefix $(TARGET_OUT_EXECUTABLES)/,$(COMMANDS))
-$(SYMLINKS): DUMPSTATE_BINARY := dumpstate
-$(SYMLINKS): $(LOCAL_INSTALLED_MODULE) $(LOCAL_PATH)/Android.mk
- @echo "Symlink: $@ -> $(DUMPSTATE_BINARY)"
- @mkdir -p $(dir $@)
- @rm -rf $@
- $(hide) ln -sf $(DUMPSTATE_BINARY) $@
-
-ALL_DEFAULT_INSTALLED_MODULES += $(SYMLINKS)
-
endif
diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c
index a2b5d8df9f2c..9300915fa458 100644
--- a/cmds/dumpstate/dumpstate.c
+++ b/cmds/dumpstate/dumpstate.c
@@ -14,361 +14,254 @@
* limitations under the License.
*/
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <unistd.h>
+#include <sys/resource.h>
#include <sys/stat.h>
-#include <limits.h>
-#include <errno.h>
-#include <fcntl.h>
#include <sys/time.h>
-#include <sys/resource.h>
+#include <unistd.h>
-#include <cutils/sockets.h>
-#include "private/android_filesystem_config.h"
+#include <cutils/properties.h>
+#include "private/android_filesystem_config.h"
#define LOG_TAG "dumpstate"
#include <utils/Log.h>
#include "dumpstate.h"
-static char* const gzip_args[] = { "gzip", "-6", 0 };
-static int start_pattern[] = { 150, 0 };
-static int end_pattern[] = { 75, 50, 75, 50, 75, 0 };
-
-static struct tm now;
-
-static void dump_kernel_log(const char *path, const char *title) ;
+/* read before root is shed */
+static char cmdline_buf[16384] = "(unknown)";
+static const char *dump_traces_path = NULL;
/* dumps the current system state to stdout */
-static void dumpstate(int full) {
- if (full) {
- PRINT("========================================================");
- PRINT("== dumpstate");
- PRINT("========================================================");
- PRINT("------ MEMORY INFO ------");
- DUMP("/proc/meminfo");
- PRINT("------ CPU INFO ------");
- EXEC7("top", "-n", "1", "-d", "1", "-m", "30", "-t");
- PRINT("------ PROCRANK ------");
- EXEC_XBIN("procrank");
- PRINT("------ VIRTUAL MEMORY STATS ------");
- DUMP("/proc/vmstat");
- PRINT("------ VMALLOC INFO ------");
- DUMP("/proc/vmallocinfo");
- PRINT("------ SLAB INFO ------");
- DUMP("/proc/slabinfo");
- PRINT("------ ZONEINFO ------");
- DUMP("/proc/zoneinfo");
- PRINT("------ SYSTEM LOG ------");
- EXEC4("logcat", "-v", "time", "-d", "*:v");
- PRINT("------ VM TRACES ------");
- DUMP("/data/anr/traces.txt");
- PRINT("------ EVENT LOG TAGS ------");
- DUMP("/etc/event-log-tags");
- PRINT("------ EVENT LOG ------");
- EXEC6("logcat", "-b", "events", "-v", "time", "-d", "*:v");
- PRINT("------ RADIO LOG ------");
- EXEC6("logcat", "-b", "radio", "-v", "time", "-d", "*:v");
- PRINT("------ NETWORK STATE ------");
- PRINT("Interfaces:");
- EXEC("netcfg");
- PRINT("");
- PRINT("Routes:");
- DUMP("/proc/net/route");
-#ifdef FWDUMP_bcm4329
- PRINT("Dump wlan FW log");
- EXEC_XBIN6("su", "root","dhdutil","-i","eth0","upload","/data/local/tmp/wlan_crash.dump");
-#endif
- PRINT("------ SYSTEM PROPERTIES ------");
- print_properties();
- PRINT("------ KERNEL LOG ------");
- EXEC("dmesg");
- PRINT("------ KERNEL WAKELOCKS ------");
- DUMP("/proc/wakelocks");
- PRINT("------ KERNEL CPUFREQ ------");
- DUMP("/sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state");
- PRINT("");
- PRINT("------ PROCESSES ------");
- EXEC1("ps", "-P");
- PRINT("------ PROCESSES AND THREADS ------");
- EXEC3("ps", "-t", "-p", "-P");
- PRINT("------ LIBRANK ------");
- EXEC_XBIN("librank");
- PRINT("------ BINDER FAILED TRANSACTION LOG ------");
- DUMP("/proc/binder/failed_transaction_log");
- PRINT("");
- PRINT("------ BINDER TRANSACTION LOG ------");
- DUMP("/proc/binder/transaction_log");
- PRINT("");
- PRINT("------ BINDER TRANSACTIONS ------");
- DUMP("/proc/binder/transactions");
- PRINT("");
- PRINT("------ BINDER STATS ------");
- DUMP("/proc/binder/stats");
- PRINT("");
- PRINT("------ BINDER PROCESS STATE: $i ------");
- DUMP_FILES("/proc/binder/proc");
- PRINT("------ FILESYSTEMS ------");
- EXEC("df");
- PRINT("------ PACKAGE SETTINGS ------");
- DUMP("/data/system/packages.xml");
- PRINT("------ PACKAGE UID ERRORS ------");
- DUMP("/data/system/uiderrors.txt");
-
- dump_kernel_log("/proc/last_kmsg", "LAST KMSG");
-
- PRINT("------ LAST RADIO LOG ------");
- EXEC1("parse_radio_log", "/proc/last_radio_log");
-
- dump_kernel_log("/data/dontpanic/apanic_console",
- "PANIC CONSOLE");
- dump_kernel_log("/data/dontpanic/apanic_threads",
- "PANIC THREADS");
-
- PRINT("------ BACKLIGHTS ------");
- DUMP_PROMPT("LCD brightness=", "/sys/class/leds/lcd-backlight/brightness");
- DUMP_PROMPT("Button brightness=", "/sys/class/leds/button-backlight/brightness");
- DUMP_PROMPT("Keyboard brightness=", "/sys/class/leds/keyboard-backlight/brightness");
- DUMP_PROMPT("ALS mode=", "/sys/class/leds/lcd-backlight/als");
- DUMP_PROMPT("LCD driver registers:\n", "/sys/class/leds/lcd-backlight/registers");
+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];
+
+ property_get("ro.build.display.id", build, "(unknown)");
+ property_get("ro.build.fingerprint", fingerprint, "(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("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");
+
+ 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");
+
+ run_command("SYSTEM LOG", 20, "logcat", "-v", "time", "-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);
}
- PRINT("========================================================");
- PRINT("== build.prop");
- PRINT("========================================================");
-
- /* the crash server parses key-value pairs between the VERSION INFO and
- * END lines so we can aggregate crash reports based on this data.
- */
- PRINT("------ VERSION INFO ------");
- print_date("currenttime=", &now);
- DUMP_PROMPT("kernel.version=", "/proc/version");
- DUMP_PROMPT("kernel.cmdline=", "/proc/cmdline");
- DUMP("/system/build.prop");
- PROPERTY("gsm.version.ril-impl");
- PROPERTY("gsm.version.baseband");
- PROPERTY("gsm.imei");
- PROPERTY("gsm.sim.operator.numeric");
- PROPERTY("gsm.operator.alpha");
- PRINT("------ END ------");
-
- if (full) {
- PRINT("========================================================");
- PRINT("== dumpsys");
- PRINT("========================================================");
- /* 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... */
- EXEC_TIMEOUT("dumpsys", 60);
+
+ /* 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] && !stat(anr_traces_path, &st) && time(NULL) - st.st_mtime < 15 * 60) {
+ dump_file("VM TRACES AT LAST ANR", anr_traces_path);
}
-}
-/* used to check the file name passed via argv[0] */
-static int check_command_name(const char* name, const char* test) {
- int name_length, test_length;
+ // dump_file("EVENT LOG TAGS", "/etc/event-log-tags");
+ run_command("EVENT LOG", 20, "logcat", "-b", "events", "-v", "time", "-d", "*:v", NULL);
+ run_command("RADIO LOG", 20, "logcat", "-b", "radio", "-v", "time", "-d", "*:v", NULL);
- if (!strcmp(name, test))
- return 1;
+ run_command("NETWORK INTERFACES", 10, "netcfg", NULL);
+ dump_file("NETWORK ROUTES", "/proc/net/route");
- name_length = strlen(name);
- test_length = strlen(test);
+#ifdef FWDUMP_bcm4329
+ run_command("DUMP WIFI FIRMWARE LOG", 60,
+ "dhdutil", "-i", "eth0", "upload", "/data/local/tmp/wlan_crash.dump", NULL);
+#endif
- if (name_length > test_length + 2) {
- name += (name_length - test_length);
- if (name[-1] != '/')
- return 0;
- if (!strcmp(name, test))
- return 1;
- }
+ print_properties();
+
+ run_command("KERNEL LOG", 20, "dmesg", NULL);
+
+ 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);
+
+ dump_file("BINDER FAILED TRANSACTION LOG", "/proc/binder/failed_transaction_log");
+ dump_file("BINDER TRANSACTION LOG", "/proc/binder/transaction_log");
+ dump_file("BINDER TRANSACTIONS", "/proc/binder/transactions");
+ dump_file("BINDER STATS", "/proc/binder/stats");
+ run_command("BINDER PROCESS STATE", 10, "sh", "-c", "cat /proc/binder/proc/*");
+
+ run_command("FILESYSTEMS & FREE SPACE", 10, "df", NULL);
+
+ dump_file("PACKAGE SETTINGS", "/data/system/packages.xml");
+ dump_file("PACKAGE UID ERRORS", "/data/system/uiderrors.txt");
+
+ dump_file("LAST KMSG", "/proc/last_kmsg");
+ run_command("LAST RADIO LOG", 10, "parse_radio_log", "/proc/last_radio_log", NULL);
+ dump_file("LAST PANIC CONSOLE", "/data/dontpanic/apanic_console");
+ dump_file("LAST PANIC THREADS", "/data/dontpanic/apanic_threads");
+
+ 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");
+
+ 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);
+}
- return 0;
+
+static void usage() {
+ fprintf(stderr, "usage: dumpstate [-d] [-o file] [-s] [-z]\n"
+ " -d: append date to filename (requires -o)\n"
+ " -o: write to file (instead of stdout)\n"
+ " -s: write output to control socket (for init)\n"
+ " -z: gzip output (requires -o)\n");
}
int main(int argc, char *argv[]) {
- int dumpcrash = check_command_name(argv[0], "dumpcrash");
- int add_date = 0;
- char* outfile = 0;
- int vibrate = 0;
- int compress = 0;
- int socket = 0;
- int c, fd, vibrate_fd, fds[2];
- char path[PATH_MAX];
- pid_t pid;
- gid_t groups[] = { AID_LOG, AID_SDCARD_RW };
+ int do_add_date = 0;
+ int do_compress = 0;
+ char* use_outfile = 0;
+ int use_socket = 0;
LOGI("begin\n");
/* set as high priority, and protect from OOM killer */
setpriority(PRIO_PROCESS, 0, -20);
- protect_from_oom_killer();
+ FILE *oom_adj = fopen("/proc/self/oom_adj", "w");
+ if (oom_adj) {
+ fputs("-17", oom_adj);
+ fclose(oom_adj);
+ }
- get_time(&now);
+ /* very first thing, collect VM traces from Dalvik (needs root) */
+ dump_traces_path = dump_vm_traces();
- do {
- c = getopt(argc, argv, "do:svz");
- if (c == EOF)
- break;
+ int c;
+ while ((c = getopt(argc, argv, "dho:svz")) != -1) {
switch (c) {
- case 'd':
- add_date = 1;
- break;
- case 'o':
- outfile = optarg;
- break;
- case 'v':
- vibrate = 1;
- break;
- case 'z':
- compress = 1;
- break;
- case 's':
- socket = 1;
- break;
- case '?':
- fprintf(stderr, "%s: invalid option -%c\n",
- argv[0], optopt);
+ case 'd': do_add_date = 1; 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 '?': printf("\n");
+ case 'h':
+ usage();
exit(1);
}
- } while (1);
+ }
- /* open vibrator before switching user */
- if (vibrate) {
- vibrate_fd = open("/sys/class/timed_output/vibrator/enable", O_WRONLY);
- if (vibrate_fd > 0)
- fcntl(vibrate_fd, F_SETFD, FD_CLOEXEC);
- } else
- vibrate_fd = -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);
+ }
/* switch to non-root user and group */
+ gid_t groups[] = { AID_LOG, AID_SDCARD_RW };
setgroups(sizeof(groups)/sizeof(groups[0]), groups);
setuid(AID_SHELL);
- /* make it safe to use both printf and STDOUT_FILENO */
- setvbuf(stdout, 0, _IONBF, 0);
-
- if (socket) {
- struct sockaddr addr;
- socklen_t alen;
-
- int s = android_get_control_socket("dumpstate");
- if (s < 0) {
- fprintf(stderr, "could not open dumpstate socket\n");
- exit(1);
- }
- if (listen(s, 4) < 0) {
- fprintf(stderr, "could not listen on dumpstate socket\n");
- exit(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));
}
+ 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);
+ }
- alen = sizeof(addr);
- fd = accept(s, &addr, &alen);
- if (fd < 0) {
- fprintf(stderr, "could not accept dumpstate socket\n");
- exit(1);
- }
+ /* bzzzzzz */
+ if (vibrator) {
+ fputs("150", vibrator);
+ fflush(vibrator);
+ }
- /* redirect stdout to the socket */
- dup2(fd, STDOUT_FILENO);
- close(fd);
- } else if (outfile) {
- if (strlen(outfile) > sizeof(path) - 100)
- exit(1);
-
- strcpy(path, outfile);
- if (add_date) {
- char date[260];
- strftime(date, sizeof(date),
- "-%Y-%m-%d-%H-%M-%S",
- &now);
- strcat(path, date);
- }
- if (compress)
- strcat(path, ".gz");
- else
- strcat(path, ".txt");
-
- /* ensure that all directories in the path exist */
- create_directories(path);
- fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
- if (fd < 0)
- return fd;
-
- if (compress) {
- pipe(fds);
-
- /* redirect our stdout to the pipe */
- dup2(fds[1], STDOUT_FILENO);
- close(fds[1]);
-
- if ((pid = fork()) < 0)
- {
- fprintf(stderr, "fork error\n");
- exit(1);
- }
-
- if (pid) {
- /* parent case */
-
- /* close our copy of the input to gzip */
- close(fds[0]);
- /* close our copy of the output file */
- close(fd);
- } else {
- /* child case */
-
- /* redirect our input pipe to stdin */
- dup2(fds[0], STDIN_FILENO);
- close(fds[0]);
-
- /* redirect stdout to the output file */
- dup2(fd, STDOUT_FILENO);
- close(fd);
-
- /* run gzip to postprocess our output */
- execv("/system/bin/gzip", gzip_args);
- fprintf(stderr, "execv returned\n");
- }
- } else {
- /* redirect stdout to the output file */
- dup2(fd, STDOUT_FILENO);
- close(fd);
+ dumpstate();
+
+ /* bzzz bzzz bzzz */
+ if (vibrator) {
+ int i;
+ for (i = 0; i < 3; i++) {
+ fputs("75\n", vibrator);
+ fflush(vibrator);
+ usleep((75 + 50) * 1000);
}
+ fclose(vibrator);
}
- /* else everything will print to stdout */
- if (vibrate) {
- vibrate_pattern(vibrate_fd, start_pattern);
- }
- dumpstate(!dumpcrash);
- if (vibrate) {
- vibrate_pattern(vibrate_fd, end_pattern);
- close(vibrate_fd);
+ /* wait for gzip to finish, otherwise it might get killed when we exit */
+ if (gzip_pid > 0) {
+ fclose(stdout);
+ waitpid(gzip_pid, NULL, 0);
}
- /* so gzip will terminate */
- close(STDOUT_FILENO);
+ /* 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));
+ }
LOGI("done\n");
return 0;
}
-
-static void dump_kernel_log(const char *path, const char *title)
-
-{
- printf("------ KERNEL %s LOG ------\n", title);
- if (access(path, R_OK) < 0)
- printf("%s: %s\n", path, strerror(errno));
- else {
- struct stat sbuf;
-
- if (stat(path, &sbuf) < 0)
- printf("%s: stat failed (%s)\n", path, strerror(errno));
- else
- printf("Harvested %s", ctime(&sbuf.st_mtime));
-
- DUMP(path);
- }
-}
diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h
index ed1f005659cb..6d48a859e15f 100644
--- a/cmds/dumpstate/dumpstate.h
+++ b/cmds/dumpstate/dumpstate.h
@@ -18,157 +18,24 @@
#define _DUMPSTATE_H_
#include <time.h>
-
-// Commands time out after 60 seconds
-#define TIMEOUT 60
-
-#define PRINT(s) printf("%s\n", s)
-
-#define DUMP(file) dump_file(file)
-
-#define DUMP_FILES(path) dump_files(path)
-
-#define DUMP_PROMPT(prompt, file) \
-{ \
- printf(prompt); \
- dump_file(file); \
-}
-
-#define EXEC(cmd) \
-{ \
- static struct Command c = { \
- "/system/bin/" cmd, \
- { cmd, 0 } \
- }; \
- run_command(&c, TIMEOUT); \
-}
-
-#define EXEC_TIMEOUT(cmd, tmout)\
-{ \
- static struct Command c = { \
- "/system/bin/" cmd, \
- { cmd, 0 } \
- }; \
- run_command(&c, tmout); \
-}
-
-#define EXEC_XBIN(cmd) \
-{ \
- static struct Command c = { \
- "/system/xbin/" cmd, \
- { cmd, 0 } \
- }; \
- run_command(&c, TIMEOUT); \
-}
-
-#define EXEC1(cmd, a1) \
-{ \
- static struct Command c = { \
- "/system/bin/" cmd, \
- { cmd, a1, 0 } \
- }; \
- run_command(&c, TIMEOUT); \
-}
-
-#define EXEC2(cmd, a1, a2) \
-{ \
- static struct Command c = { \
- "/system/bin/" cmd, \
- { cmd, a1, a2, 0 } \
- }; \
- run_command(&c, TIMEOUT); \
-}
-
-#define EXEC3(cmd, a1, a2, a3) \
-{ \
- static struct Command c = { \
- "/system/bin/" cmd, \
- { cmd, a1, a2, a3, 0 } \
- }; \
- run_command(&c, TIMEOUT); \
-}
-
-#define EXEC4(cmd, a1, a2, a3, a4) \
-{ \
- static struct Command c = { \
- "/system/bin/" cmd, \
- { cmd, a1, a2, a3, a4, 0 } \
- }; \
- run_command(&c, TIMEOUT); \
-}
-
-#define EXEC6(cmd, a1, a2, a3, a4, a5, a6) \
-{ \
- static struct Command c = { \
- "/system/bin/" cmd, \
- { cmd, a1, a2, a3, a4, a5, a6, 0 } \
- }; \
- run_command(&c, TIMEOUT); \
-}
-
-#define EXEC7(cmd, a1, a2, a3, a4, a5, a6, a7) \
-{ \
- static struct Command c = { \
- "/system/bin/" cmd, \
- { cmd, a1, a2, a3, a4, a5, a6, a7, 0 } \
- }; \
- run_command(&c, TIMEOUT); \
-}
-
-#define EXEC8(cmd, a1, a2, a3, a4, a5, a6, a7, a8) \
-{ \
- static struct Command c = { \
- "/system/bin/" cmd, \
- { cmd, a1, a2, a3, a4, a5, a6, a7, a8, 0 } \
- }; \
- run_command(&c, TIMEOUT); \
-}
-
-#define EXEC_XBIN6(cmd, a1, a2, a3, a4, a5, a6) \
-{ \
- static struct Command c = { \
- "/system/xbin/" cmd, \
- { cmd, a1, a2, a3, a4, a5, a6, 0 } \
- }; \
- run_command(&c, TIMEOUT); \
-}
-
-#define PROPERTY(name) print_property(name)
-
-struct Command {
- const char* path;
- char* const args[];
-};
-typedef struct Command Command;
+#include <unistd.h>
/* prints the contents of a file */
-int dump_file(const char* path);
-
-/* prints the contents of all files in a directory */
-void dump_files(const char* path);
-
-/* forks a command and waits for it to finish */
-int run_command(struct Command* cmd, int timeout);
-
-/* reads the current time into tm */
-void get_time(struct tm *tm);
-
-/* prints the date in tm */
-void print_date(const char* prompt, struct tm *tm);
+int dump_file(const char *title, const char* path);
-/* prints the name and value of a system property */
-int print_property(const char* name);
+/* 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();
-/* creates directories as needed for the given path */
-void create_directories(char *path);
+/* redirect output to a service control socket */
+void redirect_to_socket(FILE *redirect, const char *service);
-/* runs the vibrator using the given pattern */
-void vibrate_pattern(int fd, int* pattern);
+/* redirect output to a file, optionally gzipping; returns gzip pid */
+pid_t redirect_to_file(FILE *redirect, char *path, int gzip_level);
-/* prevents the OOM killer from killing us */
-void protect_from_oom_killer();
+/* dump Dalvik stack traces, return the trace file location (NULL if none) */
+const char *dump_vm_traces();
#endif /* _DUMPSTATE_H_ */
diff --git a/cmds/dumpstate/utils.c b/cmds/dumpstate/utils.c
index 60d845f61bf3..fda618cc4c52 100644
--- a/cmds/dumpstate/utils.c
+++ b/cmds/dumpstate/utils.c
@@ -14,217 +14,337 @@
* 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 <time.h>
-#include <unistd.h>
+#include <sys/inotify.h>
#include <sys/stat.h>
-#include <dirent.h>
-#include <limits.h>
-#include <fcntl.h>
-#include <signal.h>
#include <sys/time.h>
#include <sys/wait.h>
+#include <time.h>
+#include <unistd.h>
#include <cutils/properties.h>
-#include <sys/system_properties.h>
+#include <cutils/sockets.h>
#include "dumpstate.h"
/* prints the contents of a file */
-int dump_file(const char* path) {
- char buffer[32768];
- int fd, amount_read;
- int ret = 0;
-
- fd = open(path, O_RDONLY);
- if (fd < 0)
- return fd;
-
- do {
- ret = read(fd, buffer, sizeof(buffer));
- if (ret > 0)
- ret = write(STDOUT_FILENO, buffer, ret);
- } while (ret > 0);
-
- buffer[0] = '\n';
- write(STDOUT_FILENO, buffer, 1);
-
- close(fd);
- return ret;
-}
+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;
+ }
-/* prints the contents of all files in a directory */
-void dump_files(const char* path) {
- DIR* dir;
- struct dirent* entry;
- char buffer[PATH_MAX];
+ if (title) printf("----- %s (%s", title, path);
- dir = opendir(path);
- if (!dir) {
- fprintf(stderr, "could not open directory %s\n", path);
- return;
+ 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");
}
- while ((entry = readdir(dir))) {
- if (entry->d_type == DT_REG) {
- snprintf(buffer, sizeof(buffer), "%s/%s", path, entry->d_name);
- dump_file(path);
- 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;
}
- closedir(dir);
-}
-
-/* prints the name and value of a system property */
-int print_property(const char* name) {
- char value[PROP_VALUE_MAX];
-
- __system_property_get(name, value);
- printf("%s=%s\n", name, value);
+ close(fd);
+ if (!newline) printf("\n");
+ if (title) printf("\n");
return 0;
}
-static pid_t alarm_pid = 0;
-static int timed_out = 0;
-static void sig_alarm(int sig)
-{
- if (alarm_pid) {
- kill(alarm_pid, SIGKILL);
- timed_out = 1;
- alarm_pid = 0;
- }
-}
-
/* forks a command and waits for it to finish */
-int run_command(struct Command* cmd, int timeout) {
- struct sigaction sa;
- pid_t pid;
- int status;
+int run_command(const char *title, int timeout_seconds, const char *command, ...) {
+ fflush(stdout);
+ clock_t start = clock();
+ pid_t pid = fork();
- pid = fork();
/* handle error case */
- if (pid < 0)
+ if (pid < 0) {
+ printf("*** fork: %s\n", strerror(errno));
return pid;
+ }
/* handle child case */
if (pid == 0) {
- int ret = execv(cmd->path, cmd->args);
- if (ret)
- fprintf(stderr, "execv %s returned %d\n", cmd->path, ret);
- exit(ret);
+ 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));
+ _exit(-1);
}
/* handle parent case */
- timed_out = 0;
- if (timeout) {
- memset(&sa, 0, sizeof(sa));
- sa.sa_flags = SA_RESETHAND;
- sa.sa_handler = sig_alarm;
- sigaction(SIGALRM, &sa, NULL);
+ 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 (WEXITSTATUS(status) > 0) {
+ printf("*** %s: Exit code %d\n", command, WEXITSTATUS(status));
+ }
+ if (title) printf("[%s: %.1fs elapsed]\n\n", command, elapsed);
+ return status;
+ }
- /* set an alarm so we don't hang forever */
- alarm_pid = pid;
- alarm(timeout);
- }
+ if (timeout_seconds && elapsed > timeout_seconds) {
+ printf("*** %s: Timed out after %.1fs (killing pid %d)\n", command, elapsed, pid);
+ kill(pid, SIGTERM);
+ return -1;
+ }
- waitpid(pid, &status, 0);
+ usleep(100000); // poll every 0.1 sec
+ }
+}
- if (timed_out)
- printf("ERROR: command %s timed out\n", cmd->path);
+size_t num_props = 0;
+static char* props[2000];
- return status;
+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);
+ }
}
-/* reads the current time into tm */
-void get_time(struct tm *tm) {
- time_t t;
-
- tzset();
- time(&t);
- localtime_r(&t, tm);
+static int compare_prop(const void *a, const void *b) {
+ return strcmp(*(char * const *) a, *(char * const *) b);
}
-/* prints the date in tm */
-void print_date(const char* prompt, struct tm *tm) {
- char strbuf[260];
+/* 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);
- strftime(strbuf, sizeof(strbuf),
- "%a %b %e %H:%M:%S %Z %Y",
- tm);
- printf("%s%s\n", prompt, strbuf);
+ 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);
+ }
-static void print_prop(const char *key, const char *name,
- void *user __attribute__((unused)))
-{
- printf("[%s]: [%s]\n", key, name);
-}
+ 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);
+ }
-/* prints all the system properties */
-void print_properties() {
- property_list(print_prop, NULL);
+ fflush(redirect);
+ dup2(fd, fileno(redirect));
+ close(fd);
}
-/* creates directories as needed for the given path */
-void create_directories(char *path)
-{
+/* 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, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
- *chp = '/';
- chp++;
+ mkdir(path, 0775); /* drwxrwxr-x */
+ *chp++ = '/';
}
}
-}
-/* runs the vibrator using the given pattern */
-void vibrate_pattern(int fd, int* pattern)
-{
- struct timespec tm;
- char buffer[10];
-
- while (*pattern) {
- /* read vibrate on time */
- int on_time = *pattern++;
- snprintf(buffer, sizeof(buffer), "%d", on_time);
- write(fd, buffer, strlen(buffer));
-
- /* read vibrate off time */
- int delay = *pattern++;
- if (delay) {
- delay += on_time;
-
- tm.tv_sec = delay / 1000;
- tm.tv_nsec = (delay % 1000) * 1000000;
- nanosleep(&tm, NULL);
- } else
- break;
+ 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;
}
-/* prevents the OOM killer from killing us */
-void protect_from_oom_killer()
-{
- int fd;
+/* 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));
+ rename(traces_path, anr_traces_path);
+
+ /* 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;
+ }
- fd = open("/proc/self/oom_adj", O_WRONLY);
- if (fd >= 0) {
- // -17 should make us immune to OOM
- const char* text = "-17";
- write(fd, text, strlen(text));
+ struct dirent *d;
+ 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;
+
+ 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);
+
+ 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;
}
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index b31593277063..5d5bd9ccdd91 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -841,7 +841,14 @@ public class InputMethodService extends AbstractInputMethodService {
*/
public boolean onEvaluateFullscreenMode() {
Configuration config = getResources().getConfiguration();
- return config.orientation == Configuration.ORIENTATION_LANDSCAPE;
+ if (config.orientation != Configuration.ORIENTATION_LANDSCAPE) {
+ return false;
+ }
+ if (mInputEditorInfo != null
+ && (mInputEditorInfo.imeOptions & EditorInfo.IME_FLAG_NO_FULLSCREEN) != 0) {
+ return false;
+ }
+ return true;
}
/**
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index a127df01b8e7..30799ec9f3b8 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -129,37 +129,33 @@ public class ConnectivityManager
public static final int TYPE_WIFI = 1;
/**
* An MMS-specific Mobile data connection. This connection may be the
- * same as {@link #TYPEMOBILE} but it may be different. This is used
+ * same as {@link #TYPE_MOBILE} but it may be different. This is used
* by applications needing to talk to the carrier's Multimedia Messaging
* Service servers. It may coexist with default data connections.
- * {@hide}
*/
public static final int TYPE_MOBILE_MMS = 2;
/**
* A SUPL-specific Mobile data connection. This connection may be the
- * same as {@link #TYPEMOBILE} but it may be different. This is used
+ * same as {@link #TYPE_MOBILE} but it may be different. This is used
* by applications needing to talk to the carrier's Secure User Plane
* Location servers for help locating the device. It may coexist with
* default data connections.
- * {@hide}
*/
public static final int TYPE_MOBILE_SUPL = 3;
/**
* A DUN-specific Mobile data connection. This connection may be the
- * same as {@link #TYPEMOBILE} but it may be different. This is used
+ * same as {@link #TYPE_MOBILE} but it may be different. This is used
* by applicaitons performing a Dial Up Networking bridge so that
* the carrier is aware of DUN traffic. It may coexist with default data
* connections.
- * {@hide}
*/
public static final int TYPE_MOBILE_DUN = 4;
/**
* A High Priority Mobile data connection. This connection is typically
- * the same as {@link #TYPEMOBILE} but the routing setup is different.
+ * the same as {@link #TYPE_MOBILE} but the routing setup is different.
* Only requesting processes will have access to the Mobile DNS servers
* and only IP's explicitly requested via {@link #requestRouteToHost}
- * will route over this interface.
- *{@hide}
+ * will route over this interface if a default route exists.
*/
public static final int TYPE_MOBILE_HIPRI = 5;
/** {@hide} */
diff --git a/core/java/android/os/IMountService.aidl b/core/java/android/os/IMountService.aidl
index f0526893cff4..e73569adc97e 100644
--- a/core/java/android/os/IMountService.aidl
+++ b/core/java/android/os/IMountService.aidl
@@ -42,17 +42,17 @@ interface IMountService
/**
* Mount external storage at given mount point.
*/
- void mountMedia(String mountPoint);
+ void mountVolume(String mountPoint);
/**
* Safely unmount external storage at given mount point.
*/
- void unmountMedia(String mountPoint);
+ void unmountVolume(String mountPoint);
/**
* Format external storage given a mount point.
*/
- void formatMedia(String mountPoint);
+ void formatVolume(String mountPoint);
/**
* Returns true if media notification sounds are enabled.
@@ -104,8 +104,7 @@ interface IMountService
String[] getSecureContainerList();
/**
- * Shuts down the MountService and gracefully unmounts
- * all external media.
+ * Shuts down the MountService and gracefully unmounts all external media.
*/
void shutdown();
}
diff --git a/core/java/android/os/Power.java b/core/java/android/os/Power.java
index 3679e478126e..bc76180acab8 100644
--- a/core/java/android/os/Power.java
+++ b/core/java/android/os/Power.java
@@ -17,6 +17,8 @@
package android.os;
import java.io.IOException;
+import android.os.ServiceManager;
+import android.os.IMountService;
/**
* Class that provides access to some of the power management functions.
@@ -97,5 +99,19 @@ public class Power
* @throws IOException if reboot fails for some reason (eg, lack of
* permission)
*/
- public static native void reboot(String reason) throws IOException;
+ public static void reboot(String reason) throws IOException
+ {
+ IMountService mSvc = IMountService.Stub.asInterface(
+ ServiceManager.getService("mount"));
+
+ if (mSvc != null) {
+ try {
+ mSvc.shutdown();
+ } catch (Exception e) {
+ }
+ }
+ rebootNative(reason);
+ }
+
+ private static native void rebootNative(String reason) throws IOException ;
}
diff --git a/core/java/android/pim/vcard/VCardParser_V21.java b/core/java/android/pim/vcard/VCardParser_V21.java
index e7c19cf451ba..c2928cb9c3a9 100644
--- a/core/java/android/pim/vcard/VCardParser_V21.java
+++ b/core/java/android/pim/vcard/VCardParser_V21.java
@@ -110,11 +110,11 @@ public class VCardParser_V21 extends VCardParser {
private long mTimeHandleBase64;
public VCardParser_V21() {
- this(VCardConfig.PARSE_TYPE_UNKNOWN);
+ this(null);
}
public VCardParser_V21(VCardSourceDetector detector) {
- this(detector.getEstimatedType());
+ this(detector != null ? detector.getEstimatedType() : VCardConfig.PARSE_TYPE_UNKNOWN);
}
public VCardParser_V21(int parseType) {
diff --git a/core/java/android/provider/Calendar.java b/core/java/android/provider/Calendar.java
index 7f947e93207e..509aac56f37c 100644
--- a/core/java/android/provider/Calendar.java
+++ b/core/java/android/provider/Calendar.java
@@ -583,14 +583,14 @@ public final class Calendar {
* {@link #ACCOUNT_TYPE} identifies a specific account.
* <P>Type: TEXT</P>
*/
- public static final String ACCOUNT_NAME = "account_name";
+ public static final String ACCOUNT_NAME = "_sync_account";
/**
* The type of account to which this row belongs, which when paired with
* {@link #ACCOUNT_NAME} identifies a specific account.
* <P>Type: TEXT</P>
*/
- public static final String ACCOUNT_TYPE = "account_type";
+ public static final String ACCOUNT_TYPE = "_sync_account_type";
public static EntityIterator newEntityIterator(Cursor cursor, ContentResolver resolver) {
return new EntityIteratorImpl(cursor, resolver);
diff --git a/core/java/android/view/TransformGestureDetector.java b/core/java/android/view/TransformGestureDetector.java
new file mode 100644
index 000000000000..196716adc0fb
--- /dev/null
+++ b/core/java/android/view/TransformGestureDetector.java
@@ -0,0 +1,316 @@
+/*
+ * 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.
+ */
+
+package android.view;
+
+import android.content.Context;
+import android.util.Log;
+import android.view.GestureDetector.SimpleOnGestureListener;
+
+/**
+ * Detects transformation gestures involving more than one pointer ("multitouch")
+ * using the supplied {@link MotionEvent}s. The {@link OnGestureListener} callback
+ * will notify users when a particular gesture event has occurred. This class
+ * should only be used with {@link MotionEvent}s reported via touch.
+ *
+ * To use this class:
+ * <ul>
+ * <li>Create an instance of the {@code TransformGestureDetector} for your
+ * {@link View}
+ * <li>In the {@link View#onTouchEvent(MotionEvent)} method ensure you call
+ * {@link #onTouchEvent(MotionEvent)}. The methods defined in your
+ * callback will be executed when the events occur.
+ * </ul>
+ * @hide Pending API approval
+ */
+public class TransformGestureDetector {
+ /**
+ * The listener for receiving notifications when gestures occur.
+ * If you want to listen for all the different gestures then implement
+ * this interface. If you only want to listen for a subset it might
+ * be easier to extend {@link SimpleOnGestureListener}.
+ *
+ * An application will receive events in the following order:
+ * One onTransformBegin()
+ * Zero or more onTransform()
+ * One onTransformEnd() or onTransformFling()
+ */
+ public interface OnTransformGestureListener {
+ /**
+ * Responds to transformation events for a gesture in progress.
+ * Reported by pointer motion.
+ *
+ * @param detector The detector reporting the event - use this to
+ * retrieve extended info about event state.
+ * @return true if the event was handled, false otherwise.
+ */
+ public boolean onTransform(TransformGestureDetector detector);
+
+ /**
+ * Responds to the beginning of a transformation gesture. Reported by
+ * new pointers going down.
+ *
+ * @param detector The detector reporting the event - use this to
+ * retrieve extended info about event state.
+ * @return true if the event was handled, false otherwise.
+ */
+ public boolean onTransformBegin(TransformGestureDetector detector);
+
+ /**
+ * Responds to the end of a transformation gesture. Reported by existing
+ * pointers going up. If the end of a gesture would result in a fling,
+ * onTransformFling is called instead.
+ *
+ * @param detector The detector reporting the event - use this to
+ * retrieve extended info about event state.
+ * @return true if the event was handled, false otherwise.
+ */
+ public boolean onTransformEnd(TransformGestureDetector detector);
+
+ /**
+ * Responds to the end of a transformation gesture that begins a fling.
+ * Reported by existing pointers going up. If the end of a gesture
+ * would not result in a fling, onTransformEnd is called instead.
+ *
+ * @param detector The detector reporting the event - use this to
+ * retrieve extended info about event state.
+ * @return true if the event was handled, false otherwise.
+ */
+ public boolean onTransformFling(TransformGestureDetector detector);
+ }
+
+ private static final boolean DEBUG = false;
+
+ private static final int INITIAL_EVENT_IGNORES = 2;
+
+ private Context mContext;
+ private float mTouchSizeScale;
+ private OnTransformGestureListener mListener;
+ private int mVelocityTimeUnits;
+ private MotionEvent mInitialEvent;
+
+ private MotionEvent mPrevEvent;
+ private MotionEvent mCurrEvent;
+ private VelocityTracker mVelocityTracker;
+
+ private float mCenterX;
+ private float mCenterY;
+ private float mTransX;
+ private float mTransY;
+ private float mPrevFingerDiffX;
+ private float mPrevFingerDiffY;
+ private float mCurrFingerDiffX;
+ private float mCurrFingerDiffY;
+ private float mRotateDegrees;
+ private float mCurrLen;
+ private float mPrevLen;
+ private float mScaleFactor;
+
+ // Units in pixels. Current value is pulled out of thin air for debugging only.
+ private float mPointerJumpLimit = 30;
+
+ private int mEventIgnoreCount;
+
+ public TransformGestureDetector(Context context, OnTransformGestureListener listener,
+ int velocityTimeUnits) {
+ mContext = context;
+ mListener = listener;
+ mTouchSizeScale = context.getResources().getDisplayMetrics().widthPixels/3;
+ mVelocityTimeUnits = velocityTimeUnits;
+ mEventIgnoreCount = INITIAL_EVENT_IGNORES;
+ }
+
+ public TransformGestureDetector(Context context, OnTransformGestureListener listener) {
+ this(context, listener, 1000);
+ }
+
+ public boolean onTouchEvent(MotionEvent event) {
+ final int action = event.getAction();
+ boolean handled = true;
+
+ if (mInitialEvent == null) {
+ // No transform gesture in progress
+ if ((action == MotionEvent.ACTION_POINTER_1_DOWN ||
+ action == MotionEvent.ACTION_POINTER_2_DOWN) &&
+ event.getPointerCount() >= 2) {
+ // We have a new multi-finger gesture
+ mInitialEvent = MotionEvent.obtain(event);
+ mPrevEvent = MotionEvent.obtain(event);
+ mVelocityTracker = VelocityTracker.obtain();
+ handled = mListener.onTransformBegin(this);
+ }
+ } else {
+ // Transform gesture in progress - attempt to handle it
+ switch (action) {
+ case MotionEvent.ACTION_POINTER_1_UP:
+ case MotionEvent.ACTION_POINTER_2_UP:
+ // Gesture ended
+ handled = mListener.onTransformEnd(this);
+
+ reset();
+ break;
+
+ case MotionEvent.ACTION_CANCEL:
+ handled = mListener.onTransformEnd(this);
+
+ reset();
+ break;
+
+ case MotionEvent.ACTION_MOVE:
+ setContext(event);
+
+ // Our first few events can be crazy from some touchscreens - drop them.
+ if (mEventIgnoreCount == 0) {
+ mVelocityTracker.addMovement(event);
+ handled = mListener.onTransform(this);
+ } else {
+ mEventIgnoreCount--;
+ }
+
+ mPrevEvent.recycle();
+ mPrevEvent = MotionEvent.obtain(event);
+ break;
+ }
+ }
+ return handled;
+ }
+
+ private void setContext(MotionEvent curr) {
+ mCurrEvent = MotionEvent.obtain(curr);
+
+ mRotateDegrees = -1;
+ mCurrLen = -1;
+ mPrevLen = -1;
+ mScaleFactor = -1;
+
+ final MotionEvent prev = mPrevEvent;
+
+ float px0 = prev.getX(0);
+ float py0 = prev.getY(0);
+ float px1 = prev.getX(1);
+ float py1 = prev.getY(1);
+ float cx0 = curr.getX(0);
+ float cy0 = curr.getY(0);
+ float cx1 = curr.getX(1);
+ float cy1 = curr.getY(1);
+
+ // Some touchscreens do weird things with pointer values where points are
+ // too close along one axis. Try to detect this here and smooth things out.
+ // The main indicator is that we get the X or Y value from the other pointer.
+ final float dx0 = cx0 - px0;
+ final float dy0 = cy0 - py0;
+ final float dx1 = cx1 - px1;
+ final float dy1 = cy1 - py1;
+
+ if (cx0 == cx1) {
+ if (Math.abs(dx0) > mPointerJumpLimit) {
+ cx0 = px0;
+ } else if (Math.abs(dx1) > mPointerJumpLimit) {
+ cx1 = px1;
+ }
+ } else if (cy0 == cy1) {
+ if (Math.abs(dy0) > mPointerJumpLimit) {
+ cy0 = py0;
+ } else if (Math.abs(dy1) > mPointerJumpLimit) {
+ cy1 = py1;
+ }
+ }
+
+ final float pvx = px1 - px0;
+ final float pvy = py1 - py0;
+ final float cvx = cx1 - cx0;
+ final float cvy = cy1 - cy0;
+ mPrevFingerDiffX = pvx;
+ mPrevFingerDiffY = pvy;
+ mCurrFingerDiffX = cvx;
+ mCurrFingerDiffY = cvy;
+
+ final float pmidx = px0 + pvx * 0.5f;
+ final float pmidy = py0 + pvy * 0.5f;
+ final float cmidx = cx0 + cvx * 0.5f;
+ final float cmidy = cy0 + cvy * 0.5f;
+
+ mCenterX = cmidx;
+ mCenterY = cmidy;
+ mTransX = cmidx - pmidx;
+ mTransY = cmidy - pmidy;
+ }
+
+ private void reset() {
+ if (mInitialEvent != null) {
+ mInitialEvent.recycle();
+ mInitialEvent = null;
+ }
+ if (mPrevEvent != null) {
+ mPrevEvent.recycle();
+ mPrevEvent = null;
+ }
+ if (mCurrEvent != null) {
+ mCurrEvent.recycle();
+ mCurrEvent = null;
+ }
+ if (mVelocityTracker != null) {
+ mVelocityTracker.recycle();
+ mVelocityTracker = null;
+ }
+ mEventIgnoreCount = INITIAL_EVENT_IGNORES;
+ }
+
+ public float getCenterX() {
+ return mCenterX;
+ }
+
+ public float getCenterY() {
+ return mCenterY;
+ }
+
+ public float getTranslateX() {
+ return mTransX;
+ }
+
+ public float getTranslateY() {
+ return mTransY;
+ }
+
+ public float getCurrentSpan() {
+ if (mCurrLen == -1) {
+ final float cvx = mCurrFingerDiffX;
+ final float cvy = mCurrFingerDiffY;
+ mCurrLen = (float)Math.sqrt(cvx*cvx + cvy*cvy);
+ }
+ return mCurrLen;
+ }
+
+ public float getPreviousSpan() {
+ if (mPrevLen == -1) {
+ final float pvx = mPrevFingerDiffX;
+ final float pvy = mPrevFingerDiffY;
+ mPrevLen = (float)Math.sqrt(pvx*pvx + pvy*pvy);
+ }
+ return mPrevLen;
+ }
+
+ public float getScaleFactor() {
+ if (mScaleFactor == -1) {
+ mScaleFactor = getCurrentSpan() / getPreviousSpan();
+ }
+ return mScaleFactor;
+ }
+
+ public float getRotation() {
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/core/java/android/view/VelocityTracker.java b/core/java/android/view/VelocityTracker.java
index 5d89c46a3db1..95810807e55b 100644
--- a/core/java/android/view/VelocityTracker.java
+++ b/core/java/android/view/VelocityTracker.java
@@ -55,12 +55,12 @@ public final class VelocityTracker implements Poolable<VelocityTracker> {
}
}, 2));
- final float mPastX[] = new float[NUM_PAST];
- final float mPastY[] = new float[NUM_PAST];
- final long mPastTime[] = new long[NUM_PAST];
+ final float mPastX[][] = new float[MotionEvent.BASE_AVAIL_POINTERS][NUM_PAST];
+ final float mPastY[][] = new float[MotionEvent.BASE_AVAIL_POINTERS][NUM_PAST];
+ final long mPastTime[][] = new long[MotionEvent.BASE_AVAIL_POINTERS][NUM_PAST];
- float mYVelocity;
- float mXVelocity;
+ float mYVelocity[] = new float[MotionEvent.BASE_AVAIL_POINTERS];
+ float mXVelocity[] = new float[MotionEvent.BASE_AVAIL_POINTERS];
private VelocityTracker mNext;
@@ -105,7 +105,9 @@ public final class VelocityTracker implements Poolable<VelocityTracker> {
* Reset the velocity tracker back to its initial state.
*/
public void clear() {
- mPastTime[0] = 0;
+ for (int i = 0; i < MotionEvent.BASE_AVAIL_POINTERS; i++) {
+ mPastTime[i][0] = 0;
+ }
}
/**
@@ -120,18 +122,21 @@ public final class VelocityTracker implements Poolable<VelocityTracker> {
public void addMovement(MotionEvent ev) {
long time = ev.getEventTime();
final int N = ev.getHistorySize();
- for (int i=0; i<N; i++) {
- addPoint(ev.getHistoricalX(i), ev.getHistoricalY(i),
- ev.getHistoricalEventTime(i));
+ final int pointerCount = ev.getPointerCount();
+ for (int p = 0; p < pointerCount; p++) {
+ for (int i=0; i<N; i++) {
+ addPoint(p, ev.getHistoricalX(p, i), ev.getHistoricalY(p, i),
+ ev.getHistoricalEventTime(i));
+ }
+ addPoint(p, ev.getX(p), ev.getY(p), time);
}
- addPoint(ev.getX(), ev.getY(), time);
}
- private void addPoint(float x, float y, long time) {
+ private void addPoint(int pos, float x, float y, long time) {
int drop = -1;
int i;
if (localLOGV) Log.v(TAG, "Adding past y=" + y + " time=" + time);
- final long[] pastTime = mPastTime;
+ final long[] pastTime = mPastTime[pos];
for (i=0; i<NUM_PAST; i++) {
if (pastTime[i] == 0) {
break;
@@ -146,8 +151,8 @@ public final class VelocityTracker implements Poolable<VelocityTracker> {
drop = 0;
}
if (drop == i) drop--;
- final float[] pastX = mPastX;
- final float[] pastY = mPastY;
+ final float[] pastX = mPastX[pos];
+ final float[] pastY = mPastY[pos];
if (drop >= 0) {
if (localLOGV) Log.v(TAG, "Dropping up to #" + drop);
final int start = drop+1;
@@ -190,44 +195,48 @@ public final class VelocityTracker implements Poolable<VelocityTracker> {
* must be positive.
*/
public void computeCurrentVelocity(int units, float maxVelocity) {
- final float[] pastX = mPastX;
- final float[] pastY = mPastY;
- final long[] pastTime = mPastTime;
-
- // Kind-of stupid.
- final float oldestX = pastX[0];
- final float oldestY = pastY[0];
- final long oldestTime = pastTime[0];
- float accumX = 0;
- float accumY = 0;
- int N=0;
- while (N < NUM_PAST) {
- if (pastTime[N] == 0) {
- break;
+ for (int pos = 0; pos < MotionEvent.BASE_AVAIL_POINTERS; pos++) {
+ final float[] pastX = mPastX[pos];
+ final float[] pastY = mPastY[pos];
+ final long[] pastTime = mPastTime[pos];
+
+ // Kind-of stupid.
+ final float oldestX = pastX[0];
+ final float oldestY = pastY[0];
+ final long oldestTime = pastTime[0];
+ float accumX = 0;
+ float accumY = 0;
+ int N=0;
+ while (N < NUM_PAST) {
+ if (pastTime[N] == 0) {
+ break;
+ }
+ N++;
}
- N++;
- }
- // Skip the last received event, since it is probably pretty noisy.
- if (N > 3) N--;
-
- for (int i=1; i < N; i++) {
- final int dur = (int)(pastTime[i] - oldestTime);
- if (dur == 0) continue;
- float dist = pastX[i] - oldestX;
- float vel = (dist/dur) * units; // pixels/frame.
- if (accumX == 0) accumX = vel;
- else accumX = (accumX + vel) * .5f;
-
- dist = pastY[i] - oldestY;
- vel = (dist/dur) * units; // pixels/frame.
- if (accumY == 0) accumY = vel;
- else accumY = (accumY + vel) * .5f;
+ // Skip the last received event, since it is probably pretty noisy.
+ if (N > 3) N--;
+
+ for (int i=1; i < N; i++) {
+ final int dur = (int)(pastTime[i] - oldestTime);
+ if (dur == 0) continue;
+ float dist = pastX[i] - oldestX;
+ float vel = (dist/dur) * units; // pixels/frame.
+ if (accumX == 0) accumX = vel;
+ else accumX = (accumX + vel) * .5f;
+
+ dist = pastY[i] - oldestY;
+ vel = (dist/dur) * units; // pixels/frame.
+ if (accumY == 0) accumY = vel;
+ else accumY = (accumY + vel) * .5f;
+ }
+ mXVelocity[pos] = accumX < 0.0f ? Math.max(accumX, -maxVelocity)
+ : Math.min(accumX, maxVelocity);
+ mYVelocity[pos] = accumY < 0.0f ? Math.max(accumY, -maxVelocity)
+ : Math.min(accumY, maxVelocity);
+
+ if (localLOGV) Log.v(TAG, "Y velocity=" + mYVelocity +" X velocity="
+ + mXVelocity + " N=" + N);
}
- mXVelocity = accumX < 0.0f ? Math.max(accumX, -maxVelocity) : Math.min(accumX, maxVelocity);
- mYVelocity = accumY < 0.0f ? Math.max(accumY, -maxVelocity) : Math.min(accumY, maxVelocity);
-
- if (localLOGV) Log.v(TAG, "Y velocity=" + mYVelocity +" X velocity="
- + mXVelocity + " N=" + N);
}
/**
@@ -237,7 +246,7 @@ public final class VelocityTracker implements Poolable<VelocityTracker> {
* @return The previously computed X velocity.
*/
public float getXVelocity() {
- return mXVelocity;
+ return mXVelocity[0];
}
/**
@@ -247,6 +256,32 @@ public final class VelocityTracker implements Poolable<VelocityTracker> {
* @return The previously computed Y velocity.
*/
public float getYVelocity() {
- return mYVelocity;
+ return mYVelocity[0];
+ }
+
+ /**
+ * Retrieve the last computed X velocity. You must first call
+ * {@link #computeCurrentVelocity(int)} before calling this function.
+ *
+ * @param pos Which pointer's velocity to return.
+ * @return The previously computed X velocity.
+ *
+ * @hide Pending API approval
+ */
+ public float getXVelocity(int pos) {
+ return mXVelocity[pos];
+ }
+
+ /**
+ * Retrieve the last computed Y velocity. You must first call
+ * {@link #computeCurrentVelocity(int)} before calling this function.
+ *
+ * @param pos Which pointer's velocity to return.
+ * @return The previously computed Y velocity.
+ *
+ * @hide Pending API approval
+ */
+ public float getYVelocity(int pos) {
+ return mYVelocity[pos];
}
}
diff --git a/core/java/android/view/inputmethod/EditorInfo.java b/core/java/android/view/inputmethod/EditorInfo.java
index c718bac29776..3da18d609ac6 100644
--- a/core/java/android/view/inputmethod/EditorInfo.java
+++ b/core/java/android/view/inputmethod/EditorInfo.java
@@ -111,7 +111,15 @@ public class EditorInfo implements InputType, Parcelable {
* flag for you on multi-line text views.
*/
public static final int IME_FLAG_NO_ENTER_ACTION = 0x40000000;
-
+
+ /**
+ * Flag of {@link #imeOptions}: used to request that the IME never go
+ * into fullscreen mode. Applications need to be aware that the flag is not
+ * a guarantee, and not all IMEs will respect it.
+ * @hide
+ */
+ public static final int IME_FLAG_NO_FULLSCREEN = 0x80000000;
+
/**
* Generic unspecified type for {@link #imeOptions}.
*/
diff --git a/core/java/android/webkit/MimeTypeMap.java b/core/java/android/webkit/MimeTypeMap.java
index 84a8a3cd359c..a9d6ff6305d0 100644
--- a/core/java/android/webkit/MimeTypeMap.java
+++ b/core/java/android/webkit/MimeTypeMap.java
@@ -124,6 +124,11 @@ public class MimeTypeMap {
return null;
}
+ // Static method called by jni.
+ private static String mimeTypeFromExtension(String extension) {
+ return getSingleton().getMimeTypeFromExtension(extension);
+ }
+
/**
* Return true if the given extension has a registered MIME type.
* @param extension A file extension without the leading '.'
@@ -344,6 +349,7 @@ public class MimeTypeMap {
sMimeTypeMap.loadEntry("application/x-pkcs7-crl", "crl");
sMimeTypeMap.loadEntry("application/x-quicktimeplayer", "qtl");
sMimeTypeMap.loadEntry("application/x-shar", "shar");
+ sMimeTypeMap.loadEntry("application/x-shockwave-flash", "swf");
sMimeTypeMap.loadEntry("application/x-stuffit", "sit");
sMimeTypeMap.loadEntry("application/x-sv4cpio", "sv4cpio");
sMimeTypeMap.loadEntry("application/x-sv4crc", "sv4crc");
diff --git a/core/java/android/webkit/WebTextView.java b/core/java/android/webkit/WebTextView.java
index b6891b1d3b96..6d0be4365efa 100644
--- a/core/java/android/webkit/WebTextView.java
+++ b/core/java/android/webkit/WebTextView.java
@@ -807,19 +807,21 @@ import java.util.ArrayList;
int maxLength = -1;
int inputType = EditorInfo.TYPE_CLASS_TEXT
| EditorInfo.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT;
+ int imeOptions = EditorInfo.IME_FLAG_NO_EXTRACT_UI
+ | EditorInfo.IME_FLAG_NO_FULLSCREEN;
switch (type) {
case 1: // TEXT_AREA
single = false;
inputType |= EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE
| EditorInfo.TYPE_TEXT_FLAG_CAP_SENTENCES
| EditorInfo.TYPE_TEXT_FLAG_AUTO_CORRECT;
- setImeOptions(EditorInfo.IME_ACTION_NONE);
+ imeOptions |= EditorInfo.IME_ACTION_NONE;
break;
case 2: // PASSWORD
inPassword = true;
break;
case 3: // SEARCH
- setImeOptions(EditorInfo.IME_ACTION_SEARCH);
+ imeOptions |= EditorInfo.IME_ACTION_SEARCH;
break;
case 4: // EMAIL
// TYPE_TEXT_VARIATION_WEB_EDIT_TEXT prevents EMAIL_ADDRESS
@@ -858,14 +860,14 @@ import java.util.ArrayList;
switch (action) {
// Keep in sync with CachedRoot::ImeAction
case 0: // NEXT
- setImeOptions(EditorInfo.IME_ACTION_NEXT);
+ imeOptions |= EditorInfo.IME_ACTION_NEXT;
break;
case 1: // GO
- setImeOptions(EditorInfo.IME_ACTION_GO);
+ imeOptions |= EditorInfo.IME_ACTION_GO;
break;
case -1: // FAILURE
case 2: // DONE
- setImeOptions(EditorInfo.IME_ACTION_DONE);
+ imeOptions |= EditorInfo.IME_ACTION_DONE;
break;
}
}
@@ -874,6 +876,7 @@ import java.util.ArrayList;
setMaxLength(maxLength);
setHorizontallyScrolling(single);
setInputType(inputType);
+ setImeOptions(imeOptions);
setInPassword(inPassword);
AutoCompleteAdapter adapter = null;
setAdapterCustom(adapter);
diff --git a/core/java/com/android/internal/app/ExternalMediaFormatActivity.java b/core/java/com/android/internal/app/ExternalMediaFormatActivity.java
index 000f6c49ab49..2b07ae67c566 100644
--- a/core/java/com/android/internal/app/ExternalMediaFormatActivity.java
+++ b/core/java/com/android/internal/app/ExternalMediaFormatActivity.java
@@ -102,7 +102,7 @@ public class ExternalMediaFormatActivity extends AlertActivity implements Dialog
.getService("mount"));
if (mountService != null) {
try {
- mountService.formatMedia(Environment.getExternalStorageDirectory().toString());
+ mountService.formatVolume(Environment.getExternalStorageDirectory().toString());
} catch (RemoteException e) {
}
}
diff --git a/core/jni/android_os_Power.cpp b/core/jni/android_os_Power.cpp
index df5edba4eb76..a46c2dd5b90a 100644
--- a/core/jni/android_os_Power.cpp
+++ b/core/jni/android_os_Power.cpp
@@ -105,7 +105,7 @@ static JNINativeMethod method_table[] = {
{ "setLastUserActivityTimeout", "(J)I", (void*)setLastUserActivityTimeout },
{ "setScreenState", "(Z)I", (void*)setScreenState },
{ "shutdown", "()V", (void*)android_os_Power_shutdown },
- { "reboot", "(Ljava/lang/String;)V", (void*)android_os_Power_reboot },
+ { "rebootNative", "(Ljava/lang/String;)V", (void*)android_os_Power_reboot },
};
int register_android_os_Power(JNIEnv *env)
diff --git a/graphics/java/android/renderscript/Allocation.java b/graphics/java/android/renderscript/Allocation.java
index 115dd62ed2a4..7d100eb43c3a 100644
--- a/graphics/java/android/renderscript/Allocation.java
+++ b/graphics/java/android/renderscript/Allocation.java
@@ -39,6 +39,10 @@ public class Allocation extends BaseObj {
mType = t;
}
+ public Type getType() {
+ return mType;
+ }
+
public void uploadToTexture(int baseMipLevel) {
mRS.validate();
mRS.validateSurface();
diff --git a/graphics/java/android/renderscript/Program.java b/graphics/java/android/renderscript/Program.java
index 9d70cb27798f..1614ec590cbd 100644
--- a/graphics/java/android/renderscript/Program.java
+++ b/graphics/java/android/renderscript/Program.java
@@ -111,12 +111,13 @@ public class Program extends BaseObj {
mOutputs[mOutputCount++] = e;
}
- public void addConstant(Type t) throws IllegalStateException {
+ public int addConstant(Type t) throws IllegalStateException {
// Should check for consistant and non-conflicting names...
if(mConstantCount >= MAX_CONSTANT) {
throw new IllegalArgumentException("Max input count exceeded.");
}
- mConstants[mConstantCount++] = t;
+ mConstants[mConstantCount] = t;
+ return mConstantCount++;
}
public void setTextureCount(int count) throws IllegalArgumentException {
diff --git a/include/media/stagefright/MetaData.h b/include/media/stagefright/MetaData.h
index ef30b02c1857..2bc2734fd1be 100644
--- a/include/media/stagefright/MetaData.h
+++ b/include/media/stagefright/MetaData.h
@@ -57,6 +57,9 @@ enum {
kKeyYear = 'year', // cstring
kKeyAlbumArt = 'albA', // compressed image data
kKeyAlbumArtMIME = 'alAM', // cstring
+ kKeyAuthor = 'auth', // cstring
+ kKeyCDTrackNumber = 'cdtr', // cstring
+ kKeyDate = 'date', // cstring
};
enum {
diff --git a/libs/rs/rsProgram.cpp b/libs/rs/rsProgram.cpp
index b7639be67b55..656a3c339529 100644
--- a/libs/rs/rsProgram.cpp
+++ b/libs/rs/rsProgram.cpp
@@ -95,7 +95,9 @@ Program::Program(Context *rsc, const char * shaderText, uint32_t shaderLength,
Program::~Program()
{
- bindAllocation(NULL);
+ for (uint32_t ct=0; ct < MAX_UNIFORMS; ct++) {
+ bindAllocation(NULL, ct);
+ }
delete[] mInputElements;
delete[] mOutputElements;
@@ -106,15 +108,15 @@ Program::~Program()
}
-void Program::bindAllocation(Allocation *alloc)
+void Program::bindAllocation(Allocation *alloc, uint32_t slot)
{
- if (mConstants.get() == alloc) {
+ if (mConstants[slot].get() == alloc) {
return;
}
- if (mConstants.get()) {
- mConstants.get()->removeProgramToDirty(this);
+ if (mConstants[slot].get()) {
+ mConstants[slot].get()->removeProgramToDirty(this);
}
- mConstants.set(alloc);
+ mConstants[slot].set(alloc);
if (alloc) {
alloc->addProgramToDirty(this);
}
@@ -239,7 +241,7 @@ namespace renderscript {
void rsi_ProgramBindConstants(Context *rsc, RsProgram vp, uint32_t slot, RsAllocation constants)
{
Program *p = static_cast<Program *>(vp);
- p->bindAllocation(static_cast<Allocation *>(constants));
+ p->bindAllocation(static_cast<Allocation *>(constants), slot);
}
void rsi_ProgramBindTexture(Context *rsc, RsProgram vpf, uint32_t slot, RsAllocation a)
diff --git a/libs/rs/rsProgram.h b/libs/rs/rsProgram.h
index 4bb7802fa49d..a34e89fa40ff 100644
--- a/libs/rs/rsProgram.h
+++ b/libs/rs/rsProgram.h
@@ -39,7 +39,7 @@ public:
const uint32_t * params, uint32_t paramLength);
virtual ~Program();
- void bindAllocation(Allocation *);
+ void bindAllocation(Allocation *, uint32_t slot);
virtual void createShader();
bool isUserProgram() const {return mUserShader.size() > 0;}
@@ -69,7 +69,7 @@ protected:
uint32_t mOutputCount;
uint32_t mConstantCount;
- ObjectBaseRef<Allocation> mConstants;
+ ObjectBaseRef<Allocation> mConstants[MAX_UNIFORMS];
mutable bool mDirty;
String8 mShader;
diff --git a/libs/rs/rsProgramVertex.cpp b/libs/rs/rsProgramVertex.cpp
index 8e59bc22b05a..cf6d7fcf5f5b 100644
--- a/libs/rs/rsProgramVertex.cpp
+++ b/libs/rs/rsProgramVertex.cpp
@@ -69,7 +69,7 @@ void ProgramVertex::setupGL(const Context *rsc, ProgramVertexState *state)
}
state->mLast.set(this);
- const float *f = static_cast<const float *>(mConstants->getPtr());
+ const float *f = static_cast<const float *>(mConstants[0]->getPtr());
glMatrixMode(GL_TEXTURE);
if (mTextureMatrixEnable) {
@@ -116,16 +116,36 @@ void ProgramVertex::createShader()
{
mShader.setTo("");
- for (uint32_t ct=0; ct < mUniformCount; ct++) {
- mShader.append("uniform mat4 ");
- mShader.append(mUniformNames[ct]);
- mShader.append(";\n");
- }
-
mShader.append("varying vec4 varColor;\n");
mShader.append("varying vec4 varTex0;\n");
if (mUserShader.length() > 1) {
+ mShader.append("uniform mat4 ");
+ mShader.append(mUniformNames[0]);
+ mShader.append(";\n");
+
+ for (uint32_t ct=0; ct < mConstantCount; ct++) {
+ const Element *e = mConstantTypes[ct]->getElement();
+ for (uint32_t field=0; field < e->getFieldCount(); field++) {
+ const Element *f = e->getField(field);
+
+ // Cannot be complex
+ rsAssert(!f->getFieldCount());
+ switch(f->getComponent().getVectorSize()) {
+ case 1: mShader.append("uniform float UNI_"); break;
+ case 2: mShader.append("uniform vec2 UNI_"); break;
+ case 3: mShader.append("uniform vec3 UNI_"); break;
+ case 4: mShader.append("uniform vec4 UNI_"); break;
+ default:
+ rsAssert(0);
+ }
+
+ mShader.append(e->getFieldName(field));
+ mShader.append(";\n");
+ }
+ }
+
+
for (uint32_t ct=0; ct < mInputCount; ct++) {
const Element *e = mInputElements[ct].get();
for (uint32_t field=0; field < e->getFieldCount(); field++) {
@@ -148,6 +168,12 @@ void ProgramVertex::createShader()
}
mShader.append(mUserShader);
} else {
+ for (uint32_t ct=0; ct < mUniformCount; ct++) {
+ mShader.append("uniform mat4 ");
+ mShader.append(mUniformNames[ct]);
+ mShader.append(";\n");
+ }
+
for (uint32_t ct=VertexArray::POSITION; ct < mAttribCount; ct++) {
mShader.append("attribute vec4 ");
mShader.append(mAttribNames[ct]);
@@ -155,12 +181,12 @@ void ProgramVertex::createShader()
}
mShader.append("void main() {\n");
- mShader.append(" gl_Position = uni_MVP * ATTRIB_Position;\n");
+ mShader.append(" gl_Position = UNI_MVP * ATTRIB_Position;\n");
mShader.append(" gl_PointSize = ATTRIB_PointSize.x;\n");
mShader.append(" varColor = ATTRIB_Color;\n");
if (mTextureMatrixEnable) {
- mShader.append(" varTex0 = uni_TexMatrix * ATTRIB_Texture;\n");
+ mShader.append(" varTex0 = UNI_TexMatrix * ATTRIB_Texture;\n");
} else {
mShader.append(" varTex0 = ATTRIB_Texture;\n");
}
@@ -180,7 +206,7 @@ void ProgramVertex::setupGL2(const Context *rsc, ProgramVertexState *state, Shad
glVertexAttrib4f(1, state->color[0], state->color[1], state->color[2], state->color[3]);
- const float *f = static_cast<const float *>(mConstants->getPtr());
+ const float *f = static_cast<const float *>(mConstants[0]->getPtr());
Matrix mvp;
mvp.load(&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET]);
@@ -194,6 +220,54 @@ void ProgramVertex::setupGL2(const Context *rsc, ProgramVertexState *state, Shad
&f[RS_PROGRAM_VERTEX_TEXTURE_OFFSET]);
}
+ uint32_t uidx = 1;
+ for (uint32_t ct=0; ct < mConstantCount; ct++) {
+ Allocation *alloc = mConstants[ct+1].get();
+ if (!alloc) {
+ continue;
+ }
+
+ const uint8_t *data = static_cast<const uint8_t *>(alloc->getPtr());
+ const Element *e = mConstantTypes[ct]->getElement();
+ for (uint32_t field=0; field < e->getFieldCount(); field++) {
+ const Element *f = e->getField(field);
+ uint32_t offset = e->getFieldOffsetBytes(field);
+ int32_t slot = sc->vtxUniformSlot(uidx);
+
+ const float *fd = reinterpret_cast<const float *>(&data[offset]);
+
+ //LOGE("Uniform slot=%i, offset=%i, constant=%i, field=%i, uidx=%i", slot, offset, ct, field, uidx);
+ if (slot >= 0) {
+ switch(f->getComponent().getVectorSize()) {
+ case 1:
+ //LOGE("Uniform 1 = %f", fd[0]);
+ glUniform1fv(slot, 1, fd);
+ break;
+ case 2:
+ //LOGE("Uniform 2 = %f %f", fd[0], fd[1]);
+ glUniform2fv(slot, 1, fd);
+ break;
+ case 3:
+ //LOGE("Uniform 3 = %f %f %f", fd[0], fd[1], fd[2]);
+ glUniform3fv(slot, 1, fd);
+ break;
+ case 4:
+ //LOGE("Uniform 4 = %f %f %f %f", fd[0], fd[1], fd[2], fd[3]);
+ glUniform4fv(slot, 1, fd);
+ break;
+ default:
+ rsAssert(0);
+ }
+ }
+ uidx ++;
+ }
+ }
+
+ for (uint32_t ct=0; ct < mConstantCount; ct++) {
+ uint32_t glSlot = sc->vtxUniformSlot(ct + 1);
+
+ }
+
state->mLast.set(this);
rsc->checkError("ProgramVertex::setupGL2");
}
@@ -208,46 +282,46 @@ void ProgramVertex::addLight(const Light *l)
void ProgramVertex::setProjectionMatrix(const rsc_Matrix *m) const
{
- float *f = static_cast<float *>(mConstants->getPtr());
+ float *f = static_cast<float *>(mConstants[0]->getPtr());
memcpy(&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET], m, sizeof(rsc_Matrix));
mDirty = true;
}
void ProgramVertex::setModelviewMatrix(const rsc_Matrix *m) const
{
- float *f = static_cast<float *>(mConstants->getPtr());
+ float *f = static_cast<float *>(mConstants[0]->getPtr());
memcpy(&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET], m, sizeof(rsc_Matrix));
mDirty = true;
}
void ProgramVertex::setTextureMatrix(const rsc_Matrix *m) const
{
- float *f = static_cast<float *>(mConstants->getPtr());
+ float *f = static_cast<float *>(mConstants[0]->getPtr());
memcpy(&f[RS_PROGRAM_VERTEX_TEXTURE_OFFSET], m, sizeof(rsc_Matrix));
mDirty = true;
}
void ProgramVertex::transformToScreen(const Context *rsc, float *v4out, const float *v3in) const
{
- float *f = static_cast<float *>(mConstants->getPtr());
+ float *f = static_cast<float *>(mConstants[0]->getPtr());
Matrix mvp;
mvp.loadMultiply((Matrix *)&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET],
(Matrix *)&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET]);
mvp.vectorMultiply(v4out, v3in);
}
-void ProgramVertex::initAddUserAttrib(const Element *e)
+void ProgramVertex::initAddUserElement(const Element *e, String8 *names, uint32_t *count, const char *prefix)
{
rsAssert(e->getFieldCount());
for (uint32_t ct=0; ct < e->getFieldCount(); ct++) {
const Element *ce = e->getField(ct);
if (ce->getFieldCount()) {
- initAddUserAttrib(ce);
+ initAddUserElement(ce, names, count, prefix);
} else {
- String8 tmp("ATTRIB_");
+ String8 tmp(prefix);
tmp.append(e->getFieldName(ct));
- mAttribNames[mAttribCount].setTo(tmp.string());
- mAttribCount++;
+ names[*count].setTo(tmp.string());
+ (*count)++;
}
}
}
@@ -257,7 +331,13 @@ void ProgramVertex::init(Context *rsc)
if (mUserShader.size() > 0) {
mAttribCount = 0;
for (uint32_t ct=0; ct < mInputCount; ct++) {
- initAddUserAttrib(mInputElements[ct].get());
+ initAddUserElement(mInputElements[ct].get(), mAttribNames, &mAttribCount, "ATTRIB_");
+ }
+
+ mUniformCount = 1;
+ mUniformNames[0].setTo("UNI_MVP");
+ for (uint32_t ct=0; ct < mConstantCount; ct++) {
+ initAddUserElement(mConstantTypes[ct]->getElement(), mUniformNames, &mUniformCount, "UNI_");
}
} else {
mAttribCount = 5;
@@ -266,11 +346,11 @@ void ProgramVertex::init(Context *rsc)
mAttribNames[2].setTo("ATTRIB_Normal");
mAttribNames[3].setTo("ATTRIB_PointSize");
mAttribNames[4].setTo("ATTRIB_Texture");
- }
- mUniformCount = 2;
- mUniformNames[0].setTo("uni_MVP");
- mUniformNames[1].setTo("uni_TexMatrix");
+ mUniformCount = 2;
+ mUniformNames[0].setTo("UNI_MVP");
+ mUniformNames[1].setTo("UNI_TexMatrix");
+ }
createShader();
}
@@ -299,7 +379,7 @@ void ProgramVertexState::init(Context *rsc, int32_t w, int32_t h)
mDefaultAlloc.set(alloc);
mDefault.set(pv);
pv->init(rsc);
- pv->bindAllocation(alloc);
+ pv->bindAllocation(alloc, 0);
color[0] = 1.f;
color[1] = 1.f;
diff --git a/libs/rs/rsProgramVertex.h b/libs/rs/rsProgramVertex.h
index dcb988c1ab5e..28554cc813d6 100644
--- a/libs/rs/rsProgramVertex.h
+++ b/libs/rs/rsProgramVertex.h
@@ -61,7 +61,7 @@ protected:
bool mTextureMatrixEnable;
private:
- void initAddUserAttrib(const Element *e);
+ void initAddUserElement(const Element *e, String8 *names, uint32_t *count, const char *prefix);
};
diff --git a/libs/rs/rsScriptC_Lib.cpp b/libs/rs/rsScriptC_Lib.cpp
index 8a0ab710e36f..3ba9cee09934 100644
--- a/libs/rs/rsScriptC_Lib.cpp
+++ b/libs/rs/rsScriptC_Lib.cpp
@@ -973,6 +973,13 @@ static void SC_uploadToBufferObject(RsAllocation va)
rsi_AllocationUploadToBufferObject(rsc, va);
}
+static void SC_syncToGL(RsAllocation va)
+{
+ GET_TLS();
+ Allocation *a = static_cast<Allocation *>(va);
+
+}
+
static void SC_ClearColor(float r, float g, float b, float a)
{
//LOGE("c %f %f %f %f", r, g, b, a);
@@ -1321,6 +1328,9 @@ ScriptCState::SymbolTable_t ScriptCState::gSyms[] = {
{ "uploadToBufferObject", (void *)&SC_uploadToBufferObject,
"void", "(int)" },
+ { "syncToGL", (void *)&SC_syncToGL,
+ "void", "(int)" },
+
{ "colorFloatRGBAtoUNorm8", (void *)&SC_colorFloatRGBAtoUNorm8,
"int", "(float, float, float, float)" },
{ "colorFloatRGBto565", (void *)&SC_colorFloatRGBAto565,
diff --git a/libs/rs/rsShaderCache.cpp b/libs/rs/rsShaderCache.cpp
index 0d9863de69c4..8ac2487a5aab 100644
--- a/libs/rs/rsShaderCache.cpp
+++ b/libs/rs/rsShaderCache.cpp
@@ -132,7 +132,7 @@ bool ShaderCache::lookup(Context *rsc, ProgramVertex *vtx, ProgramFragment *frag
LOGV("vtx U, %s = %d\n", vtx->getUniformName(ct).string(), e->mVtxUniformSlots[ct]);
}
}
- for (uint32_t ct=0; ct < vtx->getUniformCount(); ct++) {
+ for (uint32_t ct=0; ct < frag->getUniformCount(); ct++) {
e->mFragUniformSlots[ct] = glGetUniformLocation(pgm, frag->getUniformName(ct));
if (rsc->props.mLogShaders) {
LOGV("frag U, %s = %d\n", frag->getUniformName(ct).string(), e->mFragUniformSlots[ct]);
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index af57a4c4a973..6563caadb4c6 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -1258,22 +1258,24 @@ Exit:
static const int NUMVIZBUF = 32;
static const int VIZBUFFRAMES = 1024;
-static const int TOTALBUFTIMEMSEC = NUMVIZBUF * VIZBUFFRAMES * 1000 / 44100;
+static const int BUFTIMEMSEC = NUMVIZBUF * VIZBUFFRAMES * 1000 / 44100;
+static const int TOTALBUFTIMEMSEC = NUMVIZBUF * BUFTIMEMSEC;
static bool gotMem = false;
+static sp<MemoryHeapBase> heap;
static sp<MemoryBase> mem[NUMVIZBUF];
-static uint64_t timeStamp[NUMVIZBUF];
+static uint64_t endTime;
static uint64_t lastReadTime;
static uint64_t lastWriteTime;
static int writeIdx = 0;
static void allocVizBufs() {
if (!gotMem) {
+ heap = new MemoryHeapBase(NUMVIZBUF * VIZBUFFRAMES * 2, 0, "snooper");
for (int i=0;i<NUMVIZBUF;i++) {
- sp<MemoryHeapBase> heap = new MemoryHeapBase(VIZBUFFRAMES*2, 0, "snooper");
- mem[i] = new MemoryBase(heap, 0, heap->getSize());
- timeStamp[i] = 0;
+ mem[i] = new MemoryBase(heap, VIZBUFFRAMES * 2 * i, VIZBUFFRAMES * 2);
}
+ endTime = 0;
gotMem = true;
}
}
@@ -1290,68 +1292,48 @@ static sp<MemoryBase> getVizBuffer() {
allocVizBufs();
- lastReadTime = uptimeMillis() + 100; // account for renderer delay (we shouldn't be doing this here)
+ lastReadTime = uptimeMillis();
// if there is no recent buffer (yet), just return empty handed
if (lastWriteTime + TOTALBUFTIMEMSEC < lastReadTime) {
- //LOGI("@@@@ no audio data to look at yet");
+ //LOGI("@@@@ no audio data to look at yet: %d + %d < %d", (int)lastWriteTime, TOTALBUFTIMEMSEC, (int)lastReadTime);
return NULL;
}
- char buf[200];
-
- int closestIdx = -1;
- uint32_t closestTime = 0x7ffffff;
-
- for (int i = 0; i < NUMVIZBUF; i++) {
- uint64_t tsi = timeStamp[i];
- uint64_t diff = tsi > lastReadTime ? tsi - lastReadTime : lastReadTime - tsi;
- if (diff < closestTime) {
- closestIdx = i;
- closestTime = diff;
- }
- }
-
-
- if (closestIdx >= 0) {
- //LOGI("@@@ return buffer %d, %d/%d", closestIdx, uint32_t(lastReadTime), uint32_t(timeStamp[closestIdx]));
- return mem[closestIdx];
- }
-
- // we won't get here, since we either bailed out early, or got a buffer
- LOGD("Didn't expect to be here");
- return NULL;
-}
-
-static void storeVizBuf(const void *data, int len, uint64_t time) {
- // Copy the data in to the visualizer buffer
- // Assume a 16 bit stereo source for now.
- short *viz = (short*)mem[writeIdx]->pointer();
- short *src = (short*)data;
- for (int i = 0; i < VIZBUFFRAMES; i++) {
- // Degrade quality by mixing to mono and clearing the lowest 3 bits.
- // This should still be good enough for a visualization
- *viz++ = ((int(src[0]) + int(src[1])) >> 1) & ~0x7;
- src += 2;
- }
- timeStamp[writeIdx++] = time;
- if (writeIdx >= NUMVIZBUF) {
- writeIdx = 0;
+ int timedelta = endTime - lastReadTime;
+ if (timedelta < 0) timedelta = 0;
+ int framedelta = timedelta * 44100 / 1000;
+ int headIdx = (writeIdx - framedelta) / VIZBUFFRAMES - 1;
+ while (headIdx < 0) {
+ headIdx += NUMVIZBUF;
}
+ return mem[headIdx];
}
+// Append the data to the vizualization buffer
static void makeVizBuffers(const char *data, int len, uint64_t time) {
allocVizBufs();
uint64_t startTime = time;
const int frameSize = 4; // 16 bit stereo sample is 4 bytes
- while (len >= VIZBUFFRAMES * frameSize) {
- storeVizBuf(data, len, time);
- data += VIZBUFFRAMES * frameSize;
- len -= VIZBUFFRAMES * frameSize;
- time += 1000 * VIZBUFFRAMES / 44100;
+ int offset = writeIdx;
+ int maxoff = heap->getSize() / 2; // in shorts
+ short *base = (short*)heap->getBase();
+ short *src = (short*)data;
+ while (len > 0) {
+
+ // Degrade quality by mixing to mono and clearing the lowest 3 bits.
+ // This should still be good enough for a visualization
+ base[offset++] = ((int(src[0]) + int(src[1])) >> 1) & ~0x7;
+ src += 2;
+ len -= frameSize;
+ if (offset >= maxoff) {
+ offset = 0;
+ }
}
+ writeIdx = offset;
+ endTime = time + (len / frameSize) / 44;
//LOGI("@@@ stored buffers from %d to %d", uint32_t(startTime), uint32_t(time));
}
@@ -1509,30 +1491,35 @@ void MediaPlayerService::AudioOutput::start()
}
}
+void MediaPlayerService::AudioOutput::snoopWrite(const void* buffer, size_t size) {
+ // Only make visualization buffers if anyone recently requested visualization data
+ uint64_t now = uptimeMillis();
+ if (lastReadTime + TOTALBUFTIMEMSEC >= now) {
+ // Based on the current play counter, the number of frames written and
+ // the current real time we can calculate the approximate real start
+ // time of the buffer we're about to write.
+ uint32_t pos;
+ mTrack->getPosition(&pos);
+
+ // we're writing ahead by this many frames:
+ int ahead = mNumFramesWritten - pos;
+ //LOGI("@@@ written: %d, playpos: %d, latency: %d", mNumFramesWritten, pos, mTrack->latency());
+ // which is this many milliseconds, assuming 44100 Hz:
+ ahead /= 44;
+
+ makeVizBuffers((const char*)buffer, size, now + ahead + mTrack->latency());
+ lastWriteTime = now;
+ }
+}
+
+
ssize_t MediaPlayerService::AudioOutput::write(const void* buffer, size_t size)
{
LOG_FATAL_IF(mCallback != NULL, "Don't call write if supplying a callback.");
//LOGV("write(%p, %u)", buffer, size);
if (mTrack) {
- // Only make visualization buffers if anyone recently requested visualization data
- uint64_t now = uptimeMillis();
- if (lastReadTime + TOTALBUFTIMEMSEC >= now) {
- // Based on the current play counter, the number of frames written and
- // the current real time we can calculate the approximate real start
- // time of the buffer we're about to write.
- uint32_t pos;
- mTrack->getPosition(&pos);
-
- // we're writing ahead by this many frames:
- int ahead = mNumFramesWritten - pos;
- //LOGI("@@@ written: %d, playpos: %d, latency: %d", mNumFramesWritten, pos, mTrack->latency());
- // which is this many milliseconds, assuming 44100 Hz:
- ahead /= 44;
-
- makeVizBuffers((const char*)buffer, size, now + ahead + mTrack->latency());
- lastWriteTime = now;
- }
+ snoopWrite(buffer, size);
ssize_t ret = mTrack->write(buffer, size);
mNumFramesWritten += ret / 4; // assume 16 bit stereo
return ret;
@@ -1580,6 +1567,7 @@ void MediaPlayerService::AudioOutput::setVolume(float left, float right)
// static
void MediaPlayerService::AudioOutput::CallbackWrapper(
int event, void *cookie, void *info) {
+ //LOGV("callbackwrapper");
if (event != AudioTrack::EVENT_MORE_DATA) {
return;
}
@@ -1589,6 +1577,7 @@ void MediaPlayerService::AudioOutput::CallbackWrapper(
(*me->mCallback)(
me, buffer->raw, buffer->size, me->mCallbackCookie);
+ me->snoopWrite(buffer->raw, buffer->size);
}
#undef LOG_TAG
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index 1c90cf910e26..d1206b46f7e5 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -113,6 +113,7 @@ class MediaPlayerService : public BnMediaPlayerService
public: // visualization hack support
uint32_t mNumFramesWritten;
+ void snoopWrite(const void*, size_t);
};
class AudioCache : public MediaPlayerBase::AudioSink
diff --git a/media/libstagefright/MP3Extractor.cpp b/media/libstagefright/MP3Extractor.cpp
index 5df1e0079b60..48130fc5e2f4 100644
--- a/media/libstagefright/MP3Extractor.cpp
+++ b/media/libstagefright/MP3Extractor.cpp
@@ -729,8 +729,10 @@ sp<MetaData> MP3Extractor::getMetaData() {
{ kKeyArtist, "TPE1", "TP1" },
{ kKeyComposer, "TCOM", "TCM" },
{ kKeyGenre, "TCON", "TCO" },
- { kKeyTitle, "TALB", "TAL" },
+ { kKeyTitle, "TIT2", "TT2" },
{ kKeyYear, "TYE", "TYER" },
+ { kKeyAuthor, "TXT", "TEXT" },
+ { kKeyCDTrackNumber, "TRK", "TRCK" },
};
static const size_t kNumMapEntries = sizeof(kMap) / sizeof(kMap[0]);
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index 143e8ee0e882..b340b298d15d 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -66,6 +66,8 @@ private:
uint32_t mCurrentSampleIndex;
bool mIsAVC;
+ size_t mNALLengthSize;
+
bool mStarted;
MediaBufferGroup *mGroup;
@@ -76,6 +78,8 @@ private:
uint8_t *mSrcBuffer;
+ size_t parseNALSize(const uint8_t *data) const;
+
MPEG4Source(const MPEG4Source &);
MPEG4Source &operator=(const MPEG4Source &);
};
@@ -770,6 +774,7 @@ MPEG4Source::MPEG4Source(
mSampleTable(sampleTable),
mCurrentSampleIndex(0),
mIsAVC(false),
+ mNALLengthSize(0),
mStarted(false),
mGroup(NULL),
mBuffer(NULL),
@@ -780,6 +785,21 @@ MPEG4Source::MPEG4Source(
CHECK(success);
mIsAVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC);
+
+ if (mIsAVC) {
+ uint32_t type;
+ const void *data;
+ size_t size;
+ CHECK(format->findData(kKeyAVCC, &type, &data, &size));
+
+ const uint8_t *ptr = (const uint8_t *)data;
+
+ CHECK(size >= 7);
+ CHECK_EQ(ptr[0], 1); // configurationVersion == 1
+
+ // The number of bytes used to encode the length of a NAL unit.
+ mNALLengthSize = 1 + (ptr[4] & 3);
+ }
}
MPEG4Source::~MPEG4Source() {
@@ -837,6 +857,25 @@ sp<MetaData> MPEG4Source::getFormat() {
return mFormat;
}
+size_t MPEG4Source::parseNALSize(const uint8_t *data) const {
+ switch (mNALLengthSize) {
+ case 1:
+ return *data;
+ case 2:
+ return U16_AT(data);
+ case 3:
+ return ((size_t)data[0] << 16) | U16_AT(&data[1]);
+ case 4:
+ return U32_AT(data);
+ }
+
+ // This cannot happen, mNALLengthSize springs to life by adding 1 to
+ // a 2-bit integer.
+ CHECK(!"Should not be here.");
+
+ return 0;
+}
+
status_t MPEG4Source::read(
MediaBuffer **out, const ReadOptions *options) {
CHECK(mStarted);
@@ -919,21 +958,20 @@ status_t MPEG4Source::read(
// Each NAL unit is split up into its constituent fragments and
// each one of them returned in its own buffer.
- CHECK(mBuffer->range_length() >= 2);
+ CHECK(mBuffer->range_length() >= mNALLengthSize);
const uint8_t *src =
(const uint8_t *)mBuffer->data() + mBuffer->range_offset();
- size_t nal_size = U16_AT(src);
-
- CHECK(mBuffer->range_length() >= 2 + nal_size);
+ size_t nal_size = parseNALSize(src);
+ CHECK(mBuffer->range_length() >= mNALLengthSize + nal_size);
MediaBuffer *clone = mBuffer->clone();
- clone->set_range(mBuffer->range_offset() + 2, nal_size);
+ clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size);
mBuffer->set_range(
- mBuffer->range_offset() + 2 + nal_size,
- mBuffer->range_length() - 2 - nal_size);
+ mBuffer->range_offset() + mNALLengthSize + nal_size,
+ mBuffer->range_length() - mNALLengthSize - nal_size);
if (mBuffer->range_length() == 0) {
mBuffer->release();
@@ -960,12 +998,12 @@ status_t MPEG4Source::read(
uint8_t *dstData = (uint8_t *)mBuffer->data();
size_t srcOffset = 0;
size_t dstOffset = 0;
+
while (srcOffset < size) {
- CHECK(srcOffset + 1 < size);
- size_t nalLength =
- (mSrcBuffer[srcOffset] << 8) | mSrcBuffer[srcOffset + 1];
- CHECK(srcOffset + 1 + nalLength < size);
- srcOffset += 2;
+ CHECK(srcOffset + mNALLengthSize <= size);
+ size_t nalLength = parseNALSize(&mSrcBuffer[srcOffset]);
+ srcOffset += mNALLengthSize;
+ CHECK(srcOffset + nalLength <= size);
if (nalLength == 0) {
continue;
@@ -981,6 +1019,7 @@ status_t MPEG4Source::read(
srcOffset += nalLength;
dstOffset += nalLength;
}
+ CHECK_EQ(srcOffset, size);
mBuffer->set_range(0, dstOffset);
mBuffer->meta_data()->clear();
diff --git a/media/libstagefright/StagefrightMetadataRetriever.cpp b/media/libstagefright/StagefrightMetadataRetriever.cpp
index be4a9d9baf4b..4cc56e3d3f79 100644
--- a/media/libstagefright/StagefrightMetadataRetriever.cpp
+++ b/media/libstagefright/StagefrightMetadataRetriever.cpp
@@ -275,9 +275,12 @@ void StagefrightMetadataRetriever::parseMetaData() {
int to;
};
static const Map kMap[] = {
+ { kKeyCDTrackNumber, METADATA_KEY_CD_TRACK_NUMBER },
{ kKeyAlbum, METADATA_KEY_ALBUM },
{ kKeyArtist, METADATA_KEY_ARTIST },
+ { kKeyAuthor, METADATA_KEY_AUTHOR },
{ kKeyComposer, METADATA_KEY_COMPOSER },
+ { kKeyDate, METADATA_KEY_DATE },
{ kKeyGenre, METADATA_KEY_GENRE },
{ kKeyTitle, METADATA_KEY_TITLE },
{ kKeyYear, METADATA_KEY_YEAR },
@@ -301,9 +304,16 @@ void StagefrightMetadataRetriever::parseMetaData() {
memcpy(mAlbumArt->mData, data, dataSize);
}
+ size_t numTracks = mExtractor->countTracks();
+
+ char tmp[32];
+ sprintf(tmp, "%d", numTracks);
+
+ mMetaData.add(METADATA_KEY_NUM_TRACKS, String8(tmp));
+
// The overall duration is the duration of the longest track.
int64_t maxDurationUs = 0;
- for (size_t i = 0; i < mExtractor->countTracks(); ++i) {
+ for (size_t i = 0; i < numTracks; ++i) {
sp<MetaData> trackMeta = mExtractor->getTrackMetaData(i);
int64_t durationUs;
@@ -315,7 +325,6 @@ void StagefrightMetadataRetriever::parseMetaData() {
}
// The duration value is a string representing the duration in ms.
- char tmp[32];
sprintf(tmp, "%lld", (maxDurationUs + 500) / 1000);
mMetaData.add(METADATA_KEY_DURATION, String8(tmp));
diff --git a/media/libstagefright/codecs/mp3dec/MP3Decoder.cpp b/media/libstagefright/codecs/mp3dec/MP3Decoder.cpp
index c115b184a2d1..f1f7194079e0 100644
--- a/media/libstagefright/codecs/mp3dec/MP3Decoder.cpp
+++ b/media/libstagefright/codecs/mp3dec/MP3Decoder.cpp
@@ -161,6 +161,9 @@ status_t MP3Decoder::read(
mConfig->pOutputBuffer = static_cast<int16_t *>(buffer->data());
if (pvmp3_framedecoder(mConfig, mDecoderBuf) != NO_DECODING_ERROR) {
+ buffer->release();
+ buffer = NULL;
+
mInputBuffer->release();
mInputBuffer = NULL;
diff --git a/tests/AndroidTests/src/com/android/unit_tests/vcard/VCardTestSuite.java b/services/java/com/android/server/INativeDaemonConnectorCallbacks.java
index f3d1c5eebe72..6fbf713d3f7a 100644
--- a/tests/AndroidTests/src/com/android/unit_tests/vcard/VCardTestSuite.java
+++ b/services/java/com/android/server/INativeDaemonConnectorCallbacks.java
@@ -1,5 +1,6 @@
+
/*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2007 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.
@@ -14,18 +15,10 @@
* limitations under the License.
*/
-package com.android.unit_tests.vcard;
-
-import com.android.unit_tests.AndroidTests;
-
-import android.test.suitebuilder.TestSuiteBuilder;
+package com.android.server;
-import junit.framework.TestSuite;
+interface INativeDaemonConnectorCallbacks {
-public class VCardTestSuite extends TestSuite {
- public static TestSuite suite() {
- TestSuiteBuilder suiteBuilder = new TestSuiteBuilder(AndroidTests.class);
- suiteBuilder.includeAllPackagesUnderHere();
- return suiteBuilder.build();
- }
-} \ No newline at end of file
+ void onDaemonConnected();
+ boolean onEvent(int code, String raw, String[] cooked);
+}
diff --git a/services/java/com/android/server/MountListener.java b/services/java/com/android/server/MountListener.java
deleted file mode 100644
index 9443ff84921f..000000000000
--- a/services/java/com/android/server/MountListener.java
+++ /dev/null
@@ -1,377 +0,0 @@
-/*
- * Copyright (C) 2007 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 com.android.server;
-
-import android.net.LocalSocketAddress;
-import android.net.LocalSocket;
-import android.os.Environment;
-import android.os.SystemClock;
-import android.os.SystemProperties;
-import android.util.Config;
-import android.util.Log;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.Socket;
-import java.lang.IllegalStateException;
-
-import java.util.List;
-import java.util.ArrayList;
-import java.util.ListIterator;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.LinkedBlockingQueue;
-
-/**
- * Vold Connection class
- */
-final class MountListener implements Runnable {
- private static final String TAG = "MountListener";
- private static final String VOLD_SOCKET = "vold";
- private static final int RESPONSE_QUEUE_SIZE = 10;
-
- private MountService mService;
- private BlockingQueue<String> mResponseQueue;
- private OutputStream mOutputStream;
-
- class ResponseCode {
- public static final int ActionInitiated = 100;
- public static final int VolumeListResult = 110;
- public static final int AsecListResult = 111;
-
- public static final int CommandOkay = 200;
- public static final int ShareAvailabilityResult = 210;
- public static final int AsecPathResult = 211;
-
- public static final int UnsolicitedInformational = 600;
- public static final int VolumeStateChange = 605;
- public static final int VolumeMountFailedBlank = 610;
- public static final int VolumeMountFailedDamaged = 611;
- public static final int VolumeMountFailedNoMedia = 612;
- public static final int ShareAvailabilityChange = 620;
- public static final int VolumeDiskInserted = 630;
- public static final int VolumeDiskRemoved = 631;
- public static final int VolumeBadRemoval = 632;
- }
-
- MountListener(MountService service) {
- mService = service;
- mResponseQueue = new LinkedBlockingQueue<String>(RESPONSE_QUEUE_SIZE);
- }
-
- public void run() {
- // Vold does not run in the simulator, so fake out a mounted event to trigger the Media Scanner
- if ("simulator".equals(SystemProperties.get("ro.product.device"))) {
- mService.notifyMediaMounted(Environment.getExternalStorageDirectory().getPath(), false);
- return;
- }
-
- try {
- while (true) {
- listenToSocket();
- }
- } catch (Throwable t) {
- Log.e(TAG, "Fatal error " + t + " in MountListener thread!");
- }
- }
-
- private void listenToSocket() {
- LocalSocket socket = null;
-
- try {
- socket = new LocalSocket();
- LocalSocketAddress address = new LocalSocketAddress(VOLD_SOCKET,
- LocalSocketAddress.Namespace.RESERVED);
-
- socket.connect(address);
- mService.onVoldConnected();
-
- InputStream inputStream = socket.getInputStream();
- mOutputStream = socket.getOutputStream();
-
- byte[] buffer = new byte[4096];
-
- while (true) {
- int count = inputStream.read(buffer);
- if (count < 0) break;
-
- int start = 0;
- for (int i = 0; i < count; i++) {
- if (buffer[i] == 0) {
- String event = new String(buffer, start, i - start);
-// Log.d(TAG, "Got packet {" + event + "}");
-
- String[] tokens = event.split(" ");
- try {
- int code = Integer.parseInt(tokens[0]);
-
- if (code >= ResponseCode.UnsolicitedInformational) {
- try {
- handleUnsolicitedEvent(code, event, tokens);
- } catch (Exception ex) {
- Log.e(TAG, String.format(
- "Error handling '%s'", event), ex);
- }
- } else {
- try {
- mResponseQueue.put(event);
- } catch (InterruptedException ex) {
- Log.e(TAG, "InterruptedException");
- }
- }
- } catch (NumberFormatException nfe) {
- Log.w(TAG,
- "Unknown msg from Vold '" + event + "'");
- }
- start = i + 1;
- }
- }
- }
- } catch (IOException ex) {
- Log.e(TAG, "IOException in listenToSocket");
- }
-
- synchronized (this) {
- if (mOutputStream != null) {
- try {
- mOutputStream.close();
- } catch (IOException e) {
- Log.w(TAG, "IOException closing output stream");
- }
-
- mOutputStream = null;
- }
- }
-
- try {
- if (socket != null) {
- socket.close();
- }
- } catch (IOException ex) {
- Log.w(TAG, "IOException closing socket");
- }
-
- Log.e(TAG, "Failed to connect to Vold", new IllegalStateException());
- SystemClock.sleep(5000);
- }
-
- private void handleUnsolicitedEvent(int code, String raw,
- String[] cooked) throws IllegalStateException {
-// Log.d(TAG, "unsolicited {" + raw + "}");
- if (code == ResponseCode.VolumeStateChange) {
- // FMT: NNN Volume <label> <mountpoint> state changed from <old_#> (<old_str>) to <new_#> (<new_str>)
- mService.notifyVolumeStateChange(cooked[2], cooked[3],
- Integer.parseInt(cooked[7]),
- Integer.parseInt(cooked[10]));
- } else if (code == ResponseCode.VolumeMountFailedBlank) {
- // FMT: NNN Volume <label> <mountpoint> mount failed - no supported file-systems
- mService.notifyMediaNoFs(cooked[3]);
- // FMT: NNN Volume <label> <mountpoint> mount failed - no media
- } else if (code == ResponseCode.VolumeMountFailedNoMedia) {
- mService.notifyMediaRemoved(cooked[3]);
- } else if (code == ResponseCode.VolumeMountFailedDamaged) {
- // FMT: NNN Volume <label> <mountpoint> mount failed - filesystem check failed
- mService.notifyMediaUnmountable(cooked[3]);
- } else if (code == ResponseCode.ShareAvailabilityChange) {
- // FMT: NNN Share method <method> now <available|unavailable>
- boolean avail = false;
- if (cooked[5].equals("available")) {
- avail = true;
- }
- mService.notifyShareAvailabilityChange(cooked[3], avail);
- } else if (code == ResponseCode.VolumeDiskInserted) {
- // FMT: NNN Volume <label> <mountpoint> disk inserted (<major>:<minor>)
- mService.notifyMediaInserted(cooked[3]);
- } else if (code == ResponseCode.VolumeDiskRemoved) {
- // FMT: NNN Volume <label> <mountpoint> disk removed (<major>:<minor>)
- mService.notifyMediaRemoved(cooked[3]);
- } else if (code == ResponseCode.VolumeBadRemoval) {
- // FMT: NNN Volume <label> <mountpoint> bad removal (<major>:<minor>)
- mService.notifyMediaBadRemoval(cooked[3]);
- } else {
- Log.w(TAG, "Unhandled event {" + raw + "}");
- }
- }
-
-
- private void sendCommand(String command) {
- sendCommand(command, null);
- }
-
- /**
- * Sends a command to Vold with a single argument
- *
- * @param command The command to send to the mount service daemon
- * @param argument The argument to send with the command (or null)
- */
- private void sendCommand(String command, String argument) {
- synchronized (this) {
- // Log.d(TAG, "sendCommand {" + command + "} {" + argument + "}");
- if (mOutputStream == null) {
- Log.e(TAG, "No connection to Vold", new IllegalStateException());
- } else {
- StringBuilder builder = new StringBuilder(command);
- if (argument != null) {
- builder.append(argument);
- }
- builder.append('\0');
-
- try {
- mOutputStream.write(builder.toString().getBytes());
- } catch (IOException ex) {
- Log.e(TAG, "IOException in sendCommand", ex);
- }
- }
- }
- }
-
- private synchronized ArrayList<String> doCommand(String cmd) throws IllegalStateException {
- sendCommand(cmd);
-
- ArrayList<String> response = new ArrayList<String>();
- boolean complete = false;
- int code = -1;
-
- while (!complete) {
- try {
- String line = mResponseQueue.take();
-// Log.d(TAG, "Removed off queue -> " + line);
- String[] tokens = line.split(" ");
- code = Integer.parseInt(tokens[0]);
-
- if ((code >= 200) && (code < 600))
- complete = true;
- response.add(line);
- } catch (InterruptedException ex) {
- Log.e(TAG, "InterruptedException");
- }
- }
-
- if (code >= 400 && code < 600) {
- throw new IllegalStateException(String.format(
- "Command %s failed with code %d",
- cmd, code));
- }
- return response;
- }
-
- boolean getShareAvailable(String method) throws IllegalStateException {
- ArrayList<String> rsp = doCommand("share_available " + method);
-
- for (String line : rsp) {
- String []tok = line.split(" ");
- int code = Integer.parseInt(tok[0]);
- if (code == ResponseCode.ShareAvailabilityResult) {
- if (tok[2].equals("available"))
- return true;
- return false;
- } else {
- throw new IllegalStateException(String.format("Unexpected response code %d", code));
- }
- }
- throw new IllegalStateException("Got an empty response");
- }
-
- /**
- * Enables or disables USB mass storage support.
- *
- * @param enable true to enable USB mass storage support
- */
- void setShareMethodEnabled(String mountPoint, String method,
- boolean enable) throws IllegalStateException {
- doCommand((enable ? "" : "un") + "share " + mountPoint + " " + method);
- }
-
- /**
- * Mount media at given mount point.
- */
- public void mountVolume(String label) throws IllegalStateException {
- doCommand("mount " + label);
- }
-
- /**
- * Unmount media at given mount point.
- */
- public void unmountVolume(String label) throws IllegalStateException {
- doCommand("unmount " + label);
- }
-
- /**
- * Format media at given mount point.
- */
- public void formatVolume(String label) throws IllegalStateException {
- doCommand("format " + label);
- }
-
- public String createAsec(String id, int sizeMb, String fstype, String key,
- int ownerUid) throws IllegalStateException {
- String cmd = String.format("create_asec %s %d %s %s %d",
- id, sizeMb, fstype, key, ownerUid);
- doCommand(cmd);
- return getAsecPath(id);
- }
-
- public void finalizeAsec(String id) throws IllegalStateException {
- doCommand("finalize_asec " + id);
- }
-
- public void destroyAsec(String id) throws IllegalStateException {
- doCommand("destroy_asec " + id);
- }
-
- public String mountAsec(String id, String key, int ownerUid) throws IllegalStateException {
- String cmd = String.format("mount_asec %s %s %d",
- id, key, ownerUid);
- doCommand(cmd);
- return getAsecPath(id);
- }
-
- public String getAsecPath(String id) throws IllegalStateException {
- ArrayList<String> rsp = doCommand("asec_path " + id);
-
- for (String line : rsp) {
- String []tok = line.split(" ");
- int code = Integer.parseInt(tok[0]);
- if (code == ResponseCode.AsecPathResult) {
- return tok[1];
- } else {
- throw new IllegalStateException(String.format("Unexpected response code %d", code));
- }
- }
- throw new IllegalStateException("Got an empty response");
- }
-
- public String[] listAsec() throws IllegalStateException {
- ArrayList<String> rsp = doCommand("list_asec");
-
- String[] rdata = new String[rsp.size()];
- int idx = 0;
-
- for (String line : rsp) {
- String []tok = line.split(" ");
- int code = Integer.parseInt(tok[0]);
- if (code == ResponseCode.AsecListResult) {
- rdata[idx++] = tok[1];
- } else if (code == ResponseCode.CommandOkay) {
- return rdata;
- } else {
- throw new IllegalStateException(String.format("Unexpected response code %d", code));
- }
- }
- throw new IllegalStateException("Got an empty response");
- }
-}
diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java
index cd17bd2e3ecf..c8a691526058 100644
--- a/services/java/com/android/server/MountService.java
+++ b/services/java/com/android/server/MountService.java
@@ -33,6 +33,7 @@ import android.os.UEventObserver;
import android.os.Handler;
import android.text.TextUtils;
import android.util.Log;
+import java.util.ArrayList;
import android.provider.Settings;
import android.content.ContentResolver;
@@ -46,7 +47,8 @@ import java.lang.IllegalStateException;
* MountService implements an to the mount service daemon
* @hide
*/
-class MountService extends IMountService.Stub {
+class MountService extends IMountService.Stub
+ implements INativeDaemonConnectorCallbacks {
private static final String TAG = "MountService";
@@ -63,15 +65,33 @@ class MountService extends IMountService.Stub {
public static final int SharedMnt = 8;
}
+ class VoldResponseCode {
+ public static final int VolumeListResult = 110;
+ public static final int AsecListResult = 111;
+
+ public static final int ShareAvailabilityResult = 210;
+ public static final int AsecPathResult = 211;
+
+ public static final int VolumeStateChange = 605;
+ public static final int VolumeMountFailedBlank = 610;
+ public static final int VolumeMountFailedDamaged = 611;
+ public static final int VolumeMountFailedNoMedia = 612;
+ public static final int ShareAvailabilityChange = 620;
+ public static final int VolumeDiskInserted = 630;
+ public static final int VolumeDiskRemoved = 631;
+ public static final int VolumeBadRemoval = 632;
+ }
+
+
/**
* Binder context for this service
*/
private Context mContext;
/**
- * listener object for communicating with the mount service daemon
+ * connectorr object for communicating with vold
*/
- private MountListener mListener;
+ private NativeDaemonConnector mConnector;
/**
* The notification that is shown when a USB mass storage host
@@ -119,12 +139,12 @@ class MountService extends IMountService.Stub {
mContext = context;
// Register a BOOT_COMPLETED handler so that we can start
- // MountListener. We defer the startup so that we don't
+ // our NativeDaemonConnector. We defer the startup so that we don't
// start processing events before we ought-to
mContext.registerReceiver(mBroadcastReceiver,
new IntentFilter(Intent.ACTION_BOOT_COMPLETED), null, null);
- mListener = new MountListener(this);
+ mConnector = new NativeDaemonConnector(this, "vold", 10, "VoldConnector");
mShowSafeUnmountNotificationWhenUnmounted = false;
mPlaySounds = SystemProperties.get("persist.service.mount.playsnd", "1").equals("1");
@@ -202,7 +222,18 @@ class MountService extends IMountService.Stub {
String action = intent.getAction();
if (action.equals(Intent.ACTION_BOOT_COMPLETED)) {
- Thread thread = new Thread(mListener, MountListener.class.getName());
+ /*
+ * Vold does not run in the simulator, so fake out a mounted
+ * event to trigger MediaScanner
+ */
+ if ("simulator".equals(SystemProperties.get("ro.product.device"))) {
+ notifyMediaMounted(
+ Environment.getExternalStorageDirectory().getPath(), false);
+ return;
+ }
+
+ Thread thread = new Thread(
+ mConnector, NativeDaemonConnector.class.getName());
thread.start();
}
}
@@ -215,7 +246,7 @@ class MountService extends IMountService.Stub {
throw new SecurityException("Requires SHUTDOWN permission");
}
- Log.i(TAG, "Shutting down");
+ Log.d(TAG, "Shutting down");
String state = Environment.getExternalStorageState();
if (state.equals(Environment.MEDIA_SHARED)) {
@@ -258,7 +289,21 @@ class MountService extends IMountService.Stub {
*/
try {
String m = Environment.getExternalStorageDirectory().toString();
- unmountMedia(m);
+ unmountVolume(m);
+
+ int retries = 12;
+ while (!state.equals(Environment.MEDIA_UNMOUNTED) && (retries-- >=0)) {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException iex) {
+ Log.e(TAG, "Interrupted while waiting for media", iex);
+ break;
+ }
+ state = Environment.getExternalStorageState();
+ }
+ if (retries == 0) {
+ Log.e(TAG, "Timed out waiting for media to unmount");
+ }
} catch (Exception e) {
Log.e(TAG, "external storage unmount failed", e);
}
@@ -288,17 +333,14 @@ class MountService extends IMountService.Stub {
String vs = getVolumeState(vp);
if (enable && vs.equals(Environment.MEDIA_MOUNTED)) {
- mListener.unmountVolume(vp);
+ unmountVolume(vp);
updateUsbMassStorageNotification(true, false);
}
- mListener.setShareMethodEnabled(Environment
- .getExternalStorageDirectory()
- .getPath(),
- "ums", enable);
+ setShareMethodEnabled(vp, "ums", enable);
mUmsEnabled = enable;
if (!enable) {
- mountMedia(vp);
+ mountVolume(vp);
if (mPromptUms) {
updateUsbMassStorageNotification(false, false);
} else {
@@ -338,19 +380,19 @@ class MountService extends IMountService.Stub {
/**
* Attempt to mount external media
*/
- public void mountMedia(String mountPath) throws IllegalStateException {
+ public void mountVolume(String mountPath) throws IllegalStateException {
if (mContext.checkCallingOrSelfPermission(
android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS)
!= PackageManager.PERMISSION_GRANTED) {
throw new SecurityException("Requires MOUNT_UNMOUNT_FILESYSTEMS permission");
}
- mListener.mountVolume(mountPath);
+ mConnector.doCommand(String.format("mount %s", mountPath));
}
/**
* Attempt to unmount external media to prepare for eject
*/
- public void unmountMedia(String mountPath) throws IllegalStateException {
+ public void unmountVolume(String mountPath) throws IllegalStateException {
if (mContext.checkCallingOrSelfPermission(
android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS)
!= PackageManager.PERMISSION_GRANTED) {
@@ -361,24 +403,52 @@ class MountService extends IMountService.Stub {
// to display the notification
mShowSafeUnmountNotificationWhenUnmounted = true;
- // tell mountd to unmount the media
- mListener.unmountVolume(mountPath);
+ mConnector.doCommand(String.format("unmount %s", mountPath));
}
/**
* Attempt to format external media
*/
- public void formatMedia(String formatPath) throws IllegalStateException {
+ public void formatVolume(String formatPath) throws IllegalStateException {
if (mContext.checkCallingOrSelfPermission(
android.Manifest.permission.MOUNT_FORMAT_FILESYSTEMS)
!= PackageManager.PERMISSION_GRANTED) {
throw new SecurityException("Requires MOUNT_FORMAT_FILESYSTEMS permission");
}
- mListener.formatVolume(formatPath);
+ mConnector.doCommand(String.format("format %s", formatPath));
+ }
+
+ boolean getShareAvailable(String method) throws IllegalStateException {
+ ArrayList<String> rsp = mConnector.doCommand("share_available " + method);
+
+ for (String line : rsp) {
+ String []tok = line.split(" ");
+ int code = Integer.parseInt(tok[0]);
+ if (code == VoldResponseCode.ShareAvailabilityResult) {
+ if (tok[2].equals("available"))
+ return true;
+ return false;
+ } else {
+ throw new IllegalStateException(String.format("Unexpected response code %d", code));
+ }
+ }
+ throw new IllegalStateException("Got an empty response");
}
/**
+ * Enables or disables USB mass storage support.
+ *
+ * @param enable true to enable USB mass storage support
+ */
+ void setShareMethodEnabled(String mountPoint, String method,
+ boolean enable) throws IllegalStateException {
+ mConnector.doCommand(String.format(
+ "%sshare %s %s", (enable ? "" : "un"), mountPoint, method));
+ }
+
+
+ /**
* Returns true if we're playing media notification sounds.
*/
public boolean getPlayNotificationSounds() {
@@ -403,7 +473,7 @@ class MountService extends IMountService.Stub {
Log.w(TAG, "Multiple volumes not currently supported");
return;
}
- Log.w(TAG, "State for {" + mountPoint + "} = {" + state + "}");
+ Log.i(TAG, "State for {" + mountPoint + "} = {" + state + "}");
mLegacyState = state;
}
@@ -441,14 +511,18 @@ class MountService extends IMountService.Stub {
}
}
- void onVoldConnected() {
+ /**
+ *
+ * Callback from NativeDaemonConnector
+ */
+ public void onDaemonConnected() {
new Thread() {
public void run() {
try {
if (!getVolumeState(Environment.getExternalStorageDirectory().getPath())
.equals(Environment.MEDIA_MOUNTED)) {
try {
- mountMedia(Environment.getExternalStorageDirectory().getPath());
+ mountVolume(Environment.getExternalStorageDirectory().getPath());
} catch (Exception ex) {
Log.w(TAG, "Connection-mount failed");
}
@@ -460,7 +534,7 @@ class MountService extends IMountService.Stub {
}
try {
- boolean avail = mListener.getShareAvailable("ums");
+ boolean avail = getShareAvailable("ums");
notifyShareAvailabilityChange("ums", avail);
} catch (Exception ex) {
Log.w(TAG, "Failed to get share availability");
@@ -469,6 +543,49 @@ class MountService extends IMountService.Stub {
}.start();
}
+ /**
+ *
+ * Callback from NativeDaemonConnector
+ */
+ public boolean onEvent(int code, String raw, String[] cooked) {
+ // Log.d(TAG, "event {" + raw + "}");
+ if (code == VoldResponseCode.VolumeStateChange) {
+ // FMT: NNN Volume <label> <mountpoint> state changed
+ // from <old_#> (<old_str>) to <new_#> (<new_str>)
+ notifyVolumeStateChange(
+ cooked[2], cooked[3], Integer.parseInt(cooked[7]),
+ Integer.parseInt(cooked[10]));
+ } else if (code == VoldResponseCode.VolumeMountFailedBlank) {
+ // FMT: NNN Volume <label> <mountpoint> mount failed - no supported file-systems
+ notifyMediaNoFs(cooked[3]);
+ // FMT: NNN Volume <label> <mountpoint> mount failed - no media
+ } else if (code == VoldResponseCode.VolumeMountFailedNoMedia) {
+ notifyMediaRemoved(cooked[3]);
+ } else if (code == VoldResponseCode.VolumeMountFailedDamaged) {
+ // FMT: NNN Volume <label> <mountpoint> mount failed - filesystem check failed
+ notifyMediaUnmountable(cooked[3]);
+ } else if (code == VoldResponseCode.ShareAvailabilityChange) {
+ // FMT: NNN Share method <method> now <available|unavailable>
+ boolean avail = false;
+ if (cooked[5].equals("available")) {
+ avail = true;
+ }
+ notifyShareAvailabilityChange(cooked[3], avail);
+ } else if (code == VoldResponseCode.VolumeDiskInserted) {
+ // FMT: NNN Volume <label> <mountpoint> disk inserted (<major>:<minor>)
+ notifyMediaInserted(cooked[3]);
+ } else if (code == VoldResponseCode.VolumeDiskRemoved) {
+ // FMT: NNN Volume <label> <mountpoint> disk removed (<major>:<minor>)
+ notifyMediaRemoved(cooked[3]);
+ } else if (code == VoldResponseCode.VolumeBadRemoval) {
+ // FMT: NNN Volume <label> <mountpoint> bad removal (<major>:<minor>)
+ notifyMediaBadRemoval(cooked[3]);
+ } else {
+ return false;
+ }
+ return true;
+ }
+
void notifyVolumeStateChange(String label, String mountPoint, int oldState,
int newState) throws IllegalStateException {
String vs = getVolumeState(mountPoint);
@@ -573,7 +690,7 @@ class MountService extends IMountService.Stub {
new Thread() {
public void run() {
try {
- mountMedia(path);
+ mountVolume(path);
} catch (Exception ex) {
Log.w(TAG, "Failed to mount media on insertion", ex);
}
@@ -889,29 +1006,62 @@ class MountService extends IMountService.Stub {
}
public String[] getSecureContainerList() throws IllegalStateException {
- return mListener.listAsec();
+ ArrayList<String> rsp = mConnector.doCommand("list_asec");
+
+ String[] rdata = new String[rsp.size()];
+ int idx = 0;
+
+ for (String line : rsp) {
+ String []tok = line.split(" ");
+ int code = Integer.parseInt(tok[0]);
+ if (code == VoldResponseCode.AsecListResult) {
+ rdata[idx++] = tok[1];
+ } else if (code == NativeDaemonConnector.ResponseCode.CommandOkay) {
+ return rdata;
+ } else {
+ throw new IllegalStateException(String.format("Unexpected response code %d", code));
+ }
+ }
+ throw new IllegalStateException("Got an empty response");
}
public String createSecureContainer(String id, int sizeMb, String fstype,
String key, int ownerUid) throws IllegalStateException {
- return mListener.createAsec(id, sizeMb, fstype, key, ownerUid);
+ String cmd = String.format("create_asec %s %d %s %s %d",
+ id, sizeMb, fstype, key, ownerUid);
+ mConnector.doCommand(cmd);
+ return getSecureContainerPath(id);
}
public void finalizeSecureContainer(String id) throws IllegalStateException {
- mListener.finalizeAsec(id);
+ mConnector.doCommand(String.format("finalize_asec %s", id));
}
public void destroySecureContainer(String id) throws IllegalStateException {
- mListener.destroyAsec(id);
+ mConnector.doCommand(String.format("destroy_asec %s", id));
}
- public String mountSecureContainer(String id, String key, int ownerUid) throws IllegalStateException {
- return mListener.mountAsec(id, key, ownerUid);
+ public String mountSecureContainer(String id, String key,
+ int ownerUid) throws IllegalStateException {
+ String cmd = String.format("mount_asec %s %s %d",
+ id, key, ownerUid);
+ mConnector.doCommand(cmd);
+ return getSecureContainerPath(id);
}
public String getSecureContainerPath(String id) throws IllegalStateException {
- return mListener.getAsecPath(id);
- }
+ ArrayList<String> rsp = mConnector.doCommand("asec_path " + id);
+ for (String line : rsp) {
+ String []tok = line.split(" ");
+ int code = Integer.parseInt(tok[0]);
+ if (code == VoldResponseCode.AsecPathResult) {
+ return tok[1];
+ } else {
+ throw new IllegalStateException(String.format("Unexpected response code %d", code));
+ }
+ }
+ throw new IllegalStateException("Got an empty response");
+ }
}
diff --git a/services/java/com/android/server/NativeDaemonConnector.java b/services/java/com/android/server/NativeDaemonConnector.java
new file mode 100644
index 000000000000..da3e562fb540
--- /dev/null
+++ b/services/java/com/android/server/NativeDaemonConnector.java
@@ -0,0 +1,239 @@
+/*
+ * Copyright (C) 2007 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 com.android.server;
+
+import android.net.LocalSocketAddress;
+import android.net.LocalSocket;
+import android.os.Environment;
+import android.os.SystemClock;
+import android.os.SystemProperties;
+import android.util.Config;
+import android.util.Log;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.lang.IllegalStateException;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.util.ListIterator;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+
+/**
+ * Generic connector class for interfacing with a native
+ * daemon which uses the libsysutils FrameworkListener
+ * protocol.
+ */
+final class NativeDaemonConnector implements Runnable {
+
+ private BlockingQueue<String> mResponseQueue;
+ private OutputStream mOutputStream;
+ private String TAG = "NativeDaemonConnector";
+ private String mSocket;
+ private INativeDaemonConnectorCallbacks mCallbacks;
+
+ class ResponseCode {
+ public static final int ActionInitiated = 100;
+
+ public static final int CommandOkay = 200;
+
+ // The range of 400 -> 599 is reserved for cmd failures
+ public static final int OperationFailed = 400;
+ public static final int CommandSyntaxError = 500;
+ public static final int CommandParameterError = 501;
+
+ public static final int UnsolicitedInformational = 600;
+
+ //
+ public static final int FailedRangeStart = 400;
+ public static final int FailedRangeEnd = 599;
+ }
+
+ NativeDaemonConnector(INativeDaemonConnectorCallbacks callbacks,
+ String socket, int responseQueueSize, String logTag) {
+ mCallbacks = callbacks;
+ if (logTag != null)
+ TAG = logTag;
+ mSocket = socket;
+ mResponseQueue = new LinkedBlockingQueue<String>(responseQueueSize);
+ }
+
+ public void run() {
+
+ while (true) {
+ try {
+ listenToSocket();
+ } catch (Exception e) {
+ Log.e(TAG, "Error in NativeDaemonConnector", e);
+ SystemClock.sleep(1000);
+ }
+ }
+ }
+
+ private void listenToSocket() {
+ LocalSocket socket = null;
+
+ try {
+ socket = new LocalSocket();
+ LocalSocketAddress address = new LocalSocketAddress(mSocket,
+ LocalSocketAddress.Namespace.RESERVED);
+
+ socket.connect(address);
+ mCallbacks.onDaemonConnected();
+
+ InputStream inputStream = socket.getInputStream();
+ mOutputStream = socket.getOutputStream();
+
+ byte[] buffer = new byte[4096];
+
+ while (true) {
+ int count = inputStream.read(buffer);
+ if (count < 0) break;
+
+ int start = 0;
+ for (int i = 0; i < count; i++) {
+ if (buffer[i] == 0) {
+ String event = new String(buffer, start, i - start);
+// Log.d(TAG, "Got packet {" + event + "}");
+
+ String[] tokens = event.split(" ");
+ try {
+ int code = Integer.parseInt(tokens[0]);
+
+ if (code >= ResponseCode.UnsolicitedInformational) {
+ try {
+ if (!mCallbacks.onEvent(code, event, tokens)) {
+ Log.w(TAG, String.format(
+ "Unhandled event (%s)", event));
+ }
+ } catch (Exception ex) {
+ Log.e(TAG, String.format(
+ "Error handling '%s'", event), ex);
+ }
+ } else {
+ try {
+ mResponseQueue.put(event);
+ } catch (InterruptedException ex) {
+ Log.e(TAG, "Failed to put response onto queue", ex);
+ }
+ }
+ } catch (NumberFormatException nfe) {
+ Log.w(TAG, String.format("Bad msg (%s)", event));
+ }
+ start = i + 1;
+ }
+ }
+ }
+ } catch (IOException ex) {
+ Log.e(TAG, "Communications error", ex);
+ }
+
+ synchronized (this) {
+ if (mOutputStream != null) {
+ try {
+ mOutputStream.close();
+ } catch (IOException e) {
+ Log.w(TAG, "Failed closing output stream", e);
+ }
+
+ mOutputStream = null;
+ }
+ }
+
+ try {
+ if (socket != null) {
+ socket.close();
+ }
+ } catch (IOException ex) {
+ Log.w(TAG, "Failed closing socket", ex);
+ }
+
+ Log.e(TAG, "Failed to connect to native daemon",
+ new IllegalStateException());
+ SystemClock.sleep(5000);
+ }
+
+ private void sendCommand(String command) {
+ sendCommand(command, null);
+ }
+
+ /**
+ * Sends a command to the daemon with a single argument
+ *
+ * @param command The command to send to the daemon
+ * @param argument The argument to send with the command (or null)
+ */
+ private void sendCommand(String command, String argument) {
+ synchronized (this) {
+ Log.d(TAG, "sendCommand {" + command + "} {" + argument + "}");
+ if (mOutputStream == null) {
+ Log.e(TAG, "No connection to daemon", new IllegalStateException());
+ } else {
+ StringBuilder builder = new StringBuilder(command);
+ if (argument != null) {
+ builder.append(argument);
+ }
+ builder.append('\0');
+
+ try {
+ mOutputStream.write(builder.toString().getBytes());
+ } catch (IOException ex) {
+ Log.e(TAG, "IOException in sendCommand", ex);
+ }
+ }
+ }
+ }
+
+ public synchronized ArrayList<String> doCommand(String cmd) throws IllegalStateException {
+ sendCommand(cmd);
+
+ ArrayList<String> response = new ArrayList<String>();
+ boolean complete = false;
+ int code = -1;
+
+ while (!complete) {
+ try {
+ String line = mResponseQueue.take();
+// Log.d(TAG, "Removed off queue -> " + line);
+ String[] tokens = line.split(" ");
+ try {
+ code = Integer.parseInt(tokens[0]);
+ } catch (NumberFormatException nfe) {
+ throw new IllegalStateException(
+ String.format("Invalid response from daemon (%s)", line));
+ }
+
+ if ((code >= 200) && (code < 600))
+ complete = true;
+ response.add(line);
+ } catch (InterruptedException ex) {
+ Log.e(TAG, "InterruptedException");
+ }
+ }
+
+ if (code >= ResponseCode.FailedRangeStart &&
+ code <= ResponseCode.FailedRangeEnd) {
+ throw new IllegalStateException(String.format(
+ "Command %s failed with code %d",
+ cmd, code));
+ }
+ return response;
+ }
+}
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index de3dcb01cee8..d5de1f0be1c1 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -330,6 +330,17 @@ public class WifiService extends IWifiManager.Stub {
return false;
}
+ /**
+ * Multiple calls to unregisterReceiver() cause exception and a system crash.
+ * This can happen if a supplicant is lost (or firmware crash occurs) and user indicates
+ * disable wifi at the same time.
+ * Avoid doing a disable when the current Wifi state is UNKNOWN
+ * TODO: Handle driver load fail and supplicant lost as seperate states
+ */
+ if (mWifiState == WIFI_STATE_UNKNOWN && !enable) {
+ return false;
+ }
+
setWifiEnabledState(enable ? WIFI_STATE_ENABLING : WIFI_STATE_DISABLING, uid);
if (enable) {
diff --git a/telephony/java/com/android/internal/telephony/Call.java b/telephony/java/com/android/internal/telephony/Call.java
index b95dd11046dd..4967ab81e5fc 100644
--- a/telephony/java/com/android/internal/telephony/Call.java
+++ b/telephony/java/com/android/internal/telephony/Call.java
@@ -18,6 +18,8 @@ package com.android.internal.telephony;
import java.util.List;
+import android.util.Log;
+
/**
* {@hide}
*/
@@ -54,6 +56,8 @@ public abstract class Call {
// merged, etc.
protected boolean isGeneric = false;
+ protected final String LOG_TAG = "Call";
+
/* Instance Methods */
/** Do not modify the List result!!! This list is not yours to keep
@@ -235,4 +239,17 @@ public abstract class Call {
public void setGeneric(boolean generic) {
isGeneric = generic;
}
+
+ /**
+ * Hangup call if it is alive
+ */
+ public void hangupIfAlive() {
+ if (getState().isAlive()) {
+ try {
+ hangup();
+ } catch (CallStateException ex) {
+ Log.w(LOG_TAG, " hangupIfActive: caught " + ex);
+ }
+ }
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/ServiceStateTracker.java b/telephony/java/com/android/internal/telephony/ServiceStateTracker.java
index 6892998479f8..73836497dc4e 100644
--- a/telephony/java/com/android/internal/telephony/ServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/ServiceStateTracker.java
@@ -271,6 +271,13 @@ public abstract class ServiceStateTracker extends Handler {
protected abstract void updateSpnDisplay();
protected abstract void setPowerStateToDesired();
+ /**
+ * Clean up existing voice and data connection then turn off radio power.
+ *
+ * Hang up the existing voice calls to decrease call drop rate.
+ */
+ protected abstract void powerOffRadioSafely();
+
/** Cancel a pending (if any) pollState() operation */
protected void cancelPollState() {
// This will effectively cancel the rest of the poll requests.
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
index af3cbd5eb7e9..42feaa904b10 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
@@ -514,7 +514,7 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
synchronized(this) {
if (mPendingRadioPowerOffAfterDataOff) {
if (DBG) log("EVENT_SET_RADIO_OFF, turn radio off now.");
- cm.setRadioPower(false, null);
+ hangupAndPowerOff();
mPendingRadioPowerOffAfterDataOff = false;
}
}
@@ -541,32 +541,42 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
dcTracker.getStateInString(),
dcTracker.getAnyDataEnabled() ? 1 : 0);
}
- Message msg = dcTracker.obtainMessage(DataConnectionTracker.EVENT_CLEAN_UP_CONNECTION);
- msg.arg1 = 1; // tearDown is true
- msg.obj = CDMAPhone.REASON_RADIO_TURNED_OFF;
- dcTracker.sendMessage(msg);
- synchronized(this) {
- if (!mPendingRadioPowerOffAfterDataOff) {
- DataConnectionTracker.State currentState = dcTracker.getState();
- if (currentState != DataConnectionTracker.State.CONNECTED
- && currentState != DataConnectionTracker.State.DISCONNECTING
- && currentState != DataConnectionTracker.State.INITING) {
- if (DBG) log("Data disconnected, turn off radio right away.");
- cm.setRadioPower(false, null);
- }
- else if (sendEmptyMessageDelayed(EVENT_SET_RADIO_POWER_OFF, 30000)) {
- if (DBG) {
- log("Wait up to 30 sec for data to disconnect, then turn off radio.");
- }
- mPendingRadioPowerOffAfterDataOff = true;
- } else {
- Log.w(LOG_TAG, "Cannot send delayed Msg, turn off radio right away.");
- cm.setRadioPower(false, null);
+ // If it's on and available and we want it off gracefully
+ powerOffRadioSafely();
+ } // Otherwise, we're in the desired state
+ }
+
+ @Override
+ protected void powerOffRadioSafely(){
+ // clean data connection
+ DataConnectionTracker dcTracker = phone.mDataConnection;
+
+ Message msg = dcTracker.obtainMessage(DataConnectionTracker.EVENT_CLEAN_UP_CONNECTION);
+ msg.arg1 = 1; // tearDown is true
+ msg.obj = CDMAPhone.REASON_RADIO_TURNED_OFF;
+ dcTracker.sendMessage(msg);
+
+ synchronized(this) {
+ if (!mPendingRadioPowerOffAfterDataOff) {
+ DataConnectionTracker.State currentState = dcTracker.getState();
+ if (currentState != DataConnectionTracker.State.CONNECTED
+ && currentState != DataConnectionTracker.State.DISCONNECTING
+ && currentState != DataConnectionTracker.State.INITING) {
+ if (DBG) log("Data disconnected, turn off radio right away.");
+ hangupAndPowerOff();
+ }
+ else if (sendEmptyMessageDelayed(EVENT_SET_RADIO_POWER_OFF, 30000)) {
+ if (DBG) {
+ log("Wait up to 30 sec for data to disconnect, then turn off radio.");
}
+ mPendingRadioPowerOffAfterDataOff = true;
+ } else {
+ Log.w(LOG_TAG, "Cannot send delayed Msg, turn off radio right away.");
+ hangupAndPowerOff();
}
}
- } // Otherwise, we're in the desired state
+ }
}
@Override
@@ -1644,11 +1654,19 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
if (mPendingRadioPowerOffAfterDataOff) {
if (DBG) log("Process pending request to turn radio off.");
removeMessages(EVENT_SET_RADIO_POWER_OFF);
- cm.setRadioPower(false, null);
+ hangupAndPowerOff();
mPendingRadioPowerOffAfterDataOff = false;
return true;
}
return false;
}
}
+
+ private void hangupAndPowerOff() {
+ // hang up all active voice calls
+ phone.mCT.ringingCall.hangupIfAlive();
+ phone.mCT.backgroundCall.hangupIfAlive();
+ phone.mCT.foregroundCall.hangupIfAlive();
+ cm.setRadioPower(false, null);
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
index 3f52eff59e67..6695ccbff2d9 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
@@ -808,7 +808,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
protected void restartRadio() {
Log.d(LOG_TAG, "************TURN OFF RADIO**************");
cleanUpConnection(true, Phone.REASON_RADIO_TURNED_OFF);
- phone.mCM.setRadioPower(false, null);
+ mGsmPhone.mSST.powerOffRadioSafely();
/* Note: no need to call setRadioPower(true). Assuming the desired
* radio power state is still ON (as tracked by ServiceStateTracker),
* ServiceStateTracker will call setRadioPower when it receives the
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
index c2c89c016449..48e5c97b1131 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
@@ -518,26 +518,41 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
EventLog.writeEvent(TelephonyEventLog.EVENT_LOG_DATA_STATE_RADIO_OFF,
dcTracker.getStateInString(), dcTracker.getAnyDataEnabled() ? 1 : 0);
}
- Message msg = dcTracker.obtainMessage(DataConnectionTracker.EVENT_CLEAN_UP_CONNECTION);
- msg.arg1 = 1; // tearDown is true
- msg.obj = GSMPhone.REASON_RADIO_TURNED_OFF;
- dcTracker.sendMessage(msg);
-
- // poll data state up to 15 times, with a 100ms delay
- // totaling 1.5 sec. Normal data disable action will finish in 100ms.
- for (int i = 0; i < MAX_NUM_DATA_STATE_READS; i++) {
- if (dcTracker.getState() != DataConnectionTracker.State.CONNECTED
- && dcTracker.getState() != DataConnectionTracker.State.DISCONNECTING) {
- Log.d(LOG_TAG, "Data shutdown complete.");
- break;
- }
- SystemClock.sleep(DATA_STATE_POLL_SLEEP_MS);
- }
- // If it's on and available and we want it off..
- cm.setRadioPower(false, null);
+ // If it's on and available and we want it off gracefully
+ powerOffRadioSafely();
} // Otherwise, we're in the desired state
}
+ @Override
+ protected void powerOffRadioSafely() {
+ // clean data connection
+ DataConnectionTracker dcTracker = phone.mDataConnection;
+ Message msg = dcTracker.obtainMessage(DataConnectionTracker.EVENT_CLEAN_UP_CONNECTION);
+ msg.arg1 = 1; // tearDown is true
+ msg.obj = GSMPhone.REASON_RADIO_TURNED_OFF;
+ dcTracker.sendMessage(msg);
+
+ // poll data state up to 15 times, with a 100ms delay
+ // totaling 1.5 sec. Normal data disable action will finish in 100ms.
+ for (int i = 0; i < MAX_NUM_DATA_STATE_READS; i++) {
+ if (dcTracker.getState() != DataConnectionTracker.State.CONNECTED
+ && dcTracker.getState() != DataConnectionTracker.State.DISCONNECTING) {
+ Log.d(LOG_TAG, "Data shutdown complete.");
+ break;
+ }
+ SystemClock.sleep(DATA_STATE_POLL_SLEEP_MS);
+ }
+
+ // hang up all active voice calls
+ if (phone.isInCall()) {
+ phone.mCT.ringingCall.hangupIfAlive();
+ phone.mCT.backgroundCall.hangupIfAlive();
+ phone.mCT.foregroundCall.hangupIfAlive();
+ }
+
+ cm.setRadioPower(false, null);
+ }
+
protected void updateSpnDisplay() {
int rule = phone.mSIMRecords.getDisplayRule(ss.getOperatorNumeric());
String spn = phone.mSIMRecords.getServiceProviderName();
diff --git a/tests/AndroidTests/src/com/android/unit_tests/AndroidTests.java b/tests/AndroidTests/src/com/android/unit_tests/AndroidTests.java
deleted file mode 100644
index 4b86add1c7d0..000000000000
--- a/tests/AndroidTests/src/com/android/unit_tests/AndroidTests.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2005 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 com.android.unit_tests;
-
-import android.test.FrameworkTests;
-import android.test.suitebuilder.TestSuiteBuilder;
-
-import junit.framework.TestSuite;
-
-public class AndroidTests extends TestSuite {
-
- public static TestSuite suite() {
- TestSuiteBuilder suiteBuilder = new TestSuiteBuilder(AndroidTests.class);
- TestSuite suite = suiteBuilder.includeAllPackagesUnderHere().build();
-
- return suite;
- }
-}
diff --git a/tests/AndroidTests/src/com/android/unit_tests/DatabaseCursorTest.java b/tests/AndroidTests/src/com/android/unit_tests/DatabaseCursorTest.java
deleted file mode 100644
index 5df499d1604d..000000000000
--- a/tests/AndroidTests/src/com/android/unit_tests/DatabaseCursorTest.java
+++ /dev/null
@@ -1,626 +0,0 @@
-/*
- * Copyright (C) 2007 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 com.android.unit_tests;
-
-import android.content.ContentValues;
-import android.database.Cursor;
-import android.database.CursorIndexOutOfBoundsException;
-import android.database.DataSetObserver;
-import android.database.DatabaseUtils;
-import android.database.sqlite.SQLiteCursor;
-import android.database.sqlite.SQLiteCursorDriver;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteQuery;
-import android.database.sqlite.SQLiteStatement;
-import android.os.Looper;
-import android.test.PerformanceTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.test.suitebuilder.annotation.Suppress;
-import android.util.Log;
-
-import java.io.File;
-import java.util.Arrays;
-import java.util.Random;
-
-import junit.framework.TestCase;
-
-public class DatabaseCursorTest extends TestCase implements PerformanceTestCase {
-
- private static final String sString1 = "this is a test";
- private static final String sString2 = "and yet another test";
- private static final String sString3 = "this string is a little longer, but still a test";
-
- private static final int CURRENT_DATABASE_VERSION = 42;
- private SQLiteDatabase mDatabase;
- private File mDatabaseFile;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- mDatabaseFile = new File("/sqlite_stmt_journals", "database_test.db");
- if (mDatabaseFile.exists()) {
- mDatabaseFile.delete();
- }
- mDatabase = SQLiteDatabase.openOrCreateDatabase(mDatabaseFile.getPath(), null);
- assertNotNull(mDatabase);
- mDatabase.setVersion(CURRENT_DATABASE_VERSION);
- }
-
- @Override
- protected void tearDown() throws Exception {
- mDatabase.close();
- mDatabaseFile.delete();
- super.tearDown();
- }
-
- public boolean isPerformanceOnly() {
- return false;
- }
-
- // These test can only be run once.
- public int startPerformance(Intermediates intermediates) {
- return 1;
- }
-
- private void populateDefaultTable() {
- mDatabase.execSQL("CREATE TABLE test (_id INTEGER PRIMARY KEY, data TEXT);");
-
- mDatabase.execSQL("INSERT INTO test (data) VALUES ('" + sString1 + "');");
- mDatabase.execSQL("INSERT INTO test (data) VALUES ('" + sString2 + "');");
- mDatabase.execSQL("INSERT INTO test (data) VALUES ('" + sString3 + "');");
- }
-
- @MediumTest
- public void testCursorUpdate() {
- mDatabase.execSQL(
- "CREATE TABLE test (_id INTEGER PRIMARY KEY, d INTEGER, s INTEGER);");
- for(int i = 0; i < 20; i++) {
- mDatabase.execSQL("INSERT INTO test (d, s) VALUES (" + i +
- "," + i%2 + ");");
- }
-
- Cursor c = mDatabase.query("test", null, "s = 0", null, null, null, null);
- int dCol = c.getColumnIndexOrThrow("d");
- int sCol = c.getColumnIndexOrThrow("s");
-
- int count = 0;
- while (c.moveToNext()) {
- assertTrue(c.updateInt(dCol, 3));
- count++;
- }
- assertEquals(10, count);
-
- assertTrue(c.commitUpdates());
-
- assertTrue(c.requery());
-
- count = 0;
- while (c.moveToNext()) {
- assertEquals(3, c.getInt(dCol));
- count++;
- }
-
- assertEquals(10, count);
- assertTrue(c.moveToFirst());
- assertTrue(c.deleteRow());
- assertEquals(9, c.getCount());
- c.close();
- }
-
- @MediumTest
- public void testBlob() throws Exception {
- // create table
- mDatabase.execSQL(
- "CREATE TABLE test (_id INTEGER PRIMARY KEY, s TEXT, d REAL, l INTEGER, b BLOB);");
- // insert blob
- Object[] args = new Object[4];
-
- byte[] blob = new byte[1000];
- byte value = 99;
- Arrays.fill(blob, value);
- args[3] = blob;
-
- String s = new String("text");
- args[0] = s;
- Double d = 99.9;
- args[1] = d;
- Long l = (long)1000;
- args[2] = l;
-
- String sql = "INSERT INTO test (s, d, l, b) VALUES (?,?,?,?)";
- mDatabase.execSQL(sql, args);
- // use cursor to access blob
- Cursor c = mDatabase.query("test", null, null, null, null, null, null);
- c.moveToNext();
- ContentValues cv = new ContentValues();
- DatabaseUtils.cursorRowToContentValues(c, cv);
-
- int bCol = c.getColumnIndexOrThrow("b");
- int sCol = c.getColumnIndexOrThrow("s");
- int dCol = c.getColumnIndexOrThrow("d");
- int lCol = c.getColumnIndexOrThrow("l");
- byte[] cBlob = c.getBlob(bCol);
- assertTrue(Arrays.equals(blob, cBlob));
- assertEquals(s, c.getString(sCol));
- assertEquals((double)d, c.getDouble(dCol));
- assertEquals((long)l, c.getLong(lCol));
-
- // new byte[]
- byte[] newblob = new byte[1000];
- value = 98;
- Arrays.fill(blob, value);
-
- c.updateBlob(bCol, newblob);
- cBlob = c.getBlob(bCol);
- assertTrue(Arrays.equals(newblob, cBlob));
-
- // commit
- assertTrue(c.commitUpdates());
- assertTrue(c.requery());
- c.moveToNext();
- cBlob = c.getBlob(bCol);
- assertTrue(Arrays.equals(newblob, cBlob));
- c.close();
- }
-
- @MediumTest
- public void testRealColumns() throws Exception {
- mDatabase.execSQL("CREATE TABLE test (_id INTEGER PRIMARY KEY, data REAL);");
- ContentValues values = new ContentValues();
- values.put("data", 42.11);
- long id = mDatabase.insert("test", "data", values);
- assertTrue(id > 0);
- Cursor c = mDatabase.rawQuery("SELECT data FROM test", null);
- assertNotNull(c);
- assertTrue(c.moveToFirst());
- assertEquals(42.11, c.getDouble(0));
- c.close();
- }
-
- @MediumTest
- public void testCursor1() throws Exception {
- populateDefaultTable();
-
- Cursor c = mDatabase.query("test", null, null, null, null, null, null);
-
- int dataColumn = c.getColumnIndexOrThrow("data");
-
- // The cursor should ignore text before the last period when looking for a column. (This
- // is a temporary hack in all implementations of getColumnIndex.)
- int dataColumn2 = c.getColumnIndexOrThrow("junk.data");
- assertEquals(dataColumn, dataColumn2);
-
- assertSame(3, c.getCount());
-
- assertTrue(c.isBeforeFirst());
-
- try {
- c.getInt(0);
- fail("CursorIndexOutOfBoundsException expected");
- } catch (CursorIndexOutOfBoundsException ex) {
- // expected
- }
-
- c.moveToNext();
- assertEquals(1, c.getInt(0));
-
- String s = c.getString(dataColumn);
- assertEquals(sString1, s);
-
- c.moveToNext();
- s = c.getString(dataColumn);
- assertEquals(sString2, s);
-
- c.moveToNext();
- s = c.getString(dataColumn);
- assertEquals(sString3, s);
-
- c.moveToPosition(-1);
- c.moveToNext();
- s = c.getString(dataColumn);
- assertEquals(sString1, s);
-
- c.moveToPosition(2);
- s = c.getString(dataColumn);
- assertEquals(sString3, s);
-
- int i;
-
- for (c.moveToFirst(), i = 0; !c.isAfterLast(); c.moveToNext(), i++) {
- c.getInt(0);
- }
-
- assertEquals(3, i);
-
- try {
- c.getInt(0);
- fail("CursorIndexOutOfBoundsException expected");
- } catch (CursorIndexOutOfBoundsException ex) {
- // expected
- }
- c.close();
- }
-
- @MediumTest
- public void testCursor2() throws Exception {
- populateDefaultTable();
-
- Cursor c = mDatabase.query("test", null, "_id > 1000", null, null, null, null);
- assertEquals(0, c.getCount());
- assertTrue(c.isBeforeFirst());
-
- try {
- c.getInt(0);
- fail("CursorIndexOutOfBoundsException expected");
- } catch (CursorIndexOutOfBoundsException ex) {
- // expected
- }
-
- int i;
- for (c.moveToFirst(), i = 0; !c.isAfterLast(); c.moveToNext(), i++) {
- c.getInt(0);
- }
- assertEquals(0, i);
- try {
- c.getInt(0);
- fail("CursorIndexOutOfBoundsException expected");
- } catch (CursorIndexOutOfBoundsException ex) {
- // expected
- }
- c.close();
- }
-
- @MediumTest
- public void testLargeField() throws Exception {
- mDatabase.execSQL("CREATE TABLE test (_id INTEGER PRIMARY KEY, data TEXT);");
-
- StringBuilder sql = new StringBuilder(2100);
- sql.append("INSERT INTO test (data) VALUES ('");
- Random random = new Random(System.currentTimeMillis());
- StringBuilder randomString = new StringBuilder(1979);
- for (int i = 0; i < 1979; i++) {
- randomString.append((random.nextInt() & 0xf) % 10);
- }
- sql.append(randomString);
- sql.append("');");
- mDatabase.execSQL(sql.toString());
-
- Cursor c = mDatabase.query("test", null, null, null, null, null, null);
- assertNotNull(c);
- assertEquals(1, c.getCount());
-
- assertTrue(c.moveToFirst());
- assertEquals(0, c.getPosition());
- String largeString = c.getString(c.getColumnIndexOrThrow("data"));
- assertNotNull(largeString);
- assertEquals(randomString.toString(), largeString);
- c.close();
- }
-
- class TestObserver extends DataSetObserver {
- int total;
- SQLiteCursor c;
- boolean quit = false;
- public TestObserver(int total_, SQLiteCursor cursor) {
- c = cursor;
- total = total_;
- }
-
- @Override
- public void onChanged() {
- int count = c.getCount();
- if (total == count) {
- int i = 0;
- while (c.moveToNext()) {
- assertEquals(i, c.getInt(1));
- i++;
- }
- assertEquals(count, i);
- quit = true;
- Looper.myLooper().quit();
- }
- }
-
- @Override
- public void onInvalidated() {
- }
- }
-
- //@Large
- @Suppress
- public void testLoadingThreadDelayRegisterData() throws Exception {
- mDatabase.execSQL("CREATE TABLE test (_id INTEGER PRIMARY KEY, data INT);");
-
- final int count = 505;
- String sql = "INSERT INTO test (data) VALUES (?);";
- SQLiteStatement s = mDatabase.compileStatement(sql);
- for (int i = 0; i < count; i++) {
- s.bindLong(1, i);
- s.execute();
- }
-
- int maxRead = 500;
- int initialRead = 5;
- SQLiteCursor c = (SQLiteCursor)mDatabase.rawQuery("select * from test;",
- null, initialRead, maxRead);
-
- TestObserver observer = new TestObserver(count, c);
- c.getCount();
- c.registerDataSetObserver(observer);
- if (!observer.quit) {
- Looper.loop();
- }
- c.close();
- }
-
- @LargeTest
- public void testLoadingThread() throws Exception {
- mDatabase.execSQL("CREATE TABLE test (_id INTEGER PRIMARY KEY, data INT);");
-
- final int count = 50000;
- String sql = "INSERT INTO test (data) VALUES (?);";
- SQLiteStatement s = mDatabase.compileStatement(sql);
- for (int i = 0; i < count; i++) {
- s.bindLong(1, i);
- s.execute();
- }
-
- int maxRead = 1000;
- int initialRead = 5;
- SQLiteCursor c = (SQLiteCursor)mDatabase.rawQuery("select * from test;",
- null, initialRead, maxRead);
-
- TestObserver observer = new TestObserver(count, c);
- c.registerDataSetObserver(observer);
- c.getCount();
-
- Looper.loop();
- c.close();
- }
-
- @LargeTest
- public void testLoadingThreadClose() throws Exception {
- mDatabase.execSQL("CREATE TABLE test (_id INTEGER PRIMARY KEY, data INT);");
-
- final int count = 1000;
- String sql = "INSERT INTO test (data) VALUES (?);";
- SQLiteStatement s = mDatabase.compileStatement(sql);
- for (int i = 0; i < count; i++) {
- s.bindLong(1, i);
- s.execute();
- }
-
- int maxRead = 11;
- int initialRead = 5;
- SQLiteCursor c = (SQLiteCursor)mDatabase.rawQuery("select * from test;",
- null, initialRead, maxRead);
-
- TestObserver observer = new TestObserver(count, c);
- c.registerDataSetObserver(observer);
- c.getCount();
- c.close();
- }
-
- @LargeTest
- public void testLoadingThreadDeactivate() throws Exception {
- mDatabase.execSQL("CREATE TABLE test (_id INTEGER PRIMARY KEY, data INT);");
-
- final int count = 1000;
- String sql = "INSERT INTO test (data) VALUES (?);";
- SQLiteStatement s = mDatabase.compileStatement(sql);
- for (int i = 0; i < count; i++) {
- s.bindLong(1, i);
- s.execute();
- }
-
- int maxRead = 11;
- int initialRead = 5;
- SQLiteCursor c = (SQLiteCursor)mDatabase.rawQuery("select * from test;",
- null, initialRead, maxRead);
-
- TestObserver observer = new TestObserver(count, c);
- c.registerDataSetObserver(observer);
- c.getCount();
- c.deactivate();
- c.close();
- }
-
- @LargeTest
- public void testManyRowsLong() throws Exception {
- mDatabase.execSQL("CREATE TABLE test (_id INTEGER PRIMARY KEY, data INT);");
-
- final int count = 36799;
- for (int i = 0; i < count; i++) {
- mDatabase.execSQL("INSERT INTO test (data) VALUES (" + i + ");");
- }
-
- Cursor c = mDatabase.query("test", new String[]{"data"}, null, null, null, null, null);
- assertNotNull(c);
-
- int i = 0;
- while (c.moveToNext()) {
- assertEquals(i, c.getInt(0));
- i++;
- }
- assertEquals(count, i);
- assertEquals(count, c.getCount());
-
- Log.d("testManyRows", "count " + Integer.toString(i));
- c.close();
- }
-
- @LargeTest
- public void testManyRowsTxt() throws Exception {
- mDatabase.execSQL("CREATE TABLE test (_id INTEGER PRIMARY KEY, data TEXT);");
- StringBuilder sql = new StringBuilder(2100);
- sql.append("INSERT INTO test (data) VALUES ('");
- Random random = new Random(System.currentTimeMillis());
- StringBuilder randomString = new StringBuilder(1979);
- for (int i = 0; i < 1979; i++) {
- randomString.append((random.nextInt() & 0xf) % 10);
- }
- sql.append(randomString);
- sql.append("');");
-
- // if cursor window size changed, adjust this value too
- final int count = 600; // more than two fillWindow needed
- for (int i = 0; i < count; i++) {
- mDatabase.execSQL(sql.toString());
- }
-
- Cursor c = mDatabase.query("test", new String[]{"data"}, null, null, null, null, null);
- assertNotNull(c);
-
- int i = 0;
- while (c.moveToNext()) {
- assertEquals(randomString.toString(), c.getString(0));
- i++;
- }
- assertEquals(count, i);
- assertEquals(count, c.getCount());
- c.close();
- }
-
- @LargeTest
- public void testManyRowsTxtLong() throws Exception {
- mDatabase.execSQL("CREATE TABLE test (_id INTEGER PRIMARY KEY, txt TEXT, data INT);");
-
- Random random = new Random(System.currentTimeMillis());
- StringBuilder randomString = new StringBuilder(1979);
- for (int i = 0; i < 1979; i++) {
- randomString.append((random.nextInt() & 0xf) % 10);
- }
-
- // if cursor window size changed, adjust this value too
- final int count = 600;
- for (int i = 0; i < count; i++) {
- StringBuilder sql = new StringBuilder(2100);
- sql.append("INSERT INTO test (txt, data) VALUES ('");
- sql.append(randomString);
- sql.append("','");
- sql.append(i);
- sql.append("');");
- mDatabase.execSQL(sql.toString());
- }
-
- Cursor c = mDatabase.query("test", new String[]{"txt", "data"}, null, null, null, null, null);
- assertNotNull(c);
-
- int i = 0;
- while (c.moveToNext()) {
- assertEquals(randomString.toString(), c.getString(0));
- assertEquals(i, c.getInt(1));
- i++;
- }
- assertEquals(count, i);
- assertEquals(count, c.getCount());
- c.close();
- }
-
- @MediumTest
- public void testRequery() throws Exception {
- populateDefaultTable();
-
- Cursor c = mDatabase.rawQuery("SELECT * FROM test", null);
- assertNotNull(c);
- assertEquals(3, c.getCount());
- c.deactivate();
- c.requery();
- assertEquals(3, c.getCount());
- c.close();
- }
-
- @MediumTest
- public void testRequeryWithSelection() throws Exception {
- populateDefaultTable();
-
- Cursor c = mDatabase.rawQuery("SELECT data FROM test WHERE data = '" + sString1 + "'",
- null);
- assertNotNull(c);
- assertEquals(1, c.getCount());
- assertTrue(c.moveToFirst());
- assertEquals(sString1, c.getString(0));
- c.deactivate();
- c.requery();
- assertEquals(1, c.getCount());
- assertTrue(c.moveToFirst());
- assertEquals(sString1, c.getString(0));
- c.close();
- }
-
- @MediumTest
- public void testRequeryWithSelectionArgs() throws Exception {
- populateDefaultTable();
-
- Cursor c = mDatabase.rawQuery("SELECT data FROM test WHERE data = ?",
- new String[]{sString1});
- assertNotNull(c);
- assertEquals(1, c.getCount());
- assertTrue(c.moveToFirst());
- assertEquals(sString1, c.getString(0));
- c.deactivate();
- c.requery();
- assertEquals(1, c.getCount());
- assertTrue(c.moveToFirst());
- assertEquals(sString1, c.getString(0));
- c.close();
- }
-
- @MediumTest
- public void testRequeryWithAlteredSelectionArgs() throws Exception {
- /**
- * Test the ability of a subclass of SQLiteCursor to change its query arguments.
- */
- populateDefaultTable();
-
- SQLiteDatabase.CursorFactory factory = new SQLiteDatabase.CursorFactory() {
- public Cursor newCursor(
- SQLiteDatabase db, SQLiteCursorDriver masterQuery, String editTable,
- SQLiteQuery query) {
- return new SQLiteCursor(db, masterQuery, editTable, query) {
- @Override
- public boolean requery() {
- setSelectionArguments(new String[]{"2"});
- return super.requery();
- }
- };
- }
- };
- Cursor c = mDatabase.rawQueryWithFactory(
- factory, "SELECT data FROM test WHERE _id <= ?", new String[]{"1"},
- null);
- assertNotNull(c);
- assertEquals(1, c.getCount());
- assertTrue(c.moveToFirst());
- assertEquals(sString1, c.getString(0));
-
- // Our hacked requery() changes the query arguments in the cursor.
- c.requery();
-
- assertEquals(2, c.getCount());
- assertTrue(c.moveToFirst());
- assertEquals(sString1, c.getString(0));
- assertTrue(c.moveToNext());
- assertEquals(sString2, c.getString(0));
-
- // Test that setting query args on a deactivated cursor also works.
- c.deactivate();
- c.requery();
- }
-}
diff --git a/tests/AndroidTests/src/com/android/unit_tests/DatabaseStatementTest.java b/tests/AndroidTests/src/com/android/unit_tests/DatabaseStatementTest.java
deleted file mode 100644
index 16ca59f51b83..000000000000
--- a/tests/AndroidTests/src/com/android/unit_tests/DatabaseStatementTest.java
+++ /dev/null
@@ -1,320 +0,0 @@
-/*
- * Copyright (C) 2007 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 com.android.unit_tests;
-
-import android.database.Cursor;
-import android.database.sqlite.SQLiteConstraintException;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteDoneException;
-import android.database.sqlite.SQLiteStatement;
-import android.test.PerformanceTestCase;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.test.suitebuilder.annotation.SmallTest;
-import junit.framework.TestCase;
-
-import java.io.File;
-
-public class DatabaseStatementTest extends TestCase implements PerformanceTestCase {
-
- private static final String sString1 = "this is a test";
- private static final String sString2 = "and yet another test";
- private static final String sString3 = "this string is a little longer, but still a test";
-
- private static final int CURRENT_DATABASE_VERSION = 42;
- private SQLiteDatabase mDatabase;
- private File mDatabaseFile;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- mDatabaseFile = new File("/sqlite_stmt_journals", "database_test.db");
- if (mDatabaseFile.exists()) {
- mDatabaseFile.delete();
- }
- mDatabase = SQLiteDatabase.openOrCreateDatabase(mDatabaseFile.getPath(), null);
- assertNotNull(mDatabase);
- mDatabase.setVersion(CURRENT_DATABASE_VERSION);
- }
-
- @Override
- protected void tearDown() throws Exception {
- mDatabase.close();
- mDatabaseFile.delete();
- super.tearDown();
- }
-
- public boolean isPerformanceOnly() {
- return false;
- }
-
- // These test can only be run once.
- public int startPerformance(Intermediates intermediates) {
- return 1;
- }
-
- private void populateDefaultTable() {
- mDatabase.execSQL("CREATE TABLE test (_id INTEGER PRIMARY KEY, data TEXT);");
-
- mDatabase.execSQL("INSERT INTO test (data) VALUES ('" + sString1 + "');");
- mDatabase.execSQL("INSERT INTO test (data) VALUES ('" + sString2 + "');");
- mDatabase.execSQL("INSERT INTO test (data) VALUES ('" + sString3 + "');");
- }
-
- @MediumTest
- public void testExecuteStatement() throws Exception {
- populateDefaultTable();
- SQLiteStatement statement = mDatabase.compileStatement("DELETE FROM test");
- statement.execute();
-
- Cursor c = mDatabase.query("test", null, null, null, null, null, null);
- assertEquals(0, c.getCount());
- c.deactivate();
- statement.close();
- }
-
- @MediumTest
- public void testSimpleQuery() throws Exception {
- mDatabase.execSQL("CREATE TABLE test (num INTEGER NOT NULL, str TEXT NOT NULL);");
- mDatabase.execSQL("INSERT INTO test VALUES (1234, 'hello');");
- SQLiteStatement statement1 =
- mDatabase.compileStatement("SELECT num FROM test WHERE str = ?");
- SQLiteStatement statement2 =
- mDatabase.compileStatement("SELECT str FROM test WHERE num = ?");
-
- try {
- statement1.bindString(1, "hello");
- long value = statement1.simpleQueryForLong();
- assertEquals(1234, value);
-
- statement1.bindString(1, "world");
- statement1.simpleQueryForLong();
- fail("shouldn't get here");
- } catch (SQLiteDoneException e) {
- // expected
- }
-
- try {
- statement2.bindLong(1, 1234);
- String value = statement1.simpleQueryForString();
- assertEquals("hello", value);
-
- statement2.bindLong(1, 5678);
- statement1.simpleQueryForString();
- fail("shouldn't get here");
- } catch (SQLiteDoneException e) {
- // expected
- }
-
- statement1.close();
- statement2.close();
- }
-
- @MediumTest
- public void testStatementLongBinding() throws Exception {
- mDatabase.execSQL("CREATE TABLE test (num INTEGER);");
- SQLiteStatement statement = mDatabase.compileStatement("INSERT INTO test (num) VALUES (?)");
-
- for (int i = 0; i < 10; i++) {
- statement.bindLong(1, i);
- statement.execute();
- }
- statement.close();
-
- Cursor c = mDatabase.query("test", null, null, null, null, null, null);
- int numCol = c.getColumnIndexOrThrow("num");
- c.moveToFirst();
- for (long i = 0; i < 10; i++) {
- long num = c.getLong(numCol);
- assertEquals(i, num);
- c.moveToNext();
- }
- c.close();
- }
-
- @MediumTest
- public void testStatementStringBinding() throws Exception {
- mDatabase.execSQL("CREATE TABLE test (num TEXT);");
- SQLiteStatement statement = mDatabase.compileStatement("INSERT INTO test (num) VALUES (?)");
-
- for (long i = 0; i < 10; i++) {
- statement.bindString(1, Long.toHexString(i));
- statement.execute();
- }
- statement.close();
-
- Cursor c = mDatabase.query("test", null, null, null, null, null, null);
- int numCol = c.getColumnIndexOrThrow("num");
- c.moveToFirst();
- for (long i = 0; i < 10; i++) {
- String num = c.getString(numCol);
- assertEquals(Long.toHexString(i), num);
- c.moveToNext();
- }
- c.close();
- }
-
- @MediumTest
- public void testStatementClearBindings() throws Exception {
- mDatabase.execSQL("CREATE TABLE test (num INTEGER);");
- SQLiteStatement statement = mDatabase.compileStatement("INSERT INTO test (num) VALUES (?)");
-
- for (long i = 0; i < 10; i++) {
- statement.bindLong(1, i);
- statement.clearBindings();
- statement.execute();
- }
- statement.close();
-
- Cursor c = mDatabase.query("test", null, null, null, null, null, "ROWID");
- int numCol = c.getColumnIndexOrThrow("num");
- assertTrue(c.moveToFirst());
- for (long i = 0; i < 10; i++) {
- assertTrue(c.isNull(numCol));
- c.moveToNext();
- }
- c.close();
- }
-
- @MediumTest
- public void testSimpleStringBinding() throws Exception {
- mDatabase.execSQL("CREATE TABLE test (num TEXT, value TEXT);");
- String statement = "INSERT INTO test (num, value) VALUES (?,?)";
-
- String[] args = new String[2];
- for (int i = 0; i < 2; i++) {
- args[i] = Integer.toHexString(i);
- }
-
- mDatabase.execSQL(statement, args);
-
- Cursor c = mDatabase.query("test", null, null, null, null, null, null);
- int numCol = c.getColumnIndexOrThrow("num");
- int valCol = c.getColumnIndexOrThrow("value");
- c.moveToFirst();
- String num = c.getString(numCol);
- assertEquals(Integer.toHexString(0), num);
-
- String val = c.getString(valCol);
- assertEquals(Integer.toHexString(1), val);
- c.close();
- }
-
- @MediumTest
- public void testStatementMultipleBindings() throws Exception {
- mDatabase.execSQL("CREATE TABLE test (num INTEGER, str TEXT);");
- SQLiteStatement statement =
- mDatabase.compileStatement("INSERT INTO test (num, str) VALUES (?, ?)");
-
- for (long i = 0; i < 10; i++) {
- statement.bindLong(1, i);
- statement.bindString(2, Long.toHexString(i));
- statement.execute();
- }
- statement.close();
-
- Cursor c = mDatabase.query("test", null, null, null, null, null, "ROWID");
- int numCol = c.getColumnIndexOrThrow("num");
- int strCol = c.getColumnIndexOrThrow("str");
- assertTrue(c.moveToFirst());
- for (long i = 0; i < 10; i++) {
- long num = c.getLong(numCol);
- String str = c.getString(strCol);
- assertEquals(i, num);
- assertEquals(Long.toHexString(i), str);
- c.moveToNext();
- }
- c.close();
- }
-
- private static class StatementTestThread extends Thread {
- private SQLiteDatabase mDatabase;
- private SQLiteStatement mStatement;
-
- public StatementTestThread(SQLiteDatabase db, SQLiteStatement statement) {
- super();
- mDatabase = db;
- mStatement = statement;
- }
-
- @Override
- public void run() {
- mDatabase.beginTransaction();
- for (long i = 0; i < 10; i++) {
- mStatement.bindLong(1, i);
- mStatement.bindString(2, Long.toHexString(i));
- mStatement.execute();
- }
- mDatabase.setTransactionSuccessful();
- mDatabase.endTransaction();
-
- Cursor c = mDatabase.query("test", null, null, null, null, null, "ROWID");
- int numCol = c.getColumnIndexOrThrow("num");
- int strCol = c.getColumnIndexOrThrow("str");
- assertTrue(c.moveToFirst());
- for (long i = 0; i < 10; i++) {
- long num = c.getLong(numCol);
- String str = c.getString(strCol);
- assertEquals(i, num);
- assertEquals(Long.toHexString(i), str);
- c.moveToNext();
- }
- c.close();
- }
- }
-
- @MediumTest
- public void testStatementMultiThreaded() throws Exception {
- mDatabase.execSQL("CREATE TABLE test (num INTEGER, str TEXT);");
- SQLiteStatement statement =
- mDatabase.compileStatement("INSERT INTO test (num, str) VALUES (?, ?)");
-
- StatementTestThread thread = new StatementTestThread(mDatabase, statement);
- thread.start();
- try {
- thread.join();
- } finally {
- statement.close();
- }
- }
-
- @MediumTest
- public void testStatementConstraint() throws Exception {
- mDatabase.execSQL("CREATE TABLE test (num INTEGER NOT NULL);");
- SQLiteStatement statement = mDatabase.compileStatement("INSERT INTO test (num) VALUES (?)");
-
- // Try to insert NULL, which violates the constraint
- try {
- statement.clearBindings();
- statement.execute();
- fail("expected exception not thrown");
- } catch (SQLiteConstraintException e) {
- // expected
- }
-
- // Make sure the statement can still be used
- statement.bindLong(1, 1);
- statement.execute();
- statement.close();
-
- Cursor c = mDatabase.query("test", null, null, null, null, null, null);
- int numCol = c.getColumnIndexOrThrow("num");
- c.moveToFirst();
- long num = c.getLong(numCol);
- assertEquals(1, num);
- c.close();
- }
-}
diff --git a/tests/AndroidTests/src/com/android/unit_tests/DatabaseTests.java b/tests/AndroidTests/src/com/android/unit_tests/DatabaseTests.java
index a7a1400341dc..a288c73facdd 100644
--- a/tests/AndroidTests/src/com/android/unit_tests/DatabaseTests.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/DatabaseTests.java
@@ -23,8 +23,6 @@ public class DatabaseTests {
TestSuite suite = new TestSuite(DatabaseTests.class.getName());
suite.addTestSuite(DatabaseGeneralTest.class);
- suite.addTestSuite(DatabaseCursorTest.class);
- suite.addTestSuite(DatabaseStatementTest.class);
suite.addTestSuite(DatabaseLocaleTest.class);
suite.addTestSuite(CursorWindowTest.class);
suite.addTestSuite(DatabaseLockTest.class);
diff --git a/tests/AndroidTests/src/com/android/unit_tests/NeighboringCellInfoTest.java b/tests/AndroidTests/src/com/android/unit_tests/NeighboringCellInfoTest.java
deleted file mode 100644
index 7252aa95fabf..000000000000
--- a/tests/AndroidTests/src/com/android/unit_tests/NeighboringCellInfoTest.java
+++ /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.
- */
-package com.android.unit_tests;
-
-import android.os.Parcel;
-import android.test.AndroidTestCase;
-import android.telephony.NeighboringCellInfo;
-import android.test. suitebuilder.annotation.SmallTest;
-
-import static android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN;
-import static android.telephony.TelephonyManager.NETWORK_TYPE_EDGE;
-import static android.telephony.TelephonyManager.NETWORK_TYPE_GPRS;
-import static android.telephony.TelephonyManager.NETWORK_TYPE_UMTS;
-
-public class NeighboringCellInfoTest extends AndroidTestCase {
- @SmallTest
- public void testConstructor() {
- int rssi = 31;
- NeighboringCellInfo nc;
-
- nc = new NeighboringCellInfo(rssi, "FFFFFFF", NETWORK_TYPE_EDGE);
- assertEquals(NETWORK_TYPE_EDGE, nc.getNetworkType());
- assertEquals(rssi, nc.getRssi());
- assertEquals(0xfff, nc.getLac());
- assertEquals(0xffff, nc.getCid());
- assertEquals(NeighboringCellInfo.UNKNOWN_CID, nc.getPsc());
-
- nc = new NeighboringCellInfo(rssi, "1FF", NETWORK_TYPE_UMTS);
- assertEquals(NETWORK_TYPE_UMTS, nc.getNetworkType());
- assertEquals(rssi, nc.getRssi());
- assertEquals(NeighboringCellInfo.UNKNOWN_CID, nc.getCid());
- assertEquals(NeighboringCellInfo.UNKNOWN_CID, nc.getLac());
- assertEquals(0x1ff, nc.getPsc());
-
- nc = new NeighboringCellInfo(rssi, "1FF", NETWORK_TYPE_UNKNOWN);
- assertEquals(NETWORK_TYPE_UNKNOWN, nc.getNetworkType());
- assertEquals(rssi, nc.getRssi());
- assertEquals(NeighboringCellInfo.UNKNOWN_CID, nc.getCid());
- assertEquals(NeighboringCellInfo.UNKNOWN_CID, nc.getLac());
- assertEquals(NeighboringCellInfo.UNKNOWN_CID, nc.getPsc());
- }
-
- @SmallTest
- public void testParcel() {
- int rssi = 20;
-
- NeighboringCellInfo nc = new NeighboringCellInfo(rssi, "12345678", NETWORK_TYPE_GPRS);
- assertEquals(NETWORK_TYPE_GPRS, nc.getNetworkType());
- assertEquals(rssi, nc.getRssi());
- assertEquals(0x1234, nc.getLac());
- assertEquals(0x5678, nc.getCid());
- assertEquals(NeighboringCellInfo.UNKNOWN_CID, nc.getPsc());
-
- Parcel p = Parcel.obtain();
- p.setDataPosition(0);
- nc.writeToParcel(p, 0);
-
- p.setDataPosition(0);
- NeighboringCellInfo nw = new NeighboringCellInfo(p);
- assertEquals(NETWORK_TYPE_GPRS, nw.getNetworkType());
- assertEquals(rssi, nw.getRssi());
- assertEquals(0x1234, nw.getLac());
- assertEquals(0x5678, nw.getCid());
- assertEquals(NeighboringCellInfo.UNKNOWN_CID, nw.getPsc());
- }
-}
diff --git a/tests/AndroidTests/src/com/android/unit_tests/content/ArrayTest.java b/tests/AndroidTests/src/com/android/unit_tests/content/ArrayTest.java
deleted file mode 100644
index 4d5b5e778041..000000000000
--- a/tests/AndroidTests/src/com/android/unit_tests/content/ArrayTest.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2007 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 com.android.unit_tests.content;
-
-import android.content.res.Resources;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.util.TypedValue;
-import com.android.unit_tests.R;
-
-public class ArrayTest extends AndroidTestCase {
- private Resources mResources;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- mResources = mContext.getResources();
- }
-
- private void checkEntry(int resid, int index, Object res, Object expected) {
- assertEquals("in resource 0x" + Integer.toHexString(resid)
- + " at index " + index, expected, res);
- }
-
- private void checkStringArray(int resid, String[] expected) {
- String[] res = mResources.getStringArray(resid);
- assertEquals(res.length, expected.length);
- for (int i=0; i<expected.length; i++) {
- checkEntry(resid, i, res[i], expected[i]);
- }
- }
-
- private void checkTextArray(int resid, String[] expected) {
- CharSequence[] res = mResources.getTextArray(resid);
- assertEquals(res.length, expected.length);
- for (int i=0; i<expected.length; i++) {
- checkEntry(resid, i, res[i], expected[i]);
- }
- }
-
- private void checkIntArray(int resid, int[] expected) {
- int[] res = mResources.getIntArray(resid);
- assertEquals(res.length, expected.length);
- for (int i=0; i<expected.length; i++) {
- assertEquals("in resource 0x" + Integer.toHexString(resid)
- + " at index " + i, expected[i], res[i]);
- }
- }
-
- @SmallTest
- public void testStrings() throws Exception {
- checkStringArray(R.array.strings, new String[] {"zero", "1", "here"});
- checkTextArray(R.array.strings, new String[] {"zero", "1", "here"});
- checkStringArray(R.array.integers, new String[] {null, null, null});
- checkTextArray(R.array.integers, new String[] {null, null, null});
- }
-
- @SmallTest
- public void testIntegers() throws Exception {
- checkIntArray(R.array.strings, new int[] {0, 0, 0});
- checkIntArray(R.array.integers, new int[] {0, 1, 101});
- }
-}
diff --git a/tests/AndroidTests/src/com/android/unit_tests/content/ConfigTest.java b/tests/AndroidTests/src/com/android/unit_tests/content/ConfigTest.java
deleted file mode 100644
index a065d7016af0..000000000000
--- a/tests/AndroidTests/src/com/android/unit_tests/content/ConfigTest.java
+++ /dev/null
@@ -1,540 +0,0 @@
-/*
- * Copyright (C) 2007 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 com.android.unit_tests.content;
-
-import android.content.Context;
-import android.content.res.AssetManager;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.util.DisplayMetrics;
-import android.view.Display;
-import android.view.WindowManager;
-import com.android.unit_tests.R;
-
-import java.util.Locale;
-
-public class ConfigTest extends AndroidTestCase {
- enum properties {
- LANGUAGE,
- COUNTRY,
- MCC,
- MNC,
- TOUCHSCREEN,
- KEYBOARD,
- KEYBOARDHIDDEN,
- NAVIGATION,
- ORIENTATION,
- WIDTH,
- HEIGHT,
- DENSITY
- }
-
- private static void checkValue(Resources res, int resId, String expectedValue) {
- try {
- String actual = res.getString(resId);
- assertNotNull("Returned wrong configuration-based simple value: expected <nothing>, got '"
- + actual + "' from resource 0x"
- + Integer.toHexString(resId),
- expectedValue);
- assertEquals("Returned wrong configuration-based simple value: expected '"
- + expectedValue + "', got '" + actual + "' from resource 0x"
- + Integer.toHexString(resId),
- expectedValue, actual);
- } catch (Resources.NotFoundException e) {
- assertNull("Resource not found for configuration-based simple value: expecting \""
- + expectedValue + "\"",
- expectedValue);
- }
- }
-
- private static void checkValue(Resources res, int resId,
- int[] styleable, String[] expectedValues) {
- Resources.Theme theme = res.newTheme();
- TypedArray sa = theme.obtainStyledAttributes(resId, styleable);
- for (int i = 0; i < styleable.length; i++) {
- String actual = sa.getString(i);
- assertEquals("Returned wrong configuration-based style value: expected '"
- + expectedValues[i] + "', got '" + actual + "' from attr "
- + i + " of resource 0x" + Integer.toHexString(resId),
- actual, expectedValues[i]);
- }
- sa.recycle();
- }
-
- class TotalConfig {
- Configuration mConfig;
- DisplayMetrics mMetrics;
-
- TotalConfig() {
- mConfig = new Configuration();
- // don't rely on build settings - they may change
- mConfig.locale = new Locale("en", "US");
- mConfig.mcc = 310;
- mConfig.mnc = 001; // unused
- mConfig.touchscreen = Configuration.TOUCHSCREEN_FINGER;
- mConfig.keyboard = Configuration.KEYBOARD_QWERTY;
- mConfig.keyboardHidden = Configuration.KEYBOARDHIDDEN_YES;
- mConfig.navigation = Configuration.NAVIGATION_TRACKBALL;
- mConfig.orientation = Configuration.ORIENTATION_PORTRAIT;
-
- mMetrics = new DisplayMetrics();
- mMetrics.widthPixels = 200;
- mMetrics.heightPixels = 320;
- mMetrics.density = 1;
- }
-
- void setProperty(properties p, int value) {
- switch(p) {
- case MCC:
- mConfig.mcc = value;
- break;
- case MNC:
- mConfig.mnc = value;
- break;
- case TOUCHSCREEN:
- mConfig.touchscreen = value;
- break;
- case KEYBOARD:
- mConfig.keyboard = value;
- break;
- case KEYBOARDHIDDEN:
- mConfig.keyboardHidden = value;
- break;
- case NAVIGATION:
- mConfig.navigation = value;
- break;
- case ORIENTATION:
- mConfig.orientation = value;
- break;
- case WIDTH:
- mMetrics.widthPixels = value;
- break;
- case HEIGHT:
- mMetrics.heightPixels = value;
- break;
- case DENSITY:
- // this is the ratio from the standard
-
- mMetrics.density = (((float)value)/((float)DisplayMetrics.DENSITY_DEFAULT));
- break;
- default:
- assert(false);
- break;
- }
- }
-
- public void setProperty(properties p, String value) {
- switch(p) {
- case LANGUAGE:
- String oldCountry = mConfig.locale.getCountry();
- mConfig.locale = new Locale(value, oldCountry);
- break;
- case COUNTRY:
- String oldLanguage = mConfig.locale.getLanguage();
- mConfig.locale = new Locale(oldLanguage, value);
- break;
- default:
- assert(false);
- break;
- }
- }
-
- public Resources getResources() {
- AssetManager assmgr = new AssetManager();
- assmgr.addAssetPath(mContext.getPackageResourcePath());
- return new Resources(assmgr, mMetrics, mConfig);
- }
- }
-
- private static void checkPair(Resources res, int[] notResIds,
- int simpleRes, String simpleString,
- int bagRes, String bagString) {
- boolean willHave = true;
- if (notResIds != null) {
- for (int i : notResIds) {
- if (i == simpleRes) {
- willHave = false;
- break;
- }
- }
- }
- checkValue(res, simpleRes, willHave ? simpleString : null);
- checkValue(res, bagRes, R.styleable.TestConfig,
- new String[]{willHave ? bagString : null});
- }
-
- @SmallTest
- public void testAllConfigs() throws Exception {
- /**
- * Test a resource that contains a value for each possible single
- * configuration value.
- */
- TotalConfig config = new TotalConfig();
- Resources res = config.getResources();
- checkValue(res, R.configVarying.simple, "simple default");
- checkValue(res, R.configVarying.bag,
- R.styleable.TestConfig, new String[]{"bag default"});
-
- config = new TotalConfig();
- config.setProperty(properties.LANGUAGE, "xx");
- res = config.getResources();
- checkValue(res, R.configVarying.simple, "simple xx");
- checkValue(res, R.configVarying.bag,
- R.styleable.TestConfig, new String[]{"bag xx"});
-
- config = new TotalConfig();
- config.setProperty(properties.LANGUAGE, "xx");
- config.setProperty(properties.COUNTRY, "YY");
- res = config.getResources();
- checkValue(res, R.configVarying.simple, "simple xx-rYY");
- checkValue(res, R.configVarying.bag,
- R.styleable.TestConfig, new String[]{"bag xx-rYY"});
-
- config = new TotalConfig();
- config.setProperty(properties.MCC, 111);
- res = config.getResources();
- checkValue(res, R.configVarying.simple, "simple mcc111");
- checkValue(res, R.configVarying.bag,
- R.styleable.TestConfig, new String[]{"bag mcc111"});
-
- config = new TotalConfig();
- config.setProperty(properties.MNC, 222);
- res = config.getResources();
- checkValue(res, R.configVarying.simple, "simple mnc222");
- checkValue(res, R.configVarying.bag,
- R.styleable.TestConfig, new String[]{"bag mnc222"});
-
- config = new TotalConfig();
- config.setProperty(properties.TOUCHSCREEN, Configuration.TOUCHSCREEN_NOTOUCH);
- res = config.getResources();
- checkValue(res, R.configVarying.simple, "simple notouch");
- checkValue(res, R.configVarying.bag,
- R.styleable.TestConfig, new String[]{"bag notouch"});
-
- config = new TotalConfig();
- config.setProperty(properties.TOUCHSCREEN, Configuration.TOUCHSCREEN_STYLUS);
- res = config.getResources();
- checkValue(res, R.configVarying.simple, "simple stylus");
- checkValue(res, R.configVarying.bag,
- R.styleable.TestConfig, new String[]{"bag stylus"});
-
- config = new TotalConfig();
- config.setProperty(properties.KEYBOARD, Configuration.KEYBOARD_NOKEYS);
- res = config.getResources();
- checkValue(res, R.configVarying.simple, "simple nokeys");
- checkValue(res, R.configVarying.bag,
- R.styleable.TestConfig, new String[]{"bag nokeys"});
-
- config = new TotalConfig();
- config.setProperty(properties.KEYBOARD, Configuration.KEYBOARD_12KEY);
- res = config.getResources();
- checkValue(res, R.configVarying.simple, "simple 12key");
- checkValue(res, R.configVarying.bag,
- R.styleable.TestConfig, new String[]{"bag 12key"});
-
- config = new TotalConfig();
- config.setProperty(properties.KEYBOARDHIDDEN, Configuration.KEYBOARDHIDDEN_NO);
- res = config.getResources();
- checkValue(res, R.configVarying.simple, "simple keysexposed");
- checkValue(res, R.configVarying.bag,
- R.styleable.TestConfig, new String[]{"bag keysexposed"});
-
- config = new TotalConfig();
- config.setProperty(properties.NAVIGATION, Configuration.NAVIGATION_NONAV);
- res = config.getResources();
- checkValue(res, R.configVarying.simple, "simple nonav");
- checkValue(res, R.configVarying.bag,
- R.styleable.TestConfig, new String[]{"bag nonav"});
-
- config = new TotalConfig();
- config.setProperty(properties.NAVIGATION, Configuration.NAVIGATION_DPAD);
- res = config.getResources();
- checkValue(res, R.configVarying.simple, "simple dpad");
- checkValue(res, R.configVarying.bag,
- R.styleable.TestConfig, new String[]{"bag dpad"});
-
- config = new TotalConfig();
- config.setProperty(properties.NAVIGATION, Configuration.NAVIGATION_WHEEL);
- res = config.getResources();
- checkValue(res, R.configVarying.simple, "simple wheel");
- checkValue(res, R.configVarying.bag,
- R.styleable.TestConfig, new String[]{"bag wheel"});
-
- config = new TotalConfig();
- config.setProperty(properties.HEIGHT, 480);
- config.setProperty(properties.WIDTH, 320);
- res = config.getResources();
- checkValue(res, R.configVarying.simple, "simple 480x320");
- checkValue(res, R.configVarying.bag,
- R.styleable.TestConfig, new String[]{"bag 480x320"});
-
- config = new TotalConfig();
- config.setProperty(properties.DENSITY, 240);
- res = config.getResources();
- checkValue(res, R.configVarying.simple, "simple 240dpi");
- checkValue(res, R.configVarying.bag,
- R.styleable.TestConfig, new String[]{"bag 240dpi"});
-
- config = new TotalConfig();
- config.setProperty(properties.ORIENTATION, Configuration.ORIENTATION_LANDSCAPE);
- res = config.getResources();
- checkValue(res, R.configVarying.simple, "simple landscape");
- checkValue(res, R.configVarying.bag,
- R.styleable.TestConfig, new String[]{"bag landscape"});
-
- config = new TotalConfig();
- config.setProperty(properties.ORIENTATION, Configuration.ORIENTATION_SQUARE);
- res = config.getResources();
- checkValue(res, R.configVarying.simple, "simple square");
- checkValue(res, R.configVarying.bag,
- R.styleable.TestConfig, new String[]{"bag square"});
- }
-
- @MediumTest
- public void testDensity() throws Exception {
- // have 32, 240 and the default 160 content.
- // rule is that closest wins, with down scaling (larger content)
- // being twice as nice as upscaling.
- // transition at H/2 * (-1 +/- sqrt(1+8L/H))
- // SO, X < 49 goes to 32
- // 49 >= X < 182 goes to 160
- // X >= 182 goes to 240
- TotalConfig config = new TotalConfig();
- config.setProperty(properties.DENSITY, 2);
- Resources res = config.getResources();
- checkValue(res, R.configVarying.simple, "simple 32dpi");
- checkValue(res, R.configVarying.bag,
- R.styleable.TestConfig, new String[]{"bag 32dpi"});
-
- config = new TotalConfig();
- config.setProperty(properties.DENSITY, 32);
- res = config.getResources();
- checkValue(res, R.configVarying.simple, "simple 32dpi");
- checkValue(res, R.configVarying.bag,
- R.styleable.TestConfig, new String[]{"bag 32dpi"});
-
- config = new TotalConfig();
- config.setProperty(properties.DENSITY, 48);
- res = config.getResources();
- checkValue(res, R.configVarying.simple, "simple 32dpi");
- checkValue(res, R.configVarying.bag,
- R.styleable.TestConfig, new String[]{"bag 32dpi"});
-
- config = new TotalConfig();
- config.setProperty(properties.DENSITY, 49);
- res = config.getResources();
- checkValue(res, R.configVarying.simple, "simple default");
- checkValue(res, R.configVarying.bag,
- R.styleable.TestConfig, new String[]{"bag default"});
-
- config = new TotalConfig();
- config.setProperty(properties.DENSITY, 150);
- res = config.getResources();
- checkValue(res, R.configVarying.simple, "simple default");
- checkValue(res, R.configVarying.bag,
- R.styleable.TestConfig, new String[]{"bag default"});
-
- config = new TotalConfig();
- config.setProperty(properties.DENSITY, 181);
- res = config.getResources();
- checkValue(res, R.configVarying.simple, "simple default");
- checkValue(res, R.configVarying.bag,
- R.styleable.TestConfig, new String[]{"bag default"});
-
- config = new TotalConfig();
- config.setProperty(properties.DENSITY, 182);
- res = config.getResources();
- checkValue(res, R.configVarying.simple, "simple 240dpi");
- checkValue(res, R.configVarying.bag,
- R.styleable.TestConfig, new String[]{"bag 240dpi"});
-
- config = new TotalConfig();
- config.setProperty(properties.DENSITY, 239);
- res = config.getResources();
- checkValue(res, R.configVarying.simple, "simple 240dpi");
- checkValue(res, R.configVarying.bag,
- R.styleable.TestConfig, new String[]{"bag 240dpi"});
-
- config = new TotalConfig();
- config.setProperty(properties.DENSITY, 490);
- res = config.getResources();
- checkValue(res, R.configVarying.simple, "simple 240dpi");
- checkValue(res, R.configVarying.bag,
- R.styleable.TestConfig, new String[]{"bag 240dpi"});
- }
-
-// TODO - add tests for special cases - ie, other key params seem ignored if
-// nokeys is set
-
- @MediumTest
- public void testCombinations() throws Exception {
- /**
- * Verify that proper strings are found for multiple-selectivity case
- * (ie, a string set for locale and mcc is found only when both are
- * true).
- */
- TotalConfig config = new TotalConfig();
- config.setProperty(properties.LANGUAGE, "xx");
- config.setProperty(properties.COUNTRY, "YY");
- config.setProperty(properties.MCC, 111);
- Resources res = config.getResources();
- checkValue(res, R.configVarying.simple, "simple mcc111 xx-rYY");
- checkValue(res, R.configVarying.bag,
- R.styleable.TestConfig, new String[]{"bag mcc111 xx-rYY"});
-
- config = new TotalConfig();
- config.setProperty(properties.LANGUAGE, "xx");
- config.setProperty(properties.COUNTRY, "YY");
- config.setProperty(properties.MCC, 333);
- res = config.getResources();
- checkValue(res, R.configVarying.simple, "simple xx-rYY");
- checkValue(res, R.configVarying.bag,
- R.styleable.TestConfig, new String[]{"bag xx-rYY"});
-
- config = new TotalConfig();
- config.setProperty(properties.MNC, 333);
- res = config.getResources();
- checkValue(res, R.configVarying.simple, "simple default");
- checkValue(res, R.configVarying.bag,
- R.styleable.TestConfig, new String[]{"bag default"});
- }
-
- @MediumTest
- public void testPrecidence() throws Exception {
- /**
- * Verify that in cases of ties, the specific ordering is followed
- */
-
- /**
- * Precidence order: mcc, mnc, locale, orientation, density,
- * touchscreen, hidden, keyboard, navigation, width-height
- */
-
- /**
- * verify mcc trumps mnc. Have 110-xx, 220-xx but no 110-220
- * so with is selected? Should be mcc110-xx.
- */
- TotalConfig config = new TotalConfig();
- config.setProperty(properties.MCC, 110);
- config.setProperty(properties.MNC, 220);
- config.setProperty(properties.LANGUAGE, "xx");
- Resources res = config.getResources();
- checkValue(res, R.configVarying.simple, "simple mcc110 xx");
- checkValue(res, R.configVarying.bag,
- R.styleable.TestConfig, new String[]{"bag mcc110 xx"});
-
- /* full A + B + C doesn't exist. Do we get A + C or B + C?
- */
- config = new TotalConfig();
- config.setProperty(properties.MCC, 111);
- config.setProperty(properties.MNC, 222);
- config.setProperty(properties.LANGUAGE, "xx");
- res = config.getResources();
- checkValue(res, R.configVarying.simple, "simple mcc111 mnc222");
- checkValue(res, R.configVarying.bag,
- R.styleable.TestConfig, new String[]{"bag mcc111 mnc222"});
-
- config = new TotalConfig();
- config.setProperty(properties.MNC, 222);
- config.setProperty(properties.LANGUAGE, "xx");
- config.setProperty(properties.ORIENTATION,
- Configuration.ORIENTATION_SQUARE);
- res = config.getResources();
- checkValue(res, R.configVarying.simple, "simple mnc222 xx");
- checkValue(res, R.configVarying.bag,
- R.styleable.TestConfig, new String[]{"bag mnc222 xx"});
-
- config = new TotalConfig();
- config.setProperty(properties.LANGUAGE, "xx");
- config.setProperty(properties.ORIENTATION,
- Configuration.ORIENTATION_SQUARE);
- config.setProperty(properties.DENSITY, 32);
- res = config.getResources();
- checkValue(res, R.configVarying.simple, "simple xx square");
- checkValue(res, R.configVarying.bag,
- R.styleable.TestConfig, new String[]{"bag xx square"});
-
- config = new TotalConfig();
- config.setProperty(properties.ORIENTATION,
- Configuration.ORIENTATION_SQUARE);
- config.setProperty(properties.DENSITY, 32);
- config.setProperty(properties.TOUCHSCREEN,
- Configuration.TOUCHSCREEN_STYLUS);
- res = config.getResources();
- checkValue(res, R.configVarying.simple, "simple square 32dpi");
- checkValue(res, R.configVarying.bag,
- R.styleable.TestConfig, new String[]{"bag square 32dpi"});
-
- config = new TotalConfig();
- config.setProperty(properties.DENSITY, 32);
- config.setProperty(properties.TOUCHSCREEN,
- Configuration.TOUCHSCREEN_STYLUS);
- config.setProperty(properties.KEYBOARDHIDDEN,
- Configuration.KEYBOARDHIDDEN_NO);
- res = config.getResources();
- checkValue(res, R.configVarying.simple, "simple 32dpi stylus");
- checkValue(res, R.configVarying.bag,
- R.styleable.TestConfig, new String[]{"bag 32dpi stylus"});
-
- config = new TotalConfig();
- config.setProperty(properties.TOUCHSCREEN,
- Configuration.TOUCHSCREEN_STYLUS);
- config.setProperty(properties.KEYBOARDHIDDEN,
- Configuration.KEYBOARDHIDDEN_NO);
- config.setProperty(properties.KEYBOARD, Configuration.KEYBOARD_12KEY);
- res = config.getResources();
- checkValue(res, R.configVarying.simple, "simple stylus keysexposed");
- checkValue(res, R.configVarying.bag,
- R.styleable.TestConfig, new String[]{"bag stylus keysexposed"});
-
- config = new TotalConfig();
- config.setProperty(properties.KEYBOARDHIDDEN,
- Configuration.KEYBOARDHIDDEN_NO);
- config.setProperty(properties.KEYBOARD, Configuration.KEYBOARD_12KEY);
- config.setProperty(properties.NAVIGATION,
- Configuration.NAVIGATION_DPAD);
- res = config.getResources();
- checkValue(res, R.configVarying.simple, "simple keysexposed 12key");
- checkValue(res, R.configVarying.bag,
- R.styleable.TestConfig, new String[]{"bag keysexposed 12key"});
-
- config = new TotalConfig();
- config.setProperty(properties.KEYBOARD, Configuration.KEYBOARD_12KEY);
- config.setProperty(properties.NAVIGATION,
- Configuration.NAVIGATION_DPAD);
- config.setProperty(properties.HEIGHT, 63);
- config.setProperty(properties.WIDTH, 57);
- res = config.getResources();
- checkValue(res, R.configVarying.simple, "simple 12key dpad");
- checkValue(res, R.configVarying.bag,
- R.styleable.TestConfig, new String[]{"bag 12key dpad"});
-
- config = new TotalConfig();
- config.setProperty(properties.NAVIGATION,
- Configuration.NAVIGATION_DPAD);
- config.setProperty(properties.HEIGHT, 640);
- config.setProperty(properties.WIDTH, 400);
- res = config.getResources();
- checkValue(res, R.configVarying.simple, "simple dpad");
- checkValue(res, R.configVarying.bag,
- R.styleable.TestConfig, new String[]{"bag dpad"});
- }
-}
diff --git a/tests/AndroidTests/src/com/android/unit_tests/content/ContentTests.java b/tests/AndroidTests/src/com/android/unit_tests/content/ContentTests.java
index 80318dcc6772..636660f8d48e 100644
--- a/tests/AndroidTests/src/com/android/unit_tests/content/ContentTests.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/content/ContentTests.java
@@ -23,10 +23,6 @@ public class ContentTests {
TestSuite suite = new TestSuite(ContentTests.class.getName());
suite.addTestSuite(AssetTest.class);
- suite.addTestSuite(IntentFilterTest.class);
- suite.addTest(ResourceTests.suite());
- suite.addTestSuite(PluralResourcesTest.class);
- suite.addTestSuite(ConfigTest.class);
return suite;
}
}
diff --git a/tests/AndroidTests/src/com/android/unit_tests/content/FractionTest.java b/tests/AndroidTests/src/com/android/unit_tests/content/FractionTest.java
deleted file mode 100644
index 74a6b8de3d5b..000000000000
--- a/tests/AndroidTests/src/com/android/unit_tests/content/FractionTest.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2007 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 com.android.unit_tests.content;
-
-import android.content.res.Resources;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.util.TypedValue;
-import com.android.unit_tests.R;
-
-public class FractionTest extends AndroidTestCase {
-
- private Resources mResources;
- private final TypedValue mValue = new TypedValue();
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- mResources = mContext.getResources();
- }
-
- @SmallTest
- public void testFractions() throws Exception {
- tryFraction(R.dimen.frac100perc, 1, 1, 1);
- tryFraction(R.dimen.frac1perc, 1, 1, .01f);
- tryFraction(R.dimen.fracp1perc, 1, 1, .001f);
- tryFraction(R.dimen.fracp01perc, 1, 1, .0001f);
- tryFraction(R.dimen.frac0perc, 1, 1, 0);
- tryFraction(R.dimen.frac1p1perc, 1, 1, .011f);
- tryFraction(R.dimen.frac100p1perc, 1, 1, 1.001f);
- tryFraction(R.dimen.frac25510perc, 1, 1, 255.1f);
- tryFraction(R.dimen.frac25610perc, 1, 1, 256.1f);
- tryFraction(R.dimen.frac6553510perc, 1, 1, 65535.1f);
- tryFraction(R.dimen.frac6553610perc, 1, 1, 65536.1f);
-
- tryFraction(R.dimen.frac100perc, 100, 1, 100);
- tryFraction(R.dimen.frac1perc, 100, 1, .01f * 100);
- tryFraction(R.dimen.fracp1perc, 100, 1, .001f * 100);
- tryFraction(R.dimen.fracp01perc, 100, 1, .0001f * 100);
- tryFraction(R.dimen.frac0perc, 100, 1, 0);
- tryFraction(R.dimen.frac1p1perc, 100, 1, .011f * 100);
- tryFraction(R.dimen.frac100p1perc, 100, 1, 1.001f * 100);
- tryFraction(R.dimen.frac25510perc, 100, 1, 255.1f * 100);
- tryFraction(R.dimen.frac25610perc, 100, 1, 256.1f * 100);
- tryFraction(R.dimen.frac6553510perc, 100, 1, 65535.1f * 100);
- tryFraction(R.dimen.frac6553610perc, 100, 1, 65536.1f * 100);
-
- tryFraction(R.dimen.frac100pperc, 100, 2, 2);
- tryFraction(R.dimen.frac1pperc, 100, 2, .01f * 2);
- tryFraction(R.dimen.fracp1pperc, 100, 2, .001f * 2);
- tryFraction(R.dimen.fracp01pperc, 100, 2, .0001f * 2);
- tryFraction(R.dimen.frac0pperc, 100, 2, 0);
- tryFraction(R.dimen.frac1p1pperc, 100, 2, .011f * 2);
- tryFraction(R.dimen.frac100p1pperc, 100, 2, 1.001f * 2);
- tryFraction(R.dimen.frac25510pperc, 100, 2, 255.1f * 2);
- tryFraction(R.dimen.frac25610pperc, 100, 2, 256.1f * 2);
- tryFraction(R.dimen.frac6553510pperc, 100, 2, 65535.1f * 2);
- tryFraction(R.dimen.frac6553610pperc, 100, 2, 65536.1f * 2);
- }
-
- private void tryFraction(int resid, float base, float pbase, float expected) {
- mResources.getValue(resid, mValue, true);
- float res = mValue.getFraction(base, pbase);
- float diff = Math.abs(expected - res);
- float prec = expected * 1e-4f;
- if (prec < 1e-5f) {
- prec = 1e-5f;
- }
- //System.out.println(
- // "Res 0x" + Integer.toHexString(resid) + ": got=" + res
- // + ", expected=" + expected + ", diff=" + diff);
- assertFalse("Expecting value " + expected + " got " + res
- + ": in resource 0x" + Integer.toHexString(resid)
- + " " + mValue,
- diff > prec);
- }
-}
-
diff --git a/tests/AndroidTests/src/com/android/unit_tests/content/IntentFilterTest.java b/tests/AndroidTests/src/com/android/unit_tests/content/IntentFilterTest.java
deleted file mode 100644
index 0335b9d38798..000000000000
--- a/tests/AndroidTests/src/com/android/unit_tests/content/IntentFilterTest.java
+++ /dev/null
@@ -1,570 +0,0 @@
-/*
- * Copyright (C) 2007 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 com.android.unit_tests.content;
-
-import android.content.IntentFilter;
-import android.test.suitebuilder.annotation.SmallTest;
-import static android.os.PatternMatcher.PATTERN_LITERAL;
-import static android.os.PatternMatcher.PATTERN_PREFIX;
-import static android.os.PatternMatcher.PATTERN_SIMPLE_GLOB;
-import android.net.Uri;
-import android.util.StringBuilderPrinter;
-import junit.framework.TestCase;
-
-import java.util.HashSet;
-
-public class IntentFilterTest extends TestCase {
-
- public static class Match extends IntentFilter {
- Match(String[] actions, String[] categories, String[] mimeTypes,
- String[] schemes, String[] authorities, String[] ports) {
- if (actions != null) {
- for (int i = 0; i < actions.length; i++) {
- addAction(actions[i]);
- }
- }
- if (categories != null) {
- for (int i = 0; i < categories.length; i++) {
- addCategory(categories[i]);
- }
- }
- if (mimeTypes != null) {
- for (int i = 0; i < mimeTypes.length; i++) {
- try {
- addDataType(mimeTypes[i]);
- } catch (IntentFilter.MalformedMimeTypeException e) {
- throw new RuntimeException("Bad mime type", e);
- }
- }
- }
- if (schemes != null) {
- for (int i = 0; i < schemes.length; i++) {
- addDataScheme(schemes[i]);
- }
- }
- if (authorities != null) {
- for (int i = 0; i < authorities.length; i++) {
- addDataAuthority(authorities[i],
- ports != null ? ports[i] : null);
- }
- }
- }
-
- Match(String[] actions, String[] categories, String[] mimeTypes,
- String[] schemes, String[] authorities, String[] ports,
- String[] paths, int[] pathTypes) {
- this(actions, categories, mimeTypes, schemes, authorities, ports);
- if (paths != null) {
- for (int i = 0; i < paths.length; i++) {
- addDataPath(paths[i], pathTypes[i]);
- }
- }
- }
- }
-
- public static class MatchCondition {
- public final int result;
- public final String action;
- public final String mimeType;
- public final Uri data;
- public final String[] categories;
-
- public MatchCondition(int _result, String _action, String[] _categories,
- String _mimeType, String _data) {
- result = _result;
- action = _action;
- mimeType = _mimeType;
- data = _data != null ? Uri.parse(_data) : null;
- categories = _categories;
- }
- }
-
- public static void checkMatches(IntentFilter filter,
- MatchCondition[] results) {
- for (int i = 0; i < results.length; i++) {
- MatchCondition mc = results[i];
- HashSet<String> categories = null;
- if (mc.categories != null) {
- for (int j = 0; j < mc.categories.length; j++) {
- if (categories == null) {
- categories = new HashSet<String>();
- }
- categories.add(mc.categories[j]);
- }
- }
- int result = filter.match(mc.action, mc.mimeType,
- mc.data != null ? mc.data.getScheme() : null, mc.data,
- categories, "test");
- if ( (result & IntentFilter.MATCH_CATEGORY_MASK)
- != (mc.result & IntentFilter.MATCH_CATEGORY_MASK) ) {
- StringBuilder msg = new StringBuilder();
- msg.append("Error matching against IntentFilter:\n");
- filter.dump(new StringBuilderPrinter(msg), " ");
- msg.append("Match action: ");
- msg.append(mc.action);
- msg.append("\nMatch mimeType: ");
- msg.append(mc.mimeType);
- msg.append("\nMatch data: ");
- msg.append(mc.data);
- msg.append("\nMatch categories: ");
- if (mc.categories != null) {
- for (int j = 0; j < mc.categories.length; j++) {
- if (j > 0) msg.append(", ");
- msg.append(mc.categories[j]);
- }
- }
- msg.append("\nExpected result: 0x");
- msg.append(Integer.toHexString(mc.result));
- msg.append(", got result: 0x");
- msg.append(Integer.toHexString(result));
- throw new RuntimeException(msg.toString());
- }
- }
- }
-
- @SmallTest
- public void testActions() throws Exception {
- IntentFilter filter = new Match(
- new String[]{"action1"}, null, null, null, null, null);
- checkMatches(filter, new MatchCondition[]{
- new MatchCondition(IntentFilter.MATCH_CATEGORY_EMPTY, null,
- null, null, null),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_EMPTY, "action1",
- null, null, null),
- new MatchCondition(IntentFilter.NO_MATCH_ACTION, "action2",
- null, null, null),
- });
-
- filter = new Match(
- new String[]{"action1", "action2"},
- null, null, null, null, null);
- checkMatches(filter, new MatchCondition[]{
- new MatchCondition(IntentFilter.MATCH_CATEGORY_EMPTY, null,
- null, null, null),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_EMPTY, "action1",
- null, null, null),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_EMPTY, "action2",
- null, null, null),
- new MatchCondition(IntentFilter.NO_MATCH_ACTION, "action3",
- null, null, null),
- });
- }
-
- @SmallTest
- public void testCategories() throws Exception {
- IntentFilter filter = new Match(
- null, new String[]{"category1"}, null, null, null, null);
- checkMatches(filter, new MatchCondition[]{
- new MatchCondition(IntentFilter.MATCH_CATEGORY_EMPTY, null,
- null, null, null),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_EMPTY, null,
- new String[]{"category1"}, null, null),
- new MatchCondition(IntentFilter.NO_MATCH_CATEGORY, null,
- new String[]{"category2"}, null, null),
- new MatchCondition(IntentFilter.NO_MATCH_CATEGORY, null,
- new String[]{"category1", "category2"}, null, null),
- });
-
- filter = new Match(
- null, new String[]{"category1", "category2"}, null, null,
- null, null);
- checkMatches(filter, new MatchCondition[]{
- new MatchCondition(IntentFilter.MATCH_CATEGORY_EMPTY, null,
- null, null, null),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_EMPTY, null,
- new String[]{"category1"}, null, null),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_EMPTY, null,
- new String[]{"category2"}, null, null),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_EMPTY, null,
- new String[]{"category1", "category2"}, null, null),
- new MatchCondition(IntentFilter.NO_MATCH_CATEGORY, null,
- new String[]{"category3"}, null, null),
- new MatchCondition(IntentFilter.NO_MATCH_CATEGORY, null,
- new String[]{"category1", "category2", "category3"},
- null, null),
- });
- }
-
- @SmallTest
- public void testMimeTypes() throws Exception {
- IntentFilter filter = new Match(
- null, null, new String[]{"which1/what1"}, null, null, null);
- checkMatches(filter, new MatchCondition[]{
- new MatchCondition(IntentFilter.NO_MATCH_TYPE, null,
- null, null, null),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null,
- "which1/what1", null),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null,
- "which1/*", null),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null,
- "*/*", null),
- new MatchCondition(IntentFilter.NO_MATCH_TYPE, null, null,
- "which2/what2", null),
- new MatchCondition(IntentFilter.NO_MATCH_TYPE, null, null,
- "which2/*", null),
- new MatchCondition(IntentFilter.NO_MATCH_TYPE, null, null,
- "which1/what2", null),
- });
-
- filter = new Match(null, null,
- new String[]{"which1/what1", "which2/what2"}, null, null,
- null);
- checkMatches(filter, new MatchCondition[]{
- new MatchCondition(IntentFilter.NO_MATCH_TYPE, null,
- null, null, null),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null,
- "which1/what1", null),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null,
- "which1/*", null),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null,
- "*/*", null),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null,
- "which2/what2", null),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null,
- "which2/*", null),
- new MatchCondition(IntentFilter.NO_MATCH_TYPE, null, null,
- "which1/what2", null),
- new MatchCondition(IntentFilter.NO_MATCH_TYPE, null, null,
- "which3/what3", null),
- });
-
- filter = new Match(null, null,
- new String[]{"which1/*"}, null, null, null);
- checkMatches(filter, new MatchCondition[]{
- new MatchCondition(IntentFilter.NO_MATCH_TYPE, null,
- null, null, null),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null,
- "which1/what1", null),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null,
- "which1/*", null),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null,
- "*/*", null),
- new MatchCondition(IntentFilter.NO_MATCH_TYPE, null, null,
- "which2/what2", null),
- new MatchCondition(IntentFilter.NO_MATCH_TYPE, null, null,
- "which2/*", null),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null,
- "which1/what2", null),
- new MatchCondition(IntentFilter.NO_MATCH_TYPE, null, null,
- "which3/what3", null),
- });
-
- filter = new Match(null, null,
- new String[]{"*/*"}, null, null, null);
- checkMatches(filter, new MatchCondition[]{
- new MatchCondition(IntentFilter.NO_MATCH_TYPE, null,
- null, null, null),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null,
- "which1/what1", null),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null,
- "which1/*", null),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null,
- "*/*", null),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null,
- "which2/what2", null),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null,
- "which2/*", null),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null,
- "which1/what2", null),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_TYPE, null, null,
- "which3/what3", null),
- });
- }
-
- @SmallTest
- public void testSchemes() throws Exception {
- IntentFilter filter = new Match(null, null, null,
- new String[]{"scheme1"}, null, null);
- checkMatches(filter, new MatchCondition[]{
- new MatchCondition(IntentFilter.NO_MATCH_DATA, null,
- null, null, null),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_SCHEME, null,
- null, null, "scheme1:foo"),
- new MatchCondition(IntentFilter.NO_MATCH_DATA, null,
- null, null, "scheme2:foo"),
- });
-
- filter = new Match(null, null, null,
- new String[]{"scheme1", "scheme2"}, null, null);
- checkMatches(filter, new MatchCondition[]{
- new MatchCondition(IntentFilter.NO_MATCH_DATA, null,
- null, null, null),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_SCHEME, null,
- null, null, "scheme1:foo"),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_SCHEME, null,
- null, null, "scheme2:foo"),
- new MatchCondition(IntentFilter.NO_MATCH_DATA, null,
- null, null, "scheme3:foo"),
- });
- }
-
- @SmallTest
- public void testAuthorities() throws Exception {
- IntentFilter filter = new Match(null, null, null,
- new String[]{"scheme1"},
- new String[]{"authority1"}, new String[]{null});
- checkMatches(filter, new MatchCondition[]{
- new MatchCondition(IntentFilter.NO_MATCH_DATA, null,
- null, null, null),
- new MatchCondition(IntentFilter.NO_MATCH_DATA, null,
- null, null, "scheme1:foo"),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_HOST, null,
- null, null, "scheme1://authority1/"),
- new MatchCondition(IntentFilter.NO_MATCH_DATA, null,
- null, null, "scheme1://authority2/"),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_HOST, null,
- null, null, "scheme1://authority1:100/"),
- });
-
- filter = new Match(null, null, null, new String[]{"scheme1"},
- new String[]{"authority1"}, new String[]{"100"});
- checkMatches(filter, new MatchCondition[]{
- new MatchCondition(IntentFilter.NO_MATCH_DATA, null,
- null, null, null),
- new MatchCondition(IntentFilter.NO_MATCH_DATA, null,
- null, null, "scheme1:foo"),
- new MatchCondition(IntentFilter.NO_MATCH_DATA, null,
- null, null, "scheme1://authority1/"),
- new MatchCondition(IntentFilter.NO_MATCH_DATA, null,
- null, null, "scheme1://authority2/"),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_PORT, null,
- null, null, "scheme1://authority1:100/"),
- new MatchCondition(IntentFilter.NO_MATCH_DATA, null,
- null, null, "scheme1://authority1:200/"),
- });
-
- filter = new Match(null, null, null, new String[]{"scheme1"},
- new String[]{"authority1", "authority2"},
- new String[]{"100", null});
- checkMatches(filter, new MatchCondition[]{
- new MatchCondition(IntentFilter.NO_MATCH_DATA, null,
- null, null, null),
- new MatchCondition(IntentFilter.NO_MATCH_DATA, null,
- null, null, "scheme1:foo"),
- new MatchCondition(IntentFilter.NO_MATCH_DATA, null,
- null, null, "scheme1://authority1/"),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_HOST, null,
- null, null, "scheme1://authority2/"),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_PORT, null,
- null, null, "scheme1://authority1:100/"),
- new MatchCondition(IntentFilter.NO_MATCH_DATA, null,
- null, null, "scheme1://authority1:200/"),
- });
- }
-
- @SmallTest
- public void testPaths() throws Exception {
- IntentFilter filter = new Match(null, null, null,
- new String[]{"scheme"}, new String[]{"authority"}, null,
- new String[]{"/literal1", "/2literal"},
- new int[]{PATTERN_LITERAL, PATTERN_LITERAL});
- checkMatches(filter, new MatchCondition[]{
- new MatchCondition(IntentFilter.NO_MATCH_DATA, null,
- null, null, null),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_PATH, null,
- null, null, "scheme://authority/literal1"),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_PATH, null,
- null, null, "scheme://authority/2literal"),
- new MatchCondition(IntentFilter.NO_MATCH_DATA, null,
- null, null, "scheme://authority/literal"),
- new MatchCondition(IntentFilter.NO_MATCH_DATA, null,
- null, null, "scheme://authority/literal12"),
- });
- filter = new Match(null, null, null,
- new String[]{"scheme"}, new String[]{"authority"}, null,
- new String[]{"/literal1", "/2literal"},
- new int[]{PATTERN_PREFIX, PATTERN_PREFIX});
- checkMatches(filter, new MatchCondition[]{
- new MatchCondition(IntentFilter.NO_MATCH_DATA, null,
- null, null, null),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_PATH, null,
- null, null, "scheme://authority/literal1"),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_PATH, null,
- null, null, "scheme://authority/2literal"),
- new MatchCondition(IntentFilter.NO_MATCH_DATA, null,
- null, null, "scheme://authority/literal"),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_PATH, null,
- null, null, "scheme://authority/literal12"),
- });
- filter = new Match(null, null, null,
- new String[]{"scheme"}, new String[]{"authority"}, null,
- new String[]{"/.*"},
- new int[]{PATTERN_SIMPLE_GLOB});
- checkMatches(filter, new MatchCondition[]{
- new MatchCondition(IntentFilter.NO_MATCH_DATA, null,
- null, null, null),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_PATH, null,
- null, null, "scheme://authority/literal1"),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_PATH, null,
- null, null, "scheme://authority/"),
- new MatchCondition(IntentFilter.NO_MATCH_DATA, null,
- null, null, "scheme://authority"),
- });
- filter = new Match(null, null, null,
- new String[]{"scheme"}, new String[]{"authority"}, null,
- new String[]{".*"},
- new int[]{PATTERN_SIMPLE_GLOB});
- checkMatches(filter, new MatchCondition[]{
- new MatchCondition(IntentFilter.NO_MATCH_DATA, null,
- null, null, null),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_PATH, null,
- null, null, "scheme://authority/literal1"),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_PATH, null,
- null, null, "scheme://authority/"),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_PATH, null,
- null, null, "scheme://authority"),
- });
- filter = new Match(null, null, null,
- new String[]{"scheme"}, new String[]{"authority"}, null,
- new String[]{"/a1*b"},
- new int[]{PATTERN_SIMPLE_GLOB});
- checkMatches(filter, new MatchCondition[]{
- new MatchCondition(IntentFilter.NO_MATCH_DATA, null,
- null, null, null),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_PATH, null,
- null, null, "scheme://authority/ab"),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_PATH, null,
- null, null, "scheme://authority/a1b"),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_PATH, null,
- null, null, "scheme://authority/a11b"),
- new MatchCondition(IntentFilter.NO_MATCH_DATA, null,
- null, null, "scheme://authority/a2b"),
- new MatchCondition(IntentFilter.NO_MATCH_DATA, null,
- null, null, "scheme://authority/a1bc"),
- new MatchCondition(IntentFilter.NO_MATCH_DATA, null,
- null, null, "scheme://authority/"),
- });
- filter = new Match(null, null, null,
- new String[]{"scheme"}, new String[]{"authority"}, null,
- new String[]{"/a1*"},
- new int[]{PATTERN_SIMPLE_GLOB});
- checkMatches(filter, new MatchCondition[]{
- new MatchCondition(IntentFilter.NO_MATCH_DATA, null,
- null, null, null),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_PATH, null,
- null, null, "scheme://authority/a1"),
- new MatchCondition(IntentFilter.NO_MATCH_DATA, null,
- null, null, "scheme://authority/ab"),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_PATH, null,
- null, null, "scheme://authority/a11"),
- new MatchCondition(IntentFilter.NO_MATCH_DATA, null,
- null, null, "scheme://authority/a1b"),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_PATH, null,
- null, null, "scheme://authority/a11"),
- new MatchCondition(IntentFilter.NO_MATCH_DATA, null,
- null, null, "scheme://authority/a2"),
- });
- filter = new Match(null, null, null,
- new String[]{"scheme"}, new String[]{"authority"}, null,
- new String[]{"/a\\.*b"},
- new int[]{PATTERN_SIMPLE_GLOB});
- checkMatches(filter, new MatchCondition[]{
- new MatchCondition(IntentFilter.NO_MATCH_DATA, null,
- null, null, null),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_PATH, null,
- null, null, "scheme://authority/ab"),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_PATH, null,
- null, null, "scheme://authority/a.b"),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_PATH, null,
- null, null, "scheme://authority/a..b"),
- new MatchCondition(IntentFilter.NO_MATCH_DATA, null,
- null, null, "scheme://authority/a2b"),
- new MatchCondition(IntentFilter.NO_MATCH_DATA, null,
- null, null, "scheme://authority/a.bc"),
- new MatchCondition(IntentFilter.NO_MATCH_DATA, null,
- null, null, "scheme://authority/"),
- });
- filter = new Match(null, null, null,
- new String[]{"scheme"}, new String[]{"authority"}, null,
- new String[]{"/a.*b"},
- new int[]{PATTERN_SIMPLE_GLOB});
- checkMatches(filter, new MatchCondition[]{
- new MatchCondition(IntentFilter.NO_MATCH_DATA, null,
- null, null, null),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_PATH, null,
- null, null, "scheme://authority/ab"),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_PATH, null,
- null, null, "scheme://authority/a.b"),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_PATH, null,
- null, null, "scheme://authority/a.1b"),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_PATH, null,
- null, null, "scheme://authority/a2b"),
- new MatchCondition(IntentFilter.NO_MATCH_DATA, null,
- null, null, "scheme://authority/a.bc"),
- new MatchCondition(IntentFilter.NO_MATCH_DATA, null,
- null, null, "scheme://authority/"),
- });
- filter = new Match(null, null, null,
- new String[]{"scheme"}, new String[]{"authority"}, null,
- new String[]{"/a.*"},
- new int[]{PATTERN_SIMPLE_GLOB});
- checkMatches(filter, new MatchCondition[]{
- new MatchCondition(IntentFilter.NO_MATCH_DATA, null,
- null, null, null),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_PATH, null,
- null, null, "scheme://authority/ab"),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_PATH, null,
- null, null, "scheme://authority/a.b"),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_PATH, null,
- null, null, "scheme://authority/a.1b"),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_PATH, null,
- null, null, "scheme://authority/a2b"),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_PATH, null,
- null, null, "scheme://authority/a.bc"),
- new MatchCondition(IntentFilter.NO_MATCH_DATA, null,
- null, null, "scheme://authority/"),
- });
- filter = new Match(null, null, null,
- new String[]{"scheme"}, new String[]{"authority"}, null,
- new String[]{"/a.\\*b"},
- new int[]{PATTERN_SIMPLE_GLOB});
- checkMatches(filter, new MatchCondition[]{
- new MatchCondition(IntentFilter.NO_MATCH_DATA, null,
- null, null, null),
- new MatchCondition(IntentFilter.NO_MATCH_DATA, null,
- null, null, "scheme://authority/ab"),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_PATH, null,
- null, null, "scheme://authority/a.*b"),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_PATH, null,
- null, null, "scheme://authority/a1*b"),
- new MatchCondition(IntentFilter.NO_MATCH_DATA, null,
- null, null, "scheme://authority/a2b"),
- new MatchCondition(IntentFilter.NO_MATCH_DATA, null,
- null, null, "scheme://authority/a.bc"),
- new MatchCondition(IntentFilter.NO_MATCH_DATA, null,
- null, null, "scheme://authority/"),
- });
- filter = new Match(null, null, null,
- new String[]{"scheme"}, new String[]{"authority"}, null,
- new String[]{"/a.\\*"},
- new int[]{PATTERN_SIMPLE_GLOB});
- checkMatches(filter, new MatchCondition[]{
- new MatchCondition(IntentFilter.NO_MATCH_DATA, null,
- null, null, null),
- new MatchCondition(IntentFilter.NO_MATCH_DATA, null,
- null, null, "scheme://authority/ab"),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_PATH, null,
- null, null, "scheme://authority/a.*"),
- new MatchCondition(IntentFilter.MATCH_CATEGORY_PATH, null,
- null, null, "scheme://authority/a1*"),
- new MatchCondition(IntentFilter.NO_MATCH_DATA, null,
- null, null, "scheme://authority/a1b"),
- });
- }
-
-}
-
diff --git a/tests/AndroidTests/src/com/android/unit_tests/content/PluralResourcesTest.java b/tests/AndroidTests/src/com/android/unit_tests/content/PluralResourcesTest.java
deleted file mode 100644
index c3d1478e8f63..000000000000
--- a/tests/AndroidTests/src/com/android/unit_tests/content/PluralResourcesTest.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2007 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 com.android.unit_tests.content;
-
-import android.content.res.AssetManager;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.util.TypedValue;
-import android.util.Log;
-import com.android.unit_tests.R;
-
-import junit.framework.Assert;
-
-import java.util.Locale;
-
-public class PluralResourcesTest extends AndroidTestCase {
- private static final String TAG = "PluralResourcesTest";
-
- private Resources mResources;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- mResources = mContext.getResources();
- }
-
- Resources resourcesForLanguage(String lang) {
- Configuration config = new Configuration();
- config.updateFrom(mResources.getConfiguration());
- config.locale = new Locale(lang);
- return new Resources(mResources.getAssets(), mResources.getDisplayMetrics(), config);
- }
-
- @SmallTest
- public void testPlurals() throws Exception {
- CharSequence cs;
- Resources res = resourcesForLanguage("en");
-
- cs = res.getQuantityText(R.plurals.plurals_test, 0);
- Log.d(TAG, "english 0 cs=" + cs);
- Assert.assertEquals(cs.toString(), "Some dogs");
-
- cs = res.getQuantityText(R.plurals.plurals_test, 1);
- Log.d(TAG, "english 1 cs=" + cs);
- Assert.assertEquals(cs.toString(), "A dog");
-
- cs = res.getQuantityText(R.plurals.plurals_test, 2);
- Assert.assertEquals(cs.toString(), "Some dogs");
-
- cs = res.getQuantityText(R.plurals.plurals_test, 5);
- Assert.assertEquals(cs.toString(), "Some dogs");
-
- cs = res.getQuantityText(R.plurals.plurals_test, 500);
- Assert.assertEquals(cs.toString(), "Some dogs");
- }
-
- @SmallTest
- public void testCzech() throws Exception {
- CharSequence cs;
- Resources res = resourcesForLanguage("cs");
-
- cs = res.getQuantityText(R.plurals.plurals_test, 0);
- Log.d(TAG, "czech 0 cs=" + cs);
- Assert.assertEquals(cs.toString(), "Some Czech dogs");
-
- cs = res.getQuantityText(R.plurals.plurals_test, 1);
- Log.d(TAG, "czech 1 cs=" + cs);
- Assert.assertEquals(cs.toString(), "A Czech dog");
-
- cs = res.getQuantityText(R.plurals.plurals_test, 2);
- Log.d(TAG, "czech 2 cs=" + cs);
- Assert.assertEquals(cs.toString(), "Few Czech dogs");
-
- cs = res.getQuantityText(R.plurals.plurals_test, 5);
- Assert.assertEquals(cs.toString(), "Some Czech dogs");
-
- cs = res.getQuantityText(R.plurals.plurals_test, 500);
- Assert.assertEquals(cs.toString(), "Some Czech dogs");
- }
-}
diff --git a/tests/AndroidTests/src/com/android/unit_tests/content/PrimitiveTest.java b/tests/AndroidTests/src/com/android/unit_tests/content/PrimitiveTest.java
deleted file mode 100644
index 44098cc5edcb..000000000000
--- a/tests/AndroidTests/src/com/android/unit_tests/content/PrimitiveTest.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright (C) 2007 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 com.android.unit_tests.content;
-
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.util.TypedValue;
-import com.android.unit_tests.R;
-
-public class PrimitiveTest extends AndroidTestCase {
- private Resources mResources;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- mResources = mContext.getResources();
- }
-
- private void tryEnum(int resid, int expected) {
- TypedArray sa =
- mContext.obtainStyledAttributes(resid, R.styleable.EnumStyle);
- int value = sa.getInt(R.styleable.EnumStyle_testEnum, -1);
- sa.recycle();
-
- assertEquals("Expecting value " + expected + " got " + value
- + ": in resource 0x" + Integer.toHexString(resid),
- expected, value);
- }
-
- @SmallTest
- public void testEnum() throws Exception {
- tryEnum(R.style.TestEnum1, 1);
- tryEnum(R.style.TestEnum2, 2);
- tryEnum(R.style.TestEnum10, 10);
- tryEnum(R.style.TestEnum1_EmptyInherit, 1);
- }
-
- private void tryFlag(int resid, int expected) {
- TypedArray sa =
- mContext.obtainStyledAttributes(resid, R.styleable.FlagStyle);
- int value = sa.getInt(R.styleable.FlagStyle_testFlags, -1);
- sa.recycle();
-
- assertEquals("Expecting value " + expected + " got " + value
- + ": in resource 0x" + Integer.toHexString(resid),
- expected, value);
- }
-
- @SmallTest
- public void testFlags() throws Exception {
- tryFlag(R.style.TestFlag1, 0x1);
- tryFlag(R.style.TestFlag2, 0x2);
- tryFlag(R.style.TestFlag31, 0x40000000);
- tryFlag(R.style.TestFlag1And2, 0x3);
- tryFlag(R.style.TestFlag1And2And31, 0x40000003);
- }
-
- private void tryBoolean(int resid, boolean expected) {
- TypedValue v = new TypedValue();
- mContext.getResources().getValue(resid, v, true);
- assertEquals(TypedValue.TYPE_INT_BOOLEAN, v.type);
- assertEquals("Expecting boolean value " + expected + " got " + v
- + " from TypedValue: in resource 0x" + Integer.toHexString(resid),
- expected, v.data != 0);
- assertEquals("Expecting boolean value " + expected + " got " + v
- + " from getBoolean(): in resource 0x" + Integer.toHexString(resid),
- expected, mContext.getResources().getBoolean(resid));
- }
-
- @SmallTest
- public void testBoolean() throws Exception {
- tryBoolean(R.bool.trueRes, true);
- tryBoolean(R.bool.falseRes, false);
- }
-
- private void tryString(int resid, String expected) {
- TypedValue v = new TypedValue();
- mContext.getResources().getValue(resid, v, true);
- assertEquals(TypedValue.TYPE_STRING, v.type);
- assertEquals("Expecting string value " + expected + " got " + v
- + ": in resource 0x" + Integer.toHexString(resid),
- expected, v.string);
- }
-
- @SmallTest
- public void testStringCoerce() throws Exception {
- tryString(R.string.coerceIntegerToString, "100");
- tryString(R.string.coerceBooleanToString, "true");
- tryString(R.string.coerceColorToString, "#fff");
- tryString(R.string.coerceFloatToString, "100.0");
- tryString(R.string.coerceDimensionToString, "100px");
- tryString(R.string.coerceFractionToString, "100%");
- }
-
- private static void checkString(int resid, String actual, String expected) {
- assertEquals("Expecting string value \"" + expected + "\" got \""
- + actual + "\" in resources 0x" + Integer.toHexString(resid),
- expected, actual);
- }
-
- @SmallTest
- public void testFormattedString() throws Exception {
- // Make sure the regular one doesn't format anything
- checkString(R.string.formattedStringNone,
- mResources.getString(R.string.formattedStringNone),
- "Format[]");
- checkString(R.string.formattedStringOne,
- mResources.getString(R.string.formattedStringOne),
- "Format[%d]");
- checkString(R.string.formattedStringTwo,
- mResources.getString(R.string.formattedStringTwo),
- "Format[%3$d,%2$s]");
- // Make sure the formatted one works
- checkString(R.string.formattedStringNone,
- mResources.getString(R.string.formattedStringNone),
- "Format[]");
- checkString(R.string.formattedStringOne,
- mResources.getString(R.string.formattedStringOne, 42),
- "Format[42]");
- checkString(R.string.formattedStringTwo,
- mResources.getString(R.string.formattedStringTwo, "unused", "hi", 43),
- "Format[43,hi]");
- }
-}
-
diff --git a/tests/AndroidTests/src/com/android/unit_tests/content/RawResourceTest.java b/tests/AndroidTests/src/com/android/unit_tests/content/RawResourceTest.java
deleted file mode 100644
index 1786dc46b89f..000000000000
--- a/tests/AndroidTests/src/com/android/unit_tests/content/RawResourceTest.java
+++ /dev/null
@@ -1,40 +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.
- */
-
-package com.android.unit_tests.content;
-
-import android.content.res.Resources;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-import com.android.unit_tests.R;
-
-import java.io.InputStream;
-
-public class RawResourceTest extends AndroidTestCase {
- private Resources mResources;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- mResources = mContext.getResources();
- }
-
- @SmallTest
- public void testReadToEnd() throws Exception {
- InputStream is = mResources.openRawResource(R.raw.text);
- AssetTest.verifyTextAsset(is);
- }
-}
diff --git a/tests/AndroidTests/src/com/android/unit_tests/content/ResourceNameTest.java b/tests/AndroidTests/src/com/android/unit_tests/content/ResourceNameTest.java
deleted file mode 100644
index 2a56243cfb0e..000000000000
--- a/tests/AndroidTests/src/com/android/unit_tests/content/ResourceNameTest.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2007 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 com.android.unit_tests.content;
-
-import android.content.res.Resources;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-
-import com.android.unit_tests.R;
-
-public class ResourceNameTest extends AndroidTestCase {
-
- @SmallTest
- public void testGetResourceName() {
- Resources res = mContext.getResources();
-
- String fullName = res.getResourceName(R.configVarying.simple);
- assertEquals("com.android.unit_tests:configVarying/simple", fullName);
-
- String packageName = res.getResourcePackageName(R.configVarying.simple);
- assertEquals("com.android.unit_tests", packageName);
-
- String typeName = res.getResourceTypeName(R.configVarying.simple);
- assertEquals("configVarying", typeName);
-
- String entryName = res.getResourceEntryName(R.configVarying.simple);
- assertEquals("simple", entryName);
- }
-
- @SmallTest
- public void testGetResourceIdentifier() {
- Resources res = mContext.getResources();
- int resid = res.getIdentifier(
- "com.android.unit_tests:configVarying/simple",
- null, null);
- assertEquals(R.configVarying.simple, resid);
-
- resid = res.getIdentifier("configVarying/simple", null,
- "com.android.unit_tests");
- assertEquals(R.configVarying.simple, resid);
-
- resid = res.getIdentifier("simple", "configVarying",
- "com.android.unit_tests");
- assertEquals(R.configVarying.simple, resid);
- }
-}
-
diff --git a/tests/AndroidTests/src/com/android/unit_tests/content/ResourceTests.java b/tests/AndroidTests/src/com/android/unit_tests/content/ResourceTests.java
deleted file mode 100644
index 943941e517a4..000000000000
--- a/tests/AndroidTests/src/com/android/unit_tests/content/ResourceTests.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2006 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 com.android.unit_tests.content;
-
-import junit.framework.TestSuite;
-
-public class ResourceTests {
- public static TestSuite suite() {
- TestSuite suite = new TestSuite(ResourceTests.class.getName());
-
- suite.addTestSuite(FractionTest.class);
- suite.addTestSuite(PrimitiveTest.class);
- suite.addTestSuite(ArrayTest.class);
- suite.addTestSuite(ConfigTest.class);
- suite.addTestSuite(RawResourceTest.class);
- suite.addTestSuite(ResourceNameTest.class);
- return suite;
- }
-}
diff --git a/tests/CoreTests/android/core/CoreTests.java b/tests/CoreTests/android/core/CoreTests.java
index e4f835c05737..442fe0f943ad 100644
--- a/tests/CoreTests/android/core/CoreTests.java
+++ b/tests/CoreTests/android/core/CoreTests.java
@@ -59,7 +59,6 @@ public class CoreTests extends TestSuite {
suite.addTestSuite(LocationManagerProximityTest.class);
suite.addTestSuite(AndroidTestRunnerTest.class);
suite.addTestSuite(InstrumentationTestRunnerTest.class);
- suite.addTestSuite(CookieTest.class);
return suite;
}
diff --git a/tests/CoreTests/android/webkit/CookieTest.java b/tests/CoreTests/android/webkit/CookieTest.java
deleted file mode 100644
index 5c5a6a825658..000000000000
--- a/tests/CoreTests/android/webkit/CookieTest.java
+++ /dev/null
@@ -1,193 +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.
- */
-
-package android.webkit;
-
-import android.content.Context;
-import android.test.AndroidTestCase;
-import android.util.Log;
-import android.webkit.CookieManager;
-import android.webkit.CookieSyncManager;
-
-public class CookieTest extends AndroidTestCase {
-
- /**
- * To run these tests: $ mmm frameworks/base/tests/CoreTests/android && adb
- * remount && adb sync $ adb shell am instrument -w \ -e class
- * android.webkit.CookieTest \
- * android.core/android.test.InstrumentationTestRunner
- */
-
- private CookieManager mCookieManager;
-
- @Override
- public void setContext(Context context) {
- assertTrue(mContext == null);
- super.setContext(context);
- CookieSyncManager.createInstance(context);
- mCookieManager = CookieManager.getInstance();
- mCookieManager.removeAllCookie();
- }
-
- public void testParse() {
- mCookieManager.removeAllCookie();
- String url = "http://www.foo.com";
-
- // basic
- mCookieManager.setCookie(url, "a=b");
- String cookie = mCookieManager.getCookie(url);
- assertTrue(cookie.equals("a=b"));
-
- // quoted
- mCookieManager.setCookie(url, "c=\"d;\"");
- cookie = mCookieManager.getCookie(url);
- assertTrue(cookie.equals("a=b; c=\"d;\""));
-
- // empty
- mCookieManager.setCookie(url, "; path=/");
- cookie = mCookieManager.getCookie(url);
- assertTrue(cookie.equals("a=b; c=\"d;\""));
- }
-
- public void testDomain() {
- mCookieManager.removeAllCookie();
- String url = "http://www.foo.com";
-
- // basic
- mCookieManager.setCookie(url, "a=b");
- String cookie = mCookieManager.getCookie(url);
- assertTrue(cookie.equals("a=b"));
-
- // no cross domain cookie
- cookie = mCookieManager.getCookie("http://bar.com");
- assertTrue(cookie == null);
-
- // more than one cookie
- mCookieManager.setCookie(url, "c=d; domain=.foo.com");
- cookie = mCookieManager.getCookie(url);
- assertTrue(cookie.equals("a=b; c=d"));
-
- // host cookie should not be accessible from a sub-domain.
- cookie = mCookieManager.getCookie("http://bar.www.foo.com");
- assertTrue(cookie.equals("c=d"));
-
- // test setting a domain= that doesn't start w/ a dot, should
- // treat it as a domain cookie, as if there was a pre-pended dot.
- mCookieManager.setCookie(url, "e=f; domain=www.foo.com");
- cookie = mCookieManager.getCookie(url);
- assertTrue(cookie.equals("a=b; c=d; e=f"));
- cookie = mCookieManager.getCookie("http://sub.www.foo.com");
- assertTrue(cookie.equals("c=d; e=f"));
- cookie = mCookieManager.getCookie("http://foo.com");
- assertTrue(cookie.equals("c=d"));
- }
-
- public void testSubDomain() {
- mCookieManager.removeAllCookie();
- String url_abcd = "http://a.b.c.d.com";
- String url_bcd = "http://b.c.d.com";
- String url_cd = "http://c.d.com";
- String url_d = "http://d.com";
-
- mCookieManager.setCookie(url_abcd, "a=1; domain=.a.b.c.d.com");
- mCookieManager.setCookie(url_abcd, "b=2; domain=.b.c.d.com");
- mCookieManager.setCookie(url_abcd, "c=3; domain=.c.d.com");
- mCookieManager.setCookie(url_abcd, "d=4; domain=.d.com");
-
- String cookie = mCookieManager.getCookie(url_abcd);
- assertTrue(cookie.equals("a=1; b=2; c=3; d=4"));
- cookie = mCookieManager.getCookie(url_bcd);
- assertTrue(cookie.equals("b=2; c=3; d=4"));
- cookie = mCookieManager.getCookie(url_cd);
- assertTrue(cookie.equals("c=3; d=4"));
- cookie = mCookieManager.getCookie(url_d);
- assertTrue(cookie.equals("d=4"));
-
- // check that the same cookie can exist on different sub-domains.
- mCookieManager.setCookie(url_bcd, "x=bcd; domain=.b.c.d.com");
- mCookieManager.setCookie(url_bcd, "x=cd; domain=.c.d.com");
- cookie = mCookieManager.getCookie(url_bcd);
- assertTrue(cookie.equals("b=2; c=3; d=4; x=bcd; x=cd"));
- cookie = mCookieManager.getCookie(url_cd);
- assertTrue(cookie.equals("c=3; d=4; x=cd"));
- }
-
- public void testInvalidDomain() {
- mCookieManager.removeAllCookie();
- String url = "http://foo.bar.com";
-
- mCookieManager.setCookie(url, "a=1; domain=.yo.foo.bar.com");
- String cookie = mCookieManager.getCookie(url);
- assertTrue(cookie == null);
-
- mCookieManager.setCookie(url, "b=2; domain=.foo.com");
- cookie = mCookieManager.getCookie(url);
- assertTrue(cookie == null);
-
- mCookieManager.setCookie(url, "c=3; domain=.bar.foo.com");
- cookie = mCookieManager.getCookie(url);
- assertTrue(cookie == null);
-
- mCookieManager.setCookie(url, "d=4; domain=.foo.bar.com.net");
- cookie = mCookieManager.getCookie(url);
- assertTrue(cookie == null);
-
- mCookieManager.setCookie(url, "e=5; domain=.ar.com");
- cookie = mCookieManager.getCookie(url);
- assertTrue(cookie == null);
-
- mCookieManager.setCookie(url, "f=6; domain=.com");
- cookie = mCookieManager.getCookie(url);
- assertTrue(cookie == null);
-
- mCookieManager.setCookie(url, "g=7; domain=.co.uk");
- cookie = mCookieManager.getCookie(url);
- assertTrue(cookie == null);
-
- mCookieManager.setCookie(url, "h=8; domain=.foo.bar.com.com");
- cookie = mCookieManager.getCookie(url);
- assertTrue(cookie == null);
- }
-
- public void testPath() {
- mCookieManager.removeAllCookie();
- String url = "http://www.foo.com";
-
- mCookieManager.setCookie(url, "a=b; path=/wee");
- String cookie = mCookieManager.getCookie(url + "/wee");
- assertTrue(cookie.equals("a=b"));
- cookie = mCookieManager.getCookie(url + "/wee/");
- assertTrue(cookie.equals("a=b"));
- cookie = mCookieManager.getCookie(url + "/wee/hee");
- assertTrue(cookie.equals("a=b"));
- cookie = mCookieManager.getCookie(url + "/wee/hee/more");
- assertTrue(cookie.equals("a=b"));
- cookie = mCookieManager.getCookie(url + "/weehee");
- assertTrue(cookie == null);
- cookie = mCookieManager.getCookie(url);
- assertTrue(cookie == null);
-
- mCookieManager.setCookie(url, "a=c; path=");
- cookie = mCookieManager.getCookie(url + "/wee");
- assertTrue(cookie.equals("a=b; a=c"));
- cookie = mCookieManager.getCookie(url);
- assertTrue(cookie.equals("a=c"));
-
- mCookieManager.setCookie(url, "a=d");
- cookie = mCookieManager.getCookie(url + "/wee");
- assertTrue(cookie.equals("a=b; a=d"));
- }
-}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/expandablelistview/ExpandableListWithHeadersTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/expandablelistview/ExpandableListWithHeadersTest.java
deleted file mode 100644
index 49b5106cf7a5..000000000000
--- a/tests/FrameworkTest/tests/src/com/android/frameworktest/expandablelistview/ExpandableListWithHeadersTest.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2007 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 com.android.frameworktest.expandablelistview;
-
-import android.test.ActivityInstrumentationTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.view.KeyEvent;
-import android.widget.ExpandableListView;
-
-import com.android.frameworktest.expandablelistview.ExpandableListWithHeaders;
-import com.android.frameworktest.util.ListUtil;
-
-public class ExpandableListWithHeadersTest extends ActivityInstrumentationTestCase<ExpandableListWithHeaders> {
- private ExpandableListView mExpandableListView;
- private ListUtil mListUtil;
-
- public ExpandableListWithHeadersTest() {
- super("com.android.frameworktest",
- ExpandableListWithHeaders.class);
- }
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
-
- mExpandableListView = getActivity().getExpandableListView();
- mListUtil = new ListUtil(mExpandableListView, getInstrumentation());
- }
-
- @MediumTest
- public void testPreconditions() {
- assertNotNull(mExpandableListView);
- }
-
- @MediumTest
- public void testExpandOnFirstPosition() {
- // Should be a header, and hence the first group should NOT have expanded
- mListUtil.arrowScrollToSelectedPosition(0);
- sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
- getInstrumentation().waitForIdleSync();
- assertFalse(mExpandableListView.isGroupExpanded(0));
- }
-
- @LargeTest
- public void testExpandOnFirstGroup() {
- mListUtil.arrowScrollToSelectedPosition(getActivity().getNumOfHeadersAndFooters());
- sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
- getInstrumentation().waitForIdleSync();
- assertTrue(mExpandableListView.isGroupExpanded(0));
- }
-}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/view/RemoteViewsActivityTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/view/RemoteViewsActivityTest.java
deleted file mode 100644
index 3dcb2525500e..000000000000
--- a/tests/FrameworkTest/tests/src/com/android/frameworktest/view/RemoteViewsActivityTest.java
+++ /dev/null
@@ -1,126 +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.
- */
-
-package com.android.frameworktest.view;
-
-import android.os.Parcel;
-import android.test.ActivityInstrumentationTestCase;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.view.InflateException;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.RemoteViews;
-
-import com.android.frameworktest.R;
-import com.android.frameworktest.view.RemoteViewsActivity;
-
-public class RemoteViewsActivityTest extends ActivityInstrumentationTestCase<RemoteViewsActivity> {
- public RemoteViewsActivityTest() {
- super("com.android.frameworktest", RemoteViewsActivity.class);
- }
-
- @Override
- public void setUp() throws Exception {
- super.setUp();
- }
-
- @MediumTest
- public void testGood() throws Exception {
- final RemoteViewsActivity activity = getActivity();
-
- RemoteViews orig = new RemoteViews("com.android.frameworktest",
- R.layout.remote_view_test_good);
- Parcel p = Parcel.obtain();
- orig.writeToParcel(p, 0);
- p.setDataPosition(0);
-
- RemoteViews r = RemoteViews.CREATOR.createFromParcel(p);
-
- ViewGroup parent = (ViewGroup) activity.findViewById(R.id.parent);
-
- View result = r.apply(activity, parent);
-
- p.recycle();
-
- assertTrue("LinearLayout not inflated", result.findViewById(R.id.linear) != null);
- assertTrue("TextView not inflated", result.findViewById(R.id.text) != null);
- assertTrue("ImageView not inflated", result.findViewById(R.id.image) != null);
- assertTrue("FrameLayout not inflated", result.findViewById(R.id.frame) != null);
- assertTrue("RelateiveLayout not inflated", result.findViewById(R.id.relative) != null);
- assertTrue("AbsoluteLayout not inflated", result.findViewById(R.id.absolute) != null);
- assertTrue("ProgressBar not inflated", result.findViewById(R.id.progress) != null);
- assertTrue("ImageButton not inflated", result.findViewById(R.id.image_button) != null);
- assertTrue("Button not inflated", result.findViewById(R.id.button) != null);
- }
-
- @MediumTest
- public void testDerivedClass() throws Exception {
- final RemoteViewsActivity activity = getActivity();
-
- RemoteViews orig = new RemoteViews("com.android.frameworktest",
- R.layout.remote_view_test_bad_1);
- Parcel p = Parcel.obtain();
- orig.writeToParcel(p, 0);
- p.setDataPosition(0);
-
- RemoteViews r = RemoteViews.CREATOR.createFromParcel(p);
-
- ViewGroup parent = (ViewGroup) activity.findViewById(R.id.parent);
-
- boolean exceptionThrown = false;
- View result = null;
-
- try {
- result = r.apply(activity, parent);
- } catch (InflateException e) {
- exceptionThrown = true;
- }
-
- p.recycle();
-
- assertTrue("Derived class (EditText) allowed to be inflated", exceptionThrown);
- assertNull("Derived class (EditText) allowed to be inflated", result);
- }
-
- @MediumTest
- public void testWebView() throws Exception {
- final RemoteViewsActivity activity = getActivity();
-
- RemoteViews orig = new RemoteViews("com.android.frameworktest",
- R.layout.remote_view_test_bad_2);
- Parcel p = Parcel.obtain();
- orig.writeToParcel(p, 0);
- p.setDataPosition(0);
-
- RemoteViews r = RemoteViews.CREATOR.createFromParcel(p);
-
- ViewGroup parent = (ViewGroup) activity.findViewById(R.id.parent);
-
- boolean exceptionThrown = false;
- View result = null;
-
- try {
- result = r.apply(activity, parent);
- } catch (InflateException e) {
- exceptionThrown = true;
- }
-
- p.recycle();
-
- assertTrue("WebView allowed to be inflated", exceptionThrown);
- assertNull("WebView allowed to be inflated", result);
- }
-}
diff --git a/tests/TransformTest/Android.mk b/tests/TransformTest/Android.mk
new file mode 100644
index 000000000000..2d3637da569a
--- /dev/null
+++ b/tests/TransformTest/Android.mk
@@ -0,0 +1,10 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_PACKAGE_NAME := TransformTest
+
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_PACKAGE)
diff --git a/tests/TransformTest/AndroidManifest.xml b/tests/TransformTest/AndroidManifest.xml
new file mode 100644
index 000000000000..5c9995f25ec6
--- /dev/null
+++ b/tests/TransformTest/AndroidManifest.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.google.android.test.transform">
+ <uses-sdk android:minSdkVersion="7" android:targetSdkVersion="7" />
+ <application android:label="TransformTest">
+ <activity android:name="TransformTestActivity">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+</manifest>
diff --git a/tests/TransformTest/res/drawable/logo.png b/tests/TransformTest/res/drawable/logo.png
new file mode 100644
index 000000000000..4d717a86143d
--- /dev/null
+++ b/tests/TransformTest/res/drawable/logo.png
Binary files differ
diff --git a/tests/TransformTest/res/values/strings.xml b/tests/TransformTest/res/values/strings.xml
new file mode 100644
index 000000000000..a0eb81ff11f6
--- /dev/null
+++ b/tests/TransformTest/res/values/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 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.
+-->
+
+<resources>
+ <string name="act_title">TransformTest</string>
+</resources>
diff --git a/tests/TransformTest/src/com/google/android/test/transform/TransformTestActivity.java b/tests/TransformTest/src/com/google/android/test/transform/TransformTestActivity.java
new file mode 100644
index 000000000000..52286d188bdb
--- /dev/null
+++ b/tests/TransformTest/src/com/google/android/test/transform/TransformTestActivity.java
@@ -0,0 +1,171 @@
+/*
+ * 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.
+ */
+
+package com.google.android.test.transform;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Matrix;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.util.DisplayMetrics;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.TransformGestureDetector;
+import android.view.View;
+import android.widget.LinearLayout;
+
+public class TransformTestActivity extends Activity {
+ public TransformTestActivity() {
+ super();
+ init(false);
+ }
+
+ public TransformTestActivity(boolean noCompat) {
+ super();
+ init(noCompat);
+ }
+
+ public void init(boolean noCompat) {
+
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ final LayoutInflater li = (LayoutInflater)getSystemService(
+ LAYOUT_INFLATER_SERVICE);
+
+ this.setTitle(R.string.act_title);
+ LinearLayout root = new LinearLayout(this);
+ root.setOrientation(LinearLayout.VERTICAL);
+
+ TransformView view = new TransformView(getApplicationContext());
+ Drawable drawable = getResources().getDrawable(R.drawable.logo);
+ drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicWidth());
+ view.setDrawable(drawable);
+
+ root.addView(view);
+ setContentView(root);
+ }
+
+ private class TransformView extends View {
+ private Drawable mDrawable;
+ private float mPosX;
+ private float mPosY;
+ private float mScale = 1.f;
+ private Matrix mMatrix;
+ private TransformGestureDetector mDetector;
+
+ private class Listener implements TransformGestureDetector.OnTransformGestureListener {
+
+ public boolean onTransform(TransformGestureDetector detector) {
+ Log.d("ttest", "Translation: (" + detector.getTranslateX() +
+ ", " + detector.getTranslateY() + ")");
+ float scale = detector.getScaleFactor();
+ Log.d("ttest", "Scale: " + scale);
+ if (mScale * scale > 0.1f) {
+ if (mScale * scale < 10.f) {
+ mScale *= scale;
+ } else {
+ mScale = 10.f;
+ }
+ } else {
+ mScale = 0.1f;
+ }
+
+ mPosX += detector.getTranslateX();
+ mPosY += detector.getTranslateY();
+
+ Log.d("ttest", "mScale: " + mScale + " mPos: (" + mPosX + ", " + mPosY + ")");
+
+ float sizeX = mDrawable.getIntrinsicWidth()/2;
+ float sizeY = mDrawable.getIntrinsicHeight()/2;
+ float centerX = detector.getCenterX();
+ float centerY = detector.getCenterY();
+ float diffX = centerX - mPosX;
+ float diffY = centerY - mPosY;
+ diffX = diffX*scale - diffX;
+ diffY = diffY*scale - diffY;
+ mPosX -= diffX;
+ mPosY -= diffY;
+ mMatrix.reset();
+ mMatrix.postTranslate(-sizeX, -sizeY);
+ mMatrix.postScale(mScale, mScale);
+ mMatrix.postTranslate(mPosX, mPosY);
+
+ invalidate();
+
+ return true;
+ }
+
+ public boolean onTransformBegin(TransformGestureDetector detector) {
+ return true;
+ }
+
+ public boolean onTransformEnd(TransformGestureDetector detector) {
+ return true;
+ }
+
+ public boolean onTransformFling(TransformGestureDetector detector) {
+ return false;
+ }
+
+ }
+
+ public TransformView(Context context) {
+ super(context);
+ mMatrix = new Matrix();
+ mDetector = new TransformGestureDetector(context, new Listener());
+ DisplayMetrics metrics = context.getResources().getDisplayMetrics();
+ mPosX = metrics.widthPixels/2;
+ mPosY = metrics.heightPixels/2;
+ }
+
+ public void setDrawable(Drawable d) {
+ mDrawable = d;
+
+ float sizeX = mDrawable.getIntrinsicWidth()/2;
+ float sizeY = mDrawable.getIntrinsicHeight()/2;
+ mMatrix.reset();
+ mMatrix.postTranslate(-sizeX, -sizeY);
+ mMatrix.postScale(mScale, mScale);
+ mMatrix.postTranslate(mPosX, mPosY);
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ boolean handled = mDetector.onTouchEvent(event);
+
+ int pointerCount = event.getPointerCount();
+ Log.d("ttest", "pointerCount: " + pointerCount);
+
+ return handled;
+ }
+
+ @Override
+ public void onDraw(Canvas canvas) {
+ int saveCount = canvas.getSaveCount();
+ canvas.save();
+ canvas.concat(mMatrix);
+ mDrawable.draw(canvas);
+ canvas.restoreToCount(saveCount);
+ }
+ }
+}
diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp
index de6ff14af41a..ae8f2423e91f 100644
--- a/tools/aapt/Resource.cpp
+++ b/tools/aapt/Resource.cpp
@@ -1768,31 +1768,33 @@ writeProguardForAndroidManifest(ProguardKeepSet* keep, const sp<AaptAssets>& ass
fprintf(stderr, "ERROR: %s\n", error.string());
return -1;
}
- // asdf --> package.asdf
- // .asdf .a.b --> package.asdf package.a.b
- // asdf.adsf --> asdf.asdf
- String8 rule("-keep class ");
- const char* p = name.string();
- const char* q = strchr(p, '.');
- if (p == q) {
- rule += pkg;
- rule += name;
- } else if (q == NULL) {
- rule += pkg;
- rule += ".";
- rule += name;
- } else {
- rule += name;
- }
+ if (name.length() > 0) {
+ // asdf --> package.asdf
+ // .asdf .a.b --> package.asdf package.a.b
+ // asdf.adsf --> asdf.asdf
+ String8 rule("-keep class ");
+ const char* p = name.string();
+ const char* q = strchr(p, '.');
+ if (p == q) {
+ rule += pkg;
+ rule += name;
+ } else if (q == NULL) {
+ rule += pkg;
+ rule += ".";
+ rule += name;
+ } else {
+ rule += name;
+ }
- String8 location = tag;
- location += " ";
- location += assFile->getSourceFile();
- char lineno[20];
- sprintf(lineno, ":%d", tree.getLineNumber());
- location += lineno;
+ String8 location = tag;
+ location += " ";
+ location += assFile->getSourceFile();
+ char lineno[20];
+ sprintf(lineno, ":%d", tree.getLineNumber());
+ location += lineno;
- keep->add(rule, location);
+ keep->add(rule, location);
+ }
}
}
}