Merge "Screen magnification should disengage on screen off." into jb-mr1-dev
diff --git a/core/java/android/webkit/BrowserFrame.java b/core/java/android/webkit/BrowserFrame.java
index 6074a0c..9e4ec3c 100644
--- a/core/java/android/webkit/BrowserFrame.java
+++ b/core/java/android/webkit/BrowserFrame.java
@@ -89,8 +89,19 @@
// Is this frame the main frame?
private boolean mIsMainFrame;
+ // Javascript interface object
+ private class JSObject {
+ Object object;
+ boolean requireAnnotation;
+
+ public JSObject(Object object, boolean requireAnnotation) {
+ this.object = object;
+ this.requireAnnotation = requireAnnotation;
+ }
+ }
+
// Attached Javascript interfaces
- private Map<String, Object> mJavaScriptObjects;
+ private Map<String, JSObject> mJavaScriptObjects;
private Set<Object> mRemovedJavaScriptObjects;
// Key store handler when Chromium HTTP stack is used.
@@ -234,10 +245,8 @@
}
sConfigCallback.addHandler(this);
- mJavaScriptObjects = javascriptInterfaces;
- if (mJavaScriptObjects == null) {
- mJavaScriptObjects = new HashMap<String, Object>();
- }
+ mJavaScriptObjects = new HashMap<String, JSObject>();
+ addJavaScriptObjects(javascriptInterfaces);
mRemovedJavaScriptObjects = new HashSet<Object>();
mSettings = settings;
@@ -590,15 +599,36 @@
Iterator<String> iter = mJavaScriptObjects.keySet().iterator();
while (iter.hasNext()) {
String interfaceName = iter.next();
- Object object = mJavaScriptObjects.get(interfaceName);
- if (object != null) {
+ JSObject jsobject = mJavaScriptObjects.get(interfaceName);
+ if (jsobject != null && jsobject.object != null) {
nativeAddJavascriptInterface(nativeFramePointer,
- mJavaScriptObjects.get(interfaceName), interfaceName);
+ jsobject.object, interfaceName, jsobject.requireAnnotation);
}
}
mRemovedJavaScriptObjects.clear();
}
+ /*
+ * Add javascript objects to the internal list of objects. The default behavior
+ * is to allow access to inherited methods (no annotation needed). This is only
+ * used when js objects are passed through a constructor (via a hidden constructor).
+ *
+ * @TODO change the default behavior to be compatible with the public addjavascriptinterface
+ */
+ private void addJavaScriptObjects(Map<String, Object> javascriptInterfaces) {
+
+ // TODO in a separate CL provide logic to enable annotations for API level JB_MR1 and above.
+ if (javascriptInterfaces == null) return;
+ Iterator<String> iter = javascriptInterfaces.keySet().iterator();
+ while (iter.hasNext()) {
+ String interfaceName = iter.next();
+ Object object = javascriptInterfaces.get(interfaceName);
+ if (object != null) {
+ mJavaScriptObjects.put(interfaceName, new JSObject(object, false));
+ }
+ }
+ }
+
/**
* This method is called by WebCore to check whether application
* wants to hijack url loading
@@ -616,11 +646,11 @@
}
}
- public void addJavascriptInterface(Object obj, String interfaceName) {
+ public void addJavascriptInterface(Object obj, String interfaceName,
+ boolean requireAnnotation) {
assert obj != null;
removeJavascriptInterface(interfaceName);
-
- mJavaScriptObjects.put(interfaceName, obj);
+ mJavaScriptObjects.put(interfaceName, new JSObject(obj, requireAnnotation));
}
public void removeJavascriptInterface(String interfaceName) {
@@ -1245,7 +1275,7 @@
* Add a javascript interface to the main frame.
*/
private native void nativeAddJavascriptInterface(int nativeFramePointer,
- Object obj, String interfaceName);
+ Object obj, String interfaceName, boolean requireAnnotation);
public native void clearCache();
diff --git a/core/java/android/webkit/JavascriptInterface.java b/core/java/android/webkit/JavascriptInterface.java
new file mode 100644
index 0000000..3f1ed12
--- /dev/null
+++ b/core/java/android/webkit/JavascriptInterface.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2012 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.webkit;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation that allows exposing methods to JavaScript. Starting from API level
+ * {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1} and above, only methods explicitly
+ * marked with this annotation are available to the Javascript code. See
+ * {@link android.webkit.Webview#addJavaScriptInterface} for more information about it.
+ *
+ * @hide
+ */
+@SuppressWarnings("javadoc")
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD})
+public @interface JavascriptInterface {
+}
\ No newline at end of file
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 82635d7..9d6d929 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -26,6 +26,7 @@
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.net.http.SslCertificate;
+import android.os.Build;
import android.os.Bundle;
import android.os.Looper;
import android.os.Message;
@@ -1507,6 +1508,9 @@
public void addJavascriptInterface(Object object, String name) {
checkThread();
mProvider.addJavascriptInterface(object, name);
+ // TODO in a separate CL provide logic to enable annotations for API level JB_MR1 and above. Don't forget to
+ // update the doc, set a link to annotation and unhide the annotation.
+ // also describe that fields of java objects are not accessible from JS.
}
/**
diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java
index 494a28c..351c4f3 100644
--- a/core/java/android/webkit/WebViewClassic.java
+++ b/core/java/android/webkit/WebViewClassic.java
@@ -4114,12 +4114,15 @@
*/
@Override
public void addJavascriptInterface(Object object, String name) {
+
if (object == null) {
return;
}
WebViewCore.JSInterfaceData arg = new WebViewCore.JSInterfaceData();
+ // TODO in a separate CL provide logic to enable annotations for API level JB_MR1 and above.
arg.mObject = object;
arg.mInterfaceName = name;
+ arg.mRequireAnnotation = false;
mWebViewCore.sendMessage(EventHub.ADD_JS_INTERFACE, arg);
}
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index 59036e7..2d834ff 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -824,6 +824,7 @@
static class JSInterfaceData {
Object mObject;
String mInterfaceName;
+ boolean mRequireAnnotation;
}
static class JSKeyData {
@@ -1489,7 +1490,7 @@
case ADD_JS_INTERFACE:
JSInterfaceData jsData = (JSInterfaceData) msg.obj;
mBrowserFrame.addJavascriptInterface(jsData.mObject,
- jsData.mInterfaceName);
+ jsData.mInterfaceName, jsData.mRequireAnnotation);
break;
case REMOVE_JS_INTERFACE:
diff --git a/core/res/res/layout-land/keyguard_host_view.xml b/core/res/res/layout-land/keyguard_host_view.xml
index 0028a54..8e7c232 100644
--- a/core/res/res/layout-land/keyguard_host_view.xml
+++ b/core/res/res/layout-land/keyguard_host_view.xml
@@ -38,7 +38,7 @@
</com.android.internal.policy.impl.keyguard.KeyguardWidgetPager>
- <ViewFlipper
+ <com.android.internal.policy.impl.keyguard.KeyguardSecurityViewFlipper
android:id="@+id/view_flipper"
android:layout_width="0dip"
android:layout_height="match_parent"
@@ -48,6 +48,6 @@
<!-- SelectorView is always used, so add it here. The rest are loaded dynamically -->
<include layout="@layout/keyguard_selector_view"/>
- </ViewFlipper>
+ </com.android.internal.policy.impl.keyguard.KeyguardSecurityViewFlipper>
</com.android.internal.policy.impl.keyguard.KeyguardHostView>
diff --git a/core/res/res/layout-port/keyguard_host_view.xml b/core/res/res/layout-port/keyguard_host_view.xml
index 5e467d1..55c4c0d 100644
--- a/core/res/res/layout-port/keyguard_host_view.xml
+++ b/core/res/res/layout-port/keyguard_host_view.xml
@@ -28,7 +28,7 @@
android:gravity="center_horizontal"
android:clipChildren="false">
- <ViewFlipper
+ <com.android.internal.policy.impl.keyguard.KeyguardSecurityViewFlipper
android:id="@+id/view_flipper"
android:layout_height="match_parent"
android:gravity="center">
@@ -36,7 +36,7 @@
<!-- SelectorView is always used, so add it here. The rest are loaded dynamically -->
<include layout="@layout/keyguard_selector_view"/>
- </ViewFlipper>
+ </com.android.internal.policy.impl.keyguard.KeyguardSecurityViewFlipper>
</com.android.internal.policy.impl.keyguard.KeyguardHostView>
diff --git a/core/res/res/layout-sw600dp-land/keyguard_host_view.xml b/core/res/res/layout-sw600dp-land/keyguard_host_view.xml
index 5b6bb2f..652bdde 100644
--- a/core/res/res/layout-sw600dp-land/keyguard_host_view.xml
+++ b/core/res/res/layout-sw600dp-land/keyguard_host_view.xml
@@ -44,7 +44,7 @@
android:layout_weight="1"
android:gravity="center">
- <ViewFlipper
+ <com.android.internal.policy.impl.keyguard.KeyguardSecurityViewFlipper
android:id="@+id/view_flipper"
android:layout_width="@dimen/kg_security_view_width"
android:layout_height="match_parent"
@@ -55,7 +55,7 @@
<!-- SelectorView is always used, so add it here. The rest are loaded dynamically -->
<include layout="@layout/keyguard_selector_view"/>
- </ViewFlipper>
+ </com.android.internal.policy.impl.keyguard.KeyguardSecurityViewFlipper>
</FrameLayout>
diff --git a/core/res/res/layout-sw600dp-port/keyguard_host_view.xml b/core/res/res/layout-sw600dp-port/keyguard_host_view.xml
index 397b881..0c1dd0c 100644
--- a/core/res/res/layout-sw600dp-port/keyguard_host_view.xml
+++ b/core/res/res/layout-sw600dp-port/keyguard_host_view.xml
@@ -40,7 +40,7 @@
</com.android.internal.policy.impl.keyguard.KeyguardWidgetPager>
- <ViewFlipper
+ <com.android.internal.policy.impl.keyguard.KeyguardSecurityViewFlipper
android:id="@+id/view_flipper"
android:layout_width="@dimen/kg_security_view_width"
android:layout_height="0dip"
@@ -50,7 +50,7 @@
<!-- SelectorView is always used, so add it here. The rest are loaded dynamically -->
<include layout="@layout/keyguard_selector_view"/>
- </ViewFlipper>
+ </com.android.internal.policy.impl.keyguard.KeyguardSecurityViewFlipper>
</com.android.internal.policy.impl.keyguard.KeyguardHostView>
diff --git a/core/res/res/layout/keyguard_pattern_view.xml b/core/res/res/layout/keyguard_pattern_view.xml
index 954a92c..356bce3 100644
--- a/core/res/res/layout/keyguard_pattern_view.xml
+++ b/core/res/res/layout/keyguard_pattern_view.xml
@@ -23,42 +23,36 @@
<com.android.internal.policy.impl.keyguard.KeyguardPatternView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/keyguard_pattern_view"
+ android:orientation="vertical"
android:layout_width="match_parent"
- android:layout_height="match_parent">
+ android:layout_height="match_parent"
+ android:gravity="center_horizontal">
- <GridLayout
- android:orientation="vertical"
+ <include layout="@layout/keyguard_navigation"/>
+
+ <Space android:layout_gravity="fill" />
+
+ <Button android:id="@+id/forgot_password_button"
+ android:layout_gravity="right"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textSize="@*android:dimen/keyguard_lockscreen_status_line_font_size"
+ android:drawableLeft="@*android:drawable/lockscreen_forgot_password_button"
+ android:drawablePadding="0dip"
+ android:visibility="gone"/>
+
+ <!-- We need MATCH_PARENT here only to force the size of the parent to be passed to
+ the pattern view for it to compute its size. This is an unusual case, caused by
+ LockPatternView's requirement to maintain a square aspect ratio based on the width
+ of the screen. -->
+ <com.android.internal.widget.LockPatternView
+ android:id="@+id/lockPatternView"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:gravity="center_horizontal">
-
- <include layout="@layout/keyguard_navigation"/>
-
- <Space android:layout_gravity="fill" />
-
- <Button android:id="@+id/forgot_password_button"
- android:layout_gravity="right"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textSize="@*android:dimen/keyguard_lockscreen_status_line_font_size"
- android:drawableLeft="@*android:drawable/lockscreen_forgot_password_button"
- android:drawablePadding="0dip"
- android:visibility="gone"/>
-
- <!-- We need MATCH_PARENT here only to force the size of the parent to be passed to
- the pattern view for it to compute its size. This is an unusual case, caused by
- LockPatternView's requirement to maintain a square aspect ratio based on the width
- of the screen. -->
- <com.android.internal.widget.LockPatternView
- android:id="@+id/lockPatternView"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_marginEnd="8dip"
- android:layout_marginBottom="4dip"
- android:layout_marginStart="8dip"
- android:layout_gravity="center_horizontal"
- />
-
- </GridLayout>
+ android:layout_marginEnd="8dip"
+ android:layout_marginBottom="4dip"
+ android:layout_marginStart="8dip"
+ android:layout_gravity="center_horizontal"
+ />
</com.android.internal.policy.impl.keyguard.KeyguardPatternView>
diff --git a/core/res/res/layout/preference_holo.xml b/core/res/res/layout/preference_holo.xml
index 7a0a494..1cc803b 100644
--- a/core/res/res/layout/preference_holo.xml
+++ b/core/res/res/layout/preference_holo.xml
@@ -33,11 +33,12 @@
android:orientation="horizontal">
<ImageView
android:id="@+android:id/icon"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_width="48dp"
+ android:layout_height="48dp"
android:layout_gravity="center"
android:minWidth="48dp"
- android:paddingRight="@dimen/preference_item_padding_inner"
+ android:scaleType="centerInside"
+ android:layout_marginEnd="@dimen/preference_item_padding_inner"
/>
</LinearLayout>
@@ -56,7 +57,7 @@
android:textAppearance="?android:attr/textAppearanceMedium"
android:ellipsize="marquee"
android:fadingEdge="horizontal" />
-
+
<TextView android:id="@+android:id/summary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
index 216344d..561e33e 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
@@ -36,6 +36,7 @@
import android.os.PowerManager;
import android.os.ServiceManager;
import android.os.SystemClock;
+import android.os.UserHandle;
import android.provider.Settings;
import android.util.Log;
import android.view.KeyEvent;
@@ -696,12 +697,12 @@
*/
public void setAirplaneMode(Context context, boolean enableAM) {
//set the airplane mode
- Settings.System.putInt(context.getContentResolver(), Settings.System.AIRPLANE_MODE_ON,
+ Settings.Global.putInt(context.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON,
enableAM ? 1 : 0);
// Post the intent
Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
intent.putExtra("state", enableAM);
- context.sendBroadcast(intent);
+ context.sendBroadcastAsUser(intent, UserHandle.ALL);
}
protected static String convertToQuotedString(String string) {
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java
index bf188d3..7928822 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java
@@ -59,8 +59,8 @@
wl = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "CMWakeLock");
wl.acquire();
// Each test case will start with cellular connection
- if (Settings.System.getInt(getInstrumentation().getContext().getContentResolver(),
- Settings.System.AIRPLANE_MODE_ON) == 1) {
+ if (Settings.Global.getInt(getInstrumentation().getContext().getContentResolver(),
+ Settings.Global.AIRPLANE_MODE_ON) == 1) {
log("airplane is not disabled, disable it.");
cmActivity.setAirplaneMode(getInstrumentation().getContext(), false);
}
@@ -84,8 +84,8 @@
wl.release();
cmActivity.removeConfiguredNetworksAndDisableWifi();
// if airplane mode is set, disable it.
- if (Settings.System.getInt(getInstrumentation().getContext().getContentResolver(),
- Settings.System.AIRPLANE_MODE_ON) == 1) {
+ if (Settings.Global.getInt(getInstrumentation().getContext().getContentResolver(),
+ Settings.Global.AIRPLANE_MODE_ON) == 1) {
log("disable airplane mode if it is enabled");
cmActivity.setAirplaneMode(getInstrumentation().getContext(), false);
}
diff --git a/core/tests/coretests/src/android/app/DownloadManagerBaseTest.java b/core/tests/coretests/src/android/app/DownloadManagerBaseTest.java
index b2075ae..af2a944 100644
--- a/core/tests/coretests/src/android/app/DownloadManagerBaseTest.java
+++ b/core/tests/coretests/src/android/app/DownloadManagerBaseTest.java
@@ -29,6 +29,7 @@
import android.net.wifi.WifiManager;
import android.os.Environment;
import android.os.ParcelFileDescriptor;
+import android.os.UserHandle;
import android.os.ParcelFileDescriptor.AutoCloseInputStream;
import android.os.SystemClock;
import android.provider.Settings;
@@ -553,7 +554,7 @@
int state = enable ? 1 : 0;
// Change the system setting
- Settings.System.putInt(mContext.getContentResolver(), Settings.System.AIRPLANE_MODE_ON,
+ Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON,
state);
String timeoutMessage = "Timed out waiting for airplane mode to be " +
@@ -561,8 +562,8 @@
// wait for airplane mode to change state
int currentWaitTime = 0;
- while (Settings.System.getInt(mContext.getContentResolver(),
- Settings.System.AIRPLANE_MODE_ON, -1) != state) {
+ while (Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.AIRPLANE_MODE_ON, -1) != state) {
timeoutWait(currentWaitTime, DEFAULT_WAIT_POLL_TIME, DEFAULT_MAX_WAIT_TIME,
timeoutMessage);
}
@@ -570,7 +571,7 @@
// Post the intent
Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
intent.putExtra("state", true);
- mContext.sendBroadcast(intent);
+ mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
}
/**
diff --git a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
index 1868d1c..785842f 100755
--- a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
+++ b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
@@ -72,6 +72,8 @@
public final long WAIT_TIME_INCR = 5 * 1000;
+ private static final String APP_LIB_DIR_PREFIX = "/data/app-lib/";
+
private static final String SECURE_CONTAINERS_PREFIX = "/mnt/asec/";
private static final int APP_INSTALL_AUTO = PackageHelper.APP_INSTALL_AUTO;
@@ -433,7 +435,7 @@
assertEquals(srcPath, appInstallPath);
assertEquals(publicSrcPath, appInstallPath);
assertStartsWith("Native library should point to shared lib directory",
- dataDir.getPath(),
+ new File(APP_LIB_DIR_PREFIX, info.packageName).getPath(),
info.nativeLibraryDir);
assertDirOwnerGroupPerms(
"Native library directory should be owned by system:system and 0755",
diff --git a/include/androidfw/Input.h b/include/androidfw/Input.h
index 2c91fab..e88835e 100644
--- a/include/androidfw/Input.h
+++ b/include/androidfw/Input.h
@@ -49,6 +49,15 @@
};
enum {
+ /* Used when a motion event is not associated with any display.
+ * Typically used for non-pointer events. */
+ ADISPLAY_ID_NONE = -1,
+
+ /* The default display id. */
+ ADISPLAY_ID_DEFAULT = 0,
+};
+
+enum {
/*
* Indicates that an input device has switches.
* This input source flag is hidden from the API because switches are only used by the system
diff --git a/libs/hwui/Patch.cpp b/libs/hwui/Patch.cpp
index 6971d8a..abc88fa 100644
--- a/libs/hwui/Patch.cpp
+++ b/libs/hwui/Patch.cpp
@@ -266,6 +266,11 @@
const uint32_t oldQuadCount = quadCount;
quadCount++;
+ if (x1 < 0.0f) x1 = 0.0f;
+ if (x2 < 0.0f) x2 = 0.0f;
+ if (y1 < 0.0f) y1 = 0.0f;
+ if (y2 < 0.0f) y2 = 0.0f;
+
// Skip degenerate and transparent (empty) quads
if ((mColorKey >> oldQuadCount) & 0x1) {
#if DEBUG_PATCHES_EMPTY_VERTICES
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
index f374c11..cad6d57 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
@@ -32,6 +32,7 @@
import android.hardware.display.WifiDisplay;
import android.hardware.display.WifiDisplayStatus;
import android.net.Uri;
+import android.os.UserHandle;
import android.provider.ContactsContract;
import android.provider.Settings;
import android.view.LayoutInflater;
@@ -147,7 +148,7 @@
// TODO: Sets the view to be "awaiting" if not already awaiting
// Change the system setting
- Settings.System.putInt(mContext.getContentResolver(), Settings.System.AIRPLANE_MODE_ON,
+ Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON,
enabled ? 1 : 0);
// TODO: Update the UI to reflect system setting
@@ -156,7 +157,7 @@
// Post the intent
Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
intent.putExtra("state", enabled);
- mContext.sendBroadcast(intent);
+ mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
}
// NetworkSignalChanged callback
@Override
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 edad370..3c8276d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AirplaneModeController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AirplaneModeController.java
@@ -74,7 +74,7 @@
private boolean getAirplaneMode() {
ContentResolver cr = mContext.getContentResolver();
- return 0 != Settings.System.getInt(cr, Settings.System.AIRPLANE_MODE_ON, 0);
+ return 0 != Settings.Global.getInt(cr, Settings.Global.AIRPLANE_MODE_ON, 0);
}
// TODO: Fix this racy API by adding something better to TelephonyManager or
@@ -82,9 +82,9 @@
private void unsafe(final boolean enabled) {
AsyncTask.execute(new Runnable() {
public void run() {
- Settings.System.putInt(
+ Settings.Global.putInt(
mContext.getContentResolver(),
- Settings.System.AIRPLANE_MODE_ON,
+ Settings.Global.AIRPLANE_MODE_ON,
enabled ? 1 : 0);
Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
index 23f27e7..ea7235d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
@@ -509,8 +509,8 @@
}
private void updateAirplaneMode() {
- mAirplaneMode = (Settings.System.getInt(mContext.getContentResolver(),
- Settings.System.AIRPLANE_MODE_ON, 0) == 1);
+ mAirplaneMode = (Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.AIRPLANE_MODE_ON, 0) == 1);
}
private final void updateTelephonySignalStrength() {
diff --git a/policy/src/com/android/internal/policy/impl/GlobalActions.java b/policy/src/com/android/internal/policy/impl/GlobalActions.java
index 10f45a5..753b864 100644
--- a/policy/src/com/android/internal/policy/impl/GlobalActions.java
+++ b/policy/src/com/android/internal/policy/impl/GlobalActions.java
@@ -115,7 +115,7 @@
context.getSystemService(Context.CONNECTIVITY_SERVICE);
mHasTelephony = cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE);
mContext.getContentResolver().registerContentObserver(
- Settings.System.getUriFor(Settings.System.AIRPLANE_MODE_ON), true,
+ Settings.Global.getUriFor(Settings.Global.AIRPLANE_MODE_ON), true,
mAirplaneModeObserver);
Vibrator vibrator = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE);
mHasVibrator = vibrator != null && vibrator.hasVibrator();
@@ -849,9 +849,9 @@
// Let the service state callbacks handle the state.
if (mHasTelephony) return;
- boolean airplaneModeOn = Settings.System.getInt(
+ boolean airplaneModeOn = Settings.Global.getInt(
mContext.getContentResolver(),
- Settings.System.AIRPLANE_MODE_ON,
+ Settings.Global.AIRPLANE_MODE_ON,
0) == 1;
mAirplaneState = airplaneModeOn ? ToggleAction.State.On : ToggleAction.State.Off;
mAirplaneModeOn.updateState(mAirplaneState);
@@ -861,9 +861,9 @@
* Change the airplane mode system setting
*/
private void changeAirplaneModeSystemSetting(boolean on) {
- Settings.System.putInt(
+ Settings.Global.putInt(
mContext.getContentResolver(),
- Settings.System.AIRPLANE_MODE_ON,
+ Settings.Global.AIRPLANE_MODE_ON,
on ? 1 : 0);
Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
index e170ec1..863f4f8 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
@@ -32,17 +32,17 @@
import android.content.pm.UserInfo;
import android.content.res.Resources;
import android.graphics.Canvas;
+import android.graphics.Rect;
import android.os.UserManager;
-import android.telephony.TelephonyManager;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Slog;
import android.view.KeyEvent;
import android.view.LayoutInflater;
+import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.view.animation.AnimationUtils;
-import android.widget.Button;
import android.widget.RemoteViews.OnClickHandler;
import android.widget.ViewFlipper;
@@ -51,7 +51,6 @@
import com.android.internal.widget.LockPatternUtils;
import java.io.File;
-import java.util.ArrayList;
import java.util.List;
public class KeyguardHostView extends KeyguardViewBase {
@@ -77,6 +76,8 @@
private KeyguardSecurityModel mSecurityModel;
+ private Rect mTempRect = new Rect();
+
public KeyguardHostView(Context context) {
this(context, null);
}
@@ -94,6 +95,17 @@
}
@Override
+ public boolean dispatchTouchEvent(MotionEvent ev) {
+ boolean result = super.dispatchTouchEvent(ev);
+ mTempRect.set(0, 0, 0, 0);
+ offsetRectIntoDescendantCoords(mSecurityViewContainer, mTempRect);
+ ev.offsetLocation(mTempRect.left, mTempRect.top);
+ result = mSecurityViewContainer.dispatchTouchEvent(ev) || result;
+ ev.offsetLocation(-mTempRect.left, -mTempRect.top);
+ return result;
+ }
+
+ @Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
mViewMediatorCallback.keyguardDoneDrawing();
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPatternView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPatternView.java
index 3a32b5b..6de40e4 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPatternView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPatternView.java
@@ -22,6 +22,7 @@
import android.accounts.AuthenticatorException;
import android.accounts.OperationCanceledException;
import android.content.Context;
+import android.graphics.Rect;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.SystemClock;
@@ -31,7 +32,7 @@
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
-import android.widget.LinearLayout;
+import android.widget.GridLayout;
import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.LockPatternView;
@@ -40,7 +41,7 @@
import java.io.IOException;
import java.util.List;
-public class KeyguardPatternView extends LinearLayout implements KeyguardSecurityView {
+public class KeyguardPatternView extends GridLayout implements KeyguardSecurityView {
private static final String TAG = "SecurityPatternView";
private static final boolean DEBUG = false;
@@ -83,6 +84,7 @@
mLockPatternView.clearPattern();
}
};
+ private Rect mTempRect = new Rect();
enum FooterMode {
Normal,
@@ -156,13 +158,18 @@
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
- final boolean result = super.dispatchTouchEvent(ev);
+ boolean result = super.dispatchTouchEvent(ev);
// as long as the user is entering a pattern (i.e sending a touch event that was handled
// by this screen), keep poking the wake lock so that the screen will stay on.
final long elapsed = SystemClock.elapsedRealtime() - mLastPokeTime;
if (result && (elapsed > (UNLOCK_PATTERN_WAKE_INTERVAL_MS - 100))) {
mLastPokeTime = SystemClock.elapsedRealtime();
}
+ mTempRect.set(0, 0, 0, 0);
+ offsetRectIntoDescendantCoords(mLockPatternView, mTempRect);
+ ev.offsetLocation(mTempRect.left, mTempRect.top);
+ result = mLockPatternView.dispatchTouchEvent(ev) || result;
+ ev.offsetLocation(-mTempRect.left, -mTempRect.top);
return result;
}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityViewFlipper.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityViewFlipper.java
new file mode 100644
index 0000000..911cfe0
--- /dev/null
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityViewFlipper.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.policy.impl.keyguard;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.View;
+import android.widget.ViewFlipper;
+
+/**
+ * Subclass of the current view flipper that allows us to overload dispatchTouchEvent() so
+ * we can emulate {@link WindowManager.LayoutParams#FLAG_SLIPPERY} within a view hierarchy.
+ *
+ */
+public class KeyguardSecurityViewFlipper extends ViewFlipper {
+ private Rect mTempRect = new Rect();
+
+ public KeyguardSecurityViewFlipper(Context context) {
+ this(context, null);
+ }
+
+ public KeyguardSecurityViewFlipper(Context context, AttributeSet attr) {
+ super(context, attr);
+ }
+
+ @Override
+ public boolean dispatchTouchEvent(MotionEvent ev) {
+ boolean result = super.dispatchTouchEvent(ev);
+ mTempRect.set(0, 0, 0, 0);
+ for (int i = 0; i < getChildCount(); i++) {
+ View child = getChildAt(i);
+ if (child.getVisibility() == View.VISIBLE) {
+ offsetRectIntoDescendantCoords(child, mTempRect);
+ ev.offsetLocation(mTempRect.left, mTempRect.top);
+ result = child.dispatchTouchEvent(ev) || result;
+ ev.offsetLocation(-mTempRect.left, -mTempRect.top);
+ }
+ }
+ return result;
+ }
+
+}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitor.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitor.java
index 66c7c10..c48e2d7 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitor.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitor.java
@@ -73,9 +73,9 @@
private static final int MSG_PHONE_STATE_CHANGED = 306;
private static final int MSG_CLOCK_VISIBILITY_CHANGED = 307;
private static final int MSG_DEVICE_PROVISIONED = 308;
- protected static final int MSG_DPM_STATE_CHANGED = 309;
- protected static final int MSG_USER_SWITCHED = 310;
- protected static final int MSG_USER_REMOVED = 311;
+ private static final int MSG_DPM_STATE_CHANGED = 309;
+ private static final int MSG_USER_SWITCHED = 310;
+ private static final int MSG_USER_REMOVED = 311;
private static KeyguardUpdateMonitor sInstance;
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java
index 3ee82f7..1f0f5ef 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java
@@ -41,6 +41,7 @@
import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.UserHandle;
+import android.os.UserManager;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.util.EventLog;
@@ -161,6 +162,9 @@
/** High level access to the power manager for WakeLocks */
private PowerManager mPM;
+ /** UserManager for querying number of users */
+ private UserManager mUserManager;
+
/**
* Used to keep the device awake while the keyguard is showing, i.e for
* calls to {@link #pokeWakelock()}
@@ -436,6 +440,7 @@
public KeyguardViewMediator(Context context, LockPatternUtils lockPatternUtils) {
mContext = context;
mPM = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
+ mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
mWakeLock = mPM.newWakeLock(
PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "keyguard");
mWakeLock.setReferenceCounted(false);
@@ -779,7 +784,8 @@
return;
}
- if (mLockPatternUtils.isLockScreenDisabled() && !lockedOrMissing) {
+ if (mUserManager.getUsers().size() < 2
+ && mLockPatternUtils.isLockScreenDisabled() && !lockedOrMissing) {
if (DEBUG) Log.d(TAG, "doKeyguard: not showing because lockscreen is off");
return;
}
diff --git a/services/input/InputDispatcher.cpp b/services/input/InputDispatcher.cpp
index 8604f95..87a6c1b 100644
--- a/services/input/InputDispatcher.cpp
+++ b/services/input/InputDispatcher.cpp
@@ -166,6 +166,10 @@
return true;
}
+static bool isMainDisplay(int32_t displayId) {
+ return displayId == ADISPLAY_ID_DEFAULT || displayId == ADISPLAY_ID_NONE;
+}
+
static void dumpRegion(String8& dump, const SkRegion& region) {
if (region.isEmpty()) {
dump.append("<empty>");
@@ -423,11 +427,12 @@
&& (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER)
&& mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY
&& mInputTargetWaitApplicationHandle != NULL) {
+ int32_t displayId = motionEntry->displayId;
int32_t x = int32_t(motionEntry->pointerCoords[0].
getAxisValue(AMOTION_EVENT_AXIS_X));
int32_t y = int32_t(motionEntry->pointerCoords[0].
getAxisValue(AMOTION_EVENT_AXIS_Y));
- sp<InputWindowHandle> touchedWindowHandle = findTouchedWindowAtLocked(x, y);
+ sp<InputWindowHandle> touchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y);
if (touchedWindowHandle != NULL
&& touchedWindowHandle->inputApplicationHandle
!= mInputTargetWaitApplicationHandle) {
@@ -444,28 +449,31 @@
return needWake;
}
-sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t x, int32_t y) {
+sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId,
+ int32_t x, int32_t y) {
// Traverse windows from front to back to find touched window.
size_t numWindows = mWindowHandles.size();
for (size_t i = 0; i < numWindows; i++) {
sp<InputWindowHandle> windowHandle = mWindowHandles.itemAt(i);
const InputWindowInfo* windowInfo = windowHandle->getInfo();
- int32_t flags = windowInfo->layoutParamsFlags;
+ if (windowInfo->displayId == displayId) {
+ int32_t flags = windowInfo->layoutParamsFlags;
- if (windowInfo->visible) {
- if (!(flags & InputWindowInfo::FLAG_NOT_TOUCHABLE)) {
- bool isTouchModal = (flags & (InputWindowInfo::FLAG_NOT_FOCUSABLE
- | InputWindowInfo::FLAG_NOT_TOUCH_MODAL)) == 0;
- if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
- // Found window.
- return windowHandle;
+ if (windowInfo->visible) {
+ if (!(flags & InputWindowInfo::FLAG_NOT_TOUCHABLE)) {
+ bool isTouchModal = (flags & (InputWindowInfo::FLAG_NOT_FOCUSABLE
+ | InputWindowInfo::FLAG_NOT_TOUCH_MODAL)) == 0;
+ if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
+ // Found window.
+ return windowHandle;
+ }
}
}
- }
- if (flags & InputWindowInfo::FLAG_SYSTEM_ERROR) {
- // Error window is on top but not visible, so touch is dropped.
- return NULL;
+ if (flags & InputWindowInfo::FLAG_SYSTEM_ERROR) {
+ // Error window is on top but not visible, so touch is dropped.
+ return NULL;
+ }
}
}
return NULL;
@@ -826,7 +834,10 @@
return true;
}
- addMonitoringTargetsLocked(inputTargets);
+ // TODO: support sending secondary display events to input monitors
+ if (isMainDisplay(entry->displayId)) {
+ addMonitoringTargetsLocked(inputTargets);
+ }
// Dispatch the motion.
if (conflictingPointerActions) {
@@ -1117,6 +1128,7 @@
//
bool screenWasOff = false; // original policy: policyFlags & POLICY_FLAG_BRIGHT_HERE;
+ int32_t displayId = entry->displayId;
int32_t action = entry->action;
int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
@@ -1126,9 +1138,10 @@
sp<InputWindowHandle> newHoverWindowHandle;
bool isSplit = mTouchState.split;
- bool switchedDevice = mTouchState.deviceId >= 0
+ bool switchedDevice = mTouchState.deviceId >= 0 && mTouchState.displayId >= 0
&& (mTouchState.deviceId != entry->deviceId
- || mTouchState.source != entry->source);
+ || mTouchState.source != entry->source
+ || mTouchState.displayId != displayId);
bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE
|| maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER
|| maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
@@ -1152,6 +1165,7 @@
mTempTouchState.down = down;
mTempTouchState.deviceId = entry->deviceId;
mTempTouchState.source = entry->source;
+ mTempTouchState.displayId = displayId;
isSplit = false;
} else {
mTempTouchState.copyFrom(mTouchState);
@@ -1174,8 +1188,11 @@
for (size_t i = 0; i < numWindows; i++) {
sp<InputWindowHandle> windowHandle = mWindowHandles.itemAt(i);
const InputWindowInfo* windowInfo = windowHandle->getInfo();
- int32_t flags = windowInfo->layoutParamsFlags;
+ if (windowInfo->displayId != displayId) {
+ continue; // wrong display
+ }
+ int32_t flags = windowInfo->layoutParamsFlags;
if (flags & InputWindowInfo::FLAG_SYSTEM_ERROR) {
if (topErrorWindowHandle == NULL) {
topErrorWindowHandle = windowHandle;
@@ -1300,7 +1317,8 @@
sp<InputWindowHandle> oldTouchedWindowHandle =
mTempTouchState.getFirstForegroundWindowHandle();
- sp<InputWindowHandle> newTouchedWindowHandle = findTouchedWindowAtLocked(x, y);
+ sp<InputWindowHandle> newTouchedWindowHandle =
+ findTouchedWindowAtLocked(displayId, x, y);
if (oldTouchedWindowHandle != newTouchedWindowHandle
&& newTouchedWindowHandle != NULL) {
#if DEBUG_FOCUS
@@ -1438,8 +1456,10 @@
if (foregroundWindowHandle->getInfo()->hasWallpaper) {
for (size_t i = 0; i < mWindowHandles.size(); i++) {
sp<InputWindowHandle> windowHandle = mWindowHandles.itemAt(i);
- if (windowHandle->getInfo()->layoutParamsType
- == InputWindowInfo::TYPE_WALLPAPER) {
+ const InputWindowInfo* info = windowHandle->getInfo();
+ if (info->displayId == displayId
+ && windowHandle->getInfo()->layoutParamsType
+ == InputWindowInfo::TYPE_WALLPAPER) {
mTempTouchState.addOrUpdateWindow(windowHandle,
InputTarget::FLAG_WINDOW_IS_OBSCURED
| InputTarget::FLAG_DISPATCH_AS_IS,
@@ -1495,6 +1515,7 @@
|| maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
mTouchState.deviceId = entry->deviceId;
mTouchState.source = entry->source;
+ mTouchState.displayId = displayId;
}
} else if (maskedAction == AMOTION_EVENT_ACTION_UP
|| maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
@@ -1610,6 +1631,7 @@
bool InputDispatcher::isWindowObscuredAtPointLocked(
const sp<InputWindowHandle>& windowHandle, int32_t x, int32_t y) const {
+ int32_t displayId = windowHandle->getInfo()->displayId;
size_t numWindows = mWindowHandles.size();
for (size_t i = 0; i < numWindows; i++) {
sp<InputWindowHandle> otherHandle = mWindowHandles.itemAt(i);
@@ -1618,7 +1640,8 @@
}
const InputWindowInfo* otherInfo = otherHandle->getInfo();
- if (otherInfo->visible && ! otherInfo->isTrustedOverlay()
+ if (otherInfo->displayId == displayId
+ && otherInfo->visible && !otherInfo->isTrustedOverlay()
&& otherInfo->frameContainsPoint(x, y)) {
return true;
}
@@ -1845,7 +1868,7 @@
}
if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE
&& !connection->inputState.isHovering(
- motionEntry->deviceId, motionEntry->source)) {
+ motionEntry->deviceId, motionEntry->source, motionEntry->displayId)) {
#if DEBUG_DISPATCH_CYCLE
ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: filling in missing hover enter event",
connection->getInputChannelName());
@@ -2271,6 +2294,7 @@
originalMotionEntry->xPrecision,
originalMotionEntry->yPrecision,
originalMotionEntry->downTime,
+ originalMotionEntry->displayId,
splitPointerCount, splitPointerProperties, splitPointerCoords);
if (originalMotionEntry->injectionState) {
@@ -2351,7 +2375,7 @@
{ // acquire lock
mLock.lock();
- if (mInputFilterEnabled) {
+ if (shouldSendKeyToInputFilterLocked(args)) {
mLock.unlock();
policyFlags |= POLICY_FLAG_FILTERED;
@@ -2377,6 +2401,10 @@
}
}
+bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args) {
+ return mInputFilterEnabled;
+}
+
void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
#if DEBUG_INBOUND_EVENT_DETAILS
ALOGD("notifyMotion - eventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, "
@@ -2415,7 +2443,7 @@
{ // acquire lock
mLock.lock();
- if (mInputFilterEnabled) {
+ if (shouldSendMotionToInputFilterLocked(args)) {
mLock.unlock();
MotionEvent event;
@@ -2438,6 +2466,7 @@
args->deviceId, args->source, policyFlags,
args->action, args->flags, args->metaState, args->buttonState,
args->edgeFlags, args->xPrecision, args->yPrecision, args->downTime,
+ args->displayId,
args->pointerCount, args->pointerProperties, args->pointerCoords);
needWake = enqueueInboundEventLocked(newEntry);
@@ -2449,6 +2478,11 @@
}
}
+bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args) {
+ // TODO: support sending secondary display events to input filter
+ return mInputFilterEnabled && isMainDisplay(args->displayId);
+}
+
void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
#if DEBUG_INBOUND_EVENT_DETAILS
ALOGD("notifySwitch - eventTime=%lld, policyFlags=0x%x, switchCode=%d, switchValue=%d",
@@ -2532,6 +2566,7 @@
case AINPUT_EVENT_TYPE_MOTION: {
const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
+ int32_t displayId = ADISPLAY_ID_DEFAULT;
int32_t action = motionEvent->getAction();
size_t pointerCount = motionEvent->getPointerCount();
const PointerProperties* pointerProperties = motionEvent->getPointerProperties();
@@ -2553,8 +2588,8 @@
motionEvent->getMetaState(), motionEvent->getButtonState(),
motionEvent->getEdgeFlags(),
motionEvent->getXPrecision(), motionEvent->getYPrecision(),
- motionEvent->getDownTime(), uint32_t(pointerCount),
- pointerProperties, samplePointerCoords);
+ motionEvent->getDownTime(), displayId,
+ uint32_t(pointerCount), pointerProperties, samplePointerCoords);
lastInjectedEntry = firstInjectedEntry;
for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
sampleEventTimes += 1;
@@ -2565,8 +2600,8 @@
motionEvent->getMetaState(), motionEvent->getButtonState(),
motionEvent->getEdgeFlags(),
motionEvent->getXPrecision(), motionEvent->getYPrecision(),
- motionEvent->getDownTime(), uint32_t(pointerCount),
- pointerProperties, samplePointerCoords);
+ motionEvent->getDownTime(), displayId,
+ uint32_t(pointerCount), pointerProperties, samplePointerCoords);
lastInjectedEntry->next = nextInjectedEntry;
lastInjectedEntry = nextInjectedEntry;
}
@@ -2939,6 +2974,12 @@
#endif
return true;
}
+ if (fromWindowHandle->getInfo()->displayId != toWindowHandle->getInfo()->displayId) {
+#if DEBUG_FOCUS
+ ALOGD("Cannot transfer focus because windows are on different displays.");
+#endif
+ return false;
+ }
bool found = false;
for (size_t i = 0; i < mTouchState.windows.size(); i++) {
@@ -3040,6 +3081,7 @@
dump.appendFormat(INDENT "TouchSplit: %s\n", toString(mTouchState.split));
dump.appendFormat(INDENT "TouchDeviceId: %d\n", mTouchState.deviceId);
dump.appendFormat(INDENT "TouchSource: 0x%08x\n", mTouchState.source);
+ dump.appendFormat(INDENT "TouchDisplayId: %d\n", mTouchState.displayId);
if (!mTouchState.windows.isEmpty()) {
dump.append(INDENT "TouchedWindows:\n");
for (size_t i = 0; i < mTouchState.windows.size(); i++) {
@@ -3059,11 +3101,12 @@
const sp<InputWindowHandle>& windowHandle = mWindowHandles.itemAt(i);
const InputWindowInfo* windowInfo = windowHandle->getInfo();
- dump.appendFormat(INDENT2 "%d: name='%s', paused=%s, hasFocus=%s, hasWallpaper=%s, "
+ dump.appendFormat(INDENT2 "%d: name='%s', displayId=%d, "
+ "paused=%s, hasFocus=%s, hasWallpaper=%s, "
"visible=%s, canReceiveKeys=%s, flags=0x%08x, type=0x%08x, layer=%d, "
"frame=[%d,%d][%d,%d], scale=%f, "
"touchableRegion=",
- i, windowInfo->name.string(),
+ i, windowInfo->name.string(), windowInfo->displayId,
toString(windowInfo->paused),
toString(windowInfo->hasFocus),
toString(windowInfo->hasWallpaper),
@@ -3802,14 +3845,14 @@
int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action, int32_t flags,
int32_t metaState, int32_t buttonState,
int32_t edgeFlags, float xPrecision, float yPrecision,
- nsecs_t downTime, uint32_t pointerCount,
+ nsecs_t downTime, int32_t displayId, uint32_t pointerCount,
const PointerProperties* pointerProperties, const PointerCoords* pointerCoords) :
EventEntry(TYPE_MOTION, eventTime, policyFlags),
eventTime(eventTime),
deviceId(deviceId), source(source), action(action), flags(flags),
metaState(metaState), buttonState(buttonState), edgeFlags(edgeFlags),
xPrecision(xPrecision), yPrecision(yPrecision),
- downTime(downTime), pointerCount(pointerCount) {
+ downTime(downTime), displayId(displayId), pointerCount(pointerCount) {
for (uint32_t i = 0; i < pointerCount; i++) {
this->pointerProperties[i].copyFrom(pointerProperties[i]);
this->pointerCoords[i].copyFrom(pointerCoords[i]);
@@ -3820,8 +3863,8 @@
}
void InputDispatcher::MotionEntry::appendDescription(String8& msg) const {
- msg.appendFormat("MotionEvent(action=%d, deviceId=%d, source=0x%08x)",
- action, deviceId, source);
+ msg.appendFormat("MotionEvent(action=%d, deviceId=%d, source=0x%08x, displayId=%d)",
+ action, deviceId, source, displayId);
}
@@ -3864,11 +3907,13 @@
return mKeyMementos.isEmpty() && mMotionMementos.isEmpty();
}
-bool InputDispatcher::InputState::isHovering(int32_t deviceId, uint32_t source) const {
+bool InputDispatcher::InputState::isHovering(int32_t deviceId, uint32_t source,
+ int32_t displayId) const {
for (size_t i = 0; i < mMotionMementos.size(); i++) {
const MotionMemento& memento = mMotionMementos.itemAt(i);
if (memento.deviceId == deviceId
&& memento.source == source
+ && memento.displayId == displayId
&& memento.hovering) {
return true;
}
@@ -4025,6 +4070,7 @@
const MotionMemento& memento = mMotionMementos.itemAt(i);
if (memento.deviceId == entry->deviceId
&& memento.source == entry->source
+ && memento.displayId == entry->displayId
&& memento.hovering == hovering) {
return i;
}
@@ -4055,6 +4101,7 @@
memento.xPrecision = entry->xPrecision;
memento.yPrecision = entry->yPrecision;
memento.downTime = entry->downTime;
+ memento.displayId = entry->displayId;
memento.setPointers(entry);
memento.hovering = hovering;
memento.policyFlags = entry->policyFlags;
@@ -4090,6 +4137,7 @@
: AMOTION_EVENT_ACTION_CANCEL,
memento.flags, 0, 0, 0,
memento.xPrecision, memento.yPrecision, memento.downTime,
+ memento.displayId,
memento.pointerCount, memento.pointerProperties, memento.pointerCoords));
}
}
@@ -4108,7 +4156,8 @@
for (size_t j = 0; j < other.mMotionMementos.size(); ) {
const MotionMemento& otherMemento = other.mMotionMementos.itemAt(j);
if (memento.deviceId == otherMemento.deviceId
- && memento.source == otherMemento.source) {
+ && memento.source == otherMemento.source
+ && memento.displayId == otherMemento.displayId) {
other.mMotionMementos.removeAt(j);
} else {
j += 1;
@@ -4240,7 +4289,7 @@
// --- InputDispatcher::TouchState ---
InputDispatcher::TouchState::TouchState() :
- down(false), split(false), deviceId(-1), source(0) {
+ down(false), split(false), deviceId(-1), source(0), displayId(-1) {
}
InputDispatcher::TouchState::~TouchState() {
@@ -4251,6 +4300,7 @@
split = false;
deviceId = -1;
source = 0;
+ displayId = -1;
windows.clear();
}
@@ -4259,6 +4309,7 @@
split = other.split;
deviceId = other.deviceId;
source = other.source;
+ displayId = other.displayId;
windows = other.windows;
}
diff --git a/services/input/InputDispatcher.h b/services/input/InputDispatcher.h
index d0824fc..af7ff5e 100644
--- a/services/input/InputDispatcher.h
+++ b/services/input/InputDispatcher.h
@@ -511,15 +511,17 @@
float xPrecision;
float yPrecision;
nsecs_t downTime;
+ int32_t displayId;
uint32_t pointerCount;
PointerProperties pointerProperties[MAX_POINTERS];
PointerCoords pointerCoords[MAX_POINTERS];
MotionEntry(nsecs_t eventTime,
- int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action,
- int32_t flags, int32_t metaState, int32_t buttonState, int32_t edgeFlags,
+ int32_t deviceId, uint32_t source, uint32_t policyFlags,
+ int32_t action, int32_t flags,
+ int32_t metaState, int32_t buttonState, int32_t edgeFlags,
float xPrecision, float yPrecision,
- nsecs_t downTime, uint32_t pointerCount,
+ nsecs_t downTime, int32_t displayId, uint32_t pointerCount,
const PointerProperties* pointerProperties, const PointerCoords* pointerCoords);
virtual void appendDescription(String8& msg) const;
@@ -696,7 +698,7 @@
// Returns true if the specified source is known to have received a hover enter
// motion event.
- bool isHovering(int32_t deviceId, uint32_t source) const;
+ bool isHovering(int32_t deviceId, uint32_t source, int32_t displayId) const;
// Records tracking information for a key event that has just been published.
// Returns true if the event should be delivered, false if it is inconsistent
@@ -752,6 +754,7 @@
float xPrecision;
float yPrecision;
nsecs_t downTime;
+ int32_t displayId;
uint32_t pointerCount;
PointerProperties pointerProperties[MAX_POINTERS];
PointerCoords pointerCoords[MAX_POINTERS];
@@ -867,7 +870,7 @@
// to transfer focus to a new application.
EventEntry* mNextUnblockedEvent;
- sp<InputWindowHandle> findTouchedWindowAtLocked(int32_t x, int32_t y);
+ sp<InputWindowHandle> findTouchedWindowAtLocked(int32_t displayId, int32_t x, int32_t y);
// All registered connections mapped by channel file descriptor.
KeyedVector<int, sp<Connection> > mConnectionsByFd;
@@ -899,6 +902,10 @@
bool runCommandsLockedInterruptible();
CommandEntry* postCommandLocked(Command command);
+ // Input filter processing.
+ bool shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args);
+ bool shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args);
+
// Inbound event processing.
void drainInboundQueueLocked();
void releasePendingEventLocked();
@@ -928,6 +935,7 @@
bool split;
int32_t deviceId; // id of the device that is currently down, others are rejected
uint32_t source; // source of the device that is current down, others are rejected
+ int32_t displayId; // id to the display that currently has a touch, others are rejected
Vector<TouchedWindow> windows;
TouchState();
diff --git a/services/input/InputListener.cpp b/services/input/InputListener.cpp
index 657a6b9..c2705b0 100644
--- a/services/input/InputListener.cpp
+++ b/services/input/InputListener.cpp
@@ -69,12 +69,12 @@
NotifyMotionArgs::NotifyMotionArgs(nsecs_t eventTime, int32_t deviceId, uint32_t source,
uint32_t policyFlags,
int32_t action, int32_t flags, int32_t metaState, int32_t buttonState,
- int32_t edgeFlags, uint32_t pointerCount,
+ int32_t edgeFlags, int32_t displayId, uint32_t pointerCount,
const PointerProperties* pointerProperties, const PointerCoords* pointerCoords,
float xPrecision, float yPrecision, nsecs_t downTime) :
eventTime(eventTime), deviceId(deviceId), source(source), policyFlags(policyFlags),
action(action), flags(flags), metaState(metaState), buttonState(buttonState),
- edgeFlags(edgeFlags), pointerCount(pointerCount),
+ edgeFlags(edgeFlags), displayId(displayId), pointerCount(pointerCount),
xPrecision(xPrecision), yPrecision(yPrecision), downTime(downTime) {
for (uint32_t i = 0; i < pointerCount; i++) {
this->pointerProperties[i].copyFrom(pointerProperties[i]);
@@ -87,7 +87,8 @@
policyFlags(other.policyFlags),
action(other.action), flags(other.flags),
metaState(other.metaState), buttonState(other.buttonState),
- edgeFlags(other.edgeFlags), pointerCount(other.pointerCount),
+ edgeFlags(other.edgeFlags), displayId(other.displayId),
+ pointerCount(other.pointerCount),
xPrecision(other.xPrecision), yPrecision(other.yPrecision), downTime(other.downTime) {
for (uint32_t i = 0; i < pointerCount; i++) {
pointerProperties[i].copyFrom(other.pointerProperties[i]);
diff --git a/services/input/InputListener.h b/services/input/InputListener.h
index b1dc0b8..486852b 100644
--- a/services/input/InputListener.h
+++ b/services/input/InputListener.h
@@ -88,6 +88,7 @@
int32_t metaState;
int32_t buttonState;
int32_t edgeFlags;
+ int32_t displayId;
uint32_t pointerCount;
PointerProperties pointerProperties[MAX_POINTERS];
PointerCoords pointerCoords[MAX_POINTERS];
@@ -99,7 +100,7 @@
NotifyMotionArgs(nsecs_t eventTime, int32_t deviceId, uint32_t source, uint32_t policyFlags,
int32_t action, int32_t flags, int32_t metaState, int32_t buttonState,
- int32_t edgeFlags, uint32_t pointerCount,
+ int32_t edgeFlags, int32_t displayId, uint32_t pointerCount,
const PointerProperties* pointerProperties, const PointerCoords* pointerCoords,
float xPrecision, float yPrecision, nsecs_t downTime);
diff --git a/services/input/InputReader.cpp b/services/input/InputReader.cpp
index 513dc13..d56b9a9 100644
--- a/services/input/InputReader.cpp
+++ b/services/input/InputReader.cpp
@@ -2431,6 +2431,7 @@
mPointerVelocityControl.move(when, &deltaX, &deltaY);
+ int32_t displayId;
if (mPointerController != NULL) {
if (moved || scrolled || buttonsChanged) {
mPointerController->setPresentation(
@@ -2451,9 +2452,11 @@
mPointerController->getPosition(&x, &y);
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
+ displayId = ADISPLAY_ID_DEFAULT;
} else {
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, deltaX);
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, deltaY);
+ displayId = ADISPLAY_ID_NONE;
}
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, down ? 1.0f : 0.0f);
@@ -2485,7 +2488,8 @@
NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
motionEventAction, 0, metaState, currentButtonState, 0,
- 1, &pointerProperties, &pointerCoords, mXPrecision, mYPrecision, downTime);
+ displayId, 1, &pointerProperties, &pointerCoords,
+ mXPrecision, mYPrecision, downTime);
getListener()->notifyMotion(&args);
// Send hover move after UP to tell the application that the mouse is hovering now.
@@ -2494,7 +2498,8 @@
NotifyMotionArgs hoverArgs(when, getDeviceId(), mSource, policyFlags,
AMOTION_EVENT_ACTION_HOVER_MOVE, 0,
metaState, currentButtonState, AMOTION_EVENT_EDGE_FLAG_NONE,
- 1, &pointerProperties, &pointerCoords, mXPrecision, mYPrecision, downTime);
+ displayId, 1, &pointerProperties, &pointerCoords,
+ mXPrecision, mYPrecision, downTime);
getListener()->notifyMotion(&hoverArgs);
}
@@ -2506,7 +2511,8 @@
NotifyMotionArgs scrollArgs(when, getDeviceId(), mSource, policyFlags,
AMOTION_EVENT_ACTION_SCROLL, 0, metaState, currentButtonState,
AMOTION_EVENT_EDGE_FLAG_NONE,
- 1, &pointerProperties, &pointerCoords, mXPrecision, mYPrecision, downTime);
+ displayId, 1, &pointerProperties, &pointerCoords,
+ mXPrecision, mYPrecision, downTime);
getListener()->notifyMotion(&scrollArgs);
}
}
@@ -2539,7 +2545,8 @@
TouchInputMapper::TouchInputMapper(InputDevice* device) :
InputMapper(device),
mSource(0), mDeviceMode(DEVICE_MODE_DISABLED),
- mSurfaceOrientation(-1), mSurfaceWidth(-1), mSurfaceHeight(-1) {
+ mSurfaceWidth(-1), mSurfaceHeight(-1), mSurfaceLeft(0), mSurfaceTop(0),
+ mSurfaceOrientation(DISPLAY_ORIENTATION_0) {
}
TouchInputMapper::~TouchInputMapper() {
@@ -2601,6 +2608,8 @@
dumpSurface(dump);
dump.appendFormat(INDENT3 "Translation and Scaling Factors:\n");
+ dump.appendFormat(INDENT4 "XTranslate: %0.3f\n", mXTranslate);
+ dump.appendFormat(INDENT4 "YTranslate: %0.3f\n", mYTranslate);
dump.appendFormat(INDENT4 "XScale: %0.3f\n", mXScale);
dump.appendFormat(INDENT4 "YScale: %0.3f\n", mYScale);
dump.appendFormat(INDENT4 "XPrecision: %0.3f\n", mXPrecision);
@@ -2810,7 +2819,7 @@
ALOG_ASSERT(false);
}
- dump.appendFormat(INDENT4 "AssociatedDisplay: present=%s, isExternal=%s\n",
+ dump.appendFormat(INDENT4 "AssociatedDisplay: hasAssociatedDisplay=%s, isExternal=%s\n",
toString(mParameters.hasAssociatedDisplay),
toString(mParameters.associatedDisplayIsExternal));
dump.appendFormat(INDENT4 "OrientationAware: %s\n",
@@ -2869,10 +2878,15 @@
return;
}
+ // Raw width and height in the natural orientation.
+ int32_t rawWidth = mRawPointerAxes.x.maxValue - mRawPointerAxes.x.minValue + 1;
+ int32_t rawHeight = mRawPointerAxes.y.maxValue - mRawPointerAxes.y.minValue + 1;
+
// Get associated display dimensions.
+ bool viewportChanged = false;
+ DisplayViewport newViewport;
if (mParameters.hasAssociatedDisplay) {
- if (!mConfig.getDisplayInfo(mParameters.associatedDisplayIsExternal,
- &mAssociatedDisplayViewport)) {
+ if (!mConfig.getDisplayInfo(mParameters.associatedDisplayIsExternal, &newViewport)) {
ALOGI(INDENT "Touch device '%s' could not query the properties of its associated "
"display. The device will be inoperable until the display size "
"becomes available.",
@@ -2880,25 +2894,77 @@
mDeviceMode = DEVICE_MODE_DISABLED;
return;
}
- }
-
- // Configure dimensions.
- int32_t width, height, orientation;
- if (mDeviceMode == DEVICE_MODE_DIRECT || mDeviceMode == DEVICE_MODE_POINTER) {
- width = mAssociatedDisplayViewport.logicalRight - mAssociatedDisplayViewport.logicalLeft;
- height = mAssociatedDisplayViewport.logicalBottom - mAssociatedDisplayViewport.logicalTop;
- if (mAssociatedDisplayViewport.orientation == DISPLAY_ORIENTATION_90
- || mAssociatedDisplayViewport.orientation == DISPLAY_ORIENTATION_270) {
- int32_t temp = height;
- height = width;
- width = temp;
- }
- orientation = mParameters.orientationAware ?
- mAssociatedDisplayViewport.orientation : DISPLAY_ORIENTATION_0;
} else {
- width = mRawPointerAxes.x.maxValue - mRawPointerAxes.x.minValue + 1;
- height = mRawPointerAxes.y.maxValue - mRawPointerAxes.y.minValue + 1;
- orientation = DISPLAY_ORIENTATION_0;
+ newViewport.setNonDisplayViewport(rawWidth, rawHeight);
+ }
+ if (mViewport != newViewport) {
+ mViewport = newViewport;
+ viewportChanged = true;
+
+ if (mDeviceMode == DEVICE_MODE_DIRECT || mDeviceMode == DEVICE_MODE_POINTER) {
+ // Convert rotated viewport to natural surface coordinates.
+ int32_t naturalLogicalWidth, naturalLogicalHeight;
+ int32_t naturalPhysicalWidth, naturalPhysicalHeight;
+ int32_t naturalPhysicalLeft, naturalPhysicalTop;
+ int32_t naturalDeviceWidth, naturalDeviceHeight;
+ switch (mViewport.orientation) {
+ case DISPLAY_ORIENTATION_90:
+ naturalLogicalWidth = mViewport.logicalBottom - mViewport.logicalTop;
+ naturalLogicalHeight = mViewport.logicalRight - mViewport.logicalLeft;
+ naturalPhysicalWidth = mViewport.physicalBottom - mViewport.physicalTop;
+ naturalPhysicalHeight = mViewport.physicalRight - mViewport.physicalLeft;
+ naturalPhysicalLeft = mViewport.deviceHeight - mViewport.physicalBottom;
+ naturalPhysicalTop = mViewport.physicalLeft;
+ naturalDeviceWidth = mViewport.deviceHeight;
+ naturalDeviceHeight = mViewport.deviceWidth;
+ break;
+ case DISPLAY_ORIENTATION_180:
+ naturalLogicalWidth = mViewport.logicalRight - mViewport.logicalLeft;
+ naturalLogicalHeight = mViewport.logicalBottom - mViewport.logicalTop;
+ naturalPhysicalWidth = mViewport.physicalRight - mViewport.physicalLeft;
+ naturalPhysicalHeight = mViewport.physicalBottom - mViewport.physicalTop;
+ naturalPhysicalLeft = mViewport.deviceWidth - mViewport.physicalRight;
+ naturalPhysicalTop = mViewport.deviceHeight - mViewport.physicalBottom;
+ naturalDeviceWidth = mViewport.deviceWidth;
+ naturalDeviceHeight = mViewport.deviceHeight;
+ break;
+ case DISPLAY_ORIENTATION_270:
+ naturalLogicalWidth = mViewport.logicalBottom - mViewport.logicalTop;
+ naturalLogicalHeight = mViewport.logicalRight - mViewport.logicalLeft;
+ naturalPhysicalWidth = mViewport.physicalBottom - mViewport.physicalTop;
+ naturalPhysicalHeight = mViewport.physicalRight - mViewport.physicalLeft;
+ naturalPhysicalLeft = mViewport.physicalTop;
+ naturalPhysicalTop = mViewport.deviceWidth - mViewport.physicalRight;
+ naturalDeviceWidth = mViewport.deviceHeight;
+ naturalDeviceHeight = mViewport.deviceWidth;
+ break;
+ case DISPLAY_ORIENTATION_0:
+ default:
+ naturalLogicalWidth = mViewport.logicalRight - mViewport.logicalLeft;
+ naturalLogicalHeight = mViewport.logicalBottom - mViewport.logicalTop;
+ naturalPhysicalWidth = mViewport.physicalRight - mViewport.physicalLeft;
+ naturalPhysicalHeight = mViewport.physicalBottom - mViewport.physicalTop;
+ naturalPhysicalLeft = mViewport.physicalLeft;
+ naturalPhysicalTop = mViewport.physicalTop;
+ naturalDeviceWidth = mViewport.deviceWidth;
+ naturalDeviceHeight = mViewport.deviceHeight;
+ break;
+ }
+
+ mSurfaceWidth = naturalLogicalWidth * naturalDeviceWidth / naturalPhysicalWidth;
+ mSurfaceHeight = naturalLogicalHeight * naturalDeviceHeight / naturalPhysicalHeight;
+ mSurfaceLeft = naturalPhysicalLeft * naturalLogicalWidth / naturalPhysicalWidth;
+ mSurfaceTop = naturalPhysicalTop * naturalLogicalHeight / naturalPhysicalHeight;
+
+ mSurfaceOrientation = mParameters.orientationAware ?
+ mViewport.orientation : DISPLAY_ORIENTATION_0;
+ } else {
+ mSurfaceWidth = rawWidth;
+ mSurfaceHeight = rawHeight;
+ mSurfaceLeft = 0;
+ mSurfaceTop = 0;
+ mSurfaceOrientation = DISPLAY_ORIENTATION_0;
+ }
}
// If moving between pointer modes, need to reset some state.
@@ -2918,22 +2984,17 @@
mPointerController.clear();
}
- bool orientationChanged = mSurfaceOrientation != orientation;
- if (orientationChanged) {
- mSurfaceOrientation = orientation;
- }
-
- bool sizeChanged = mSurfaceWidth != width || mSurfaceHeight != height;
- if (sizeChanged || deviceModeChanged) {
- ALOGI("Device reconfigured: id=%d, name='%s', surface size is now %dx%d, mode is %d",
- getDeviceId(), getDeviceName().string(), width, height, mDeviceMode);
-
- mSurfaceWidth = width;
- mSurfaceHeight = height;
+ if (viewportChanged || deviceModeChanged) {
+ ALOGI("Device reconfigured: id=%d, name='%s', size %dx%d, orientation %d, mode %d, "
+ "display id %d",
+ getDeviceId(), getDeviceName().string(), mSurfaceWidth, mSurfaceHeight,
+ mSurfaceOrientation, mDeviceMode, mViewport.displayId);
// Configure X and Y factors.
- mXScale = float(width) / (mRawPointerAxes.x.maxValue - mRawPointerAxes.x.minValue + 1);
- mYScale = float(height) / (mRawPointerAxes.y.maxValue - mRawPointerAxes.y.minValue + 1);
+ mXScale = float(mSurfaceWidth) / rawWidth;
+ mYScale = float(mSurfaceHeight) / rawHeight;
+ mXTranslate = -mSurfaceLeft;
+ mYTranslate = -mSurfaceTop;
mXPrecision = 1.0f / mXScale;
mYPrecision = 1.0f / mYScale;
@@ -2950,7 +3011,7 @@
mGeometricScale = avg(mXScale, mYScale);
// Size of diagonal axis.
- float diagonalSize = hypotf(width, height);
+ float diagonalSize = hypotf(mSurfaceWidth, mSurfaceHeight);
// Size factors.
if (mCalibration.sizeCalibration != Calibration::SIZE_CALIBRATION_NONE) {
@@ -3102,50 +3163,38 @@
mOrientedRanges.distance.fuzz =
mRawPointerAxes.distance.fuzz * mDistanceScale;
}
- }
- if (orientationChanged || sizeChanged || deviceModeChanged) {
- // Compute oriented surface dimensions, precision, scales and ranges.
+ // Compute oriented precision, scales and ranges.
// Note that the maximum value reported is an inclusive maximum value so it is one
// unit less than the total width or height of surface.
switch (mSurfaceOrientation) {
case DISPLAY_ORIENTATION_90:
case DISPLAY_ORIENTATION_270:
- mOrientedSurfaceWidth = mSurfaceHeight;
- mOrientedSurfaceHeight = mSurfaceWidth;
-
mOrientedXPrecision = mYPrecision;
mOrientedYPrecision = mXPrecision;
- mOrientedRanges.x.min = 0;
- mOrientedRanges.x.max = (mRawPointerAxes.y.maxValue - mRawPointerAxes.y.minValue)
- * mYScale;
+ mOrientedRanges.x.min = mYTranslate;
+ mOrientedRanges.x.max = mSurfaceHeight + mYTranslate - 1;
mOrientedRanges.x.flat = 0;
mOrientedRanges.x.fuzz = mYScale;
- mOrientedRanges.y.min = 0;
- mOrientedRanges.y.max = (mRawPointerAxes.x.maxValue - mRawPointerAxes.x.minValue)
- * mXScale;
+ mOrientedRanges.y.min = mXTranslate;
+ mOrientedRanges.y.max = mSurfaceWidth + mXTranslate - 1;
mOrientedRanges.y.flat = 0;
mOrientedRanges.y.fuzz = mXScale;
break;
default:
- mOrientedSurfaceWidth = mSurfaceWidth;
- mOrientedSurfaceHeight = mSurfaceHeight;
-
mOrientedXPrecision = mXPrecision;
mOrientedYPrecision = mYPrecision;
- mOrientedRanges.x.min = 0;
- mOrientedRanges.x.max = (mRawPointerAxes.x.maxValue - mRawPointerAxes.x.minValue)
- * mXScale;
+ mOrientedRanges.x.min = mXTranslate;
+ mOrientedRanges.x.max = mSurfaceWidth + mXTranslate - 1;
mOrientedRanges.x.flat = 0;
mOrientedRanges.x.fuzz = mXScale;
- mOrientedRanges.y.min = 0;
- mOrientedRanges.y.max = (mRawPointerAxes.y.maxValue - mRawPointerAxes.y.minValue)
- * mYScale;
+ mOrientedRanges.y.min = mYTranslate;
+ mOrientedRanges.y.max = mSurfaceHeight + mYTranslate - 1;
mOrientedRanges.y.flat = 0;
mOrientedRanges.y.fuzz = mYScale;
break;
@@ -3153,10 +3202,8 @@
// Compute pointer gesture detection parameters.
if (mDeviceMode == DEVICE_MODE_POINTER) {
- int32_t rawWidth = mRawPointerAxes.x.maxValue - mRawPointerAxes.x.minValue + 1;
- int32_t rawHeight = mRawPointerAxes.y.maxValue - mRawPointerAxes.y.minValue + 1;
float rawDiagonal = hypotf(rawWidth, rawHeight);
- float displayDiagonal = hypotf(width, height);
+ float displayDiagonal = hypotf(mSurfaceWidth, mSurfaceHeight);
// Scale movements such that one whole swipe of the touch pad covers a
// given area relative to the diagonal size of the display when no acceleration
@@ -3191,8 +3238,21 @@
}
void TouchInputMapper::dumpSurface(String8& dump) {
+ dump.appendFormat(INDENT3 "Viewport: displayId=%d, orientation=%d, "
+ "logicalFrame=[%d, %d, %d, %d], "
+ "physicalFrame=[%d, %d, %d, %d], "
+ "deviceSize=[%d, %d]\n",
+ mViewport.displayId, mViewport.orientation,
+ mViewport.logicalLeft, mViewport.logicalTop,
+ mViewport.logicalRight, mViewport.logicalBottom,
+ mViewport.physicalLeft, mViewport.physicalTop,
+ mViewport.physicalRight, mViewport.physicalBottom,
+ mViewport.deviceWidth, mViewport.deviceHeight);
+
dump.appendFormat(INDENT3 "SurfaceWidth: %dpx\n", mSurfaceWidth);
dump.appendFormat(INDENT3 "SurfaceHeight: %dpx\n", mSurfaceHeight);
+ dump.appendFormat(INDENT3 "SurfaceLeft: %d\n", mSurfaceLeft);
+ dump.appendFormat(INDENT3 "SurfaceTop: %d\n", mSurfaceTop);
dump.appendFormat(INDENT3 "SurfaceOrientation: %d\n", mSurfaceOrientation);
}
@@ -4087,28 +4147,28 @@
float x, y;
switch (mSurfaceOrientation) {
case DISPLAY_ORIENTATION_90:
- x = float(in.y - mRawPointerAxes.y.minValue) * mYScale;
- y = float(mRawPointerAxes.x.maxValue - in.x) * mXScale;
+ x = float(in.y - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
+ y = float(mRawPointerAxes.x.maxValue - in.x) * mXScale + mXTranslate;
orientation -= M_PI_2;
if (orientation < - M_PI_2) {
orientation += M_PI;
}
break;
case DISPLAY_ORIENTATION_180:
- x = float(mRawPointerAxes.x.maxValue - in.x) * mXScale;
- y = float(mRawPointerAxes.y.maxValue - in.y) * mYScale;
+ x = float(mRawPointerAxes.x.maxValue - in.x) * mXScale + mXTranslate;
+ y = float(mRawPointerAxes.y.maxValue - in.y) * mYScale + mYTranslate;
break;
case DISPLAY_ORIENTATION_270:
- x = float(mRawPointerAxes.y.maxValue - in.y) * mYScale;
- y = float(in.x - mRawPointerAxes.x.minValue) * mXScale;
+ x = float(mRawPointerAxes.y.maxValue - in.y) * mYScale + mYTranslate;
+ y = float(in.x - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
orientation += M_PI_2;
if (orientation > M_PI_2) {
orientation -= M_PI;
}
break;
default:
- x = float(in.x - mRawPointerAxes.x.minValue) * mXScale;
- y = float(in.y - mRawPointerAxes.y.minValue) * mYScale;
+ x = float(in.x - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
+ y = float(in.y - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
break;
}
@@ -4364,7 +4424,8 @@
NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
AMOTION_EVENT_ACTION_HOVER_MOVE, 0,
metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
- 1, &pointerProperties, &pointerCoords, 0, 0, mPointerGesture.downTime);
+ mViewport.displayId, 1, &pointerProperties, &pointerCoords,
+ 0, 0, mPointerGesture.downTime);
getListener()->notifyMotion(&args);
}
@@ -5272,6 +5333,7 @@
// Send up.
NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
AMOTION_EVENT_ACTION_UP, 0, metaState, mLastButtonState, 0,
+ mViewport.displayId,
1, &mPointerSimple.lastProperties, &mPointerSimple.lastCoords,
mOrientedXPrecision, mOrientedYPrecision,
mPointerSimple.downTime);
@@ -5284,6 +5346,7 @@
// Send hover exit.
NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
AMOTION_EVENT_ACTION_HOVER_EXIT, 0, metaState, mLastButtonState, 0,
+ mViewport.displayId,
1, &mPointerSimple.lastProperties, &mPointerSimple.lastCoords,
mOrientedXPrecision, mOrientedYPrecision,
mPointerSimple.downTime);
@@ -5298,6 +5361,7 @@
// Send down.
NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
AMOTION_EVENT_ACTION_DOWN, 0, metaState, mCurrentButtonState, 0,
+ mViewport.displayId,
1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
mOrientedXPrecision, mOrientedYPrecision,
mPointerSimple.downTime);
@@ -5307,6 +5371,7 @@
// Send move.
NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
AMOTION_EVENT_ACTION_MOVE, 0, metaState, mCurrentButtonState, 0,
+ mViewport.displayId,
1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
mOrientedXPrecision, mOrientedYPrecision,
mPointerSimple.downTime);
@@ -5320,6 +5385,7 @@
// Send hover enter.
NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
AMOTION_EVENT_ACTION_HOVER_ENTER, 0, metaState, mCurrentButtonState, 0,
+ mViewport.displayId,
1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
mOrientedXPrecision, mOrientedYPrecision,
mPointerSimple.downTime);
@@ -5329,6 +5395,7 @@
// Send hover move.
NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
AMOTION_EVENT_ACTION_HOVER_MOVE, 0, metaState, mCurrentButtonState, 0,
+ mViewport.displayId,
1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
mOrientedXPrecision, mOrientedYPrecision,
mPointerSimple.downTime);
@@ -5349,6 +5416,7 @@
NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
AMOTION_EVENT_ACTION_SCROLL, 0, metaState, mCurrentButtonState, 0,
+ mViewport.displayId,
1, &mPointerSimple.currentProperties, &pointerCoords,
mOrientedXPrecision, mOrientedYPrecision,
mPointerSimple.downTime);
@@ -5410,7 +5478,8 @@
NotifyMotionArgs args(when, getDeviceId(), source, policyFlags,
action, flags, metaState, buttonState, edgeFlags,
- pointerCount, pointerProperties, pointerCoords, xPrecision, yPrecision, downTime);
+ mViewport.displayId, pointerCount, pointerProperties, pointerCoords,
+ xPrecision, yPrecision, downTime);
getListener()->notifyMotion(&args);
}
@@ -6213,7 +6282,7 @@
}
}
- // Moving a joystick axis should not wake the devide because joysticks can
+ // Moving a joystick axis should not wake the device because joysticks can
// be fairly noisy even when not in use. On the other hand, pushing a gamepad
// button will likely wake the device.
// TODO: Use the input device configuration to control this behavior more finely.
@@ -6221,7 +6290,7 @@
NotifyMotionArgs args(when, getDeviceId(), AINPUT_SOURCE_JOYSTICK, policyFlags,
AMOTION_EVENT_ACTION_MOVE, 0, metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
- 1, &pointerProperties, &pointerCoords, 0, 0, 0);
+ ADISPLAY_ID_NONE, 1, &pointerProperties, &pointerCoords, 0, 0, 0);
getListener()->notifyMotion(&args);
}
diff --git a/services/input/InputReader.h b/services/input/InputReader.h
index e345a5fb..e1a8dd8 100644
--- a/services/input/InputReader.h
+++ b/services/input/InputReader.h
@@ -62,11 +62,14 @@
int32_t physicalTop;
int32_t physicalRight;
int32_t physicalBottom;
+ int32_t deviceWidth;
+ int32_t deviceHeight;
DisplayViewport() :
- displayId(-1), orientation(DISPLAY_ORIENTATION_0),
+ displayId(ADISPLAY_ID_NONE), orientation(DISPLAY_ORIENTATION_0),
logicalLeft(0), logicalTop(0), logicalRight(0), logicalBottom(0),
- physicalLeft(0), physicalTop(0), physicalRight(0), physicalBottom(0) {
+ physicalLeft(0), physicalTop(0), physicalRight(0), physicalBottom(0),
+ deviceWidth(0), deviceHeight(0) {
}
bool operator==(const DisplayViewport& other) const {
@@ -79,12 +82,33 @@
&& physicalLeft == other.physicalLeft
&& physicalTop == other.physicalTop
&& physicalRight == other.physicalRight
- && physicalBottom == other.physicalBottom;
+ && physicalBottom == other.physicalBottom
+ && deviceWidth == other.deviceWidth
+ && deviceHeight == other.deviceHeight;
}
bool operator!=(const DisplayViewport& other) const {
return !(*this == other);
}
+
+ inline bool isValid() const {
+ return displayId >= 0;
+ }
+
+ void setNonDisplayViewport(int32_t width, int32_t height) {
+ displayId = ADISPLAY_ID_NONE;
+ orientation = DISPLAY_ORIENTATION_0;
+ logicalLeft = 0;
+ logicalTop = 0;
+ logicalRight = width;
+ logicalBottom = height;
+ physicalLeft = 0;
+ physicalTop = 0;
+ physicalRight = width;
+ physicalBottom = height;
+ deviceWidth = width;
+ deviceHeight = height;
+ }
};
/*
@@ -1297,18 +1321,30 @@
virtual void syncTouch(nsecs_t when, bool* outHavePointerIds) = 0;
private:
- // The surface orientation and width and height set by configureSurface().
- int32_t mSurfaceOrientation;
+ // The current viewport.
+ // The components of the viewport are specified in the display's rotated orientation.
+ DisplayViewport mViewport;
+
+ // The surface orientation, width and height set by configureSurface().
+ // The width and height are derived from the viewport but are specified
+ // in the natural orientation.
+ // The surface origin specifies how the surface coordinates should be translated
+ // to align with the logical display coordinate space.
+ // The orientation may be different from the viewport orientation as it specifies
+ // the rotation of the surface coordinates required to produce the viewport's
+ // requested orientation, so it will depend on whether the device is orientation aware.
int32_t mSurfaceWidth;
int32_t mSurfaceHeight;
-
- // The associated display viewport set by configureSurface().
- DisplayViewport mAssociatedDisplayViewport;
+ int32_t mSurfaceLeft;
+ int32_t mSurfaceTop;
+ int32_t mSurfaceOrientation;
// Translation and scaling factors, orientation-independent.
+ float mXTranslate;
float mXScale;
float mXPrecision;
+ float mYTranslate;
float mYScale;
float mYPrecision;
@@ -1369,8 +1405,6 @@
} mOrientedRanges;
// Oriented dimensions and precision.
- float mOrientedSurfaceWidth;
- float mOrientedSurfaceHeight;
float mOrientedXPrecision;
float mOrientedYPrecision;
diff --git a/services/input/InputWindow.h b/services/input/InputWindow.h
index 824a64b..3118099 100644
--- a/services/input/InputWindow.h
+++ b/services/input/InputWindow.h
@@ -132,6 +132,7 @@
int32_t ownerPid;
int32_t ownerUid;
int32_t inputFeatures;
+ int32_t displayId;
bool touchableRegionContainsPoint(int32_t x, int32_t y) const;
bool frameContainsPoint(int32_t x, int32_t y) const;
diff --git a/services/input/tests/InputReader_test.cpp b/services/input/tests/InputReader_test.cpp
index 03516af..c6dbbf3 100644
--- a/services/input/tests/InputReader_test.cpp
+++ b/services/input/tests/InputReader_test.cpp
@@ -151,6 +151,8 @@
v.physicalTop = 0;
v.physicalRight = isRotated ? height : width;
v.physicalBottom = isRotated ? width : height;
+ v.deviceWidth = isRotated ? height : width;
+ v.deviceHeight = isRotated ? width : height;
mConfig.setDisplayInfo(false /*external*/, v);
mConfig.setDisplayInfo(true /*external*/, v);
}
@@ -487,6 +489,7 @@
return OK;
}
}
+ outAxisInfo->clear();
return -1;
}
diff --git a/services/java/com/android/server/BluetoothManagerService.java b/services/java/com/android/server/BluetoothManagerService.java
index 9404dce..e68686d 100755
--- a/services/java/com/android/server/BluetoothManagerService.java
+++ b/services/java/com/android/server/BluetoothManagerService.java
@@ -75,12 +75,12 @@
private void registerForAirplaneMode(IntentFilter filter) {
final ContentResolver resolver = mContext.getContentResolver();
- final String airplaneModeRadios = Settings.System.getString(resolver,
- Settings.System.AIRPLANE_MODE_RADIOS);
- final String toggleableRadios = Settings.System.getString(resolver,
- Settings.System.AIRPLANE_MODE_TOGGLEABLE_RADIOS);
+ final String airplaneModeRadios = Settings.Global.getString(resolver,
+ Settings.Global.AIRPLANE_MODE_RADIOS);
+ final String toggleableRadios = Settings.Global.getString(resolver,
+ Settings.Global.AIRPLANE_MODE_TOGGLEABLE_RADIOS);
boolean mIsAirplaneSensitive = airplaneModeRadios == null ? true :
- airplaneModeRadios.contains(Settings.System.RADIO_BLUETOOTH);
+ airplaneModeRadios.contains(Settings.Global.RADIO_BLUETOOTH);
if (mIsAirplaneSensitive) {
filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
}
@@ -151,8 +151,8 @@
* Returns true if airplane mode is currently on
*/
private final boolean isAirplaneModeOn() {
- return Settings.System.getInt(mContext.getContentResolver(),
- Settings.System.AIRPLANE_MODE_ON, 0) == 1;
+ return Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.AIRPLANE_MODE_ON, 0) == 1;
}
/**
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index 6bc5e10..7ed4f8a 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -1179,17 +1179,17 @@
}
private boolean isAirplaneSensitive() {
- String airplaneModeRadios = Settings.System.getString(mContext.getContentResolver(),
- Settings.System.AIRPLANE_MODE_RADIOS);
+ String airplaneModeRadios = Settings.Global.getString(mContext.getContentResolver(),
+ Settings.Global.AIRPLANE_MODE_RADIOS);
return airplaneModeRadios == null
- || airplaneModeRadios.contains(Settings.System.RADIO_WIFI);
+ || airplaneModeRadios.contains(Settings.Global.RADIO_WIFI);
}
private boolean isAirplaneToggleable() {
- String toggleableRadios = Settings.System.getString(mContext.getContentResolver(),
- Settings.System.AIRPLANE_MODE_TOGGLEABLE_RADIOS);
+ String toggleableRadios = Settings.Global.getString(mContext.getContentResolver(),
+ Settings.Global.AIRPLANE_MODE_TOGGLEABLE_RADIOS);
return toggleableRadios != null
- && toggleableRadios.contains(Settings.System.RADIO_WIFI);
+ && toggleableRadios.contains(Settings.Global.RADIO_WIFI);
}
/**
@@ -1198,8 +1198,8 @@
* @return {@code true} if airplane mode is on.
*/
private boolean isAirplaneModeOn() {
- return isAirplaneSensitive() && Settings.System.getInt(mContext.getContentResolver(),
- Settings.System.AIRPLANE_MODE_ON, 0) == 1;
+ return isAirplaneSensitive() && Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.AIRPLANE_MODE_ON, 0) == 1;
}
@Override
@@ -1213,8 +1213,8 @@
}
pw.println("Wi-Fi is " + mWifiStateMachine.syncGetWifiStateByName());
pw.println("Stay-awake conditions: " +
- Settings.System.getInt(mContext.getContentResolver(),
- Settings.System.STAY_ON_WHILE_PLUGGED_IN, 0));
+ Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.STAY_ON_WHILE_PLUGGED_IN, 0));
pw.println();
pw.println("Internal state:");
diff --git a/services/java/com/android/server/display/DisplayDevice.java b/services/java/com/android/server/display/DisplayDevice.java
index 8eeefb4..f5aa3d4 100644
--- a/services/java/com/android/server/display/DisplayDevice.java
+++ b/services/java/com/android/server/display/DisplayDevice.java
@@ -176,6 +176,12 @@
} else {
viewport.physicalFrame.setEmpty();
}
+
+ boolean isRotated = (mCurrentOrientation == Surface.ROTATION_90
+ || mCurrentOrientation == Surface.ROTATION_270);
+ DisplayDeviceInfo info = getDisplayDeviceInfoLocked();
+ viewport.deviceWidth = isRotated ? info.height : info.width;
+ viewport.deviceHeight = isRotated ? info.width : info.height;
}
/**
diff --git a/services/java/com/android/server/display/DisplayViewport.java b/services/java/com/android/server/display/DisplayViewport.java
index ed4016d..5080556 100644
--- a/services/java/com/android/server/display/DisplayViewport.java
+++ b/services/java/com/android/server/display/DisplayViewport.java
@@ -44,12 +44,20 @@
// should be scaled or translated after rotation.
public final Rect physicalFrame = new Rect();
+ // The full width and height of the display device, rotated in the same
+ // manner as physicalFrame. This expresses the full native size of the display device.
+ // The physical frame should usually fit within this area.
+ public int deviceWidth;
+ public int deviceHeight;
+
public void copyFrom(DisplayViewport viewport) {
valid = viewport.valid;
displayId = viewport.displayId;
orientation = viewport.orientation;
logicalFrame.set(viewport.logicalFrame);
physicalFrame.set(viewport.physicalFrame);
+ deviceWidth = viewport.deviceWidth;
+ deviceHeight = viewport.deviceHeight;
}
// For debugging purposes.
@@ -60,6 +68,8 @@
+ ", orientation=" + orientation
+ ", logicalFrame=" + logicalFrame
+ ", physicalFrame=" + physicalFrame
+ + ", deviceWidth=" + deviceWidth
+ + ", deviceHeight=" + deviceHeight
+ "}";
}
}
diff --git a/services/java/com/android/server/input/InputManagerService.java b/services/java/com/android/server/input/InputManagerService.java
index 95655a5..805818a 100644
--- a/services/java/com/android/server/input/InputManagerService.java
+++ b/services/java/com/android/server/input/InputManagerService.java
@@ -149,7 +149,8 @@
private static native void nativeSetDisplayViewport(int ptr, boolean external,
int displayId, int rotation,
int logicalLeft, int logicalTop, int logicalRight, int logicalBottom,
- int physicalLeft, int physicalTop, int physicalRight, int physicalBottom);
+ int physicalLeft, int physicalTop, int physicalRight, int physicalBottom,
+ int deviceWidth, int deviceHeight);
private static native int nativeGetScanCodeState(int ptr,
int deviceId, int sourceMask, int scanCode);
@@ -305,7 +306,8 @@
viewport.logicalFrame.left, viewport.logicalFrame.top,
viewport.logicalFrame.right, viewport.logicalFrame.bottom,
viewport.physicalFrame.left, viewport.physicalFrame.top,
- viewport.physicalFrame.right, viewport.physicalFrame.bottom);
+ viewport.physicalFrame.right, viewport.physicalFrame.bottom,
+ viewport.deviceWidth, viewport.deviceHeight);
}
/**
diff --git a/services/java/com/android/server/location/ComprehensiveCountryDetector.java b/services/java/com/android/server/location/ComprehensiveCountryDetector.java
index 1026a0d..354858b 100755
--- a/services/java/com/android/server/location/ComprehensiveCountryDetector.java
+++ b/services/java/com/android/server/location/ComprehensiveCountryDetector.java
@@ -384,8 +384,8 @@
}
protected boolean isAirplaneModeOff() {
- return Settings.System.getInt(
- mContext.getContentResolver(), Settings.System.AIRPLANE_MODE_ON, 0) == 0;
+ return Settings.Global.getInt(
+ mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 0) == 0;
}
/**
diff --git a/services/java/com/android/server/pm/Installer.java b/services/java/com/android/server/pm/Installer.java
index 3329acb..4268ae0 100644
--- a/services/java/com/android/server/pm/Installer.java
+++ b/services/java/com/android/server/pm/Installer.java
@@ -359,6 +359,14 @@
return execute("movefiles");
}
+ /**
+ * Links the native library directory in an application's directory to its
+ * real location.
+ *
+ * @param dataPath data directory where the application is
+ * @param nativeLibPath target native library path
+ * @return -1 on error
+ */
public int linkNativeLibraryDirectory(String dataPath, String nativeLibPath) {
if (dataPath == null) {
Slog.e(TAG, "unlinkNativeLibraryDirectory dataPath is null");
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index 4bb6e38..b5ae214 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -25,6 +25,11 @@
import static com.android.internal.util.ArrayUtils.appendInt;
import static com.android.internal.util.ArrayUtils.removeInt;
import static libcore.io.OsConstants.S_ISLNK;
+import static libcore.io.OsConstants.S_IRWXU;
+import static libcore.io.OsConstants.S_IRGRP;
+import static libcore.io.OsConstants.S_IXGRP;
+import static libcore.io.OsConstants.S_IROTH;
+import static libcore.io.OsConstants.S_IXOTH;
import com.android.internal.app.IMediaContainerService;
import com.android.internal.app.ResolverActivity;
@@ -147,6 +152,7 @@
import libcore.io.ErrnoException;
import libcore.io.IoUtils;
import libcore.io.Libcore;
+import libcore.io.OsConstants;
import libcore.io.StructStat;
/**
@@ -276,7 +282,7 @@
// This is the object monitoring mDrmAppPrivateInstallDir.
final FileObserver mDrmAppInstallObserver;
- // Used for priviledge escalation. MUST NOT BE CALLED WITH mPackages
+ // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages
// LOCK HELD. Can be called with mInstallLock held.
final Installer mInstaller;
@@ -286,6 +292,12 @@
final File mAppInstallDir;
final File mDalvikCacheDir;
+ /**
+ * Directory to which applications installed internally have native
+ * libraries copied.
+ */
+ private File mAppLibInstallDir;
+
// Directory containing the private parts (e.g. code and non-resource assets) of forward-locked
// apps.
final File mDrmAppPrivateInstallDir;
@@ -1215,6 +1227,7 @@
}
mAppInstallDir = new File(dataDir, "app");
+ mAppLibInstallDir = new File(dataDir, "app-lib");
//look for any incomplete package installations
ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
//clean up list
@@ -3607,6 +3620,13 @@
res = resInner;
}
}
+
+ final File nativeLibraryFile = new File(mAppLibInstallDir, packageName);
+ NativeLibraryHelper.removeNativeBinariesFromDirLI(nativeLibraryFile);
+ if (!nativeLibraryFile.delete()) {
+ Slog.w(TAG, "Couldn't delete native library directory " + nativeLibraryFile.getPath());
+ }
+
return res;
}
@@ -4048,9 +4068,7 @@
*/
if (pkg.applicationInfo.nativeLibraryDir == null && pkg.applicationInfo.dataDir != null) {
if (pkgSetting.nativeLibraryPathString == null) {
- final String nativeLibraryPath = new File(dataPath, LIB_DIR_NAME).getPath();
- pkg.applicationInfo.nativeLibraryDir = nativeLibraryPath;
- pkgSetting.nativeLibraryPathString = nativeLibraryPath;
+ setInternalAppNativeLibraryPath(pkg, pkgSetting);
} else {
pkg.applicationInfo.nativeLibraryDir = pkgSetting.nativeLibraryPathString;
}
@@ -4072,7 +4090,7 @@
*/
if (pkg.applicationInfo.nativeLibraryDir != null) {
try {
- final File nativeLibraryDir = new File(pkg.applicationInfo.nativeLibraryDir);
+ File nativeLibraryDir = new File(pkg.applicationInfo.nativeLibraryDir);
final String dataPathString = dataPath.getCanonicalPath();
if (isSystemApp(pkg) && !isUpdatedSystemApp(pkg)) {
@@ -4087,30 +4105,31 @@
Log.i(TAG, "removed obsolete native libraries for system package "
+ path);
}
- } else if (nativeLibraryDir.getParentFile().getCanonicalPath()
- .equals(dataPathString)) {
- /*
- * Make sure the native library dir isn't a symlink to
- * something. If it is, ask installd to remove it and create
- * a directory so we can copy to it afterwards.
- */
- boolean isSymLink;
- try {
- isSymLink = S_ISLNK(Libcore.os.lstat(nativeLibraryDir.getPath()).st_mode);
- } catch (ErrnoException e) {
- // This shouldn't happen, but we'll fail-safe.
- isSymLink = true;
- }
- if (isSymLink) {
- mInstaller.unlinkNativeLibraryDirectory(dataPathString);
+ } else if (!isForwardLocked(pkg) && !isExternal(pkg)) {
+ // Update native library dir if it starts with /data/data
+ if (nativeLibraryDir.getParent().startsWith(dataPathString)) {
+ setInternalAppNativeLibraryPath(pkg, pkgSetting);
+ nativeLibraryDir = new File(pkg.applicationInfo.nativeLibraryDir);
}
- /*
- * If this is an internal application or our
- * nativeLibraryPath points to our data directory, unpack
- * the libraries if necessary.
- */
- NativeLibraryHelper.copyNativeBinariesIfNeededLI(scanFile, nativeLibraryDir);
+ try {
+ if (copyNativeLibrariesForInternalApp(scanFile, nativeLibraryDir) != PackageManager.INSTALL_SUCCEEDED) {
+ Slog.e(TAG, "Unable to copy native libraries");
+ mLastScanError = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
+ return null;
+ }
+ } catch (IOException e) {
+ Slog.e(TAG, "Unable to copy native libraries", e);
+ mLastScanError = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
+ return null;
+ }
+
+ if (mInstaller.linkNativeLibraryDirectory(dataPathString,
+ pkg.applicationInfo.nativeLibraryDir) == -1) {
+ Slog.e(TAG, "Unable to link native library directory");
+ mLastScanError = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
+ return null;
+ }
} else {
Slog.i(TAG, "Linking native library dir for " + path);
int ret = mInstaller.linkNativeLibraryDirectory(dataPathString,
@@ -4122,7 +4141,7 @@
}
}
} catch (IOException ioe) {
- Log.e(TAG, "Unable to get canonical file " + ioe.toString());
+ Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
}
}
pkg.mScanPath = path;
@@ -4437,6 +4456,37 @@
return pkg;
}
+ private void setInternalAppNativeLibraryPath(PackageParser.Package pkg,
+ PackageSetting pkgSetting) {
+ final String apkLibPath = getApkName(pkgSetting.codePathString);
+ final String nativeLibraryPath = new File(mAppLibInstallDir, apkLibPath).getPath();
+ pkg.applicationInfo.nativeLibraryDir = nativeLibraryPath;
+ pkgSetting.nativeLibraryPathString = nativeLibraryPath;
+ }
+
+ private static int copyNativeLibrariesForInternalApp(File scanFile, final File nativeLibraryDir)
+ throws IOException {
+ if (!nativeLibraryDir.isDirectory()) {
+ nativeLibraryDir.delete();
+ if (!nativeLibraryDir.mkdir()) {
+ throw new IOException("Cannot create " + nativeLibraryDir.getPath());
+ }
+ try {
+ Libcore.os.chmod(nativeLibraryDir.getPath(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH
+ | S_IXOTH);
+ } catch (ErrnoException e) {
+ throw new IOException("Cannot chmod native library directory "
+ + nativeLibraryDir.getPath(), e);
+ }
+ }
+
+ /*
+ * If this is an internal application or our nativeLibraryPath points to
+ * the app-lib directory, unpack the libraries if necessary.
+ */
+ return NativeLibraryHelper.copyNativeBinariesIfNeededLI(scanFile, nativeLibraryDir);
+ }
+
private void killApplication(String pkgName, int appId) {
// Request the ActivityManager to kill the process(only for existing packages)
// so that we do not end up in a confused state while the user is still using the older
@@ -6737,7 +6787,7 @@
String apkName = getNextCodePath(null, pkgName, ".apk");
codeFileName = new File(installDir, apkName + ".apk").getPath();
resourceFileName = getResourcePathFromCodePath();
- libraryPath = new File(dataDir, LIB_DIR_NAME).getPath();
+ libraryPath = new File(mAppLibInstallDir, pkgName).getPath();
}
boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException {
@@ -6774,6 +6824,7 @@
installDir = isFwdLocked() ? mDrmAppPrivateInstallDir : mAppInstallDir;
codeFileName = createTempPackageFile(installDir).getPath();
resourceFileName = getResourcePathFromCodePath();
+ libraryPath = getLibraryPathFromCodePath();
created = true;
}
@@ -6828,6 +6879,23 @@
return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
}
}
+
+ final File nativeLibraryFile = new File(getNativeLibraryPath());
+ Slog.i(TAG, "Copying native libraries to " + nativeLibraryFile.getPath());
+ if (nativeLibraryFile.exists()) {
+ NativeLibraryHelper.removeNativeBinariesFromDirLI(nativeLibraryFile);
+ nativeLibraryFile.delete();
+ }
+ try {
+ int copyRet = copyNativeLibrariesForInternalApp(codeFile, nativeLibraryFile);
+ if (copyRet != PackageManager.INSTALL_SUCCEEDED) {
+ return copyRet;
+ }
+ } catch (IOException e) {
+ Slog.e(TAG, "Copying native libraries failed", e);
+ ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
+ }
+
return ret;
}
@@ -6845,6 +6913,7 @@
} else {
final File oldCodeFile = new File(getCodePath());
final File oldResourceFile = new File(getResourcePath());
+ final File oldLibraryFile = new File(getNativeLibraryPath());
// Rename APK file based on packageName
final String apkName = getNextCodePath(oldCodePath, pkgName, ".apk");
@@ -6859,7 +6928,20 @@
if (isFwdLocked() && !oldResourceFile.renameTo(newResFile)) {
return false;
}
- resourceFileName = getResourcePathFromCodePath();
+ resourceFileName = newResFile.getPath();
+
+ // Rename library path
+ final File newLibraryFile = new File(getLibraryPathFromCodePath());
+ if (newLibraryFile.exists()) {
+ NativeLibraryHelper.removeNativeBinariesFromDirLI(newLibraryFile);
+ newLibraryFile.delete();
+ }
+ if (!oldLibraryFile.renameTo(newLibraryFile)) {
+ Slog.e(TAG, "Cannot rename native library directory "
+ + oldLibraryFile.getPath() + " to " + newLibraryFile.getPath());
+ return false;
+ }
+ libraryPath = newLibraryFile.getPath();
// Attempt to set permissions
if (!setPermissions()) {
@@ -6910,8 +6992,15 @@
}
}
+ private String getLibraryPathFromCodePath() {
+ return new File(mAppLibInstallDir, getApkName(getCodePath())).getPath();
+ }
+
@Override
String getNativeLibraryPath() {
+ if (libraryPath == null) {
+ libraryPath = getLibraryPathFromCodePath();
+ }
return libraryPath;
}
@@ -6937,6 +7026,15 @@
publicSourceFile.delete();
}
}
+
+ if (libraryPath != null) {
+ File nativeLibraryFile = new File(libraryPath);
+ NativeLibraryHelper.removeNativeBinariesFromDirLI(nativeLibraryFile);
+ if (!nativeLibraryFile.delete()) {
+ Slog.w(TAG, "Couldn't delete native library directory " + libraryPath);
+ }
+ }
+
return ret;
}
@@ -9779,31 +9877,26 @@
final String newNativePath = mp.targetArgs
.getNativeLibraryPath();
- try {
- final File newNativeDir = new File(newNativePath);
+ final File newNativeDir = new File(newNativePath);
- final String libParentDir = newNativeDir.getParentFile()
- .getCanonicalPath();
- if (newNativeDir.getParentFile().getCanonicalPath()
- .equals(pkg.applicationInfo.dataDir)) {
- if (mInstaller
- .unlinkNativeLibraryDirectory(pkg.applicationInfo.dataDir) < 0) {
- returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE;
- } else {
- NativeLibraryHelper.copyNativeBinariesIfNeededLI(
- new File(newCodePath), newNativeDir);
- }
- } else {
+ if (!isForwardLocked(pkg) && !isExternal(pkg)) {
+ synchronized (mInstallLock) {
if (mInstaller.linkNativeLibraryDirectory(
pkg.applicationInfo.dataDir, newNativePath) < 0) {
returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE;
}
}
- } catch (IOException e) {
- returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION;
+ NativeLibraryHelper.copyNativeBinariesIfNeededLI(new File(
+ newCodePath), newNativeDir);
+ } else {
+ synchronized (mInstallLock) {
+ if (mInstaller.linkNativeLibraryDirectory(
+ pkg.applicationInfo.dataDir, newNativePath) < 0) {
+ returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE;
+ }
+ }
}
-
if (returnCode == PackageManager.MOVE_SUCCEEDED) {
pkg.mPath = newCodePath;
// Move dex files around
diff --git a/services/java/com/android/server/wm/InputMonitor.java b/services/java/com/android/server/wm/InputMonitor.java
index 5ff8a9b..aa18ee4 100644
--- a/services/java/com/android/server/wm/InputMonitor.java
+++ b/services/java/com/android/server/wm/InputMonitor.java
@@ -19,11 +19,13 @@
import com.android.server.input.InputManagerService;
import com.android.server.input.InputApplicationHandle;
import com.android.server.input.InputWindowHandle;
+import com.android.server.wm.WindowManagerService.AllWindowsIterator;
import android.graphics.Rect;
import android.os.RemoteException;
import android.util.Log;
import android.util.Slog;
+import android.view.Display;
import android.view.InputChannel;
import android.view.KeyEvent;
import android.view.WindowManager;
@@ -225,10 +227,11 @@
addInputWindowHandleLw(mService.mFakeWindows.get(i).mWindowHandle);
}
- // TODO(multidisplay): Input only occurs on the default display.
- final WindowList windows = mService.getDefaultWindowList();
- for (int i = windows.size() - 1; i >= 0; i--) {
- final WindowState child = windows.get(i);
+ // Add all windows on the default display.
+ final AllWindowsIterator iterator = mService.new AllWindowsIterator(
+ WindowManagerService.REVERSE_ITERATOR);
+ while (iterator.hasNext()) {
+ final WindowState child = iterator.next();
final InputChannel inputChannel = child.mInputChannel;
final InputWindowHandle inputWindowHandle = child.mInputWindowHandle;
if (inputChannel == null || inputWindowHandle == null || child.mRemoved) {
@@ -243,15 +246,16 @@
final boolean isVisible = child.isVisibleLw();
final boolean hasWallpaper = (child == mService.mWallpaperTarget)
&& (type != WindowManager.LayoutParams.TYPE_KEYGUARD);
+ final boolean onDefaultDisplay = (child.getDisplayId() == Display.DEFAULT_DISPLAY);
// If there's a drag in progress and 'child' is a potential drop target,
// make sure it's been told about the drag
- if (inDrag && isVisible) {
+ if (inDrag && isVisible && onDefaultDisplay) {
mService.mDragState.sendDragStartedIfNeededLw(child);
}
if (universeBackground != null && !addedUniverse
- && child.mBaseLayer < aboveUniverseLayer) {
+ && child.mBaseLayer < aboveUniverseLayer && onDefaultDisplay) {
final WindowState u = universeBackground.mWin;
if (u.mInputChannel != null && u.mInputWindowHandle != null) {
addInputWindowHandleLw(u.mInputWindowHandle, u, u.mAttrs.flags,
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index cdca8bc..17f4a96 100755
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -434,6 +434,7 @@
final float[] mTmpFloats = new float[9];
+ boolean mDisplayReady;
boolean mSafeMode;
boolean mDisplayEnabled = false;
boolean mSystemBooted = false;
@@ -503,8 +504,6 @@
final ArrayList<AppWindowToken> mOpeningApps = new ArrayList<AppWindowToken>();
final ArrayList<AppWindowToken> mClosingApps = new ArrayList<AppWindowToken>();
- Display mDefaultDisplay;
-
boolean mIsTouchDevice;
final DisplayMetrics mDisplayMetrics = new DisplayMetrics();
@@ -2085,7 +2084,7 @@
long origId;
synchronized(mWindowMap) {
- if (mDefaultDisplay == null) {
+ if (!mDisplayReady) {
throw new IllegalStateException("Display has not been initialialized");
}
@@ -5604,8 +5603,10 @@
">>> OPEN TRANSACTION showStrictModeViolation");
Surface.openTransaction();
try {
+ // TODO(multi-display): support multiple displays
if (mStrictModeFlash == null) {
- mStrictModeFlash = new StrictModeFlash(mDefaultDisplay, mFxSession);
+ mStrictModeFlash = new StrictModeFlash(
+ getDefaultDisplayContent().getDisplay(), mFxSession);
}
mStrictModeFlash.setVisibility(on);
} finally {
@@ -5718,7 +5719,7 @@
}
// The screenshot API does not apply the current screen rotation.
- rot = mDefaultDisplay.getRotation();
+ rot = getDefaultDisplayContent().getDisplay().getRotation();
int fw = frame.width();
int fh = frame.height();
@@ -6751,7 +6752,7 @@
}
boolean computeScreenConfigurationLocked(Configuration config) {
- if (mDefaultDisplay == null) {
+ if (!mDisplayReady) {
return false;
}
@@ -6785,13 +6786,8 @@
}
if (config != null) {
- int orientation = Configuration.ORIENTATION_SQUARE;
- if (dw < dh) {
- orientation = Configuration.ORIENTATION_PORTRAIT;
- } else if (dw > dh) {
- orientation = Configuration.ORIENTATION_LANDSCAPE;
- }
- config.orientation = orientation;
+ config.orientation = (dw <= dh) ? Configuration.ORIENTATION_PORTRAIT :
+ Configuration.ORIENTATION_LANDSCAPE;
}
// Update application display metrics.
@@ -6958,9 +6954,12 @@
synchronized (mWindowMap) {
try {
if (mDragState == null) {
+ // TODO(multi-display): support other displays
+ final DisplayContent displayContent = getDefaultDisplayContent();
+ final Display display = displayContent.getDisplay();
Surface surface = new Surface(session, "drag surface",
width, height, PixelFormat.TRANSLUCENT, Surface.HIDDEN);
- surface.setLayerStack(mDefaultDisplay.getLayerStack());
+ surface.setLayerStack(display.getLayerStack());
if (SHOW_TRANSACTIONS) Slog.i(TAG, " DRAG "
+ surface + ": CREATE");
outSurface.copyFrom(surface);
@@ -7102,26 +7101,28 @@
}
public void displayReady() {
- WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
- final Display display = wm.getDefaultDisplay();
- displayReady(display.getDisplayId());
+ displayReady(Display.DEFAULT_DISPLAY);
synchronized(mWindowMap) {
- readForcedDisplaySizeAndDensityLocked(getDefaultDisplayContent());
+ final DisplayContent displayContent = getDefaultDisplayContent();
+ final Display display = displayContent.getDisplay();
+ readForcedDisplaySizeAndDensityLocked(displayContent);
- mDefaultDisplay = display;
+ mDisplayReady = true;
mIsTouchDevice = mContext.getPackageManager().hasSystemFeature(
- PackageManager.FEATURE_TOUCHSCREEN);
+ PackageManager.FEATURE_TOUCHSCREEN);
mAnimator.initializeLocked(display.getLayerStack());
final DisplayInfo displayInfo = getDefaultDisplayInfo();
- mAnimator.setDisplayDimensions(displayInfo.logicalWidth, displayInfo.logicalHeight,
- displayInfo.appWidth, displayInfo.appHeight);
+ mAnimator.setDisplayDimensions(
+ displayInfo.logicalWidth, displayInfo.logicalHeight,
+ displayInfo.appWidth, displayInfo.appHeight);
- final DisplayContent displayContent = getDefaultDisplayContent();
- mPolicy.setInitialDisplaySize(mDefaultDisplay, displayContent.mInitialDisplayWidth,
- displayContent.mInitialDisplayHeight, displayContent.mInitialDisplayDensity);
+ mPolicy.setInitialDisplaySize(displayContent.getDisplay(),
+ displayContent.mInitialDisplayWidth,
+ displayContent.mInitialDisplayHeight,
+ displayContent.mInitialDisplayDensity);
}
try {
@@ -7802,6 +7803,7 @@
}
// TODO(multidisplay): For now rotations are only main screen.
final DisplayContent displayContent = getDefaultDisplayContent();
+ final Display display = displayContent.getDisplay();
if (displayContent.mBaseDisplayWidth < displayContent.mInitialDisplayWidth
|| displayContent.mBaseDisplayHeight < displayContent.mInitialDisplayHeight) {
int initW, initH, baseW, baseH;
@@ -7829,7 +7831,7 @@
Rect inner = new Rect(0, 0, baseW, baseH);
try {
mBlackFrame = new BlackFrame(mFxSession, outer, inner, MASK_LAYER,
- mDefaultDisplay.getLayerStack());
+ display.getLayerStack());
} catch (Surface.OutOfResourcesException e) {
}
}
@@ -7929,8 +7931,10 @@
private void reconfigureDisplayLocked(DisplayContent displayContent) {
// TODO: Multidisplay: for now only use with default display.
- mPolicy.setInitialDisplaySize(mDefaultDisplay, displayContent.mBaseDisplayWidth,
- displayContent.mBaseDisplayHeight, displayContent.mBaseDisplayDensity);
+ mPolicy.setInitialDisplaySize(displayContent.getDisplay(),
+ displayContent.mBaseDisplayWidth,
+ displayContent.mBaseDisplayHeight,
+ displayContent.mBaseDisplayDensity);
displayContent.layoutNeeded = true;
@@ -8154,7 +8158,7 @@
return;
}
- if (mDefaultDisplay == null) {
+ if (!mDisplayReady) {
// Not yet initialized, nothing to do.
return;
}
@@ -8600,11 +8604,14 @@
Rect dirty = new Rect(0, 0, mNextAppTransitionThumbnail.getWidth(),
mNextAppTransitionThumbnail.getHeight());
try {
+ // TODO(multi-display): support other displays
+ final DisplayContent displayContent = getDefaultDisplayContent();
+ final Display display = displayContent.getDisplay();
Surface surface = new Surface(mFxSession,
"thumbnail anim",
dirty.width(), dirty.height(),
PixelFormat.TRANSLUCENT, Surface.HIDDEN);
- surface.setLayerStack(mDefaultDisplay.getLayerStack());
+ surface.setLayerStack(display.getLayerStack());
topOpeningApp.mAppAnimator.thumbnail = surface;
if (SHOW_TRANSACTIONS) Slog.i(TAG, " THUMBNAIL "
+ surface + ": CREATE");
@@ -9857,7 +9864,7 @@
return;
}
- if (mDefaultDisplay == null || !mPolicy.isScreenOnFully()) {
+ if (!mDisplayReady || !mPolicy.isScreenOnFully()) {
// No need to freeze the screen before the system is ready or if
// the screen is off.
return;
@@ -9889,10 +9896,12 @@
}
// TODO(multidisplay): rotation on main screen only.
- DisplayInfo displayInfo = getDefaultDisplayContent().getDisplayInfo();
+ final DisplayContent displayContent = getDefaultDisplayContent();
+ final Display display = displayContent.getDisplay();
+ final DisplayInfo displayInfo = displayContent.getDisplayInfo();
mAnimator.mScreenRotationAnimation = new ScreenRotationAnimation(mContext,
- mDefaultDisplay, mFxSession, inTransaction, displayInfo.logicalWidth,
- displayInfo.logicalHeight, mDefaultDisplay.getRotation());
+ display, mFxSession, inTransaction, displayInfo.logicalWidth,
+ displayInfo.logicalHeight, display.getRotation());
}
}
@@ -10003,8 +10012,8 @@
if (line != null) {
String[] toks = line.split("%");
if (toks != null && toks.length > 0) {
- mWatermark =
- new Watermark(mDefaultDisplay, mRealDisplayMetrics, mFxSession, toks);
+ mWatermark = new Watermark(getDefaultDisplayContent().getDisplay(),
+ mRealDisplayMetrics, mFxSession, toks);
}
}
} catch (FileNotFoundException e) {
@@ -10372,7 +10381,7 @@
}
}
pw.println();
- if (mDefaultDisplay != null) {
+ if (mDisplayReady) {
DisplayContentsIterator dCIterator = new DisplayContentsIterator();
while (dCIterator.hasNext()) {
dCIterator.next().dump(pw);
@@ -10744,7 +10753,7 @@
}
}
- boolean REVERSE_ITERATOR = true;
+ final static boolean REVERSE_ITERATOR = true;
class AllWindowsIterator implements Iterator<WindowState> {
private DisplayContent mDisplayContent;
private DisplayContentsIterator mDisplayContentsIterator;
@@ -10804,9 +10813,7 @@
}
public DisplayContent getDefaultDisplayContent() {
- final int displayId = mDefaultDisplay == null
- ? Display.DEFAULT_DISPLAY : mDefaultDisplay.getDisplayId();
- return getDisplayContent(displayId);
+ return getDisplayContent(Display.DEFAULT_DISPLAY);
}
public WindowList getDefaultWindowList() {
diff --git a/services/jni/com_android_server_input_InputManagerService.cpp b/services/jni/com_android_server_input_InputManagerService.cpp
index 5e36bf8..319cacd 100644
--- a/services/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/jni/com_android_server_input_InputManagerService.cpp
@@ -993,7 +993,8 @@
static void nativeSetDisplayViewport(JNIEnv* env, jclass clazz, jint ptr, jboolean external,
jint displayId, jint orientation,
jint logicalLeft, jint logicalTop, jint logicalRight, jint logicalBottom,
- jint physicalLeft, jint physicalTop, jint physicalRight, jint physicalBottom) {
+ jint physicalLeft, jint physicalTop, jint physicalRight, jint physicalBottom,
+ jint deviceWidth, jint deviceHeight) {
NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
DisplayViewport v;
@@ -1007,6 +1008,8 @@
v.physicalTop = physicalTop;
v.physicalRight = physicalRight;
v.physicalBottom = physicalBottom;
+ v.deviceWidth = deviceWidth;
+ v.deviceHeight = deviceHeight;
im->setDisplayViewport(external, v);
}
@@ -1288,7 +1291,7 @@
(void*) nativeInit },
{ "nativeStart", "(I)V",
(void*) nativeStart },
- { "nativeSetDisplayViewport", "(IZIIIIIIIIII)V",
+ { "nativeSetDisplayViewport", "(IZIIIIIIIIIIII)V",
(void*) nativeSetDisplayViewport },
{ "nativeGetScanCodeState", "(IIII)I",
(void*) nativeGetScanCodeState },
diff --git a/services/jni/com_android_server_input_InputWindowHandle.cpp b/services/jni/com_android_server_input_InputWindowHandle.cpp
index 01fb781..6692994 100644
--- a/services/jni/com_android_server_input_InputWindowHandle.cpp
+++ b/services/jni/com_android_server_input_InputWindowHandle.cpp
@@ -52,6 +52,7 @@
jfieldID ownerPid;
jfieldID ownerUid;
jfieldID inputFeatures;
+ jfieldID displayId;
} gInputWindowHandleClassInfo;
static Mutex gHandleMutex;
@@ -151,6 +152,8 @@
gInputWindowHandleClassInfo.ownerUid);
mInfo->inputFeatures = env->GetIntField(obj,
gInputWindowHandleClassInfo.inputFeatures);
+ mInfo->displayId = env->GetIntField(obj,
+ gInputWindowHandleClassInfo.displayId);
env->DeleteLocalRef(obj);
return true;
@@ -291,6 +294,9 @@
GET_FIELD_ID(gInputWindowHandleClassInfo.inputFeatures, clazz,
"inputFeatures", "I");
+
+ GET_FIELD_ID(gInputWindowHandleClassInfo.displayId, clazz,
+ "displayId", "I");
return 0;
}