diff options
109 files changed, 2442 insertions, 943 deletions
diff --git a/api/11.xml b/api/11.xml index 34a7a5c41ec2..1ac57a16d1fc 100644 --- a/api/11.xml +++ b/api/11.xml @@ -4250,6 +4250,17 @@ visibility="public" > </field> +<field name="fastScrollTextColor" + type="int" + transient="false" + volatile="false" + value="16843611" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> <field name="fastScrollThumbDrawable" type="int" transient="false" @@ -5812,6 +5823,17 @@ visibility="public" > </field> +<field name="largeHeap" + type="int" + transient="false" + volatile="false" + value="16843612" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> <field name="largeScreens" type="int" transient="false" @@ -11462,6 +11484,28 @@ visibility="public" > </field> +<field name="notification_large_icon_height" + type="int" + transient="false" + volatile="false" + value="17104902" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="notification_large_icon_width" + type="int" + transient="false" + volatile="false" + value="17104901" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> <field name="thumbnail_height" type="int" transient="false" @@ -20082,42 +20126,6 @@ </parameter> </method> </class> -<class name="DoubleEvaluator" - extends="java.lang.Object" - abstract="false" - static="false" - final="false" - deprecated="not deprecated" - visibility="public" -> -<implements name="android.animation.TypeEvaluator"> -</implements> -<constructor name="DoubleEvaluator" - type="android.animation.DoubleEvaluator" - static="false" - final="false" - deprecated="not deprecated" - visibility="public" -> -</constructor> -<method name="evaluate" - return="java.lang.Object" - abstract="false" - native="false" - synchronized="false" - static="false" - final="false" - deprecated="not deprecated" - visibility="public" -> -<parameter name="fraction" type="float"> -</parameter> -<parameter name="startValue" type="java.lang.Object"> -</parameter> -<parameter name="endValue" type="java.lang.Object"> -</parameter> -</method> -</class> <class name="FloatEvaluator" extends="java.lang.Object" abstract="false" @@ -25150,17 +25158,6 @@ visibility="public" > </field> -<field name="TASKS_GET_THUMBNAILS" - type="int" - transient="false" - volatile="false" - value="4096" - static="true" - final="true" - deprecated="not deprecated" - visibility="public" -> -</field> </class> <class name="ActivityManager.MemoryInfo" extends="java.lang.Object" @@ -25559,16 +25556,6 @@ visibility="public" > </field> -<field name="thumbnail" - type="android.graphics.Bitmap" - transient="false" - volatile="false" - static="false" - final="false" - deprecated="not deprecated" - visibility="public" -> -</field> </class> <class name="ActivityManager.RunningAppProcessInfo" extends="java.lang.Object" @@ -38983,6 +38970,17 @@ visibility="public" > </method> +<method name="clearViews" + return="void" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="protected" +> +</method> <method name="createView" return="android.appwidget.AppWidgetHostView" abstract="false" @@ -48155,6 +48153,17 @@ visibility="public" > </method> +<method name="getObbDir" + return="java.io.File" + abstract="true" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</method> <method name="getPackageCodePath" return="java.lang.String" abstract="true" @@ -49763,6 +49772,17 @@ visibility="public" > </method> +<method name="getObbDir" + return="java.io.File" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</method> <method name="getPackageCodePath" return="java.lang.String" abstract="false" @@ -58246,6 +58266,17 @@ visibility="public" > </field> +<field name="FLAG_LARGE_HEAP" + type="int" + transient="false" + volatile="false" + value="1048576" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> <field name="FLAG_PERSISTENT" type="int" transient="false" @@ -60256,6 +60287,19 @@ <exception name="PackageManager.NameNotFoundException" type="android.content.pm.PackageManager.NameNotFoundException"> </exception> </method> +<method name="getPackageObbPaths" + return="java.lang.String[]" + abstract="true" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="packageName" type="java.lang.String"> +</parameter> +</method> <method name="getPackagesForUid" return="java.lang.String[]" abstract="true" @@ -60742,6 +60786,21 @@ <parameter name="installerPackageName" type="java.lang.String"> </parameter> </method> +<method name="setPackageObbPaths" + return="void" + abstract="true" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="packageName" type="java.lang.String"> +</parameter> +<parameter name="paths" type="java.lang.String[]"> +</parameter> +</method> <field name="COMPONENT_ENABLED_STATE_DEFAULT" type="int" transient="false" @@ -137482,6 +137541,34 @@ <parameter name="params" type="Params..."> </parameter> </method> +<method name="execute" + return="void" + abstract="false" + native="false" + synchronized="false" + static="true" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="runnable" type="java.lang.Runnable"> +</parameter> +</method> +<method name="executeOnExecutor" + return="android.os.AsyncTask<Params, Progress, Result>" + abstract="false" + native="false" + synchronized="false" + static="false" + final="true" + deprecated="not deprecated" + visibility="public" +> +<parameter name="exec" type="java.util.concurrent.Executor"> +</parameter> +<parameter name="params" type="Params..."> +</parameter> +</method> <method name="get" return="Result" abstract="false" @@ -137614,6 +137701,16 @@ <parameter name="values" type="Progress..."> </parameter> </method> +<field name="THREAD_POOL_EXECUTOR" + type="java.util.concurrent.ThreadPoolExecutor" + transient="false" + volatile="false" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> </class> <class name="AsyncTask.Status" extends="java.lang.Enum" @@ -185207,6 +185304,19 @@ <exception name="PackageManager.NameNotFoundException" type="android.content.pm.PackageManager.NameNotFoundException"> </exception> </method> +<method name="getPackageObbPaths" + return="java.lang.String[]" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="packageName" type="java.lang.String"> +</parameter> +</method> <method name="getPackagesForUid" return="java.lang.String[]" abstract="false" @@ -185706,6 +185816,21 @@ <parameter name="path" type="java.lang.String"> </parameter> </method> +<method name="setPackageObbPaths" + return="void" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="packageName" type="java.lang.String"> +</parameter> +<parameter name="paths" type="java.lang.String[]"> +</parameter> +</method> </class> <class name="MockResources" extends="android.content.res.Resources" @@ -238120,6 +238245,34 @@ > </field> </class> +<class name="WebViewFragment" + extends="android.app.Fragment" + abstract="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<constructor name="WebViewFragment" + type="android.webkit.WebViewFragment" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</constructor> +<method name="getWebView" + return="android.webkit.WebView" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</method> +</class> </package> <package name="android.widget" > diff --git a/api/current.xml b/api/current.xml index 5866d1fbcf33..6b7907472981 100644 --- a/api/current.xml +++ b/api/current.xml @@ -5823,6 +5823,17 @@ visibility="public" > </field> +<field name="largeHeap" + type="int" + transient="false" + volatile="false" + value="16843612" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> <field name="largeScreens" type="int" transient="false" @@ -20115,42 +20126,6 @@ </parameter> </method> </class> -<class name="DoubleEvaluator" - extends="java.lang.Object" - abstract="false" - static="false" - final="false" - deprecated="not deprecated" - visibility="public" -> -<implements name="android.animation.TypeEvaluator"> -</implements> -<constructor name="DoubleEvaluator" - type="android.animation.DoubleEvaluator" - static="false" - final="false" - deprecated="not deprecated" - visibility="public" -> -</constructor> -<method name="evaluate" - return="java.lang.Object" - abstract="false" - native="false" - synchronized="false" - static="false" - final="false" - deprecated="not deprecated" - visibility="public" -> -<parameter name="fraction" type="float"> -</parameter> -<parameter name="startValue" type="java.lang.Object"> -</parameter> -<parameter name="endValue" type="java.lang.Object"> -</parameter> -</method> -</class> <class name="FloatEvaluator" extends="java.lang.Object" abstract="false" @@ -25183,17 +25158,6 @@ visibility="public" > </field> -<field name="TASKS_GET_THUMBNAILS" - type="int" - transient="false" - volatile="false" - value="4096" - static="true" - final="true" - deprecated="not deprecated" - visibility="public" -> -</field> </class> <class name="ActivityManager.MemoryInfo" extends="java.lang.Object" @@ -25592,16 +25556,6 @@ visibility="public" > </field> -<field name="thumbnail" - type="android.graphics.Bitmap" - transient="false" - volatile="false" - static="false" - final="false" - deprecated="not deprecated" - visibility="public" -> -</field> </class> <class name="ActivityManager.RunningAppProcessInfo" extends="java.lang.Object" @@ -48199,6 +48153,17 @@ visibility="public" > </method> +<method name="getObbDir" + return="java.io.File" + abstract="true" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</method> <method name="getPackageCodePath" return="java.lang.String" abstract="true" @@ -49807,6 +49772,17 @@ visibility="public" > </method> +<method name="getObbDir" + return="java.io.File" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</method> <method name="getPackageCodePath" return="java.lang.String" abstract="false" @@ -58290,6 +58266,17 @@ visibility="public" > </field> +<field name="FLAG_LARGE_HEAP" + type="int" + transient="false" + volatile="false" + value="1048576" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> <field name="FLAG_PERSISTENT" type="int" transient="false" @@ -61575,6 +61562,36 @@ visibility="public" > </field> +<field name="externalCacheSize" + type="long" + transient="false" + volatile="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="externalDataSize" + type="long" + transient="false" + volatile="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="externalMediaSize" + type="long" + transient="false" + volatile="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</field> <field name="packageName" type="java.lang.String" transient="false" @@ -95590,6 +95607,17 @@ visibility="public" > </field> +<field name="TOUCHABLE_INSETS_REGION" + type="int" + transient="false" + volatile="false" + value="3" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> <field name="TOUCHABLE_INSETS_VISIBLE" type="int" transient="false" @@ -95621,6 +95649,16 @@ visibility="public" > </field> +<field name="touchableRegion" + type="android.graphics.Region" + transient="false" + volatile="false" + static="false" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> <field name="visibleTopInsets" type="int" transient="false" @@ -137554,6 +137592,34 @@ <parameter name="params" type="Params..."> </parameter> </method> +<method name="execute" + return="void" + abstract="false" + native="false" + synchronized="false" + static="true" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="runnable" type="java.lang.Runnable"> +</parameter> +</method> +<method name="executeOnExecutor" + return="android.os.AsyncTask<Params, Progress, Result>" + abstract="false" + native="false" + synchronized="false" + static="false" + final="true" + deprecated="not deprecated" + visibility="public" +> +<parameter name="exec" type="java.util.concurrent.Executor"> +</parameter> +<parameter name="params" type="Params..."> +</parameter> +</method> <method name="get" return="Result" abstract="false" @@ -137686,6 +137752,16 @@ <parameter name="values" type="Progress..."> </parameter> </method> +<field name="THREAD_POOL_EXECUTOR" + type="java.util.concurrent.ThreadPoolExecutor" + transient="false" + volatile="false" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> </class> <class name="AsyncTask.Status" extends="java.lang.Enum" @@ -167331,6 +167407,38 @@ <parameter name="dimX" type="int"> </parameter> </method> +<method name="setFromFieldPacker" + return="void" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="xoff" type="int"> +</parameter> +<parameter name="fp" type="android.renderscript.FieldPacker"> +</parameter> +</method> +<method name="setFromFieldPacker" + return="void" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="xoff" type="int"> +</parameter> +<parameter name="component_number" type="int"> +</parameter> +<parameter name="fp" type="android.renderscript.FieldPacker"> +</parameter> +</method> <method name="syncAll" return="void" abstract="false" @@ -173091,6 +173199,49 @@ deprecated="not deprecated" visibility="public" > +<method name="bindAllocation" + return="void" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="va" type="android.renderscript.Allocation"> +</parameter> +<parameter name="slot" type="int"> +</parameter> +</method> +<method name="invoke" + return="void" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="protected" +> +<parameter name="slot" type="int"> +</parameter> +</method> +<method name="invoke" + return="void" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="protected" +> +<parameter name="slot" type="int"> +</parameter> +<parameter name="v" type="android.renderscript.FieldPacker"> +</parameter> +</method> <method name="setTimeZone" return="void" abstract="false" @@ -173104,6 +173255,111 @@ <parameter name="timeZone" type="java.lang.String"> </parameter> </method> +<method name="setVar" + return="void" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="index" type="int"> +</parameter> +<parameter name="v" type="float"> +</parameter> +</method> +<method name="setVar" + return="void" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="index" type="int"> +</parameter> +<parameter name="v" type="double"> +</parameter> +</method> +<method name="setVar" + return="void" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="index" type="int"> +</parameter> +<parameter name="v" type="int"> +</parameter> +</method> +<method name="setVar" + return="void" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="index" type="int"> +</parameter> +<parameter name="v" type="long"> +</parameter> +</method> +<method name="setVar" + return="void" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="index" type="int"> +</parameter> +<parameter name="v" type="boolean"> +</parameter> +</method> +<method name="setVar" + return="void" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="index" type="int"> +</parameter> +<parameter name="o" type="android.renderscript.BaseObj"> +</parameter> +</method> +<method name="setVar" + return="void" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="index" type="int"> +</parameter> +<parameter name="v" type="android.renderscript.FieldPacker"> +</parameter> +</method> </class> <class name="Script.Builder" extends="java.lang.Object" @@ -173235,6 +173491,32 @@ deprecated="not deprecated" visibility="public" > +<constructor name="ScriptC" + type="android.renderscript.ScriptC" + static="false" + final="false" + deprecated="not deprecated" + visibility="protected" +> +<parameter name="id" type="int"> +</parameter> +<parameter name="rs" type="android.renderscript.RenderScript"> +</parameter> +</constructor> +<constructor name="ScriptC" + type="android.renderscript.ScriptC" + static="false" + final="false" + deprecated="not deprecated" + visibility="protected" +> +<parameter name="rs" type="android.renderscript.RenderScript"> +</parameter> +<parameter name="resources" type="android.content.res.Resources"> +</parameter> +<parameter name="resourceID" type="int"> +</parameter> +</constructor> </class> <class name="Short2" extends="java.lang.Object" diff --git a/core/java/android/animation/DoubleEvaluator.java b/core/java/android/animation/DoubleEvaluator.java deleted file mode 100644 index e46eb372e554..000000000000 --- a/core/java/android/animation/DoubleEvaluator.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2010 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.animation; - -/** - * This evaluator can be used to perform type interpolation between <code>double</code> values. - */ -public class DoubleEvaluator implements TypeEvaluator { - /** - * This function returns the result of linearly interpolating the start and end values, with - * <code>fraction</code> representing the proportion between the start and end values. The - * calculation is a simple parametric calculation: <code>result = x0 + t * (v1 - v0)</code>, - * where <code>x0</code> is <code>startValue</code>, <code>x1</code> is <code>endValue</code>, - * and <code>t</code> is <code>fraction</code>. - * - * @param fraction The fraction from the starting to the ending values - * @param startValue The start value; should be of type <code>double</code> or - * <code>Double</code> - * @param endValue The end value; should be of type <code>double</code> or - * <code>Double</code> - * @return A linear interpolation between the start and end values, given the - * <code>fraction</code> parameter. - */ - public Object evaluate(float fraction, Object startValue, Object endValue) { - double startDouble = ((Number) startValue).doubleValue(); - return startDouble + fraction * (((Number) endValue).doubleValue() - startDouble); - } -}
\ No newline at end of file diff --git a/core/java/android/animation/FloatKeyframeSet.java b/core/java/android/animation/FloatKeyframeSet.java index 6fad4a68e18b..4009f139db73 100644 --- a/core/java/android/animation/FloatKeyframeSet.java +++ b/core/java/android/animation/FloatKeyframeSet.java @@ -25,8 +25,8 @@ import java.util.ArrayList; * values between those keyframes for a given animation. The class internal to the animation * package because it is an implementation detail of how Keyframes are stored and used. * - * <p>This type-specific subclass of KeyframeSet, along with the other type-specific subclasses for - * int, long, and double, exists to speed up the getValue() method when there is no custom + * <p>This type-specific subclass of KeyframeSet, along with the other type-specific subclass for + * int, exists to speed up the getValue() method when there is no custom * TypeEvaluator set for the animation, so that values can be calculated without autoboxing to the * Object equivalents of these primitive types.</p> */ diff --git a/core/java/android/animation/IntKeyframeSet.java b/core/java/android/animation/IntKeyframeSet.java index 14a4e3aacc24..5629c5ef9783 100644 --- a/core/java/android/animation/IntKeyframeSet.java +++ b/core/java/android/animation/IntKeyframeSet.java @@ -25,8 +25,8 @@ import java.util.ArrayList; * values between those keyframes for a given animation. The class internal to the animation * package because it is an implementation detail of how Keyframes are stored and used. * - * <p>This type-specific subclass of KeyframeSet, along with the other type-specific subclasses for - * float, long, and double, exists to speed up the getValue() method when there is no custom + * <p>This type-specific subclass of KeyframeSet, along with the other type-specific subclass for + * float, exists to speed up the getValue() method when there is no custom * TypeEvaluator set for the animation, so that values can be calculated without autoboxing to the * Object equivalents of these primitive types.</p> */ diff --git a/core/java/android/animation/ObjectAnimator.java b/core/java/android/animation/ObjectAnimator.java index 3212cba76bbb..d038cd6d1a97 100644 --- a/core/java/android/animation/ObjectAnimator.java +++ b/core/java/android/animation/ObjectAnimator.java @@ -18,7 +18,6 @@ package android.animation; import android.util.Log; -import java.lang.ref.WeakReference; import java.lang.reflect.Method; import java.util.ArrayList; @@ -29,8 +28,6 @@ import java.util.ArrayList; * are then determined internally and the animation will call these functions as necessary to * animate the property. * - * <p class="note"><b>Note:</b> Instances of this class hold only a {@link WeakReference} - * to the target object.</p> * @see #setPropertyName(String) * */ @@ -38,7 +35,7 @@ public final class ObjectAnimator extends ValueAnimator { private static final boolean DBG = false; // The target object on which the property exists, set in the constructor - private WeakReference<Object> mTargetRef; + private Object mTarget; private String mPropertyName; @@ -105,9 +102,6 @@ public final class ObjectAnimator extends ValueAnimator { * @return Method the method associated with mPropertyName. */ private Method getPropertyFunction(String prefix, Class valueType) { - final Object target = mTargetRef == null ? null : mTargetRef.get(); - if (target == null) return null; - // TODO: faster implementation... Method returnVal = null; String firstLetter = mPropertyName.substring(0, 1); @@ -120,7 +114,7 @@ public final class ObjectAnimator extends ValueAnimator { args[0] = valueType; } try { - returnVal = target.getClass().getMethod(setterName, args); + returnVal = mTarget.getClass().getMethod(setterName, args); } catch (NoSuchMethodException e) { Log.e("ObjectAnimator", "Couldn't find setter/getter for property " + mPropertyName + ": " + e); @@ -140,14 +134,13 @@ public final class ObjectAnimator extends ValueAnimator { * A constructor that takes a single property name and set of values. This constructor is * used in the simple case of animating a single property. * - * @param target The object whose property is to be animated. It will be weakly referenced - * from the newly-created ObjectAnimator. This object should have a public method on it called - * <code>setName()</code>, where <code>name</code> is the value of the <code>propertyName</code> - * parameter. + * @param target The object whose property is to be animated. This object should + * have a public method on it called <code>setName()</code>, where <code>name</code> is + * the value of the <code>propertyName</code> parameter. * @param propertyName The name of the property being animated. */ private ObjectAnimator(Object target, String propertyName) { - mTargetRef = new WeakReference<Object>(target); + mTarget = target; setPropertyName(propertyName); } @@ -159,10 +152,9 @@ public final class ObjectAnimator extends ValueAnimator { * from the target object and property being animated). Therefore, there should typically * be two or more values. * - * @param target The object whose property is to be animated. It will be weakly referenced - * from the newly-created ObjectAnimator. This object should have a public method on it called - * <code>setName()</code>, where <code>name</code> is the value of the <code>propertyName</code> - * parameter. + * @param target The object whose property is to be animated. This object should + * have a public method on it called <code>setName()</code>, where <code>name</code> is + * the value of the <code>propertyName</code> parameter. * @param propertyName The name of the property being animated. * @param values A set of values that the animation will animate between over time. * @return A ValueAnimator object that is set up to animate between the given values. @@ -181,10 +173,9 @@ public final class ObjectAnimator extends ValueAnimator { * from the target object and property being animated). Therefore, there should typically * be two or more values. * - * @param target The object whose property is to be animated. It will be weakly referenced - * from the newly-created ObjectAnimator. This object should have a public method on it called - * <code>setName()</code>, where <code>name</code> is the value of the <code>propertyName</code> - * parameter. + * @param target The object whose property is to be animated. This object should + * have a public method on it called <code>setName()</code>, where <code>name</code> is + * the value of the <code>propertyName</code> parameter. * @param propertyName The name of the property being animated. * @param values A set of values that the animation will animate between over time. * @return A ValueAnimator object that is set up to animate between the given values. @@ -201,10 +192,10 @@ public final class ObjectAnimator extends ValueAnimator { * PropertyValuesHolder allows you to associate a set of animation values with a property * name. * - * @param target The object whose property is to be animated. It will be weakly referenced - * from the newly-created ObjectAnimator. This object should have public methods on it called - * <code>setName()</code>, where <code>name</code> is the name of the property passed in as the - * <code>propertyName</code> parameter for each of the PropertyValuesHolder objects. + * @param target The object whose property is to be animated. This object should + * have public methods on it called <code>setName()</code>, where <code>name</code> is + * the name of the property passed in as the <code>propertyName</code> parameter for + * each of the PropertyValuesHolder objects. * @param propertyName The name of the property being animated. * @param evaluator A TypeEvaluator that will be called on each animation frame to * provide the ncessry interpolation between the Object values to derive the animated @@ -227,10 +218,10 @@ public final class ObjectAnimator extends ValueAnimator { * PropertyValuesHolder allows you to associate a set of animation values with a property * name. * - * @param target The object whose property is to be animated. It will be weakly referenced - * from the newly-created ObjectAnimator. This object should have public methods on it called - * <code>setName()</code>, where <code>name</code> is the name of the property passed in as the - * <code>propertyName</code> parameter for each of the PropertyValuesHolder objects. + * @param target The object whose property is to be animated. This object should + * have public methods on it called <code>setName()</code>, where <code>name</code> is + * the name of the property passed in as the <code>propertyName</code> parameter for + * each of the PropertyValuesHolder objects. * @param values A set of PropertyValuesHolder objects whose values will be animated * between over time. * @return A ValueAnimator object that is set up to animate between the given values. @@ -238,7 +229,7 @@ public final class ObjectAnimator extends ValueAnimator { public static ObjectAnimator ofPropertyValuesHolder(Object target, PropertyValuesHolder... values) { ObjectAnimator anim = new ObjectAnimator(); - anim.mTargetRef = new WeakReference<Object>(target); + anim.mTarget = target; anim.setValues(values); return anim; } @@ -279,8 +270,7 @@ public final class ObjectAnimator extends ValueAnimator { @Override public void start() { if (DBG) { - final Object target = mTargetRef == null ? null : mTargetRef.get(); - Log.d("ObjectAnimator", "Anim target, duration" + target + ", " + getDuration()); + Log.d("ObjectAnimator", "Anim target, duration" + mTarget + ", " + getDuration()); for (int i = 0; i < mValues.length; ++i) { PropertyValuesHolder pvh = mValues[i]; ArrayList<Keyframe> keyframes = pvh.mKeyframeSet.mKeyframes; @@ -307,14 +297,11 @@ public final class ObjectAnimator extends ValueAnimator { @Override void initAnimation() { if (!mInitialized) { - final Object target = mTargetRef == null ? null : mTargetRef.get(); - if (target == null) return; - // mValueType may change due to setter/getter setup; do this before calling super.init(), // which uses mValueType to set up the default type evaluator. int numValues = mValues.length; for (int i = 0; i < numValues; ++i) { - mValues[i].setupSetterAndGetter(target); + mValues[i].setupSetterAndGetter(mTarget); } super.initAnimation(); } @@ -339,26 +326,23 @@ public final class ObjectAnimator extends ValueAnimator { /** * The target object whose property will be animated by this animation * - * @return The object being animated, or null if the object has been garbage collected. + * @return The object being animated */ public Object getTarget() { - return mTargetRef == null ? null : mTargetRef.get(); + return mTarget; } /** - * Sets the target object whose property will be animated by this animation. The target - * will be weakly referenced from this object. + * Sets the target object whose property will be animated by this animation * * @param target The object being animated */ @Override public void setTarget(Object target) { - final Object currentTarget = mTargetRef == null ? null : mTargetRef.get(); - - if (currentTarget != target) { - mTargetRef = new WeakReference<Object>(target); - if (currentTarget != null && target != null - && currentTarget.getClass() == target.getClass()) { + if (mTarget != target) { + final Object oldTarget = mTarget; + mTarget = target; + if (oldTarget != null && target != null && oldTarget.getClass() == target.getClass()) { return; } // New target type should cause re-initialization prior to starting @@ -368,25 +352,19 @@ public final class ObjectAnimator extends ValueAnimator { @Override public void setupStartValues() { - final Object target = mTargetRef == null ? null : mTargetRef.get(); - if (target == null) return; - initAnimation(); int numValues = mValues.length; for (int i = 0; i < numValues; ++i) { - mValues[i].setupStartValue(target); + mValues[i].setupStartValue(mTarget); } } @Override public void setupEndValues() { - final Object target = mTargetRef == null ? null : mTargetRef.get(); - if (target == null) return; - initAnimation(); int numValues = mValues.length; for (int i = 0; i < numValues; ++i) { - mValues[i].setupEndValue(target); + mValues[i].setupEndValue(mTarget); } } @@ -405,13 +383,9 @@ public final class ObjectAnimator extends ValueAnimator { @Override void animateValue(float fraction) { super.animateValue(fraction); - - final Object target = mTargetRef == null ? null : mTargetRef.get(); - if (target == null) return; - int numValues = mValues.length; for (int i = 0; i < numValues; ++i) { - mValues[i].setAnimatedValue(target); + mValues[i].setAnimatedValue(mTarget); } } diff --git a/core/java/android/animation/PropertyValuesHolder.java b/core/java/android/animation/PropertyValuesHolder.java index 0254924ca4a7..0c30aadea953 100644 --- a/core/java/android/animation/PropertyValuesHolder.java +++ b/core/java/android/animation/PropertyValuesHolder.java @@ -67,10 +67,9 @@ public class PropertyValuesHolder implements Cloneable { KeyframeSet mKeyframeSet = null; - // type evaluators for the three primitive types handled by this implementation + // type evaluators for the primitive types handled by this implementation private static final TypeEvaluator sIntEvaluator = new IntEvaluator(); private static final TypeEvaluator sFloatEvaluator = new FloatEvaluator(); - private static final TypeEvaluator sDoubleEvaluator = new DoubleEvaluator(); // We try several different types when searching for appropriate setter/getter functions. // The caller may have supplied values in a type that does not match the setter/getter @@ -104,7 +103,7 @@ public class PropertyValuesHolder implements Cloneable { /** * The type evaluator used to calculate the animated values. This evaluator is determined * automatically based on the type of the start/end objects passed into the constructor, - * but the system only knows about the primitive types int, double, and float. Any other + * but the system only knows about the primitive types int and float. Any other * type will need to set the evaluator to a custom evaluator for that type. */ private TypeEvaluator mEvaluator; @@ -501,7 +500,7 @@ public class PropertyValuesHolder implements Cloneable { */ void init() { if (mEvaluator == null) { - // We already handle int, float, long, double automatically, but not their Object + // We already handle int and float automatically, but not their Object // equivalents mEvaluator = (mValueType == Integer.class) ? sIntEvaluator : (mValueType == Float.class) ? sFloatEvaluator : @@ -509,7 +508,7 @@ public class PropertyValuesHolder implements Cloneable { } if (mEvaluator != null) { // KeyframeSet knows how to evaluate the common types - only give it a custom - // evaulator if one has been set on this class + // evaluator if one has been set on this class mKeyframeSet.setEvaluator(mEvaluator); } } @@ -520,7 +519,7 @@ public class PropertyValuesHolder implements Cloneable { * desired. This may be important in cases where either the type of the values supplied * do not match the way that they should be interpolated between, or if the values * are of a custom type or one not currently understood by the animation system. Currently, - * only values of type float, double, and int (and their Object equivalents, Float, Double, + * only values of type float and int (and their Object equivalents: Float * and Integer) are correctly interpolated; all other types require setting a TypeEvaluator. * @param evaluator */ diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java index f8844733f9d2..5705057f25ee 100755 --- a/core/java/android/animation/ValueAnimator.java +++ b/core/java/android/animation/ValueAnimator.java @@ -143,10 +143,9 @@ public class ValueAnimator extends Animator { private static final TimeInterpolator sDefaultInterpolator = new AccelerateDecelerateInterpolator(); - // type evaluators for the three primitive types handled by this implementation + // type evaluators for the primitive types handled by this implementation private static final TypeEvaluator sIntEvaluator = new IntEvaluator(); private static final TypeEvaluator sFloatEvaluator = new FloatEvaluator(); - private static final TypeEvaluator sDoubleEvaluator = new DoubleEvaluator(); /** * Used to indicate whether the animation is currently playing in reverse. This causes the @@ -858,7 +857,7 @@ public class ValueAnimator extends Animator { /** * The type evaluator to be used when calculating the animated values of this animation. - * The system will automatically assign a float, int, or double evaluator based on the type + * The system will automatically assign a float or int evaluator based on the type * of <code>startValue</code> and <code>endValue</code> in the constructor. But if these values * are not one of these primitive types, or if different evaluation is desired (such as is * necessary with int values that represent colors), a custom evaluator needs to be assigned. @@ -1193,4 +1192,16 @@ public class ValueAnimator extends Animator { public static int getCurrentAnimationsCount() { return sAnimations.get().size(); } + + /** + * Clear all animations on this thread, without canceling or ending them. + * This should be used with caution. + * + * @hide + */ + public static void clearAllAnimations() { + sAnimations.get().clear(); + sPendingAnimations.get().clear(); + sDelayedAnims.get().clear(); + } } diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index 44db50fa974b..d5aa9619962c 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -77,6 +77,9 @@ public class ActivityManager { * This may be the same size as {@link #getMemoryClass()} on memory * constrained devices, or it may be significantly larger on devices with * a large amount of available RAM. + * + * <p>The is the size of the application's Dalvik heap if it has + * specified <code>android:largeHeap="true"</code> in its manifest. */ public int getLargeMemoryClass() { return staticGetLargeMemoryClass(); @@ -119,6 +122,8 @@ public class ActivityManager { /** * Thumbnail representation of the task's last state. Must * use {@link ActivityManager#TASKS_GET_THUMBNAILS} to have this set. + * @hide -- this is not scalable, need to have a separate API to get + * the bitmap. */ public Bitmap thumbnail; @@ -200,6 +205,7 @@ public class ActivityManager { /** * Flag for use with {@link #getRecentTasks}: also return the thumbnail * bitmap (if available) for each recent task. + * @hide */ public static final int TASKS_GET_THUMBNAILS = 0x0001000; @@ -211,8 +217,7 @@ public class ActivityManager { * actual number returned may be smaller, depending on how many tasks the * user has started and the maximum number the system can remember. * @param flags Information about what to return. May be any combination - * of {@link #RECENT_WITH_EXCLUDED}, {@link #RECENT_IGNORE_UNAVAILABLE}, - * and {@link #TASKS_GET_THUMBNAILS}. + * of {@link #RECENT_WITH_EXCLUDED} and {@link #RECENT_IGNORE_UNAVAILABLE}. * * @return Returns a list of RecentTaskInfo records describing each of * the recent tasks. @@ -258,8 +263,8 @@ public class ActivityManager { public ComponentName topActivity; /** - * Thumbnail representation of the task's current state. Must - * use {@link ActivityManager#TASKS_GET_THUMBNAILS} to have this set. + * Thumbnail representation of the task's current state. Currently + * always null. */ public Bitmap thumbnail; diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index cc94aa08c2d7..db046ef73597 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -45,7 +45,6 @@ import android.graphics.Canvas; import android.net.IConnectivityManager; import android.net.Proxy; import android.net.ProxyProperties; -import android.os.Build; import android.os.Bundle; import android.os.Debug; import android.os.Handler; @@ -3463,6 +3462,10 @@ public final class ActivityThread { mInstrumentation = new Instrumentation(); } + if ((data.appInfo.flags&ApplicationInfo.FLAG_LARGE_HEAP) != 0) { + // XXX bump up Dalvik's heap. + } + // If the app is being launched for full backup or restore, bring it up in // a restricted environment with the base application class. Application app = data.info.makeApplication(data.restrictedBackupMode, null); @@ -3471,7 +3474,7 @@ public final class ActivityThread { List<ProviderInfo> providers = data.providers; if (providers != null) { installContentProviders(app, providers); - // For process that contain content providers, we want to + // For process that contains content providers, we want to // ensure that the JIT is enabled "at some point". mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000); } diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index e133ea02e29f..6f639906097d 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -153,6 +153,7 @@ class ContextImpl extends Context { private File mPreferencesDir; private File mFilesDir; private File mCacheDir; + private File mObbDir; private File mExternalFilesDir; private File mExternalCacheDir; @@ -647,6 +648,17 @@ class ContextImpl extends Context { } @Override + public File getObbDir() { + synchronized (mSync) { + if (mObbDir == null) { + mObbDir = Environment.getExternalStorageAppObbDirectory( + getPackageName()); + } + return mObbDir; + } + } + + @Override public File getCacheDir() { synchronized (mSync) { if (mCacheDir == null) { diff --git a/core/java/android/app/NativeActivity.java b/core/java/android/app/NativeActivity.java index a5c49ecb5caf..35cc3248f456 100644 --- a/core/java/android/app/NativeActivity.java +++ b/core/java/android/app/NativeActivity.java @@ -84,7 +84,7 @@ public class NativeActivity extends Activity implements SurfaceHolder.Callback2, private boolean mDestroyed; private native int loadNativeCode(String path, String funcname, MessageQueue queue, - String internalDataPath, String externalDataPath, int sdkVersion, + String internalDataPath, String obbPath, String externalDataPath, int sdkVersion, AssetManager assetMgr, byte[] savedState); private native void unloadNativeCode(int handle); @@ -191,7 +191,7 @@ public class NativeActivity extends Activity implements SurfaceHolder.Callback2, ? savedInstanceState.getByteArray(KEY_NATIVE_SAVED_STATE) : null; mNativeHandle = loadNativeCode(path, funcname, Looper.myQueue(), - getFilesDir().toString(), + getFilesDir().toString(), getObbDir().toString(), Environment.getExternalStorageAppFilesDirectory(ai.packageName).toString(), Build.VERSION.SDK_INT, getAssets(), nativeSavedState); diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 227df21d2462..d14cf4d56fc1 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -516,6 +516,13 @@ public abstract class Context { public abstract File getExternalFilesDir(String type); /** + * Return the directory where this application's OBB files (if there + * are any) can be found. Note if the application does not have any OBB + * files, this directory may not exist. + */ + public abstract File getObbDir(); + + /** * Returns the absolute path to the application specific cache directory * on the filesystem. These files will be ones that get deleted first when the * device runs low on storage. diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java index 545144ee1eee..3928aaf62d10 100644 --- a/core/java/android/content/ContextWrapper.java +++ b/core/java/android/content/ContextWrapper.java @@ -191,6 +191,11 @@ public class ContextWrapper extends Context { } @Override + public File getObbDir() { + return mBase.getObbDir(); + } + + @Override public File getCacheDir() { return mBase.getCacheDir(); } diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java index bb0ed6af77da..2d95781781d5 100644 --- a/core/java/android/content/pm/ApplicationInfo.java +++ b/core/java/android/content/pm/ApplicationInfo.java @@ -270,19 +270,19 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { public static final int FLAG_SUPPORTS_XLARGE_SCREENS = 1<<19; /** - * Value for {@link #flags}: this is true if the application has set - * its android:neverEncrypt to true, false otherwise. It is used to specify - * that this package specifically "opts-out" of a secured file system solution, - * and will always store its data in-the-clear. - * - * {@hide} + * Value for {@link #flags}: true when the application has requested a + * large heap for its processes. Corresponds to + * {@link android.R.styleable#AndroidManifestApplication_largeHeap + * android:largeHeap}. */ - public static final int FLAG_NEVER_ENCRYPT = 1<<30; + public static final int FLAG_LARGE_HEAP = 1<<20; /** * Value for {@link #flags}: Set to true if the application has been * installed using the forward lock option. * + * NOTE: DO NOT CHANGE THIS VALUE! It is saved in packages.xml. + * * {@hide} */ public static final int FLAG_FORWARD_LOCK = 1<<29; @@ -298,7 +298,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { * * {@hide} */ - public static final int FLAG_CANT_SAVE_STATE = 1<<27; + public static final int FLAG_CANT_SAVE_STATE = 1<<28; /** * Flags associated with the application. Any combination of diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index b2937babef0b..7676258b4659 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -389,11 +389,15 @@ public class PackageParser { XmlResourceParser parser = null; AssetManager assmgr = null; + Resources res = null; boolean assetError = true; try { assmgr = new AssetManager(); int cookie = assmgr.addAssetPath(mArchiveSourcePath); - if(cookie != 0) { + if (cookie != 0) { + res = new Resources(assmgr, metrics, null); + assmgr.setConfiguration(0, 0, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + Build.VERSION.RESOURCES_SDK_INT); parser = assmgr.openXmlResourceParser(cookie, "AndroidManifest.xml"); assetError = false; } else { @@ -403,7 +407,7 @@ public class PackageParser { Log.w(TAG, "Unable to read AndroidManifest.xml of " + mArchiveSourcePath, e); } - if(assetError) { + if (assetError) { if (assmgr != null) assmgr.close(); mParseError = PackageManager.INSTALL_PARSE_FAILED_BAD_MANIFEST; return null; @@ -413,7 +417,6 @@ public class PackageParser { Exception errorException = null; try { // XXXX todo: need to figure out correct configuration. - Resources res = new Resources(assmgr, metrics, null); pkg = parsePackage(res, parser, flags, errorText); } catch (Exception e) { errorException = e; @@ -593,6 +596,8 @@ public class PackageParser { AssetManager assmgr = null; try { assmgr = new AssetManager(); + assmgr.setConfiguration(0, 0, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + Build.VERSION.RESOURCES_SDK_INT); int cookie = assmgr.addAssetPath(packageFilePath); parser = assmgr.openXmlResourceParser(cookie, "AndroidManifest.xml"); } catch (Exception e) { @@ -1574,9 +1579,9 @@ public class PackageParser { } if (sa.getBoolean( - com.android.internal.R.styleable.AndroidManifestApplication_neverEncrypt, + com.android.internal.R.styleable.AndroidManifestApplication_largeHeap, false)) { - ai.flags |= ApplicationInfo.FLAG_NEVER_ENCRYPT; + ai.flags |= ApplicationInfo.FLAG_LARGE_HEAP; } String str; diff --git a/core/java/android/content/pm/PackageStats.java b/core/java/android/content/pm/PackageStats.java index 9464321acbd1..28a288647885 100755 --- a/core/java/android/content/pm/PackageStats.java +++ b/core/java/android/content/pm/PackageStats.java @@ -19,20 +19,44 @@ package android.content.pm; import android.os.Parcel; import android.os.Parcelable; -import java.util.Arrays; - /** * implementation of PackageStats associated with a * application package. */ public class PackageStats implements Parcelable { + /** Name of the package to which this stats applies. */ public String packageName; + + /** Size of the code (e.g., APK) */ public long codeSize; + + /** + * Size of the internal data size for the application. (e.g., + * /data/data/<app>) + */ public long dataSize; + + /** Size of cache used by the application. (e.g., /data/data/<app>/cache) */ public long cacheSize; - + + /** + * Size of the external data used by the application (e.g., + * <sdcard>/Android/data/<app>) + */ + public long externalDataSize; + + /** + * Size of the external cache used by the application (i.e., on the SD + * card). If this is a subdirectory of the data directory, this size will be + * subtracted out of the external data size. + */ + public long externalCacheSize; + + /** Size of the external media size used by the application. */ + public long externalMediaSize; + public static final Parcelable.Creator<PackageStats> CREATOR - = new Parcelable.Creator<PackageStats>() { + = new Parcelable.Creator<PackageStats>() { public PackageStats createFromParcel(Parcel in) { return new PackageStats(in); } @@ -41,29 +65,49 @@ public class PackageStats implements Parcelable { return new PackageStats[size]; } }; - + public String toString() { - return "PackageStats{" - + Integer.toHexString(System.identityHashCode(this)) - + " " + packageName + "}"; + final StringBuilder sb = new StringBuilder("PackageStats{"); + sb.append(Integer.toHexString(System.identityHashCode(this))); + sb.append(" packageName="); + sb.append(packageName); + sb.append(",codeSize="); + sb.append(codeSize); + sb.append(",dataSize="); + sb.append(dataSize); + sb.append(",cacheSize="); + sb.append(cacheSize); + sb.append(",externalDataSize="); + sb.append(externalDataSize); + sb.append(",externalCacheSize="); + sb.append(externalCacheSize); + sb.append(",externalMediaSize="); + sb.append(externalMediaSize); + return sb.toString(); } - + public PackageStats(String pkgName) { packageName = pkgName; } - + public PackageStats(Parcel source) { packageName = source.readString(); codeSize = source.readLong(); dataSize = source.readLong(); cacheSize = source.readLong(); + externalDataSize = source.readLong(); + externalCacheSize = source.readLong(); + externalMediaSize = source.readLong(); } - + public PackageStats(PackageStats pStats) { packageName = pStats.packageName; codeSize = pStats.codeSize; dataSize = pStats.dataSize; cacheSize = pStats.cacheSize; + externalDataSize = pStats.externalDataSize; + externalCacheSize = pStats.externalCacheSize; + externalMediaSize = pStats.externalMediaSize; } public int describeContents() { @@ -75,5 +119,8 @@ public class PackageStats implements Parcelable { dest.writeLong(codeSize); dest.writeLong(dataSize); dest.writeLong(cacheSize); + dest.writeLong(externalDataSize); + dest.writeLong(externalCacheSize); + dest.writeLong(externalMediaSize); } } diff --git a/core/java/android/content/res/CompatibilityInfo.java b/core/java/android/content/res/CompatibilityInfo.java index 406b091278f8..6baf1c21db88 100644 --- a/core/java/android/content/res/CompatibilityInfo.java +++ b/core/java/android/content/res/CompatibilityInfo.java @@ -283,6 +283,7 @@ public class CompatibilityInfo { private Rect mContentInsetsBuffer = null; private Rect mVisibleInsetsBuffer = null; + private Region mTouchableAreaBuffer = null; Translator(float applicationScale, float applicationInvertedScale) { this.applicationScale = applicationScale; @@ -395,14 +396,25 @@ public class CompatibilityInfo { /** * Translate the visible insets in application window to Screen. This uses - * the internal buffer for content insets to avoid extra object allocation. + * the internal buffer for visible insets to avoid extra object allocation. */ - public Rect getTranslatedVisbileInsets(Rect visibleInsets) { + public Rect getTranslatedVisibleInsets(Rect visibleInsets) { if (mVisibleInsetsBuffer == null) mVisibleInsetsBuffer = new Rect(); mVisibleInsetsBuffer.set(visibleInsets); translateRectInAppWindowToScreen(mVisibleInsetsBuffer); return mVisibleInsetsBuffer; } + + /** + * Translate the touchable area in application window to Screen. This uses + * the internal buffer for touchable area to avoid extra object allocation. + */ + public Region getTranslatedTouchableArea(Region touchableArea) { + if (mTouchableAreaBuffer == null) mTouchableAreaBuffer = new Region(); + mTouchableAreaBuffer.set(touchableArea); + mTouchableAreaBuffer.scale(applicationScale); + return mTouchableAreaBuffer; + } } /** diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java index b40a22648be1..29bb004cf0ac 100755 --- a/core/java/android/content/res/Resources.java +++ b/core/java/android/content/res/Resources.java @@ -56,10 +56,6 @@ public class Resources { private static final int ID_OTHER = 0x01000004; - // Use the current SDK version code. If we are a development build, - // also allow the previous SDK version + 1. - private static final int sSdkVersion = Build.VERSION.SDK_INT - + ("REL".equals(Build.VERSION.CODENAME) ? 0 : 1); private static final Object mSync = new Object(); private static Resources mSystem = null; @@ -1427,14 +1423,14 @@ public class Resources { mConfiguration.touchscreen, (int)(mMetrics.density*160), mConfiguration.keyboard, keyboardHidden, mConfiguration.navigation, width, height, - mConfiguration.screenLayout, mConfiguration.uiMode, sSdkVersion); + mConfiguration.screenLayout, mConfiguration.uiMode, + Build.VERSION.RESOURCES_SDK_INT); clearDrawableCache(mDrawableCache, configChanges); clearDrawableCache(mColorDrawableCache, configChanges); mColorStateListCache.clear(); - flushLayoutCache(); } synchronized (mSync) { diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java index 23b9ad583edf..4d25bac067d4 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -25,6 +25,7 @@ import android.content.res.Configuration; import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Rect; +import android.graphics.Region; import android.os.Bundle; import android.os.IBinder; import android.os.ResultReceiver; @@ -283,11 +284,13 @@ public class InputMethodService extends AbstractInputMethodService { View decor = getWindow().getWindow().getDecorView(); info.contentInsets.top = info.visibleInsets.top = decor.getHeight(); + info.touchableRegion.setEmpty(); info.setTouchableInsets(ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME); } else { onComputeInsets(mTmpInsets); info.contentInsets.top = mTmpInsets.contentTopInsets; info.visibleInsets.top = mTmpInsets.visibleTopInsets; + info.touchableRegion.set(mTmpInsets.touchableRegion); info.setTouchableInsets(mTmpInsets.touchableInsets); } } @@ -510,7 +513,14 @@ public class InputMethodService extends AbstractInputMethodService { * of the input method window. */ public int visibleTopInsets; - + + /** + * This is the region of the UI that is touchable. It is used when + * {@link #touchableInsets} is set to {@link #TOUCHABLE_INSETS_REGION}. + * The region should be specified relative to the origin of the window frame. + */ + public final Region touchableRegion = new Region(); + /** * Option for {@link #touchableInsets}: the entire window frame * can be touched. @@ -531,11 +541,19 @@ public class InputMethodService extends AbstractInputMethodService { */ public static final int TOUCHABLE_INSETS_VISIBLE = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE; - + + /** + * Option for {@link #touchableInsets}: the region specified by + * {@link #touchableRegion} can be touched. + */ + public static final int TOUCHABLE_INSETS_REGION + = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION; + /** * Determine which area of the window is touchable by the user. May * be one of: {@link #TOUCHABLE_INSETS_FRAME}, - * {@link #TOUCHABLE_INSETS_CONTENT}, or {@link #TOUCHABLE_INSETS_VISIBLE}. + * {@link #TOUCHABLE_INSETS_CONTENT}, {@link #TOUCHABLE_INSETS_VISIBLE}, + * or {@link #TOUCHABLE_INSETS_REGION}. */ public int touchableInsets; } @@ -950,6 +968,7 @@ public class InputMethodService extends AbstractInputMethodService { } outInsets.visibleTopInsets = loc[1]; outInsets.touchableInsets = Insets.TOUCHABLE_INSETS_VISIBLE; + outInsets.touchableRegion.setEmpty(); } /** @@ -2153,6 +2172,7 @@ public class InputMethodService extends AbstractInputMethodService { p.println("Last computed insets:"); p.println(" contentTopInsets=" + mTmpInsets.contentTopInsets + " visibleTopInsets=" + mTmpInsets.visibleTopInsets - + " touchableInsets=" + mTmpInsets.touchableInsets); + + " touchableInsets=" + mTmpInsets.touchableInsets + + " touchableRegion=" + mTmpInsets.touchableRegion); } } diff --git a/core/java/android/os/AsyncTask.java b/core/java/android/os/AsyncTask.java index 9f7e31cd8edb..5a35eb050482 100644 --- a/core/java/android/os/AsyncTask.java +++ b/core/java/android/os/AsyncTask.java @@ -16,9 +16,11 @@ package android.os; +import java.util.ArrayDeque; import java.util.concurrent.BlockingQueue; import java.util.concurrent.Callable; import java.util.concurrent.CancellationException; +import java.util.concurrent.Executor; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; import java.util.concurrent.LinkedBlockingQueue; @@ -151,8 +153,6 @@ public abstract class AsyncTask<Params, Progress, Result> { private static final int MAXIMUM_POOL_SIZE = 128; private static final int KEEP_ALIVE = 1; - private static final BlockingQueue<Runnable> sWorkQueue = - new LinkedBlockingQueue<Runnable>(10); private static final ThreadFactory sThreadFactory = new ThreadFactory() { private final AtomicInteger mCount = new AtomicInteger(1); @@ -162,8 +162,17 @@ public abstract class AsyncTask<Params, Progress, Result> { } }; - private static final ThreadPoolExecutor sExecutor = new ThreadPoolExecutor(CORE_POOL_SIZE, - MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sWorkQueue, sThreadFactory); + private static final BlockingQueue<Runnable> sPoolWorkQueue = + new LinkedBlockingQueue<Runnable>(10); + + /** + * A {@link ThreadPoolExecutor} that can be used to execute tasks in parallel. + */ + public static final ThreadPoolExecutor THREAD_POOL_EXECUTOR + = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE, + TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory); + + private static final SerialExecutor sSerialExecutor = new SerialExecutor(); private static final int MESSAGE_POST_RESULT = 0x1; private static final int MESSAGE_POST_PROGRESS = 0x2; @@ -177,6 +186,32 @@ public abstract class AsyncTask<Params, Progress, Result> { private final AtomicBoolean mTaskInvoked = new AtomicBoolean(); + private static class SerialExecutor implements Executor { + final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>(); + Runnable mActive; + + public synchronized void execute(final Runnable r) { + mTasks.offer(new Runnable() { + public void run() { + try { + r.run(); + } finally { + scheduleNext(); + } + } + }); + if (mActive == null) { + scheduleNext(); + } + } + + protected synchronized void scheduleNext() { + if ((mActive = mTasks.poll()) != null) { + THREAD_POOL_EXECUTOR.execute(mActive); + } + } + } + /** * Indicates the current status of the task. Each status will be set only once * during the lifetime of a task. @@ -433,7 +468,11 @@ public abstract class AsyncTask<Params, Progress, Result> { /** * Executes the task with the specified parameters. The task returns - * itself (this) so that the caller can keep a reference to it. + * itself (this) so that the caller can keep a reference to it. The tasks + * started by all invocations of this method in a given process are run + * sequentially. Call the executeOnExecutor(Executor,Params...) + * with a custom {@link Executor} to have finer grained control over how the + * tasks are run. * * This method must be invoked on the UI thread. * @@ -445,6 +484,26 @@ public abstract class AsyncTask<Params, Progress, Result> { * {@link AsyncTask.Status#RUNNING} or {@link AsyncTask.Status#FINISHED}. */ public final AsyncTask<Params, Progress, Result> execute(Params... params) { + return executeOnExecutor(sSerialExecutor, params); + } + + /** + * Executes the task with the specified parameters. The task returns + * itself (this) so that the caller can keep a reference to it. + * + * This method must be invoked on the UI thread. + * + * @param exec The executor to use. {@link #THREAD_POOL_EXECUTOR} is available as a + * convenient process-wide thread pool for tasks that are loosely coupled. + * @param params The parameters of the task. + * + * @return This instance of AsyncTask. + * + * @throws IllegalStateException If {@link #getStatus()} returns either + * {@link AsyncTask.Status#RUNNING} or {@link AsyncTask.Status#FINISHED}. + */ + public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec, + Params... params) { if (mStatus != Status.PENDING) { switch (mStatus) { case RUNNING: @@ -462,12 +521,20 @@ public abstract class AsyncTask<Params, Progress, Result> { onPreExecute(); mWorker.mParams = params; - sExecutor.execute(mFuture); + exec.execute(mFuture); return this; } /** + * Schedules the {@link Runnable} in serial with the other AsyncTasks that were started + * with {@link #execute}. + */ + public static void execute(Runnable runnable) { + sSerialExecutor.execute(runnable); + } + + /** * This method can be invoked from {@link #doInBackground} to * publish updates on the UI thread while the background computation is * still running. Each call to this method will trigger the execution of diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java index 6e50e97ae996..af7b28b416e2 100644 --- a/core/java/android/os/Build.java +++ b/core/java/android/os/Build.java @@ -100,6 +100,15 @@ public class Build { * a release build. */ public static final String CODENAME = getString("ro.build.version.codename"); + + /** + * The SDK version to use when accessing resources. + * Use the current SDK version code. If we are a development build, + * also allow the previous SDK version + 1. + * @hide + */ + public static final int RESOURCES_SDK_INT = SDK_INT + + ("REL".equals(CODENAME) ? 0 : 1); } /** diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java index 4f188f8576d4..cc956428fb5a 100644 --- a/core/java/android/os/Environment.java +++ b/core/java/android/os/Environment.java @@ -107,6 +107,10 @@ public class Environment { = new File (new File(getDirectory("EXTERNAL_STORAGE", "/sdcard"), "Android"), "media"); + private static final File EXTERNAL_STORAGE_ANDROID_OBB_DIRECTORY + = new File (new File(getDirectory("EXTERNAL_STORAGE", "/sdcard"), + "Android"), "obb"); + private static final File DOWNLOAD_CACHE_DIRECTORY = getDirectory("DOWNLOAD_CACHE", "/cache"); @@ -304,6 +308,14 @@ public class Environment { } /** + * Generates the raw path to an application's OBB files + * @hide + */ + public static File getExternalStorageAppObbDirectory(String packageName) { + return new File(EXTERNAL_STORAGE_ANDROID_OBB_DIRECTORY, packageName); + } + + /** * Generates the path to an application's files. * @hide */ diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl index a5f405aca1e4..1218e81d7708 100644 --- a/core/java/android/view/IWindowSession.aidl +++ b/core/java/android/view/IWindowSession.aidl @@ -101,7 +101,7 @@ interface IWindowSession { * {@link android.view.ViewTreeObserver.InternalInsetsInfo}. */ void setInsets(IWindow window, int touchableInsets, in Rect contentInsets, - in Rect visibleInsets); + in Rect visibleInsets, in Region touchableRegion); /** * Return the current display size in which the window is being laid out, diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java index ad9e68633958..96f8cdcce70b 100644 --- a/core/java/android/view/ViewRoot.java +++ b/core/java/android/view/ViewRoot.java @@ -1229,24 +1229,34 @@ public final class ViewRoot extends Handler implements ViewParent, } if (computesInternalInsets) { - ViewTreeObserver.InternalInsetsInfo insets = attachInfo.mGivenInternalInsets; - final Rect givenContent = attachInfo.mGivenInternalInsets.contentInsets; - final Rect givenVisible = attachInfo.mGivenInternalInsets.visibleInsets; - givenContent.left = givenContent.top = givenContent.right - = givenContent.bottom = givenVisible.left = givenVisible.top - = givenVisible.right = givenVisible.bottom = 0; + // Clear the original insets. + final ViewTreeObserver.InternalInsetsInfo insets = attachInfo.mGivenInternalInsets; + insets.reset(); + + // Compute new insets in place. attachInfo.mTreeObserver.dispatchOnComputeInternalInsets(insets); - Rect contentInsets = insets.contentInsets; - Rect visibleInsets = insets.visibleInsets; - if (mTranslator != null) { - contentInsets = mTranslator.getTranslatedContentInsets(contentInsets); - visibleInsets = mTranslator.getTranslatedVisbileInsets(visibleInsets); - } + + // Tell the window manager. if (insetsPending || !mLastGivenInsets.equals(insets)) { mLastGivenInsets.set(insets); + + // Translate insets to screen coordinates if needed. + final Rect contentInsets; + final Rect visibleInsets; + final Region touchableRegion; + if (mTranslator != null) { + contentInsets = mTranslator.getTranslatedContentInsets(insets.contentInsets); + visibleInsets = mTranslator.getTranslatedVisibleInsets(insets.visibleInsets); + touchableRegion = mTranslator.getTranslatedTouchableArea(insets.touchableRegion); + } else { + contentInsets = insets.contentInsets; + visibleInsets = insets.visibleInsets; + touchableRegion = insets.touchableRegion; + } + try { sWindowSession.setInsets(mWindow, insets.mTouchableInsets, - contentInsets, visibleInsets); + contentInsets, visibleInsets, touchableRegion); } catch (RemoteException e) { } } @@ -1780,7 +1790,7 @@ public final class ViewRoot extends Handler implements ViewParent, } void dispatchDetachedFromWindow() { - if (mView != null) { + if (mView != null && mView.mAttachInfo != null) { mView.dispatchDetachedFromWindow(); } diff --git a/core/java/android/view/ViewTreeObserver.java b/core/java/android/view/ViewTreeObserver.java index 06a0fa6eb8ee..db8717517e48 100644 --- a/core/java/android/view/ViewTreeObserver.java +++ b/core/java/android/view/ViewTreeObserver.java @@ -17,6 +17,7 @@ package android.view; import android.graphics.Rect; +import android.graphics.Region; import java.util.ArrayList; import java.util.concurrent.CopyOnWriteArrayList; @@ -126,11 +127,18 @@ public final class ViewTreeObserver { public final Rect contentInsets = new Rect(); /** - * Offsets from the fram of the window at which windows behind it + * Offsets from the frame of the window at which windows behind it * are visible. */ public final Rect visibleInsets = new Rect(); - + + /** + * Touchable region defined relative to the origin of the frame of the window. + * Only used when {@link #setTouchableInsets(int)} is called with + * the option {@link #TOUCHABLE_INSETS_REGION}. + */ + public final Region touchableRegion = new Region(); + /** * Option for {@link #setTouchableInsets(int)}: the entire window frame * can be touched. @@ -148,11 +156,17 @@ public final class ViewTreeObserver { * the visible insets can be touched. */ public static final int TOUCHABLE_INSETS_VISIBLE = 2; - + + /** + * Option for {@link #setTouchableInsets(int)}: the area inside of + * the provided touchable region in {@link #touchableRegion} can be touched. + */ + public static final int TOUCHABLE_INSETS_REGION = 3; + /** * Set which parts of the window can be touched: either * {@link #TOUCHABLE_INSETS_FRAME}, {@link #TOUCHABLE_INSETS_CONTENT}, - * or {@link #TOUCHABLE_INSETS_VISIBLE}. + * {@link #TOUCHABLE_INSETS_VISIBLE}, or {@link #TOUCHABLE_INSETS_REGION}. */ public void setTouchableInsets(int val) { mTouchableInsets = val; @@ -165,11 +179,9 @@ public final class ViewTreeObserver { int mTouchableInsets; void reset() { - final Rect givenContent = contentInsets; - final Rect givenVisible = visibleInsets; - givenContent.left = givenContent.top = givenContent.right - = givenContent.bottom = givenVisible.left = givenVisible.top - = givenVisible.right = givenVisible.bottom = 0; + contentInsets.setEmpty(); + visibleInsets.setEmpty(); + touchableRegion.setEmpty(); mTouchableInsets = TOUCHABLE_INSETS_FRAME; } @@ -179,13 +191,16 @@ public final class ViewTreeObserver { return false; } InternalInsetsInfo other = (InternalInsetsInfo)o; + if (mTouchableInsets != other.mTouchableInsets) { + return false; + } if (!contentInsets.equals(other.contentInsets)) { return false; } if (!visibleInsets.equals(other.visibleInsets)) { return false; } - return mTouchableInsets == other.mTouchableInsets; + return touchableRegion.equals(other.touchableRegion); } catch (ClassCastException e) { return false; } @@ -194,6 +209,7 @@ public final class ViewTreeObserver { void set(InternalInsetsInfo other) { contentInsets.set(other.contentInsets); visibleInsets.set(other.visibleInsets); + touchableRegion.set(other.touchableRegion); mTouchableInsets = other.mTouchableInsets; } } diff --git a/core/java/android/widget/ExpandableListView.java b/core/java/android/widget/ExpandableListView.java index 3d21048e5f30..472a33521b53 100644 --- a/core/java/android/widget/ExpandableListView.java +++ b/core/java/android/widget/ExpandableListView.java @@ -22,7 +22,6 @@ import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Rect; -import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.os.Parcel; import android.os.Parcelable; @@ -212,6 +211,9 @@ public class ExpandableListView extends ListView { .getDimensionPixelSize(com.android.internal.R.styleable.ExpandableListView_indicatorLeft, 0); mIndicatorRight = a .getDimensionPixelSize(com.android.internal.R.styleable.ExpandableListView_indicatorRight, 0); + if (mIndicatorRight == 0) { + mIndicatorRight = mIndicatorLeft + mGroupIndicator.getIntrinsicWidth(); + } mChildIndicatorLeft = a.getDimensionPixelSize( com.android.internal.R.styleable.ExpandableListView_childIndicatorLeft, CHILD_INDICATOR_INHERIT); mChildIndicatorRight = a.getDimensionPixelSize( diff --git a/core/java/android/widget/SearchView.java b/core/java/android/widget/SearchView.java index 2c960562f85f..585dcf23952a 100644 --- a/core/java/android/widget/SearchView.java +++ b/core/java/android/widget/SearchView.java @@ -83,6 +83,7 @@ public class SearchView extends LinearLayout { private CursorAdapter mSuggestionsAdapter; private View mSearchButton; private View mSubmitButton; + private View mSubmitArea; private ImageView mCloseButton; private View mSearchEditFrame; private View mVoiceButton; @@ -92,6 +93,7 @@ public class SearchView extends LinearLayout { private boolean mQueryRefinement; private boolean mClearingFocus; private int mMaxWidth; + private boolean mVoiceButtonEnabled; private SearchableInfo mSearchable; @@ -187,6 +189,7 @@ public class SearchView extends LinearLayout { mQueryTextView.setSearchView(this); mSearchEditFrame = findViewById(R.id.search_edit_frame); + mSubmitArea = findViewById(R.id.submit_area); mSubmitButton = findViewById(R.id.search_go_btn); mCloseButton = (ImageView) findViewById(R.id.search_close_btn); mVoiceButton = findViewById(R.id.search_voice_btn); @@ -248,6 +251,8 @@ public class SearchView extends LinearLayout { if (mSearchable != null) { updateSearchAutoComplete(); } + // Cache the voice search capability + mVoiceButtonEnabled = hasVoiceSearch(); updateViewsVisibility(mIconifiedByDefault); } @@ -513,18 +518,55 @@ public class SearchView extends LinearLayout { mIconified = collapsed; // Visibility of views that are visible when collapsed final int visCollapsed = collapsed ? VISIBLE : GONE; - // Visibility of views that are visible when expanded - final int visExpanded = collapsed ? GONE : VISIBLE; // Is there text in the query final boolean hasText = !TextUtils.isEmpty(mQueryTextView.getText()); mSearchButton.setVisibility(visCollapsed); - mSubmitButton.setVisibility(mSubmitButtonEnabled && hasText ? visExpanded : GONE); - mSearchEditFrame.setVisibility(visExpanded); + updateSubmitButton(hasText); + mSearchEditFrame.setVisibility(collapsed ? GONE : VISIBLE); updateCloseButton(); updateVoiceButton(!hasText); + updateSubmitArea(); requestLayout(); - invalidate(); + } + + private boolean hasVoiceSearch() { + if (mSearchable != null && mSearchable.getVoiceSearchEnabled()) { + Intent testIntent = null; + if (mSearchable.getVoiceSearchLaunchWebSearch()) { + testIntent = mVoiceWebSearchIntent; + } else if (mSearchable.getVoiceSearchLaunchRecognizer()) { + testIntent = mVoiceAppSearchIntent; + } + if (testIntent != null) { + ResolveInfo ri = getContext().getPackageManager().resolveActivity(testIntent, + PackageManager.MATCH_DEFAULT_ONLY); + return ri != null; + } + } + return false; + } + + private boolean isSubmitAreaEnabled() { + return (mSubmitButtonEnabled || mVoiceButtonEnabled) && !isIconified(); + } + + private void updateSubmitButton(boolean hasText) { + mSubmitButton.setVisibility( + isSubmitAreaEnabled() ? (hasText ? VISIBLE : INVISIBLE) : GONE); + } + + private void updateSubmitArea() { + int visibility = GONE; + if (isSubmitAreaEnabled()) { + if (mSubmitButton.getVisibility() == VISIBLE + || mVoiceButton.getVisibility() == VISIBLE) { + visibility = VISIBLE; + } else { + visibility = INVISIBLE; + } + } + mSubmitArea.setVisibility(visibility); } private void updateCloseButton() { @@ -790,22 +832,14 @@ public class SearchView extends LinearLayout { * be visible - i.e., if the user has typed a query, remove the voice button. */ private void updateVoiceButton(boolean empty) { - int visibility = View.GONE; - if (mSearchable != null && mSearchable.getVoiceSearchEnabled() && empty - && !isIconified()) { - Intent testIntent = null; - if (mSearchable.getVoiceSearchLaunchWebSearch()) { - testIntent = mVoiceWebSearchIntent; - } else if (mSearchable.getVoiceSearchLaunchRecognizer()) { - testIntent = mVoiceAppSearchIntent; - } - if (testIntent != null) { - ResolveInfo ri = getContext().getPackageManager().resolveActivity(testIntent, - PackageManager.MATCH_DEFAULT_ONLY); - if (ri != null) { - visibility = View.VISIBLE; - } - } + // If the voice button is to be visible, show it + // Else, make it gone if the submit button is enabled, otherwise invisible to + // avoid losing the real-estate + int visibility = mSubmitButtonEnabled ? GONE : INVISIBLE; + + if (mVoiceButtonEnabled && !isIconified() && empty) { + visibility = VISIBLE; + mSubmitButton.setVisibility(GONE); } mVoiceButton.setVisibility(visibility); } @@ -825,12 +859,11 @@ public class SearchView extends LinearLayout { CharSequence text = mQueryTextView.getText(); boolean hasText = !TextUtils.isEmpty(text); if (isSubmitButtonEnabled()) { - mSubmitButton.setVisibility(hasText ? VISIBLE : GONE); - requestLayout(); - invalidate(); + updateSubmitButton(hasText); } updateVoiceButton(!hasText); updateCloseButton(); + updateSubmitArea(); if (mOnQueryChangeListener != null) { mOnQueryChangeListener.onQueryTextChanged(newText.toString()); } diff --git a/core/java/android/widget/StackView.java b/core/java/android/widget/StackView.java index 264af71eb438..2c100773951c 100644 --- a/core/java/android/widget/StackView.java +++ b/core/java/android/widget/StackView.java @@ -1,5 +1,4 @@ -/* - * Copyright (C) 2010 The Android Open Source Project +/* Copyright (C) 2010 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. @@ -209,22 +208,19 @@ public class StackView extends AdapterViewAnimator { } } - if (fromIndex == -1 && toIndex == NUM_ACTIVE_VIEWS -1) { + if (fromIndex == -1 && toIndex == getNumActiveViews() -1) { // Fade item in if (view.getAlpha() == 1) { view.setAlpha(0); } - view.setScaleX(1 - PERSPECTIVE_SCALE_FACTOR); - view.setScaleY(1 - PERSPECTIVE_SCALE_FACTOR); - view.setTranslationX(mPerspectiveShiftX); - view.setTranslationY(0); + transformViewAtIndex(toIndex, view, false); view.setVisibility(VISIBLE); alphaOa = ObjectAnimator.ofFloat(view, "alpha", view.getAlpha(), 1.0f); alphaOa.setDuration(FADE_IN_ANIMATION_DURATION); if (oldAlphaOa != null) oldAlphaOa.cancel(); alphaOa.start(); - view.setTagInternal(com.android.internal.R.id.viewAlphaAnimation, + view.setTagInternal(com.android.internal.R.id.viewAlphaAnimation, new WeakReference<ObjectAnimator>(alphaOa)); } else if (fromIndex == 0 && toIndex == 1) { // Slide item in @@ -270,7 +266,7 @@ public class StackView extends AdapterViewAnimator { alphaOa.setDuration(STACK_RELAYOUT_DURATION); if (oldAlphaOa != null) oldAlphaOa.cancel(); alphaOa.start(); - view.setTagInternal(com.android.internal.R.id.viewAlphaAnimation, + view.setTagInternal(com.android.internal.R.id.viewAlphaAnimation, new WeakReference<ObjectAnimator>(alphaOa)); } @@ -284,16 +280,20 @@ public class StackView extends AdapterViewAnimator { final float maxPerspectiveShiftY = mPerspectiveShiftY; final float maxPerspectiveShiftX = mPerspectiveShiftX; - index = mMaxNumActiveViews - index - 1; - if (index == mMaxNumActiveViews - 1) index--; + if (mStackMode == ITEMS_SLIDE_DOWN) { + index = mMaxNumActiveViews - index - 1; + if (index == mMaxNumActiveViews - 1) index--; + } else { + index--; + if (index < 0) index++; + } float r = (index * 1.0f) / (mMaxNumActiveViews - 2); final float scale = 1 - PERSPECTIVE_SCALE_FACTOR * (1 - r); - int stackDirection = (mStackMode == ITEMS_SLIDE_UP) ? 1 : -1; - float perspectiveTranslationY = -stackDirection * r * maxPerspectiveShiftY; - float scaleShiftCorrectionY = stackDirection * (1 - scale) * + float perspectiveTranslationY = r * maxPerspectiveShiftY; + float scaleShiftCorrectionY = (scale - 1) * (getMeasuredHeight() * (1 - PERSPECTIVE_SHIFT_FACTOR_Y) / 2.0f); final float transY = perspectiveTranslationY + scaleShiftCorrectionY; @@ -302,7 +302,7 @@ public class StackView extends AdapterViewAnimator { (getMeasuredWidth() * (1 - PERSPECTIVE_SHIFT_FACTOR_X) / 2.0f); final float transX = perspectiveTranslationX + scaleShiftCorrectionX; - // If this view is currently being animated for a certain position, we need to cancel + // If this view is currently being animated for a certain position, we need to cancel // this animation so as not to interfere with the new transformation. Object tag = view.getTag(com.android.internal.R.id.viewAnimation); if (tag instanceof WeakReference<?>) { @@ -515,11 +515,12 @@ public class StackView extends AdapterViewAnimator { private void beginGestureIfNeeded(float deltaY) { if ((int) Math.abs(deltaY) > mTouchSlop && mSwipeGestureType == GESTURE_NONE) { - int swipeGestureType = deltaY < 0 ? GESTURE_SLIDE_UP : GESTURE_SLIDE_DOWN; + final int swipeGestureType = deltaY < 0 ? GESTURE_SLIDE_UP : GESTURE_SLIDE_DOWN; cancelLongPress(); requestDisallowInterceptTouchEvent(true); if (mAdapter == null) return; + final int adapterCount = mAdapter.getCount(); int activeIndex; if (mStackMode == ITEMS_SLIDE_UP) { @@ -528,13 +529,20 @@ public class StackView extends AdapterViewAnimator { activeIndex = (swipeGestureType == GESTURE_SLIDE_DOWN) ? 1 : 0; } + boolean endOfStack = mLoopViews && adapterCount == 1 && + ((mStackMode == ITEMS_SLIDE_UP && swipeGestureType == GESTURE_SLIDE_UP) || + (mStackMode == ITEMS_SLIDE_DOWN && swipeGestureType == GESTURE_SLIDE_DOWN)); + boolean beginningOfStack = mLoopViews && adapterCount == 1 && + ((mStackMode == ITEMS_SLIDE_DOWN && swipeGestureType == GESTURE_SLIDE_UP) || + (mStackMode == ITEMS_SLIDE_UP && swipeGestureType == GESTURE_SLIDE_DOWN)); + int stackMode; - if (mLoopViews) { + if (mLoopViews && !beginningOfStack && !endOfStack) { stackMode = StackSlider.NORMAL_MODE; - } else if (mCurrentWindowStartUnbounded + activeIndex == -1) { + } else if (mCurrentWindowStartUnbounded + activeIndex == -1 || beginningOfStack) { activeIndex++; stackMode = StackSlider.BEGINNING_OF_STACK_MODE; - } else if (mCurrentWindowStartUnbounded + activeIndex == mAdapter.getCount() - 1) { + } else if (mCurrentWindowStartUnbounded + activeIndex == adapterCount - 1 || endOfStack) { stackMode = StackSlider.END_OF_STACK_MODE; } else { stackMode = StackSlider.NORMAL_MODE; @@ -989,6 +997,11 @@ public class StackView extends AdapterViewAnimator { @Override public void advance() { long timeSinceLastInteraction = System.currentTimeMillis() - mLastInteractionTime; + + if (mAdapter == null) return; + final int adapterCount = mAdapter.getCount(); + if (adapterCount == 1 && mLoopViews) return; + if (mSwipeGestureType == GESTURE_NONE && timeSinceLastInteraction > MIN_TIME_BETWEEN_INTERACTION_AND_AUTOADVANCE) { showNext(); @@ -1266,4 +1279,4 @@ public class StackView extends AdapterViewAnimator { mask.recycle(); } } -} +}
\ No newline at end of file diff --git a/core/java/com/android/internal/view/menu/ActionMenuView.java b/core/java/com/android/internal/view/menu/ActionMenuView.java index 8e491e9fdd62..8825c02415e6 100644 --- a/core/java/com/android/internal/view/menu/ActionMenuView.java +++ b/core/java/com/android/internal/view/menu/ActionMenuView.java @@ -20,7 +20,6 @@ import android.content.res.Configuration; import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.drawable.Drawable; -import android.text.TextUtils; import android.util.AttributeSet; import android.view.Gravity; import android.view.View; @@ -44,6 +43,7 @@ public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvo private MenuBuilder mMenu; private int mMaxItems; + private int mWidthLimit; private boolean mReserveOverflow; private OverflowMenuButton mOverflowButton; private MenuPopupHelper mOverflowPopup; @@ -91,6 +91,7 @@ public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvo final int screen = res.getConfiguration().screenLayout; mReserveOverflow = (screen & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_XLARGE; + mWidthLimit = res.getDisplayMetrics().widthPixels / 2; TypedArray a = context.obtainStyledAttributes(com.android.internal.R.styleable.Theme); mDivider = a.getDrawable(com.android.internal.R.styleable.Theme_dividerVertical); @@ -108,6 +109,7 @@ public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvo mReserveOverflow = (screen & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_XLARGE; mMaxItems = getMaxActionButtons(); + mWidthLimit = getResources().getDisplayMetrics().widthPixels / 2; if (mMenu != null) { mMenu.setMaxActionItems(mMaxItems); updateChildren(false); @@ -172,6 +174,19 @@ public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvo } public void initialize(MenuBuilder menu, int menuType) { + int width = mWidthLimit; + if (mReserveOverflow) { + if (mOverflowButton == null) { + OverflowMenuButton button = new OverflowMenuButton(mContext); + mOverflowButton = button; + } + final int spec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); + mOverflowButton.measure(spec, spec); + width -= mOverflowButton.getMeasuredWidth(); + } + + menu.setActionWidthLimit(width); + menu.setMaxActionItems(mMaxItems); mMenu = menu; updateChildren(true); @@ -219,9 +234,11 @@ public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvo if (itemCount > 0) { addView(makeDividerView(), makeDividerLayoutParams()); } - OverflowMenuButton button = new OverflowMenuButton(mContext); - addView(button); - mOverflowButton = button; + if (mOverflowButton == null) { + OverflowMenuButton button = new OverflowMenuButton(mContext); + mOverflowButton = button; + } + addView(mOverflowButton); } else { mOverflowButton = null; } diff --git a/core/java/com/android/internal/view/menu/MenuBuilder.java b/core/java/com/android/internal/view/menu/MenuBuilder.java index 830c2c1f865a..588b10c2d066 100644 --- a/core/java/com/android/internal/view/menu/MenuBuilder.java +++ b/core/java/com/android/internal/view/menu/MenuBuilder.java @@ -27,9 +27,10 @@ import android.content.res.Resources; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.Parcelable; -import android.util.Log; import android.util.SparseArray; +import android.util.SparseBooleanArray; import android.util.TypedValue; +import android.view.ContextMenu.ContextMenuInfo; import android.view.ContextThemeWrapper; import android.view.KeyCharacterMap; import android.view.KeyEvent; @@ -38,8 +39,8 @@ import android.view.Menu; import android.view.MenuItem; import android.view.SubMenu; import android.view.View; +import android.view.View.MeasureSpec; import android.view.ViewGroup; -import android.view.ContextMenu.ContextMenuInfo; import android.widget.AdapterView; import android.widget.BaseAdapter; @@ -164,6 +165,10 @@ public class MenuBuilder implements Menu { */ private int mMaxActionItems; /** + * The total width limit in pixels for all action items within a menu + */ + private int mActionWidthLimit; + /** * Whether or not the items (or any one item's action state) has changed since it was * last fetched. */ @@ -208,6 +213,11 @@ public class MenuBuilder implements Menu { private boolean mOptionalIconsVisible = false; + private ViewGroup mMeasureActionButtonParent; + + // Group IDs that have been added as actions - used temporarily, allocated here for reuse. + private final SparseBooleanArray mActionButtonGroups = new SparseBooleanArray(); + private static int getAlertDialogTheme(Context context) { TypedValue outValue = new TypedValue(); context.getTheme().resolveAttribute(com.android.internal.R.attr.alertDialogTheme, @@ -1035,6 +1045,44 @@ public class MenuBuilder implements Menu { return mVisibleItems; } + /** + * @return A fake action button parent view for obtaining child views. + */ + private ViewGroup getMeasureActionButtonParent() { + if (mMeasureActionButtonParent == null) { + mMeasureActionButtonParent = (ViewGroup) mMenuTypes[TYPE_ACTION_BUTTON].getInflater() + .inflate(LAYOUT_RES_FOR_TYPE[TYPE_ACTION_BUTTON], null, false); + } + return mMeasureActionButtonParent; + } + + /** + * This method determines which menu items get to be 'action items' that will appear + * in an action bar and which items should be 'overflow items' in a secondary menu. + * The rules are as follows: + * + * <p>Items are considered for inclusion in the order specified within the menu. + * There is a limit of mMaxActionItems as a total count, optionally including the overflow + * menu button itself. This is a soft limit; if an item shares a group ID with an item + * previously included as an action item, the new item will stay with its group and become + * an action item itself even if it breaks the max item count limit. This is done to + * limit the conceptual complexity of the items presented within an action bar. Only a few + * unrelated concepts should be presented to the user in this space, and groups are treated + * as a single concept. + * + * <p>There is also a hard limit of consumed measurable space: mActionWidthLimit. This + * limit may be broken by a single item that exceeds the remaining space, but no further + * items may be added. If an item that is part of a group cannot fit within the remaining + * measured width, the entire group will be demoted to overflow. This is done to ensure room + * for navigation and other affordances in the action bar as well as reduce general UI clutter. + * + * <p>The space freed by demoting a full group cannot be consumed by future menu items. + * Once items begin to overflow, all future items become overflow items as well. This is + * to avoid inadvertent reordering that may break the app's intended design. + * + * @param reserveActionOverflow true if an overflow button should consume one space + * in the available item count + */ private void flagActionItems(boolean reserveActionOverflow) { if (reserveActionOverflow != mReserveActionOverflow) { mReserveActionOverflow = reserveActionOverflow; @@ -1048,9 +1096,13 @@ public class MenuBuilder implements Menu { final ArrayList<MenuItemImpl> visibleItems = getVisibleItems(); final int itemsSize = visibleItems.size(); int maxActions = mMaxActionItems; + int widthLimit = mActionWidthLimit; + final int querySpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); + final ViewGroup parent = getMeasureActionButtonParent(); int requiredItems = 0; int requestedItems = 0; + int firstActionWidth = 0; boolean hasOverflow = false; for (int i = 0; i < itemsSize; i++) { MenuItemImpl item = visibleItems.get(i); @@ -1070,12 +1122,68 @@ public class MenuBuilder implements Menu { } maxActions -= requiredItems; + final SparseBooleanArray seenGroups = mActionButtonGroups; + seenGroups.clear(); + // Flag as many more requested items as will fit. for (int i = 0; i < itemsSize; i++) { MenuItemImpl item = visibleItems.get(i); - if (item.requestsActionButton()) { - item.setIsActionButton(maxActions > 0); + + if (item.requiresActionButton()) { + View v = item.getActionView(); + if (v == null) { + v = item.getItemView(TYPE_ACTION_BUTTON, parent); + } + v.measure(querySpec, querySpec); + final int measuredWidth = v.getMeasuredWidth(); + widthLimit -= measuredWidth; + if (firstActionWidth == 0) { + firstActionWidth = measuredWidth; + } + final int groupId = item.getGroupId(); + if (groupId != 0) { + seenGroups.put(groupId, true); + } + } else if (item.requestsActionButton()) { + // Items in a group with other items that already have an action slot + // can break the max actions rule, but not the width limit. + final int groupId = item.getGroupId(); + final boolean inGroup = seenGroups.get(groupId); + boolean isAction = (maxActions > 0 || inGroup) && widthLimit > 0; maxActions--; + + if (isAction) { + View v = item.getActionView(); + if (v == null) { + v = item.getItemView(TYPE_ACTION_BUTTON, parent); + } + v.measure(querySpec, querySpec); + final int measuredWidth = v.getMeasuredWidth(); + widthLimit -= measuredWidth; + if (firstActionWidth == 0) { + firstActionWidth = measuredWidth; + } + + // Did this push the entire first item past halfway? + if (widthLimit + firstActionWidth <= 0) { + isAction = false; + } + } + + if (isAction && groupId != 0) { + seenGroups.put(groupId, true); + } else if (inGroup) { + // We broke the width limit. Demote the whole group, they all overflow now. + seenGroups.put(groupId, false); + for (int j = 0; j < i; j++) { + MenuItemImpl areYouMyGroupie = visibleItems.get(j); + if (areYouMyGroupie.getGroupId() == groupId) { + areYouMyGroupie.setIsActionButton(false); + } + } + } + + item.setIsActionButton(isAction); } } @@ -1108,6 +1216,11 @@ public class MenuBuilder implements Menu { mIsActionItemsStale = true; } + void setActionWidthLimit(int widthLimit) { + mActionWidthLimit = widthLimit; + mIsActionItemsStale = true; + } + public void clearHeader() { mHeaderIcon = null; mHeaderTitle = null; diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index d28bdc91213f..f023e9469578 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -63,7 +63,6 @@ extern int register_android_graphics_MaskFilter(JNIEnv* env); extern int register_android_graphics_Movie(JNIEnv* env); extern int register_android_graphics_NinePatch(JNIEnv*); extern int register_android_graphics_PathEffect(JNIEnv* env); -extern int register_android_graphics_Region(JNIEnv* env); extern int register_android_graphics_Shader(JNIEnv* env); extern int register_android_graphics_Typeface(JNIEnv* env); extern int register_android_graphics_YuvImage(JNIEnv* env); @@ -111,6 +110,7 @@ extern int register_android_graphics_PathMeasure(JNIEnv* env); extern int register_android_graphics_Picture(JNIEnv*); extern int register_android_graphics_PorterDuff(JNIEnv* env); extern int register_android_graphics_Rasterizer(JNIEnv* env); +extern int register_android_graphics_Region(JNIEnv* env); extern int register_android_graphics_SurfaceTexture(JNIEnv* env); extern int register_android_graphics_Xfermode(JNIEnv* env); extern int register_android_graphics_PixelFormat(JNIEnv* env); diff --git a/core/jni/android/graphics/Region.cpp b/core/jni/android/graphics/Region.cpp index 723cd37b8877..c43b5ce14eb1 100644 --- a/core/jni/android/graphics/Region.cpp +++ b/core/jni/android/graphics/Region.cpp @@ -1,8 +1,30 @@ +/* + * Copyright (C) 2011 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. + */ + #include "SkRegion.h" #include "SkPath.h" #include "GraphicsJNI.h" +#include <binder/Parcel.h> +#include "android_util_Binder.h" + #include <jni.h> +#include <android_runtime/AndroidRuntime.h> + +namespace android { static jfieldID gRegion_nativeInstanceFieldID; @@ -134,9 +156,6 @@ static void Region_scale(JNIEnv* env, jobject region, jfloat scale, jobject dst) //////////////////////////////////////////////////////////////////////////////////////////////////////////// -#include <binder/Parcel.h> -#include "android_util_Binder.h" - static SkRegion* Region_createFromParcel(JNIEnv* env, jobject clazz, jobject parcel) { if (parcel == NULL) { @@ -215,8 +234,6 @@ static jboolean RegionIter_next(JNIEnv* env, jobject, RgnIterPair* pair, jobject //////////////////////////////////////////////////////////////////////////////////////////////////////////// -#include <android_runtime/AndroidRuntime.h> - static JNINativeMethod gRegionIterMethods[] = { { "nativeConstructor", "(I)I", (void*)RegionIter_constructor }, { "nativeDestructor", "(I)V", (void*)RegionIter_destructor }, @@ -268,3 +285,9 @@ int register_android_graphics_Region(JNIEnv* env) return android::AndroidRuntime::registerNativeMethods(env, "android/graphics/RegionIterator", gRegionIterMethods, SK_ARRAY_COUNT(gRegionIterMethods)); } + +SkRegion* android_graphics_Region_getSkRegion(JNIEnv* env, jobject regionObj) { + return GetSkRegion(env, regionObj); +} + +} // namespace android diff --git a/core/jni/android/graphics/Region.h b/core/jni/android/graphics/Region.h new file mode 100644 index 000000000000..c15f06edd3cb --- /dev/null +++ b/core/jni/android/graphics/Region.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2011 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. + */ + +#ifndef _ANDROID_GRAPHICS_REGION_H +#define _ANDROID_GRAPHICS_REGION_H + +#include "jni.h" +#include "SkRegion.h" + +namespace android { + +/* Gets the underlying SkRegion from a Region object. */ +extern SkRegion* android_graphics_Region_getSkRegion(JNIEnv* env, jobject regionObj); + +} // namespace android + +#endif // _ANDROID_GRAPHICS_REGION_H diff --git a/core/jni/android/graphics/SurfaceTexture.cpp b/core/jni/android/graphics/SurfaceTexture.cpp index c1229f302977..88de94fe3f2d 100644 --- a/core/jni/android/graphics/SurfaceTexture.cpp +++ b/core/jni/android/graphics/SurfaceTexture.cpp @@ -25,8 +25,8 @@ #include <utils/Log.h> #include <utils/misc.h> -#include "android/graphics/GraphicsJNI.h" #include "jni.h" +#include "JNIHelp.h" // ---------------------------------------------------------------------------- @@ -35,57 +35,127 @@ namespace android { static const char* const OutOfResourcesException = "android/graphics/SurfaceTexture$OutOfResourcesException"; -struct st_t { - jfieldID surfaceTexture; +struct fields_t { + jfieldID surfaceTexture; + jmethodID postEvent; }; -static st_t st; +static fields_t fields; // ---------------------------------------------------------------------------- -static void setSurfaceTexture(JNIEnv* env, jobject clazz, +static void SurfaceTexture_setSurfaceTexture(JNIEnv* env, jobject thiz, const sp<SurfaceTexture>& surfaceTexture) { SurfaceTexture* const p = - (SurfaceTexture*)env->GetIntField(clazz, st.surfaceTexture); + (SurfaceTexture*)env->GetIntField(thiz, fields.surfaceTexture); if (surfaceTexture.get()) { - surfaceTexture->incStrong(clazz); + surfaceTexture->incStrong(thiz); } if (p) { - p->decStrong(clazz); + p->decStrong(thiz); } - env->SetIntField(clazz, st.surfaceTexture, (int)surfaceTexture.get()); + env->SetIntField(thiz, fields.surfaceTexture, (int)surfaceTexture.get()); } -sp<SurfaceTexture> getSurfaceTexture(JNIEnv* env, jobject clazz) +sp<SurfaceTexture> SurfaceTexture_getSurfaceTexture(JNIEnv* env, jobject thiz) { sp<SurfaceTexture> surfaceTexture( - (SurfaceTexture*)env->GetIntField(clazz, st.surfaceTexture)); + (SurfaceTexture*)env->GetIntField(thiz, fields.surfaceTexture)); return surfaceTexture; } // ---------------------------------------------------------------------------- -static void SurfaceTexture_init(JNIEnv* env, jobject clazz, jint texName) +class JNISurfaceTextureContext : public SurfaceTexture::FrameAvailableListener { - sp<SurfaceTexture> surfaceTexture(new SurfaceTexture(texName)); +public: + JNISurfaceTextureContext(JNIEnv* env, jobject weakThiz, jclass clazz); + virtual ~JNISurfaceTextureContext(); + virtual void onFrameAvailable(); + +private: + jobject mWeakThiz; + jclass mClazz; +}; + +JNISurfaceTextureContext::JNISurfaceTextureContext(JNIEnv* env, + jobject weakThiz, jclass clazz) : + mWeakThiz(env->NewGlobalRef(weakThiz)), + mClazz((jclass)env->NewGlobalRef(clazz)) +{} + +JNISurfaceTextureContext::~JNISurfaceTextureContext() +{ + JNIEnv *env = AndroidRuntime::getJNIEnv(); + env->DeleteGlobalRef(mWeakThiz); + env->DeleteGlobalRef(mClazz); +} + +void JNISurfaceTextureContext::onFrameAvailable() +{ + JNIEnv *env = AndroidRuntime::getJNIEnv(); + env->CallStaticVoidMethod(mClazz, fields.postEvent, mWeakThiz); +} + +// ---------------------------------------------------------------------------- + +static void SurfaceTexture_classInit(JNIEnv* env, jclass clazz) +{ + fields.surfaceTexture = env->GetFieldID(clazz, + ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID, "I"); + if (fields.surfaceTexture == NULL) { + LOGE("can't find android/graphics/SurfaceTexture.%s", + ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID); + } + + fields.postEvent = env->GetStaticMethodID(clazz, "postEventFromNative", + "(Ljava/lang/Object;)V"); + if (fields.postEvent == NULL) { + LOGE("can't find android/graphics/SurfaceTexture.postEventFromNative"); + } + +} +static void SurfaceTexture_init(JNIEnv* env, jobject thiz, jint texName, + jobject weakThiz) +{ + sp<SurfaceTexture> surfaceTexture(new SurfaceTexture(texName)); if (surfaceTexture == 0) { - doThrow(env, OutOfResourcesException); + jniThrowException(env, OutOfResourcesException, + "Unable to create native SurfaceTexture"); + return; + } + SurfaceTexture_setSurfaceTexture(env, thiz, surfaceTexture); + + jclass clazz = env->GetObjectClass(thiz); + if (clazz == NULL) { + jniThrowRuntimeException(env, + "Can't find android/graphics/SurfaceTexture"); return; } - setSurfaceTexture(env, clazz, surfaceTexture); + + sp<JNISurfaceTextureContext> ctx(new JNISurfaceTextureContext(env, weakThiz, + clazz)); + surfaceTexture->setFrameAvailableListener(ctx); +} + +static void SurfaceTexture_finalize(JNIEnv* env, jobject thiz) +{ + sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz)); + surfaceTexture->setFrameAvailableListener(0); + SurfaceTexture_setSurfaceTexture(env, thiz, 0); } -static void SurfaceTexture_updateTexImage(JNIEnv* env, jobject clazz) +static void SurfaceTexture_updateTexImage(JNIEnv* env, jobject thiz) { - sp<SurfaceTexture> surfaceTexture(getSurfaceTexture(env, clazz)); + sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz)); surfaceTexture->updateTexImage(); } -static void SurfaceTexture_getTransformMatrix(JNIEnv* env, jobject clazz, +static void SurfaceTexture_getTransformMatrix(JNIEnv* env, jobject thiz, jfloatArray jmtx) { - sp<SurfaceTexture> surfaceTexture(getSurfaceTexture(env, clazz)); + sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz)); float* mtx = env->GetFloatArrayElements(jmtx, NULL); surfaceTexture->getTransformMatrix(mtx); env->ReleaseFloatArrayElements(jmtx, mtx, 0); @@ -94,21 +164,15 @@ static void SurfaceTexture_getTransformMatrix(JNIEnv* env, jobject clazz, // ---------------------------------------------------------------------------- const char* const kSurfaceTextureClassPathName = "android/graphics/SurfaceTexture"; -static void nativeClassInit(JNIEnv* env, jclass clazz); static JNINativeMethod gSurfaceTextureMethods[] = { - {"nativeClassInit", "()V", (void*)nativeClassInit }, - {"init", "(I)V", (void*)SurfaceTexture_init }, - {"updateTexImage", "()V", (void*)SurfaceTexture_updateTexImage }, - {"getTransformMatrixImpl", "([F)V", (void*)SurfaceTexture_getTransformMatrix }, + {"nativeClassInit", "()V", (void*)SurfaceTexture_classInit }, + {"nativeInit", "(ILjava/lang/Object;)V", (void*)SurfaceTexture_init }, + {"nativeFinalize", "()V", (void*)SurfaceTexture_finalize }, + {"nativeUpdateTexImage", "()V", (void*)SurfaceTexture_updateTexImage }, + {"nativeGetTransformMatrix", "([F)V", (void*)SurfaceTexture_getTransformMatrix }, }; -static void nativeClassInit(JNIEnv* env, jclass clazz) -{ - st.surfaceTexture = env->GetFieldID(clazz, - ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID, "I"); -} - int register_android_graphics_SurfaceTexture(JNIEnv* env) { int err = 0; diff --git a/core/jni/android_app_NativeActivity.cpp b/core/jni/android_app_NativeActivity.cpp index b0338787d5f3..0430a819d02d 100644 --- a/core/jni/android_app_NativeActivity.cpp +++ b/core/jni/android_app_NativeActivity.cpp @@ -500,8 +500,9 @@ struct NativeCode : public ANativeActivity { void* dlhandle; ANativeActivity_createFunc* createActivityFunc; - String8 internalDataPath; - String8 externalDataPath; + String8 internalDataPathObj; + String8 externalDataPathObj; + String8 obbPathObj; sp<ANativeWindow> nativeWindow; int32_t lastWindowWidth; @@ -641,8 +642,8 @@ static int mainWorkCallback(int fd, int events, void* data) { static jint loadNativeCode_native(JNIEnv* env, jobject clazz, jstring path, jstring funcName, - jobject messageQueue, - jstring internalDataDir, jstring externalDataDir, int sdkVersion, + jobject messageQueue, jstring internalDataDir, jstring obbDir, + jstring externalDataDir, int sdkVersion, jobject jAssetMgr, jbyteArray savedState) { LOG_TRACE("loadNativeCode_native"); @@ -699,19 +700,24 @@ loadNativeCode_native(JNIEnv* env, jobject clazz, jstring path, jstring funcName code->clazz = env->NewGlobalRef(clazz); const char* dirStr = env->GetStringUTFChars(internalDataDir, NULL); - code->internalDataPath = dirStr; - code->internalDataPath = code->internalDataPath.string(); - env->ReleaseStringUTFChars(path, dirStr); + code->internalDataPathObj = dirStr; + code->internalDataPath = code->internalDataPathObj.string(); + env->ReleaseStringUTFChars(internalDataDir, dirStr); dirStr = env->GetStringUTFChars(externalDataDir, NULL); - code->externalDataPath = dirStr; - code->externalDataPath = code->externalDataPath.string(); - env->ReleaseStringUTFChars(path, dirStr); + code->externalDataPathObj = dirStr; + code->externalDataPath = code->externalDataPathObj.string(); + env->ReleaseStringUTFChars(externalDataDir, dirStr); code->sdkVersion = sdkVersion; code->assetManager = assetManagerForJavaObject(env, jAssetMgr); + dirStr = env->GetStringUTFChars(obbDir, NULL); + code->obbPathObj = dirStr; + code->obbPath = code->obbPathObj.string(); + env->ReleaseStringUTFChars(obbDir, dirStr); + jbyte* rawSavedState = NULL; jsize rawSavedSize = 0; if (savedState != NULL) { @@ -1022,7 +1028,7 @@ finishPreDispatchKeyEvent_native(JNIEnv* env, jobject clazz, jint handle, } static const JNINativeMethod g_methods[] = { - { "loadNativeCode", "(Ljava/lang/String;Ljava/lang/String;Landroid/os/MessageQueue;Ljava/lang/String;Ljava/lang/String;ILandroid/content/res/AssetManager;[B)I", + { "loadNativeCode", "(Ljava/lang/String;Ljava/lang/String;Landroid/os/MessageQueue;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILandroid/content/res/AssetManager;[B)I", (void*)loadNativeCode_native }, { "unloadNativeCode", "(I)V", (void*)unloadNativeCode_native }, { "onStartNative", "(I)V", (void*)onStart_native }, diff --git a/core/res/res/layout-xlarge/keyguard_screen_glogin_unlock.xml b/core/res/res/layout-xlarge/keyguard_screen_glogin_unlock.xml index 8a46546dee58..4f5beff4c205 100644 --- a/core/res/res/layout-xlarge/keyguard_screen_glogin_unlock.xml +++ b/core/res/res/layout-xlarge/keyguard_screen_glogin_unlock.xml @@ -27,12 +27,11 @@ android:layout_height="0px" android:layout_weight="1" android:layout_above="@+id/emergencyCall"> - <RelativeLayout + <RelativeLayout android:layout_width="match_parent" - android:layout_height="match_parent" - > - - <TextView + android:layout_height="match_parent"> + + <TextView android:id="@+id/topHeader" android:layout_width="match_parent" android:layout_height="64dip" @@ -43,7 +42,7 @@ android:drawableLeft="@drawable/ic_lock_idle_lock" android:drawablePadding="5dip" /> - + <!-- spacer below header --> <View android:id="@+id/spacerTop" @@ -51,7 +50,7 @@ android:layout_height="1dip" android:layout_below="@id/topHeader" android:background="@drawable/divider_horizontal_dark"/> - + <TextView android:id="@+id/instructions" android:layout_width="match_parent" @@ -62,7 +61,7 @@ android:textAppearance="?android:attr/textAppearanceSmall" android:text="@android:string/lockscreen_glogin_instructions" /> - + <EditText android:id="@+id/login" android:layout_width="match_parent" @@ -74,7 +73,7 @@ android:hint="@android:string/lockscreen_glogin_username_hint" android:inputType="textEmailAddress" /> - + <EditText android:id="@+id/password" android:layout_width="match_parent" @@ -88,11 +87,11 @@ android:nextFocusRight="@+id/ok" android:nextFocusDown="@+id/ok" /> - + <!-- ok below password, aligned to right of screen --> <Button android:id="@+id/ok" - android:layout_width="85dip" + android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/password" android:layout_marginTop="7dip" @@ -100,10 +99,10 @@ android:layout_alignParentRight="true" android:text="@android:string/lockscreen_glogin_submit_button" /> - + </RelativeLayout> </ScrollView> - + <!-- spacer above emergency call --> <View android:layout_width="match_parent" @@ -121,6 +120,7 @@ android:drawableLeft="@drawable/ic_emergency" android:drawablePadding="8dip" android:text="@android:string/lockscreen_emergency_call" + android:visibility="gone" /> </LinearLayout> diff --git a/core/res/res/layout/search_view.xml b/core/res/res/layout/search_view.xml index 46d0341d3f41..0a7cd3c8c191 100644 --- a/core/res/res/layout/search_view.xml +++ b/core/res/res/layout/search_view.xml @@ -100,8 +100,8 @@ android:id="@+id/search_close_btn" android:layout_width="wrap_content" android:layout_height="match_parent" - android:paddingLeft="4dip" - android:paddingRight="4dip" + android:paddingLeft="8dip" + android:paddingRight="8dip" android:layout_gravity="center_vertical" android:background="?android:attr/selectableItemBackground" android:src="?android:attr/searchViewCloseIcon" @@ -111,26 +111,34 @@ </LinearLayout> - <ImageView - android:id="@+id/search_go_btn" + <LinearLayout + android:id="@+id/submit_area" + android:orientation="horizontal" android:layout_width="wrap_content" - android:layout_height="match_parent" - android:layout_gravity="center_vertical" - android:paddingLeft="4dip" - android:paddingRight="4dip" - android:background="?android:attr/selectableItemBackground" - android:src="?android:attr/searchViewGoIcon" - /> + android:layout_height="match_parent"> - <ImageView - android:id="@+id/search_voice_btn" - android:layout_width="wrap_content" - android:layout_height="match_parent" - android:layout_gravity="center_vertical" - android:paddingLeft="4dip" - android:paddingRight="4dip" - android:src="?android:attr/searchViewVoiceIcon" - android:background="?android:attr/selectableItemBackground" - android:visibility="gone" - /> + <ImageView + android:id="@+id/search_go_btn" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:layout_gravity="center_vertical" + android:paddingLeft="16dip" + android:paddingRight="16dip" + android:background="?android:attr/selectableItemBackground" + android:src="?android:attr/searchViewGoIcon" + android:visibility="gone" + /> + + <ImageView + android:id="@+id/search_voice_btn" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:layout_gravity="center_vertical" + android:paddingLeft="16dip" + android:paddingRight="16dip" + android:src="?android:attr/searchViewVoiceIcon" + android:background="?android:attr/selectableItemBackground" + android:visibility="gone" + /> + </LinearLayout> </LinearLayout> diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml index 5ff6212dd074..a9a7e4af8592 100644 --- a/core/res/res/values/attrs_manifest.xml +++ b/core/res/res/values/attrs_manifest.xml @@ -778,6 +778,13 @@ <attr name="restoreNeedsApplication" /> <attr name="restoreAnyVersion" /> <attr name="neverEncrypt" /> + <!-- Request that your application's processes be created with + a large Dalvik heap. This applies to <em>all</em> processes + created for the application. It only applies to the first + application loaded into a process; if using a sharedUserId + to allow multiple applications to use a process, they all must + use this option consistently or will get unpredictable results. --> + <attr name="largeHeap" format="boolean" /> <!-- Declare that this applicationn can't participate in the normal state save/restore mechanism. Since it is not able to save and restore its state on demand, diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index a8fc4f334ba4..3ad29c4bd933 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -1426,6 +1426,7 @@ <public type="attr" name="windowMinWidthMinor" /> <public type="attr" name="queryHint" /> <public type="attr" name="fastScrollTextColor" /> + <public type="attr" name="largeHeap" /> <!-- A simple fade-in animation. --> <public type="animator" name="fade_in" id="0x010b0000" /> diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml index f65b1f2ba414..744d0d8ffef5 100644 --- a/core/res/res/values/themes.xml +++ b/core/res/res/values/themes.xml @@ -114,7 +114,7 @@ ?android:attr/expandableListPreferredItemPaddingLeft</item> <item name="expandableListPreferredItemIndicatorLeft">3dip</item> - <item name="expandableListPreferredItemIndicatorRight">33dip</item> + <item name="expandableListPreferredItemIndicatorRight">0dip</item> <item name="expandableListPreferredChildIndicatorLeft"> ?android:attr/expandableListPreferredItemIndicatorLeft</item> <item name="expandableListPreferredChildIndicatorRight"> @@ -816,7 +816,7 @@ ?android:attr/expandableListPreferredItemPaddingLeft</item> <item name="expandableListPreferredItemIndicatorLeft">3dip</item> - <item name="expandableListPreferredItemIndicatorRight">33dip</item> + <item name="expandableListPreferredItemIndicatorRight">0dip</item> <item name="expandableListPreferredChildIndicatorLeft"> ?android:attr/expandableListPreferredItemIndicatorLeft</item> <item name="expandableListPreferredChildIndicatorRight"> @@ -1075,7 +1075,7 @@ ?android:attr/expandableListPreferredItemPaddingLeft</item> <item name="expandableListPreferredItemIndicatorLeft">3dip</item> - <item name="expandableListPreferredItemIndicatorRight">33dip</item> + <item name="expandableListPreferredItemIndicatorRight">0dip</item> <item name="expandableListPreferredChildIndicatorLeft"> ?android:attr/expandableListPreferredItemIndicatorLeft</item> <item name="expandableListPreferredChildIndicatorRight"> diff --git a/graphics/java/android/graphics/SurfaceTexture.java b/graphics/java/android/graphics/SurfaceTexture.java index 3eb0b03d4cc1..64c209a38801 100644 --- a/graphics/java/android/graphics/SurfaceTexture.java +++ b/graphics/java/android/graphics/SurfaceTexture.java @@ -16,6 +16,11 @@ package android.graphics; +import java.lang.ref.WeakReference; +import android.os.Handler; +import android.os.Looper; +import android.os.Message; + /** * Captures frames from an image stream as an OpenGL ES texture. * @@ -32,6 +37,9 @@ package android.graphics; */ public class SurfaceTexture { + private EventHandler mEventHandler; + private OnFrameAvailableListener mOnFrameAvailableListener; + @SuppressWarnings("unused") private int mSurfaceTexture; @@ -59,7 +67,15 @@ public class SurfaceTexture { * @param texName the OpenGL texture object name (e.g. generated via glGenTextures) */ public SurfaceTexture(int texName) { - init(texName); + Looper looper; + if ((looper = Looper.myLooper()) != null) { + mEventHandler = new EventHandler(looper); + } else if ((looper = Looper.getMainLooper()) != null) { + mEventHandler = new EventHandler(looper); + } else { + mEventHandler = null; + } + nativeInit(texName, new WeakReference<SurfaceTexture>(this)); } /** @@ -69,7 +85,7 @@ public class SurfaceTexture { * thread invoking the callback. */ public void setOnFrameAvailableListener(OnFrameAvailableListener l) { - // TODO: Implement this! + mOnFrameAvailableListener = l; } /** @@ -77,8 +93,9 @@ public class SurfaceTexture { * called while the OpenGL ES context that owns the texture is bound to the thread. It will * implicitly bind its texture to the GL_TEXTURE_EXTERNAL_OES texture target. */ - public native void updateTexImage(); - + public void updateTexImage() { + nativeUpdateTexImage(); + } /** * Retrieve the 4x4 texture coordinate transform matrix associated with the texture image set by @@ -99,12 +116,48 @@ public class SurfaceTexture { if (mtx.length != 16) { throw new IllegalArgumentException(); } - getTransformMatrixImpl(mtx); + nativeGetTransformMatrix(mtx); } - private native void getTransformMatrixImpl(float[] mtx); + protected void finalize() throws Throwable { + try { + nativeFinalize(); + } finally { + super.finalize(); + } + } + + private class EventHandler extends Handler { + public EventHandler(Looper looper) { + super(looper); + } + + @Override + public void handleMessage(Message msg) { + if (mOnFrameAvailableListener != null) { + mOnFrameAvailableListener.onFrameAvailable(SurfaceTexture.this); + } + return; + } + } + + private static void postEventFromNative(Object selfRef) { + WeakReference weakSelf = (WeakReference)selfRef; + SurfaceTexture st = (SurfaceTexture)weakSelf.get(); + if (st == null) { + return; + } + + if (st.mEventHandler != null) { + Message m = st.mEventHandler.obtainMessage(); + st.mEventHandler.sendMessage(m); + } + } - private native void init(int texName); + private native void nativeInit(int texName, Object weakSelf); + private native void nativeFinalize(); + private native void nativeGetTransformMatrix(float[] mtx); + private native void nativeUpdateTexImage(); /* * We use a class initializer to allow the native code to cache some diff --git a/graphics/java/android/renderscript/Allocation.java b/graphics/java/android/renderscript/Allocation.java index 579f3142f2f4..852aabf5858f 100644 --- a/graphics/java/android/renderscript/Allocation.java +++ b/graphics/java/android/renderscript/Allocation.java @@ -239,15 +239,13 @@ public class Allocation extends BaseObj { } /** - * @hide - * * This is only intended to be used by auto-generate code reflected from the * renderscript script files. * * @param xoff * @param fp */ - public void setOneElement(int xoff, FieldPacker fp) { + public void setFromFieldPacker(int xoff, FieldPacker fp) { int eSize = mType.mElement.getSizeBytes(); final byte[] data = fp.getData(); @@ -262,8 +260,6 @@ public class Allocation extends BaseObj { /** - * @hide - * * This is only intended to be used by auto-generate code reflected from the * renderscript script files. * @@ -271,7 +267,7 @@ public class Allocation extends BaseObj { * @param component_number * @param fp */ - public void setOneComponent(int xoff, int component_number, FieldPacker fp) { + public void setFromFieldPacker(int xoff, int component_number, FieldPacker fp) { if (component_number >= mType.mElement.mElements.length) { throw new RSIllegalArgumentException("Component_number " + component_number + " out of range."); } diff --git a/graphics/java/android/renderscript/Script.java b/graphics/java/android/renderscript/Script.java index b3ad20a3bf4d..56abba51a836 100644 --- a/graphics/java/android/renderscript/Script.java +++ b/graphics/java/android/renderscript/Script.java @@ -21,8 +21,6 @@ package android.renderscript; **/ public class Script extends BaseObj { /** - * @hide - * * Only intended for use by generated reflected code. * * @param slot @@ -32,8 +30,6 @@ public class Script extends BaseObj { } /** - * @hide - * * Only intended for use by generated reflected code. * * @param slot @@ -54,8 +50,6 @@ public class Script extends BaseObj { /** - * @hide - * * Only intended for use by generated reflected code. * * @param va @@ -71,8 +65,6 @@ public class Script extends BaseObj { } /** - * @hide - * * Only intended for use by generated reflected code. * * @param index @@ -83,8 +75,6 @@ public class Script extends BaseObj { } /** - * @hide - * * Only intended for use by generated reflected code. * * @param index @@ -95,8 +85,6 @@ public class Script extends BaseObj { } /** - * @hide - * * Only intended for use by generated reflected code. * * @param index @@ -107,8 +95,6 @@ public class Script extends BaseObj { } /** - * @hide - * * Only intended for use by generated reflected code. * * @param index @@ -119,8 +105,6 @@ public class Script extends BaseObj { } /** - * @hide - * * Only intended for use by generated reflected code. * * @param index @@ -131,8 +115,6 @@ public class Script extends BaseObj { } /** - * @hide - * * Only intended for use by generated reflected code. * * @param index @@ -143,8 +125,6 @@ public class Script extends BaseObj { } /** - * @hide - * * Only intended for use by generated reflected code. * * @param index diff --git a/graphics/java/android/renderscript/ScriptC.java b/graphics/java/android/renderscript/ScriptC.java index 14e4ab5a00f2..ff8f09323503 100644 --- a/graphics/java/android/renderscript/ScriptC.java +++ b/graphics/java/android/renderscript/ScriptC.java @@ -36,8 +36,6 @@ public class ScriptC extends Script { private static final String TAG = "ScriptC"; /** - * @hide - * * Only intended for use by the generated derived classes. * * @param id @@ -48,8 +46,6 @@ public class ScriptC extends Script { } /** - * @hide - * * Only intended for use by the generated derived classes. * * diff --git a/include/gui/SurfaceTexture.h b/include/gui/SurfaceTexture.h index 002e48b6d925..79c33f54f559 100644 --- a/include/gui/SurfaceTexture.h +++ b/include/gui/SurfaceTexture.h @@ -40,6 +40,10 @@ public: enum { MIN_BUFFER_SLOTS = 3 }; enum { NUM_BUFFER_SLOTS = 32 }; + struct FrameAvailableListener : public virtual RefBase { + virtual void onFrameAvailable() = 0; + }; + // tex indicates the name OpenGL texture to which images are to be streamed. // This texture name cannot be changed once the SurfaceTexture is created. SurfaceTexture(GLuint tex); @@ -93,6 +97,10 @@ public: // functions. void getTransformMatrix(float mtx[16]); + // setFrameAvailableListener sets the listener object that will be notified + // when a new frame becomes available. + void setFrameAvailableListener(const sp<FrameAvailableListener>& l); + private: // freeAllBuffers frees the resources (both GraphicBuffer and EGLImage) for @@ -195,6 +203,11 @@ private: // to a buffer, but other processes do. Vector<sp<GraphicBuffer> > mAllocdBuffers; + // mFrameAvailableListener is the listener object that will be called when a + // new frame becomes available. If it is not NULL it will be called from + // queueBuffer. + sp<FrameAvailableListener> mFrameAvailableListener; + // mMutex is the mutex used to prevent concurrent access to the member // variables of SurfaceTexture objects. It must be locked whenever the // member variables are accessed. diff --git a/libs/gui/SurfaceTexture.cpp b/libs/gui/SurfaceTexture.cpp index 447de76508cd..1dadd5389154 100644 --- a/libs/gui/SurfaceTexture.cpp +++ b/libs/gui/SurfaceTexture.cpp @@ -166,6 +166,9 @@ status_t SurfaceTexture::queueBuffer(int buf) { mLastQueued = buf; mLastQueuedCrop = mNextCrop; mLastQueuedTransform = mNextTransform; + if (mFrameAvailableListener != 0) { + mFrameAvailableListener->onFrameAvailable(); + } return OK; } @@ -237,43 +240,68 @@ void SurfaceTexture::getTransformMatrix(float mtx[16]) { LOGV("SurfaceTexture::updateTexImage"); Mutex::Autolock lock(mMutex); - float* xform = mtxIdentity; - switch (mCurrentTransform) { - case 0: - xform = mtxIdentity; - break; - case NATIVE_WINDOW_TRANSFORM_FLIP_H: - xform = mtxFlipH; - break; - case NATIVE_WINDOW_TRANSFORM_FLIP_V: - xform = mtxFlipV; - break; - case NATIVE_WINDOW_TRANSFORM_ROT_90: - xform = mtxRot90; - break; - case NATIVE_WINDOW_TRANSFORM_ROT_180: - xform = mtxRot180; - break; - case NATIVE_WINDOW_TRANSFORM_ROT_270: - xform = mtxRot270; - break; - default: - LOGE("getTransformMatrix: unknown transform: %d", mCurrentTransform); + float xform[16]; + for (int i = 0; i < 16; i++) { + xform[i] = mtxIdentity[i]; + } + if (mCurrentTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) { + float result[16]; + mtxMul(result, xform, mtxFlipH); + for (int i = 0; i < 16; i++) { + xform[i] = result[i]; + } + } + if (mCurrentTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) { + float result[16]; + mtxMul(result, xform, mtxFlipV); + for (int i = 0; i < 16; i++) { + xform[i] = result[i]; + } + } + if (mCurrentTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) { + float result[16]; + mtxMul(result, xform, mtxRot90); + for (int i = 0; i < 16; i++) { + xform[i] = result[i]; + } } sp<GraphicBuffer>& buf(mSlots[mCurrentTexture].mGraphicBuffer); - float tx = float(mCurrentCrop.left) / float(buf->getWidth()); - float ty = float(mCurrentCrop.bottom) / float(buf->getHeight()); - float sx = float(mCurrentCrop.width()) / float(buf->getWidth()); - float sy = float(mCurrentCrop.height()) / float(buf->getHeight()); + float tx, ty, sx, sy; + if (!mCurrentCrop.isEmpty()) { + tx = float(mCurrentCrop.left) / float(buf->getWidth()); + ty = float(buf->getHeight() - mCurrentCrop.bottom) / + float(buf->getHeight()); + sx = float(mCurrentCrop.width()) / float(buf->getWidth()); + sy = float(mCurrentCrop.height()) / float(buf->getHeight()); + } else { + tx = 0.0f; + ty = 0.0f; + sx = 1.0f; + sy = 1.0f; + } float crop[16] = { - sx, 0, 0, sx*tx, - 0, sy, 0, sy*ty, + sx, 0, 0, 0, + 0, sy, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 1, + sx*tx, sy*ty, 0, 1, }; - mtxMul(mtx, crop, xform); + float mtxBeforeFlipV[16]; + mtxMul(mtxBeforeFlipV, crop, xform); + + // SurfaceFlinger expects the top of its window textures to be at a Y + // coordinate of 0, so SurfaceTexture must behave the same way. We don't + // want to expose this to applications, however, so we must add an + // additional vertical flip to the transform after all the other transforms. + mtxMul(mtx, mtxFlipV, mtxBeforeFlipV); +} + +void SurfaceTexture::setFrameAvailableListener( + const sp<FrameAvailableListener>& l) { + LOGV("SurfaceTexture::setFrameAvailableListener"); + Mutex::Autolock lock(mMutex); + mFrameAvailableListener = l; } void SurfaceTexture::freeAllBuffers() { diff --git a/libs/hwui/Debug.h b/libs/hwui/Debug.h index bdd8e7357200..71ec7609f0d0 100644 --- a/libs/hwui/Debug.h +++ b/libs/hwui/Debug.h @@ -37,6 +37,10 @@ // Turn on to display vertex and tex coords data about 9patch objects // This flag requires DEBUG_PATCHES to be turned on #define DEBUG_PATCHES_VERTICES 0 +// Turn on to display vertex and tex coords data used by empty quads +// in 9patch objects +// This flag requires DEBUG_PATCHES to be turned on +#define DEBUG_PATCHES_EMPTY_VERTICES 0 // Turn on to display debug info about paths #define DEBUG_PATHS 0 diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h index 7d54d3b3255d..bb2843790ed7 100644 --- a/libs/hwui/Layer.h +++ b/libs/hwui/Layer.h @@ -27,6 +27,7 @@ #include "Rect.h" #include "SkiaColorFilter.h" +#include "Vertex.h" namespace android { namespace uirenderer { @@ -41,6 +42,14 @@ namespace uirenderer { struct Layer { Layer(const uint32_t layerWidth, const uint32_t layerHeight): width(layerWidth), height(layerHeight) { + mesh = NULL; + meshIndices = NULL; + meshElementCount = 0; + } + + ~Layer() { + if (mesh) delete mesh; + if (meshIndices) delete meshIndices; } /** @@ -99,6 +108,13 @@ struct Layer { * Color filter used to draw this layer. Optional. */ SkiaColorFilter* colorFilter; + + /** + * If the layer can be rendered as a mesh, this is non-null. + */ + TextureVertex* mesh; + uint16_t* meshIndices; + GLsizei meshElementCount; }; // struct Layer }; // namespace uirenderer diff --git a/libs/hwui/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp index a25c95ed6614..e6bea786dfdc 100644 --- a/libs/hwui/LayerRenderer.cpp +++ b/libs/hwui/LayerRenderer.cpp @@ -39,11 +39,100 @@ void LayerRenderer::finish() { OpenGLRenderer::finish(); glBindFramebuffer(GL_FRAMEBUFFER, mPreviousFbo); + generateMesh(); + LAYER_RENDERER_LOGD("Finished rendering into layer, fbo = %d", mLayer->mFbo); } /////////////////////////////////////////////////////////////////////////////// -// Static functions +// Dirty region tracking +/////////////////////////////////////////////////////////////////////////////// + +bool LayerRenderer::hasLayer() { + return true; +} + +Region* LayerRenderer::getRegion() { +#if RENDER_LAYERS_AS_REGIONS + if (getSnapshot()->flags & Snapshot::kFlagFboTarget) { + return OpenGLRenderer::getRegion(); + } + return &mLayer->region; +#else + return OpenGLRenderer::getRegion(); +#endif +} + +void LayerRenderer::generateMesh() { +#if RENDER_LAYERS_AS_REGIONS + if (mLayer->region.isRect() || mLayer->region.isEmpty()) { + if (mLayer->mesh) { + delete mLayer->mesh; + delete mLayer->meshIndices; + + mLayer->mesh = NULL; + mLayer->meshIndices = NULL; + mLayer->meshElementCount = 0; + } + mLayer->region.clear(); + return; + } + + size_t count; + const android::Rect* rects = mLayer->region.getArray(&count); + + GLsizei elementCount = count * 6; + + if (mLayer->mesh && mLayer->meshElementCount < elementCount) { + delete mLayer->mesh; + delete mLayer->meshIndices; + + mLayer->mesh = NULL; + mLayer->meshIndices = NULL; + } + + if (!mLayer->mesh) { + mLayer->mesh = new TextureVertex[count * 4]; + mLayer->meshIndices = new uint16_t[elementCount]; + mLayer->meshElementCount = elementCount; + } + + const float texX = 1.0f / float(mLayer->width); + const float texY = 1.0f / float(mLayer->height); + const float height = mLayer->layer.getHeight(); + + TextureVertex* mesh = mLayer->mesh; + uint16_t* indices = mLayer->meshIndices; + + for (size_t i = 0; i < count; i++) { + const android::Rect* r = &rects[i]; + + const float u1 = r->left * texX; + const float v1 = (height - r->top) * texY; + const float u2 = r->right * texX; + const float v2 = (height - r->bottom) * texY; + + TextureVertex::set(mesh++, r->left, r->top, u1, v1); + TextureVertex::set(mesh++, r->right, r->top, u2, v1); + TextureVertex::set(mesh++, r->left, r->bottom, u1, v2); + TextureVertex::set(mesh++, r->right, r->bottom, u2, v2); + + uint16_t quad = i * 4; + int index = i * 6; + indices[index ] = quad; // top-left + indices[index + 1] = quad + 1; // top-right + indices[index + 2] = quad + 2; // bottom-left + indices[index + 3] = quad + 2; // bottom-left + indices[index + 4] = quad + 1; // top-right + indices[index + 5] = quad + 3; // bottom-right + } + + mLayer->region.clear(); +#endif +} + +/////////////////////////////////////////////////////////////////////////////// +// Layers management /////////////////////////////////////////////////////////////////////////////// Layer* LayerRenderer::createLayer(uint32_t width, uint32_t height, bool isOpaque) { diff --git a/libs/hwui/LayerRenderer.h b/libs/hwui/LayerRenderer.h index ed5d9609c001..f2fb898b21c7 100644 --- a/libs/hwui/LayerRenderer.h +++ b/libs/hwui/LayerRenderer.h @@ -49,12 +49,17 @@ public: void prepare(bool opaque); void finish(); + bool hasLayer(); + Region* getRegion(); + static Layer* createLayer(uint32_t width, uint32_t height, bool isOpaque = false); static bool resizeLayer(Layer* layer, uint32_t width, uint32_t height); static void destroyLayer(Layer* layer); static void destroyLayerDeferred(Layer* layer); private: + void generateMesh(); + Layer* mLayer; GLuint mPreviousFbo; diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index b9332327df99..16a1de7adc32 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -615,6 +615,7 @@ void OpenGLRenderer::composeLayerRegion(Layer* layer, const Rect& rect) { const float alpha = layer->alpha / 255.0f; const float texX = 1.0f / float(layer->width); const float texY = 1.0f / float(layer->height); + const float height = rect.getHeight(); TextureVertex* mesh = mCaches.getRegionMesh(); GLsizei numQuads = 0; @@ -636,9 +637,9 @@ void OpenGLRenderer::composeLayerRegion(Layer* layer, const Rect& rect) { const android::Rect* r = &rects[i]; const float u1 = r->left * texX; - const float v1 = (rect.getHeight() - r->top) * texY; + const float v1 = (height - r->top) * texY; const float u2 = r->right * texX; - const float v2 = (rect.getHeight() - r->bottom) * texY; + const float v2 = (height - r->bottom) * texY; // TODO: Reject quads outside of the clip TextureVertex::set(mesh++, r->left, r->top, u1, v1); @@ -694,10 +695,10 @@ void OpenGLRenderer::composeLayerRegion(Layer* layer, const Rect& rect) { void OpenGLRenderer::dirtyLayer(const float left, const float top, const float right, const float bottom, const mat4 transform) { #if RENDER_LAYERS_AS_REGIONS - if ((mSnapshot->flags & Snapshot::kFlagFboTarget) && mSnapshot->region) { + if (hasLayer()) { Rect bounds(left, top, right, bottom); transform.mapRect(bounds); - dirtyLayerUnchecked(bounds, mSnapshot->region); + dirtyLayerUnchecked(bounds, getRegion()); } #endif } @@ -705,9 +706,9 @@ void OpenGLRenderer::dirtyLayer(const float left, const float top, void OpenGLRenderer::dirtyLayer(const float left, const float top, const float right, const float bottom) { #if RENDER_LAYERS_AS_REGIONS - if ((mSnapshot->flags & Snapshot::kFlagFboTarget) && mSnapshot->region) { + if (hasLayer()) { Rect bounds(left, top, right, bottom); - dirtyLayerUnchecked(bounds, mSnapshot->region); + dirtyLayerUnchecked(bounds, getRegion()); } #endif } @@ -1419,24 +1420,20 @@ void OpenGLRenderer::drawText(const char* text, int bytesCount, int count, Rect bounds(FLT_MAX / 2.0f, FLT_MAX / 2.0f, FLT_MIN / 2.0f, FLT_MIN / 2.0f); #if RENDER_LAYERS_AS_REGIONS - bool hasLayer = (mSnapshot->flags & Snapshot::kFlagFboTarget) && mSnapshot->region; + bool hasActiveLayer = hasLayer(); #else - bool hasLayer = false; + bool hasActiveLayer = false; #endif mCaches.unbindMeshBuffer(); if (fontRenderer.renderText(paint, clip, text, 0, bytesCount, count, x, y, - hasLayer ? &bounds : NULL)) { + hasActiveLayer ? &bounds : NULL)) { #if RENDER_LAYERS_AS_REGIONS - if (hasLayer) { + if (hasActiveLayer) { if (!pureTranslate) { mSnapshot->transform->mapRect(bounds); } - bounds.intersect(*mSnapshot->clipRect); - bounds.snapToPixelBoundaries(); - - android::Rect dirty(bounds.left, bounds.top, bounds.right, bounds.bottom); - mSnapshot->region->orSelf(dirty); + dirtyLayerUnchecked(bounds, getRegion()); } #endif } @@ -1501,8 +1498,36 @@ void OpenGLRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) { layer->alpha = alpha; layer->mode = mode; + +#if RENDER_LAYERS_AS_REGIONS + if (layer->region.isRect()) { + const Rect r(x, y, x + layer->layer.getWidth(), y + layer->layer.getHeight()); + composeLayerRect(layer, r); + } else if (!layer->region.isEmpty() && layer->mesh) { + const Rect& rect = layer->layer; + + setupDraw(); + setupDrawWithTexture(); + setupDrawColor(alpha, alpha, alpha, alpha); + setupDrawColorFilter(); + setupDrawBlending(layer->blend || layer->alpha < 255, layer->mode, false); + setupDrawProgram(); + setupDrawDirtyRegionsDisabled(); + setupDrawPureColorUniforms(); + setupDrawColorFilterUniforms(); + setupDrawTexture(layer->texture); + setupDrawModelViewTranslate(rect.left, rect.top, rect.right, rect.bottom); + setupDrawMesh(&layer->mesh[0].position[0], &layer->mesh[0].texture[0]); + + glDrawElements(GL_TRIANGLES, layer->meshElementCount, + GL_UNSIGNED_SHORT, layer->meshIndices); + + finishDrawTexture(); + } +#else const Rect r(x, y, x + layer->layer.getWidth(), y + layer->layer.getHeight()); composeLayerRect(layer, r); +#endif } /////////////////////////////////////////////////////////////////////////////// diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h index 56be13458e10..7387b9268c39 100644 --- a/libs/hwui/OpenGLRenderer.h +++ b/libs/hwui/OpenGLRenderer.h @@ -133,19 +133,24 @@ protected: virtual void composeLayer(sp<Snapshot> current, sp<Snapshot> previous); /** - * Mark the layer as dirty at the specified coordinates. The coordinates - * are transformed with the supplied matrix. + * Marks the specified region as dirty at the specified bounds. */ - virtual void dirtyLayer(const float left, const float top, - const float right, const float bottom, const mat4 transform); + void dirtyLayerUnchecked(Rect& bounds, Region* region); /** - * Mark the layer as dirty at the specified coordinates. + * Returns the current snapshot. */ - virtual void dirtyLayer(const float left, const float top, - const float right, const float bottom); + sp<Snapshot> getSnapshot() { + return mSnapshot; + } - void dirtyLayerUnchecked(Rect& bounds, Region* region); + virtual Region* getRegion() { + return mSnapshot->region; + } + + virtual bool hasLayer() { + return (mSnapshot->flags & Snapshot::kFlagFboTarget) && mSnapshot->region; + } private: /** @@ -225,6 +230,19 @@ private: void clearLayerRegions(); /** + * Mark the layer as dirty at the specified coordinates. The coordinates + * are transformed with the supplied matrix. + */ + void dirtyLayer(const float left, const float top, + const float right, const float bottom, const mat4 transform); + + /** + * Mark the layer as dirty at the specified coordinates. + */ + void dirtyLayer(const float left, const float top, + const float right, const float bottom); + + /** * Draws a colored rectangle with the specified color. The specified coordinates * are transformed by the current snapshot's transform matrix. * diff --git a/libs/hwui/Patch.cpp b/libs/hwui/Patch.cpp index e5cb67b81be3..77cbb80fa4da 100644 --- a/libs/hwui/Patch.cpp +++ b/libs/hwui/Patch.cpp @@ -212,7 +212,7 @@ void Patch::generateRow(TextureVertex*& vertex, float y1, float y2, float v1, fl } float u2 = fmax(0.0f, stepX - 0.5f) / bitmapWidth; - generateQuad(vertex, x1, y1, x2, y2, u1, v1, u2, v2, quadCount); + bool valid = generateQuad(vertex, x1, y1, x2, y2, u1, v1, u2, v2, quadCount); x1 = x2; u1 = (stepX + 0.5f) / bitmapWidth; @@ -223,17 +223,22 @@ void Patch::generateRow(TextureVertex*& vertex, float y1, float y2, float v1, fl generateQuad(vertex, x1, y1, width, y2, u1, v1, 1.0f, v2, quadCount); } -void Patch::generateQuad(TextureVertex*& vertex, float x1, float y1, float x2, float y2, +bool Patch::generateQuad(TextureVertex*& vertex, float x1, float y1, float x2, float y2, float u1, float v1, float u2, float v2, uint32_t& quadCount) { const uint32_t oldQuadCount = quadCount; - const bool valid = x2 - x1 > 0.9999f && y2 - y1 > 0.9999f; + const bool valid = x2 >= x1 && y2 >= y1; if (valid) { quadCount++; } // Skip degenerate and transparent (empty) quads if (!valid || ((mColorKey >> oldQuadCount) & 0x1) == 1) { - return; +#if DEBUG_PATCHES_EMPTY_VERTICES + PATCH_LOGD(" quad %d (empty)", oldQuadCount); + PATCH_LOGD(" left, top = %.2f, %.2f\t\tu1, v1 = %.2f, %.2f", x1, y1, u1, v1); + PATCH_LOGD(" right, bottom = %.2f, %.2f\t\tu2, v2 = %.2f, %.2f", x2, y2, u2, v2); +#endif + return false; } #if RENDER_LAYERS_AS_REGIONS @@ -262,6 +267,8 @@ void Patch::generateQuad(TextureVertex*& vertex, float x1, float y1, float x2, f PATCH_LOGD(" left, top = %.2f, %.2f\t\tu1, v1 = %.2f, %.2f", x1, y1, u1, v1); PATCH_LOGD(" right, bottom = %.2f, %.2f\t\tu2, v2 = %.2f, %.2f", x2, y2, u2, v2); #endif + + return true; } }; // namespace uirenderer diff --git a/libs/hwui/Patch.h b/libs/hwui/Patch.h index 0f0ffa22594e..45ce99842c20 100644 --- a/libs/hwui/Patch.h +++ b/libs/hwui/Patch.h @@ -71,7 +71,7 @@ private: void generateRow(TextureVertex*& vertex, float y1, float y2, float v1, float v2, float stretchX, float width, float bitmapWidth, uint32_t& quadCount); - void generateQuad(TextureVertex*& vertex, + bool generateQuad(TextureVertex*& vertex, float x1, float y1, float x2, float y2, float u1, float v1, float u2, float v2, uint32_t& quadCount); diff --git a/libs/hwui/Snapshot.h b/libs/hwui/Snapshot.h index 9898df491eba..595ad4e92e3b 100644 --- a/libs/hwui/Snapshot.h +++ b/libs/hwui/Snapshot.h @@ -268,7 +268,7 @@ public: Rect* clipRect; /** - * The ancestor layer's dirty region.. + * The ancestor layer's dirty region. */ Region* region; diff --git a/libs/rs/java/ImageProcessing/src/com/android/rs/image/vertical_blur.rs b/libs/rs/java/ImageProcessing/src/com/android/rs/image/vertical_blur.rs index aa4cf2d90597..4615e1fba4e4 100644 --- a/libs/rs/java/ImageProcessing/src/com/android/rs/image/vertical_blur.rs +++ b/libs/rs/java/ImageProcessing/src/com/android/rs/image/vertical_blur.rs @@ -56,7 +56,7 @@ void setGamma(float g) { } //sliao -uchar3 convert2uchar3(float3 xyz); +extern uchar3 __attribute__((overloadable)) convert2uchar3(float3 xyz); void root(const void *v_in, void *v_out, const void *usrData, uint32_t x, uint32_t y) { uchar4 *output = (uchar4 *)v_out; diff --git a/libs/rs/rsAllocation.cpp b/libs/rs/rsAllocation.cpp index 2ed77749a311..41c9fe2d016c 100644 --- a/libs/rs/rsAllocation.cpp +++ b/libs/rs/rsAllocation.cpp @@ -188,12 +188,7 @@ void Allocation::uploadToTexture(const Context *rsc) { isFirstUpload = true; } - GLenum target = (GLenum)getGLTarget(); - if (target == GL_TEXTURE_2D) { - upload2DTexture(isFirstUpload, mPtr); - } else if (target == GL_TEXTURE_CUBE_MAP) { - uploadCubeTexture(isFirstUpload); - } + upload2DTexture(isFirstUpload); if (!(mUsageFlags & RS_ALLOCATION_USAGE_SCRIPT)) { freeScriptMemory(); @@ -202,48 +197,32 @@ void Allocation::uploadToTexture(const Context *rsc) { rsc->checkError("Allocation::uploadToTexture"); } +const static GLenum gFaceOrder[] = { + GL_TEXTURE_CUBE_MAP_POSITIVE_X, + GL_TEXTURE_CUBE_MAP_NEGATIVE_X, + GL_TEXTURE_CUBE_MAP_POSITIVE_Y, + GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, + GL_TEXTURE_CUBE_MAP_POSITIVE_Z, + GL_TEXTURE_CUBE_MAP_NEGATIVE_Z +}; + void Allocation::update2DTexture(const void *ptr, uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face, uint32_t w, uint32_t h) { GLenum type = mType->getElement()->getComponent().getGLType(); GLenum format = mType->getElement()->getComponent().getGLFormat(); GLenum target = (GLenum)getGLTarget(); + rsAssert(mTextureID); glBindTexture(target, mTextureID); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glTexSubImage2D(GL_TEXTURE_2D, lod, xoff, yoff, w, h, format, type, ptr); -} - -void Allocation::upload2DTexture(bool isFirstUpload, const void *ptr) { - GLenum type = mType->getElement()->getComponent().getGLType(); - GLenum format = mType->getElement()->getComponent().getGLFormat(); - - GLenum target = (GLenum)getGLTarget(); - glBindTexture(target, mTextureID); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - - for (uint32_t lod = 0; lod < mType->getLODCount(); lod++) { - const uint8_t *p = (const uint8_t *)ptr; - p += mType->getLODOffset(lod); - - if (isFirstUpload) { - glTexImage2D(GL_TEXTURE_2D, lod, format, - mType->getLODDimX(lod), mType->getLODDimY(lod), - 0, format, type, p); - } else { - glTexSubImage2D(GL_TEXTURE_2D, lod, 0, 0, - mType->getLODDimX(lod), mType->getLODDimY(lod), - format, type, p); - } - } - - if (mMipmapControl == RS_ALLOCATION_MIPMAP_ON_SYNC_TO_TEXTURE) { -#ifndef ANDROID_RS_BUILD_FOR_HOST - glGenerateMipmap(target); -#endif //ANDROID_RS_BUILD_FOR_HOST + GLenum t = GL_TEXTURE_2D; + if (mType->getDimFaces()) { + t = gFaceOrder[face]; } + glTexSubImage2D(t, lod, xoff, yoff, w, h, format, type, ptr); } -void Allocation::uploadCubeTexture(bool isFirstUpload) { +void Allocation::upload2DTexture(bool isFirstUpload) { GLenum type = mType->getElement()->getComponent().getGLType(); GLenum format = mType->getElement()->getComponent().getGLFormat(); @@ -251,32 +230,29 @@ void Allocation::uploadCubeTexture(bool isFirstUpload) { glBindTexture(target, mTextureID); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - GLenum faceOrder[] = { - GL_TEXTURE_CUBE_MAP_POSITIVE_X, - GL_TEXTURE_CUBE_MAP_NEGATIVE_X, - GL_TEXTURE_CUBE_MAP_POSITIVE_Y, - GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, - GL_TEXTURE_CUBE_MAP_POSITIVE_Z, - GL_TEXTURE_CUBE_MAP_NEGATIVE_Z - }; - - Adapter2D adapt(getContext(), this); - for (uint32_t face = 0; face < 6; face ++) { - adapt.setFace(face); + uint32_t faceCount = 1; + if (mType->getDimFaces()) { + faceCount = 6; + } + for (uint32_t face = 0; face < faceCount; face ++) { for (uint32_t lod = 0; lod < mType->getLODCount(); lod++) { - adapt.setLOD(lod); + const uint8_t *p = (const uint8_t *)mPtr; + p += mType->getLODFaceOffset(lod, (RsAllocationCubemapFace)face, 0, 0); - uint16_t * ptr = static_cast<uint16_t *>(adapt.getElement(0,0)); + GLenum t = GL_TEXTURE_2D; + if (mType->getDimFaces()) { + t = gFaceOrder[face]; + } if (isFirstUpload) { - glTexImage2D(faceOrder[face], lod, format, - adapt.getDimX(), adapt.getDimY(), - 0, format, type, ptr); + glTexImage2D(t, lod, format, + mType->getLODDimX(lod), mType->getLODDimY(lod), + 0, format, type, p); } else { - glTexSubImage2D(faceOrder[face], lod, 0, 0, - adapt.getDimX(), adapt.getDimY(), - format, type, ptr); + glTexSubImage2D(t, lod, 0, 0, + mType->getLODDimX(lod), mType->getLODDimY(lod), + format, type, p); } } } @@ -364,7 +340,7 @@ void Allocation::data(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t lod, if (mPtr) { const uint8_t *src = static_cast<const uint8_t *>(data); uint8_t *dst = static_cast<uint8_t *>(mPtr); - dst += mType->getLODOffset(lod, xoff, yoff); + dst += mType->getLODFaceOffset(lod, face, xoff, yoff); //LOGE(" %p %p %i ", dst, src, eSize); for (uint32_t line=yoff; line < (yoff+h); line++) { diff --git a/libs/rs/rsAllocation.h b/libs/rs/rsAllocation.h index a160765b9773..4f5d5a8e351f 100644 --- a/libs/rs/rsAllocation.h +++ b/libs/rs/rsAllocation.h @@ -105,9 +105,6 @@ public: return mMipmapControl != RS_ALLOCATION_MIPMAP_NONE; } - void upload2DTexture(bool isFirstUpload, const void *ptr); - void update2DTexture(const void *ptr, uint32_t xoff, uint32_t yoff, - uint32_t lod, RsAllocationCubemapFace face, uint32_t w, uint32_t h); protected: ObjectBaseRef<const Type> mType; @@ -149,7 +146,9 @@ protected: private: void init(Context *rsc, const Type *); - void uploadCubeTexture(bool isFirstUpload); + void upload2DTexture(bool isFirstUpload); + void update2DTexture(const void *ptr, uint32_t xoff, uint32_t yoff, + uint32_t lod, RsAllocationCubemapFace face, uint32_t w, uint32_t h); void allocScriptMemory(); void freeScriptMemory(); diff --git a/libs/rs/rsScriptC.cpp b/libs/rs/rsScriptC.cpp index 0ecb18a28d88..1ab210950525 100644 --- a/libs/rs/rsScriptC.cpp +++ b/libs/rs/rsScriptC.cpp @@ -490,7 +490,8 @@ void ScriptCState::runCompiler(Context *rsc, if (bccLinkBC(s->mBccScript, resName, NULL /*rs_runtime_lib_bc*/, - 0 /*rs_runtime_lib_bc_size*/, + 1 /*rs_runtime_lib_bc_size*/ + /*"1" means skip buffer here, and let libbcc decide*/, 0) != 0) { LOGE("bcc: FAILS to link bitcode"); // Handle Fatal Error diff --git a/libs/rs/rsThreadIO.cpp b/libs/rs/rsThreadIO.cpp index 1c6c5ac426bb..001ac5529e20 100644 --- a/libs/rs/rsThreadIO.cpp +++ b/libs/rs/rsThreadIO.cpp @@ -53,6 +53,10 @@ bool ThreadIO::playCoreCommands(Context *con, bool waitForCommand) { waitForCommand = false; //LOGV("playCoreCommands 3 %i %i", cmdID, cmdSize); + if (cmdID >= (sizeof(gPlaybackFuncs) / sizeof(void *))) { + rsAssert(cmdID < (sizeof(gPlaybackFuncs) / sizeof(void *))); + LOGE("playCoreCommands error con %p, cmd %i", con, cmdID); + } gPlaybackFuncs[cmdID](con, data); mToCore.next(); } diff --git a/libs/rs/rsType.cpp b/libs/rs/rsType.cpp index 670ea33a111f..d7b5f1204361 100644 --- a/libs/rs/rsType.cpp +++ b/libs/rs/rsType.cpp @@ -132,6 +132,17 @@ uint32_t Type::getLODOffset(uint32_t lod, uint32_t x, uint32_t y, uint32_t z) co return offset; } +uint32_t Type::getLODFaceOffset(uint32_t lod, RsAllocationCubemapFace face, uint32_t x, uint32_t y) const { + uint32_t offset = mLODs[lod].mOffset; + offset += (x + y * mLODs[lod].mX) * mElement->getSizeBytes(); + + if (face != 0) { + uint32_t faceOffset = getSizeBytes() / 6; + offset += faceOffset * face; + } + return offset; +} + void Type::dumpLOGV(const char *prefix) const { char buf[1024]; ObjectBase::dumpLOGV(prefix); diff --git a/libs/rs/rsType.h b/libs/rs/rsType.h index 34498f076464..90ae039da3e3 100644 --- a/libs/rs/rsType.h +++ b/libs/rs/rsType.h @@ -44,12 +44,14 @@ public: uint32_t getLODDimX(uint32_t lod) const {rsAssert(lod < mLODCount); return mLODs[lod].mX;} uint32_t getLODDimY(uint32_t lod) const {rsAssert(lod < mLODCount); return mLODs[lod].mY;} uint32_t getLODDimZ(uint32_t lod) const {rsAssert(lod < mLODCount); return mLODs[lod].mZ;} - uint32_t getLODOffset(uint32_t lod) const {rsAssert(lod < mLODCount); return mLODs[lod].mOffset;} + uint32_t getLODOffset(uint32_t lod) const {rsAssert(lod < mLODCount); return mLODs[lod].mOffset;} uint32_t getLODOffset(uint32_t lod, uint32_t x) const; uint32_t getLODOffset(uint32_t lod, uint32_t x, uint32_t y) const; uint32_t getLODOffset(uint32_t lod, uint32_t x, uint32_t y, uint32_t z) const; + uint32_t getLODFaceOffset(uint32_t lod, RsAllocationCubemapFace face, uint32_t x, uint32_t y) const; + uint32_t getLODCount() const {return mLODCount;} bool getIsNp2() const; diff --git a/libs/rs/rsg_generator.c b/libs/rs/rsg_generator.c index 1e468bb985e4..4ac5b7fce136 100644 --- a/libs/rs/rsg_generator.c +++ b/libs/rs/rsg_generator.c @@ -219,7 +219,7 @@ void printPlaybackCpp(FILE *f) { fprintf(f, "};\n\n"); } - fprintf(f, "RsPlaybackFunc gPlaybackFuncs[] = {\n"); + fprintf(f, "RsPlaybackFunc gPlaybackFuncs[%i] = {\n", apiCount + 1); fprintf(f, " NULL,\n"); for (ct=0; ct < apiCount; ct++) { fprintf(f, " %s%s,\n", "rsp_", apis[ct].name); @@ -265,7 +265,7 @@ int main(int argc, char **argv) { printFuncDecls(f, "rsi_", 1); printPlaybackFuncs(f, "rsp_"); fprintf(f, "\n\ntypedef void (*RsPlaybackFunc)(Context *, const void *);\n"); - fprintf(f, "extern RsPlaybackFunc gPlaybackFuncs[];\n"); + fprintf(f, "extern RsPlaybackFunc gPlaybackFuncs[%i];\n", apiCount + 1); fprintf(f, "}\n"); fprintf(f, "}\n"); diff --git a/native/android/looper.cpp b/native/android/looper.cpp index 9f5cda9a9e98..615493fe9a6c 100644 --- a/native/android/looper.cpp +++ b/native/android/looper.cpp @@ -19,9 +19,11 @@ #include <android/looper.h> #include <utils/Looper.h> +#include <binder/IPCThreadState.h> using android::Looper; using android::sp; +using android::IPCThreadState; ALooper* ALooper_forThread() { return Looper::getForThread().get(); @@ -46,6 +48,7 @@ int ALooper_pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outDa return ALOOPER_POLL_ERROR; } + IPCThreadState::self()->flushCommands(); return looper->pollOnce(timeoutMillis, outFd, outEvents, outData); } @@ -55,7 +58,8 @@ int ALooper_pollAll(int timeoutMillis, int* outFd, int* outEvents, void** outDat LOGE("ALooper_pollAll: No looper for this thread!"); return ALOOPER_POLL_ERROR; } - + + IPCThreadState::self()->flushCommands(); return looper->pollAll(timeoutMillis, outFd, outEvents, outData); } diff --git a/native/include/android/native_activity.h b/native/include/android/native_activity.h index d89bc8b9b6d3..a361846ea416 100644 --- a/native/include/android/native_activity.h +++ b/native/include/android/native_activity.h @@ -91,6 +91,13 @@ typedef struct ANativeActivity { * uses this to access binary assets bundled inside its own .apk file. */ AAssetManager* assetManager; + + /** + * Available starting with Honeycomb: path to the directory containing + * the application's OBB files (if any). If the app doesn't have any + * OBB files, this directory may not exist. + */ + const char* obbPath; } ANativeActivity; /** diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp index 386cc5d05268..ed3617182cf4 100644 --- a/opengl/libs/EGL/egl.cpp +++ b/opengl/libs/EGL/egl.cpp @@ -62,6 +62,8 @@ static char const * const gExtensionString = "EGL_KHR_image_base " "EGL_KHR_image_pixmap " "EGL_KHR_gl_texture_2D_image " + "EGL_KHR_gl_texture_cubemap_image " + "EGL_KHR_gl_renderbuffer_image " "EGL_KHR_fence_sync " "EGL_ANDROID_image_native_buffer " "EGL_ANDROID_swap_rectangle " @@ -1471,6 +1473,29 @@ EGLint eglGetError(void) return result; } +// Note: Similar implementations of these functions also exist in +// gl2.cpp and gl.cpp, and are used by applications that call the +// exported entry points directly. +typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) (GLenum target, GLeglImageOES image); +typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC) (GLenum target, GLeglImageOES image); + +static PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES_impl = NULL; +static PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC glEGLImageTargetRenderbufferStorageOES_impl = NULL; + +static void glEGLImageTargetTexture2DOES_wrapper(GLenum target, GLeglImageOES image) +{ + GLeglImageOES implImage = + (GLeglImageOES)egl_get_image_for_current_context((EGLImageKHR)image); + glEGLImageTargetTexture2DOES_impl(target, implImage); +} + +static void glEGLImageTargetRenderbufferStorageOES_wrapper(GLenum target, GLeglImageOES image) +{ + GLeglImageOES implImage = + (GLeglImageOES)egl_get_image_for_current_context((EGLImageKHR)image); + glEGLImageTargetRenderbufferStorageOES_impl(target, implImage); +} + __eglMustCastToProperFunctionPointerType eglGetProcAddress(const char *procname) { // eglGetProcAddress() could be the very first function called @@ -1531,6 +1556,16 @@ __eglMustCastToProperFunctionPointerType eglGetProcAddress(const char *procname) } if (found) { addr = gExtensionForwarders[slot]; + + if (!strcmp(procname, "glEGLImageTargetTexture2DOES")) { + glEGLImageTargetTexture2DOES_impl = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)addr; + addr = (__eglMustCastToProperFunctionPointerType)glEGLImageTargetTexture2DOES_wrapper; + } + if (!strcmp(procname, "glEGLImageTargetRenderbufferStorageOES")) { + glEGLImageTargetRenderbufferStorageOES_impl = (PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC)addr; + addr = (__eglMustCastToProperFunctionPointerType)glEGLImageTargetRenderbufferStorageOES_wrapper; + } + gGLExtentionMap.add(name, addr); gGLExtentionSlot++; } diff --git a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java index 0c85af8e34d1..2ec222651436 100644 --- a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java +++ b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java @@ -165,8 +165,13 @@ public class DefaultContainerService extends IntentService { } @Override - public long calculateDirectorySize(String directory) throws RemoteException { - return MeasurementUtils.measureDirectory(directory); + public long calculateDirectorySize(String path) throws RemoteException { + final File directory = new File(path); + if (directory.exists() && directory.isDirectory()) { + return MeasurementUtils.measureDirectory(path); + } else { + return 0L; + } } }; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java index 73b67231a4b5..dfe0262dd525 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java @@ -668,7 +668,8 @@ public class PhoneStatusBarPolicy { if ((mPhoneState == TelephonyManager.CALL_STATE_IDLE) && isEvdo()){ iconLevel = getEvdoLevel(); if (false) { - Slog.d(TAG, "use Evdo level=" + iconLevel + " to replace Cdma Level=" + getCdmaLevel()); + Slog.d(TAG, "use Evdo level=" + iconLevel + " to replace Cdma Level=" + + getCdmaLevel()); } } else { iconLevel = getCdmaLevel(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AirplaneModeController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AirplaneModeController.java index da60f0d681c7..0d2538d82f8b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AirplaneModeController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AirplaneModeController.java @@ -21,6 +21,7 @@ import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.os.AsyncTask; import android.os.RemoteException; import android.os.ServiceManager; import android.provider.Settings; @@ -54,7 +55,6 @@ public class AirplaneModeController extends BroadcastReceiver } public void onCheckedChanged(CompoundButton view, boolean checked) { - Slog.d(TAG, "onCheckedChanged checked=" + checked + " mAirplaneMode=" + mAirplaneMode); if (checked != mAirplaneMode) { mAirplaneMode = checked; unsafe(checked); @@ -78,15 +78,19 @@ public class AirplaneModeController extends BroadcastReceiver // TODO: Fix this racy API by adding something better to TelephonyManager or // ConnectivityService. - private void unsafe(boolean enabled) { - Settings.System.putInt( - mContext.getContentResolver(), - Settings.System.AIRPLANE_MODE_ON, - enabled ? 1 : 0); - Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); - intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); - intent.putExtra("state", enabled); - mContext.sendBroadcast(intent); + private void unsafe(final boolean enabled) { + AsyncTask.execute(new Runnable() { + public void run() { + Settings.System.putInt( + mContext.getContentResolver(), + Settings.System.AIRPLANE_MODE_ON, + enabled ? 1 : 0); + Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); + intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); + intent.putExtra("state", enabled); + mContext.sendBroadcast(intent); + } + }); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AutoRotateController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AutoRotateController.java index 866e5fcad7b4..b0a6d7aeca78 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AutoRotateController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AutoRotateController.java @@ -18,6 +18,7 @@ package com.android.systemui.statusbar.policy; import android.content.ContentResolver; import android.content.Context; +import android.os.AsyncTask; import android.os.RemoteException; import android.os.ServiceManager; import android.provider.Settings; @@ -45,7 +46,6 @@ public class AutoRotateController implements CompoundButton.OnCheckedChangeListe } public void onCheckedChanged(CompoundButton view, boolean checked) { - Slog.d(TAG, "onCheckedChanged checked=" + checked + " mLockRotation=" + mLockRotation); if (checked != mLockRotation) { setLockRotation(checked); } @@ -56,18 +56,22 @@ public class AutoRotateController implements CompoundButton.OnCheckedChangeListe return 0 == Settings.System.getInt(cr, Settings.System.ACCELEROMETER_ROTATION, 0); } - private void setLockRotation(boolean locked) { + private void setLockRotation(final boolean locked) { mLockRotation = locked; - try { - IWindowManager wm = IWindowManager.Stub.asInterface(ServiceManager.getService( - Context.WINDOW_SERVICE)); - ContentResolver cr = mContext.getContentResolver(); - if (locked) { - wm.freezeRotation(); - } else { - wm.thawRotation(); - } - } catch (RemoteException exc) { - } + AsyncTask.execute(new Runnable() { + public void run() { + try { + IWindowManager wm = IWindowManager.Stub.asInterface( + ServiceManager.getService(Context.WINDOW_SERVICE)); + ContentResolver cr = mContext.getContentResolver(); + if (locked) { + wm.freezeRotation(); + } else { + wm.thawRotation(); + } + } catch (RemoteException exc) { + } + } + }); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessController.java index ca1d98fc8984..521467a5d76a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessController.java @@ -18,6 +18,7 @@ package com.android.systemui.statusbar.policy; import android.content.ContentResolver; import android.content.Context; +import android.os.AsyncTask; import android.os.IPowerManager; import android.os.RemoteException; import android.os.ServiceManager; @@ -79,11 +80,15 @@ public class BrightnessController implements ToggleSlider.Listener { setMode(automatic ? Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC : Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL); if (!automatic) { - value = value + value + MINIMUM_BACKLIGHT; - setBrightness(value); + final int val = value + value + MINIMUM_BACKLIGHT; + setBrightness(val); if (!tracking) { - Settings.System.putInt(mContext.getContentResolver(), - Settings.System.SCREEN_BRIGHTNESS, value); + AsyncTask.execute(new Runnable() { + public void run() { + Settings.System.putInt(mContext.getContentResolver(), + Settings.System.SCREEN_BRIGHTNESS, val); + } + }); } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java index 3a7bd90d7326..e80e37d95763 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java @@ -47,7 +47,6 @@ public class KeyButtonView extends ImageView { int mRepeat; Runnable mCheckLongPress = new Runnable() { public void run() { - Slog.d("KeyButtonView", "longpress"); if (isPressed()) { mLongPressed = true; mRepeat++; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/HeightReceiver.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/HeightReceiver.java index 561615929571..90c95685ecd9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/HeightReceiver.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/HeightReceiver.java @@ -73,12 +73,10 @@ public class HeightReceiver extends BroadcastReceiver { private void setPlugged(boolean plugged) { final Resources res = mContext.getResources(); - Slog.d(TAG, "plugged=" + plugged); int height = -1; if (plugged) { final DisplayMetrics metrics = new DisplayMetrics(); mWindowManager.getDefaultDisplay().getMetrics(metrics); - Slog.d(TAG, "metrics=" + metrics); height = metrics.heightPixels - 720; } @@ -87,7 +85,8 @@ public class HeightReceiver extends BroadcastReceiver { if (height < minHeight) { height = minHeight; } - Slog.d(TAG, "using height=" + height + " old=" + mHeight); + Slog.i(TAG, "Resizing status bar plugged=" + plugged + " height=" + + height + " old=" + mHeight); mHeight = height; final int N = mListeners.size(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java index a2f6e3abdf99..45a22b61904d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java @@ -269,7 +269,8 @@ public class NotificationPanel extends RelativeLayout implements StatusBarPanel, // fully closed, no animation necessary } else if (mVisible) { if (DEBUG) { - Slog.d(TAG, "panelHeight not zero but trying to open; scheduling an anim to open fully"); + Slog.d(TAG, "panelHeight not zero but trying to open; scheduling an anim" + + " to open fully"); } startAnimation(true); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/SettingsView.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/SettingsView.java index 07af46665623..9ca83e6bff8c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/SettingsView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/SettingsView.java @@ -95,7 +95,6 @@ public class SettingsView extends LinearLayout implements View.OnClickListener { // Network // ---------------------------- private void onClickNetwork() { - Slog.d(TAG, "onClickNetwork"); getContext().startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS) .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); getStatusBarManager().collapse(); @@ -104,7 +103,6 @@ public class SettingsView extends LinearLayout implements View.OnClickListener { // Settings // ---------------------------- private void onClickSettings() { - Slog.d(TAG, "onClickSettings"); getContext().startActivity(new Intent(Settings.ACTION_SETTINGS) .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); getStatusBarManager().collapse(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/ShirtPocket.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/ShirtPocket.java index 2ebd067a2675..e864577b97c6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/ShirtPocket.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/ShirtPocket.java @@ -143,7 +143,6 @@ public class ShirtPocket extends ImageView { hideWindow(); return true; } else if (action == MotionEvent.ACTION_DOWN) { - Slog.d(TAG, "ACTION_DOWN"); final ClipData clip = mClipping; if (clip != null) { final Bitmap icon = clip.getIcon(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java index d8e3053ff68f..825877a7451f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java @@ -596,7 +596,7 @@ public class TabletStatusBar extends StatusBar implements // TODO: immersive mode popups for tablet } else if (notification.notification.fullScreenIntent != null) { // not immersive & a full-screen alert should be shown - Slog.d(TAG, "Notification has fullScreenIntent and activity is not immersive;" + Slog.w(TAG, "Notification has fullScreenIntent and activity is not immersive;" + " sending fullScreenIntent"); try { notification.notification.fullScreenIntent.send(); @@ -732,28 +732,28 @@ public class TabletStatusBar extends StatusBar implements // act accordingly if ((diff & StatusBarManager.DISABLE_CLOCK) != 0) { boolean show = (state & StatusBarManager.DISABLE_CLOCK) == 0; - Slog.d(TAG, "DISABLE_CLOCK: " + (show ? "no" : "yes")); + Slog.i(TAG, "DISABLE_CLOCK: " + (show ? "no" : "yes")); showClock(show); } if ((diff & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) { boolean show = (state & StatusBarManager.DISABLE_SYSTEM_INFO) == 0; - Slog.d(TAG, "DISABLE_SYSTEM_INFO: " + (show ? "no" : "yes")); + Slog.i(TAG, "DISABLE_SYSTEM_INFO: " + (show ? "no" : "yes")); mNotificationTrigger.setVisibility(show ? View.VISIBLE : View.GONE); } if ((diff & StatusBarManager.DISABLE_EXPAND) != 0) { if ((state & StatusBarManager.DISABLE_EXPAND) != 0) { - Slog.d(TAG, "DISABLE_EXPAND: yes"); + Slog.i(TAG, "DISABLE_EXPAND: yes"); animateCollapse(); } } if ((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) { if ((state & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) { - Slog.d(TAG, "DISABLE_NOTIFICATION_ICONS: yes"); + Slog.i(TAG, "DISABLE_NOTIFICATION_ICONS: yes"); // synchronize with current shadow state mNotificationIconArea.setVisibility(View.GONE); mTicker.halt(); } else { - Slog.d(TAG, "DISABLE_NOTIFICATION_ICONS: no"); + Slog.i(TAG, "DISABLE_NOTIFICATION_ICONS: no"); // synchronize with current shadow state mNotificationIconArea.setVisibility(View.VISIBLE); } @@ -764,11 +764,11 @@ public class TabletStatusBar extends StatusBar implements } if ((diff & StatusBarManager.DISABLE_NAVIGATION) != 0) { if ((state & StatusBarManager.DISABLE_NAVIGATION) != 0) { - Slog.d(TAG, "DISABLE_NAVIGATION: yes"); + Slog.i(TAG, "DISABLE_NAVIGATION: yes"); mNavigationArea.setVisibility(View.GONE); mInputMethodSwitchButton.setScreenLocked(true); } else { - Slog.d(TAG, "DISABLE_NAVIGATION: no"); + Slog.i(TAG, "DISABLE_NAVIGATION: no"); mNavigationArea.setVisibility(View.VISIBLE); mInputMethodSwitchButton.setScreenLocked(false); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarView.java index 4ee985df1f8e..98f718baccee 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarView.java @@ -65,7 +65,9 @@ public class TabletStatusBarView extends FrameLayout { } } } - Slog.d(TabletStatusBar.TAG, "TabletStatusBarView not intercepting event"); + if (TabletStatusBar.DEBUG) { + Slog.d(TabletStatusBar.TAG, "TabletStatusBarView not intercepting event"); + } return super.onInterceptTouchEvent(ev); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java index fa732c322485..440d68081fd0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java @@ -111,7 +111,6 @@ public class TabletTicker public void remove(IBinder key, boolean advance) { if (mCurrentKey == key) { - Slog.d(TAG, "removed current"); // Showing now if (advance) { removeMessages(MSG_ADVANCE); @@ -121,7 +120,6 @@ public class TabletTicker // In the queue for (int i=0; i<QUEUE_LENGTH; i++) { if (mKeys[i] == key) { - Slog.d(TAG, "removed from queue: " + i); for (; i<QUEUE_LENGTH-1; i++) { mKeys[i] = mKeys[i+1]; mQueue[i] = mQueue[i+1]; diff --git a/policy/src/com/android/internal/policy/impl/LockScreen.java b/policy/src/com/android/internal/policy/impl/LockScreen.java index 79fbe0e79f12..1b810d5832bb 100644 --- a/policy/src/com/android/internal/policy/impl/LockScreen.java +++ b/policy/src/com/android/internal/policy/impl/LockScreen.java @@ -311,8 +311,8 @@ class LockScreen extends LinearLayout implements KeyguardScreen, setFocusableInTouchMode(true); setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS); - updateMonitor.registerInfoCallback(this); - updateMonitor.registerSimStateCallback(this); + mUpdateMonitor.registerInfoCallback(this); + mUpdateMonitor.registerSimStateCallback(this); mAudioManager = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE); mSilentMode = isSilentMode(); @@ -414,6 +414,9 @@ class LockScreen extends LinearLayout implements KeyguardScreen, public void onRefreshBatteryInfo(boolean showBatteryInfo, boolean pluggedIn, int batteryLevel) { if (DBG) Log.d(TAG, "onRefreshBatteryInfo(" + showBatteryInfo + ", " + pluggedIn + ")"); + + mStatusView.onRefreshBatteryInfo(showBatteryInfo, pluggedIn, batteryLevel); + mShowingBatteryInfo = showBatteryInfo; mPluggedIn = pluggedIn; mBatteryLevel = batteryLevel; diff --git a/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java b/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java index 9db86aa42d8b..eb4d930e3f85 100644 --- a/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java +++ b/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java @@ -109,22 +109,21 @@ public class PasswordUnlockScreen extends LinearLayout implements KeyguardScreen mLockPatternUtils.updateEmergencyCallButtonState(mEmergencyCallButton); mKeyboardHelper = new PasswordEntryKeyboardHelper(context, mKeyboardView, this, false); + // TODO: re-enable on phones with keyboards + boolean isPhysicalKbShowing = false; + //mCreationHardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO; if (mKeyboardViewAlpha == null || !mIsAlpha) { mKeyboardHelper.setKeyboardMode(mIsAlpha ? PasswordEntryKeyboardHelper.KEYBOARD_MODE_ALPHA : PasswordEntryKeyboardHelper.KEYBOARD_MODE_NUMERIC); - mKeyboardView.setVisibility( - mCreationHardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO - ? View.INVISIBLE : View.VISIBLE); + mKeyboardView.setVisibility(isPhysicalKbShowing ? View.INVISIBLE : View.VISIBLE); } else { mKeyboardHelperAlpha = new PasswordEntryKeyboardHelper(context, mKeyboardViewAlpha, this, false); mKeyboardHelper.setKeyboardMode(PasswordEntryKeyboardHelper.KEYBOARD_MODE_NUMERIC); mKeyboardHelperAlpha.setKeyboardMode(PasswordEntryKeyboardHelper.KEYBOARD_MODE_ALPHA); mKeyboardView.setVisibility(View.GONE); - mKeyboardViewAlpha.setVisibility( - mCreationHardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO - ? View.INVISIBLE : View.VISIBLE); + mKeyboardViewAlpha.setVisibility(isPhysicalKbShowing ? View.INVISIBLE : View.VISIBLE); mPasswordEntry.setWidth(mKeyboardViewAlpha.getLayoutParams().width); } @@ -136,9 +135,12 @@ public class PasswordUnlockScreen extends LinearLayout implements KeyguardScreen // numeric keys. if (mIsAlpha) { mPasswordEntry.setKeyListener(TextKeyListener.getInstance()); + mStatusView.setHelpMessage(R.string.keyguard_password_enter_password_code, + StatusView.LOCK_ICON); } else { mPasswordEntry.setKeyListener(DigitsKeyListener.getInstance()); - mStatusView.setInstructionText(R.string.keyguard_password_enter_pin_password_code); + mStatusView.setHelpMessage(R.string.keyguard_password_enter_pin_code, + StatusView.LOCK_ICON); } mKeyboardHelper.setVibratePattern(mLockPatternUtils.isTactileFeedbackEnabled() ? @@ -152,6 +154,11 @@ public class PasswordUnlockScreen extends LinearLayout implements KeyguardScreen mStatusView.setCarrierText(LockScreen.getCarrierString( mUpdateMonitor.getTelephonyPlmn(), mUpdateMonitor.getTelephonySpn())); + + mUpdateMonitor.registerInfoCallback(this); + //mUpdateMonitor.registerSimStateCallback(this); + + resetStatusInfo(); } @Override @@ -205,6 +212,7 @@ public class PasswordUnlockScreen extends LinearLayout implements KeyguardScreen if (mLockPatternUtils.checkPassword(entry)) { mCallback.keyguardDone(true); mCallback.reportSuccessfulUnlockAttempt(); + mStatusView.setInstructionText(null); } else if (entry.length() > MINIMUM_PASSWORD_LENGTH_BEFORE_REPORT ) { // to avoid accidental lockout, only count attempts that are long enough to be a // real password. This may require some tweaking. @@ -317,11 +325,8 @@ public class PasswordUnlockScreen extends LinearLayout implements KeyguardScreen } private void resetStatusInfo() { - if(mIsAlpha) { - mStatusView.setInstructionText(R.string.keyguard_password_enter_password_code); - } else { - mStatusView.setInstructionText(R.string.keyguard_password_enter_pin_password_code); - } + mStatusView.setInstructionText(null); + mStatusView.updateStatusLines(true); } } diff --git a/policy/src/com/android/internal/policy/impl/PatternUnlockScreen.java b/policy/src/com/android/internal/policy/impl/PatternUnlockScreen.java index 5d1455e5b935..6815d5080c21 100644 --- a/policy/src/com/android/internal/policy/impl/PatternUnlockScreen.java +++ b/policy/src/com/android/internal/policy/impl/PatternUnlockScreen.java @@ -169,6 +169,9 @@ class PatternUnlockScreen extends LinearLayoutWithDefaultTouchRecepient } mStatusView = new StatusView(this, mUpdateMonitor, mLockPatternUtils); + // This shows up when no other information is required on status1 + mStatusView.setHelpMessage(R.string.lockscreen_pattern_instructions, + StatusView.LOCK_ICON); mLockPatternView = (LockPatternView) findViewById(R.id.lockPattern); @@ -216,8 +219,8 @@ class PatternUnlockScreen extends LinearLayoutWithDefaultTouchRecepient // assume normal footer mode for now updateFooter(FooterMode.Normal); - updateMonitor.registerInfoCallback(this); - updateMonitor.registerSimStateCallback(this); + mUpdateMonitor.registerInfoCallback(this); + mUpdateMonitor.registerSimStateCallback(this); setFocusableInTouchMode(true); // until we get an update... diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java index 2a393227745c..6b559cf6dce5 100755 --- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java @@ -191,9 +191,6 @@ public class PhoneWindowManager implements WindowManagerPolicy { static final int APPLICATION_PANEL_SUBLAYER = 1; static final int APPLICATION_SUB_PANEL_SUBLAYER = 2; - // Debugging: set this to have the system act like there is no hard keyboard. - static final boolean KEYBOARD_ALWAYS_HIDDEN = false; - static public final String SYSTEM_DIALOG_REASON_KEY = "reason"; static public final String SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS = "globalactions"; static public final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps"; @@ -914,38 +911,44 @@ public class PhoneWindowManager implements WindowManagerPolicy { } private int determineHiddenState(int mode, int hiddenValue, int visibleValue) { - if (KEYBOARD_ALWAYS_HIDDEN) { - return hiddenValue; - } - if (mLidOpen == LID_ABSENT) { - return visibleValue; - } - - switch (mode) { - case 1: - return mLidOpen == LID_OPEN ? visibleValue : hiddenValue; - case 2: - return mLidOpen == LID_OPEN ? hiddenValue : visibleValue; + if (mLidOpen != LID_ABSENT) { + switch (mode) { + case 1: + return mLidOpen == LID_OPEN ? visibleValue : hiddenValue; + case 2: + return mLidOpen == LID_OPEN ? hiddenValue : visibleValue; + } } return visibleValue; } - + /** {@inheritDoc} */ public void adjustConfigurationLw(Configuration config) { readLidState(); + mPowerManager.setKeyboardVisibility(mLidOpen == LID_OPEN); - config.hardKeyboardHidden = determineHiddenState( - mLidKeyboardAccessibility, Configuration.HARDKEYBOARDHIDDEN_YES, - Configuration.HARDKEYBOARDHIDDEN_NO); - config.navigationHidden = determineHiddenState( - mLidNavigationAccessibility, Configuration.NAVIGATIONHIDDEN_YES, - Configuration.NAVIGATIONHIDDEN_NO); - config.keyboardHidden = (config.hardKeyboardHidden - == Configuration.HARDKEYBOARDHIDDEN_NO || mHasSoftInput) - ? Configuration.KEYBOARDHIDDEN_NO - : Configuration.KEYBOARDHIDDEN_YES; + + if (config.keyboard == Configuration.KEYBOARD_NOKEYS) { + config.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_YES; + } else { + config.hardKeyboardHidden = determineHiddenState(mLidKeyboardAccessibility, + Configuration.HARDKEYBOARDHIDDEN_YES, Configuration.HARDKEYBOARDHIDDEN_NO); + } + + if (config.navigation == Configuration.NAVIGATION_NONAV) { + config.navigationHidden = Configuration.NAVIGATIONHIDDEN_YES; + } else { + config.navigationHidden = determineHiddenState(mLidNavigationAccessibility, + Configuration.NAVIGATIONHIDDEN_YES, Configuration.NAVIGATIONHIDDEN_NO); + } + + if (mHasSoftInput || config.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO) { + config.keyboardHidden = Configuration.KEYBOARDHIDDEN_NO; + } else { + config.keyboardHidden = Configuration.KEYBOARDHIDDEN_YES; + } } - + /** {@inheritDoc} */ public int windowTypeToLayerLw(int type) { if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) { diff --git a/policy/src/com/android/internal/policy/impl/StatusView.java b/policy/src/com/android/internal/policy/impl/StatusView.java index 1caf0b724022..4b91b6564bd4 100644 --- a/policy/src/com/android/internal/policy/impl/StatusView.java +++ b/policy/src/com/android/internal/policy/impl/StatusView.java @@ -19,10 +19,10 @@ import android.view.View; import android.widget.TextView; class StatusView { - private static final int LOCK_ICON = R.drawable.ic_lock_idle_lock; - private static final int ALARM_ICON = R.drawable.ic_lock_idle_alarm; - private static final int CHARGING_ICON = R.drawable.ic_lock_idle_charging; - private static final int BATTERY_LOW_ICON = R.drawable.ic_lock_idle_low_battery; + public static final int LOCK_ICON = R.drawable.ic_lock_idle_lock; + public static final int ALARM_ICON = R.drawable.ic_lock_idle_alarm; + public static final int CHARGING_ICON = R.drawable.ic_lock_idle_charging; + public static final int BATTERY_LOW_ICON = R.drawable.ic_lock_idle_low_battery; private String mDateFormatString; @@ -49,6 +49,8 @@ class StatusView { private TextView mAlarmStatus; private LockPatternUtils mLockPatternUtils; + private int mHelpMessageId; + private int mHelpIconId; private View findViewById(int id) { return mView.findViewById(id); @@ -123,13 +125,13 @@ class StatusView { void setInstructionText(int stringId) { mStatus1.setText(stringId); mStatus1.setCompoundDrawablesWithIntrinsicBounds(LOCK_ICON, 0, 0, 0); - mStatus1.setVisibility(View.VISIBLE); + mStatus1.setVisibility(stringId != 0 ? View.VISIBLE : View.INVISIBLE); } void setInstructionText(String string) { mStatus1.setText(string); mStatus1.setCompoundDrawablesWithIntrinsicBounds(LOCK_ICON, 0, 0, 0); - mStatus1.setVisibility(View.VISIBLE); + mStatus1.setVisibility(TextUtils.isEmpty(string) ? View.INVISIBLE : View.VISIBLE); } void setCarrierText(int stringId) { @@ -148,8 +150,8 @@ class StatusView { */ void updateStatusLines(boolean showStatusLines) { if (!showStatusLines) { - mStatus1.setVisibility(showStatusLines ? View.VISIBLE : View.GONE); - mAlarmStatus.setVisibility(showStatusLines ? View.VISIBLE : View.GONE); + mStatus1.setVisibility(showStatusLines ? View.VISIBLE : View.INVISIBLE); + mAlarmStatus.setVisibility(showStatusLines ? View.VISIBLE : View.INVISIBLE); return; } @@ -171,15 +173,14 @@ class StatusView { mAlarmStatus.setText(nextAlarm); mAlarmStatus.setVisibility(View.VISIBLE); } else { - mAlarmStatus.setVisibility(View.GONE); + mAlarmStatus.setVisibility(View.INVISIBLE); } // Update Status1 - if (mInstructions != null) { + if (!TextUtils.isEmpty(mInstructions)) { // Instructions only - final int resId = TextUtils.isEmpty(mInstructions) ? 0 : LOCK_ICON; mStatus1.setText(mInstructions); - mStatus1.setCompoundDrawablesWithIntrinsicBounds(resId, 0, 0, 0); + mStatus1.setCompoundDrawablesWithIntrinsicBounds(LOCK_ICON, 0, 0, 0); mStatus1.setVisibility(View.VISIBLE); } else if (mShowingBatteryInfo) { // Battery status @@ -199,13 +200,22 @@ class StatusView { } mStatus1.setVisibility(View.VISIBLE); } else { - // nothing specific to show; show general instructions - mStatus1.setText(R.string.lockscreen_pattern_instructions); - mStatus1.setCompoundDrawablesWithIntrinsicBounds(LOCK_ICON, 0,0, 0); - mStatus1.setVisibility(View.VISIBLE); + // nothing specific to show; show help message and icon, if provided + if (mHelpMessageId != 0) { + mStatus1.setText(mHelpMessageId); + mStatus1.setCompoundDrawablesWithIntrinsicBounds(mHelpIconId, 0,0, 0); + mStatus1.setVisibility(View.VISIBLE); + } else { + mStatus1.setVisibility(View.INVISIBLE); + } } } + void setHelpMessage(int messageId, int iconId) { + mHelpMessageId = messageId; + mHelpIconId = iconId; + } + void refreshTimeAndDateDisplay() { if (mHasDate) { mDate.setText(DateFormat.format(mDateFormatString, new Date())); diff --git a/services/input/InputDispatcher.cpp b/services/input/InputDispatcher.cpp index b5a4bd2da0c7..e314145112bf 100644 --- a/services/input/InputDispatcher.cpp +++ b/services/input/InputDispatcher.cpp @@ -154,6 +154,24 @@ static bool validateMotionEvent(int32_t action, size_t pointerCount, return true; } +static void dumpRegion(String8& dump, const SkRegion& region) { + if (region.isEmpty()) { + dump.append("<empty>"); + return; + } + + bool first = true; + for (SkRegion::Iterator it(region); !it.done(); it.next()) { + if (first) { + first = false; + } else { + dump.append("|"); + } + const SkIRect& rect = it.rect(); + dump.appendFormat("[%d,%d][%d,%d]", rect.fLeft, rect.fTop, rect.fRight, rect.fBottom); + } +} + // --- InputDispatcher --- @@ -495,7 +513,7 @@ const InputWindow* InputDispatcher::findTouchedWindowAtLocked(int32_t x, int32_t if (!(flags & InputWindow::FLAG_NOT_TOUCHABLE)) { bool isTouchModal = (flags & (InputWindow::FLAG_NOT_FOCUSABLE | InputWindow::FLAG_NOT_TOUCH_MODAL)) == 0; - if (isTouchModal || window->touchableAreaContainsPoint(x, y)) { + if (isTouchModal || window->touchableRegionContainsPoint(x, y)) { // Found window. return window; } @@ -1188,7 +1206,7 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, if (! (flags & InputWindow::FLAG_NOT_TOUCHABLE)) { bool isTouchModal = (flags & (InputWindow::FLAG_NOT_FOCUSABLE | InputWindow::FLAG_NOT_TOUCH_MODAL)) == 0; - if (isTouchModal || window->touchableAreaContainsPoint(x, y)) { + if (isTouchModal || window->touchableRegionContainsPoint(x, y)) { if (! screenWasOff || flags & InputWindow::FLAG_TOUCHABLE_WHEN_WAKING) { newTouchedWindow = window; } @@ -2884,9 +2902,7 @@ void InputDispatcher::dumpDispatchStateLocked(String8& dump) { dump.appendFormat(INDENT2 "%d: name='%s', paused=%s, hasFocus=%s, hasWallpaper=%s, " "visible=%s, canReceiveKeys=%s, flags=0x%08x, type=0x%08x, layer=%d, " "frame=[%d,%d][%d,%d], " - "visibleFrame=[%d,%d][%d,%d], " - "touchableArea=[%d,%d][%d,%d], " - "ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n", + "touchableRegion=", i, window.name.string(), toString(window.paused), toString(window.hasFocus), @@ -2896,11 +2912,9 @@ void InputDispatcher::dumpDispatchStateLocked(String8& dump) { window.layoutParamsFlags, window.layoutParamsType, window.layer, window.frameLeft, window.frameTop, - window.frameRight, window.frameBottom, - window.visibleFrameLeft, window.visibleFrameTop, - window.visibleFrameRight, window.visibleFrameBottom, - window.touchableAreaLeft, window.touchableAreaTop, - window.touchableAreaRight, window.touchableAreaBottom, + window.frameRight, window.frameBottom); + dumpRegion(dump, window.touchableRegion); + dump.appendFormat(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n", window.ownerPid, window.ownerUid, window.dispatchingTimeout / 1000000.0); } diff --git a/services/input/InputWindow.cpp b/services/input/InputWindow.cpp index 9ce45f50513c..b552f6d5b43d 100644 --- a/services/input/InputWindow.cpp +++ b/services/input/InputWindow.cpp @@ -24,9 +24,8 @@ namespace android { // --- InputWindow --- -bool InputWindow::touchableAreaContainsPoint(int32_t x, int32_t y) const { - return x >= touchableAreaLeft && x <= touchableAreaRight - && y >= touchableAreaTop && y <= touchableAreaBottom; +bool InputWindow::touchableRegionContainsPoint(int32_t x, int32_t y) const { + return touchableRegion.contains(x, y); } bool InputWindow::frameContainsPoint(int32_t x, int32_t y) const { diff --git a/services/input/InputWindow.h b/services/input/InputWindow.h index b3d5a651ba75..9c43067363a9 100644 --- a/services/input/InputWindow.h +++ b/services/input/InputWindow.h @@ -23,6 +23,8 @@ #include <utils/Timers.h> #include <utils/String8.h> +#include <SkRegion.h> + #include "InputApplication.h" namespace android { @@ -129,14 +131,7 @@ struct InputWindow { int32_t frameTop; int32_t frameRight; int32_t frameBottom; - int32_t visibleFrameLeft; - int32_t visibleFrameTop; - int32_t visibleFrameRight; - int32_t visibleFrameBottom; - int32_t touchableAreaLeft; - int32_t touchableAreaTop; - int32_t touchableAreaRight; - int32_t touchableAreaBottom; + SkRegion touchableRegion; bool visible; bool canReceiveKeys; bool hasFocus; @@ -146,7 +141,7 @@ struct InputWindow { int32_t ownerPid; int32_t ownerUid; - bool touchableAreaContainsPoint(int32_t x, int32_t y) const; + bool touchableRegionContainsPoint(int32_t x, int32_t y) const; bool frameContainsPoint(int32_t x, int32_t y) const; /* Returns true if the window is of a trusted type that is allowed to silently diff --git a/services/java/com/android/server/InputWindow.java b/services/java/com/android/server/InputWindow.java index 1515290145d8..2c2cdfe8ae77 100644 --- a/services/java/com/android/server/InputWindow.java +++ b/services/java/com/android/server/InputWindow.java @@ -16,6 +16,7 @@ package com.android.server; +import android.graphics.Region; import android.view.InputChannel; /** @@ -39,23 +40,14 @@ public final class InputWindow { // Dispatching timeout. public long dispatchingTimeoutNanos; - // Window frame area. + // Window frame. public int frameLeft; public int frameTop; public int frameRight; public int frameBottom; - // Window visible frame area. - public int visibleFrameLeft; - public int visibleFrameTop; - public int visibleFrameRight; - public int visibleFrameBottom; - - // Window touchable area. - public int touchableAreaLeft; - public int touchableAreaTop; - public int touchableAreaRight; - public int touchableAreaBottom; + // Window touchable region. + public final Region touchableRegion = new Region(); // Window is visible. public boolean visible; diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java index 1efc645cc7c4..19667d4a1be6 100644 --- a/services/java/com/android/server/PackageManagerService.java +++ b/services/java/com/android/server/PackageManagerService.java @@ -1050,7 +1050,7 @@ class PackageManagerService extends IPackageManager.Stub { void cleanupInstallFailedPackage(PackageSetting ps) { Slog.i(TAG, "Cleaning up incompletely installed app: " + ps.name); if (mInstaller != null) { - boolean useSecureFS = useEncryptedFilesystemForPackage(ps.pkg); + boolean useSecureFS = false; int retCode = mInstaller.remove(ps.name, useSecureFS); if (retCode < 0) { Slog.w(TAG, "Couldn't remove app data directory for package: " @@ -2780,11 +2780,6 @@ class PackageManagerService extends IPackageManager.Stub { return performed ? DEX_OPT_PERFORMED : DEX_OPT_SKIPPED; } - private static boolean useEncryptedFilesystemForPackage(PackageParser.Package pkg) { - return Environment.isEncryptedFilesystemEnabled() && - ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_NEVER_ENCRYPT) == 0); - } - private boolean verifyPackageUpdate(PackageSetting oldPkg, PackageParser.Package newPkg) { if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) { Slog.w(TAG, "Unable to update from " + oldPkg.name @@ -2801,7 +2796,7 @@ class PackageManagerService extends IPackageManager.Stub { } private File getDataPathForPackage(PackageParser.Package pkg) { - boolean useEncryptedFSDir = useEncryptedFilesystemForPackage(pkg); + boolean useEncryptedFSDir = false; File dataPath; if (useEncryptedFSDir) { dataPath = new File(mSecureAppDataDir, pkg.packageName); @@ -3157,7 +3152,7 @@ class PackageManagerService extends IPackageManager.Stub { pkg.applicationInfo.dataDir = dataPath.getPath(); } else { // This is a normal package, need to make its data directory. - boolean useEncryptedFSDir = useEncryptedFilesystemForPackage(pkg); + boolean useEncryptedFSDir = false; dataPath = getDataPathForPackage(pkg); boolean uidError = false; @@ -4811,6 +4806,74 @@ class PackageManagerService extends IPackageManager.Stub { abstract void handleReturnCode(); } + class MeasureParams extends HandlerParams { + private final PackageStats mStats; + private boolean mSuccess; + + private final IPackageStatsObserver mObserver; + + public MeasureParams(PackageStats stats, boolean success, + IPackageStatsObserver observer) { + mObserver = observer; + mStats = stats; + mSuccess = success; + } + + @Override + void handleStartCopy() throws RemoteException { + final boolean mounted; + + if (Environment.isExternalStorageEmulated()) { + mounted = true; + } else { + final String status = Environment.getExternalStorageState(); + + mounted = status.equals(Environment.MEDIA_MOUNTED) + || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY); + } + + if (mounted) { + final File externalCacheDir = Environment + .getExternalStorageAppCacheDirectory(mStats.packageName); + final long externalCacheSize = mContainerService + .calculateDirectorySize(externalCacheDir.getPath()); + mStats.externalCacheSize = externalCacheSize; + + final File externalDataDir = Environment + .getExternalStorageAppDataDirectory(mStats.packageName); + long externalDataSize = mContainerService.calculateDirectorySize(externalDataDir + .getPath()); + + if (externalCacheDir.getParentFile().equals(externalDataDir)) { + externalDataSize -= externalCacheSize; + } + mStats.externalDataSize = externalDataSize; + + final File externalMediaDir = Environment + .getExternalStorageAppMediaDirectory(mStats.packageName); + mStats.externalMediaSize = mContainerService + .calculateDirectorySize(externalCacheDir.getPath()); + } + } + + @Override + void handleReturnCode() { + if (mObserver != null) { + try { + mObserver.onGetStatsCompleted(mStats, mSuccess); + } catch (RemoteException e) { + Slog.i(TAG, "Observer no longer exists."); + } + } + } + + @Override + void handleServiceError() { + Slog.e(TAG, "Could not measure application " + mStats.packageName + + " external storage"); + } + } + class InstallParams extends HandlerParams { final IPackageInstallObserver observer; int flags; @@ -6296,7 +6359,7 @@ class PackageManagerService extends IPackageManager.Stub { deletedPs = mSettings.mPackages.get(packageName); } if ((flags&PackageManager.DONT_DELETE_DATA) == 0) { - boolean useEncryptedFSDir = useEncryptedFilesystemForPackage(p); + boolean useEncryptedFSDir = false; if (mInstaller != null) { int retCode = mInstaller.remove(packageName, useEncryptedFSDir); if (retCode < 0) { @@ -6540,7 +6603,7 @@ class PackageManagerService extends IPackageManager.Stub { } boolean useEncryptedFSDir = false; - if(!dataOnly) { + if (!dataOnly) { //need to check this only for fully installed applications if (p == null) { Slog.w(TAG, "Package named '" + packageName +"' doesn't exist."); @@ -6551,7 +6614,6 @@ class PackageManagerService extends IPackageManager.Stub { Slog.w(TAG, "Package " + packageName + " has no applicationInfo."); return false; } - useEncryptedFSDir = useEncryptedFilesystemForPackage(p); } if (mInstaller != null) { int retCode = mInstaller.clearUserData(packageName, useEncryptedFSDir); @@ -6605,7 +6667,7 @@ class PackageManagerService extends IPackageManager.Stub { Slog.w(TAG, "Package " + packageName + " has no applicationInfo."); return false; } - boolean useEncryptedFSDir = useEncryptedFilesystemForPackage(p); + boolean useEncryptedFSDir = false; if (mInstaller != null) { int retCode = mInstaller.deleteCacheFiles(packageName, useEncryptedFSDir); if (retCode < 0) { @@ -6625,18 +6687,16 @@ class PackageManagerService extends IPackageManager.Stub { mHandler.post(new Runnable() { public void run() { mHandler.removeCallbacks(this); - PackageStats lStats = new PackageStats(packageName); - final boolean succeded; + PackageStats stats = new PackageStats(packageName); + + final boolean success; synchronized (mInstallLock) { - succeded = getPackageSizeInfoLI(packageName, lStats); + success = getPackageSizeInfoLI(packageName, stats); } - if(observer != null) { - try { - observer.onGetStatsCompleted(lStats, succeded); - } catch (RemoteException e) { - Log.i(TAG, "Observer no longer exists."); - } - } //end if observer + + Message msg = mHandler.obtainMessage(INIT_COPY); + msg.obj = new MeasureParams(stats, success, observer); + mHandler.sendMessage(msg); } //end run }); } @@ -6669,7 +6729,7 @@ class PackageManagerService extends IPackageManager.Stub { } publicSrcDir = isForwardLocked(p) ? applicationInfo.publicSourceDir : null; } - boolean useEncryptedFSDir = useEncryptedFilesystemForPackage(p); + boolean useEncryptedFSDir = false; if (mInstaller != null) { int res = mInstaller.getSizeInfo(packageName, p.mPath, publicSrcDir, pStats, useEncryptedFSDir); @@ -7842,8 +7902,7 @@ class PackageManagerService extends IPackageManager.Stub { this.pkgFlags = pkgFlags & ( ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_FORWARD_LOCK | - ApplicationInfo.FLAG_EXTERNAL_STORAGE | - ApplicationInfo.FLAG_NEVER_ENCRYPT); + ApplicationInfo.FLAG_EXTERNAL_STORAGE); } } diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index 6f4b4c5be403..978946f546a3 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -204,11 +204,9 @@ class ServerThread extends Thread { // TODO: Use a more reliable check to see if this product should // support Bluetooth - see bug 988521 if (SystemProperties.get("ro.kernel.qemu").equals("1")) { - Slog.i(TAG, "Registering null Bluetooth Service (emulator)"); - ServiceManager.addService(BluetoothAdapter.BLUETOOTH_SERVICE, null); + Slog.i(TAG, "No Bluetooh Service (emulator)"); } else if (factoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) { - Slog.i(TAG, "Registering null Bluetooth Service (factory test)"); - ServiceManager.addService(BluetoothAdapter.BLUETOOTH_SERVICE, null); + Slog.i(TAG, "No Bluetooth Service (factory test)"); } else { Slog.i(TAG, "Bluetooth Service"); bluetooth = new BluetoothService(context); diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java index 1b590ba2190b..cf072392cbe1 100644 --- a/services/java/com/android/server/WifiService.java +++ b/services/java/com/android/server/WifiService.java @@ -37,6 +37,7 @@ import android.net.wifi.WifiConfiguration; import android.net.wifi.SupplicantState; import android.net.wifi.WifiConfiguration.KeyMgmt; import android.net.wifi.WpsConfiguration; +import android.net.wifi.WpsResult; import android.net.ConnectivityManager; import android.net.InterfaceConfiguration; import android.net.DhcpInfo; @@ -841,13 +842,13 @@ public class WifiService extends IWifiManager.Stub { mWifiStateMachine.forgetNetwork(netId); } - public String startWps(WpsConfiguration config) { + public WpsResult startWps(WpsConfiguration config) { enforceChangePermission(); if (mChannel != null) { return mWifiStateMachine.startWps(mChannel, config); } else { Slog.e(TAG, "mChannel is not initialized"); - return ""; + return new WpsResult(WpsResult.Status.FAILURE); } } diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java index bdc779c3e11e..1b3725c4d051 100644 --- a/services/java/com/android/server/WindowManagerService.java +++ b/services/java/com/android/server/WindowManagerService.java @@ -520,7 +520,7 @@ public class WindowManagerService extends IWindowManager.Stub int mRotation; int mAnimFlags; - private final Rect tmpRect = new Rect(); + private final Region mTmpRegion = new Region(); DragState(IBinder token, Surface surface, int flags, IBinder localWin) { mToken = token; @@ -816,31 +816,13 @@ public class WindowManagerService extends IWindowManager.Stub // not touchable == don't tell about drags continue; } - // account for the window's decor etc - tmpRect.set(child.mFrame); - if (child.mTouchableInsets == ViewTreeObserver - .InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT) { - // The point is inside of the window if it is - // inside the frame, AND the content part of that - // frame that was given by the application. - tmpRect.left += child.mGivenContentInsets.left; - tmpRect.top += child.mGivenContentInsets.top; - tmpRect.right -= child.mGivenContentInsets.right; - tmpRect.bottom -= child.mGivenContentInsets.bottom; - } else if (child.mTouchableInsets == ViewTreeObserver - .InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE) { - // The point is inside of the window if it is - // inside the frame, AND the visible part of that - // frame that was given by the application. - tmpRect.left += child.mGivenVisibleInsets.left; - tmpRect.top += child.mGivenVisibleInsets.top; - tmpRect.right -= child.mGivenVisibleInsets.right; - tmpRect.bottom -= child.mGivenVisibleInsets.bottom; - } + + child.getTouchableRegion(mTmpRegion); + final int touchFlags = flags & - (WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE - | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL); - if (tmpRect.contains(x, y) || touchFlags == 0) { + (WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE + | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL); + if (mTmpRegion.contains(x, y) || touchFlags == 0) { // Found it touchedWin = child; break; @@ -2667,7 +2649,7 @@ public class WindowManagerService extends IWindowManager.Stub void setInsetsWindow(Session session, IWindow client, int touchableInsets, Rect contentInsets, - Rect visibleInsets) { + Rect visibleInsets, Region touchableRegion) { long origId = Binder.clearCallingIdentity(); try { synchronized (mWindowMap) { @@ -2676,6 +2658,7 @@ public class WindowManagerService extends IWindowManager.Stub w.mGivenInsetsPending = false; w.mGivenContentInsets.set(contentInsets); w.mGivenVisibleInsets.set(visibleInsets); + w.mGivenTouchableRegion.set(touchableRegion); w.mTouchableInsets = touchableInsets; mLayoutNeeded = true; performLayoutAndPlaceSurfacesLocked(); @@ -5882,7 +5865,7 @@ public class WindowManagerService extends IWindowManager.Stub final InputWindow inputWindow = windowList.add(); inputWindow.inputChannel = mDragState.mServerChannel; inputWindow.name = "drag"; - inputWindow.layoutParamsFlags = 0; + inputWindow.layoutParamsFlags = WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; inputWindow.layoutParamsType = WindowManager.LayoutParams.TYPE_DRAG; inputWindow.dispatchingTimeoutNanos = DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS; inputWindow.visible = true; @@ -5900,15 +5883,8 @@ public class WindowManagerService extends IWindowManager.Stub inputWindow.frameRight = mDisplay.getWidth(); inputWindow.frameBottom = mDisplay.getHeight(); - inputWindow.visibleFrameLeft = inputWindow.frameLeft; - inputWindow.visibleFrameTop = inputWindow.frameTop; - inputWindow.visibleFrameRight = inputWindow.frameRight; - inputWindow.visibleFrameBottom = inputWindow.frameBottom; - - inputWindow.touchableAreaLeft = inputWindow.frameLeft; - inputWindow.touchableAreaTop = inputWindow.frameTop; - inputWindow.touchableAreaRight = inputWindow.frameRight; - inputWindow.touchableAreaBottom = inputWindow.frameBottom; + // The drag window cannot receive new touches. + inputWindow.touchableRegion.setEmpty(); } /* Updates the cached window information provided to the input dispatcher. */ @@ -5973,40 +5949,8 @@ public class WindowManagerService extends IWindowManager.Stub inputWindow.frameTop = frame.top; inputWindow.frameRight = frame.right; inputWindow.frameBottom = frame.bottom; - - final Rect visibleFrame = child.mVisibleFrame; - inputWindow.visibleFrameLeft = visibleFrame.left; - inputWindow.visibleFrameTop = visibleFrame.top; - inputWindow.visibleFrameRight = visibleFrame.right; - inputWindow.visibleFrameBottom = visibleFrame.bottom; - - switch (child.mTouchableInsets) { - default: - case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME: - inputWindow.touchableAreaLeft = frame.left; - inputWindow.touchableAreaTop = frame.top; - inputWindow.touchableAreaRight = frame.right; - inputWindow.touchableAreaBottom = frame.bottom; - break; - - case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT: { - Rect inset = child.mGivenContentInsets; - inputWindow.touchableAreaLeft = frame.left + inset.left; - inputWindow.touchableAreaTop = frame.top + inset.top; - inputWindow.touchableAreaRight = frame.right - inset.right; - inputWindow.touchableAreaBottom = frame.bottom - inset.bottom; - break; - } - - case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE: { - Rect inset = child.mGivenVisibleInsets; - inputWindow.touchableAreaLeft = frame.left + inset.left; - inputWindow.touchableAreaTop = frame.top + inset.top; - inputWindow.touchableAreaRight = frame.right - inset.right; - inputWindow.touchableAreaBottom = frame.bottom - inset.bottom; - break; - } - } + + child.getTouchableRegion(inputWindow.touchableRegion); } // Send windows to native code. @@ -6516,9 +6460,9 @@ public class WindowManagerService extends IWindowManager.Stub } public void setInsets(IWindow window, int touchableInsets, - Rect contentInsets, Rect visibleInsets) { + Rect contentInsets, Rect visibleInsets, Region touchableArea) { setInsetsWindow(this, window, touchableInsets, contentInsets, - visibleInsets); + visibleInsets, touchableArea); } public void getDisplayFrame(IWindow window, Rect outDisplayFrame) { @@ -6648,7 +6592,7 @@ public class WindowManagerService extends IWindowManager.Stub synchronized (mWindowMap) { long ident = Binder.clearCallingIdentity(); try { - if (mDragState.mToken != token) { + if (mDragState == null || mDragState.mToken != token) { Slog.w(TAG, "Invalid drop-result claim by " + window); throw new IllegalStateException("reportDropResult() by non-recipient"); } @@ -6857,6 +6801,11 @@ public class WindowManagerService extends IWindowManager.Stub final Rect mGivenVisibleInsets = new Rect(); /** + * This is the given touchable area relative to the window frame, or null if none. + */ + final Region mGivenTouchableRegion = new Region(); + + /** * Flag indicating whether the touchable region should be adjusted by * the visible insets; if false the area outside the visible insets is * NOT touchable, so we must use those to adjust the frame during hit @@ -8139,6 +8088,36 @@ public class WindowManagerService extends IWindowManager.Stub return true; } + public void getTouchableRegion(Region outRegion) { + final Rect frame = mFrame; + switch (mTouchableInsets) { + default: + case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME: + outRegion.set(frame); + break; + case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT: { + final Rect inset = mGivenContentInsets; + outRegion.set( + frame.left + inset.left, frame.top + inset.top, + frame.right - inset.right, frame.bottom - inset.bottom); + break; + } + case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE: { + final Rect inset = mGivenVisibleInsets; + outRegion.set( + frame.left + inset.left, frame.top + inset.top, + frame.right - inset.right, frame.bottom - inset.bottom); + break; + } + case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION: { + final Region givenTouchableRegion = mGivenTouchableRegion; + outRegion.set(givenTouchableRegion); + outRegion.translate(frame.left, frame.top); + break; + } + } + } + void dump(PrintWriter pw, String prefix) { pw.print(prefix); pw.print("mSession="); pw.print(mSession); pw.print(" mClient="); pw.println(mClient.asBinder()); diff --git a/services/jni/com_android_server_InputWindow.cpp b/services/jni/com_android_server_InputWindow.cpp index a4609a0f9b85..75154567c149 100644 --- a/services/jni/com_android_server_InputWindow.cpp +++ b/services/jni/com_android_server_InputWindow.cpp @@ -21,6 +21,7 @@ #include <android_runtime/AndroidRuntime.h> #include <android_view_InputChannel.h> +#include <android/graphics/Region.h> #include "com_android_server_InputWindow.h" #include "com_android_server_InputWindowHandle.h" @@ -39,14 +40,7 @@ static struct { jfieldID frameTop; jfieldID frameRight; jfieldID frameBottom; - jfieldID visibleFrameLeft; - jfieldID visibleFrameTop; - jfieldID visibleFrameRight; - jfieldID visibleFrameBottom; - jfieldID touchableAreaLeft; - jfieldID touchableAreaTop; - jfieldID touchableAreaRight; - jfieldID touchableAreaBottom; + jfieldID touchableRegion; jfieldID visible; jfieldID canReceiveKeys; jfieldID hasFocus; @@ -108,22 +102,17 @@ void android_server_InputWindow_toNative( gInputWindowClassInfo.frameRight); outInputWindow->frameBottom = env->GetIntField(inputWindowObj, gInputWindowClassInfo.frameBottom); - outInputWindow->visibleFrameLeft = env->GetIntField(inputWindowObj, - gInputWindowClassInfo.visibleFrameLeft); - outInputWindow->visibleFrameTop = env->GetIntField(inputWindowObj, - gInputWindowClassInfo.visibleFrameTop); - outInputWindow->visibleFrameRight = env->GetIntField(inputWindowObj, - gInputWindowClassInfo.visibleFrameRight); - outInputWindow->visibleFrameBottom = env->GetIntField(inputWindowObj, - gInputWindowClassInfo.visibleFrameBottom); - outInputWindow->touchableAreaLeft = env->GetIntField(inputWindowObj, - gInputWindowClassInfo.touchableAreaLeft); - outInputWindow->touchableAreaTop = env->GetIntField(inputWindowObj, - gInputWindowClassInfo.touchableAreaTop); - outInputWindow->touchableAreaRight = env->GetIntField(inputWindowObj, - gInputWindowClassInfo.touchableAreaRight); - outInputWindow->touchableAreaBottom = env->GetIntField(inputWindowObj, - gInputWindowClassInfo.touchableAreaBottom); + + jobject regionObj = env->GetObjectField(inputWindowObj, + gInputWindowClassInfo.touchableRegion); + if (regionObj) { + SkRegion* region = android_graphics_Region_getSkRegion(env, regionObj); + outInputWindow->touchableRegion.set(*region); + env->DeleteLocalRef(regionObj); + } else { + outInputWindow->touchableRegion.setEmpty(); + } + outInputWindow->visible = env->GetBooleanField(inputWindowObj, gInputWindowClassInfo.visible); outInputWindow->canReceiveKeys = env->GetBooleanField(inputWindowObj, @@ -187,29 +176,8 @@ int register_android_server_InputWindow(JNIEnv* env) { GET_FIELD_ID(gInputWindowClassInfo.frameBottom, gInputWindowClassInfo.clazz, "frameBottom", "I"); - GET_FIELD_ID(gInputWindowClassInfo.visibleFrameLeft, gInputWindowClassInfo.clazz, - "visibleFrameLeft", "I"); - - GET_FIELD_ID(gInputWindowClassInfo.visibleFrameTop, gInputWindowClassInfo.clazz, - "visibleFrameTop", "I"); - - GET_FIELD_ID(gInputWindowClassInfo.visibleFrameRight, gInputWindowClassInfo.clazz, - "visibleFrameRight", "I"); - - GET_FIELD_ID(gInputWindowClassInfo.visibleFrameBottom, gInputWindowClassInfo.clazz, - "visibleFrameBottom", "I"); - - GET_FIELD_ID(gInputWindowClassInfo.touchableAreaLeft, gInputWindowClassInfo.clazz, - "touchableAreaLeft", "I"); - - GET_FIELD_ID(gInputWindowClassInfo.touchableAreaTop, gInputWindowClassInfo.clazz, - "touchableAreaTop", "I"); - - GET_FIELD_ID(gInputWindowClassInfo.touchableAreaRight, gInputWindowClassInfo.clazz, - "touchableAreaRight", "I"); - - GET_FIELD_ID(gInputWindowClassInfo.touchableAreaBottom, gInputWindowClassInfo.clazz, - "touchableAreaBottom", "I"); + GET_FIELD_ID(gInputWindowClassInfo.touchableRegion, gInputWindowClassInfo.clazz, + "touchableRegion", "Landroid/graphics/Region;"); GET_FIELD_ID(gInputWindowClassInfo.visible, gInputWindowClassInfo.clazz, "visible", "Z"); diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 154b8224c34f..65ad9568b3d3 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -2132,6 +2132,9 @@ status_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy, sh = (!sh) ? hw_h : sh; const size_t size = sw * sh * 4; + LOGD("screenshot: sw=%d, sh=%d, minZ=%d, maxZ=%d", + sw, sh, minLayerZ, maxLayerZ); + // make sure to clear all GL error flags while ( glGetError() != GL_NO_ERROR ) ; @@ -2146,6 +2149,9 @@ status_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, tname); GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES); + + LOGD("screenshot: FBO created, status=0x%x", status); + if (status == GL_FRAMEBUFFER_COMPLETE_OES) { // invert everything, b/c glReadPixel() below will invert the FB @@ -2161,6 +2167,8 @@ status_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy, glClearColor(0,0,0,1); glClear(GL_COLOR_BUFFER_BIT); + LOGD("screenshot: glClear() issued"); + const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); const size_t count = layers.size(); for (size_t i=0 ; i<count ; ++i) { @@ -2171,6 +2179,8 @@ status_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy, } } + LOGD("screenshot: All layers rendered"); + // XXX: this is needed on tegra glScissor(0, 0, sw, sh); @@ -2185,6 +2195,10 @@ status_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy, new MemoryHeapBase(size, 0, "screen-capture") ); void* const ptr = base->getBase(); if (ptr) { + + LOGD("screenshot: about to call glReadPixels(0,0,%d,%d,...,%p)", + sw, sh, ptr); + // capture the screen with glReadPixels() glReadPixels(0, 0, sw, sh, GL_RGBA, GL_UNSIGNED_BYTE, ptr); if (glGetError() == GL_NO_ERROR) { @@ -2197,25 +2211,32 @@ status_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy, } else { result = NO_MEMORY; } + + LOGD("screenshot: glReadPixels() returned %s", strerror(result)); + } glEnable(GL_SCISSOR_TEST); glViewport(0, 0, hw_w, hw_h); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); - - } else { result = BAD_VALUE; } + LOGD("screenshot: about to release FBO resources"); + // release FBO resources glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); glDeleteRenderbuffersOES(1, &tname); glDeleteFramebuffersOES(1, &name); + LOGD("screenshot: about to call compositionComplete()"); + hw.compositionComplete(); + LOGD("screenshot: result = %s", strerror(result)); + return result; } diff --git a/test-runner/src/android/test/mock/MockContext.java b/test-runner/src/android/test/mock/MockContext.java index 3b52252e34ae..0b4fc51454b2 100644 --- a/test-runner/src/android/test/mock/MockContext.java +++ b/test-runner/src/android/test/mock/MockContext.java @@ -164,6 +164,11 @@ public class MockContext extends Context { } @Override + public File getObbDir() { + throw new UnsupportedOperationException(); + } + + @Override public File getCacheDir() { throw new UnsupportedOperationException(); } diff --git a/tests/HwAccelerationTest/AndroidManifest.xml b/tests/HwAccelerationTest/AndroidManifest.xml index e73afa0f4eb4..7099ab57a812 100644 --- a/tests/HwAccelerationTest/AndroidManifest.xml +++ b/tests/HwAccelerationTest/AndroidManifest.xml @@ -25,6 +25,16 @@ android:hardwareAccelerated="true"> <activity + android:name="SimplePatchActivity" + android:label="_SimplePatch" + android:theme="@android:style/Theme.Translucent.NoTitleBar"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + + <activity android:name="ViewLayersActivity" android:label="_ViewLayers"> <intent-filter> diff --git a/tests/HwAccelerationTest/res/drawable-mdpi/expander_ic_maximized.9.png b/tests/HwAccelerationTest/res/drawable-mdpi/expander_ic_maximized.9.png Binary files differnew file mode 100644 index 000000000000..d5c32766cece --- /dev/null +++ b/tests/HwAccelerationTest/res/drawable-mdpi/expander_ic_maximized.9.png diff --git a/tests/HwAccelerationTest/res/drawable-mdpi/expander_ic_minimized.9.png b/tests/HwAccelerationTest/res/drawable-mdpi/expander_ic_minimized.9.png Binary files differnew file mode 100644 index 000000000000..4515b42177bb --- /dev/null +++ b/tests/HwAccelerationTest/res/drawable-mdpi/expander_ic_minimized.9.png diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/SimplePatchActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/SimplePatchActivity.java new file mode 100644 index 000000000000..a9b4d1c3cefb --- /dev/null +++ b/tests/HwAccelerationTest/src/com/android/test/hwui/SimplePatchActivity.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2011 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.test.hwui; + +import android.app.Activity; +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.drawable.Drawable; +import android.os.Bundle; +import android.view.View; + +@SuppressWarnings({"UnusedDeclaration"}) +public class SimplePatchActivity extends Activity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(new PatchView(this)); + } + + private static class PatchView extends View { + private final Drawable mDrawable; + + public PatchView(Context context) { + super(context); + setBackgroundColor(0xff000000); + mDrawable = context.getResources().getDrawable(R.drawable.expander_ic_minimized); + } + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + canvas.save(); + canvas.translate(200, 200); + mDrawable.setBounds(3, 0, 33, 64); + mDrawable.draw(canvas); + mDrawable.setBounds(63, 0, 94, 64); + mDrawable.draw(canvas); + canvas.restore(); + } + } +} diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java index 443d881e7a4d..8422d4890b0a 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java @@ -102,7 +102,7 @@ public final class BridgeWindowSession implements IWindowSession { } public void setInsets(IWindow window, int touchable, Rect contentInsets, - Rect visibleInsets) { + Rect visibleInsets, Region touchableRegion) { // pass for now. } diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl index 9dbba202689c..847577fea4ff 100644 --- a/wifi/java/android/net/wifi/IWifiManager.aidl +++ b/wifi/java/android/net/wifi/IWifiManager.aidl @@ -19,6 +19,7 @@ package android.net.wifi; import android.net.wifi.WifiInfo; import android.net.wifi.WifiConfiguration; import android.net.wifi.WpsConfiguration; +import android.net.wifi.WpsResult; import android.net.wifi.ScanResult; import android.net.DhcpInfo; @@ -109,6 +110,6 @@ interface IWifiManager void forgetNetwork(int networkId); - String startWps(in WpsConfiguration config); + WpsResult startWps(in WpsConfiguration config); } diff --git a/wifi/java/android/net/wifi/WifiConfigStore.java b/wifi/java/android/net/wifi/WifiConfigStore.java index 56bc5d773851..73c24cf02397 100644 --- a/wifi/java/android/net/wifi/WifiConfigStore.java +++ b/wifi/java/android/net/wifi/WifiConfigStore.java @@ -370,44 +370,52 @@ class WifiConfigStore { * Start WPS pin method configuration with pin obtained * from the access point */ - static boolean startWpsWithPinFromAccessPoint(WpsConfiguration config) { + static WpsResult startWpsWithPinFromAccessPoint(WpsConfiguration config) { + WpsResult result = new WpsResult(); if (WifiNative.startWpsWithPinFromAccessPointCommand(config.BSSID, config.pin)) { /* WPS leaves all networks disabled */ markAllNetworksDisabled(); - return true; + result.status = WpsResult.Status.SUCCESS; + } else { + Log.e(TAG, "Failed to start WPS pin method configuration"); + result.status = WpsResult.Status.FAILURE; } - Log.e(TAG, "Failed to start WPS pin method configuration"); - return false; + return result; } /** * Start WPS pin method configuration with pin obtained * from the device - * @return empty string on failure. null is never returned. + * @return WpsResult indicating status and pin */ - static String startWpsWithPinFromDevice(WpsConfiguration config) { - String pin = WifiNative.startWpsWithPinFromDeviceCommand(config.BSSID); + static WpsResult startWpsWithPinFromDevice(WpsConfiguration config) { + WpsResult result = new WpsResult(); + result.pin = WifiNative.startWpsWithPinFromDeviceCommand(config.BSSID); /* WPS leaves all networks disabled */ - if (!TextUtils.isEmpty(pin)) { + if (!TextUtils.isEmpty(result.pin)) { markAllNetworksDisabled(); + result.status = WpsResult.Status.SUCCESS; } else { Log.e(TAG, "Failed to start WPS pin method configuration"); - pin = ""; + result.status = WpsResult.Status.FAILURE; } - return pin; + return result; } /** * Start WPS push button configuration */ - static boolean startWpsPbc(WpsConfiguration config) { + static WpsResult startWpsPbc(WpsConfiguration config) { + WpsResult result = new WpsResult(); if (WifiNative.startWpsPbcCommand(config.BSSID)) { /* WPS leaves all networks disabled */ markAllNetworksDisabled(); - return true; + result.status = WpsResult.Status.SUCCESS; + } else { + Log.e(TAG, "Failed to start WPS push button configuration"); + result.status = WpsResult.Status.FAILURE; } - Log.e(TAG, "Failed to start WPS push button configuration"); - return false; + return result; } /** diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 46237214861b..d05918f51e39 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -274,6 +274,25 @@ public class WifiManager { * @see #ERROR_AUTHENTICATING */ public static final String EXTRA_SUPPLICANT_ERROR = "supplicantError"; + + /** + * Broadcast intent action for reporting errors + * @hide + */ + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String ERROR_ACTION = "android.net.wifi.ERROR"; + /** + * The type of error being reported + * @hide + */ + public static final String EXTRA_ERROR_CODE = "errorCode"; + + /** + * Valid error codes + * @hide + */ + public static final int WPS_OVERLAP_ERROR = 1; + /** * Broadcast intent action indicating that the configured networks changed. * This can be as a result of adding/updating/deleting a network @@ -1074,15 +1093,15 @@ public class WifiManager { * Start Wi-fi Protected Setup * * @param config WPS configuration - * @return pin generated by device, if any + * @return WpsResult containing pin and status * @hide * TODO: with use of AsyncChannel, return value should go away */ - public String startWps(WpsConfiguration config) { + public WpsResult startWps(WpsConfiguration config) { try { return mService.startWps(config); } catch (RemoteException e) { - return null; + return new WpsResult(WpsResult.Status.FAILURE); } } diff --git a/wifi/java/android/net/wifi/WifiMonitor.java b/wifi/java/android/net/wifi/WifiMonitor.java index 934e5090e28f..090ad3b6ad2a 100644 --- a/wifi/java/android/net/wifi/WifiMonitor.java +++ b/wifi/java/android/net/wifi/WifiMonitor.java @@ -53,6 +53,9 @@ public class WifiMonitor { private static final String passwordKeyMayBeIncorrectEvent = "pre-shared key may be incorrect"; + /* WPS events */ + private static final String wpsOverlapEvent = "WPS-OVERLAP-DETECTED"; + /** * Names of events from wpa_supplicant (minus the prefix). In the * format descriptions, * "<code>x</code>" @@ -174,6 +177,8 @@ public class WifiMonitor { if (eventStr.startsWith(wpaEventPrefix) && 0 < eventStr.indexOf(passwordKeyMayBeIncorrectEvent)) { handlePasswordKeyMayBeIncorrect(); + } else if (eventStr.startsWith(wpsOverlapEvent)) { + mWifiStateMachine.notifyWpsOverlap(); } continue; } diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java index 871811730679..0548b4d5b341 100644 --- a/wifi/java/android/net/wifi/WifiStateMachine.java +++ b/wifi/java/android/net/wifi/WifiStateMachine.java @@ -47,6 +47,7 @@ import android.net.ConnectivityManager; import android.net.NetworkInfo.DetailedState; import android.net.LinkProperties; import android.net.wifi.NetworkUpdateResult; +import android.net.wifi.WpsResult.Status; import android.os.Binder; import android.os.Message; import android.os.IBinder; @@ -214,6 +215,9 @@ public class WifiStateMachine extends HierarchicalStateMachine { static final int SUPPLICANT_STATE_CHANGE_EVENT = 39; /* Password may be incorrect */ static final int PASSWORD_MAY_BE_INCORRECT_EVENT = 40; + /* WPS overlap detected */ + static final int WPS_OVERLAP_EVENT = 41; + /* Supplicant commands */ /* Is supplicant alive ? */ @@ -302,10 +306,11 @@ public class WifiStateMachine extends HierarchicalStateMachine { /* Reset the supplicant state tracker */ static final int CMD_RESET_SUPPLICANT_STATE = 111; - /* Commands/events reported by WpsStateMachine */ /* Indicates the completion of WPS activity */ static final int WPS_COMPLETED_EVENT = 121; + /* Reset the WPS state machine */ + static final int CMD_RESET_WPS_STATE = 122; private static final int CONNECT_MODE = 1; private static final int SCAN_ONLY_MODE = 2; @@ -793,18 +798,19 @@ public class WifiStateMachine extends HierarchicalStateMachine { sendMessage(obtainMessage(CMD_FORGET_NETWORK, netId, 0)); } - public String startWps(AsyncChannel channel, WpsConfiguration config) { - String result = null; + public WpsResult startWps(AsyncChannel channel, WpsConfiguration config) { + WpsResult result; switch (config.setup) { case PIN_FROM_DEVICE: + case PBC: + case PIN_FROM_ACCESS_POINT: //TODO: will go away with AsyncChannel use from settings Message resultMsg = channel.sendMessageSynchronously(CMD_START_WPS, config); - result = (String) resultMsg.obj; + result = (WpsResult) resultMsg.obj; resultMsg.recycle(); break; - case PBC: - case PIN_FROM_ACCESS_POINT: - sendMessage(obtainMessage(CMD_START_WPS, config)); + default: + result = new WpsResult(Status.FAILURE); break; } return result; @@ -1284,6 +1290,13 @@ public class WifiStateMachine extends HierarchicalStateMachine { mContext.sendStickyBroadcast(intent); } + private void sendErrorBroadcast(int errorCode) { + Intent intent = new Intent(WifiManager.ERROR_ACTION); + intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); + intent.putExtra(WifiManager.EXTRA_ERROR_CODE, errorCode); + mContext.sendBroadcast(intent); + } + private void sendLinkConfigurationChangedBroadcast() { Intent intent = new Intent(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); @@ -1379,6 +1392,14 @@ public class WifiStateMachine extends HierarchicalStateMachine { } /** + * Send a notification that the supplicant has detected overlapped + * WPS sessions + */ + void notifyWpsOverlap() { + sendMessage(WPS_OVERLAP_EVENT); + } + + /** * Send the tracker a notification that a connection to the supplicant * daemon has been established. */ @@ -1496,6 +1517,7 @@ public class WifiStateMachine extends HierarchicalStateMachine { case SCAN_RESULTS_EVENT: case SUPPLICANT_STATE_CHANGE_EVENT: case PASSWORD_MAY_BE_INCORRECT_EVENT: + case WPS_OVERLAP_EVENT: case CMD_BLACKLIST_NETWORK: case CMD_CLEAR_BLACKLIST: case CMD_SET_SCAN_MODE: @@ -1511,13 +1533,9 @@ public class WifiStateMachine extends HierarchicalStateMachine { case CMD_ENABLE_ALL_NETWORKS: break; case CMD_START_WPS: - WpsConfiguration config = (WpsConfiguration) message.obj; - switch (config.setup) { - case PIN_FROM_DEVICE: - String pin = ""; - mReplyChannel.replyToMessage(message, message.what, pin); - break; - } + /* Return failure when the state machine cannot handle WPS initiation*/ + mReplyChannel.replyToMessage(message, message.what, + new WpsResult(Status.FAILURE)); break; default: Log.e(TAG, "Error! unhandled message" + message); @@ -1803,6 +1821,7 @@ public class WifiStateMachine extends HierarchicalStateMachine { /* Reset the supplicant state to indicate the supplicant * state is not known at this time */ mSupplicantStateTracker.sendMessage(CMD_RESET_SUPPLICANT_STATE); + mWpsStateMachine.sendMessage(CMD_RESET_WPS_STATE); /* Initialize data structures */ mLastBssid = null; mLastNetworkId = -1; @@ -1884,6 +1903,7 @@ public class WifiStateMachine extends HierarchicalStateMachine { setWifiState(WIFI_STATE_DISABLING); sendSupplicantConnectionChangedBroadcast(false); mSupplicantStateTracker.sendMessage(CMD_RESET_SUPPLICANT_STATE); + mWpsStateMachine.sendMessage(CMD_RESET_WPS_STATE); transitionTo(mSupplicantStoppingState); break; case SUP_DISCONNECTION_EVENT: /* Supplicant connection lost */ @@ -1894,6 +1914,7 @@ public class WifiStateMachine extends HierarchicalStateMachine { handleNetworkDisconnect(); sendSupplicantConnectionChangedBroadcast(false); mSupplicantStateTracker.sendMessage(CMD_RESET_SUPPLICANT_STATE); + mWpsStateMachine.sendMessage(CMD_RESET_WPS_STATE); transitionTo(mDriverLoadedState); sendMessageDelayed(CMD_START_SUPPLICANT, SUPPLICANT_RESTART_INTERVAL_MSECS); break; @@ -2040,6 +2061,7 @@ public class WifiStateMachine extends HierarchicalStateMachine { case NETWORK_CONNECTION_EVENT: case NETWORK_DISCONNECTION_EVENT: case PASSWORD_MAY_BE_INCORRECT_EVENT: + case WPS_OVERLAP_EVENT: case CMD_SET_SCAN_TYPE: case CMD_SET_HIGH_PERF_MODE: case CMD_SET_COUNTRY_CODE: @@ -2274,6 +2296,10 @@ public class WifiStateMachine extends HierarchicalStateMachine { case PASSWORD_MAY_BE_INCORRECT_EVENT: mSupplicantStateTracker.sendMessage(PASSWORD_MAY_BE_INCORRECT_EVENT); break; + case WPS_OVERLAP_EVENT: + /* We just need to broadcast the error */ + sendErrorBroadcast(WifiManager.WPS_OVERLAP_ERROR); + break; case SUPPLICANT_STATE_CHANGE_EVENT: stateChangeResult = (StateChangeResult) message.obj; SupplicantState state = stateChangeResult.state; diff --git a/wifi/java/android/net/wifi/WpsResult.aidl b/wifi/java/android/net/wifi/WpsResult.aidl new file mode 100644 index 000000000000..eb4c4f5539ba --- /dev/null +++ b/wifi/java/android/net/wifi/WpsResult.aidl @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2010, 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.net.wifi; + +parcelable WpsResult; diff --git a/wifi/java/android/net/wifi/WpsResult.java b/wifi/java/android/net/wifi/WpsResult.java new file mode 100644 index 000000000000..d4fd3e23d08f --- /dev/null +++ b/wifi/java/android/net/wifi/WpsResult.java @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2010 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.net.wifi; + +import android.os.Parcel; +import android.os.Parcelable; + +/** + * A class representing the result of a WPS request + * @hide + */ +public class WpsResult implements Parcelable { + + public enum Status { + SUCCESS, + FAILURE, + IN_PROGRESS, + } + + public Status status; + + public String pin; + + public WpsResult() { + status = Status.FAILURE; + pin = null; + } + + public WpsResult(Status s) { + status = s; + pin = null; + } + + public String toString() { + StringBuffer sbuf = new StringBuffer(); + sbuf.append(" status: ").append(status.toString()); + sbuf.append('\n'); + sbuf.append(" pin: ").append(pin); + sbuf.append("\n"); + return sbuf.toString(); + } + + /** Implement the Parcelable interface {@hide} */ + public int describeContents() { + return 0; + } + + /** copy constructor {@hide} */ + public WpsResult(WpsResult source) { + if (source != null) { + status = source.status; + pin = source.pin; + } + } + + /** Implement the Parcelable interface {@hide} */ + public void writeToParcel(Parcel dest, int flags) { + dest.writeString(status.name()); + dest.writeString(pin); + } + + /** Implement the Parcelable interface {@hide} */ + public static final Creator<WpsResult> CREATOR = + new Creator<WpsResult>() { + public WpsResult createFromParcel(Parcel in) { + WpsResult result = new WpsResult(); + result.status = Status.valueOf(in.readString()); + result.pin = in.readString(); + return result; + } + + public WpsResult[] newArray(int size) { + return new WpsResult[size]; + } + }; +} diff --git a/wifi/java/android/net/wifi/WpsStateMachine.java b/wifi/java/android/net/wifi/WpsStateMachine.java index 381444c9b53f..92f9f57f5448 100644 --- a/wifi/java/android/net/wifi/WpsStateMachine.java +++ b/wifi/java/android/net/wifi/WpsStateMachine.java @@ -23,6 +23,7 @@ import com.android.internal.util.HierarchicalStateMachine; import android.content.Context; import android.content.Intent; import android.net.wifi.WifiStateMachine.StateChangeResult; +import android.net.wifi.WpsResult.Status; import android.os.Handler; import android.os.Message; import android.os.Parcelable; @@ -93,29 +94,32 @@ class WpsStateMachine extends HierarchicalStateMachine { switch (message.what) { case WifiStateMachine.CMD_START_WPS: mWpsConfig = (WpsConfiguration) message.obj; - boolean success = false; + WpsResult result; switch (mWpsConfig.setup) { case PBC: - success = WifiConfigStore.startWpsPbc(mWpsConfig); + result = WifiConfigStore.startWpsPbc(mWpsConfig); break; case PIN_FROM_ACCESS_POINT: - success = WifiConfigStore.startWpsWithPinFromAccessPoint(mWpsConfig); + result = WifiConfigStore.startWpsWithPinFromAccessPoint(mWpsConfig); break; case PIN_FROM_DEVICE: - String pin = WifiConfigStore.startWpsWithPinFromDevice(mWpsConfig); - success = (pin != null); - mReplyChannel.replyToMessage(message, message.what, pin); + result = WifiConfigStore.startWpsWithPinFromDevice(mWpsConfig); break; default: + result = new WpsResult(Status.FAILURE); Log.e(TAG, "Invalid setup for WPS"); break; } - if (success) { + mReplyChannel.replyToMessage(message, message.what, result); + if (result.status == Status.SUCCESS) { transitionTo(mActiveState); } else { Log.e(TAG, "Failed to start WPS with config " + mWpsConfig.toString()); } break; + case WifiStateMachine.CMD_RESET_WPS_STATE: + transitionTo(mInactiveState); + break; default: Log.e(TAG, "Failed to handle " + message); break; @@ -167,7 +171,9 @@ class WpsStateMachine extends HierarchicalStateMachine { } break; case WifiStateMachine.CMD_START_WPS: - deferMessage(message); + /* Ignore request and send an in progress message */ + mReplyChannel.replyToMessage(message, message.what, + new WpsResult(Status.IN_PROGRESS)); break; default: retValue = NOT_HANDLED; @@ -197,4 +203,4 @@ class WpsStateMachine extends HierarchicalStateMachine { } } -}
\ No newline at end of file +} |