Merge change 9551
* changes:
Implement the jni bindings for Adapter2D. Fix a refcount bug in the native adapter implementation. Use adapters in Film to border the mipmaps.
diff --git a/Android.mk b/Android.mk
index 728ae46..275807a 100644
--- a/Android.mk
+++ b/Android.mk
@@ -332,7 +332,13 @@
framework_docs_LOCAL_MODULE_CLASS := JAVA_LIBRARIES
framework_docs_LOCAL_DROIDDOC_HTML_DIR := docs/html
+# The since flag (-since N.xml API_LEVEL) is used to add API Level information
+# to the reference documentation. Must be in order of oldest to newest.
framework_docs_LOCAL_DROIDDOC_OPTIONS := \
+ -since ./frameworks/base/api/1.xml 1 \
+ -since ./frameworks/base/api/2.xml 2 \
+ -since ./frameworks/base/api/3.xml 3 \
+ -since ./frameworks/base/api/current.xml Donut \
-error 1 -error 2 -warning 3 -error 4 -error 6 -error 8 \
-overview $(LOCAL_PATH)/core/java/overview.html
diff --git a/cmds/keystore/netkeystore.c b/cmds/keystore/netkeystore.c
index eac455e..637e0d8 100644
--- a/cmds/keystore/netkeystore.c
+++ b/cmds/keystore/netkeystore.c
@@ -37,6 +37,7 @@
#include "netkeystore.h"
#include "keymgmt.h"
+#define DBG 1
#define CMD_PUT_WITH_FILE "putfile"
typedef void CMD_FUNC(LPC_MARSHAL *cmd, LPC_MARSHAL *reply);
@@ -397,12 +398,12 @@
// read the command, execute and send the result back.
if(read_marshal(s, &cmd)) goto err;
- LOGI("new connection\n");
+ if (DBG) LOGD("new connection\n");
execute(&cmd, &reply);
write_marshal(s, &reply);
err:
memset(&reply, 0, sizeof(LPC_MARSHAL));
- LOGI("closing connection\n");
+ if (DBG) LOGD("closing connection\n");
close(s);
}
diff --git a/core/java/android/net/http/EventHandler.java b/core/java/android/net/http/EventHandler.java
index 830d1f1..a035c19 100644
--- a/core/java/android/net/http/EventHandler.java
+++ b/core/java/android/net/http/EventHandler.java
@@ -141,7 +141,10 @@
* SSL certificate error callback. Handles SSL error(s) on the way
* up to the user. The callback has to make sure that restartConnection() is called,
* otherwise the connection will be suspended indefinitely.
+ * @return True if the callback can handle the error, which means it will
+ * call restartConnection() to unblock the thread later,
+ * otherwise return false.
*/
- public void handleSslErrorRequest(SslError error);
+ public boolean handleSslErrorRequest(SslError error);
}
diff --git a/core/java/android/net/http/HttpsConnection.java b/core/java/android/net/http/HttpsConnection.java
index 55b733f..8a69d0d 100644
--- a/core/java/android/net/http/HttpsConnection.java
+++ b/core/java/android/net/http/HttpsConnection.java
@@ -323,7 +323,10 @@
mSuspended = true;
}
// don't hold the lock while calling out to the event handler
- eventHandler.handleSslErrorRequest(error);
+ boolean canHandle = eventHandler.handleSslErrorRequest(error);
+ if(!canHandle) {
+ throw new IOException("failed to handle "+ error);
+ }
synchronized (mSuspendLock) {
if (mSuspended) {
try {
diff --git a/core/java/android/net/http/LoggingEventHandler.java b/core/java/android/net/http/LoggingEventHandler.java
index 1b18651..bdafa0b 100644
--- a/core/java/android/net/http/LoggingEventHandler.java
+++ b/core/java/android/net/http/LoggingEventHandler.java
@@ -82,9 +82,11 @@
}
}
- public void handleSslErrorRequest(SslError error) {
+ public boolean handleSslErrorRequest(SslError error) {
if (HttpLog.LOGV) {
HttpLog.v("LoggingEventHandler: handleSslErrorRequest():" + error);
}
+ // return false so that the caller thread won't wait forever
+ return false;
}
}
diff --git a/core/java/android/provider/Contacts.java b/core/java/android/provider/Contacts.java
index 5f84e57..c0dbf4d 100644
--- a/core/java/android/provider/Contacts.java
+++ b/core/java/android/provider/Contacts.java
@@ -1523,6 +1523,15 @@
ContactsContract.Intents.EXTRA_CREATE_DESCRIPTION;
/**
+ * Optional extra used with {@link #SHOW_OR_CREATE_CONTACT} to specify a
+ * dialog location using screen coordinates. When not specified, the
+ * dialog will be centered.
+ *
+ * @hide pending API council review
+ */
+ public static final String EXTRA_TARGET_RECT = ContactsContract.Intents.EXTRA_TARGET_RECT;
+
+ /**
* Intents related to the Contacts app UI.
*/
public static final class UI {
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index 01189fe..227c675 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -1009,6 +1009,8 @@
public static final String PROTOCOL = "data5";
+ public static final String CUSTOM_PROTOCOL = "data6";
+
/**
* The predefined IM protocol types. The protocol can either be non-present, one
* of these types, or a free-form string. These cases are encoded in the PROTOCOL
@@ -1019,6 +1021,7 @@
* <li>custom:<a string></li>
* </ul>
*/
+ public static final int PROTOCOL_CUSTOM = -1;
public static final int PROTOCOL_AIM = 0;
public static final int PROTOCOL_MSN = 1;
public static final int PROTOCOL_YAHOO = 2;
@@ -1027,31 +1030,6 @@
public static final int PROTOCOL_GOOGLE_TALK = 5;
public static final int PROTOCOL_ICQ = 6;
public static final int PROTOCOL_JABBER = 7;
-
- public static String encodePredefinedImProtocol(int protocol) {
- return "pre:" + protocol;
- }
-
- public static String encodeCustomImProtocol(String protocolString) {
- return "custom:" + protocolString;
- }
-
- public static Object decodeImProtocol(String encodedString) {
- if (encodedString == null) {
- return null;
- }
-
- if (encodedString.startsWith("pre:")) {
- return Integer.parseInt(encodedString.substring(4));
- }
-
- if (encodedString.startsWith("custom:")) {
- return encodedString.substring(7);
- }
-
- throw new IllegalArgumentException(
- "the value is not a valid encoded protocol, " + encodedString);
- }
}
/**
@@ -1397,6 +1375,13 @@
"com.android.contacts.action.CREATE_DESCRIPTION";
/**
+ * Optional extra used with {@link #SHOW_OR_CREATE_CONTACT} to specify a
+ * dialog location using screen coordinates. When not specified, the
+ * dialog will be centered.
+ */
+ public static final String EXTRA_TARGET_RECT = "target_rect";
+
+ /**
* Intents related to the Contacts app UI.
*/
public static final class UI {
diff --git a/core/java/android/util/MathUtils.java b/core/java/android/util/MathUtils.java
new file mode 100644
index 0000000..d8509a0
--- /dev/null
+++ b/core/java/android/util/MathUtils.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.util;
+
+import java.util.Random;
+
+/**
+ * A class that contains utility methods related to numbers.
+ *
+ * @hide Pending API council approval
+ */
+public final class MathUtils {
+ private static final Random sRandom = new Random();
+ private static final float DEG_TO_RAD = 3.1415926f / 180.0f;
+ private static final float RAD_TO_DEG = 180.0f / 3.1415926f;
+
+ private MathUtils() {
+ }
+
+ public static float abs(float v) {
+ return v > 0 ? v : -v;
+ }
+
+ public static int constrain(int amount, int low, int high) {
+ return amount < low ? low : (amount > high ? high : amount);
+ }
+
+ public static float constrain(float amount, float low, float high) {
+ return amount < low ? low : (amount > high ? high : amount);
+ }
+
+ public static float log(float a) {
+ return (float) Math.log(a);
+ }
+
+ public static float exp(float a) {
+ return (float) Math.exp(a);
+ }
+
+ public static float pow(float a, float b) {
+ return (float) Math.pow(a, b);
+ }
+
+ public static float max(float a, float b) {
+ return a > b ? a : b;
+ }
+
+ public static float max(int a, int b) {
+ return a > b ? a : b;
+ }
+
+ public static float max(float a, float b, float c) {
+ return a > b ? (a > c ? a : c) : (b > c ? b : c);
+ }
+
+ public static float max(int a, int b, int c) {
+ return a > b ? (a > c ? a : c) : (b > c ? b : c);
+ }
+
+ public static float min(float a, float b) {
+ return a < b ? a : b;
+ }
+
+ public static float min(int a, int b) {
+ return a < b ? a : b;
+ }
+
+ public static float min(float a, float b, float c) {
+ return a < b ? (a < c ? a : c) : (b < c ? b : c);
+ }
+
+ public static float min(int a, int b, int c) {
+ return a < b ? (a < c ? a : c) : (b < c ? b : c);
+ }
+
+ public static float dist(float x1, float y1, float x2, float y2) {
+ final float x = (x2 - x1);
+ final float y = (y2 - y1);
+ return (float) Math.sqrt(x * x + y * y);
+ }
+
+ public static float dist(float x1, float y1, float z1, float x2, float y2, float z2) {
+ final float x = (x2 - x1);
+ final float y = (y2 - y1);
+ final float z = (z2 - z1);
+ return (float) Math.sqrt(x * x + y * y + z * z);
+ }
+
+ public static float mag(float a, float b) {
+ return (float) Math.sqrt(a * a + b * b);
+ }
+
+ public static float mag(float a, float b, float c) {
+ return (float) Math.sqrt(a * a + b * b + c * c);
+ }
+
+ public static float sq(float v) {
+ return v * v;
+ }
+
+ public static float radians(float degrees) {
+ return degrees * DEG_TO_RAD;
+ }
+
+ public static float degress(float radians) {
+ return radians * RAD_TO_DEG;
+ }
+
+ public static float acos(float value) {
+ return (float) Math.acos(value);
+ }
+
+ public static float asin(float value) {
+ return (float) Math.asin(value);
+ }
+
+ public static float atan(float value) {
+ return (float) Math.atan(value);
+ }
+
+ public static float atan2(float a, float b) {
+ return (float) Math.atan2(a, b);
+ }
+
+ public static float tan(float angle) {
+ return (float) Math.tan(angle);
+ }
+
+ public static float lerp(float start, float stop, float amount) {
+ return start + (stop - start) * amount;
+ }
+
+ public static int random(int howbig) {
+ return (int) (sRandom.nextFloat() * howbig);
+ }
+
+ public static int random(int howsmall, int howbig) {
+ if (howsmall >= howbig) return howsmall;
+ return (int) (sRandom.nextFloat() * (howbig - howsmall) + howsmall);
+ }
+
+ public static float random(float howbig) {
+ return sRandom.nextFloat() * howbig;
+ }
+
+ public static float random(float howsmall, float howbig) {
+ if (howsmall >= howbig) return howsmall;
+ return sRandom.nextFloat() * (howbig - howsmall) + howsmall;
+ }
+
+ public static void randomSeed(long seed) {
+ sRandom.setSeed(seed);
+ }
+}
diff --git a/core/java/android/webkit/CookieManager.java b/core/java/android/webkit/CookieManager.java
index 7b91724..c81c4b6 100644
--- a/core/java/android/webkit/CookieManager.java
+++ b/core/java/android/webkit/CookieManager.java
@@ -23,9 +23,12 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
+import java.util.Comparator;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
+import java.util.SortedSet;
+import java.util.TreeSet;
/**
* CookieManager manages cookies according to RFC2109 spec.
@@ -190,6 +193,14 @@
}
}
+ private static final CookieComparator COMPARATOR = new CookieComparator();
+
+ private static final class CookieComparator implements Comparator<Cookie> {
+ public int compare(Cookie cookie1, Cookie cookie2) {
+ return cookie2.path.length() - cookie1.path.length();
+ }
+ }
+
private CookieManager() {
}
@@ -401,8 +412,8 @@
long now = System.currentTimeMillis();
boolean secure = HTTPS.equals(uri.mScheme);
Iterator<Cookie> iter = cookieList.iterator();
- StringBuilder ret = new StringBuilder(256);
+ SortedSet<Cookie> cookieSet = new TreeSet<Cookie>(COMPARATOR);
while (iter.hasNext()) {
Cookie cookie = iter.next();
if (cookie.domainMatch(hostAndPath[0]) &&
@@ -413,19 +424,26 @@
&& (!cookie.secure || secure)
&& cookie.mode != Cookie.MODE_DELETED) {
cookie.lastAcessTime = now;
-
- if (ret.length() > 0) {
- ret.append(SEMICOLON);
- // according to RC2109, SEMICOLON is office separator,
- // but when log in yahoo.com, it needs WHITE_SPACE too.
- ret.append(WHITE_SPACE);
- }
-
- ret.append(cookie.name);
- ret.append(EQUAL);
- ret.append(cookie.value);
+ cookieSet.add(cookie);
}
}
+
+ StringBuilder ret = new StringBuilder(256);
+ Iterator<Cookie> setIter = cookieSet.iterator();
+ while (setIter.hasNext()) {
+ Cookie cookie = setIter.next();
+ if (ret.length() > 0) {
+ ret.append(SEMICOLON);
+ // according to RC2109, SEMICOLON is official separator,
+ // but when log in yahoo.com, it needs WHITE_SPACE too.
+ ret.append(WHITE_SPACE);
+ }
+
+ ret.append(cookie.name);
+ ret.append(EQUAL);
+ ret.append(cookie.value);
+ }
+
if (ret.length() > 0) {
if (DebugFlags.COOKIE_MANAGER) {
Log.v(LOGTAG, "getCookie: uri: " + uri + " value: " + ret);
diff --git a/core/java/android/webkit/LoadListener.java b/core/java/android/webkit/LoadListener.java
index 50436d8..7fff014 100644
--- a/core/java/android/webkit/LoadListener.java
+++ b/core/java/android/webkit/LoadListener.java
@@ -104,6 +104,7 @@
private String mErrorDescription;
private SslError mSslError;
private RequestHandle mRequestHandle;
+ private RequestHandle mSslErrorRequestHandle;
// Request data. It is only valid when we are doing a load from the
// cache. It is needed if the cache returns a redirect
@@ -673,7 +674,7 @@
* IMPORTANT: as this is called from network thread, can't call native
* directly
*/
- public void handleSslErrorRequest(SslError error) {
+ public boolean handleSslErrorRequest(SslError error) {
if (DebugFlags.LOAD_LISTENER) {
Log.v(LOGTAG,
"LoadListener.handleSslErrorRequest(): url:" + url() +
@@ -681,6 +682,15 @@
" certificate: " + error.getCertificate());
}
sendMessageInternal(obtainMessage(MSG_SSL_ERROR, error));
+ // if it has been canceled, return false so that the network thread
+ // won't be blocked. If it is not canceled, save the mRequestHandle
+ // so that if it is canceled when MSG_SSL_ERROR is handled, we can
+ // still call handleSslErrorResponse which will call restartConnection
+ // to unblock the network thread.
+ if (!mCancelled) {
+ mSslErrorRequestHandle = mRequestHandle;
+ }
+ return !mCancelled;
}
// Handle the ssl error on the WebCore thread.
@@ -688,7 +698,10 @@
if (!mCancelled) {
mSslError = error;
Network.getInstance(mContext).handleSslErrorRequest(this);
+ } else if (mSslErrorRequestHandle != null) {
+ mSslErrorRequestHandle.handleSslErrorResponse(true);
}
+ mSslErrorRequestHandle = null;
}
/**
diff --git a/core/java/com/android/internal/widget/ContactHeaderWidget.java b/core/java/com/android/internal/widget/ContactHeaderWidget.java
new file mode 100644
index 0000000..ccb537a
--- /dev/null
+++ b/core/java/com/android/internal/widget/ContactHeaderWidget.java
@@ -0,0 +1,351 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.widget;
+
+import android.content.AsyncQueryHandler;
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.Message;
+import android.os.SystemClock;
+import android.provider.SocialContract;
+import android.provider.ContactsContract.Contacts;
+import android.provider.ContactsContract.Data;
+import android.provider.ContactsContract.PhoneLookup;
+import android.provider.ContactsContract.RawContacts;
+import android.provider.ContactsContract.CommonDataKinds.Photo;
+import android.provider.SocialContract.Activities;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.CheckBox;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+import com.android.internal.R;
+
+
+/* Widget that is used across system apps for displaying a header banner with contact info */
+public class ContactHeaderWidget extends FrameLayout implements View.OnClickListener {
+
+ private static final String TAG = "ContactHeaderWidget";
+
+ private TextView mDisplayNameView;
+ private TextView mPhoneticNameView;
+ private CheckBox mStarredView;
+ private ImageView mPhotoView;
+ private TextView mStatusView;
+ private int mNoPhotoResource;
+ private QueryHandler mQueryHandler;
+
+ protected long mContactId;
+ protected Uri mContactDataUri;
+ protected Uri mContactUri;
+ protected Uri mStatusUri;
+
+ protected ContentResolver mContentResolver;
+
+ //Projection used for the summary info in the header.
+ protected static final String[] HEADER_PROJECTION = new String[] {
+ Contacts.DISPLAY_NAME,
+ Contacts.STARRED,
+ Contacts.PHOTO_ID,
+ };
+ protected static final int HEADER_DISPLAY_NAME_COLUMN_INDEX = 0;
+ //TODO: We need to figure out how we're going to get the phonetic name.
+ //static final int HEADER_PHONETIC_NAME_COLUMN_INDEX
+ protected static final int HEADER_STARRED_COLUMN_INDEX = 1;
+ protected static final int HEADER_PHOTO_ID_COLUMN_INDEX = 2;
+
+ //Projection used for finding the most recent social status.
+ protected static final String[] SOCIAL_PROJECTION = new String[] {
+ Activities.TITLE,
+ Activities.PUBLISHED,
+ };
+ protected static final int SOCIAL_TITLE_COLUMN_INDEX = 0;
+ protected static final int SOCIAL_PUBLISHED_COLUMN_INDEX = 1;
+
+ //Projection used for looking up contact id from phone number
+ protected static final String[] PHONE_LOOKUP_PROJECTION = new String[] {
+ RawContacts.CONTACT_ID,
+ };
+ protected static final int PHONE_LOOKUP_CONTACT_ID_COLUMN_INDEX = 0;
+
+ //Projection used for looking up contact id from email address
+ protected static final String[] EMAIL_LOOKUP_PROJECTION = new String[] {
+ RawContacts.CONTACT_ID,
+ };
+ protected static final int EMAIL_LOOKUP_CONTACT_ID_COLUMN_INDEX = 0;
+
+
+ private static final int TOKEN_CONTACT_INFO = 0;
+ private static final int TOKEN_SOCIAL = 1;
+
+ public ContactHeaderWidget(Context context) {
+ this(context, null);
+ }
+
+ public ContactHeaderWidget(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public ContactHeaderWidget(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+
+ mContentResolver = mContext.getContentResolver();
+
+ LayoutInflater inflater =
+ (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ inflater.inflate(R.layout.contact_header, this);
+
+ mDisplayNameView = (TextView) findViewById(R.id.name);
+ mPhoneticNameView = (TextView) findViewById(R.id.phonetic_name);
+ mStarredView = (CheckBox) findViewById(R.id.star);
+ mStarredView.setOnClickListener(this);
+ // Don't show start by default.
+ mStarredView.setVisibility(View.GONE);
+ mPhotoView = (ImageView) findViewById(R.id.photo);
+ mStatusView = (TextView) findViewById(R.id.status);
+
+ // Set the photo with a random "no contact" image
+ long now = SystemClock.elapsedRealtime();
+ int num = (int) now & 0xf;
+ if (num < 9) {
+ // Leaning in from right, common
+ mNoPhotoResource = R.drawable.ic_contact_picture;
+ } else if (num < 14) {
+ // Leaning in from left uncommon
+ mNoPhotoResource = R.drawable.ic_contact_picture_2;
+ } else {
+ // Coming in from the top, rare
+ mNoPhotoResource = R.drawable.ic_contact_picture_3;
+ }
+
+ mQueryHandler = new QueryHandler(mContentResolver);
+ }
+
+ private class QueryHandler extends AsyncQueryHandler {
+
+ public QueryHandler(ContentResolver cr) {
+ super(cr);
+ }
+
+ @Override
+ protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
+ try{
+ if (token == TOKEN_CONTACT_INFO) {
+ bindContactInfo(cursor);
+ invalidate();
+ } else if (token == TOKEN_SOCIAL) {
+ bindSocial(cursor);
+ invalidate();
+ }
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
+ }
+ }
+ }
+
+
+ /** {@inheritDoc} */
+ public void onQueryComplete(int token, Object cookie, Cursor cursor) {
+ try{
+ if (token == TOKEN_CONTACT_INFO) {
+ bindContactInfo(cursor);
+ invalidate();
+ } else if (token == TOKEN_SOCIAL) {
+ bindSocial(cursor);
+ invalidate();
+ }
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
+ }
+ }
+
+ /**
+ * Turn on/off showing of the star element.
+ */
+ public void showStar(boolean showStar) {
+ mStarredView.setVisibility(showStar ? View.VISIBLE : View.GONE);
+ }
+
+ /**
+ * Convenience method for binding all available data from an existing
+ * contact.
+ *
+ * @param contactId the contact id of the contact whose info should be displayed.
+ */
+ public void bindFromContactId(long contactId) {
+ mContactId = contactId;
+ mContactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, mContactId);
+ mContactDataUri = Uri.withAppendedPath(mContactUri, Contacts.Data.CONTENT_DIRECTORY);
+ mStatusUri = ContentUris.withAppendedId(
+ SocialContract.Activities.CONTENT_CONTACT_STATUS_URI, mContactId);
+ redrawHeader();
+ }
+
+ /**
+ * Convenience method for binding all available data from an existing
+ * contact.
+ *
+ * @param emailAddress The email address used to do a reverse lookup in
+ * the contacts database. If more than one contact contains this email
+ * address, one of them will be chosen to bind to.
+ */
+ public void bindFromEmail(String emailAddress) {
+ Cursor c = null;
+ try {
+ c = mContentResolver.query(Uri.withAppendedPath(
+ RawContacts.CONTENT_FILTER_EMAIL_URI, Uri.encode(emailAddress)),
+ EMAIL_LOOKUP_PROJECTION, null, null, null);
+ if (c.moveToFirst()) {
+ long contactId = c.getLong(EMAIL_LOOKUP_CONTACT_ID_COLUMN_INDEX);
+ bindFromContactId(contactId);
+ }
+ } finally {
+ if (c != null) {
+ c.close();
+ }
+ }
+ }
+
+ /**
+ * Convenience method for binding all available data from an existing
+ * contact.
+ *
+ * @param number The phone number used to do a reverse lookup in
+ * the contacts database. If more than one contact contains this phone
+ * number, one of them will be chosen to bind to.
+ */
+ public void bindFromPhoneNumber(String number) {
+ Cursor c = null;
+ try {
+ c = mContentResolver.query(Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, number),
+ PHONE_LOOKUP_PROJECTION, null, null, null);
+ if (c.moveToFirst()) {
+ long contactId = c.getLong(PHONE_LOOKUP_CONTACT_ID_COLUMN_INDEX);
+ bindFromContactId(contactId);
+ }
+ } finally {
+ if (c != null) {
+ c.close();
+ }
+ }
+ }
+
+ protected void redrawHeader() {
+ if (mContactDataUri != null) {
+ mQueryHandler.startQuery(TOKEN_CONTACT_INFO, null, mContactDataUri, HEADER_PROJECTION,
+ null, null, null);
+ }
+
+ if (mStatusUri != null) {
+ mQueryHandler.startQuery(TOKEN_SOCIAL, null, mStatusUri, SOCIAL_PROJECTION,
+ null, null, null);
+ }
+ }
+
+ protected void bindContactInfo(Cursor c) {
+ if (c == null) {
+ return;
+ }
+ if (c.moveToFirst()) {
+ //Set name
+ String displayName = c.getString(HEADER_DISPLAY_NAME_COLUMN_INDEX);
+ Log.i(TAG, displayName);
+ mDisplayNameView.setText(displayName);
+ //TODO: Bring back phonetic name
+ /*if (mPhoneticNameView != null) {
+ String phoneticName = c.getString(CONTACT_PHONETIC_NAME_COLUMN);
+ mPhoneticNameView.setText(phoneticName);
+ }*/
+
+ //Set starred
+ mStarredView.setChecked(c.getInt(HEADER_STARRED_COLUMN_INDEX) == 1);
+
+ //Set the photo
+ Bitmap photoBitmap = loadContactPhoto(c.getLong(HEADER_PHOTO_ID_COLUMN_INDEX), null);
+ if (photoBitmap == null) {
+ photoBitmap = loadPlaceholderPhoto(null);
+ }
+ mPhotoView.setImageBitmap(photoBitmap);
+ }
+ }
+
+ protected void bindSocial(Cursor c) {
+ if (c == null) {
+ return;
+ }
+ if (c.moveToFirst()) {
+ String status = c.getString(SOCIAL_TITLE_COLUMN_INDEX);
+ mStatusView.setText(status);
+ }
+ }
+
+ public void onClick(View view) {
+ if (view.getId() == R.id.star) {
+ ContentValues values = new ContentValues(1);
+ values.put(Contacts.STARRED, mStarredView.isChecked());
+ mContentResolver.update(mContactUri, values, null, null);
+ }
+ }
+
+ private Bitmap loadContactPhoto(long photoId, BitmapFactory.Options options) {
+ Cursor photoCursor = null;
+ Bitmap photoBm = null;
+
+ try {
+ photoCursor = mContentResolver.query(
+ ContentUris.withAppendedId(Data.CONTENT_URI, photoId),
+ new String[] { Photo.PHOTO },
+ null, null, null);
+
+ if (photoCursor.moveToFirst() && !photoCursor.isNull(0)) {
+ byte[] photoData = photoCursor.getBlob(0);
+ photoBm = BitmapFactory.decodeByteArray(photoData, 0,
+ photoData.length, options);
+ }
+ } finally {
+ if (photoCursor != null) {
+ photoCursor.close();
+ }
+ }
+
+ return photoBm;
+ }
+
+ private Bitmap loadPlaceholderPhoto(BitmapFactory.Options options) {
+ if (mNoPhotoResource == 0) {
+ return null;
+ }
+ return BitmapFactory.decodeResource(mContext.getResources(),
+ mNoPhotoResource, options);
+ }
+}
diff --git a/core/res/res/drawable/contact_header_bg.9.png b/core/res/res/drawable/contact_header_bg.9.png
new file mode 100644
index 0000000..7f9a5a3
--- /dev/null
+++ b/core/res/res/drawable/contact_header_bg.9.png
Binary files differ
diff --git a/core/res/res/drawable/contact_picture_bg.9.png b/core/res/res/drawable/contact_picture_bg.9.png
new file mode 100644
index 0000000..ae9c709
--- /dev/null
+++ b/core/res/res/drawable/contact_picture_bg.9.png
Binary files differ
diff --git a/core/res/res/drawable/ic_contact_picture_2.png b/core/res/res/drawable/ic_contact_picture_2.png
new file mode 100644
index 0000000..8b184af
--- /dev/null
+++ b/core/res/res/drawable/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/ic_contact_picture_3.png
new file mode 100644
index 0000000..a2d08b5
--- /dev/null
+++ b/core/res/res/drawable/ic_contact_picture_3.png
Binary files differ
diff --git a/core/res/res/layout-ja/contact_header_name.xml b/core/res/res/layout-ja/contact_header_name.xml
new file mode 100644
index 0000000..03332b1
--- /dev/null
+++ b/core/res/res/layout-ja/contact_header_name.xml
@@ -0,0 +1,39 @@
+<?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.
+-->
+
+<!-- In Japanese-language locales, the "Name" field contains two separate
+ TextViews: the name itself, and also the phonetic ("furigana") field. -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="0dip"
+ android:layout_weight="1"
+ android:layout_height="wrap_content">
+
+ <TextView android:id="@+id/name"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceLargeInverse"
+ android:textColor="@android:color/secondary_text_light"
+ />
+
+ <TextView android:id="@+id/phonetic_name"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceSmallInverse"
+ android:textColor="@android:color/secondary_text_light"
+ />
+
+</LinearLayout>
diff --git a/core/res/res/layout/contact_header.xml b/core/res/res/layout/contact_header.xml
new file mode 100644
index 0000000..04b34b8
--- /dev/null
+++ b/core/res/res/layout/contact_header.xml
@@ -0,0 +1,56 @@
+<?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:id="@+id/banner"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:background="@drawable/contact_header_bg"
+ android:paddingRight="5dip"
+ android:gravity="center_vertical">
+
+ <ImageView android:id="@+id/photo"
+ android:layout_width="64dip"
+ android:layout_height="64dip"
+ android:layout_marginRight="7dip"
+ android:layout_marginLeft="2dip"
+ android:scaleType="fitCenter"
+ android:background="@drawable/contact_picture_bg"/>
+
+ <LinearLayout
+ android:layout_width="0dip"
+ android:layout_height="fill_parent"
+ android:layout_weight="1"
+ android:orientation="vertical">
+
+ <!-- "Name" field is locale-specific. -->
+ <include layout="@layout/contact_header_name"/>
+
+ <TextView android:id="@+id/status"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:maxLines="2"/>
+
+ </LinearLayout>
+
+ <CheckBox android:id="@+id/star"
+ style="?android:attr/starStyle"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/core/res/res/layout/contact_header_name.xml b/core/res/res/layout/contact_header_name.xml
new file mode 100644
index 0000000..aec943e
--- /dev/null
+++ b/core/res/res/layout/contact_header_name.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.
+-->
+
+<!-- In the default locale, the "Name" field is a single TextView -->
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/name"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceLargeInverse"
+ android:textColor="@android:color/secondary_text_light"
+ android:maxLines="2"
+ android:ellipsize="end"
+ />
diff --git a/core/res/res/values-ko/donottranslate-cldr.xml b/core/res/res/values-ko/donottranslate-cldr.xml
index 47f8c03..6b792c6 100644
--- a/core/res/res/values-ko/donottranslate-cldr.xml
+++ b/core/res/res/values-ko/donottranslate-cldr.xml
@@ -101,16 +101,16 @@
<string name="numeric_date_template">"%s. %s. %s."</string>
<string name="month_day_year">%Y년 %-m월 %-e일</string>
<string name="time_of_day">%p %-l:%M:%S</string>
- <string name="date_and_time">%Y. %-m. %-e. %p %-l:%M:%S</string>
+ <string name="date_and_time">%Y년 %-m월 %-e일 %p %-l:%M:%S</string>
<string name="date_time">%1$s %2$s</string>
<string name="time_date">%3$s %1$s</string>
- <string name="abbrev_month_day_year">%Y. %-m. %-e.</string>
+ <string name="abbrev_month_day_year">%Y년 %-m월 %-e일</string>
<string name="month_day">%B %-e일</string>
<string name="month">%-B</string>
<string name="month_year">%Y년 %B</string>
- <string name="abbrev_month_day">%-m. %-e.</string>
+ <string name="abbrev_month_day">%-m월 %-e일</string>
<string name="abbrev_month">%-m월</string>
- <string name="abbrev_month_year">%Y. %-m.</string>
+ <string name="abbrev_month_year">%Y년 %-m월</string>
<string name="time1_time2">%1$s ~ %2$s</string>
<string name="date1_date2">%2$s ~ %5$s</string>
<string name="numeric_md1_md2">%2$s. %3$s ~ %7$s. %8$s</string>
diff --git a/graphics/java/android/graphics/Color.java b/graphics/java/android/graphics/Color.java
index 3fc391c..5cefaa3 100644
--- a/graphics/java/android/graphics/Color.java
+++ b/graphics/java/android/graphics/Color.java
@@ -16,6 +16,8 @@
package android.graphics;
+import android.util.MathUtils;
+
import java.util.HashMap;
import java.util.Locale;
@@ -105,6 +107,92 @@
}
/**
+ * Returns the hue component of a color int.
+ *
+ * @return A value between 0.0f and 1.0f
+ *
+ * @hide Pending API council
+ */
+ public static float hue(int color) {
+ int r = (color >> 16) & 0xFF;
+ int g = (color >> 8) & 0xFF;
+ int b = color & 0xFF;
+
+ int V = Math.max(b, Math.max(r, g));
+ int temp = Math.min(b, Math.min(r, g));
+
+ float H;
+
+ if (V == temp) {
+ H = 0;
+ } else {
+ final float vtemp = (float) (V - temp);
+ final float cr = (V - r) / vtemp;
+ final float cg = (V - g) / vtemp;
+ final float cb = (V - b) / vtemp;
+
+ if (r == V) {
+ H = cb - cg;
+ } else if (g == V) {
+ H = 2 + cr - cb;
+ } else {
+ H = 4 + cg - cr;
+ }
+
+ H /= 6.f;
+ if (H < 0) {
+ H++;
+ }
+ }
+
+ return H;
+ }
+
+ /**
+ * Returns the saturation component of a color int.
+ *
+ * @return A value between 0.0f and 1.0f
+ *
+ * @hide Pending API council
+ */
+ public static float saturation(int color) {
+ int r = (color >> 16) & 0xFF;
+ int g = (color >> 8) & 0xFF;
+ int b = color & 0xFF;
+
+
+ int V = Math.max(b, Math.max(r, g));
+ int temp = Math.min(b, Math.min(r, g));
+
+ float S;
+
+ if (V == temp) {
+ S = 0;
+ } else {
+ S = (V - temp) / (float) V;
+ }
+
+ return S;
+ }
+
+ /**
+ * Returns the brightness component of a color int.
+ *
+ * @return A value between 0.0f and 1.0f
+ *
+ * @hide Pending API council
+ */
+ public static float brightness(int color) {
+ int r = (color >> 16) & 0xFF;
+ int g = (color >> 8) & 0xFF;
+ int b = color & 0xFF;
+
+ int V = Math.max(b, Math.max(r, g));
+
+ return (V / 255.f);
+ }
+
+ /**
* Parse the color string, and return the corresponding color-int.
* If the string cannot be parsed, throws an IllegalArgumentException
* exception. Supported formats are:
@@ -134,6 +222,87 @@
}
/**
+ * Convert HSB components to an ARGB color. Alpha set to 0xFF.
+ * hsv[0] is Hue [0 .. 1)
+ * hsv[1] is Saturation [0...1]
+ * hsv[2] is Value [0...1]
+ * If hsv values are out of range, they are pinned.
+ * @param hsb 3 element array which holds the input HSB components.
+ * @return the resulting argb color
+ *
+ * @hide Pending API council
+ */
+ public static int HSBtoColor(float[] hsb) {
+ return HSBtoColor(hsb[0], hsb[1], hsb[2]);
+ }
+
+ /**
+ * Convert HSB components to an ARGB color. Alpha set to 0xFF.
+ * hsv[0] is Hue [0 .. 1)
+ * hsv[1] is Saturation [0...1]
+ * hsv[2] is Value [0...1]
+ * If hsv values are out of range, they are pinned.
+ * @param h Hue component
+ * @param s Saturation component
+ * @param b Brightness component
+ * @return the resulting argb color
+ *
+ * @hide Pending API council
+ */
+ public static int HSBtoColor(float h, float s, float b) {
+ h = MathUtils.constrain(h, 0.0f, 1.0f);
+ s = MathUtils.constrain(s, 0.0f, 1.0f);
+ b = MathUtils.constrain(b, 0.0f, 1.0f);
+
+ float red = 0.0f;
+ float green = 0.0f;
+ float blue = 0.0f;
+
+ final float hf = (h - (int) h) * 6.0f;
+ final int ihf = (int) hf;
+ final float f = hf - ihf;
+ final float pv = b * (1.0f - s);
+ final float qv = b * (1.0f - s * f);
+ final float tv = b * (1.0f - s * (1.0f - f));
+
+ switch (ihf) {
+ case 0: // Red is the dominant color
+ red = b;
+ green = tv;
+ blue = pv;
+ break;
+ case 1: // Green is the dominant color
+ red = qv;
+ green = b;
+ blue = pv;
+ break;
+ case 2:
+ red = pv;
+ green = b;
+ blue = tv;
+ break;
+ case 3: // Blue is the dominant color
+ red = pv;
+ green = qv;
+ blue = b;
+ break;
+ case 4:
+ red = tv;
+ green = pv;
+ blue = b;
+ break;
+ case 5: // Red is the dominant color
+ red = b;
+ green = pv;
+ blue = qv;
+ break;
+ }
+
+ return 0xFF000000 | (((int) (red * 255.0f)) << 16) |
+ (((int) (green * 255.0f)) << 8) | ((int) (blue * 255.0f));
+ }
+
+ /**
* Convert RGB components to HSV.
* hsv[0] is Hue [0 .. 360)
* hsv[1] is Saturation [0...1]
@@ -193,25 +362,24 @@
return nativeHSVToColor(alpha, hsv);
}
- private static native void nativeRGBToHSV(int red, int greed, int blue,
- float hsv[]);
+ private static native void nativeRGBToHSV(int red, int greed, int blue, float hsv[]);
private static native int nativeHSVToColor(int alpha, float hsv[]);
private static final HashMap<String, Integer> sColorNameMap;
static {
- sColorNameMap = new HashMap();
- sColorNameMap.put("black", Integer.valueOf(BLACK));
- sColorNameMap.put("darkgray", Integer.valueOf(DKGRAY));
- sColorNameMap.put("gray", Integer.valueOf(GRAY));
- sColorNameMap.put("lightgray", Integer.valueOf(LTGRAY));
- sColorNameMap.put("white", Integer.valueOf(WHITE));
- sColorNameMap.put("red", Integer.valueOf(RED));
- sColorNameMap.put("green", Integer.valueOf(GREEN));
- sColorNameMap.put("blue", Integer.valueOf(BLUE));
- sColorNameMap.put("yellow", Integer.valueOf(YELLOW));
- sColorNameMap.put("cyan", Integer.valueOf(CYAN));
- sColorNameMap.put("magenta", Integer.valueOf(MAGENTA));
+ sColorNameMap = new HashMap<String, Integer>();
+ sColorNameMap.put("black", BLACK);
+ sColorNameMap.put("darkgray", DKGRAY);
+ sColorNameMap.put("gray", GRAY);
+ sColorNameMap.put("lightgray", LTGRAY);
+ sColorNameMap.put("white", WHITE);
+ sColorNameMap.put("red", RED);
+ sColorNameMap.put("green", GREEN);
+ sColorNameMap.put("blue", BLUE);
+ sColorNameMap.put("yellow", YELLOW);
+ sColorNameMap.put("cyan", CYAN);
+ sColorNameMap.put("magenta", MAGENTA);
}
}
diff --git a/keystore/java/android/security/CertTool.java b/keystore/java/android/security/CertTool.java
index b1b78ea..989432a 100644
--- a/keystore/java/android/security/CertTool.java
+++ b/keystore/java/android/security/CertTool.java
@@ -209,6 +209,10 @@
}
freeX509Certificate(handle);
}
- if (intent != null) context.startActivity(intent);
+ if (intent != null) {
+ context.startActivity(intent);
+ } else {
+ Log.w("CertTool", "incorrect data for addCertificate()");
+ }
}
}
diff --git a/keystore/java/android/security/ServiceCommand.java b/keystore/java/android/security/ServiceCommand.java
index 6178d59..dddf654 100644
--- a/keystore/java/android/security/ServiceCommand.java
+++ b/keystore/java/android/security/ServiceCommand.java
@@ -49,6 +49,8 @@
public static final int BUFFER_LENGTH = 4096;
+ private static final boolean DBG = true;
+
private String mServiceName;
private String mTag;
private InputStream mIn;
@@ -59,7 +61,7 @@
if (mSocket != null) {
return true;
}
- Log.i(mTag, "connecting...");
+ if (DBG) Log.d(mTag, "connecting...");
try {
mSocket = new LocalSocket();
@@ -78,7 +80,7 @@
}
private void disconnect() {
- Log.i(mTag,"disconnecting...");
+ if (DBG) Log.d(mTag,"disconnecting...");
try {
if (mSocket != null) mSocket.close();
} catch (IOException ex) { }
@@ -105,7 +107,7 @@
}
off += count;
} catch (IOException ex) {
- Log.e(mTag,"read exception");
+ Log.e(mTag,"read exception", ex);
break;
}
}
@@ -156,7 +158,7 @@
mOut.write(buf, 0, 8);
mOut.write(data, 0, len);
} catch (IOException ex) {
- Log.e(mTag,"write error");
+ Log.e(mTag,"write error", ex);
disconnect();
return false;
}
diff --git a/libs/rs/java/Grass/res/raw/grass.c b/libs/rs/java/Grass/res/raw/grass.c
index b1b89f0..79cf483 100644
--- a/libs/rs/java/Grass/res/raw/grass.c
+++ b/libs/rs/java/Grass/res/raw/grass.c
@@ -1,21 +1,19 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
+// 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.
+
#pragma version(1)
-#pragma stateVertex(default)
+#pragma stateVertex(PVBackground)
#pragma stateFragment(PFBackground)
#pragma stateFragmentStore(PFSBackground)
@@ -23,7 +21,8 @@
#define WVGA_PORTRAIT_HEIGHT 762.0f
#define RSID_STATE 0
-#define RSID_FRAMECOUNT 0
+#define RSID_FRAME_COUNT 0
+#define RSID_BLADES_COUNT 1
#define RSID_SKY_TEXTURES 1
#define RSID_SKY_TEXTURE_NIGHT 0
@@ -31,6 +30,21 @@
#define RSID_SKY_TEXTURE_NOON 2
#define RSID_SKY_TEXTURE_SUNSET 3
+#define RSID_BLADES 2
+#define BLADE_STRUCT_FIELDS_COUNT 12
+#define BLADE_STRUCT_DEGREE 0
+#define BLADE_STRUCT_SIZE 1
+#define BLADE_STRUCT_XPOS 2
+#define BLADE_STRUCT_YPOS 3
+#define BLADE_STRUCT_OFFSET 4
+#define BLADE_STRUCT_SCALE 5
+#define BLADE_STRUCT_LENGTHX 6
+#define BLADE_STRUCT_LENGTHY 7
+#define BLADE_STRUCT_HARDNESS 8
+#define BLADE_STRUCT_H 9
+#define BLADE_STRUCT_S 10
+#define BLADE_STRUCT_B 11
+
#define MIDNIGHT 0.0f
#define MORNING 0.375f
#define AFTERNOON 0.6f
@@ -38,6 +52,8 @@
#define SECONDS_IN_DAY 24.0f * 3600.0f
+#define PI 3.1415926f
+
#define REAL_TIME 0
float time(int frameCount) {
@@ -51,10 +67,6 @@
color(1.0f, 1.0f, 1.0f, a);
}
-float norm(float a, float start, float end) {
- return (a - start) / (end - start);
-}
-
void drawNight() {
bindTexture(NAMED_PFBackground, 0, loadI32(RSID_SKY_TEXTURES, RSID_SKY_TEXTURE_NIGHT));
// NOTE: Hacky way to draw the night sky
@@ -76,37 +88,111 @@
drawRect(0.0f, 0.0f, WVGA_PORTRAIT_WIDTH, WVGA_PORTRAIT_HEIGHT, 0.0f);
}
+void drawBlade(int index, float now) {
+ float offset = loadF(RSID_BLADES, index + BLADE_STRUCT_OFFSET);
+ float scale = loadF(RSID_BLADES, index + BLADE_STRUCT_SCALE);
+ float degree = loadF(RSID_BLADES, index + BLADE_STRUCT_DEGREE);
+ float hardness = loadF(RSID_BLADES, index + BLADE_STRUCT_HARDNESS);
+
+ float xpos = loadF(RSID_BLADES, index + BLADE_STRUCT_XPOS);
+ float ypos = loadF(RSID_BLADES, index + BLADE_STRUCT_YPOS);
+
+ float lengthX = loadF(RSID_BLADES, index + BLADE_STRUCT_LENGTHX);
+ float lengthY = loadF(RSID_BLADES, index + BLADE_STRUCT_LENGTHY);
+
+ int size = loadF(RSID_BLADES, index + BLADE_STRUCT_SIZE);
+
+ float h = loadF(RSID_BLADES, index + BLADE_STRUCT_H);
+ float s = loadF(RSID_BLADES, index + BLADE_STRUCT_S);
+ float b = loadF(RSID_BLADES, index + BLADE_STRUCT_B);
+
+ float newB = 1.0f;
+ if (now >= MIDNIGHT && now < MORNING) {
+ newB = now / MORNING;
+ }
+
+ if (now >= AFTERNOON && now < DUSK) {
+ newB = 1.0f - normf(AFTERNOON, DUSK, now);
+ }
+
+ if (now >= DUSK) {
+ newB = 0.0f;
+ }
+
+ hsb(h, s, lerpf(0, b, newB), 1.0f);
+
+ float targetDegree = 0.0f; // TODO Compute
+ degree += (targetDegree - degree) * 0.3f;
+
+ float angle = PI / 2.0f;
+
+ float currentX = xpos;
+ float currentY = ypos;
+
+ int i = size;
+
+ for ( ; i > 0; i--) {
+ float nextX = currentX - cosf(angle) * size * lengthX;
+ float nextY = currentY - sinf(angle) * size * lengthY;
+ angle += degree * hardness;
+
+ drawQuad(nextX + (i - 1) * scale, nextY, 0.0f,
+ nextX - (i - 1) * scale, nextY, 0.0f,
+ currentX - i * scale, currentY + 0.7f, 0.0f,
+ currentX + i * scale, currentY + 0.7f, 0.0f);
+
+ currentX = nextX;
+ currentY = nextY;
+ }
+
+ storeF(RSID_BLADES, index + BLADE_STRUCT_DEGREE, degree);
+}
+
+void drawBlades(float now) {
+ bindTexture(NAMED_PFBackground, 0, 0);
+
+ int bladesCount = loadI32(RSID_STATE, RSID_BLADES_COUNT);
+ int count = bladesCount * BLADE_STRUCT_FIELDS_COUNT;
+
+ int i = 0;
+ for ( ; i < count; i += BLADE_STRUCT_FIELDS_COUNT) {
+ drawBlade(i, now);
+ }
+}
+
int main(int launchID) {
- int frameCount = loadI32(RSID_STATE, RSID_FRAMECOUNT);
+ int frameCount = loadI32(RSID_STATE, RSID_FRAME_COUNT);
float now = time(frameCount);
alpha(1.0f);
if (now >= MIDNIGHT && now < MORNING) {
drawNight();
- alpha(norm(now, MIDNIGHT, MORNING));
+ alpha(normf(MIDNIGHT, MORNING, now));
drawSunrise();
}
if (now >= MORNING && now < AFTERNOON) {
drawSunrise();
- alpha(norm(now, MORNING, AFTERNOON));
+ alpha(normf(MORNING, AFTERNOON, now));
drawNoon();
}
if (now >= AFTERNOON && now < DUSK) {
drawNoon();
- alpha(norm(now, AFTERNOON, DUSK));
+ alpha(normf(AFTERNOON, DUSK, now));
drawSunset();
}
if (now >= DUSK) {
- drawSunset();
- alpha(norm(now, DUSK, 1.0f));
drawNight();
+ alpha(1.0f - normf(DUSK, 1.0f, now));
+ drawSunset();
}
+
+ drawBlades(now);
frameCount++;
- storeI32(RSID_STATE, RSID_FRAMECOUNT, frameCount);
+ storeI32(RSID_STATE, RSID_FRAME_COUNT, frameCount);
return 1;
}
diff --git a/libs/rs/java/Grass/src/com/android/grass/rs/GrassRS.java b/libs/rs/java/Grass/src/com/android/grass/rs/GrassRS.java
index 70cb012..435b5ce 100644
--- a/libs/rs/java/Grass/src/com/android/grass/rs/GrassRS.java
+++ b/libs/rs/java/Grass/src/com/android/grass/rs/GrassRS.java
@@ -23,20 +23,45 @@
import static android.renderscript.RenderScript.DepthFunc.*;
import static android.renderscript.RenderScript.BlendSrcFunc;
import static android.renderscript.RenderScript.BlendDstFunc;
-
import android.renderscript.RenderScript;
import android.renderscript.Element;
import android.renderscript.Allocation;
+import android.renderscript.ProgramVertexAlloc;
+import static android.renderscript.Element.*;
+
+import static android.util.MathUtils.*;
import java.util.TimeZone;
class GrassRS {
private static final int RSID_STATE = 0;
+ private static final int RSID_STATE_FRAMECOUNT = 0;
+ private static final int RSID_STATE_BLADES_COUNT = 1;
+
private static final int RSID_SKY_TEXTURES = 1;
private static final int SKY_TEXTURES_COUNT = 4;
-
+
+ private static final int RSID_BLADES = 2;
+ private static final int BLADES_COUNT = 100;
+ private static final int BLADE_STRUCT_FIELDS_COUNT = 12;
+ private static final int BLADE_STRUCT_DEGREE = 0;
+ private static final int BLADE_STRUCT_SIZE = 1;
+ private static final int BLADE_STRUCT_XPOS = 2;
+ private static final int BLADE_STRUCT_YPOS = 3;
+ private static final int BLADE_STRUCT_OFFSET = 4;
+ private static final int BLADE_STRUCT_SCALE = 5;
+ private static final int BLADE_STRUCT_LENGTHX = 6;
+ private static final int BLADE_STRUCT_LENGTHY = 7;
+ private static final int BLADE_STRUCT_HARDNESS = 8;
+ private static final int BLADE_STRUCT_H = 9;
+ private static final int BLADE_STRUCT_S = 10;
+ private static final int BLADE_STRUCT_B = 11;
+
private Resources mResources;
private RenderScript mRS;
+
+ private final int mWidth;
+ private final int mHeight;
@SuppressWarnings({"FieldCanBeLocal"})
private RenderScript.Script mScript;
@@ -46,6 +71,10 @@
private RenderScript.ProgramFragment mPfBackground;
@SuppressWarnings({"FieldCanBeLocal"})
private RenderScript.ProgramFragmentStore mPfsBackground;
+ @SuppressWarnings({"FieldCanBeLocal"})
+ private RenderScript.ProgramVertex mPvBackground;
+ @SuppressWarnings({"FieldCanBeLocal"})
+ private ProgramVertexAlloc mPvOrthoAlloc;
@SuppressWarnings({"FieldCanBeLocal"})
private Allocation mSkyTexturesIDs;
@@ -55,8 +84,12 @@
private int[] mSkyBufferIDs;
@SuppressWarnings({"FieldCanBeLocal"})
private Allocation mState;
+ @SuppressWarnings({"FieldCanBeLocal"})
+ private Allocation mBlades;
- public GrassRS() {
+ public GrassRS(int width, int height) {
+ mWidth = width;
+ mHeight = height;
}
public void init(RenderScript rs, Resources res) {
@@ -82,20 +115,46 @@
loadSkyTextures();
mScript.bindAllocation(mState, RSID_STATE);
mScript.bindAllocation(mSkyTexturesIDs, RSID_SKY_TEXTURES);
+ mScript.bindAllocation(mBlades, RSID_BLADES);
mRS.contextBindRootScript(mScript);
}
private void createScriptStructures() {
- mState = Allocation.createSized(mRS, Element.USER_I32, 1);
- mState.data(new int[1]);
+ final int[] data = new int[2];
+ mState = Allocation.createSized(mRS, USER_I32, data.length);
+ data[RSID_STATE_FRAMECOUNT] = 0;
+ data[RSID_STATE_BLADES_COUNT] = BLADES_COUNT;
+ mState.data(data);
+
+ final float[] blades = new float[BLADES_COUNT * BLADE_STRUCT_FIELDS_COUNT];
+ mBlades = Allocation.createSized(mRS, USER_FLOAT, blades.length);
+ for (int i = 0; i < blades.length; i+= BLADE_STRUCT_FIELDS_COUNT) {
+ createBlade(blades, i);
+ }
+ mBlades.data(blades);
+ }
+
+ private void createBlade(float[] blades, int index) {
+ //noinspection PointlessArithmeticExpression
+ blades[index + BLADE_STRUCT_DEGREE] = 0.0f;
+ blades[index + BLADE_STRUCT_SIZE] = random(4.0f) + 4.0f;
+ blades[index + BLADE_STRUCT_XPOS] = random(mWidth);
+ blades[index + BLADE_STRUCT_YPOS] = mHeight;
+ blades[index + BLADE_STRUCT_OFFSET] = random(0.2f) - 0.1f;
+ blades[index + BLADE_STRUCT_SCALE] = random(0.6f) + 0.2f;
+ blades[index + BLADE_STRUCT_LENGTHX] = random(4.5f) + 3.0f;
+ blades[index + BLADE_STRUCT_LENGTHY] = random(5.5f) + 2.0f;
+ blades[index + BLADE_STRUCT_HARDNESS] = random(1.0f) + 0.2f;
+ blades[index + BLADE_STRUCT_H] = (51.0f + random(5.0f)) / 255.0f;
+ blades[index + BLADE_STRUCT_S] = (200.0f + random(55.0f)) / 255.0f;
+ blades[index + BLADE_STRUCT_B] = (90.0f + random(165.0f)) / 255.0f;
}
private void loadSkyTextures() {
mSkyBufferIDs = new int[SKY_TEXTURES_COUNT];
mSkyTextures = new Allocation[SKY_TEXTURES_COUNT];
- mSkyTexturesIDs = Allocation.createSized(
- mRS, Element.USER_FLOAT, SKY_TEXTURES_COUNT);
+ mSkyTexturesIDs = Allocation.createSized(mRS, USER_FLOAT, SKY_TEXTURES_COUNT);
final Allocation[] textures = mSkyTextures;
textures[0] = loadTexture(R.drawable.night, "night");
@@ -149,5 +208,13 @@
}
private void createProgramVertex() {
+ mPvOrthoAlloc = new ProgramVertexAlloc(mRS);
+ mPvOrthoAlloc.setupOrthoWindow(mWidth, mHeight);
+
+ mRS.programVertexBegin(null, null);
+ mRS.programVertexSetTextureMatrixEnable(true);
+ mPvBackground = mRS.programVertexCreate();
+ mPvBackground.bindAllocation(0, mPvOrthoAlloc.mAlloc);
+ mPvBackground.setName("PVBackground");
}
}
diff --git a/libs/rs/java/Grass/src/com/android/grass/rs/GrassView.java b/libs/rs/java/Grass/src/com/android/grass/rs/GrassView.java
index a641e1e..44d5b08 100644
--- a/libs/rs/java/Grass/src/com/android/grass/rs/GrassView.java
+++ b/libs/rs/java/Grass/src/com/android/grass/rs/GrassView.java
@@ -30,7 +30,7 @@
super.surfaceChanged(holder, format, w, h);
RenderScript RS = createRenderScript();
- GrassRS render = new GrassRS();
+ GrassRS render = new GrassRS(w, h);
render.init(RS, getResources());
}
}
diff --git a/libs/rs/rsScriptC_Lib.cpp b/libs/rs/rsScriptC_Lib.cpp
index 21c9753..e4979ea 100644
--- a/libs/rs/rsScriptC_Lib.cpp
+++ b/libs/rs/rsScriptC_Lib.cpp
@@ -566,6 +566,59 @@
glColor4f(r, g, b, a);
}
+static void SC_hsb(float h, float s, float b, float a)
+{
+ float red = 0.0f;
+ float green = 0.0f;
+ float blue = 0.0f;
+
+ float x = h;
+ float y = s;
+ float z = b;
+
+ float hf = (x - (int) x) * 6.0f;
+ int ihf = (int) hf;
+ float f = hf - ihf;
+ float pv = z * (1.0f - y);
+ float qv = z * (1.0f - y * f);
+ float tv = z * (1.0f - y * (1.0f - f));
+
+ switch (ihf) {
+ case 0: // Red is the dominant color
+ red = z;
+ green = tv;
+ blue = pv;
+ break;
+ case 1: // Green is the dominant color
+ red = qv;
+ green = z;
+ blue = pv;
+ break;
+ case 2:
+ red = pv;
+ green = z;
+ blue = tv;
+ break;
+ case 3: // Blue is the dominant color
+ red = pv;
+ green = qv;
+ blue = z;
+ break;
+ case 4:
+ red = tv;
+ green = pv;
+ blue = z;
+ break;
+ case 5: // Red is the dominant color
+ red = z;
+ green = pv;
+ blue = qv;
+ break;
+ }
+
+ glColor4f(red, green, blue, a);
+}
+
/*
extern "C" void materialDiffuse(float r, float g, float b, float a)
{
@@ -650,7 +703,7 @@
{ "atanf", (void *)&atanf,
"float", "(float)" },
{ "atan2f", (void *)&atan2f,
- "float", "(floatm float)" },
+ "float", "(float, float)" },
{ "fabsf", (void *)&fabsf,
"float", "(float)" },
{ "randf", (void *)&SC_randf,
@@ -772,6 +825,8 @@
"void", "(float, float, float, float)" },
{ "color", (void *)&SC_color,
"void", "(float, float, float, float)" },
+ { "hsb", (void *)&SC_hsb,
+ "void", "(float, float, float, float)" },
{ "uploadToTexture", (void *)&SC_uploadToTexture,
"void", "(int, int)" },
diff --git a/libs/surfaceflinger/LayerBitmap.cpp b/libs/surfaceflinger/LayerBitmap.cpp
index ff49c87..5221fed 100644
--- a/libs/surfaceflinger/LayerBitmap.cpp
+++ b/libs/surfaceflinger/LayerBitmap.cpp
@@ -178,6 +178,7 @@
{
Mutex::Autolock _l(mLock);
surface_info_t* info = mInfo;
+ mBuffer.clear(); // free buffer before allocating a new one
sp<Buffer> buffer = new Buffer(mWidth, mHeight, mFormat, mFlags);
status_t err = buffer->initCheck();
if (LIKELY(err == NO_ERROR)) {
diff --git a/libs/utils/Threads.cpp b/libs/utils/Threads.cpp
index 4036c49..6be372c 100644
--- a/libs/utils/Threads.cpp
+++ b/libs/utils/Threads.cpp
@@ -296,6 +296,19 @@
// XXX: name not used for now
HANDLE hMutex;
+ assert(sizeof(hMutex) == sizeof(mState));
+
+ hMutex = CreateMutex(NULL, FALSE, NULL);
+ mState = (void*) hMutex;
+}
+
+Mutex::Mutex(int type, const char* name)
+{
+ // XXX: type and name not used for now
+ HANDLE hMutex;
+
+ assert(sizeof(hMutex) == sizeof(mState));
+
hMutex = CreateMutex(NULL, FALSE, NULL);
mState = (void*) hMutex;
}
@@ -486,7 +499,11 @@
status_t Condition::waitRelative(Mutex& mutex, nsecs_t reltime)
{
- return wait(mutex, systemTime()+reltime);
+ WinCondition* condState = (WinCondition*) mState;
+ HANDLE hMutex = (HANDLE) mutex.mState;
+ nsecs_t absTime = systemTime()+reltime;
+
+ return ((WinCondition*)mState)->wait(condState, hMutex, &absTime);
}
/*
diff --git a/media/java/android/media/MediaMetadataRetriever.java b/media/java/android/media/MediaMetadataRetriever.java
index 3a49a5f..c6a9ae8 100644
--- a/media/java/android/media/MediaMetadataRetriever.java
+++ b/media/java/android/media/MediaMetadataRetriever.java
@@ -35,6 +35,7 @@
{
static {
System.loadLibrary("media_jni");
+ native_init();
}
// The field below is accessed by native methods
@@ -211,7 +212,8 @@
* allocated internally.
*/
public native void release();
- private native void native_setup();
+ private native void native_setup();
+ private static native void native_init();
private native final void native_finalize();
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index a23f535..a8689f2 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -466,6 +466,7 @@
static {
System.loadLibrary("media_jni");
+ native_init();
}
private final static String TAG = "MediaPlayer";
@@ -1109,6 +1110,7 @@
*/
private native final int native_setMetadataFilter(Parcel request);
+ private static native final void native_init();
private native final void native_setup(Object mediaplayer_this);
private native final void native_finalize();
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index be4b489..46ede7f 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -57,6 +57,7 @@
{
static {
System.loadLibrary("media_jni");
+ native_init();
}
private final static String TAG = "MediaRecorder";
@@ -655,6 +656,8 @@
*/
public native void release();
+ private static native final void native_init();
+
private native final void native_setup(Object mediarecorder_this) throws IllegalStateException;
private native final void native_finalize();
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index d5801f7..71af909 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -99,6 +99,7 @@
{
static {
System.loadLibrary("media_jni");
+ native_init();
}
private final static String TAG = "MediaScanner";
@@ -680,6 +681,26 @@
}
values.put(MediaStore.MediaColumns.TITLE, title);
}
+ String album = values.getAsString(Audio.Media.ALBUM);
+ if (MediaFile.UNKNOWN_STRING.equals(album)) {
+ album = values.getAsString(MediaStore.MediaColumns.DATA);
+ // extract last path segment before file name
+ int lastSlash = album.lastIndexOf('/');
+ if (lastSlash >= 0) {
+ int previousSlash = 0;
+ while (true) {
+ int idx = album.indexOf('/', previousSlash + 1);
+ if (idx < 0 || idx >= lastSlash) {
+ break;
+ }
+ previousSlash = idx;
+ }
+ if (previousSlash != 0) {
+ album = album.substring(previousSlash + 1, lastSlash);
+ values.put(Audio.Media.ALBUM, album);
+ }
+ }
+ }
if (isAudio) {
values.put(Audio.Media.IS_RINGTONE, ringtones);
values.put(Audio.Media.IS_NOTIFICATION, notifications);
@@ -1404,6 +1425,7 @@
public native byte[] extractAlbumArt(FileDescriptor fd);
+ private static native final void native_init();
private native final void native_setup();
private native final void native_finalize();
@Override
diff --git a/media/jni/Android.mk b/media/jni/Android.mk
index 1f37111..49a82e6 100644
--- a/media/jni/Android.mk
+++ b/media/jni/Android.mk
@@ -12,11 +12,9 @@
LOCAL_SHARED_LIBRARIES := \
libopencore_player \
- libopencore_author \
libomx_amrenc_sharedlibrary \
libandroid_runtime \
libnativehelper \
- libcutils \
libutils \
libbinder \
libmedia \
diff --git a/media/jni/android_media_AmrInputStream.cpp b/media/jni/android_media_AmrInputStream.cpp
index 51cb6c7..c4dd07e 100644
--- a/media/jni/android_media_AmrInputStream.cpp
+++ b/media/jni/android_media_AmrInputStream.cpp
@@ -169,13 +169,6 @@
int register_android_media_AmrInputStream(JNIEnv *env)
{
const char* const kClassPathName = "android/media/AmrInputStream";
- jclass clazz;
-
- clazz = env->FindClass(kClassPathName);
- if (clazz == NULL) {
- LOGE("Can't find %s", kClassPathName);
- return -1;
- }
return AndroidRuntime::registerNativeMethods(env,
kClassPathName, gMethods, NELEM(gMethods));
diff --git a/media/jni/android_media_MediaMetadataRetriever.cpp b/media/jni/android_media_MediaMetadataRetriever.cpp
index 4624a18..49f8cdd 100644
--- a/media/jni/android_media_MediaMetadataRetriever.cpp
+++ b/media/jni/android_media_MediaMetadataRetriever.cpp
@@ -40,6 +40,7 @@
static fields_t fields;
static Mutex sLock;
+static const char* const kClassPathName = "android/media/MediaMetadataRetriever";
static void process_media_retriever_call(JNIEnv *env, status_t opStatus, const char* exception, const char *message)
{
@@ -269,6 +270,36 @@
android_media_MediaMetadataRetriever_release(env, thiz);
}
+// This function gets a field ID, which in turn causes class initialization.
+// It is called from a static block in MediaMetadataRetriever, which won't run until the
+// first time an instance of this class is used.
+static void android_media_MediaMetadataRetriever_native_init(JNIEnv *env)
+{
+ jclass clazz = env->FindClass(kClassPathName);
+ if (clazz == NULL) {
+ jniThrowException(env, "java/lang/RuntimeException", "Can't find android/media/MediaMetadataRetriever");
+ return;
+ }
+
+ fields.context = env->GetFieldID(clazz, "mNativeContext", "I");
+ if (fields.context == NULL) {
+ jniThrowException(env, "java/lang/RuntimeException", "Can't find MediaMetadataRetriever.mNativeContext");
+ return;
+ }
+
+ fields.bitmapClazz = env->FindClass("android/graphics/Bitmap");
+ if (fields.bitmapClazz == NULL) {
+ jniThrowException(env, "java/lang/RuntimeException", "Can't find android/graphics/Bitmap");
+ return;
+ }
+
+ fields.bitmapConstructor = env->GetMethodID(fields.bitmapClazz, "<init>", "(IZ[B)V");
+ if (fields.bitmapConstructor == NULL) {
+ jniThrowException(env, "java/lang/RuntimeException", "Can't find Bitmap constructor");
+ return;
+ }
+}
+
static void android_media_MediaMetadataRetriever_native_setup(JNIEnv *env, jobject thiz)
{
LOGV("native_setup");
@@ -292,36 +323,13 @@
{"release", "()V", (void *)android_media_MediaMetadataRetriever_release},
{"native_finalize", "()V", (void *)android_media_MediaMetadataRetriever_native_finalize},
{"native_setup", "()V", (void *)android_media_MediaMetadataRetriever_native_setup},
+ {"native_init", "()V", (void *)android_media_MediaMetadataRetriever_native_init},
};
-// Register native mehtods with Android runtime environment
+// This function only registers the native methods, and is called from
+// JNI_OnLoad in android_media_MediaPlayer.cpp
int register_android_media_MediaMetadataRetriever(JNIEnv *env)
{
- static const char* const kClassPathName = "android/media/MediaMetadataRetriever";
- jclass clazz = env->FindClass(kClassPathName);
- if (clazz == NULL) {
- LOGE("Can't find class: %s", kClassPathName);
- return -1;
- }
-
- fields.context = env->GetFieldID(clazz, "mNativeContext", "I");
- if (fields.context == NULL) {
- LOGE("Can't find MediaMetadataRetriever.mNativeContext");
- return -1;
- }
-
- fields.bitmapClazz = env->FindClass("android/graphics/Bitmap");
- if (fields.bitmapClazz == NULL) {
- LOGE("Bitmap class is not found");
- return -1;
- }
-
- fields.bitmapConstructor = env->GetMethodID(fields.bitmapClazz, "<init>", "(IZ[B)V");
- if (fields.bitmapConstructor == NULL) {
- LOGE("Bitmap constructor is not found");
- return -1;
- }
-
return AndroidRuntime::registerNativeMethods
- (env, kClassPathName, nativeMethods, NELEM(nativeMethods));
+ (env, kClassPathName, nativeMethods, NELEM(nativeMethods));
}
diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp
index d26d039..df98de5 100644
--- a/media/jni/android_media_MediaPlayer.cpp
+++ b/media/jni/android_media_MediaPlayer.cpp
@@ -511,6 +511,51 @@
return media_player->getMetadata(update_only, apply_filter, metadata) == OK;
}
+// This function gets some field IDs, which in turn causes class initialization.
+// It is called from a static block in MediaPlayer, which won't run until the
+// first time an instance of this class is used.
+static void
+android_media_MediaPlayer_native_init(JNIEnv *env)
+{
+ jclass clazz;
+
+ clazz = env->FindClass("android/media/MediaPlayer");
+ if (clazz == NULL) {
+ jniThrowException(env, "java/lang/RuntimeException", "Can't find android/media/MediaPlayer");
+ return;
+ }
+
+ fields.context = env->GetFieldID(clazz, "mNativeContext", "I");
+ if (fields.context == NULL) {
+ jniThrowException(env, "java/lang/RuntimeException", "Can't find MediaPlayer.mNativeContext");
+ return;
+ }
+
+ fields.post_event = env->GetStaticMethodID(clazz, "postEventFromNative",
+ "(Ljava/lang/Object;IIILjava/lang/Object;)V");
+ if (fields.post_event == NULL) {
+ jniThrowException(env, "java/lang/RuntimeException", "Can't find MediaPlayer.postEventFromNative");
+ return;
+ }
+
+ fields.surface = env->GetFieldID(clazz, "mSurface", "Landroid/view/Surface;");
+ if (fields.surface == NULL) {
+ jniThrowException(env, "java/lang/RuntimeException", "Can't find MediaPlayer.mSurface");
+ return;
+ }
+
+ jclass surface = env->FindClass("android/view/Surface");
+ if (surface == NULL) {
+ jniThrowException(env, "java/lang/RuntimeException", "Can't find android/view/Surface");
+ return;
+ }
+
+ fields.surface_native = env->GetFieldID(surface, "mSurface", "I");
+ if (fields.surface_native == NULL) {
+ jniThrowException(env, "java/lang/RuntimeException", "Can't find Surface.mSurface");
+ return;
+ }
+}
static void
android_media_MediaPlayer_native_setup(JNIEnv *env, jobject thiz, jobject weak_this)
@@ -576,53 +621,16 @@
{"native_invoke", "(Landroid/os/Parcel;Landroid/os/Parcel;)I",(void *)android_media_MediaPlayer_invoke},
{"native_setMetadataFilter", "(Landroid/os/Parcel;)I", (void *)android_media_MediaPlayer_setMetadataFilter},
{"native_getMetadata", "(ZZLandroid/os/Parcel;)Z", (void *)android_media_MediaPlayer_getMetadata},
+ {"native_init", "()V", (void *)android_media_MediaPlayer_native_init},
{"native_setup", "(Ljava/lang/Object;)V", (void *)android_media_MediaPlayer_native_setup},
{"native_finalize", "()V", (void *)android_media_MediaPlayer_native_finalize},
};
static const char* const kClassPathName = "android/media/MediaPlayer";
+// This function only registers the native methods
static int register_android_media_MediaPlayer(JNIEnv *env)
{
- jclass clazz;
-
- clazz = env->FindClass("android/media/MediaPlayer");
- if (clazz == NULL) {
- LOGE("Can't find android/media/MediaPlayer");
- return -1;
- }
-
- fields.context = env->GetFieldID(clazz, "mNativeContext", "I");
- if (fields.context == NULL) {
- LOGE("Can't find MediaPlayer.mNativeContext");
- return -1;
- }
-
- fields.post_event = env->GetStaticMethodID(clazz, "postEventFromNative",
- "(Ljava/lang/Object;IIILjava/lang/Object;)V");
- if (fields.post_event == NULL) {
- LOGE("Can't find MediaPlayer.postEventFromNative");
- return -1;
- }
-
- fields.surface = env->GetFieldID(clazz, "mSurface", "Landroid/view/Surface;");
- if (fields.surface == NULL) {
- LOGE("Can't find MediaPlayer.mSurface");
- return -1;
- }
-
- jclass surface = env->FindClass("android/view/Surface");
- if (surface == NULL) {
- LOGE("Can't find android/view/Surface");
- return -1;
- }
-
- fields.surface_native = env->GetFieldID(surface, "mSurface", "I");
- if (fields.surface_native == NULL) {
- LOGE("Can't find Surface fields");
- return -1;
- }
-
return AndroidRuntime::registerNativeMethods(env,
"android/media/MediaPlayer", gMethods, NELEM(gMethods));
}
diff --git a/media/jni/android_media_MediaRecorder.cpp b/media/jni/android_media_MediaRecorder.cpp
index 304f521..cad65b3 100644
--- a/media/jni/android_media_MediaRecorder.cpp
+++ b/media/jni/android_media_MediaRecorder.cpp
@@ -371,6 +371,53 @@
}
}
+// This function gets some field IDs, which in turn causes class initialization.
+// It is called from a static block in MediaRecorder, which won't run until the
+// first time an instance of this class is used.
+static void
+android_media_MediaRecorder_native_init(JNIEnv *env)
+{
+ jclass clazz;
+
+ clazz = env->FindClass("android/media/MediaRecorder");
+ if (clazz == NULL) {
+ jniThrowException(env, "java/lang/RuntimeException", "Can't find android/media/MediaRecorder");
+ return;
+ }
+
+ fields.context = env->GetFieldID(clazz, "mNativeContext", "I");
+ if (fields.context == NULL) {
+ jniThrowException(env, "java/lang/RuntimeException", "Can't find MediaRecorder.mNativeContext");
+ return;
+ }
+
+ fields.surface = env->GetFieldID(clazz, "mSurface", "Landroid/view/Surface;");
+ if (fields.surface == NULL) {
+ jniThrowException(env, "java/lang/RuntimeException", "Can't find MediaRecorder.mSurface");
+ return;
+ }
+
+ jclass surface = env->FindClass("android/view/Surface");
+ if (surface == NULL) {
+ jniThrowException(env, "java/lang/RuntimeException", "Can't find android/view/Surface");
+ return;
+ }
+
+ fields.surface_native = env->GetFieldID(surface, "mSurface", "I");
+ if (fields.surface_native == NULL) {
+ jniThrowException(env, "java/lang/RuntimeException", "Can't find Surface.mSurface");
+ return;
+ }
+
+ fields.post_event = env->GetStaticMethodID(clazz, "postEventFromNative",
+ "(Ljava/lang/Object;IIILjava/lang/Object;)V");
+ if (fields.post_event == NULL) {
+ jniThrowException(env, "java/lang/RuntimeException", "MediaRecorder.postEventFromNative");
+ return;
+ }
+}
+
+
static void
android_media_MediaRecorder_native_setup(JNIEnv *env, jobject thiz, jobject weak_this)
{
@@ -418,55 +465,19 @@
{"getMaxAmplitude", "()I", (void *)android_media_MediaRecorder_native_getMaxAmplitude},
{"start", "()V", (void *)android_media_MediaRecorder_start},
{"stop", "()V", (void *)android_media_MediaRecorder_stop},
- {"native_reset", "()V", (void *)android_media_MediaRecorder_native_reset},
+ {"native_reset", "()V", (void *)android_media_MediaRecorder_native_reset},
{"release", "()V", (void *)android_media_MediaRecorder_release},
+ {"native_init", "()V", (void *)android_media_MediaRecorder_native_init},
{"native_setup", "(Ljava/lang/Object;)V", (void *)android_media_MediaRecorder_native_setup},
{"native_finalize", "()V", (void *)android_media_MediaRecorder_native_finalize},
};
static const char* const kClassPathName = "android/media/MediaRecorder";
+// This function only registers the native methods, and is called from
+// JNI_OnLoad in android_media_MediaPlayer.cpp
int register_android_media_MediaRecorder(JNIEnv *env)
{
- jclass clazz;
-
- clazz = env->FindClass("android/media/MediaRecorder");
- if (clazz == NULL) {
- LOGE("Can't find android/media/MediaRecorder");
- return -1;
- }
-
- fields.context = env->GetFieldID(clazz, "mNativeContext", "I");
- if (fields.context == NULL) {
- LOGE("Can't find MediaRecorder.mNativeContext");
- return -1;
- }
-
- fields.surface = env->GetFieldID(clazz, "mSurface", "Landroid/view/Surface;");
- if (fields.surface == NULL) {
- LOGE("Can't find MediaRecorder.mSurface");
- return -1;
- }
-
- jclass surface = env->FindClass("android/view/Surface");
- if (surface == NULL) {
- LOGE("Can't find android/view/Surface");
- return -1;
- }
-
- fields.surface_native = env->GetFieldID(surface, "mSurface", "I");
- if (fields.surface_native == NULL) {
- LOGE("Can't find Surface fields");
- return -1;
- }
-
- fields.post_event = env->GetStaticMethodID(clazz, "postEventFromNative",
- "(Ljava/lang/Object;IIILjava/lang/Object;)V");
- if (fields.post_event == NULL) {
- LOGE("Can't find MediaRecorder.postEventFromNative");
- return -1;
- }
-
return AndroidRuntime::registerNativeMethods(env,
"android/media/MediaRecorder", gMethods, NELEM(gMethods));
}
diff --git a/media/jni/android_media_MediaScanner.cpp b/media/jni/android_media_MediaScanner.cpp
index 8764a70..97de486 100644
--- a/media/jni/android_media_MediaScanner.cpp
+++ b/media/jni/android_media_MediaScanner.cpp
@@ -241,6 +241,27 @@
return array;
}
+// This function gets a field ID, which in turn causes class initialization.
+// It is called from a static block in MediaScanner, which won't run until the
+// first time an instance of this class is used.
+static void
+android_media_MediaScanner_native_init(JNIEnv *env)
+{
+ jclass clazz;
+
+ clazz = env->FindClass("android/media/MediaScanner");
+ if (clazz == NULL) {
+ jniThrowException(env, "java/lang/RuntimeException", "Can't find android/media/MediaScanner");
+ return;
+ }
+
+ fields.context = env->GetFieldID(clazz, "mNativeContext", "I");
+ if (fields.context == NULL) {
+ jniThrowException(env, "java/lang/RuntimeException", "Can't find MediaScanner.mNativeContext");
+ return;
+ }
+}
+
static void
android_media_MediaScanner_native_setup(JNIEnv *env, jobject thiz)
{
@@ -275,28 +296,17 @@
(void *)android_media_MediaScanner_processFile},
{"setLocale", "(Ljava/lang/String;)V", (void *)android_media_MediaScanner_setLocale},
{"extractAlbumArt", "(Ljava/io/FileDescriptor;)[B", (void *)android_media_MediaScanner_extractAlbumArt},
+ {"native_init", "()V", (void *)android_media_MediaScanner_native_init},
{"native_setup", "()V", (void *)android_media_MediaScanner_native_setup},
{"native_finalize", "()V", (void *)android_media_MediaScanner_native_finalize},
};
static const char* const kClassPathName = "android/media/MediaScanner";
+// This function only registers the native methods, and is called from
+// JNI_OnLoad in android_media_MediaPlayer.cpp
int register_android_media_MediaScanner(JNIEnv *env)
{
- jclass clazz;
-
- clazz = env->FindClass("android/media/MediaScanner");
- if (clazz == NULL) {
- LOGE("Can't find android/media/MediaScanner");
- return -1;
- }
-
- fields.context = env->GetFieldID(clazz, "mNativeContext", "I");
- if (fields.context == NULL) {
- LOGE("Can't find MediaScanner.mNativeContext");
- return -1;
- }
-
return AndroidRuntime::registerNativeMethods(env,
"android/media/MediaScanner", gMethods, NELEM(gMethods));
}
diff --git a/media/jni/android_media_ResampleInputStream.cpp b/media/jni/android_media_ResampleInputStream.cpp
index 0247cdb..f248557 100644
--- a/media/jni/android_media_ResampleInputStream.cpp
+++ b/media/jni/android_media_ResampleInputStream.cpp
@@ -128,13 +128,6 @@
int register_android_media_ResampleInputStream(JNIEnv *env)
{
const char* const kClassPathName = "android/media/ResampleInputStream";
- jclass clazz;
-
- clazz = env->FindClass(kClassPathName);
- if (clazz == NULL) {
- LOGE("Can't find %s", kClassPathName);
- return -1;
- }
return AndroidRuntime::registerNativeMethods(env,
kClassPathName, gMethods, NELEM(gMethods));
diff --git a/packages/TtsService/src/android/tts/TtsService.java b/packages/TtsService/src/android/tts/TtsService.java
index 1b99d32..70960b5 100755
--- a/packages/TtsService/src/android/tts/TtsService.java
+++ b/packages/TtsService/src/android/tts/TtsService.java
@@ -142,6 +142,8 @@
private final ReentrantLock synthesizerLock = new ReentrantLock();
private static SynthProxy sNativeSynth = null;
+ private static Boolean sIsKillingSynth = true;
+
@Override
public void onCreate() {
super.onCreate();
@@ -152,6 +154,7 @@
String soLibPath = "/system/lib/libttspico.so";
if (sNativeSynth == null) {
sNativeSynth = new SynthProxy(soLibPath);
+ sIsKillingSynth = false;
}
mSelf = this;
@@ -172,6 +175,9 @@
@Override
public void onDestroy() {
super.onDestroy();
+
+ sIsKillingSynth = true;
+ Log.i("TtsService", "TtsService.onDestroy()");
// Don't hog the media player
cleanUpPlayer();
@@ -180,6 +186,7 @@
// Unregister all callbacks.
mCallbacks.kill();
+ //Log.i("TtsService", "TtsService.onDestroy() ended");
}
@@ -243,6 +250,9 @@
private int setSpeechRate(String callingApp, int rate) {
+ if (sIsKillingSynth) {
+ return TextToSpeech.ERROR;
+ }
if (isDefaultEnforced()) {
return sNativeSynth.setSpeechRate(getDefaultRate());
} else {
@@ -252,23 +262,37 @@
private int setPitch(String callingApp, int pitch) {
+ if (sIsKillingSynth) {
+ return TextToSpeech.ERROR;
+ }
return sNativeSynth.setPitch(pitch);
}
private int isLanguageAvailable(String lang, String country, String variant) {
+ if (sIsKillingSynth) {
+ return TextToSpeech.LANG_NOT_SUPPORTED;
+ }
//Log.v("TtsService", "TtsService.isLanguageAvailable(" + lang + ", " + country + ", " +variant+")");
return sNativeSynth.isLanguageAvailable(lang, country, variant);
}
private String[] getLanguage() {
+ if (sIsKillingSynth) {
+ Log.v("TtsService", "killing synth:: aborting getLanguage()");
+ return null;
+ }
return sNativeSynth.getLanguage();
}
private int setLanguage(String callingApp, String lang, String country, String variant) {
Log.v("TtsService", "TtsService.setLanguage(" + lang + ", " + country + ", " + variant + ")");
+ if (sIsKillingSynth) {
+ Log.v("TtsService", "killing synth:: aborting setLanguage()");
+ return TextToSpeech.ERROR;
+ }
if (isDefaultEnforced()) {
return sNativeSynth.setLanguage(getDefaultLanguage(), getDefaultCountry(),
getDefaultLocVariant());
@@ -402,7 +426,12 @@
}
if ((mCurrentSpeechItem != null) &&
mCurrentSpeechItem.mCallingApp.equals(callingApp)) {
- result = sNativeSynth.stop();
+ if (sIsKillingSynth) {
+ Log.v("TtsService", "killing synth:: aborting stop()");
+ result = TextToSpeech.ERROR;
+ } else {
+ result = sNativeSynth.stop();
+ }
mKillList.put(mCurrentSpeechItem, true);
if (mPlayer != null) {
try {
@@ -451,7 +480,12 @@
if ((mCurrentSpeechItem != null) &&
((mCurrentSpeechItem.mType != SpeechItem.TEXT_TO_FILE) ||
mCurrentSpeechItem.mCallingApp.equals(callingApp))) {
- result = sNativeSynth.stop();
+ if (sIsKillingSynth) {
+ Log.v("TtsService", "killing synth:: aborting stop()");
+ result = TextToSpeech.ERROR;
+ } else {
+ result = sNativeSynth.stop();
+ }
mKillList.put(mCurrentSpeechItem, true);
if (mPlayer != null) {
try {
@@ -591,7 +625,9 @@
if (speechRate.length() > 0){
setSpeechRate("", Integer.parseInt(speechRate));
}
- sNativeSynth.speak(speechItem.mText, streamType);
+ if (!sIsKillingSynth) {
+ sNativeSynth.speak(speechItem.mText, streamType);
+ }
}
} catch (InterruptedException e) {
Log.e("TtsService", "TTS speakInternalOnly(): tryLock interrupted");
@@ -660,7 +696,9 @@
if (speechRate.length() > 0){
setSpeechRate("", Integer.parseInt(speechRate));
}
- sNativeSynth.synthesizeToFile(speechItem.mText, speechItem.mFilename);
+ if (!sIsKillingSynth) {
+ sNativeSynth.synthesizeToFile(speechItem.mText, speechItem.mFilename);
+ }
}
} catch (InterruptedException e) {
Log.e("TtsService", "TTS synthToFileInternalOnly(): tryLock interrupted");
diff --git a/packages/VpnServices/src/com/android/server/vpn/VpnService.java b/packages/VpnServices/src/com/android/server/vpn/VpnService.java
index b107c7d..f410c7b 100644
--- a/packages/VpnServices/src/com/android/server/vpn/VpnService.java
+++ b/packages/VpnServices/src/com/android/server/vpn/VpnService.java
@@ -147,8 +147,7 @@
synchronized boolean onConnect(String username, String password) {
try {
- mState = VpnState.CONNECTING;
- broadcastConnectivity(VpnState.CONNECTING);
+ setState(VpnState.CONNECTING);
stopPreviouslyRunDaemons();
String serverIp = getIp(getProfile().getServerName());
@@ -166,8 +165,7 @@
synchronized void onDisconnect() {
try {
Log.i(TAG, "disconnecting VPN...");
- mState = VpnState.DISCONNECTING;
- broadcastConnectivity(VpnState.DISCONNECTING);
+ setState(VpnState.DISCONNECTING);
mNotification.showDisconnect();
mDaemonHelper.stopAll();
@@ -235,14 +233,13 @@
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);
+ setState(VpnState.CONNECTED);
enterConnectivityLoop();
}
@@ -261,10 +258,10 @@
restoreOriginalDns();
restoreOriginalDomainSuffices();
- mState = VpnState.IDLE;
- broadcastConnectivity(VpnState.IDLE);
+ setState(VpnState.IDLE);
// stop the service itself
+ SystemProperties.set(VPN_STATUS, VPN_IS_DOWN);
mContext.removeStates();
mContext.stopSelf();
}
@@ -316,6 +313,11 @@
SystemProperties.set(DNS_DOMAIN_SUFFICES, mOriginalDomainSuffices);
}
+ private void setState(VpnState newState) {
+ mState = newState;
+ broadcastConnectivity(newState);
+ }
+
private void broadcastConnectivity(VpnState s) {
VpnManager m = new VpnManager(mContext);
Throwable err = mError;
@@ -326,6 +328,9 @@
} else if (err instanceof VpnConnectingError) {
m.broadcastConnectivity(mProfile.getName(), s,
((VpnConnectingError) err).getErrorCode());
+ } else if (VPN_IS_UP.equals(SystemProperties.get(VPN_STATUS))) {
+ m.broadcastConnectivity(mProfile.getName(), s,
+ VpnManager.VPN_ERROR_CONNECTION_LOST);
} else {
m.broadcastConnectivity(mProfile.getName(), s,
VpnManager.VPN_ERROR_CONNECTION_FAILED);
@@ -373,7 +378,7 @@
// returns false if vpn connectivity is broken
private boolean checkConnectivity() {
if (mDaemonHelper.anyDaemonStopped() || isLocalIpChanged()) {
- onDisconnect();
+ onError(new IOException("Connectivity lost"));
return false;
} else {
return true;
diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java
index a3c3436..447e9fa 100644
--- a/services/java/com/android/server/PowerManagerService.java
+++ b/services/java/com/android/server/PowerManagerService.java
@@ -765,15 +765,17 @@
switch (type)
{
case PowerManager.FULL_WAKE_LOCK:
- return "FULL_WAKE_LOCK ";
+ return "FULL_WAKE_LOCK ";
case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
- return "SCREEN_BRIGHT_WAKE_LOCK";
+ return "SCREEN_BRIGHT_WAKE_LOCK ";
case PowerManager.SCREEN_DIM_WAKE_LOCK:
- return "SCREEN_DIM_WAKE_LOCK ";
+ return "SCREEN_DIM_WAKE_LOCK ";
case PowerManager.PARTIAL_WAKE_LOCK:
- return "PARTIAL_WAKE_LOCK ";
+ return "PARTIAL_WAKE_LOCK ";
+ case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
+ return "PROXIMITY_SCREEN_OFF_WAKE_LOCK";
default:
- return "??? ";
+ return "??? ";
}
}
diff --git a/services/java/com/android/server/status/StatusBarPolicy.java b/services/java/com/android/server/status/StatusBarPolicy.java
index 5aed396..e71d3291 100644
--- a/services/java/com/android/server/status/StatusBarPolicy.java
+++ b/services/java/com/android/server/status/StatusBarPolicy.java
@@ -375,7 +375,8 @@
else if (action.equals(Intent.ACTION_BATTERY_LOW)) {
onBatteryLow(intent);
}
- else if (action.equals(Intent.ACTION_BATTERY_OKAY)) {
+ else if (action.equals(Intent.ACTION_BATTERY_OKAY)
+ || action.equals(Intent.ACTION_POWER_CONNECTED)) {
onBatteryOkay(intent);
}
else if (action.equals(BluetoothIntent.BLUETOOTH_STATE_CHANGED_ACTION) ||
@@ -523,6 +524,7 @@
filter.addAction(Intent.ACTION_BATTERY_CHANGED);
filter.addAction(Intent.ACTION_BATTERY_LOW);
filter.addAction(Intent.ACTION_BATTERY_OKAY);
+ filter.addAction(Intent.ACTION_POWER_CONNECTED);
filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
filter.addAction(Intent.ACTION_ALARM_CHANGED);
filter.addAction(Intent.ACTION_SYNC_STATE_CHANGED);
diff --git a/telephony/java/com/android/internal/telephony/cdma/SignalToneUtil.java b/telephony/java/com/android/internal/telephony/cdma/SignalToneUtil.java
index 44958e9..4b88057 100644
--- a/telephony/java/com/android/internal/telephony/cdma/SignalToneUtil.java
+++ b/telephony/java/com/android/internal/telephony/cdma/SignalToneUtil.java
@@ -35,7 +35,12 @@
static public final int IS95_CONST_IR_ALERT_MED = 0;
static public final int IS95_CONST_IR_ALERT_HIGH = 1;
static public final int IS95_CONST_IR_ALERT_LOW = 2;
- static public final int TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN = 255;
+
+ // Based on 3GPP2 C.S0005-E, seciton 3.7.5.5 Signal,
+ // set TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN to 0 to avoid
+ // the alert pitch to be involved in hash calculation for
+ // signal type other than IS54B.
+ static public final int TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN = 0;
// public final int int IS95_CONST_IR_SIGNAL_TYPE;
static public final int IS95_CONST_IR_SIG_ISDN_NORMAL = 0;
@@ -81,6 +86,15 @@
(alertPitch < 0) || (signal > 256) || (signal < 0)) {
return new Integer(CDMA_INVALID_TONE);
}
+ // Based on 3GPP2 C.S0005-E, seciton 3.7.5.5 Signal,
+ // the alert pitch field is ignored by the mobile station unless
+ // SIGNAL_TYPE is '10',IS-54B Alerting.
+ // Set alert pitch to TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN
+ // so the alert pitch is not involved in hash calculation
+ // when signal type is not IS-54B.
+ if (signalType != IS95_CONST_IR_SIGNAL_IS54B) {
+ alertPitch = TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN;
+ }
return new Integer(signalType * 256 * 256 + alertPitch * 256 + signal);
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java b/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java
index c71003b..d4ec85a 100644
--- a/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java
+++ b/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java
@@ -853,7 +853,7 @@
}
}
- private static String decodeIa5(byte[] data, int offset, int numFields)
+ private static String decode7bitAscii(byte[] data, int offset, int numFields)
throws CodingException
{
try {
@@ -868,38 +868,20 @@
inStream.skip(offset);
for (int i = 0; i < numFields; i++) {
int charCode = inStream.read(7);
- if ((charCode < UserData.IA5_MAP_BASE_INDEX) ||
- (charCode > UserData.IA5_MAP_MAX_INDEX)) {
- throw new CodingException("unsupported AI5 character code (" + charCode + ")");
+ if ((charCode >= UserData.ASCII_MAP_BASE_INDEX) ||
+ (charCode <= UserData.ASCII_MAP_MAX_INDEX)) {
+ strBuf.append(UserData.ASCII_MAP[charCode - UserData.ASCII_MAP_BASE_INDEX]);
+ } else if (charCode == UserData.ASCII_LF_INDEX) {
+ strBuf.append('\r');
+ } else if (charCode == UserData.ASCII_CR_INDEX) {
+ strBuf.append('\n');
+ } else {
+ /* For other charCodes, they are unprintable, and so simply use SPACE. */
+ strBuf.append(' ');
}
- strBuf.append(UserData.IA5_MAP[charCode - UserData.IA5_MAP_BASE_INDEX]);
}
return strBuf.toString();
} catch (BitwiseInputStream.AccessException ex) {
- throw new CodingException("AI5 decode failed: " + ex);
- }
- }
-
- private static String decode7bitAscii(byte[] data, int offset, int numFields)
- throws CodingException
- {
- try {
- offset *= 8;
- BitwiseInputStream inStream = new BitwiseInputStream(data);
- int wantedBits = offset + (numFields * 7);
- if (inStream.available() < wantedBits) {
- throw new CodingException("insufficient data (wanted " + wantedBits +
- " bits, but only have " + inStream.available() + ")");
- }
- inStream.skip(offset);
- byte[] expandedData = new byte[numFields];
- for (int i = 0; i < numFields; i++) {
- expandedData[i] = (byte)inStream.read(7);
- }
- return new String(expandedData, 0, numFields, "US-ASCII");
- } catch (java.io.UnsupportedEncodingException ex) {
- throw new CodingException("7bit ASCII decode failed: " + ex);
- } catch (BitwiseInputStream.AccessException ex) {
throw new CodingException("7bit ASCII decode failed: " + ex);
}
}
@@ -956,12 +938,10 @@
// octet encoded.
userData.payloadStr = decodeLatin(userData.payload, offset, userData.numFields);
break;
+ case UserData.ENCODING_IA5:
case UserData.ENCODING_7BIT_ASCII:
userData.payloadStr = decode7bitAscii(userData.payload, offset, userData.numFields);
break;
- case UserData.ENCODING_IA5:
- userData.payloadStr = decodeIa5(userData.payload, offset, userData.numFields);
- break;
case UserData.ENCODING_UNICODE_16:
userData.payloadStr = decodeUtf16(userData.payload, offset, userData.numFields);
break;
@@ -1003,7 +983,7 @@
try {
StringBuffer strbuf = new StringBuffer(dataLen);
while (inStream.available() >= 6) {
- strbuf.append(UserData.IA5_MAP[inStream.read(6)]);
+ strbuf.append(UserData.ASCII_MAP[inStream.read(6)]);
}
String data = strbuf.toString();
bData.numberOfMessages = Integer.parseInt(data.substring(0, 2));
@@ -1045,7 +1025,7 @@
}
StringBuffer strbuf = new StringBuffer(dataLen);
for (int i = 0; i < numFields; i++) {
- strbuf.append(UserData.IA5_MAP[inStream.read(6)]);
+ strbuf.append(UserData.ASCII_MAP[inStream.read(6)]);
}
bData.userData.payloadStr = strbuf.toString();
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/UserData.java b/telephony/java/com/android/internal/telephony/cdma/sms/UserData.java
index 54c1f80..15cb5e4 100644
--- a/telephony/java/com/android/internal/telephony/cdma/sms/UserData.java
+++ b/telephony/java/com/android/internal/telephony/cdma/sms/UserData.java
@@ -49,19 +49,20 @@
public static final int IS91_MSG_TYPE_SHORT_MESSAGE = 0x85;
/**
- * IA5 data encoding character mappings.
- * (See CCITT Rec. T.50 Tables 1 and 3)
+ * US ASCII character mapping table.
*
- * Note this mapping is the the same as for printable ASCII
- * characters, with a 0x20 offset, meaning that the ASCII SPACE
- * character occurs with code 0x20.
+ * This table contains only the printable ASCII characters, with a
+ * 0x20 offset, meaning that the ASCII SPACE character is at index
+ * 0, with the resulting code of 0x20.
*
- * Note this mapping is also equivalent to that used by the IS-91
- * protocol, except for the latter using only 6 bits, and hence
- * mapping only entries up to the '_' character.
+ * Note this mapping is also equivalent to that used by both the
+ * IS5 and the IS-91 encodings. For the former this is defined
+ * using CCITT Rec. T.50 Tables 1 and 3. For the latter IS 637 B,
+ * Table 4.3.1.4.1-1 -- and note the encoding uses only 6 bits,
+ * and hence only maps entries up to the '_' character.
*
*/
- public static final char[] IA5_MAP = {
+ public static final char[] ASCII_MAP = {
' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?',
'@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
@@ -85,8 +86,8 @@
public static final int ASCII_CR_INDEX = 0x0D;
public static final SparseIntArray charToAscii = new SparseIntArray();
static {
- for (int i = 0; i < IA5_MAP.length; i++) {
- charToAscii.put(IA5_MAP[i], PRINTABLE_ASCII_MIN_INDEX + i);
+ for (int i = 0; i < ASCII_MAP.length; i++) {
+ charToAscii.put(ASCII_MAP[i], PRINTABLE_ASCII_MIN_INDEX + i);
}
charToAscii.put('\r', ASCII_LF_INDEX);
charToAscii.put('\n', ASCII_CR_INDEX);
@@ -113,11 +114,11 @@
}
/**
- * Mapping for IA5 values less than 32 are flow control signals
+ * Mapping for ASCII values less than 32 are flow control signals
* and not used here.
*/
- public static final int IA5_MAP_BASE_INDEX = 0x20;
- public static final int IA5_MAP_MAX_INDEX = IA5_MAP_BASE_INDEX + IA5_MAP.length - 1;
+ public static final int ASCII_MAP_BASE_INDEX = 0x20;
+ public static final int ASCII_MAP_MAX_INDEX = ASCII_MAP_BASE_INDEX + ASCII_MAP.length - 1;
/**
* Contains the data header of the user data
diff --git a/tests/CoreTests/android/core/TestEventHandler.java b/tests/CoreTests/android/core/TestEventHandler.java
index 4cfcade..45f2f69 100644
--- a/tests/CoreTests/android/core/TestEventHandler.java
+++ b/tests/CoreTests/android/core/TestEventHandler.java
@@ -497,7 +497,7 @@
* SSL certificate error callback. Handles SSL error(s) on the way
* up to the user.
*/
- public void handleSslErrorRequest(SslError error) {
+ public boolean handleSslErrorRequest(SslError error) {
int primaryError = error.getPrimaryError();
if (Config.LOGV) {
@@ -527,6 +527,9 @@
if (expectSslErrors == -1) // && expectSslCertificate == certificate?
expects[TEST_SSL_CERTIFICATE_ERROR] = false;
+
+ // return false so that we won't block the thread
+ return false;
}
/**
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTest.java b/tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTest.java
index de39800..71d9758 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTest.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTest.java
@@ -1,5 +1,7 @@
package com.android.dumprendertree;
+import android.app.Activity;
+import android.content.Intent;
import android.os.Handler;
import android.os.Message;
import android.test.ActivityInstrumentationTestCase2;
@@ -33,7 +35,7 @@
}
public void runReliabilityTest() throws Throwable {
- ReliabilityTestActivity activity = getActivity();
+// ReliabilityTestActivity activity = getActivity();
LayoutTestsAutoRunner runner = (LayoutTestsAutoRunner)getInstrumentation();
File testListFile = new File(TEST_LIST_FILE);
@@ -54,6 +56,8 @@
boolean timeoutFlag = false;
long start, elapsed;
+ Intent intent = new Intent(runner.getContext(), ReliabilityTestActivity.class);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//read from BufferedReader instead of populating a list in advance,
//this will avoid excessive memory usage in case of a large list
while((url = listReader.readLine()) != null) {
@@ -63,6 +67,8 @@
start = System.currentTimeMillis();
Log.v(LOGTAG, "Testing URL: " + url);
FsUtils.updateTestStatus(TEST_STATUS_FILE, url);
+ ReliabilityTestActivity activity = (ReliabilityTestActivity)runner.startActivitySync(
+ intent);
activity.reset();
//use message to send new URL to avoid interacting with
//WebView in non-UI thread
@@ -88,12 +94,13 @@
if(runner.mLogtime) {
writeLoadTime(url, activity.getPageLoadTime());
}
+ activity.finish();
System.runFinalization();
System.gc();
System.gc();
}
FsUtils.updateTestStatus(TEST_STATUS_FILE, TEST_DONE);
- activity.finish();
+// activity.finish();
listReader.close();
}
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTestActivity.java b/tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTestActivity.java
index 5ddd0b3..db40daf 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTestActivity.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTestActivity.java
@@ -122,8 +122,9 @@
@Override
protected void onDestroy() {
- Log.v(LOGTAG, "onDestroy, inst=" + Integer.toHexString(hashCode()));
super.onDestroy();
+ Log.v(LOGTAG, "onDestroy, inst=" + Integer.toHexString(hashCode()));
+ webView.destroy();
}
private boolean isPageDone() {
@@ -270,8 +271,7 @@
}
public void run() {
- if (initialStartCount == pageStartCount) {
- //perform cleanup
+ if (initialStartCount == pageStartCount && !isPageDone()) {
handler.removeMessages(MSG_TIMEOUT);
webView.stopLoading();
handler.postDelayed(pageDoneRunner, manualDelay);
diff --git a/vpn/java/android/net/vpn/VpnManager.java b/vpn/java/android/net/vpn/VpnManager.java
index e448e5a..f71bbea 100644
--- a/vpn/java/android/net/vpn/VpnManager.java
+++ b/vpn/java/android/net/vpn/VpnManager.java
@@ -54,6 +54,8 @@
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;
+ /** Error code to indicate an error of losing connectivity. */
+ public static final int VPN_ERROR_CONNECTION_LOST = 6;
private static final int VPN_ERROR_NO_ERROR = 0;
public static final String PROFILES_PATH = "/data/misc/vpn/profiles";