diff options
27 files changed, 577 insertions, 254 deletions
@@ -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" @@ -25114,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" @@ -25523,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" @@ -38947,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" @@ -48119,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" @@ -49727,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" @@ -58210,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" @@ -60220,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" @@ -60706,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" @@ -137446,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" @@ -137578,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" @@ -185171,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" @@ -185670,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" @@ -238084,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 f7172f4..6b79074 100644 --- a/api/current.xml +++ b/api/current.xml @@ -25158,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" @@ -25567,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" @@ -48174,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" @@ -49782,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" @@ -95606,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" @@ -95637,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" diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index 4eae14b..d5aa961 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -122,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; @@ -203,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; @@ -214,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. @@ -261,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/ContextImpl.java b/core/java/android/app/ContextImpl.java index e133ea0..6f63990 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 a5c49ec..35cc324 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 227df21..d14cf4d 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 545144e..3928aaf 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/res/CompatibilityInfo.java b/core/java/android/content/res/CompatibilityInfo.java index 406b091..6baf1c2 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/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java index 23b9ad5..4d25bac 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/Environment.java b/core/java/android/os/Environment.java index 4f188f8..cc95642 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 a5f405a..1218e81 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 e228537..96f8cdc 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) { } } diff --git a/core/java/android/view/ViewTreeObserver.java b/core/java/android/view/ViewTreeObserver.java index 06a0fa6..db87175 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/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index d28bdc9..f023e94 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 723cd37..c43b5ce 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 0000000..c15f06e --- /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_app_NativeActivity.cpp b/core/jni/android_app_NativeActivity.cpp index b033878..0430a81 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/native/include/android/native_activity.h b/native/include/android/native_activity.h index d89bc8b..a361846 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/services/input/InputDispatcher.cpp b/services/input/InputDispatcher.cpp index b5a4bd2..e314145 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 9ce45f5..b552f6d 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 b3d5a65..9c43067 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 1515290..2c2cdfe 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/SystemServer.java b/services/java/com/android/server/SystemServer.java index 6f4b4c5..978946f 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/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java index bdc779c..1b3725c 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 a4609a0..7515456 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/test-runner/src/android/test/mock/MockContext.java b/test-runner/src/android/test/mock/MockContext.java index 3b52252..0b4fc51 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/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java index 443d881..8422d48 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. } |