Merge "Update airplane-mode manipulation for the new Settings namespace" into jb-mr1-dev
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 38e6970..09fa99c 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -4066,7 +4066,8 @@
// send up app name; do this *before* waiting for debugger
Process.setArgV0(data.processName);
- android.ddm.DdmHandleAppName.setAppName(data.processName);
+ android.ddm.DdmHandleAppName.setAppName(data.processName,
+ UserHandle.myUserId());
if (data.persistent) {
// Persistent processes on low-memory devices do not get to
@@ -4792,7 +4793,8 @@
ensureJitEnabled();
}
});
- android.ddm.DdmHandleAppName.setAppName("<pre-initialized>");
+ android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
+ UserHandle.myUserId());
RuntimeInit.setApplicationObject(mAppThread.asBinder());
IActivityManager mgr = ActivityManagerNative.getDefault();
try {
@@ -4803,7 +4805,8 @@
} else {
// Don't set application object here -- if the system crashes,
// we can't display an alert, we just want to die die die.
- android.ddm.DdmHandleAppName.setAppName("system_process");
+ android.ddm.DdmHandleAppName.setAppName("system_process",
+ UserHandle.myUserId());
try {
mInstrumentation = new Instrumentation();
ContextImpl context = new ContextImpl();
diff --git a/core/java/android/appwidget/AppWidgetManager.java b/core/java/android/appwidget/AppWidgetManager.java
index 810e790..2df675e 100644
--- a/core/java/android/appwidget/AppWidgetManager.java
+++ b/core/java/android/appwidget/AppWidgetManager.java
@@ -237,8 +237,9 @@
/**
* Sent when the custom extras for an AppWidget change.
*
- * @see AppWidgetProvider#onAppWidgetExtrasChanged AppWidgetProvider#onAppWidgetExtrasChanged(
- * Context context, AppWidgetManager appWidgetManager, int appWidgetId, Bundle newExtras)
+ * @see AppWidgetProvider#onAppWidgetOptionsChanged
+ * AppWidgetProvider.onAppWidgetOptionsChanged(Context context,
+ * AppWidgetManager appWidgetManager, int appWidgetId, Bundle newExtras)
*/
public static final String ACTION_APPWIDGET_OPTIONS_CHANGED = "android.appwidget.action.APPWIDGET_UPDATE_OPTIONS";
diff --git a/core/java/android/ddm/DdmHandleAppName.java b/core/java/android/ddm/DdmHandleAppName.java
index 78dd23e..7e39e47 100644
--- a/core/java/android/ddm/DdmHandleAppName.java
+++ b/core/java/android/ddm/DdmHandleAppName.java
@@ -69,14 +69,14 @@
* before or after DDMS connects. For the latter we need to send up
* an APNM message.
*/
- public static void setAppName(String name) {
+ public static void setAppName(String name, int userId) {
if (name == null || name.length() == 0)
return;
mAppName = name;
// if DDMS is already connected, send the app name up
- sendAPNM(name);
+ sendAPNM(name, userId);
}
public static String getAppName() {
@@ -86,14 +86,18 @@
/*
* Send an APNM (APplication NaMe) chunk.
*/
- private static void sendAPNM(String appName) {
+ private static void sendAPNM(String appName, int userId) {
if (false)
Log.v("ddm", "Sending app name");
- ByteBuffer out = ByteBuffer.allocate(4 + appName.length()*2);
+ ByteBuffer out = ByteBuffer.allocate(
+ 4 /* appName's length */
+ + appName.length()*2 /* appName */
+ + 4 /* userId */);
out.order(ChunkHandler.CHUNK_ORDER);
out.putInt(appName.length());
putString(out, appName);
+ out.putInt(userId);
Chunk chunk = new Chunk(CHUNK_APNM, out);
DdmServer.sendChunk(chunk);
diff --git a/core/java/android/ddm/DdmHandleHello.java b/core/java/android/ddm/DdmHandleHello.java
index 5088d22..e99fa92 100644
--- a/core/java/android/ddm/DdmHandleHello.java
+++ b/core/java/android/ddm/DdmHandleHello.java
@@ -21,6 +21,7 @@
import org.apache.harmony.dalvik.ddmc.DdmServer;
import android.util.Log;
import android.os.Debug;
+import android.os.UserHandle;
import java.nio.ByteBuffer;
@@ -119,7 +120,7 @@
// appName = "unknown";
String appName = DdmHandleAppName.getAppName();
- ByteBuffer out = ByteBuffer.allocate(16
+ ByteBuffer out = ByteBuffer.allocate(20
+ vmIdent.length()*2 + appName.length()*2);
out.order(ChunkHandler.CHUNK_ORDER);
out.putInt(DdmServer.CLIENT_PROTOCOL_VERSION);
@@ -128,6 +129,7 @@
out.putInt(appName.length());
putString(out, vmIdent);
putString(out, appName);
+ out.putInt(UserHandle.myUserId());
Chunk reply = new Chunk(CHUNK_HELO, out);
diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java
index 9334036..494a28c 100644
--- a/core/java/android/webkit/WebViewClassic.java
+++ b/core/java/android/webkit/WebViewClassic.java
@@ -27,7 +27,6 @@
import android.content.ComponentCallbacks2;
import android.content.Context;
import android.content.DialogInterface;
-import android.content.DialogInterface.OnCancelListener;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
@@ -69,7 +68,6 @@
import android.util.DisplayMetrics;
import android.util.EventLog;
import android.util.Log;
-import android.view.Display;
import android.view.Gravity;
import android.view.HapticFeedbackConstants;
import android.view.HardwareCanvas;
@@ -87,7 +85,6 @@
import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.ViewRootImpl;
-import android.view.WindowManager;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityNodeInfo;
@@ -136,9 +133,6 @@
import java.util.Map;
import java.util.Set;
import java.util.Vector;
-import java.util.concurrent.CountDownLatch;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
/**
* Implements a backend provider for the {@link WebView} public API.
@@ -1891,9 +1885,9 @@
mSavePasswordDialog = null;
}
})
- .setOnCancelListener(new OnCancelListener() {
+ .setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
- public void onCancel(DialogInterface dialog) {
+ public void onDismiss(DialogInterface dialog) {
if (mResumeMsg != null) {
resumeMsg.sendToTarget();
mResumeMsg = null;
@@ -2098,14 +2092,18 @@
hideSoftKeyboard();
clearActionModes();
dismissFullScreenMode();
- cancelSelectDialog();
+ cancelDialogs();
}
- private void cancelSelectDialog() {
+ private void cancelDialogs() {
if (mListBoxDialog != null) {
mListBoxDialog.cancel();
mListBoxDialog = null;
}
+ if (mSavePasswordDialog != null) {
+ mSavePasswordDialog.dismiss();
+ mSavePasswordDialog = null;
+ }
}
/**
@@ -2133,15 +2131,6 @@
private void destroyJava() {
mCallbackProxy.blockMessages();
- clearHelpers();
- if (mListBoxDialog != null) {
- mListBoxDialog.dismiss();
- mListBoxDialog = null;
- }
- if (mSavePasswordDialog != null) {
- mSavePasswordDialog.dismiss();
- mSavePasswordDialog = null;
- }
if (mWebViewCore != null) {
// Tell WebViewCore to destroy itself
synchronized (this) {
@@ -3492,7 +3481,7 @@
nativeSetPauseDrawing(mNativeClass, true);
}
- cancelSelectDialog();
+ cancelDialogs();
WebCoreThreadWatchdog.pause();
}
}
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/docs/html/guide/topics/resources/providing-resources.jd b/docs/html/guide/topics/resources/providing-resources.jd
index b2c95b9..749e458 100644
--- a/docs/html/guide/topics/resources/providing-resources.jd
+++ b/docs/html/guide/topics/resources/providing-resources.jd
@@ -573,6 +573,10 @@
no display</li>
</ul>
<p><em>Added in API level 8, television added in API 13.</em></p>
+ <p>For information about how your app can respond when the device is inserted into or
+ removed from a dock, read <a
+ href="{@docRoot}training/monitoring-device-state/docking-monitoring.html">Determining
+and Monitoring the Docking State and Type</a>.</p>
<p>This can change during the life of your application if the user places the device in a
dock. You can enable or disable some of these modes using {@link
android.app.UiModeManager}. See <a href="runtime-changes.html">Handling Runtime Changes</a> for
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/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/accessibility/ScreenMagnifier.java b/services/java/com/android/server/accessibility/ScreenMagnifier.java
index 62d410b..ca61400 100644
--- a/services/java/com/android/server/accessibility/ScreenMagnifier.java
+++ b/services/java/com/android/server/accessibility/ScreenMagnifier.java
@@ -121,10 +121,8 @@
private static final int STATE_DELEGATING = 1;
private static final int STATE_DETECTING = 2;
- private static final int STATE_SCALING = 3;
- private static final int STATE_VIEWPORT_DRAGGING = 4;
- private static final int STATE_PANNING = 5;
- private static final int STATE_DECIDE_PAN_OR_SCALE = 6;
+ private static final int STATE_VIEWPORT_DRAGGING = 3;
+ private static final int STATE_MAGNIFIED_INTERACTION = 4;
private static final float DEFAULT_MAGNIFICATION_SCALE = 2.0f;
private static final int DEFAULT_SCREEN_MAGNIFICATION_AUTO_UPDATE = 1;
@@ -160,6 +158,7 @@
private EventStreamTransformation mNext;
private int mCurrentState;
+ private int mPreviousState;
private boolean mTranslationEnabledBeforePan;
private PointerCoords[] mTempPointerCoords;
@@ -193,6 +192,7 @@
@Override
public void onMotionEvent(MotionEvent event, int policyFlags) {
+ mGestureDetector.onMotionEvent(event);
switch (mCurrentState) {
case STATE_DELEGATING: {
handleMotionEventStateDelegating(event, policyFlags);
@@ -203,18 +203,15 @@
case STATE_VIEWPORT_DRAGGING: {
mStateViewportDraggingHandler.onMotionEvent(event, policyFlags);
} break;
- case STATE_SCALING:
- case STATE_PANNING:
- case STATE_DECIDE_PAN_OR_SCALE: {
+ case STATE_MAGNIFIED_INTERACTION: {
// Handled by the gesture detector. Since the detector
// needs all touch events to work properly we cannot
- // call it only for these states.
+ // call it only for this state.
} break;
default: {
throw new IllegalStateException("Unknown state: " + mCurrentState);
}
}
- mGestureDetector.onMotionEvent(event);
}
@Override
@@ -326,20 +323,15 @@
case STATE_VIEWPORT_DRAGGING: {
Slog.i(LOG_TAG, "mCurrentState: STATE_VIEWPORT_DRAGGING");
} break;
- case STATE_SCALING: {
- Slog.i(LOG_TAG, "mCurrentState: STATE_SCALING");
- } break;
- case STATE_PANNING: {
- Slog.i(LOG_TAG, "mCurrentState: STATE_PANNING");
- } break;
- case STATE_DECIDE_PAN_OR_SCALE: {
- Slog.i(LOG_TAG, "mCurrentState: STATE_DECIDE_PAN_OR_SCALE");
+ case STATE_MAGNIFIED_INTERACTION: {
+ Slog.i(LOG_TAG, "mCurrentState: STATE_MAGNIFIED_INTERACTION");
} break;
default: {
throw new IllegalArgumentException("Unknown state: " + state);
}
}
}
+ mPreviousState = mCurrentState;
mCurrentState = state;
}
@@ -347,7 +339,7 @@
private static final float MIN_SCALE = 1.3f;
private static final float MAX_SCALE = 5.0f;
- private static final float DETECT_SCALING_THRESHOLD = 0.25f;
+ private static final float DETECT_SCALING_THRESHOLD = 0.30f;
private static final int DETECT_PANNING_THRESHOLD_DIP = 30;
private final float mScaledDetectPanningThreshold;
@@ -366,6 +358,9 @@
private float mScaleFocusX = Float.NaN;
private float mScaleFocusY = Float.NaN;
+ private boolean mScaling;
+ private boolean mPanning;
+
public GestureDetector(Context context) {
final float density = context.getResources().getDisplayMetrics().density;
mScaledDetectPanningThreshold = DETECT_PANNING_THRESHOLD_DIP * density;
@@ -383,10 +378,15 @@
}
if (event.getActionMasked() == MotionEvent.ACTION_UP) {
clear();
- if (mCurrentState == STATE_SCALING) {
- persistScale(mMagnificationController.getScale());
+ final float scale = mMagnificationController.getScale();
+ if (scale != getPersistedScale()) {
+ persistScale(scale);
}
- transitionToState(STATE_DETECTING);
+ if (mPreviousState == STATE_VIEWPORT_DRAGGING) {
+ transitionToState(STATE_VIEWPORT_DRAGGING);
+ } else {
+ transitionToState(STATE_DETECTING);
+ }
}
}
@@ -398,18 +398,20 @@
case STATE_VIEWPORT_DRAGGING: {
return true;
}
- case STATE_DECIDE_PAN_OR_SCALE: {
+ case STATE_MAGNIFIED_INTERACTION: {
mCurrScaleFactor = mScaleGestureDetector.getScaleFactor();
final float scaleDelta = Math.abs(1.0f - mCurrScaleFactor * mPrevScaleFactor);
if (DEBUG_GESTURE_DETECTOR) {
Slog.i(LOG_TAG, "scaleDelta: " + scaleDelta);
}
- if (scaleDelta > DETECT_SCALING_THRESHOLD) {
- performScale(detector, true);
- clear();
- transitionToState(STATE_SCALING);
+ if (!mScaling && scaleDelta > DETECT_SCALING_THRESHOLD) {
+ mScaling = true;
+ clearContextualState();
return true;
}
+ if (mScaling) {
+ performScale(detector);
+ }
mCurrPan = (float) MathUtils.dist(
mScaleGestureDetector.getFocusX(),
mScaleGestureDetector.getFocusY(),
@@ -418,18 +420,14 @@
if (DEBUG_GESTURE_DETECTOR) {
Slog.i(LOG_TAG, "panDelta: " + panDelta);
}
- if (panDelta > mScaledDetectPanningThreshold) {
- performPan(detector, true);
- clear();
- transitionToState(STATE_PANNING);
+ if (!mPanning && panDelta > mScaledDetectPanningThreshold) {
+ mPanning = true;
+ clearContextualState();
return true;
}
- } break;
- case STATE_SCALING: {
- performScale(detector, false);
- } break;
- case STATE_PANNING: {
- performPan(detector, false);
+ if (mPanning) {
+ performPan(detector);
+ }
} break;
}
return false;
@@ -437,32 +435,26 @@
@Override
public boolean onScaleBegin(ScaleGestureDetector detector) {
- switch (mCurrentState) {
- case STATE_DECIDE_PAN_OR_SCALE: {
- mPrevScaleFactor *= mCurrScaleFactor;
- mPrevPan += mCurrPan;
- mPrevFocus.x = mInitialFocus.x = detector.getFocusX();
- mPrevFocus.y = mInitialFocus.y = detector.getFocusY();
- } break;
- case STATE_SCALING: {
- mPrevScaleFactor = 1.0f;
- mCurrScale = Float.NaN;
- } break;
- case STATE_PANNING: {
- mPrevPan += mCurrPan;
- mPrevFocus.x = mInitialFocus.x = detector.getFocusX();
- mPrevFocus.y = mInitialFocus.y = detector.getFocusY();
- } break;
- }
+ mPrevScaleFactor *= mCurrScaleFactor;
+ mCurrScale = Float.NaN;
+ mPrevPan += mCurrPan;
+ mPrevFocus.x = mInitialFocus.x = detector.getFocusX();
+ mPrevFocus.y = mInitialFocus.y = detector.getFocusY();
return true;
}
@Override
public void onScaleEnd(ScaleGestureDetector detector) {
- clear();
+ clearContextualState();
}
public void clear() {
+ clearContextualState();
+ mScaling = false;
+ mPanning = false;
+ }
+
+ private void clearContextualState() {
mCurrScaleFactor = 1.0f;
mPrevScaleFactor = 1.0f;
mPrevPan = 0;
@@ -474,7 +466,7 @@
mScaleFocusY = Float.NaN;
}
- private void performPan(ScaleGestureDetector detector, boolean animate) {
+ private void performPan(ScaleGestureDetector detector) {
if (Float.compare(mPrevFocus.x, Float.NaN) == 0
&& Float.compare(mPrevFocus.y, Float.NaN) == 0) {
mPrevFocus.set(detector.getFocusX(), detector.getFocusY());
@@ -491,11 +483,11 @@
Slog.i(LOG_TAG, "Panned content by scrollX: " + scrollX
+ " scrollY: " + scrollY);
}
- mMagnificationController.setMagnifiedRegionCenter(centerX, centerY, animate);
+ mMagnificationController.setMagnifiedRegionCenter(centerX, centerY, false);
mPrevFocus.set(detector.getFocusX(), detector.getFocusY());
}
- private void performScale(ScaleGestureDetector detector, boolean animate) {
+ private void performScale(ScaleGestureDetector detector) {
if (Float.compare(mCurrScale, Float.NaN) == 0) {
mCurrScale = mMagnificationController.getScale();
return;
@@ -513,7 +505,7 @@
mScaleFocusY = detector.getFocusY();
}
mMagnificationController.setScale(normalizedNewScale, mScaleFocusX,
- mScaleFocusY, animate);
+ mScaleFocusY, false);
}
}
@@ -528,7 +520,7 @@
}
case MotionEvent.ACTION_POINTER_DOWN: {
clear();
- transitionToState(STATE_SCALING);
+ transitionToState(STATE_MAGNIFIED_INTERACTION);
} break;
case MotionEvent.ACTION_MOVE: {
if (event.getPointerCount() != 1) {
@@ -632,7 +624,7 @@
} break;
case MotionEvent.ACTION_POINTER_DOWN: {
if (mMagnificationController.isMagnifying()) {
- transitionToState(STATE_DECIDE_PAN_OR_SCALE);
+ transitionToState(STATE_MAGNIFIED_INTERACTION);
clear();
} else {
transitionToDelegatingStateAndClear();
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/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;
}