Merge change 9267
* changes:
Don't invalidate view if setEnabled doesn't change the state.
diff --git a/api/current.xml b/api/current.xml
index 1f53be9..b0b9ce65 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -117837,6 +117837,746 @@
>
</field>
</class>
+<class name="SmsManager"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="divideMessage"
+ return="java.util.ArrayList<java.lang.String>"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="text" type="java.lang.String">
+</parameter>
+</method>
+<method name="getDefault"
+ return="android.telephony.SmsManager"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="sendDataMessage"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="destinationAddress" type="java.lang.String">
+</parameter>
+<parameter name="scAddress" type="java.lang.String">
+</parameter>
+<parameter name="destinationPort" type="short">
+</parameter>
+<parameter name="data" type="byte[]">
+</parameter>
+<parameter name="sentIntent" type="android.app.PendingIntent">
+</parameter>
+<parameter name="deliveryIntent" type="android.app.PendingIntent">
+</parameter>
+</method>
+<method name="sendMultipartTextMessage"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="destinationAddress" type="java.lang.String">
+</parameter>
+<parameter name="scAddress" type="java.lang.String">
+</parameter>
+<parameter name="parts" type="java.util.ArrayList<java.lang.String>">
+</parameter>
+<parameter name="sentIntents" type="java.util.ArrayList<android.app.PendingIntent>">
+</parameter>
+<parameter name="deliveryIntents" type="java.util.ArrayList<android.app.PendingIntent>">
+</parameter>
+</method>
+<method name="sendTextMessage"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="destinationAddress" type="java.lang.String">
+</parameter>
+<parameter name="scAddress" type="java.lang.String">
+</parameter>
+<parameter name="text" type="java.lang.String">
+</parameter>
+<parameter name="sentIntent" type="android.app.PendingIntent">
+</parameter>
+<parameter name="deliveryIntent" type="android.app.PendingIntent">
+</parameter>
+</method>
+<field name="RESULT_ERROR_GENERIC_FAILURE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="RESULT_ERROR_NO_SERVICE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="4"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="RESULT_ERROR_NULL_PDU"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="3"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="RESULT_ERROR_RADIO_OFF"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="STATUS_ON_ICC_FREE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="0"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="STATUS_ON_ICC_READ"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="STATUS_ON_ICC_SENT"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="5"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="STATUS_ON_ICC_UNREAD"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="3"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="STATUS_ON_ICC_UNSENT"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="7"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
+<class name="SmsMessage"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="calculateLength"
+ return="int[]"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="msgBody" type="java.lang.CharSequence">
+</parameter>
+<parameter name="use7bitOnly" type="boolean">
+</parameter>
+</method>
+<method name="calculateLength"
+ return="int[]"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="messageBody" type="java.lang.String">
+</parameter>
+<parameter name="use7bitOnly" type="boolean">
+</parameter>
+</method>
+<method name="createFromPdu"
+ return="android.telephony.SmsMessage"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="pdu" type="byte[]">
+</parameter>
+</method>
+<method name="getDisplayMessageBody"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getDisplayOriginatingAddress"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getEmailBody"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getEmailFrom"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getIndexOnIcc"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getIndexOnSim"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="deprecated"
+ visibility="public"
+>
+</method>
+<method name="getMessageBody"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getMessageClass"
+ return="android.telephony.SmsMessage.MessageClass"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getOriginatingAddress"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getPdu"
+ return="byte[]"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getProtocolIdentifier"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getPseudoSubject"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getServiceCenterAddress"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getStatus"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getStatusOnIcc"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getStatusOnSim"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSubmitPdu"
+ return="android.telephony.SmsMessage.SubmitPdu"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="scAddress" type="java.lang.String">
+</parameter>
+<parameter name="destinationAddress" type="java.lang.String">
+</parameter>
+<parameter name="message" type="java.lang.String">
+</parameter>
+<parameter name="statusReportRequested" type="boolean">
+</parameter>
+</method>
+<method name="getSubmitPdu"
+ return="android.telephony.SmsMessage.SubmitPdu"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="scAddress" type="java.lang.String">
+</parameter>
+<parameter name="destinationAddress" type="java.lang.String">
+</parameter>
+<parameter name="destinationPort" type="short">
+</parameter>
+<parameter name="data" type="byte[]">
+</parameter>
+<parameter name="statusReportRequested" type="boolean">
+</parameter>
+</method>
+<method name="getTPLayerLengthForPDU"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="pdu" type="java.lang.String">
+</parameter>
+</method>
+<method name="getTimestampMillis"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getUserData"
+ return="byte[]"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="isCphsMwiMessage"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="isEmail"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="isMWIClearMessage"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="isMWISetMessage"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="isMwiDontStore"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="isReplace"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="isReplyPathPresent"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="isStatusReportMessage"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<field name="ENCODING_16BIT"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="3"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="ENCODING_7BIT"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="ENCODING_8BIT"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="ENCODING_UNKNOWN"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="0"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="MAX_USER_DATA_BYTES"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="140"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="MAX_USER_DATA_BYTES_WITH_HEADER"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="134"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="MAX_USER_DATA_SEPTETS"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="160"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="MAX_USER_DATA_SEPTETS_WITH_HEADER"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="153"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
+<class name="SmsMessage.MessageClass"
+ extends="java.lang.Enum"
+ abstract="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="valueOf"
+ return="android.telephony.SmsMessage.MessageClass"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="name" type="java.lang.String">
+</parameter>
+</method>
+<method name="values"
+ return="android.telephony.SmsMessage.MessageClass[]"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+</class>
+<class name="SmsMessage.SubmitPdu"
+ extends="java.lang.Object"
+ abstract="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<field name="encodedMessage"
+ type="byte[]"
+ transient="false"
+ volatile="false"
+ value="null"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="encodedScAddress"
+ type="byte[]"
+ transient="false"
+ volatile="false"
+ value="null"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
<class name="TelephonyManager"
extends="java.lang.Object"
abstract="false"
diff --git a/cmds/keystore/keymgmt.c b/cmds/keystore/keymgmt.c
index c45b53c..9a1f845 100644
--- a/cmds/keystore/keymgmt.c
+++ b/cmds/keystore/keymgmt.c
@@ -228,6 +228,11 @@
char keyfile[KEYFILE_LEN];
if (state != UNLOCKED) return -state;
+ if ((strlen(namespace) >= MAX_KEY_NAME_LENGTH) ||
+ (strlen(keyname) >= MAX_KEY_NAME_LENGTH)) {
+ LOGE("keyname is too long.");
+ return -1;
+ }
sprintf(keyfile, KEYFILE_NAME, namespace, keyname);
return unlink(keyfile);
}
@@ -243,12 +248,12 @@
LOGE("Can not store key with current state %d\n", state);
return -state;
}
- sprintf(keyfile, KEYFILE_NAME, namespace, keyname);
- // flatten the args
- if (strlen(keyname) >= MAX_KEY_NAME_LENGTH) {
+ if ((strlen(namespace) >= MAX_KEY_NAME_LENGTH) ||
+ (strlen(keyname) >= MAX_KEY_NAME_LENGTH)) {
LOGE("keyname is too long.");
return -1;
}
+ sprintf(keyfile, KEYFILE_NAME, namespace, keyname);
strcpy(blob.keyname, keyname);
blob.value_size = size;
if (size > MAX_KEY_VALUE_LENGTH) {
@@ -271,6 +276,11 @@
LOGE("Can not retrieve key value with current state %d\n", state);
return -state;
}
+ if ((strlen(namespace) >= MAX_KEY_NAME_LENGTH) ||
+ (strlen(keyname) >= MAX_KEY_NAME_LENGTH)) {
+ LOGE("keyname is too long.");
+ return -1;
+ }
sprintf(keyfile, KEYFILE_NAME, namespace, keyname);
ret = load_n_decrypt(keyname, keyfile, &decryptKey, &blob);
if (!ret) {
@@ -299,6 +309,13 @@
LOGE("cannot open keystore dir or namespace is null\n");
return -1;
}
+
+ if (strlen(namespace) >= MAX_KEY_NAME_LENGTH) {
+ LOGE("namespace is too long.");
+ return -1;
+ }
+
+ reply[0] = 0;
while ((de = readdir(d))) {
char *prefix, *name, *keyfile = de->d_name;
char *context = NULL;
@@ -367,6 +384,7 @@
int reset_keystore()
{
+ int ret = 0;
DIR *d;
struct dirent *de;
@@ -374,18 +392,24 @@
LOGE("cannot open keystore dir\n");
return -1;
}
- while ((de = readdir(d))) unlink(de->d_name);
+ while ((de = readdir(d))) {
+ if (unlink(de->d_name) != 0) ret = -1;
+ }
closedir(d);
state = UNINITIALIZED;
- LOGI("keystore is reset.");
- return 0;
+ if (ret == 0) {
+ LOGI("keystore is reset.");
+ } else {
+ LOGI("keystore can not be cleaned up entirely.");
+ }
+ return ret;
}
int init_keystore(const char *dir)
{
int fd;
- if (!dir) mkdir(dir, 0770);
+ if (dir) mkdir(dir, 0770);
if (!dir || chdir(dir)) {
LOGE("Can not open/create the keystore directory %s\n",
dir ? dir : "(null)");
diff --git a/cmds/keystore/tests/Android.mk b/cmds/keystore/tests/Android.mk
new file mode 100644
index 0000000..33541cc
--- /dev/null
+++ b/cmds/keystore/tests/Android.mk
@@ -0,0 +1,28 @@
+# 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.
+#
+# define the KEYSTORE_TESTS environment variable to build the test programs
+ifdef KEYSTORE_TESTS
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES:= netkeystore_test.c ../keymgmt.c
+LOCAL_SHARED_LIBRARIES := libcutils libssl
+LOCAL_MODULE:= netkeystore_test
+LOCAL_MODULE_TAGS := optional
+LOCAL_C_INCLUDES := external/openssl/include \
+ frameworks/base/cmds/keystore
+EXTRA_CFLAGS := -g -O0 -DGTEST_OS_LINUX -DGTEST_HAS_STD_STRING
+include $(BUILD_EXECUTABLE)
+
+endif #KEYSTORE_TESTS
diff --git a/cmds/keystore/tests/netkeystore_test.c b/cmds/keystore/tests/netkeystore_test.c
new file mode 100644
index 0000000..e7e686b
--- /dev/null
+++ b/cmds/keystore/tests/netkeystore_test.c
@@ -0,0 +1,249 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "common.h"
+#include "keymgmt.h"
+
+typedef int FUNC_PTR();
+typedef struct {
+ const char *name;
+ FUNC_PTR *func;
+} TESTFUNC;
+
+#define FUNC_NAME(x) { #x, test_##x }
+#define FUNC_BODY(x) int test_##x()
+
+#define TEST_PASSWD "12345678"
+#define TEST_NPASSWD "11111111"
+#define TEST_DIR "/data/local/tmp/keystore"
+#define READONLY_DIR "/proc/keystore"
+#define TEST_NAMESPACE "test"
+#define TEST_KEYNAME "key"
+#define TEST_KEYNAME2 "key2"
+#define TEST_KEYVALUE "ANDROID"
+
+void setup()
+{
+ if (init_keystore(TEST_DIR) != 0) {
+ fprintf(stderr, "Can not create the test directory %s\n", TEST_DIR);
+ exit(-1);
+ }
+}
+
+void teardown()
+{
+ reset_keystore();
+ rmdir(TEST_DIR);
+}
+
+FUNC_BODY(init_keystore)
+{
+ if (init_keystore(READONLY_DIR) == 0) return -1;
+
+ return EXIT_SUCCESS;
+}
+
+FUNC_BODY(reset_keystore)
+{
+ chdir("/procx");
+ if (reset_keystore() == 0) return -1;
+ chdir(TEST_DIR);
+ return EXIT_SUCCESS;
+}
+
+FUNC_BODY(get_state)
+{
+ if (get_state() != UNINITIALIZED) return -1;
+ passwd(TEST_PASSWD);
+ if (get_state() != UNLOCKED) return -1;
+ lock();
+ if (get_state() != LOCKED) return -1;
+ reset_keystore();
+ if (get_state() != UNINITIALIZED) return -1;
+ return EXIT_SUCCESS;
+}
+
+FUNC_BODY(passwd)
+{
+ char buf[512];
+
+ if (passwd(" 23432dsfsdf") == 0) return -1;
+ if (passwd("dsfsdf") == 0) return -1;
+ passwd(TEST_PASSWD);
+ lock();
+ if (unlock("55555555") == 0) return -1;
+ if (unlock(TEST_PASSWD) != 0) return -1;
+
+ // change the password
+ sprintf(buf, "%s %s", "klfdjdsklfjg", "abcdefghi");
+ if (passwd(buf) == 0) return -1;
+
+ sprintf(buf, "%s %s", TEST_PASSWD, TEST_NPASSWD);
+ if (passwd(buf) != 0) return -1;
+ lock();
+
+ if (unlock(TEST_PASSWD) == 0) return -1;
+ if (unlock(TEST_NPASSWD) != 0) return -1;
+
+ return EXIT_SUCCESS;
+}
+
+FUNC_BODY(lock)
+{
+ if (lock() == 0) return -1;
+ passwd(TEST_PASSWD);
+ if (lock() != 0) return -1;
+ if (lock() != 0) return -1;
+ return EXIT_SUCCESS;
+}
+
+FUNC_BODY(unlock)
+{
+ int i = MAX_RETRY_COUNT;
+ passwd(TEST_PASSWD);
+ lock();
+ while (i > 1) {
+ if (unlock(TEST_NPASSWD) != --i) return -1;
+ }
+ if (unlock(TEST_NPASSWD) != -1) return -1;
+ return EXIT_SUCCESS;
+}
+
+FUNC_BODY(put_key)
+{
+ int i = 0;
+ char keyname[512];
+
+ if (put_key(TEST_NAMESPACE, TEST_KEYNAME, (unsigned char *)TEST_KEYVALUE,
+ strlen(TEST_KEYVALUE)) == 0) return -1;
+ passwd(TEST_PASSWD);
+ if (put_key(TEST_NAMESPACE, TEST_KEYNAME, (unsigned char *)TEST_KEYVALUE,
+ strlen(TEST_KEYVALUE)) != 0) return -1;
+
+ for(i = 0; i < 500; i++) keyname[i] = 'K';
+ keyname[i] = 0;
+ if (put_key(TEST_NAMESPACE, keyname, (unsigned char *)TEST_KEYVALUE,
+ strlen(TEST_KEYVALUE)) == 0) return -1;
+ if (put_key(TEST_NAMESPACE, TEST_KEYNAME, (unsigned char *)TEST_KEYVALUE,
+ MAX_KEY_VALUE_LENGTH + 1) == 0) return -1;
+ return EXIT_SUCCESS;
+}
+
+FUNC_BODY(get_key)
+{
+ int size;
+ unsigned char data[MAX_KEY_VALUE_LENGTH];
+
+ if (get_key(TEST_NAMESPACE, TEST_KEYNAME, data, &size) == 0) return -1;
+
+ passwd(TEST_PASSWD);
+ put_key(TEST_NAMESPACE, TEST_KEYNAME, (unsigned char *)TEST_KEYVALUE,
+ strlen(TEST_KEYVALUE));
+ if (get_key(TEST_NAMESPACE, TEST_KEYNAME, data, &size) != 0) return -1;
+ if (memcmp(data, TEST_KEYVALUE, size) != 0) return -1;
+
+ return EXIT_SUCCESS;
+}
+
+FUNC_BODY(remove_key)
+{
+ if (remove_key(TEST_NAMESPACE, TEST_KEYNAME) == 0) return -1;
+
+ passwd(TEST_PASSWD);
+ if (remove_key(TEST_NAMESPACE, TEST_KEYNAME) == 0) return -1;
+
+ put_key(TEST_NAMESPACE, TEST_KEYNAME, (unsigned char *)TEST_KEYVALUE,
+ strlen(TEST_KEYVALUE));
+ if (remove_key(TEST_NAMESPACE, TEST_KEYNAME) != 0) return -1;
+
+ return EXIT_SUCCESS;
+}
+
+FUNC_BODY(list_keys)
+{
+ int i;
+ char buf[128];
+ char reply[BUFFER_MAX];
+
+ for(i = 0; i < 100; i++) buf[i] = 'K';
+ buf[i] = 0;
+
+ if (list_keys(TEST_NAMESPACE, reply) == 0) return -1;
+
+ passwd(TEST_PASSWD);
+ if (list_keys(buf, reply) == 0) return -1;
+
+ if (list_keys(TEST_NAMESPACE, reply) != 0) return -1;
+ if (strcmp(reply, "") != 0) return -1;
+
+ put_key(TEST_NAMESPACE, TEST_KEYNAME, (unsigned char *)TEST_KEYVALUE,
+ strlen(TEST_KEYVALUE));
+ if (list_keys(TEST_NAMESPACE, reply) != 0) return -1;
+ if (strcmp(reply, TEST_KEYNAME) != 0) return -1;
+
+ put_key(TEST_NAMESPACE, TEST_KEYNAME2, (unsigned char *)TEST_KEYVALUE,
+ strlen(TEST_KEYVALUE));
+
+ if (list_keys(TEST_NAMESPACE, reply) != 0) return -1;
+ sprintf(buf, "%s %s", TEST_KEYNAME2, TEST_KEYNAME);
+ if (strcmp(reply, buf) != 0) return -1;
+
+ return EXIT_SUCCESS;
+}
+
+TESTFUNC all_tests[] = {
+ FUNC_NAME(init_keystore),
+ FUNC_NAME(reset_keystore),
+ FUNC_NAME(get_state),
+ FUNC_NAME(passwd),
+ FUNC_NAME(lock),
+ FUNC_NAME(unlock),
+ FUNC_NAME(put_key),
+ FUNC_NAME(get_key),
+ FUNC_NAME(remove_key),
+ FUNC_NAME(list_keys),
+};
+
+int main(int argc, char **argv) {
+ int i, ret;
+ for (i = 0 ; i < (int)(sizeof(all_tests)/sizeof(TESTFUNC)) ; ++i) {
+ setup();
+ if ((ret = all_tests[i].func()) != EXIT_SUCCESS) {
+ fprintf(stderr, "ERROR in function %s\n", all_tests[i].name);
+ return ret;
+ } else {
+ fprintf(stderr, "function %s PASSED!\n", all_tests[i].name);
+ }
+ teardown();
+ }
+ return EXIT_SUCCESS;
+}
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java
index 4dd2433..18e4a528 100644
--- a/core/java/android/app/SearchDialog.java
+++ b/core/java/android/app/SearchDialog.java
@@ -903,6 +903,12 @@
getContext().startActivity(mVoiceWebSearchIntent);
} else if (mSearchable.getVoiceSearchLaunchRecognizer()) {
Intent appSearchIntent = createVoiceAppSearchIntent(mVoiceAppSearchIntent);
+
+ // Stop the existing search before starting voice search, or else we'll end
+ // up showing the search dialog again once we return to the app.
+ ((SearchManager) getContext().getSystemService(Context.SEARCH_SERVICE)).
+ stopSearch();
+
getContext().startActivity(appSearchIntent);
}
} catch (ActivityNotFoundException e) {
@@ -1238,11 +1244,11 @@
// ensure the icons will work for global search
cv.put(SearchManager.SUGGEST_COLUMN_ICON_1,
wrapIconForPackage(
- source,
+ mSearchable.getSuggestPackage(),
getColumnString(c, SearchManager.SUGGEST_COLUMN_ICON_1)));
cv.put(SearchManager.SUGGEST_COLUMN_ICON_2,
wrapIconForPackage(
- source,
+ mSearchable.getSuggestPackage(),
getColumnString(c, SearchManager.SUGGEST_COLUMN_ICON_2)));
// the rest can be passed through directly
@@ -1281,11 +1287,11 @@
* Wraps an icon for a particular package. If the icon is a resource id, it is converted into
* an android.resource:// URI.
*
- * @param source The source of the icon
+ * @param packageName The source of the icon
* @param icon The icon retrieved from a suggestion column
* @return An icon string appropriate for the package.
*/
- private String wrapIconForPackage(ComponentName source, String icon) {
+ private String wrapIconForPackage(String packageName, String icon) {
if (icon == null || icon.length() == 0 || "0".equals(icon)) {
// SearchManager specifies that null or zero can be returned to indicate
// no icon. We also allow empty string.
@@ -1293,7 +1299,6 @@
} else if (!Character.isDigit(icon.charAt(0))){
return icon;
} else {
- String packageName = source.getPackageName();
return new Uri.Builder()
.scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
.authority(packageName)
diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java
index 5c7b01f..8ebe093 100644
--- a/core/java/android/content/res/AssetManager.java
+++ b/core/java/android/content/res/AssetManager.java
@@ -637,12 +637,13 @@
* mRetData. */
private native final int loadResourceBagValue(int ident, int bagEntryId, TypedValue outValue,
boolean resolve);
- /*package*/ static final int STYLE_NUM_ENTRIES = 5;
+ /*package*/ static final int STYLE_NUM_ENTRIES = 6;
/*package*/ static final int STYLE_TYPE = 0;
/*package*/ static final int STYLE_DATA = 1;
/*package*/ static final int STYLE_ASSET_COOKIE = 2;
/*package*/ static final int STYLE_RESOURCE_ID = 3;
/*package*/ static final int STYLE_CHANGING_CONFIGURATIONS = 4;
+ /*package*/ static final int STYLE_DENSITY = 5;
/*package*/ native static final boolean applyStyle(int theme,
int defStyleAttr, int defStyleRes, int xmlParser,
int[] inAttrs, int[] outValues, int[] outIndices);
diff --git a/core/java/android/content/res/TypedArray.java b/core/java/android/content/res/TypedArray.java
index 3a32c03..016ee7f 100644
--- a/core/java/android/content/res/TypedArray.java
+++ b/core/java/android/content/res/TypedArray.java
@@ -654,6 +654,7 @@
outValue.assetCookie = data[index+AssetManager.STYLE_ASSET_COOKIE];
outValue.resourceId = data[index+AssetManager.STYLE_RESOURCE_ID];
outValue.changingConfigurations = data[index+AssetManager.STYLE_CHANGING_CONFIGURATIONS];
+ outValue.density = data[index+AssetManager.STYLE_DENSITY];
if (type == TypedValue.TYPE_STRING) {
outValue.string = loadStringValueAt(index);
}
diff --git a/core/java/android/provider/SocialContract.java b/core/java/android/provider/SocialContract.java
index d542774..ee271ba 100644
--- a/core/java/android/provider/SocialContract.java
+++ b/core/java/android/provider/SocialContract.java
@@ -165,11 +165,11 @@
/**
* The {@link Uri} for the latest social activity performed by any
- * contact aggregated under the specified {@link Contacts#_ID}. Will
+ * raw contact aggregated under the specified {@link Contacts#_ID}. Will
* also join with most-present {@link Presence} for this aggregate.
*/
- public static final Uri CONTENT_AGGREGATE_STATUS_URI =
- Uri.withAppendedPath(AUTHORITY_URI, "aggregate_status");
+ public static final Uri CONTENT_CONTACT_STATUS_URI =
+ Uri.withAppendedPath(AUTHORITY_URI, "contact_status");
/**
* The MIME type of {@link #CONTENT_URI} providing a directory of social
diff --git a/core/java/android/server/search/SearchableInfo.java b/core/java/android/server/search/SearchableInfo.java
index 045b0c2..69ef98c 100644
--- a/core/java/android/server/search/SearchableInfo.java
+++ b/core/java/android/server/search/SearchableInfo.java
@@ -103,6 +103,14 @@
}
/**
+ * Gets the name of the package where the suggestion provider lives,
+ * or {@code null}.
+ */
+ public String getSuggestPackage() {
+ return mSuggestProviderPackage;
+ }
+
+ /**
* Gets the component name of the searchable activity.
*/
public ComponentName getSearchActivity() {
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index 884950f..0d44b4e 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -21,7 +21,6 @@
import android.graphics.Canvas;
import android.graphics.PixelFormat;
-import android.graphics.Point;
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.Region;
@@ -1220,6 +1219,8 @@
if (mTranslator != null) {
mTranslator.translateCanvas(canvas);
}
+ canvas.setScreenDensity(scalingRequired
+ ? DisplayMetrics.DENSITY_DEVICE : 0);
mView.draw(canvas);
if (Config.DEBUG && ViewDebug.consistencyCheckEnabled) {
mView.dispatchConsistencyCheck(ViewDebug.CONSISTENCY_DRAWING);
@@ -1328,6 +1329,8 @@
if (mTranslator != null) {
mTranslator.translateCanvas(canvas);
}
+ canvas.setScreenDensity(scalingRequired
+ ? DisplayMetrics.DENSITY_DEVICE : 0);
mView.draw(canvas);
} finally {
mAttachInfo.mIgnoreDirtyState = false;
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 358fc9e..05a7806 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -206,11 +206,6 @@
static final String LOGTAG = "webview";
- static class ScaleLimitData {
- int mMinScale;
- int mMaxScale;
- }
-
private static class ExtendedZoomControls extends FrameLayout {
public ExtendedZoomControls(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -472,7 +467,6 @@
static final int UPDATE_TEXT_ENTRY_MSG_ID = 15;
static final int WEBCORE_INITIALIZED_MSG_ID = 16;
static final int UPDATE_TEXTFIELD_TEXT_MSG_ID = 17;
- static final int DID_FIRST_LAYOUT_MSG_ID = 18;
static final int MOVE_OUT_OF_PLUGIN = 19;
static final int CLEAR_TEXT_ENTRY = 20;
@@ -502,7 +496,7 @@
"UPDATE_TEXT_ENTRY_MSG_ID", // = 15;
"WEBCORE_INITIALIZED_MSG_ID", // = 16;
"UPDATE_TEXTFIELD_TEXT_MSG_ID", // = 17;
- "DID_FIRST_LAYOUT_MSG_ID", // = 18;
+ "18", // = 18;
"MOVE_OUT_OF_PLUGIN", // = 19;
"CLEAR_TEXT_ENTRY", // = 20;
"21", // = 21;
@@ -1892,6 +1886,13 @@
r.bottom = viewToContent(r.bottom);
}
+ static class ViewSizeData {
+ int mWidth;
+ int mHeight;
+ int mTextWrapWidth;
+ float mScale;
+ }
+
/**
* Compute unzoomed width and height, and if they differ from the last
* values we sent, send them to webkit (to be used has new viewport)
@@ -1899,7 +1900,8 @@
* @return true if new values were sent
*/
private boolean sendViewSizeZoom() {
- int newWidth = Math.round(getViewWidth() * mInvActualScale);
+ int viewWidth = getViewWidth();
+ int newWidth = Math.round(viewWidth * mInvActualScale);
int newHeight = Math.round(getViewHeight() * mInvActualScale);
/*
* Because the native side may have already done a layout before the
@@ -1914,8 +1916,16 @@
}
// Avoid sending another message if the dimensions have not changed.
if (newWidth != mLastWidthSent || newHeight != mLastHeightSent) {
- mWebViewCore.sendMessage(EventHub.VIEW_SIZE_CHANGED,
- newWidth, newHeight, new Float(mActualScale));
+ ViewSizeData data = new ViewSizeData();
+ data.mWidth = newWidth;
+ data.mHeight = newHeight;
+ // while in zoom overview mode, the text are wrapped to the screen
+ // width matching mLastScale. So that we don't trigger re-flow while
+ // toggling between overview mode and normal mode.
+ data.mTextWrapWidth = mInZoomOverview ? Math.round(viewWidth
+ / mLastScale) : newWidth;
+ data.mScale = mActualScale;
+ mWebViewCore.sendMessage(EventHub.VIEW_SIZE_CHANGED, data);
mLastWidthSent = newWidth;
mLastHeightSent = newHeight;
return true;
@@ -3877,11 +3887,6 @@
if (!mDragFromTextInput) {
nativeHideCursor();
}
- // remove the zoom anchor if there is any
- if (mZoomScale != 0) {
- mWebViewCore
- .sendMessage(EventHub.SET_SNAP_ANCHOR, 0, 0);
- }
WebSettings settings = getSettings();
if (settings.supportZoom() && !mInZoomOverview
&& settings.getBuiltInZoomControls()
@@ -4982,15 +4987,35 @@
final WebViewCore.DrawData draw =
(WebViewCore.DrawData) msg.obj;
final Point viewSize = draw.mViewPoint;
- if (mZoomScale > 0) {
- // use the same logic in sendViewSizeZoom() to make sure
- // the mZoomScale has matched the viewSize so that we
- // can clear mZoomScale
- if (Math.round(viewWidth / mZoomScale) == viewSize.x) {
- mZoomScale = 0;
- mWebViewCore.sendMessage(EventHub.SET_SNAP_ANCHOR,
- 0, 0);
+ boolean useWideViewport =
+ mWebViewCore.getSettings().getUseWideViewPort();
+ WebViewCore.RestoreState restoreState = draw.mRestoreState;
+ if (restoreState != null) {
+ mInZoomOverview = false;
+ mLastScale = restoreState.mTextWrapScale;
+ if (restoreState.mMinScale == 0) {
+ mMinZoomScale = DEFAULT_MIN_ZOOM_SCALE;
+ mMinZoomScaleFixed = false;
+ } else {
+ mMinZoomScale = restoreState.mMinScale;
+ mMinZoomScaleFixed = true;
}
+ if (restoreState.mMaxScale == 0) {
+ mMaxZoomScale = DEFAULT_MAX_ZOOM_SCALE;
+ } else {
+ mMaxZoomScale = restoreState.mMaxScale;
+ }
+ if (useWideViewport && restoreState.mViewScale == 0) {
+ mInZoomOverview = ENABLE_DOUBLETAP_ZOOM;
+ }
+ setNewZoomScale(mLastScale, false);
+ setContentScrollTo(restoreState.mScrollX,
+ restoreState.mScrollY);
+ // As we are on a new page, remove the WebTextView. This
+ // is necessary for page loads driven by webkit, and in
+ // particular when the user was on a password field, so
+ // the WebTextView was visible.
+ clearTextEntry();
}
// We update the layout (i.e. request a layout from the
// view system) if the last view size that we sent to
@@ -5009,7 +5034,7 @@
if (mPictureListener != null) {
mPictureListener.onNewPicture(WebView.this, capturePicture());
}
- if (mWebViewCore.getSettings().getUseWideViewPort()) {
+ if (useWideViewport) {
mZoomOverviewWidth = Math.max(draw.mMinPrefWidth,
draw.mViewPoint.x);
}
@@ -5056,76 +5081,6 @@
}
}
break;
- case DID_FIRST_LAYOUT_MSG_ID: {
- if (mNativeClass == 0) {
- break;
- }
- ScaleLimitData scaleLimit = (ScaleLimitData) msg.obj;
- int minScale = scaleLimit.mMinScale;
- if (minScale == 0) {
- mMinZoomScale = DEFAULT_MIN_ZOOM_SCALE;
- mMinZoomScaleFixed = false;
- } else {
- mMinZoomScale = (float) (minScale / 100.0);
- mMinZoomScaleFixed = true;
- }
- int maxScale = scaleLimit.mMaxScale;
- if (maxScale == 0) {
- mMaxZoomScale = DEFAULT_MAX_ZOOM_SCALE;
- } else {
- mMaxZoomScale = (float) (maxScale / 100.0);
- }
- // If history Picture is drawn, don't update zoomWidth
- if (mDrawHistory) {
- break;
- }
- int width = getViewWidth();
- if (width == 0) {
- break;
- }
- final WebSettings settings = mWebViewCore.getSettings();
- int initialScale = msg.arg1;
- int viewportWidth = msg.arg2;
- // start a new page with DEFAULT_SCALE zoom scale.
- float scale = mDefaultScale;
- mInZoomOverview = false;
- if (mInitialScale > 0) {
- scale = mInitialScale / 100.0f;
- } else {
- if (initialScale == -1) break;
- if (settings.getUseWideViewPort()) {
- // force viewSizeChanged by setting mLastWidthSent
- // to 0
- mLastWidthSent = 0;
- }
- if (initialScale == 0) {
- // if viewportWidth is defined and it is smaller
- // than the view width, zoom in to fill the view
- if (viewportWidth > 0 && viewportWidth < width) {
- scale = (float) width / viewportWidth;
- } else {
- if (settings.getUseWideViewPort()) {
- mInZoomOverview = ENABLE_DOUBLETAP_ZOOM;
- }
- }
- } else if (initialScale < 0) {
- // this should only happen when
- // ENABLE_DOUBLETAP_ZOOM is true
- mInZoomOverview = true;
- scale = -initialScale / 100.0f;
- } else {
- scale = initialScale / 100.0f;
- }
- }
- mLastScale = scale;
- setNewZoomScale(scale, false);
- // As we are on a new page, remove the WebTextView. This
- // is necessary for page loads driven by webkit, and in
- // particular when the user was on a password field, so
- // the WebTextView was visible.
- clearTextEntry();
- break;
- }
case MOVE_OUT_OF_PLUGIN:
if (nativePluginEatsNavKey()) {
navHandledKey(msg.arg1, 1, false, 0, true);
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index 4afc4cd..8ec8174 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -443,10 +443,6 @@
private native void nativeUpdateFrameCache();
- private native void nativeSetSnapAnchor(int x, int y);
-
- private native void nativeSnapToAnchor();
-
private native void nativeSetBackgroundColor(int color);
private native void nativeDumpDomTree(boolean useFile);
@@ -674,7 +670,7 @@
"CLICK", // = 118;
"SET_NETWORK_STATE", // = 119;
"DOC_HAS_IMAGES", // = 120;
- "SET_SNAP_ANCHOR", // = 121;
+ "121", // = 121;
"DELETE_SELECTION", // = 122;
"LISTBOX_CHOICES", // = 123;
"SINGLE_LISTBOX_CHOICE", // = 124;
@@ -725,7 +721,6 @@
static final int CLICK = 118;
static final int SET_NETWORK_STATE = 119;
static final int DOC_HAS_IMAGES = 120;
- static final int SET_SNAP_ANCHOR = 121;
static final int DELETE_SELECTION = 122;
static final int LISTBOX_CHOICES = 123;
static final int SINGLE_LISTBOX_CHOICE = 124;
@@ -904,11 +899,13 @@
nativeClick(msg.arg1, msg.arg2);
break;
- case VIEW_SIZE_CHANGED:
- viewSizeChanged(msg.arg1, msg.arg2,
- ((Float) msg.obj).floatValue());
+ case VIEW_SIZE_CHANGED: {
+ WebView.ViewSizeData data =
+ (WebView.ViewSizeData) msg.obj;
+ viewSizeChanged(data.mWidth, data.mHeight,
+ data.mTextWrapWidth, data.mScale);
break;
-
+ }
case SET_SCROLL_OFFSET:
// note: these are in document coordinates
// (inv-zoom)
@@ -1107,10 +1104,6 @@
imageResult.sendToTarget();
break;
- case SET_SNAP_ANCHOR:
- nativeSetSnapAnchor(msg.arg1, msg.arg2);
- break;
-
case DELETE_SELECTION:
DeleteSelectionData deleteSelectionData
= (DeleteSelectionData) msg.obj;
@@ -1401,16 +1394,20 @@
// These values are used to avoid requesting a layout based on old values
private int mCurrentViewWidth = 0;
private int mCurrentViewHeight = 0;
+ private float mCurrentViewScale = 1.0f;
// notify webkit that our virtual view size changed size (after inv-zoom)
- private void viewSizeChanged(int w, int h, float scale) {
- if (DebugFlags.WEB_VIEW_CORE) Log.v(LOGTAG, "CORE onSizeChanged");
+ private void viewSizeChanged(int w, int h, int textwrapWidth, float scale) {
+ if (DebugFlags.WEB_VIEW_CORE) {
+ Log.v(LOGTAG, "viewSizeChanged w=" + w + "; h=" + h
+ + "; textwrapWidth=" + textwrapWidth + "; scale=" + scale);
+ }
if (w == 0) {
Log.w(LOGTAG, "skip viewSizeChanged as w is 0");
return;
}
+ int width = w;
if (mSettings.getUseWideViewPort()) {
- int width;
if (mViewportWidth == -1) {
if (mSettings.getLayoutAlgorithm() ==
WebSettings.LayoutAlgorithm.NORMAL) {
@@ -1433,19 +1430,14 @@
} else {
width = Math.max(w, mViewportWidth);
}
- // while in zoom overview mode, the text are wrapped to the screen
- // width matching mWebView.mLastScale. So that we don't trigger
- // re-flow while toggling between overview mode and normal mode.
- nativeSetSize(width, Math.round((float) width * h / w),
- Math.round(mWebView.mInZoomOverview ? w * scale
- / mWebView.mLastScale : w), scale, w, h);
- } else {
- nativeSetSize(w, h, w, scale, w, h);
}
+ nativeSetSize(width, width == w ? h : Math.round((float) width * h / w),
+ textwrapWidth, scale, w, h);
// Remember the current width and height
boolean needInvalidate = (mCurrentViewWidth == 0);
mCurrentViewWidth = w;
mCurrentViewHeight = h;
+ mCurrentViewScale = scale;
if (needInvalidate) {
// ensure {@link #webkitDraw} is called as we were blocking in
// {@link #contentDraw} when mCurrentViewWidth is 0
@@ -1490,15 +1482,30 @@
// Used to end scale+scroll mode, accessed by both threads
boolean mEndScaleZoom = false;
- public class DrawData {
- public DrawData() {
+ // mRestoreState is set in didFirstLayout(), and reset in the next
+ // webkitDraw after passing it to the UI thread.
+ private RestoreState mRestoreState = null;
+
+ static class RestoreState {
+ float mMinScale;
+ float mMaxScale;
+ float mViewScale;
+ float mTextWrapScale;
+ int mScrollX;
+ int mScrollY;
+ }
+
+ static class DrawData {
+ DrawData() {
mInvalRegion = new Region();
mWidthHeight = new Point();
}
- public Region mInvalRegion;
- public Point mViewPoint;
- public Point mWidthHeight;
- public int mMinPrefWidth;
+ Region mInvalRegion;
+ Point mViewPoint;
+ Point mWidthHeight;
+ int mMinPrefWidth;
+ RestoreState mRestoreState; // only non-null if it is for the first
+ // picture set after the first layout
}
private void webkitDraw() {
@@ -1517,6 +1524,10 @@
if (WebView.ENABLE_DOUBLETAP_ZOOM && mSettings.getUseWideViewPort()) {
draw.mMinPrefWidth = nativeGetContentMinPrefWidth();
}
+ if (mRestoreState != null) {
+ draw.mRestoreState = mRestoreState;
+ mRestoreState = null;
+ }
if (DebugFlags.WEB_VIEW_CORE) Log.v(LOGTAG, "webkitDraw NEW_PICTURE_MSG_ID");
Message.obtain(mWebView.mPrivateHandler,
WebView.NEW_PICTURE_MSG_ID, draw).sendToTarget();
@@ -1527,9 +1538,6 @@
mWebkitScrollY).sendToTarget();
mWebkitScrollX = mWebkitScrollY = 0;
}
- // nativeSnapToAnchor() needs to be called after NEW_PICTURE_MSG_ID
- // is sent, so that scroll will be based on the new content size.
- nativeSnapToAnchor();
}
}
@@ -1751,17 +1759,8 @@
// called by JNI
private void didFirstLayout(boolean standardLoad) {
- // Trick to ensure that the Picture has the exact height for the content
- // by forcing to layout with 0 height after the page is ready, which is
- // indicated by didFirstLayout. This is essential to get rid of the
- // white space in the GMail which uses WebView for message view.
- if (mWebView != null && mWebView.mHeightCanMeasure) {
- mWebView.mLastHeightSent = 0;
- // Send a negative scale to indicate that WebCore should reuse the
- // current scale
- mEventHub.sendMessage(Message.obtain(null,
- EventHub.VIEW_SIZE_CHANGED, mWebView.mLastWidthSent,
- mWebView.mLastHeightSent, -1.0f));
+ if (DebugFlags.WEB_VIEW_CORE) {
+ Log.v(LOGTAG, "didFirstLayout standardLoad =" + standardLoad);
}
mBrowserFrame.didFirstLayout();
@@ -1769,6 +1768,9 @@
// reset the scroll position as it is a new page now
mWebkitScrollX = mWebkitScrollY = 0;
+ // for non-standard load, we only adjust scale if mRestoredScale > 0
+ if (mWebView == null || (mRestoredScale == 0 && !standardLoad)) return;
+
// set the viewport settings from WebKit
setViewportSettingsFromNative();
@@ -1820,47 +1822,74 @@
}
// now notify webview
- if (mWebView != null) {
- WebView.ScaleLimitData scaleLimit = new WebView.ScaleLimitData();
- scaleLimit.mMinScale = mViewportMinimumScale;
- scaleLimit.mMaxScale = mViewportMaximumScale;
-
- if (mRestoredScale > 0) {
- Message.obtain(mWebView.mPrivateHandler,
- WebView.DID_FIRST_LAYOUT_MSG_ID,
- mRestoredScreenWidthScale > 0 ?
- -mRestoredScreenWidthScale : mRestoredScale, 0,
- scaleLimit).sendToTarget();
+ int webViewWidth = Math.round(mCurrentViewWidth * mCurrentViewScale);
+ mRestoreState = new RestoreState();
+ mRestoreState.mMinScale = mViewportMinimumScale / 100.0f;
+ mRestoreState.mMaxScale = mViewportMaximumScale / 100.0f;
+ mRestoreState.mScrollX = mRestoredX;
+ mRestoreState.mScrollY = mRestoredY;
+ if (mRestoredScale > 0) {
+ if (mRestoredScreenWidthScale > 0) {
+ mRestoreState.mTextWrapScale =
+ mRestoredScreenWidthScale / 100.0f;
+ // 0 will trigger WebView to turn on zoom overview mode
+ mRestoreState.mViewScale = 0;
} else {
- // if standardLoad is true, use mViewportInitialScale, otherwise
- // pass -1 to the WebView to indicate no change of the scale.
- Message.obtain(mWebView.mPrivateHandler,
- WebView.DID_FIRST_LAYOUT_MSG_ID,
- standardLoad ? mViewportInitialScale : -1,
- mViewportWidth, scaleLimit).sendToTarget();
+ mRestoreState.mViewScale = mRestoreState.mTextWrapScale =
+ mRestoredScale / 100.0f;
}
-
- // force an early draw for quick feedback after the first layout
- if (mCurrentViewWidth != 0) {
- synchronized (this) {
- if (mDrawIsScheduled) {
- mEventHub.removeMessages(EventHub.WEBKIT_DRAW);
- }
- mDrawIsScheduled = true;
- // if no restored offset, move the new page to (0, 0)
- mEventHub.sendMessageAtFrontOfQueue(Message.obtain(null,
- EventHub.MESSAGE_RELAY, Message.obtain(
- mWebView.mPrivateHandler,
- WebView.SCROLL_TO_MSG_ID, mRestoredX,
- mRestoredY)));
- mEventHub.sendMessageAtFrontOfQueue(Message.obtain(null,
- EventHub.WEBKIT_DRAW));
- }
+ } else {
+ if (mViewportInitialScale > 0) {
+ mRestoreState.mViewScale = mRestoreState.mTextWrapScale =
+ mViewportInitialScale / 100.0f;
+ } else if (mViewportWidth > 0 && mViewportWidth < webViewWidth) {
+ mRestoreState.mViewScale = mRestoreState.mTextWrapScale =
+ (float) webViewWidth / mViewportWidth;
+ } else {
+ mRestoreState.mTextWrapScale =
+ WebView.DEFAULT_SCALE_PERCENT / 100.0f;
+ // 0 will trigger WebView to turn on zoom overview mode
+ mRestoreState.mViewScale = 0;
}
-
- // reset restored offset, scale
- mRestoredX = mRestoredY = mRestoredScale = mRestoredScreenWidthScale = 0;
}
+
+ if (mWebView.mHeightCanMeasure) {
+ // Trick to ensure that the Picture has the exact height for the
+ // content by forcing to layout with 0 height after the page is
+ // ready, which is indicated by didFirstLayout. This is essential to
+ // get rid of the white space in the GMail which uses WebView for
+ // message view.
+ mWebView.mLastHeightSent = 0;
+ // Send a negative scale to indicate that WebCore should reuse
+ // the current scale
+ WebView.ViewSizeData data = new WebView.ViewSizeData();
+ data.mWidth = mWebView.mLastWidthSent;
+ data.mHeight = 0;
+ // if mHeightCanMeasure is true, getUseWideViewPort() can't be
+ // true. It is safe to use mWidth for mTextWrapWidth.
+ data.mTextWrapWidth = data.mWidth;
+ data.mScale = -1.0f;
+ mEventHub.sendMessageAtFrontOfQueue(Message.obtain(null,
+ EventHub.VIEW_SIZE_CHANGED, data));
+ } else if (mSettings.getUseWideViewPort() && mCurrentViewWidth > 0) {
+ WebView.ViewSizeData data = new WebView.ViewSizeData();
+ // mViewScale as 0 means it is in zoom overview mode. So we don't
+ // know the exact scale. If mRestoredScale is non-zero, use it;
+ // otherwise just use mTextWrapScale as the initial scale.
+ data.mScale = mRestoreState.mViewScale == 0
+ ? (mRestoredScale > 0 ? mRestoredScale
+ : mRestoreState.mTextWrapScale)
+ : mRestoreState.mViewScale;
+ data.mWidth = Math.round(webViewWidth / data.mScale);
+ data.mHeight = mCurrentViewHeight * data.mWidth
+ / mCurrentViewWidth;
+ data.mTextWrapWidth = Math.round(webViewWidth
+ / mRestoreState.mTextWrapScale);
+ mEventHub.sendMessageAtFrontOfQueue(Message.obtain(null,
+ EventHub.VIEW_SIZE_CHANGED, data));
+ }
+ // reset restored offset, scale
+ mRestoredX = mRestoredY = mRestoredScale = mRestoredScreenWidthScale = 0;
}
// called by JNI
diff --git a/core/jni/android/graphics/Canvas.cpp b/core/jni/android/graphics/Canvas.cpp
index c16a75e..dc72008 100644
--- a/core/jni/android/graphics/Canvas.cpp
+++ b/core/jni/android/graphics/Canvas.cpp
@@ -464,13 +464,22 @@
SkCanvas* canvas, SkBitmap* bitmap,
jfloat left, jfloat top,
SkPaint* paint, jint canvasDensity,
- jint bitmapDensity) {
+ jint screenDensity, jint bitmapDensity) {
SkScalar left_ = SkFloatToScalar(left);
SkScalar top_ = SkFloatToScalar(top);
if (canvasDensity == bitmapDensity || canvasDensity == 0
|| bitmapDensity == 0) {
- canvas->drawBitmap(*bitmap, left_, top_, paint);
+ if (screenDensity != 0 && screenDensity != bitmapDensity) {
+ SkPaint filteredPaint;
+ if (paint) {
+ filteredPaint = *paint;
+ }
+ filteredPaint.setFilterBitmap(true);
+ canvas->drawBitmap(*bitmap, left_, top_, &filteredPaint);
+ } else {
+ canvas->drawBitmap(*bitmap, left_, top_, paint);
+ }
} else {
canvas->save();
SkScalar scale = SkFloatToScalar(canvasDensity / (float)bitmapDensity);
@@ -490,30 +499,45 @@
}
static void doDrawBitmap(JNIEnv* env, SkCanvas* canvas, SkBitmap* bitmap,
- jobject srcIRect, const SkRect& dst, SkPaint* paint) {
+ jobject srcIRect, const SkRect& dst, SkPaint* paint,
+ jint screenDensity, jint bitmapDensity) {
SkIRect src, *srcPtr = NULL;
if (NULL != srcIRect) {
GraphicsJNI::jrect_to_irect(env, srcIRect, &src);
srcPtr = &src;
}
- canvas->drawBitmapRect(*bitmap, srcPtr, dst, paint);
+
+ if (screenDensity != 0 && screenDensity != bitmapDensity) {
+ SkPaint filteredPaint;
+ if (paint) {
+ filteredPaint = *paint;
+ }
+ filteredPaint.setFilterBitmap(true);
+ canvas->drawBitmapRect(*bitmap, srcPtr, dst, &filteredPaint);
+ } else {
+ canvas->drawBitmapRect(*bitmap, srcPtr, dst, paint);
+ }
}
static void drawBitmapRF(JNIEnv* env, jobject, SkCanvas* canvas,
SkBitmap* bitmap, jobject srcIRect,
- jobject dstRectF, SkPaint* paint) {
+ jobject dstRectF, SkPaint* paint,
+ jint screenDensity, jint bitmapDensity) {
SkRect dst;
GraphicsJNI::jrectf_to_rect(env, dstRectF, &dst);
- doDrawBitmap(env, canvas, bitmap, srcIRect, dst, paint);
+ doDrawBitmap(env, canvas, bitmap, srcIRect, dst, paint,
+ screenDensity, bitmapDensity);
}
static void drawBitmapRR(JNIEnv* env, jobject, SkCanvas* canvas,
SkBitmap* bitmap, jobject srcIRect,
- jobject dstRect, SkPaint* paint) {
+ jobject dstRect, SkPaint* paint,
+ jint screenDensity, jint bitmapDensity) {
SkRect dst;
GraphicsJNI::jrect_to_rect(env, dstRect, &dst);
- doDrawBitmap(env, canvas, bitmap, srcIRect, dst, paint);
+ doDrawBitmap(env, canvas, bitmap, srcIRect, dst, paint,
+ screenDensity, bitmapDensity);
}
static void drawBitmapArray(JNIEnv* env, jobject, SkCanvas* canvas,
@@ -907,11 +931,11 @@
{"native_drawRoundRect","(ILandroid/graphics/RectF;FFI)V",
(void*) SkCanvasGlue::drawRoundRect},
{"native_drawPath","(III)V", (void*) SkCanvasGlue::drawPath},
- {"native_drawBitmap","(IIFFIII)V",
+ {"native_drawBitmap","(IIFFIIII)V",
(void*) SkCanvasGlue::drawBitmap__BitmapFFPaint},
- {"native_drawBitmap","(IILandroid/graphics/Rect;Landroid/graphics/RectF;I)V",
+ {"native_drawBitmap","(IILandroid/graphics/Rect;Landroid/graphics/RectF;III)V",
(void*) SkCanvasGlue::drawBitmapRF},
- {"native_drawBitmap","(IILandroid/graphics/Rect;Landroid/graphics/Rect;I)V",
+ {"native_drawBitmap","(IILandroid/graphics/Rect;Landroid/graphics/Rect;III)V",
(void*) SkCanvasGlue::drawBitmapRR},
{"native_drawBitmap", "(I[IIIFFIIZI)V",
(void*)SkCanvasGlue::drawBitmapArray},
diff --git a/core/jni/android/graphics/MaskFilter.cpp b/core/jni/android/graphics/MaskFilter.cpp
index e6048cd..0f8dff1 100644
--- a/core/jni/android/graphics/MaskFilter.cpp
+++ b/core/jni/android/graphics/MaskFilter.cpp
@@ -4,15 +4,23 @@
#include <jni.h>
+static void ThrowIAE_IfNull(JNIEnv* env, void* ptr) {
+ if (NULL == ptr) {
+ doThrowIAE(env);
+ }
+}
+
class SkMaskFilterGlue {
public:
static void destructor(JNIEnv* env, jobject, SkMaskFilter* filter) {
- SkASSERT(filter);
- filter->unref();
+ filter->safeUnref();
}
static SkMaskFilter* createBlur(JNIEnv* env, jobject, float radius, int blurStyle) {
- return SkBlurMaskFilter::Create(SkFloatToScalar(radius), (SkBlurMaskFilter::BlurStyle)blurStyle);
+ SkMaskFilter* filter = SkBlurMaskFilter::Create(SkFloatToScalar(radius),
+ (SkBlurMaskFilter::BlurStyle)blurStyle);
+ ThrowIAE_IfNull(env, filter);
+ return filter;
}
static SkMaskFilter* createEmboss(JNIEnv* env, jobject, jfloatArray dirArray, float ambient, float specular, float radius) {
@@ -24,8 +32,12 @@
direction[i] = SkFloatToScalar(values[i]);
}
- return SkBlurMaskFilter::CreateEmboss(direction, SkFloatToScalar(ambient),
- SkFloatToScalar(specular), SkFloatToScalar(radius));
+ SkMaskFilter* filter = SkBlurMaskFilter::CreateEmboss(direction,
+ SkFloatToScalar(ambient),
+ SkFloatToScalar(specular),
+ SkFloatToScalar(radius));
+ ThrowIAE_IfNull(env, filter);
+ return filter;
}
};
diff --git a/core/jni/android/graphics/Shader.cpp b/core/jni/android/graphics/Shader.cpp
index b28eb90..b09c62b 100644
--- a/core/jni/android/graphics/Shader.cpp
+++ b/core/jni/android/graphics/Shader.cpp
@@ -43,25 +43,23 @@
static void Shader_destructor(JNIEnv* env, jobject, SkShader* shader)
{
- SkASSERT(shader != NULL);
- shader->unref();
+ shader->safeUnref();
}
static bool Shader_getLocalMatrix(JNIEnv* env, jobject, const SkShader* shader, SkMatrix* matrix)
{
- SkASSERT(shader != NULL);
- return shader->getLocalMatrix(matrix);
+ return shader ? shader->getLocalMatrix(matrix) : false;
}
static void Shader_setLocalMatrix(JNIEnv* env, jobject, SkShader* shader, const SkMatrix* matrix)
{
- SkASSERT(shader != NULL);
-
- if (NULL == matrix) {
- shader->resetLocalMatrix();
- }
- else {
- shader->setLocalMatrix(*matrix);
+ if (shader) {
+ if (NULL == matrix) {
+ shader->resetLocalMatrix();
+ }
+ else {
+ shader->setLocalMatrix(*matrix);
+ }
}
}
diff --git a/core/jni/android_util_AssetManager.cpp b/core/jni/android_util_AssetManager.cpp
index 59f4067..66b2506 100644
--- a/core/jni/android_util_AssetManager.cpp
+++ b/core/jni/android_util_AssetManager.cpp
@@ -74,12 +74,13 @@
}
enum {
- STYLE_NUM_ENTRIES = 5,
+ STYLE_NUM_ENTRIES = 6,
STYLE_TYPE = 0,
STYLE_DATA = 1,
STYLE_ASSET_COOKIE = 2,
STYLE_RESOURCE_ID = 3,
- STYLE_CHANGING_CONFIGURATIONS = 4
+ STYLE_CHANGING_CONFIGURATIONS = 4,
+ STYLE_DENSITY = 5
};
static jint copyValue(JNIEnv* env, jobject outValue, const ResTable* table,
@@ -896,6 +897,7 @@
ResTable::Theme* theme = (ResTable::Theme*)themeToken;
const ResTable& res = theme->getResTable();
ResXMLParser* xmlParser = (ResXMLParser*)xmlParserToken;
+ ResTable_config config;
Res_value value;
const jsize NI = env->GetArrayLength(attrs);
@@ -995,6 +997,7 @@
value.dataType = Res_value::TYPE_NULL;
value.data = 0;
typeSetFlags = 0;
+ config.density = 0;
// Skip through XML attributes until the end or the next possible match.
while (ix < NX && curIdent > curXmlAttr) {
@@ -1042,7 +1045,8 @@
if (value.dataType != Res_value::TYPE_NULL) {
// Take care of resolving the found resource to its final value.
//printf("Resolving attribute reference\n");
- ssize_t newBlock = theme->resolveAttributeReference(&value, block, &resid, &typeSetFlags);
+ ssize_t newBlock = theme->resolveAttributeReference(&value, block,
+ &resid, &typeSetFlags, &config);
if (newBlock >= 0) block = newBlock;
} else {
// If we still don't have a value for this attribute, try to find
@@ -1051,7 +1055,8 @@
ssize_t newBlock = theme->getAttribute(curIdent, &value, &typeSetFlags);
if (newBlock >= 0) {
//printf("Resolving resource reference\n");
- newBlock = res.resolveReference(&value, block, &resid, &typeSetFlags);
+ newBlock = res.resolveReference(&value, block, &resid,
+ &typeSetFlags, &config);
if (newBlock >= 0) block = newBlock;
}
}
@@ -1070,6 +1075,7 @@
block != kXmlBlock ? (jint)res.getTableCookie(block) : (jint)-1;
dest[STYLE_RESOURCE_ID] = resid;
dest[STYLE_CHANGING_CONFIGURATIONS] = typeSetFlags;
+ dest[STYLE_DENSITY] = config.density;
if (indices != NULL && value.dataType != Res_value::TYPE_NULL) {
indicesIdx++;
@@ -1108,6 +1114,7 @@
}
const ResTable& res(am->getResources());
ResXMLParser* xmlParser = (ResXMLParser*)xmlParserToken;
+ ResTable_config config;
Res_value value;
const jsize NI = env->GetArrayLength(attrs);
@@ -1160,6 +1167,7 @@
value.dataType = Res_value::TYPE_NULL;
value.data = 0;
typeSetFlags = 0;
+ config.density = 0;
// Skip through XML attributes until the end or the next possible match.
while (ix < NX && curIdent > curXmlAttr) {
@@ -1179,7 +1187,8 @@
if (value.dataType != Res_value::TYPE_NULL) {
// Take care of resolving the found resource to its final value.
//printf("Resolving attribute reference\n");
- ssize_t newBlock = res.resolveReference(&value, block, &resid, &typeSetFlags);
+ ssize_t newBlock = res.resolveReference(&value, block, &resid,
+ &typeSetFlags, &config);
if (newBlock >= 0) block = newBlock;
}
@@ -1197,6 +1206,7 @@
block != kXmlBlock ? (jint)res.getTableCookie(block) : (jint)-1;
dest[STYLE_RESOURCE_ID] = resid;
dest[STYLE_CHANGING_CONFIGURATIONS] = typeSetFlags;
+ dest[STYLE_DENSITY] = config.density;
if (indices != NULL && value.dataType != Res_value::TYPE_NULL) {
indicesIdx++;
@@ -1250,6 +1260,7 @@
return JNI_FALSE;
}
const ResTable& res(am->getResources());
+ ResTable_config config;
Res_value value;
ssize_t block;
@@ -1276,13 +1287,15 @@
while (i < NV && arrayEnt < endArrayEnt) {
block = arrayEnt->stringBlock;
typeSetFlags = arrayTypeSetFlags;
+ config.density = 0;
value = arrayEnt->map.value;
uint32_t resid = 0;
if (value.dataType != Res_value::TYPE_NULL) {
// Take care of resolving the found resource to its final value.
//printf("Resolving attribute reference\n");
- ssize_t newBlock = res.resolveReference(&value, block, &resid, &typeSetFlags);
+ ssize_t newBlock = res.resolveReference(&value, block, &resid,
+ &typeSetFlags, &config);
if (newBlock >= 0) block = newBlock;
}
@@ -1299,6 +1312,7 @@
dest[STYLE_ASSET_COOKIE] = (jint)res.getTableCookie(block);
dest[STYLE_RESOURCE_ID] = resid;
dest[STYLE_CHANGING_CONFIGURATIONS] = typeSetFlags;
+ dest[STYLE_DENSITY] = config.density;
dest += STYLE_NUM_ENTRIES;
i+= STYLE_NUM_ENTRIES;
arrayEnt++;
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 5f94ee5..69ef96c 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1132,8 +1132,7 @@
<activity android:name="com.android.server.ShutdownActivity"
android:permission="android.permission.SHUTDOWN"
- android:excludeFromRecents="true"
- android:multiprocess="true">
+ android:excludeFromRecents="true">
<intent-filter>
<action android:name="android.intent.action.ACTION_REQUEST_SHUTDOWN" />
<category android:name="android.intent.category.DEFAULT" />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 549b668..558d91e 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -916,12 +916,12 @@
you.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permlab_readPhoneState">read phone state</string>
+ <string name="permlab_readPhoneState">read phone state and identity</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_readPhoneState">Allows the application to access the phone
features of the device. An application with this permission can determine the phone
- number of this phone, whether a call is active, the number that call is connected to
- and the like.</string>
+ number and serial number of this phone, whether a call is active, the number that call
+ is connected to and the like.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_wakeLock">prevent phone from sleeping</string>
diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java
index bc2e42e..345f810 100644
--- a/graphics/java/android/graphics/Canvas.java
+++ b/graphics/java/android/graphics/Canvas.java
@@ -50,6 +50,9 @@
// Package-scoped for quick access.
/*package*/ int mDensity = Bitmap.DENSITY_NONE;
+
+ // Used to determine when compatibility scaling is in effect.
+ private int mScreenDensity = Bitmap.DENSITY_NONE;
// Used by native code
@SuppressWarnings({"UnusedDeclaration"})
@@ -219,6 +222,11 @@
mDensity = density;
}
+ /** @hide */
+ public void setScreenDensity(int density) {
+ mScreenDensity = density;
+ }
+
// the SAVE_FLAG constants must match their native equivalents
/** restore the current matrix when restore() is called */
@@ -971,7 +979,8 @@
public void drawBitmap(Bitmap bitmap, float left, float top, Paint paint) {
throwIfRecycled(bitmap);
native_drawBitmap(mNativeCanvas, bitmap.ni(), left, top,
- paint != null ? paint.mNativePaint : 0, mDensity, bitmap.mDensity);
+ paint != null ? paint.mNativePaint : 0, mDensity, mScreenDensity,
+ bitmap.mDensity);
}
/**
@@ -1002,7 +1011,8 @@
}
throwIfRecycled(bitmap);
native_drawBitmap(mNativeCanvas, bitmap.ni(), src, dst,
- paint != null ? paint.mNativePaint : 0);
+ paint != null ? paint.mNativePaint : 0,
+ mScreenDensity, bitmap.mDensity);
}
/**
@@ -1033,7 +1043,8 @@
}
throwIfRecycled(bitmap);
native_drawBitmap(mNativeCanvas, bitmap.ni(), src, dst,
- paint != null ? paint.mNativePaint : 0);
+ paint != null ? paint.mNativePaint : 0,
+ mScreenDensity, bitmap.mDensity);
}
/**
@@ -1513,13 +1524,19 @@
private native void native_drawBitmap(int nativeCanvas, int bitmap,
float left, float top,
int nativePaintOrZero,
- int canvasDensity, int bitmapDensity);
+ int canvasDensity,
+ int screenDensity,
+ int bitmapDensity);
private native void native_drawBitmap(int nativeCanvas, int bitmap,
Rect src, RectF dst,
- int nativePaintOrZero);
+ int nativePaintOrZero,
+ int screenDensity,
+ int bitmapDensity);
private static native void native_drawBitmap(int nativeCanvas, int bitmap,
Rect src, Rect dst,
- int nativePaintOrZero);
+ int nativePaintOrZero,
+ int screenDensity,
+ int bitmapDensity);
private static native void native_drawBitmap(int nativeCanvas, int[] colors,
int offset, int stride, float x,
float y, int width, int height,
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index 2b9e448..1770a7a 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -23,6 +23,12 @@
import java.io.InputStream;
import java.io.IOException;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.graphics.Color;
+
import android.os.Bundle;
import android.content.res.Resources;
import android.util.Log;
@@ -32,8 +38,6 @@
import android.view.Window;
import android.view.View;
import android.view.Surface;
-import android.graphics.Bitmap;
-import android.graphics.Color;
/**
* @hide
@@ -53,6 +57,8 @@
private static boolean sInitialized;
native private static void _nInit();
+ private static BitmapFactory.Options mBitmapOptions = new BitmapFactory.Options();
+
static {
sInitialized = false;
try {
@@ -62,6 +68,7 @@
} catch (UnsatisfiedLinkError e) {
Log.d(LOG_TAG, "RenderScript JNI library not found!");
}
+ mBitmapOptions.inScaled = false;
}
native private int nDeviceCreate();
@@ -539,6 +546,17 @@
return new Allocation(id);
}
+ public Allocation allocationCreateFromBitmapResource(Resources res, int id, ElementPredefined internalElement, boolean genMips) {
+ Bitmap b = BitmapFactory.decodeResource(res, id, mBitmapOptions);
+ return allocationCreateFromBitmap(b, internalElement, genMips);
+ }
+
+ public Allocation allocationCreateFromBitmapResourceBoxed(Resources res, int id, ElementPredefined internalElement, boolean genMips) {
+ Bitmap b = BitmapFactory.decodeResource(res, id, mBitmapOptions);
+ return allocationCreateFromBitmapBoxed(b, internalElement, genMips);
+ }
+
+
//////////////////////////////////////////////////////////////////////////////////
// Adapter1D
diff --git a/include/media/mediarecorder.h b/include/media/mediarecorder.h
index ad27903..13316a9 100644
--- a/include/media/mediarecorder.h
+++ b/include/media/mediarecorder.h
@@ -93,10 +93,6 @@
VIDEO_ENCODER_LIST_END // must be the last - used to validate the video encoder type
};
-
-// Maximum frames per second is 24
-#define MEDIA_RECORDER_MAX_FRAME_RATE 24
-
/*
* The state machine of the media_recorder uses a set of different state names.
* The mapping between the media_recorder and the pvauthorengine is shown below:
diff --git a/include/ui/Overlay.h b/include/ui/Overlay.h
index acc9bea..a9ae1c4 100644
--- a/include/ui/Overlay.h
+++ b/include/ui/Overlay.h
@@ -82,10 +82,16 @@
/* release the overlay buffer and post it */
status_t queueBuffer(overlay_buffer_t buffer);
+ /* change the width and height of the overlay */
+ status_t resizeInput(uint32_t width, uint32_t height);
+
status_t setCrop(uint32_t x, uint32_t y, uint32_t w, uint32_t h) ;
status_t getCrop(uint32_t* x, uint32_t* y, uint32_t* w, uint32_t* h) ;
+ /* set the buffer attributes */
+ status_t setParameter(int param, int value);
+
/* returns the address of a given buffer if supported, NULL otherwise. */
void* getBufferAddress(overlay_buffer_t buffer);
diff --git a/include/utils/ResourceTypes.h b/include/utils/ResourceTypes.h
index edd0cae6..e524e2a 100644
--- a/include/utils/ResourceTypes.h
+++ b/include/utils/ResourceTypes.h
@@ -1655,7 +1655,8 @@
ssize_t resolveReference(Res_value* inOutValue,
ssize_t blockIndex,
uint32_t* outLastRef = NULL,
- uint32_t* inoutTypeSpecFlags = NULL) const;
+ uint32_t* inoutTypeSpecFlags = NULL,
+ ResTable_config* outConfig = NULL) const;
enum {
TMP_BUFFER_SIZE = 16
@@ -1729,7 +1730,8 @@
*/
ssize_t resolveAttributeReference(Res_value* inOutValue,
ssize_t blockIndex, uint32_t* outLastRef = NULL,
- uint32_t* inoutTypeSpecFlags = NULL) const;
+ uint32_t* inoutTypeSpecFlags = NULL,
+ ResTable_config* inoutConfig = NULL) const;
void dumpToLog() const;
diff --git a/libs/rs/java/Film/src/com/android/film/FilmRS.java b/libs/rs/java/Film/src/com/android/film/FilmRS.java
index a639c55..12a14e3 100644
--- a/libs/rs/java/Film/src/com/android/film/FilmRS.java
+++ b/libs/rs/java/Film/src/com/android/film/FilmRS.java
@@ -163,7 +163,6 @@
mPVImages.setName("PVImages");
}
-
private void loadImages() {
mBufferIDs = new int[13];
mImages = new RenderScript.Allocation[13];
@@ -171,51 +170,22 @@
RenderScript.ElementPredefined.USER_FLOAT,
mBufferIDs.length);
- Bitmap b;
- BitmapFactory.Options opts = new BitmapFactory.Options();
- opts.inScaled = false;
-
RenderScript.ElementPredefined ie =
RenderScript.ElementPredefined.RGB_565;
- b = BitmapFactory.decodeResource(mRes, R.drawable.p01, opts);
- mImages[0] = mRS.allocationCreateFromBitmapBoxed(b, ie, true);
-
- b = BitmapFactory.decodeResource(mRes, R.drawable.p02, opts);
- mImages[1] = mRS.allocationCreateFromBitmapBoxed(b, ie, true);
-
- b = BitmapFactory.decodeResource(mRes, R.drawable.p03, opts);
- mImages[2] = mRS.allocationCreateFromBitmapBoxed(b, ie, true);
-
- b = BitmapFactory.decodeResource(mRes, R.drawable.p04, opts);
- mImages[3] = mRS.allocationCreateFromBitmapBoxed(b, ie, true);
-
- b = BitmapFactory.decodeResource(mRes, R.drawable.p05, opts);
- mImages[4] = mRS.allocationCreateFromBitmapBoxed(b, ie, true);
-
- b = BitmapFactory.decodeResource(mRes, R.drawable.p06, opts);
- mImages[5] = mRS.allocationCreateFromBitmapBoxed(b, ie, true);
-
- b = BitmapFactory.decodeResource(mRes, R.drawable.p07, opts);
- mImages[6] = mRS.allocationCreateFromBitmapBoxed(b, ie, true);
-
- b = BitmapFactory.decodeResource(mRes, R.drawable.p08, opts);
- mImages[7] = mRS.allocationCreateFromBitmapBoxed(b, ie, true);
-
- b = BitmapFactory.decodeResource(mRes, R.drawable.p09, opts);
- mImages[8] = mRS.allocationCreateFromBitmapBoxed(b, ie, true);
-
- b = BitmapFactory.decodeResource(mRes, R.drawable.p10, opts);
- mImages[9] = mRS.allocationCreateFromBitmapBoxed(b, ie, true);
-
- b = BitmapFactory.decodeResource(mRes, R.drawable.p11, opts);
- mImages[10] = mRS.allocationCreateFromBitmapBoxed(b, ie, true);
-
- b = BitmapFactory.decodeResource(mRes, R.drawable.p12, opts);
- mImages[11] = mRS.allocationCreateFromBitmapBoxed(b, ie, true);
-
- b = BitmapFactory.decodeResource(mRes, R.drawable.p13, opts);
- mImages[12] = mRS.allocationCreateFromBitmapBoxed(b, ie, true);
+ mImages[0] = mRS.allocationCreateFromBitmapResourceBoxed(mRes, R.drawable.p01, ie, true);
+ mImages[1] = mRS.allocationCreateFromBitmapResourceBoxed(mRes, R.drawable.p02, ie, true);
+ mImages[2] = mRS.allocationCreateFromBitmapResourceBoxed(mRes, R.drawable.p03, ie, true);
+ mImages[3] = mRS.allocationCreateFromBitmapResourceBoxed(mRes, R.drawable.p04, ie, true);
+ mImages[4] = mRS.allocationCreateFromBitmapResourceBoxed(mRes, R.drawable.p05, ie, true);
+ mImages[5] = mRS.allocationCreateFromBitmapResourceBoxed(mRes, R.drawable.p06, ie, true);
+ mImages[6] = mRS.allocationCreateFromBitmapResourceBoxed(mRes, R.drawable.p07, ie, true);
+ mImages[7] = mRS.allocationCreateFromBitmapResourceBoxed(mRes, R.drawable.p08, ie, true);
+ mImages[8] = mRS.allocationCreateFromBitmapResourceBoxed(mRes, R.drawable.p09, ie, true);
+ mImages[9] = mRS.allocationCreateFromBitmapResourceBoxed(mRes, R.drawable.p10, ie, true);
+ mImages[10] = mRS.allocationCreateFromBitmapResourceBoxed(mRes, R.drawable.p11, ie, true);
+ mImages[11] = mRS.allocationCreateFromBitmapResourceBoxed(mRes, R.drawable.p12, ie, true);
+ mImages[12] = mRS.allocationCreateFromBitmapResourceBoxed(mRes, R.drawable.p13, ie, true);
for(int ct=0; ct < mImages.length; ct++) {
mImages[ct].uploadToTexture(1);
diff --git a/libs/rs/java/Rollo/res/raw/maps.png b/libs/rs/java/Rollo/res/raw/maps.png
new file mode 100644
index 0000000..fd5fc39
--- /dev/null
+++ b/libs/rs/java/Rollo/res/raw/maps.png
Binary files differ
diff --git a/libs/rs/java/Rollo/src/com/android/rollo/RolloRS.java b/libs/rs/java/Rollo/src/com/android/rollo/RolloRS.java
index c080176..039d4e9 100644
--- a/libs/rs/java/Rollo/src/com/android/rollo/RolloRS.java
+++ b/libs/rs/java/Rollo/src/com/android/rollo/RolloRS.java
@@ -18,7 +18,6 @@
import java.io.Writer;
-import android.renderscript.RSSurfaceView;
import android.renderscript.RenderScript;
import android.renderscript.ProgramVertexAlloc;
@@ -33,13 +32,7 @@
import android.graphics.Typeface;
import android.os.Handler;
import android.os.Message;
-import android.util.AttributeSet;
import android.util.Log;
-import android.view.Surface;
-import android.view.SurfaceHolder;
-import android.view.SurfaceView;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
public class RolloRS {
//public static final int STATE_SELECTED_ID = 0;
@@ -101,7 +94,6 @@
private RenderScript.Sampler mSamplerText;
private RenderScript.ProgramFragmentStore mPFSBackground;
private RenderScript.ProgramFragmentStore mPFSText;
- private RenderScript.ProgramFragment mPFBackground;
private RenderScript.ProgramFragment mPFImages;
private RenderScript.ProgramFragment mPFText;
private RenderScript.ProgramVertex mPV;
@@ -110,8 +102,6 @@
private ProgramVertexAlloc mPVOrthoAlloc;
private RenderScript.Allocation[] mIcons;
private RenderScript.Allocation[] mLabels;
- private RenderScript.Allocation mIconPlate;
- private RenderScript.Allocation mBackground;
private int[] mAllocStateBuf;
private RenderScript.Allocation mAllocState;
@@ -219,155 +209,85 @@
mAllocLabelID = mRS.allocationCreatePredefSized(
RenderScript.ElementPredefined.USER_I32, mLabels.length);
+ RenderScript.ElementPredefined ie565 =
+ RenderScript.ElementPredefined.RGB_565;
+ RenderScript.ElementPredefined ie8888 =
+ RenderScript.ElementPredefined.RGBA_8888;
- Bitmap b;
- BitmapFactory.Options opts = new BitmapFactory.Options();
- opts.inScaled = false;
+ mIcons[0] = mRS.allocationCreateFromBitmapResource(mRes, R.raw.browser, ie8888, true);
+ mIcons[1] = mRS.allocationCreateFromBitmapResource(mRes, R.raw.market, ie8888, true);
+ mIcons[2] = mRS.allocationCreateFromBitmapResource(mRes, R.raw.photos, ie8888, true);
+ mIcons[3] = mRS.allocationCreateFromBitmapResource(mRes, R.raw.settings, ie8888, true);
+ mIcons[4] = mRS.allocationCreateFromBitmapResource(mRes, R.raw.calendar, ie8888, true);
+ mIcons[5] = mRS.allocationCreateFromBitmapResource(mRes, R.raw.g1155, ie8888, true);
+ mIcons[6] = mRS.allocationCreateFromBitmapResource(mRes, R.raw.g2140, ie8888, true);
+ mIcons[7] = mRS.allocationCreateFromBitmapResource(mRes, R.raw.maps, ie8888, true);
+ mIcons[8] = mRS.allocationCreateFromBitmapResource(mRes, R.raw.path431, ie8888, true);
+ mIcons[9] = mRS.allocationCreateFromBitmapResource(mRes, R.raw.path676, ie8888, true);
+ mIcons[10] = mRS.allocationCreateFromBitmapResource(mRes, R.raw.path754, ie8888, true);
+ mIcons[11] = mRS.allocationCreateFromBitmapResource(mRes, R.raw.path815, ie8888, true);
+ mIcons[12] = mRS.allocationCreateFromBitmapResource(mRes, R.raw.path1920, ie8888, true);
+ mIcons[13] = mRS.allocationCreateFromBitmapResource(mRes, R.raw.path1927, ie8888, true);
+ mIcons[14] = mRS.allocationCreateFromBitmapResource(mRes, R.raw.path3099, ie8888, true);
+ mIcons[15] = mRS.allocationCreateFromBitmapResource(mRes, R.raw.path3950, ie8888, true);
+ mIcons[16] = mRS.allocationCreateFromBitmapResource(mRes, R.raw.path4481, ie8888, true);
+ mIcons[17] = mRS.allocationCreateFromBitmapResource(mRes, R.raw.path5168, ie8888, true);
+ mIcons[18] = mRS.allocationCreateFromBitmapResource(mRes, R.raw.polygon2408, ie8888, true);
- b = BitmapFactory.decodeResource(mRes, R.raw.cf_background, opts);
- mBackground = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGB_565, true);
- mBackground.setName("TexBk");
-
-
- b = BitmapFactory.decodeResource(mRes, R.raw.browser, opts);
- mIcons[0] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGBA_8888, true);
mLabels[0] = makeTextBitmap("browser");
-
- b = BitmapFactory.decodeResource(mRes, R.raw.market, opts);
- mIcons[1] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGBA_8888, true);
mLabels[1] = makeTextBitmap("market");
-
- b = BitmapFactory.decodeResource(mRes, R.raw.photos, opts);
- mIcons[2] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGBA_8888, true);
mLabels[2] = makeTextBitmap("photos");
-
- b = BitmapFactory.decodeResource(mRes, R.raw.settings, opts);
- mIcons[3] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGBA_8888, true);
mLabels[3] = makeTextBitmap("settings");
-
- b = BitmapFactory.decodeResource(mRes, R.raw.calendar, opts);
- mIcons[4] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGBA_8888, true);
- mLabels[4] = makeTextBitmap("creed");
-
- b = BitmapFactory.decodeResource(mRes, R.raw.g1155, opts);
- mIcons[5] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGBA_8888, true);
- mLabels[5] = makeTextBitmap("BOA");
-
- b = BitmapFactory.decodeResource(mRes, R.raw.g2140, opts);
- mIcons[6] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGBA_8888, true);
- mLabels[6] = makeTextBitmap("chess");
-
- b = BitmapFactory.decodeResource(mRes, R.raw.maps, opts);
- mIcons[7] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGBA_8888, true);
- mLabels[7] = makeTextBitmap("Dictionary");
-
- b = BitmapFactory.decodeResource(mRes, R.raw.path431, opts);
- mIcons[8] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGBA_8888, true);
- mLabels[8] = makeTextBitmap("facebook");
-
- b = BitmapFactory.decodeResource(mRes, R.raw.path676, opts);
- mIcons[9] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGBA_8888, true);
- mLabels[9] = makeTextBitmap("Flash Light");
-
- b = BitmapFactory.decodeResource(mRes, R.raw.path754, opts);
- mIcons[10] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGBA_8888, true);
- mLabels[10] = makeTextBitmap("Flight Control");
-
- b = BitmapFactory.decodeResource(mRes, R.raw.path815, opts);
- mIcons[11] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGBA_8888, true);
- mLabels[11] = makeTextBitmap("google earth");
-
- b = BitmapFactory.decodeResource(mRes, R.raw.path1920, opts);
- mIcons[12] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGBA_8888, true);
- mLabels[12] = makeTextBitmap("Harry Potter");
-
- b = BitmapFactory.decodeResource(mRes, R.raw.path1927, opts);
- mIcons[13] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGBA_8888, true);
- mLabels[13] = makeTextBitmap("Movies");
-
- b = BitmapFactory.decodeResource(mRes, R.raw.path3099, opts);
- mIcons[14] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGBA_8888, true);
- mLabels[14] = makeTextBitmap("NY Times");
-
- b = BitmapFactory.decodeResource(mRes, R.raw.path3950, opts);
- mIcons[15] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGBA_8888, true);
- mLabels[15] = makeTextBitmap("Pandora");
-
- b = BitmapFactory.decodeResource(mRes, R.raw.path4481, opts);
- mIcons[16] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGBA_8888, true);
- mLabels[16] = makeTextBitmap("Public Radio");
-
- b = BitmapFactory.decodeResource(mRes, R.raw.path5168, opts);
- mIcons[17] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGBA_8888, true);
- mLabels[17] = makeTextBitmap("Public Radio");
-
- b = BitmapFactory.decodeResource(mRes, R.raw.polygon2408, opts);
- mIcons[18] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGBA_8888, true);
- mLabels[18] = makeTextBitmap("Public Radio");
-
- /*
- b = BitmapFactory.decodeResource(mRes, R.raw.solitaire, opts);
- mIcons[19] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGB_565, true);
- mLabels[19] = makeTextBitmap("Public Radio");
-
- b = BitmapFactory.decodeResource(mRes, R.raw.sudoku, opts);
- mIcons[20] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGB_565, true);
- mLabels[20] = makeTextBitmap("Public Radio");
-
- b = BitmapFactory.decodeResource(mRes, R.raw.taptaprevenge, opts);
- mIcons[21] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGB_565, true);
- mLabels[21] = makeTextBitmap("Public Radio");
-
- b = BitmapFactory.decodeResource(mRes, R.raw.tetris, opts);
- mIcons[22] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGB_565, true);
- mLabels[22] = makeTextBitmap("Public Radio");
-
- b = BitmapFactory.decodeResource(mRes, R.raw.tictactoe, opts);
- mIcons[23] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGB_565, true);
- mLabels[23] = makeTextBitmap("Public Radio");
-
- b = BitmapFactory.decodeResource(mRes, R.raw.tweetie, opts);
- mIcons[24] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGB_565, true);
- mLabels[24] = makeTextBitmap("Public Radio");
-
- b = BitmapFactory.decodeResource(mRes, R.raw.urbanspoon, opts);
- mIcons[25] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGB_565, true);
- mLabels[25] = makeTextBitmap("Public Radio");
-
- b = BitmapFactory.decodeResource(mRes, R.raw.waterslide_extreme, opts);
- mIcons[26] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGB_565, true);
- mLabels[26] = makeTextBitmap("Public Radio");
-
- b = BitmapFactory.decodeResource(mRes, R.raw.weather_channel, opts);
- mIcons[27] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGB_565, true);
- mLabels[27] = makeTextBitmap("Public Radio");
-
- b = BitmapFactory.decodeResource(mRes, R.raw.zippo, opts);
- mIcons[28] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGB_565, true);
- mLabels[28] = makeTextBitmap("Public Radio");
-*/
+ mLabels[4] = makeTextBitmap("calendar");
+ mLabels[5] = makeTextBitmap("g1155");
+ mLabels[6] = makeTextBitmap("g2140");
+ mLabels[7] = makeTextBitmap("maps");
+ mLabels[8] = makeTextBitmap("path431");
+ mLabels[9] = makeTextBitmap("path676");
+ mLabels[10] = makeTextBitmap("path754");
+ mLabels[11] = makeTextBitmap("path815");
+ mLabels[12] = makeTextBitmap("path1920");
+ mLabels[13] = makeTextBitmap("path1927");
+ mLabels[14] = makeTextBitmap("path3099");
+ mLabels[15] = makeTextBitmap("path3950");
+ mLabels[16] = makeTextBitmap("path4481");
+ mLabels[17] = makeTextBitmap("path5168");
+ mLabels[18] = makeTextBitmap("polygon2408");
mIcons[19] = mIcons[0];
mIcons[20] = mIcons[1];
mIcons[21] = mIcons[2];
mIcons[22] = mIcons[3];
- mIcons[23] = mIcons[2];
- mIcons[24] = mIcons[1];
- mIcons[25] = mIcons[0];
- mIcons[26] = mIcons[1];
- mIcons[27] = mIcons[2];
- mIcons[28] = mIcons[3];
+ mIcons[23] = mIcons[4];
+ mIcons[24] = mIcons[5];
+ mIcons[25] = mIcons[6];
+ mIcons[26] = mIcons[7];
+ mIcons[27] = mIcons[8];
+ mIcons[28] = mIcons[9];
mLabels[19] = mLabels[0];
mLabels[20] = mLabels[1];
mLabels[21] = mLabels[2];
mLabels[22] = mLabels[3];
- mLabels[23] = mLabels[2];
- mLabels[24] = mLabels[1];
- mLabels[25] = mLabels[0];
- mLabels[26] = mLabels[1];
- mLabels[27] = mLabels[2];
- mLabels[28] = mLabels[3];
+ mLabels[23] = mLabels[4];
+ mLabels[24] = mLabels[5];
+ mLabels[25] = mLabels[6];
+ mLabels[26] = mLabels[7];
+ mLabels[27] = mLabels[8];
+ mLabels[28] = mLabels[9];
+
+/*
+ mIcons[19] = mRS.allocationCreateFromBitmapResource(mRes, R.raw.solitaire, ie8888, true);
+ mIcons[20] = mRS.allocationCreateFromBitmapResource(mRes, R.raw.sudoku, ie8888, true);
+ mIcons[21] = mRS.allocationCreateFromBitmapResource(mRes, R.raw.taptaprevenge, ie8888, true);
+ mIcons[22] = mRS.allocationCreateFromBitmapResource(mRes, R.raw.tetris, ie8888, true);
+ mIcons[23] = mRS.allocationCreateFromBitmapResource(mRes, R.raw.tictactoe, ie8888, true);
+ mIcons[24] = mRS.allocationCreateFromBitmapResource(mRes, R.raw.tweetie, ie8888, true);
+ mIcons[25] = mRS.allocationCreateFromBitmapResource(mRes, R.raw.urbanspoon, ie8888, true);
+ mIcons[26] = mRS.allocationCreateFromBitmapResource(mRes, R.raw.waterslide_extreme, ie8888, true);
+ mIcons[27] = mRS.allocationCreateFromBitmapResource(mRes, R.raw.weather_channel, ie8888, true);
+ mIcons[28] = mRS.allocationCreateFromBitmapResource(mRes, R.raw.zippo, ie8888, true);
+*/
for(int ct=0; ct < mIcons.length; ct++) {
@@ -378,33 +298,6 @@
}
mAllocIconID.data(mAllocIconIDBuf);
mAllocLabelID.data(mAllocLabelIDBuf);
-
- RenderScript.Element e = mRS.elementGetPredefined(RenderScript.ElementPredefined.RGB_565);
- mRS.typeBegin(e);
- mRS.typeAdd(RenderScript.Dimension.X, 64);
- mRS.typeAdd(RenderScript.Dimension.Y, 64);
- RenderScript.Type t = mRS.typeCreate();
- mIconPlate = mRS.allocationCreateTyped(t);
- //t.destroy();
- //e.destroy();
-
- int tmp[] = new int[64 * 32];
- for(int ct = 0; ct < (64*32); ct++) {
- tmp[ct] = 7 | (13 << 5) | (7 << 11);
- tmp[ct] = tmp[ct] | (tmp[ct] << 16);
- }
- for(int ct = 0; ct < 32; ct++) {
- tmp[ct] = 0;
- tmp[ct + (63*32)] = 0;
- }
- for(int ct = 0; ct < 64; ct++) {
- tmp[ct * 32] = 0;
- tmp[ct * 32 + 31] = 0;
- }
- mIconPlate.data(tmp);
- mIconPlate.uploadToTexture(0);
- mIconPlate.setName("Plate");
- mPFImages.bindTexture(mIconPlate, 0);
}
}
@@ -427,7 +320,6 @@
mRS.scriptCSetScript(mRes, R.raw.rollo);
//mRS.scriptCSetScript(mRes, R.raw.rollo2);
mRS.scriptCSetRoot(true);
- //mRS.scriptCSetClearDepth(0);
mScript = mRS.scriptCCreate();
mAllocStateBuf = new int[] {0, 0, 0, 8, 0, 0, -1, 0, mAllocIconIDBuf.length, 0, 0};
diff --git a/libs/surfaceflinger/LayerBase.cpp b/libs/surfaceflinger/LayerBase.cpp
index a841ab3..fbce73d 100644
--- a/libs/surfaceflinger/LayerBase.cpp
+++ b/libs/surfaceflinger/LayerBase.cpp
@@ -461,7 +461,8 @@
glRotatef(-90, 0, 0, 1);
}
- if (!(mFlags & DisplayHardware::NPOT_EXTENSION)) {
+ if (!(mFlags & (DisplayHardware::NPOT_EXTENSION |
+ DisplayHardware::DIRECT_TEXTURE))) {
// find the smallest power-of-two that will accommodate our surface
GLuint tw = 1 << (31 - clz(width));
GLuint th = 1 << (31 - clz(height));
diff --git a/libs/ui/BufferMapper.cpp b/libs/ui/BufferMapper.cpp
index 92a9a86..4add8f9 100644
--- a/libs/ui/BufferMapper.cpp
+++ b/libs/ui/BufferMapper.cpp
@@ -65,7 +65,7 @@
{
status_t err = mAllocMod->lock(mAllocMod, handle, usage,
bounds.left, bounds.top, bounds.width(), bounds.height(), vaddr);
- LOGW_IF(err, "unlock(...) failed %d (%s)", err, strerror(-err));
+ LOGW_IF(err, "lock(...) failed %d (%s)", err, strerror(-err));
return err;
}
diff --git a/libs/ui/Overlay.cpp b/libs/ui/Overlay.cpp
index 4854d6a..3aa8950 100644
--- a/libs/ui/Overlay.cpp
+++ b/libs/ui/Overlay.cpp
@@ -59,6 +59,18 @@
return mOverlayData->queueBuffer(mOverlayData, buffer);
}
+status_t Overlay::resizeInput(uint32_t width, uint32_t height)
+{
+ if (mStatus != NO_ERROR) return mStatus;
+ return mOverlayData->resizeInput(mOverlayData, width, height);
+}
+
+status_t Overlay::setParameter(int param, int value)
+{
+ if (mStatus != NO_ERROR) return mStatus;
+ return mOverlayData->setParameter(mOverlayData, param, value);
+}
+
status_t Overlay::setCrop(uint32_t x, uint32_t y, uint32_t w, uint32_t h)
{
if (mStatus != NO_ERROR) return mStatus;
diff --git a/libs/utils/ResourceTypes.cpp b/libs/utils/ResourceTypes.cpp
index 4dca8bd..0831f4a 100644
--- a/libs/utils/ResourceTypes.cpp
+++ b/libs/utils/ResourceTypes.cpp
@@ -1486,7 +1486,7 @@
ssize_t ResTable::Theme::resolveAttributeReference(Res_value* inOutValue,
ssize_t blockIndex, uint32_t* outLastRef,
- uint32_t* inoutTypeSpecFlags) const
+ uint32_t* inoutTypeSpecFlags, ResTable_config* inoutConfig) const
{
//printf("Resolving type=0x%x\n", inOutValue->dataType);
if (inOutValue->dataType == Res_value::TYPE_ATTRIBUTE) {
@@ -1498,7 +1498,8 @@
return blockIndex;
}
}
- return mTable.resolveReference(inOutValue, blockIndex, outLastRef);
+ return mTable.resolveReference(inOutValue, blockIndex, outLastRef,
+ inoutTypeSpecFlags, inoutConfig);
}
void ResTable::Theme::dumpToLog() const
@@ -1891,7 +1892,8 @@
}
ssize_t ResTable::resolveReference(Res_value* value, ssize_t blockIndex,
- uint32_t* outLastRef, uint32_t* inoutTypeSpecFlags) const
+ uint32_t* outLastRef, uint32_t* inoutTypeSpecFlags,
+ ResTable_config* outConfig) const
{
int count=0;
while (blockIndex >= 0 && value->dataType == value->TYPE_REFERENCE
@@ -1899,7 +1901,8 @@
if (outLastRef) *outLastRef = value->data;
uint32_t lastRef = value->data;
uint32_t newFlags = 0;
- const ssize_t newIndex = getResource(value->data, value, true, &newFlags);
+ const ssize_t newIndex = getResource(value->data, value, true, &newFlags,
+ outConfig);
//LOGI("Resolving reference d=%p: newIndex=%d, t=0x%02x, d=%p\n",
// (void*)lastRef, (int)newIndex, (int)value->dataType, (void*)value->data);
//printf("Getting reference 0x%08x: newIndex=%d\n", value->data, newIndex);
diff --git a/media/jni/android_media_MediaRecorder.cpp b/media/jni/android_media_MediaRecorder.cpp
index 0273a5a..304f521 100644
--- a/media/jni/android_media_MediaRecorder.cpp
+++ b/media/jni/android_media_MediaRecorder.cpp
@@ -276,7 +276,7 @@
android_media_MediaRecorder_setVideoFrameRate(JNIEnv *env, jobject thiz, jint rate)
{
LOGV("setVideoFrameRate(%d)", rate);
- if (rate <= 0 || rate > MEDIA_RECORDER_MAX_FRAME_RATE) {
+ if (rate <= 0) {
jniThrowException(env, "java/lang/IllegalArgumentException", "invalid frame rate");
return;
}
diff --git a/packages/VpnServices/src/com/android/server/vpn/DaemonProxy.java b/packages/VpnServices/src/com/android/server/vpn/DaemonProxy.java
index b749821..289ee45 100644
--- a/packages/VpnServices/src/com/android/server/vpn/DaemonProxy.java
+++ b/packages/VpnServices/src/com/android/server/vpn/DaemonProxy.java
@@ -25,6 +25,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.io.Serializable;
/**
* Proxy to start, stop and interact with a VPN daemon.
@@ -33,7 +34,10 @@
* connection with the daemon, to both send commands to the daemon and receive
* response and connecting error code from the daemon.
*/
-class DaemonProxy {
+class DaemonProxy implements Serializable {
+ private static final long serialVersionUID = 1L;
+ private static final boolean DBG = true;
+
private static final int WAITING_TIME = 15; // sec
private static final String SVC_STATE_CMD_PREFIX = "init.svc.";
@@ -45,8 +49,8 @@
private static final int END_OF_ARGUMENTS = 255;
private String mName;
- private LocalSocket mControlSocket;
private String mTag;
+ private transient LocalSocket mControlSocket;
/**
* Creates a proxy of the specified daemon.
@@ -63,14 +67,8 @@
void start() throws IOException {
String svc = mName;
- Log.d(mTag, "----- Stop the daemon just in case: " + mName);
- SystemProperties.set(SVC_STOP_CMD, mName);
- if (!blockUntil(SVC_STATE_STOPPED, 5)) {
- throw new IOException("cannot start service anew: " + svc
- + ", it is still running");
- }
- Log.d(mTag, "+++++ Start: " + svc);
+ Log.i(mTag, "Start VPN daemon: " + svc);
SystemProperties.set(SVC_START_CMD, svc);
if (!blockUntil(SVC_STATE_RUNNING, WAITING_TIME)) {
@@ -103,7 +101,7 @@
try {
mControlSocket.close();
} catch (IOException e) {
- Log.e(mTag, "close control socket", e);
+ Log.w(mTag, "close control socket", e);
} finally {
mControlSocket = null;
}
@@ -111,10 +109,10 @@
void stop() {
String svc = mName;
- Log.d(mTag, "----- Stop: " + svc);
+ Log.i(mTag, "Stop VPN daemon: " + svc);
SystemProperties.set(SVC_STOP_CMD, svc);
boolean success = blockUntil(SVC_STATE_STOPPED, 5);
- Log.d(mTag, "stopping " + svc + ", success? " + success);
+ if (DBG) Log.d(mTag, "stopping " + svc + ", success? " + success);
}
boolean isStopped() {
@@ -129,7 +127,7 @@
if (!blocking && in.available() == 0) return 0;
int data = in.read();
- Log.d(mTag, "got data from control socket: " + data);
+ Log.i(mTag, "got data from control socket: " + data);
return data;
}
@@ -146,7 +144,7 @@
s.connect(a);
return s;
} catch (IOException e) {
- Log.d(mTag, "service not yet listen()ing; try again");
+ if (DBG) Log.d(mTag, "service not yet listen()ing; try again");
excp = e;
sleep(500);
}
@@ -173,8 +171,10 @@
int n = waitTime * 1000 / sleepTime;
for (int i = 0; i < n; i++) {
if (expectedState.equals(SystemProperties.get(cmd))) {
- Log.d(mTag, mName + " is " + expectedState + " after "
- + (i * sleepTime) + " msec");
+ if (DBG) {
+ Log.d(mTag, mName + " is " + expectedState + " after "
+ + (i * sleepTime) + " msec");
+ }
break;
}
sleep(sleepTime);
diff --git a/packages/VpnServices/src/com/android/server/vpn/L2tpIpsecPskService.java b/packages/VpnServices/src/com/android/server/vpn/L2tpIpsecPskService.java
index 8efd7c4..7910f4a 100644
--- a/packages/VpnServices/src/com/android/server/vpn/L2tpIpsecPskService.java
+++ b/packages/VpnServices/src/com/android/server/vpn/L2tpIpsecPskService.java
@@ -45,4 +45,10 @@
(p.isSecretEnabled() ? p.getSecretString() : null),
username, password);
}
+
+ @Override
+ protected void stopPreviouslyRunDaemons() {
+ stopDaemon(IPSEC);
+ stopDaemon(MtpdHelper.MTPD);
+ }
}
diff --git a/packages/VpnServices/src/com/android/server/vpn/L2tpIpsecService.java b/packages/VpnServices/src/com/android/server/vpn/L2tpIpsecService.java
index 56694b6..13b4952 100644
--- a/packages/VpnServices/src/com/android/server/vpn/L2tpIpsecService.java
+++ b/packages/VpnServices/src/com/android/server/vpn/L2tpIpsecService.java
@@ -46,6 +46,12 @@
username, password);
}
+ @Override
+ protected void stopPreviouslyRunDaemons() {
+ stopDaemon(IPSEC);
+ stopDaemon(MtpdHelper.MTPD);
+ }
+
private String getCaCertPath() {
return CertTool.getInstance().getCaCertificate(
getProfile().getCaCertificate());
diff --git a/packages/VpnServices/src/com/android/server/vpn/L2tpService.java b/packages/VpnServices/src/com/android/server/vpn/L2tpService.java
index 9273f35..d658a366 100644
--- a/packages/VpnServices/src/com/android/server/vpn/L2tpService.java
+++ b/packages/VpnServices/src/com/android/server/vpn/L2tpService.java
@@ -35,4 +35,9 @@
(p.isSecretEnabled() ? p.getSecretString() : null),
username, password);
}
+
+ @Override
+ protected void stopPreviouslyRunDaemons() {
+ stopDaemon(MtpdHelper.MTPD);
+ }
}
diff --git a/packages/VpnServices/src/com/android/server/vpn/MtpdHelper.java b/packages/VpnServices/src/com/android/server/vpn/MtpdHelper.java
index 805a5b5..9078d9b 100644
--- a/packages/VpnServices/src/com/android/server/vpn/MtpdHelper.java
+++ b/packages/VpnServices/src/com/android/server/vpn/MtpdHelper.java
@@ -24,26 +24,33 @@
* A helper class for sending commands to the MTP daemon (mtpd).
*/
class MtpdHelper {
- private static final String MTPD = "mtpd";
+ static final String MTPD = "mtpd";
private static final String VPN_LINKNAME = "vpn";
private static final String PPP_ARGS_SEPARATOR = "";
static void sendCommand(VpnService<?> vpnService, String protocol,
String serverIp, String port, String secret, String username,
String password) throws IOException {
+ sendCommand(vpnService, protocol, serverIp, port, secret, username,
+ password, false);
+ }
+
+ static void sendCommand(VpnService<?> vpnService, String protocol,
+ String serverIp, String port, String secret, String username,
+ String password, boolean encryption) throws IOException {
ArrayList<String> args = new ArrayList<String>();
args.addAll(Arrays.asList(protocol, serverIp, port));
if (secret != null) args.add(secret);
args.add(PPP_ARGS_SEPARATOR);
- addPppArguments(vpnService, args, serverIp, username, password);
+ addPppArguments(args, serverIp, username, password, encryption);
DaemonProxy mtpd = vpnService.startDaemon(MTPD);
mtpd.sendCommand(args.toArray(new String[args.size()]));
}
- private static void addPppArguments(VpnService<?> vpnService,
- ArrayList<String> args, String serverIp, String username,
- String password) throws IOException {
+ private static void addPppArguments(ArrayList<String> args, String serverIp,
+ String username, String password, boolean encryption)
+ throws IOException {
args.addAll(Arrays.asList(
"linkname", VPN_LINKNAME,
"name", username,
@@ -52,6 +59,9 @@
"idle", "1800",
"mtu", "1400",
"mru", "1400"));
+ if (encryption) {
+ args.add("+mppe");
+ }
}
private MtpdHelper() {
diff --git a/packages/VpnServices/src/com/android/server/vpn/PptpService.java b/packages/VpnServices/src/com/android/server/vpn/PptpService.java
index 01362a5..d903d1b 100644
--- a/packages/VpnServices/src/com/android/server/vpn/PptpService.java
+++ b/packages/VpnServices/src/com/android/server/vpn/PptpService.java
@@ -26,11 +26,17 @@
class PptpService extends VpnService<PptpProfile> {
static final String PPTP_DAEMON = "pptp";
static final String PPTP_PORT = "1723";
+
@Override
protected void connect(String serverIp, String username, String password)
throws IOException {
+ PptpProfile p = getProfile();
MtpdHelper.sendCommand(this, PPTP_DAEMON, serverIp, PPTP_PORT, null,
- username, password);
+ username, password, p.isEncryptionEnabled());
}
+ @Override
+ protected void stopPreviouslyRunDaemons() {
+ stopDaemon(MtpdHelper.MTPD);
+ }
}
diff --git a/packages/VpnServices/src/com/android/server/vpn/VpnService.java b/packages/VpnServices/src/com/android/server/vpn/VpnService.java
index 60a07d5..b107c7d 100644
--- a/packages/VpnServices/src/com/android/server/vpn/VpnService.java
+++ b/packages/VpnServices/src/com/android/server/vpn/VpnService.java
@@ -28,7 +28,11 @@
import android.util.Log;
import java.io.IOException;
+import java.io.Serializable;
+import java.net.DatagramSocket;
+import java.net.Socket;
import java.net.InetAddress;
+import java.net.NetworkInterface;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
@@ -36,7 +40,9 @@
/**
* The service base class for managing a type of VPN connection.
*/
-abstract class VpnService<E extends VpnProfile> {
+abstract class VpnService<E extends VpnProfile> implements Serializable {
+ protected static final long serialVersionUID = 1L;
+ private static final boolean DBG = true;
private static final int NOTIFICATION_ID = 1;
private static final String DNS1 = "net.dns1";
@@ -50,12 +56,16 @@
private static final String REMOTE_IP = "net.ipremote";
private static final String DNS_DOMAIN_SUFFICES = "net.dns.search";
+ private static final int CHALLENGE_ERROR_CODE = 5;
+ private static final int REMOTE_HUNG_UP_ERROR_CODE = 7;
private static final int AUTH_ERROR_CODE = 51;
private final String TAG = VpnService.class.getSimpleName();
+ // FIXME: profile is only needed in connecting phase, so we can just save
+ // the profile name and service class name for recovery
E mProfile;
- VpnServiceBinder mContext;
+ transient VpnServiceBinder mContext;
private VpnState mState = VpnState.IDLE;
private Throwable mError;
@@ -63,9 +73,9 @@
// connection settings
private String mOriginalDns1;
private String mOriginalDns2;
- private String mVpnDns1 = "";
- private String mVpnDns2 = "";
private String mOriginalDomainSuffices;
+ private String mLocalIp;
+ private String mLocalIf;
private long mStartTime; // VPN connection start time
@@ -73,7 +83,7 @@
private DaemonHelper mDaemonHelper = new DaemonHelper();
// for helping showing, updating notification
- private NotificationHelper mNotification = new NotificationHelper();
+ private transient NotificationHelper mNotification;
/**
* Establishes a VPN connection with the specified username and password.
@@ -81,6 +91,8 @@
protected abstract void connect(String serverIp, String username,
String password) throws IOException;
+ protected abstract void stopPreviouslyRunDaemons();
+
/**
* Starts a VPN daemon.
*/
@@ -90,6 +102,13 @@
}
/**
+ * Stops a VPN daemon.
+ */
+ protected void stopDaemon(String daemonName) {
+ new DaemonProxy(daemonName).stop();
+ }
+
+ /**
* Returns the VPN profile associated with the connection.
*/
protected E getProfile() {
@@ -104,8 +123,22 @@
}
void setContext(VpnServiceBinder context, E profile) {
- mContext = context;
mProfile = profile;
+ recover(context);
+ }
+
+ void recover(VpnServiceBinder context) {
+ mContext = context;
+ mNotification = new NotificationHelper();
+
+ if (VpnState.CONNECTED.equals(mState)) {
+ Log.i("VpnService", " recovered: " + mProfile.getName());
+ new Thread(new Runnable() {
+ public void run() {
+ enterConnectivityLoop();
+ }
+ }).start();
+ }
}
VpnState getState() {
@@ -117,14 +150,14 @@
mState = VpnState.CONNECTING;
broadcastConnectivity(VpnState.CONNECTING);
+ stopPreviouslyRunDaemons();
String serverIp = getIp(getProfile().getServerName());
-
+ saveLocalIpAndInterface(serverIp);
onBeforeConnect();
connect(serverIp, username, password);
waitUntilConnectedOrTimedout();
return true;
} catch (Throwable e) {
- Log.e(TAG, "onConnect()", e);
onError(e);
return false;
}
@@ -132,7 +165,7 @@
synchronized void onDisconnect() {
try {
- Log.d(TAG, " disconnecting VPN...");
+ Log.i(TAG, "disconnecting VPN...");
mState = VpnState.DISCONNECTING;
broadcastConnectivity(VpnState.DISCONNECTING);
mNotification.showDisconnect();
@@ -152,6 +185,7 @@
Log.w(TAG, " multiple errors occur, record the last one: "
+ error);
}
+ Log.e(TAG, "onError()", error);
mError = error;
onDisconnect();
}
@@ -161,16 +195,18 @@
}
- private void onBeforeConnect() {
+ private void onBeforeConnect() throws IOException {
mNotification.disableNotification();
- SystemProperties.set(VPN_DNS1, "-");
- SystemProperties.set(VPN_DNS2, "-");
+ SystemProperties.set(VPN_DNS1, "");
+ SystemProperties.set(VPN_DNS2, "");
SystemProperties.set(VPN_STATUS, VPN_IS_DOWN);
- Log.d(TAG, " VPN UP: " + SystemProperties.get(VPN_STATUS));
+ if (DBG) {
+ Log.d(TAG, " VPN UP: " + SystemProperties.get(VPN_STATUS));
+ }
}
- private void waitUntilConnectedOrTimedout() {
+ private void waitUntilConnectedOrTimedout() throws IOException {
sleep(2000); // 2 seconds
for (int i = 0; i < 60; i++) {
if (mState != VpnState.CONNECTING) {
@@ -187,39 +223,49 @@
synchronized (VpnService.this) {
if (mState == VpnState.CONNECTING) {
- Log.d(TAG, " connecting timed out !!");
onError(new IOException("Connecting timed out"));
}
}
}
- private synchronized void onConnected() {
- Log.d(TAG, "onConnected()");
+ private synchronized void onConnected() throws IOException {
+ if (DBG) Log.d(TAG, "onConnected()");
mDaemonHelper.closeSockets();
- saveVpnDnsProperties();
+ saveOriginalDns();
saveAndSetDomainSuffices();
mState = VpnState.CONNECTED;
+ mStartTime = System.currentTimeMillis();
+
+ // set DNS after saving the states in case the process gets killed
+ // before states are saved
+ saveSelf();
+ setVpnDns();
broadcastConnectivity(VpnState.CONNECTED);
enterConnectivityLoop();
}
+ private void saveSelf() throws IOException {
+ mContext.saveStates();
+ }
+
private synchronized void onFinalCleanUp() {
- Log.d(TAG, "onFinalCleanUp()");
+ if (DBG) Log.d(TAG, "onFinalCleanUp()");
if (mState == VpnState.IDLE) return;
// keep the notification when error occurs
if (!anyError()) mNotification.disableNotification();
- restoreOriginalDnsProperties();
+ restoreOriginalDns();
restoreOriginalDomainSuffices();
mState = VpnState.IDLE;
broadcastConnectivity(VpnState.IDLE);
// stop the service itself
+ mContext.removeStates();
mContext.stopSelf();
}
@@ -227,46 +273,38 @@
return (mError != null);
}
- private void restoreOriginalDnsProperties() {
+ private void restoreOriginalDns() {
// restore only if they are not overridden
- if (mVpnDns1.equals(SystemProperties.get(DNS1))) {
- Log.d(TAG, String.format("restore original dns prop: %s --> %s",
+ String vpnDns1 = SystemProperties.get(VPN_DNS1);
+ if (vpnDns1.equals(SystemProperties.get(DNS1))) {
+ Log.i(TAG, String.format("restore original dns prop: %s --> %s",
SystemProperties.get(DNS1), mOriginalDns1));
- Log.d(TAG, String.format("restore original dns prop: %s --> %s",
+ Log.i(TAG, String.format("restore original dns prop: %s --> %s",
SystemProperties.get(DNS2), mOriginalDns2));
SystemProperties.set(DNS1, mOriginalDns1);
SystemProperties.set(DNS2, mOriginalDns2);
}
}
- private void saveVpnDnsProperties() {
- mOriginalDns1 = mOriginalDns2 = "";
- for (int i = 0; i < 5; i++) {
- mVpnDns1 = SystemProperties.get(VPN_DNS1);
- mVpnDns2 = SystemProperties.get(VPN_DNS2);
- if (mOriginalDns1.equals(mVpnDns1)) {
- Log.d(TAG, "wait for vpn dns to settle in..." + i);
- sleep(200);
- } else {
- mOriginalDns1 = SystemProperties.get(DNS1);
- mOriginalDns2 = SystemProperties.get(DNS2);
- SystemProperties.set(DNS1, mVpnDns1);
- SystemProperties.set(DNS2, mVpnDns2);
- Log.d(TAG, String.format("save original dns prop: %s, %s",
- mOriginalDns1, mOriginalDns2));
- Log.d(TAG, String.format("set vpn dns prop: %s, %s",
- mVpnDns1, mVpnDns2));
- return;
- }
- }
- Log.d(TAG, "saveVpnDnsProperties(): DNS not updated??");
- mOriginalDns1 = mVpnDns1 = SystemProperties.get(DNS1);
- mOriginalDns2 = mVpnDns2 = SystemProperties.get(DNS2);
+ private void saveOriginalDns() {
+ mOriginalDns1 = SystemProperties.get(DNS1);
+ mOriginalDns2 = SystemProperties.get(DNS2);
+ Log.i(TAG, String.format("save original dns prop: %s, %s",
+ mOriginalDns1, mOriginalDns2));
+ }
+
+ private void setVpnDns() {
+ String vpnDns1 = SystemProperties.get(VPN_DNS1);
+ String vpnDns2 = SystemProperties.get(VPN_DNS2);
+ SystemProperties.set(DNS1, vpnDns1);
+ SystemProperties.set(DNS2, vpnDns2);
+ Log.i(TAG, String.format("set vpn dns prop: %s, %s",
+ vpnDns1, vpnDns2));
}
private void saveAndSetDomainSuffices() {
mOriginalDomainSuffices = SystemProperties.get(DNS_DOMAIN_SUFFICES);
- Log.d(TAG, "save original dns search: " + mOriginalDomainSuffices);
+ Log.i(TAG, "save original suffices: " + mOriginalDomainSuffices);
String list = mProfile.getDomainSuffices();
if (!TextUtils.isEmpty(list)) {
SystemProperties.set(DNS_DOMAIN_SUFFICES, list);
@@ -274,7 +312,7 @@
}
private void restoreOriginalDomainSuffices() {
- Log.d(TAG, "restore original dns search --> " + mOriginalDomainSuffices);
+ Log.i(TAG, "restore original suffices --> " + mOriginalDomainSuffices);
SystemProperties.set(DNS_DOMAIN_SUFFICES, mOriginalDomainSuffices);
}
@@ -298,46 +336,73 @@
}
private void enterConnectivityLoop() {
- mStartTime = System.currentTimeMillis();
-
- Log.d(TAG, " +++++ connectivity monitor running");
+ Log.i(TAG, "VPN connectivity monitor running");
try {
for (;;) {
synchronized (VpnService.this) {
- if (mState != VpnState.CONNECTED) break;
+ if (mState != VpnState.CONNECTED || !checkConnectivity()) {
+ break;
+ }
mNotification.update();
- checkConnectivity();
+ checkDns();
VpnService.this.wait(1000); // 1 second
}
}
} catch (InterruptedException e) {
- Log.e(TAG, "connectivity monitor", e);
+ onError(e);
}
- Log.d(TAG, " ----- connectivity monitor stopped");
+ Log.i(TAG, "VPN connectivity monitor stopped");
}
- private void checkConnectivity() {
+ private void saveLocalIpAndInterface(String serverIp) throws IOException {
+ DatagramSocket s = new DatagramSocket();
+ int port = 80; // arbitrary
+ s.connect(InetAddress.getByName(serverIp), port);
+ InetAddress localIp = s.getLocalAddress();
+ mLocalIp = localIp.getHostAddress();
+ NetworkInterface localIf = NetworkInterface.getByInetAddress(localIp);
+ mLocalIf = (localIf == null) ? null : localIf.getName();
+ if (TextUtils.isEmpty(mLocalIf)) {
+ throw new IOException("Local interface is empty!");
+ }
+ if (DBG) {
+ Log.d(TAG, " Local IP: " + mLocalIp + ", if: " + mLocalIf);
+ }
+ }
+
+ // returns false if vpn connectivity is broken
+ private boolean checkConnectivity() {
if (mDaemonHelper.anyDaemonStopped() || isLocalIpChanged()) {
onDisconnect();
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ private void checkDns() {
+ String dns1 = SystemProperties.get(DNS1);
+ String vpnDns1 = SystemProperties.get(VPN_DNS1);
+ if (!dns1.equals(vpnDns1) && dns1.equals(mOriginalDns1)) {
+ // dhcp expires?
+ setVpnDns();
}
}
private boolean isLocalIpChanged() {
- // TODO
- if (!isDnsIntact()) {
- Log.w(TAG, " local IP changed");
- return true;
- } else {
- return false;
- }
- }
-
- private boolean isDnsIntact() {
- String dns1 = SystemProperties.get(DNS1);
- if (!mVpnDns1.equals(dns1)) {
- Log.w(TAG, " dns being overridden by: " + dns1);
- return false;
- } else {
+ try {
+ InetAddress localIp = InetAddress.getByName(mLocalIp);
+ NetworkInterface localIf =
+ NetworkInterface.getByInetAddress(localIp);
+ if (localIf == null || !mLocalIf.equals(localIf.getName())) {
+ Log.w(TAG, " local If changed from " + mLocalIf
+ + " to " + localIf);
+ return true;
+ } else {
+ return false;
+ }
+ } catch (IOException e) {
+ Log.w(TAG, "isLocalIpChanged()", e);
return true;
}
}
@@ -349,7 +414,7 @@
}
}
- private class DaemonHelper {
+ private class DaemonHelper implements Serializable {
private List<DaemonProxy> mDaemonList =
new ArrayList<DaemonProxy>();
@@ -376,7 +441,7 @@
synchronized boolean anyDaemonStopped() {
for (DaemonProxy s : mDaemonList) {
if (s.isStopped()) {
- Log.w(TAG, " daemon gone: " + s.getName());
+ Log.w(TAG, " VPN daemon gone: " + s.getName());
return true;
}
}
@@ -401,6 +466,14 @@
onError(VpnManager.VPN_ERROR_AUTH);
return true;
+ case CHALLENGE_ERROR_CODE:
+ onError(VpnManager.VPN_ERROR_CHALLENGE);
+ return true;
+
+ case REMOTE_HUNG_UP_ERROR_CODE:
+ onError(VpnManager.VPN_ERROR_REMOTE_HUNG_UP);
+ return true;
+
default:
onError(VpnManager.VPN_ERROR_CONNECTION_FAILED);
return true;
diff --git a/packages/VpnServices/src/com/android/server/vpn/VpnServiceBinder.java b/packages/VpnServices/src/com/android/server/vpn/VpnServiceBinder.java
index 513a2c9..4892a7b 100644
--- a/packages/VpnServices/src/com/android/server/vpn/VpnServiceBinder.java
+++ b/packages/VpnServices/src/com/android/server/vpn/VpnServiceBinder.java
@@ -27,23 +27,31 @@
import android.net.vpn.VpnProfile;
import android.net.vpn.VpnState;
import android.os.IBinder;
+import android.util.Log;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
/**
* The service class for managing a VPN connection. It implements the
* {@link IVpnService} binder interface.
*/
public class VpnServiceBinder extends Service {
- private final String TAG = VpnServiceBinder.class.getSimpleName();
+ private static final String TAG = VpnServiceBinder.class.getSimpleName();
+ private static final boolean DBG = true;
+
+ private static final String STATES_FILE_PATH = "/data/misc/vpn/.states";
// The actual implementation is delegated to the VpnService class.
private VpnService<? extends VpnProfile> mService;
private final IBinder mBinder = new IVpnService.Stub() {
public boolean connect(VpnProfile p, String username, String password) {
- android.util.Log.d("VpnServiceBinder", "becoming foreground");
- setForeground(true);
return VpnServiceBinder.this.connect(p, username, password);
}
@@ -57,6 +65,13 @@
};
@Override
+ public void onCreate() {
+ super.onCreate();
+ checkSavedStates();
+ }
+
+
+ @Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
}
@@ -66,14 +81,30 @@
return mBinder;
}
+ void saveStates() throws IOException {
+ if (DBG) Log.d("VpnServiceBinder", " saving states");
+ ObjectOutputStream oos =
+ new ObjectOutputStream(new FileOutputStream(STATES_FILE_PATH));
+ oos.writeObject(mService);
+ oos.close();
+ }
+
+ void removeStates() {
+ try {
+ new File(STATES_FILE_PATH).delete();
+ } catch (Throwable e) {
+ if (DBG) Log.d("VpnServiceBinder", " remove states: " + e);
+ }
+ }
+
private synchronized boolean connect(final VpnProfile p,
final String username, final String password) {
if (mService != null) return false;
+ final VpnService s = mService = createService(p);
new Thread(new Runnable() {
public void run() {
- mService = createService(p);
- mService.onConnect(username, password);
+ s.onConnect(username, password);
}
}).start();
return true;
@@ -81,12 +112,11 @@
private synchronized void disconnect() {
if (mService == null) return;
+ final VpnService s = mService;
new Thread(new Runnable() {
public void run() {
- mService.onDisconnect();
- android.util.Log.d("VpnServiceBinder", "becoming background");
- setForeground(false);
+ s.onDisconnect();
}
}).start();
}
@@ -100,6 +130,21 @@
}
}
+ private void checkSavedStates() {
+ try {
+ ObjectInputStream ois = new ObjectInputStream(new FileInputStream(
+ STATES_FILE_PATH));
+ mService = (VpnService<? extends VpnProfile>) ois.readObject();
+ mService.recover(this);
+ ois.close();
+ } catch (FileNotFoundException e) {
+ // do nothing
+ } catch (Throwable e) {
+ Log.i("VpnServiceBinder", "recovery error, remove states: " + e);
+ removeStates();
+ }
+ }
+
private VpnService<? extends VpnProfile> createService(VpnProfile p) {
switch (p.getType()) {
case L2TP:
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index 134fb6f..9e8816b 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -494,7 +494,7 @@
mDrmAppInstallObserver = new AppDirObserver(
mDrmAppPrivateInstallDir.getPath(), OBSERVER_EVENTS, false);
mDrmAppInstallObserver.startWatching();
- scanDirLI(mDrmAppPrivateInstallDir, 0, scanMode);
+ scanDirLI(mDrmAppPrivateInstallDir, 0, scanMode | SCAN_FORWARD_LOCKED);
EventLog.writeEvent(LOG_BOOT_PROGRESS_PMS_SCAN_END,
SystemClock.uptimeMillis());
@@ -1766,7 +1766,12 @@
int i;
for (i=0; i<files.length; i++) {
File file = new File(dir, files[i]);
- PackageParser.Package pkg = scanPackageLI(file, file, file,
+ File resFile = file;
+ // Pick up the resource path from settings for fwd locked apps
+ if ((scanMode & SCAN_FORWARD_LOCKED) != 0) {
+ resFile = null;
+ }
+ PackageParser.Package pkg = scanPackageLI(file, file, resFile,
flags|PackageParser.PARSE_MUST_BE_APK, scanMode);
}
}
@@ -1868,8 +1873,12 @@
if (ps != null && !ps.codePath.equals(ps.resourcePath)) {
scanMode |= SCAN_FORWARD_LOCKED;
}
+ File resFile = destResourceFile;
+ if ((scanMode & SCAN_FORWARD_LOCKED) != 0) {
+ resFile = getFwdLockedResource(ps.name);
+ }
// Note that we invoke the following method only if we are about to unpack an application
- return scanPackageLI(scanFile, destCodeFile, destResourceFile,
+ return scanPackageLI(scanFile, destCodeFile, resFile,
pkg, parseFlags, scanMode | SCAN_UPDATE_SIGNATURE);
}
@@ -3811,6 +3820,11 @@
}
}
+ private File getFwdLockedResource(String pkgName) {
+ final String publicZipFileName = pkgName + ".zip";
+ return new File(mAppInstallDir, publicZipFileName);
+ }
+
private PackageInstalledInfo installPackageLI(Uri pPackageURI,
int pFlags, boolean newInstall, String installerPackageName) {
File tmpPackageFile = null;
@@ -3890,8 +3904,7 @@
final String destFilePath = destPackageFile.getAbsolutePath();
File destResourceFile;
if ((pFlags&PackageManager.INSTALL_FORWARD_LOCK) != 0) {
- final String publicZipFileName = pkgName + ".zip";
- destResourceFile = new File(mAppInstallDir, publicZipFileName);
+ destResourceFile = getFwdLockedResource(pkgName);
forwardLocked = true;
} else {
destResourceFile = destPackageFile;
diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java
index 890f930..82539fb 100644
--- a/telephony/java/android/telephony/SmsManager.java
+++ b/telephony/java/android/telephony/SmsManager.java
@@ -40,7 +40,6 @@
/**
* Manages SMS operations such as sending data, text, and pdu SMS messages.
* Get this object by calling the static method SmsManager.getDefault().
- * @hide
*/
public final class SmsManager {
private static SmsManager sInstance;
@@ -202,6 +201,8 @@
/**
* Send a raw SMS PDU.
+ * A PDU is a protocol data unit. It contains the message and the
+ * associated meta information.
*
* @param smsc the SMSC to send the message through, or NULL for the
* default SMSC
@@ -219,8 +220,6 @@
* @param deliveryIntent if not NULL this <code>PendingIntent</code> is
* broadcast when the message is delivered to the recipient. The
* raw pdu of the status report is in the extended data ("pdu").
- *
- * @hide
*/
private void sendRawPdu(byte[] smsc, byte[] pdu, PendingIntent sentIntent,
PendingIntent deliveryIntent) {
@@ -252,6 +251,8 @@
/**
* Copy a raw SMS PDU to the ICC.
+ * ICC (Integrated Circuit Card) is the card of the device.
+ * For example, this can be the SIM or USIM for GSM.
*
* @param smsc the SMSC for this message, or NULL for the default SMSC
* @param pdu the raw PDU to store
@@ -278,6 +279,8 @@
/**
* Delete the specified message from the ICC.
+ * ICC (Integrated Circuit Card) is the card of the device.
+ * For example, this can be the SIM or USIM for GSM.
*
* @param messageIndex is the record index of the message on ICC
* @return true for success
@@ -304,6 +307,8 @@
/**
* Update the specified message on the ICC.
+ * ICC (Integrated Circuit Card) is the card of the device.
+ * For example, this can be the SIM or USIM for GSM.
*
* @param messageIndex record index of message to update
* @param newStatus new message status (STATUS_ON_ICC_READ,
@@ -331,6 +336,8 @@
/**
* Retrieves all messages currently stored on ICC.
+ * ICC (Integrated Circuit Card) is the card of the device.
+ * For example, this can be the SIM or USIM for GSM.
*
* @return <code>ArrayList</code> of <code>SmsMessage</code> objects
*
@@ -359,12 +366,12 @@
* <code>getAllMessagesFromIcc</code>
* @return <code>ArrayList</code> of <code>SmsMessage</code> objects.
*/
- private ArrayList<SmsMessage> createMessageListFromRawRecords(List records) {
+ private ArrayList<SmsMessage> createMessageListFromRawRecords(List<SmsRawData> records) {
ArrayList<SmsMessage> messages = new ArrayList<SmsMessage>();
if (records != null) {
int count = records.size();
for (int i = 0; i < count; i++) {
- SmsRawData data = (SmsRawData)records.get(i);
+ SmsRawData data = records.get(i);
// List contains all records, including "free" records (null)
if (data != null) {
SmsMessage sms = SmsMessage.createFromEfRecord(i+1, data.getBytes());
diff --git a/telephony/java/android/telephony/SmsMessage.java b/telephony/java/android/telephony/SmsMessage.java
index fc491d7..0617dad 100644
--- a/telephony/java/android/telephony/SmsMessage.java
+++ b/telephony/java/android/telephony/SmsMessage.java
@@ -28,13 +28,13 @@
import java.lang.Math;
import java.util.ArrayList;
+import java.util.Arrays;
import static android.telephony.TelephonyManager.PHONE_TYPE_CDMA;
/**
* A Short Message Service message.
- * @hide
*/
public class SmsMessage {
private static final boolean LOCAL_DEBUG = true;
@@ -49,18 +49,6 @@
UNKNOWN, CLASS_0, CLASS_1, CLASS_2, CLASS_3;
}
- /**
- * TODO(cleanup): given that we now have more than one possible
- * 7bit encoding, this result starts to look rather vague and
- * maybe confusing... If this is just an indication of code unit
- * size, maybe that is no problem. Otherwise, should we try to
- * create an aggregate collection of GSM and CDMA encodings? CDMA
- * contains a superset of the encodings we use (it does not
- * support 8-bit GSM, but we also do not use that encoding
- * currently)... We could get rid of these and directly reference
- * the CDMA encoding definitions...
- */
-
/** User data text encoding code unit size */
public static final int ENCODING_UNKNOWN = 0;
public static final int ENCODING_7BIT = 1;
@@ -71,24 +59,9 @@
public static final int MAX_USER_DATA_BYTES = 140;
/**
- * TODO(cleanup): It would be more flexible and less fragile to
- * rewrite this (meaning get rid of the following constant) such
- * that an actual UDH is taken into consideration (meaning its
- * length is measured), allowing for messages that actually
- * contain other UDH fields... Hence it is actually a shame to
- * extend the API with this constant. If necessary, maybe define
- * the size of such a header and let the math for calculating
- * max_octets/septets be done elsewhere. And, while I am griping,
- * if we use the word septet, we should use the word octet in
- * corresponding places, not byte...
- */
-
- /**
* The maximum number of payload bytes per message if a user data header
* is present. This assumes the header only contains the
* CONCATENATED_8_BIT_REFERENCE element.
- *
- * @hide pending API Council approval to extend the public API
*/
public static final int MAX_USER_DATA_BYTES_WITH_HEADER = 134;
@@ -103,17 +76,26 @@
public static final int MAX_USER_DATA_SEPTETS_WITH_HEADER = 153;
/** Contains actual SmsMessage. Only public for debugging and for framework layer.
- * {@hide}
- */
+ *
+ * @hide
+ */
public SmsMessageBase mWrappedSmsMessage;
- public static class SubmitPdu extends SubmitPduBase {
+ public static class SubmitPdu {
- //Constructor
- public SubmitPdu() {
+ public byte[] encodedScAddress; // Null if not applicable.
+ public byte[] encodedMessage;
+
+ public String toString() {
+ return "SubmitPdu: encodedScAddress = "
+ + Arrays.toString(encodedScAddress)
+ + ", encodedMessage = "
+ + Arrays.toString(encodedMessage);
}
- /* {@hide} */
+ /**
+ * @hide
+ */
protected SubmitPdu(SubmitPduBase spb) {
this.encodedMessage = spb.encodedMessage;
this.encodedScAddress = spb.encodedScAddress;
@@ -121,7 +103,11 @@
}
- // Constructor
+ /**
+ * Constructor
+ *
+ * @hide
+ */
public SmsMessage() {
this(getSmsFacility());
}
@@ -295,6 +281,8 @@
* @param text text, must not be null.
* @return an <code>ArrayList</code> of strings that, in order,
* comprise the original msg text
+ *
+ * @hide
*/
public static ArrayList<String> fragmentText(String text) {
int activePhone = TelephonyManager.getDefault().getPhoneType();
@@ -343,10 +331,11 @@
* current encoding.
*
* @param messageBody the message to encode
- * @param use7bitOnly if true, characters that are not part of the GSM
- * alphabet are counted as a single space char. If false, a
- * messageBody containing non-GSM alphabet characters is calculated
- * for 16-bit encoding.
+ * @param use7bitOnly if true, characters that are not part of the radio
+ * specific (GSM / CDMA) alphabet encoding are converted to as a
+ * single space characters. If false, a messageBody containing
+ * non-GSM or non-CDMA alphabet characters are encoded using
+ * 16-bit encoding.
* @return an int[4] with int[0] being the number of SMS's required, int[1]
* the number of code units used, and int[2] is the number of code
* units remaining until the next message. int[3] is the encoding
@@ -688,6 +677,8 @@
/** This method returns the reference to a specific
* SmsMessage object, which is used for accessing its static methods.
* @return Specific SmsMessage.
+ *
+ * @hide
*/
private static final SmsMessageBase getSmsFacility(){
int activePhone = TelephonyManager.getDefault().getPhoneType();
diff --git a/telephony/java/android/telephony/gsm/SmsManager.java b/telephony/java/android/telephony/gsm/SmsManager.java
index cdd707e..241c485 100644
--- a/telephony/java/android/telephony/gsm/SmsManager.java
+++ b/telephony/java/android/telephony/gsm/SmsManager.java
@@ -43,6 +43,7 @@
return sInstance;
}
+ @Deprecated
private SmsManager() {
mSmsMgrProxy = android.telephony.SmsManager.getDefault();
}
diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java
index 1f4ce3d..0763e63 100644
--- a/telephony/java/com/android/internal/telephony/RILConstants.java
+++ b/telephony/java/com/android/internal/telephony/RILConstants.java
@@ -86,14 +86,6 @@
>>java/android/com.android.internal.telephony/gsm/RILConstants.java
*/
-
- int RIL_SIM_ABSENT = 0;
- int RIL_SIM_NOT_READY = 1;
- int RIL_SIM_READY = 2;
- int RIL_SIM_PIN = 3;
- int RIL_SIM_PUK = 4;
- int RIL_SIM_NETWORK_PERSONALIZATION = 5;
-
/**
* No restriction at all including voice/SMS/USSD/SS/AV64
* and packet data.
diff --git a/telephony/java/com/android/internal/telephony/SmsMessageBase.java b/telephony/java/com/android/internal/telephony/SmsMessageBase.java
index 9c78b98..7a15c32 100644
--- a/telephony/java/com/android/internal/telephony/SmsMessageBase.java
+++ b/telephony/java/com/android/internal/telephony/SmsMessageBase.java
@@ -118,6 +118,7 @@
public int codeUnitSize;
}
+ // TODO(): This class is duplicated in SmsMessage.java. Refactor accordingly.
public static abstract class SubmitPduBase {
public byte[] encodedScAddress; // Null if not applicable.
public byte[] encodedMessage;
diff --git a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
index 28ce6a5..0d46777 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
@@ -1338,25 +1338,26 @@
return isOtaSpNum;
}
- /**
- * isOTASPNumber: checks a given number against the IS-683A OTASP dial string and carrier
- * OTASP dial string.
- *
- * @param dialStr the number to look up.
- * @return true if the number is in IS-683A OTASP dial string or carrier OTASP dial string
- */
+ /**
+ * isOTASPNumber: checks a given number against the IS-683A OTASP dial string and carrier
+ * OTASP dial string.
+ *
+ * @param dialStr the number to look up.
+ * @return true if the number is in IS-683A OTASP dial string or carrier OTASP dial string
+ */
@Override
- public boolean isOtaSpNumber(String dialStr){
- boolean isOtaSpNum = false;
- if (dialStr != null) {
- isOtaSpNum = isIs683OtaSpDialStr(dialStr);
- if(isOtaSpNum == false){
- isOtaSpNum = isCarrierOtaSpNum(dialStr);
- }
- }
- if (DBG) Log.d(LOG_TAG, "isOtaSpNumber " + isOtaSpNum);
- return isOtaSpNum;
- }
+ public boolean isOtaSpNumber(String dialStr){
+ boolean isOtaSpNum = false;
+ String dialableStr = PhoneNumberUtils.extractNetworkPortion(dialStr);
+ if (dialableStr != null) {
+ isOtaSpNum = isIs683OtaSpDialStr(dialableStr);
+ if (isOtaSpNum == false) {
+ isOtaSpNum = isCarrierOtaSpNum(dialableStr);
+ }
+ }
+ if (DBG) Log.d(LOG_TAG, "isOtaSpNumber " + isOtaSpNum);
+ return isOtaSpNum;
+ }
@Override
public int getCdmaEriIconIndex() {
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
index 0cae604..53f0274 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
@@ -121,8 +121,8 @@
private int curSpnRule = 0;
private String mMdn;
- private int mHomeSystemId;
- private int mHomeNetworkId;
+ private int mHomeSystemId[] = null;
+ private int mHomeNetworkId[] = null;
private String mMin;
private String mPrlVersion;
@@ -398,23 +398,31 @@
String cdmaSubscription[] = (String[])ar.result;
if (cdmaSubscription != null && cdmaSubscription.length >= 5) {
mMdn = cdmaSubscription[0];
- // TODO: Only grabbing the first SID/NID for now.
if (cdmaSubscription[1] != null) {
String[] sid = cdmaSubscription[1].split(",");
- try {
- mHomeSystemId = sid.length > 0 ? Integer.parseInt(sid[0]) : 0;
- } catch (NumberFormatException e) {
- mHomeSystemId = 0;
+ mHomeSystemId = new int[sid.length];
+ for (int i = 0; i < sid.length; i++) {
+ try {
+ mHomeSystemId[i] = Integer.parseInt(sid[i]);
+ } catch (NumberFormatException ex) {
+ Log.e(LOG_TAG, "error parsing system id: ", ex);
+ }
}
}
+ Log.d(LOG_TAG,"GET_CDMA_SUBSCRIPTION SID=" + cdmaSubscription[1] );
+
if (cdmaSubscription[2] != null) {
String[] nid = cdmaSubscription[2].split(",");
- try {
- mHomeNetworkId = nid.length > 0 ? Integer.parseInt(nid[0]) : 0;
- } catch (NumberFormatException e) {
- mHomeNetworkId = 0;
+ mHomeNetworkId = new int[nid.length];
+ for (int i = 0; i < nid.length; i++) {
+ try {
+ mHomeNetworkId[i] = Integer.parseInt(nid[i]);
+ } catch (NumberFormatException ex) {
+ Log.e(LOG_TAG, "error parsing network id: ", ex);
+ }
}
}
+ Log.d(LOG_TAG,"GET_CDMA_SUBSCRIPTION NID=" + cdmaSubscription[2] );
mMin = cdmaSubscription[3];
mPrlVersion = cdmaSubscription[4];
Log.d(LOG_TAG,"GET_CDMA_SUBSCRIPTION MDN=" + mMdn);
@@ -712,7 +720,7 @@
if (pollingContext[0] == 0) {
boolean namMatch = false;
- if ((mHomeSystemId != 0) && (mHomeSystemId == newSS.getSystemId()) ) {
+ if (!isSidsAllZeros() && isHomeSid(newSS.getSystemId())) {
namMatch = true;
}
@@ -724,33 +732,43 @@
}
// Setting SS CdmaRoamingIndicator and CdmaDefaultRoamingIndicator
- // TODO(Teleca): Validate this is correct.
- if (mIsInPrl) {
- if (namMatch && (mRoamingIndicator <= 2)) {
- // System is acquired, prl match, nam match and mRoamingIndicator <= 2
- newSS.setCdmaRoamingIndicator(EriInfo.ROAMING_INDICATOR_OFF);
- } else {
- // System is acquired, prl match, no nam match or mRoamingIndicator > 2
- newSS.setCdmaRoamingIndicator(mRoamingIndicator);
- }
- } else {
- if (mRegistrationState == 5) {
- // System is acquired but prl not loaded or no prl match
+ newSS.setCdmaDefaultRoamingIndicator(mDefaultRoamingIndicator);
+ newSS.setCdmaRoamingIndicator(mRoamingIndicator);
+ boolean isPrlLoaded = true;
+ if (TextUtils.isEmpty(mPrlVersion)) {
+ isPrlLoaded = false;
+ }
+ if (!isPrlLoaded) {
+ newSS.setCdmaRoamingIndicator(EriInfo.ROAMING_INDICATOR_FLASH);
+ } else if (!isSidsAllZeros()) {
+ if (!namMatch && !mIsInPrl) {
+ // Use default
+ newSS.setCdmaRoamingIndicator(mDefaultRoamingIndicator);
+ } else if (namMatch && !mIsInPrl) {
newSS.setCdmaRoamingIndicator(EriInfo.ROAMING_INDICATOR_FLASH);
+ } else if (!namMatch && mIsInPrl) {
+ // Use the one from PRL/ERI
+ newSS.setCdmaRoamingIndicator(mRoamingIndicator);
} else {
- // Use the default indicator
+ // It means namMatch && mIsInPrl
+ if ((mRoamingIndicator <= 2)) {
+ newSS.setCdmaRoamingIndicator(EriInfo.ROAMING_INDICATOR_OFF);
+ } else {
+ // Use the one from PRL/ERI
+ newSS.setCdmaRoamingIndicator(mRoamingIndicator);
+ }
}
}
- newSS.setCdmaDefaultRoamingIndicator(mDefaultRoamingIndicator);
// NOTE: Some operator may require to override the mCdmaRoaming (set by the modem)
// depending on the mRoamingIndicator.
if (DBG) {
log("Set CDMA Roaming Indicator to: " + newSS.getCdmaRoamingIndicator()
- + ". mCdmaRoaming = " + mCdmaRoaming + ", namMatch = " + namMatch
- + ", mIsInPrl = " + mIsInPrl + ", mRoamingIndicator = " + mRoamingIndicator
+ + ". mCdmaRoaming = " + mCdmaRoaming + ", isPrlLoaded = " + isPrlLoaded
+ + ". namMatch = " + namMatch + " , mIsInPrl = " + mIsInPrl
+ + ", mRoamingIndicator = " + mRoamingIndicator
+ ", mDefaultRoamingIndicator= " + mDefaultRoamingIndicator);
}
pollStateDone();
@@ -1458,6 +1476,31 @@
}
}
+ private boolean isSidsAllZeros() {
+ if (mHomeSystemId != null) {
+ for (int i=0; i < mHomeSystemId.length; i++) {
+ if (mHomeSystemId[i] != 0) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Check whether a specified system ID that matches one of the home system IDs.
+ */
+ private boolean isHomeSid(int sid) {
+ if (mHomeSystemId != null) {
+ for (int i=0; i < mHomeSystemId.length; i++) {
+ if (sid == mHomeSystemId[i]) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
/**
* @return true if phone is camping on a technology
* that could support voice and data simultaneously.
diff --git a/tests/DpiTest/res/drawable-hdpi/reslogo240dpi.png b/tests/DpiTest/res/drawable-hdpi/reslogo240dpi.png
new file mode 100644
index 0000000..4d717a8
--- /dev/null
+++ b/tests/DpiTest/res/drawable-hdpi/reslogo240dpi.png
Binary files differ
diff --git a/tests/DpiTest/res/drawable-hdpi/stylogo240dpi.png b/tests/DpiTest/res/drawable-hdpi/stylogo240dpi.png
new file mode 100644
index 0000000..4d717a8
--- /dev/null
+++ b/tests/DpiTest/res/drawable-hdpi/stylogo240dpi.png
Binary files differ
diff --git a/tests/DpiTest/res/drawable-ldpi/reslogo120dpi.png b/tests/DpiTest/res/drawable-ldpi/reslogo120dpi.png
new file mode 100644
index 0000000..46bbd5b
--- /dev/null
+++ b/tests/DpiTest/res/drawable-ldpi/reslogo120dpi.png
Binary files differ
diff --git a/tests/DpiTest/res/drawable-ldpi/stylogo120dpi.png b/tests/DpiTest/res/drawable-ldpi/stylogo120dpi.png
new file mode 100644
index 0000000..46bbd5b
--- /dev/null
+++ b/tests/DpiTest/res/drawable-ldpi/stylogo120dpi.png
Binary files differ
diff --git a/tests/DpiTest/res/drawable/reslogo160dpi.png b/tests/DpiTest/res/drawable/reslogo160dpi.png
new file mode 100644
index 0000000..c23b2ce
--- /dev/null
+++ b/tests/DpiTest/res/drawable/reslogo160dpi.png
Binary files differ
diff --git a/tests/DpiTest/res/drawable/stylogo160dpi.png b/tests/DpiTest/res/drawable/stylogo160dpi.png
new file mode 100644
index 0000000..c23b2ce
--- /dev/null
+++ b/tests/DpiTest/res/drawable/stylogo160dpi.png
Binary files differ
diff --git a/tests/DpiTest/res/layout/image_views.xml b/tests/DpiTest/res/layout/image_views.xml
new file mode 100644
index 0000000..6a91497
--- /dev/null
+++ b/tests/DpiTest/res/layout/image_views.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content">
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/reslogo120dpi" />
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/reslogo160dpi" />
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/reslogo240dpi" />
+
+</LinearLayout>
diff --git a/tests/DpiTest/res/layout/styled_image_views.xml b/tests/DpiTest/res/layout/styled_image_views.xml
new file mode 100644
index 0000000..86c63bf
--- /dev/null
+++ b/tests/DpiTest/res/layout/styled_image_views.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content">
+
+ <ImageView style="@style/ImageView120dpi" />
+ <ImageView style="@style/ImageView160dpi" />
+ <ImageView style="@style/ImageView240dpi" />
+
+</LinearLayout>
diff --git a/tests/DpiTest/res/values/styles.xml b/tests/DpiTest/res/values/styles.xml
new file mode 100644
index 0000000..bb4b13c
--- /dev/null
+++ b/tests/DpiTest/res/values/styles.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<resources>
+ <style name="ImageView120dpi">
+ <item name="android:src">@drawable/stylogo120dpi</item>
+ <item name="android:layout_width">wrap_content</item>
+ <item name="android:layout_height">wrap_content</item>
+ </style>
+
+ <style name="ImageView160dpi">
+ <item name="android:src">@drawable/stylogo160dpi</item>
+ <item name="android:layout_width">wrap_content</item>
+ <item name="android:layout_height">wrap_content</item>
+ </style>
+
+ <style name="ImageView240dpi">
+ <item name="android:src">@drawable/stylogo240dpi</item>
+ <item name="android:layout_width">wrap_content</item>
+ <item name="android:layout_height">wrap_content</item>
+ </style>
+</resources>
diff --git a/tests/DpiTest/src/com/google/android/test/dpi/DpiTestActivity.java b/tests/DpiTest/src/com/google/android/test/dpi/DpiTestActivity.java
index 68220a1..ae53b76 100644
--- a/tests/DpiTest/src/com/google/android/test/dpi/DpiTestActivity.java
+++ b/tests/DpiTest/src/com/google/android/test/dpi/DpiTestActivity.java
@@ -28,6 +28,7 @@
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.ScrollView;
+import android.view.LayoutInflater;
import android.view.View;
import android.content.Context;
import android.content.pm.ApplicationInfo;
@@ -71,6 +72,9 @@
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ final LayoutInflater li = (LayoutInflater)getSystemService(
+ LAYOUT_INFLATER_SERVICE);
+
this.setTitle(R.string.act_title);
LinearLayout root = new LinearLayout(this);
root.setOrientation(LinearLayout.VERTICAL);
@@ -96,6 +100,14 @@
addLabelToRoot(root, "Prescaled resource drawable");
addChildToRoot(root, layout);
+ layout = (LinearLayout)li.inflate(R.layout.image_views, null);
+ addLabelToRoot(root, "Inflated layout");
+ addChildToRoot(root, layout);
+
+ layout = (LinearLayout)li.inflate(R.layout.styled_image_views, null);
+ addLabelToRoot(root, "Inflated styled layout");
+ addChildToRoot(root, layout);
+
layout = new LinearLayout(this);
addCanvasBitmap(layout, R.drawable.logo120dpi, true);
addCanvasBitmap(layout, R.drawable.logo160dpi, true);
diff --git a/vpn/java/android/net/vpn/PptpProfile.java b/vpn/java/android/net/vpn/PptpProfile.java
index c68bb71..b4b7be5 100644
--- a/vpn/java/android/net/vpn/PptpProfile.java
+++ b/vpn/java/android/net/vpn/PptpProfile.java
@@ -16,15 +16,41 @@
package android.net.vpn;
+import android.os.Parcel;
+
/**
* The profile for PPTP type of VPN.
* {@hide}
*/
public class PptpProfile extends VpnProfile {
private static final long serialVersionUID = 1L;
+ private boolean mEncryption = true;
@Override
public VpnType getType() {
return VpnType.PPTP;
}
+
+ /**
+ * Enables/disables the encryption for PPTP tunnel.
+ */
+ public void setEncryptionEnabled(boolean enabled) {
+ mEncryption = enabled;
+ }
+
+ public boolean isEncryptionEnabled() {
+ return mEncryption;
+ }
+
+ @Override
+ protected void readFromParcel(Parcel in) {
+ super.readFromParcel(in);
+ mEncryption = in.readInt() > 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel parcel, int flags) {
+ super.writeToParcel(parcel, flags);
+ parcel.writeInt(mEncryption ? 1 : 0);
+ }
}
diff --git a/vpn/java/android/net/vpn/VpnManager.java b/vpn/java/android/net/vpn/VpnManager.java
index 0bf2346..e448e5a 100644
--- a/vpn/java/android/net/vpn/VpnManager.java
+++ b/vpn/java/android/net/vpn/VpnManager.java
@@ -50,6 +50,10 @@
public static final int VPN_ERROR_CONNECTION_FAILED = 2;
/** Error code to indicate the server is not known. */
public static final int VPN_ERROR_UNKNOWN_SERVER = 3;
+ /** Error code to indicate an error from challenge response. */
+ public static final int VPN_ERROR_CHALLENGE = 4;
+ /** Error code to indicate an error of remote server hanging up. */
+ public static final int VPN_ERROR_REMOTE_HUNG_UP = 5;
private static final int VPN_ERROR_NO_ERROR = 0;
public static final String PROFILES_PATH = "/data/misc/vpn/profiles";