diff options
42 files changed, 852 insertions, 246 deletions
@@ -332,7 +332,13 @@ framework_docs_LOCAL_JAVA_LIBRARIES := \ 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/api/current.xml b/api/current.xml index b0b9ce6..f65b5ce 100644 --- a/api/current.xml +++ b/api/current.xml @@ -186298,6 +186298,211 @@ </parameter> </method> </class> +<class name="ZoomButtonsController" + extends="java.lang.Object" + abstract="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<implements name="android.view.View.OnTouchListener"> +</implements> +<constructor name="ZoomButtonsController" + type="android.widget.ZoomButtonsController" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="ownerView" type="android.view.View"> +</parameter> +</constructor> +<method name="getContainer" + return="android.view.ViewGroup" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</method> +<method name="getZoomControls" + return="android.view.View" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</method> +<method name="isAutoDismissed" + return="boolean" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</method> +<method name="isVisible" + return="boolean" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</method> +<method name="onTouch" + return="boolean" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="v" type="android.view.View"> +</parameter> +<parameter name="event" type="android.view.MotionEvent"> +</parameter> +</method> +<method name="setAutoDismissed" + return="void" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="autoDismiss" type="boolean"> +</parameter> +</method> +<method name="setFocusable" + return="void" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="focusable" type="boolean"> +</parameter> +</method> +<method name="setOnZoomListener" + return="void" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="listener" type="android.widget.ZoomButtonsController.OnZoomListener"> +</parameter> +</method> +<method name="setVisible" + return="void" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="visible" type="boolean"> +</parameter> +</method> +<method name="setZoomInEnabled" + return="void" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="enabled" type="boolean"> +</parameter> +</method> +<method name="setZoomOutEnabled" + return="void" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="enabled" type="boolean"> +</parameter> +</method> +<method name="setZoomSpeed" + return="void" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="speed" type="long"> +</parameter> +</method> +</class> +<interface name="ZoomButtonsController.OnZoomListener" + abstract="true" + static="true" + final="false" + deprecated="not deprecated" + visibility="public" +> +<method name="onVisibilityChanged" + return="void" + abstract="true" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="visible" type="boolean"> +</parameter> +</method> +<method name="onZoom" + return="void" + abstract="true" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="zoomIn" type="boolean"> +</parameter> +</method> +</interface> <class name="ZoomControls" extends="android.widget.LinearLayout" abstract="false" 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 @@ public interface EventHandler { * 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 @@ public class HttpsConnection extends Connection { 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 class LoggingEventHandler implements EventHandler { } } - 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/test/AndroidTestCase.java b/core/java/android/test/AndroidTestCase.java index de0587a..1015506 100644 --- a/core/java/android/test/AndroidTestCase.java +++ b/core/java/android/test/AndroidTestCase.java @@ -30,6 +30,7 @@ import java.lang.reflect.Field; public class AndroidTestCase extends TestCase { protected Context mContext; + private Context mTestContext; @Override protected void setUp() throws Exception { @@ -43,7 +44,7 @@ public class AndroidTestCase extends TestCase { public void testAndroidTestCaseSetupProperly() { assertNotNull("Context is null. setContext should be called before tests are run", - mContext); + mContext); } public void setContext(Context context) { @@ -55,6 +56,25 @@ public class AndroidTestCase extends TestCase { } /** + * Test context can be used to access resources from the test's own package + * as opposed to the resources from the test target package. Access to the + * latter is provided by the context set with the {@link #setContext} + * method. + * + * @hide + */ + public void setTestContext(Context context) { + mTestContext = context; + } + + /** + * @hide + */ + public Context getTestContext() { + return mTestContext; + } + + /** * Asserts that launching a given activity is protected by a particular permission by * attempting to start the activity and validating that a {@link SecurityException} * is thrown that mentions the permission in its error message. @@ -125,9 +145,9 @@ public class AndroidTestCase extends TestCase { * to scrub out any class variables. This protects against memory leaks in the case where a * test case creates a non-static inner class (thus referencing the test case) and gives it to * someone else to hold onto. - * + * * @param testCaseClass The class of the derived TestCase implementation. - * + * * @throws IllegalAccessException */ protected void scrubClass(final Class<?> testCaseClass) diff --git a/core/java/android/webkit/CookieManager.java b/core/java/android/webkit/CookieManager.java index 7b91724..d188a39 100644 --- a/core/java/android/webkit/CookieManager.java +++ b/core/java/android/webkit/CookieManager.java @@ -23,9 +23,12 @@ import android.util.Log; 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,31 @@ public final class CookieManager { } } + private static final CookieComparator COMPARATOR = new CookieComparator(); + + private static final class CookieComparator implements Comparator<Cookie> { + public int compare(Cookie cookie1, Cookie cookie2) { + // According to RFC 2109, multiple cookies are ordered in a way such + // that those with more specific Path attributes precede those with + // less specific. Ordering with respect to other attributes (e.g., + // Domain) is unspecified. + // As Set is not modified if the two objects are same, we do want to + // assign different value for each cookie. + int diff = cookie2.path.length() - cookie1.path.length(); + if (diff == 0) { + diff = cookie2.domain.length() - cookie1.domain.length(); + if (diff == 0) { + diff = cookie2.name.hashCode() - cookie1.name.hashCode(); + if (diff == 0) { + Log.w(LOGTAG, "Found two cookies with the same value." + + "cookie1=" + cookie1 + " , cookie2=" + cookie2); + } + } + } + return diff; + } + } + private CookieManager() { } @@ -401,8 +429,8 @@ public final class CookieManager { 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 +441,26 @@ public final class CookieManager { && (!cookie.secure || secure) && cookie.mode != Cookie.MODE_DELETED) { cookie.lastAcessTime = now; + cookieSet.add(cookie); + } + } - 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); + 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 @@ class LoadListener extends Handler implements EventHandler { 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 @@ class LoadListener extends Handler implements EventHandler { * 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 @@ class LoadListener extends Handler implements EventHandler { " 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 @@ class LoadListener extends Handler implements EventHandler { if (!mCancelled) { mSslError = error; Network.getInstance(mContext).handleSslErrorRequest(this); + } else if (mSslErrorRequestHandle != null) { + mSslErrorRequestHandle.handleSslErrorResponse(true); } + mSslErrorRequestHandle = null; } /** diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java index 2f9e153..7cfe5b5 100644 --- a/core/java/android/webkit/WebViewCore.java +++ b/core/java/android/webkit/WebViewCore.java @@ -1164,6 +1164,7 @@ final class WebViewCore { case SET_JS_FLAGS: nativeSetJsFlags((String)msg.obj); + break; case GEOLOCATION_PERMISSIONS_PROVIDE: GeolocationPermissionsData data = diff --git a/core/java/android/widget/ZoomButtonsController.java b/core/java/android/widget/ZoomButtonsController.java index bae4dad..a41e2e3 100644 --- a/core/java/android/widget/ZoomButtonsController.java +++ b/core/java/android/widget/ZoomButtonsController.java @@ -69,7 +69,6 @@ import android.view.WindowManager.LayoutParams; * {@link #setVisible(boolean) setVisible(false)} from the * {@link View#onDetachedFromWindow}. * - * @hide */ public class ZoomButtonsController implements View.OnTouchListener { diff --git a/core/java/com/android/internal/widget/ContactHeaderWidget.java b/core/java/com/android/internal/widget/ContactHeaderWidget.java index 94d4edc..ccb537a 100644 --- a/core/java/com/android/internal/widget/ContactHeaderWidget.java +++ b/core/java/com/android/internal/widget/ContactHeaderWidget.java @@ -225,9 +225,10 @@ public class ContactHeaderWidget extends FrameLayout implements View.OnClickList c = mContentResolver.query(Uri.withAppendedPath( RawContacts.CONTENT_FILTER_EMAIL_URI, Uri.encode(emailAddress)), EMAIL_LOOKUP_PROJECTION, null, null, null); - c.moveToFirst(); - long contactId = c.getLong(EMAIL_LOOKUP_CONTACT_ID_COLUMN_INDEX); - bindFromContactId(contactId); + if (c.moveToFirst()) { + long contactId = c.getLong(EMAIL_LOOKUP_CONTACT_ID_COLUMN_INDEX); + bindFromContactId(contactId); + } } finally { if (c != null) { c.close(); @@ -248,9 +249,10 @@ public class ContactHeaderWidget extends FrameLayout implements View.OnClickList try { c = mContentResolver.query(Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, number), PHONE_LOOKUP_PROJECTION, null, null, null); - c.moveToFirst(); - long contactId = c.getLong(PHONE_LOOKUP_CONTACT_ID_COLUMN_INDEX); - bindFromContactId(contactId); + if (c.moveToFirst()) { + long contactId = c.getLong(PHONE_LOOKUP_CONTACT_ID_COLUMN_INDEX); + bindFromContactId(contactId); + } } finally { if (c != null) { c.close(); diff --git a/core/jni/android_net_wifi_Wifi.cpp b/core/jni/android_net_wifi_Wifi.cpp index 70b7da1..38f3fda 100644 --- a/core/jni/android_net_wifi_Wifi.cpp +++ b/core/jni/android_net_wifi_Wifi.cpp @@ -324,6 +324,13 @@ static jint android_net_wifi_getRssiHelper(const char *cmd) // number we're interested in. if we're associating, it returns "OK". // beware - <SSID> can contain spaces. if (strcmp(reply, "OK") != 0) { + // beware of trailing spaces + char* end = reply + strlen(reply); + while (end > reply && end[-1] == ' ') { + end--; + } + *end = 0; + char* lastSpace = strrchr(reply, ' '); // lastSpace should be preceded by "rssi" and followed by the value if (lastSpace && !strncmp(lastSpace - 4, "rssi", 4)) { 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/renderscript/Allocation.java b/graphics/java/android/renderscript/Allocation.java index 1327328..3b6571a 100644 --- a/graphics/java/android/renderscript/Allocation.java +++ b/graphics/java/android/renderscript/Allocation.java @@ -90,14 +90,14 @@ public class Allocation extends BaseObj { mRS.nAdapter1DData(mID, d); } - public void subData(int off, int count, int[] d) { - mRS.nAdapter1DSubData(mID, off, count, d); - } - public void data(float[] d) { mRS.nAdapter1DData(mID, d); } + public void subData(int off, int count, int[] d) { + mRS.nAdapter1DSubData(mID, off, count, d); + } + public void subData(int off, int count, float[] d) { mRS.nAdapter1DSubData(mID, off, count, d); } @@ -112,6 +112,46 @@ public class Allocation extends BaseObj { } + public class Adapter2D extends BaseObj { + Adapter2D(int id, RenderScript rs) { + super(rs); + mID = id; + } + + public void destroy() { + mRS.nAdapter2DDestroy(mID); + mID = 0; + } + + public void setConstraint(Dimension dim, int value) { + mRS.nAdapter2DSetConstraint(mID, dim.mID, value); + } + + public void data(int[] d) { + mRS.nAdapter2DData(mID, d); + } + + public void data(float[] d) { + mRS.nAdapter2DData(mID, d); + } + + public void subData(int xoff, int yoff, int w, int h, int[] d) { + mRS.nAdapter2DSubData(mID, xoff, yoff, w, h, d); + } + + public void subData(int xoff, int yoff, int w, int h, float[] d) { + mRS.nAdapter2DSubData(mID, xoff, yoff, w, h, d); + } + } + + public Adapter2D createAdapter2D() { + int id = mRS.nAdapter2DCreate(); + if (id != 0) { + mRS.nAdapter2DBindAllocation(id, mID); + } + return new Adapter2D(id, mRS); + } + // creation diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java index dc87b6a..dd7dd02 100644 --- a/graphics/java/android/renderscript/RenderScript.java +++ b/graphics/java/android/renderscript/RenderScript.java @@ -113,11 +113,20 @@ public class RenderScript { native void nAdapter1DBindAllocation(int ad, int alloc); native void nAdapter1DSetConstraint(int ad, int dim, int value); native void nAdapter1DData(int ad, int[] d); - native void nAdapter1DSubData(int ad, int off, int count, int[] d); native void nAdapter1DData(int ad, float[] d); + native void nAdapter1DSubData(int ad, int off, int count, int[] d); native void nAdapter1DSubData(int ad, int off, int count, float[] d); native int nAdapter1DCreate(); + native void nAdapter2DDestroy(int id); + native void nAdapter2DBindAllocation(int ad, int alloc); + native void nAdapter2DSetConstraint(int ad, int dim, int value); + native void nAdapter2DData(int ad, int[] d); + native void nAdapter2DData(int ad, float[] d); + native void nAdapter2DSubData(int ad, int xoff, int yoff, int w, int h, int[] d); + native void nAdapter2DSubData(int ad, int xoff, int yoff, int w, int h, float[] d); + native int nAdapter2DCreate(); + native void nScriptDestroy(int script); native void nScriptBindAllocation(int vtm, int alloc, int slot); native void nScriptCBegin(); @@ -720,19 +729,6 @@ public class RenderScript { nContextBindProgramVertex(pf.mID); } -/* - RsAdapter2D rsAdapter2DCreate (); - void rsAdapter2DBindAllocation (RsAdapter2D adapt, RsAllocation alloc); - void rsAdapter2DDestroy (RsAdapter2D adapter); - void rsAdapter2DSetConstraint (RsAdapter2D adapter, RsDimension dim, uint32_t value); - void rsAdapter2DData (RsAdapter2D adapter, const void * data); - void rsAdapter2DSubData (RsAdapter2D adapter, uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, const void * data); - void rsSamplerBegin (); - void rsSamplerSet (RsSamplerParam p, RsSamplerValue value); - RsSampler rsSamplerCreate (); - void rsSamplerBind (RsSampler sampler, RsAllocation alloc); -*/ - } diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp index a02abca..f5227a0 100644 --- a/graphics/jni/android_renderscript_RenderScript.cpp +++ b/graphics/jni/android_renderscript_RenderScript.cpp @@ -551,6 +551,86 @@ nAdapter1DCreate(JNIEnv *_env, jobject _this) // ----------------------------------- static void +nAdapter2DDestroy(JNIEnv *_env, jobject _this, jint adapter) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nAdapter2DDestroy, con(%p), adapter(%p)", con, (RsAdapter2D)adapter); + rsAdapter2DDestroy((RsAdapter2D)adapter); +} + +static void +nAdapter2DBindAllocation(JNIEnv *_env, jobject _this, jint adapter, jint alloc) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nAdapter2DBindAllocation, con(%p), adapter(%p), alloc(%p)", con, (RsAdapter2D)adapter, (RsAllocation)alloc); + rsAdapter2DBindAllocation((RsAdapter2D)adapter, (RsAllocation)alloc); +} + +static void +nAdapter2DSetConstraint(JNIEnv *_env, jobject _this, jint adapter, jint dim, jint value) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nAdapter2DSetConstraint, con(%p), adapter(%p), dim(%i), value(%i)", con, (RsAdapter2D)adapter, dim, value); + rsAdapter2DSetConstraint((RsAdapter2D)adapter, (RsDimension)dim, value); +} + +static void +nAdapter2DData_i(JNIEnv *_env, jobject _this, jint adapter, jintArray data) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + jint len = _env->GetArrayLength(data); + LOG_API("nAdapter2DData_i, con(%p), adapter(%p), len(%i)", con, (RsAdapter2D)adapter, len); + jint *ptr = _env->GetIntArrayElements(data, NULL); + rsAdapter2DData((RsAdapter2D)adapter, ptr); + _env->ReleaseIntArrayElements(data, ptr, 0/*JNI_ABORT*/); +} + +static void +nAdapter2DData_f(JNIEnv *_env, jobject _this, jint adapter, jfloatArray data) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + jint len = _env->GetArrayLength(data); + LOG_API("nAdapter2DData_f, con(%p), adapter(%p), len(%i)", con, (RsAdapter2D)adapter, len); + jfloat *ptr = _env->GetFloatArrayElements(data, NULL); + rsAdapter2DData((RsAdapter2D)adapter, ptr); + _env->ReleaseFloatArrayElements(data, ptr, 0/*JNI_ABORT*/); +} + +static void +nAdapter2DSubData_i(JNIEnv *_env, jobject _this, jint adapter, jint xoff, jint yoff, jint w, jint h, jintArray data) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + jint len = _env->GetArrayLength(data); + LOG_API("nAdapter2DSubData_i, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i)", + con, (RsAdapter2D)adapter, xoff, yoff, w, h, len); + jint *ptr = _env->GetIntArrayElements(data, NULL); + rsAdapter2DSubData((RsAdapter2D)adapter, xoff, yoff, w, h, ptr); + _env->ReleaseIntArrayElements(data, ptr, 0/*JNI_ABORT*/); +} + +static void +nAdapter2DSubData_f(JNIEnv *_env, jobject _this, jint adapter, jint xoff, jint yoff, jint w, jint h, jfloatArray data) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + jint len = _env->GetArrayLength(data); + LOG_API("nAdapter2DSubData_f, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i)", + con, (RsAdapter2D)adapter, xoff, yoff, w, h, len); + jfloat *ptr = _env->GetFloatArrayElements(data, NULL); + rsAdapter2DSubData((RsAdapter1D)adapter, xoff, yoff, w, h, ptr); + _env->ReleaseFloatArrayElements(data, ptr, 0/*JNI_ABORT*/); +} + +static jint +nAdapter2DCreate(JNIEnv *_env, jobject _this) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nAdapter2DCreate, con(%p)", con); + return (jint)rsAdapter2DCreate(); +} + +// ----------------------------------- + +static void nScriptDestroy(JNIEnv *_env, jobject _this, jint script) { RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); @@ -1058,11 +1138,20 @@ static JNINativeMethod methods[] = { {"nAdapter1DBindAllocation", "(II)V", (void*)nAdapter1DBindAllocation }, {"nAdapter1DSetConstraint", "(III)V", (void*)nAdapter1DSetConstraint }, {"nAdapter1DData", "(I[I)V", (void*)nAdapter1DData_i }, -{"nAdapter1DSubData", "(III[I)V", (void*)nAdapter1DSubData_i }, {"nAdapter1DData", "(I[F)V", (void*)nAdapter1DData_f }, +{"nAdapter1DSubData", "(III[I)V", (void*)nAdapter1DSubData_i }, {"nAdapter1DSubData", "(III[F)V", (void*)nAdapter1DSubData_f }, {"nAdapter1DCreate", "()I", (void*)nAdapter1DCreate }, +{"nAdapter2DDestroy", "(I)V", (void*)nAdapter2DDestroy }, +{"nAdapter2DBindAllocation", "(II)V", (void*)nAdapter2DBindAllocation }, +{"nAdapter2DSetConstraint", "(III)V", (void*)nAdapter2DSetConstraint }, +{"nAdapter2DData", "(I[I)V", (void*)nAdapter2DData_i }, +{"nAdapter2DData", "(I[F)V", (void*)nAdapter2DData_f }, +{"nAdapter2DSubData", "(IIIII[I)V", (void*)nAdapter2DSubData_i }, +{"nAdapter2DSubData", "(IIIII[F)V", (void*)nAdapter2DSubData_f }, +{"nAdapter2DCreate", "()I", (void*)nAdapter2DCreate }, + {"nScriptDestroy", "(I)V", (void*)nScriptDestroy }, {"nScriptBindAllocation", "(III)V", (void*)nScriptBindAllocation }, {"nScriptCBegin", "()V", (void*)nScriptCBegin }, diff --git a/libs/rs/java/Film/src/com/android/film/FilmRS.java b/libs/rs/java/Film/src/com/android/film/FilmRS.java index 777a7cf..eda7624 100644 --- a/libs/rs/java/Film/src/com/android/film/FilmRS.java +++ b/libs/rs/java/Film/src/com/android/film/FilmRS.java @@ -28,6 +28,7 @@ import android.renderscript.ProgramVertexAlloc; import android.renderscript.RenderScript; import android.renderscript.Element; import android.renderscript.Allocation; +import android.renderscript.Dimension; public class FilmRS { private final int POS_TRANSLATE = 0; @@ -175,7 +176,23 @@ public class FilmRS { mImages[11] = Allocation.createFromBitmapResourceBoxed(mRS, mRes, R.drawable.p12, ie, true); mImages[12] = Allocation.createFromBitmapResourceBoxed(mRS, mRes, R.drawable.p13, ie, true); + int black[] = new int[1024]; for(int ct=0; ct < mImages.length; ct++) { + Allocation.Adapter2D a = mImages[ct].createAdapter2D(); + + int size = 512; + int mip = 0; + while(size >= 2) { + a.subData(0, 0, 2, size, black); + a.subData(size-2, 0, 2, size, black); + a.subData(0, 0, size, 2, black); + a.subData(0, size-2, size, 2, black); + size >>= 1; + mip++; + a.setConstraint(Dimension.LOD, mip); + } + a.destroy(); + mImages[ct].uploadToTexture(1); mBufferIDs[ct] = mImages[ct].getID(); } diff --git a/libs/rs/java/Grass/res/drawable-hdpi/aa.png b/libs/rs/java/Grass/res/drawable-hdpi/aa.png Binary files differnew file mode 100644 index 0000000..34cd891 --- /dev/null +++ b/libs/rs/java/Grass/res/drawable-hdpi/aa.png diff --git a/libs/rs/java/Grass/res/raw/grass.c b/libs/rs/java/Grass/res/raw/grass.c index 79cf483..f6dae81 100644 --- a/libs/rs/java/Grass/res/raw/grass.c +++ b/libs/rs/java/Grass/res/raw/grass.c @@ -24,11 +24,12 @@ #define RSID_FRAME_COUNT 0 #define RSID_BLADES_COUNT 1 -#define RSID_SKY_TEXTURES 1 +#define RSID_TEXTURES 1 #define RSID_SKY_TEXTURE_NIGHT 0 #define RSID_SKY_TEXTURE_SUNRISE 1 #define RSID_SKY_TEXTURE_NOON 2 #define RSID_SKY_TEXTURE_SUNSET 3 +#define RSID_GRASS_TEXTURE 4 #define RSID_BLADES 2 #define BLADE_STRUCT_FIELDS_COUNT 12 @@ -45,6 +46,8 @@ #define BLADE_STRUCT_S 10 #define BLADE_STRUCT_B 11 +#define TESSELATION 4.0f + #define MIDNIGHT 0.0f #define MORNING 0.375f #define AFTERNOON 0.6f @@ -68,23 +71,23 @@ void alpha(float a) { } void drawNight() { - bindTexture(NAMED_PFBackground, 0, loadI32(RSID_SKY_TEXTURES, RSID_SKY_TEXTURE_NIGHT)); + bindTexture(NAMED_PFBackground, 0, loadI32(RSID_TEXTURES, RSID_SKY_TEXTURE_NIGHT)); // NOTE: Hacky way to draw the night sky drawRect(WVGA_PORTRAIT_WIDTH - 512.0f, -32.0f, WVGA_PORTRAIT_WIDTH, 1024.0f - 32.0f, 0.0f); } void drawSunrise() { - bindTexture(NAMED_PFBackground, 0, loadI32(RSID_SKY_TEXTURES, RSID_SKY_TEXTURE_SUNRISE)); + bindTexture(NAMED_PFBackground, 0, loadI32(RSID_TEXTURES, RSID_SKY_TEXTURE_SUNRISE)); drawRect(0.0f, 0.0f, WVGA_PORTRAIT_WIDTH, WVGA_PORTRAIT_HEIGHT, 0.0f); } void drawNoon() { - bindTexture(NAMED_PFBackground, 0, loadI32(RSID_SKY_TEXTURES, RSID_SKY_TEXTURE_NOON)); + bindTexture(NAMED_PFBackground, 0, loadI32(RSID_TEXTURES, RSID_SKY_TEXTURE_NOON)); drawRect(0.0f, 0.0f, WVGA_PORTRAIT_WIDTH, WVGA_PORTRAIT_HEIGHT, 0.0f); } void drawSunset() { - bindTexture(NAMED_PFBackground, 0, loadI32(RSID_SKY_TEXTURES, RSID_SKY_TEXTURE_SUNSET)); + bindTexture(NAMED_PFBackground, 0, loadI32(RSID_TEXTURES, RSID_SKY_TEXTURE_SUNSET)); drawRect(0.0f, 0.0f, WVGA_PORTRAIT_WIDTH, WVGA_PORTRAIT_HEIGHT, 0.0f); } @@ -125,21 +128,25 @@ void drawBlade(int index, float now) { degree += (targetDegree - degree) * 0.3f; float angle = PI / 2.0f; - + float currentX = xpos; float currentY = ypos; - - int i = size; + + int i = size * TESSELATION; + float lx = lengthX / TESSELATION; + float ly = lengthY / TESSELATION; + float ss = 2.0f / i + scale / TESSELATION; + float sh = 0.7f / TESSELATION; for ( ; i > 0; i--) { - float nextX = currentX - cosf(angle) * size * lengthX; - float nextY = currentY - sinf(angle) * size * lengthY; + float nextX = currentX - cosf(angle) * size * lx; + float nextY = currentY - sinf(angle) * size * ly; 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); + drawQuad(nextX + (i - 1) * ss, nextY, 0.0f, + nextX - (i - 1) * ss, nextY, 0.0f, + currentX - i * ss, currentY + sh, 0.0f, + currentX + i * ss, currentY + sh, 0.0f); currentX = nextX; currentY = nextY; @@ -149,7 +156,10 @@ void drawBlade(int index, float now) { } void drawBlades(float now) { - bindTexture(NAMED_PFBackground, 0, 0); + // For anti-aliasing + bindProgramFragmentStore(NAMED_PFSGrass); + bindProgramFragment(NAMED_PFGrass); + bindTexture(NAMED_PFGrass, 0, loadI32(RSID_TEXTURES, RSID_GRASS_TEXTURE)); int bladesCount = loadI32(RSID_STATE, RSID_BLADES_COUNT); int count = bladesCount * BLADE_STRUCT_FIELDS_COUNT; @@ -188,7 +198,7 @@ int main(int launchID) { alpha(1.0f - normf(DUSK, 1.0f, now)); drawSunset(); } - + drawBlades(now); frameCount++; 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 435b5ce..cf7affc 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 @@ -24,12 +24,13 @@ 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 android.graphics.Bitmap; +import android.graphics.BitmapFactory; import java.util.TimeZone; @@ -39,7 +40,7 @@ class GrassRS { 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 SKY_TEXTURES_COUNT = 5; private static final int RSID_BLADES = 2; private static final int BLADES_COUNT = 100; @@ -59,6 +60,7 @@ class GrassRS { private Resources mResources; private RenderScript mRS; + private final BitmapFactory.Options mBitmapOptions = new BitmapFactory.Options(); private final int mWidth; private final int mHeight; @@ -77,19 +79,25 @@ class GrassRS { private ProgramVertexAlloc mPvOrthoAlloc; @SuppressWarnings({"FieldCanBeLocal"}) - private Allocation mSkyTexturesIDs; + private Allocation mTexturesIDs; @SuppressWarnings({"FieldCanBeLocal"}) - private Allocation[] mSkyTextures; + private Allocation[] mTextures; @SuppressWarnings({"FieldCanBeLocal"}) - private int[] mSkyBufferIDs; + private int[] mTextureBufferIDs; @SuppressWarnings({"FieldCanBeLocal"}) private Allocation mState; @SuppressWarnings({"FieldCanBeLocal"}) private Allocation mBlades; + @SuppressWarnings({"FieldCanBeLocal"}) + private RenderScript.ProgramFragment mPfGrass; + @SuppressWarnings({"FieldCanBeLocal"}) + private RenderScript.ProgramFragmentStore mPfsGrass; public GrassRS(int width, int height) { mWidth = width; mHeight = height; + mBitmapOptions.inScaled = false; + mBitmapOptions.inPreferredConfig = Bitmap.Config.ARGB_8888; } public void init(RenderScript rs, Resources res) { @@ -114,7 +122,7 @@ class GrassRS { loadSkyTextures(); mScript.bindAllocation(mState, RSID_STATE); - mScript.bindAllocation(mSkyTexturesIDs, RSID_SKY_TEXTURES); + mScript.bindAllocation(mTexturesIDs, RSID_SKY_TEXTURES); mScript.bindAllocation(mBlades, RSID_BLADES); mRS.contextBindRootScript(mScript); @@ -146,23 +154,24 @@ class GrassRS { 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; + blades[index + BLADE_STRUCT_H] = random(0.02f) + 0.2f; + blades[index + BLADE_STRUCT_S] = random(0.22f) + 0.78f; + blades[index + BLADE_STRUCT_B] = random(0.65f) + 0.35f; } private void loadSkyTextures() { - mSkyBufferIDs = new int[SKY_TEXTURES_COUNT]; - mSkyTextures = new Allocation[SKY_TEXTURES_COUNT]; - mSkyTexturesIDs = Allocation.createSized(mRS, USER_FLOAT, SKY_TEXTURES_COUNT); + mTextureBufferIDs = new int[SKY_TEXTURES_COUNT]; + mTextures = new Allocation[SKY_TEXTURES_COUNT]; + mTexturesIDs = Allocation.createSized(mRS, USER_FLOAT, SKY_TEXTURES_COUNT); - final Allocation[] textures = mSkyTextures; + final Allocation[] textures = mTextures; textures[0] = loadTexture(R.drawable.night, "night"); textures[1] = loadTexture(R.drawable.sunrise, "sunrise"); textures[2] = loadTexture(R.drawable.sky, "sky"); textures[3] = loadTexture(R.drawable.sunset, "sunset"); + textures[4] = loadTextureARGB(R.drawable.aa, "aa"); - final int[] bufferIds = mSkyBufferIDs; + final int[] bufferIds = mTextureBufferIDs; final int count = textures.length; for (int i = 0; i < count; i++) { @@ -171,12 +180,21 @@ class GrassRS { bufferIds[i] = texture.getID(); } - mSkyTexturesIDs.data(bufferIds); + mTexturesIDs.data(bufferIds); } private Allocation loadTexture(int id, String name) { - Allocation allocation = Allocation.createFromBitmapResource(mRS, mResources, id, - Element.RGB_565, false); + final Allocation allocation = Allocation.createFromBitmapResource(mRS, mResources, + id, RGB_565, false); + allocation.setName(name); + return allocation; + } + + private Allocation loadTextureARGB(int id, String name) { + // Forces ARGB 32 bits, because pngcrush sometimes optimize our PNGs to + // indexed pictures, which are not well supported + final Bitmap b = BitmapFactory.decodeResource(mResources, id, mBitmapOptions); + final Allocation allocation = Allocation.createFromBitmap(mRS, b, RGBA_8888, false); allocation.setName(name); return allocation; } @@ -195,6 +213,13 @@ class GrassRS { mPfBackground = mRS.programFragmentCreate(); mPfBackground.setName("PFBackground"); mPfBackground.bindSampler(mSampler, 0); + + mRS.programFragmentBegin(null, null); + mRS.programFragmentSetTexEnable(0, true); + mRS.programFragmentSetTexEnvMode(0, MODULATE); + mPfGrass = mRS.programFragmentCreate(); + mPfGrass.setName("PFGrass"); + mPfGrass.bindSampler(mSampler, 0); } private void createProgramFragmentStore() { @@ -205,6 +230,14 @@ class GrassRS { mRS.programFragmentStoreDepthMask(false); mPfsBackground = mRS.programFragmentStoreCreate(); mPfsBackground.setName("PFSBackground"); + + mRS.programFragmentStoreBegin(null, null); + mRS.programFragmentStoreDepthFunc(ALWAYS); + mRS.programFragmentStoreBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ONE_MINUS_SRC_ALPHA); + mRS.programFragmentStoreDitherEnable(true); + mRS.programFragmentStoreDepthMask(false); + mPfsGrass = mRS.programFragmentStoreCreate(); + mPfsGrass.setName("PFSGrass"); } private void createProgramVertex() { diff --git a/libs/rs/rsAdapter.cpp b/libs/rs/rsAdapter.cpp index 7ac2aed..25f3340 100644 --- a/libs/rs/rsAdapter.cpp +++ b/libs/rs/rsAdapter.cpp @@ -61,8 +61,8 @@ void Adapter1D::subData(uint32_t xoff, uint32_t count, const void *data) void Adapter1D::data(const void *data) { - memcpy(getElement(0), - data, + memcpy(getElement(0), + data, mAllocation.get()->getType()->getSizeBytes()); } @@ -71,7 +71,9 @@ namespace renderscript { RsAdapter1D rsi_Adapter1DCreate(Context *rsc) { - return new Adapter1D(); + Adapter1D *a = new Adapter1D(); + a->incRef(); + return a; } void rsi_Adapter1DDestroy(Context *rsc, RsAdapter1D va) @@ -176,8 +178,8 @@ void Adapter2D::subData(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, co void Adapter2D::data(const void *data) { - memcpy(getElement(0,0), - data, + memcpy(getElement(0,0), + data, mAllocation.get()->getType()->getSizeBytes()); } @@ -188,7 +190,9 @@ namespace renderscript { RsAdapter2D rsi_Adapter2DCreate(Context *rsc) { - return new Adapter2D(); + Adapter2D *a = new Adapter2D(); + a->incRef(); + return a; } void rsi_Adapter2DDestroy(Context *rsc, RsAdapter2D va) 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 @@ sp<Buffer> LayerBitmap::allocate() { 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/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 @@ public class MediaMetadataRetriever { static { System.loadLibrary("media_jni"); + native_init(); } // The field below is accessed by native methods @@ -211,7 +212,8 @@ public class MediaMetadataRetriever * 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 @@ public class MediaPlayer static { System.loadLibrary("media_jni"); + native_init(); } private final static String TAG = "MediaPlayer"; @@ -1109,6 +1110,7 @@ public class MediaPlayer */ 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 @@ public class MediaRecorder { static { System.loadLibrary("media_jni"); + native_init(); } private final static String TAG = "MediaRecorder"; @@ -655,6 +656,8 @@ public class MediaRecorder */ 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 @@ public class MediaScanner { static { System.loadLibrary("media_jni"); + native_init(); } private final static String TAG = "MediaScanner"; @@ -680,6 +681,26 @@ public class MediaScanner } 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 class MediaScanner 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_SRC_FILES:= \ 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 @@ static JNINativeMethod gMethods[] = { 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 @@ struct fields_t { 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 @@ static void android_media_MediaMetadataRetriever_native_finalize(JNIEnv *env, jo 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 @@ static JNINativeMethod nativeMethods[] = { {"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 @@ android_media_MediaPlayer_getMetadata(JNIEnv *env, jobject thiz, jboolean update 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 @@ static JNINativeMethod gMethods[] = { {"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 @@ android_media_MediaRecorder_release(JNIEnv *env, jobject thiz) } } +// 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 @@ static JNINativeMethod gMethods[] = { {"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 @@ done: 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 @@ static JNINativeMethod gMethods[] = { (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 @@ static JNINativeMethod gMethods[] = { 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 @@ public class TtsService extends Service implements OnCompletionListener { 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 @@ public class TtsService extends Service implements OnCompletionListener { String soLibPath = "/system/lib/libttspico.so"; if (sNativeSynth == null) { sNativeSynth = new SynthProxy(soLibPath); + sIsKillingSynth = false; } mSelf = this; @@ -172,6 +175,9 @@ public class TtsService extends Service implements OnCompletionListener { @Override public void onDestroy() { super.onDestroy(); + + sIsKillingSynth = true; + Log.i("TtsService", "TtsService.onDestroy()"); // Don't hog the media player cleanUpPlayer(); @@ -180,6 +186,7 @@ public class TtsService extends Service implements OnCompletionListener { // Unregister all callbacks. mCallbacks.kill(); + //Log.i("TtsService", "TtsService.onDestroy() ended"); } @@ -243,6 +250,9 @@ public class TtsService extends Service implements OnCompletionListener { private int setSpeechRate(String callingApp, int rate) { + if (sIsKillingSynth) { + return TextToSpeech.ERROR; + } if (isDefaultEnforced()) { return sNativeSynth.setSpeechRate(getDefaultRate()); } else { @@ -252,23 +262,37 @@ public class TtsService extends Service implements OnCompletionListener { 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 @@ public class TtsService extends Service implements OnCompletionListener { } 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 @@ public class TtsService extends Service implements OnCompletionListener { 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 @@ public class TtsService extends Service implements OnCompletionListener { 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 @@ public class TtsService extends Service implements OnCompletionListener { 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/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 @@ class PowerManagerService extends IPowerManager.Stub 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..e71d329 100644 --- a/services/java/com/android/server/status/StatusBarPolicy.java +++ b/services/java/com/android/server/status/StatusBarPolicy.java @@ -375,7 +375,8 @@ public class StatusBarPolicy { 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 @@ public class StatusBarPolicy { 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 @@ public class SignalToneUtil { 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 @@ public class SignalToneUtil { (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/test-runner/android/test/AndroidTestRunner.java b/test-runner/android/test/AndroidTestRunner.java index 79cedb0..00440b4 100644 --- a/test-runner/android/test/AndroidTestRunner.java +++ b/test-runner/android/test/AndroidTestRunner.java @@ -158,16 +158,18 @@ public class AndroidTestRunner extends BaseTestRunner { mTestResult.addListener(testListener); } + Context testContext = mInstrumentation.getContext(); for (TestCase testCase : mTestCases) { - setContextIfAndroidTestCase(testCase, mContext); + setContextIfAndroidTestCase(testCase, mContext, testContext); setInstrumentationIfInstrumentationTestCase(testCase, mInstrumentation); testCase.run(mTestResult); } } - private void setContextIfAndroidTestCase(Test test, Context context) { + private void setContextIfAndroidTestCase(Test test, Context context, Context testContext) { if (AndroidTestCase.class.isAssignableFrom(test.getClass())) { ((AndroidTestCase) test).setContext(context); + ((AndroidTestCase) test).setTestContext(testContext); } } diff --git a/test-runner/android/test/TestRunner.java b/test-runner/android/test/TestRunner.java index efa2480..012df35 100644 --- a/test-runner/android/test/TestRunner.java +++ b/test-runner/android/test/TestRunner.java @@ -39,7 +39,7 @@ import com.google.android.collect.Lists; * and you probably will not need to instantiate, extend, or call this * class yourself. See the full {@link android.test} package description * to learn more about testing Android applications. - * + * * {@hide} Not needed for 1.0 SDK. */ public class TestRunner implements PerformanceTestCase.Intermediates { @@ -84,6 +84,7 @@ public class TestRunner implements PerformanceTestCase.Intermediates { super(); } + @Override public void run(TestResult result) { result.addListener(this); super.run(result); @@ -301,7 +302,7 @@ public class TestRunner implements PerformanceTestCase.Intermediates { if (mMode == PERFORMANCE) { runInPerformanceMode(test, className, false, className); } else if (mMode == PROFILING) { - //Need a way to mark a test to be run in profiling mode or not. + //Need a way to mark a test to be run in profiling mode or not. startProfiling(); test.run(); finishProfiling(); @@ -337,6 +338,7 @@ public class TestRunner implements PerformanceTestCase.Intermediates { AndroidTestCase testcase = (AndroidTestCase) test; try { testcase.setContext(mContext); + testcase.setTestContext(mContext); } catch (Exception ex) { Log.i("TestHarness", ex.toString()); } @@ -700,7 +702,7 @@ public class TestRunner implements PerformanceTestCase.Intermediates { } } catch (ClassNotFoundException e) { return 1; // this gets the count right, because either this test - // is missing, and it will fail when run or it is a single Junit test to be run. + // is missing, and it will fail when run or it is a single Junit test to be run. } return 0; } 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 @@ public class TestEventHandler implements EventHandler { * 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 @@ public class TestEventHandler implements EventHandler { 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 class ReliabilityTest extends ActivityInstrumentationTestCase2<Reliabilit } 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 @@ public class ReliabilityTest extends ActivityInstrumentationTestCase2<Reliabilit 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 @@ public class ReliabilityTest extends ActivityInstrumentationTestCase2<Reliabilit 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 @@ public class ReliabilityTest extends ActivityInstrumentationTestCase2<Reliabilit 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 @@ public class ReliabilityTestActivity extends Activity { @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 class ReliabilityTestActivity extends Activity { } public void run() { - if (initialStartCount == pageStartCount) { - //perform cleanup + if (initialStartCount == pageStartCount && !isPageDone()) { handler.removeMessages(MSG_TIMEOUT); webView.stopLoading(); handler.postDelayed(pageDoneRunner, manualDelay); |
