diff options
121 files changed, 3186 insertions, 1833 deletions
diff --git a/api/current.xml b/api/current.xml index 31b135301bb8..22d82cee056a 100644 --- a/api/current.xml +++ b/api/current.xml @@ -57955,6 +57955,17 @@ visibility="public" > </field> +<field name="CONFIG_SCREEN_SIZE" + type="int" + transient="false" + volatile="false" + value="1024" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> <field name="CONFIG_TOUCHSCREEN" type="int" transient="false" @@ -64017,6 +64028,28 @@ visibility="public" > </field> +<field name="SCREEN_HEIGHT_DP_UNDEFINED" + type="int" + transient="false" + volatile="false" + value="0" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="SCREEN_WIDTH_DP_UNDEFINED" + type="int" + transient="false" + volatile="false" + value="0" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> <field name="TOUCHSCREEN_FINGER" type="int" transient="false" @@ -64260,6 +64293,16 @@ visibility="public" > </field> +<field name="screenHeightDp" + type="int" + transient="false" + volatile="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</field> <field name="screenLayout" type="int" transient="false" @@ -64270,6 +64313,16 @@ visibility="public" > </field> +<field name="screenWidthDp" + type="int" + transient="false" + volatile="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</field> <field name="touchscreen" type="int" transient="false" @@ -144074,6 +144127,17 @@ visibility="public" > </field> +<field name="ICE_CREAM_SANDWICH" + type="int" + transient="false" + volatile="false" + value="10000" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> </class> <class name="Bundle" extends="java.lang.Object" @@ -180231,6 +180295,17 @@ visibility="public" > </field> +<field name="EXTRA_CONFIDENCE_SCORES" + type="java.lang.String" + transient="false" + volatile="false" + value=""android.speech.extra.CONFIDENCE_SCORES"" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> <field name="EXTRA_LANGUAGE" type="java.lang.String" transient="false" @@ -180286,6 +180361,17 @@ visibility="public" > </field> +<field name="EXTRA_ORIGIN" + type="java.lang.String" + transient="false" + volatile="false" + value=""android.speech.extra.ORIGIN"" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> <field name="EXTRA_PARTIAL_RESULTS" type="java.lang.String" transient="false" @@ -180668,6 +180754,17 @@ visibility="public" > </method> +<field name="CONFIDENCE_SCORES" + type="java.lang.String" + transient="false" + volatile="false" + value=""confidence_scores"" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> <field name="ERROR_AUDIO" type="int" transient="false" @@ -267744,7 +267841,7 @@ deprecated="not deprecated" visibility="public" > -<parameter name="t" type="T"> +<parameter name="arg0" type="T"> </parameter> </method> </interface> diff --git a/cmds/installd/Android.mk b/cmds/installd/Android.mk index 8641c3090a6c..d7a9ef67df05 100644 --- a/cmds/installd/Android.mk +++ b/cmds/installd/Android.mk @@ -1,13 +1,34 @@ ifneq ($(TARGET_SIMULATOR),true) LOCAL_PATH := $(call my-dir) + +common_src_files := \ + commands.c utils.c + +# +# Static library used in testing and executable +# + include $(CLEAR_VARS) LOCAL_SRC_FILES := \ - installd.c commands.c utils.c + $(common_src_files) + +LOCAL_MODULE := libinstalld + +LOCAL_MODULE_TAGS := eng tests -#LOCAL_C_INCLUDES := \ -# $(call include-path-for, system-core)/cutils +include $(BUILD_STATIC_LIBRARY) + +# +# Executable +# + +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := \ + installd.c \ + $(common_src_files) LOCAL_SHARED_LIBRARIES := \ libcutils diff --git a/cmds/installd/commands.c b/cmds/installd/commands.c index 4d49c30501f5..80ba1e986dca 100644 --- a/cmds/installd/commands.c +++ b/cmds/installd/commands.c @@ -17,6 +17,13 @@ #include "installd.h" #include <diskusage/dirsize.h> +/* Directory records that are used in execution of commands. */ +dir_rec_t android_data_dir; +dir_rec_t android_asec_dir; +dir_rec_t android_app_dir; +dir_rec_t android_app_private_dir; +dir_rec_array_t android_system_dirs; + int install(const char *pkgname, uid_t uid, gid_t gid) { char pkgdir[PKG_PATH_MAX]; @@ -27,10 +34,15 @@ int install(const char *pkgname, uid_t uid, gid_t gid) return -1; } - if (create_pkg_path(pkgdir, PKG_DIR_PREFIX, pkgname, PKG_DIR_POSTFIX)) + if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, 0)) { + LOGE("cannot create package path\n"); return -1; - if (create_pkg_path(libdir, PKG_LIB_PREFIX, pkgname, PKG_LIB_POSTFIX)) + } + + if (create_pkg_path(libdir, pkgname, PKG_LIB_POSTFIX, 0)) { + LOGE("cannot create package lib path\n"); return -1; + } if (mkdir(pkgdir, 0751) < 0) { LOGE("cannot create dir '%s': %s\n", pkgdir, strerror(errno)); @@ -59,7 +71,7 @@ int uninstall(const char *pkgname) { char pkgdir[PKG_PATH_MAX]; - if (create_pkg_path(pkgdir, PKG_DIR_PREFIX, pkgname, PKG_DIR_POSTFIX)) + if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, 0)) return -1; /* delete contents AND directory, no exceptions */ @@ -71,9 +83,9 @@ int renamepkg(const char *oldpkgname, const char *newpkgname) char oldpkgdir[PKG_PATH_MAX]; char newpkgdir[PKG_PATH_MAX]; - if (create_pkg_path(oldpkgdir, PKG_DIR_PREFIX, oldpkgname, PKG_DIR_POSTFIX)) + if (create_pkg_path(oldpkgdir, oldpkgname, PKG_DIR_POSTFIX, 0)) return -1; - if (create_pkg_path(newpkgdir, PKG_DIR_PREFIX, newpkgname, PKG_DIR_POSTFIX)) + if (create_pkg_path(newpkgdir, newpkgname, PKG_DIR_POSTFIX, 0)) return -1; if (rename(oldpkgdir, newpkgdir) < 0) { @@ -87,7 +99,7 @@ int delete_user_data(const char *pkgname) { char pkgdir[PKG_PATH_MAX]; - if (create_pkg_path(pkgdir, PKG_DIR_PREFIX, pkgname, PKG_DIR_POSTFIX)) + if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, 0)) return -1; /* delete contents, excluding "lib", but not the directory itself */ @@ -98,7 +110,7 @@ int delete_cache(const char *pkgname) { char cachedir[PKG_PATH_MAX]; - if (create_pkg_path(cachedir, CACHE_DIR_PREFIX, pkgname, CACHE_DIR_POSTFIX)) + if (create_pkg_path(cachedir, pkgname, CACHE_DIR_POSTFIX, 0)) return -1; /* delete contents, not the directory, no exceptions */ @@ -108,10 +120,10 @@ int delete_cache(const char *pkgname) static int64_t disk_free() { struct statfs sfs; - if (statfs(PKG_DIR_PREFIX, &sfs) == 0) { + if (statfs(android_data_dir.path, &sfs) == 0) { return sfs.f_bavail * sfs.f_bsize; } else { - LOGE("Couldn't statfs " PKG_DIR_PREFIX ": %s\n", strerror(errno)); + LOGE("Couldn't statfs %s: %s\n", android_data_dir.path, strerror(errno)); return -1; } } @@ -137,9 +149,9 @@ int free_cache(int64_t free_size) LOGI("free_cache(%" PRId64 ") avail %" PRId64 "\n", free_size, avail); if (avail >= free_size) return 0; - d = opendir(PKG_DIR_PREFIX); + d = opendir(android_data_dir.path); if (d == NULL) { - LOGE("cannot open %s: %s\n", PKG_DIR_PREFIX, strerror(errno)); + LOGE("cannot open %s: %s\n", android_data_dir.path, strerror(errno)); return -1; } dfd = dirfd(d); @@ -172,43 +184,13 @@ int free_cache(int64_t free_size) return -1; } -/* used by move_dex, rm_dex, etc to ensure that the provided paths - * don't point anywhere other than at the APK_DIR_PREFIX - */ -static int is_valid_apk_path(const char *path) -{ - int len = strlen(APK_DIR_PREFIX); -int nosubdircheck = 0; - if (strncmp(path, APK_DIR_PREFIX, len)) { - len = strlen(PROTECTED_DIR_PREFIX); - if (strncmp(path, PROTECTED_DIR_PREFIX, len)) { - len = strlen(SDCARD_DIR_PREFIX); - if (strncmp(path, SDCARD_DIR_PREFIX, len)) { - LOGE("invalid apk path '%s' (bad prefix)\n", path); - return 0; - } else { - nosubdircheck = 1; - } - } - } - if ((nosubdircheck != 1) && strchr(path + len, '/')) { - LOGE("invalid apk path '%s' (subdir?)\n", path); - return 0; - } - if (path[len] == '.') { - LOGE("invalid apk path '%s' (trickery)\n", path); - return 0; - } - return 1; -} - int move_dex(const char *src, const char *dst) { char src_dex[PKG_PATH_MAX]; char dst_dex[PKG_PATH_MAX]; - if (!is_valid_apk_path(src)) return -1; - if (!is_valid_apk_path(dst)) return -1; + if (validate_apk_path(src)) return -1; + if (validate_apk_path(dst)) return -1; if (create_cache_path(src_dex, src)) return -1; if (create_cache_path(dst_dex, dst)) return -1; @@ -226,7 +208,7 @@ int rm_dex(const char *path) { char dex_path[PKG_PATH_MAX]; - if (!is_valid_apk_path(path)) return -1; + if (validate_apk_path(path)) return -1; if (create_cache_path(dex_path, path)) return -1; LOGI("unlink %s\n", dex_path); @@ -245,7 +227,7 @@ int protect(char *pkgname, gid_t gid) if (gid < AID_SYSTEM) return -1; - if (create_pkg_path(pkgpath, PROTECTED_DIR_PREFIX, pkgname, ".apk")) + if (create_pkg_path_in_dir(pkgpath, &android_app_private_dir, pkgname, ".apk")) return -1; if (stat(pkgpath, &s) < 0) return -1; @@ -280,8 +262,8 @@ int get_size(const char *pkgname, const char *apkpath, /* count the source apk as code -- but only if it's not * on the /system partition and its not on the sdcard. */ - if (strncmp(apkpath, "/system", 7) != 0 && - strncmp(apkpath, SDCARD_DIR_PREFIX, 7) != 0) { + if (validate_system_app_path(apkpath) && + strncmp(apkpath, android_asec_dir.path, android_asec_dir.len) != 0) { if (stat(apkpath, &s) == 0) { codesize += stat_size(&s); } @@ -300,7 +282,7 @@ int get_size(const char *pkgname, const char *apkpath, } } - if (create_pkg_path(path, PKG_DIR_PREFIX, pkgname, PKG_DIR_POSTFIX)) { + if (create_pkg_path(path, pkgname, PKG_DIR_POSTFIX, 0)) { goto done; } @@ -310,10 +292,10 @@ int get_size(const char *pkgname, const char *apkpath, } dfd = dirfd(d); - /* most stuff in the pkgdir is data, except for the "cache" - * directory and below, which is cache, and the "lib" directory - * and below, which is code... - */ + /* most stuff in the pkgdir is data, except for the "cache" + * directory and below, which is cache, and the "lib" directory + * and below, which is code... + */ while ((de = readdir(d))) { const char *name = de->d_name; @@ -544,15 +526,15 @@ fail: } int create_move_path(char path[PKG_PATH_MAX], - const char* prefix, const char* pkgname, - const char* leaf) + const char* leaf, + uid_t persona) { - if ((strlen(prefix) + strlen(pkgname) + strlen(leaf) + 1) >= PKG_PATH_MAX) { + if ((android_data_dir.len + strlen(pkgname) + strlen(leaf) + 1) >= PKG_PATH_MAX) { return -1; } - sprintf(path, "%s%s/%s", prefix, pkgname, leaf); + sprintf(path, "%s%s%s/%s", android_data_dir.path, PRIMARY_USER_PREFIX, pkgname, leaf); return 0; } @@ -720,8 +702,8 @@ int movefiles() // Skip -- source package no longer exists. } else { LOGV("Move file: %s (from %s to %s)\n", buf+bufp, srcpkg, dstpkg); - if (!create_move_path(srcpath, PKG_DIR_PREFIX, srcpkg, buf+bufp) && - !create_move_path(dstpath, PKG_DIR_PREFIX, dstpkg, buf+bufp)) { + if (!create_move_path(srcpath, srcpkg, buf+bufp, 0) && + !create_move_path(dstpath, dstpkg, buf+bufp, 0)) { movefileordir(srcpath, dstpath, strlen(dstpath)-strlen(buf+bufp), dstuid, dstgid, &s); @@ -750,8 +732,7 @@ int movefiles() UPDATE_COMMANDS_DIR_PREFIX, name, div); } if (srcpkg[0] != 0) { - if (!create_pkg_path(srcpath, PKG_DIR_PREFIX, srcpkg, - PKG_DIR_POSTFIX)) { + if (!create_pkg_path(srcpath, srcpkg, PKG_DIR_POSTFIX, 0)) { if (lstat(srcpath, &s) < 0) { // Package no longer exists -- skip. srcpkg[0] = 0; @@ -762,8 +743,7 @@ int movefiles() div, UPDATE_COMMANDS_DIR_PREFIX, name); } if (srcpkg[0] != 0) { - if (!create_pkg_path(dstpath, PKG_DIR_PREFIX, dstpkg, - PKG_DIR_POSTFIX)) { + if (!create_pkg_path(dstpath, dstpkg, PKG_DIR_POSTFIX, 0)) { if (lstat(dstpath, &s) == 0) { dstuid = s.st_uid; dstgid = s.st_gid; diff --git a/cmds/installd/installd.c b/cmds/installd/installd.c index d2b2f7f9fc60..e0d0f97b3094 100644 --- a/cmds/installd/installd.c +++ b/cmds/installd/installd.c @@ -21,7 +21,6 @@ #define TOKEN_MAX 8 /* max number of arguments in buffer */ #define REPLY_MAX 256 /* largest reply allowed */ - static int do_ping(char **arg, char reply[REPLY_MAX]) { return 0; @@ -235,12 +234,77 @@ done: return 0; } -int main(const int argc, const char *argv[]) { +/** + * Initialize all the global variables that are used elsewhere. Returns 0 upon + * success and -1 on error. + */ +void free_globals() { + size_t i; + + for (i = 0; i < android_system_dirs.count; i++) { + if (android_system_dirs.dirs[i].path != NULL) { + free(android_system_dirs.dirs[i].path); + } + } + + free(android_system_dirs.dirs); +} + +int initialize_globals() { + // Get the android data directory. + if (get_path_from_env(&android_data_dir, "ANDROID_DATA") < 0) { + return -1; + } + + // Get the android app directory. + if (copy_and_append(&android_app_dir, &android_data_dir, APP_SUBDIR) < 0) { + return -1; + } + + // Get the android protected app directory. + if (copy_and_append(&android_app_private_dir, &android_data_dir, PRIVATE_APP_SUBDIR) < 0) { + return -1; + } + + // Get the sd-card ASEC mount point. + if (get_path_from_env(&android_asec_dir, "ASEC_MOUNTPOINT") < 0) { + return -1; + } + + // Take note of the system and vendor directories. + android_system_dirs.count = 2; + + android_system_dirs.dirs = calloc(android_system_dirs.count, sizeof(dir_rec_t)); + if (android_system_dirs.dirs == NULL) { + LOGE("Couldn't allocate array for dirs; aborting\n"); + return -1; + } + + // system + if (get_path_from_env(&android_system_dirs.dirs[0], "ANDROID_ROOT") < 0) { + free_globals(); + return -1; + } + + // vendor + // TODO replace this with an environment variable (doesn't exist yet) + android_system_dirs.dirs[1].path = "/vendor/"; + android_system_dirs.dirs[1].len = strlen(android_system_dirs.dirs[1].path); + + return 0; +} + +int main(const int argc, const char *argv[]) { char buf[BUFFER_MAX]; struct sockaddr addr; socklen_t alen; int lsocket, s, count; + if (initialize_globals() < 0) { + LOGE("Could not initialize globals; exiting.\n"); + exit(1); + } + lsocket = android_get_control_socket(SOCKET_PATH); if (lsocket < 0) { LOGE("Failed to get socket from environment: %s\n", strerror(errno)); diff --git a/cmds/installd/installd.h b/cmds/installd/installd.h index 77b58ec10692..cbca135c3043 100644 --- a/cmds/installd/installd.h +++ b/cmds/installd/installd.h @@ -49,37 +49,60 @@ /* elements combined with a valid package name to form paths */ -#define PKG_DIR_PREFIX "/data/data/" +#define PRIMARY_USER_PREFIX "data/" +#define SECONDARY_USER_PREFIX "user/" + #define PKG_DIR_POSTFIX "" -#define PKG_LIB_PREFIX "/data/data/" #define PKG_LIB_POSTFIX "/lib" -#define CACHE_DIR_PREFIX "/data/data/" #define CACHE_DIR_POSTFIX "/cache" -#define APK_DIR_PREFIX "/data/app/" +#define APP_SUBDIR "app/" // sub-directory under ANDROID_DATA /* other handy constants */ -#define PROTECTED_DIR_PREFIX "/data/app-private/" -#define SDCARD_DIR_PREFIX getenv("ASEC_MOUNTPOINT") +#define PRIVATE_APP_SUBDIR "app-private/" // sub-directory under ANDROID_DATA -#define DALVIK_CACHE_PREFIX "/data/dalvik-cache/" -#define DALVIK_CACHE_POSTFIX "/classes.dex" +#define DALVIK_CACHE_PREFIX "/data/dalvik-cache/" +#define DALVIK_CACHE_POSTFIX "/classes.dex" #define UPDATE_COMMANDS_DIR_PREFIX "/system/etc/updatecmds/" #define PKG_NAME_MAX 128 /* largest allowed package name */ #define PKG_PATH_MAX 256 /* max size of any path we use */ +/* data structures */ + +typedef struct { + char* path; + size_t len; +} dir_rec_t; + +typedef struct { + size_t count; + dir_rec_t* dirs; +} dir_rec_array_t; + +extern dir_rec_t android_app_dir; +extern dir_rec_t android_app_private_dir; +extern dir_rec_t android_data_dir; +extern dir_rec_t android_asec_dir; +extern dir_rec_array_t android_system_dirs; /* util.c */ +int create_pkg_path_in_dir(char path[PKG_PATH_MAX], + const dir_rec_t* dir, + const char* pkgname, + const char* postfix); + int create_pkg_path(char path[PKG_PATH_MAX], - const char *prefix, const char *pkgname, - const char *postfix); + const char *postfix, + uid_t persona); + +int is_valid_package_name(const char* pkgname); int create_cache_path(char path[PKG_PATH_MAX], const char *src); @@ -89,6 +112,18 @@ int delete_dir_contents(const char *pathname, int delete_dir_contents_fd(int dfd, const char *name); +int validate_system_app_path(const char* path); + +int get_path_from_env(dir_rec_t* rec, const char* var); + +int get_path_from_string(dir_rec_t* rec, const char* path); + +int copy_and_append(dir_rec_t* dst, const dir_rec_t* src, const char* suffix); + +int validate_apk_path(const char *path); + +int append_and_increment(char** dst, const char* src, size_t* dst_size); + /* commands.c */ int install(const char *pkgname, uid_t uid, gid_t gid); diff --git a/cmds/installd/tests/Android.mk b/cmds/installd/tests/Android.mk new file mode 100644 index 000000000000..e53378d9f724 --- /dev/null +++ b/cmds/installd/tests/Android.mk @@ -0,0 +1,42 @@ +# Build the unit tests for installd +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +ifneq ($(TARGET_SIMULATOR),true) + +# Build the unit tests. +test_src_files := \ + installd_utils_test.cpp + +shared_libraries := \ + libutils \ + libcutils \ + libstlport + +static_libraries := \ + libinstalld \ + libdiskusage \ + libgtest \ + libgtest_main + +c_includes := \ + frameworks/base/cmds/installd \ + bionic \ + bionic/libstdc++/include \ + external/gtest/include \ + external/stlport/stlport + +module_tags := eng tests + +$(foreach file,$(test_src_files), \ + $(eval include $(CLEAR_VARS)) \ + $(eval LOCAL_SHARED_LIBRARIES := $(shared_libraries)) \ + $(eval LOCAL_STATIC_LIBRARIES := $(static_libraries)) \ + $(eval LOCAL_SRC_FILES := $(file)) \ + $(eval LOCAL_C_INCLUDES := $(c_includes)) \ + $(eval LOCAL_MODULE := $(notdir $(file:%.cpp=%))) \ + $(eval LOCAL_MODULE_TAGS := $(module_tags)) \ + $(eval include $(BUILD_EXECUTABLE)) \ +) + +endif diff --git a/cmds/installd/tests/installd_utils_test.cpp b/cmds/installd/tests/installd_utils_test.cpp new file mode 100644 index 000000000000..1128fceca0af --- /dev/null +++ b/cmds/installd/tests/installd_utils_test.cpp @@ -0,0 +1,383 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <stdlib.h> +#include <string.h> + +#define LOG_TAG "utils_test" +#include <utils/Log.h> + +#include <gtest/gtest.h> + +extern "C" { +#include "installd.h" +} + +#define TEST_DATA_DIR "/data/" +#define TEST_APP_DIR "/data/app/" +#define TEST_APP_PRIVATE_DIR "/data/app-private/" +#define TEST_ASEC_DIR "/mnt/asec/" + +#define TEST_SYSTEM_DIR1 "/system/app/" +#define TEST_SYSTEM_DIR2 "/vendor/app/" + +namespace android { + +class UtilsTest : public testing::Test { +protected: + virtual void SetUp() { + android_app_dir.path = TEST_APP_DIR; + android_app_dir.len = strlen(TEST_APP_DIR); + + android_app_private_dir.path = TEST_APP_PRIVATE_DIR; + android_app_private_dir.len = strlen(TEST_APP_PRIVATE_DIR); + + android_data_dir.path = TEST_DATA_DIR; + android_data_dir.len = strlen(TEST_DATA_DIR); + + android_asec_dir.path = TEST_ASEC_DIR; + android_asec_dir.len = strlen(TEST_ASEC_DIR); + + android_system_dirs.count = 2; + + android_system_dirs.dirs = (dir_rec_t*) calloc(android_system_dirs.count, sizeof(dir_rec_t)); + android_system_dirs.dirs[0].path = TEST_SYSTEM_DIR1; + android_system_dirs.dirs[0].len = strlen(TEST_SYSTEM_DIR1); + + android_system_dirs.dirs[1].path = TEST_SYSTEM_DIR2; + android_system_dirs.dirs[1].len = strlen(TEST_SYSTEM_DIR2); + } + + virtual void TearDown() { + free(android_system_dirs.dirs); + } +}; + +TEST_F(UtilsTest, IsValidApkPath_BadPrefix) { + // Bad prefixes directories + const char *badprefix1 = "/etc/passwd"; + EXPECT_EQ(-1, validate_apk_path(badprefix1)) + << badprefix1 << " should be allowed as a valid path"; + + const char *badprefix2 = "../.." TEST_APP_DIR "../../../blah"; + EXPECT_EQ(-1, validate_apk_path(badprefix2)) + << badprefix2 << " should be allowed as a valid path"; + + const char *badprefix3 = "init.rc"; + EXPECT_EQ(-1, validate_apk_path(badprefix3)) + << badprefix3 << " should be allowed as a valid path"; + + const char *badprefix4 = "/init.rc"; + EXPECT_EQ(-1, validate_apk_path(badprefix4)) + << badprefix4 << " should be allowed as a valid path"; +} + +TEST_F(UtilsTest, IsValidApkPath_Internal) { + // Internal directories + const char *internal1 = TEST_APP_DIR "example.apk"; + EXPECT_EQ(0, validate_apk_path(internal1)) + << internal1 << " should be allowed as a valid path"; + + const char *badint1 = TEST_APP_DIR "../example.apk"; + EXPECT_EQ(-1, validate_apk_path(badint1)) + << badint1 << " should be rejected as a invalid path"; + + const char *badint2 = TEST_APP_DIR "/../example.apk"; + EXPECT_EQ(-1, validate_apk_path(badint2)) + << badint2 << " should be rejected as a invalid path"; + + const char *badint3 = TEST_APP_DIR "example.com/pkg.apk"; + EXPECT_EQ(-1, validate_apk_path(badint3)) + << badint3 << " should be rejected as a invalid path"; +} + +TEST_F(UtilsTest, IsValidApkPath_Private) { + // Internal directories + const char *private1 = TEST_APP_PRIVATE_DIR "example.apk"; + EXPECT_EQ(0, validate_apk_path(private1)) + << private1 << " should be allowed as a valid path"; + + const char *badpriv1 = TEST_APP_PRIVATE_DIR "../example.apk"; + EXPECT_EQ(-1, validate_apk_path(badpriv1)) + << badpriv1 << " should be rejected as a invalid path"; + + const char *badpriv2 = TEST_APP_PRIVATE_DIR "/../example.apk"; + EXPECT_EQ(-1, validate_apk_path(badpriv2)) + << badpriv2 << " should be rejected as a invalid path"; + + const char *badpriv3 = TEST_APP_PRIVATE_DIR "example.com/pkg.apk"; + EXPECT_EQ(-1, validate_apk_path(badpriv3)) + << badpriv3 << " should be rejected as a invalid path"; +} + + +TEST_F(UtilsTest, IsValidApkPath_AsecGood1) { + const char *asec1 = TEST_ASEC_DIR "example.apk"; + EXPECT_EQ(0, validate_apk_path(asec1)) + << asec1 << " should be allowed as a valid path"; +} + +TEST_F(UtilsTest, IsValidApkPath_AsecGood2) { + const char *asec2 = TEST_ASEC_DIR "com.example.asec/pkg.apk"; + EXPECT_EQ(0, validate_apk_path(asec2)) + << asec2 << " should be allowed as a valid path"; +} + +TEST_F(UtilsTest, IsValidApkPath_EscapeFail) { + const char *badasec1 = TEST_ASEC_DIR "../example.apk"; + EXPECT_EQ(-1, validate_apk_path(badasec1)) + << badasec1 << " should be rejected as a invalid path"; +} + +TEST_F(UtilsTest, IsValidApkPath_DoubleSlashFail) { + const char *badasec2 = TEST_ASEC_DIR "com.example.asec//pkg.apk"; + EXPECT_EQ(-1, validate_apk_path(badasec2)) + << badasec2 << " should be rejected as a invalid path"; +} + +TEST_F(UtilsTest, IsValidApkPath_SubdirEscapeFail) { + const char *badasec3 = TEST_ASEC_DIR "com.example.asec/../../../pkg.apk"; + EXPECT_EQ(-1, validate_apk_path(badasec3)) + << badasec3 << " should be rejected as a invalid path"; +} + +TEST_F(UtilsTest, IsValidApkPath_SlashEscapeFail) { + const char *badasec4 = TEST_ASEC_DIR "/../example.apk"; + EXPECT_EQ(-1, validate_apk_path(badasec4)) + << badasec4 << " should be rejected as a invalid path"; +} + +TEST_F(UtilsTest, IsValidApkPath_CrazyDirFail) { + const char *badasec5 = TEST_ASEC_DIR ".//../.."; + EXPECT_EQ(-1, validate_apk_path(badasec5)) + << badasec5 << " should be rejected as a invalid path"; +} + +TEST_F(UtilsTest, IsValidApkPath_SubdirEscapeSingleFail) { + const char *badasec6 = TEST_ASEC_DIR "com.example.asec/../pkg.apk"; + EXPECT_EQ(-1, validate_apk_path(badasec6)) + << badasec6 << " should be rejected as a invalid path"; +} + +TEST_F(UtilsTest, IsValidApkPath_TwoSubdirFail) { + const char *badasec7 = TEST_ASEC_DIR "com.example.asec/subdir1/pkg.apk"; + EXPECT_EQ(-1, validate_apk_path(badasec7)) + << badasec7 << " should be rejected as a invalid path"; +} + +TEST_F(UtilsTest, CheckSystemApp_Dir1) { + const char *sysapp1 = TEST_SYSTEM_DIR1 "Voice.apk"; + EXPECT_EQ(0, validate_system_app_path(sysapp1)) + << sysapp1 << " should be allowed as a system path"; +} + +TEST_F(UtilsTest, CheckSystemApp_Dir2) { + const char *sysapp2 = TEST_SYSTEM_DIR2 "com.example.myapp.apk"; + EXPECT_EQ(0, validate_system_app_path(sysapp2)) + << sysapp2 << " should be allowed as a system path"; +} + +TEST_F(UtilsTest, CheckSystemApp_EscapeFail) { + const char *badapp1 = TEST_SYSTEM_DIR1 "../com.example.apk"; + EXPECT_EQ(-1, validate_system_app_path(badapp1)) + << badapp1 << " should be rejected not a system path"; +} + +TEST_F(UtilsTest, CheckSystemApp_DoubleEscapeFail) { + const char *badapp2 = TEST_SYSTEM_DIR2 "/../../com.example.apk"; + EXPECT_EQ(-1, validate_system_app_path(badapp2)) + << badapp2 << " should be rejected not a system path"; +} + +TEST_F(UtilsTest, CheckSystemApp_BadPathEscapeFail) { + const char *badapp3 = TEST_APP_DIR "/../../com.example.apk"; + EXPECT_EQ(-1, validate_system_app_path(badapp3)) + << badapp3 << " should be rejected not a system path"; +} + +TEST_F(UtilsTest, GetPathFromString_NullPathFail) { + dir_rec_t test1; + EXPECT_EQ(-1, get_path_from_string(&test1, NULL)) + << "Should not allow NULL as a path."; +} + +TEST_F(UtilsTest, GetPathFromString_EmptyPathFail) { + dir_rec_t test1; + EXPECT_EQ(-1, get_path_from_string(&test1, "")) + << "Should not allow empty paths."; +} + +TEST_F(UtilsTest, GetPathFromString_RelativePathFail) { + dir_rec_t test1; + EXPECT_EQ(-1, get_path_from_string(&test1, "mnt/asec")) + << "Should not allow relative paths."; +} + +TEST_F(UtilsTest, GetPathFromString_NonCanonical) { + dir_rec_t test1; + + EXPECT_EQ(0, get_path_from_string(&test1, "/mnt/asec")) + << "Should be able to canonicalize directory /mnt/asec"; + EXPECT_STREQ("/mnt/asec/", test1.path) + << "/mnt/asec should be canonicalized to /mnt/asec/"; + EXPECT_EQ(10, (ssize_t) test1.len) + << "path len should be equal to the length of /mnt/asec/ (10)"; + free(test1.path); +} + +TEST_F(UtilsTest, GetPathFromString_CanonicalPath) { + dir_rec_t test3; + EXPECT_EQ(0, get_path_from_string(&test3, "/data/app/")) + << "Should be able to canonicalize directory /data/app/"; + EXPECT_STREQ("/data/app/", test3.path) + << "/data/app/ should be canonicalized to /data/app/"; + EXPECT_EQ(10, (ssize_t) test3.len) + << "path len should be equal to the length of /data/app/ (10)"; + free(test3.path); +} + +TEST_F(UtilsTest, CreatePkgPath_LongPkgNameSuccess) { + char path[PKG_PATH_MAX]; + + // Create long packagename of "aaaaa..." + size_t pkgnameSize = PKG_NAME_MAX; + char pkgname[pkgnameSize + 1]; + memset(pkgname, 'a', pkgnameSize); + pkgname[pkgnameSize] = '\0'; + + EXPECT_EQ(0, create_pkg_path(path, pkgname, "", 0)) + << "Should successfully be able to create package name."; + + const char *prefix = TEST_DATA_DIR PRIMARY_USER_PREFIX; + size_t offset = strlen(prefix); + EXPECT_STREQ(pkgname, path + offset) + << "Package path should be a really long string of a's"; +} + +TEST_F(UtilsTest, CreatePkgPath_LongPkgNameFail) { + char path[PKG_PATH_MAX]; + + // Create long packagename of "aaaaa..." + size_t pkgnameSize = PKG_NAME_MAX + 1; + char pkgname[pkgnameSize + 1]; + memset(pkgname, 'a', pkgnameSize); + pkgname[pkgnameSize] = '\0'; + + EXPECT_EQ(-1, create_pkg_path(path, pkgname, "", 0)) + << "Should return error because package name is too long."; +} + +TEST_F(UtilsTest, CreatePkgPath_LongPostfixFail) { + char path[PKG_PATH_MAX]; + + // Create long packagename of "aaaaa..." + size_t postfixSize = PKG_PATH_MAX; + char postfix[postfixSize + 1]; + memset(postfix, 'a', postfixSize); + postfix[postfixSize] = '\0'; + + EXPECT_EQ(-1, create_pkg_path(path, "com.example.package", postfix, 0)) + << "Should return error because postfix is too long."; +} + +TEST_F(UtilsTest, CreatePkgPath_PrimaryUser) { + char path[PKG_PATH_MAX]; + + EXPECT_EQ(0, create_pkg_path(path, "com.example.package", "", 0)) + << "Should return error because postfix is too long."; + + EXPECT_STREQ(TEST_DATA_DIR PRIMARY_USER_PREFIX "com.example.package", path) + << "Package path should be in /data/data/"; +} + +TEST_F(UtilsTest, CreatePkgPath_SecondaryUser) { + char path[PKG_PATH_MAX]; + + EXPECT_EQ(0, create_pkg_path(path, "com.example.package", "", 1)) + << "Should successfully create package path."; + + EXPECT_STREQ(TEST_DATA_DIR SECONDARY_USER_PREFIX "1/com.example.package", path) + << "Package path should be in /data/user/"; +} + +TEST_F(UtilsTest, CreatePkgPathInDir_ProtectedDir) { + char path[PKG_PATH_MAX]; + + dir_rec_t dir; + dir.path = "/data/app-private/"; + dir.len = strlen(dir.path); + + EXPECT_EQ(0, create_pkg_path_in_dir(path, &dir, "com.example.package", ".apk")) + << "Should successfully create package path."; + + EXPECT_STREQ("/data/app-private/com.example.package.apk", path) + << "Package path should be in /data/app-private/"; +} + +TEST_F(UtilsTest, CopyAndAppend_Normal) { + //int copy_and_append(dir_rec_t* dst, dir_rec_t* src, char* suffix) + dir_rec_t dst; + dir_rec_t src; + + src.path = "/data/"; + src.len = strlen(src.path); + + EXPECT_EQ(0, copy_and_append(&dst, &src, "app/")) + << "Should return error because postfix is too long."; + + EXPECT_STREQ("/data/app/", dst.path) + << "Appended path should be correct"; + + EXPECT_EQ(10, (ssize_t) dst.len) + << "Appended path should be length of '/data/app/' (10)"; +} + +TEST_F(UtilsTest, AppendAndIncrement_Normal) { + size_t dst_size = 10; + char dst[dst_size]; + char *dstp = dst; + const char* src = "FOO"; + + EXPECT_EQ(0, append_and_increment(&dstp, src, &dst_size)) + << "String should append successfully"; + + EXPECT_STREQ("FOO", dst) + << "String should append correctly"; + + EXPECT_EQ(0, append_and_increment(&dstp, src, &dst_size)) + << "String should append successfully again"; + + EXPECT_STREQ("FOOFOO", dst) + << "String should append correctly again"; +} + +TEST_F(UtilsTest, AppendAndIncrement_TooBig) { + size_t dst_size = 5; + char dst[dst_size]; + char *dstp = dst; + const char* src = "FOO"; + + EXPECT_EQ(0, append_and_increment(&dstp, src, &dst_size)) + << "String should append successfully"; + + EXPECT_STREQ("FOO", dst) + << "String should append correctly"; + + EXPECT_EQ(-1, append_and_increment(&dstp, src, &dst_size)) + << "String should fail because it's too large to fit"; +} + +} diff --git a/cmds/installd/utils.c b/cmds/installd/utils.c index a5e4b5a1557d..f37a6fbae152 100644 --- a/cmds/installd/utils.c +++ b/cmds/installd/utils.c @@ -16,24 +16,93 @@ #include "installd.h" +int create_pkg_path_in_dir(char path[PKG_PATH_MAX], + const dir_rec_t* dir, + const char* pkgname, + const char* postfix) +{ + const size_t postfix_len = strlen(postfix); + + const size_t pkgname_len = strlen(pkgname); + if (pkgname_len > PKG_NAME_MAX) { + return -1; + } + + if (is_valid_package_name(pkgname) < 0) { + return -1; + } + + if ((pkgname_len + dir->len + postfix_len) >= PKG_PATH_MAX) { + return -1; + } + + char *dst = path; + size_t dst_size = PKG_PATH_MAX; + + if (append_and_increment(&dst, dir->path, &dst_size) < 0 + || append_and_increment(&dst, pkgname, &dst_size) < 0 + || append_and_increment(&dst, postfix, &dst_size) < 0) { + LOGE("Error building APK path"); + return -1; + } + + return 0; +} + +/** + * Create the package path name for a given package name with a postfix for + * a certain persona. Returns 0 on success, and -1 on failure. + */ int create_pkg_path(char path[PKG_PATH_MAX], - const char *prefix, const char *pkgname, - const char *postfix) + const char *postfix, + uid_t persona) { - int len; - const char *x; + size_t uid_len; + char* persona_prefix; + if (persona == 0) { + persona_prefix = PRIMARY_USER_PREFIX; + uid_len = 0; + } else { + persona_prefix = SECONDARY_USER_PREFIX; + uid_len = snprintf(NULL, 0, "%d", persona); + } + + const size_t prefix_len = android_data_dir.len + strlen(persona_prefix) + uid_len + 1 /*slash*/; + char prefix[prefix_len + 1]; - len = strlen(pkgname); - if (len > PKG_NAME_MAX) { + char *dst = prefix; + size_t dst_size = sizeof(prefix); + + if (append_and_increment(&dst, android_data_dir.path, &dst_size) < 0 + || append_and_increment(&dst, persona_prefix, &dst_size) < 0) { + LOGE("Error building prefix for APK path"); return -1; } - if ((len + strlen(prefix) + strlen(postfix)) >= PKG_PATH_MAX) { - return -1; + + if (persona != 0) { + int ret = snprintf(dst, dst_size, "%d/", persona); + if (ret < 0 || (size_t) ret != uid_len + 1) { + LOGW("Error appending UID to APK path"); + return -1; + } } - x = pkgname; + dir_rec_t dir; + dir.path = prefix; + dir.len = prefix_len; + + return create_pkg_path_in_dir(path, &dir, pkgname, postfix); +} + +/** + * Checks whether the package name is valid. Returns -1 on error and + * 0 on success. + */ +int is_valid_package_name(const char* pkgname) { + const char *x = pkgname; int alpha = -1; + while (*x) { if (isalnum(*x) || (*x == '_')) { /* alphanumeric or underscore are fine */ @@ -47,13 +116,15 @@ int create_pkg_path(char path[PKG_PATH_MAX], /* Suffix -X is fine to let versioning of packages. But whatever follows should be alphanumeric.*/ alpha = 1; - }else { + } else { /* anything not A-Z, a-z, 0-9, _, or . is invalid */ LOGE("invalid package name '%s'\n", pkgname); return -1; } + x++; } + if (alpha == 1) { // Skip current character x++; @@ -66,7 +137,6 @@ int create_pkg_path(char path[PKG_PATH_MAX], } } - sprintf(path, "%s%s%s", prefix, pkgname, postfix); return 0; } @@ -171,3 +241,170 @@ int delete_dir_contents_fd(int dfd, const char *name) closedir(d); return res; } + +/** + * Checks whether a path points to a system app (.apk file). Returns 0 + * if it is a system app or -1 if it is not. + */ +int validate_system_app_path(const char* path) { + size_t i; + + for (i = 0; i < android_system_dirs.count; i++) { + const size_t dir_len = android_system_dirs.dirs[i].len; + if (!strncmp(path, android_system_dirs.dirs[i].path, dir_len)) { + if (path[dir_len] == '.' || strchr(path + dir_len, '/') != NULL) { + LOGE("invalid system apk path '%s' (trickery)\n", path); + return -1; + } + return 0; + } + } + + return -1; +} + +/** + * Get the contents of a environment variable that contains a path. Caller + * owns the string that is inserted into the directory record. Returns + * 0 on success and -1 on error. + */ +int get_path_from_env(dir_rec_t* rec, const char* var) { + const char* path = getenv(var); + int ret = get_path_from_string(rec, path); + if (ret < 0) { + LOGW("Problem finding value for environment variable %s\n", var); + } + return ret; +} + +/** + * Puts the string into the record as a directory. Appends '/' to the end + * of all paths. Caller owns the string that is inserted into the directory + * record. A null value will result in an error. + * + * Returns 0 on success and -1 on error. + */ +int get_path_from_string(dir_rec_t* rec, const char* path) { + if (path == NULL) { + return -1; + } else { + const size_t path_len = strlen(path); + if (path_len <= 0) { + return -1; + } + + // Make sure path is absolute. + if (path[0] != '/') { + return -1; + } + + if (path[path_len - 1] == '/') { + // Path ends with a forward slash. Make our own copy. + + rec->path = strdup(path); + if (rec->path == NULL) { + return -1; + } + + rec->len = path_len; + } else { + // Path does not end with a slash. Generate a new string. + char *dst; + + // Add space for slash and terminating null. + size_t dst_size = path_len + 2; + + rec->path = malloc(dst_size); + if (rec->path == NULL) { + return -1; + } + + dst = rec->path; + + if (append_and_increment(&dst, path, &dst_size) < 0 + || append_and_increment(&dst, "/", &dst_size)) { + LOGE("Error canonicalizing path"); + return -1; + } + + rec->len = dst - rec->path; + } + } + return 0; +} + +int copy_and_append(dir_rec_t* dst, const dir_rec_t* src, const char* suffix) { + dst->len = src->len + strlen(suffix); + const size_t dstSize = dst->len + 1; + dst->path = (char*) malloc(dstSize); + + if (dst->path == NULL + || snprintf(dst->path, dstSize, "%s%s", src->path, suffix) + != (ssize_t) dst->len) { + LOGE("Could not allocate memory to hold appended path; aborting\n"); + return -1; + } + + return 0; +} + +/** + * Check whether path points to a valid path for an APK file. An ASEC + * directory is allowed to have one level of subdirectory names. Returns -1 + * when an invalid path is encountered and 0 when a valid path is encountered. + */ +int validate_apk_path(const char *path) +{ + int allowsubdir = 0; + char *subdir = NULL; + size_t dir_len; + size_t path_len; + + if (!strncmp(path, android_app_dir.path, android_app_dir.len)) { + dir_len = android_app_dir.len; + } else if (!strncmp(path, android_app_private_dir.path, android_app_private_dir.len)) { + dir_len = android_app_private_dir.len; + } else if (!strncmp(path, android_asec_dir.path, android_asec_dir.len)) { + dir_len = android_asec_dir.len; + allowsubdir = 1; + } else { + LOGE("invalid apk path '%s' (bad prefix)\n", path); + return -1; + } + + path_len = strlen(path); + + /* + * Only allow the path to have a subdirectory if it's been marked as being allowed. + */ + if ((subdir = strchr(path + dir_len, '/')) != NULL) { + ++subdir; + if (!allowsubdir + || (path_len > (size_t) (subdir - path) && (strchr(subdir, '/') != NULL))) { + LOGE("invalid apk path '%s' (subdir?)\n", path); + return -1; + } + } + + /* + * Directories can't have a period directly after the directory markers + * to prevent ".." + */ + if (path[dir_len] == '.' + || (subdir != NULL && ((*subdir == '.') || (strchr(subdir, '/') != NULL)))) { + LOGE("invalid apk path '%s' (trickery)\n", path); + return -1; + } + + return 0; +} + +int append_and_increment(char** dst, const char* src, size_t* dst_size) { + ssize_t ret = strlcpy(*dst, src, *dst_size); + if (ret < 0 || (size_t) ret >= *dst_size) { + return -1; + } + *dst += ret; + *dst_size -= ret; + return 0; +} diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java index 46f611fba8cb..64c437d1cda1 100644 --- a/core/java/android/content/pm/ActivityInfo.java +++ b/core/java/android/content/pm/ActivityInfo.java @@ -334,6 +334,12 @@ public class ActivityInfo extends ComponentInfo public static final int CONFIG_UI_MODE = 0x0200; /** * Bit in {@link #configChanges} that indicates that the activity + * can itself handle the screen size. Set from the + * {@link android.R.attr#configChanges} attribute. + */ + public static final int CONFIG_SCREEN_SIZE = 0x0400; + /** + * Bit in {@link #configChanges} that indicates that the activity * can itself handle changes to the font scaling factor. Set from the * {@link android.R.attr#configChanges} attribute. This is * not a core resource configutation, but a higher-level value, so its @@ -341,6 +347,37 @@ public class ActivityInfo extends ComponentInfo */ public static final int CONFIG_FONT_SCALE = 0x40000000; + /** @hide + * Unfortunately the constants for config changes in native code are + * different from ActivityInfo. :( Here are the values we should use for the + * native side given the bit we have assigned in ActivityInfo. + */ + public static int[] CONFIG_NATIVE_BITS = new int[] { + 0x0001, // MNC + 0x0002, // MCC + 0x0004, // LOCALE + 0x0008, // TOUCH SCREEN + 0x0010, // KEYBOARD + 0x0020, // KEYBOARD HIDDEN + 0x0040, // NAVIGATION + 0x0080, // ORIENTATION + 0x0800, // SCREEN LAYOUT + 0x1000, // UI MODE + 0x0200, // SCREEN SIZE + }; + /** @hide + * Convert Java change bits to native. + */ + public static int activityInfoConfigToNative(int input) { + int output = 0; + for (int i=0; i<CONFIG_NATIVE_BITS.length; i++) { + if ((input&(1<<i)) != 0) { + output |= CONFIG_NATIVE_BITS[i]; + } + } + return output; + } + /** * Bit mask of kinds of configuration changes that this activity * can handle itself (without being restarted by the system). diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index 7ebfda4b8f13..8dfdaa8daa50 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -396,7 +396,7 @@ public class PackageParser { int cookie = assmgr.addAssetPath(mArchiveSourcePath); if (cookie != 0) { res = new Resources(assmgr, metrics, null); - assmgr.setConfiguration(0, 0, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + assmgr.setConfiguration(0, 0, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, Build.VERSION.RESOURCES_SDK_INT); parser = assmgr.openXmlResourceParser(cookie, "AndroidManifest.xml"); assetError = false; @@ -596,7 +596,7 @@ public class PackageParser { AssetManager assmgr = null; try { assmgr = new AssetManager(); - assmgr.setConfiguration(0, 0, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + assmgr.setConfiguration(0, 0, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, Build.VERSION.RESOURCES_SDK_INT); int cookie = assmgr.addAssetPath(packageFilePath); parser = assmgr.openXmlResourceParser(cookie, "AndroidManifest.xml"); @@ -1931,6 +1931,10 @@ public class PackageParser { a.info.configChanges = sa.getInt( com.android.internal.R.styleable.AndroidManifestActivity_configChanges, 0); + if (owner.applicationInfo.targetSdkVersion + < android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) { + a.info.configChanges |= ActivityInfo.CONFIG_SCREEN_SIZE; + } a.info.softInputMode = sa.getInt( com.android.internal.R.styleable.AndroidManifestActivity_windowSoftInputMode, 0); diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java index e279f64fb7bc..afa68c3cc373 100644 --- a/core/java/android/content/res/AssetManager.java +++ b/core/java/android/content/res/AssetManager.java @@ -652,7 +652,8 @@ public final class AssetManager { public native final void setConfiguration(int mcc, int mnc, String locale, int orientation, int touchscreen, int density, int keyboard, int keyboardHidden, int navigation, int screenWidth, int screenHeight, - int screenLayout, int uiMode, int majorVersion); + int screenWidthDp, int screenHeightDp, int screenLayout, int uiMode, + int majorVersion); /** * Retrieve the resource identifier for the given resource name. diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java index 72fa07c40d9d..28ba4e7c119d 100644 --- a/core/java/android/content/res/Configuration.java +++ b/core/java/android/content/res/Configuration.java @@ -241,6 +241,20 @@ public final class Configuration implements Parcelable, Comparable<Configuration */ public int uiMode; + public static final int SCREEN_WIDTH_DP_UNDEFINED = 0; + + /** + * The current width of the available screen space, in dp units. + */ + public int screenWidthDp; + + public static final int SCREEN_HEIGHT_DP_UNDEFINED = 0; + + /** + * The current height of the available screen space, in dp units. + */ + public int screenHeightDp; + /** * @hide Internal book-keeping. */ @@ -278,6 +292,8 @@ public final class Configuration implements Parcelable, Comparable<Configuration orientation = o.orientation; screenLayout = o.screenLayout; uiMode = o.uiMode; + screenWidthDp = o.screenWidthDp; + screenHeightDp = o.screenHeightDp; seq = o.seq; } @@ -316,6 +332,10 @@ public final class Configuration implements Parcelable, Comparable<Configuration sb.append(java.lang.Integer.toHexString(screenLayout)); sb.append(" uiMode=0x"); sb.append(java.lang.Integer.toHexString(uiMode)); + sb.append(" wdp="); + sb.append(screenWidthDp); + sb.append(" hdp="); + sb.append(screenHeightDp); if (seq != 0) { sb.append(" seq="); sb.append(seq); @@ -341,6 +361,8 @@ public final class Configuration implements Parcelable, Comparable<Configuration orientation = ORIENTATION_UNDEFINED; screenLayout = SCREENLAYOUT_SIZE_UNDEFINED; uiMode = UI_MODE_TYPE_UNDEFINED; + screenWidthDp = SCREEN_WIDTH_DP_UNDEFINED; + screenHeightDp = SCREEN_HEIGHT_DP_UNDEFINED; seq = 0; } @@ -434,6 +456,16 @@ public final class Configuration implements Parcelable, Comparable<Configuration | (delta.uiMode&UI_MODE_NIGHT_MASK); } } + if (delta.screenWidthDp != SCREEN_WIDTH_DP_UNDEFINED + && screenWidthDp != delta.screenWidthDp) { + changed |= ActivityInfo.CONFIG_SCREEN_SIZE; + screenWidthDp = delta.screenWidthDp; + } + if (delta.screenHeightDp != SCREEN_HEIGHT_DP_UNDEFINED + && screenHeightDp != delta.screenHeightDp) { + changed |= ActivityInfo.CONFIG_SCREEN_SIZE; + screenHeightDp = delta.screenHeightDp; + } if (delta.seq != 0) { seq = delta.seq; @@ -463,9 +495,11 @@ public final class Configuration implements Parcelable, Comparable<Configuration * {@link android.content.pm.ActivityInfo#CONFIG_NAVIGATION * PackageManager.ActivityInfo.CONFIG_NAVIGATION}, * {@link android.content.pm.ActivityInfo#CONFIG_ORIENTATION - * PackageManager.ActivityInfo.CONFIG_ORIENTATION}, or + * PackageManager.ActivityInfo.CONFIG_ORIENTATION}, * {@link android.content.pm.ActivityInfo#CONFIG_SCREEN_LAYOUT - * PackageManager.ActivityInfo.CONFIG_SCREEN_LAYOUT}. + * PackageManager.ActivityInfo.CONFIG_SCREEN_LAYOUT}, or + * {@link android.content.pm.ActivityInfo#CONFIG_SCREEN_SIZE + * PackageManager.ActivityInfo.CONFIG_SCREEN_SIZE}. */ public int diff(Configuration delta) { int changed = 0; @@ -518,6 +552,14 @@ public final class Configuration implements Parcelable, Comparable<Configuration && uiMode != delta.uiMode) { changed |= ActivityInfo.CONFIG_UI_MODE; } + if (delta.screenWidthDp != SCREEN_WIDTH_DP_UNDEFINED + && screenWidthDp != delta.screenWidthDp) { + changed |= ActivityInfo.CONFIG_SCREEN_SIZE; + } + if (delta.screenHeightDp != SCREEN_HEIGHT_DP_UNDEFINED + && screenHeightDp != delta.screenHeightDp) { + changed |= ActivityInfo.CONFIG_SCREEN_SIZE; + } return changed; } @@ -599,6 +641,8 @@ public final class Configuration implements Parcelable, Comparable<Configuration dest.writeInt(orientation); dest.writeInt(screenLayout); dest.writeInt(uiMode); + dest.writeInt(screenWidthDp); + dest.writeInt(screenHeightDp); dest.writeInt(seq); } @@ -620,6 +664,8 @@ public final class Configuration implements Parcelable, Comparable<Configuration orientation = source.readInt(); screenLayout = source.readInt(); uiMode = source.readInt(); + screenWidthDp = source.readInt(); + screenHeightDp = source.readInt(); seq = source.readInt(); } @@ -680,6 +726,10 @@ public final class Configuration implements Parcelable, Comparable<Configuration n = this.screenLayout - that.screenLayout; if (n != 0) return n; n = this.uiMode - that.uiMode; + if (n != 0) return n; + n = this.screenWidthDp - that.screenWidthDp; + if (n != 0) return n; + n = this.screenHeightDp - that.screenHeightDp; //if (n != 0) return n; return n; } @@ -704,6 +754,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration + this.touchscreen + this.keyboard + this.keyboardHidden + this.hardKeyboardHidden + this.navigation + this.navigationHidden - + this.orientation + this.screenLayout + this.uiMode; + + this.orientation + this.screenLayout + this.uiMode + + this.screenWidthDp + this.screenHeightDp; } } diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java index 81eb09c1ad99..2e6ae7014421 100755 --- a/core/java/android/content/res/Resources.java +++ b/core/java/android/content/res/Resources.java @@ -21,6 +21,7 @@ import com.android.internal.util.XmlUtils; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; +import android.content.pm.ActivityInfo; import android.graphics.Movie; import android.graphics.drawable.Drawable; import android.graphics.drawable.ColorDrawable; @@ -1404,6 +1405,7 @@ public class Resources { int configChanges = 0xfffffff; if (config != null) { configChanges = mConfiguration.updateFrom(config); + configChanges = ActivityInfo.activityInfoConfigToNative(configChanges); } if (mConfiguration.locale == null) { mConfiguration.locale = Locale.getDefault(); @@ -1443,6 +1445,7 @@ public class Resources { mConfiguration.touchscreen, (int)(mMetrics.density*160), mConfiguration.keyboard, keyboardHidden, mConfiguration.navigation, width, height, + mConfiguration.screenWidthDp, mConfiguration.screenHeightDp, mConfiguration.screenLayout, mConfiguration.uiMode, Build.VERSION.RESOURCES_SDK_INT); diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java index 3bb082100444..24d5369ea6f1 100644 --- a/core/java/android/os/Build.java +++ b/core/java/android/os/Build.java @@ -230,6 +230,11 @@ public class Build { * Newest version of Android, version 3.1. */ public static final int HONEYCOMB_MR1 = 12; + + /** + * Current version under development. + */ + public static final int ICE_CREAM_SANDWICH = CUR_DEVELOPMENT; } /** The type of build, like "user" or "eng". */ diff --git a/core/java/android/os/storage/IMountService.java b/core/java/android/os/storage/IMountService.java index 4c8351597a05..27da3c344880 100644 --- a/core/java/android/os/storage/IMountService.java +++ b/core/java/android/os/storage/IMountService.java @@ -637,6 +637,22 @@ public interface IMountService extends IInterface { } return _result; } + + public String[] getVolumeList() throws RemoteException { + Parcel _data = Parcel.obtain(); + Parcel _reply = Parcel.obtain(); + String[] _result; + try { + _data.writeInterfaceToken(DESCRIPTOR); + mRemote.transact(Stub.TRANSACTION_getVolumeList, _data, _reply, 0); + _reply.readException(); + _result = _reply.readStringArray(); + } finally { + _reply.recycle(); + _data.recycle(); + } + return _result; + } } private static final String DESCRIPTOR = "IMountService"; @@ -699,6 +715,8 @@ public interface IMountService extends IInterface { static final int TRANSACTION_changeEncryptionPassword = IBinder.FIRST_CALL_TRANSACTION + 28; + static final int TRANSACTION_getVolumeList = IBinder.FIRST_CALL_TRANSACTION + 29; + /** * Cast an IBinder object into an IMountService interface, generating a * proxy if needed. @@ -1004,6 +1022,13 @@ public interface IMountService extends IInterface { reply.writeInt(result); return true; } + case TRANSACTION_getVolumeList: { + data.enforceInterface(DESCRIPTOR); + String[] result = getVolumeList(); + reply.writeNoException(); + reply.writeStringArray(result); + return true; + } } return super.onTransact(code, data, reply, flags); } @@ -1179,4 +1204,8 @@ public interface IMountService extends IInterface { */ public int changeEncryptionPassword(String password) throws RemoteException; + /** + * Returns list of all mountable volumes. + */ + public String[] getVolumeList() throws RemoteException; } diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java index 73ac79f302b5..234057b8632e 100644 --- a/core/java/android/os/storage/StorageManager.java +++ b/core/java/android/os/storage/StorageManager.java @@ -527,4 +527,30 @@ public class StorageManager return null; } + + /** + * Gets the state of a volume via its mountpoint. + * @hide + */ + public String getVolumeState(String mountPoint) { + try { + return mMountService.getVolumeState(mountPoint); + } catch (RemoteException e) { + Log.e(TAG, "Failed to get volume state", e); + return null; + } + } + + /** + * Returns list of all mountable volumes. + * @hide + */ + public String[] getVolumeList() { + try { + return mMountService.getVolumeList(); + } catch (RemoteException e) { + Log.e(TAG, "Failed to get volume list", e); + return null; + } + } } diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java index bb8d874ee674..02fd6e4a57d8 100644 --- a/core/java/android/provider/MediaStore.java +++ b/core/java/android/provider/MediaStore.java @@ -346,6 +346,13 @@ public final class MediaStore { */ public interface FileColumns extends MediaColumns { /** + * The MTP storage ID of the file + * <P>Type: INTEGER</P> + * @hide + */ + public static final String STORAGE_ID = "storage_id"; + + /** * The MTP format code of the file * <P>Type: INTEGER</P> * @hide diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 6deb5a01de91..c75b0fe339a2 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -3303,12 +3303,20 @@ public final class Settings { public static final String WIFI_IDLE_MS = "wifi_idle_ms"; /** - * The interval in milliseconds to issue scans when the driver is - * started. This is necessary to allow wifi to connect to an - * access point when the driver is suspended. + * The interval in milliseconds to issue wake up scans when wifi needs + * to connect. This is necessary to connect to an access point when + * device is on the move and the screen is off. * @hide */ - public static final String WIFI_SCAN_INTERVAL_MS = "wifi_scan_interval_ms"; + public static final String WIFI_FRAMEWORK_SCAN_INTERVAL_MS = + "wifi_framework_scan_interval_ms"; + + /** + * The interval in milliseconds to scan as used by the wifi supplicant + * @hide + */ + public static final String WIFI_SUPPLICANT_SCAN_INTERVAL_MS = + "wifi_supplicant_scan_interval_ms"; /** * The interval in milliseconds at which to check packet counts on the diff --git a/core/java/android/server/BluetoothAdapterProperties.java b/core/java/android/server/BluetoothAdapterProperties.java index ae8104bad954..9723f60243fd 100644 --- a/core/java/android/server/BluetoothAdapterProperties.java +++ b/core/java/android/server/BluetoothAdapterProperties.java @@ -76,14 +76,13 @@ class BluetoothAdapterProperties { for (int i = 0; i < properties.length; i++) { String name = properties[i]; String newValue = null; - int len; if (name == null) { Log.e(TAG, "Error:Adapter Property at index " + i + " is null"); continue; } if (name.equals("Devices") || name.equals("UUIDs")) { StringBuilder str = new StringBuilder(); - len = Integer.valueOf(properties[++i]); + int len = Integer.valueOf(properties[++i]); for (int j = 0; j < len; j++) { str.append(properties[++i]); str.append(","); diff --git a/core/java/android/speech/RecognitionListener.java b/core/java/android/speech/RecognitionListener.java index 5eb71d7eb939..bdb3ba9bbc50 100644 --- a/core/java/android/speech/RecognitionListener.java +++ b/core/java/android/speech/RecognitionListener.java @@ -70,7 +70,8 @@ public interface RecognitionListener { * * @param results the recognition results. To retrieve the results in {@code * ArrayList<String>} format use {@link Bundle#getStringArrayList(String)} with - * {@link SpeechRecognizer#RESULTS_RECOGNITION} as a parameter + * {@link SpeechRecognizer#RESULTS_RECOGNITION} as a parameter. A float array of + * confidence values might also be given in {@link SpeechRecognizer#CONFIDENCE_SCORES}. */ void onResults(Bundle results); diff --git a/core/java/android/speech/RecognizerIntent.java b/core/java/android/speech/RecognizerIntent.java index 02c324c791fb..fd709f214bb7 100644 --- a/core/java/android/speech/RecognizerIntent.java +++ b/core/java/android/speech/RecognizerIntent.java @@ -46,7 +46,7 @@ public class RecognizerIntent { } /** - * Starts an activity that will prompt the user for speech and sends it through a + * Starts an activity that will prompt the user for speech and send it through a * speech recognizer. The results will be returned via activity results (in * {@link Activity#onActivityResult}, if you start the intent using * {@link Activity#startActivityForResult(Intent, int)}), or forwarded via a PendingIntent @@ -81,8 +81,8 @@ public class RecognizerIntent { public static final String ACTION_RECOGNIZE_SPEECH = "android.speech.action.RECOGNIZE_SPEECH"; /** - * Starts an activity that will prompt the user for speech, sends it through a - * speech recognizer, and invokes and either displays a web search result or triggers + * Starts an activity that will prompt the user for speech, send it through a + * speech recognizer, and either display a web search result or trigger * another type of action based on the user's speech. * * <p>If you want to avoid triggering any type of action besides web search, you can use @@ -100,11 +100,13 @@ public class RecognizerIntent { * <li>{@link #EXTRA_MAX_RESULTS} * <li>{@link #EXTRA_PARTIAL_RESULTS} * <li>{@link #EXTRA_WEB_SEARCH_ONLY} + * <li>{@link #EXTRA_ORIGIN} * </ul> * * <p> Result extras (returned in the result, not to be specified in the request): * <ul> * <li>{@link #EXTRA_RESULTS} + * <li>{@link #EXTRA_CONFIDENCE_SCORES} (optional) * </ul> * * <p>NOTE: There may not be any applications installed to handle this action, so you should @@ -181,6 +183,13 @@ public class RecognizerIntent { * {@link java.util.Locale#getDefault()}. */ public static final String EXTRA_LANGUAGE = "android.speech.extra.LANGUAGE"; + + /** + * Optional value which can be used to indicate the referer url of a page in which + * speech was requested. For example, a web browser may choose to provide this for + * uses of speech on a given page. + */ + public static final String EXTRA_ORIGIN = "android.speech.extra.ORIGIN"; /** * Optional limit on the maximum number of results to return. If omitted the recognizer @@ -232,13 +241,31 @@ public class RecognizerIntent { /** * An ArrayList<String> of the recognition results when performing - * {@link #ACTION_RECOGNIZE_SPEECH}. Returned in the results; not to be specified in the - * recognition request. Only present when {@link Activity#RESULT_OK} is returned in - * an activity result. In a PendingIntent, the lack of this extra indicates failure. + * {@link #ACTION_RECOGNIZE_SPEECH}. Generally this list should be ordered in + * descending order of speech recognizer confidence. (See {@link #EXTRA_CONFIDENCE_SCORES}). + * Returned in the results; not to be specified in the recognition request. Only present + * when {@link Activity#RESULT_OK} is returned in an activity result. In a PendingIntent, + * the lack of this extra indicates failure. */ public static final String EXTRA_RESULTS = "android.speech.extra.RESULTS"; /** + * A float array of confidence scores of the recognition results when performing + * {@link #ACTION_RECOGNIZE_SPEECH}. The array should be the same size as the ArrayList + * returned in {@link #EXTRA_RESULTS}, and should contain values ranging from 0.0 to 1.0, + * or -1 to represent an unavailable confidence score. + * <p> + * Confidence values close to 1.0 indicate high confidence (the speech recognizer is + * confident that the recognition result is correct), while values close to 0.0 indicate + * low confidence. + * <p> + * Returned in the results; not to be specified in the recognition request. This extra is + * optional and might not be provided. Only present when {@link Activity#RESULT_OK} is + * returned in an activity result. + */ + public static final String EXTRA_CONFIDENCE_SCORES = "android.speech.extra.CONFIDENCE_SCORES"; + + /** * Returns the broadcast intent to fire with * {@link Context#sendOrderedBroadcast(Intent, String, BroadcastReceiver, android.os.Handler, int, String, Bundle)} * to receive details from the package that implements voice search. diff --git a/core/java/android/speech/SpeechRecognizer.java b/core/java/android/speech/SpeechRecognizer.java index cd73ba850631..8fee41d1bcb7 100644 --- a/core/java/android/speech/SpeechRecognizer.java +++ b/core/java/android/speech/SpeechRecognizer.java @@ -50,12 +50,26 @@ public class SpeechRecognizer { private static final String TAG = "SpeechRecognizer"; /** - * Used to retrieve an {@code ArrayList<String>} from the {@link Bundle} passed to the + * Key used to retrieve an {@code ArrayList<String>} from the {@link Bundle} passed to the * {@link RecognitionListener#onResults(Bundle)} and * {@link RecognitionListener#onPartialResults(Bundle)} methods. These strings are the possible * recognition results, where the first element is the most likely candidate. */ public static final String RESULTS_RECOGNITION = "results_recognition"; + + /** + * Key used to retrieve a float array from the {@link Bundle} passed to the + * {@link RecognitionListener#onResults(Bundle)} and + * {@link RecognitionListener#onPartialResults(Bundle)} methods. The array should be + * the same size as the ArrayList provided in {@link #RESULTS_RECOGNITION}, and should contain + * values ranging from 0.0 to 1.0, or -1 to represent an unavailable confidence score. + * <p> + * Confidence values close to 1.0 indicate high confidence (the speech recognizer is confident + * that the recognition result is correct), while values close to 0.0 indicate low confidence. + * <p> + * This value is optional and might not be provided. + */ + public static final String CONFIDENCE_SCORES = "confidence_scores"; /** Network operation timed out. */ public static final int ERROR_NETWORK_TIMEOUT = 1; diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java index e7f87963536e..e0783f3a8570 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -5569,6 +5569,7 @@ public class WebView extends AbsoluteLayout ted.mNativeLayer = nativeScrollableLayer( contentX, contentY, ted.mNativeLayerRect, null); ted.mSequence = mTouchEventQueue.nextTouchSequence(); + mTouchEventQueue.preQueueTouchEventData(ted); mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted); if (mDeferTouchProcess) { // still needs to set them for compute deltaX/Y @@ -5618,6 +5619,7 @@ public class WebView extends AbsoluteLayout ted.mNativeLayer = mScrollingLayer; ted.mNativeLayerRect.set(mScrollingLayerRect); ted.mSequence = mTouchEventQueue.nextTouchSequence(); + mTouchEventQueue.preQueueTouchEventData(ted); mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted); mLastSentTouchTime = eventTime; if (mDeferTouchProcess) { @@ -5802,6 +5804,7 @@ public class WebView extends AbsoluteLayout ted.mNativeLayer = mScrollingLayer; ted.mNativeLayerRect.set(mScrollingLayerRect); ted.mSequence = mTouchEventQueue.nextTouchSequence(); + mTouchEventQueue.preQueueTouchEventData(ted); mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted); } mLastTouchUpTime = eventTime; @@ -5827,6 +5830,7 @@ public class WebView extends AbsoluteLayout contentX, contentY, ted.mNativeLayerRect, null); ted.mSequence = mTouchEventQueue.nextTouchSequence(); + mTouchEventQueue.preQueueTouchEventData(ted); mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted); } else if (mPreventDefault != PREVENT_DEFAULT_YES){ mZoomManager.handleDoubleTap(mLastTouchX, mLastTouchY); @@ -5973,6 +5977,7 @@ public class WebView extends AbsoluteLayout ted.mReprocess = true; ted.mMotionEvent = MotionEvent.obtain(ev); ted.mSequence = sequence; + mTouchEventQueue.preQueueTouchEventData(ted); mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted); cancelLongPress(); mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS); @@ -7190,9 +7195,17 @@ public class WebView extends AbsoluteLayout private long mNextTouchSequence = Long.MIN_VALUE + 1; private long mLastHandledTouchSequence = Long.MIN_VALUE; private long mIgnoreUntilSequence = Long.MIN_VALUE + 1; + + // Events waiting to be processed. private QueuedTouch mTouchEventQueue; + + // Known events that are waiting on a response before being enqueued. + private QueuedTouch mPreQueue; + + // Pool of QueuedTouch objects saved for later use. private QueuedTouch mQueuedTouchRecycleBin; private int mQueuedTouchRecycleCount; + private long mLastEventTime = Long.MAX_VALUE; private static final int MAX_RECYCLED_QUEUED_TOUCH = 15; @@ -7214,6 +7227,57 @@ public class WebView extends AbsoluteLayout */ public void ignoreCurrentlyMissingEvents() { mIgnoreUntilSequence = mNextTouchSequence; + + // Run any events we have available and complete, pre-queued or otherwise. + runQueuedAndPreQueuedEvents(); + } + + private void runQueuedAndPreQueuedEvents() { + QueuedTouch qd = mPreQueue; + boolean fromPreQueue = true; + while (qd != null && qd.mSequence == mLastHandledTouchSequence + 1) { + handleQueuedTouch(qd); + QueuedTouch recycleMe = qd; + if (fromPreQueue) { + mPreQueue = qd.mNext; + } else { + mTouchEventQueue = qd.mNext; + } + recycleQueuedTouch(recycleMe); + mLastHandledTouchSequence++; + + long nextPre = mPreQueue != null ? mPreQueue.mSequence : Long.MAX_VALUE; + long nextQueued = mTouchEventQueue != null ? + mTouchEventQueue.mSequence : Long.MAX_VALUE; + fromPreQueue = nextPre < nextQueued; + qd = fromPreQueue ? mPreQueue : mTouchEventQueue; + } + } + + /** + * Add a TouchEventData to the pre-queue. + * + * An event in the pre-queue is an event that we know about that + * has been sent to webkit, but that we haven't received back and + * enqueued into the normal touch queue yet. If webkit ever times + * out and we need to ignore currently missing events, we'll run + * events from the pre-queue to patch the holes. + * + * @param ted TouchEventData to pre-queue + */ + public void preQueueTouchEventData(TouchEventData ted) { + QueuedTouch newTouch = obtainQueuedTouch().set(ted); + if (mPreQueue == null) { + mPreQueue = newTouch; + } else { + QueuedTouch insertionPoint = mPreQueue; + while (insertionPoint.mNext != null && + insertionPoint.mNext.mSequence < newTouch.mSequence) { + insertionPoint = insertionPoint.mNext; + } + newTouch.mNext = insertionPoint.mNext; + insertionPoint.mNext = newTouch; + } } private void recycleQueuedTouch(QueuedTouch qd) { @@ -7237,6 +7301,11 @@ public class WebView extends AbsoluteLayout mTouchEventQueue = mTouchEventQueue.mNext; recycleQueuedTouch(recycleMe); } + while (mPreQueue != null) { + QueuedTouch recycleMe = mPreQueue; + mPreQueue = mPreQueue.mNext; + recycleQueuedTouch(recycleMe); + } } /** @@ -7259,6 +7328,28 @@ public class WebView extends AbsoluteLayout * @return true if the event was processed before returning, false if it was just enqueued. */ public boolean enqueueTouchEvent(TouchEventData ted) { + // Remove from the pre-queue if present + QueuedTouch preQueue = mPreQueue; + if (preQueue != null) { + // On exiting this block, preQueue is set to the pre-queued QueuedTouch object + // if it was present in the pre-queue, and removed from the pre-queue itself. + if (preQueue.mSequence == ted.mSequence) { + mPreQueue = preQueue.mNext; + } else { + QueuedTouch prev = preQueue; + preQueue = null; + while (prev.mNext != null) { + if (prev.mNext.mSequence == ted.mSequence) { + preQueue = prev.mNext; + prev.mNext = preQueue.mNext; + break; + } else { + prev = prev.mNext; + } + } + } + } + if (ted.mSequence < mLastHandledTouchSequence) { // Stale event and we already moved on; drop it. (Should not be common.) Log.w(LOGTAG, "Stale touch event " + MotionEvent.actionToString(ted.mAction) + @@ -7270,23 +7361,24 @@ public class WebView extends AbsoluteLayout return false; } + // dropStaleGestures above might have fast-forwarded us to + // an event we have already. + runNextQueuedEvents(); + if (mLastHandledTouchSequence + 1 == ted.mSequence) { + if (preQueue != null) { + recycleQueuedTouch(preQueue); + preQueue = null; + } handleQueuedTouchEventData(ted); mLastHandledTouchSequence++; // Do we have any more? Run them if so. - QueuedTouch qd = mTouchEventQueue; - while (qd != null && qd.mSequence == mLastHandledTouchSequence + 1) { - handleQueuedTouch(qd); - QueuedTouch recycleMe = qd; - qd = qd.mNext; - recycleQueuedTouch(recycleMe); - mLastHandledTouchSequence++; - } - mTouchEventQueue = qd; + runNextQueuedEvents(); } else { - QueuedTouch qd = obtainQueuedTouch().set(ted); + // Reuse the pre-queued object if we had it. + QueuedTouch qd = preQueue != null ? preQueue : obtainQueuedTouch().set(ted); mTouchEventQueue = mTouchEventQueue == null ? qd : mTouchEventQueue.add(qd); } return true; @@ -7308,27 +7400,35 @@ public class WebView extends AbsoluteLayout return; } + // dropStaleGestures above might have fast-forwarded us to + // an event we have already. + runNextQueuedEvents(); + if (mLastHandledTouchSequence + 1 == sequence) { handleQueuedMotionEvent(ev); mLastHandledTouchSequence++; // Do we have any more? Run them if so. - QueuedTouch qd = mTouchEventQueue; - while (qd != null && qd.mSequence == mLastHandledTouchSequence + 1) { - handleQueuedTouch(qd); - QueuedTouch recycleMe = qd; - qd = qd.mNext; - recycleQueuedTouch(recycleMe); - mLastHandledTouchSequence++; - } - mTouchEventQueue = qd; + runNextQueuedEvents(); } else { QueuedTouch qd = obtainQueuedTouch().set(ev, sequence); mTouchEventQueue = mTouchEventQueue == null ? qd : mTouchEventQueue.add(qd); } } + private void runNextQueuedEvents() { + QueuedTouch qd = mTouchEventQueue; + while (qd != null && qd.mSequence == mLastHandledTouchSequence + 1) { + handleQueuedTouch(qd); + QueuedTouch recycleMe = qd; + qd = qd.mNext; + recycleQueuedTouch(recycleMe); + mLastHandledTouchSequence++; + } + mTouchEventQueue = qd; + } + private boolean dropStaleGestures(MotionEvent ev, long sequence) { if (ev != null && ev.getAction() == MotionEvent.ACTION_MOVE && !mConfirmMove) { // This is to make sure that we don't attempt to process a tap @@ -7348,13 +7448,16 @@ public class WebView extends AbsoluteLayout } // If we have a new down event and it's been a while since the last event - // we saw, just reset and keep going. + // we saw, catch up as best we can and keep going. if (ev != null && ev.getAction() == MotionEvent.ACTION_DOWN) { long eventTime = ev.getEventTime(); long lastHandledEventTime = mLastEventTime; if (eventTime > lastHandledEventTime + QUEUED_GESTURE_TIMEOUT) { Log.w(LOGTAG, "Got ACTION_DOWN but still waiting on stale event. " + - "Ignoring previous queued events."); + "Catching up."); + runQueuedAndPreQueuedEvents(); + + // Drop leftovers that we truly don't have. QueuedTouch qd = mTouchEventQueue; while (qd != null && qd.mSequence < sequence) { QueuedTouch recycleMe = qd; @@ -7377,6 +7480,17 @@ public class WebView extends AbsoluteLayout mLastHandledTouchSequence = mIgnoreUntilSequence - 1; } + if (mPreQueue != null) { + // Drop stale prequeued events + QueuedTouch qd = mPreQueue; + while (qd != null && qd.mSequence < mIgnoreUntilSequence) { + QueuedTouch recycleMe = qd; + qd = qd.mNext; + recycleQueuedTouch(recycleMe); + } + mPreQueue = qd; + } + return sequence <= mLastHandledTouchSequence; } @@ -7626,6 +7740,7 @@ public class WebView extends AbsoluteLayout ted.mPoints[0].x, ted.mPoints[0].y, ted.mNativeLayerRect, null); ted.mSequence = mTouchEventQueue.nextTouchSequence(); + mTouchEventQueue.preQueueTouchEventData(ted); mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted); } else if (mPreventDefault != PREVENT_DEFAULT_YES) { mTouchMode = TOUCH_DONE_MODE; diff --git a/core/jni/android/graphics/Movie.cpp b/core/jni/android/graphics/Movie.cpp index de18f9f82a45..b319a74df783 100644 --- a/core/jni/android/graphics/Movie.cpp +++ b/core/jni/android/graphics/Movie.cpp @@ -137,7 +137,6 @@ static JNINativeMethod gMethods[] = { #define RETURN_ERR_IF_NULL(value) do { if (!(value)) { assert(0); return -1; } } while (false) -int register_android_graphics_Movie(JNIEnv* env); int register_android_graphics_Movie(JNIEnv* env) { gMovie_class = env->FindClass(kClassPathName); diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp index 27be87182490..fbb9cea236ff 100644 --- a/core/jni/android/graphics/Paint.cpp +++ b/core/jni/android/graphics/Paint.cpp @@ -407,7 +407,7 @@ public: HB_ShaperItem shaperItem; HB_FontRec font; FontData fontData; - RunAdvanceDescription::shapeWithHarfbuzz(&shaperItem, &font, &fontData, paint, text, + TextLayoutCacheValue::shapeWithHarfbuzz(&shaperItem, &font, &fontData, paint, text, start, count, contextCount, flags); int glyphCount = shaperItem.num_glyphs; diff --git a/core/jni/android/graphics/TextLayout.cpp b/core/jni/android/graphics/TextLayout.cpp index 434f63b8ed7b..2578ea18668d 100644 --- a/core/jni/android/graphics/TextLayout.cpp +++ b/core/jni/android/graphics/TextLayout.cpp @@ -264,7 +264,7 @@ void TextLayout::getTextRunAdvances(SkPaint* paint, const jchar* chars, jint sta dirFlags, resultAdvances, &resultTotalAdvance); #else // Compute advances and return them - RunAdvanceDescription::computeAdvances(paint, chars, start, count, contextCount, dirFlags, + TextLayoutCacheValue::computeAdvances(paint, chars, start, count, contextCount, dirFlags, resultAdvances, &resultTotalAdvance); #endif } @@ -273,7 +273,7 @@ void TextLayout::getTextRunAdvancesHB(SkPaint* paint, const jchar* chars, jint s jint count, jint contextCount, jint dirFlags, jfloat* resultAdvances, jfloat& resultTotalAdvance) { // Compute advances and return them - RunAdvanceDescription::computeAdvancesWithHarfbuzz(paint, chars, start, count, contextCount, dirFlags, + TextLayoutCacheValue::computeAdvancesWithHarfbuzz(paint, chars, start, count, contextCount, dirFlags, resultAdvances, &resultTotalAdvance); } @@ -281,7 +281,7 @@ void TextLayout::getTextRunAdvancesICU(SkPaint* paint, const jchar* chars, jint jint count, jint contextCount, jint dirFlags, jfloat* resultAdvances, jfloat& resultTotalAdvance) { // Compute advances and return them - RunAdvanceDescription::computeAdvancesWithICU(paint, chars, start, count, contextCount, dirFlags, + TextLayoutCacheValue::computeAdvancesWithICU(paint, chars, start, count, contextCount, dirFlags, resultAdvances, &resultTotalAdvance); } diff --git a/core/jni/android/graphics/TextLayoutCache.cpp b/core/jni/android/graphics/TextLayoutCache.cpp index a7265beb5fc8..10e2e411ea38 100644 --- a/core/jni/android/graphics/TextLayoutCache.cpp +++ b/core/jni/android/graphics/TextLayoutCache.cpp @@ -19,14 +19,14 @@ namespace android { TextLayoutCache::TextLayoutCache(): - mCache(GenerationCache<TextLayoutCacheKey, RunAdvanceDescription*>::kUnlimitedCapacity), + mCache(GenerationCache<TextLayoutCacheKey, TextLayoutCacheValue*>::kUnlimitedCapacity), mSize(0), mMaxSize(MB(DEFAULT_TEXT_LAYOUT_CACHE_SIZE_IN_MB)), mCacheHitCount(0), mNanosecondsSaved(0) { init(); } TextLayoutCache::TextLayoutCache(uint32_t max): - mCache(GenerationCache<TextLayoutCacheKey, RunAdvanceDescription*>::kUnlimitedCapacity), + mCache(GenerationCache<TextLayoutCacheKey, TextLayoutCacheValue*>::kUnlimitedCapacity), mSize(0), mMaxSize(max), mCacheHitCount(0), mNanosecondsSaved(0) { init(); @@ -88,12 +88,12 @@ void TextLayoutCache::removeOldests() { /** * Callbacks */ -void TextLayoutCache::operator()(TextLayoutCacheKey& text, RunAdvanceDescription*& desc) { +void TextLayoutCache::operator()(TextLayoutCacheKey& text, TextLayoutCacheValue*& desc) { if (desc) { size_t totalSizeToDelete = text.getSize() + desc->getSize(); mSize -= totalSizeToDelete; if (mDebugEnabled) { - LOGD("RunAdvance description deleted, size = %d", totalSizeToDelete); + LOGD("Cache value deleted, size = %d", totalSizeToDelete); } delete desc; } @@ -120,21 +120,21 @@ void TextLayoutCache::getRunAdvances(SkPaint* paint, const jchar* text, startTime = systemTime(SYSTEM_TIME_MONOTONIC); } - TextLayoutCacheKey entry(paint, text, start, count, contextCount, dirFlags); + TextLayoutCacheKey key(paint, text, start, count, contextCount, dirFlags); // Get entry for cache if possible - RunAdvanceDescription* desc = mCache.get(entry); + TextLayoutCacheValue* value = mCache.get(key); // Value not found for the entry, we need to add a new value in the cache - if (!desc) { - desc = new RunAdvanceDescription(); + if (!value) { + value = new TextLayoutCacheValue(); // Compute advances and store them - desc->computeAdvances(paint, text, start, count, contextCount, dirFlags); - desc->copyResult(outAdvances, outTotalAdvance); + value->computeAdvances(paint, text, start, count, contextCount, dirFlags); + value->copyResult(outAdvances, outTotalAdvance); // Don't bother to add in the cache if the entry is too big - size_t size = entry.getSize() + desc->getSize(); + size_t size = key.getSize() + value->getSize(); if (size <= mMaxSize) { // Cleanup to make some room if needed if (mSize + size > mMaxSize) { @@ -152,18 +152,18 @@ void TextLayoutCache::getRunAdvances(SkPaint* paint, const jchar* text, mSize += size; // Copy the text when we insert the new entry - entry.internalTextCopy(); - mCache.put(entry, desc); + key.internalTextCopy(); + mCache.put(key, value); if (mDebugEnabled) { // Update timing information for statistics. - desc->setElapsedTime(systemTime(SYSTEM_TIME_MONOTONIC) - startTime); + value->setElapsedTime(systemTime(SYSTEM_TIME_MONOTONIC) - startTime); LOGD("CACHE MISS: Added entry for text='%s' with start=%d, count=%d, " "contextCount=%d, entry size %d bytes, remaining space %d bytes" " - Compute time in nanos: %d", String8(text, contextCount).string(), start, count, contextCount, - size, mMaxSize - mSize, desc->getElapsedTime()); + size, mMaxSize - mSize, value->getElapsedTime()); } } else { if (mDebugEnabled) { @@ -172,27 +172,27 @@ void TextLayoutCache::getRunAdvances(SkPaint* paint, const jchar* text, "entry size %d bytes, remaining space %d bytes" " - Compute time in nanos: %d", String8(text, contextCount).string(), start, count, contextCount, - size, mMaxSize - mSize, desc->getElapsedTime()); + size, mMaxSize - mSize, value->getElapsedTime()); } - delete desc; + delete value; } } else { // This is a cache hit, just copy the pre-computed results - desc->copyResult(outAdvances, outTotalAdvance); + value->copyResult(outAdvances, outTotalAdvance); if (mDebugEnabled) { nsecs_t elapsedTimeThruCacheGet = systemTime(SYSTEM_TIME_MONOTONIC) - startTime; - mNanosecondsSaved += (desc->getElapsedTime() - elapsedTimeThruCacheGet); + mNanosecondsSaved += (value->getElapsedTime() - elapsedTimeThruCacheGet); ++mCacheHitCount; - if (desc->getElapsedTime() > 0) { - float deltaPercent = 100 * ((desc->getElapsedTime() - elapsedTimeThruCacheGet) - / ((float)desc->getElapsedTime())); + if (value->getElapsedTime() > 0) { + float deltaPercent = 100 * ((value->getElapsedTime() - elapsedTimeThruCacheGet) + / ((float)value->getElapsedTime())); LOGD("CACHE HIT #%d for text='%s' with start=%d, count=%d, contextCount=%d " "- Compute time in nanos: %d - " "Cache get time in nanos: %lld - Gain in percent: %2.2f", mCacheHitCount, String8(text, contextCount).string(), start, count, contextCount, - desc->getElapsedTime(), elapsedTimeThruCacheGet, deltaPercent); + value->getElapsedTime(), elapsedTimeThruCacheGet, deltaPercent); } if (mCacheHitCount % DEFAULT_DUMP_STATS_CACHE_HIT_INTERVAL == 0) { dumpCacheStats(); @@ -215,4 +215,309 @@ void TextLayoutCache::dumpCacheStats() { LOGD("------------------------------------------------"); } +/** + * TextLayoutCacheKey + */ +TextLayoutCacheKey::TextLayoutCacheKey() : text(NULL), start(0), count(0), contextCount(0), + dirFlags(0), typeface(NULL), textSize(0), textSkewX(0), textScaleX(0), flags(0), + hinting(SkPaint::kNo_Hinting) { +} + +TextLayoutCacheKey::TextLayoutCacheKey(const SkPaint* paint, + const UChar* text, size_t start, size_t count, + size_t contextCount, int dirFlags) : + text(text), start(start), count(count), contextCount(contextCount), + dirFlags(dirFlags) { + typeface = paint->getTypeface(); + textSize = paint->getTextSize(); + textSkewX = paint->getTextSkewX(); + textScaleX = paint->getTextScaleX(); + flags = paint->getFlags(); + hinting = paint->getHinting(); +} + +bool TextLayoutCacheKey::operator<(const TextLayoutCacheKey& rhs) const { + LTE_INT(count) { + LTE_INT(contextCount) { + LTE_INT(start) { + LTE_INT(typeface) { + LTE_FLOAT(textSize) { + LTE_FLOAT(textSkewX) { + LTE_FLOAT(textScaleX) { + LTE_INT(flags) { + LTE_INT(hinting) { + LTE_INT(dirFlags) { + return strncmp16(text, rhs.text, contextCount) < 0; + } + } + } + } + } + } + } + } + } + } + return false; +} + +void TextLayoutCacheKey::internalTextCopy() { + textCopy.setTo(text, contextCount); + text = textCopy.string(); +} + +size_t TextLayoutCacheKey::getSize() { + return sizeof(TextLayoutCacheKey) + sizeof(UChar) * contextCount; +} + +/** + * TextLayoutCacheValue + */ +TextLayoutCacheValue::TextLayoutCacheValue() { + advances = NULL; + totalAdvance = 0; +} + +TextLayoutCacheValue::~TextLayoutCacheValue() { + delete[] advances; +} + +void TextLayoutCacheValue::setElapsedTime(uint32_t time) { + elapsedTime = time; +} + +uint32_t TextLayoutCacheValue::getElapsedTime() { + return elapsedTime; +} + +void TextLayoutCacheValue::computeAdvances(SkPaint* paint, const UChar* chars, size_t start, + size_t count, size_t contextCount, int dirFlags) { + advances = new float[count]; + this->count = count; + +#if RTL_USE_HARFBUZZ + computeAdvancesWithHarfbuzz(paint, chars, start, count, contextCount, dirFlags, + advances, &totalAdvance); +#else + computeAdvancesWithICU(paint, chars, start, count, contextCount, dirFlags, + advances, &totalAdvance); +#endif +#if DEBUG_ADVANCES + LOGD("Advances - count=%d - countextCount=%d - totalAdvance=%f - " + "adv[0]=%f adv[1]=%f adv[2]=%f adv[3]=%f", count, contextCount, totalAdvance, + advances[0], advances[1], advances[2], advances[3]); +#endif +} + +void TextLayoutCacheValue::copyResult(jfloat* outAdvances, jfloat* outTotalAdvance) { + memcpy(outAdvances, advances, count * sizeof(jfloat)); + *outTotalAdvance = totalAdvance; +} + +size_t TextLayoutCacheValue::getSize() { + return sizeof(TextLayoutCacheValue) + sizeof(jfloat) * count; +} + +void TextLayoutCacheValue::setupShaperItem(HB_ShaperItem* shaperItem, HB_FontRec* font, + FontData* fontData, SkPaint* paint, const UChar* chars, size_t start, size_t count, + size_t contextCount, int dirFlags) { + bool isRTL = dirFlags & 0x1; + + font->klass = &harfbuzzSkiaClass; + font->userData = 0; + // The values which harfbuzzSkiaClass returns are already scaled to + // pixel units, so we just set all these to one to disable further + // scaling. + font->x_ppem = 1; + font->y_ppem = 1; + font->x_scale = 1; + font->y_scale = 1; + + memset(shaperItem, 0, sizeof(*shaperItem)); + shaperItem->font = font; + shaperItem->face = HB_NewFace(shaperItem->font, harfbuzzSkiaGetTable); + + shaperItem->kerning_applied = false; + + // We cannot know, ahead of time, how many glyphs a given script run + // will produce. We take a guess that script runs will not produce more + // than twice as many glyphs as there are code points plus a bit of + // padding and fallback if we find that we are wrong. + createGlyphArrays(shaperItem, (contextCount + 2) * 2); + + // Free memory for clusters if needed and recreate the clusters array + if (shaperItem->log_clusters) { + delete shaperItem->log_clusters; + } + shaperItem->log_clusters = new unsigned short[contextCount]; + + shaperItem->item.pos = start; + shaperItem->item.length = count; + shaperItem->item.bidiLevel = isRTL; + shaperItem->item.script = isRTL ? HB_Script_Arabic : HB_Script_Common; + + shaperItem->string = chars; + shaperItem->stringLength = contextCount; + + fontData->typeFace = paint->getTypeface(); + fontData->textSize = paint->getTextSize(); + fontData->textSkewX = paint->getTextSkewX(); + fontData->textScaleX = paint->getTextScaleX(); + fontData->flags = paint->getFlags(); + fontData->hinting = paint->getHinting(); + + shaperItem->font->userData = fontData; +} + +void TextLayoutCacheValue::shapeWithHarfbuzz(HB_ShaperItem* shaperItem, HB_FontRec* font, + FontData* fontData, SkPaint* paint, const UChar* chars, size_t start, size_t count, + size_t contextCount, int dirFlags) { + // Setup Harfbuzz Shaper + setupShaperItem(shaperItem, font, fontData, paint, chars, start, count, + contextCount, dirFlags); + + // Shape + resetGlyphArrays(shaperItem); + while (!HB_ShapeItem(shaperItem)) { + // We overflowed our arrays. Resize and retry. + // HB_ShapeItem fills in shaperItem.num_glyphs with the needed size. + deleteGlyphArrays(shaperItem); + createGlyphArrays(shaperItem, shaperItem->num_glyphs << 1); + resetGlyphArrays(shaperItem); + } +} + +void TextLayoutCacheValue::computeAdvancesWithHarfbuzz(SkPaint* paint, const UChar* chars, + size_t start, size_t count, size_t contextCount, int dirFlags, + jfloat* outAdvances, jfloat* outTotalAdvance) { + + bool isRTL = dirFlags & 0x1; + + HB_ShaperItem shaperItem; + HB_FontRec font; + FontData fontData; + shapeWithHarfbuzz(&shaperItem, &font, &fontData, paint, chars, start, count, + contextCount, dirFlags); + +#if DEBUG_ADVANCES + LOGD("HARFBUZZ -- num_glypth=%d - kerning_applied=%d", shaperItem.num_glyphs, + shaperItem.kerning_applied); + LOGD(" -- string= '%s'", String8(chars, contextCount).string()); + LOGD(" -- isDevKernText=%d", paint->isDevKernText()); +#endif + + jfloat totalAdvance = 0; + + for (size_t i = 0; i < count; i++) { + totalAdvance += outAdvances[i] = HBFixedToFloat(shaperItem.advances[i]); + +#if DEBUG_ADVANCES + LOGD("hb-adv = %d - rebased = %f - total = %f", shaperItem.advances[i], outAdvances[i], + totalAdvance); +#endif + } + + deleteGlyphArrays(&shaperItem); + HB_FreeFace(shaperItem.face); + + *outTotalAdvance = totalAdvance; +} + +void TextLayoutCacheValue::computeAdvancesWithICU(SkPaint* paint, const UChar* chars, + size_t start, size_t count, size_t contextCount, int dirFlags, + jfloat* outAdvances, jfloat* outTotalAdvance) { + + SkAutoSTMalloc<CHAR_BUFFER_SIZE, jchar> tempBuffer(contextCount); + jchar* buffer = tempBuffer.get(); + + SkScalar* scalarArray = (SkScalar*)outAdvances; + + // this is where we'd call harfbuzz + // for now we just use ushape.c + size_t widths; + const jchar* text; + if (dirFlags & 0x1) { // rtl, call arabic shaping in case + UErrorCode status = U_ZERO_ERROR; + // Use fixed length since we need to keep start and count valid + u_shapeArabic(chars, contextCount, buffer, contextCount, + U_SHAPE_LENGTH_FIXED_SPACES_NEAR | + U_SHAPE_TEXT_DIRECTION_LOGICAL | U_SHAPE_LETTERS_SHAPE | + U_SHAPE_X_LAMALEF_SUB_ALTERNATE, &status); + // we shouldn't fail unless there's an out of memory condition, + // in which case we're hosed anyway + for (int i = start, e = i + count; i < e; ++i) { + if (buffer[i] == UNICODE_NOT_A_CHAR) { + buffer[i] = UNICODE_ZWSP; // zero-width-space for skia + } + } + text = buffer + start; + widths = paint->getTextWidths(text, count << 1, scalarArray); + } else { + text = chars + start; + widths = paint->getTextWidths(text, count << 1, scalarArray); + } + + jfloat totalAdvance = 0; + if (widths < count) { +#if DEBUG_ADVANCES + LOGD("ICU -- count=%d", widths); +#endif + // Skia operates on code points, not code units, so surrogate pairs return only + // one value. Expand the result so we have one value per UTF-16 code unit. + + // Note, skia's getTextWidth gets confused if it encounters a surrogate pair, + // leaving the remaining widths zero. Not nice. + for (size_t i = 0, p = 0; i < widths; ++i) { + totalAdvance += outAdvances[p++] = SkScalarToFloat(scalarArray[i]); + if (p < count && + text[p] >= UNICODE_FIRST_LOW_SURROGATE && + text[p] < UNICODE_FIRST_PRIVATE_USE && + text[p-1] >= UNICODE_FIRST_HIGH_SURROGATE && + text[p-1] < UNICODE_FIRST_LOW_SURROGATE) { + outAdvances[p++] = 0; + } +#if DEBUG_ADVANCES + LOGD("icu-adv = %f - total = %f", outAdvances[i], totalAdvance); +#endif + } + } else { +#if DEBUG_ADVANCES + LOGD("ICU -- count=%d", count); +#endif + for (size_t i = 0; i < count; i++) { + totalAdvance += outAdvances[i] = SkScalarToFloat(scalarArray[i]); +#if DEBUG_ADVANCES + LOGD("icu-adv = %f - total = %f", outAdvances[i], totalAdvance); +#endif + } + } + *outTotalAdvance = totalAdvance; +} + +void TextLayoutCacheValue::deleteGlyphArrays(HB_ShaperItem* shaperItem) { + delete[] shaperItem->glyphs; + delete[] shaperItem->attributes; + delete[] shaperItem->advances; + delete[] shaperItem->offsets; +} + +void TextLayoutCacheValue::createGlyphArrays(HB_ShaperItem* shaperItem, int size) { + shaperItem->glyphs = new HB_Glyph[size]; + shaperItem->attributes = new HB_GlyphAttributes[size]; + shaperItem->advances = new HB_Fixed[size]; + shaperItem->offsets = new HB_FixedPoint[size]; + shaperItem->num_glyphs = size; +} + +void TextLayoutCacheValue::resetGlyphArrays(HB_ShaperItem* shaperItem) { + int size = shaperItem->num_glyphs; + // All the types here don't have pointers. It is safe to reset to + // zero unless Harfbuzz breaks the compatibility in the future. + memset(shaperItem->glyphs, 0, size * sizeof(shaperItem->glyphs[0])); + memset(shaperItem->attributes, 0, size * sizeof(shaperItem->attributes[0])); + memset(shaperItem->advances, 0, size * sizeof(shaperItem->advances[0])); + memset(shaperItem->offsets, 0, size * sizeof(shaperItem->offsets[0])); +} + + } // namespace android diff --git a/core/jni/android/graphics/TextLayoutCache.h b/core/jni/android/graphics/TextLayoutCache.h index bced40c8e9d4..cd5a58d7cd63 100644 --- a/core/jni/android/graphics/TextLayoutCache.h +++ b/core/jni/android/graphics/TextLayoutCache.h @@ -64,62 +64,24 @@ namespace android { */ class TextLayoutCacheKey { public: - TextLayoutCacheKey() : text(NULL), start(0), count(0), contextCount(0), - dirFlags(0), typeface(NULL), textSize(0), textSkewX(0), textScaleX(0), flags(0), - hinting(SkPaint::kNo_Hinting) { - } + TextLayoutCacheKey(); TextLayoutCacheKey(const SkPaint* paint, const UChar* text, size_t start, size_t count, - size_t contextCount, int dirFlags) : - text(text), start(start), count(count), contextCount(contextCount), - dirFlags(dirFlags) { - typeface = paint->getTypeface(); - textSize = paint->getTextSize(); - textSkewX = paint->getTextSkewX(); - textScaleX = paint->getTextScaleX(); - flags = paint->getFlags(); - hinting = paint->getHinting(); - } + size_t contextCount, int dirFlags); - bool operator<(const TextLayoutCacheKey& rhs) const { - LTE_INT(count) { - LTE_INT(contextCount) { - LTE_INT(start) { - LTE_INT(typeface) { - LTE_FLOAT(textSize) { - LTE_FLOAT(textSkewX) { - LTE_FLOAT(textScaleX) { - LTE_INT(flags) { - LTE_INT(hinting) { - LTE_INT(dirFlags) { - return strncmp16(text, rhs.text, contextCount) < 0; - } - } - } - } - } - } - } - } - } - } - return false; - } + bool operator<(const TextLayoutCacheKey& rhs) const; - // We need to copy the text when we insert the key into the cache itself. - // We don't need to copy the text when we are only comparing keys. - void internalTextCopy() { - textCopy.setTo(text, contextCount); - text = textCopy.string(); - } + /** + * We need to copy the text when we insert the key into the cache itself. + * We don't need to copy the text when we are only comparing keys. + */ + void internalTextCopy(); /** * Get the size of the Cache key. */ - size_t getSize() { - return sizeof(TextLayoutCacheKey) + sizeof(UChar) * contextCount; - } + size_t getSize(); private: const UChar* text; @@ -137,232 +99,41 @@ private: }; // TextLayoutCacheKey /* - * RunAdvanceDescription is the Cache entry + * TextLayoutCacheValue is the Cache value */ -class RunAdvanceDescription { +class TextLayoutCacheValue { public: - RunAdvanceDescription() { - advances = NULL; - totalAdvance = 0; - } - - ~RunAdvanceDescription() { - delete[] advances; - } + TextLayoutCacheValue(); + ~TextLayoutCacheValue(); - void setElapsedTime(uint32_t time) { - elapsedTime = time; - } - - uint32_t getElapsedTime() { - return elapsedTime; - } + void setElapsedTime(uint32_t time); + uint32_t getElapsedTime(); void computeAdvances(SkPaint* paint, const UChar* chars, size_t start, size_t count, - size_t contextCount, int dirFlags) { - advances = new float[count]; - this->count = count; - -#if RTL_USE_HARFBUZZ - computeAdvancesWithHarfbuzz(paint, chars, start, count, contextCount, dirFlags, - advances, &totalAdvance); -#else - computeAdvancesWithICU(paint, chars, start, count, contextCount, dirFlags, - advances, &totalAdvance); -#endif -#if DEBUG_ADVANCES - LOGD("Advances - count=%d - countextCount=%d - totalAdvance=%f - " - "adv[0]=%f adv[1]=%f adv[2]=%f adv[3]=%f", count, contextCount, totalAdvance, - advances[0], advances[1], advances[2], advances[3]); -#endif - } + size_t contextCount, int dirFlags); - void copyResult(jfloat* outAdvances, jfloat* outTotalAdvance) { - memcpy(outAdvances, advances, count * sizeof(jfloat)); - *outTotalAdvance = totalAdvance; - } + void copyResult(jfloat* outAdvances, jfloat* outTotalAdvance); /** * Get the size of the Cache entry */ - size_t getSize() { - return sizeof(RunAdvanceDescription) + sizeof(jfloat) * count; - } + size_t getSize(); static void setupShaperItem(HB_ShaperItem* shaperItem, HB_FontRec* font, FontData* fontData, SkPaint* paint, const UChar* chars, size_t start, size_t count, size_t contextCount, - int dirFlags) { - bool isRTL = dirFlags & 0x1; - - font->klass = &harfbuzzSkiaClass; - font->userData = 0; - // The values which harfbuzzSkiaClass returns are already scaled to - // pixel units, so we just set all these to one to disable further - // scaling. - font->x_ppem = 1; - font->y_ppem = 1; - font->x_scale = 1; - font->y_scale = 1; - - memset(shaperItem, 0, sizeof(*shaperItem)); - shaperItem->font = font; - shaperItem->face = HB_NewFace(shaperItem->font, harfbuzzSkiaGetTable); - - shaperItem->kerning_applied = false; - - // We cannot know, ahead of time, how many glyphs a given script run - // will produce. We take a guess that script runs will not produce more - // than twice as many glyphs as there are code points plus a bit of - // padding and fallback if we find that we are wrong. - createGlyphArrays(shaperItem, (contextCount + 2) * 2); - - // Free memory for clusters if needed and recreate the clusters array - if (shaperItem->log_clusters) { - delete shaperItem->log_clusters; - } - shaperItem->log_clusters = new unsigned short[contextCount]; - - shaperItem->item.pos = start; - shaperItem->item.length = count; - shaperItem->item.bidiLevel = isRTL; - shaperItem->item.script = isRTL ? HB_Script_Arabic : HB_Script_Common; - - shaperItem->string = chars; - shaperItem->stringLength = contextCount; - - fontData->typeFace = paint->getTypeface(); - fontData->textSize = paint->getTextSize(); - fontData->textSkewX = paint->getTextSkewX(); - fontData->textScaleX = paint->getTextScaleX(); - fontData->flags = paint->getFlags(); - fontData->hinting = paint->getHinting(); - - shaperItem->font->userData = fontData; - } + int dirFlags); static void shapeWithHarfbuzz(HB_ShaperItem* shaperItem, HB_FontRec* font, FontData* fontData, SkPaint* paint, const UChar* chars, size_t start, size_t count, size_t contextCount, - int dirFlags) { - // Setup Harfbuzz Shaper - setupShaperItem(shaperItem, font, fontData, paint, chars, start, count, - contextCount, dirFlags); - - // Shape - resetGlyphArrays(shaperItem); - while (!HB_ShapeItem(shaperItem)) { - // We overflowed our arrays. Resize and retry. - // HB_ShapeItem fills in shaperItem.num_glyphs with the needed size. - deleteGlyphArrays(shaperItem); - createGlyphArrays(shaperItem, shaperItem->num_glyphs << 1); - resetGlyphArrays(shaperItem); - } - } + int dirFlags); static void computeAdvancesWithHarfbuzz(SkPaint* paint, const UChar* chars, size_t start, size_t count, size_t contextCount, int dirFlags, - jfloat* outAdvances, jfloat* outTotalAdvance) { - - bool isRTL = dirFlags & 0x1; - - HB_ShaperItem shaperItem; - HB_FontRec font; - FontData fontData; - shapeWithHarfbuzz(&shaperItem, &font, &fontData, paint, chars, start, count, - contextCount, dirFlags); - -#if DEBUG_ADVANCES - LOGD("HARFBUZZ -- num_glypth=%d - kerning_applied=%d", shaperItem.num_glyphs, shaperItem.kerning_applied); - LOGD(" -- string= '%s'", String8(chars, contextCount).string()); - LOGD(" -- isDevKernText=%d", paint->isDevKernText()); -#endif - - jfloat totalAdvance = 0; - - for (size_t i = 0; i < count; i++) { - totalAdvance += outAdvances[i] = HBFixedToFloat(shaperItem.advances[i]); - -#if DEBUG_ADVANCES - LOGD("hb-adv = %d - rebased = %f - total = %f", shaperItem.advances[i], outAdvances[i], - totalAdvance); -#endif - } - - deleteGlyphArrays(&shaperItem); - HB_FreeFace(shaperItem.face); - - *outTotalAdvance = totalAdvance; - } + jfloat* outAdvances, jfloat* outTotalAdvance); static void computeAdvancesWithICU(SkPaint* paint, const UChar* chars, size_t start, size_t count, size_t contextCount, int dirFlags, - jfloat* outAdvances, jfloat* outTotalAdvance) { - - SkAutoSTMalloc<CHAR_BUFFER_SIZE, jchar> tempBuffer(contextCount); - jchar* buffer = tempBuffer.get(); - - SkScalar* scalarArray = (SkScalar*)outAdvances; - - // this is where we'd call harfbuzz - // for now we just use ushape.c - size_t widths; - const jchar* text; - if (dirFlags & 0x1) { // rtl, call arabic shaping in case - UErrorCode status = U_ZERO_ERROR; - // Use fixed length since we need to keep start and count valid - u_shapeArabic(chars, contextCount, buffer, contextCount, - U_SHAPE_LENGTH_FIXED_SPACES_NEAR | - U_SHAPE_TEXT_DIRECTION_LOGICAL | U_SHAPE_LETTERS_SHAPE | - U_SHAPE_X_LAMALEF_SUB_ALTERNATE, &status); - // we shouldn't fail unless there's an out of memory condition, - // in which case we're hosed anyway - for (int i = start, e = i + count; i < e; ++i) { - if (buffer[i] == UNICODE_NOT_A_CHAR) { - buffer[i] = UNICODE_ZWSP; // zero-width-space for skia - } - } - text = buffer + start; - widths = paint->getTextWidths(text, count << 1, scalarArray); - } else { - text = chars + start; - widths = paint->getTextWidths(text, count << 1, scalarArray); - } - - jfloat totalAdvance = 0; - if (widths < count) { -#if DEBUG_ADVANCES - LOGD("ICU -- count=%d", widths); -#endif - // Skia operates on code points, not code units, so surrogate pairs return only - // one value. Expand the result so we have one value per UTF-16 code unit. - - // Note, skia's getTextWidth gets confused if it encounters a surrogate pair, - // leaving the remaining widths zero. Not nice. - for (size_t i = 0, p = 0; i < widths; ++i) { - totalAdvance += outAdvances[p++] = SkScalarToFloat(scalarArray[i]); - if (p < count && - text[p] >= UNICODE_FIRST_LOW_SURROGATE && - text[p] < UNICODE_FIRST_PRIVATE_USE && - text[p-1] >= UNICODE_FIRST_HIGH_SURROGATE && - text[p-1] < UNICODE_FIRST_LOW_SURROGATE) { - outAdvances[p++] = 0; - } -#if DEBUG_ADVANCES - LOGD("icu-adv = %f - total = %f", outAdvances[i], totalAdvance); -#endif - } - } else { -#if DEBUG_ADVANCES - LOGD("ICU -- count=%d", count); -#endif - for (size_t i = 0; i < count; i++) { - totalAdvance += outAdvances[i] = SkScalarToFloat(scalarArray[i]); -#if DEBUG_ADVANCES - LOGD("icu-adv = %f - total = %f", outAdvances[i], totalAdvance); -#endif - } - } - *outTotalAdvance = totalAdvance; - } + jfloat* outAdvances, jfloat* outTotalAdvance); private: jfloat* advances; @@ -371,35 +142,14 @@ private: uint32_t elapsedTime; - static void deleteGlyphArrays(HB_ShaperItem* shaperItem) { - delete[] shaperItem->glyphs; - delete[] shaperItem->attributes; - delete[] shaperItem->advances; - delete[] shaperItem->offsets; - } - - static void createGlyphArrays(HB_ShaperItem* shaperItem, int size) { - shaperItem->glyphs = new HB_Glyph[size]; - shaperItem->attributes = new HB_GlyphAttributes[size]; - shaperItem->advances = new HB_Fixed[size]; - shaperItem->offsets = new HB_FixedPoint[size]; - shaperItem->num_glyphs = size; - } - - static void resetGlyphArrays(HB_ShaperItem* shaperItem) { - int size = shaperItem->num_glyphs; - // All the types here don't have pointers. It is safe to reset to - // zero unless Harfbuzz breaks the compatibility in the future. - memset(shaperItem->glyphs, 0, size * sizeof(shaperItem->glyphs[0])); - memset(shaperItem->attributes, 0, size * sizeof(shaperItem->attributes[0])); - memset(shaperItem->advances, 0, size * sizeof(shaperItem->advances[0])); - memset(shaperItem->offsets, 0, size * sizeof(shaperItem->offsets[0])); - } + static void deleteGlyphArrays(HB_ShaperItem* shaperItem); + static void createGlyphArrays(HB_ShaperItem* shaperItem, int size); + static void resetGlyphArrays(HB_ShaperItem* shaperItem); -}; // RunAdvanceDescription +}; // TextLayoutCacheValue -class TextLayoutCache: public OnEntryRemoved<TextLayoutCacheKey, RunAdvanceDescription*> +class TextLayoutCache: public OnEntryRemoved<TextLayoutCacheKey, TextLayoutCacheValue*> { public: TextLayoutCache(); @@ -415,7 +165,7 @@ public: * Used as a callback when an entry is removed from the cache. * Do not invoke directly. */ - void operator()(TextLayoutCacheKey& text, RunAdvanceDescription*& desc); + void operator()(TextLayoutCacheKey& text, TextLayoutCacheValue*& desc); /** * Get cache entries @@ -448,7 +198,7 @@ private: Mutex mLock; bool mInitialized; - GenerationCache<TextLayoutCacheKey, RunAdvanceDescription*> mCache; + GenerationCache<TextLayoutCacheKey, TextLayoutCacheValue*> mCache; uint32_t mSize; uint32_t mMaxSize; diff --git a/core/jni/android_bluetooth_BluetoothAudioGateway.cpp b/core/jni/android_bluetooth_BluetoothAudioGateway.cpp index acf858aff440..cb742a3d5b1c 100755 --- a/core/jni/android_bluetooth_BluetoothAudioGateway.cpp +++ b/core/jni/android_bluetooth_BluetoothAudioGateway.cpp @@ -484,21 +484,21 @@ static int setup_listening_socket(int dev, int channel) { lm = RFCOMM_LM_AUTH | RFCOMM_LM_ENCRYPT; } - if (lm && setsockopt(sk, SOL_RFCOMM, RFCOMM_LM, &lm, sizeof(lm)) < 0) { - LOGE("Can't set RFCOMM link mode"); - close(sk); - return -1; - } + if (lm && setsockopt(sk, SOL_RFCOMM, RFCOMM_LM, &lm, sizeof(lm)) < 0) { + LOGE("Can't set RFCOMM link mode"); + close(sk); + return -1; + } laddr.rc_family = AF_BLUETOOTH; - bacpy(&laddr.rc_bdaddr, BDADDR_ANY); + memcpy(&laddr.rc_bdaddr, BDADDR_ANY, sizeof(bdaddr_t)); laddr.rc_channel = channel; - if (bind(sk, (struct sockaddr *)&laddr, sizeof(laddr)) < 0) { - LOGE("Can't bind RFCOMM socket"); - close(sk); - return -1; - } + if (bind(sk, (struct sockaddr *)&laddr, sizeof(laddr)) < 0) { + LOGE("Can't bind RFCOMM socket"); + close(sk); + return -1; + } listen(sk, 10); return sk; diff --git a/core/jni/android_bluetooth_common.cpp b/core/jni/android_bluetooth_common.cpp index aae0f21d5d87..6ae3e35c24dd 100644 --- a/core/jni/android_bluetooth_common.cpp +++ b/core/jni/android_bluetooth_common.cpp @@ -43,6 +43,7 @@ static Properties remote_device_properties[] = { {"Icon", DBUS_TYPE_STRING}, {"Class", DBUS_TYPE_UINT32}, {"UUIDs", DBUS_TYPE_ARRAY}, + {"Services", DBUS_TYPE_ARRAY}, {"Paired", DBUS_TYPE_BOOLEAN}, {"Connected", DBUS_TYPE_BOOLEAN}, {"Trusted", DBUS_TYPE_BOOLEAN}, @@ -52,7 +53,8 @@ static Properties remote_device_properties[] = { {"Adapter", DBUS_TYPE_OBJECT_PATH}, {"LegacyPairing", DBUS_TYPE_BOOLEAN}, {"RSSI", DBUS_TYPE_INT16}, - {"TX", DBUS_TYPE_UINT32} + {"TX", DBUS_TYPE_UINT32}, + {"Broadcaster", DBUS_TYPE_BOOLEAN} }; static Properties adapter_properties[] = { diff --git a/core/jni/android_media_AudioRecord.cpp b/core/jni/android_media_AudioRecord.cpp index b6619ab3d06f..1b6b24fff092 100644 --- a/core/jni/android_media_AudioRecord.cpp +++ b/core/jni/android_media_AudioRecord.cpp @@ -41,7 +41,6 @@ static const char* const kClassPathName = "android/media/AudioRecord"; struct fields_t { // these fields provide access from C++ to the... - jclass audioRecordClass; //... AudioRecord class jmethodID postNativeEventInJava; //... event post callback method int PCM16; //... format constants int PCM8; //... format constants @@ -520,22 +519,20 @@ extern bool android_media_getIntConstantFromClass(JNIEnv* pEnv, // ---------------------------------------------------------------------------- int register_android_media_AudioRecord(JNIEnv *env) { - javaAudioRecordFields.audioRecordClass = NULL; javaAudioRecordFields.postNativeEventInJava = NULL; javaAudioRecordFields.nativeRecorderInJavaObj = NULL; javaAudioRecordFields.nativeCallbackCookie = NULL; // Get the AudioRecord class - javaAudioRecordFields.audioRecordClass = env->FindClass(kClassPathName); - if (javaAudioRecordFields.audioRecordClass == NULL) { + jclass audioRecordClass = env->FindClass(kClassPathName); + if (audioRecordClass == NULL) { LOGE("Can't find %s", kClassPathName); return -1; } - // Get the postEvent method javaAudioRecordFields.postNativeEventInJava = env->GetStaticMethodID( - javaAudioRecordFields.audioRecordClass, + audioRecordClass, JAVA_POSTEVENT_CALLBACK_NAME, "(Ljava/lang/Object;IIILjava/lang/Object;)V"); if (javaAudioRecordFields.postNativeEventInJava == NULL) { LOGE("Can't find AudioRecord.%s", JAVA_POSTEVENT_CALLBACK_NAME); @@ -545,7 +542,7 @@ int register_android_media_AudioRecord(JNIEnv *env) // Get the variables // mNativeRecorderInJavaObj javaAudioRecordFields.nativeRecorderInJavaObj = - env->GetFieldID(javaAudioRecordFields.audioRecordClass, + env->GetFieldID(audioRecordClass, JAVA_NATIVERECORDERINJAVAOBJ_FIELD_NAME, "I"); if (javaAudioRecordFields.nativeRecorderInJavaObj == NULL) { LOGE("Can't find AudioRecord.%s", JAVA_NATIVERECORDERINJAVAOBJ_FIELD_NAME); @@ -553,7 +550,7 @@ int register_android_media_AudioRecord(JNIEnv *env) } // mNativeCallbackCookie javaAudioRecordFields.nativeCallbackCookie = env->GetFieldID( - javaAudioRecordFields.audioRecordClass, + audioRecordClass, JAVA_NATIVECALLBACKINFO_FIELD_NAME, "I"); if (javaAudioRecordFields.nativeCallbackCookie == NULL) { LOGE("Can't find AudioRecord.%s", JAVA_NATIVECALLBACKINFO_FIELD_NAME); diff --git a/core/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp index 44d2a52e67ac..587a16c72dc9 100644 --- a/core/jni/android_media_AudioTrack.cpp +++ b/core/jni/android_media_AudioTrack.cpp @@ -43,7 +43,6 @@ static const char* const kClassPathName = "android/media/AudioTrack"; struct fields_t { // these fields provide access from C++ to the... - jclass audioTrackClass; //... AudioTrack class jmethodID postNativeEventInJava; //... event post callback method int PCM16; //... format constants int PCM8; //... format constants @@ -915,20 +914,19 @@ bool android_media_getIntConstantFromClass(JNIEnv* pEnv, jclass theClass, const // ---------------------------------------------------------------------------- int register_android_media_AudioTrack(JNIEnv *env) { - javaAudioTrackFields.audioTrackClass = NULL; javaAudioTrackFields.nativeTrackInJavaObj = NULL; javaAudioTrackFields.postNativeEventInJava = NULL; // Get the AudioTrack class - javaAudioTrackFields.audioTrackClass = env->FindClass(kClassPathName); - if (javaAudioTrackFields.audioTrackClass == NULL) { + jclass audioTrackClass = env->FindClass(kClassPathName); + if (audioTrackClass == NULL) { LOGE("Can't find %s", kClassPathName); return -1; } // Get the postEvent method javaAudioTrackFields.postNativeEventInJava = env->GetStaticMethodID( - javaAudioTrackFields.audioTrackClass, + audioTrackClass, JAVA_POSTEVENT_CALLBACK_NAME, "(Ljava/lang/Object;IIILjava/lang/Object;)V"); if (javaAudioTrackFields.postNativeEventInJava == NULL) { LOGE("Can't find AudioTrack.%s", JAVA_POSTEVENT_CALLBACK_NAME); @@ -938,7 +936,7 @@ int register_android_media_AudioTrack(JNIEnv *env) // Get the variables fields // nativeTrackInJavaObj javaAudioTrackFields.nativeTrackInJavaObj = env->GetFieldID( - javaAudioTrackFields.audioTrackClass, + audioTrackClass, JAVA_NATIVETRACKINJAVAOBJ_FIELD_NAME, "I"); if (javaAudioTrackFields.nativeTrackInJavaObj == NULL) { LOGE("Can't find AudioTrack.%s", JAVA_NATIVETRACKINJAVAOBJ_FIELD_NAME); @@ -946,7 +944,7 @@ int register_android_media_AudioTrack(JNIEnv *env) } // jniData; javaAudioTrackFields.jniData = env->GetFieldID( - javaAudioTrackFields.audioTrackClass, + audioTrackClass, JAVA_JNIDATA_FIELD_NAME, "I"); if (javaAudioTrackFields.jniData == NULL) { LOGE("Can't find AudioTrack.%s", JAVA_JNIDATA_FIELD_NAME); @@ -954,10 +952,10 @@ int register_android_media_AudioTrack(JNIEnv *env) } // Get the memory mode constants - if ( !android_media_getIntConstantFromClass(env, javaAudioTrackFields.audioTrackClass, + if ( !android_media_getIntConstantFromClass(env, audioTrackClass, kClassPathName, JAVA_CONST_MODE_STATIC_NAME, &(javaAudioTrackFields.MODE_STATIC)) - || !android_media_getIntConstantFromClass(env, javaAudioTrackFields.audioTrackClass, + || !android_media_getIntConstantFromClass(env, audioTrackClass, kClassPathName, JAVA_CONST_MODE_STREAM_NAME, &(javaAudioTrackFields.MODE_STREAM)) ) { // error log performed in android_media_getIntConstantFromClass() diff --git a/core/jni/android_net_NetUtils.cpp b/core/jni/android_net_NetUtils.cpp index 3adf7705cca9..db132ec019aa 100644 --- a/core/jni/android_net_NetUtils.cpp +++ b/core/jni/android_net_NetUtils.cpp @@ -55,7 +55,6 @@ namespace android { * to look them up every time. */ static struct fieldIds { - jclass dhcpInfoInternalClass; jmethodID constructorId; jfieldID ipaddress; jfieldID gateway; @@ -163,7 +162,7 @@ static jboolean android_net_utils_runDhcp(JNIEnv* env, jobject clazz, jstring if result = ::dhcp_do_request(nameStr, ipaddr, gateway, &prefixLength, dns1, dns2, server, &lease); env->ReleaseStringUTFChars(ifname, nameStr); - if (result == 0 && dhcpInfoInternalFieldIds.dhcpInfoInternalClass != NULL) { + if (result == 0) { env->SetObjectField(info, dhcpInfoInternalFieldIds.ipaddress, env->NewStringUTF(ipaddr)); env->SetObjectField(info, dhcpInfoInternalFieldIds.gateway, env->NewStringUTF(gateway)); env->SetIntField(info, dhcpInfoInternalFieldIds.prefixLength, prefixLength); @@ -229,17 +228,16 @@ int register_android_net_NetworkUtils(JNIEnv* env) jclass netutils = env->FindClass(NETUTILS_PKG_NAME); LOG_FATAL_IF(netutils == NULL, "Unable to find class " NETUTILS_PKG_NAME); - dhcpInfoInternalFieldIds.dhcpInfoInternalClass = env->FindClass("android/net/DhcpInfoInternal"); - if (dhcpInfoInternalFieldIds.dhcpInfoInternalClass != NULL) { - dhcpInfoInternalFieldIds.constructorId = env->GetMethodID(dhcpInfoInternalFieldIds.dhcpInfoInternalClass, "<init>", "()V"); - dhcpInfoInternalFieldIds.ipaddress = env->GetFieldID(dhcpInfoInternalFieldIds.dhcpInfoInternalClass, "ipAddress", "Ljava/lang/String;"); - dhcpInfoInternalFieldIds.gateway = env->GetFieldID(dhcpInfoInternalFieldIds.dhcpInfoInternalClass, "gateway", "Ljava/lang/String;"); - dhcpInfoInternalFieldIds.prefixLength = env->GetFieldID(dhcpInfoInternalFieldIds.dhcpInfoInternalClass, "prefixLength", "I"); - dhcpInfoInternalFieldIds.dns1 = env->GetFieldID(dhcpInfoInternalFieldIds.dhcpInfoInternalClass, "dns1", "Ljava/lang/String;"); - dhcpInfoInternalFieldIds.dns2 = env->GetFieldID(dhcpInfoInternalFieldIds.dhcpInfoInternalClass, "dns2", "Ljava/lang/String;"); - dhcpInfoInternalFieldIds.serverAddress = env->GetFieldID(dhcpInfoInternalFieldIds.dhcpInfoInternalClass, "serverAddress", "Ljava/lang/String;"); - dhcpInfoInternalFieldIds.leaseDuration = env->GetFieldID(dhcpInfoInternalFieldIds.dhcpInfoInternalClass, "leaseDuration", "I"); - } + jclass dhcpInfoInternalClass = env->FindClass("android/net/DhcpInfoInternal"); + LOG_FATAL_IF(dhcpInfoInternalClass == NULL, "Unable to find class android/net/DhcpInfoInternal"); + dhcpInfoInternalFieldIds.constructorId = env->GetMethodID(dhcpInfoInternalClass, "<init>", "()V"); + dhcpInfoInternalFieldIds.ipaddress = env->GetFieldID(dhcpInfoInternalClass, "ipAddress", "Ljava/lang/String;"); + dhcpInfoInternalFieldIds.gateway = env->GetFieldID(dhcpInfoInternalClass, "gateway", "Ljava/lang/String;"); + dhcpInfoInternalFieldIds.prefixLength = env->GetFieldID(dhcpInfoInternalClass, "prefixLength", "I"); + dhcpInfoInternalFieldIds.dns1 = env->GetFieldID(dhcpInfoInternalClass, "dns1", "Ljava/lang/String;"); + dhcpInfoInternalFieldIds.dns2 = env->GetFieldID(dhcpInfoInternalClass, "dns2", "Ljava/lang/String;"); + dhcpInfoInternalFieldIds.serverAddress = env->GetFieldID(dhcpInfoInternalClass, "serverAddress", "Ljava/lang/String;"); + dhcpInfoInternalFieldIds.leaseDuration = env->GetFieldID(dhcpInfoInternalClass, "leaseDuration", "I"); return AndroidRuntime::registerNativeMethods(env, NETUTILS_PKG_NAME, gNetworkUtilMethods, NELEM(gNetworkUtilMethods)); diff --git a/core/jni/android_net_wifi_Wifi.cpp b/core/jni/android_net_wifi_Wifi.cpp index 667ba75ebd46..494dc27f5616 100644 --- a/core/jni/android_net_wifi_Wifi.cpp +++ b/core/jni/android_net_wifi_Wifi.cpp @@ -556,7 +556,7 @@ static jboolean android_net_wifi_setSuspendOptimizationsCommand(JNIEnv* env, job return doBooleanCommand(cmdstr, "OK"); } -static void android_net_wifi_enableBackgroundScan(JNIEnv* env, jobject clazz, jboolean enable) +static void android_net_wifi_enableBackgroundScanCommand(JNIEnv* env, jobject clazz, jboolean enable) { //Note: BGSCAN-START and BGSCAN-STOP are documented in core/res/res/values/config.xml //and will need an update if the names are changed @@ -568,6 +568,16 @@ static void android_net_wifi_enableBackgroundScan(JNIEnv* env, jobject clazz, jb } } +static void android_net_wifi_setScanIntervalCommand(JNIEnv* env, jobject clazz, jint scanInterval) +{ + char cmdstr[BUF_SIZE]; + + int numWritten = snprintf(cmdstr, sizeof(cmdstr), "SCAN_INTERVAL %d", scanInterval); + + if(numWritten < (int)sizeof(cmdstr)) doBooleanCommand(cmdstr, "OK"); +} + + // ---------------------------------------------------------------------------- /* @@ -635,7 +645,8 @@ static JNINativeMethod gWifiMethods[] = { (void*) android_net_wifi_setSuspendOptimizationsCommand}, { "setCountryCodeCommand", "(Ljava/lang/String;)Z", (void*) android_net_wifi_setCountryCodeCommand}, - { "enableBackgroundScan", "(Z)V", (void*) android_net_wifi_enableBackgroundScan}, + { "enableBackgroundScanCommand", "(Z)V", (void*) android_net_wifi_enableBackgroundScanCommand}, + { "setScanIntervalCommand", "(I)V", (void*) android_net_wifi_setScanIntervalCommand}, }; int register_android_net_wifi_WifiManager(JNIEnv* env) diff --git a/core/jni/android_server_BluetoothEventLoop.cpp b/core/jni/android_server_BluetoothEventLoop.cpp index afaade8b21ee..dced1a574cf4 100644 --- a/core/jni/android_server_BluetoothEventLoop.cpp +++ b/core/jni/android_server_BluetoothEventLoop.cpp @@ -373,7 +373,6 @@ static int register_agent(native_data_t *nat, } dbus_message_append_args(msg, DBUS_TYPE_OBJECT_PATH, &agent_path, DBUS_TYPE_STRING, &capabilities, - DBUS_TYPE_BOOLEAN, &oob, DBUS_TYPE_INVALID); dbus_error_init(&err); diff --git a/core/jni/android_server_BluetoothService.cpp b/core/jni/android_server_BluetoothService.cpp index 158e47573c52..5c6958a4fd08 100644 --- a/core/jni/android_server_BluetoothService.cpp +++ b/core/jni/android_server_BluetoothService.cpp @@ -695,9 +695,7 @@ static jobjectArray getDevicePropertiesNative(JNIEnv *env, jobject object, str_array = parse_remote_device_properties(env, &iter); dbus_message_unref(reply); - env->PopLocalFrame(NULL); - - return str_array; + return (jobjectArray) env->PopLocalFrame(str_array); } #endif return NULL; @@ -731,8 +729,7 @@ static jobjectArray getAdapterPropertiesNative(JNIEnv *env, jobject object) { str_array = parse_adapter_properties(env, &iter); dbus_message_unref(reply); - env->PopLocalFrame(NULL); - return str_array; + return (jobjectArray) env->PopLocalFrame(str_array); } #endif return NULL; diff --git a/core/jni/android_util_AssetManager.cpp b/core/jni/android_util_AssetManager.cpp index fdb7fda2dd6d..65b599017a19 100644 --- a/core/jni/android_util_AssetManager.cpp +++ b/core/jni/android_util_AssetManager.cpp @@ -532,6 +532,7 @@ static void android_content_AssetManager_setConfiguration(JNIEnv* env, jobject c jint keyboard, jint keyboardHidden, jint navigation, jint screenWidth, jint screenHeight, + jint screenWidthDp, jint screenHeightDp, jint screenLayout, jint uiMode, jint sdkVersion) { @@ -555,6 +556,8 @@ static void android_content_AssetManager_setConfiguration(JNIEnv* env, jobject c config.navigation = (uint8_t)navigation; config.screenWidth = (uint16_t)screenWidth; config.screenHeight = (uint16_t)screenHeight; + config.screenWidthDp = (uint16_t)screenWidthDp; + config.screenHeightDp = (uint16_t)screenHeightDp; config.screenLayout = (uint8_t)screenLayout; config.uiMode = (uint8_t)uiMode; config.sdkVersion = (uint16_t)sdkVersion; @@ -1693,7 +1696,7 @@ static JNINativeMethod gAssetManagerMethods[] = { (void*) android_content_AssetManager_setLocale }, { "getLocales", "()[Ljava/lang/String;", (void*) android_content_AssetManager_getLocales }, - { "setConfiguration", "(IILjava/lang/String;IIIIIIIIIII)V", + { "setConfiguration", "(IILjava/lang/String;IIIIIIIIIIIII)V", (void*) android_content_AssetManager_setConfiguration }, { "getResourceIdentifier","(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I", (void*) android_content_AssetManager_getResourceIdentifier }, diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp index 9a727a7fe25d..f31bba91f841 100644 --- a/core/jni/android_view_GLES20Canvas.cpp +++ b/core/jni/android_view_GLES20Canvas.cpp @@ -736,9 +736,9 @@ const char* const kActivityThreadPathName = "android/app/ActivityThread"; int register_android_app_ActivityThread(JNIEnv* env) { - jclass gFileDescriptorClass = env->FindClass("java/io/FileDescriptor"); + jclass fileDescriptorClass = env->FindClass("java/io/FileDescriptor"); LOG_FATAL_IF(clazz == NULL, "Unable to find class java.io.FileDescriptor"); - gFileDescriptorField = env->GetFieldID(gFileDescriptorClass, "descriptor", "I"); + gFileDescriptorField = env->GetFieldID(fileDescriptorClass, "descriptor", "I"); LOG_FATAL_IF(gFileDescriptorField == NULL, "Unable to find descriptor field in java.io.FileDescriptor"); diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml index 25e66b41f1c6..d8c64f0e9df0 100644 --- a/core/res/res/values-hr/strings.xml +++ b/core/res/res/values-hr/strings.xml @@ -987,7 +987,7 @@ <item quantity="other" msgid="4641872797067609177">"<xliff:g id="INDEX">%d</xliff:g> od <xliff:g id="TOTAL">%d</xliff:g>"</item> </plurals> <string name="action_mode_done" msgid="7217581640461922289">"Gotovo"</string> - <string name="progress_unmounting" product="nosdcard" msgid="535863554318797377">"Isključivanje memorije USB..."</string> + <string name="progress_unmounting" product="nosdcard" msgid="535863554318797377">"Isključivanje USB memorije..."</string> <string name="progress_unmounting" product="default" msgid="5556813978958789471">"Isključivanje SD kartice..."</string> <string name="progress_erasing" product="nosdcard" msgid="4183664626203056915">"Brisanje memorije USB..."</string> <string name="progress_erasing" product="default" msgid="2115214724367534095">"Brisanje SD kartice..."</string> diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml index de44e7228974..043faafce74d 100644 --- a/core/res/res/values-pl/strings.xml +++ b/core/res/res/values-pl/strings.xml @@ -251,8 +251,8 @@ <string name="permdesc_injectEvents" product="default" msgid="3946098050410874715">"Pozwala aplikacjom na dostarczanie własnych zdarzeń wprowadzania danych (naciśnięcie klawisza itp.) do innych aplikacji. Szkodliwe aplikacje mogą to wykorzystać do przejęcia kontroli nad telefonem."</string> <string name="permlab_readInputState" msgid="469428900041249234">"zapamiętywanie wpisywanych znaków oraz wykonywanych czynności"</string> <string name="permdesc_readInputState" msgid="5132879321450325445">"Pozwala aplikacjom na śledzenie naciskanych klawiszy, nawet podczas pracy z innym programem (na przykład podczas wpisywania hasła). Nigdy nie powinno być potrzebne normalnym aplikacjom."</string> - <string name="permlab_bindInputMethod" msgid="3360064620230515776">"tworzenie powiązania z metodą wejściową"</string> - <string name="permdesc_bindInputMethod" msgid="3734838321027317228">"Pozwala na tworzenie powiązania z interfejsem najwyższego poziomu metody wejściowej. To uprawnienie nie powinno być nigdy wymagane przez zwykłe aplikacje."</string> + <string name="permlab_bindInputMethod" msgid="3360064620230515776">"powiązanie ze sposobem wprowadzania tekstu"</string> + <string name="permdesc_bindInputMethod" msgid="3734838321027317228">"Pozwala na powiązanie wybranego sposobu wprowadzania tekstu z interfejsem najwyższego poziomu. To uprawnienie nie powinno być nigdy wymagane przez zwykłe aplikacje."</string> <string name="permlab_bindWallpaper" msgid="8716400279937856462">"powiązanie z tapetą"</string> <string name="permdesc_bindWallpaper" msgid="5287754520361915347">"Umożliwia posiadaczowi powiązać interfejs najwyższego poziomu dla tapety. Nie powinno być nigdy potrzebne w przypadku zwykłych aplikacji."</string> <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"powiązanie z usługą widżetów"</string> @@ -797,7 +797,7 @@ <string name="copyUrl" msgid="2538211579596067402">"Kopiuj adres URL"</string> <string name="selectTextMode" msgid="6738556348861347240">"Zaznacz tekst"</string> <string name="textSelectionCABTitle" msgid="5236850394370820357">"Zaznaczanie tekstu"</string> - <string name="inputMethod" msgid="1653630062304567879">"Metoda wprowadzania"</string> + <string name="inputMethod" msgid="1653630062304567879">"Sposób wprowadzania tekstu"</string> <string name="editTextMenuTitle" msgid="4909135564941815494">"Działania na tekście"</string> <string name="low_internal_storage_view_title" msgid="1399732408701697546">"Mało miejsca"</string> <string name="low_internal_storage_view_text" product="tablet" msgid="4231085657068852042">"Pamięć tabletu wkrótce zostanie zapełniona."</string> @@ -903,7 +903,7 @@ <string name="extmedia_format_button_format" msgid="4131064560127478695">"Formatuj"</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"Podłączono moduł debugowania USB"</string> <string name="adb_active_notification_message" msgid="8470296818270110396">"Wybierz, aby wyłączyć debugowanie USB."</string> - <string name="select_input_method" msgid="6865512749462072765">"Wybierz metodę wprowadzania"</string> + <string name="select_input_method" msgid="6865512749462072765">"Wybierz sposób wprowadzania tekstu"</string> <string name="configure_input_methods" msgid="6324843080254191535">"Konfiguruj metody wprowadzania"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" AĄBCĆDEĘFGHIJKLŁMNŃOÓPQRSŚTUVWXYZŹŻ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> @@ -956,7 +956,7 @@ <string name="deny" msgid="2081879885755434506">"Odmów"</string> <string name="permission_request_notification_title" msgid="5390555465778213840">"Żądane pozwolenie"</string> <string name="permission_request_notification_with_subtitle" msgid="4325409589686688000">"Prośba o pozwolenie"\n"dotyczące konta <xliff:g id="ACCOUNT">%s</xliff:g>"</string> - <string name="input_method_binding_label" msgid="1283557179944992649">"Metoda wprowadzania"</string> + <string name="input_method_binding_label" msgid="1283557179944992649">"Sposób wprowadzania tekstu"</string> <string name="sync_binding_label" msgid="3687969138375092423">"Synchronizacja"</string> <string name="accessibility_binding_label" msgid="4148120742096474641">"Ułatwienia dostępu"</string> <string name="wallpaper_binding_label" msgid="1240087844304687662">"Tapeta"</string> diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml index 10a2898b3b33..8e8f87fd47e5 100644 --- a/core/res/res/values-ru/strings.xml +++ b/core/res/res/values-ru/strings.xml @@ -416,7 +416,7 @@ <string name="permdesc_authenticateAccounts" msgid="4006839406474208874">"Разрешает приложению использовать возможности аутентификации диспетчера аккаунта, в том числе создавать аккаунты, получать и устанавливать пароли для них."</string> <string name="permlab_manageAccounts" msgid="4440380488312204365">"управление списком аккаунтов"</string> <string name="permdesc_manageAccounts" msgid="8804114016661104517">"Разрешает приложению добавлять и удалять аккаунты и стирать их пароли."</string> - <string name="permlab_useCredentials" msgid="6401886092818819856">"использование регистрационных данных аккаунта для аутентификации"</string> + <string name="permlab_useCredentials" msgid="6401886092818819856">"использование учетных данных аккаунта для аутентификации"</string> <string name="permdesc_useCredentials" msgid="7416570544619546974">"Разрешает приложению запрашивать маркеры аутентификации."</string> <string name="permlab_accessNetworkState" msgid="6865575199464405769">"просматривать состояние сети"</string> <string name="permdesc_accessNetworkState" msgid="558721128707712766">"Позволяет приложению просматривать состояние всех сетей."</string> @@ -460,11 +460,11 @@ <string name="permdesc_readDictionary" msgid="1082972603576360690">"Позволяет приложению считывать любые слова, имена и фразы личного пользования, которые могут храниться в пользовательском словаре."</string> <string name="permlab_writeDictionary" msgid="6703109511836343341">"записывать в словарь пользователя"</string> <string name="permdesc_writeDictionary" msgid="2241256206524082880">"Позволяет приложению записывать новые слова в словарь пользователя."</string> - <string name="permlab_sdcardWrite" product="nosdcard" msgid="85430876310764752">"изменять и удалять содержимое USB-накопителя"</string> + <string name="permlab_sdcardWrite" product="nosdcard" msgid="85430876310764752">"изм./удал. содерж. накопителя"</string> <string name="permlab_sdcardWrite" product="default" msgid="8079403759001777291">"изменять/удалять содержимое SD-карты"</string> <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6594393334785738252">"Разрешает приложению запись на USB-накопитель."</string> <string name="permdesc_sdcardWrite" product="default" msgid="6643963204976471878">"Разрешает приложению запись на SD-карту"</string> - <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"изменение/удаление данных из внутреннего хранилища мультимедиа"</string> + <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"изм./удал. данных мультимедиа"</string> <string name="permdesc_mediaStorageWrite" product="default" msgid="8232008512478316233">"Приложение сможет изменять содержание внутреннего хранилища мультимедиа."</string> <string name="permlab_cache_filesystem" msgid="5656487264819669824">"получать доступ к кэшу файловой системы"</string> <string name="permdesc_cache_filesystem" msgid="1624734528435659906">"Разрешает программам доступ для записи и чтения к кэшу файловой системы."</string> @@ -825,7 +825,7 @@ <string name="anr_application_process" msgid="4185842666452210193">"Приложение <xliff:g id="APPLICATION">%1$s</xliff:g> (в процессе <xliff:g id="PROCESS">%2$s</xliff:g>) не отвечает."</string> <string name="anr_process" msgid="1246866008169975783">"Процесс <xliff:g id="PROCESS">%1$s</xliff:g> не отвечает."</string> <string name="force_close" msgid="3653416315450806396">"Закрыть"</string> - <string name="report" msgid="4060218260984795706">"Отчет"</string> + <string name="report" msgid="4060218260984795706">"Отзыв"</string> <string name="wait" msgid="7147118217226317732">"Подождать"</string> <string name="launch_warning_title" msgid="8323761616052121936">"Приложение перенаправлено"</string> <string name="launch_warning_replace" msgid="6202498949970281412">"Приложение <xliff:g id="APP_NAME">%1$s</xliff:g> выполняется."</string> @@ -919,7 +919,7 @@ <string name="ext_media_unmountable_notification_title" product="default" msgid="6410723906019100189">"Поврежденная карта SD"</string> <string name="ext_media_unmountable_notification_message" product="nosdcard" msgid="529021299294450667">"USB-накопитель поврежден. Попробуйте отформатировать его."</string> <string name="ext_media_unmountable_notification_message" product="default" msgid="6902531775948238989">"SD-карта повреждена. Попробуйте отформатировать ее."</string> - <string name="ext_media_badremoval_notification_title" product="nosdcard" msgid="1661683031330951073">"USB-накопитель неожиданно отключен"</string> + <string name="ext_media_badremoval_notification_title" product="nosdcard" msgid="1661683031330951073">"Накопитель неожиданно отключен"</string> <string name="ext_media_badremoval_notification_title" product="default" msgid="6872152882604407837">"Карта SD неожиданно извлечена"</string> <string name="ext_media_badremoval_notification_message" product="nosdcard" msgid="4329848819865594241">"Перед извлечением USB-накопителя отключите его во избежание потери данных."</string> <string name="ext_media_badremoval_notification_message" product="default" msgid="7260183293747448241">"Перед извлечением карты SD отключите ее во избежание потери данных."</string> diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml index 58b681efb225..ad4eee7946ab 100644 --- a/core/res/res/values-tr/strings.xml +++ b/core/res/res/values-tr/strings.xml @@ -896,7 +896,7 @@ <string name="dlg_confirm_kill_storage_users_text" msgid="3202838234780505886">"USB depolama birimini açarsanız, kullanmakta olduğunuz bazı uygulamalar durur ve USB depolama birimi kapatılıncaya kadar kullanılamayabilir."</string> <string name="dlg_error_title" msgid="8048999973837339174">"USB işlemi başarısız oldu"</string> <string name="dlg_ok" msgid="7376953167039865701">"Tamam"</string> - <string name="extmedia_format_title" product="nosdcard" msgid="7980995592595097841">"USB dep br biçimlndr"</string> + <string name="extmedia_format_title" product="nosdcard" msgid="7980995592595097841">"USB\'yi biçimlendir"</string> <string name="extmedia_format_title" product="default" msgid="8663247929551095854">"SD kartı biçimlendir"</string> <string name="extmedia_format_message" product="nosdcard" msgid="8296908079722897772">"USB depolama birimi biçimlendirilsin mi? Depolama biriminde saklanan tüm dosyalar silinir. İşlem geri alınamaz!"</string> <string name="extmedia_format_message" product="default" msgid="3621369962433523619">"SD kartı biçimlendirmek istediğinizden emin misiniz? Kartınızdaki tüm veriler yok olacak."</string> diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml index e8f30ad28f6b..80beaa54f548 100644 --- a/core/res/res/values/attrs_manifest.xml +++ b/core/res/res/values/attrs_manifest.xml @@ -590,6 +590,11 @@ <!-- The global user interface mode has changed. For example, going in or out of car mode, night mode changing, etc. --> <flag name="uiMode" value="0x0200" /> + <!-- The physical screen size has changed. If applications don't + target at least {@link android.os.Build.VERSION_CODES#ICE_CREAM_SANDWICH} + then the activity will always handle this itself (the change + will not result in a restart). --> + <flag name="screenSize" value="0x0400" /> <!-- The font scaling factor has changed, that is the user has selected a new global font size. --> <flag name="fontScale" value="0x40000000" /> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 56bc1d3f5ef0..51a32b0d02e3 100755 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -114,6 +114,23 @@ removable. --> <bool name="config_externalStorageRemovable" product="default">true</bool> + <!-- List of mount points for external storage devices. + The first item on the list should be the primary external storage and should match the + value returned by Environment.getExternalStorageDirectory (/mnt/sdcard). + MTP storage IDs will be generated based on the position of the mountpoint in this list: + 0x00010001 - ID for primary external storage (/mnt/sdcard) + 0x00020001 - ID for first secondary external storage + 0x00030001 - ID for second secondary external storage + etc. --> + <string-array translatable="false" name="config_externalStoragePaths"> + <item>"/mnt/sdcard"</item> + </string-array> + + <!-- User visible descriptions of the volumes in the config_externalStoragePaths array. --> + <string-array translatable="true" name="config_externalStorageDescriptions"> + <item>"SD card"</item> + </string-array> + <!-- Number of megabytes of space to leave unallocated by MTP. MTP will subtract this value from the free space it reports back to the host via GetStorageInfo, and will not allow new files to @@ -209,6 +226,15 @@ The driver commands needed to support the feature are BGSCAN-START and BGSCAN-STOP --> <bool translatable="false" name="config_wifi_background_scan_support">false</bool> + <!-- Integer indicating wpa_supplicant scan interval in milliseconds --> + <integer translatable="false" name="config_wifi_supplicant_scan_interval">15000</integer> + + <!-- Integer indicating the framework scan interval in milliseconds. This is used in the scenario + where the chipset does not support background scanning (config_wifi_background_scan_suport + is false) to set up a periodic wake up scan so that the device can connect to a new access + point on the move. A value of 0 means no periodic scans will be used in the framework. --> + <integer translatable="false" name="config_wifi_framework_scan_interval">300000</integer> + <!-- Flag indicating whether the keyguard should be bypassed when the slider is open. This can be set or unset depending how easily the slider can be opened (for example, in a pocket or purse). --> diff --git a/docs/html/guide/developing/index.jd b/docs/html/guide/developing/index.jd index 4257bf04ef4c..3d7e35351b2a 100644 --- a/docs/html/guide/developing/index.jd +++ b/docs/html/guide/developing/index.jd @@ -9,25 +9,21 @@ page.title=Introduction <p>However, you may choose to develop with another IDE or a simple text editor and invoke the tools on the command line or with scripts. This is a less streamlined way to develop because you will sometimes have to call command line tools manually, but you will have access to the same - amount of features that you would have in Eclipse.</p> + number of features that you would have in Eclipse.</p> + + <p class="note"><strong>Note:</strong> Before you begin developing Android applications, make + sure you have gone through all of the steps outlined in <a +href="{@docRoot}sdk/installing.html">Installing the SDK</a>.</p> <p>The basic steps for developing applications with or without Eclipse are the same:</p> <ol> - <li>Install Eclipse or your own IDE. - - <p>Install Eclipse along with <a href="{@docRoot}sdk/eclipse-adt.html#installing">the ADT - Plugin</a>, or install an editor of your choice if you want to use the command line SDK tools. - If you are already developing applications, be sure to <a href= - "{@docRoot}sdk/eclipse-adt.html#updating">update Your ADT Plugin</a> to the latest version - before continuing.</p> - </li> <li>Set up Android Virtual Devices or hardware devices. <p>You need to create Android Virtual Devices (AVD) or connect hardware devices on which you will install your applications.</p> - + <p>See <a href="{@docRoot}guide/developing/devices/index.html">Managing Virtual Devices</a> and <a href="{@docRoot}guide/developing/device.html">Using Hardware Devices</a> for more information. diff --git a/docs/html/guide/developing/tools/index.jd b/docs/html/guide/developing/tools/index.jd index c60378020cc2..3d831f3e390c 100644 --- a/docs/html/guide/developing/tools/index.jd +++ b/docs/html/guide/developing/tools/index.jd @@ -3,83 +3,83 @@ page.title=Tools <img src="{@docRoot}assets/images/android_wrench.png" alt="" align="right"> -<p>The Android SDK includes a variety of custom tools that help you develop mobile -applications on the Android platform. The most important of these are the Android -Emulator and the Android Development Tools plugin for Eclipse, but the SDK also -includes a variety of other tools for debugging, packaging, and installing your -applications on the emulator. </p> - - <dl> - <dt><a href="adb.html">Android Debug Bridge</a></dt> - <dd>A versatile tool lets you manage the state of an emulator instance - or Android-powered device.</dd> - - <dt><a href="android.html">android</a></dt> - <dd>Lets you manage AVDs, projects, and the installed components of the SDK. - </dd> - - <dt><a href="bmgr.html">bmgr</a></dt> - - <dd>Lets you interact with the Backup Manager on Android devices - supporting API Level 8 or greater. It provides commands to invoke backup and restore operations - so that you don't need to repeatedly wipe data or take similar intrusive steps in order to test - your application's backup agent. These commands are accessed via the adb shell. - </dd> - +<p>The Android SDK includes a variety of tools that help you develop mobile +applications for the Android platform. The tools are classified into two groups: SDK tools +and platform tools. SDK tools are platform independent and are required no matter which +Android platform you are developing on. Platform tools are customized to support the features of the +latest Android platform.</p> + +<h2 id="tools-sdk">SDK Tools</h2> +<p>The SDK tools are installed with the SDK starter package and are periodically updated. +The SDK tools are required if you are developing Android applications. The most important SDK tools +include the Android SDK and AVD Manager (<code>android</code>), the emulator +(<code>emulator</code>), and the Dalvik Debug Monitor Server +(<code>ddms</code>). A short summary of some frequently-used SDK tools is provided below.</p> + +<dl> + <dt><a href="android.html">android</a></dt> + <dd>Lets you manage AVDs, projects, and the installed components of the SDK.</dd> + <dt><a href="{@docRoot}guide/developing/debugging/ddms.html">Dalvik Debug Monitor +Server (ddms)</a></dt> + <dd>Lets you debug Android applications.</dd> <dt><a href="dmtracedump.html">dmtracedump</a></dt> - - <dd>Generates graphical call-stack diagrams from trace log files. - The tool uses the Graphviz Dot utility to create the graphical output, so you need to install - Graphviz before running <code>dmtracedump</code>. For more information on using <code>dmtracedump</code>, see - <a href="{@docRoot}guide/developing/debugging/debugging-tracing.html#dmtracedump">Profiling with - Traceview and dmtracedump</a> - </dd> - - <dt><a href="draw9patch.html">Draw 9-patch</a></dt> - <dd>Allows you to easily create a {@link android.graphics.NinePatch} graphic using a WYSIWYG editor. - It also previews stretched versions of the image, and highlights the area in which content is allowed. - </dd> - - <dt><a href="emulator.html">Android Emulator</a></dt> - <dd>A QEMU-based device-emulation tool that you can use to design, - debug, and test your applications in an actual Android run-time environment. </dd> - + <dd>Generates graphical call-stack diagrams from trace log files. The tool uses the +Graphviz Dot utility to create the graphical output, so you need to install Graphviz before +running <code>dmtracedump</code>. For more information on using <code>dmtracedump</code>, see <a +href="{@docRoot}guide/developing/debugging/debugging-tracing.html#dmtracedump">Profiling +with Traceview and dmtracedump</a></dd> + <dt><a href="draw9patch.html">Draw 9-patch</a></dt> + <dd>Allows you to easily create a {@link android.graphics.NinePatch} graphic using a +WYSIWYG editor. It also previews stretched versions of the image, and highlights the area in which +content is allowed.</dd> + <dt><a href="emulator.html">Android Emulator (emulator)</a></dt> + <dd>A QEMU-based device-emulation tool that you can use to design, debug, and test +your applications in an actual Android run-time environment.</dd> + <dt><a href="hierarchy-viewer.html">Hierarchy Viewer (hierarchyviewer)</a></dt> + <dd>Lets you debug and optimize an Android application's user interface.</dd> <dt><a href="hprof-conv.html">hprof-conv</a></dt> - - <dd>Converts the HPROF file that is generated by the Android SDK tools to a - standard format so you can view the file in a profiling tool of your choice.</dd> - + <dd>Converts the HPROF file that is generated by the Android SDK tools to a standard format so +you can view the file in a profiling tool of your choice.</dd> <dt><a href="layoutopt.html">layoutopt</a></dt> - <dd>Lets you quickly analyze your application's layouts in order to - optimize them for efficiency. - </dd> - - <dt><a href="mksdcard.html">logcat</a></dt> - <dd>Lets you read system log messages that are output on an Android device or emulator.</dd> - + <dd>Lets you quickly analyze your application's layouts in order to optimize them for +efficiency.</dd> <dt><a href="mksdcard.html">mksdcard</a></dt> - <dd>Helps you create a disk image that you can use with the emulator, - to simulate the presence of an external storage card (such as an SD card).</dd> - + <dd>Helps you create a disk image that you can use with the emulator, to simulate the presence +of an external storage card (such as an SD card).</dd> <dt><a href="monkey.html">Monkey</a></dt> - <dd>Runs on your emulator or device and generates pseudo-random - streams of user events such as clicks, touches, or gestures, as well as a number of system-level events. - You can use the Monkey to stress-test applications that you are developing, in a random yet repeatable manner.</dd> - + <dd>Runs on your emulator or device and generates pseudo-random streams of user events such +as clicks, touches, or gestures, as well as a number of system-level events. You can use the Monkey +to stress-test applications that you are developing, in a random yet repeatable manner.</dd> <dt><a href="monkeyrunner_concepts.html">monkeyrunner</a></dt> - <dd>Provides an API for writing programs that control an Android device - or emulator from outside of Android code.</dd> - + <dd>Provides an API for writing programs that control an Android device or emulator from +outside of Android code.</dd> <dt><a href="proguard.html">ProGuard</a></dt> - <dd>Shrinks, optimizes, and obfuscates your code by removing unused code and renaming classes, - fields, and methods with semantically obscure names.</dd> - + <dd>Shrinks, optimizes, and obfuscates your code by removing unused code and renaming +classes, fields, and methods with semantically obscure names.</dd> <dt><a href="sqlite3.html">sqlite3</a></dt> - <dd>Lets you access the SQLite data files created and used by Android applications.</dd> - + <dd>Lets you access the SQLite data files created and used by Android applications.</dd> + <dt><a href="traceview.html">traceview</a></dt> + <dd>Provides a graphical viewer for execution logs saved by your application.</dd> <dt><a href="zipalign.html">zipalign</a></dt> - <dd>Optimizes <code>.apk</code> files by ensuring that all uncompressed data starts - with a particular alignment relative to the start of the file. This should always be used - to align .apk files after they have been signed.</dd> -</dl> - + <dd>Optimizes <code>.apk</code> files by ensuring that all uncompressed data starts with a +particular alignment relative to the start of the file. This should always be used to align .apk +files after they have been signed.</dd> + </dl> + +<h2 id="tools-platform">Platform Tools</h2> + +<p>The platform tools are typically updated every time you install a new SDK platform. Each update +of the platform tools is backward compatible with older platforms. Usually, you directly use only +one of the platform tools—the <a href="adb.html">Android Debug Bridge (<code>adb</code>)</a>. +Android Debug Bridge is a versatile tool that lets you manage the state of an emulator instance or +Android-powered device. You can also use it to install an Android application (.apk) file on a +device.</p> + +<p>The other platform tools, such as <a href="{@docRoot}guide/developing/tools/aidl.html">aidl</a>, +<code>aapt</code>, <code>dexdump</code>, and <code>dx</code>, are typically called by the Android +build tools or Android Development Tools (ADT), so you rarely need to invoke these tools directly. +As a general rule, you should rely on the build tools or the ADT plugin to call them as needed.</p> + +<p class="note"><strong>Note:</strong> The Android SDK provides additional shell tools that can +be accessed through <code>adb</code>, such as <a href="bmgr.html">bmgr</a> and +<a href="logcat.html">logcat</a>.</p>
\ No newline at end of file diff --git a/docs/html/guide/topics/data/data-storage.jd b/docs/html/guide/topics/data/data-storage.jd index e20d1ed22761..d31afa554c5e 100644 --- a/docs/html/guide/topics/data/data-storage.jd +++ b/docs/html/guide/topics/data/data-storage.jd @@ -16,9 +16,22 @@ page.title=Data Storage <h2>In this document</h2> <ol> <li><a href="#pref">Using Shared Preferences</a></li> - <li><a href="#filesInternal">Using the Internal Storage</a></li> - <li><a href="#filesExternal">Using the External Storage</a></li> - <li><a href="#db">Using Databases</a></li> + <li><a href="#filesInternal">Using the Internal Storage</a> + <ol> + <li><a href="#InternalCache">Saving cache files</a></li> + <li><a href="#InternalMethods">Other useful methods</a></li> + </ol></li> + <li><a href="#filesExternal">Using the External Storage</a> + <ol> + <li><a href="#MediaAvail">Checking media availability</a></li> + <li><a href="#AccessingExtFiles">Accessing files on external storage</a></li> + <li><a href="#SavingSharedFiles">Saving files that should be shared</a></li> + <li><a href="#ExternalCache">Saving cache files</a></li> + </ol></li> + <li><a href="#db">Using Databases</a> + <ol> + <li><a href="#dbDebugging">Database debugging</a></li> + </ol></li> <li><a href="#netw">Using a Network Connection</a></li> </ol> @@ -238,7 +251,7 @@ save to the external storage. All applications can read and write files placed o storage and the user can remove them.</p> -<h3>Checking media availability</h3> +<h3 id="MediaAvail">Checking media availability</h3> <p>Before you do any work with the external storage, you should always call {@link android.os.Environment#getExternalStorageState()} to check whether the media is available. The @@ -271,7 +284,7 @@ entirely, has been removed badly, etc. You can use these to notify the user with when your application needs to access the media.</p> -<h3>Accessing files on external storage</h3> +<h3 id="AccessingExtFiles">Accessing files on external storage</h3> <p>If you're using API Level 8 or greater, use {@link android.content.Context#getExternalFilesDir(String) getExternalFilesDir()} to open a {@link @@ -310,7 +323,7 @@ files and including them in apps like Gallery or Music.</p> </div> -<h3>Saving files that should be shared</h3> +<h3 id="SavingSharedFiles">Saving files that should be shared</h3> <p>If you want to save files that are not specific to your application and that should <em>not</em> be deleted when your application is uninstalled, save them to one of the public directories on the diff --git a/docs/html/guide/topics/fundamentals/fragments.jd b/docs/html/guide/topics/fundamentals/fragments.jd index f78096072fc6..3908a7c48e9f 100644 --- a/docs/html/guide/topics/fundamentals/fragments.jd +++ b/docs/html/guide/topics/fundamentals/fragments.jd @@ -515,7 +515,7 @@ ExampleFragment fragment = (ExampleFragment) getFragmentManager().findFragmentBy </pre> -<h4 id="EventCallbacks">Creating event callbacks to the activity</h4> +<h3 id="EventCallbacks">Creating event callbacks to the activity</h3> <p>In some cases, you might need a fragment to share events with the activity. A good way to do that is to define a callback interface inside the fragment and require that the host activity implement diff --git a/docs/html/guide/topics/nfc/index.jd b/docs/html/guide/topics/nfc/index.jd index f907b7057dc8..b486d3b081e9 100644 --- a/docs/html/guide/topics/nfc/index.jd +++ b/docs/html/guide/topics/nfc/index.jd @@ -1,35 +1,24 @@ page.title=Near Field Communication @jd:body - <div id="qv-wrapper"> - <div id="qv"> - <h2>Near Field Communication quickview</h2> - +<div id="qv-wrapper"> +<div id="qv"> + <h2>In this document</h2> + <ol> + <li><a href="#api">API Overview</a></li> + <li><a href="#manifest">Declaring Android Manifest elements</a></li> + <li><a href="#dispatch">The Tag Dispatch System</a> <ol> - <li><a href="#api">API Overview</a></li> - - <li><a href="#manifest">Declaring Android Manifest Elements</a></li> - - <li> - <a href="#dispatch">The Tag Dispatch System</a> - - <ol> - <li><a href="#intent-dispatch">Using the intent dispatch system</a></li> - - <li><a href="#foreground-dispatch">Using the foreground dispatch system</a></li> - </ol> - </li> - - <li><a href="#ndef">NDEF Messages</a></li> - - <li><a href="#read">Reading an NFC Tag</a></li> - - <li><a href="#write">Writing to an NFC Tag</a></li> - - <li><a href="#p2p">Peer to Peer Data Exchange</a></li> - </ol> - </div> - </div> + <li><a href="#intent-dispatch">Using the intent dispatch system</a></li> + <li><a href="#foreground-dispatch">Using the foreground dispatch system</a></li> + </ol></li> + <li><a href="#ndef">Working with Data on NFC Tags</a></li> + <li><a href="#read">Reading an NFC Tag</a></li> + <li><a href="#write">Writing to an NFC Tag</a></li> + <li><a href="#p2p">Peer-to-Peer Data Exchange</a></li> + </ol> +</div> +</div> <p>Near Field Communication (NFC) is a set of short-range wireless technologies, typically requiring a distance of 4cm or less. NFC operates at 13.56mhz, and at rates ranging from 106 diff --git a/docs/html/guide/topics/resources/providing-resources.jd b/docs/html/guide/topics/resources/providing-resources.jd index 1da2622f2b8a..10d25bb10730 100644 --- a/docs/html/guide/topics/resources/providing-resources.jd +++ b/docs/html/guide/topics/resources/providing-resources.jd @@ -383,6 +383,46 @@ is not related to the screen orientation.</p> which indicates whether the screen is long.</p> </td> </tr> + <tr id="ScreenWidthQualifier"> + <td>Screen width</td> + <td>Examples:<br/> + <code>w720dp</code><br/> + <code>w1024dp</code><br/> + etc. + </td> + <td> + <p>Specifies a minimum screen width, in "dp" units, at which the resource + should be used. This configuration value will change when the orientation + changes between landscape and portrait to match the current actual width. + When multiple screen width configurations are available, the closest to + the current screen width will be used. The value specified here is + approximate; screen decorations like a status bar or system bar may cause + the actual space available in your UI to be slightly smaller. + <p><em>Added in API Level 13.</em></p> + <p>Also see the {@link android.content.res.Configuration#screenWidthDp} + configuration field, which holds the current screen width.</p> + </td> + </tr> + <tr id="ScreenHeightQualifier"> + <td>Screen height</td> + <td>Examples:<br/> + <code>h720dp</code><br/> + <code>h1024dp</code><br/> + etc. + </td> + <td> + <p>Specifies a minimum screen height, in "dp" units, at which the resource + should be used. This configuration value will change when the orientation + changes between landscape and portrait to match the current actual height. + When multiple screen height configurations are available, the closest to + the current screen height will be used. The value specified here is + approximate; screen decorations like a status bar or system bar may cause + the actual space available in your UI to be slightly smaller. + <p><em>Added in API Level 13.</em></p> + <p>Also see the {@link android.content.res.Configuration#screenHeightDp} + configuration field, which holds the current screen width.</p> + </td> + </tr> <tr id="OrientationQualifier"> <td>Screen orientation</td> <td> diff --git a/docs/html/guide/topics/wireless/bluetooth.jd b/docs/html/guide/topics/wireless/bluetooth.jd index ae078b9da81e..48632ea6f5e1 100644 --- a/docs/html/guide/topics/wireless/bluetooth.jd +++ b/docs/html/guide/topics/wireless/bluetooth.jd @@ -18,18 +18,13 @@ other devices</li> <li><a href="#FindingDevices">Finding Devices</a> <ol> <li><a href="#QueryingPairedDevices">Querying paired devices</a></li> - <li><a href="#DiscoveringDevices">Discovering devices</a> - <ol><li><a href="#EnablingDiscoverability">Enabling - discoverability</a></li></ol> - </li> - </ol> - </li> + <li><a href="#DiscoveringDevices">Discovering devices</a></li> + </ol></li> <li><a href="#ConnectingDevices">Connecting Devices</a> <ol> <li><a href="#ConnectingAsAServer">Connecting as a server</a></li> <li><a href="#ConnectingAsAClient">Connecting as a client</a></li> - </ol> - </li> + </ol></li> <li><a href="#ManagingAConnection">Managing a Connection</a></li> </ol> diff --git a/docs/html/sdk/eclipse-adt.jd b/docs/html/sdk/eclipse-adt.jd index ece9d4ae0c02..feb84b1175cc 100644 --- a/docs/html/sdk/eclipse-adt.jd +++ b/docs/html/sdk/eclipse-adt.jd @@ -656,7 +656,7 @@ ADT installation as described in the steps below. </p> <h3 id="downloading">Downloading the ADT Plugin</h3> <p>Use the Update Manager feature of your Eclipse installation to install the latest -revision of ADT on your development computer.<p> +revision of ADT on your development computer.<> <p>Assuming that you have a compatible version of the Eclipse IDE installed, as described in <a href="#preparing">Preparing for Installation</a>, above, follow @@ -671,26 +671,32 @@ Software...</strong>.</li> <li>In the Add Repository dialog that appears, enter "ADT Plugin" for the <em>Name</em> and the following URL for the <em>Location</em>: <pre>https://dl-ssl.google.com/android/eclipse/</pre> - <p>Note: If you have trouble acquiring the plugin, try using "http" in the Location URL, - instead of "https" (https is preferred for security reasons).</p> - <p>Click <strong>OK</strong>.</p></li> - <li>In the Available Software dialog, select -the checkbox next to Developer Tools and click <strong>Next</strong>.</li> + </li> + <li>Click <strong>OK</strong> + <p>Note: If you have trouble acquiring the plugin, try using "http" in the Location URL, +instead of "https" (https is preferred for security reasons).</p></li> + <li>In the Available Software dialog, select the checkbox next to Developer Tools and click +<strong>Next</strong>.</li> <li>In the next window, you'll see a list of the tools to be downloaded. Click <strong>Next</strong>. </li> - <li>Read and accept the license agreements, then click <strong>Finish</strong>.</li> + <li>Read and accept the license agreements, then click <strong>Finish</strong>. + <p>Note: If you get a security warning saying that the authenticity or validity of +the software can't be established, click <strong>OK</strong>.</p></li> <li>When the installation completes, restart Eclipse. </li> </ol> <h3 id="configuring">Configuring the ADT Plugin</h3> -<p>Once you've successfully downloaded ADT as described above, the next step +<p>After you've successfully downloaded the ADT as described above, the next step is to modify your ADT preferences in Eclipse to point to the Android SDK directory:</p> <ol> <li>Select <strong>Window</strong> > <strong>Preferences...</strong> to open the Preferences panel (Mac OS X: <strong>Eclipse</strong> > <strong>Preferences</strong>).</li> - <li>Select <strong>Android</strong> from the left panel. </li> + <li>Select <strong>Android</strong> from the left panel.</li> + <p>You may see a dialog asking whether you want to send usage statistics to Google. If so, +make your choice and click <strong>Proceed</strong>. You cannot continue with this procedure until +you click <strong>Proceed</strong>.</p> <li>For the <em>SDK Location</em> in the main panel, click <strong>Browse...</strong> and locate your downloaded SDK directory. </li> <li>Click <strong>Apply</strong>, then <strong>OK</strong>.</li> diff --git a/docs/html/sdk/installing.jd b/docs/html/sdk/installing.jd index a1080c2c1a67..1dce483c273b 100644 --- a/docs/html/sdk/installing.jd +++ b/docs/html/sdk/installing.jd @@ -81,9 +81,9 @@ this page.</p> <h4>Updating?</h4> -<p>If you already have an Android SDK, use the <em>Android SDK and AVD Manager</em> tool to install +<p>If you already have an Android SDK, use the Android SDK and AVD Manager tool to install updated tools and new Android platforms into your existing environment. For information about how to -do that, see <a href="{@docRoot}sdk/adding-components.html">Adding SDK Components</a></p> +do that, see <a href="{@docRoot}sdk/adding-components.html">Adding SDK Components</a>.</p> <h2 id="Preparing">Step 1. Preparing Your Development Computer</h2> @@ -126,7 +126,7 @@ install the SDK Tools into a default location (which you can modify).</p> <p>Make a note of the name and location of the SDK directory on your system—you will need to refer to the SDK directory later, when setting up the ADT plugin and when using -the SDK tools from command line.</p> +the SDK tools from the command line.</p> <h2 id="InstallingADT">Step 3. Installing the ADT Plugin for Eclipse</h2> @@ -147,26 +147,25 @@ step-by-step installation instructions, then return here to continue the last step in setting up your Android SDK.</p> <p>If you prefer to work in a different IDE, you do not need to -install Eclipse or ADT, instead, you can directly use the SDK tools to build and -debug your application. The <a href="{@docRoot}guide/developing/index.html">Overview</a> -section of the developer guide outlines the major steps that you need to complete -when developing in Eclipse or other IDEs.</p> +install Eclipse or ADT. Instead, you can directly use the SDK tools to build and +debug your application. The <a href="{@docRoot}guide/developing/index.html">Introduction</a> +to Android application development outlines the major steps that you need to complete when +developing in Eclipse or other IDEs.</p> <h2 id="AddingComponents">Step 4. Adding Platforms and Other Components</h2> -<p>The last step in setting up your SDK is using the <em>Android SDK and AVD Manager</em> (a -tool included in the SDK starter package) to download -essential SDK components into your development environment.</p> +<p>The last step in setting up your SDK is using the Android SDK and AVD Manager (a +tool included in the SDK starter package) to download essential SDK components into your development +environment.</p> <p>The SDK uses a modular structure that separates the major parts of the SDK—Android platform versions, add-ons, tools, samples, and documentation—into a set of separately installable components. The SDK starter package, which you've already downloaded, includes only a single -component: the latest version of the SDK Tools. To develop an Android -application, you also need to download at least one Android platform and the SDK Platform-tools -(tools that the latest platform depend upon). However, downloading -additional components is highly recommended.</p> +component: the latest version of the SDK Tools. To develop an Android application, you also need to +download at least one Android platform and the associated platform tools. You can add other +components and platforms as well, which is highly recommended.</p> <p>If you used the Windows installer, when you complete the installation wizard, it will launch the Android SDK and AVD Manager with a default set of platforms and other components selected @@ -185,10 +184,10 @@ Android SDK, then execute: <pre>android</pre> </li> </ul> <p>To download components, use the graphical UI of the Android SDK and AVD -Manager, shown in Figure 1, to browse the SDK repository and select new or updated -components. The Android SDK and AVD Manager will install the selected components in -your SDK environment. For information about which components you should download, see the following -section about <a href="#which">Recommended Components</a>.</p> +Manager to browse the SDK repository and select new or updated +components (see figure 1). The Android SDK and AVD Manager installs the selected components in +your SDK environment. For information about which components you should download, see <a +href="#which">Recommended Components</a>.</p> <img src="/images/sdk_manager_packages.png" /> <p class="img-caption"><strong>Figure 1.</strong> The Android SDK and AVD Manager's @@ -204,35 +203,34 @@ Repository</em> and <em>Third party Add-ons</em>.</p> <p>The <em>Android Repository</em> offers these types of components:</p> <ul> -<li><strong>SDK Tools</strong> (pre-installed in the Android SDK starter -package) — Contains tools for debugging -and testing your application and other utility tools. You can access these -in the <code><sdk>/tools/</code> directory of your SDK and read more about them in the <a -href="{@docRoot}guide/developing/tools/index.html">Tools</a> section of the developer guide. </li> - -<li><strong>SDK Platform-tools</strong> — Contains tools that are required to develop and -debug your application, but which are developed alongside the Android platform in order to support -the latest features. These tools are typically updated only when a new platform becomes -available. You can access these -in the <code><sdk>/platform-tools/</code> directory. Read more about them in -the <a href="{@docRoot}guide/developing/tools/index.html">Tools</a> section of the developer guide. -</li> +<li><strong>SDK Tools</strong> — Contains tools for debugging and testing your application +and other utility tools. These tools are installed with the Android SDK starter package and receive +periodic updates. You can access these tools in the <code><sdk>/tools/</code> directory of +your SDK. To learn more about +them, see <a href="{@docRoot}guide/developing/tools/index.html#tools-sdk">SDK Tools</a> in the +developer guide.</li> + +<li><strong>SDK Platform-tools</strong> — Contains platform-dependent tools for developing +and debugging your application. These tools support the latest features of the Android platform and +are typically updated only when a new platform becomes available. You can access these tools in the +<code><sdk>/platform-tools/</code> directory. To learn more about them, see <a +href="{@docRoot}guide/developing/tools/index.html#tools-platform">Platform Tools</a> in the +developer guide.</li> <li><strong>Android platforms</strong> — An SDK platform is -available for every production Android platform deployable to Android-powered -devices. Each platform component includes a fully compliant Android library and -system image, sample code, emulator skins, and any version specific tools. For -detailed information about each platform, see the overview documents available -under the section "Downloadable SDK Components," at left. </li> +available for every production Android platform deployable to Android-powered devices. Each +SDK platform component includes a fully compliant Android library, system image, sample code, +and emulator skins. To learn more about a specific platform, see the list of platforms that appears +under the section "Downloadable SDK Components" on the left part of this page.</li> <li><strong>USB Driver for Windows</strong> (Windows only) — Contains driver files that you can install on your Windows computer, so that you can run and debug your applications on an actual device. You <em>do not</em> need the USB driver unless you plan to debug your application on an actual Android-powered device. If you develop on Mac OS X or Linux, you do not need a special driver to debug -your application on an Android-powered device. (See <a -href="{@docRoot}guide/developing/device.html">Developing on a Device</a> for more information -about developing on a real device.)</li> +your application on an Android-powered device. See <a +href="{@docRoot}guide/developing/device.html">Using Hardware Devices</a> for more information +about developing on a real device.</li> <li><strong>Samples</strong> — Contains the sample code and apps available for each Android development platform. If you are just getting started with @@ -247,8 +245,8 @@ multiversion documentation for the Android framework API. </li> <p>The <em>Third party Add-ons</em> provide components that allow you to create a development environment using a specific Android external library (such as the Google Maps library) or a -customized (but fully compliant) Android system image. You can add additional Add-on repositories, -by clicking <strong>Add Add-on Site</strong>.</p> +customized (but fully compliant) Android system image. You can add additional Add-on repositories by +clicking <strong>Add Add-on Site</strong>.</p> <h3 id="which">Recommended Components</h3> @@ -381,12 +379,11 @@ file <code>offline.html</code> in a web browser.</td> </tr> <tr> <td colspan="3"><code>platform-tools/</code></td> -<td>Contains development tools that may be updated with each platform release (from the <em>Android -SDK Platform-tools</em> component). Tools in here include {@code adb}, {@code dexdump}, and others -others that you don't typically use directly. These tools are separate from the generic development -tools in the {@code tools/} directory, because these tools may be updated in order to support new -features in the latest Android platform, whereas the other tools have no dependencies on the -platform version.</td> +<td>Contains platform-dependent development tools that may be updated with each platform release. +The platform tools include the Android Debug Bridge ({@code adb}) as well as other tools that you +don't typically use directly. These tools are separate from the development tools in the {@code +tools/} directory because these tools may be updated in order to support new +features in the latest Android platform.</td> </tr> <tr> <td colspan="3"><code>platforms/</code></td> @@ -394,52 +391,12 @@ platform version.</td> applications against, each in a separate directory. </td> </tr> <tr> -<td style="width:2em;border-bottom-color:white;"></td> -<td colspan="2"><code><em><platform></em>/</code></td> -<td>Platform version directory, for example "android-1.6". All platform version -directories contain a similar set of files and subdirectory structure.</td> -</tr> - -<tr> -<td style="width:2em;border-bottom-color:white;"> </td> -<td style="width:2em;border-bottom-color:white;"></td> -<td><code>data/</code></td> -<td>Storage area for default fonts and resource definitions.</td> -</tr> -<tr> -<td style="width:2em;border-bottom-color:white;"></td> -<td style="width:2em;border-bottom-color:white;"></td> -<td><code>images/</code></td> -<td>Storage area for default disk images, including the Android system image, -the default userdata image, the default ramdisk image, and more. The images -are used in emulator sessions.</td> -</tr> -<tr> -<td style="width:2em;border-bottom-color:white;"></td> -<td style="width:2em;border-bottom-color:white;"></td> -<td><code>skins/</code></td> -<td>A set of emulator skins available for the platform version. Each skin is -designed for a specific screen resolution.</td> -</tr> -<tr> -<td style="width:2em;border-bottom-color:white;"></td> -<td style="width:2em;border-bottom-color:white;"></td> -<td><code>templates/</code></td> -<td>Storage area for file templates used by the SDK development tools.</td> -</tr> -<tr> -<td style="width:2em;border-bottom-color:white;"></td> -<td style="width:2em;border-bottom-color:white;"></td> -<td><code>tools/</code></td> -<td>This directory is used only by SDK Tools r7 and below for development tools that are specific to -this platform version—it's not used by SDK Tools r8 and above.</td> -</tr> -<tr> -<td style="width:2em;"></td> <td style="width:2em;"></td> -<td><code>android.jar</code></td> -<td>The Android library used when compiling applications against this platform -version.</td> +<td colspan="2"><code><em><platform></em>/</code></td> +<td>Platform version directory, for example "android-11". All platform version directories contain +a similar set of files and subdirectory structure. Each platform directory also includes the +Android library (<code>android.jar</code>) that is used to compile applications against the +platform version.</td> </tr> <tr> <td colspan="3"><code>samples/</code></td> @@ -448,21 +405,20 @@ version.</td> <tr> <td colspan="3"><code>tools/</code></td> <td>Contains the set of development and profiling tools that are platform-independent, such -as the emulator, the AVD and SDK Manager, ddms, hierarchyviewer and more. The tools in -this directory may be updated at any time (from the <em>Android SDK Tools</em> component), -independent of platform releases, whereas the tools in {@code platform-tools/} may be updated based -on the latest platform release.</td> +as the emulator, the Android SDK and AVD Manager, <code>ddms</code>, <code>hierarchyviewer</code> +and more. The tools in this directory may be updated at any time using the Android SDK and AVD +Manager and are independent of platform releases.</td> </tr> <tr> <td colspan="3"><code>SDK Readme.txt</code></td> <td>A file that explains how to perform the initial setup of your SDK, including how to launch the Android SDK and AVD Manager tool on all -platforms</td> +platforms.</td> </tr> <tr> <td colspan="3"><code>SDK Manager.exe</code></td> <td>Windows SDK only. A shortcut that launches the Android SDK and AVD -Manager tool, which you use to add components to your SDK. </td> +Manager tool, which you use to add components to your SDK.</td> </tr> <!--<tr> <td colspan="3"><code>documentation.html</code></td> @@ -499,7 +455,7 @@ include these directories in your PATH in the following way:</p> <li>On Linux, edit your <code>~/.bash_profile</code> or <code>~/.bashrc</code> file. Look for a line that sets the PATH environment variable and add the - full path to the <code>tools/</code> and <code>platform-tools</code> directories to it. If you + full path to the <code>tools/</code> and <code>platform-tools/</code> directories to it. If you don't see a line setting the path, you can add one: <pre>export PATH=${PATH}:<sdk>/tools:<sdk>/platform-tools</pre> </li> @@ -533,28 +489,27 @@ first step in getting started with Android development. </p> <p><strong>Learn about Android</strong></p> <ul> <li>Take a look at the <a href="{@docRoot}guide/index.html">Dev - Guide</a> and the types of information it provides</li> + Guide</a> and the types of information it provides.</li> <li>Read an introduction to Android as a platform in <a href="{@docRoot}guide/basics/what-is-android.html">What is Android?</a></li> <li>Learn about the Android framework and how applications run on it in <a href="{@docRoot}guide/topics/fundamentals.html">Application - Fundamentals</a></li> + Fundamentals</a>.</li> <li>Take a look at the Android framework API specification in the <a - href="{@docRoot}reference/packages.html">Reference</a> tab</li> + href="{@docRoot}reference/packages.html">Reference</a> tab.</li> </ul> <p><strong>Explore the development tools</strong></p> <ul> <li>Get an overview of the <a href="{@docRoot}guide/developing/tools/index.html">development - tools</a> that are available to you</li> - <li>Read the <a - href="{@docRoot}guide/developing/index.html">Overview</a> - for how to develop an Android application. + tools</a> that are available to you.</li> + <li>Read the <a href="{@docRoot}guide/developing/index.html">Introduction</a> to Android +application development. </li> - <li>Read <a href="{@docRoot}guide/developing/device.html">Developing on a Device</a> to set up an -Android-powered device to run and test your application.</li> + <li>Read <a href="{@docRoot}guide/developing/device.html">Using Hardware Devices</a> to learn +how to set up an Android-powered device so you can run and test your application.</li> </ul> <p><strong>Follow the Notepad tutorial</strong></p> diff --git a/include/private/media/AudioTrackShared.h b/include/private/media/AudioTrackShared.h index 46101353e650..1827c3ea2ba9 100644 --- a/include/private/media/AudioTrackShared.h +++ b/include/private/media/AudioTrackShared.h @@ -83,13 +83,12 @@ struct audio_track_cblk_t uint8_t frameSize; uint8_t channelCount; - uint16_t flags; - uint16_t bufferTimeoutMs; // Maximum cumulated timeout before restarting audioflinger - uint16_t waitTimeMs; // Cumulated wait time + uint16_t waitTimeMs; // Cumulated wait time uint16_t sendLevel; - uint16_t reserved; + volatile int32_t flags; + // Cache line boundary (32 bytes) audio_track_cblk_t(); uint32_t stepUser(uint32_t frameCount); @@ -98,6 +97,7 @@ struct audio_track_cblk_t uint32_t framesAvailable(); uint32_t framesAvailable_l(); uint32_t framesReady(); + bool tryLock(); }; diff --git a/include/utils/ResourceTypes.h b/include/utils/ResourceTypes.h index 6227f3e92853..35792dc0c7bd 100644 --- a/include/utils/ResourceTypes.h +++ b/include/utils/ResourceTypes.h @@ -972,6 +972,14 @@ struct ResTable_config uint32_t screenConfig; }; + union { + struct { + uint16_t screenWidthDp; + uint16_t screenHeightDp; + }; + uint32_t screenSizeDp; + }; + inline void copyFromDeviceNoSwap(const ResTable_config& o) { const size_t size = dtohl(o.size); if (size >= sizeof(ResTable_config)) { @@ -992,6 +1000,8 @@ struct ResTable_config screenHeight = dtohs(screenHeight); sdkVersion = dtohs(sdkVersion); minorVersion = dtohs(minorVersion); + screenWidthDp = dtohs(screenWidthDp); + screenHeightDp = dtohs(screenHeightDp); } inline void swapHtoD() { @@ -1003,6 +1013,8 @@ struct ResTable_config screenHeight = htods(screenHeight); sdkVersion = htods(sdkVersion); minorVersion = htods(minorVersion); + screenWidthDp = htods(screenWidthDp); + screenHeightDp = htods(screenHeightDp); } inline int compare(const ResTable_config& o) const { @@ -1021,6 +1033,8 @@ struct ResTable_config diff = (int32_t)(screenLayout - o.screenLayout); if (diff != 0) return diff; diff = (int32_t)(uiMode - o.uiMode); + if (diff != 0) return diff; + diff = (int32_t)(screenSizeDp - o.screenSizeDp); return (int)diff; } @@ -1061,6 +1075,7 @@ struct ResTable_config if (version != o.version) diffs |= CONFIG_VERSION; if (screenLayout != o.screenLayout) diffs |= CONFIG_SCREEN_LAYOUT; if (uiMode != o.uiMode) diffs |= CONFIG_UI_MODE; + if (screenSizeDp != o.screenSizeDp) diffs |= CONFIG_SCREEN_SIZE; return diffs; } @@ -1105,6 +1120,18 @@ struct ResTable_config } } + if (screenSizeDp || o.screenSizeDp) { + if (screenWidthDp != o.screenWidthDp) { + if (!screenWidthDp) return false; + if (!o.screenWidthDp) return true; + } + + if (screenHeightDp != o.screenHeightDp) { + if (!screenHeightDp) return false; + if (!o.screenHeightDp) return true; + } + } + if (orientation != o.orientation) { if (!orientation) return false; if (!o.orientation) return true; @@ -1243,6 +1270,30 @@ struct ResTable_config } } + if (screenSizeDp || o.screenSizeDp) { + // Better is based on the sum of the difference between both + // width and height from the requested dimensions. We are + // assuming the invalid configs (with smaller dimens) have + // already been filtered. Note that if a particular dimension + // is unspecified, we will end up with a large value (the + // difference between 0 and the requested dimension), which is + // good since we will prefer a config that has specified a + // dimension value. + int myDelta = 0, otherDelta = 0; + if (requested->screenWidthDp) { + myDelta += requested->screenWidthDp - screenWidthDp; + otherDelta += requested->screenWidthDp - o.screenWidthDp; + } + if (requested->screenHeightDp) { + myDelta += requested->screenHeightDp - screenHeightDp; + otherDelta += requested->screenHeightDp - o.screenHeightDp; + } + //LOGI("Comparing this %dx%d to other %dx%d in %dx%d: myDelta=%d otherDelta=%d", + // screenWidthDp, screenHeightDp, o.screenWidthDp, o.screenHeightDp, + // requested->screenWidthDp, requested->screenHeightDp, myDelta, otherDelta); + return (myDelta <= otherDelta); + } + if ((orientation != o.orientation) && requested->orientation) { return (orientation); } @@ -1426,6 +1477,18 @@ struct ResTable_config return false; } } + if (screenSizeDp != 0) { + if (settings.screenWidthDp != 0 && screenWidthDp != 0 + && screenWidthDp > settings.screenWidthDp) { + //LOGI("Filtering out width %d in requested %d", screenWidthDp, settings.screenWidthDp); + return false; + } + if (settings.screenHeightDp != 0 && screenHeightDp != 0 + && screenHeightDp > settings.screenHeightDp) { + //LOGI("Filtering out height %d in requested %d", screenHeightDp, settings.screenHeightDp); + return false; + } + } if (screenType != 0) { if (settings.orientation != 0 && orientation != 0 && orientation != settings.orientation) { @@ -1505,13 +1568,13 @@ struct ResTable_config String8 toString() const { char buf[200]; sprintf(buf, "imsi=%d/%d lang=%c%c reg=%c%c orient=%d touch=%d dens=%d " - "kbd=%d nav=%d input=%d scrnW=%d scrnH=%d sz=%d long=%d " + "kbd=%d nav=%d input=%d ssz=%dx%d %ddp x %ddp sz=%d long=%d " "ui=%d night=%d vers=%d.%d", mcc, mnc, language[0] ? language[0] : '-', language[1] ? language[1] : '-', country[0] ? country[0] : '-', country[1] ? country[1] : '-', orientation, touchscreen, density, keyboard, navigation, inputFlags, - screenWidth, screenHeight, + screenWidth, screenHeight, screenWidthDp, screenHeightDp, screenLayout&MASK_SCREENSIZE, screenLayout&MASK_SCREENLONG, uiMode&MASK_UI_MODE_TYPE, uiMode&MASK_UI_MODE_NIGHT, sdkVersion, minorVersion); diff --git a/libs/utils/ResourceTypes.cpp b/libs/utils/ResourceTypes.cpp index 7197ad7a2b7e..ac9cdf9f9f21 100644 --- a/libs/utils/ResourceTypes.cpp +++ b/libs/utils/ResourceTypes.cpp @@ -2424,7 +2424,7 @@ void ResTable::setParameters(const ResTable_config* params) { mLock.lock(); TABLE_GETENTRY(LOGI("Setting parameters: imsi:%d/%d lang:%c%c cnt:%c%c " - "orien:%d touch:%d density:%d key:%d inp:%d nav:%d w:%d h:%d\n", + "orien:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d %ddp x %ddp\n", params->mcc, params->mnc, params->language[0] ? params->language[0] : '-', params->language[1] ? params->language[1] : '-', @@ -2437,7 +2437,9 @@ void ResTable::setParameters(const ResTable_config* params) params->inputFlags, params->navigation, params->screenWidth, - params->screenHeight)); + params->screenHeight, + params->screenWidthDp, + params->screenHeightDp)); mParams = *params; for (size_t i=0; i<mPackageGroups.size(); i++) { TABLE_NOISY(LOGI("CLEARING BAGS FOR GROUP %d!", i)); @@ -3758,8 +3760,10 @@ ssize_t ResTable::getEntry( ResTable_config thisConfig; thisConfig.copyFromDtoH(thisType->config); - TABLE_GETENTRY(LOGI("Match entry 0x%x in type 0x%x (sz 0x%x): imsi:%d/%d=%d/%d lang:%c%c=%c%c cnt:%c%c=%c%c " - "orien:%d=%d touch:%d=%d density:%d=%d key:%d=%d inp:%d=%d nav:%d=%d w:%d=%d h:%d=%d\n", + TABLE_GETENTRY(LOGI("Match entry 0x%x in type 0x%x (sz 0x%x): imsi:%d/%d=%d/%d " + "lang:%c%c=%c%c cnt:%c%c=%c%c orien:%d=%d touch:%d=%d " + "density:%d=%d key:%d=%d inp:%d=%d nav:%d=%d w:%d=%d h:%d=%d " + "wdp:%d=%d hdp:%d=%d\n", entryIndex, typeIndex+1, dtohl(thisType->config.size), thisConfig.mcc, thisConfig.mnc, config ? config->mcc : 0, config ? config->mnc : 0, @@ -3786,7 +3790,11 @@ ssize_t ResTable::getEntry( thisConfig.screenWidth, config ? config->screenWidth : 0, thisConfig.screenHeight, - config ? config->screenHeight : 0)); + config ? config->screenHeight : 0, + thisConfig.screenWidthDp, + config ? config->screenWidthDp : 0, + thisConfig.screenHeightDp, + config ? config->screenHeightDp : 0)); // Check to make sure this one is valid for the current parameters. if (config && !thisConfig.match(*config)) { @@ -4067,7 +4075,8 @@ status_t ResTable::parsePackage(const ResTable_package* const pkg, ResTable_config thisConfig; thisConfig.copyFromDtoH(type->config); LOGI("Adding config to type %d: imsi:%d/%d lang:%c%c cnt:%c%c " - "orien:%d touch:%d density:%d key:%d inp:%d nav:%d w:%d h:%d\n", + "orien:%d touch:%d density:%d key:%d inp:%d nav:%d w:%d h:%d " + "wdp:%d hdp:%d\n", type->id, thisConfig.mcc, thisConfig.mnc, thisConfig.language[0] ? thisConfig.language[0] : '-', @@ -4081,7 +4090,9 @@ status_t ResTable::parsePackage(const ResTable_package* const pkg, thisConfig.inputFlags, thisConfig.navigation, thisConfig.screenWidth, - thisConfig.screenHeight)); + thisConfig.screenHeight, + thisConfig.screenWidthDp, + thisConfig.screenHeightDp)); t->configs.add(type); } else { status_t err = validate_chunk(chunk, sizeof(ResChunk_header), @@ -4444,6 +4455,12 @@ void ResTable::print(bool inclValues) const if (type->config.screenHeight != 0) { printf(" h=%d", dtohs(type->config.screenHeight)); } + if (type->config.screenWidthDp != 0) { + printf(" wdp=%d", dtohs(type->config.screenWidthDp)); + } + if (type->config.screenHeightDp != 0) { + printf(" hdp=%d", dtohs(type->config.screenHeightDp)); + } if (type->config.sdkVersion != 0) { printf(" sdk=%d", dtohs(type->config.sdkVersion)); } diff --git a/media/java/android/mtp/MtpDatabase.java b/media/java/android/mtp/MtpDatabase.java index b4a46891f95a..b900671c22fc 100644 --- a/media/java/android/mtp/MtpDatabase.java +++ b/media/java/android/mtp/MtpDatabase.java @@ -50,7 +50,8 @@ public class MtpDatabase { private final IContentProvider mMediaProvider; private final String mVolumeName; private final Uri mObjectsUri; - private final String mMediaStoragePath; + private final String mMediaStoragePath; // path to primary storage + private final HashMap<String, MtpStorage> mStorageMap = new HashMap<String, MtpStorage>(); // cached property groups for single properties private final HashMap<Integer, MtpPropertyGroup> mPropertyGroupsByProperty @@ -67,9 +68,6 @@ public class MtpDatabase { private SharedPreferences mDeviceProperties; private static final int DEVICE_PROPERTIES_DATABASE_VERSION = 1; - // FIXME - this should be passed in via the constructor - private final int mStorageID = 0x00010001; - private static final String[] ID_PROJECTION = new String[] { Files.FileColumns._ID, // 0 }; @@ -85,17 +83,22 @@ public class MtpDatabase { }; private static final String[] OBJECT_INFO_PROJECTION = new String[] { Files.FileColumns._ID, // 0 - Files.FileColumns.DATA, // 1 + Files.FileColumns.STORAGE_ID, // 1 Files.FileColumns.FORMAT, // 2 Files.FileColumns.PARENT, // 3 - Files.FileColumns.SIZE, // 4 - Files.FileColumns.DATE_MODIFIED, // 5 + Files.FileColumns.DATA, // 4 + Files.FileColumns.SIZE, // 5 + Files.FileColumns.DATE_MODIFIED, // 6 }; private static final String ID_WHERE = Files.FileColumns._ID + "=?"; private static final String PATH_WHERE = Files.FileColumns.DATA + "=?"; private static final String PARENT_WHERE = Files.FileColumns.PARENT + "=?"; private static final String PARENT_FORMAT_WHERE = PARENT_WHERE + " AND " + Files.FileColumns.FORMAT + "=?"; + private static final String PARENT_STORAGE_WHERE = PARENT_WHERE + " AND " + + Files.FileColumns.STORAGE_ID + "=?"; + private static final String PARENT_STORAGE_FORMAT_WHERE = PARENT_STORAGE_WHERE + " AND " + + Files.FileColumns.FORMAT + "=?"; private final MediaScanner mMediaScanner; @@ -124,6 +127,14 @@ public class MtpDatabase { } } + public void addStorage(MtpStorage storage) { + mStorageMap.put(storage.getPath(), storage); + } + + public void removeStorage(MtpStorage storage) { + mStorageMap.remove(storage.getPath()); + } + private void initDeviceProperties(Context context) { final String devicePropertiesName = "device-properties"; mDeviceProperties = context.getSharedPreferences(devicePropertiesName, Context.MODE_PRIVATE); @@ -160,7 +171,7 @@ public class MtpDatabase { } private int beginSendObject(String path, int format, int parent, - int storage, long size, long modified) { + int storageId, long size, long modified) { // first make sure the object does not exist if (path != null) { Cursor c = null; @@ -185,7 +196,7 @@ public class MtpDatabase { values.put(Files.FileColumns.DATA, path); values.put(Files.FileColumns.FORMAT, format); values.put(Files.FileColumns.PARENT, parent); - // storage is ignored for now + values.put(Files.FileColumns.STORAGE_ID, storageId); values.put(Files.FileColumns.SIZE, size); values.put(Files.FileColumns.DATE_MODIFIED, modified); @@ -237,19 +248,35 @@ public class MtpDatabase { } } - private int[] getObjectList(int storageID, int format, int parent) { - // we can ignore storageID until we support multiple storages - Cursor c = null; - try { + private Cursor createObjectQuery(int storageID, int format, int parent) throws RemoteException { + if (storageID != 0) { + if (format != 0) { + return mMediaProvider.query(mObjectsUri, ID_PROJECTION, + PARENT_STORAGE_FORMAT_WHERE, + new String[] { Integer.toString(parent), Integer.toString(storageID), + Integer.toString(format) }, null); + } else { + return mMediaProvider.query(mObjectsUri, ID_PROJECTION, + PARENT_STORAGE_WHERE, new String[] + { Integer.toString(parent), Integer.toString(storageID) }, null); + } + } else { if (format != 0) { - c = mMediaProvider.query(mObjectsUri, ID_PROJECTION, + return mMediaProvider.query(mObjectsUri, ID_PROJECTION, PARENT_FORMAT_WHERE, new String[] { Integer.toString(parent), Integer.toString(format) }, null); } else { - c = mMediaProvider.query(mObjectsUri, ID_PROJECTION, + return mMediaProvider.query(mObjectsUri, ID_PROJECTION, PARENT_WHERE, new String[] { Integer.toString(parent) }, null); } + } + } + + private int[] getObjectList(int storageID, int format, int parent) { + Cursor c = null; + try { + c = createObjectQuery(storageID, format, parent); if (c == null) { return null; } @@ -273,18 +300,9 @@ public class MtpDatabase { } private int getNumObjects(int storageID, int format, int parent) { - // we can ignore storageID until we support multiple storages Cursor c = null; try { - if (format != 0) { - c = mMediaProvider.query(mObjectsUri, ID_PROJECTION, - PARENT_FORMAT_WHERE, - new String[] { Integer.toString(parent), Integer.toString(format) }, - null); - } else { - c = mMediaProvider.query(mObjectsUri, ID_PROJECTION, - PARENT_WHERE, new String[] { Integer.toString(parent) }, null); - } + c = createObjectQuery(storageID, format, parent); if (c != null) { return c.getCount(); } @@ -508,7 +526,7 @@ public class MtpDatabase { } } - return propertyGroup.getPropertyList((int)handle, format, depth, mStorageID); + return propertyGroup.getPropertyList((int)handle, format, depth); } private int renameFile(int handle, String newName) { @@ -631,12 +649,12 @@ public class MtpDatabase { c = mMediaProvider.query(mObjectsUri, OBJECT_INFO_PROJECTION, ID_WHERE, new String[] { Integer.toString(handle) }, null); if (c != null && c.moveToNext()) { - outStorageFormatParent[0] = mStorageID; + outStorageFormatParent[0] = c.getInt(1); outStorageFormatParent[1] = c.getInt(2); outStorageFormatParent[2] = c.getInt(3); // extract name from path - String path = c.getString(1); + String path = c.getString(4); int lastSlash = path.lastIndexOf('/'); int start = (lastSlash >= 0 ? lastSlash + 1 : 0); int end = path.length(); @@ -646,8 +664,8 @@ public class MtpDatabase { path.getChars(start, end, outName, 0); outName[end - start] = 0; - outSizeModified[0] = c.getLong(4); - outSizeModified[1] = c.getLong(5); + outSizeModified[0] = c.getLong(5); + outSizeModified[1] = c.getLong(6); return true; } } catch (RemoteException e) { diff --git a/media/java/android/mtp/MtpPropertyGroup.java b/media/java/android/mtp/MtpPropertyGroup.java index fceedd28e040..b75b11a0ff99 100644 --- a/media/java/android/mtp/MtpPropertyGroup.java +++ b/media/java/android/mtp/MtpPropertyGroup.java @@ -93,7 +93,7 @@ class MtpPropertyGroup { switch (code) { case MtpConstants.PROPERTY_STORAGE_ID: - // no query needed until we support multiple storage units + column = Files.FileColumns.STORAGE_ID; type = MtpConstants.TYPE_UINT32; break; case MtpConstants.PROPERTY_OBJECT_FORMAT: @@ -134,6 +134,7 @@ class MtpPropertyGroup { break; case MtpConstants.PROPERTY_PERSISTENT_UID: // PUID is concatenation of storageID and object handle + column = Files.FileColumns.STORAGE_ID; type = MtpConstants.TYPE_UINT128; break; case MtpConstants.PROPERTY_DURATION: @@ -280,7 +281,7 @@ class MtpPropertyGroup { return path.substring(start, end); } - MtpPropertyList getPropertyList(int handle, int format, int depth, int storageID) { + MtpPropertyList getPropertyList(int handle, int format, int depth) { //Log.d(TAG, "getPropertyList handle: " + handle + " format: " + format + " depth: " + depth); if (depth > 1) { // we only support depth 0 and 1 @@ -348,10 +349,6 @@ class MtpPropertyGroup { // handle some special cases switch (propertyCode) { - case MtpConstants.PROPERTY_STORAGE_ID: - result.append(handle, propertyCode, MtpConstants.TYPE_UINT32, - storageID); - break; case MtpConstants.PROPERTY_PROTECTION_STATUS: // protection status is always 0 result.append(handle, propertyCode, MtpConstants.TYPE_UINT16, 0); @@ -398,7 +395,7 @@ class MtpPropertyGroup { break; case MtpConstants.PROPERTY_PERSISTENT_UID: // PUID is concatenation of storageID and object handle - long puid = storageID; + long puid = c.getLong(column); puid <<= 32; puid += handle; result.append(handle, propertyCode, MtpConstants.TYPE_UINT128, puid); diff --git a/media/java/android/mtp/MtpServer.java b/media/java/android/mtp/MtpServer.java index 006fa6d22aa2..c065ca842b23 100644 --- a/media/java/android/mtp/MtpServer.java +++ b/media/java/android/mtp/MtpServer.java @@ -33,8 +33,8 @@ public class MtpServer { System.loadLibrary("media_jni"); } - public MtpServer(MtpDatabase database, String storagePath, long reserveSpace) { - native_setup(database, storagePath, reserveSpace); + public MtpServer(MtpDatabase database) { + native_setup(database); } public void start() { @@ -65,18 +65,20 @@ public class MtpServer { native_set_ptp_mode(usePtp); } - // Used to disable MTP by removing all storage units. - // This is done to disable access to file transfer when the device is locked. - public void setLocked(boolean locked) { - native_set_locked(locked); + public void addStorage(MtpStorage storage) { + native_add_storage(storage); } - private native final void native_setup(MtpDatabase database, String storagePath, - long reserveSpace); + public void removeStorage(MtpStorage storage) { + native_remove_storage(storage.getStorageId()); + } + + private native final void native_setup(MtpDatabase database); private native final void native_start(); private native final void native_stop(); private native final void native_send_object_added(int handle); private native final void native_send_object_removed(int handle); private native final void native_set_ptp_mode(boolean usePtp); - private native final void native_set_locked(boolean locked); + private native final void native_add_storage(MtpStorage storage); + private native final void native_remove_storage(int storageId); } diff --git a/media/java/android/mtp/MtpStorage.java b/media/java/android/mtp/MtpStorage.java new file mode 100644 index 000000000000..33146e7dadb4 --- /dev/null +++ b/media/java/android/mtp/MtpStorage.java @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.mtp; + +/** + * This class represents a storage unit on an MTP device. + * Used only for MTP support in USB responder mode. + * MtpStorageInfo is used in MTP host mode + * + * @hide + */ +public class MtpStorage { + + private final int mStorageId; + private final String mPath; + private final String mDescription; + private final long mReserveSpace; + + public MtpStorage(int id, String path, String description, long reserveSpace) { + mStorageId = id; + mPath = path; + mDescription = description; + mReserveSpace = reserveSpace; + } + + /** + * Returns the storage ID for the storage unit + * + * @return the storage ID + */ + public final int getStorageId() { + return mStorageId; + } + + /** + * Generates a storage ID for storage of given index. + * Index 0 is for primary external storage + * + * @return the storage ID + */ + public static int getStorageId(int index) { + // storage ID is 0x00010001 for primary storage, + // then 0x00020001, 0x00030001, etc. for secondary storages + return ((index + 1) << 16) + 1; + } + + /** + * Returns the file path for the storage unit's storage in the file system + * + * @return the storage file path + */ + public final String getPath() { + return mPath; + } + + /** + * Returns the description string for the storage unit + * + * @return the storage unit description + */ + public final String getDescription() { + return mDescription; + } + + /** + * Returns the amount of space to reserve on the storage file system. + * This can be set to a non-zero value to prevent MTP from filling up the entire storage. + * + * @return the storage unit description + */ + public final long getReserveSpace() { + return mReserveSpace; + } + +} diff --git a/media/jni/android_media_MediaMetadataRetriever.cpp b/media/jni/android_media_MediaMetadataRetriever.cpp index 5d9a3c5ce0ae..27b37b7a3c11 100644 --- a/media/jni/android_media_MediaMetadataRetriever.cpp +++ b/media/jni/android_media_MediaMetadataRetriever.cpp @@ -441,19 +441,20 @@ static void android_media_MediaMetadataRetriever_native_init(JNIEnv *env) { jclass clazz = env->FindClass(kClassPathName); if (clazz == NULL) { - jniThrowException(env, "java/lang/RuntimeException", "Can't find android/media/MediaMetadataRetriever"); return; } fields.context = env->GetFieldID(clazz, "mNativeContext", "I"); if (fields.context == NULL) { - jniThrowException(env, "java/lang/RuntimeException", "Can't find MediaMetadataRetriever.mNativeContext"); return; } - fields.bitmapClazz = env->FindClass("android/graphics/Bitmap"); + jclass bitmapClazz = env->FindClass("android/graphics/Bitmap"); + if (bitmapClazz == NULL) { + return; + } + fields.bitmapClazz = (jclass) env->NewGlobalRef(bitmapClazz); if (fields.bitmapClazz == NULL) { - jniThrowException(env, "java/lang/RuntimeException", "Can't find android/graphics/Bitmap"); return; } fields.createBitmapMethod = @@ -461,8 +462,6 @@ static void android_media_MediaMetadataRetriever_native_init(JNIEnv *env) "(IILandroid/graphics/Bitmap$Config;)" "Landroid/graphics/Bitmap;"); if (fields.createBitmapMethod == NULL) { - jniThrowException(env, "java/lang/RuntimeException", - "Can't find Bitmap.createBitmap(int, int, Config) method"); return; } fields.createScaledBitmapMethod = @@ -470,28 +469,25 @@ static void android_media_MediaMetadataRetriever_native_init(JNIEnv *env) "(Landroid/graphics/Bitmap;IIZ)" "Landroid/graphics/Bitmap;"); if (fields.createScaledBitmapMethod == NULL) { - jniThrowException(env, "java/lang/RuntimeException", - "Can't find Bitmap.createScaledBitmap(Bitmap, int, int, boolean) method"); return; } fields.nativeBitmap = env->GetFieldID(fields.bitmapClazz, "mNativeBitmap", "I"); if (fields.nativeBitmap == NULL) { - jniThrowException(env, "java/lang/RuntimeException", - "Can't find Bitmap.mNativeBitmap field"); + return; } - fields.configClazz = env->FindClass("android/graphics/Bitmap$Config"); + jclass configClazz = env->FindClass("android/graphics/Bitmap$Config"); + if (configClazz == NULL) { + return; + } + fields.configClazz = (jclass) env->NewGlobalRef(configClazz); if (fields.configClazz == NULL) { - jniThrowException(env, "java/lang/RuntimeException", - "Can't find Bitmap$Config class"); return; } fields.createConfigMethod = env->GetStaticMethodID(fields.configClazz, "nativeToConfig", "(I)Landroid/graphics/Bitmap$Config;"); if (fields.createConfigMethod == NULL) { - jniThrowException(env, "java/lang/RuntimeException", - "Can't find Bitmap$Config.nativeToConfig(int) method"); return; } } diff --git a/media/jni/android_mtp_MtpServer.cpp b/media/jni/android_mtp_MtpServer.cpp index e025ef1acff8..c55189f3491d 100644 --- a/media/jni/android_mtp_MtpServer.cpp +++ b/media/jni/android_mtp_MtpServer.cpp @@ -39,6 +39,17 @@ using namespace android; +// MtpStorage class +jclass clazz_MtpStorage; + +// MtpStorage fields +static jfieldID field_MtpStorage_storageId; +static jfieldID field_MtpStorage_path; +static jfieldID field_MtpStorage_description; +static jfieldID field_MtpStorage_reserveSpace; + +static Mutex sMutex; + // ---------------------------------------------------------------------------- // in android_mtp_MtpDatabase.cpp @@ -57,70 +68,77 @@ class MtpThread : public Thread { private: MtpDatabase* mDatabase; MtpServer* mServer; - MtpStorage* mStorage; - Mutex mMutex; + MtpStorageList mStorageList; bool mUsePtp; - bool mLocked; int mFd; public: - MtpThread(MtpDatabase* database, MtpStorage* storage) + MtpThread(MtpDatabase* database) : mDatabase(database), mServer(NULL), - mStorage(storage), mUsePtp(false), - mLocked(false), mFd(-1) { } virtual ~MtpThread() { - delete mStorage; } void setPtpMode(bool usePtp) { - mMutex.lock(); mUsePtp = usePtp; - mMutex.unlock(); } - void setLocked(bool locked) { - mMutex.lock(); - if (locked != mLocked) { - if (mServer) { - if (locked) - mServer->removeStorage(mStorage); - else - mServer->addStorage(mStorage); + void addStorage(MtpStorage *storage) { + mStorageList.push(storage); + if (mServer) + mServer->addStorage(storage); + } + + void removeStorage(MtpStorageID id) { + MtpStorage* storage = mServer->getStorage(id); + if (storage) { + for (int i = 0; i < mStorageList.size(); i++) { + if (mStorageList[i] == storage) { + mStorageList.removeAt(i); + break; + } } - mLocked = locked; + if (mServer) + mServer->removeStorage(storage); + delete storage; } - mMutex.unlock(); + } + + void start() { + run("MtpThread"); } virtual bool threadLoop() { - mMutex.lock(); + sMutex.lock(); + mFd = open("/dev/mtp_usb", O_RDWR); if (mFd >= 0) { ioctl(mFd, MTP_SET_INTERFACE_MODE, (mUsePtp ? MTP_INTERFACE_MODE_PTP : MTP_INTERFACE_MODE_MTP)); mServer = new MtpServer(mFd, mDatabase, AID_MEDIA_RW, 0664, 0775); - if (!mLocked) - mServer->addStorage(mStorage); - - mMutex.unlock(); - mServer->run(); - mMutex.lock(); - - close(mFd); - mFd = -1; - delete mServer; - mServer = NULL; + for (int i = 0; i < mStorageList.size(); i++) { + mServer->addStorage(mStorageList[i]); + } } else { LOGE("could not open MTP driver, errno: %d", errno); } - mMutex.unlock(); + + sMutex.unlock(); + mServer->run(); + sMutex.lock(); + + close(mFd); + mFd = -1; + delete mServer; + mServer = NULL; + + sMutex.unlock(); // delay a bit before retrying to avoid excessive spin if (!exitPending()) { sleep(1); @@ -130,17 +148,13 @@ public: } void sendObjectAdded(MtpObjectHandle handle) { - mMutex.lock(); if (mServer) mServer->sendObjectAdded(handle); - mMutex.unlock(); } void sendObjectRemoved(MtpObjectHandle handle) { - mMutex.lock(); if (mServer) mServer->sendObjectRemoved(handle); - mMutex.unlock(); } }; @@ -150,18 +164,11 @@ static sp<MtpThread> sThread; #endif // HAVE_ANDROID_OS static void -android_mtp_MtpServer_setup(JNIEnv *env, jobject thiz, jobject javaDatabase, - jstring storagePath, jlong reserveSpace) +android_mtp_MtpServer_setup(JNIEnv *env, jobject thiz, jobject javaDatabase) { #ifdef HAVE_ANDROID_OS - MtpDatabase* database = getMtpDatabase(env, javaDatabase); - const char *storagePathStr = env->GetStringUTFChars(storagePath, NULL); - // create the thread and assign it to the smart pointer - MtpStorage* storage = new MtpStorage(MTP_FIRST_STORAGE_ID, storagePathStr, reserveSpace); - sThread = new MtpThread(database, storage); - - env->ReleaseStringUTFChars(storagePath, storagePathStr); + sThread = new MtpThread(getMtpDatabase(env, javaDatabase)); #endif } @@ -169,9 +176,11 @@ static void android_mtp_MtpServer_start(JNIEnv *env, jobject thiz) { #ifdef HAVE_ANDROID_OS + sMutex.lock(); MtpThread *thread = sThread.get(); if (thread) - thread->run("MtpThread"); + thread->start(); + sMutex.unlock(); #endif // HAVE_ANDROID_OS } @@ -179,11 +188,13 @@ static void android_mtp_MtpServer_stop(JNIEnv *env, jobject thiz) { #ifdef HAVE_ANDROID_OS + sMutex.lock(); MtpThread *thread = sThread.get(); if (thread) { thread->requestExitAndWait(); sThread = NULL; } + sMutex.unlock(); #endif } @@ -191,9 +202,11 @@ static void android_mtp_MtpServer_send_object_added(JNIEnv *env, jobject thiz, jint handle) { #ifdef HAVE_ANDROID_OS + sMutex.lock(); MtpThread *thread = sThread.get(); if (thread) thread->sendObjectAdded(handle); + sMutex.unlock(); #endif } @@ -201,9 +214,11 @@ static void android_mtp_MtpServer_send_object_removed(JNIEnv *env, jobject thiz, jint handle) { #ifdef HAVE_ANDROID_OS + sMutex.lock(); MtpThread *thread = sThread.get(); if (thread) thread->sendObjectRemoved(handle); + sMutex.unlock(); #endif } @@ -211,33 +226,68 @@ static void android_mtp_MtpServer_set_ptp_mode(JNIEnv *env, jobject thiz, jboolean usePtp) { #ifdef HAVE_ANDROID_OS + sMutex.lock(); MtpThread *thread = sThread.get(); if (thread) thread->setPtpMode(usePtp); + sMutex.unlock(); #endif } static void -android_mtp_MtpServer_set_locked(JNIEnv *env, jobject thiz, jboolean locked) +android_mtp_MtpServer_add_storage(JNIEnv *env, jobject thiz, jobject jstorage) { #ifdef HAVE_ANDROID_OS + sMutex.lock(); + MtpThread *thread = sThread.get(); + if (thread) { + jint storageID = env->GetIntField(jstorage, field_MtpStorage_storageId); + jstring path = (jstring)env->GetObjectField(jstorage, field_MtpStorage_path); + jstring description = (jstring)env->GetObjectField(jstorage, field_MtpStorage_description); + jlong reserveSpace = env->GetLongField(jstorage, field_MtpStorage_reserveSpace); + + const char *pathStr = env->GetStringUTFChars(path, NULL); + const char *descriptionStr = env->GetStringUTFChars(description, NULL); + + MtpStorage* storage = new MtpStorage(storageID, pathStr, descriptionStr, reserveSpace); + thread->addStorage(storage); + + env->ReleaseStringUTFChars(path, pathStr); + env->ReleaseStringUTFChars(description, descriptionStr); + } else { + LOGE("MtpThread is null in add_storage"); + } + sMutex.unlock(); +#endif +} + +static void +android_mtp_MtpServer_remove_storage(JNIEnv *env, jobject thiz, jint storageId) +{ +#ifdef HAVE_ANDROID_OS + sMutex.lock(); MtpThread *thread = sThread.get(); if (thread) - thread->setLocked(locked); + thread->removeStorage(storageId); + else + LOGE("MtpThread is null in remove_storage"); + sMutex.unlock(); #endif } // ---------------------------------------------------------------------------- static JNINativeMethod gMethods[] = { - {"native_setup", "(Landroid/mtp/MtpDatabase;Ljava/lang/String;J)V", + {"native_setup", "(Landroid/mtp/MtpDatabase;)V", (void *)android_mtp_MtpServer_setup}, {"native_start", "()V", (void *)android_mtp_MtpServer_start}, {"native_stop", "()V", (void *)android_mtp_MtpServer_stop}, {"native_send_object_added", "(I)V", (void *)android_mtp_MtpServer_send_object_added}, {"native_send_object_removed", "(I)V", (void *)android_mtp_MtpServer_send_object_removed}, {"native_set_ptp_mode", "(Z)V", (void *)android_mtp_MtpServer_set_ptp_mode}, - {"native_set_locked", "(Z)V", (void *)android_mtp_MtpServer_set_locked}, + {"native_add_storage", "(Landroid/mtp/MtpStorage;)V", + (void *)android_mtp_MtpServer_add_storage}, + {"native_remove_storage", "(I)V", (void *)android_mtp_MtpServer_remove_storage}, }; static const char* const kClassPathName = "android/mtp/MtpServer"; @@ -246,6 +296,33 @@ int register_android_mtp_MtpServer(JNIEnv *env) { jclass clazz; + clazz = env->FindClass("android/mtp/MtpStorage"); + if (clazz == NULL) { + LOGE("Can't find android/mtp/MtpStorage"); + return -1; + } + field_MtpStorage_storageId = env->GetFieldID(clazz, "mStorageId", "I"); + if (field_MtpStorage_storageId == NULL) { + LOGE("Can't find MtpStorage.mStorageId"); + return -1; + } + field_MtpStorage_path = env->GetFieldID(clazz, "mPath", "Ljava/lang/String;"); + if (field_MtpStorage_path == NULL) { + LOGE("Can't find MtpStorage.mPath"); + return -1; + } + field_MtpStorage_description = env->GetFieldID(clazz, "mDescription", "Ljava/lang/String;"); + if (field_MtpStorage_description == NULL) { + LOGE("Can't find MtpStorage.mDescription"); + return -1; + } + field_MtpStorage_reserveSpace = env->GetFieldID(clazz, "mReserveSpace", "J"); + if (field_MtpStorage_reserveSpace == NULL) { + LOGE("Can't find MtpStorage.mStorageId"); + return -1; + } + clazz_MtpStorage = (jclass)env->NewGlobalRef(clazz); + clazz = env->FindClass("android/mtp/MtpServer"); if (clazz == NULL) { LOGE("Can't find android/mtp/MtpServer"); diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp index cee1c7540cdd..5d74a0a33f8c 100644 --- a/media/libmedia/AudioRecord.cpp +++ b/media/libmedia/AudioRecord.cpp @@ -35,6 +35,7 @@ #include <binder/Parcel.h> #include <binder/IPCThreadState.h> #include <utils/Timers.h> +#include <utils/Atomic.h> #define LIKELY( exp ) (__builtin_expect( (exp) != 0, true )) #define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false )) @@ -299,7 +300,7 @@ status_t AudioRecord::start() ret = mAudioRecord->start(); cblk->lock.lock(); if (ret == DEAD_OBJECT) { - cblk->flags |= CBLK_INVALID_MSK; + android_atomic_or(CBLK_INVALID_ON, &cblk->flags); } } if (cblk->flags & CBLK_INVALID_MSK) { @@ -467,7 +468,7 @@ status_t AudioRecord::openRecord_l( mCblkMemory = cblk; mCblk = static_cast<audio_track_cblk_t*>(cblk->pointer()); mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t); - mCblk->flags &= ~CBLK_DIRECTION_MSK; + android_atomic_and(~CBLK_DIRECTION_MSK, &mCblk->flags); mCblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS; mCblk->waitTimeMs = 0; return NO_ERROR; @@ -522,7 +523,7 @@ status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount) result = mAudioRecord->start(); cblk->lock.lock(); if (result == DEAD_OBJECT) { - cblk->flags |= CBLK_INVALID_MSK; + android_atomic_or(CBLK_INVALID_ON, &cblk->flags); create_new_record: result = AudioRecord::restoreRecord_l(cblk); } @@ -722,12 +723,8 @@ bool AudioRecord::processAudioBuffer(const sp<ClientRecordThread>& thread) // Manage overrun callback if (mActive && (cblk->framesAvailable() == 0)) { LOGV("Overrun user: %x, server: %x, flags %04x", cblk->user, cblk->server, cblk->flags); - AutoMutex _l(cblk->lock); - if ((cblk->flags & CBLK_UNDERRUN_MSK) == CBLK_UNDERRUN_OFF) { - cblk->flags |= CBLK_UNDERRUN_ON; - cblk->lock.unlock(); + if (!(android_atomic_or(CBLK_UNDERRUN_ON, &cblk->flags) & CBLK_UNDERRUN_MSK)) { mCbf(EVENT_OVERRUN, mUserData, 0); - cblk->lock.lock(); } } @@ -746,10 +743,8 @@ status_t AudioRecord::restoreRecord_l(audio_track_cblk_t*& cblk) { status_t result; - if (!(cblk->flags & CBLK_RESTORING_MSK)) { + if (!(android_atomic_or(CBLK_RESTORING_ON, &cblk->flags) & CBLK_RESTORING_MSK)) { LOGW("dead IAudioRecord, creating a new one"); - - cblk->flags |= CBLK_RESTORING_ON; // signal old cblk condition so that other threads waiting for available buffers stop // waiting now cblk->cv.broadcast(); @@ -768,10 +763,8 @@ status_t AudioRecord::restoreRecord_l(audio_track_cblk_t*& cblk) } // signal old cblk condition for other threads waiting for restore completion - cblk->lock.lock(); - cblk->flags |= CBLK_RESTORED_MSK; + android_atomic_or(CBLK_RESTORED_ON, &cblk->flags); cblk->cv.broadcast(); - cblk->lock.unlock(); } else { if (!(cblk->flags & CBLK_RESTORED_MSK)) { LOGW("dead IAudioRecord, waiting for a new one to be created"); diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp index fb2ee0f813f3..66e11d282d72 100644 --- a/media/libmedia/AudioTrack.cpp +++ b/media/libmedia/AudioTrack.cpp @@ -35,6 +35,7 @@ #include <binder/Parcel.h> #include <binder/IPCThreadState.h> #include <utils/Timers.h> +#include <utils/Atomic.h> #define LIKELY( exp ) (__builtin_expect( (exp) != 0, true )) #define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false )) @@ -332,7 +333,7 @@ void AudioTrack::start() cblk->lock.lock(); cblk->bufferTimeoutMs = MAX_STARTUP_TIMEOUT_MS; cblk->waitTimeMs = 0; - cblk->flags &= ~CBLK_DISABLED_ON; + android_atomic_and(~CBLK_DISABLED_ON, &cblk->flags); if (t != 0) { t->run("AudioTrackThread", THREAD_PRIORITY_AUDIO_CLIENT); } else { @@ -345,7 +346,7 @@ void AudioTrack::start() status = mAudioTrack->start(); cblk->lock.lock(); if (status == DEAD_OBJECT) { - cblk->flags |= CBLK_INVALID_MSK; + android_atomic_or(CBLK_INVALID_ON, &cblk->flags); } } if (cblk->flags & CBLK_INVALID_MSK) { @@ -636,7 +637,7 @@ status_t AudioTrack::setPosition(uint32_t position) if (position > mCblk->user) return BAD_VALUE; mCblk->server = position; - mCblk->flags |= CBLK_FORCEREADY_ON; + android_atomic_or(CBLK_FORCEREADY_ON, &mCblk->flags); return NO_ERROR; } @@ -793,7 +794,7 @@ status_t AudioTrack::createTrack_l( mCblkMemory.clear(); mCblkMemory = cblk; mCblk = static_cast<audio_track_cblk_t*>(cblk->pointer()); - mCblk->flags |= CBLK_DIRECTION_OUT; + android_atomic_or(CBLK_DIRECTION_OUT, &mCblk->flags); if (sharedBuffer == 0) { mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t); } else { @@ -873,7 +874,7 @@ status_t AudioTrack::obtainBuffer(Buffer* audioBuffer, int32_t waitCount) result = mAudioTrack->start(); cblk->lock.lock(); if (result == DEAD_OBJECT) { - cblk->flags |= CBLK_INVALID_MSK; + android_atomic_or(CBLK_INVALID_ON, &cblk->flags); create_new_track: result = restoreTrack_l(cblk, false); } @@ -900,14 +901,9 @@ create_new_track: // restart track if it was disabled by audioflinger due to previous underrun if (mActive && (cblk->flags & CBLK_DISABLED_MSK)) { - AutoMutex _l(cblk->lock); - if (mActive && (cblk->flags & CBLK_DISABLED_MSK)) { - cblk->flags &= ~CBLK_DISABLED_ON; - cblk->lock.unlock(); - LOGW("obtainBuffer() track %p disabled, restarting", this); - mAudioTrack->start(); - cblk->lock.lock(); - } + android_atomic_and(~CBLK_DISABLED_ON, &cblk->flags); + LOGW("obtainBuffer() track %p disabled, restarting", this); + mAudioTrack->start(); } cblk->waitTimeMs = 0; @@ -1026,17 +1022,13 @@ bool AudioTrack::processAudioBuffer(const sp<AudioTrackThread>& thread) mLock.unlock(); // Manage underrun callback - if (mActive && (cblk->framesReady() == 0)) { + if (mActive && (cblk->framesAvailable() == cblk->frameCount)) { LOGV("Underrun user: %x, server: %x, flags %04x", cblk->user, cblk->server, cblk->flags); - AutoMutex _l(cblk->lock); - if ((cblk->flags & CBLK_UNDERRUN_MSK) == CBLK_UNDERRUN_OFF) { - cblk->flags |= CBLK_UNDERRUN_ON; - cblk->lock.unlock(); + if (!(android_atomic_or(CBLK_UNDERRUN_ON, &cblk->flags) & CBLK_UNDERRUN_MSK)) { mCbf(EVENT_UNDERRUN, mUserData, 0); if (cblk->server == cblk->frameCount) { mCbf(EVENT_BUFFER_END, mUserData, 0); } - cblk->lock.lock(); if (mSharedBuffer != 0) return false; } } @@ -1150,12 +1142,10 @@ status_t AudioTrack::restoreTrack_l(audio_track_cblk_t*& cblk, bool fromStart) { status_t result; - if (!(cblk->flags & CBLK_RESTORING_MSK)) { + if (!(android_atomic_or(CBLK_RESTORING_ON, &cblk->flags) & CBLK_RESTORING_MSK)) { LOGW("dead IAudioTrack, creating a new one from %s", fromStart ? "start()" : "obtainBuffer()"); - cblk->flags |= CBLK_RESTORING_ON; - // signal old cblk condition so that other threads waiting for available buffers stop // waiting now cblk->cv.broadcast(); @@ -1198,10 +1188,8 @@ status_t AudioTrack::restoreTrack_l(audio_track_cblk_t*& cblk, bool fromStart) } // signal old cblk condition for other threads waiting for restore completion - cblk->lock.lock(); - cblk->flags |= CBLK_RESTORED_MSK; + android_atomic_or(CBLK_RESTORED_ON, &cblk->flags); cblk->cv.broadcast(); - cblk->lock.unlock(); } else { if (!(cblk->flags & CBLK_RESTORED_MSK)) { LOGW("dead IAudioTrack, waiting for a new one"); @@ -1275,11 +1263,12 @@ void AudioTrack::AudioTrackThread::onFirstRef() // ========================================================================= + audio_track_cblk_t::audio_track_cblk_t() : lock(Mutex::SHARED), cv(Condition::SHARED), user(0), server(0), userBase(0), serverBase(0), buffers(0), frameCount(0), loopStart(UINT_MAX), loopEnd(UINT_MAX), loopCount(0), volumeLR(0), - flags(0), sendLevel(0) + sendLevel(0), flags(0) { } @@ -1307,10 +1296,7 @@ uint32_t audio_track_cblk_t::stepUser(uint32_t frameCount) // Clear flow control error condition as new data has been written/read to/from buffer. if (flags & CBLK_UNDERRUN_MSK) { - AutoMutex _l(lock); - if (flags & CBLK_UNDERRUN_MSK) { - flags &= ~CBLK_UNDERRUN_MSK; - } + android_atomic_and(~CBLK_UNDERRUN_MSK, &flags); } return u; @@ -1318,18 +1304,8 @@ uint32_t audio_track_cblk_t::stepUser(uint32_t frameCount) bool audio_track_cblk_t::stepServer(uint32_t frameCount) { - // the code below simulates lock-with-timeout - // we MUST do this to protect the AudioFlinger server - // as this lock is shared with the client. - status_t err; - - err = lock.tryLock(); - if (err == -EBUSY) { // just wait a bit - usleep(1000); - err = lock.tryLock(); - } - if (err != NO_ERROR) { - // probably, the client just died. + if (!tryLock()) { + LOGW("stepServer() could not lock cblk"); return false; } @@ -1406,18 +1382,42 @@ uint32_t audio_track_cblk_t::framesReady() if (u < loopEnd) { return u - s; } else { - Mutex::Autolock _l(lock); + // do not block on mutex shared with client on AudioFlinger side + if (!tryLock()) { + LOGW("framesReady() could not lock cblk"); + return 0; + } + uint32_t frames = UINT_MAX; if (loopCount >= 0) { - return (loopEnd - loopStart)*loopCount + u - s; - } else { - return UINT_MAX; + frames = (loopEnd - loopStart)*loopCount + u - s; } + lock.unlock(); + return frames; } } else { return s - u; } } +bool audio_track_cblk_t::tryLock() +{ + // the code below simulates lock-with-timeout + // we MUST do this to protect the AudioFlinger server + // as this lock is shared with the client. + status_t err; + + err = lock.tryLock(); + if (err == -EBUSY) { // just wait a bit + usleep(1000); + err = lock.tryLock(); + } + if (err != NO_ERROR) { + // probably, the client just died. + return false; + } + return true; +} + // ------------------------------------------------------------------------- }; // namespace android diff --git a/media/mtp/MtpServer.h b/media/mtp/MtpServer.h index 1efa7158baa6..fa729a893bc0 100644 --- a/media/mtp/MtpServer.h +++ b/media/mtp/MtpServer.h @@ -70,6 +70,9 @@ public: int fileGroup, int filePerm, int directoryPerm); virtual ~MtpServer(); + MtpStorage* getStorage(MtpStorageID id); + inline bool hasStorage() { return mStorages.size() > 0; } + bool hasStorage(MtpStorageID id); void addStorage(MtpStorage* storage); void removeStorage(MtpStorage* storage); @@ -79,9 +82,6 @@ public: void sendObjectRemoved(MtpObjectHandle handle); private: - MtpStorage* getStorage(MtpStorageID id); - inline bool hasStorage() { return mStorages.size() > 0; } - bool hasStorage(MtpStorageID id); void sendStoreAdded(MtpStorageID id); void sendStoreRemoved(MtpStorageID id); void sendEvent(MtpEventCode code, uint32_t param1); diff --git a/media/mtp/MtpStorage.cpp b/media/mtp/MtpStorage.cpp index 6cb88b33551f..fff0b5f27ccd 100644 --- a/media/mtp/MtpStorage.cpp +++ b/media/mtp/MtpStorage.cpp @@ -32,9 +32,11 @@ namespace android { -MtpStorage::MtpStorage(MtpStorageID id, const char* filePath, uint64_t reserveSpace) +MtpStorage::MtpStorage(MtpStorageID id, const char* filePath, + const char* description, uint64_t reserveSpace) : mStorageID(id), mFilePath(filePath), + mDescription(description), mMaxCapacity(0), mReserveSpace(reserveSpace) { @@ -75,7 +77,7 @@ uint64_t MtpStorage::getFreeSpace() { } const char* MtpStorage::getDescription() const { - return "Device Storage"; + return (const char *)mDescription; } } // namespace android diff --git a/media/mtp/MtpStorage.h b/media/mtp/MtpStorage.h index 858c9d38a3f6..d6ad25f33abb 100644 --- a/media/mtp/MtpStorage.h +++ b/media/mtp/MtpStorage.h @@ -29,13 +29,14 @@ class MtpStorage { private: MtpStorageID mStorageID; MtpString mFilePath; + MtpString mDescription; uint64_t mMaxCapacity; // amount of free space to leave unallocated uint64_t mReserveSpace; public: MtpStorage(MtpStorageID id, const char* filePath, - uint64_t reserveSpace); + const char* description, uint64_t reserveSpace); virtual ~MtpStorage(); inline MtpStorageID getStorageID() const { return mStorageID; } diff --git a/media/mtp/mtp.h b/media/mtp/mtp.h index 6fedc161b9c1..8bc2e22c31d8 100644 --- a/media/mtp/mtp.h +++ b/media/mtp/mtp.h @@ -22,8 +22,6 @@ #define MTP_STANDARD_VERSION 100 -#define MTP_FIRST_STORAGE_ID 0x00010001 - // Container Types #define MTP_CONTAINER_TYPE_UNDEFINED 0 #define MTP_CONTAINER_TYPE_COMMAND 1 diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml index 0660a17f3e27..399a77488d79 100644 --- a/packages/SystemUI/res/values-ar/strings.xml +++ b/packages/SystemUI/res/values-ar/strings.xml @@ -44,22 +44,13 @@ <string name="bluetooth_tethered" msgid="7094101612161133267">"تم إنشاء الاتصال بالإنترنت عن طريق البلوتوث."</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"تهيئة طرق الإدخال"</string> <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"استخدام لوحة المفاتيح الفعلية"</string> - <!-- no translation found for usb_device_permission_prompt (3816016361969816903) --> - <skip /> - <!-- no translation found for usb_accessory_permission_prompt (6888598803988889959) --> - <skip /> - <!-- no translation found for usb_device_confirm_prompt (5161205258635253206) --> - <skip /> - <!-- no translation found for usb_accessory_confirm_prompt (3808984931830229888) --> - <skip /> - <!-- no translation found for usb_accessory_uri_prompt (6332150684964235705) --> - <skip /> - <!-- no translation found for title_usb_accessory (4966265263465181372) --> - <skip /> - <!-- no translation found for label_view (6304565553218192990) --> - <skip /> - <!-- no translation found for always_use_device (1450287437017315906) --> - <skip /> - <!-- no translation found for always_use_accessory (1210954576979621596) --> - <skip /> + <string name="usb_device_permission_prompt" msgid="3816016361969816903">"هل تريد السماح للتطبيق <xliff:g id="APPLICATION">%1$s</xliff:g> بالدخول إلى جهاز USB؟"</string> + <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"هل تريد السماح للتطبيق <xliff:g id="APPLICATION">%1$s</xliff:g> بالدخول إلى ملحق USB؟"</string> + <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"هل تريد فتح <xliff:g id="ACTIVITY">%1$s</xliff:g> عند توصيل جهاز USB هذا؟"</string> + <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"هل تريد فتح <xliff:g id="ACTIVITY">%1$s</xliff:g> عند توصيل ملحق USB هذا؟"</string> + <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"لا يعمل أي تطبيق مثبت مع ملحق UEB هذا. تعرف على المزيد عن هذا الملحق على <xliff:g id="URL">%1$s</xliff:g>."</string> + <string name="title_usb_accessory" msgid="4966265263465181372">"ملحق USB"</string> + <string name="label_view" msgid="6304565553218192990">"عرض"</string> + <string name="always_use_device" msgid="1450287437017315906">"الاستخدام بشكل افتراضي لجهاز USB هذا"</string> + <string name="always_use_accessory" msgid="1210954576979621596">"الاستخدام بشكل افتراضي لملحق USB هذا"</string> </resources> diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml index 4c9ecfcb45e0..0fddf238b879 100644 --- a/packages/SystemUI/res/values-bg/strings.xml +++ b/packages/SystemUI/res/values-bg/strings.xml @@ -44,22 +44,13 @@ <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth има връзка с тетъринг"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Конфигуриране на въвеждането"</string> <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Използване на физ. клав."</string> - <!-- no translation found for usb_device_permission_prompt (3816016361969816903) --> - <skip /> - <!-- no translation found for usb_accessory_permission_prompt (6888598803988889959) --> - <skip /> - <!-- no translation found for usb_device_confirm_prompt (5161205258635253206) --> - <skip /> - <!-- no translation found for usb_accessory_confirm_prompt (3808984931830229888) --> - <skip /> - <!-- no translation found for usb_accessory_uri_prompt (6332150684964235705) --> - <skip /> - <!-- no translation found for title_usb_accessory (4966265263465181372) --> - <skip /> - <!-- no translation found for label_view (6304565553218192990) --> - <skip /> - <!-- no translation found for always_use_device (1450287437017315906) --> - <skip /> - <!-- no translation found for always_use_accessory (1210954576979621596) --> - <skip /> + <string name="usb_device_permission_prompt" msgid="3816016361969816903">"Да се разреши ли на приложението <xliff:g id="APPLICATION">%1$s</xliff:g> достъп до USB устройството?"</string> + <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"Да се разреши ли на приложението <xliff:g id="APPLICATION">%1$s</xliff:g> достъп до аксесоара за USB?"</string> + <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Да се отвори ли <xliff:g id="ACTIVITY">%1$s</xliff:g>, когато това USB устройство е свързано?"</string> + <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Да се отвори ли <xliff:g id="ACTIVITY">%1$s</xliff:g>, когато този аксесоар за USB е свързан?"</string> + <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Инсталираните приложения не работят с този аксесоар за USB. Научете повече на адрес <xliff:g id="URL">%1$s</xliff:g>"</string> + <string name="title_usb_accessory" msgid="4966265263465181372">"Аксесоар за USB"</string> + <string name="label_view" msgid="6304565553218192990">"Преглед"</string> + <string name="always_use_device" msgid="1450287437017315906">"Използване по подразб. за това USB устройство"</string> + <string name="always_use_accessory" msgid="1210954576979621596">"Използване по подразб. за този аксесоар за USB"</string> </resources> diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml index 9a4a360ded29..64f53d0bfcc0 100644 --- a/packages/SystemUI/res/values-ca/strings.xml +++ b/packages/SystemUI/res/values-ca/strings.xml @@ -44,22 +44,13 @@ <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth sense fil"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Configura mètodes d\'entrada"</string> <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Utilitza un teclat físic"</string> - <!-- no translation found for usb_device_permission_prompt (3816016361969816903) --> - <skip /> - <!-- no translation found for usb_accessory_permission_prompt (6888598803988889959) --> - <skip /> - <!-- no translation found for usb_device_confirm_prompt (5161205258635253206) --> - <skip /> - <!-- no translation found for usb_accessory_confirm_prompt (3808984931830229888) --> - <skip /> - <!-- no translation found for usb_accessory_uri_prompt (6332150684964235705) --> - <skip /> - <!-- no translation found for title_usb_accessory (4966265263465181372) --> - <skip /> - <!-- no translation found for label_view (6304565553218192990) --> - <skip /> - <!-- no translation found for always_use_device (1450287437017315906) --> - <skip /> - <!-- no translation found for always_use_accessory (1210954576979621596) --> - <skip /> + <string name="usb_device_permission_prompt" msgid="3816016361969816903">"Vols permetre que l\'aplicació <xliff:g id="APPLICATION">%1$s</xliff:g> accedeixi al dispositiu USB?"</string> + <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"Vols permetre que l\'aplicació <xliff:g id="APPLICATION">%1$s</xliff:g> accedeixi a l\'accessori USB?"</string> + <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Vols que s\'obri <xliff:g id="ACTIVITY">%1$s</xliff:g> quan aquest dispositiu USB estigui connectat?"</string> + <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Vols que s\'obri <xliff:g id="ACTIVITY">%1$s</xliff:g> quan aquest accessori USB estigui connectat?"</string> + <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Cap de les aplicacions instal·lades no funciona amb aquest accessori USB. Més informació a <xliff:g id="URL">%1$s</xliff:g>"</string> + <string name="title_usb_accessory" msgid="4966265263465181372">"Accessori USB"</string> + <string name="label_view" msgid="6304565553218192990">"Mostra"</string> + <string name="always_use_device" msgid="1450287437017315906">"Utilitza de manera predet. per al dispositiu USB"</string> + <string name="always_use_accessory" msgid="1210954576979621596">"Utilitza de manera predet. per a l\'accessori USB"</string> </resources> diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml index 31aa1a71fa71..f1bab7ea3934 100644 --- a/packages/SystemUI/res/values-cs/strings.xml +++ b/packages/SystemUI/res/values-cs/strings.xml @@ -44,22 +44,13 @@ <string name="bluetooth_tethered" msgid="7094101612161133267">"Datové připojení Bluetooth se sdílí"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Nakonfigurovat metody vstupu"</string> <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Použít fyz. klávesnici"</string> - <!-- no translation found for usb_device_permission_prompt (3816016361969816903) --> - <skip /> - <!-- no translation found for usb_accessory_permission_prompt (6888598803988889959) --> - <skip /> - <!-- no translation found for usb_device_confirm_prompt (5161205258635253206) --> - <skip /> - <!-- no translation found for usb_accessory_confirm_prompt (3808984931830229888) --> - <skip /> - <!-- no translation found for usb_accessory_uri_prompt (6332150684964235705) --> - <skip /> - <!-- no translation found for title_usb_accessory (4966265263465181372) --> - <skip /> - <!-- no translation found for label_view (6304565553218192990) --> - <skip /> - <!-- no translation found for always_use_device (1450287437017315906) --> - <skip /> - <!-- no translation found for always_use_accessory (1210954576979621596) --> - <skip /> + <string name="usb_device_permission_prompt" msgid="3816016361969816903">"Povolit aplikaci <xliff:g id="APPLICATION">%1$s</xliff:g> přístup k zařízení USB?"</string> + <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"Povolit aplikaci <xliff:g id="APPLICATION">%1$s</xliff:g> přístup k perifernímu zařízení USB?"</string> + <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Chcete při připojení tohoto zařízení USB otevřít aplikaci <xliff:g id="ACTIVITY">%1$s</xliff:g>?"</string> + <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Chcete při připojení tohoto periferního zařízení USB otevřít aplikaci <xliff:g id="ACTIVITY">%1$s</xliff:g>?"</string> + <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"S tímto periferním zařízením USB nefunguje žádná nainstalovaná aplikace. Další informace naleznete na stránkách <xliff:g id="URL">%1$s</xliff:g>"</string> + <string name="title_usb_accessory" msgid="4966265263465181372">"Periferní zařízení USB"</string> + <string name="label_view" msgid="6304565553218192990">"Zobrazit"</string> + <string name="always_use_device" msgid="1450287437017315906">"Pro toto zařízení USB použít jako výchozí"</string> + <string name="always_use_accessory" msgid="1210954576979621596">"Pro toto periferní zařízení USB použít jako výchozí"</string> </resources> diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml index ddbcf259ab98..054b53c5aa72 100644 --- a/packages/SystemUI/res/values-da/strings.xml +++ b/packages/SystemUI/res/values-da/strings.xml @@ -44,22 +44,13 @@ <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth-tethering anvendt"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Konfigurer inputmetoder"</string> <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Brug fysisk tastatur"</string> - <!-- no translation found for usb_device_permission_prompt (3816016361969816903) --> - <skip /> - <!-- no translation found for usb_accessory_permission_prompt (6888598803988889959) --> - <skip /> - <!-- no translation found for usb_device_confirm_prompt (5161205258635253206) --> - <skip /> - <!-- no translation found for usb_accessory_confirm_prompt (3808984931830229888) --> - <skip /> - <!-- no translation found for usb_accessory_uri_prompt (6332150684964235705) --> - <skip /> - <!-- no translation found for title_usb_accessory (4966265263465181372) --> - <skip /> - <!-- no translation found for label_view (6304565553218192990) --> - <skip /> - <!-- no translation found for always_use_device (1450287437017315906) --> - <skip /> - <!-- no translation found for always_use_accessory (1210954576979621596) --> - <skip /> + <string name="usb_device_permission_prompt" msgid="3816016361969816903">"Vil du tillade, at programmet <xliff:g id="APPLICATION">%1$s</xliff:g> får adgang til USB-enheden?"</string> + <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"Vil du tillade, at programmet <xliff:g id="APPLICATION">%1$s</xliff:g> får adgang til USB-ekstraudstyret?"</string> + <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Vil du åbne <xliff:g id="ACTIVITY">%1$s</xliff:g>, når denne USB-enhed er tilsluttet?"</string> + <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Vil du åbne <xliff:g id="ACTIVITY">%1$s</xliff:g>, når dette USB-ekstraudstyr er tilsluttet?"</string> + <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Ingen inst. programmer virker med USB-ekstraudstyret. Få oplysninger om ekstraudstyret på <xliff:g id="URL">%1$s</xliff:g>"</string> + <string name="title_usb_accessory" msgid="4966265263465181372">"USB-ekstraudstyr"</string> + <string name="label_view" msgid="6304565553218192990">"Vis"</string> + <string name="always_use_device" msgid="1450287437017315906">"Brug som standard til denne USB-enhed"</string> + <string name="always_use_accessory" msgid="1210954576979621596">"Brug som standard til dette USB-tilbehør"</string> </resources> diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml index c7d95027b084..857d3a0d9e4d 100644 --- a/packages/SystemUI/res/values-de/strings.xml +++ b/packages/SystemUI/res/values-de/strings.xml @@ -44,22 +44,13 @@ <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth-Tethering aktiv"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Eingabemethoden konfigurieren"</string> <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Physische Tastatur"</string> - <!-- no translation found for usb_device_permission_prompt (3816016361969816903) --> - <skip /> - <!-- no translation found for usb_accessory_permission_prompt (6888598803988889959) --> - <skip /> - <!-- no translation found for usb_device_confirm_prompt (5161205258635253206) --> - <skip /> - <!-- no translation found for usb_accessory_confirm_prompt (3808984931830229888) --> - <skip /> - <!-- no translation found for usb_accessory_uri_prompt (6332150684964235705) --> - <skip /> - <!-- no translation found for title_usb_accessory (4966265263465181372) --> - <skip /> - <!-- no translation found for label_view (6304565553218192990) --> - <skip /> - <!-- no translation found for always_use_device (1450287437017315906) --> - <skip /> - <!-- no translation found for always_use_accessory (1210954576979621596) --> - <skip /> + <string name="usb_device_permission_prompt" msgid="3816016361969816903">"Anwendung <xliff:g id="APPLICATION">%1$s</xliff:g> Zugriff auf USB-Gerät gewähren?"</string> + <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"Anwendung <xliff:g id="APPLICATION">%1$s</xliff:g> Zugriff auf USB-Zubehör gewähren?"</string> + <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"<xliff:g id="ACTIVITY">%1$s</xliff:g> öffnen, wenn dieses USB-Gerät verbunden ist?"</string> + <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"<xliff:g id="ACTIVITY">%1$s</xliff:g> öffnen, wenn dieses USB-Zubehör verbunden ist?"</string> + <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Keine installierten Anwendungen für dieses USB-Zubehör. Weitere Informationen unter <xliff:g id="URL">%1$s</xliff:g>"</string> + <string name="title_usb_accessory" msgid="4966265263465181372">"USB-Zubehör"</string> + <string name="label_view" msgid="6304565553218192990">"Anzeigen"</string> + <string name="always_use_device" msgid="1450287437017315906">"Standardmäßig für dieses USB-Gerät verwenden"</string> + <string name="always_use_accessory" msgid="1210954576979621596">"Standardmäßig für dieses USB-Zubehör verwenden"</string> </resources> diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml index 7e15f7fe2068..424faab7dbf5 100644 --- a/packages/SystemUI/res/values-el/strings.xml +++ b/packages/SystemUI/res/values-el/strings.xml @@ -44,22 +44,13 @@ <string name="bluetooth_tethered" msgid="7094101612161133267">"Έγινε σύνδεση μέσω Bluetooth"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Διαμόρφωση μεθόδων εισαγωγής"</string> <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Χρήση κανονικού πληκτρολ."</string> - <!-- no translation found for usb_device_permission_prompt (3816016361969816903) --> - <skip /> - <!-- no translation found for usb_accessory_permission_prompt (6888598803988889959) --> - <skip /> - <!-- no translation found for usb_device_confirm_prompt (5161205258635253206) --> - <skip /> - <!-- no translation found for usb_accessory_confirm_prompt (3808984931830229888) --> - <skip /> - <!-- no translation found for usb_accessory_uri_prompt (6332150684964235705) --> - <skip /> - <!-- no translation found for title_usb_accessory (4966265263465181372) --> - <skip /> - <!-- no translation found for label_view (6304565553218192990) --> - <skip /> - <!-- no translation found for always_use_device (1450287437017315906) --> - <skip /> - <!-- no translation found for always_use_accessory (1210954576979621596) --> - <skip /> + <string name="usb_device_permission_prompt" msgid="3816016361969816903">"Να επιτρέπεται στην εφαρμογή <xliff:g id="APPLICATION">%1$s</xliff:g> η πρόσβαση στη συσκευή USB;"</string> + <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"Να επιτρέπεται στην εφαρμογή <xliff:g id="APPLICATION">%1$s</xliff:g> η πρόσβαση στο αξεσουάρ USB;"</string> + <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Άνοιγμα του <xliff:g id="ACTIVITY">%1$s</xliff:g> κατά τη σύνδεση αυτής της συσκευής USB;"</string> + <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Άνοιγμα του <xliff:g id="ACTIVITY">%1$s</xliff:g> κατά τη σύνδεση αυτού του αξεσουάρ USB;"</string> + <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Καμία εγκατ. εφαρμ. δεν συνεργ. με το αξ. USB. Μάθετε περισ. για το αξ. στο <xliff:g id="URL">%1$s</xliff:g>"</string> + <string name="title_usb_accessory" msgid="4966265263465181372">"Αξεσουάρ USB"</string> + <string name="label_view" msgid="6304565553218192990">"Προβολή"</string> + <string name="always_use_device" msgid="1450287437017315906">"Χρήση από προεπιλογή για αυτή τη συσκευή USB"</string> + <string name="always_use_accessory" msgid="1210954576979621596">"Χρήση από προεπιλογή για αυτό το εξάρτημα USB"</string> </resources> diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml index 350913a6d7b9..8c84b676ce9b 100644 --- a/packages/SystemUI/res/values-en-rGB/strings.xml +++ b/packages/SystemUI/res/values-en-rGB/strings.xml @@ -44,22 +44,13 @@ <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth tethered"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Configure input methods"</string> <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Use physical keyboard"</string> - <!-- no translation found for usb_device_permission_prompt (3816016361969816903) --> - <skip /> - <!-- no translation found for usb_accessory_permission_prompt (6888598803988889959) --> - <skip /> - <!-- no translation found for usb_device_confirm_prompt (5161205258635253206) --> - <skip /> - <!-- no translation found for usb_accessory_confirm_prompt (3808984931830229888) --> - <skip /> - <!-- no translation found for usb_accessory_uri_prompt (6332150684964235705) --> - <skip /> - <!-- no translation found for title_usb_accessory (4966265263465181372) --> - <skip /> - <!-- no translation found for label_view (6304565553218192990) --> - <skip /> - <!-- no translation found for always_use_device (1450287437017315906) --> - <skip /> - <!-- no translation found for always_use_accessory (1210954576979621596) --> - <skip /> + <string name="usb_device_permission_prompt" msgid="3816016361969816903">"Allow the application <xliff:g id="APPLICATION">%1$s</xliff:g> to access the USB device?"</string> + <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"Allow the application <xliff:g id="APPLICATION">%1$s</xliff:g> to access the USB accessory?"</string> + <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Open <xliff:g id="ACTIVITY">%1$s</xliff:g> when this USB device is connected?"</string> + <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Open <xliff:g id="ACTIVITY">%1$s</xliff:g> when this USB accessory is connected?"</string> + <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"No installed applications work with this USB accessory. Learn more about this accessory at <xliff:g id="URL">%1$s</xliff:g>"</string> + <string name="title_usb_accessory" msgid="4966265263465181372">"USB accessory"</string> + <string name="label_view" msgid="6304565553218192990">"View"</string> + <string name="always_use_device" msgid="1450287437017315906">"Use by default for this USB device"</string> + <string name="always_use_accessory" msgid="1210954576979621596">"Use by default for this USB accessory"</string> </resources> diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml index 43d9337a66f7..ae747d4b7425 100644 --- a/packages/SystemUI/res/values-es-rUS/strings.xml +++ b/packages/SystemUI/res/values-es-rUS/strings.xml @@ -44,22 +44,13 @@ <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth anclado"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Configurar métodos de entrada"</string> <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Usar teclado físico"</string> - <!-- no translation found for usb_device_permission_prompt (3816016361969816903) --> - <skip /> - <!-- no translation found for usb_accessory_permission_prompt (6888598803988889959) --> - <skip /> - <!-- no translation found for usb_device_confirm_prompt (5161205258635253206) --> - <skip /> - <!-- no translation found for usb_accessory_confirm_prompt (3808984931830229888) --> - <skip /> - <!-- no translation found for usb_accessory_uri_prompt (6332150684964235705) --> - <skip /> - <!-- no translation found for title_usb_accessory (4966265263465181372) --> - <skip /> - <!-- no translation found for label_view (6304565553218192990) --> - <skip /> - <!-- no translation found for always_use_device (1450287437017315906) --> - <skip /> - <!-- no translation found for always_use_accessory (1210954576979621596) --> - <skip /> + <string name="usb_device_permission_prompt" msgid="3816016361969816903">"¿Permitir la aplicación <xliff:g id="APPLICATION">%1$s</xliff:g> para acceder al dispositivo USB?"</string> + <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"¿Permitir la aplicación <xliff:g id="APPLICATION">%1$s</xliff:g> para acceder al accesorio USB?"</string> + <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"¿Abrir <xliff:g id="ACTIVITY">%1$s</xliff:g> cuando este dispositivo USB esté conectado?"</string> + <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"¿Abrir <xliff:g id="ACTIVITY">%1$s</xliff:g> cuando este accesorio USB esté conectado?"</string> + <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Las aplicaciones instaladas no funcionan con este accesorio USB. Obtener más información acerca de este accesorio en <xliff:g id="URL">%1$s</xliff:g>"</string> + <string name="title_usb_accessory" msgid="4966265263465181372">"Accesorio USB"</string> + <string name="label_view" msgid="6304565553218192990">"Ver"</string> + <string name="always_use_device" msgid="1450287437017315906">"Se usa de forma predeterminada para este dispositivo USB."</string> + <string name="always_use_accessory" msgid="1210954576979621596">"Se usa de forma predeterminada para este accesorio USB."</string> </resources> diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml index e6c1ce232f85..d58af48c5f94 100644 --- a/packages/SystemUI/res/values-es/strings.xml +++ b/packages/SystemUI/res/values-es/strings.xml @@ -44,22 +44,13 @@ <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth anclado"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Configurar métodos de introducción"</string> <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Utilizar teclado físico"</string> - <!-- no translation found for usb_device_permission_prompt (3816016361969816903) --> - <skip /> - <!-- no translation found for usb_accessory_permission_prompt (6888598803988889959) --> - <skip /> - <!-- no translation found for usb_device_confirm_prompt (5161205258635253206) --> - <skip /> - <!-- no translation found for usb_accessory_confirm_prompt (3808984931830229888) --> - <skip /> - <!-- no translation found for usb_accessory_uri_prompt (6332150684964235705) --> - <skip /> - <!-- no translation found for title_usb_accessory (4966265263465181372) --> - <skip /> - <!-- no translation found for label_view (6304565553218192990) --> - <skip /> - <!-- no translation found for always_use_device (1450287437017315906) --> - <skip /> - <!-- no translation found for always_use_accessory (1210954576979621596) --> - <skip /> + <string name="usb_device_permission_prompt" msgid="3816016361969816903">"¿Permitir que la aplicación <xliff:g id="APPLICATION">%1$s</xliff:g> acceda al dispositivo USB?"</string> + <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"¿Permitir que la aplicación <xliff:g id="APPLICATION">%1$s</xliff:g> acceda al accesorio USB?"</string> + <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"¿Quieres abrir <xliff:g id="ACTIVITY">%1$s</xliff:g> al conectar este dispositivo USB?"</string> + <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"¿Quieres abrir <xliff:g id="ACTIVITY">%1$s</xliff:g> al conectar este accesorio USB?"</string> + <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Ninguna aplicación instalada funciona con este accesorio USB. Más información: <xliff:g id="URL">%1$s</xliff:g>"</string> + <string name="title_usb_accessory" msgid="4966265263465181372">"Accesorio USB"</string> + <string name="label_view" msgid="6304565553218192990">"Ver"</string> + <string name="always_use_device" msgid="1450287437017315906">"Usar de forma predeterminada para este dispositivo USB"</string> + <string name="always_use_accessory" msgid="1210954576979621596">"Usar de forma predeterminada para este accesorio USB"</string> </resources> diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml index 9e70d5a588af..b763771098df 100644 --- a/packages/SystemUI/res/values-fa/strings.xml +++ b/packages/SystemUI/res/values-fa/strings.xml @@ -44,22 +44,13 @@ <string name="bluetooth_tethered" msgid="7094101612161133267">"اتصال اینترنتی با بلوتوث تلفن همراه"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"پیکربندی روش های ورودی"</string> <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"از صفحه کلید فیزیکی استفاده کنید"</string> - <!-- no translation found for usb_device_permission_prompt (3816016361969816903) --> - <skip /> - <!-- no translation found for usb_accessory_permission_prompt (6888598803988889959) --> - <skip /> - <!-- no translation found for usb_device_confirm_prompt (5161205258635253206) --> - <skip /> - <!-- no translation found for usb_accessory_confirm_prompt (3808984931830229888) --> - <skip /> - <!-- no translation found for usb_accessory_uri_prompt (6332150684964235705) --> - <skip /> - <!-- no translation found for title_usb_accessory (4966265263465181372) --> - <skip /> - <!-- no translation found for label_view (6304565553218192990) --> - <skip /> - <!-- no translation found for always_use_device (1450287437017315906) --> - <skip /> - <!-- no translation found for always_use_accessory (1210954576979621596) --> - <skip /> + <string name="usb_device_permission_prompt" msgid="3816016361969816903">"به برنامه <xliff:g id="APPLICATION">%1$s</xliff:g> اجازه می دهید به دستگاه USB وصل شود؟"</string> + <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"به برنامه <xliff:g id="APPLICATION">%1$s</xliff:g> اجازه می دهید به وسیله جانبی USB وصل شود؟"</string> + <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"وقتی این دستگاه USB وصل است، <xliff:g id="ACTIVITY">%1$s</xliff:g> باز شود؟"</string> + <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"وقتی این وسیله جانبی USB وصل است، <xliff:g id="ACTIVITY">%1$s</xliff:g> باز شود؟"</string> + <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"برنامه های نصب شده با این وسیله جانبی USB کار می کنند. در <xliff:g id="URL">%1$s</xliff:g>راجع به این لوازم جانبی بیشتر بیاموزید"</string> + <string name="title_usb_accessory" msgid="4966265263465181372">"لوازم جانبی USB"</string> + <string name="label_view" msgid="6304565553218192990">"مشاهده"</string> + <string name="always_use_device" msgid="1450287437017315906">"استفاده به صورت پیش فرض برای این دستگاه USB"</string> + <string name="always_use_accessory" msgid="1210954576979621596">"استفاده به صورت پیش فرض برای این دستگاه USB"</string> </resources> diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml index 47b32202ec3d..9255dbd94a53 100644 --- a/packages/SystemUI/res/values-fi/strings.xml +++ b/packages/SystemUI/res/values-fi/strings.xml @@ -44,22 +44,13 @@ <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth yhdistetty"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Määritä syöttötavat"</string> <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Käytä fyysistä näppäimistöä"</string> - <!-- no translation found for usb_device_permission_prompt (3816016361969816903) --> - <skip /> - <!-- no translation found for usb_accessory_permission_prompt (6888598803988889959) --> - <skip /> - <!-- no translation found for usb_device_confirm_prompt (5161205258635253206) --> - <skip /> - <!-- no translation found for usb_accessory_confirm_prompt (3808984931830229888) --> - <skip /> - <!-- no translation found for usb_accessory_uri_prompt (6332150684964235705) --> - <skip /> - <!-- no translation found for title_usb_accessory (4966265263465181372) --> - <skip /> - <!-- no translation found for label_view (6304565553218192990) --> - <skip /> - <!-- no translation found for always_use_device (1450287437017315906) --> - <skip /> - <!-- no translation found for always_use_accessory (1210954576979621596) --> - <skip /> + <string name="usb_device_permission_prompt" msgid="3816016361969816903">"Annetaanko sovellukselle <xliff:g id="APPLICATION">%1$s</xliff:g> lupa käyttää USB-laitetta?"</string> + <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"Annetaanko sovellukselle <xliff:g id="APPLICATION">%1$s</xliff:g> lupa käyttää USB-lisälaitetta?"</string> + <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Avataanko <xliff:g id="ACTIVITY">%1$s</xliff:g> tämän USB-laitteen ollessa kytkettynä?"</string> + <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Avataanko <xliff:g id="ACTIVITY">%1$s</xliff:g> tämän USB-lisälaitteen ollessa kytkettynä?"</string> + <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Asennetut sov. eivät toimi tämän USB-lisälaitteen kanssa. Lisätietoja lisälaitteesta os. <xliff:g id="URL">%1$s</xliff:g>"</string> + <string name="title_usb_accessory" msgid="4966265263465181372">"USB-lisälaite"</string> + <string name="label_view" msgid="6304565553218192990">"Näytä"</string> + <string name="always_use_device" msgid="1450287437017315906">"Käytä oletuksena tällä USB-laitteella"</string> + <string name="always_use_accessory" msgid="1210954576979621596">"Käytä oletuksena tällä USB-lisälaitteella"</string> </resources> diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml index a4a287e86f75..c41acd3d3fcb 100644 --- a/packages/SystemUI/res/values-fr/strings.xml +++ b/packages/SystemUI/res/values-fr/strings.xml @@ -44,22 +44,13 @@ <string name="bluetooth_tethered" msgid="7094101612161133267">"Connexion Bluetooth partagée"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Configurer les modes de saisie"</string> <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Utiliser clavier physique"</string> - <!-- no translation found for usb_device_permission_prompt (3816016361969816903) --> - <skip /> - <!-- no translation found for usb_accessory_permission_prompt (6888598803988889959) --> - <skip /> - <!-- no translation found for usb_device_confirm_prompt (5161205258635253206) --> - <skip /> - <!-- no translation found for usb_accessory_confirm_prompt (3808984931830229888) --> - <skip /> - <!-- no translation found for usb_accessory_uri_prompt (6332150684964235705) --> - <skip /> - <!-- no translation found for title_usb_accessory (4966265263465181372) --> - <skip /> - <!-- no translation found for label_view (6304565553218192990) --> - <skip /> - <!-- no translation found for always_use_device (1450287437017315906) --> - <skip /> - <!-- no translation found for always_use_accessory (1210954576979621596) --> - <skip /> + <string name="usb_device_permission_prompt" msgid="3816016361969816903">"Autoriser l\'application <xliff:g id="APPLICATION">%1$s</xliff:g> à accéder au périphérique USB ?"</string> + <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"Autoriser l\'application <xliff:g id="APPLICATION">%1$s</xliff:g> à accéder à l\'accessoire USB ?"</string> + <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Ouvrir <xliff:g id="ACTIVITY">%1$s</xliff:g> lors de la connexion de ce périphérique USB ?"</string> + <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Ouvrir <xliff:g id="ACTIVITY">%1$s</xliff:g> lors de la connexion de cet accessoire USB ?"</string> + <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Aucune application installée n\'est compatible avec cet accessoire USB. En savoir plus sur <xliff:g id="URL">%1$s</xliff:g>."</string> + <string name="title_usb_accessory" msgid="4966265263465181372">"Accessoire USB"</string> + <string name="label_view" msgid="6304565553218192990">"Afficher"</string> + <string name="always_use_device" msgid="1450287437017315906">"Utiliser par défaut pour ce périphérique USB"</string> + <string name="always_use_accessory" msgid="1210954576979621596">"Utiliser par défaut pour cet accessoire USB"</string> </resources> diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml index 680a3e33311a..eda1a93fdd8c 100644 --- a/packages/SystemUI/res/values-hr/strings.xml +++ b/packages/SystemUI/res/values-hr/strings.xml @@ -44,22 +44,13 @@ <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth posredno povezan"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Konfiguriraj načine ulaza"</string> <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Rabi fizičku tipkovnicu"</string> - <!-- no translation found for usb_device_permission_prompt (3816016361969816903) --> - <skip /> - <!-- no translation found for usb_accessory_permission_prompt (6888598803988889959) --> - <skip /> - <!-- no translation found for usb_device_confirm_prompt (5161205258635253206) --> - <skip /> - <!-- no translation found for usb_accessory_confirm_prompt (3808984931830229888) --> - <skip /> - <!-- no translation found for usb_accessory_uri_prompt (6332150684964235705) --> - <skip /> - <!-- no translation found for title_usb_accessory (4966265263465181372) --> - <skip /> - <!-- no translation found for label_view (6304565553218192990) --> - <skip /> - <!-- no translation found for always_use_device (1450287437017315906) --> - <skip /> - <!-- no translation found for always_use_accessory (1210954576979621596) --> - <skip /> + <string name="usb_device_permission_prompt" msgid="3816016361969816903">"Dopustiti aplikaciji <xliff:g id="APPLICATION">%1$s</xliff:g> da pristupi ovom USB uređaju?"</string> + <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"Dopustiti aplikaciji <xliff:g id="APPLICATION">%1$s</xliff:g> da pristupi ovom USB dodatku?"</string> + <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Otvoriti <xliff:g id="ACTIVITY">%1$s</xliff:g> kad se spoji ovaj USB uređaj?"</string> + <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Otvoriti <xliff:g id="ACTIVITY">%1$s</xliff:g> kad se spoji ovaj USB dodatak?"</string> + <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Nijedna instalirana aplikacija ne radi s ovim USB dodatkom. Saznajte više o ovom dodatku na <xliff:g id="URL">%1$s</xliff:g>"</string> + <string name="title_usb_accessory" msgid="4966265263465181372">"USB pribor"</string> + <string name="label_view" msgid="6304565553218192990">"Prikaži"</string> + <string name="always_use_device" msgid="1450287437017315906">"Koristi se prema zadanim postavkama za ovaj USB uređaj"</string> + <string name="always_use_accessory" msgid="1210954576979621596">"Koristi se prema zadanim postavkama za ovaj USB pribor"</string> </resources> diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml index 9a103f7ae001..2261c2b4b947 100644 --- a/packages/SystemUI/res/values-hu/strings.xml +++ b/packages/SystemUI/res/values-hu/strings.xml @@ -44,22 +44,13 @@ <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth megosztva"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Beviteli módok konfigurálása"</string> <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Valódi bill. használata"</string> - <!-- no translation found for usb_device_permission_prompt (3816016361969816903) --> - <skip /> - <!-- no translation found for usb_accessory_permission_prompt (6888598803988889959) --> - <skip /> - <!-- no translation found for usb_device_confirm_prompt (5161205258635253206) --> - <skip /> - <!-- no translation found for usb_accessory_confirm_prompt (3808984931830229888) --> - <skip /> - <!-- no translation found for usb_accessory_uri_prompt (6332150684964235705) --> - <skip /> - <!-- no translation found for title_usb_accessory (4966265263465181372) --> - <skip /> - <!-- no translation found for label_view (6304565553218192990) --> - <skip /> - <!-- no translation found for always_use_device (1450287437017315906) --> - <skip /> - <!-- no translation found for always_use_accessory (1210954576979621596) --> - <skip /> + <string name="usb_device_permission_prompt" msgid="3816016361969816903">"<xliff:g id="APPLICATION">%1$s</xliff:g> alkalmazás hozzáférhet az USB-eszközhöz?"</string> + <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"<xliff:g id="APPLICATION">%1$s</xliff:g> alkalmazás hozzáférhet az USB-kiegészítőhöz?"</string> + <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"<xliff:g id="ACTIVITY">%1$s</xliff:g> megnyitása, ha USB-kiegészítő csatlakoztatva van?"</string> + <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"<xliff:g id="ACTIVITY">%1$s</xliff:g> megnyitása, ha ez az USB-kiegészítő csatlakoztatva van?"</string> + <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"A telepített alkalmazások nem működnek ezzel az USB-kiegészítővel. Bővebben: <xliff:g id="URL">%1$s</xliff:g>"</string> + <string name="title_usb_accessory" msgid="4966265263465181372">"USB-kellék"</string> + <string name="label_view" msgid="6304565553218192990">"Megtekintés"</string> + <string name="always_use_device" msgid="1450287437017315906">"Alapértelmezett használat ehhez az USB-eszközhöz"</string> + <string name="always_use_accessory" msgid="1210954576979621596">"Alapértelmezett használat ehhez az USB-kiegészítőhöz"</string> </resources> diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml index e7fbbbecbe7b..53bfc76f89ea 100644 --- a/packages/SystemUI/res/values-in/strings.xml +++ b/packages/SystemUI/res/values-in/strings.xml @@ -44,22 +44,13 @@ <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth tertambat"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Konfigurasikan metode masukan"</string> <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Gunakan keyboard fisik"</string> - <!-- no translation found for usb_device_permission_prompt (3816016361969816903) --> - <skip /> - <!-- no translation found for usb_accessory_permission_prompt (6888598803988889959) --> - <skip /> - <!-- no translation found for usb_device_confirm_prompt (5161205258635253206) --> - <skip /> - <!-- no translation found for usb_accessory_confirm_prompt (3808984931830229888) --> - <skip /> - <!-- no translation found for usb_accessory_uri_prompt (6332150684964235705) --> - <skip /> - <!-- no translation found for title_usb_accessory (4966265263465181372) --> - <skip /> - <!-- no translation found for label_view (6304565553218192990) --> - <skip /> - <!-- no translation found for always_use_device (1450287437017315906) --> - <skip /> - <!-- no translation found for always_use_accessory (1210954576979621596) --> - <skip /> + <string name="usb_device_permission_prompt" msgid="3816016361969816903">"Izinkan aplikasi <xliff:g id="APPLICATION">%1$s</xliff:g> mengakses perangkat USB?"</string> + <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"Izinkan aplikasi <xliff:g id="APPLICATION">%1$s</xliff:g> mengakses aksesori USB?"</string> + <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Buka <xliff:g id="ACTIVITY">%1$s</xliff:g> ketika perangkat USB ini tersambung?"</string> + <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Buka <xliff:g id="ACTIVITY">%1$s</xliff:g> ketika aksesori USB ini tersambung?"</string> + <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Tidak ada aplikasi terpasang yang bekerja dengan aksesori USB ini. Pelajari aksesori ini lebih lanjut di <xliff:g id="URL">%1$s</xliff:g>"</string> + <string name="title_usb_accessory" msgid="4966265263465181372">"Aksesori USB"</string> + <string name="label_view" msgid="6304565553218192990">"Lihat"</string> + <string name="always_use_device" msgid="1450287437017315906">"Gunakan secara bawaan untuk perangkat USB ini"</string> + <string name="always_use_accessory" msgid="1210954576979621596">"Gunakan secara bawaan untuk aksesori USB ini"</string> </resources> diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml index b541374a2c58..055e7838476e 100644 --- a/packages/SystemUI/res/values-it/strings.xml +++ b/packages/SystemUI/res/values-it/strings.xml @@ -44,22 +44,13 @@ <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth con tethering"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Configura metodi di input"</string> <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Utilizza tastiera fisica"</string> - <!-- no translation found for usb_device_permission_prompt (3816016361969816903) --> - <skip /> - <!-- no translation found for usb_accessory_permission_prompt (6888598803988889959) --> - <skip /> - <!-- no translation found for usb_device_confirm_prompt (5161205258635253206) --> - <skip /> - <!-- no translation found for usb_accessory_confirm_prompt (3808984931830229888) --> - <skip /> - <!-- no translation found for usb_accessory_uri_prompt (6332150684964235705) --> - <skip /> - <!-- no translation found for title_usb_accessory (4966265263465181372) --> - <skip /> - <!-- no translation found for label_view (6304565553218192990) --> - <skip /> - <!-- no translation found for always_use_device (1450287437017315906) --> - <skip /> - <!-- no translation found for always_use_accessory (1210954576979621596) --> - <skip /> + <string name="usb_device_permission_prompt" msgid="3816016361969816903">"Consentire all\'applicazione <xliff:g id="APPLICATION">%1$s</xliff:g> di accedere al dispositivo USB?"</string> + <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"Consentire all\'applicazione <xliff:g id="APPLICATION">%1$s</xliff:g> di accedere all\'accessorio USB?"</string> + <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Aprire <xliff:g id="ACTIVITY">%1$s</xliff:g> quando questo dispositivo USB è collegato?"</string> + <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Aprire <xliff:g id="ACTIVITY">%1$s</xliff:g> quando questo accessorio USB è collegato?"</string> + <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Applicazioni installate non funzionano con accessorio USB. Altre informazioni su accessorio su <xliff:g id="URL">%1$s</xliff:g>."</string> + <string name="title_usb_accessory" msgid="4966265263465181372">"Accessorio USB"</string> + <string name="label_view" msgid="6304565553218192990">"Visualizza"</string> + <string name="always_use_device" msgid="1450287437017315906">"Usa per impostazione predef. per dispositivo USB"</string> + <string name="always_use_accessory" msgid="1210954576979621596">"Usa per impostazione predef. per accessorio USB"</string> </resources> diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml index 3194cf5410c7..04fa6866e438 100644 --- a/packages/SystemUI/res/values-iw/strings.xml +++ b/packages/SystemUI/res/values-iw/strings.xml @@ -44,22 +44,13 @@ <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth קשור"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"הגדר שיטות קלט"</string> <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"השתמש במקלדת הפיזית"</string> - <!-- no translation found for usb_device_permission_prompt (3816016361969816903) --> - <skip /> - <!-- no translation found for usb_accessory_permission_prompt (6888598803988889959) --> - <skip /> - <!-- no translation found for usb_device_confirm_prompt (5161205258635253206) --> - <skip /> - <!-- no translation found for usb_accessory_confirm_prompt (3808984931830229888) --> - <skip /> - <!-- no translation found for usb_accessory_uri_prompt (6332150684964235705) --> - <skip /> - <!-- no translation found for title_usb_accessory (4966265263465181372) --> - <skip /> - <!-- no translation found for label_view (6304565553218192990) --> - <skip /> - <!-- no translation found for always_use_device (1450287437017315906) --> - <skip /> - <!-- no translation found for always_use_accessory (1210954576979621596) --> - <skip /> + <string name="usb_device_permission_prompt" msgid="3816016361969816903">"האם לאפשר ליישום <xliff:g id="APPLICATION">%1$s</xliff:g> לגשת להתקן ה-USB?"</string> + <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"האם לאפשר ליישום <xliff:g id="APPLICATION">%1$s</xliff:g> לגשת לאביזר ה-USB?"</string> + <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"האם לפתוח את <xliff:g id="ACTIVITY">%1$s</xliff:g> כאשר התקן USB זה מחובר?"</string> + <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"האם לפתוח את <xliff:g id="ACTIVITY">%1$s</xliff:g> כאשר אביזר USB זה מחובר?"</string> + <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"אין יישומים מותקנים הפועלים עם אביזר ה-USB. למידע נוסף אודות אביזר זה בכתובת <xliff:g id="URL">%1$s</xliff:g>"</string> + <string name="title_usb_accessory" msgid="4966265263465181372">"עזרי USB"</string> + <string name="label_view" msgid="6304565553218192990">"הצג"</string> + <string name="always_use_device" msgid="1450287437017315906">"השתמש כברירת מחדל עבור התקן USB זה"</string> + <string name="always_use_accessory" msgid="1210954576979621596">"השתמש כברירת מחדל עבור אביזר USB זה"</string> </resources> diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml index ac82ed477adb..4ec1d1b54453 100644 --- a/packages/SystemUI/res/values-ja/strings.xml +++ b/packages/SystemUI/res/values-ja/strings.xml @@ -44,22 +44,13 @@ <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetoothテザリング接続"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"入力方法の設定"</string> <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"物理キーボードを使用"</string> - <!-- no translation found for usb_device_permission_prompt (3816016361969816903) --> - <skip /> - <!-- no translation found for usb_accessory_permission_prompt (6888598803988889959) --> - <skip /> - <!-- no translation found for usb_device_confirm_prompt (5161205258635253206) --> - <skip /> - <!-- no translation found for usb_accessory_confirm_prompt (3808984931830229888) --> - <skip /> - <!-- no translation found for usb_accessory_uri_prompt (6332150684964235705) --> - <skip /> - <!-- no translation found for title_usb_accessory (4966265263465181372) --> - <skip /> - <!-- no translation found for label_view (6304565553218192990) --> - <skip /> - <!-- no translation found for always_use_device (1450287437017315906) --> - <skip /> - <!-- no translation found for always_use_accessory (1210954576979621596) --> - <skip /> + <string name="usb_device_permission_prompt" msgid="3816016361969816903">"アプリケーション<xliff:g id="APPLICATION">%1$s</xliff:g>にUSBデバイスへのアクセスを許可しますか?"</string> + <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"アプリケーション<xliff:g id="APPLICATION">%1$s</xliff:g>にUSBアクセサリへのアクセスを許可しますか?"</string> + <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"このUSBデバイスが接続されたときに<xliff:g id="ACTIVITY">%1$s</xliff:g>を開きますか?"</string> + <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"このUSBアクセサリが接続されたときに<xliff:g id="ACTIVITY">%1$s</xliff:g>を開きますか?"</string> + <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"このUSBアクセサリを扱うアプリはインストールされていません。詳細は <xliff:g id="URL">%1$s</xliff:g> をご覧ください。"</string> + <string name="title_usb_accessory" msgid="4966265263465181372">"USBアクセサリ"</string> + <string name="label_view" msgid="6304565553218192990">"表示"</string> + <string name="always_use_device" msgid="1450287437017315906">"このUSBデバイスにデフォルトで使用する"</string> + <string name="always_use_accessory" msgid="1210954576979621596">"このUSBアクセサリにデフォルトで使用する"</string> </resources> diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml index 2d4786d80013..357682c2e812 100644 --- a/packages/SystemUI/res/values-ko/strings.xml +++ b/packages/SystemUI/res/values-ko/strings.xml @@ -44,22 +44,13 @@ <string name="bluetooth_tethered" msgid="7094101612161133267">"블루투스 테더링됨"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"입력 방법 구성"</string> <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"물리적 키보드 사용"</string> - <!-- no translation found for usb_device_permission_prompt (3816016361969816903) --> - <skip /> - <!-- no translation found for usb_accessory_permission_prompt (6888598803988889959) --> - <skip /> - <!-- no translation found for usb_device_confirm_prompt (5161205258635253206) --> - <skip /> - <!-- no translation found for usb_accessory_confirm_prompt (3808984931830229888) --> - <skip /> - <!-- no translation found for usb_accessory_uri_prompt (6332150684964235705) --> - <skip /> - <!-- no translation found for title_usb_accessory (4966265263465181372) --> - <skip /> - <!-- no translation found for label_view (6304565553218192990) --> - <skip /> - <!-- no translation found for always_use_device (1450287437017315906) --> - <skip /> - <!-- no translation found for always_use_accessory (1210954576979621596) --> - <skip /> + <string name="usb_device_permission_prompt" msgid="3816016361969816903">"애플리케이션 <xliff:g id="APPLICATION">%1$s</xliff:g>(이)가 USB 기기에 액세스하도록 허용하시겠습니까?"</string> + <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"애플리케이션 <xliff:g id="APPLICATION">%1$s</xliff:g>(이)가 USB 액세서리에 액세스하도록 허용하시겠습니까"</string> + <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"USB 기기가 연결될 때 <xliff:g id="ACTIVITY">%1$s</xliff:g>(을)를 여시겠습니까?"</string> + <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"USB 액세서리가 연결될 때 <xliff:g id="ACTIVITY">%1$s</xliff:g>(을)를 여시겠습니까?"</string> + <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"이 USB와 호환되는 설치 애플리케이션이 없습니다. <xliff:g id="URL">%1$s</xliff:g>에서 세부정보를 참조하세요."</string> + <string name="title_usb_accessory" msgid="4966265263465181372">"USB 액세서리"</string> + <string name="label_view" msgid="6304565553218192990">"보기"</string> + <string name="always_use_device" msgid="1450287437017315906">"이 USB 기기에 기본값으로 사용"</string> + <string name="always_use_accessory" msgid="1210954576979621596">"이 USB 액세서리에 기본값으로 사용"</string> </resources> diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml index db06596a7fb9..4c7986c36810 100644 --- a/packages/SystemUI/res/values-lt/strings.xml +++ b/packages/SystemUI/res/values-lt/strings.xml @@ -44,22 +44,13 @@ <string name="bluetooth_tethered" msgid="7094101612161133267">"„Bluetooth“ susieta"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Konfigūruoti įvesties metodus"</string> <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Naudoti fizinę klaviatūrą"</string> - <!-- no translation found for usb_device_permission_prompt (3816016361969816903) --> - <skip /> - <!-- no translation found for usb_accessory_permission_prompt (6888598803988889959) --> - <skip /> - <!-- no translation found for usb_device_confirm_prompt (5161205258635253206) --> - <skip /> - <!-- no translation found for usb_accessory_confirm_prompt (3808984931830229888) --> - <skip /> - <!-- no translation found for usb_accessory_uri_prompt (6332150684964235705) --> - <skip /> - <!-- no translation found for title_usb_accessory (4966265263465181372) --> - <skip /> - <!-- no translation found for label_view (6304565553218192990) --> - <skip /> - <!-- no translation found for always_use_device (1450287437017315906) --> - <skip /> - <!-- no translation found for always_use_accessory (1210954576979621596) --> - <skip /> + <string name="usb_device_permission_prompt" msgid="3816016361969816903">"Leisti programai „<xliff:g id="APPLICATION">%1$s</xliff:g>“ pasiekti USB įrenginį?"</string> + <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"Leisti programai „<xliff:g id="APPLICATION">%1$s</xliff:g>“ pasiekti USB priedą?"</string> + <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Atidaryti <xliff:g id="ACTIVITY">%1$s</xliff:g>, kai prijungtas šis USB įrenginys?"</string> + <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Atidaryti <xliff:g id="ACTIVITY">%1$s</xliff:g>, kai prijungtas šis USB priedas?"</string> + <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Su šiuo USB pr. nev. jokios įdieg. pr. Suž. daugiau apie šį pr. šiuo adr.: <xliff:g id="URL">%1$s</xliff:g>"</string> + <string name="title_usb_accessory" msgid="4966265263465181372">"USB reikmuo"</string> + <string name="label_view" msgid="6304565553218192990">"Žiūrėti"</string> + <string name="always_use_device" msgid="1450287437017315906">"Šiam USB įreng. naudoti pagal numat. nustatymus"</string> + <string name="always_use_accessory" msgid="1210954576979621596">"Šiam USB priedui naudoti pagal numat. nustatymus"</string> </resources> diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml index 079591e6fc73..2804ffa21155 100644 --- a/packages/SystemUI/res/values-lv/strings.xml +++ b/packages/SystemUI/res/values-lv/strings.xml @@ -44,22 +44,13 @@ <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth piesaiste"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Konfigurēt ievades metodes"</string> <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Izmantot fizisku tastatūru"</string> - <!-- no translation found for usb_device_permission_prompt (3816016361969816903) --> - <skip /> - <!-- no translation found for usb_accessory_permission_prompt (6888598803988889959) --> - <skip /> - <!-- no translation found for usb_device_confirm_prompt (5161205258635253206) --> - <skip /> - <!-- no translation found for usb_accessory_confirm_prompt (3808984931830229888) --> - <skip /> - <!-- no translation found for usb_accessory_uri_prompt (6332150684964235705) --> - <skip /> - <!-- no translation found for title_usb_accessory (4966265263465181372) --> - <skip /> - <!-- no translation found for label_view (6304565553218192990) --> - <skip /> - <!-- no translation found for always_use_device (1450287437017315906) --> - <skip /> - <!-- no translation found for always_use_accessory (1210954576979621596) --> - <skip /> + <string name="usb_device_permission_prompt" msgid="3816016361969816903">"Vai ļaut lietojumprogrammai <xliff:g id="APPLICATION">%1$s</xliff:g> piekļūt šai USB ierīcei?"</string> + <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"Vai ļaut lietojumprogrammai <xliff:g id="APPLICATION">%1$s</xliff:g> piekļūt šim USB piederumam?"</string> + <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Vai atvērt darbību <xliff:g id="ACTIVITY">%1$s</xliff:g>, kad tiek pievienota šī USB ierīce?"</string> + <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Vai atvērt darbību <xliff:g id="ACTIVITY">%1$s</xliff:g>, kad tiek pievienots šis USB piederums?"</string> + <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Neinst. lietojumpr. darbojas ar šo USB pied. Uzz. vairāk par šo piederumu: <xliff:g id="URL">%1$s</xliff:g>."</string> + <string name="title_usb_accessory" msgid="4966265263465181372">"USB piederums"</string> + <string name="label_view" msgid="6304565553218192990">"Skatīt"</string> + <string name="always_use_device" msgid="1450287437017315906">"Pēc noklusējuma izmantot šai USB ierīcei"</string> + <string name="always_use_accessory" msgid="1210954576979621596">"Pēc noklusējuma izmantot šim USB piederumam"</string> </resources> diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml index b7e7711e8eb5..0dc10401e33f 100644 --- a/packages/SystemUI/res/values-nb/strings.xml +++ b/packages/SystemUI/res/values-nb/strings.xml @@ -44,22 +44,13 @@ <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth tilknyttet"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Konfigurer inndatametoder"</string> <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Bruk fysisk tastatur"</string> - <!-- no translation found for usb_device_permission_prompt (3816016361969816903) --> - <skip /> - <!-- no translation found for usb_accessory_permission_prompt (6888598803988889959) --> - <skip /> - <!-- no translation found for usb_device_confirm_prompt (5161205258635253206) --> - <skip /> - <!-- no translation found for usb_accessory_confirm_prompt (3808984931830229888) --> - <skip /> - <!-- no translation found for usb_accessory_uri_prompt (6332150684964235705) --> - <skip /> - <!-- no translation found for title_usb_accessory (4966265263465181372) --> - <skip /> - <!-- no translation found for label_view (6304565553218192990) --> - <skip /> - <!-- no translation found for always_use_device (1450287437017315906) --> - <skip /> - <!-- no translation found for always_use_accessory (1210954576979621596) --> - <skip /> + <string name="usb_device_permission_prompt" msgid="3816016361969816903">"Vil du tillate at applikasjonen <xliff:g id="APPLICATION">%1$s</xliff:g> får tilgang til USB-enheten?"</string> + <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"Vil du tillate at applikasjonen <xliff:g id="APPLICATION">%1$s</xliff:g> får tilgang til USB-tilbehøret?"</string> + <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Vil du åpne <xliff:g id="ACTIVITY">%1$s</xliff:g> når denne USB-enheten er tilkoblet?"</string> + <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Vil du åpne <xliff:g id="ACTIVITY">%1$s</xliff:g> når dette USB-tilbehøret er tilkoblet?"</string> + <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Ingen installerte applikasjoner støtter dette USB-tilbehøret. Les mer om tilbehøret på <xliff:g id="URL">%1$s</xliff:g>"</string> + <string name="title_usb_accessory" msgid="4966265263465181372">"USB-enhet"</string> + <string name="label_view" msgid="6304565553218192990">"Vis"</string> + <string name="always_use_device" msgid="1450287437017315906">"Bruk som standard for denne USB-enheten"</string> + <string name="always_use_accessory" msgid="1210954576979621596">"Bruk som standard for dette USB-tilbehøret"</string> </resources> diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml index cc9e7a360f2d..4682f9365972 100644 --- a/packages/SystemUI/res/values-nl/strings.xml +++ b/packages/SystemUI/res/values-nl/strings.xml @@ -44,22 +44,13 @@ <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth getetherd"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Invoermethoden configureren"</string> <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Fysiek toetsenbord gebruiken"</string> - <!-- no translation found for usb_device_permission_prompt (3816016361969816903) --> - <skip /> - <!-- no translation found for usb_accessory_permission_prompt (6888598803988889959) --> - <skip /> - <!-- no translation found for usb_device_confirm_prompt (5161205258635253206) --> - <skip /> - <!-- no translation found for usb_accessory_confirm_prompt (3808984931830229888) --> - <skip /> - <!-- no translation found for usb_accessory_uri_prompt (6332150684964235705) --> - <skip /> - <!-- no translation found for title_usb_accessory (4966265263465181372) --> - <skip /> - <!-- no translation found for label_view (6304565553218192990) --> - <skip /> - <!-- no translation found for always_use_device (1450287437017315906) --> - <skip /> - <!-- no translation found for always_use_accessory (1210954576979621596) --> - <skip /> + <string name="usb_device_permission_prompt" msgid="3816016361969816903">"De applicatie <xliff:g id="APPLICATION">%1$s</xliff:g> toegang tot het USB-apparaat geven?"</string> + <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"De applicatie <xliff:g id="APPLICATION">%1$s</xliff:g> toegang tot het USB-accessoire geven?"</string> + <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"<xliff:g id="ACTIVITY">%1$s</xliff:g> openen wanneer dit USB-apparaat wordt aangesloten?"</string> + <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"<xliff:g id="ACTIVITY">%1$s</xliff:g> openen wanneer dit USB-accessoire wordt aangesloten?"</string> + <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Er zijn geen geïnstalleerde applicaties die werken met dit USB-accessoire. Meer informatie over dit accessoire vindt u op <xliff:g id="URL">%1$s</xliff:g>"</string> + <string name="title_usb_accessory" msgid="4966265263465181372">"USB-accessoire"</string> + <string name="label_view" msgid="6304565553218192990">"Weergeven"</string> + <string name="always_use_device" msgid="1450287437017315906">"Standaard gebruiken voor dit USB-apparaat"</string> + <string name="always_use_accessory" msgid="1210954576979621596">"Standaard gebruiken voor dit USB-accessoire"</string> </resources> diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml index 67d9cc1385cb..198e3e3c16f5 100644 --- a/packages/SystemUI/res/values-pl/strings.xml +++ b/packages/SystemUI/res/values-pl/strings.xml @@ -44,22 +44,13 @@ <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth – podłączono"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Konfiguruj metody wprowadzania"</string> <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Używaj klawiatury fizycznej"</string> - <!-- no translation found for usb_device_permission_prompt (3816016361969816903) --> - <skip /> - <!-- no translation found for usb_accessory_permission_prompt (6888598803988889959) --> - <skip /> - <!-- no translation found for usb_device_confirm_prompt (5161205258635253206) --> - <skip /> - <!-- no translation found for usb_accessory_confirm_prompt (3808984931830229888) --> - <skip /> - <!-- no translation found for usb_accessory_uri_prompt (6332150684964235705) --> - <skip /> - <!-- no translation found for title_usb_accessory (4966265263465181372) --> - <skip /> - <!-- no translation found for label_view (6304565553218192990) --> - <skip /> - <!-- no translation found for always_use_device (1450287437017315906) --> - <skip /> - <!-- no translation found for always_use_accessory (1210954576979621596) --> - <skip /> + <string name="usb_device_permission_prompt" msgid="3816016361969816903">"Czy zezwolić aplikacji <xliff:g id="APPLICATION">%1$s</xliff:g> na dostęp do urządzenia USB?"</string> + <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"Czy zezwolić aplikacji <xliff:g id="APPLICATION">%1$s</xliff:g> na dostęp do akcesorium USB?"</string> + <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Czy otworzyć <xliff:g id="ACTIVITY">%1$s</xliff:g> po podłączeniu tego urządzenia USB?"</string> + <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Czy otworzyć <xliff:g id="ACTIVITY">%1$s</xliff:g> po podłączeniu tego akcesorium USB?"</string> + <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Zainstalowane aplikacje nie działają z tym akcesorium USB. Więcej informacji: <xliff:g id="URL">%1$s</xliff:g>"</string> + <string name="title_usb_accessory" msgid="4966265263465181372">"Akcesorium USB"</string> + <string name="label_view" msgid="6304565553218192990">"Wyświetl"</string> + <string name="always_use_device" msgid="1450287437017315906">"Używaj domyślnie dla tego urządzenia USB"</string> + <string name="always_use_accessory" msgid="1210954576979621596">"Używaj domyślnie dla tego akcesorium USB"</string> </resources> diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml index 5ee79a09c3ec..c79dbf013681 100644 --- a/packages/SystemUI/res/values-pt-rPT/strings.xml +++ b/packages/SystemUI/res/values-pt-rPT/strings.xml @@ -44,22 +44,13 @@ <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth ligado"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Configurar métodos de entrada"</string> <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Utilizar teclado físico"</string> - <!-- no translation found for usb_device_permission_prompt (3816016361969816903) --> - <skip /> - <!-- no translation found for usb_accessory_permission_prompt (6888598803988889959) --> - <skip /> - <!-- no translation found for usb_device_confirm_prompt (5161205258635253206) --> - <skip /> - <!-- no translation found for usb_accessory_confirm_prompt (3808984931830229888) --> - <skip /> - <!-- no translation found for usb_accessory_uri_prompt (6332150684964235705) --> - <skip /> - <!-- no translation found for title_usb_accessory (4966265263465181372) --> - <skip /> - <!-- no translation found for label_view (6304565553218192990) --> - <skip /> - <!-- no translation found for always_use_device (1450287437017315906) --> - <skip /> - <!-- no translation found for always_use_accessory (1210954576979621596) --> - <skip /> + <string name="usb_device_permission_prompt" msgid="3816016361969816903">"Permitir que a aplicação <xliff:g id="APPLICATION">%1$s</xliff:g> aceda ao dispositivo USB?"</string> + <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"Permitir que a aplicação <xliff:g id="APPLICATION">%1$s</xliff:g> aceda ao acessório USB?"</string> + <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Abrir <xliff:g id="ACTIVITY">%1$s</xliff:g> quando este dispositivo USB estiver ligado?"</string> + <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Abrir <xliff:g id="ACTIVITY">%1$s</xliff:g> quando este acessório USB estiver ligado?"</string> + <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Nenhuma das aplicações instaladas funciona com este acessório USB. Saiba mais sobre este acessório em <xliff:g id="URL">%1$s</xliff:g>."</string> + <string name="title_usb_accessory" msgid="4966265263465181372">"Acessório USB"</string> + <string name="label_view" msgid="6304565553218192990">"Ver"</string> + <string name="always_use_device" msgid="1450287437017315906">"Utilizar por predefinição para este aparelho USB"</string> + <string name="always_use_accessory" msgid="1210954576979621596">"Utilizar por predefinição para este acessório USB"</string> </resources> diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml index a91d40697799..d37988f5068d 100644 --- a/packages/SystemUI/res/values-pt/strings.xml +++ b/packages/SystemUI/res/values-pt/strings.xml @@ -44,22 +44,13 @@ <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth vinculado"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Configurar métodos de entrada"</string> <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Usar o teclado físico"</string> - <!-- no translation found for usb_device_permission_prompt (3816016361969816903) --> - <skip /> - <!-- no translation found for usb_accessory_permission_prompt (6888598803988889959) --> - <skip /> - <!-- no translation found for usb_device_confirm_prompt (5161205258635253206) --> - <skip /> - <!-- no translation found for usb_accessory_confirm_prompt (3808984931830229888) --> - <skip /> - <!-- no translation found for usb_accessory_uri_prompt (6332150684964235705) --> - <skip /> - <!-- no translation found for title_usb_accessory (4966265263465181372) --> - <skip /> - <!-- no translation found for label_view (6304565553218192990) --> - <skip /> - <!-- no translation found for always_use_device (1450287437017315906) --> - <skip /> - <!-- no translation found for always_use_accessory (1210954576979621596) --> - <skip /> + <string name="usb_device_permission_prompt" msgid="3816016361969816903">"Permitir que o aplicativo <xliff:g id="APPLICATION">%1$s</xliff:g> acesse o dispositivo USB?"</string> + <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"Permitir que o aplicativo <xliff:g id="APPLICATION">%1$s</xliff:g> acesse o acessório USB?"</string> + <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Abrir <xliff:g id="ACTIVITY">%1$s</xliff:g> quando este dispositivo USB estiver conectado?"</string> + <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Abrir <xliff:g id="ACTIVITY">%1$s</xliff:g> quando este acessório USB estiver conectado?"</string> + <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Nenhum apl. instalado funciona com o acess. USB. Saiba mais sobre o acessório em <xliff:g id="URL">%1$s</xliff:g>"</string> + <string name="title_usb_accessory" msgid="4966265263465181372">"Acessório USB"</string> + <string name="label_view" msgid="6304565553218192990">"Visualizar"</string> + <string name="always_use_device" msgid="1450287437017315906">"Usar por padrão para este dispositivo USB"</string> + <string name="always_use_accessory" msgid="1210954576979621596">"Usar por padrão para este acessório USB"</string> </resources> diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml index 36628aa95cfb..afecb921a031 100644 --- a/packages/SystemUI/res/values-ro/strings.xml +++ b/packages/SystemUI/res/values-ro/strings.xml @@ -44,22 +44,13 @@ <string name="bluetooth_tethered" msgid="7094101612161133267">"Conectat prin tethering prin Bluetooth"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Configuraţi metode de intrare"</string> <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Utilizaţi tastat. fizică"</string> - <!-- no translation found for usb_device_permission_prompt (3816016361969816903) --> - <skip /> - <!-- no translation found for usb_accessory_permission_prompt (6888598803988889959) --> - <skip /> - <!-- no translation found for usb_device_confirm_prompt (5161205258635253206) --> - <skip /> - <!-- no translation found for usb_accessory_confirm_prompt (3808984931830229888) --> - <skip /> - <!-- no translation found for usb_accessory_uri_prompt (6332150684964235705) --> - <skip /> - <!-- no translation found for title_usb_accessory (4966265263465181372) --> - <skip /> - <!-- no translation found for label_view (6304565553218192990) --> - <skip /> - <!-- no translation found for always_use_device (1450287437017315906) --> - <skip /> - <!-- no translation found for always_use_accessory (1210954576979621596) --> - <skip /> + <string name="usb_device_permission_prompt" msgid="3816016361969816903">"Permiteţi aplicaţiei <xliff:g id="APPLICATION">%1$s</xliff:g> să acceseze dispozitivul USB?"</string> + <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"Permiteţi aplicaţiei <xliff:g id="APPLICATION">%1$s</xliff:g> să acceseze accesoriul USB?"</string> + <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Deschideţi <xliff:g id="ACTIVITY">%1$s</xliff:g> la conectarea acestui dispozitiv USB?"</string> + <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Deschideţi <xliff:g id="ACTIVITY">%1$s</xliff:g> la conectarea acestui accesoriu USB?"</string> + <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Aplic. instal. nu funcţ. cu acest acces. USB. Aflaţi despre acest acces. la <xliff:g id="URL">%1$s</xliff:g>"</string> + <string name="title_usb_accessory" msgid="4966265263465181372">"Accesoriu USB"</string> + <string name="label_view" msgid="6304565553218192990">"Afişaţi"</string> + <string name="always_use_device" msgid="1450287437017315906">"Utilizaţi în mod prestabilit pt. acest dispoz. USB"</string> + <string name="always_use_accessory" msgid="1210954576979621596">"Utiliz. în mod prestabilit pt. acest accesoriu USB"</string> </resources> diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml index 13da8a3fd270..623bb65ea6ca 100644 --- a/packages/SystemUI/res/values-ru/strings.xml +++ b/packages/SystemUI/res/values-ru/strings.xml @@ -44,22 +44,13 @@ <string name="bluetooth_tethered" msgid="7094101612161133267">"Общий модем доступен через Bluetooth"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Настроить способ ввода"</string> <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Использовать физическую клавиатуру"</string> - <!-- no translation found for usb_device_permission_prompt (3816016361969816903) --> - <skip /> - <!-- no translation found for usb_accessory_permission_prompt (6888598803988889959) --> - <skip /> - <!-- no translation found for usb_device_confirm_prompt (5161205258635253206) --> - <skip /> - <!-- no translation found for usb_accessory_confirm_prompt (3808984931830229888) --> - <skip /> - <!-- no translation found for usb_accessory_uri_prompt (6332150684964235705) --> - <skip /> - <!-- no translation found for title_usb_accessory (4966265263465181372) --> - <skip /> - <!-- no translation found for label_view (6304565553218192990) --> - <skip /> - <!-- no translation found for always_use_device (1450287437017315906) --> - <skip /> - <!-- no translation found for always_use_accessory (1210954576979621596) --> - <skip /> + <string name="usb_device_permission_prompt" msgid="3816016361969816903">"Разрешить приложению <xliff:g id="APPLICATION">%1$s</xliff:g> доступ к USB-устройству?"</string> + <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"Разрешить приложению <xliff:g id="APPLICATION">%1$s</xliff:g> доступ к USB-аксессуару?"</string> + <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Запускать <xliff:g id="ACTIVITY">%1$s</xliff:g> при подключении этого USB-устройства?"</string> + <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Запускать <xliff:g id="ACTIVITY">%1$s</xliff:g> при подключении этого USB-аксессуара?"</string> + <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Установленные приложения не поддерживают этот USB-аксессуар. Подробнее о нем читайте здесь: <xliff:g id="URL">%1$s</xliff:g>."</string> + <string name="title_usb_accessory" msgid="4966265263465181372">"USB-устройство"</string> + <string name="label_view" msgid="6304565553218192990">"Просмотр"</string> + <string name="always_use_device" msgid="1450287437017315906">"Использовать по умолчанию для этого USB-устройства"</string> + <string name="always_use_accessory" msgid="1210954576979621596">"Использовать по умолчанию для этого USB-аксессуара"</string> </resources> diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml index c08eb2164c23..025046183b0b 100644 --- a/packages/SystemUI/res/values-sk/strings.xml +++ b/packages/SystemUI/res/values-sk/strings.xml @@ -44,22 +44,13 @@ <string name="bluetooth_tethered" msgid="7094101612161133267">"Zdieľané dátové pripojenie cez Bluetooth"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Konfigurovať metódy vstupu"</string> <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Použiť fyzickú klávesnicu"</string> - <!-- no translation found for usb_device_permission_prompt (3816016361969816903) --> - <skip /> - <!-- no translation found for usb_accessory_permission_prompt (6888598803988889959) --> - <skip /> - <!-- no translation found for usb_device_confirm_prompt (5161205258635253206) --> - <skip /> - <!-- no translation found for usb_accessory_confirm_prompt (3808984931830229888) --> - <skip /> - <!-- no translation found for usb_accessory_uri_prompt (6332150684964235705) --> - <skip /> - <!-- no translation found for title_usb_accessory (4966265263465181372) --> - <skip /> - <!-- no translation found for label_view (6304565553218192990) --> - <skip /> - <!-- no translation found for always_use_device (1450287437017315906) --> - <skip /> - <!-- no translation found for always_use_accessory (1210954576979621596) --> - <skip /> + <string name="usb_device_permission_prompt" msgid="3816016361969816903">"Povoliť aplikácii <xliff:g id="APPLICATION">%1$s</xliff:g> prístup k zariadeniu USB?"</string> + <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"Povoliť aplikácii <xliff:g id="APPLICATION">%1$s</xliff:g> prístup k periférnemu zariadeniu USB?"</string> + <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Chcete pri pripojení tohto zariadenia USB otvoriť aplikáciu <xliff:g id="ACTIVITY">%1$s</xliff:g>?"</string> + <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Chcete pri pripojení tohto periférneho zariadenia USB otvoriť aplikáciu <xliff:g id="ACTIVITY">%1$s</xliff:g>?"</string> + <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"S týmto periférnym zariad. USB nefunguje žiadna nainštalovaná aplikácia. Viac informácií nájdete na stránkach <xliff:g id="URL">%1$s</xliff:g>"</string> + <string name="title_usb_accessory" msgid="4966265263465181372">"Periférne zariadenie USB"</string> + <string name="label_view" msgid="6304565553218192990">"Zobraziť"</string> + <string name="always_use_device" msgid="1450287437017315906">"Pre toto zariadenie USB použiť ako predvolené"</string> + <string name="always_use_accessory" msgid="1210954576979621596">"Pre toto periférne zar. USB použiť ako predvolené"</string> </resources> diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml index d7cb726e3476..d31a30b84134 100644 --- a/packages/SystemUI/res/values-sl/strings.xml +++ b/packages/SystemUI/res/values-sl/strings.xml @@ -44,22 +44,13 @@ <string name="bluetooth_tethered" msgid="7094101612161133267">"Internetna povezava prek Bluetootha"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Nastavitev načinov vnosa"</string> <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Uporabi fizično tipkovn."</string> - <!-- no translation found for usb_device_permission_prompt (3816016361969816903) --> - <skip /> - <!-- no translation found for usb_accessory_permission_prompt (6888598803988889959) --> - <skip /> - <!-- no translation found for usb_device_confirm_prompt (5161205258635253206) --> - <skip /> - <!-- no translation found for usb_accessory_confirm_prompt (3808984931830229888) --> - <skip /> - <!-- no translation found for usb_accessory_uri_prompt (6332150684964235705) --> - <skip /> - <!-- no translation found for title_usb_accessory (4966265263465181372) --> - <skip /> - <!-- no translation found for label_view (6304565553218192990) --> - <skip /> - <!-- no translation found for always_use_device (1450287437017315906) --> - <skip /> - <!-- no translation found for always_use_accessory (1210954576979621596) --> - <skip /> + <string name="usb_device_permission_prompt" msgid="3816016361969816903">"Želite programu <xliff:g id="APPLICATION">%1$s</xliff:g> omogočiti dostop do naprave USB?"</string> + <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"Želite programu <xliff:g id="APPLICATION">%1$s</xliff:g> omogočiti dostop do dodatka USB?"</string> + <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Želite, da se odpre <xliff:g id="ACTIVITY">%1$s</xliff:g>, ko priključite to napravo USB?"</string> + <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Želite, da se odpre <xliff:g id="ACTIVITY">%1$s</xliff:g>, ko priključite ta dodatek USB?"</string> + <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Noben nameščen program ne deluje s tem dodatkom USB. Več o tem dodatku: <xliff:g id="URL">%1$s</xliff:g>"</string> + <string name="title_usb_accessory" msgid="4966265263465181372">"Dodatek USB"</string> + <string name="label_view" msgid="6304565553218192990">"Prikaži"</string> + <string name="always_use_device" msgid="1450287437017315906">"Privzeto uporabi za to napravo USB"</string> + <string name="always_use_accessory" msgid="1210954576979621596">"Privzeto uporabi za ta dodatek USB"</string> </resources> diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml index 6e67293f602f..2c44f6758a46 100644 --- a/packages/SystemUI/res/values-sr/strings.xml +++ b/packages/SystemUI/res/values-sr/strings.xml @@ -44,22 +44,13 @@ <string name="bluetooth_tethered" msgid="7094101612161133267">"Веза преко Bluetooth-а"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Конфигуриши методе уноса"</string> <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Користи физичку тастатуру"</string> - <!-- no translation found for usb_device_permission_prompt (3816016361969816903) --> - <skip /> - <!-- no translation found for usb_accessory_permission_prompt (6888598803988889959) --> - <skip /> - <!-- no translation found for usb_device_confirm_prompt (5161205258635253206) --> - <skip /> - <!-- no translation found for usb_accessory_confirm_prompt (3808984931830229888) --> - <skip /> - <!-- no translation found for usb_accessory_uri_prompt (6332150684964235705) --> - <skip /> - <!-- no translation found for title_usb_accessory (4966265263465181372) --> - <skip /> - <!-- no translation found for label_view (6304565553218192990) --> - <skip /> - <!-- no translation found for always_use_device (1450287437017315906) --> - <skip /> - <!-- no translation found for always_use_accessory (1210954576979621596) --> - <skip /> + <string name="usb_device_permission_prompt" msgid="3816016361969816903">"Желите ли да омогућите апликацији <xliff:g id="APPLICATION">%1$s</xliff:g> да приступи USB уређају?"</string> + <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"Желите ли да омогућите апликацији <xliff:g id="APPLICATION">%1$s</xliff:g> да приступи USB додатку?"</string> + <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Желите ли да се отвори <xliff:g id="ACTIVITY">%1$s</xliff:g> када се прикључи овај USB уређај?"</string> + <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Желите ли да се отвори <xliff:g id="ACTIVITY">%1$s</xliff:g> када се прикључи овај USB додатак?"</string> + <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Ниједна инстал. апликација не функционише са овим USB додатком. Сазнајте више о додатку на <xliff:g id="URL">%1$s</xliff:g>"</string> + <string name="title_usb_accessory" msgid="4966265263465181372">"USB помоћни уређај"</string> + <string name="label_view" msgid="6304565553218192990">"Прикажи"</string> + <string name="always_use_device" msgid="1450287437017315906">"Користи подразумевано за овај USB уређај"</string> + <string name="always_use_accessory" msgid="1210954576979621596">"Користи подразумевано за овај USB додатак"</string> </resources> diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml index e2905b638710..343d6a811194 100644 --- a/packages/SystemUI/res/values-sv/strings.xml +++ b/packages/SystemUI/res/values-sv/strings.xml @@ -44,22 +44,13 @@ <string name="bluetooth_tethered" msgid="7094101612161133267">"Internetdelning via Bluetooth"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Konfigurera inmatningsmetoder"</string> <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Använd fysiska tangenter"</string> - <!-- no translation found for usb_device_permission_prompt (3816016361969816903) --> - <skip /> - <!-- no translation found for usb_accessory_permission_prompt (6888598803988889959) --> - <skip /> - <!-- no translation found for usb_device_confirm_prompt (5161205258635253206) --> - <skip /> - <!-- no translation found for usb_accessory_confirm_prompt (3808984931830229888) --> - <skip /> - <!-- no translation found for usb_accessory_uri_prompt (6332150684964235705) --> - <skip /> - <!-- no translation found for title_usb_accessory (4966265263465181372) --> - <skip /> - <!-- no translation found for label_view (6304565553218192990) --> - <skip /> - <!-- no translation found for always_use_device (1450287437017315906) --> - <skip /> - <!-- no translation found for always_use_accessory (1210954576979621596) --> - <skip /> + <string name="usb_device_permission_prompt" msgid="3816016361969816903">"Vill du tillåta att programmet <xliff:g id="APPLICATION">%1$s</xliff:g> använder USB-enheten?"</string> + <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"Vill du tillåta att programmet <xliff:g id="APPLICATION">%1$s</xliff:g> använder USB-tillbehöret?"</string> + <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Vill du öppna <xliff:g id="ACTIVITY">%1$s</xliff:g> när den här USB-enheten ansluts?"</string> + <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Vill du öppna <xliff:g id="ACTIVITY">%1$s</xliff:g> när det här USB-tillbehöret ansluts?"</string> + <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Inga program fungerar med det här USB-tillbehöret. Läs mer om det på <xliff:g id="URL">%1$s</xliff:g>"</string> + <string name="title_usb_accessory" msgid="4966265263465181372">"USB-tillbehör"</string> + <string name="label_view" msgid="6304565553218192990">"Visa"</string> + <string name="always_use_device" msgid="1450287437017315906">"Använd som standard för den här USB-enheten"</string> + <string name="always_use_accessory" msgid="1210954576979621596">"Använd som standard för det här USB-tillbehöret"</string> </resources> diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml index 1e7af69e65bd..4db4e24a462e 100644 --- a/packages/SystemUI/res/values-th/strings.xml +++ b/packages/SystemUI/res/values-th/strings.xml @@ -44,22 +44,13 @@ <string name="bluetooth_tethered" msgid="7094101612161133267">"บลูทูธที่ปล่อยสัญญาณ"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"กำหนดค่าวิธีการป้อนข้อมูล"</string> <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"ใช้แป้นพิมพ์จริง"</string> - <!-- no translation found for usb_device_permission_prompt (3816016361969816903) --> - <skip /> - <!-- no translation found for usb_accessory_permission_prompt (6888598803988889959) --> - <skip /> - <!-- no translation found for usb_device_confirm_prompt (5161205258635253206) --> - <skip /> - <!-- no translation found for usb_accessory_confirm_prompt (3808984931830229888) --> - <skip /> - <!-- no translation found for usb_accessory_uri_prompt (6332150684964235705) --> - <skip /> - <!-- no translation found for title_usb_accessory (4966265263465181372) --> - <skip /> - <!-- no translation found for label_view (6304565553218192990) --> - <skip /> - <!-- no translation found for always_use_device (1450287437017315906) --> - <skip /> - <!-- no translation found for always_use_accessory (1210954576979621596) --> - <skip /> + <string name="usb_device_permission_prompt" msgid="3816016361969816903">"อนุญาตให้แอปพลิเคชัน <xliff:g id="APPLICATION">%1$s</xliff:g> เข้าถึงอุปกรณ์ USB นี้หรือไม่"</string> + <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"อนุญาตให้แอปพลิเคชัน <xliff:g id="APPLICATION">%1$s</xliff:g> เข้าถึงอุปกรณ์เสริม USB นี้หรือไม่"</string> + <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"เปิด <xliff:g id="ACTIVITY">%1$s</xliff:g> เมื่อมีการเชื่อมต่ออุปกรณ์ USB นี้หรือไม่"</string> + <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"เปิด <xliff:g id="ACTIVITY">%1$s</xliff:g> เมื่อมีการเชื่อมต่ออุปกรณ์เสริม USB นี้หรือไม่"</string> + <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"แอปพลิเคชันที่ติดตั้งใช้กับอุปกรณ์ USB นี้ไม่ได้ เรียนรู้เพิ่มเติมที่ <xliff:g id="URL">%1$s</xliff:g>"</string> + <string name="title_usb_accessory" msgid="4966265263465181372">"อุปกรณ์เสริม USB"</string> + <string name="label_view" msgid="6304565553218192990">"ดู"</string> + <string name="always_use_device" msgid="1450287437017315906">"ใช้ค่าเริ่มต้นสำหรับอุปกรณ์ USB นี้"</string> + <string name="always_use_accessory" msgid="1210954576979621596">"ใช้ค่าเริ่มต้นสำหรับอุปกรณ์เสริม USB นี้"</string> </resources> diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml index 9fadf73e578d..8cd8cfaeca90 100644 --- a/packages/SystemUI/res/values-tl/strings.xml +++ b/packages/SystemUI/res/values-tl/strings.xml @@ -44,22 +44,13 @@ <string name="bluetooth_tethered" msgid="7094101612161133267">"Na-tether ang bluetooth"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"I-configure paraan ng input"</string> <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Gamitin ang pisikal na keyboard"</string> - <!-- no translation found for usb_device_permission_prompt (3816016361969816903) --> - <skip /> - <!-- no translation found for usb_accessory_permission_prompt (6888598803988889959) --> - <skip /> - <!-- no translation found for usb_device_confirm_prompt (5161205258635253206) --> - <skip /> - <!-- no translation found for usb_accessory_confirm_prompt (3808984931830229888) --> - <skip /> - <!-- no translation found for usb_accessory_uri_prompt (6332150684964235705) --> - <skip /> - <!-- no translation found for title_usb_accessory (4966265263465181372) --> - <skip /> - <!-- no translation found for label_view (6304565553218192990) --> - <skip /> - <!-- no translation found for always_use_device (1450287437017315906) --> - <skip /> - <!-- no translation found for always_use_accessory (1210954576979621596) --> - <skip /> + <string name="usb_device_permission_prompt" msgid="3816016361969816903">"Payagan ang application <xliff:g id="APPLICATION">%1$s</xliff:g> na i-access ang USB device?"</string> + <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"Payagan ang application <xliff:g id="APPLICATION">%1$s</xliff:g> na i-access ang USB accessory?"</string> + <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Buksan ang <xliff:g id="ACTIVITY">%1$s</xliff:g> kapag nakakonekta ang USB device na ito?"</string> + <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Buksan ang <xliff:g id="ACTIVITY">%1$s</xliff:g> kapag nakakonekta ang accessory na USB na ito?"</string> + <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Walang gumaganang mga naka-install na application sa USB accessory na ito <xliff:g id="URL">%1$s</xliff:g>"</string> + <string name="title_usb_accessory" msgid="4966265263465181372">"USB accessory"</string> + <string name="label_view" msgid="6304565553218192990">"Tingnan"</string> + <string name="always_use_device" msgid="1450287437017315906">"Gamitin bilang default para sa USB device"</string> + <string name="always_use_accessory" msgid="1210954576979621596">"Gamitin bilang default sa USB accessory na ito"</string> </resources> diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml index 7c3585aa1227..87ffc8b9643a 100644 --- a/packages/SystemUI/res/values-tr/strings.xml +++ b/packages/SystemUI/res/values-tr/strings.xml @@ -44,22 +44,13 @@ <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth paylaşımı tamam"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Giriş yöntemlerini yapılandır"</string> <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Fiziksel klavyeyi kullan"</string> - <!-- no translation found for usb_device_permission_prompt (3816016361969816903) --> - <skip /> - <!-- no translation found for usb_accessory_permission_prompt (6888598803988889959) --> - <skip /> - <!-- no translation found for usb_device_confirm_prompt (5161205258635253206) --> - <skip /> - <!-- no translation found for usb_accessory_confirm_prompt (3808984931830229888) --> - <skip /> - <!-- no translation found for usb_accessory_uri_prompt (6332150684964235705) --> - <skip /> - <!-- no translation found for title_usb_accessory (4966265263465181372) --> - <skip /> - <!-- no translation found for label_view (6304565553218192990) --> - <skip /> - <!-- no translation found for always_use_device (1450287437017315906) --> - <skip /> - <!-- no translation found for always_use_accessory (1210954576979621596) --> - <skip /> + <string name="usb_device_permission_prompt" msgid="3816016361969816903">"<xliff:g id="APPLICATION">%1$s</xliff:g> uygulamasının bu USB cihazına erişmesine izin verilsin mi?"</string> + <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"<xliff:g id="APPLICATION">%1$s</xliff:g> uygulamasının bu USB aksesuarına erişmesine izin verilsin mi?"</string> + <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Bu USB cihaz bağlandığında <xliff:g id="ACTIVITY">%1$s</xliff:g> açılsın mı?"</string> + <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Bu USB aksesuarı bağlandığında <xliff:g id="ACTIVITY">%1$s</xliff:g> açılsın mı?"</string> + <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Hiçbir yüklü uyg bu USB aksesuarıyla çalışmıyor. Bu aksesuar hakknd daha fazla bilgi için: <xliff:g id="URL">%1$s</xliff:g>"</string> + <string name="title_usb_accessory" msgid="4966265263465181372">"USB aksesuarı"</string> + <string name="label_view" msgid="6304565553218192990">"Görüntüle"</string> + <string name="always_use_device" msgid="1450287437017315906">"Bu USB cihazı için varsayılan olarak kullan"</string> + <string name="always_use_accessory" msgid="1210954576979621596">"Bu USB aksesuar için varsayılan olarak kullan"</string> </resources> diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml index a17e59d32027..6ebad573cc8c 100644 --- a/packages/SystemUI/res/values-uk/strings.xml +++ b/packages/SystemUI/res/values-uk/strings.xml @@ -44,22 +44,13 @@ <string name="bluetooth_tethered" msgid="7094101612161133267">"Створено прив\'язку Bluetooth"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Налаштувати методи введення"</string> <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Викор. реальну клавіатуру"</string> - <!-- no translation found for usb_device_permission_prompt (3816016361969816903) --> - <skip /> - <!-- no translation found for usb_accessory_permission_prompt (6888598803988889959) --> - <skip /> - <!-- no translation found for usb_device_confirm_prompt (5161205258635253206) --> - <skip /> - <!-- no translation found for usb_accessory_confirm_prompt (3808984931830229888) --> - <skip /> - <!-- no translation found for usb_accessory_uri_prompt (6332150684964235705) --> - <skip /> - <!-- no translation found for title_usb_accessory (4966265263465181372) --> - <skip /> - <!-- no translation found for label_view (6304565553218192990) --> - <skip /> - <!-- no translation found for always_use_device (1450287437017315906) --> - <skip /> - <!-- no translation found for always_use_accessory (1210954576979621596) --> - <skip /> + <string name="usb_device_permission_prompt" msgid="3816016361969816903">"Надати програмі <xliff:g id="APPLICATION">%1$s</xliff:g> доступ до пристрою USB?"</string> + <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"Надати програмі <xliff:g id="APPLICATION">%1$s</xliff:g> доступ до аксесуара USB?"</string> + <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Відкривати \"<xliff:g id="ACTIVITY">%1$s</xliff:g>\", коли під’єднано пристрій USB?"</string> + <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Відкривати \"<xliff:g id="ACTIVITY">%1$s</xliff:g>\", коли під’єднано аксесуар USB?"</string> + <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Установлені прогр. не працюють із цим аксесуаром USB. Більше про цей аксесуар: <xliff:g id="URL">%1$s</xliff:g>"</string> + <string name="title_usb_accessory" msgid="4966265263465181372">"Пристрій USB"</string> + <string name="label_view" msgid="6304565553218192990">"Переглянути"</string> + <string name="always_use_device" msgid="1450287437017315906">"Використовувати за умовчанням для пристрою USB"</string> + <string name="always_use_accessory" msgid="1210954576979621596">"Використовувати за умовчанням для аксесуара USB"</string> </resources> diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml index a994ee08b818..13a5737c8197 100644 --- a/packages/SystemUI/res/values-vi/strings.xml +++ b/packages/SystemUI/res/values-vi/strings.xml @@ -44,22 +44,13 @@ <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth được dùng làm điểm truy cập Internet"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Định cấu hình phương pháp nhập liệu"</string> <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Sử dụng bàn phím vật lý"</string> - <!-- no translation found for usb_device_permission_prompt (3816016361969816903) --> - <skip /> - <!-- no translation found for usb_accessory_permission_prompt (6888598803988889959) --> - <skip /> - <!-- no translation found for usb_device_confirm_prompt (5161205258635253206) --> - <skip /> - <!-- no translation found for usb_accessory_confirm_prompt (3808984931830229888) --> - <skip /> - <!-- no translation found for usb_accessory_uri_prompt (6332150684964235705) --> - <skip /> - <!-- no translation found for title_usb_accessory (4966265263465181372) --> - <skip /> - <!-- no translation found for label_view (6304565553218192990) --> - <skip /> - <!-- no translation found for always_use_device (1450287437017315906) --> - <skip /> - <!-- no translation found for always_use_accessory (1210954576979621596) --> - <skip /> + <string name="usb_device_permission_prompt" msgid="3816016361969816903">"Cho phép ứng dụng <xliff:g id="APPLICATION">%1$s</xliff:g> truy cập thiết bị USB?"</string> + <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"Cho phép ứng dụng <xliff:g id="APPLICATION">%1$s</xliff:g> truy cập phụ kiện USB?"</string> + <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Mở <xliff:g id="ACTIVITY">%1$s</xliff:g> khi thiết bị USB này được kết nối?"</string> + <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Mở <xliff:g id="ACTIVITY">%1$s</xliff:g> khi phụ kiện USB này được kết nối?"</string> + <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Không có ứng dụng được cài đặt nào hoạt động với phụ kiện USB này. Tìm hiểu thêm về phụ kiện này tại <xliff:g id="URL">%1$s</xliff:g>"</string> + <string name="title_usb_accessory" msgid="4966265263465181372">"Phụ kiện USB"</string> + <string name="label_view" msgid="6304565553218192990">"Xem"</string> + <string name="always_use_device" msgid="1450287437017315906">"Sử dụng theo mặc định cho thiết bị USB này"</string> + <string name="always_use_accessory" msgid="1210954576979621596">"Sử dụng theo mặc định cho phụ kiện USB này"</string> </resources> diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml index baae9e1b0fe8..099ed6bf285e 100644 --- a/packages/SystemUI/res/values-zh-rCN/strings.xml +++ b/packages/SystemUI/res/values-zh-rCN/strings.xml @@ -44,22 +44,13 @@ <string name="bluetooth_tethered" msgid="7094101612161133267">"蓝牙已绑定"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"配置输入法"</string> <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"使用物理键盘"</string> - <!-- no translation found for usb_device_permission_prompt (3816016361969816903) --> - <skip /> - <!-- no translation found for usb_accessory_permission_prompt (6888598803988889959) --> - <skip /> - <!-- no translation found for usb_device_confirm_prompt (5161205258635253206) --> - <skip /> - <!-- no translation found for usb_accessory_confirm_prompt (3808984931830229888) --> - <skip /> - <!-- no translation found for usb_accessory_uri_prompt (6332150684964235705) --> - <skip /> - <!-- no translation found for title_usb_accessory (4966265263465181372) --> - <skip /> - <!-- no translation found for label_view (6304565553218192990) --> - <skip /> - <!-- no translation found for always_use_device (1450287437017315906) --> - <skip /> - <!-- no translation found for always_use_accessory (1210954576979621596) --> - <skip /> + <string name="usb_device_permission_prompt" msgid="3816016361969816903">"允许应用程序<xliff:g id="APPLICATION">%1$s</xliff:g>访问 USB 设备吗?"</string> + <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"允许应用程序<xliff:g id="APPLICATION">%1$s</xliff:g>访问 USB 配件吗?"</string> + <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"要在连接此 USB 设备时打开<xliff:g id="ACTIVITY">%1$s</xliff:g>吗?"</string> + <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"要在连接此 USB 配件时打开<xliff:g id="ACTIVITY">%1$s</xliff:g>吗?"</string> + <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"未安装此 USB 配件适用的应用程序。要了解关于此配件的详情,请访问:<xliff:g id="URL">%1$s</xliff:g>"</string> + <string name="title_usb_accessory" msgid="4966265263465181372">"USB 配件"</string> + <string name="label_view" msgid="6304565553218192990">"查看"</string> + <string name="always_use_device" msgid="1450287437017315906">"默认情况下用于该 USB 设备"</string> + <string name="always_use_accessory" msgid="1210954576979621596">"默认情况下用于该 USB 配件"</string> </resources> diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml index 0d83d4410257..2885adff9bf4 100644 --- a/packages/SystemUI/res/values-zh-rTW/strings.xml +++ b/packages/SystemUI/res/values-zh-rTW/strings.xml @@ -44,22 +44,13 @@ <string name="bluetooth_tethered" msgid="7094101612161133267">"已透過藍牙進行網際網路共用"</string> <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"設定輸入方式"</string> <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"使用實體鍵盤"</string> - <!-- no translation found for usb_device_permission_prompt (3816016361969816903) --> - <skip /> - <!-- no translation found for usb_accessory_permission_prompt (6888598803988889959) --> - <skip /> - <!-- no translation found for usb_device_confirm_prompt (5161205258635253206) --> - <skip /> - <!-- no translation found for usb_accessory_confirm_prompt (3808984931830229888) --> - <skip /> - <!-- no translation found for usb_accessory_uri_prompt (6332150684964235705) --> - <skip /> - <!-- no translation found for title_usb_accessory (4966265263465181372) --> - <skip /> - <!-- no translation found for label_view (6304565553218192990) --> - <skip /> - <!-- no translation found for always_use_device (1450287437017315906) --> - <skip /> - <!-- no translation found for always_use_accessory (1210954576979621596) --> - <skip /> + <string name="usb_device_permission_prompt" msgid="3816016361969816903">"允許 <xliff:g id="APPLICATION">%1$s</xliff:g> 應用程式存取 USB 裝置嗎?"</string> + <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"允許 <xliff:g id="APPLICATION">%1$s</xliff:g> 應用程式存取 USB 配件嗎?"</string> + <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"連接這個 USB 裝置時啟用 <xliff:g id="ACTIVITY">%1$s</xliff:g> 嗎?"</string> + <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"連接這個 USB 配件時啟用 <xliff:g id="ACTIVITY">%1$s</xliff:g> 嗎?"</string> + <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"已安裝的應用程式均無法存取這類 USB 配件,如要進一步瞭解這個配件,請造訪 <xliff:g id="URL">%1$s</xliff:g>"</string> + <string name="title_usb_accessory" msgid="4966265263465181372">"USB 配件"</string> + <string name="label_view" msgid="6304565553218192990">"查看"</string> + <string name="always_use_device" msgid="1450287437017315906">"預設用於這個 USB 裝置"</string> + <string name="always_use_accessory" msgid="1210954576979621596">"預設用於這個 USB 配件"</string> </resources> diff --git a/packages/TtsService/jni/android_tts_SynthProxy.cpp b/packages/TtsService/jni/android_tts_SynthProxy.cpp index 27d1fc0aeca0..e00fa852f41a 100644 --- a/packages/TtsService/jni/android_tts_SynthProxy.cpp +++ b/packages/TtsService/jni/android_tts_SynthProxy.cpp @@ -53,7 +53,6 @@ using namespace android; // ---------------------------------------------------------------------------- struct fields_t { jfieldID synthProxyFieldJniData; - jclass synthProxyClass; jmethodID synthProxyMethodPost; }; @@ -1043,7 +1042,6 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved) goto bail; } - javaTTSFields.synthProxyClass = clazz; javaTTSFields.synthProxyFieldJniData = NULL; javaTTSFields.synthProxyMethodPost = NULL; diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp index 2702242f8d32..e27a10ff5eef 100644 --- a/services/audioflinger/AudioFlinger.cpp +++ b/services/audioflinger/AudioFlinger.cpp @@ -31,6 +31,7 @@ #include <binder/IPCThreadState.h> #include <utils/String16.h> #include <utils/threads.h> +#include <utils/Atomic.h> #include <cutils/properties.h> @@ -1738,10 +1739,7 @@ uint32_t AudioFlinger::MixerThread::prepareTracks_l(const SortedVector< wp<Track LOGV("BUFFER TIMEOUT: remove(%d) from active list on thread %p", track->name(), this); tracksToRemove->add(track); // indicate to client process that the track was disabled because of underrun - { - AutoMutex _l(cblk->lock); - cblk->flags |= CBLK_DISABLED_ON; - } + android_atomic_or(CBLK_DISABLED_ON, &cblk->flags); } else if (mixerStatus != MIXER_TRACKS_READY) { mixerStatus = MIXER_TRACKS_ENABLED; } @@ -1790,8 +1788,7 @@ void AudioFlinger::MixerThread::invalidateTracks(int streamType) for (size_t i = 0; i < size; i++) { sp<Track> t = mTracks[i]; if (t->type() == streamType) { - AutoMutex _lcblk(t->mCblk->lock); - t->mCblk->flags |= CBLK_INVALID_ON; + android_atomic_or(CBLK_INVALID_ON, &t->mCblk->flags); t->mCblk->cv.signal(); } } @@ -2950,9 +2947,8 @@ bool AudioFlinger::PlaybackThread::Track::isReady() const { if (mCblk->framesReady() >= mCblk->frameCount || (mCblk->flags & CBLK_FORCEREADY_MSK)) { - AutoMutex _l(mCblk->lock); mFillingUpStatus = FS_FILLED; - mCblk->flags &= ~CBLK_FORCEREADY_MSK; + android_atomic_and(~CBLK_FORCEREADY_MSK, &mCblk->flags); return true; } return false; @@ -3066,26 +3062,25 @@ void AudioFlinger::PlaybackThread::Track::flush() // STOPPED state mState = STOPPED; - // NOTE: reset() will reset cblk->user and cblk->server with - // the risk that at the same time, the AudioMixer is trying to read - // data. In this case, getNextBuffer() would return a NULL pointer - // as audio buffer => the AudioMixer code MUST always test that pointer - // returned by getNextBuffer() is not NULL! - reset(); + // do not reset the track if it is still in the process of being stopped or paused. + // this will be done by prepareTracks_l() when the track is stopped. + PlaybackThread *playbackThread = (PlaybackThread *)thread.get(); + if (playbackThread->mActiveTracks.indexOf(this) < 0) { + reset(); + } } } void AudioFlinger::PlaybackThread::Track::reset() { - AutoMutex _l(mCblk->lock); // Do not reset twice to avoid discarding data written just after a flush and before // the audioflinger thread detects the track is stopped. if (!mResetDone) { TrackBase::reset(); // Force underrun condition to avoid false underrun callback until first data is // written to buffer - mCblk->flags |= CBLK_UNDERRUN_ON; - mCblk->flags &= ~CBLK_FORCEREADY_MSK; + android_atomic_and(~CBLK_FORCEREADY_MSK, &mCblk->flags); + android_atomic_or(CBLK_UNDERRUN_ON, &mCblk->flags); mFillingUpStatus = FS_FILLING; mResetDone = true; } @@ -3211,13 +3206,10 @@ void AudioFlinger::RecordThread::RecordTrack::stop() if (thread != 0) { RecordThread *recordThread = (RecordThread *)thread.get(); recordThread->stop(this); - { - AutoMutex _l(mCblk->lock); - TrackBase::reset(); - // Force overerrun condition to avoid false overrun callback until first data is - // read from buffer - mCblk->flags |= CBLK_UNDERRUN_ON; - } + TrackBase::reset(); + // Force overerrun condition to avoid false overrun callback until first data is + // read from buffer + android_atomic_or(CBLK_UNDERRUN_ON, &mCblk->flags); } } diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java index ea38fbbeea41..6e7633130462 100644 --- a/services/java/com/android/server/BackupManagerService.java +++ b/services/java/com/android/server/BackupManagerService.java @@ -760,15 +760,15 @@ class BackupManagerService extends IBackupManager.Stub { sf.delete(); } } + } - // Enqueue a new backup of every participant - int N = mBackupParticipants.size(); - for (int i=0; i<N; i++) { - int uid = mBackupParticipants.keyAt(i); - HashSet<ApplicationInfo> participants = mBackupParticipants.valueAt(i); - for (ApplicationInfo app: participants) { - dataChangedImpl(app.packageName); - } + // Enqueue a new backup of every participant + int N = mBackupParticipants.size(); + for (int i=0; i<N; i++) { + int uid = mBackupParticipants.keyAt(i); + HashSet<ApplicationInfo> participants = mBackupParticipants.valueAt(i); + for (ApplicationInfo app: participants) { + dataChangedImpl(app.packageName); } } } diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java index d407268ee821..c18ccc8c1548 100644 --- a/services/java/com/android/server/MountService.java +++ b/services/java/com/android/server/MountService.java @@ -65,6 +65,7 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.Set; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; @@ -148,7 +149,8 @@ class MountService extends IMountService.Stub implements INativeDaemonConnectorC private Context mContext; private NativeDaemonConnector mConnector; - private String mLegacyState = Environment.MEDIA_REMOVED; + private final HashMap<String, String> mVolumeStates = new HashMap<String, String>(); + private String mExternalStoragePath; private PackageManagerService mPms; private boolean mUmsEnabling; // Used as a lock for methods that register/unregister listeners. @@ -446,29 +448,54 @@ class MountService extends IMountService.Stub implements INativeDaemonConnectorC * to make the media scanner run. */ if ("simulator".equals(SystemProperties.get("ro.product.device"))) { - notifyVolumeStateChange(null, "/sdcard", VolumeState.NoMedia, VolumeState.Mounted); + notifyVolumeStateChange(null, "/sdcard", VolumeState.NoMedia, + VolumeState.Mounted); return; } new Thread() { @Override public void run() { try { - String path = Environment.getExternalStorageDirectory().getPath(); - String state = getVolumeState(path); + // it is not safe to call vold with mVolumeStates locked + // so we make a copy of the paths and states and process them + // outside the lock + String[] paths, states; + int count; + synchronized (mVolumeStates) { + Set<String> keys = mVolumeStates.keySet(); + count = keys.size(); + paths = (String[])keys.toArray(new String[count]); + states = new String[count]; + for (int i = 0; i < count; i++) { + states[i] = mVolumeStates.get(paths[i]); + } + } - if (mEmulateExternalStorage) { - notifyVolumeStateChange(null, path, VolumeState.NoMedia, VolumeState.Mounted); - } else if (state.equals(Environment.MEDIA_UNMOUNTED)) { - int rc = doMountVolume(path); - if (rc != StorageResultCode.OperationSucceeded) { - Slog.e(TAG, String.format("Boot-time mount failed (%d)", rc)); + for (int i = 0; i < count; i++) { + String path = paths[i]; + String state = states[i]; + + if (state.equals(Environment.MEDIA_UNMOUNTED)) { + int rc = doMountVolume(path); + if (rc != StorageResultCode.OperationSucceeded) { + Slog.e(TAG, String.format("Boot-time mount failed (%d)", + rc)); + } + } else if (state.equals(Environment.MEDIA_SHARED)) { + /* + * Bootstrap UMS enabled state since vold indicates + * the volume is shared (runtime restart while ums enabled) + */ + notifyVolumeStateChange(null, path, VolumeState.NoMedia, + VolumeState.Shared); } - } else if (state.equals(Environment.MEDIA_SHARED)) { - /* - * Bootstrap UMS enabled state since vold indicates - * the volume is shared (runtime restart while ums enabled) - */ - notifyVolumeStateChange(null, path, VolumeState.NoMedia, VolumeState.Shared); + } + + /* notify external storage has mounted to trigger media scanner */ + if (mEmulateExternalStorage) { + notifyVolumeStateChange(null, + Environment.getExternalStorageDirectory().getPath(), + VolumeState.NoMedia, VolumeState.Mounted); } /* @@ -519,35 +546,36 @@ class MountService extends IMountService.Stub implements INativeDaemonConnectorC } private void updatePublicVolumeState(String path, String state) { - if (!path.equals(Environment.getExternalStorageDirectory().getPath())) { - Slog.w(TAG, "Multiple volumes not currently supported"); - return; + String oldState; + synchronized(mVolumeStates) { + oldState = mVolumeStates.put(path, state); } - - if (mLegacyState.equals(state)) { - Slog.w(TAG, String.format("Duplicate state transition (%s -> %s)", mLegacyState, state)); + if (state.equals(oldState)) { + Slog.w(TAG, String.format("Duplicate state transition (%s -> %s) for %s", + state, state, path)); return; } - // Update state on PackageManager, but only of real events - if (!mEmulateExternalStorage) { - if (Environment.MEDIA_UNMOUNTED.equals(state)) { - mPms.updateExternalMediaStatus(false, false); - /* - * Some OBBs might have been unmounted when this volume was - * unmounted, so send a message to the handler to let it know to - * remove those from the list of mounted OBBS. - */ - mObbActionHandler.sendMessage(mObbActionHandler.obtainMessage(OBB_FLUSH_MOUNT_STATE, - path)); - } else if (Environment.MEDIA_MOUNTED.equals(state)) { - mPms.updateExternalMediaStatus(true, false); - } - } + Slog.d(TAG, "volume state changed for " + path + " (" + oldState + " -> " + state + ")"); - String oldState = mLegacyState; - mLegacyState = state; + if (path.equals(mExternalStoragePath)) { + // Update state on PackageManager, but only of real events + if (!mEmulateExternalStorage) { + if (Environment.MEDIA_UNMOUNTED.equals(state)) { + mPms.updateExternalMediaStatus(false, false); + /* + * Some OBBs might have been unmounted when this volume was + * unmounted, so send a message to the handler to let it know to + * remove those from the list of mounted OBBS. + */ + mObbActionHandler.sendMessage(mObbActionHandler.obtainMessage( + OBB_FLUSH_MOUNT_STATE, path)); + } else if (Environment.MEDIA_MOUNTED.equals(state)) { + mPms.updateExternalMediaStatus(true, false); + } + } + } synchronized (mListeners) { for (int i = mListeners.size() -1; i >= 0; i--) { MountServiceBinderListener bl = mListeners.get(i); @@ -578,20 +606,15 @@ class MountService extends IMountService.Stub implements INativeDaemonConnectorC /** * Determine media state and UMS detection status */ - String path = Environment.getExternalStorageDirectory().getPath(); - String state = Environment.MEDIA_REMOVED; - try { String[] vols = mConnector.doListCommand( "volume list", VoldResponseCode.VolumeListResult); for (String volstr : vols) { String[] tok = volstr.split(" "); // FMT: <label> <mountpoint> <state> - if (!tok[1].equals(path)) { - Slog.w(TAG, String.format( - "Skipping unknown volume '%s'",tok[1])); - continue; - } + String path = tok[1]; + String state = Environment.MEDIA_REMOVED; + int st = Integer.parseInt(tok[2]); if (st == VolumeState.NoMedia) { state = Environment.MEDIA_REMOVED; @@ -606,14 +629,15 @@ class MountService extends IMountService.Stub implements INativeDaemonConnectorC } else { throw new Exception(String.format("Unexpected state %d", st)); } - } - if (state != null) { - if (DEBUG_EVENTS) Slog.i(TAG, "Updating valid state " + state); - updatePublicVolumeState(path, state); + + if (state != null) { + if (DEBUG_EVENTS) Slog.i(TAG, "Updating valid state " + state); + updatePublicVolumeState(path, state); + } } } catch (Exception e) { Slog.e(TAG, "Error processing initial volume state", e); - updatePublicVolumeState(path, Environment.MEDIA_REMOVED); + updatePublicVolumeState(mExternalStoragePath, Environment.MEDIA_REMOVED); } try { @@ -1055,11 +1079,12 @@ class MountService extends IMountService.Stub implements INativeDaemonConnectorC public MountService(Context context) { mContext = context; + mExternalStoragePath = Environment.getExternalStorageDirectory().getPath(); mEmulateExternalStorage = context.getResources().getBoolean( com.android.internal.R.bool.config_emulateExternalStorage); if (mEmulateExternalStorage) { Slog.d(TAG, "using emulated external storage"); - mLegacyState = Environment.MEDIA_MOUNTED; + mVolumeStates.put(mExternalStoragePath, Environment.MEDIA_MOUNTED); } // XXX: This will go away soon in favor of IMountServiceObserver @@ -1127,54 +1152,56 @@ class MountService extends IMountService.Stub implements INativeDaemonConnectorC validatePermission(android.Manifest.permission.SHUTDOWN); Slog.i(TAG, "Shutting down"); - - String path = Environment.getExternalStorageDirectory().getPath(); - String state = getVolumeState(path); - - if (state.equals(Environment.MEDIA_SHARED)) { - /* - * If the media is currently shared, unshare it. - * XXX: This is still dangerous!. We should not - * be rebooting at *all* if UMS is enabled, since - * the UMS host could have dirty FAT cache entries - * yet to flush. - */ - setUsbMassStorageEnabled(false); - } else if (state.equals(Environment.MEDIA_CHECKING)) { - /* - * If the media is being checked, then we need to wait for - * it to complete before being able to proceed. - */ - // XXX: @hackbod - Should we disable the ANR timer here? - int retries = 30; - while (state.equals(Environment.MEDIA_CHECKING) && (retries-- >=0)) { - try { - Thread.sleep(1000); - } catch (InterruptedException iex) { - Slog.e(TAG, "Interrupted while waiting for media", iex); - break; + synchronized (mVolumeStates) { + for (String path : mVolumeStates.keySet()) { + String state = mVolumeStates.get(path); + + if (state.equals(Environment.MEDIA_SHARED)) { + /* + * If the media is currently shared, unshare it. + * XXX: This is still dangerous!. We should not + * be rebooting at *all* if UMS is enabled, since + * the UMS host could have dirty FAT cache entries + * yet to flush. + */ + setUsbMassStorageEnabled(false); + } else if (state.equals(Environment.MEDIA_CHECKING)) { + /* + * If the media is being checked, then we need to wait for + * it to complete before being able to proceed. + */ + // XXX: @hackbod - Should we disable the ANR timer here? + int retries = 30; + while (state.equals(Environment.MEDIA_CHECKING) && (retries-- >=0)) { + try { + Thread.sleep(1000); + } catch (InterruptedException iex) { + Slog.e(TAG, "Interrupted while waiting for media", iex); + break; + } + state = Environment.getExternalStorageState(); + } + if (retries == 0) { + Slog.e(TAG, "Timed out waiting for media to check"); + } } - state = Environment.getExternalStorageState(); - } - if (retries == 0) { - Slog.e(TAG, "Timed out waiting for media to check"); - } - } - if (state.equals(Environment.MEDIA_MOUNTED)) { - // Post a unmount message. - ShutdownCallBack ucb = new ShutdownCallBack(path, observer); - mHandler.sendMessage(mHandler.obtainMessage(H_UNMOUNT_PM_UPDATE, ucb)); - } else if (observer != null) { - /* - * Observer is waiting for onShutDownComplete when we are done. - * Since nothing will be done send notification directly so shutdown - * sequence can continue. - */ - try { - observer.onShutDownComplete(StorageResultCode.OperationSucceeded); - } catch (RemoteException e) { - Slog.w(TAG, "RemoteException when shutting down"); + if (state.equals(Environment.MEDIA_MOUNTED)) { + // Post a unmount message. + ShutdownCallBack ucb = new ShutdownCallBack(path, observer); + mHandler.sendMessage(mHandler.obtainMessage(H_UNMOUNT_PM_UPDATE, ucb)); + } else if (observer != null) { + /* + * Observer is waiting for onShutDownComplete when we are done. + * Since nothing will be done send notification directly so shutdown + * sequence can continue. + */ + try { + observer.onShutDownComplete(StorageResultCode.OperationSucceeded); + } catch (RemoteException e) { + Slog.w(TAG, "RemoteException when shutting down"); + } + } } } } @@ -1246,16 +1273,15 @@ class MountService extends IMountService.Stub implements INativeDaemonConnectorC * @return state of the volume at the specified mount point */ public String getVolumeState(String mountPoint) { - /* - * XXX: Until we have multiple volume discovery, just hardwire - * this to /sdcard - */ - if (!mountPoint.equals(Environment.getExternalStorageDirectory().getPath())) { - Slog.w(TAG, "getVolumeState(" + mountPoint + "): Unknown volume"); - throw new IllegalArgumentException(); - } + synchronized (mVolumeStates) { + String state = mVolumeStates.get(mountPoint); + if (state == null) { + Slog.w(TAG, "getVolumeState(" + mountPoint + "): Unknown volume"); + throw new IllegalArgumentException(); + } - return mLegacyState; + return state; + } } public boolean isExternalStorageEmulated() { @@ -1730,6 +1756,18 @@ class MountService extends IMountService.Stub implements INativeDaemonConnectorC } } + public String[] getVolumeList() { + synchronized(mVolumeStates) { + Set<String> volumes = mVolumeStates.keySet(); + String[] result = new String[volumes.size()]; + int i = 0; + for (String volume : volumes) { + result[i++] = volume; + } + return result; + } + } + private void addObbStateLocked(ObbState obbState) throws RemoteException { final IBinder binder = obbState.getBinder(); List<ObbState> obbStates = mObbMounts.get(binder); diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java index 915b679a041f..a2d10dfa70b4 100644 --- a/services/java/com/android/server/WifiService.java +++ b/services/java/com/android/server/WifiService.java @@ -937,7 +937,7 @@ public class WifiService extends IWifiManager.Stub { evaluateTrafficStatsPolling(); mWifiStateMachine.enableRssiPolling(true); if (mBackgroundScanSupported) { - mWifiStateMachine.enableBackgroundScan(false); + mWifiStateMachine.enableBackgroundScanCommand(false); } mWifiStateMachine.enableAllNetworks(); updateWifiState(); @@ -949,7 +949,7 @@ public class WifiService extends IWifiManager.Stub { evaluateTrafficStatsPolling(); mWifiStateMachine.enableRssiPolling(false); if (mBackgroundScanSupported) { - mWifiStateMachine.enableBackgroundScan(true); + mWifiStateMachine.enableBackgroundScanCommand(true); } /* * Set a timer to put Wi-Fi to sleep, but only if the screen is off diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java index 79c45187ed71..e2874f816dc8 100644 --- a/services/java/com/android/server/wm/WindowManagerService.java +++ b/services/java/com/android/server/wm/WindowManagerService.java @@ -5453,6 +5453,9 @@ public class WindowManagerService extends IWindowManager.Stub mDisplay.getMetrics(dm); CompatibilityInfo.updateCompatibleScreenFrame(dm, orientation, mCompatibleScreenFrame); + config.screenWidthDp = (int)(dm.widthPixels / dm.density); + config.screenHeightDp = (int)(dm.heightPixels / dm.density); + if (mScreenLayout == Configuration.SCREENLAYOUT_SIZE_UNDEFINED) { // Note we only do this once because at this point we don't // expect the screen to change in this way at runtime, and want diff --git a/services/jni/com_android_server_UsbService.cpp b/services/jni/com_android_server_UsbService.cpp index 6aeede2eddde..00ee7e30002c 100644 --- a/services/jni/com_android_server_UsbService.cpp +++ b/services/jni/com_android_server_UsbService.cpp @@ -260,7 +260,7 @@ int register_android_server_UsbService(JNIEnv *env) return -1; } - clazz = env->FindClass("java/io/FileDescriptor"); + clazz = env->FindClass("java/io/FileDescriptor"); LOG_FATAL_IF(clazz == NULL, "Unable to find class java.io.FileDescriptor"); gFileDescriptorOffsets.mClass = (jclass) env->NewGlobalRef(clazz); gFileDescriptorOffsets.mConstructor = env->GetMethodID(clazz, "<init>", "()V"); @@ -268,7 +268,7 @@ int register_android_server_UsbService(JNIEnv *env) LOG_FATAL_IF(gFileDescriptorOffsets.mDescriptor == NULL, "Unable to find descriptor field in java.io.FileDescriptor"); - clazz = env->FindClass("android/os/ParcelFileDescriptor"); + clazz = env->FindClass("android/os/ParcelFileDescriptor"); LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.ParcelFileDescriptor"); gParcelFileDescriptorOffsets.mClass = (jclass) env->NewGlobalRef(clazz); gParcelFileDescriptorOffsets.mConstructor = env->GetMethodID(clazz, "<init>", "(Ljava/io/FileDescriptor;)V"); diff --git a/tools/aapt/AaptAssets.cpp b/tools/aapt/AaptAssets.cpp index 2b2ec7b3e9a7..a2271d9a357f 100644 --- a/tools/aapt/AaptAssets.cpp +++ b/tools/aapt/AaptAssets.cpp @@ -156,6 +156,20 @@ AaptGroupEntry::parseNamePart(const String8& part, int* axis, uint32_t* value) return 0; } + // screen dp width + if (getScreenWidthDpName(part.string(), &config)) { + *axis = AXIS_SCREENWIDTHDP; + *value = config.screenWidthDp; + return 0; + } + + // screen dp height + if (getScreenHeightDpName(part.string(), &config)) { + *axis = AXIS_SCREENHEIGHTDP; + *value = config.screenHeightDp; + return 0; + } + // orientation if (getOrientationName(part.string(), &config)) { *axis = AXIS_ORIENTATION; @@ -243,7 +257,7 @@ AaptGroupEntry::initFromDirName(const char* dir, String8* resType) String8 mcc, mnc, loc, layoutsize, layoutlong, orient, den; String8 touch, key, keysHidden, nav, navHidden, size, vers; - String8 uiModeType, uiModeNight; + String8 uiModeType, uiModeNight, widthdp, heightdp; const char *p = dir; const char *q; @@ -354,6 +368,30 @@ AaptGroupEntry::initFromDirName(const char* dir, String8* resType) //printf("not screen layout long: %s\n", part.string()); } + if (getScreenWidthDpName(part.string())) { + widthdp = part; + + index++; + if (index == N) { + goto success; + } + part = parts[index]; + } else { + //printf("not screen width dp: %s\n", part.string()); + } + + if (getScreenHeightDpName(part.string())) { + heightdp = part; + + index++; + if (index == N) { + goto success; + } + part = parts[index]; + } else { + //printf("not screen height dp: %s\n", part.string()); + } + // orientation if (getOrientationName(part.string())) { orient = part; @@ -503,6 +541,8 @@ success: this->locale = loc; this->screenLayoutSize = layoutsize; this->screenLayoutLong = layoutlong; + this->screenWidthDp = widthdp; + this->screenHeightDp = heightdp; this->orientation = orient; this->uiModeType = uiModeType; this->uiModeNight = uiModeNight; @@ -534,6 +574,10 @@ AaptGroupEntry::toString() const s += ","; s += screenLayoutLong; s += ","; + s += screenWidthDp; + s += ","; + s += screenHeightDp; + s += ","; s += this->orientation; s += ","; s += uiModeType; @@ -582,6 +626,14 @@ AaptGroupEntry::toDirName(const String8& resType) const s += "-"; s += screenLayoutLong; } + if (this->screenWidthDp != "") { + s += "-"; + s += screenWidthDp; + } + if (this->screenHeightDp != "") { + s += "-"; + s += screenHeightDp; + } if (this->orientation != "") { s += "-"; s += orientation; @@ -1039,8 +1091,7 @@ bool AaptGroupEntry::getNavigationName(const char* name, return false; } -bool AaptGroupEntry::getScreenSizeName(const char* name, - ResTable_config* out) +bool AaptGroupEntry::getScreenSizeName(const char* name, ResTable_config* out) { if (strcmp(name, kWildcardName) == 0) { if (out) { @@ -1075,8 +1126,53 @@ bool AaptGroupEntry::getScreenSizeName(const char* name, return true; } -bool AaptGroupEntry::getVersionName(const char* name, - ResTable_config* out) +bool AaptGroupEntry::getScreenWidthDpName(const char* name, ResTable_config* out) +{ + if (strcmp(name, kWildcardName) == 0) { + if (out) { + out->screenWidthDp = out->SCREENWIDTH_ANY; + } + return true; + } + + if (*name != 'w') return false; + name++; + const char* x = name; + while (*x >= '0' && *x <= '9') x++; + if (x == name || x[0] != 'd' || x[1] != 'p' || x[2] != 0) return false; + String8 xName(name, x-name); + + if (out) { + out->screenWidthDp = (uint16_t)atoi(xName.string()); + } + + return true; +} + +bool AaptGroupEntry::getScreenHeightDpName(const char* name, ResTable_config* out) +{ + if (strcmp(name, kWildcardName) == 0) { + if (out) { + out->screenHeightDp = out->SCREENWIDTH_ANY; + } + return true; + } + + if (*name != 'h') return false; + name++; + const char* x = name; + while (*x >= '0' && *x <= '9') x++; + if (x == name || x[0] != 'd' || x[1] != 'p' || x[2] != 0) return false; + String8 xName(name, x-name); + + if (out) { + out->screenHeightDp = (uint16_t)atoi(xName.string()); + } + + return true; +} + +bool AaptGroupEntry::getVersionName(const char* name, ResTable_config* out) { if (strcmp(name, kWildcardName) == 0) { if (out) { @@ -1112,6 +1208,8 @@ int AaptGroupEntry::compare(const AaptGroupEntry& o) const if (v == 0) v = vendor.compare(o.vendor); if (v == 0) v = screenLayoutSize.compare(o.screenLayoutSize); if (v == 0) v = screenLayoutLong.compare(o.screenLayoutLong); + if (v == 0) v = screenWidthDp.compare(o.screenWidthDp); + if (v == 0) v = screenHeightDp.compare(o.screenHeightDp); if (v == 0) v = orientation.compare(o.orientation); if (v == 0) v = uiModeType.compare(o.uiModeType); if (v == 0) v = uiModeNight.compare(o.uiModeNight); @@ -1135,6 +1233,8 @@ ResTable_config AaptGroupEntry::toParams() const getLocaleName(locale.string(), ¶ms); getScreenLayoutSizeName(screenLayoutSize.string(), ¶ms); getScreenLayoutLongName(screenLayoutLong.string(), ¶ms); + getScreenWidthDpName(screenWidthDp.string(), ¶ms); + getScreenHeightDpName(screenHeightDp.string(), ¶ms); getOrientationName(orientation.string(), ¶ms); getUiModeTypeName(uiModeType.string(), ¶ms); getUiModeNightName(uiModeNight.string(), ¶ms); @@ -1149,7 +1249,10 @@ ResTable_config AaptGroupEntry::toParams() const // Fix up version number based on specified parameters. int minSdk = 0; - if ((params.uiMode&ResTable_config::MASK_UI_MODE_TYPE) + if (params.screenWidthDp != ResTable_config::SCREENWIDTH_ANY + || params.screenHeightDp != ResTable_config::SCREENHEIGHT_ANY) { + minSdk = SDK_ICS; + } else if ((params.uiMode&ResTable_config::MASK_UI_MODE_TYPE) != ResTable_config::UI_MODE_TYPE_ANY || (params.uiMode&ResTable_config::MASK_UI_MODE_NIGHT) != ResTable_config::UI_MODE_NIGHT_ANY) { diff --git a/tools/aapt/AaptAssets.h b/tools/aapt/AaptAssets.h index eeb00c0be1ba..e5afd1bca1c1 100644 --- a/tools/aapt/AaptAssets.h +++ b/tools/aapt/AaptAssets.h @@ -42,6 +42,8 @@ enum { AXIS_NAVHIDDEN, AXIS_NAVIGATION, AXIS_SCREENSIZE, + AXIS_SCREENWIDTHDP, + AXIS_SCREENHEIGHTDP, AXIS_VERSION }; @@ -52,6 +54,7 @@ enum { SDK_ECLAIR_0_1 = 6, SDK_MR1 = 7, SDK_FROYO = 8, + SDK_ICS = 13, }; /** @@ -71,6 +74,8 @@ public: String8 vendor; String8 screenLayoutSize; String8 screenLayoutLong; + String8 screenWidthDp; + String8 screenHeightDp; String8 orientation; String8 uiModeType; String8 uiModeNight; @@ -102,6 +107,8 @@ public: static bool getNavigationName(const char* name, ResTable_config* out = NULL); static bool getNavHiddenName(const char* name, ResTable_config* out = NULL); static bool getScreenSizeName(const char* name, ResTable_config* out = NULL); + static bool getScreenWidthDpName(const char* name, ResTable_config* out = NULL); + static bool getScreenHeightDpName(const char* name, ResTable_config* out = NULL); static bool getVersionName(const char* name, ResTable_config* out = NULL); int compare(const AaptGroupEntry& o) const; diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp index 10815a1e04ec..3dcc09399850 100644 --- a/tools/aapt/ResourceTable.cpp +++ b/tools/aapt/ResourceTable.cpp @@ -2607,6 +2607,12 @@ ResourceFilter::match(const ResTable_config& config) const if (!match(AXIS_SCREENSIZE, config.screenSize)) { return false; } + if (!match(AXIS_SCREENWIDTHDP, config.screenWidthDp)) { + return false; + } + if (!match(AXIS_SCREENHEIGHTDP, config.screenHeightDp)) { + return false; + } if (!match(AXIS_SCREENLAYOUTSIZE, config.screenLayout&ResTable_config::MASK_SCREENSIZE)) { return false; } @@ -2803,7 +2809,7 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp<AaptFile>& dest) ConfigDescription config = t->getUniqueConfigs().itemAt(ci); NOISY(printf("Writing config %d config: imsi:%d/%d lang:%c%c cnt:%c%c " - "orien:%d ui:%d touch:%d density:%d key:%d inp:%d nav:%d w:%d h:%d\n", + "orien:%d ui:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d %ddp x %ddp\n", ti+1, config.mcc, config.mnc, config.language[0] ? config.language[0] : '-', @@ -2818,7 +2824,9 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp<AaptFile>& dest) config.inputFlags, config.navigation, config.screenWidth, - config.screenHeight)); + config.screenHeight, + config.screenWidthDp, + config.screenHeightDp)); if (filterable && !filter.match(config)) { continue; @@ -2841,7 +2849,7 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp<AaptFile>& dest) tHeader->entriesStart = htodl(typeSize); tHeader->config = config; NOISY(printf("Writing type %d config: imsi:%d/%d lang:%c%c cnt:%c%c " - "orien:%d ui:%d touch:%d density:%d key:%d inp:%d nav:%d w:%d h:%d\n", + "orien:%d ui:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d %ddp x %ddp\n", ti+1, tHeader->config.mcc, tHeader->config.mnc, tHeader->config.language[0] ? tHeader->config.language[0] : '-', @@ -2856,7 +2864,9 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp<AaptFile>& dest) tHeader->config.inputFlags, tHeader->config.navigation, tHeader->config.screenWidth, - tHeader->config.screenHeight)); + tHeader->config.screenHeight, + tHeader->config.screenWidthDp, + tHeader->config.screenHeightDp)); tHeader->config.swapHtoD(); // Build the entries inside of this type. @@ -3438,7 +3448,7 @@ sp<ResourceTable::Entry> ResourceTable::Type::getEntry(const String16& entry, if (e == NULL) { if (config != NULL) { NOISY(printf("New entry at %s:%d: imsi:%d/%d lang:%c%c cnt:%c%c " - "orien:%d touch:%d density:%d key:%d inp:%d nav:%d w:%d h:%d\n", + "orien:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d %ddp x %ddp\n", sourcePos.file.string(), sourcePos.line, config->mcc, config->mnc, config->language[0] ? config->language[0] : '-', @@ -3452,7 +3462,9 @@ sp<ResourceTable::Entry> ResourceTable::Type::getEntry(const String16& entry, config->inputFlags, config->navigation, config->screenWidth, - config->screenHeight)); + config->screenHeight, + config->screenWidthDp, + config->screenHeightDp)); } else { NOISY(printf("New entry at %s:%d: NULL config\n", sourcePos.file.string(), sourcePos.line)); diff --git a/voip/jni/rtp/AudioGroup.cpp b/voip/jni/rtp/AudioGroup.cpp index c031eeed96bb..41fedcee1f4c 100644 --- a/voip/jni/rtp/AudioGroup.cpp +++ b/voip/jni/rtp/AudioGroup.cpp @@ -30,6 +30,7 @@ #define LOG_TAG "AudioGroup" #include <cutils/atomic.h> +#include <cutils/properties.h> #include <utils/Log.h> #include <utils/Errors.h> #include <utils/RefBase.h> @@ -619,6 +620,14 @@ bool AudioGroup::setMode(int mode) if (mode < 0 || mode > LAST_MODE) { return false; } + //FIXME: temporary code to overcome echo and mic gain issues on herring board. + // Must be modified/removed when proper support for voice processing query and control + // is included in audio framework + char value[PROPERTY_VALUE_MAX]; + property_get("ro.product.board", value, ""); + if (mode == NORMAL && !strcmp(value, "herring")) { + mode = ECHO_SUPPRESSION; + } if (mode == ECHO_SUPPRESSION && AudioSystem::getParameters( 0, String8("ec_supported")) == "ec_supported=yes") { mode = NORMAL; diff --git a/wifi/java/android/net/wifi/WifiNative.java b/wifi/java/android/net/wifi/WifiNative.java index 909605dc55d4..6e13d0fb349c 100644 --- a/wifi/java/android/net/wifi/WifiNative.java +++ b/wifi/java/android/net/wifi/WifiNative.java @@ -171,5 +171,7 @@ public class WifiNative { */ public native static String waitForEvent(); - public native static void enableBackgroundScan(boolean enable); + public native static void enableBackgroundScanCommand(boolean enable); + + public native static void setScanIntervalCommand(int scanInterval); } diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java index 4346b327f97c..46c07a303b90 100644 --- a/wifi/java/android/net/wifi/WifiStateMachine.java +++ b/wifi/java/android/net/wifi/WifiStateMachine.java @@ -339,10 +339,20 @@ public class WifiStateMachine extends HierarchicalStateMachine { private static final int POWER_MODE_AUTO = 0; /** - * See {@link Settings.Secure#WIFI_SCAN_INTERVAL_MS}. This is the default value if a - * Settings.Secure value is not present. + * Default framework scan interval in milliseconds. This is used in the scenario in which + * wifi chipset does not support background scanning to set up a + * periodic wake up scan so that the device can connect to a new access + * point on the move. {@link Settings.Secure#WIFI_FRAMEWORK_SCAN_INTERVAL_MS} can + * override this. */ - private static final long DEFAULT_SCAN_INTERVAL_MS = 60 * 1000; /* 1 minute */ + private final int mDefaultFrameworkScanIntervalMs; + + /** + * Default supplicant scan interval in milliseconds. + * {@link Settings.Secure#WIFI_SUPPLICANT_SCAN_INTERVAL_MS} can override this. + */ + private final int mDefaultSupplicantScanIntervalMs; + private static final int MIN_RSSI = -200; private static final int MAX_RSSI = 256; @@ -472,6 +482,12 @@ public class WifiStateMachine extends HierarchicalStateMachine { Intent scanIntent = new Intent(ACTION_START_SCAN, null); mScanIntent = PendingIntent.getBroadcast(mContext, SCAN_REQUEST, scanIntent, 0); + mDefaultFrameworkScanIntervalMs = mContext.getResources().getInteger( + com.android.internal.R.integer.config_wifi_framework_scan_interval); + + mDefaultSupplicantScanIntervalMs = mContext.getResources().getInteger( + com.android.internal.R.integer.config_wifi_supplicant_scan_interval); + mContext.registerReceiver( new BroadcastReceiver() { @Override @@ -819,7 +835,7 @@ public class WifiStateMachine extends HierarchicalStateMachine { sendMessage(obtainMessage(CMD_ENABLE_RSSI_POLL, enabled ? 1 : 0, 0)); } - public void enableBackgroundScan(boolean enabled) { + public void enableBackgroundScanCommand(boolean enabled) { sendMessage(obtainMessage(CMD_ENABLE_BACKGROUND_SCAN, enabled ? 1 : 0, 0)); } @@ -1949,6 +1965,11 @@ public class WifiStateMachine extends HierarchicalStateMachine { mIsScanMode = false; /* Wifi is available as long as we have a connection to supplicant */ mNetworkInfo.setIsAvailable(true); + /* Set scan interval */ + long supplicantScanIntervalMs = Settings.Secure.getLong(mContext.getContentResolver(), + Settings.Secure.WIFI_SUPPLICANT_SCAN_INTERVAL_MS, + mDefaultSupplicantScanIntervalMs); + WifiNative.setScanIntervalCommand((int)supplicantScanIntervalMs / 1000); } @Override public boolean processMessage(Message message) { @@ -2800,17 +2821,21 @@ public class WifiStateMachine extends HierarchicalStateMachine { class DisconnectedState extends HierarchicalState { private boolean mAlarmEnabled = false; - private long mScanIntervalMs; + /* This is set from the overlay config file or from a secure setting. + * A value of 0 disables scanning in the framework. + */ + private long mFrameworkScanIntervalMs; private void setScanAlarm(boolean enabled) { if (enabled == mAlarmEnabled) return; if (enabled) { - mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP, - System.currentTimeMillis() + mScanIntervalMs, - mScanIntervalMs, - mScanIntent); - - mAlarmEnabled = true; + if (mFrameworkScanIntervalMs > 0) { + mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP, + System.currentTimeMillis() + mFrameworkScanIntervalMs, + mFrameworkScanIntervalMs, + mScanIntent); + mAlarmEnabled = true; + } } else { mAlarmManager.cancel(mScanIntent); mAlarmEnabled = false; @@ -2822,8 +2847,9 @@ public class WifiStateMachine extends HierarchicalStateMachine { if (DBG) Log.d(TAG, getName() + "\n"); EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName()); - mScanIntervalMs = Settings.Secure.getLong(mContext.getContentResolver(), - Settings.Secure.WIFI_SCAN_INTERVAL_MS, DEFAULT_SCAN_INTERVAL_MS); + mFrameworkScanIntervalMs = Settings.Secure.getLong(mContext.getContentResolver(), + Settings.Secure.WIFI_FRAMEWORK_SCAN_INTERVAL_MS, + mDefaultFrameworkScanIntervalMs); /* * We initiate background scanning if it is enabled, otherwise we * initiate an infrequent scan that wakes up the device to ensure @@ -2837,7 +2863,7 @@ public class WifiStateMachine extends HierarchicalStateMachine { * cleared */ if (!mScanResultIsPending) { - WifiNative.enableBackgroundScan(true); + WifiNative.enableBackgroundScanCommand(true); } } else { setScanAlarm(true); @@ -2859,10 +2885,10 @@ public class WifiStateMachine extends HierarchicalStateMachine { case CMD_ENABLE_BACKGROUND_SCAN: mEnableBackgroundScan = (message.arg1 == 1); if (mEnableBackgroundScan) { - WifiNative.enableBackgroundScan(true); + WifiNative.enableBackgroundScanCommand(true); setScanAlarm(false); } else { - WifiNative.enableBackgroundScan(false); + WifiNative.enableBackgroundScanCommand(false); setScanAlarm(true); } break; @@ -2877,14 +2903,14 @@ public class WifiStateMachine extends HierarchicalStateMachine { case CMD_START_SCAN: /* Disable background scan temporarily during a regular scan */ if (mEnableBackgroundScan) { - WifiNative.enableBackgroundScan(false); + WifiNative.enableBackgroundScanCommand(false); } /* Handled in parent state */ return NOT_HANDLED; case SCAN_RESULTS_EVENT: /* Re-enable background scan when a pending scan result is received */ if (mEnableBackgroundScan && mScanResultIsPending) { - WifiNative.enableBackgroundScan(true); + WifiNative.enableBackgroundScanCommand(true); } /* Handled in parent state */ return NOT_HANDLED; @@ -2899,7 +2925,7 @@ public class WifiStateMachine extends HierarchicalStateMachine { public void exit() { /* No need for a background scan upon exit from a disconnected state */ if (mEnableBackgroundScan) { - WifiNative.enableBackgroundScan(false); + WifiNative.enableBackgroundScanCommand(false); } setScanAlarm(false); } |