Merge change Ia75da053 into eclair
* changes:
Remove DEBUG-only logging in metadata backup agent
diff --git a/api/current.xml b/api/current.xml
index 74f04ab..7dd8b73 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -59234,46 +59234,6 @@
<parameter name="end" type="int">
</parameter>
</method>
-<method name="native_breakText"
- return="int"
- abstract="false"
- native="true"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="text" type="char[]">
-</parameter>
-<parameter name="index" type="int">
-</parameter>
-<parameter name="count" type="int">
-</parameter>
-<parameter name="maxWidth" type="float">
-</parameter>
-<parameter name="measuredWidth" type="float[]">
-</parameter>
-</method>
-<method name="native_breakText"
- return="int"
- abstract="false"
- native="true"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="text" type="java.lang.String">
-</parameter>
-<parameter name="measureForwards" type="boolean">
-</parameter>
-<parameter name="maxWidth" type="float">
-</parameter>
-<parameter name="measuredWidth" type="float[]">
-</parameter>
-</method>
<method name="reset"
return="void"
abstract="false"
diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java
index 2d2e75f..3b39ae43 100644
--- a/core/java/android/accounts/AccountManagerService.java
+++ b/core/java/android/accounts/AccountManagerService.java
@@ -102,6 +102,7 @@
private static final String ACCOUNTS_ID = "_id";
private static final String ACCOUNTS_NAME = "name";
private static final String ACCOUNTS_TYPE = "type";
+ private static final String ACCOUNTS_TYPE_COUNT = "count(type)";
private static final String ACCOUNTS_PASSWORD = "password";
private static final String TABLE_AUTHTOKENS = "authtokens";
@@ -127,6 +128,8 @@
private static final String[] ACCOUNT_NAME_TYPE_PROJECTION =
new String[]{ACCOUNTS_ID, ACCOUNTS_NAME, ACCOUNTS_TYPE};
+ private static final String[] ACCOUNT_TYPE_COUNT_PROJECTION =
+ new String[] { ACCOUNTS_TYPE, ACCOUNTS_TYPE_COUNT};
private static final Intent ACCOUNTS_CHANGED_INTENT;
private static final String COUNT_OF_MATCHING_GRANTS = ""
@@ -1455,18 +1458,54 @@
return asBinder();
}
- protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) {
- synchronized (mSessions) {
- final long now = SystemClock.elapsedRealtime();
- fout.println("AccountManagerService: " + mSessions.size() + " sessions");
- for (Session session : mSessions.values()) {
- fout.println(" " + session.toDebugString(now));
+ /**
+ * Searches array of arguments for the specified string
+ * @param args array of argument strings
+ * @param value value to search for
+ * @return true if the value is contained in the array
+ */
+ private static boolean scanArgs(String[] args, String value) {
+ if (args != null) {
+ for (String arg : args) {
+ if (value.equals(arg)) {
+ return true;
+ }
}
}
+ return false;
+ }
- fout.println();
+ protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) {
+ final boolean isCheckinRequest = scanArgs(args, "--checkin") || scanArgs(args, "-c");
- mAuthenticatorCache.dump(fd, fout, args);
+ if (isCheckinRequest) {
+ // This is a checkin request. *Only* upload the account types and the count of each.
+ SQLiteDatabase db = mOpenHelper.getReadableDatabase();
+
+ Cursor cursor = db.query(TABLE_ACCOUNTS, ACCOUNT_TYPE_COUNT_PROJECTION,
+ null, null, ACCOUNTS_TYPE, null, null);
+ try {
+ while (cursor.moveToNext()) {
+ // print type,count
+ fout.println(cursor.getString(0) + "," + cursor.getString(1));
+ }
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
+ }
+ } else {
+ synchronized (mSessions) {
+ final long now = SystemClock.elapsedRealtime();
+ fout.println("AccountManagerService: " + mSessions.size() + " sessions");
+ for (Session session : mSessions.values()) {
+ fout.println(" " + session.toDebugString(now));
+ }
+ }
+
+ fout.println();
+ mAuthenticatorCache.dump(fd, fout, args);
+ }
}
private void doNotification(Account account, CharSequence message, Intent intent) {
diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java
index e425f3a..f621483 100644
--- a/core/java/android/database/sqlite/SQLiteDatabase.java
+++ b/core/java/android/database/sqlite/SQLiteDatabase.java
@@ -54,7 +54,8 @@
*/
public class SQLiteDatabase extends SQLiteClosable {
private static final String TAG = "Database";
- private static final int DB_OPERATION_EVENT = 52000;
+ private static final int EVENT_DB_OPERATION = 52000;
+ private static final int EVENT_DB_CORRUPT = 75004;
/**
* Algorithms used in ON CONFLICT clause
@@ -739,6 +740,7 @@
// Try to recover from this, if we can.
// TODO: should we do this for other open failures?
Log.e(TAG, "Deleting and re-creating corrupt database " + path, e);
+ EventLog.writeEvent(EVENT_DB_CORRUPT, path);
new File(path).delete();
return new SQLiteDatabase(path, factory, flags);
}
@@ -1732,7 +1734,7 @@
}
/* package */ void logTimeStat(boolean read, long begin, long end) {
- EventLog.writeEvent(DB_OPERATION_EVENT, mPath, read ? 0 : 1, end - begin);
+ EventLog.writeEvent(EVENT_DB_OPERATION, mPath, read ? 0 : 1, end - begin);
}
/**
diff --git a/core/java/android/pim/vcard/ContactStruct.java b/core/java/android/pim/vcard/ContactStruct.java
index 35224c7..915f09e 100644
--- a/core/java/android/pim/vcard/ContactStruct.java
+++ b/core/java/android/pim/vcard/ContactStruct.java
@@ -1051,8 +1051,8 @@
List<String> nameList;
switch (VCardConfig.getNameOrderType(mVCardType)) {
case VCardConfig.NAME_ORDER_JAPANESE:
- if (VCardUtils.containsOnlyAscii(mFamilyName) &&
- VCardUtils.containsOnlyAscii(mGivenName)) {
+ if (VCardUtils.containsOnlyPrintableAscii(mFamilyName) &&
+ VCardUtils.containsOnlyPrintableAscii(mGivenName)) {
nameList = Arrays.asList(mPrefix, mGivenName, mMiddleName, mFamilyName, mSuffix);
} else {
nameList = Arrays.asList(mPrefix, mFamilyName, mMiddleName, mGivenName, mSuffix);
diff --git a/core/java/android/pim/vcard/VCardComposer.java b/core/java/android/pim/vcard/VCardComposer.java
index 40b4fc4..b0376c4 100644
--- a/core/java/android/pim/vcard/VCardComposer.java
+++ b/core/java/android/pim/vcard/VCardComposer.java
@@ -56,8 +56,10 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
/**
* <p>
@@ -234,9 +236,8 @@
private static final String VCARD_PROPERTY_X_PHONETIC_LAST_NAME = "X-PHONETIC-LAST-NAME";
// Android specific properties
- private static final String VCARD_PROPERTY_X_PHONETIC_NAME = "X-PHONETIC-NAME";
+ // TODO: ues extra MIME-TYPE instead of adding this kind of inflexible fields
private static final String VCARD_PROPERTY_X_NICKNAME = "X-NICKNAME";
- // TODO: add properties like X-LATITUDE
// Property for call log entry
private static final String VCARD_PROPERTY_X_TIMESTAMP = "X-IRMC-CALL-DATETIME";
@@ -396,7 +397,7 @@
}
boolean needCharset = false;
- if (!(VCardUtils.containsOnlyAscii(phoneName))) {
+ if (!(VCardUtils.containsOnlyPrintableAscii(phoneName))) {
needCharset = true;
}
appendVCardLine(builder, VCARD_PROPERTY_FULL_NAME, phoneName, needCharset, false);
@@ -596,7 +597,7 @@
if (TextUtils.isEmpty(name)) {
name = mCursor.getString(NUMBER_COLUMN_INDEX);
}
- final boolean needCharset = !(VCardUtils.containsOnlyAscii(name));
+ final boolean needCharset = !(VCardUtils.containsOnlyPrintableAscii(name));
appendVCardLine(builder, VCARD_PROPERTY_FULL_NAME, name, needCharset, false);
appendVCardLine(builder, VCARD_PROPERTY_NAME, name, needCharset, false);
@@ -740,213 +741,220 @@
final Map<String, List<ContentValues>> contentValuesListMap) {
final List<ContentValues> contentValuesList = contentValuesListMap
.get(StructuredName.CONTENT_ITEM_TYPE);
- if (contentValuesList != null) {
+ if (contentValuesList != null && contentValuesList.size() > 0) {
appendStructuredNamesInternal(builder, contentValuesList);
} else if (mIsDoCoMo) {
appendVCardLine(builder, VCARD_PROPERTY_NAME, "");
+ } else if (mIsV30) {
+ // vCard 3.0 requires "N" and "FN" properties.
+ appendVCardLine(builder, VCARD_PROPERTY_NAME, "");
+ appendVCardLine(builder, VCARD_PROPERTY_FULL_NAME, "");
}
}
private void appendStructuredNamesInternal(final StringBuilder builder,
final List<ContentValues> contentValuesList) {
+ // For safety, we'll emit just one value around StructuredName, as external importers
+ // may get confused with multiple "N", "FN", etc. properties, though it is valid in
+ // vCard spec.
+ ContentValues primaryContentValues = null;
for (ContentValues contentValues : contentValuesList) {
- final String familyName = contentValues
- .getAsString(StructuredName.FAMILY_NAME);
- final String middleName = contentValues
- .getAsString(StructuredName.MIDDLE_NAME);
- final String givenName = contentValues
- .getAsString(StructuredName.GIVEN_NAME);
- final String prefix = contentValues
- .getAsString(StructuredName.PREFIX);
- final String suffix = contentValues
- .getAsString(StructuredName.SUFFIX);
- final String displayName = contentValues
- .getAsString(StructuredName.DISPLAY_NAME);
+ Integer isSuperPrimary = contentValues.getAsInteger(StructuredName.IS_SUPER_PRIMARY);
+ if (isSuperPrimary != null && isSuperPrimary != 0) {
+ // We choose "super primary" ContentValues.
+ primaryContentValues = contentValues;
+ break;
+ } else if (primaryContentValues == null && contentValues != null) {
+ // We choose the first ContentValues if "super primary" ContentValues does not exist.
+ primaryContentValues = contentValues;
+ }
+ }
- // For now, some primary element is not encoded into Quoted-Printable, which is not
- // valid in vCard spec strictly. In the future, we may have to have some flag to
- // enable composer to encode these primary field into Quoted-Printable.
- if (!TextUtils.isEmpty(familyName) || !TextUtils.isEmpty(givenName)) {
- final String encodedFamily = escapeCharacters(familyName);
- final String encodedGiven = escapeCharacters(givenName);
- final String encodedMiddle = escapeCharacters(middleName);
- final String encodedPrefix = escapeCharacters(prefix);
- final String encodedSuffix = escapeCharacters(suffix);
+ if (primaryContentValues == null) {
+ Log.e(LOG_TAG, "All ContentValues given from database is empty.");
+ primaryContentValues = new ContentValues();
+ }
- // N property. This order is specified by vCard spec and does not depend on countries.
- builder.append(VCARD_PROPERTY_NAME);
- if (!(VCardUtils.containsOnlyAscii(familyName) &&
- VCardUtils.containsOnlyAscii(givenName) &&
- VCardUtils.containsOnlyAscii(middleName) &&
- VCardUtils.containsOnlyAscii(prefix) &&
- VCardUtils.containsOnlyAscii(suffix))) {
- builder.append(VCARD_ATTR_SEPARATOR);
- builder.append(mVCardAttributeCharset);
- }
+ final String familyName = primaryContentValues
+ .getAsString(StructuredName.FAMILY_NAME);
+ final String middleName = primaryContentValues
+ .getAsString(StructuredName.MIDDLE_NAME);
+ final String givenName = primaryContentValues
+ .getAsString(StructuredName.GIVEN_NAME);
+ final String prefix = primaryContentValues
+ .getAsString(StructuredName.PREFIX);
+ final String suffix = primaryContentValues
+ .getAsString(StructuredName.SUFFIX);
+ final String displayName = primaryContentValues
+ .getAsString(StructuredName.DISPLAY_NAME);
- builder.append(VCARD_DATA_SEPARATOR);
- builder.append(encodedFamily);
- builder.append(VCARD_ITEM_SEPARATOR);
- builder.append(encodedGiven);
- builder.append(VCARD_ITEM_SEPARATOR);
- builder.append(encodedMiddle);
- builder.append(VCARD_ITEM_SEPARATOR);
- builder.append(encodedPrefix);
- builder.append(VCARD_ITEM_SEPARATOR);
- builder.append(encodedSuffix);
- builder.append(VCARD_COL_SEPARATOR);
+ // For now, some primary element is not encoded into Quoted-Printable, which is not
+ // valid in vCard spec strictly. In the future, we may have to have some flag to
+ // enable composer to encode these primary field into Quoted-Printable.
+ if (!TextUtils.isEmpty(familyName) || !TextUtils.isEmpty(givenName)) {
+ final String encodedFamily = escapeCharacters(familyName);
+ final String encodedGiven = escapeCharacters(givenName);
+ final String encodedMiddle = escapeCharacters(middleName);
+ final String encodedPrefix = escapeCharacters(prefix);
+ final String encodedSuffix = escapeCharacters(suffix);
- final String encodedFullname = VCardUtils.constructNameFromElements(
- VCardConfig.getNameOrderType(mVCardType),
- encodedFamily, encodedMiddle, encodedGiven, encodedPrefix, encodedSuffix);
-
- // FN property
- builder.append(VCARD_PROPERTY_FULL_NAME);
- if (!VCardUtils.containsOnlyAscii(encodedFullname)) {
- builder.append(VCARD_ATTR_SEPARATOR);
- builder.append(mVCardAttributeCharset);
- }
- builder.append(VCARD_DATA_SEPARATOR);
- builder.append(encodedFullname);
- builder.append(VCARD_COL_SEPARATOR);
- } else if (!TextUtils.isEmpty(displayName)) {
- builder.append(VCARD_PROPERTY_NAME);
+ // N property. This order is specified by vCard spec and does not depend on countries.
+ builder.append(VCARD_PROPERTY_NAME);
+ if (!(VCardUtils.containsOnlyPrintableAscii(familyName) &&
+ VCardUtils.containsOnlyPrintableAscii(givenName) &&
+ VCardUtils.containsOnlyPrintableAscii(middleName) &&
+ VCardUtils.containsOnlyPrintableAscii(prefix) &&
+ VCardUtils.containsOnlyPrintableAscii(suffix))) {
builder.append(VCARD_ATTR_SEPARATOR);
builder.append(mVCardAttributeCharset);
- builder.append(VCARD_DATA_SEPARATOR);
- builder.append(escapeCharacters(displayName));
- builder.append(VCARD_ITEM_SEPARATOR);
- builder.append(VCARD_ITEM_SEPARATOR);
- builder.append(VCARD_ITEM_SEPARATOR);
- builder.append(VCARD_ITEM_SEPARATOR);
- builder.append(VCARD_COL_SEPARATOR);
- } else if (mIsDoCoMo) {
- appendVCardLine(builder, VCARD_PROPERTY_NAME, "");
}
- String phoneticFamilyName = contentValues
- .getAsString(StructuredName.PHONETIC_FAMILY_NAME);
- String phoneticMiddleName = contentValues
- .getAsString(StructuredName.PHONETIC_MIDDLE_NAME);
- String phoneticGivenName = contentValues
- .getAsString(StructuredName.PHONETIC_GIVEN_NAME);
- if (!(TextUtils.isEmpty(phoneticFamilyName)
- && TextUtils.isEmpty(phoneticMiddleName) && TextUtils
- .isEmpty(phoneticGivenName))) { // if not empty
- if (mIsJapaneseMobilePhone) {
- phoneticFamilyName = VCardUtils
- .toHalfWidthString(phoneticFamilyName);
- phoneticMiddleName = VCardUtils
- .toHalfWidthString(phoneticMiddleName);
- phoneticGivenName = VCardUtils
- .toHalfWidthString(phoneticGivenName);
- }
+ builder.append(VCARD_DATA_SEPARATOR);
+ builder.append(encodedFamily);
+ builder.append(VCARD_ITEM_SEPARATOR);
+ builder.append(encodedGiven);
+ builder.append(VCARD_ITEM_SEPARATOR);
+ builder.append(encodedMiddle);
+ builder.append(VCARD_ITEM_SEPARATOR);
+ builder.append(encodedPrefix);
+ builder.append(VCARD_ITEM_SEPARATOR);
+ builder.append(encodedSuffix);
+ builder.append(VCARD_COL_SEPARATOR);
- if (mIsV30) {
- final String sortString = VCardUtils
- .constructNameFromElements(mVCardType,
- phoneticFamilyName, phoneticMiddleName,
- phoneticGivenName);
- builder.append(VCARD_PROPERTY_SORT_STRING);
+ final String encodedFullname = VCardUtils.constructNameFromElements(
+ VCardConfig.getNameOrderType(mVCardType),
+ encodedFamily, encodedMiddle, encodedGiven, encodedPrefix, encodedSuffix);
- if (!VCardUtils.containsOnlyAscii(sortString)) {
- // Strictly, adding charset information is NOT valid in
- // VCard 3.0,
- // but we'll add this info since parser side may be able to
- // use the charset via
- // this attribute field.
- //
- // e.g. Japanese mobile phones use Shift_Jis while RFC 2426
- // recommends
- // UTF-8. By adding this field, parsers may be able to know
- // this text
- // is NOT UTF-8 but Shift_Jis.
- builder.append(VCARD_ATTR_SEPARATOR);
- builder.append(mVCardAttributeCharset);
- }
+ // FN property
+ builder.append(VCARD_PROPERTY_FULL_NAME);
+ if (!VCardUtils.containsOnlyPrintableAscii(encodedFullname)) {
+ builder.append(VCARD_ATTR_SEPARATOR);
+ builder.append(mVCardAttributeCharset);
+ }
+ builder.append(VCARD_DATA_SEPARATOR);
+ builder.append(encodedFullname);
+ builder.append(VCARD_COL_SEPARATOR);
+ } else if (!TextUtils.isEmpty(displayName)) {
+ builder.append(VCARD_PROPERTY_NAME);
+ builder.append(VCARD_ATTR_SEPARATOR);
+ builder.append(mVCardAttributeCharset);
+ builder.append(VCARD_DATA_SEPARATOR);
+ builder.append(escapeCharacters(displayName));
+ builder.append(VCARD_ITEM_SEPARATOR);
+ builder.append(VCARD_ITEM_SEPARATOR);
+ builder.append(VCARD_ITEM_SEPARATOR);
+ builder.append(VCARD_ITEM_SEPARATOR);
+ builder.append(VCARD_COL_SEPARATOR);
+ } else if (mIsDoCoMo) {
+ appendVCardLine(builder, VCARD_PROPERTY_NAME, "");
+ } else if (mIsV30) {
+ appendVCardLine(builder, VCARD_PROPERTY_NAME, "");
+ appendVCardLine(builder, VCARD_PROPERTY_FULL_NAME, "");
+ }
- builder.append(VCARD_DATA_SEPARATOR);
- builder.append(sortString);
- builder.append(VCARD_COL_SEPARATOR);
- } else {
- // Note: There is no appropriate property for expressing
- // phonetic name in
- // VCard 2.1, while there is in VCard 3.0 (SORT-STRING).
- // We chose to use DoCoMo's way since it is supported by a
- // lot of
- // Japanese mobile phones.
+ String phoneticFamilyName = primaryContentValues
+ .getAsString(StructuredName.PHONETIC_FAMILY_NAME);
+ String phoneticMiddleName = primaryContentValues
+ .getAsString(StructuredName.PHONETIC_MIDDLE_NAME);
+ String phoneticGivenName = primaryContentValues
+ .getAsString(StructuredName.PHONETIC_GIVEN_NAME);
+ if (!(TextUtils.isEmpty(phoneticFamilyName)
+ && TextUtils.isEmpty(phoneticMiddleName) &&
+ TextUtils.isEmpty(phoneticGivenName))) { // if not empty
+ if (mIsJapaneseMobilePhone) {
+ phoneticFamilyName = VCardUtils
+ .toHalfWidthString(phoneticFamilyName);
+ phoneticMiddleName = VCardUtils
+ .toHalfWidthString(phoneticMiddleName);
+ phoneticGivenName = VCardUtils
+ .toHalfWidthString(phoneticGivenName);
+ }
+
+ if (mIsV30) {
+ final String sortString = VCardUtils
+ .constructNameFromElements(mVCardType,
+ phoneticFamilyName, phoneticMiddleName,
+ phoneticGivenName);
+ builder.append(VCARD_PROPERTY_SORT_STRING);
+
+ if (!VCardUtils.containsOnlyPrintableAscii(sortString)) {
+ // Strictly, adding charset information is NOT valid in
+ // VCard 3.0,
+ // but we'll add this info since parser side may be able to
+ // use the charset via
+ // this attribute field.
//
- // TODO: should use Quoted-Pritable?
- builder.append(VCARD_PROPERTY_SOUND);
+ // e.g. Japanese mobile phones use Shift_Jis while RFC 2426
+ // recommends
+ // UTF-8. By adding this field, parsers may be able to know
+ // this text
+ // is NOT UTF-8 but Shift_Jis.
builder.append(VCARD_ATTR_SEPARATOR);
- builder.append(Constants.ATTR_TYPE_X_IRMC_N);
- builder.append(VCARD_ATTR_SEPARATOR);
-
- if (!(VCardUtils.containsOnlyAscii(phoneticFamilyName) &&
- VCardUtils.containsOnlyAscii(phoneticMiddleName) &&
- VCardUtils.containsOnlyAscii(phoneticGivenName))) {
- builder.append(mVCardAttributeCharset);
- builder.append(VCARD_DATA_SEPARATOR);
- }
-
- builder.append(escapeCharacters(phoneticFamilyName));
- builder.append(VCARD_ITEM_SEPARATOR);
- builder.append(escapeCharacters(phoneticMiddleName));
- builder.append(VCARD_ITEM_SEPARATOR);
- builder.append(escapeCharacters(phoneticGivenName));
- builder.append(VCARD_ITEM_SEPARATOR);
- builder.append(VCARD_ITEM_SEPARATOR);
- builder.append(VCARD_COL_SEPARATOR);
-
- if (mUsesAndroidProperty) {
- final String phoneticName = VCardUtils
- .constructNameFromElements(mVCardType,
- phoneticFamilyName, phoneticMiddleName,
- phoneticGivenName);
- builder.append(VCARD_PROPERTY_X_PHONETIC_NAME);
-
- if (!VCardUtils.containsOnlyAscii(phoneticName)) {
- builder.append(VCARD_ATTR_SEPARATOR);
- builder.append(mVCardAttributeCharset);
- }
-
- builder.append(VCARD_DATA_SEPARATOR);
- // TODO: may need to make the text quoted-printable.
- builder.append(phoneticName);
- builder.append(VCARD_COL_SEPARATOR);
- }
+ builder.append(mVCardAttributeCharset);
}
- } else if (mIsDoCoMo) {
+
+ builder.append(VCARD_DATA_SEPARATOR);
+ builder.append(sortString);
+ builder.append(VCARD_COL_SEPARATOR);
+ } else {
+ // Note: There is no appropriate property for expressing
+ // phonetic name in
+ // VCard 2.1, while there is in VCard 3.0 (SORT-STRING).
+ // We chose to use DoCoMo's way since it is supported by a
+ // lot of Japanese mobile phones.
+ //
+ // TODO: should use Quoted-Pritable?
builder.append(VCARD_PROPERTY_SOUND);
builder.append(VCARD_ATTR_SEPARATOR);
builder.append(Constants.ATTR_TYPE_X_IRMC_N);
- builder.append(VCARD_DATA_SEPARATOR);
+ builder.append(VCARD_ATTR_SEPARATOR);
+
+ if (!(VCardUtils.containsOnlyPrintableAscii(phoneticFamilyName) &&
+ VCardUtils.containsOnlyPrintableAscii(phoneticMiddleName) &&
+ VCardUtils.containsOnlyPrintableAscii(phoneticGivenName))) {
+ builder.append(mVCardAttributeCharset);
+ builder.append(VCARD_DATA_SEPARATOR);
+ }
+
+ builder.append(escapeCharacters(phoneticFamilyName));
builder.append(VCARD_ITEM_SEPARATOR);
+ builder.append(escapeCharacters(phoneticMiddleName));
builder.append(VCARD_ITEM_SEPARATOR);
+ builder.append(escapeCharacters(phoneticGivenName));
builder.append(VCARD_ITEM_SEPARATOR);
builder.append(VCARD_ITEM_SEPARATOR);
builder.append(VCARD_COL_SEPARATOR);
}
+ } else if (mIsDoCoMo) {
+ builder.append(VCARD_PROPERTY_SOUND);
+ builder.append(VCARD_ATTR_SEPARATOR);
+ builder.append(Constants.ATTR_TYPE_X_IRMC_N);
+ builder.append(VCARD_DATA_SEPARATOR);
+ builder.append(VCARD_ITEM_SEPARATOR);
+ builder.append(VCARD_ITEM_SEPARATOR);
+ builder.append(VCARD_ITEM_SEPARATOR);
+ builder.append(VCARD_ITEM_SEPARATOR);
+ builder.append(VCARD_COL_SEPARATOR);
+ }
- if (mUsesDefactProperty) {
- if (!TextUtils.isEmpty(phoneticGivenName)) {
- builder.append(VCARD_PROPERTY_X_PHONETIC_FIRST_NAME);
- builder.append(VCARD_DATA_SEPARATOR);
- builder.append(phoneticGivenName);
- builder.append(VCARD_COL_SEPARATOR);
- }
- if (!TextUtils.isEmpty(phoneticMiddleName)) {
- builder.append(VCARD_PROPERTY_X_PHONETIC_MIDDLE_NAME);
- builder.append(VCARD_DATA_SEPARATOR);
- builder.append(phoneticMiddleName);
- builder.append(VCARD_COL_SEPARATOR);
- }
- if (!TextUtils.isEmpty(phoneticFamilyName)) {
- builder.append(VCARD_PROPERTY_X_PHONETIC_LAST_NAME);
- builder.append(VCARD_DATA_SEPARATOR);
- builder.append(phoneticFamilyName);
- builder.append(VCARD_COL_SEPARATOR);
- }
+ if (mUsesDefactProperty) {
+ if (!TextUtils.isEmpty(phoneticGivenName)) {
+ builder.append(VCARD_PROPERTY_X_PHONETIC_FIRST_NAME);
+ builder.append(VCARD_DATA_SEPARATOR);
+ builder.append(phoneticGivenName);
+ builder.append(VCARD_COL_SEPARATOR);
+ }
+ if (!TextUtils.isEmpty(phoneticMiddleName)) {
+ builder.append(VCARD_PROPERTY_X_PHONETIC_MIDDLE_NAME);
+ builder.append(VCARD_DATA_SEPARATOR);
+ builder.append(phoneticMiddleName);
+ builder.append(VCARD_COL_SEPARATOR);
+ }
+ if (!TextUtils.isEmpty(phoneticFamilyName)) {
+ builder.append(VCARD_PROPERTY_X_PHONETIC_LAST_NAME);
+ builder.append(VCARD_DATA_SEPARATOR);
+ builder.append(phoneticFamilyName);
+ builder.append(VCARD_COL_SEPARATOR);
}
}
}
@@ -974,7 +982,7 @@
}
builder.append(propertyNickname);
- if (!VCardUtils.containsOnlyAscii(propertyNickname)) {
+ if (!VCardUtils.containsOnlyPrintableAscii(propertyNickname)) {
// Strictly, this is not valid in vCard 3.0. See above.
builder.append(VCARD_ATTR_SEPARATOR);
builder.append(mVCardAttributeCharset);
@@ -991,16 +999,31 @@
final Map<String, List<ContentValues>> contentValuesListMap) {
final List<ContentValues> contentValuesList = contentValuesListMap
.get(Phone.CONTENT_ITEM_TYPE);
+ boolean phoneLineExists = false;
if (contentValuesList != null) {
+ Set<String> phoneSet = new HashSet<String>();
for (ContentValues contentValues : contentValuesList) {
- Integer phoneType = contentValues.getAsInteger(Phone.TYPE);
- int phoneTypeAsPrimitive =
- (phoneType == null ? Phone.TYPE_HOME : phoneType);
- appendVCardTelephoneLine(builder, phoneTypeAsPrimitive,
- contentValues.getAsString(Phone.LABEL),
- contentValues.getAsString(Phone.NUMBER));
+ final Integer typeAsObject = contentValues.getAsInteger(Phone.TYPE);
+ final String label = contentValues.getAsString(Phone.LABEL);
+ String phoneNumber = contentValues.getAsString(Phone.NUMBER);
+ if (phoneNumber != null) {
+ phoneNumber = phoneNumber.trim();
+ }
+ if (TextUtils.isEmpty(phoneNumber)) {
+ continue;
+ }
+ phoneLineExists = true;
+ int type = (typeAsObject != null ? typeAsObject : Phone.TYPE_HOME);
+ // TODO: Premature, since this allows two phone numbers which are
+ // same from the view of phone number format (e.g. "100" v.s. "1-0-0")
+ if (!phoneSet.contains(phoneNumber)) {
+ phoneSet.add(phoneNumber);
+ appendVCardTelephoneLine(builder, type, label, phoneNumber);
+ }
}
- } else if (mIsDoCoMo) {
+ }
+
+ if (!phoneLineExists && mIsDoCoMo) {
appendVCardTelephoneLine(builder, Phone.TYPE_HOME, "", "");
}
}
@@ -1009,14 +1032,31 @@
final Map<String, List<ContentValues>> contentValuesListMap) {
final List<ContentValues> contentValuesList = contentValuesListMap
.get(Email.CONTENT_ITEM_TYPE);
+ boolean emailAddressExists = false;
if (contentValuesList != null) {
+ Set<String> addressSet = new HashSet<String>();
for (ContentValues contentValues : contentValuesList) {
- appendVCardEmailLine(builder, contentValues
- .getAsInteger(Email.TYPE), contentValues
- .getAsString(Email.LABEL), contentValues
- .getAsString(Email.DATA));
+ Integer typeAsObject = contentValues.getAsInteger(Email.TYPE);
+ final int type = (typeAsObject != null ?
+ typeAsObject : Email.TYPE_OTHER);
+ final String label = contentValues.getAsString(Email.LABEL);
+ String emailAddress = contentValues.getAsString(Email.DATA);
+ if (emailAddress != null) {
+ emailAddress = emailAddress.trim();
+ }
+ if (TextUtils.isEmpty(emailAddress)) {
+ continue;
+ }
+ emailAddressExists = true;
+ // Do not allow completely same email address line emitted into each file.
+ if (!addressSet.contains(emailAddress)) {
+ addressSet.add(emailAddress);
+ appendVCardEmailLine(builder, type, label, emailAddress);
+ }
}
- } else if (mIsDoCoMo) {
+ }
+
+ if (!emailAddressExists && mIsDoCoMo) {
appendVCardEmailLine(builder, Email.TYPE_HOME, "", "");
}
}
@@ -1087,7 +1127,9 @@
for (ContentValues contentValues : contentValuesList) {
final Integer type = contentValues.getAsInteger(StructuredPostal.TYPE);
final String label = contentValues.getAsString(StructuredPostal.LABEL);
- appendVCardPostalLine(builder, type, label, contentValues);
+ if (type != null) {
+ appendVCardPostalLine(builder, type, label, contentValues);
+ }
}
}
@@ -1099,6 +1141,12 @@
for (ContentValues contentValues : contentValuesList) {
Integer protocol = contentValues.getAsInteger(Im.PROTOCOL);
String data = contentValues.getAsString(Im.DATA);
+ if (data != null) {
+ data = data.trim();
+ }
+ if (TextUtils.isEmpty(data)) {
+ continue;
+ }
if (protocol != null && protocol == Im.PROTOCOL_GOOGLE_TALK) {
if (VCardConfig.usesAndroidSpecificProperty(mVCardType)) {
@@ -1116,8 +1164,13 @@
.get(Website.CONTENT_ITEM_TYPE);
if (contentValuesList != null) {
for (ContentValues contentValues : contentValuesList) {
- final String website = contentValues.getAsString(Website.URL);
- appendVCardLine(builder, VCARD_PROPERTY_URL, website);
+ String website = contentValues.getAsString(Website.URL);
+ if (website != null) {
+ website = website.trim();
+ }
+ if (!TextUtils.isEmpty(website)) {
+ appendVCardLine(builder, VCARD_PROPERTY_URL, website);
+ }
}
}
}
@@ -1130,8 +1183,13 @@
// Theoretically, there must be only one birthday for each vCard data and
// we are afraid of some parse error occuring in some devices, so
// we emit only one birthday entry for now.
- final String birthday = contentValuesList.get(0).getAsString(Birthday.BIRTHDAY);
- appendVCardLine(builder, VCARD_PROPERTY_BIRTHDAY, birthday);
+ String birthday = contentValuesList.get(0).getAsString(Birthday.BIRTHDAY);
+ if (birthday != null) {
+ birthday = birthday.trim();
+ }
+ if (!TextUtils.isEmpty(birthday)) {
+ appendVCardLine(builder, VCARD_PROPERTY_BIRTHDAY, birthday);
+ }
}
}
@@ -1141,14 +1199,29 @@
.get(Organization.CONTENT_ITEM_TYPE);
if (contentValuesList != null) {
for (ContentValues contentValues : contentValuesList) {
- final String company = contentValues
+ String company = contentValues
.getAsString(Organization.COMPANY);
- final String title = contentValues
+ if (company != null) {
+ company = company.trim();
+ }
+ String title = contentValues
.getAsString(Organization.TITLE);
- appendVCardLine(builder, VCARD_PROPERTY_ORG, company, true,
- mUsesQuotedPrintable);
- appendVCardLine(builder, VCARD_PROPERTY_TITLE, title, true,
- mUsesQuotedPrintable);
+ if (title != null) {
+ title = title.trim();
+ }
+
+ if (!TextUtils.isEmpty(company)) {
+ appendVCardLine(builder, VCARD_PROPERTY_ORG, company,
+ !VCardUtils.containsOnlyPrintableAscii(company),
+ (mUsesQuotedPrintable &&
+ !VCardUtils.containsOnlyNonCrLfPrintableAscii(company)));
+ }
+ if (!TextUtils.isEmpty(title)) {
+ appendVCardLine(builder, VCARD_PROPERTY_TITLE, title,
+ !VCardUtils.containsOnlyPrintableAscii(title),
+ (mUsesQuotedPrintable &&
+ !VCardUtils.containsOnlyNonCrLfPrintableAscii(title)));
+ }
}
}
}
@@ -1201,7 +1274,10 @@
StringBuilder noteBuilder = new StringBuilder();
boolean first = true;
for (ContentValues contentValues : contentValuesList) {
- final String note = contentValues.getAsString(Note.NOTE);
+ String note = contentValues.getAsString(Note.NOTE);
+ if (note == null) {
+ note = "";
+ }
if (note.length() > 0) {
if (first) {
first = false;
@@ -1211,14 +1287,27 @@
noteBuilder.append(note);
}
}
- appendVCardLine(builder, VCARD_PROPERTY_NOTE, noteBuilder.toString(),
- true, mUsesQuotedPrintable);
+ final String noteStr = noteBuilder.toString();
+ // This means we scan noteStr completely twice, which is redundant.
+ // But for now, we assume this is not so time-consuming..
+ final boolean shouldAppendCharsetInfo =
+ !VCardUtils.containsOnlyPrintableAscii(noteStr);
+ final boolean reallyUseQuotedPrintable =
+ (mUsesQuotedPrintable &&
+ !VCardUtils.containsOnlyNonCrLfPrintableAscii(noteStr));
+ appendVCardLine(builder, VCARD_PROPERTY_NOTE, noteStr,
+ shouldAppendCharsetInfo, reallyUseQuotedPrintable);
} else {
for (ContentValues contentValues : contentValuesList) {
- final String note = contentValues.getAsString(Note.NOTE);
- if (!TextUtils.isEmpty(note)) {
- appendVCardLine(builder, VCARD_PROPERTY_NOTE, note, true,
- mUsesQuotedPrintable);
+ final String noteStr = contentValues.getAsString(Note.NOTE);
+ if (!TextUtils.isEmpty(noteStr)) {
+ final boolean shouldAppendCharsetInfo =
+ !VCardUtils.containsOnlyPrintableAscii(noteStr);
+ final boolean reallyUseQuotedPrintable =
+ (mUsesQuotedPrintable &&
+ !VCardUtils.containsOnlyNonCrLfPrintableAscii(noteStr));
+ appendVCardLine(builder, VCARD_PROPERTY_NOTE, noteStr,
+ shouldAppendCharsetInfo, reallyUseQuotedPrintable);
}
}
}
@@ -1339,15 +1428,31 @@
builder.append(VCARD_PROPERTY_ADR);
builder.append(VCARD_ATTR_SEPARATOR);
+ // Note: Not sure why we need to emit "empty" line even when actual data does not exist.
+ // There may be some reason or may not be any. We keep safer side.
+ // TODO: investigate this.
boolean dataExists = false;
String[] dataArray = VCardUtils.getVCardPostalElements(contentValues);
+ boolean actuallyUseQuotedPrintable = false;
+ boolean shouldAppendCharset = false;
+ for (String data : dataArray) {
+ if (!TextUtils.isEmpty(data)) {
+ dataExists = true;
+ if (!shouldAppendCharset && !VCardUtils.containsOnlyPrintableAscii(data)) {
+ shouldAppendCharset = true;
+ }
+ if (mUsesQuotedPrintable && !VCardUtils.containsOnlyNonCrLfPrintableAscii(data)) {
+ actuallyUseQuotedPrintable = true;
+ break;
+ }
+ }
+ }
+
int length = dataArray.length;
- final boolean useQuotedPrintable = mUsesQuotedPrintable;
for (int i = 0; i < length; i++) {
String data = dataArray[i];
if (!TextUtils.isEmpty(data)) {
- dataExists = true;
- if (useQuotedPrintable) {
+ if (actuallyUseQuotedPrintable) {
dataArray[i] = encodeQuotedPrintable(data);
} else {
dataArray[i] = escapeCharacters(data);
@@ -1394,25 +1499,40 @@
}
}
- if (typeAsString != null) {
- appendTypeAttribute(builder, typeAsString);
- }
+ // Attribute(s).
- if (dataExists) {
- // Strictly, vCard 3.0 does not allow exporters to emit charset information,
- // but we will add it since the information should be useful for importers,
- //
- // Assume no parser does not emit error with this attribute in vCard 3.0.
+ {
+ boolean shouldAppendAttrSeparator = false;
if (typeAsString != null) {
- builder.append(VCARD_ATTR_SEPARATOR);
+ appendTypeAttribute(builder, typeAsString);
+ shouldAppendAttrSeparator = true;
}
- builder.append(mVCardAttributeCharset);
- if (useQuotedPrintable) {
- builder.append(VCARD_ATTR_SEPARATOR);
- builder.append(VCARD_ATTR_ENCODING_QP);
+ if (dataExists) {
+ if (shouldAppendCharset) {
+ // Strictly, vCard 3.0 does not allow exporters to emit charset information,
+ // but we will add it since the information should be useful for importers,
+ //
+ // Assume no parser does not emit error with this attribute in vCard 3.0.
+ if (shouldAppendAttrSeparator) {
+ builder.append(VCARD_ATTR_SEPARATOR);
+ }
+ builder.append(mVCardAttributeCharset);
+ shouldAppendAttrSeparator = true;
+ }
+
+ if (actuallyUseQuotedPrintable) {
+ if (shouldAppendAttrSeparator) {
+ builder.append(VCARD_ATTR_SEPARATOR);
+ }
+ builder.append(VCARD_ATTR_ENCODING_QP);
+ shouldAppendAttrSeparator = true;
+ }
}
}
+
+ // Property values.
+
builder.append(VCARD_DATA_SEPARATOR);
if (dataExists) {
// The elements in dataArray are already encoded to quoted printable
diff --git a/core/java/android/pim/vcard/VCardUtils.java b/core/java/android/pim/vcard/VCardUtils.java
index ffceade..4f50103 100644
--- a/core/java/android/pim/vcard/VCardUtils.java
+++ b/core/java/android/pim/vcard/VCardUtils.java
@@ -283,7 +283,7 @@
return builder.toString();
}
- public static boolean containsOnlyAscii(String str) {
+ public static boolean containsOnlyPrintableAscii(String str) {
if (TextUtils.isEmpty(str)) {
return true;
}
@@ -299,13 +299,35 @@
}
return true;
}
-
+
+ /**
+ * This is useful when checking the string should be encoded into quoted-printable
+ * or not, which is required by vCard 2.1.
+ * See the definition of "7bit" in vCard 2.1 spec for more information.
+ */
+ public static boolean containsOnlyNonCrLfPrintableAscii(String str) {
+ if (TextUtils.isEmpty(str)) {
+ return true;
+ }
+
+ final int length = str.length();
+ final int asciiFirst = 0x20;
+ final int asciiLast = 0x126;
+ for (int i = 0; i < length; i = str.offsetByCodePoints(i, 1)) {
+ int c = str.codePointAt(i);
+ if (c < asciiFirst || asciiLast < c || c == '\n' || c == '\r') {
+ return false;
+ }
+ }
+ return true;
+ }
+
/**
* This is useful since vCard 3.0 often requires the ("X-") properties and groups
* should contain only alphabets, digits, and hyphen.
*
* Note: It is already known some devices (wrongly) outputs properties with characters
- * which should not be in the field. One example is "X-GOOGLE TALK". We appreciate
+ * which should not be in the field. One example is "X-GOOGLE TALK". We accept
* such kind of input but must never output it unless the target is very specific
* to the device which is able to parse the malformed input.
*/
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index 1b13f52..70a20d6 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -57,6 +57,14 @@
public static final String CALLER_IS_SYNCADAPTER = "caller_is_syncadapter";
/**
+ * A query parameter key used to specify the package that is requesting a query.
+ * This is used for restricting data based on package name.
+ *
+ * @hide
+ */
+ public static final String REQUESTING_PACKAGE_PARAM_KEY = "requesting_package";
+
+ /**
* @hide should be removed when users are updated to refer to SyncState
* @deprecated use SyncState instead
*/
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 1cd4506..f27902d 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -3191,6 +3191,13 @@
"vending_pd_resend_frequency_ms";
/**
+ * Time before an asset in the 'DOWNLOADING' state is considered ready
+ * for an install kick on the client.
+ */
+ public static final String VENDING_DOWNLOADING_KICK_TIMEOUT_MS =
+ "vending_downloading_kick_ms";
+
+ /**
* Size of buffer in bytes for Vending to use when reading cache files.
*/
public static final String VENDING_DISK_INPUT_BUFFER_BYTES =
diff --git a/core/java/android/text/method/Touch.java b/core/java/android/text/method/Touch.java
index dfc16f5..6995107 100644
--- a/core/java/android/text/method/Touch.java
+++ b/core/java/android/text/method/Touch.java
@@ -72,6 +72,24 @@
}
/**
+ * @hide
+ * Returns the maximum scroll value in x.
+ */
+ public static int getMaxScrollX(TextView widget, Layout layout, int y) {
+ int top = layout.getLineForVertical(y);
+ int bottom = layout.getLineForVertical(y + widget.getHeight()
+ - widget.getTotalPaddingTop() -widget.getTotalPaddingBottom());
+ int left = Integer.MAX_VALUE;
+ int right = 0;
+ for (int i = top; i <= bottom; i++) {
+ left = (int) Math.min(left, layout.getLineLeft(i));
+ right = (int) Math.max(right, layout.getLineRight(i));
+ }
+ return right - left - widget.getWidth() - widget.getTotalPaddingLeft()
+ - widget.getTotalPaddingRight();
+ }
+
+ /**
* Handles touch events for dragging. You may want to do other actions
* like moving the cursor on touch as well.
*/
diff --git a/core/java/android/webkit/WebTextView.java b/core/java/android/webkit/WebTextView.java
index 65ce158..f479124 100644
--- a/core/java/android/webkit/WebTextView.java
+++ b/core/java/android/webkit/WebTextView.java
@@ -276,25 +276,6 @@
}
/**
- * Create a fake touch up event at (x,y) with respect to this WebTextView.
- * This is used by WebView to act as though a touch event which happened
- * before we placed the WebTextView actually hit it, so that it can place
- * the cursor accordingly.
- */
- /* package */ void fakeTouchEvent(float x, float y) {
- // We need to ensure that there is a Layout, since the Layout is used
- // in determining where to place the cursor.
- if (getLayout() == null) {
- measure(mWidthSpec, mHeightSpec);
- }
- // Create a fake touch up, which is used to place the cursor.
- MotionEvent ev = MotionEvent.obtain(0, 0, MotionEvent.ACTION_UP,
- x, y, 0);
- onTouchEvent(ev);
- ev.recycle();
- }
-
- /**
* Determine whether this WebTextView currently represents the node
* represented by ptr.
* @param ptr Pointer to a node to compare to.
@@ -457,7 +438,14 @@
int smallerSlop = slop/2;
if (dx > smallerSlop || dy > smallerSlop) {
if (mWebView != null) {
- mWebView.scrollFocusedTextInput(mScrollX, mScrollY);
+ float maxScrollX = (float) Touch.getMaxScrollX(this,
+ getLayout(), mScrollY);
+ if (DebugFlags.WEB_TEXT_VIEW) {
+ Log.v(LOGTAG, "onTouchEvent x=" + mScrollX + " y="
+ + mScrollY + " maxX=" + maxScrollX);
+ }
+ mWebView.scrollFocusedTextInput(maxScrollX > 0 ?
+ mScrollX / maxScrollX : 0, mScrollY);
}
mScrolled = true;
return true;
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 8858b81..68a9a92 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -1111,6 +1111,12 @@
ArrayList<byte[]> history = new ArrayList<byte[]>(size);
for (int i = 0; i < size; i++) {
WebHistoryItem item = list.getItemAtIndex(i);
+ if (null == item) {
+ // FIXME: this shouldn't happen
+ // need to determine how item got set to null
+ Log.w(LOGTAG, "saveState: Unexpected null history item.");
+ return null;
+ }
byte[] data = item.getFlattenedData();
if (data == null) {
// It would be very odd to not have any data for a given history
@@ -1917,12 +1923,15 @@
int oldY = mScrollY;
mScrollX = pinLocX(mScrollX);
mScrollY = pinLocY(mScrollY);
- // android.util.Log.d("skia", "recordNewContentSize -
- // abortAnimation");
- abortAnimation(); // just in case
if (oldX != mScrollX || oldY != mScrollY) {
sendOurVisibleRect();
}
+ if (!mScroller.isFinished()) {
+ // We are in the middle of a scroll. Repin the final scroll
+ // position.
+ mScroller.setFinalX(pinLocX(mScroller.getFinalX()));
+ mScroller.setFinalY(pinLocY(mScroller.getFinalY()));
+ }
}
}
contentSizeChanged(updateLayout);
@@ -3004,17 +3013,6 @@
if (mWebTextView == null) return;
imm.showSoftInput(mWebTextView, 0);
- // Now we need to fake a touch event to place the cursor where the
- // user touched.
- AbsoluteLayout.LayoutParams lp = (AbsoluteLayout.LayoutParams)
- mWebTextView.getLayoutParams();
- if (lp != null) {
- // Take the last touch and adjust for the location of the
- // WebTextView.
- float x = mLastTouchX + (float) (mScrollX - lp.x);
- float y = mLastTouchY + (float) (mScrollY - lp.y);
- mWebTextView.fakeTouchEvent(x, y);
- }
if (mInZoomOverview) {
// if in zoom overview mode, call doDoubleTap() to bring it back
// to normal mode so that user can enter text.
@@ -4502,18 +4500,19 @@
/**
* Scroll the focused text field/area to match the WebTextView
- * @param x New x position of the WebTextView in view coordinates
+ * @param xPercent New x position of the WebTextView from 0 to 1.
* @param y New y position of the WebTextView in view coordinates
*/
- /*package*/ void scrollFocusedTextInput(int x, int y) {
+ /*package*/ void scrollFocusedTextInput(float xPercent, int y) {
if (!inEditingMode() || mWebViewCore == null) {
return;
}
- mWebViewCore.sendMessage(EventHub.SCROLL_TEXT_INPUT, viewToContentX(x),
+ mWebViewCore.sendMessage(EventHub.SCROLL_TEXT_INPUT,
// Since this position is relative to the top of the text input
// field, we do not need to take the title bar's height into
// consideration.
- viewToContentDimension(y));
+ viewToContentDimension(y),
+ new Float(xPercent));
}
/**
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index 8b6746e..e2aa1d0 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -872,7 +872,8 @@
break;
case SCROLL_TEXT_INPUT:
- nativeScrollFocusedTextInput(msg.arg1, msg.arg2);
+ nativeScrollFocusedTextInput(
+ ((Float) msg.obj).floatValue(), msg.arg1);
break;
case LOAD_URL:
@@ -2076,9 +2077,9 @@
private native void nativeUpdateFrameCacheIfLoading();
/**
- * Scroll the focused textfield to (x, y) in document space
+ * Scroll the focused textfield to (xPercent, y) in document space
*/
- private native void nativeScrollFocusedTextInput(int x, int y);
+ private native void nativeScrollFocusedTextInput(float xPercent, int y);
// these must be in document space (i.e. not scaled/zoomed).
private native void nativeSetScrollOffset(int gen, int dx, int dy);
diff --git a/core/java/android/widget/FasttrackBadgeWidget.java b/core/java/android/widget/FasttrackBadgeWidget.java
index 8c8e054..ba8539f 100644
--- a/core/java/android/widget/FasttrackBadgeWidget.java
+++ b/core/java/android/widget/FasttrackBadgeWidget.java
@@ -33,6 +33,7 @@
import android.util.AttributeSet;
import android.view.View;
import android.view.View.OnClickListener;
+import com.android.internal.R;
/**
* Widget used to show an image with the standard fasttrack badge
@@ -48,6 +49,7 @@
private int mMode;
private QueryHandler mQueryHandler;
private Drawable mBadgeBackground;
+ private Drawable mNoBadgeBackground;
protected String[] mExcludeMimes = null;
@@ -119,7 +121,10 @@
private void onContactUriChanged() {
if (mContactUri == null && mContactEmail == null && mContactPhone == null) {
- setBackgroundDrawable(null);
+ if (mNoBadgeBackground == null) {
+ mNoBadgeBackground = getResources().getDrawable(R.drawable.fasttrack_nobadge);
+ }
+ setBackgroundDrawable(mNoBadgeBackground);
} else {
setBackgroundDrawable(mBadgeBackground);
}
diff --git a/core/java/android/widget/GridView.java b/core/java/android/widget/GridView.java
index 70555dc..ffe9908 100644
--- a/core/java/android/widget/GridView.java
+++ b/core/java/android/widget/GridView.java
@@ -220,6 +220,8 @@
selectedView = temp;
}
+ // mReferenceView will change with each call to makeRow()
+ // do not cache in a local variable outside of this loop
nextTop = mReferenceView.getBottom() + mVerticalSpacing;
pos += mNumColumns;
@@ -233,7 +235,8 @@
final int horizontalSpacing = mHorizontalSpacing;
int last;
- int nextLeft = mListPadding.left + ((mStretchMode == STRETCH_SPACING_UNIFORM) ? horizontalSpacing : 0);
+ int nextLeft = mListPadding.left +
+ ((mStretchMode == STRETCH_SPACING_UNIFORM) ? horizontalSpacing : 0);
if (!mStackFromBottom) {
last = Math.min(startPos + mNumColumns, mItemCount);
@@ -252,16 +255,14 @@
final boolean inClick = touchModeDrawsInPressedState();
final int selectedPosition = mSelectedPosition;
- mReferenceView = null;
-
+ View child = null;
for (int pos = startPos; pos < last; pos++) {
// is this the selected item?
boolean selected = pos == selectedPosition;
// does the list view have focus or contain focus
final int where = flow ? -1 : pos - startPos;
- final View child = makeAndAddView(pos, y, flow, nextLeft, selected, where);
- mReferenceView = child;
+ child = makeAndAddView(pos, y, flow, nextLeft, selected, where);
nextLeft += columnWidth;
if (pos < last - 1) {
@@ -273,6 +274,8 @@
}
}
+ mReferenceView = child;
+
if (selectedView != null) {
mReferenceViewInSelectedRow = mReferenceView;
}
@@ -465,6 +468,11 @@
mFirstPosition = motionRowStart;
final View referenceView = mReferenceView;
+ // We didn't have anything to layout, bail out
+ if (referenceView == null) {
+ return null;
+ }
+
final int verticalSpacing = mVerticalSpacing;
View above;
diff --git a/core/java/com/android/internal/widget/LockPatternView.java b/core/java/com/android/internal/widget/LockPatternView.java
index cfcf111..0d0a3c2 100644
--- a/core/java/com/android/internal/widget/LockPatternView.java
+++ b/core/java/com/android/internal/widget/LockPatternView.java
@@ -213,6 +213,12 @@
void onPatternCleared();
/**
+ * The user extended the pattern currently being drawn by one cell.
+ * @param pattern The pattern with newly added cell.
+ */
+ void onPatternCellAdded(List<Cell> pattern);
+
+ /**
* A pattern was detected from the user.
* @param pattern The pattern.
*/
@@ -447,6 +453,9 @@
private void addCellToPattern(Cell newCell) {
mPatternDrawLookup[newCell.getRow()][newCell.getColumn()] = true;
mPattern.add(newCell);
+ if (mOnPatternListener != null) {
+ mOnPatternListener.onPatternCellAdded(mPattern);
+ }
}
// helper method to find which cell a point maps to
diff --git a/core/res/res/drawable-hdpi/contact_header_bg.9.png b/core/res/res/drawable-hdpi/contact_header_bg.9.png
new file mode 100755
index 0000000..981b2e9
--- /dev/null
+++ b/core/res/res/drawable-hdpi/contact_header_bg.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_contact_picture_2.png b/core/res/res/drawable-hdpi/ic_contact_picture_2.png
new file mode 100755
index 0000000..5e65276
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_contact_picture_2.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_contact_picture_3.png b/core/res/res/drawable-hdpi/ic_contact_picture_3.png
new file mode 100755
index 0000000..a8ec1e1
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_contact_picture_3.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_data_connected_h.png b/core/res/res/drawable-hdpi/stat_sys_data_connected_h.png
new file mode 100755
index 0000000..24e07ab
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_sys_data_connected_h.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_data_in_h.png b/core/res/res/drawable-hdpi/stat_sys_data_in_h.png
new file mode 100755
index 0000000..f2f6daa
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_sys_data_in_h.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_data_inandout_h.png b/core/res/res/drawable-hdpi/stat_sys_data_inandout_h.png
new file mode 100755
index 0000000..5d6ef05
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_sys_data_inandout_h.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_data_out_h.png b/core/res/res/drawable-hdpi/stat_sys_data_out_h.png
new file mode 100755
index 0000000..5e3122d6
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_sys_data_out_h.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/statusbar_background.9.png b/core/res/res/drawable-hdpi/statusbar_background.9.png
new file mode 100644
index 0000000..dcca695
--- /dev/null
+++ b/core/res/res/drawable-hdpi/statusbar_background.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/statusbar_background.png b/core/res/res/drawable-hdpi/statusbar_background.png
deleted file mode 100644
index c2b3a5e..0000000
--- a/core/res/res/drawable-hdpi/statusbar_background.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/sym_def_app_icon.png b/core/res/res/drawable-hdpi/sym_def_app_icon.png
index 4b5384f..4870fbb 100644
--- a/core/res/res/drawable-hdpi/sym_def_app_icon.png
+++ b/core/res/res/drawable-hdpi/sym_def_app_icon.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/title_bar_medium.9.png b/core/res/res/drawable-hdpi/title_bar_medium.9.png
new file mode 100644
index 0000000..311a54a
--- /dev/null
+++ b/core/res/res/drawable-hdpi/title_bar_medium.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/title_bar_medium.png b/core/res/res/drawable-hdpi/title_bar_medium.png
deleted file mode 100644
index c13dd26..0000000
--- a/core/res/res/drawable-hdpi/title_bar_medium.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/title_bar_portrait.9.png b/core/res/res/drawable-hdpi/title_bar_portrait.9.png
index 161432f..70f7cc2 100644
--- a/core/res/res/drawable-hdpi/title_bar_portrait.9.png
+++ b/core/res/res/drawable-hdpi/title_bar_portrait.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/title_bar_shadow.9.png b/core/res/res/drawable-hdpi/title_bar_shadow.9.png
index e67f457..e6dab63 100644
--- a/core/res/res/drawable-hdpi/title_bar_shadow.9.png
+++ b/core/res/res/drawable-hdpi/title_bar_shadow.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/title_bar_tall.9.png b/core/res/res/drawable-hdpi/title_bar_tall.9.png
new file mode 100644
index 0000000..5c1a69f
--- /dev/null
+++ b/core/res/res/drawable-hdpi/title_bar_tall.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/title_bar_tall.png b/core/res/res/drawable-hdpi/title_bar_tall.png
deleted file mode 100644
index f177440..0000000
--- a/core/res/res/drawable-hdpi/title_bar_tall.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-land-hdpi/bottombar_565.png b/core/res/res/drawable-land-hdpi/bottombar_565.png
new file mode 100755
index 0000000..9df56ca
--- /dev/null
+++ b/core/res/res/drawable-land-hdpi/bottombar_565.png
Binary files differ
diff --git a/core/res/res/drawable-land-hdpi/statusbar_background.png b/core/res/res/drawable-land-hdpi/statusbar_background.png
deleted file mode 100644
index 4a955c5..0000000
--- a/core/res/res/drawable-land-hdpi/statusbar_background.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-land-hdpi/title_bar_tall.png b/core/res/res/drawable-land-hdpi/title_bar_tall.png
deleted file mode 100644
index 96b5ffe..0000000
--- a/core/res/res/drawable-land-hdpi/title_bar_tall.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-land/bottombar_565.png b/core/res/res/drawable-land-mdpi/bottombar_565.png
similarity index 100%
rename from core/res/res/drawable-land/bottombar_565.png
rename to core/res/res/drawable-land-mdpi/bottombar_565.png
Binary files differ
diff --git a/core/res/res/drawable-land-mdpi/statusbar_background.png b/core/res/res/drawable-land-mdpi/statusbar_background.png
deleted file mode 100644
index ef61e52..0000000
--- a/core/res/res/drawable-land-mdpi/statusbar_background.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-land-mdpi/title_bar_tall.png b/core/res/res/drawable-land-mdpi/title_bar_tall.png
deleted file mode 100644
index 16290fb..0000000
--- a/core/res/res/drawable-land-mdpi/title_bar_tall.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable/contact_header_bg.9.png b/core/res/res/drawable-mdpi/contact_header_bg.9.png
similarity index 100%
rename from core/res/res/drawable/contact_header_bg.9.png
rename to core/res/res/drawable-mdpi/contact_header_bg.9.png
Binary files differ
diff --git a/core/res/res/drawable/ic_contact_picture_2.png b/core/res/res/drawable-mdpi/ic_contact_picture_2.png
similarity index 100%
rename from core/res/res/drawable/ic_contact_picture_2.png
rename to core/res/res/drawable-mdpi/ic_contact_picture_2.png
Binary files differ
diff --git a/core/res/res/drawable/ic_contact_picture_3.png b/core/res/res/drawable-mdpi/ic_contact_picture_3.png
similarity index 100%
rename from core/res/res/drawable/ic_contact_picture_3.png
rename to core/res/res/drawable-mdpi/ic_contact_picture_3.png
Binary files differ
diff --git a/core/res/res/drawable/stat_sys_data_connected_h.png b/core/res/res/drawable-mdpi/stat_sys_data_connected_h.png
similarity index 100%
rename from core/res/res/drawable/stat_sys_data_connected_h.png
rename to core/res/res/drawable-mdpi/stat_sys_data_connected_h.png
Binary files differ
diff --git a/core/res/res/drawable/stat_sys_data_in_h.png b/core/res/res/drawable-mdpi/stat_sys_data_in_h.png
similarity index 100%
rename from core/res/res/drawable/stat_sys_data_in_h.png
rename to core/res/res/drawable-mdpi/stat_sys_data_in_h.png
Binary files differ
diff --git a/core/res/res/drawable/stat_sys_data_inandout_h.png b/core/res/res/drawable-mdpi/stat_sys_data_inandout_h.png
similarity index 100%
rename from core/res/res/drawable/stat_sys_data_inandout_h.png
rename to core/res/res/drawable-mdpi/stat_sys_data_inandout_h.png
Binary files differ
diff --git a/core/res/res/drawable/stat_sys_data_out_h.png b/core/res/res/drawable-mdpi/stat_sys_data_out_h.png
similarity index 100%
rename from core/res/res/drawable/stat_sys_data_out_h.png
rename to core/res/res/drawable-mdpi/stat_sys_data_out_h.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/statusbar_background.9.png b/core/res/res/drawable-mdpi/statusbar_background.9.png
new file mode 100644
index 0000000..eb7c1a4
--- /dev/null
+++ b/core/res/res/drawable-mdpi/statusbar_background.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/statusbar_background.png b/core/res/res/drawable-mdpi/statusbar_background.png
deleted file mode 100644
index 204d76a..0000000
--- a/core/res/res/drawable-mdpi/statusbar_background.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/title_bar_medium.9.png b/core/res/res/drawable-mdpi/title_bar_medium.9.png
new file mode 100644
index 0000000..2d41d02
--- /dev/null
+++ b/core/res/res/drawable-mdpi/title_bar_medium.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/title_bar_medium.png b/core/res/res/drawable-mdpi/title_bar_medium.png
deleted file mode 100644
index 9d01f79..0000000
--- a/core/res/res/drawable-mdpi/title_bar_medium.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/title_bar_portrait.9.png b/core/res/res/drawable-mdpi/title_bar_portrait.9.png
index 482d82e..13b18d8 100644
--- a/core/res/res/drawable-mdpi/title_bar_portrait.9.png
+++ b/core/res/res/drawable-mdpi/title_bar_portrait.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/title_bar_shadow.9.png b/core/res/res/drawable-mdpi/title_bar_shadow.9.png
index 08723665..dbcefee 100644
--- a/core/res/res/drawable-mdpi/title_bar_shadow.9.png
+++ b/core/res/res/drawable-mdpi/title_bar_shadow.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/title_bar_tall.9.png b/core/res/res/drawable-mdpi/title_bar_tall.9.png
new file mode 100644
index 0000000..5a050c4
--- /dev/null
+++ b/core/res/res/drawable-mdpi/title_bar_tall.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/title_bar_tall.png b/core/res/res/drawable-mdpi/title_bar_tall.png
deleted file mode 100644
index cd565dc..0000000
--- a/core/res/res/drawable-mdpi/title_bar_tall.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable/fasttrack_nobadge.xml b/core/res/res/drawable/fasttrack_nobadge.xml
new file mode 100644
index 0000000..538e165
--- /dev/null
+++ b/core/res/res/drawable/fasttrack_nobadge.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* bubble_with_chats.xml
+**
+** Copyright 2009, Google Inc.
+**
+** 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.
+*/
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_pressed="true" android:drawable="@drawable/fasttrack_nobadge_pressed" />
+ <item android:state_selected="true" android:drawable="@drawable/fasttrack_nobadge_highlight" />
+ <item android:state_focused="true" android:drawable="@drawable/fasttrack_nobadge_highlight" />
+ <item android:state_enabled="false" android:drawable="@drawable/fasttrack_nobadge_normal" />
+ <item android:drawable="@drawable/fasttrack_nobadge_normal" />
+</selector>
diff --git a/core/res/res/drawable/fasttrack_nobadge_highlight.9.png b/core/res/res/drawable/fasttrack_nobadge_highlight.9.png
new file mode 100644
index 0000000..f0f50b3
--- /dev/null
+++ b/core/res/res/drawable/fasttrack_nobadge_highlight.9.png
Binary files differ
diff --git a/core/res/res/drawable/fasttrack_nobadge_normal.9.png b/core/res/res/drawable/fasttrack_nobadge_normal.9.png
new file mode 100644
index 0000000..01cc9dc
--- /dev/null
+++ b/core/res/res/drawable/fasttrack_nobadge_normal.9.png
Binary files differ
diff --git a/core/res/res/drawable/fasttrack_nobadge_pressed.9.png b/core/res/res/drawable/fasttrack_nobadge_pressed.9.png
new file mode 100644
index 0000000..6e22c87
--- /dev/null
+++ b/core/res/res/drawable/fasttrack_nobadge_pressed.9.png
Binary files differ
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index 3d6d273..3e3f87b 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -1102,8 +1102,8 @@
return res;
}
- public native int native_breakText(char[] text, int index, int count,
- float maxWidth, float[] measuredWidth);
+ private native int native_breakText(char[] text, int index, int count,
+ float maxWidth, float[] measuredWidth);
/**
* Measure the text, stopping early if the measured width exceeds maxWidth.
@@ -1174,8 +1174,8 @@
return res;
}
- public native int native_breakText(String text, boolean measureForwards,
- float maxWidth, float[] measuredWidth);
+ private native int native_breakText(String text, boolean measureForwards,
+ float maxWidth, float[] measuredWidth);
/**
* Return the advance widths for the characters in the string.
diff --git a/libs/rs/rsScriptC_Lib.cpp b/libs/rs/rsScriptC_Lib.cpp
index 2f195a5..8919465 100644
--- a/libs/rs/rsScriptC_Lib.cpp
+++ b/libs/rs/rsScriptC_Lib.cpp
@@ -996,7 +996,7 @@
"float", "(float, float)" },
{ "abs", (void *)&abs,
"int", "(int)" },
- { "absf", (void *)&fabs,
+ { "absf", (void *)&fabsf,
"float", "(float)" },
{ "sinf_fast", (void *)&SC_sinf_fast,
"float", "(float)" },
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index d6463a1..bb16215a 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -725,7 +725,7 @@
* false if otherwise
*/
public boolean isBluetoothA2dpOn() {
- if (AudioSystem.getDeviceConnectionState(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,"")
+ if (AudioSystem.getDeviceConnectionState(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,"")
== AudioSystem.DEVICE_STATE_UNAVAILABLE) {
return false;
} else {
@@ -750,7 +750,7 @@
* false if otherwise
*/
public boolean isWiredHeadsetOn() {
- if (AudioSystem.getDeviceConnectionState(AudioSystem.DEVICE_OUT_WIRED_HEADSET,"")
+ if (AudioSystem.getDeviceConnectionState(AudioSystem.DEVICE_OUT_WIRED_HEADSET,"")
== AudioSystem.DEVICE_STATE_UNAVAILABLE) {
return false;
} else {
@@ -1063,7 +1063,9 @@
* {@link #FX_KEYPRESS_SPACEBAR},
* {@link #FX_KEYPRESS_DELETE},
* {@link #FX_KEYPRESS_RETURN},
- * @param volume Sound effect volume
+ * @param volume Sound effect volume.
+ * The volume value is a raw scalar so UI controls should be scaled logarithmically.
+ * If a volume of -1 is specified, the AudioManager.STREAM_MUSIC stream volume minus 3dB will be used.
* NOTE: This version is for applications that have their own
* settings panel for enabling and controlling volume.
*/
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index 307cf22..f4c4586 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -619,11 +619,12 @@
/** @see AudioManager#playSoundEffect(int) */
public void playSoundEffect(int effectType) {
sendMsg(mAudioHandler, MSG_PLAY_SOUND_EFFECT, SHARED_MSG, SENDMSG_NOOP,
- effectType, SOUND_EFFECT_VOLUME, null, 0);
+ effectType, -1, null, 0);
}
/** @see AudioManager#playSoundEffect(int, float) */
public void playSoundEffectVolume(int effectType, float volume) {
+ loadSoundEffects();
sendMsg(mAudioHandler, MSG_PLAY_SOUND_EFFECT, SHARED_MSG, SENDMSG_NOOP,
effectType, (int) (volume * 1000), null, 0);
}
@@ -634,6 +635,9 @@
*/
public boolean loadSoundEffects() {
synchronized (mSoundEffectsLock) {
+ if (mSoundPool != null) {
+ return true;
+ }
mSoundPool = new SoundPool(NUM_SOUNDPOOL_CHANNELS, AudioSystem.STREAM_SYSTEM, 0);
if (mSoundPool == null) {
return false;
@@ -1197,10 +1201,20 @@
if (mSoundPool == null) {
return;
}
+ float volFloat;
+ // use STREAM_MUSIC volume attenuated by 3 dB if volume is not specified by caller
+ if (volume < 0) {
+ // Same linear to log conversion as in native AudioSystem::linearToLog() (AudioSystem.cpp)
+ float dBPerStep = (float)((0.5 * 100) / MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC]);
+ int musicVolIndex = (mStreamStates[AudioSystem.STREAM_MUSIC].mIndex + 5) / 10;
+ float musicVoldB = dBPerStep * (musicVolIndex - MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC]);
+ volFloat = (float)Math.pow(10, (musicVoldB - 3)/20);
+ } else {
+ volFloat = (float) volume / 1000.0f;
+ }
if (SOUND_EFFECT_FILES_MAP[effectType][1] > 0) {
- float v = (float) volume / 1000.0f;
- mSoundPool.play(SOUND_EFFECT_FILES_MAP[effectType][1], v, v, 0, 0, 1.0f);
+ mSoundPool.play(SOUND_EFFECT_FILES_MAP[effectType][1], volFloat, volFloat, 0, 0, 1.0f);
} else {
MediaPlayer mediaPlayer = new MediaPlayer();
if (mediaPlayer != null) {
@@ -1209,6 +1223,7 @@
mediaPlayer.setDataSource(filePath);
mediaPlayer.setAudioStreamType(AudioSystem.STREAM_SYSTEM);
mediaPlayer.prepare();
+ mediaPlayer.setVolume(volFloat, volFloat);
mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
cleanupPlayer(mp);
diff --git a/media/java/android/media/MiniThumbFile.java b/media/java/android/media/MiniThumbFile.java
index def0288..3cc115e 100644
--- a/media/java/android/media/MiniThumbFile.java
+++ b/media/java/android/media/MiniThumbFile.java
@@ -25,6 +25,7 @@
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
+import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.util.Hashtable;
@@ -44,12 +45,6 @@
* only.
*/
public class MiniThumbFile {
- public static final int THUMBNAIL_TARGET_SIZE = 320;
- public static final int MINI_THUMB_TARGET_SIZE = 96;
- public static final int THUMBNAIL_MAX_NUM_PIXELS = 512 * 384;
- public static final int MINI_THUMB_MAX_NUM_PIXELS = 128 * 128;
- public static final int UNCONSTRAINED = -1;
-
private static final String TAG = "MiniThumbFile";
private static final int MINI_THUMB_DATA_FILE_VERSION = 3;
public static final int BYTES_PER_MINTHUMB = 10000;
@@ -57,6 +52,7 @@
private Uri mUri;
private RandomAccessFile mMiniThumbFile;
private FileChannel mChannel;
+ private ByteBuffer mBuffer;
private static Hashtable<String, MiniThumbFile> sThumbFiles =
new Hashtable<String, MiniThumbFile>();
@@ -130,6 +126,7 @@
public MiniThumbFile(Uri uri) {
mUri = uri;
+ mBuffer = ByteBuffer.allocateDirect(BYTES_PER_MINTHUMB);
}
public synchronized void deactivate() {
@@ -154,14 +151,16 @@
long pos = id * BYTES_PER_MINTHUMB;
FileLock lock = null;
try {
- lock = mChannel.lock();
+ mBuffer.clear();
+ mBuffer.limit(1 + 8);
+
+ lock = mChannel.lock(pos, 1 + 8, true);
// check that we can read the following 9 bytes
// (1 for the "status" and 8 for the long)
- if (r.length() >= pos + 1 + 8) {
- r.seek(pos);
- if (r.readByte() == 1) {
- long fileMagic = r.readLong();
- return fileMagic;
+ if (mChannel.read(mBuffer, pos) == 9) {
+ mBuffer.position(0);
+ if (mBuffer.get() == 1) {
+ return mBuffer.getLong();
}
}
} catch (IOException ex) {
@@ -196,25 +195,20 @@
long pos = id * BYTES_PER_MINTHUMB;
FileLock lock = null;
try {
- lock = mChannel.lock();
if (data != null) {
if (data.length > BYTES_PER_MINTHUMB - HEADER_SIZE) {
// not enough space to store it.
return;
}
- r.seek(pos);
- r.writeByte(0); // we have no data in this slot
+ mBuffer.clear();
+ mBuffer.put((byte) 1);
+ mBuffer.putLong(magic);
+ mBuffer.putInt(data.length);
+ mBuffer.put(data);
+ mBuffer.flip();
- // if magic is 0 then leave it alone
- if (magic == 0) {
- r.skipBytes(8);
- } else {
- r.writeLong(magic);
- }
- r.writeInt(data.length);
- r.write(data);
- r.seek(pos);
- r.writeByte(1); // we have data in this slot
+ lock = mChannel.lock(pos, BYTES_PER_MINTHUMB, false);
+ mChannel.write(mBuffer, pos);
}
} catch (IOException ex) {
Log.e(TAG, "couldn't save mini thumbnail data for "
@@ -248,20 +242,22 @@
long pos = id * BYTES_PER_MINTHUMB;
FileLock lock = null;
try {
- lock = mChannel.lock();
- r.seek(pos);
- if (r.readByte() == 1) {
- long magic = r.readLong();
- int length = r.readInt();
- int got = r.read(data, 0, length);
- if (got != length) return null;
- return data;
- } else {
- return null;
+ mBuffer.clear();
+ lock = mChannel.lock(pos, BYTES_PER_MINTHUMB, true);
+ int size = mChannel.read(mBuffer, pos);
+ if (size > 1 + 8 + 4) { // flag, magic, length
+ mBuffer.position(0);
+ byte flag = mBuffer.get();
+ long magic = mBuffer.getLong();
+ int length = mBuffer.getInt();
+
+ if (size >= 1 + 8 + 4 + length && data.length >= length) {
+ mBuffer.get(data, 0, length);
+ return data;
+ }
}
} catch (IOException ex) {
- Log.w(TAG, "got exception when reading thumbnail: " + ex);
- return null;
+ Log.w(TAG, "got exception when reading thumbnail id=" + id + ", exception: " + ex);
} catch (RuntimeException ex) {
// Other NIO related exception like disk full, read only channel..etc
Log.e(TAG, "Got exception when reading thumbnail, id = " + id +
diff --git a/media/libmediaplayerservice/MetadataRetrieverClient.cpp b/media/libmediaplayerservice/MetadataRetrieverClient.cpp
index b34421d..ddd4e24 100644
--- a/media/libmediaplayerservice/MetadataRetrieverClient.cpp
+++ b/media/libmediaplayerservice/MetadataRetrieverClient.cpp
@@ -51,15 +51,8 @@
mAlbumArtDealer = NULL;
mThumbnail = NULL;
mAlbumArt = NULL;
-
-#ifndef NO_OPENCORE
- mRetriever = new PVMetadataRetriever();
-#else
mRetriever = NULL;
-#endif
- if (mRetriever == NULL) {
- LOGE("failed to initialize the retriever");
- }
+ mMode = METADATA_MODE_FRAME_CAPTURE_AND_METADATA_RETRIEVAL;
}
MetadataRetrieverClient::~MetadataRetrieverClient()
@@ -74,7 +67,7 @@
char buffer[SIZE];
String8 result;
result.append(" MetadataRetrieverClient\n");
- snprintf(buffer, 255, " pid(%d)\n", mPid);
+ snprintf(buffer, 255, " pid(%d) mode(%d)\n", mPid, mMode);
result.append(buffer);
write(fd, result.string(), result.size());
write(fd, "\n", 1);
@@ -90,6 +83,7 @@
mAlbumArtDealer.clear();
mThumbnail.clear();
mAlbumArt.clear();
+ mMode = METADATA_MODE_FRAME_CAPTURE_AND_METADATA_RETRIEVAL;
IPCThreadState::self()->flushCommands();
}
@@ -134,7 +128,10 @@
LOGV("player type = %d", playerType);
sp<MediaMetadataRetrieverBase> p = createRetriever(playerType);
if (p == NULL) return NO_INIT;
- status_t ret = p->setDataSource(url);
+ status_t ret = p->setMode(mMode);
+ if (ret == NO_ERROR) {
+ ret = p->setDataSource(url);
+ }
if (ret == NO_ERROR) mRetriever = p;
return ret;
}
@@ -143,12 +140,6 @@
{
LOGV("setDataSource fd=%d, offset=%lld, length=%lld", fd, offset, length);
Mutex::Autolock lock(mLock);
- if (mRetriever == NULL) {
- LOGE("retriever is not initialized");
- ::close(fd);
- return NO_INIT;
- }
-
struct stat sb;
int ret = fstat(fd, &sb);
if (ret != 0) {
@@ -178,7 +169,10 @@
::close(fd);
return NO_INIT;
}
- status_t status = p->setDataSource(fd, offset, length);
+ status_t status = p->setMode(mMode);
+ if (status == NO_ERROR) {
+ p->setDataSource(fd, offset, length);
+ }
if (status == NO_ERROR) mRetriever = p;
::close(fd);
return status;
@@ -188,22 +182,30 @@
{
LOGV("setMode");
Mutex::Autolock lock(mLock);
- if (mRetriever == NULL) {
- LOGE("retriever is not initialized");
- return NO_INIT;
+ if (mode < METADATA_MODE_NOOP ||
+ mode > METADATA_MODE_FRAME_CAPTURE_AND_METADATA_RETRIEVAL) {
+ LOGE("invalid mode %d", mode);
+ return BAD_VALUE;
}
- return mRetriever->setMode(mode);
+ mMode = mode;
+ return NO_ERROR;
}
status_t MetadataRetrieverClient::getMode(int* mode) const
{
LOGV("getMode");
Mutex::Autolock lock(mLock);
+
+ // TODO:
+ // This may not be necessary.
+ // If setDataSource() has not been called, return the cached value
+ // otherwise, return the value retrieved from the retriever
if (mRetriever == NULL) {
- LOGE("retriever is not initialized");
- return NO_INIT;
+ *mode = mMode;
+ } else {
+ mRetriever->getMode(mode);
}
- return mRetriever->getMode(mode);
+ return NO_ERROR;
}
sp<IMemory> MetadataRetrieverClient::captureFrame()
diff --git a/media/libmediaplayerservice/MetadataRetrieverClient.h b/media/libmediaplayerservice/MetadataRetrieverClient.h
index 88d50bf..8cb8ad1 100644
--- a/media/libmediaplayerservice/MetadataRetrieverClient.h
+++ b/media/libmediaplayerservice/MetadataRetrieverClient.h
@@ -60,6 +60,7 @@
mutable Mutex mLock;
sp<MediaMetadataRetrieverBase> mRetriever;
pid_t mPid;
+ int mMode;
// Keep the shared memory copy of album art and capture frame (for thumbnail)
sp<MemoryDealer> mAlbumArtDealer;
diff --git a/packages/SettingsProvider/res/drawable-hdpi/ic_launcher_settings.png b/packages/SettingsProvider/res/drawable-hdpi/ic_launcher_settings.png
new file mode 100644
index 0000000..aad82c5
--- /dev/null
+++ b/packages/SettingsProvider/res/drawable-hdpi/ic_launcher_settings.png
Binary files differ
diff --git a/packages/SettingsProvider/res/drawable/ic_launcher_settings.png b/packages/SettingsProvider/res/drawable/ic_launcher_settings.png
index 16db056..aad82c5 100755
--- a/packages/SettingsProvider/res/drawable/ic_launcher_settings.png
+++ b/packages/SettingsProvider/res/drawable/ic_launcher_settings.png
Binary files differ
diff --git a/packages/TtsService/AndroidManifest.xml b/packages/TtsService/AndroidManifest.xml
index bd17ba0..46e0ad1 100755
--- a/packages/TtsService/AndroidManifest.xml
+++ b/packages/TtsService/AndroidManifest.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="android.tts">
- <application android:label="TTS Service">
+ <application android:label="TTS Service"
+ android:icon="@drawable/ic_launcher_text_to_speech">
<service android:enabled="true"
android:name=".TtsService"
android:label="TTS Service">
diff --git a/packages/TtsService/res/drawable-hdpi/ic_launcher_text_to_speech.png b/packages/TtsService/res/drawable-hdpi/ic_launcher_text_to_speech.png
new file mode 100644
index 0000000..3d0c807
--- /dev/null
+++ b/packages/TtsService/res/drawable-hdpi/ic_launcher_text_to_speech.png
Binary files differ
diff --git a/telephony/java/com/android/internal/telephony/Connection.java b/telephony/java/com/android/internal/telephony/Connection.java
index a48900a..37e8a99 100644
--- a/telephony/java/com/android/internal/telephony/Connection.java
+++ b/telephony/java/com/android/internal/telephony/Connection.java
@@ -59,6 +59,7 @@
CDMA_ACCESS_FAILURE,
CDMA_PREEMPTED,
CDMA_NOT_EMERGENCY, /* not an emergency call */
+ CDMA_ACCESS_BLOCKED, /* Access Blocked by CDMA network */
ERROR_UNSPECIFIED
}
diff --git a/telephony/java/com/android/internal/telephony/RIL.java b/telephony/java/com/android/internal/telephony/RIL.java
index f3b59a8..d802efa 100644
--- a/telephony/java/com/android/internal/telephony/RIL.java
+++ b/telephony/java/com/android/internal/telephony/RIL.java
@@ -2174,7 +2174,7 @@
case RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG: ret = responseCdmaBroadcastConfig(p); break;
case RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG: ret = responseVoid(p); break;
case RIL_REQUEST_CDMA_BROADCAST_ACTIVATION: ret = responseVoid(p); break;
- case RIL_REQUEST_CDMA_VALIDATE_AKEY: ret = responseVoid(p); break;
+ case RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY: ret = responseVoid(p); break;
case RIL_REQUEST_CDMA_SUBSCRIPTION: ret = responseStrings(p); break;
case RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM: ret = responseInts(p); break;
case RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM: ret = responseVoid(p); break;
@@ -3197,7 +3197,7 @@
case RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG: return "RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG";
case RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG: return "RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG";
case RIL_REQUEST_GSM_BROADCAST_ACTIVATION: return "RIL_REQUEST_GSM_BROADCAST_ACTIVATION";
- case RIL_REQUEST_CDMA_VALIDATE_AKEY: return "RIL_REQUEST_CDMA_VALIDATE_AKEY";
+ case RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY: return "RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY";
case RIL_REQUEST_CDMA_BROADCAST_ACTIVATION: return "RIL_REQUEST_CDMA_BROADCAST_ACTIVATION";
case RIL_REQUEST_CDMA_SUBSCRIPTION: return "RIL_REQUEST_CDMA_SUBSCRIPTION";
case RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM: return "RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM";
diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java
index 3e9d8ad..c29adcf 100644
--- a/telephony/java/com/android/internal/telephony/RILConstants.java
+++ b/telephony/java/com/android/internal/telephony/RILConstants.java
@@ -210,7 +210,7 @@
int RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE = 83;
int RIL_REQUEST_CDMA_FLASH = 84;
int RIL_REQUEST_CDMA_BURST_DTMF = 85;
- int RIL_REQUEST_CDMA_VALIDATE_AKEY = 86;
+ int RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY = 86;
int RIL_REQUEST_CDMA_SEND_SMS = 87;
int RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE = 88;
int RIL_REQUEST_GSM_GET_BROADCAST_CONFIG = 89;
diff --git a/telephony/java/com/android/internal/telephony/cdma/CallFailCause.java b/telephony/java/com/android/internal/telephony/cdma/CallFailCause.java
index fb5f0fa..ad6c23c 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CallFailCause.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CallFailCause.java
@@ -17,9 +17,10 @@
package com.android.internal.telephony.cdma;
/**
- * Call fail causes from TS 24.008 .
- * These are mostly the cause codes we need to distinguish for the UI.
- * See 22.001 Annex F.4 for mapping of cause codes to local tones.
+ * CDMA Call fail causes covering all the possible failures that are
+ * needed to be distinguished by the UI. CDMA call failure reasons
+ * are derived from the possible call failure scenarios described
+ * in "CDMA IS2000 - Release A (C.S0005-A v6.0)" standard.
*
* {@hide}
*
@@ -51,5 +52,8 @@
// For non-emergency number dialed while in emergency callback mode.
static final int CDMA_NOT_EMERGENCY = 1008;
+ // Access Blocked by CDMA Network.
+ static final int CDMA_ACCESS_BLOCKED = 1009;
+
static final int ERROR_UNSPECIFIED = 0xffff;
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java b/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java
index bc04e02..f637d33 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java
@@ -418,6 +418,8 @@
return DisconnectCause.CDMA_PREEMPTED;
case CallFailCause.CDMA_NOT_EMERGENCY:
return DisconnectCause.CDMA_NOT_EMERGENCY;
+ case CallFailCause.CDMA_ACCESS_BLOCKED:
+ return DisconnectCause.CDMA_ACCESS_BLOCKED;
case CallFailCause.ERROR_UNSPECIFIED:
case CallFailCause.NORMAL_CLEARING:
default:
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
index 9407603..d0a9337 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
@@ -76,6 +76,9 @@
/** Currently active CdmaDataConnection */
private CdmaDataConnection mActiveDataConnection;
+ /** mimic of GSM's mActiveApn */
+ private boolean mIsApnActive = false;
+
private boolean mPendingRestartRadio = false;
private static final int TIME_DELAYED_TO_RESTART_RADIO =
SystemProperties.getInt("ro.cdma.timetoradiorestart", 20000);
@@ -245,8 +248,7 @@
@Override
protected boolean isApnTypeActive(String type) {
- return (isApnTypeAvailable(type) &&
- (state != State.IDLE));
+ return (mIsApnActive && isApnTypeAvailable(type));
}
@Override
@@ -260,10 +262,15 @@
}
protected String[] getActiveApnTypes() {
- if (state != State.IDLE) {
- return mSupportedApnTypes.clone();
+ String[] result;
+ if (mIsApnActive) {
+ result = mSupportedApnTypes.clone();
+ } else {
+ // TODO - should this return an empty array? See GSM too.
+ result = new String[1];
+ result[0] = Phone.APN_TYPE_DEFAULT;
}
- return new String[0];
+ return result;
}
protected String getActiveApnString() {
@@ -386,6 +393,7 @@
if (!tearDown) {
setState(State.IDLE);
phone.notifyDataConnection(reason);
+ mIsApnActive = false;
}
}
@@ -409,6 +417,7 @@
}
mActiveDataConnection = conn;
+ mIsApnActive = true;
Message msg = obtainMessage();
msg.what = EVENT_DATA_SETUP_COMPLETE;
@@ -742,6 +751,7 @@
}
phone.notifyDataConnection(reason);
+ mIsApnActive = false;
if (retryAfterDisconnected(reason)) {
trySetupData(reason);
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
index c85b9bd..5bdf09f 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
@@ -596,32 +596,36 @@
}
protected String getInterfaceName(String apnType) {
- if (mActivePdp != null
- && (apnType == null || mActiveApn.canHandleType(apnType))) {
+ if (mActivePdp != null &&
+ (apnType == null ||
+ (mActiveApn != null && mActiveApn.canHandleType(apnType)))) {
return mActivePdp.getInterface();
}
return null;
}
protected String getIpAddress(String apnType) {
- if (mActivePdp != null
- && (apnType == null || mActiveApn.canHandleType(apnType))) {
+ if (mActivePdp != null &&
+ (apnType == null ||
+ (mActiveApn != null && mActiveApn.canHandleType(apnType)))) {
return mActivePdp.getIpAddress();
}
return null;
}
public String getGateway(String apnType) {
- if (mActivePdp != null
- && (apnType == null || mActiveApn.canHandleType(apnType))) {
+ if (mActivePdp != null &&
+ (apnType == null ||
+ (mActiveApn != null && mActiveApn.canHandleType(apnType)))) {
return mActivePdp.getGatewayAddress();
}
return null;
}
protected String[] getDnsServers(String apnType) {
- if (mActivePdp != null
- && (apnType == null || mActiveApn.canHandleType(apnType))) {
+ if (mActivePdp != null &&
+ (apnType == null ||
+ (mActiveApn != null && mActiveApn.canHandleType(apnType)))) {
return mActivePdp.getDnsServers();
}
return null;