Merge change 4455 into donut
* changes:
add feedback test with gsm7bit special case characters
diff --git a/camera/libcameraservice/CameraService.cpp b/camera/libcameraservice/CameraService.cpp
index a3ab641..128fd5a 100644
--- a/camera/libcameraservice/CameraService.cpp
+++ b/camera/libcameraservice/CameraService.cpp
@@ -215,7 +215,7 @@
{
Mutex::Autolock _l(mLock);
// allow anyone to use camera
- LOGV("unlock (%p)", getCameraClient()->asBinder().get());
+ LOGD("unlock (%p)", getCameraClient()->asBinder().get());
status_t result = checkPid();
if (result == NO_ERROR) {
mClientPid = 0;
@@ -230,7 +230,7 @@
status_t CameraService::Client::connect(const sp<ICameraClient>& client)
{
// connect a new process to the camera
- LOGV("connect (%p)", client->asBinder().get());
+ LOGD("connect (%p)", client->asBinder().get());
// I hate this hack, but things get really ugly when the media recorder
// service is handing back the camera to the app. The ICameraClient
@@ -257,7 +257,7 @@
mCameraClient = client;
mClientPid = -1;
mPreviewCallbackFlag = FRAME_CALLBACK_FLAG_NOOP;
- LOGV("connect new process (%d) to existing camera client", mClientPid);
+ LOGD("connect new process (%d) to existing camera client", mClientPid);
}
}
@@ -319,17 +319,17 @@
IPCThreadState::self()->getCallingPid());
Mutex::Autolock lock(mLock);
if (mClientPid <= 0) {
- LOGV("camera is unlocked, don't tear down hardware");
+ LOGD("camera is unlocked, don't tear down hardware");
return;
}
if (checkPid() != NO_ERROR) {
- LOGV("Different client - don't disconnect");
+ LOGD("Different client - don't disconnect");
return;
}
mCameraService->removeClient(mCameraClient);
if (mHardware != 0) {
- LOGV("hardware teardown");
+ LOGD("hardware teardown");
// Before destroying mHardware, we must make sure it's in the
// idle state.
mHardware->stopPreview();
diff --git a/cmds/backup/backup.cpp b/cmds/backup/backup.cpp
index 22dd486..d4e669b 100644
--- a/cmds/backup/backup.cpp
+++ b/cmds/backup/backup.cpp
@@ -64,22 +64,14 @@
}
BackupDataReader reader(fd);
+ bool done;
int type;
- while (reader.ReadNextHeader(&type) == 0) {
+ while (reader.ReadNextHeader(&done, &type) == 0) {
+ if (done) {
+ break;
+ }
switch (type) {
- case BACKUP_HEADER_APP_V1:
- {
- String8 packageName;
- int cookie;
- err = reader.ReadAppHeader(&packageName, &cookie);
- if (err == 0) {
- printf("App header: %s 0x%08x (%d)\n", packageName.string(), cookie, cookie);
- } else {
- printf("Error reading app header\n");
- }
- break;
- }
case BACKUP_HEADER_ENTITY_V1:
{
String8 key;
@@ -92,17 +84,6 @@
}
break;
}
- case BACKUP_FOOTER_APP_V1:
- {
- int cookie;
- err = reader.ReadAppFooter(&cookie);
- if (err == 0) {
- printf(" App footer: 0x%08x (%d)\n", cookie, cookie);
- } else {
- printf(" Error reading entity header\n");
- }
- break;
- }
default:
{
printf("Unknown chunk type: 0x%08x\n", type);
diff --git a/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java b/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
index 467cac1..3af80fa 100644
--- a/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
+++ b/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
@@ -36,9 +36,14 @@
private String mCurArgData;
public static void main(String[] args) {
- new Bmgr().run(args);
+ try {
+ new Bmgr().run(args);
+ } catch (Exception e) {
+ System.err.println("Exception caught:");
+ e.printStackTrace();
+ }
}
-
+
public void run(String[] args) {
boolean validCommand = false;
if (args.length < 1) {
@@ -70,6 +75,11 @@
doList();
return;
}
+
+ if ("restore".equals(op)) {
+ doRestore();
+ return;
+ }
}
private void doRun() {
@@ -114,6 +124,10 @@
try {
int curTransport = mBmgr.getCurrentTransport();
mRestore = mBmgr.beginRestoreSession(curTransport);
+ if (mRestore == null) {
+ System.err.println(BMGR_NOT_RUNNING_ERR);
+ return;
+ }
if ("sets".equals(arg)) {
doListRestoreSets();
@@ -127,13 +141,12 @@
}
private void doListTransports() {
-
}
private void doListRestoreSets() {
try {
RestoreSet[] sets = mRestore.getAvailableRestoreSets();
- if (sets.length == 0) {
+ if (sets == null || sets.length == 0) {
System.out.println("No restore sets available");
} else {
for (RestoreSet s : sets) {
@@ -146,6 +159,37 @@
}
}
+ private void doRestore() {
+ int token;
+ try {
+ token = Integer.parseInt(nextArg());
+ } catch (NumberFormatException e) {
+ showUsage();
+ return;
+ }
+
+ try {
+ int curTransport = mBmgr.getCurrentTransport();
+ mRestore = mBmgr.beginRestoreSession(curTransport);
+ if (mRestore == null) {
+ System.err.println(BMGR_NOT_RUNNING_ERR);
+ return;
+ }
+ RestoreSet[] sets = mRestore.getAvailableRestoreSets();
+ for (RestoreSet s : sets) {
+ if (s.token == token) {
+ System.out.println("Scheduling restore: " + s.name);
+ mRestore.performRestore(token);
+ break;
+ }
+ }
+ mRestore.endRestoreSession();
+ } catch (RemoteException e) {
+ System.err.println(e.toString());
+ System.err.println(BMGR_NOT_RUNNING_ERR);
+ }
+ }
+
private String nextArg() {
if (mNextArg >= mArgs.length) {
return null;
@@ -161,7 +205,7 @@
System.err.println(" bmgr list sets");
System.err.println(" #bmgr list transports");
System.err.println(" #bmgr transport which#");
- System.err.println(" #bmgr restore set#");
+ System.err.println(" bmgr restore token#");
System.err.println(" bmgr run");
}
}
\ No newline at end of file
diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c
index 9a6684a..cc951c1 100644
--- a/cmds/dumpstate/dumpstate.c
+++ b/cmds/dumpstate/dumpstate.c
@@ -49,11 +49,7 @@
PRINT("------ VIRTUAL MEMORY STATS ------");
DUMP("/proc/vmstat");
PRINT("------ SLAB INFO ------");
-#if 0
DUMP("/proc/slabinfo");
-#else
- PRINT("temporarily disabled to avoid kernel crasher");
-#endif
PRINT("------ ZONEINFO ------");
DUMP("/proc/zoneinfo");
PRINT("------ SYSTEM LOG ------");
diff --git a/cmds/keystore/commands.c b/cmds/keystore/commands.c
index e53cece..17dd060 100644
--- a/cmds/keystore/commands.c
+++ b/cmds/keystore/commands.c
@@ -1,5 +1,5 @@
/*
-** Copyright 2008, The Android Open Source Project
+** Copyright 2009, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
@@ -30,7 +30,8 @@
return d;
}
-static int list_files(const char *dir, char reply[REPLY_MAX]) {
+static int list_files(const char *dir, char reply[REPLY_MAX])
+{
struct dirent *de;
DIR *d;
@@ -39,7 +40,9 @@
}
reply[0]=0;
while ((de = readdir(d))) {
- if (de->d_type != DT_REG) continue;
+ if (de->d_type != DT_DIR) continue;
+ if ((strcmp(DOT, de->d_name) == 0) ||
+ (strcmp(DOTDOT, de->d_name) == 0)) continue;
if (reply[0] != 0) strlcat(reply, " ", REPLY_MAX);
if (strlcat(reply, de->d_name, REPLY_MAX) >= REPLY_MAX) {
LOGE("reply is too long(too many files under '%s'\n", dir);
@@ -50,31 +53,25 @@
return 0;
}
-static int copy_keyfile(const char *keystore, const char *srcfile) {
- int srcfd, dstfd;
- int length;
- char buf[2048];
- char dstfile[KEYNAME_LENGTH];
- const char *filename = strrchr(srcfile, '/');
+static int copy_keyfile(const char *src, int src_type, const char *dstfile) {
+ int srcfd = -1, dstfd;
+ char buf[REPLY_MAX];
- strlcpy(dstfile, keystore, KEYNAME_LENGTH);
- strlcat(dstfile, "/", KEYNAME_LENGTH);
- if (strlcat(dstfile, filename ? filename + 1 : srcfile,
- KEYNAME_LENGTH) >= KEYNAME_LENGTH) {
- LOGE("keyname is too long '%s'\n", srcfile);
- return -1;
- }
-
- if ((srcfd = open(srcfile, O_RDONLY)) == -1) {
- LOGE("Cannot open the original file '%s'\n", srcfile);
+ if ((src_type == IS_FILE) && (srcfd = open(src, O_RDONLY)) == -1) {
+ LOGE("Cannot open the original file '%s'\n", src);
return -1;
}
if ((dstfd = open(dstfile, O_CREAT|O_RDWR)) == -1) {
LOGE("Cannot open the destination file '%s'\n", dstfile);
return -1;
}
- while((length = read(srcfd, buf, 2048)) > 0) {
- write(dstfd, buf, length);
+ if (src_type == IS_FILE) {
+ int length;
+ while((length = read(srcfd, buf, REPLY_MAX)) > 0) {
+ write(dstfd, buf, length);
+ }
+ } else {
+ write(dstfd, src, strlen(src));
}
close(srcfd);
close(dstfd);
@@ -82,60 +79,149 @@
return 0;
}
-static int install_key(const char *dir, const char *keyfile)
+static int install_key(const char *path, const char *certname, const char *src,
+ int src_is_file, char *dstfile)
{
struct dirent *de;
+ char fullpath[KEYNAME_LENGTH];
DIR *d;
- if ((d = open_keystore(dir)) == NULL) {
+ if (snprintf(fullpath, sizeof(fullpath), "%s/%s/", path, certname)
+ >= KEYNAME_LENGTH) {
+ LOGE("cert name '%s' is too long.\n", certname);
return -1;
}
- return copy_keyfile(dir, keyfile);
+
+ if ((d = open_keystore(fullpath)) == NULL) {
+ LOGE("Can not open the keystore '%s'\n", fullpath);
+ return -1;
+ }
+ closedir(d);
+ if (strlcat(fullpath, dstfile, KEYNAME_LENGTH) >= KEYNAME_LENGTH) {
+ LOGE("cert name '%s' is too long.\n", certname);
+ return -1;
+ }
+ return copy_keyfile(src, src_is_file, fullpath);
}
-static int remove_key(const char *dir, const char *keyfile)
+static int get_key(const char *path, const char *keyname, const char *file,
+ char reply[REPLY_MAX])
{
- char dstfile[KEYNAME_LENGTH];
+ struct dirent *de;
+ char filename[KEYNAME_LENGTH];
+ int fd;
- strlcpy(dstfile, dir, KEYNAME_LENGTH);
- strlcat(dstfile, "/", KEYNAME_LENGTH);
- if (strlcat(dstfile, keyfile, KEYNAME_LENGTH) >= KEYNAME_LENGTH) {
- LOGE("keyname is too long '%s'\n", keyfile);
+ if (snprintf(filename, sizeof(filename), "%s/%s/%s", path, keyname, file)
+ >= KEYNAME_LENGTH) {
+ LOGE("cert name '%s' is too long.\n", keyname);
return -1;
}
- if (unlink(dstfile)) {
- LOGE("cannot delete '%s': %s\n", dstfile, strerror(errno));
+
+ if ((fd = open(filename, O_RDONLY)) == -1) {
+ return -1;
+ }
+ close(fd);
+ strlcpy(reply, filename, REPLY_MAX);
+ return 0;
+}
+
+static int remove_key(const char *dir, const char *key)
+{
+ char dstfile[KEYNAME_LENGTH];
+ char *keyfile[4] = { USER_KEY, USER_P12_CERT, USER_CERTIFICATE,
+ CA_CERTIFICATE };
+ int i, count = 0;
+
+ for ( i = 0 ; i < 4 ; i++) {
+ if (snprintf(dstfile, KEYNAME_LENGTH, "%s/%s/%s", dir, key, keyfile[i])
+ >= KEYNAME_LENGTH) {
+ LOGE("keyname is too long '%s'\n", key);
+ return -1;
+ }
+ if (unlink(dstfile) == 0) count++;
+ }
+
+ if (count == 0) {
+ LOGE("can not clean up '%s' keys or not exist\n", key);
+ return -1;
+ }
+
+ snprintf(dstfile, KEYNAME_LENGTH, "%s/%s", dir, key);
+ if (rmdir(dstfile)) {
+ LOGE("can not clean up '%s' directory\n", key);
return -1;
}
return 0;
}
-int list_certs(char reply[REPLY_MAX])
+int list_user_certs(char reply[REPLY_MAX])
{
return list_files(CERTS_DIR, reply);
}
-int list_userkeys(char reply[REPLY_MAX])
+int list_ca_certs(char reply[REPLY_MAX])
{
- return list_files(USERKEYS_DIR, reply);
+ return list_files(CACERTS_DIR, reply);
}
-int install_cert(const char *certfile)
+int install_user_cert(const char *keyname, const char *cert, const char *key)
{
- return install_key(CERTS_DIR, certfile);
+ if (install_key(CERTS_DIR, keyname, cert, IS_FILE, USER_CERTIFICATE) == 0) {
+ return install_key(CERTS_DIR, keyname, key, IS_FILE, USER_KEY);
+ }
+ return -1;
}
-int install_userkey(const char *keyfile)
+int install_ca_cert(const char *keyname, const char *certfile)
{
- return install_key(USERKEYS_DIR, keyfile);
+ return install_key(CACERTS_DIR, keyname, certfile, IS_FILE, CA_CERTIFICATE);
}
-int remove_cert(const char *certfile)
+int install_p12_cert(const char *keyname, const char *certfile)
{
- return remove_key(CERTS_DIR, certfile);
+ return install_key(CERTS_DIR, keyname, certfile, IS_FILE, USER_P12_CERT);
}
-int remove_userkey(const char *keyfile)
+int add_ca_cert(const char *keyname, const char *certificate)
{
- return remove_key(USERKEYS_DIR, keyfile);
+ return install_key(CACERTS_DIR, keyname, certificate, IS_CONTENT,
+ CA_CERTIFICATE);
+}
+
+int add_user_cert(const char *keyname, const char *certificate)
+{
+ return install_key(CERTS_DIR, keyname, certificate, IS_CONTENT,
+ USER_CERTIFICATE);
+}
+
+int add_user_key(const char *keyname, const char *key)
+{
+ return install_key(CERTS_DIR, keyname, key, IS_CONTENT, USER_KEY);
+}
+
+int get_ca_cert(const char *keyname, char reply[REPLY_MAX])
+{
+ return get_key(CACERTS_DIR, keyname, CA_CERTIFICATE, reply);
+}
+
+int get_user_cert(const char *keyname, char reply[REPLY_MAX])
+{
+ return get_key(CERTS_DIR, keyname, USER_CERTIFICATE, reply);
+}
+
+int get_user_key(const char *keyname, char reply[REPLY_MAX])
+{
+ if(get_key(CERTS_DIR, keyname, USER_KEY, reply))
+ return get_key(CERTS_DIR, keyname, USER_P12_CERT, reply);
+ return 0;
+}
+
+int remove_user_cert(const char *key)
+{
+ return remove_key(CERTS_DIR, key);
+}
+
+int remove_ca_cert(const char *key)
+{
+ return remove_key(CACERTS_DIR, key);
}
diff --git a/cmds/keystore/keystore.c b/cmds/keystore/keystore.c
index 5193b3d..df8d832 100644
--- a/cmds/keystore/keystore.c
+++ b/cmds/keystore/keystore.c
@@ -16,37 +16,89 @@
#include "keystore.h"
-
-static int do_list_certs(char **arg, char reply[REPLY_MAX])
+static inline int has_whitespace(char *name)
{
- return list_certs(reply);
+ if((strrchr(name, ' ') != NULL)) {
+ LOGE("'%s' contains whitespace character\n", name);
+ return 1;
+ }
+ return 0;
}
-static int do_list_userkeys(char **arg, char reply[REPLY_MAX])
+static int do_list_user_certs(char **arg, char reply[REPLY_MAX])
{
- return list_userkeys(reply);
+ return list_user_certs(reply);
}
-static int do_install_cert(char **arg, char reply[REPLY_MAX])
+static int do_list_ca_certs(char **arg, char reply[REPLY_MAX])
{
- return install_cert(arg[0]); /* move the certificate to keystore */
+ return list_ca_certs(reply);
}
-static int do_remove_cert(char **arg, char reply[REPLY_MAX])
+static int do_install_user_cert(char **arg, char reply[REPLY_MAX])
{
- return remove_cert(arg[0]); /* certificate */
+ if (has_whitespace(arg[0])) return -1;
+ /* copy the certificate and key to keystore */
+ return install_user_cert(arg[0], arg[1], arg[2]);
}
-static int do_install_userkey(char **arg, char reply[REPLY_MAX])
+static int do_install_p12_cert(char **arg, char reply[REPLY_MAX])
{
- return install_userkey(arg[0]); /* move the certificate to keystore */
+ if (has_whitespace(arg[0])) return -1;
+ return install_p12_cert(arg[0], arg[1]);
}
-static int do_remove_userkey(char **arg, char reply[REPLY_MAX])
+static int do_install_ca_cert(char **arg, char reply[REPLY_MAX])
{
- return remove_userkey(arg[0]); /* userkey */
+ if (has_whitespace(arg[0])) return -1;
+ /* copy the certificate and key to keystore */
+ return install_ca_cert(arg[0], arg[1]);
}
+static int do_add_ca_cert(char **arg, char reply[REPLY_MAX])
+{
+ if (has_whitespace(arg[0])) return -1;
+ return add_ca_cert(arg[0], arg[1]);
+}
+
+static int do_add_user_cert(char **arg, char reply[REPLY_MAX])
+{
+ if (has_whitespace(arg[0])) return -1;
+ return add_user_cert(arg[0], arg[1]);
+}
+
+static int do_add_user_key(char **arg, char reply[REPLY_MAX])
+{
+ if (has_whitespace(arg[0])) return -1;
+ return add_user_key(arg[0], arg[1]);
+}
+
+static int do_get_ca_cert(char **arg, char reply[REPLY_MAX])
+{
+ return get_ca_cert(arg[0], reply);
+}
+
+static int do_get_user_cert(char **arg, char reply[REPLY_MAX])
+{
+ return get_user_cert(arg[0], reply);
+}
+
+static int do_get_user_key(char **arg, char reply[REPLY_MAX])
+{
+ return get_user_key(arg[0], reply);
+}
+
+static int do_remove_user_cert(char **arg, char reply[REPLY_MAX])
+{
+ return remove_user_cert(arg[0]);
+}
+
+static int do_remove_ca_cert(char **arg, char reply[REPLY_MAX])
+{
+ return remove_ca_cert(arg[0]);
+}
+
+
struct cmdinfo {
const char *name;
unsigned numargs;
@@ -55,12 +107,19 @@
struct cmdinfo cmds[] = {
- { "listcerts", 0, do_list_certs },
- { "listuserkeys", 0, do_list_userkeys },
- { "installcert", 1, do_install_cert },
- { "removecert", 1, do_remove_cert },
- { "installuserkey", 1, do_install_userkey },
- { "removeuserkey", 1, do_remove_userkey },
+ { "listcacerts", 0, do_list_ca_certs },
+ { "listusercerts", 0, do_list_user_certs },
+ { "installusercert", 3, do_install_user_cert },
+ { "installcacert", 2, do_install_ca_cert },
+ { "installp12cert", 2, do_install_p12_cert },
+ { "addusercert", 2, do_add_user_cert },
+ { "adduserkey", 2, do_add_user_key },
+ { "addcacert", 2, do_add_ca_cert },
+ { "getusercert", 1, do_get_user_cert },
+ { "getuserkey", 1, do_get_user_key },
+ { "getcacert", 1, do_get_ca_cert },
+ { "removecacert", 1, do_remove_ca_cert },
+ { "removeusercert", 1, do_remove_user_cert },
};
static int readx(int s, void *_buf, int count)
@@ -121,7 +180,7 @@
/* n is number of args (not counting arg[0]) */
arg[0] = cmd;
while (*cmd) {
- if (isspace(*cmd)) {
+ if (*cmd == CMD_DELIMITER) {
*cmd++ = 0;
n++;
arg[n] = cmd;
@@ -167,6 +226,7 @@
int fd, i;
short ret;
unsigned short count;
+ char delimiter[2] = { CMD_DELIMITER, 0 };
char buf[BUFFER_MAX]="";
fd = socket_local_client(SOCKET_PATH,
@@ -177,7 +237,7 @@
exit(1);
}
for(i = 0; i < argc; i++) {
- if (i > 0) strlcat(buf, " ", BUFFER_MAX);
+ if (i > 0) strlcat(buf, delimiter, BUFFER_MAX);
if(strlcat(buf, argv[i], BUFFER_MAX) >= BUFFER_MAX) {
fprintf(stderr, "Arguments are too long\n");
exit(1);
diff --git a/cmds/keystore/keystore.h b/cmds/keystore/keystore.h
index 35acf0b9..b9cb185 100644
--- a/cmds/keystore/keystore.h
+++ b/cmds/keystore/keystore.h
@@ -40,18 +40,35 @@
/* path of the keystore */
#define KEYSTORE_DIR_PREFIX "/data/misc/keystore"
-#define CERTS_DIR KEYSTORE_DIR_PREFIX "/certs"
-#define USERKEYS_DIR KEYSTORE_DIR_PREFIX "/userkeys"
+#define CERTS_DIR KEYSTORE_DIR_PREFIX "/keys"
+#define CACERTS_DIR KEYSTORE_DIR_PREFIX "/cacerts"
+#define CA_CERTIFICATE "ca.crt"
+#define USER_CERTIFICATE "user.crt"
+#define USER_P12_CERT "user.p12"
+#define USER_KEY "user.key"
+#define DOT "."
+#define DOTDOT ".."
-#define BUFFER_MAX 1024 /* input buffer for commands */
+#define BUFFER_MAX 4096 /* input buffer for commands */
#define TOKEN_MAX 8 /* max number of arguments in buffer */
-#define REPLY_MAX 1024 /* largest reply allowed */
+#define REPLY_MAX 4096 /* largest reply allowed */
+#define CMD_DELIMITER '\t'
#define KEYNAME_LENGTH 128
+#define IS_CONTENT 0
+#define IS_FILE 1
+
/* commands.c */
-int list_certs(char reply[REPLY_MAX]);
-int list_userkeys(char reply[REPLY_MAX]);
-int install_cert(const char *certfile);
-int install_userkey(const char *keyfile);
-int remove_cert(const char *certfile);
-int remove_userkey(const char *keyfile);
+int list_ca_certs(char reply[REPLY_MAX]);
+int list_user_certs(char reply[REPLY_MAX]);
+int install_user_cert(const char *certname, const char *cert, const char *key);
+int install_ca_cert(const char *certname, const char *cert);
+int install_p12_cert(const char *certname, const char *cert);
+int add_ca_cert(const char *certname, const char *content);
+int add_user_cert(const char *certname, const char *content);
+int add_user_key(const char *keyname, const char *content);
+int get_ca_cert(const char *keyname, char reply[REPLY_MAX]);
+int get_user_cert(const char *keyname, char reply[REPLY_MAX]);
+int get_user_key(const char *keyname, char reply[REPLY_MAX]);
+int remove_user_cert(const char *certname);
+int remove_ca_cert(const char *certname);
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index d08fc11..3676594 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -31,6 +31,7 @@
import android.content.pm.PackageManager;
import android.content.pm.ProviderInfo;
import android.content.pm.ServiceInfo;
+import android.content.pm.PackageParser.Component;
import android.content.res.AssetManager;
import android.content.res.Configuration;
import android.content.res.Resources;
@@ -3216,7 +3217,7 @@
r.activity.getComponentName().getClassName());
if (!r.activity.mCalled) {
throw new SuperNotCalledException(
- "Activity " + r.intent.getComponent().toShortString()
+ "Activity " + safeToComponentShortString(r.intent)
+ " did not call through to super.onPause()");
}
} catch (SuperNotCalledException e) {
@@ -3225,7 +3226,7 @@
if (!mInstrumentation.onException(r.activity, e)) {
throw new RuntimeException(
"Unable to pause activity "
- + r.intent.getComponent().toShortString()
+ + safeToComponentShortString(r.intent)
+ ": " + e.toString(), e);
}
}
@@ -3240,7 +3241,7 @@
if (!mInstrumentation.onException(r.activity, e)) {
throw new RuntimeException(
"Unable to stop activity "
- + r.intent.getComponent().toShortString()
+ + safeToComponentShortString(r.intent)
+ ": " + e.toString(), e);
}
}
@@ -3265,7 +3266,7 @@
if (!mInstrumentation.onException(r.activity, e)) {
throw new RuntimeException(
"Unable to retain child activities "
- + r.intent.getComponent().toShortString()
+ + safeToComponentShortString(r.intent)
+ ": " + e.toString(), e);
}
}
@@ -3276,7 +3277,7 @@
r.activity.onDestroy();
if (!r.activity.mCalled) {
throw new SuperNotCalledException(
- "Activity " + r.intent.getComponent().toShortString() +
+ "Activity " + safeToComponentShortString(r.intent) +
" did not call through to super.onDestroy()");
}
if (r.window != null) {
@@ -3287,8 +3288,7 @@
} catch (Exception e) {
if (!mInstrumentation.onException(r.activity, e)) {
throw new RuntimeException(
- "Unable to destroy activity "
- + r.intent.getComponent().toShortString()
+ "Unable to destroy activity " + safeToComponentShortString(r.intent)
+ ": " + e.toString(), e);
}
}
@@ -3298,6 +3298,11 @@
return r;
}
+ private static String safeToComponentShortString(Intent intent) {
+ ComponentName component = intent.getComponent();
+ return component == null ? "[Unknown]" : component.toShortString();
+ }
+
private final void handleDestroyActivity(IBinder token, boolean finishing,
int configChanges, boolean getNonConfigInstance) {
ActivityRecord r = performDestroyActivity(token, finishing,
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java
index 9141c4c..21c9e65 100644
--- a/core/java/android/app/SearchDialog.java
+++ b/core/java/android/app/SearchDialog.java
@@ -35,11 +35,6 @@
import android.database.Cursor;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.Drawable;
-import android.location.Criteria;
-import android.location.Location;
-import android.location.LocationListener;
-import android.location.LocationManager;
-import android.location.LocationProvider;
import android.net.Uri;
import android.os.Bundle;
import android.os.SystemClock;
@@ -153,15 +148,6 @@
private final WeakHashMap<String, Drawable> mOutsideDrawablesCache =
new WeakHashMap<String, Drawable>();
- // Objects we keep around for requesting location updates when the dialog is started
- // (and canceling them when the dialog is stopped). We don't actually make use of the
- // updates ourselves here, so the LocationListener is just a dummy which doesn't do
- // anything. We only do this here so that other suggest providers which wish to provide
- // location-based suggestions are more likely to get a good fresh location.
- private LocationManager mLocationManager;
- private LocationProvider mLocationProvider;
- private LocationListener mDummyLocationListener;
-
/**
* Constructor - fires it up and makes it look like the search UI.
*
@@ -240,37 +226,6 @@
mVoiceAppSearchIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
mVoiceAppSearchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-
- mLocationManager =
- (LocationManager) getContext().getSystemService(Context.LOCATION_SERVICE);
-
- if (mLocationManager != null) {
- Criteria criteria = new Criteria();
- criteria.setAccuracy(Criteria.ACCURACY_COARSE);
-
- String providerName = mLocationManager.getBestProvider(criteria, true);
-
- if (providerName != null) {
- mLocationProvider = mLocationManager.getProvider(providerName);
- }
-
- // Just a dumb listener that doesn't do anything - requesting location updates here
- // is only intended to give location-based suggestion providers the best chance
- // of getting a good fresh location.
- mDummyLocationListener = new LocationListener() {
- public void onLocationChanged(Location location) {
- }
-
- public void onProviderDisabled(String provider) {
- }
-
- public void onProviderEnabled(String provider) {
- }
-
- public void onStatusChanged(String provider, int status, Bundle extras) {
- }
- };
- }
}
/**
@@ -423,8 +378,6 @@
// receive broadcasts
getContext().registerReceiver(mBroadcastReceiver, mCloseDialogsFilter);
getContext().registerReceiver(mBroadcastReceiver, mPackageFilter);
-
- startLocationUpdates();
}
/**
@@ -437,8 +390,6 @@
public void onStop() {
super.onStop();
- stopLocationUpdates();
-
// stop receiving broadcasts (throws exception if none registered)
try {
getContext().unregisterReceiver(mBroadcastReceiver);
@@ -456,26 +407,7 @@
mUserQuery = null;
mPreviousComponents = null;
}
-
- /**
- * Asks the LocationManager for location updates so that it goes and gets a fresh location
- * if needed.
- */
- private void startLocationUpdates() {
- if (mLocationManager != null && mLocationProvider != null) {
- mLocationManager.requestLocationUpdates(mLocationProvider.getName(),
- 0, 0, mDummyLocationListener, getContext().getMainLooper());
- }
- }
-
- /**
- * Makes sure to stop listening for location updates to save battery.
- */
- private void stopLocationUpdates() {
- mLocationManager.removeUpdates(mDummyLocationListener);
- }
-
/**
* Sets the search dialog to the 'working' state, which shows a working spinner in the
* right hand size of the text field.
diff --git a/core/java/android/backup/BackupDataInput.java b/core/java/android/backup/BackupDataInput.java
index 609dd90..69c206c 100644
--- a/core/java/android/backup/BackupDataInput.java
+++ b/core/java/android/backup/BackupDataInput.java
@@ -82,9 +82,9 @@
}
}
- public int readEntityData(byte[] data, int size) throws IOException {
+ public int readEntityData(byte[] data, int offset, int size) throws IOException {
if (mHeaderReady) {
- int result = readEntityData_native(mBackupReader, data, size);
+ int result = readEntityData_native(mBackupReader, data, offset, size);
if (result >= 0) {
return result;
} else {
@@ -95,9 +95,23 @@
}
}
+ public void skipEntityData() throws IOException {
+ if (mHeaderReady) {
+ int result = skipEntityData_native(mBackupReader);
+ if (result >= 0) {
+ return;
+ } else {
+ throw new IOException("result=0x" + Integer.toHexString(result));
+ }
+ } else {
+ throw new IllegalStateException("mHeaderReady=false");
+ }
+ }
+
private native static int ctor(FileDescriptor fd);
private native static void dtor(int mBackupReader);
private native int readNextHeader_native(int mBackupReader, EntityHeader entity);
- private native int readEntityData_native(int mBackupReader, byte[] data, int size);
+ private native int readEntityData_native(int mBackupReader, byte[] data, int offset, int size);
+ private native int skipEntityData_native(int mBackupReader);
}
diff --git a/core/java/android/backup/BackupDataInputStream.java b/core/java/android/backup/BackupDataInputStream.java
new file mode 100644
index 0000000..52b1675
--- /dev/null
+++ b/core/java/android/backup/BackupDataInputStream.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.backup;
+
+import java.io.InputStream;
+import java.io.IOException;
+
+/** @hide */
+public class BackupDataInputStream extends InputStream {
+
+ String key;
+ int dataSize;
+
+ BackupDataInput mData;
+ byte[] mOneByte;
+
+ BackupDataInputStream(BackupDataInput data) {
+ mData = data;
+ }
+
+ public int read() throws IOException {
+ byte[] one = mOneByte;
+ if (mOneByte == null) {
+ one = mOneByte = new byte[1];
+ }
+ mData.readEntityData(one, 0, 1);
+ return one[0];
+ }
+
+ public int read(byte[] b, int offset, int size) throws IOException {
+ return mData.readEntityData(b, offset, size);
+ }
+
+ public int read(byte[] b) throws IOException {
+ return mData.readEntityData(b, 0, b.length);
+ }
+
+ public String getKey() {
+ return this.key;
+ }
+
+ public int size() {
+ return this.dataSize;
+ }
+}
+
+
diff --git a/core/java/android/backup/RestoreHelper.java b/core/java/android/backup/RestoreHelper.java
index ebd9906e..ee8bedd 100644
--- a/core/java/android/backup/RestoreHelper.java
+++ b/core/java/android/backup/RestoreHelper.java
@@ -16,8 +16,16 @@
package android.backup;
+import java.io.InputStream;
+
/** @hide */
public interface RestoreHelper {
- public void performRestore();
+ /**
+ * Called by RestoreHelperDispatcher to dispatch one entity of data.
+ * <p class=note>
+ * Do not close the <code>data</code> stream. Do not read more than
+ * <code>dataSize</code> bytes from <code>data</code>.
+ */
+ public void performRestore(BackupDataInputStream data);
}
diff --git a/core/java/android/backup/RestoreHelperDispatcher.java b/core/java/android/backup/RestoreHelperDispatcher.java
new file mode 100644
index 0000000..cbfefdc
--- /dev/null
+++ b/core/java/android/backup/RestoreHelperDispatcher.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.backup;
+
+import java.io.IOException;
+import java.util.HashMap;
+
+/** @hide */
+public class RestoreHelperDispatcher {
+ HashMap<String,RestoreHelper> mHelpers;
+
+ public void addHelper(String keyPrefix, RestoreHelper helper) {
+ mHelpers.put(keyPrefix, helper);
+ }
+
+ public void dispatch(BackupDataInput input) throws IOException {
+ BackupDataInputStream stream = new BackupDataInputStream(input);
+ while (input.readNextHeader()) {
+ String rawKey = input.getKey();
+ int pos = rawKey.indexOf(':');
+ if (pos > 0) {
+ String prefix = rawKey.substring(0, pos);
+ RestoreHelper helper = mHelpers.get(prefix);
+ if (helper != null) {
+ stream.dataSize = input.getDataSize();
+ stream.key = rawKey.substring(pos+1);
+ helper.performRestore(stream);
+ }
+ }
+ input.skipEntityData(); // In case they didn't consume the data.
+ }
+ }
+}
diff --git a/core/java/android/backup/RestoreHelperDistributor.java b/core/java/android/backup/RestoreHelperDistributor.java
deleted file mode 100644
index 555ca79..0000000
--- a/core/java/android/backup/RestoreHelperDistributor.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.backup;
-
-import java.util.HashMap;
-
-/** @hide */
-public class RestoreHelperDistributor {
- HashMap<String,RestoreHelper> mHelpers;
-
- public void addHelper(String keyPrefix, RestoreHelper helper) {
- mHelpers.put(keyPrefix, helper);
- }
-}
diff --git a/core/java/android/backup/RestoreSet.java b/core/java/android/backup/RestoreSet.java
index 7f09af3..96a99ae 100644
--- a/core/java/android/backup/RestoreSet.java
+++ b/core/java/android/backup/RestoreSet.java
@@ -46,11 +46,11 @@
public int token;
- RestoreSet() {
+ public RestoreSet() {
// Leave everything zero / null
}
- RestoreSet(String _name, String _dev, int _token) {
+ public RestoreSet(String _name, String _dev, int _token) {
name = _name;
device = _dev;
token = _token;
diff --git a/core/java/android/gesture/GestureOverlayView.java b/core/java/android/gesture/GestureOverlayView.java
index fd6d850..5bfdcc4 100755
--- a/core/java/android/gesture/GestureOverlayView.java
+++ b/core/java/android/gesture/GestureOverlayView.java
@@ -84,6 +84,7 @@
private final Rect mInvalidRect = new Rect();
private final Path mPath = new Path();
+ private boolean mGestureVisible = true;
private float mX;
private float mY;
@@ -274,14 +275,6 @@
return mCurrentGesture;
}
- public long getFadeOffset() {
- return mFadeOffset;
- }
-
- public void setFadeOffset(long fadeOffset) {
- mFadeOffset = fadeOffset;
- }
-
public void setGesture(Gesture gesture) {
if (mCurrentGesture != null) {
clear(false);
@@ -304,6 +297,31 @@
invalidate();
}
+ public Path getGesturePath() {
+ return mPath;
+ }
+
+ public Path getGesturePath(Path path) {
+ path.set(mPath);
+ return path;
+ }
+
+ public boolean isGestureVisible() {
+ return mGestureVisible;
+ }
+
+ public void setGestureVisible(boolean visible) {
+ mGestureVisible = visible;
+ }
+
+ public long getFadeOffset() {
+ return mFadeOffset;
+ }
+
+ public void setFadeOffset(long fadeOffset) {
+ mFadeOffset = fadeOffset;
+ }
+
public void addOnGestureListener(OnGestureListener listener) {
mOnGestureListeners.add(listener);
}
@@ -372,7 +390,7 @@
public void draw(Canvas canvas) {
super.draw(canvas);
- if (mCurrentGesture != null) {
+ if (mCurrentGesture != null && mGestureVisible) {
canvas.drawPath(mPath, mGesturePaint);
}
}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 0497344..ec8fd96 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -7157,8 +7157,10 @@
getLocationInWindow(location);
final AttachInfo info = mAttachInfo;
- location[0] += info.mWindowLeft;
- location[1] += info.mWindowTop;
+ if (info != null) {
+ location[0] += info.mWindowLeft;
+ location[1] += info.mWindowTop;
+ }
}
/**
diff --git a/core/java/com/android/internal/backup/IBackupTransport.aidl b/core/java/com/android/internal/backup/IBackupTransport.aidl
index 9daabca..84ed729 100644
--- a/core/java/com/android/internal/backup/IBackupTransport.aidl
+++ b/core/java/com/android/internal/backup/IBackupTransport.aidl
@@ -42,11 +42,14 @@
*/
/**
* Verify that this is a suitable time for a backup pass. This should return zero
- * if a backup is reasonable right now, false otherwise. This method will be called
- * outside of the {@link #startSession}/{@link #endSession} pair.
+ * if a backup is reasonable right now, some positive value otherwise. This method
+ * will be called outside of the {@link #startSession}/{@link #endSession} pair.
*
- * <p>If this is not a suitable time for a backup, the transport should suggest a
+ * <p>If this is not a suitable time for a backup, the transport should return a
* backoff delay, in milliseconds, after which the Backup Manager should try again.
+ *
+ * @return Zero if this is a suitable time for a backup pass, or a positive time delay
+ * in milliseconds to suggest deferring the backup pass for a while.
*/
long requestBackupTime();
diff --git a/core/java/com/android/internal/backup/LocalTransport.java b/core/java/com/android/internal/backup/LocalTransport.java
index f7b89f2..123c072 100644
--- a/core/java/com/android/internal/backup/LocalTransport.java
+++ b/core/java/com/android/internal/backup/LocalTransport.java
@@ -84,7 +84,7 @@
bufSize = dataSize;
buf = new byte[bufSize];
}
- changeSet.readEntityData(buf, dataSize);
+ changeSet.readEntityData(buf, 0, dataSize);
if (DEBUG) Log.v(TAG, " + data size " + dataSize);
File entityFile = new File(packageDir, key);
@@ -112,11 +112,9 @@
// Restore handling
public RestoreSet[] getAvailableRestoreSets() throws android.os.RemoteException {
// one hardcoded restore set
- RestoreSet[] set = new RestoreSet[1];
- set[0].device = "flash";
- set[0].name = "Local disk image";
- set[0].token = 0;
- return set;
+ RestoreSet set = new RestoreSet("Local disk image", "flash", 0);
+ RestoreSet[] array = { set };
+ return array;
}
public PackageInfo[] getAppSet(int token) throws android.os.RemoteException {
diff --git a/core/jni/android_backup_BackupDataInput.cpp b/core/jni/android_backup_BackupDataInput.cpp
index 5b2fb73..cf8a8e8 100644
--- a/core/jni/android_backup_BackupDataInput.cpp
+++ b/core/jni/android_backup_BackupDataInput.cpp
@@ -55,18 +55,13 @@
readNextHeader_native(JNIEnv* env, jobject clazz, int r, jobject entity)
{
int err;
+ bool done;
BackupDataReader* reader = (BackupDataReader*)r;
- err = reader->Status();
- if (err != 0) {
- return err < 0 ? err : -1;
- }
-
int type = 0;
- err = reader->ReadNextHeader(&type);
- if (err == EIO) {
- // Clean EOF with no footer block; just claim we're done
+ err = reader->ReadNextHeader(&done, &type);
+ if (done) {
return 1;
}
@@ -75,24 +70,12 @@
}
switch (type) {
- case BACKUP_HEADER_APP_V1:
- {
- String8 packageName;
- int cookie;
- err = reader->ReadAppHeader(&packageName, &cookie);
- if (err != 0) {
- LOGD("ReadAppHeader() returned %d; aborting", err);
- return err < 0 ? err : -1;
- }
- break;
- }
case BACKUP_HEADER_ENTITY_V1:
{
String8 key;
size_t dataSize;
err = reader->ReadEntityHeader(&key, &dataSize);
if (err != 0) {
- LOGD("ReadEntityHeader(); aborting", err);
return err < 0 ? err : -1;
}
// TODO: Set the fields in the entity object
@@ -101,10 +84,6 @@
env->SetIntField(entity, s_dataSizeField, dataSize);
return 0;
}
- case BACKUP_FOOTER_APP_V1:
- {
- break;
- }
default:
LOGD("Unknown header type: 0x%08x\n", type);
return -1;
@@ -115,12 +94,12 @@
}
static jint
-readEntityData_native(JNIEnv* env, jobject clazz, int r, jbyteArray data, int size)
+readEntityData_native(JNIEnv* env, jobject clazz, int r, jbyteArray data, int offset, int size)
{
int err;
BackupDataReader* reader = (BackupDataReader*)r;
- if (env->GetArrayLength(data) < size) {
+ if (env->GetArrayLength(data) < (size+offset)) {
// size mismatch
return -1;
}
@@ -130,19 +109,31 @@
return -2;
}
- err = reader->ReadEntityData(dataBytes, size);
+ err = reader->ReadEntityData(dataBytes+offset, size);
env->ReleaseByteArrayElements(data, dataBytes, 0);
return err;
}
+static jint
+skipEntityData_native(JNIEnv* env, jobject clazz, int r)
+{
+ int err;
+ BackupDataReader* reader = (BackupDataReader*)r;
+
+ err = reader->SkipEntityData();
+
+ return err;
+}
+
static const JNINativeMethod g_methods[] = {
{ "ctor", "(Ljava/io/FileDescriptor;)I", (void*)ctor_native },
{ "dtor", "(I)V", (void*)dtor_native },
{ "readNextHeader_native", "(ILandroid/backup/BackupDataInput$EntityHeader;)I",
(void*)readNextHeader_native },
- { "readEntityData_native", "(I[BI)I", (void*)readEntityData_native },
+ { "readEntityData_native", "(I[BII)I", (void*)readEntityData_native },
+ { "skipEntityData_native", "(I)I", (void*)skipEntityData_native },
};
int register_android_backup_BackupDataInput(JNIEnv* env)
diff --git a/include/tts/TtsEngine.h b/include/tts/TtsEngine.h
index d2aa30e..8486532 100644
--- a/include/tts/TtsEngine.h
+++ b/include/tts/TtsEngine.h
@@ -99,14 +99,18 @@
// @param size length of the language value
// @return TTS_SUCCESS, or TTS_FAILURE
virtual tts_result loadLanguage(const char *value, const size_t size);
-
- // Signal the engine to use the specified language. This will force the
- // language to be loaded if it wasn't loaded previously with loadLanguage().
- // See loadLanguage for the specification of the language.
- // @param value pointer to the language value
- // @param size length of the language value
+
+ // Load the resources associated with the specified language, country and Locale variant.
+ // The loaded language will only be used once a call to setLanguageFromLocale() with the same
+ // language value is issued. Language and country values are coded according to the ISO three
+ // letter codes for languages and countries, as can be retrieved from a java.util.Locale
+ // instance. The variant value is encoded as the variant string retrieved from a
+ // java.util.Locale instance built with that variant data.
+ // @param lang pointer to the ISO three letter code for the language
+ // @param country pointer to the ISO three letter code for the country
+ // @param variant pointer to the variant code
// @return TTS_SUCCESS, or TTS_FAILURE
- virtual tts_result setLanguage(const char *value, const size_t size);
+ virtual tts_result setLanguage(const char *lang, const char *country, const char *variant);
// Retrieve the currently set language, or an empty "value" if no language
// has been set.
diff --git a/include/utils/BackupHelpers.h b/include/utils/BackupHelpers.h
index f60f4ea..3ca8ad2 100644
--- a/include/utils/BackupHelpers.h
+++ b/include/utils/BackupHelpers.h
@@ -23,30 +23,15 @@
namespace android {
enum {
- BACKUP_HEADER_APP_V1 = 0x31707041, // App1 (little endian)
BACKUP_HEADER_ENTITY_V1 = 0x61746144, // Data (little endian)
- BACKUP_FOOTER_APP_V1 = 0x746f6f46, // Foot (little endian)
};
-// the sizes of all of these match.
-typedef struct {
- int type; // == BACKUP_HEADER_APP_V1
- int packageLen; // length of the name of the package that follows, not including the null.
- int cookie;
-} app_header_v1;
-
typedef struct {
int type; // BACKUP_HEADER_ENTITY_V1
int keyLen; // length of the key name, not including the null terminator
int dataSize; // size of the data, not including the padding, -1 means delete
} entity_header_v1;
-typedef struct {
- int type; // BACKUP_FOOTER_APP_V1
- int entityCount; // the number of entities that were written
- int cookie;
-} app_footer_v1;
-
/**
* Writes the data.
@@ -61,13 +46,9 @@
// does not close fd
~BackupDataWriter();
- status_t WriteAppHeader(const String8& packageName, int cookie);
-
status_t WriteEntityHeader(const String8& key, size_t dataSize);
status_t WriteEntityData(const void* data, size_t size);
- status_t WriteAppFooter(int cookie);
-
private:
explicit BackupDataWriter();
status_t write_padding_for(int n);
@@ -92,28 +73,26 @@
~BackupDataReader();
status_t Status();
- status_t ReadNextHeader(int* type = NULL);
+ status_t ReadNextHeader(bool* done, int* type);
- status_t ReadAppHeader(String8* packageName, int* cookie);
bool HasEntities();
status_t ReadEntityHeader(String8* key, size_t* dataSize);
status_t SkipEntityData(); // must be called with the pointer at the begining of the data.
status_t ReadEntityData(void* data, size_t size);
- status_t ReadAppFooter(int* cookie);
private:
explicit BackupDataReader();
status_t skip_padding();
int m_fd;
+ bool m_done;
status_t m_status;
ssize_t m_pos;
+ ssize_t m_dataEndPos;
int m_entityCount;
union {
int type;
- app_header_v1 app;
entity_header_v1 entity;
- app_footer_v1 footer;
} m_header;
};
diff --git a/keystore/java/android/security/Keystore.java b/keystore/java/android/security/Keystore.java
index 3f83473..ce3fa88 100644
--- a/keystore/java/android/security/Keystore.java
+++ b/keystore/java/android/security/Keystore.java
@@ -30,6 +30,7 @@
return new FileKeystore();
}
+ // for compatiblity, start from here
/**
*/
public abstract String getUserkey(String key);
@@ -46,15 +47,70 @@
*/
public abstract String[] getAllUserkeyKeys();
+ // to here
+
+ /**
+ */
+ public abstract String getCaCertificate(String key);
+
+ /**
+ */
+ public abstract String getUserCertificate(String key);
+
+ /**
+ */
+ public abstract String getUserPrivateKey(String key);
+
+ /**
+ * Returns the array of the certificate keynames in keystore if successful.
+ * Or return an empty array if error.
+ *
+ * @return array of the certificate keynames
+ */
+ public abstract String[] getAllUserCertificateKeys();
+
+ /**
+ */
+ public abstract String[] getAllCaCertificateKeys();
+
+ /**
+ */
+ public abstract String[] getSupportedKeyStrenghs();
+
+ /**
+ * Generates a key pair and returns the certificate request.
+ * @param keyStrengthIndex index to the array of supported key strengths
+ * @param challenge the challenge message in the keygen tag
+ * @param organizations the organization string, e.g.,
+ * "/C=US/ST={state}/L={city}/O={company}/OU={app}/CN={hostname}"
+ * @return the certificate request
+ */
+ public abstract String generateKeyPair(
+ int keyStrengthIndex, String challenge, String organizations);
+
+ public abstract void addCertificate(String cert);
+
private static class FileKeystore extends Keystore {
private static final String SERVICE_NAME = "keystore";
+ private static final String LIST_CA_CERTIFICATES = "listcacerts";
+ private static final String LIST_USER_CERTIFICATES = "listusercerts";
+ private static final String GET_CA_CERTIFICATE = "getcacert";
+ private static final String GET_USER_CERTIFICATE = "getusercert";
+ private static final String GET_USER_KEY = "getuserkey";
+ private static final String ADD_CA_CERTIFICATE = "addcacert";
+ private static final String ADD_USER_CERTIFICATE = "addusercert";
+ private static final String ADD_USER_KEY = "adduserkey";
+ private static final String COMMAND_DELIMITER = "\t";
+ private static final ServiceCommand mServiceCommand =
+ new ServiceCommand(SERVICE_NAME);
+
+ // for compatiblity, start from here
+
private static final String LIST_CERTIFICATES = "listcerts";
private static final String LIST_USERKEYS = "listuserkeys";
private static final String PATH = "/data/misc/keystore/";
private static final String USERKEY_PATH = PATH + "userkeys/";
private static final String CERT_PATH = PATH + "certs/";
- private static final ServiceCommand mServiceCommand =
- new ServiceCommand(SERVICE_NAME);
@Override
public String getUserkey(String key) {
@@ -66,12 +122,6 @@
return CERT_PATH + key;
}
- /**
- * Returns the array of the certificate names in keystore if successful.
- * Or return an empty array if error.
- *
- * @return array of the certificates
- */
@Override
public String[] getAllCertificateKeys() {
try {
@@ -83,12 +133,6 @@
}
}
- /**
- * Returns the array of the names of private keys in keystore if successful.
- * Or return an empty array if errors.
- *
- * @return array of the user keys
- */
@Override
public String[] getAllUserkeyKeys() {
try {
@@ -99,5 +143,103 @@
return NOTFOUND;
}
}
+
+ // to here
+
+ @Override
+ public String getUserPrivateKey(String key) {
+ return mServiceCommand.execute(
+ GET_USER_KEY + COMMAND_DELIMITER + key);
+ }
+
+ @Override
+ public String getUserCertificate(String key) {
+ return mServiceCommand.execute(
+ GET_USER_CERTIFICATE + COMMAND_DELIMITER + key);
+ }
+
+ @Override
+ public String getCaCertificate(String key) {
+ return mServiceCommand.execute(
+ GET_CA_CERTIFICATE + COMMAND_DELIMITER + key);
+ }
+
+ @Override
+ public String[] getAllUserCertificateKeys() {
+ try {
+ String result = mServiceCommand.execute(LIST_USER_CERTIFICATES);
+ if (result != null) return result.split("\\s+");
+ return NOTFOUND;
+ } catch (NumberFormatException ex) {
+ return NOTFOUND;
+ }
+ }
+
+ @Override
+ public String[] getAllCaCertificateKeys() {
+ try {
+ String result = mServiceCommand.execute(LIST_CA_CERTIFICATES);
+ if (result != null) return result.split("\\s+");
+ return NOTFOUND;
+ } catch (NumberFormatException ex) {
+ return NOTFOUND;
+ }
+ }
+
+ @Override
+ public String[] getSupportedKeyStrenghs() {
+ // TODO: real implementation
+ return new String[] {"High Grade", "Medium Grade"};
+ }
+
+ @Override
+ public String generateKeyPair(int keyStrengthIndex, String challenge,
+ String organizations) {
+ // TODO: real implementation
+ return "-----BEGIN CERTIFICATE REQUEST-----"
+ + "\nMIICzjCCAbYCAQAwgYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh"
+ + "\nMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRMwEQYDVQQKEwpHb29nbGUgSW5jMRYw"
+ + "\nFAYDVQQLEw1SZW1vdGUgQWNjZXNzMRAwDgYDVQQLEwdHbGFwdG9wMQ0wCwYDVQQD"
+ + "\nEwR0ZXN0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAznwy7a16O35u"
+ + "\nODLQOw6yHAxozrrX1J+c0reiIh8GYohwKrBedFnQ/FnTls6bxY4fNHD+SZvFFgvU"
+ + "\nECBFOfRmRm7AFo51qT0t2a8qgvDLM6L1qGkmy94W28Q3OlcpF2QianHYdjyGT+Ac"
+ + "\nYDek1Zi/E/mdPzuVM/K8tkB7n8ktC0PTm1ZtdMRauE5R0WrEhWuF6In/2gy1Q/Zh"
+ + "\noy7/zQqpbPl2ouulvkx1Y3OXHM6XPNFLoHS1gH0HyAuBUokO0QmetRn6ngJSvz7e"
+ + "\nVD7QYRppGp+g4BxqaV9XSxhaaKrMs4PAld9enV51X9qjvjCRBve2QxtuJgMfGJdU"
+ + "\njGr/JweZoQIDAQABoAAwDQYJKoZIhvcNAQEFBQADggEBADtxOtEseoLOVYh6sh4b"
+ + "\nWCdngK87uHn2bdGipFwKdNTxQDdxNQLAKdoGYIfbVsC1cDgFiufeNwVukxxymdnm"
+ + "\nk0GGK+0O0tZKENv8ysgfbgEsHpJH9FoR5Y5XEq1etejkcgCp59dyhrSk0DLyVm0D"
+ + "\nIfTC/nsK95H7AAGOkbbDFo2otyLNNrthYncQ9diAG0UzzLacA+86JXZmD3HyC48u"
+ + "\nI9hsivVnTTfl9afcfVAhfxbQ6HgkhZZjbjFjfABSd4v8wKlAAqK58VxCajNVOVcV"
+ + "\ncCzOWf6NpE7xEHCf32i8bWDP6hi0WgQcdpQwnZNKhhTLGNb23Uty6HYlJhbxexC7"
+ + "\nUoM="
+ + "\n-----END CERTIFICATE REQUEST-----";
+ }
+
+ @Override
+ public void addCertificate(String cert) {
+ // TODO: real implementation
+ }
+
+ private boolean addUserCertificate(String key, String certificate,
+ String privateKey) {
+ if(mServiceCommand.execute(ADD_USER_CERTIFICATE + COMMAND_DELIMITER
+ + key + COMMAND_DELIMITER + certificate) != null) {
+ if (mServiceCommand.execute(ADD_USER_KEY + COMMAND_DELIMITER
+ + key + COMMAND_DELIMITER + privateKey) != null) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private boolean addCaCertificate(String key, String content) {
+ if (mServiceCommand.execute(ADD_CA_CERTIFICATE + COMMAND_DELIMITER
+ + key + COMMAND_DELIMITER + content) != null) {
+ return true;
+ }
+ return false;
+ }
+
}
}
diff --git a/libs/utils/BackupData.cpp b/libs/utils/BackupData.cpp
index 8c9f875..16ff1e5 100644
--- a/libs/utils/BackupData.cpp
+++ b/libs/utils/BackupData.cpp
@@ -86,46 +86,6 @@
}
status_t
-BackupDataWriter::WriteAppHeader(const String8& packageName, int cookie)
-{
- if (m_status != NO_ERROR) {
- return m_status;
- }
-
- ssize_t amt;
-
- amt = write_padding_for(m_pos);
- if (amt != 0) {
- return amt;
- }
-
- app_header_v1 header;
- ssize_t nameLen;
-
- nameLen = packageName.length();
-
- header.type = tolel(BACKUP_HEADER_APP_V1);
- header.packageLen = tolel(nameLen);
- header.cookie = cookie;
-
- amt = write(m_fd, &header, sizeof(app_header_v1));
- if (amt != sizeof(app_header_v1)) {
- m_status = errno;
- return m_status;
- }
- m_pos += amt;
-
- amt = write(m_fd, packageName.string(), nameLen+1);
- if (amt != nameLen+1) {
- m_status = errno;
- return m_status;
- }
- m_pos += amt;
-
- return NO_ERROR;
-}
-
-status_t
BackupDataWriter::WriteEntityHeader(const String8& key, size_t dataSize)
{
if (m_status != NO_ERROR) {
@@ -188,40 +148,11 @@
return NO_ERROR;
}
-status_t
-BackupDataWriter::WriteAppFooter(int cookie)
-{
- if (m_status != NO_ERROR) {
- return m_status;
- }
-
- ssize_t amt;
-
- amt = write_padding_for(m_pos);
- if (amt != 0) {
- return amt;
- }
-
- app_footer_v1 footer;
- ssize_t nameLen;
-
- footer.type = tolel(BACKUP_FOOTER_APP_V1);
- footer.entityCount = tolel(m_entityCount);
- footer.cookie = cookie;
-
- amt = write(m_fd, &footer, sizeof(app_footer_v1));
- if (amt != sizeof(app_footer_v1)) {
- m_status = errno;
- return m_status;
- }
- m_pos += amt;
-
- return NO_ERROR;
-}
BackupDataReader::BackupDataReader(int fd)
:m_fd(fd),
+ m_done(false),
m_status(NO_ERROR),
m_pos(0),
m_entityCount(0)
@@ -260,31 +191,25 @@
} while(0)
status_t
-BackupDataReader::ReadNextHeader(int* type)
+BackupDataReader::ReadNextHeader(bool* done, int* type)
{
+ *done = m_done;
if (m_status != NO_ERROR) {
return m_status;
}
int amt;
- SKIP_PADDING();
+ // No error checking here, in case we're at the end of the stream. Just let read() fail.
+ skip_padding();
amt = read(m_fd, &m_header, sizeof(m_header));
+ *done = m_done = (amt == 0);
CHECK_SIZE(amt, sizeof(m_header));
// validate and fix up the fields.
m_header.type = fromlel(m_header.type);
switch (m_header.type)
{
- case BACKUP_HEADER_APP_V1:
- m_header.app.packageLen = fromlel(m_header.app.packageLen);
- if (m_header.app.packageLen < 0) {
- LOGD("App header at %d has packageLen<0: 0x%08x\n", (int)m_pos,
- (int)m_header.app.packageLen);
- m_status = EINVAL;
- }
- m_header.app.cookie = m_header.app.cookie;
- break;
case BACKUP_HEADER_ENTITY_V1:
m_header.entity.keyLen = fromlel(m_header.entity.keyLen);
if (m_header.entity.keyLen <= 0) {
@@ -295,15 +220,6 @@
m_header.entity.dataSize = fromlel(m_header.entity.dataSize);
m_entityCount++;
break;
- case BACKUP_FOOTER_APP_V1:
- m_header.footer.entityCount = fromlel(m_header.footer.entityCount);
- if (m_header.footer.entityCount < 0) {
- LOGD("Entity header at %d has entityCount<0: 0x%08x\n", (int)m_pos,
- (int)m_header.footer.entityCount);
- m_status = EINVAL;
- }
- m_header.footer.cookie = m_header.footer.cookie;
- break;
default:
LOGD("Chunk header at %d has invalid type: 0x%08x", (int)m_pos, (int)m_header.type);
m_status = EINVAL;
@@ -316,30 +232,6 @@
return m_status;
}
-status_t
-BackupDataReader::ReadAppHeader(String8* packageName, int* cookie)
-{
- if (m_status != NO_ERROR) {
- return m_status;
- }
- if (m_header.type != BACKUP_HEADER_APP_V1) {
- return EINVAL;
- }
- size_t size = m_header.app.packageLen;
- char* buf = packageName->lockBuffer(size);
- if (buf == NULL) {
- packageName->unlockBuffer();
- m_status = ENOMEM;
- return m_status;
- }
- int amt = read(m_fd, buf, size+1);
- CHECK_SIZE(amt, (int)size+1);
- packageName->unlockBuffer(size);
- m_pos += size+1;
- *cookie = m_header.app.cookie;
- return NO_ERROR;
-}
-
bool
BackupDataReader::HasEntities()
{
@@ -368,6 +260,7 @@
m_pos += size+1;
*dataSize = m_header.entity.dataSize;
SKIP_PADDING();
+ m_dataEndPos = m_pos + *dataSize;
return NO_ERROR;
}
@@ -381,7 +274,7 @@
return EINVAL;
}
if (m_header.entity.dataSize > 0) {
- int pos = lseek(m_fd, m_header.entity.dataSize, SEEK_CUR);
+ int pos = lseek(m_fd, m_dataEndPos, SEEK_SET);
return pos == -1 ? (int)errno : (int)NO_ERROR;
} else {
return NO_ERROR;
@@ -394,6 +287,15 @@
if (m_status != NO_ERROR) {
return m_status;
}
+ int remaining = m_dataEndPos - m_pos;
+ if (size > remaining) {
+ printf("size=%d m_pos=0x%x m_dataEndPos=0x%x remaining=%d\n",
+ size, m_pos, m_dataEndPos, remaining);
+ size = remaining;
+ }
+ if (remaining <= 0) {
+ return 0;
+ }
int amt = read(m_fd, data, size);
CHECK_SIZE(amt, (int)size);
m_pos += size;
@@ -401,25 +303,6 @@
}
status_t
-BackupDataReader::ReadAppFooter(int* cookie)
-{
- if (m_status != NO_ERROR) {
- return m_status;
- }
- if (m_header.type != BACKUP_FOOTER_APP_V1) {
- return EINVAL;
- }
- if (m_header.footer.entityCount != m_entityCount) {
- LOGD("entity count mismatch actual=%d expected=%d", m_entityCount,
- m_header.footer.entityCount);
- m_status = EINVAL;
- return m_status;
- }
- *cookie = m_header.footer.cookie;
- return NO_ERROR;
-}
-
-status_t
BackupDataReader::skip_padding()
{
ssize_t amt;
diff --git a/libs/utils/BackupHelpers.cpp b/libs/utils/BackupHelpers.cpp
index 4c3e37d..c1d5404 100644
--- a/libs/utils/BackupHelpers.cpp
+++ b/libs/utils/BackupHelpers.cpp
@@ -689,41 +689,27 @@
// hexdump -v -e '" " 8/1 " 0x%02x," "\n"' data_writer.data
const unsigned char DATA_GOLDEN_FILE[] = {
- 0x41, 0x70, 0x70, 0x31, 0x0b, 0x00, 0x00, 0x00,
- 0xdd, 0xcc, 0xbb, 0xaa, 0x6e, 0x6f, 0x5f, 0x70,
- 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x00,
0x44, 0x61, 0x74, 0x61, 0x0b, 0x00, 0x00, 0x00,
0x0c, 0x00, 0x00, 0x00, 0x6e, 0x6f, 0x5f, 0x70,
0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x00,
0x6e, 0x6f, 0x5f, 0x70, 0x61, 0x64, 0x64, 0x69,
- 0x6e, 0x67, 0x5f, 0x00, 0x41, 0x70, 0x70, 0x31,
- 0x0c, 0x00, 0x00, 0x00, 0xdd, 0xcc, 0xbb, 0xaa,
+ 0x6e, 0x67, 0x5f, 0x00, 0x44, 0x61, 0x74, 0x61,
+ 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
0x70, 0x61, 0x64, 0x64, 0x65, 0x64, 0x5f, 0x74,
0x6f, 0x5f, 0x5f, 0x33, 0x00, 0xbc, 0xbc, 0xbc,
- 0x44, 0x61, 0x74, 0x61, 0x0c, 0x00, 0x00, 0x00,
- 0x0d, 0x00, 0x00, 0x00, 0x70, 0x61, 0x64, 0x64,
- 0x65, 0x64, 0x5f, 0x74, 0x6f, 0x5f, 0x5f, 0x33,
- 0x00, 0xbc, 0xbc, 0xbc, 0x70, 0x61, 0x64, 0x64,
- 0x65, 0x64, 0x5f, 0x74, 0x6f, 0x5f, 0x5f, 0x33,
- 0x00, 0xbc, 0xbc, 0xbc, 0x41, 0x70, 0x70, 0x31,
- 0x0d, 0x00, 0x00, 0x00, 0xdd, 0xcc, 0xbb, 0xaa,
0x70, 0x61, 0x64, 0x64, 0x65, 0x64, 0x5f, 0x74,
- 0x6f, 0x5f, 0x32, 0x5f, 0x5f, 0x00, 0xbc, 0xbc,
+ 0x6f, 0x5f, 0x5f, 0x33, 0x00, 0xbc, 0xbc, 0xbc,
0x44, 0x61, 0x74, 0x61, 0x0d, 0x00, 0x00, 0x00,
0x0e, 0x00, 0x00, 0x00, 0x70, 0x61, 0x64, 0x64,
0x65, 0x64, 0x5f, 0x74, 0x6f, 0x5f, 0x32, 0x5f,
0x5f, 0x00, 0xbc, 0xbc, 0x70, 0x61, 0x64, 0x64,
0x65, 0x64, 0x5f, 0x74, 0x6f, 0x5f, 0x32, 0x5f,
- 0x5f, 0x00, 0xbc, 0xbc, 0x41, 0x70, 0x70, 0x31,
- 0x0a, 0x00, 0x00, 0x00, 0xdd, 0xcc, 0xbb, 0xaa,
- 0x70, 0x61, 0x64, 0x64, 0x65, 0x64, 0x5f, 0x74,
- 0x6f, 0x31, 0x00, 0xbc, 0x44, 0x61, 0x74, 0x61,
+ 0x5f, 0x00, 0xbc, 0xbc, 0x44, 0x61, 0x74, 0x61,
0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
0x70, 0x61, 0x64, 0x64, 0x65, 0x64, 0x5f, 0x74,
0x6f, 0x31, 0x00, 0xbc, 0x70, 0x61, 0x64, 0x64,
- 0x65, 0x64, 0x5f, 0x74, 0x6f, 0x31, 0x00, 0xbc,
- 0x46, 0x6f, 0x6f, 0x74, 0x04, 0x00, 0x00, 0x00,
- 0x99, 0x99, 0x77, 0x77
+ 0x65, 0x64, 0x5f, 0x74, 0x6f, 0x31, 0x00
+
};
const int DATA_GOLDEN_FILE_SIZE = sizeof(DATA_GOLDEN_FILE);
@@ -733,12 +719,6 @@
int err;
String8 text(str);
- err = writer.WriteAppHeader(text, 0xaabbccdd);
- if (err != 0) {
- fprintf(stderr, "WriteAppHeader failed with %s\n", strerror(err));
- return err;
- }
-
err = writer.WriteEntityHeader(text, text.length()+1);
if (err != 0) {
fprintf(stderr, "WriteEntityHeader failed with %s\n", strerror(err));
@@ -779,8 +759,6 @@
err |= test_write_header_and_entity(writer, "padded_to_2__");
err |= test_write_header_and_entity(writer, "padded_to1");
- writer.WriteAppFooter(0x77779999);
-
close(fd);
err = compare_file(filename, DATA_GOLDEN_FILE, DATA_GOLDEN_FILE_SIZE);
@@ -800,70 +778,59 @@
String8 string;
int cookie = 0x11111111;
size_t actualSize;
+ bool done;
+ int type;
// printf("\n\n---------- test_read_header_and_entity -- %s\n\n", str);
- err = reader.ReadNextHeader();
+ err = reader.ReadNextHeader(&done, &type);
+ if (done) {
+ fprintf(stderr, "should not be done yet\n");
+ goto finished;
+ }
if (err != 0) {
fprintf(stderr, "ReadNextHeader (for app header) failed with %s\n", strerror(err));
- goto done;
+ goto finished;
}
-
- err = reader.ReadAppHeader(&string, &cookie);
- if (err != 0) {
- fprintf(stderr, "ReadAppHeader failed with %s\n", strerror(err));
- goto done;
- }
- if (string != str) {
- fprintf(stderr, "ReadAppHeader expected packageName '%s' got '%s'\n", str, string.string());
+ if (type != BACKUP_HEADER_ENTITY_V1) {
err = EINVAL;
- goto done;
- }
- if (cookie != (int)0xaabbccdd) {
- fprintf(stderr, "ReadAppHeader expected cookie 0x%08x got 0x%08x\n", 0xaabbccdd, cookie);
- err = EINVAL;
- goto done;
- }
-
- err = reader.ReadNextHeader();
- if (err != 0) {
- fprintf(stderr, "ReadNextHeader (for entity header) failed with %s\n", strerror(err));
- goto done;
+ fprintf(stderr, "type=0x%08x expected 0x%08x\n", type, BACKUP_HEADER_ENTITY_V1);
}
err = reader.ReadEntityHeader(&string, &actualSize);
if (err != 0) {
fprintf(stderr, "ReadEntityHeader failed with %s\n", strerror(err));
- goto done;
+ goto finished;
}
if (string != str) {
fprintf(stderr, "ReadEntityHeader expected key '%s' got '%s'\n", str, string.string());
err = EINVAL;
- goto done;
+ goto finished;
}
if ((int)actualSize != bufSize) {
fprintf(stderr, "ReadEntityHeader expected dataSize 0x%08x got 0x%08x\n", bufSize,
actualSize);
err = EINVAL;
- goto done;
+ goto finished;
}
err = reader.ReadEntityData(buf, bufSize);
if (err != NO_ERROR) {
fprintf(stderr, "ReadEntityData failed with %s\n", strerror(err));
- goto done;
+ goto finished;
}
if (0 != memcmp(buf, str, bufSize)) {
fprintf(stderr, "ReadEntityData expected '%s' but got something starting with "
- "%02x %02x %02x %02x\n", str, buf[0], buf[1], buf[2], buf[3]);
+ "%02x %02x %02x %02x '%c%c%c%c'\n", str, buf[0], buf[1], buf[2], buf[3],
+ buf[0], buf[1], buf[2], buf[3]);
err = EINVAL;
- goto done;
+ goto finished;
}
// The next read will confirm whether it got the right amount of data.
-done:
+finished:
if (err != NO_ERROR) {
fprintf(stderr, "test_read_header_and_entity failed with %s\n", strerror(err));
}
@@ -923,23 +890,6 @@
if (err == NO_ERROR) {
err = test_read_header_and_entity(reader, "padded_to1");
}
-
- if (err == NO_ERROR) {
- err = reader.ReadNextHeader();
- if (err != 0) {
- fprintf(stderr, "ReadNextHeader (for app header) failed with %s\n", strerror(err));
- }
-
- if (err == NO_ERROR) {
- int cookie;
- err |= reader.ReadAppFooter(&cookie);
- if (cookie != 0x77779999) {
- fprintf(stderr, "app footer cookie expected=0x%08x actual=0x%08x\n",
- 0x77779999, cookie);
- err = EINVAL;
- }
- }
- }
}
close(fd);
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index da15adf..937baad 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -668,7 +668,7 @@
mSpeakerIsOn = true;
mRoutes[AudioSystem.MODE_IN_CALL] = AudioSystem.ROUTE_SPEAKER;
incallMask = AudioSystem.ROUTE_ALL;
- } else if (mSpeakerIsOn) {
+ } else if (routes == 0 && mSpeakerIsOn) {
mSpeakerIsOn = false;
if (mBluetoothScoIsConnected) {
mRoutes[AudioSystem.MODE_IN_CALL] = AudioSystem.ROUTE_BLUETOOTH_SCO;
@@ -695,7 +695,7 @@
// should not affect A2DP routing
ringtoneMask = AudioSystem.ROUTE_ALL & ~AudioSystem.ROUTE_BLUETOOTH_A2DP;
normalMask = AudioSystem.ROUTE_ALL & ~AudioSystem.ROUTE_BLUETOOTH_A2DP;
- } else if (mBluetoothScoIsConnected) {
+ } else if (routes == 0 && mBluetoothScoIsConnected) {
mBluetoothScoIsConnected = false;
if (mHeadsetIsConnected) {
mRoutes[AudioSystem.MODE_IN_CALL] = AudioSystem.ROUTE_HEADSET;
@@ -739,7 +739,7 @@
ringtoneMask = AudioSystem.ROUTE_ALL & ~AudioSystem.ROUTE_BLUETOOTH_A2DP;
normalMask = AudioSystem.ROUTE_ALL & ~AudioSystem.ROUTE_BLUETOOTH_A2DP;
}
- } else if (mHeadsetIsConnected) {
+ } else if (routes == 0 && mHeadsetIsConnected) {
mHeadsetIsConnected = false;
// do not act upon headset disconnection if bluetooth SCO is connected to match phone app behavior
if (!mBluetoothScoIsConnected) {
@@ -772,7 +772,7 @@
// so there is no need to disable other routes.
ringtoneMask = AudioSystem.ROUTE_BLUETOOTH_A2DP;
normalMask = AudioSystem.ROUTE_BLUETOOTH_A2DP;
- } else if (mBluetoothA2dpIsConnected) {
+ } else if (routes == 0 && mBluetoothA2dpIsConnected) {
mBluetoothA2dpIsConnected = false;
mRoutes[AudioSystem.MODE_RINGTONE] &= ~AudioSystem.ROUTE_BLUETOOTH_A2DP;
mRoutes[AudioSystem.MODE_NORMAL] &= ~AudioSystem.ROUTE_BLUETOOTH_A2DP;
diff --git a/packages/TtsService/jni/android_tts_SynthProxy.cpp b/packages/TtsService/jni/android_tts_SynthProxy.cpp
index 582e6219..dfecfd8 100644
--- a/packages/TtsService/jni/android_tts_SynthProxy.cpp
+++ b/packages/TtsService/jni/android_tts_SynthProxy.cpp
@@ -269,7 +269,7 @@
}
}
-
+// TODO update to use language, country, variant
static void
android_tts_SynthProxy_setLanguage(JNIEnv *env, jobject thiz, jint jniData,
jstring language)
@@ -283,8 +283,10 @@
const char *langNativeString = env->GetStringUTFChars(language, 0);
// TODO check return codes
if (pSynthData->mNativeSynthInterface) {
- pSynthData->mNativeSynthInterface->setLanguage(langNativeString,
- strlen(langNativeString));
+ // TODO update to use language, country, variant
+ // commented out to not break the build
+ //pSynthData->mNativeSynthInterface->setLanguage(langNativeString,
+ // strlen(langNativeString));
}
env->ReleaseStringUTFChars(language, langNativeString);
}
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index 2f964ba..d842d34 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -68,7 +68,7 @@
class BackupManagerService extends IBackupManager.Stub {
private static final String TAG = "BackupManagerService";
private static final boolean DEBUG = true;
-
+
private static final long COLLECTION_INTERVAL = 1000;
//private static final long COLLECTION_INTERVAL = 3 * 60 * 1000;
@@ -90,7 +90,7 @@
private class BackupRequest {
public ApplicationInfo appInfo;
public boolean fullBackup;
-
+
BackupRequest(ApplicationInfo app, boolean isFull) {
appInfo = app;
fullBackup = isFull;
@@ -120,14 +120,17 @@
private final Object mClearDataLock = new Object();
private volatile boolean mClearingData;
+ // Current active transport & restore session
private int mTransportId;
+ private IBackupTransport mTransport;
+ private RestoreSession mActiveRestoreSession;
private File mStateDir;
private File mDataDir;
private File mJournalDir;
private File mJournal;
private RandomAccessFile mJournalStream;
-
+
public BackupManagerService(Context context) {
mContext = context;
mPackageManager = context.getPackageManager();
@@ -143,14 +146,16 @@
mJournalDir.mkdirs();
makeJournalLocked(); // okay because no other threads are running yet
- //!!! TODO: default to cloud transport, not local
- mTransportId = BackupManager.TRANSPORT_LOCAL;
-
// Build our mapping of uid to backup client services
synchronized (mBackupParticipants) {
addPackageParticipantsLocked(null);
}
+ // Stand up our default transport
+ //!!! TODO: default to cloud transport, not local
+ mTransportId = BackupManager.TRANSPORT_LOCAL;
+ mTransport = createTransport(mTransportId);
+
// Now that we know about valid backup participants, parse any
// leftover journal files and schedule a new backup pass
parseLeftoverJournals();
@@ -283,7 +288,7 @@
// deleted. If we crash prior to that, the old journal is parsed
// at next boot and the journaled requests fulfilled.
}
- (new PerformBackupThread(mTransportId, mBackupQueue, oldJournal)).run();
+ (new PerformBackupThread(mTransport, mBackupQueue, oldJournal)).run();
break;
case MSG_RUN_FULL_BACKUP:
@@ -395,7 +400,7 @@
}
return allApps;
}
-
+
// Reset the given package's known backup participants. Unlike add/remove, the update
// action cannot be passed a null package name.
void updatePackageParticipantsLocked(String packageName) {
@@ -427,7 +432,7 @@
break;
default:
- Log.e(TAG, "creating unknown transport " + transportID);
+ Log.e(TAG, "Asked for unknown transport " + transportID);
}
return transport;
}
@@ -495,7 +500,7 @@
throws android.os.RemoteException {
synchronized(mClearDataLock) {
mClearingData = false;
- notifyAll();
+ mClearDataLock.notifyAll();
}
}
}
@@ -504,13 +509,13 @@
class PerformBackupThread extends Thread {
private static final String TAG = "PerformBackupThread";
- int mTransport;
+ IBackupTransport mTransport;
ArrayList<BackupRequest> mQueue;
File mJournal;
- public PerformBackupThread(int transportId, ArrayList<BackupRequest> queue,
+ public PerformBackupThread(IBackupTransport transport, ArrayList<BackupRequest> queue,
File journal) {
- mTransport = transportId;
+ mTransport = transport;
mQueue = queue;
mJournal = journal;
}
@@ -519,15 +524,9 @@
public void run() {
if (DEBUG) Log.v(TAG, "Beginning backup of " + mQueue.size() + " targets");
- // stand up the current transport
- IBackupTransport transport = createTransport(mTransport);
- if (transport == null) {
- return;
- }
-
// start up the transport
try {
- transport.startSession();
+ mTransport.startSession();
} catch (Exception e) {
Log.e(TAG, "Error session transport");
e.printStackTrace();
@@ -535,11 +534,11 @@
}
// The transport is up and running; now run all the backups in our queue
- doQueuedBackups(transport);
+ doQueuedBackups(mTransport);
// Finally, tear down the transport
try {
- transport.endSession();
+ mTransport.endSession();
} catch (Exception e) {
Log.e(TAG, "Error ending transport");
e.printStackTrace();
@@ -849,8 +848,26 @@
// a backup pass for each of them.
Log.d(TAG, "dataChanged packageName=" + packageName);
-
- HashSet<ApplicationInfo> targets = mBackupParticipants.get(Binder.getCallingUid());
+
+ // If the caller does not hold the BACKUP permission, it can only request a
+ // backup of its own data.
+ HashSet<ApplicationInfo> targets;
+ if ((mContext.checkPermission("android.permission.BACKUP", Binder.getCallingPid(),
+ Binder.getCallingUid())) == PackageManager.PERMISSION_DENIED) {
+ targets = mBackupParticipants.get(Binder.getCallingUid());
+ } else {
+ // a caller with full permission can ask to back up any participating app
+ // !!! TODO: allow backup of ANY app?
+ if (DEBUG) Log.v(TAG, "Privileged caller, allowing backup of other apps");
+ targets = new HashSet<ApplicationInfo>();
+ int N = mBackupParticipants.size();
+ for (int i = 0; i < N; i++) {
+ HashSet<ApplicationInfo> s = mBackupParticipants.valueAt(i);
+ if (s != null) {
+ targets.addAll(s);
+ }
+ }
+ }
if (targets != null) {
synchronized (mQueueLock) {
// Note that this client has made data changes that need to be backed up
@@ -920,8 +937,14 @@
public int selectBackupTransport(int transportId) {
mContext.enforceCallingPermission("android.permission.BACKUP", "selectBackupTransport");
- int prevTransport = mTransportId;
- mTransportId = transportId;
+ int prevTransport = -1;
+ IBackupTransport newTransport = createTransport(transportId);
+ if (newTransport != null) {
+ // !!! TODO: a method on the old transport that says it's being deactivated?
+ mTransport = newTransport;
+ prevTransport = mTransportId;
+ mTransportId = transportId;
+ }
return prevTransport;
}
@@ -962,12 +985,22 @@
// Hand off a restore session
public IRestoreSession beginRestoreSession(int transportID) {
mContext.enforceCallingPermission("android.permission.BACKUP", "beginRestoreSession");
- return null;
+
+ synchronized(this) {
+ if (mActiveRestoreSession != null) {
+ Log.d(TAG, "Restore session requested but one already active");
+ return null;
+ }
+ mActiveRestoreSession = new RestoreSession(transportID);
+ }
+ return mActiveRestoreSession;
}
// ----- Restore session -----
class RestoreSession extends IRestoreSession.Stub {
+ private static final String TAG = "RestoreSession";
+
private IBackupTransport mRestoreTransport = null;
RestoreSet[] mRestoreSets = null;
@@ -980,12 +1013,18 @@
mContext.enforceCallingPermission("android.permission.BACKUP",
"getAvailableRestoreSets");
+ try {
synchronized(this) {
if (mRestoreSets == null) {
mRestoreSets = mRestoreTransport.getAvailableRestoreSets();
}
return mRestoreSets;
}
+ } catch (RuntimeException e) {
+ Log.d(TAG, "getAvailableRestoreSets exception");
+ e.printStackTrace();
+ throw e;
+ }
}
public int performRestore(int token) throws android.os.RemoteException {
@@ -1001,6 +1040,8 @@
return 0;
}
}
+ } else {
+ if (DEBUG) Log.v(TAG, "No current restore set, not doing restore");
}
return -1;
}
@@ -1011,6 +1052,13 @@
mRestoreTransport.endSession();
mRestoreTransport = null;
+ synchronized(BackupManagerService.this) {
+ if (BackupManagerService.this.mActiveRestoreSession == this) {
+ BackupManagerService.this.mActiveRestoreSession = null;
+ } else {
+ Log.e(TAG, "ending non-current restore session");
+ }
+ }
}
}
diff --git a/telephony/java/com/android/internal/telephony/DataConnection.java b/telephony/java/com/android/internal/telephony/DataConnection.java
index 6e9d1ab..7809fed 100644
--- a/telephony/java/com/android/internal/telephony/DataConnection.java
+++ b/telephony/java/com/android/internal/telephony/DataConnection.java
@@ -55,57 +55,83 @@
public enum FailCause {
NONE,
- BAD_APN,
- BAD_PAP_SECRET,
- BARRED,
+ OPERATOR_BARRED,
+ INSUFFICIENT_RESOURCES,
+ MISSING_UKNOWN_APN,
+ UNKNOWN_PDP_ADDRESS,
USER_AUTHENTICATION,
+ ACTIVATION_REJECT_GGSN,
+ ACTIVATION_REJECT_UNSPECIFIED,
SERVICE_OPTION_NOT_SUPPORTED,
SERVICE_OPTION_NOT_SUBSCRIBED,
- SIM_LOCKED,
- RADIO_OFF,
- NO_SIGNAL,
- NO_DATA_PLAN,
+ SERVICE_OPTION_OUT_OF_ORDER,
+ NSAPI_IN_USE,
+ PROTOCOL_ERRORS,
+ REGISTRATION_FAIL,
+ GPRS_REGISTRATION_FAIL,
+ UNKNOWN,
+
RADIO_NOT_AVAILABLE,
- SUSPENED_TEMPORARY,
- RADIO_ERROR_RETRY,
- UNKNOWN;
+ RADIO_ERROR_RETRY;
public boolean isPermanentFail() {
- return (this == RADIO_OFF);
+ return (this == OPERATOR_BARRED) || (this == MISSING_UKNOWN_APN) ||
+ (this == UNKNOWN_PDP_ADDRESS) || (this == USER_AUTHENTICATION) ||
+ (this == ACTIVATION_REJECT_GGSN) || (this == ACTIVATION_REJECT_UNSPECIFIED) ||
+ (this == SERVICE_OPTION_NOT_SUPPORTED) ||
+ (this == SERVICE_OPTION_NOT_SUBSCRIBED) || (this == NSAPI_IN_USE) ||
+ (this == PROTOCOL_ERRORS);
}
+ public boolean isEventLoggable() {
+ return (this == OPERATOR_BARRED) || (this == INSUFFICIENT_RESOURCES) ||
+ (this == UNKNOWN_PDP_ADDRESS) || (this == USER_AUTHENTICATION) ||
+ (this == ACTIVATION_REJECT_GGSN) || (this == ACTIVATION_REJECT_UNSPECIFIED) ||
+ (this == SERVICE_OPTION_NOT_SUBSCRIBED) ||
+ (this == SERVICE_OPTION_NOT_SUPPORTED) ||
+ (this == SERVICE_OPTION_OUT_OF_ORDER) || (this == NSAPI_IN_USE) ||
+ (this == PROTOCOL_ERRORS);
+ }
+
+ @Override
public String toString() {
switch (this) {
case NONE:
- return "no error";
- case BAD_APN:
- return "bad apn";
- case BAD_PAP_SECRET:
- return "bad pap secret";
- case BARRED:
- return "barred";
+ return "No Error";
+ case OPERATOR_BARRED:
+ return "Operator Barred";
+ case INSUFFICIENT_RESOURCES:
+ return "Insufficient Resources";
+ case MISSING_UKNOWN_APN:
+ return "Missing / Unknown APN";
+ case UNKNOWN_PDP_ADDRESS:
+ return "Unknown PDP Address";
case USER_AUTHENTICATION:
- return "error user autentication";
+ return "Error User Autentication";
+ case ACTIVATION_REJECT_GGSN:
+ return "Activation Reject GGSN";
+ case ACTIVATION_REJECT_UNSPECIFIED:
+ return "Activation Reject unspecified";
case SERVICE_OPTION_NOT_SUPPORTED:
- return "data not supported";
+ return "Data Not Supported";
case SERVICE_OPTION_NOT_SUBSCRIBED:
- return "datt not subcribed";
- case SIM_LOCKED:
- return "sim locked";
- case RADIO_OFF:
- return "radio is off";
- case NO_SIGNAL:
- return "no signal";
- case NO_DATA_PLAN:
- return "no data plan";
+ return "Data Not subscribed";
+ case SERVICE_OPTION_OUT_OF_ORDER:
+ return "Data Services Out of Order";
+ case NSAPI_IN_USE:
+ return "NSAPI in use";
+ case PROTOCOL_ERRORS:
+ return "Protocol Errors";
+ case REGISTRATION_FAIL:
+ return "Network Registration Failure";
+ case GPRS_REGISTRATION_FAIL:
+ return "Data Network Registration Failure";
case RADIO_NOT_AVAILABLE:
- return "radio not available";
- case SUSPENED_TEMPORARY:
- return "suspend temporary";
+ return "Radio Not Available";
case RADIO_ERROR_RETRY:
- return "transient radio error";
+ return "Transient Radio Rrror";
default:
- return "unknown data error";
+ return "Unknown Data Error";
}
}
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java
index a9c0f46..f2b07a8 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java
@@ -233,7 +233,7 @@
switch (rilCause) {
case PS_NET_DOWN_REASON_OPERATOR_DETERMINED_BARRING:
- cause = FailCause.BARRED;
+ cause = FailCause.OPERATOR_BARRED;
break;
case PS_NET_DOWN_REASON_AUTH_FAILED:
cause = FailCause.USER_AUTHENTICATION;
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
index c922cec..2a65de3 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
@@ -746,16 +746,9 @@
// No try for permanent failure
if (cause.isPermanentFail()) {
notifyNoData(cause);
+ return;
}
-
- if (tryAgain(cause)) {
- // Wait a bit before trying again, so that
- // we're not tying up the RIL command channel
- sendMessageDelayed(obtainMessage(EVENT_TRY_SETUP_DATA, reason),
- RECONNECT_DELAY_INITIAL_MILLIS);
- } else {
- startDelayedRetry(cause, reason);
- }
+ startDelayedRetry(cause, reason);
}
}
@@ -812,14 +805,6 @@
cleanUpConnection(tearDown, reason);
}
- private boolean tryAgain(FailCause cause) {
- return (cause != FailCause.RADIO_NOT_AVAILABLE)
- && (cause != FailCause.RADIO_OFF)
- && (cause != FailCause.RADIO_ERROR_RETRY)
- && (cause != FailCause.NO_SIGNAL)
- && (cause != FailCause.SIM_LOCKED);
- }
-
private void createAllDataConnectionList() {
dataConnectionList = new ArrayList<DataConnection>();
CdmaDataConnection dataConn;
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
index 71af406..035c690 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
@@ -588,7 +588,7 @@
waitingApns = buildWaitingApns();
if (waitingApns.isEmpty()) {
if (DBG) log("No APN found");
- notifyNoData(PdpConnection.FailCause.BAD_APN);
+ notifyNoData(PdpConnection.FailCause.MISSING_UKNOWN_APN);
return false;
} else {
log ("Create from allApns : " + apnListToString(allApns));
@@ -1315,13 +1315,7 @@
cause = (PdpConnection.FailCause) (ar.result);
if(DBG) log("PDP setup failed " + cause);
// Log this failure to the Event Logs.
- if (cause == PdpConnection.FailCause.BAD_APN ||
- cause == PdpConnection.FailCause.BAD_PAP_SECRET ||
- cause == PdpConnection.FailCause.BARRED ||
- cause == PdpConnection.FailCause.RADIO_ERROR_RETRY ||
- cause == PdpConnection.FailCause.SUSPENED_TEMPORARY ||
- cause == PdpConnection.FailCause.UNKNOWN ||
- cause == PdpConnection.FailCause.USER_AUTHENTICATION) {
+ if (cause.isEventLoggable()) {
int cid = -1;
GsmCellLocation loc = ((GsmCellLocation)phone.getCellLocation());
if (loc != null) cid = loc.getCid();
@@ -1335,23 +1329,20 @@
// No try for permanent failure
if (cause.isPermanentFail()) {
notifyNoData(cause);
+ return;
}
- if (tryNextApn(cause)) {
- waitingApns.remove(0);
- if (waitingApns.isEmpty()) {
- // No more to try, start delayed retry
- startDelayedRetry(cause, reason);
- } else {
- // we still have more apns to try
- setState(State.SCANNING);
- // Wait a bit before trying the next APN, so that
- // we're not tying up the RIL command channel
- sendMessageDelayed(obtainMessage(EVENT_TRY_SETUP_DATA, reason),
- RECONNECT_DELAY_INITIAL_MILLIS);
- }
- } else {
+ waitingApns.remove(0);
+ if (waitingApns.isEmpty()) {
+ // No more to try, start delayed retry
startDelayedRetry(cause, reason);
+ } else {
+ // we still have more apns to try
+ setState(State.SCANNING);
+ // Wait a bit before trying the next APN, so that
+ // we're not tying up the RIL command channel
+ sendMessageDelayed(obtainMessage(EVENT_TRY_SETUP_DATA, reason),
+ RECONNECT_DELAY_INITIAL_MILLIS);
}
}
}
@@ -1406,14 +1397,6 @@
cleanUpConnection(tearDown, reason);
}
- private boolean tryNextApn(FailCause cause) {
- return (cause != FailCause.RADIO_NOT_AVAILABLE)
- && (cause != FailCause.RADIO_OFF)
- && (cause != FailCause.RADIO_ERROR_RETRY)
- && (cause != FailCause.NO_SIGNAL)
- && (cause != FailCause.SIM_LOCKED);
- }
-
private int getRestoreDefaultApnDelay() {
String restoreApnDelayStr = SystemProperties.get(APN_RESTORE_DELAY_PROP_NAME);
@@ -1460,7 +1443,7 @@
if (allApns.isEmpty()) {
if (DBG) log("No APN found for carrier: " + operator);
preferredApn = null;
- notifyNoData(PdpConnection.FailCause.BAD_APN);
+ notifyNoData(PdpConnection.FailCause.MISSING_UKNOWN_APN);
} else {
preferredApn = getPreferredApn();
Log.d(LOG_TAG, "Get PreferredAPN");
diff --git a/telephony/java/com/android/internal/telephony/gsm/PdpConnection.java b/telephony/java/com/android/internal/telephony/gsm/PdpConnection.java
index 3f794a8..278beef 100644
--- a/telephony/java/com/android/internal/telephony/gsm/PdpConnection.java
+++ b/telephony/java/com/android/internal/telephony/gsm/PdpConnection.java
@@ -35,15 +35,24 @@
private static final String LOG_TAG = "GSM";
private static final boolean DBG = true;
- private static final boolean FAKE_FAIL = false;
/** Fail cause of last PDP activate, from RIL_LastPDPActivateFailCause */
- private static final int PDP_FAIL_RIL_BARRED = 8;
- private static final int PDP_FAIL_RIL_BAD_APN = 27;
- private static final int PDP_FAIL_RIL_USER_AUTHENTICATION = 29;
- private static final int PDP_FAIL_RIL_SERVICE_OPTION_NOT_SUPPORTED = 32;
- private static final int PDP_FAIL_RIL_SERVICE_OPTION_NOT_SUBSCRIBED = 33;
- private static final int PDP_FAIL_RIL_ERROR_UNSPECIFIED = 0xffff;
+ private static final int PDP_FAIL_OPERATOR_BARRED = 0x08;
+ private static final int PDP_FAIL_INSUFFICIENT_RESOURCES = 0x1A;
+ private static final int PDP_FAIL_MISSING_UKNOWN_APN = 0x1B;
+ private static final int PDP_FAIL_UNKNOWN_PDP_ADDRESS_TYPE = 0x1C;
+ private static final int PDP_FAIL_USER_AUTHENTICATION = 0x1D;
+ private static final int PDP_FAIL_ACTIVATION_REJECT_GGSN = 0x1E;
+ private static final int PDP_FAIL_ACTIVATION_REJECT_UNSPECIFIED = 0x1F;
+ private static final int PDP_FAIL_SERVICE_OPTION_NOT_SUPPORTED = 0x20;
+ private static final int PDP_FAIL_SERVICE_OPTION_NOT_SUBSCRIBED = 0x21;
+ private static final int PDP_FAIL_SERVICE_OPTION_OUT_OF_ORDER = 0x22;
+ private static final int PDP_FAIL_NSAPI_IN_USE = 0x23;
+ private static final int PDP_FAIL_PROTOCOL_ERRORS = 0x6F;
+ private static final int PDP_FAIL_ERROR_UNSPECIFIED = 0xffff;
+
+ private static final int PDP_FAIL_REGISTRATION_FAIL = -1;
+ private static final int PDP_FAIL_GPRS_REGISTRATION_FAIL = -2;
//***** Instance Variables
private String pdp_name;
@@ -83,14 +92,6 @@
lastFailCause = FailCause.NONE;
receivedDisconnectReq = false;
- if (FAKE_FAIL) {
- // for debug before baseband implement error in setup PDP
- if (apn.apn.equalsIgnoreCase("badapn")){
- notifyFail(FailCause.BAD_APN, onConnectCompleted);
- return;
- }
- }
-
phone.mCM.setupDataCall(Integer.toString(RILConstants.GSM_PHONE), null, apn.apn, apn.user,
apn.password, obtainMessage(EVENT_SETUP_DATA_CONNECTION_DONE));
}
@@ -190,21 +191,51 @@
FailCause cause;
switch (rilCause) {
- case PDP_FAIL_RIL_BARRED:
- cause = FailCause.BARRED;
+ case PDP_FAIL_OPERATOR_BARRED:
+ cause = FailCause.OPERATOR_BARRED;
break;
- case PDP_FAIL_RIL_BAD_APN:
- cause = FailCause.BAD_APN;
+ case PDP_FAIL_INSUFFICIENT_RESOURCES:
+ cause = FailCause.INSUFFICIENT_RESOURCES;
break;
- case PDP_FAIL_RIL_USER_AUTHENTICATION:
+ case PDP_FAIL_MISSING_UKNOWN_APN:
+ cause = FailCause.MISSING_UKNOWN_APN;
+ break;
+ case PDP_FAIL_UNKNOWN_PDP_ADDRESS_TYPE:
+ cause = FailCause.UNKNOWN_PDP_ADDRESS;
+ break;
+ case PDP_FAIL_USER_AUTHENTICATION:
cause = FailCause.USER_AUTHENTICATION;
break;
- case PDP_FAIL_RIL_SERVICE_OPTION_NOT_SUPPORTED:
+ case PDP_FAIL_ACTIVATION_REJECT_GGSN:
+ cause = FailCause.ACTIVATION_REJECT_GGSN;
+ break;
+ case PDP_FAIL_ACTIVATION_REJECT_UNSPECIFIED:
+ cause = FailCause.ACTIVATION_REJECT_UNSPECIFIED;
+ break;
+ case PDP_FAIL_SERVICE_OPTION_OUT_OF_ORDER:
+ cause = FailCause.SERVICE_OPTION_OUT_OF_ORDER;
+ break;
+ case PDP_FAIL_SERVICE_OPTION_NOT_SUPPORTED:
cause = FailCause.SERVICE_OPTION_NOT_SUPPORTED;
break;
- case PDP_FAIL_RIL_SERVICE_OPTION_NOT_SUBSCRIBED:
+ case PDP_FAIL_SERVICE_OPTION_NOT_SUBSCRIBED:
cause = FailCause.SERVICE_OPTION_NOT_SUBSCRIBED;
break;
+ case PDP_FAIL_NSAPI_IN_USE:
+ cause = FailCause.NSAPI_IN_USE;
+ break;
+ case PDP_FAIL_PROTOCOL_ERRORS:
+ cause = FailCause.PROTOCOL_ERRORS;
+ break;
+ case PDP_FAIL_ERROR_UNSPECIFIED:
+ cause = FailCause.UNKNOWN;
+ break;
+ case PDP_FAIL_REGISTRATION_FAIL:
+ cause = FailCause.REGISTRATION_FAIL;
+ break;
+ case PDP_FAIL_GPRS_REGISTRATION_FAIL:
+ cause = FailCause.GPRS_REGISTRATION_FAIL;
+ break;
default:
cause = FailCause.UNKNOWN;
}