summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorJeff Brown <jeffbrown@google.com>2011-01-16 14:06:57 -0800
committerJeff Brown <jeffbrown@google.com>2011-01-16 18:58:49 -0800
commitfbf097732137a32930d151f7ba6816a5b870c32a (patch)
tree1f05823ea1cb06aaa3ab0954cdde614b370f30e6 /core
parent115ad16551c9cf9551f44cbea59f3edf83e4a340 (diff)
downloadframeworks_base-fbf097732137a32930d151f7ba6816a5b870c32a.zip
frameworks_base-fbf097732137a32930d151f7ba6816a5b870c32a.tar.gz
frameworks_base-fbf097732137a32930d151f7ba6816a5b870c32a.tar.bz2
Support non-rectangular input regions.
This enables the system bar to carve out a region through which events will be sent to the IME behind it. Bug: 3238092 Change-Id: I69b855a8d9b5b3ee525266c0861826e53e5b5028
Diffstat (limited to 'core')
-rw-r--r--core/java/android/content/res/CompatibilityInfo.java16
-rw-r--r--core/java/android/inputmethodservice/InputMethodService.java28
-rw-r--r--core/java/android/view/IWindowSession.aidl2
-rw-r--r--core/java/android/view/ViewRoot.java36
-rw-r--r--core/java/android/view/ViewTreeObserver.java36
-rw-r--r--core/jni/AndroidRuntime.cpp2
-rw-r--r--core/jni/android/graphics/Region.cpp33
-rw-r--r--core/jni/android/graphics/Region.h30
8 files changed, 147 insertions, 36 deletions
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/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 ad9e6863..b7ab3c1 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