summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/current.txt5
-rw-r--r--core/java/android/view/ViewConfiguration.java40
-rw-r--r--core/java/android/webkit/WebView.java2
-rw-r--r--core/res/res/values/public.xml5
-rw-r--r--core/tests/coretests/Android.mk2
-rw-r--r--core/tests/coretests/src/android/net/http/AbstractProxyTest.java8
-rw-r--r--core/tests/coretests/src/android/net/http/CookiesTest.java6
-rw-r--r--core/tests/coretests/src/android/net/http/DefaultHttpClientTest.java12
-rw-r--r--include/ui/Input.h5
-rw-r--r--libs/ui/Input.cpp9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java16
-rw-r--r--services/input/InputReader.cpp418
-rw-r--r--services/input/InputReader.h21
-rw-r--r--services/input/PointerController.cpp8
-rw-r--r--services/input/PointerController.h39
-rw-r--r--services/input/tests/InputReader_test.cpp4
-rw-r--r--services/java/com/android/server/ConnectivityService.java6
-rw-r--r--services/java/com/android/server/WifiService.java14
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java1
-rw-r--r--services/java/com/android/server/connectivity/Tethering.java7
-rw-r--r--services/java/com/android/server/wm/InputManager.java14
-rw-r--r--services/java/com/android/server/wm/WindowManagerService.java43
-rw-r--r--services/jni/com_android_server_InputManager.cpp34
-rw-r--r--telephony/java/com/android/internal/telephony/BaseCommands.java6
-rw-r--r--telephony/java/com/android/internal/telephony/RIL.java24
-rw-r--r--tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java4
-rw-r--r--tools/layoutlib/bridge/src/android/os/HandlerThread_Delegate.java80
-rw-r--r--tools/layoutlib/bridge/src/android/view/LayoutInflater_Delegate.java129
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java2
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java114
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeInflater.java4
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeResources.java9
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeTypedArray.java93
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java2
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java5
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java5
-rw-r--r--tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java2
-rw-r--r--tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java2
38 files changed, 681 insertions, 519 deletions
diff --git a/api/current.txt b/api/current.txt
index 073bf91..4a35785 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -1516,12 +1516,13 @@ package android {
field public static final int Theme_Holo_Light_Dialog_NoActionBar = 16973941; // 0x1030075
field public static final int Theme_Holo_Light_Dialog_NoActionBar_MinWidth = 16973942; // 0x1030076
field public static final int Theme_Holo_Light_NoActionBar = 16974064; // 0x10300f0
+ field public static final int Theme_Holo_Light_NoActionBar_Fullscreen = 16974065; // 0x10300f1
field public static final int Theme_Holo_Light_Panel = 16973948; // 0x103007c
- field public static final int Theme_Holo_Light_SplitActionBarWhenNarrow = 16974067; // 0x10300f3
+ field public static final int Theme_Holo_Light_SplitActionBarWhenNarrow = 16974068; // 0x10300f4
field public static final int Theme_Holo_NoActionBar = 16973932; // 0x103006c
field public static final int Theme_Holo_NoActionBar_Fullscreen = 16973933; // 0x103006d
field public static final int Theme_Holo_Panel = 16973947; // 0x103007b
- field public static final int Theme_Holo_SplitActionBarWhenNarrow = 16974066; // 0x10300f2
+ field public static final int Theme_Holo_SplitActionBarWhenNarrow = 16974067; // 0x10300f3
field public static final int Theme_Holo_Wallpaper = 16973949; // 0x103007d
field public static final int Theme_Holo_Wallpaper_NoTitleBar = 16973950; // 0x103007e
field public static final int Theme_InputMethod = 16973908; // 0x1030054
diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java
index 36bb046..5919150 100644
--- a/core/java/android/view/ViewConfiguration.java
+++ b/core/java/android/view/ViewConfiguration.java
@@ -110,7 +110,21 @@ public class ViewConfiguration {
* double-tap.
*/
private static final int DOUBLE_TAP_TIMEOUT = 300;
-
+
+ /**
+ * Defines the maximum duration in milliseconds between a touch pad
+ * touch and release for a given touch to be considered a tap (click) as
+ * opposed to a hover movement gesture.
+ */
+ private static final int HOVER_TAP_TIMEOUT = 150;
+
+ /**
+ * Defines the maximum distance in pixels that a touch pad touch can move
+ * before being released for it to be considered a tap (click) as opposed
+ * to a hover movement gesture.
+ */
+ private static final int HOVER_TAP_SLOP = 20;
+
/**
* Defines the duration in milliseconds we want to display zoom controls in response
* to a user panning within an application.
@@ -369,7 +383,7 @@ public class ViewConfiguration {
public static int getTapTimeout() {
return TAP_TIMEOUT;
}
-
+
/**
* @return the duration in milliseconds we will wait to see if a touch event
* is a jump tap. If the user does not move within this interval, it is
@@ -387,7 +401,27 @@ public class ViewConfiguration {
public static int getDoubleTapTimeout() {
return DOUBLE_TAP_TIMEOUT;
}
-
+
+ /**
+ * @return the maximum duration in milliseconds between a touch pad
+ * touch and release for a given touch to be considered a tap (click) as
+ * opposed to a hover movement gesture.
+ * @hide
+ */
+ public static int getHoverTapTimeout() {
+ return HOVER_TAP_TIMEOUT;
+ }
+
+ /**
+ * @return the maximum distance in pixels that a touch pad touch can move
+ * before being released for it to be considered a tap (click) as opposed
+ * to a hover movement gesture.
+ * @hide
+ */
+ public static int getHoverTapSlop() {
+ return HOVER_TAP_SLOP;
+ }
+
/**
* @return Inset in pixels to look for touchable content when the user touches the edge of the
* screen
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index a68ca60..4aad022 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -6461,7 +6461,7 @@ public class WebView extends AbsoluteLayout
if (hscroll != 0 || vscroll != 0) {
final int vdelta = (int) (vscroll * getVerticalScrollFactor());
final int hdelta = (int) (hscroll * getHorizontalScrollFactor());
- if (pinScrollBy(hdelta, vdelta, true, 0)) {
+ if (pinScrollBy(hdelta, vdelta, false, 0)) {
return true;
}
}
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index f2bd7cb..55312e3 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1657,6 +1657,9 @@
<public type="attr" name="compatibleWidthLimitDp" />
<public type="attr" name="largestWidthLimitDp" />
+ <public type="style" name="Theme.Holo.Light.NoActionBar" />
+ <public type="style" name="Theme.Holo.Light.NoActionBar.Fullscreen" />
+
<!-- ===============================================================
Resources added in version 13 of the platform (Ice Cream Sandwich)
=============================================================== -->
@@ -1666,7 +1669,6 @@
<public type="attr" name="state_drag_hovered" />
<public type="attr" name="stopWithTask" />
- <public type="style" name="Theme.Holo.Light.NoActionBar" />
<public type="style" name="TextAppearance.SuggestionHighlight" />
<public type="style" name="Theme.Holo.SplitActionBarWhenNarrow" />
<public type="style" name="Theme.Holo.Light.SplitActionBarWhenNarrow" />
@@ -1704,4 +1706,5 @@
<public type="attr" name="notificationTimeout" />
<public type="attr" name="accessibilityFlags" />
<public type="attr" name="canRetrieveWindowContent" />
+
</resources>
diff --git a/core/tests/coretests/Android.mk b/core/tests/coretests/Android.mk
index b02d904..00f47fa 100644
--- a/core/tests/coretests/Android.mk
+++ b/core/tests/coretests/Android.mk
@@ -12,7 +12,7 @@ LOCAL_SRC_FILES := \
$(call all-java-files-under, EnabledTestApp/src)
LOCAL_DX_FLAGS := --core-library
-LOCAL_STATIC_JAVA_LIBRARIES := core-tests android-common frameworks-core-util-lib
+LOCAL_STATIC_JAVA_LIBRARIES := core-tests android-common frameworks-core-util-lib mockwebserver
LOCAL_JAVA_LIBRARIES := android.test.runner
LOCAL_PACKAGE_NAME := FrameworksCoreTests
diff --git a/core/tests/coretests/src/android/net/http/AbstractProxyTest.java b/core/tests/coretests/src/android/net/http/AbstractProxyTest.java
index ee89414..ee4ce95 100644
--- a/core/tests/coretests/src/android/net/http/AbstractProxyTest.java
+++ b/core/tests/coretests/src/android/net/http/AbstractProxyTest.java
@@ -16,6 +16,10 @@
package android.net.http;
+import com.google.mockwebserver.MockResponse;
+import com.google.mockwebserver.MockWebServer;
+import com.google.mockwebserver.RecordedRequest;
+import com.google.mockwebserver.SocketPolicy;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
@@ -33,10 +37,6 @@ import org.apache.http.conn.params.ConnRouteParams;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.ssl.AllowAllHostnameVerifier;
import org.apache.http.conn.ssl.SSLSocketFactory;
-import tests.http.MockResponse;
-import tests.http.MockWebServer;
-import tests.http.RecordedRequest;
-import tests.http.SocketPolicy;
public abstract class AbstractProxyTest extends TestCase {
diff --git a/core/tests/coretests/src/android/net/http/CookiesTest.java b/core/tests/coretests/src/android/net/http/CookiesTest.java
index e736bc9..29e590f 100644
--- a/core/tests/coretests/src/android/net/http/CookiesTest.java
+++ b/core/tests/coretests/src/android/net/http/CookiesTest.java
@@ -16,6 +16,9 @@
package android.net.http;
+import com.google.mockwebserver.MockResponse;
+import com.google.mockwebserver.MockWebServer;
+import com.google.mockwebserver.RecordedRequest;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URISyntaxException;
@@ -30,9 +33,6 @@ import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.params.ConnRoutePNames;
import org.apache.http.impl.client.DefaultHttpClient;
-import tests.http.MockResponse;
-import tests.http.MockWebServer;
-import tests.http.RecordedRequest;
public final class CookiesTest extends TestCase {
diff --git a/core/tests/coretests/src/android/net/http/DefaultHttpClientTest.java b/core/tests/coretests/src/android/net/http/DefaultHttpClientTest.java
index ad3ec3d..da77298 100644
--- a/core/tests/coretests/src/android/net/http/DefaultHttpClientTest.java
+++ b/core/tests/coretests/src/android/net/http/DefaultHttpClientTest.java
@@ -16,6 +16,12 @@
package android.net.http;
+import com.google.mockwebserver.MockResponse;
+import com.google.mockwebserver.MockWebServer;
+import com.google.mockwebserver.SocketPolicy;
+import static com.google.mockwebserver.SocketPolicy.DISCONNECT_AT_END;
+import static com.google.mockwebserver.SocketPolicy.SHUTDOWN_INPUT_AT_END;
+import static com.google.mockwebserver.SocketPolicy.SHUTDOWN_OUTPUT_AT_END;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
@@ -24,12 +30,6 @@ import junit.framework.TestCase;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
-import tests.http.MockResponse;
-import tests.http.MockWebServer;
-import tests.http.SocketPolicy;
-import static tests.http.SocketPolicy.DISCONNECT_AT_END;
-import static tests.http.SocketPolicy.SHUTDOWN_INPUT_AT_END;
-import static tests.http.SocketPolicy.SHUTDOWN_OUTPUT_AT_END;
public final class DefaultHttpClientTest extends TestCase {
diff --git a/include/ui/Input.h b/include/ui/Input.h
index 3b5aba4..c9f694a 100644
--- a/include/ui/Input.h
+++ b/include/ui/Input.h
@@ -655,11 +655,6 @@ private:
// Oldest sample to consider when calculating the velocity.
static const nsecs_t MAX_AGE = 200 * 1000000; // 200 ms
- // When the total duration of the window of samples being averaged is less
- // than the window size, the resulting velocity is scaled to reduce the impact
- // of overestimation in short traces.
- static const nsecs_t MIN_WINDOW = 100 * 1000000; // 100 ms
-
// The minimum duration between samples when estimating velocity.
static const nsecs_t MIN_DURATION = 10 * 1000000; // 10 ms
diff --git a/libs/ui/Input.cpp b/libs/ui/Input.cpp
index e95dbe4..0af7f80 100644
--- a/libs/ui/Input.cpp
+++ b/libs/ui/Input.cpp
@@ -700,7 +700,6 @@ bool MotionEvent::isTouchEvent(int32_t source, int32_t action) {
const uint32_t VelocityTracker::HISTORY_SIZE;
const nsecs_t VelocityTracker::MAX_AGE;
-const nsecs_t VelocityTracker::MIN_WINDOW;
const nsecs_t VelocityTracker::MIN_DURATION;
VelocityTracker::VelocityTracker() {
@@ -891,14 +890,6 @@ bool VelocityTracker::getVelocity(uint32_t id, float* outVx, float* outVy) const
// Make sure we used at least one sample.
if (samplesUsed != 0) {
- // Scale the velocity linearly if the window of samples is small.
- nsecs_t totalDuration = newestMovement.eventTime - oldestMovement.eventTime;
- if (totalDuration < MIN_WINDOW) {
- float scale = float(totalDuration) / float(MIN_WINDOW);
- accumVx *= scale;
- accumVy *= scale;
- }
-
*outVx = accumVx;
*outVy = accumVy;
return true;
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 70a78df..3175a99 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
@@ -446,12 +446,14 @@ public class NetworkController extends BroadcastReceiver {
}
boolean isCdmaEri() {
- final int iconIndex = mServiceState.getCdmaEriIconIndex();
- if (iconIndex != EriInfo.ROAMING_INDICATOR_OFF) {
- final int iconMode = mServiceState.getCdmaEriIconMode();
- if (iconMode == EriInfo.ROAMING_ICON_MODE_NORMAL
- || iconMode == EriInfo.ROAMING_ICON_MODE_FLASH) {
- return true;
+ if (mServiceState != null) {
+ final int iconIndex = mServiceState.getCdmaEriIconIndex();
+ if (iconIndex != EriInfo.ROAMING_INDICATOR_OFF) {
+ final int iconMode = mServiceState.getCdmaEriIconMode();
+ if (iconMode == EriInfo.ROAMING_ICON_MODE_NORMAL
+ || iconMode == EriInfo.ROAMING_ICON_MODE_FLASH) {
+ return true;
+ }
}
}
return false;
@@ -854,7 +856,7 @@ public class NetworkController extends BroadcastReceiver {
pw.print(" mDataActivity=");
pw.println(mDataActivity);
pw.print(" mServiceState=");
- pw.println(mServiceState.toString());
+ pw.println(mServiceState);
pw.print(" mNetworkName=");
pw.println(mNetworkName);
pw.print(" mNetworkNameDefault=");
diff --git a/services/input/InputReader.cpp b/services/input/InputReader.cpp
index c42e3ab..09b24a8 100644
--- a/services/input/InputReader.cpp
+++ b/services/input/InputReader.cpp
@@ -200,23 +200,6 @@ static int32_t calculateEdgeFlagsUsingPointerBounds(
return edgeFlags;
}
-static void clampPositionUsingPointerBounds(
- const sp<PointerControllerInterface>& pointerController, float* x, float* y) {
- float minX, minY, maxX, maxY;
- if (pointerController->getBounds(&minX, &minY, &maxX, &maxY)) {
- if (*x < minX) {
- *x = minX;
- } else if (*x > maxX) {
- *x = maxX;
- }
- if (*y < minY) {
- *y = minY;
- } else if (*y > maxY) {
- *y = maxY;
- }
- }
-}
-
static float calculateCommonVector(float a, float b) {
if (a > 0 && b > 0) {
return a < b ? a : b;
@@ -787,8 +770,8 @@ void InputReader::dump(String8& dump) {
mConfig.pointerGestureTapSlop);
dump.appendFormat(INDENT3 "MultitouchSettleInterval: %0.1fms\n",
mConfig.pointerGestureMultitouchSettleInterval * 0.000001f);
- dump.appendFormat(INDENT3 "MultitouchMinSpeed: %0.1fpx/s\n",
- mConfig.pointerGestureMultitouchMinSpeed);
+ dump.appendFormat(INDENT3 "MultitouchMinDistance: %0.1fpx\n",
+ mConfig.pointerGestureMultitouchMinDistance);
dump.appendFormat(INDENT3 "SwipeTransitionAngleCosine: %0.1f\n",
mConfig.pointerGestureSwipeTransitionAngleCosine);
dump.appendFormat(INDENT3 "SwipeMaxWidthRatio: %0.1f\n",
@@ -3509,11 +3492,18 @@ void TouchInputMapper::dispatchPointerGestures(nsecs_t when, uint32_t policyFlag
cancelPreviousGesture = false;
}
- // Switch pointer presentation.
- mPointerController->setPresentation(
- mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS
- ? PointerControllerInterface::PRESENTATION_SPOT
- : PointerControllerInterface::PRESENTATION_POINTER);
+ // Update the pointer presentation and spots.
+ if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) {
+ mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_SPOT);
+ if (finishPreviousGesture || cancelPreviousGesture) {
+ mPointerController->clearSpots();
+ }
+ mPointerController->setSpots(mPointerGesture.currentGestureCoords,
+ mPointerGesture.currentGestureIdToIndex,
+ mPointerGesture.currentGestureIdBits);
+ } else {
+ mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_POINTER);
+ }
// Show or hide the pointer if needed.
switch (mPointerGesture.currentGestureMode) {
@@ -3712,12 +3702,6 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
mPointerGesture.currentGestureIdBits.clear();
mPointerGesture.pointerVelocityControl.reset();
-
- if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) {
- mPointerGesture.spotGesture = PointerControllerInterface::SPOT_GESTURE_NEUTRAL;
- mPointerGesture.spotIdBits.clear();
- moveSpotsLocked();
- }
return true;
}
}
@@ -3798,22 +3782,18 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
if (isQuietTime) {
// Case 1: Quiet time. (QUIET)
#if DEBUG_GESTURES
- LOGD("Gestures: QUIET for next %0.3fms",
- (mPointerGesture.quietTime + QUIET_INTERVAL - when) * 0.000001f);
+ LOGD("Gestures: QUIET for next %0.3fms", (mPointerGesture.quietTime
+ + mConfig->pointerGestureQuietInterval - when) * 0.000001f);
#endif
- *outFinishPreviousGesture = true;
+ if (mPointerGesture.lastGestureMode != PointerGesture::QUIET) {
+ *outFinishPreviousGesture = true;
+ }
mPointerGesture.activeGestureId = -1;
mPointerGesture.currentGestureMode = PointerGesture::QUIET;
mPointerGesture.currentGestureIdBits.clear();
mPointerGesture.pointerVelocityControl.reset();
-
- if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) {
- mPointerGesture.spotGesture = PointerControllerInterface::SPOT_GESTURE_NEUTRAL;
- mPointerGesture.spotIdBits.clear();
- moveSpotsLocked();
- }
} else if (isPointerDown(mCurrentTouch.buttonState)) {
// Case 2: Button is pressed. (BUTTON_CLICK_OR_DRAG)
// The pointer follows the active touch point.
@@ -3899,32 +3879,11 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, x);
mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, y);
mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 1.0f);
-
- if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) {
- if (activeTouchId >= 0) {
- // Collapse all spots into one point at the pointer location.
- mPointerGesture.spotGesture = PointerControllerInterface::SPOT_GESTURE_BUTTON_DRAG;
- mPointerGesture.spotIdBits.clear();
- for (uint32_t i = 0; i < mCurrentTouch.pointerCount; i++) {
- uint32_t id = mCurrentTouch.pointers[i].id;
- mPointerGesture.spotIdBits.markBit(id);
- mPointerGesture.spotIdToIndex[id] = i;
- mPointerGesture.spotCoords[i] = mPointerGesture.currentGestureCoords[0];
- }
- } else {
- // No fingers. Generate a spot at the pointer location so the
- // anchor appears to be pressed.
- mPointerGesture.spotGesture = PointerControllerInterface::SPOT_GESTURE_BUTTON_CLICK;
- mPointerGesture.spotIdBits.clear();
- mPointerGesture.spotIdBits.markBit(0);
- mPointerGesture.spotIdToIndex[0] = 0;
- mPointerGesture.spotCoords[0] = mPointerGesture.currentGestureCoords[0];
- }
- moveSpotsLocked();
- }
} else if (mCurrentTouch.pointerCount == 0) {
// Case 3. No fingers down and button is not pressed. (NEUTRAL)
- *outFinishPreviousGesture = true;
+ if (mPointerGesture.lastGestureMode != PointerGesture::NEUTRAL) {
+ *outFinishPreviousGesture = true;
+ }
// Watch for taps coming out of HOVER or TAP_DRAG mode.
// Checking for taps after TAP_DRAG allows us to detect double-taps.
@@ -3965,15 +3924,6 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
mPointerGesture.currentGestureCoords[0].setAxisValue(
AMOTION_EVENT_AXIS_PRESSURE, 1.0f);
- if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) {
- mPointerGesture.spotGesture = PointerControllerInterface::SPOT_GESTURE_TAP;
- mPointerGesture.spotIdBits.clear();
- mPointerGesture.spotIdBits.markBit(lastActiveTouchId);
- mPointerGesture.spotIdToIndex[lastActiveTouchId] = 0;
- mPointerGesture.spotCoords[0] = mPointerGesture.currentGestureCoords[0];
- moveSpotsLocked();
- }
-
tapped = true;
} else {
#if DEBUG_GESTURES
@@ -3999,12 +3949,6 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
mPointerGesture.activeGestureId = -1;
mPointerGesture.currentGestureMode = PointerGesture::NEUTRAL;
mPointerGesture.currentGestureIdBits.clear();
-
- if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) {
- mPointerGesture.spotGesture = PointerControllerInterface::SPOT_GESTURE_NEUTRAL;
- mPointerGesture.spotIdBits.clear();
- moveSpotsLocked();
- }
}
} else if (mCurrentTouch.pointerCount == 1) {
// Case 4. Exactly one finger down, button is not pressed. (HOVER or TAP_DRAG)
@@ -4067,7 +4011,9 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
#if DEBUG_GESTURES
LOGD("Gestures: HOVER");
#endif
- *outFinishPreviousGesture = true;
+ if (mPointerGesture.lastGestureMode != PointerGesture::HOVER) {
+ *outFinishPreviousGesture = true;
+ }
mPointerGesture.activeGestureId = 0;
down = false;
}
@@ -4094,16 +4040,6 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
mPointerGesture.tapX = x;
mPointerGesture.tapY = y;
}
-
- if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) {
- mPointerGesture.spotGesture = down ? PointerControllerInterface::SPOT_GESTURE_DRAG
- : PointerControllerInterface::SPOT_GESTURE_HOVER;
- mPointerGesture.spotIdBits.clear();
- mPointerGesture.spotIdBits.markBit(activeTouchId);
- mPointerGesture.spotIdToIndex[activeTouchId] = 0;
- mPointerGesture.spotCoords[0] = mPointerGesture.currentGestureCoords[0];
- moveSpotsLocked();
- }
} else {
// Case 5. At least two fingers down, button is not pressed. (PRESS, SWIPE or FREEFORM)
// We need to provide feedback for each finger that goes down so we cannot wait
@@ -4131,8 +4067,8 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
// Reset the gesture.
#if DEBUG_GESTURES
LOGD("Gestures: Resetting gesture since additional pointers went down for MULTITOUCH, "
- "settle time remaining %0.3fms",
- (mPointerGesture.firstTouchTime + MULTITOUCH_SETTLE_INTERVAL - when)
+ "settle time remaining %0.3fms", (mPointerGesture.firstTouchTime
+ + mConfig->pointerGestureMultitouchSettleInterval - when)
* 0.000001f);
#endif
*outCancelPreviousGesture = true;
@@ -4147,101 +4083,134 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
mPointerGesture.referenceIdBits.clear();
mPointerGesture.pointerVelocityControl.reset();
- if (settled && mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS
- && mLastTouch.idBits.hasBit(mPointerGesture.activeTouchId)) {
- // The spot is already visible and has settled, use it as the reference point
- // for the gesture. Other spots will be positioned relative to this one.
+ // Use the centroid and pointer location as the reference points for the gesture.
#if DEBUG_GESTURES
- LOGD("Gestures: Using active spot as reference for MULTITOUCH, "
- "settle time expired %0.3fms ago",
- (when - mPointerGesture.firstTouchTime - MULTITOUCH_SETTLE_INTERVAL)
- * 0.000001f);
+ LOGD("Gestures: Using centroid as reference for MULTITOUCH, "
+ "settle time remaining %0.3fms", (mPointerGesture.firstTouchTime
+ + mConfig->pointerGestureMultitouchSettleInterval - when)
+ * 0.000001f);
#endif
- const PointerData& d = mLastTouch.pointers[mLastTouch.idToIndex[
- mPointerGesture.activeTouchId]];
- mPointerGesture.referenceTouchX = d.x;
- mPointerGesture.referenceTouchY = d.y;
- const PointerCoords& c = mPointerGesture.spotCoords[mPointerGesture.spotIdToIndex[
- mPointerGesture.activeTouchId]];
- mPointerGesture.referenceGestureX = c.getAxisValue(AMOTION_EVENT_AXIS_X);
- mPointerGesture.referenceGestureY = c.getAxisValue(AMOTION_EVENT_AXIS_Y);
+ mCurrentTouch.getCentroid(&mPointerGesture.referenceTouchX,
+ &mPointerGesture.referenceTouchY);
+ mPointerController->getPosition(&mPointerGesture.referenceGestureX,
+ &mPointerGesture.referenceGestureY);
+ }
+
+ // Clear the reference deltas for fingers not yet included in the reference calculation.
+ for (BitSet32 idBits(mCurrentTouch.idBits.value & ~mPointerGesture.referenceIdBits.value);
+ !idBits.isEmpty(); ) {
+ uint32_t id = idBits.firstMarkedBit();
+ idBits.clearBit(id);
+
+ mPointerGesture.referenceDeltas[id].dx = 0;
+ mPointerGesture.referenceDeltas[id].dy = 0;
+ }
+ mPointerGesture.referenceIdBits = mCurrentTouch.idBits;
+
+ // Add delta for all fingers and calculate a common movement delta.
+ float commonDeltaX = 0, commonDeltaY = 0;
+ BitSet32 commonIdBits(mLastTouch.idBits.value & mCurrentTouch.idBits.value);
+ for (BitSet32 idBits(commonIdBits); !idBits.isEmpty(); ) {
+ bool first = (idBits == commonIdBits);
+ uint32_t id = idBits.firstMarkedBit();
+ idBits.clearBit(id);
+
+ const PointerData& cpd = mCurrentTouch.pointers[mCurrentTouch.idToIndex[id]];
+ const PointerData& lpd = mLastTouch.pointers[mLastTouch.idToIndex[id]];
+ PointerGesture::Delta& delta = mPointerGesture.referenceDeltas[id];
+ delta.dx += cpd.x - lpd.x;
+ delta.dy += cpd.y - lpd.y;
+
+ if (first) {
+ commonDeltaX = delta.dx;
+ commonDeltaY = delta.dy;
} else {
- // Use the centroid and pointer location as the reference points for the gesture.
-#if DEBUG_GESTURES
- LOGD("Gestures: Using centroid as reference for MULTITOUCH, "
- "settle time remaining %0.3fms",
- (mPointerGesture.firstTouchTime + MULTITOUCH_SETTLE_INTERVAL - when)
- * 0.000001f);
-#endif
- mCurrentTouch.getCentroid(&mPointerGesture.referenceTouchX,
- &mPointerGesture.referenceTouchY);
- mPointerController->getPosition(&mPointerGesture.referenceGestureX,
- &mPointerGesture.referenceGestureY);
+ commonDeltaX = calculateCommonVector(commonDeltaX, delta.dx);
+ commonDeltaY = calculateCommonVector(commonDeltaY, delta.dy);
}
}
+ // Consider transitions from PRESS to SWIPE or MULTITOUCH.
if (mPointerGesture.currentGestureMode == PointerGesture::PRESS) {
- float d;
- if (mCurrentTouch.pointerCount > 2) {
- // There are more than two pointers, switch to FREEFORM.
+ float dist[MAX_POINTER_ID + 1];
+ int32_t distOverThreshold = 0;
+ for (BitSet32 idBits(mPointerGesture.referenceIdBits); !idBits.isEmpty(); ) {
+ uint32_t id = idBits.firstMarkedBit();
+ idBits.clearBit(id);
+
+ PointerGesture::Delta& delta = mPointerGesture.referenceDeltas[id];
+ dist[id] = hypotf(delta.dx * mLocked.pointerGestureXZoomScale,
+ delta.dy * mLocked.pointerGestureYZoomScale);
+ if (dist[id] > mConfig->pointerGestureMultitouchMinDistance) {
+ distOverThreshold += 1;
+ }
+ }
+
+ // Only transition when at least two pointers have moved further than
+ // the minimum distance threshold.
+ if (distOverThreshold >= 2) {
+ float d;
+ if (mCurrentTouch.pointerCount > 2) {
+ // There are more than two pointers, switch to FREEFORM.
#if DEBUG_GESTURES
- LOGD("Gestures: PRESS transitioned to FREEFORM, number of pointers %d > 2",
- mCurrentTouch.pointerCount);
+ LOGD("Gestures: PRESS transitioned to FREEFORM, number of pointers %d > 2",
+ mCurrentTouch.pointerCount);
#endif
- *outCancelPreviousGesture = true;
- mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
- } else if (((d = distance(
- mCurrentTouch.pointers[0].x, mCurrentTouch.pointers[0].y,
- mCurrentTouch.pointers[1].x, mCurrentTouch.pointers[1].y))
- > mLocked.pointerGestureMaxSwipeWidth)) {
- // There are two pointers but they are too far apart, switch to FREEFORM.
+ *outCancelPreviousGesture = true;
+ mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
+ } else if (((d = distance(
+ mCurrentTouch.pointers[0].x, mCurrentTouch.pointers[0].y,
+ mCurrentTouch.pointers[1].x, mCurrentTouch.pointers[1].y))
+ > mLocked.pointerGestureMaxSwipeWidth)) {
+ // There are two pointers but they are too far apart for a SWIPE,
+ // switch to FREEFORM.
#if DEBUG_GESTURES
- LOGD("Gestures: PRESS transitioned to FREEFORM, distance %0.3f > %0.3f",
- d, mLocked.pointerGestureMaxSwipeWidth);
+ LOGD("Gestures: PRESS transitioned to FREEFORM, distance %0.3f > %0.3f",
+ d, mLocked.pointerGestureMaxSwipeWidth);
#endif
- *outCancelPreviousGesture = true;
- mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
- } else {
- // There are two pointers. Wait for both pointers to start moving
- // before deciding whether this is a SWIPE or FREEFORM gesture.
- uint32_t id1 = mCurrentTouch.pointers[0].id;
- uint32_t id2 = mCurrentTouch.pointers[1].id;
-
- float vx1, vy1, vx2, vy2;
- mPointerGesture.velocityTracker.getVelocity(id1, &vx1, &vy1);
- mPointerGesture.velocityTracker.getVelocity(id2, &vx2, &vy2);
-
- float speed1 = hypotf(vx1, vy1);
- float speed2 = hypotf(vx2, vy2);
- if (speed1 >= mConfig->pointerGestureMultitouchMinSpeed
- && speed2 >= mConfig->pointerGestureMultitouchMinSpeed) {
- // Calculate the dot product of the velocity vectors.
- // When the vectors are oriented in approximately the same direction,
- // the angle betweeen them is near zero and the cosine of the angle
- // approches 1.0. Recall that dot(v1, v2) = cos(angle) * mag(v1) * mag(v2).
- float dot = vx1 * vx2 + vy1 * vy2;
- float cosine = dot / (speed1 * speed2); // denominator always > 0
- if (cosine >= mConfig->pointerGestureSwipeTransitionAngleCosine) {
- // Pointers are moving in the same direction. Switch to SWIPE.
+ *outCancelPreviousGesture = true;
+ mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
+ } else {
+ // There are two pointers. Wait for both pointers to start moving
+ // before deciding whether this is a SWIPE or FREEFORM gesture.
+ uint32_t id1 = mCurrentTouch.pointers[0].id;
+ uint32_t id2 = mCurrentTouch.pointers[1].id;
+ float dist1 = dist[id1];
+ float dist2 = dist[id2];
+ if (dist1 >= mConfig->pointerGestureMultitouchMinDistance
+ && dist2 >= mConfig->pointerGestureMultitouchMinDistance) {
+ // Calculate the dot product of the displacement vectors.
+ // When the vectors are oriented in approximately the same direction,
+ // the angle betweeen them is near zero and the cosine of the angle
+ // approches 1.0. Recall that dot(v1, v2) = cos(angle) * mag(v1) * mag(v2).
+ PointerGesture::Delta& delta1 = mPointerGesture.referenceDeltas[id1];
+ PointerGesture::Delta& delta2 = mPointerGesture.referenceDeltas[id2];
+ float dot = delta1.dx * delta2.dx + delta1.dy * delta2.dy;
+ float cosine = dot / (dist1 * dist2); // denominator always > 0
+ if (cosine >= mConfig->pointerGestureSwipeTransitionAngleCosine) {
+ // Pointers are moving in the same direction. Switch to SWIPE.
#if DEBUG_GESTURES
- LOGD("Gestures: PRESS transitioned to SWIPE, "
- "speed1 %0.3f >= %0.3f, speed2 %0.3f >= %0.3f, "
- "cosine %0.3f >= %0.3f",
- speed1, MULTITOUCH_MIN_SPEED, speed2, MULTITOUCH_MIN_SPEED,
- cosine, SWIPE_TRANSITION_ANGLE_COSINE);
+ LOGD("Gestures: PRESS transitioned to SWIPE, "
+ "dist1 %0.3f >= %0.3f, dist2 %0.3f >= %0.3f, "
+ "cosine %0.3f >= %0.3f",
+ dist1, mConfig->pointerGestureMultitouchMinDistance,
+ dist2, mConfig->pointerGestureMultitouchMinDistance,
+ cosine, mConfig->pointerGestureSwipeTransitionAngleCosine);
#endif
- mPointerGesture.currentGestureMode = PointerGesture::SWIPE;
- } else {
- // Pointers are moving in different directions. Switch to FREEFORM.
+ mPointerGesture.currentGestureMode = PointerGesture::SWIPE;
+ } else {
+ // Pointers are moving in different directions. Switch to FREEFORM.
#if DEBUG_GESTURES
- LOGD("Gestures: PRESS transitioned to FREEFORM, "
- "speed1 %0.3f >= %0.3f, speed2 %0.3f >= %0.3f, "
- "cosine %0.3f < %0.3f",
- speed1, MULTITOUCH_MIN_SPEED, speed2, MULTITOUCH_MIN_SPEED,
- cosine, SWIPE_TRANSITION_ANGLE_COSINE);
+ LOGD("Gestures: PRESS transitioned to FREEFORM, "
+ "dist1 %0.3f >= %0.3f, dist2 %0.3f >= %0.3f, "
+ "cosine %0.3f < %0.3f",
+ dist1, mConfig->pointerGestureMultitouchMinDistance,
+ dist2, mConfig->pointerGestureMultitouchMinDistance,
+ cosine, mConfig->pointerGestureSwipeTransitionAngleCosine);
#endif
- *outCancelPreviousGesture = true;
- mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
+ *outCancelPreviousGesture = true;
+ mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
+ }
}
}
}
@@ -4258,67 +4227,28 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
}
}
- // Clear the reference deltas for fingers not yet included in the reference calculation.
- for (BitSet32 idBits(mCurrentTouch.idBits.value & ~mPointerGesture.referenceIdBits.value);
- !idBits.isEmpty(); ) {
- uint32_t id = idBits.firstMarkedBit();
- idBits.clearBit(id);
-
- mPointerGesture.referenceDeltas[id].dx = 0;
- mPointerGesture.referenceDeltas[id].dy = 0;
- }
- mPointerGesture.referenceIdBits = mCurrentTouch.idBits;
-
- // Move the reference points based on the overall group motion of the fingers.
- // The objective is to calculate a vector delta that is common to the movement
- // of all fingers.
- BitSet32 commonIdBits(mLastTouch.idBits.value & mCurrentTouch.idBits.value);
- if (!commonIdBits.isEmpty()) {
- float commonDeltaX = 0, commonDeltaY = 0;
- for (BitSet32 idBits(commonIdBits); !idBits.isEmpty(); ) {
- bool first = (idBits == commonIdBits);
+ // Move the reference points based on the overall group motion of the fingers
+ // except in PRESS mode while waiting for a transition to occur.
+ if (mPointerGesture.currentGestureMode != PointerGesture::PRESS
+ && (commonDeltaX || commonDeltaY)) {
+ for (BitSet32 idBits(mPointerGesture.referenceIdBits); !idBits.isEmpty(); ) {
uint32_t id = idBits.firstMarkedBit();
idBits.clearBit(id);
- const PointerData& cpd = mCurrentTouch.pointers[mCurrentTouch.idToIndex[id]];
- const PointerData& lpd = mLastTouch.pointers[mLastTouch.idToIndex[id]];
PointerGesture::Delta& delta = mPointerGesture.referenceDeltas[id];
- delta.dx += cpd.x - lpd.x;
- delta.dy += cpd.y - lpd.y;
-
- if (first) {
- commonDeltaX = delta.dx;
- commonDeltaY = delta.dy;
- } else {
- commonDeltaX = calculateCommonVector(commonDeltaX, delta.dx);
- commonDeltaY = calculateCommonVector(commonDeltaY, delta.dy);
- }
+ delta.dx = 0;
+ delta.dy = 0;
}
- if (commonDeltaX || commonDeltaY) {
- for (BitSet32 idBits(commonIdBits); !idBits.isEmpty(); ) {
- uint32_t id = idBits.firstMarkedBit();
- idBits.clearBit(id);
-
- PointerGesture::Delta& delta = mPointerGesture.referenceDeltas[id];
- delta.dx = 0;
- delta.dy = 0;
- }
-
- mPointerGesture.referenceTouchX += commonDeltaX;
- mPointerGesture.referenceTouchY += commonDeltaY;
+ mPointerGesture.referenceTouchX += commonDeltaX;
+ mPointerGesture.referenceTouchY += commonDeltaY;
- commonDeltaX *= mLocked.pointerGestureXMovementScale;
- commonDeltaY *= mLocked.pointerGestureYMovementScale;
- mPointerGesture.pointerVelocityControl.move(when, &commonDeltaX, &commonDeltaY);
+ commonDeltaX *= mLocked.pointerGestureXMovementScale;
+ commonDeltaY *= mLocked.pointerGestureYMovementScale;
+ mPointerGesture.pointerVelocityControl.move(when, &commonDeltaX, &commonDeltaY);
- mPointerGesture.referenceGestureX += commonDeltaX;
- mPointerGesture.referenceGestureY += commonDeltaY;
-
- clampPositionUsingPointerBounds(mPointerController,
- &mPointerGesture.referenceGestureX,
- &mPointerGesture.referenceGestureY);
- }
+ mPointerGesture.referenceGestureX += commonDeltaX;
+ mPointerGesture.referenceGestureY += commonDeltaY;
}
// Report gestures.
@@ -4344,10 +4274,6 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y,
mPointerGesture.referenceGestureY);
mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 1.0f);
-
- if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) {
- mPointerGesture.spotGesture = PointerControllerInterface::SPOT_GESTURE_PRESS;
- }
} else if (mPointerGesture.currentGestureMode == PointerGesture::SWIPE) {
// SWIPE mode.
#if DEBUG_GESTURES
@@ -4370,10 +4296,6 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y,
mPointerGesture.referenceGestureY);
mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 1.0f);
-
- if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) {
- mPointerGesture.spotGesture = PointerControllerInterface::SPOT_GESTURE_SWIPE;
- }
} else if (mPointerGesture.currentGestureMode == PointerGesture::FREEFORM) {
// FREEFORM mode.
#if DEBUG_GESTURES
@@ -4475,33 +4397,6 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
"activeGestureId=%d", mPointerGesture.activeGestureId);
#endif
}
-
- if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) {
- mPointerGesture.spotGesture = PointerControllerInterface::SPOT_GESTURE_FREEFORM;
- }
- }
-
- // Update spot locations for PRESS, SWIPE and FREEFORM.
- // We use the same calculation as we do to calculate the gesture pointers
- // for FREEFORM so that the spots smoothly track gestures.
- if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) {
- mPointerGesture.spotIdBits.clear();
- for (uint32_t i = 0; i < mCurrentTouch.pointerCount; i++) {
- uint32_t id = mCurrentTouch.pointers[i].id;
- mPointerGesture.spotIdBits.markBit(id);
- mPointerGesture.spotIdToIndex[id] = i;
-
- float x = (mCurrentTouch.pointers[i].x - mPointerGesture.referenceTouchX)
- * mLocked.pointerGestureXZoomScale + mPointerGesture.referenceGestureX;
- float y = (mCurrentTouch.pointers[i].y - mPointerGesture.referenceTouchY)
- * mLocked.pointerGestureYZoomScale + mPointerGesture.referenceGestureY;
-
- mPointerGesture.spotCoords[i].clear();
- mPointerGesture.spotCoords[i].setAxisValue(AMOTION_EVENT_AXIS_X, x);
- mPointerGesture.spotCoords[i].setAxisValue(AMOTION_EVENT_AXIS_Y, y);
- mPointerGesture.spotCoords[i].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 1.0f);
- }
- moveSpotsLocked();
}
}
@@ -4544,11 +4439,6 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
return true;
}
-void TouchInputMapper::moveSpotsLocked() {
- mPointerController->setSpots(mPointerGesture.spotGesture,
- mPointerGesture.spotCoords, mPointerGesture.spotIdToIndex, mPointerGesture.spotIdBits);
-}
-
void TouchInputMapper::dispatchMotion(nsecs_t when, uint32_t policyFlags, uint32_t source,
int32_t action, int32_t flags, int32_t metaState, int32_t buttonState, int32_t edgeFlags,
const PointerProperties* properties, const PointerCoords* coords,
diff --git a/services/input/InputReader.h b/services/input/InputReader.h
index 1d4ad87..36cd89c 100644
--- a/services/input/InputReader.h
+++ b/services/input/InputReader.h
@@ -101,8 +101,8 @@ struct InputReaderConfiguration {
nsecs_t pointerGestureMultitouchSettleInterval;
// The transition from PRESS to SWIPE or FREEFORM gesture mode is made when
- // both of the pointers are moving at least this fast.
- float pointerGestureMultitouchMinSpeed; // in pixels per second
+ // at least two pointers have moved at least this far from their starting place.
+ float pointerGestureMultitouchMinDistance; // in pixels
// The transition from PRESS to SWIPE gesture mode can only occur when the
// cosine of the angle between the two vectors is greater than or equal to than this value
@@ -134,7 +134,7 @@ struct InputReaderConfiguration {
filterTouchEvents(false),
filterJumpyTouchEvents(false),
virtualKeyQuietTime(0),
- pointerVelocityControlParameters(1.0f, 80.0f, 400.0f, 4.0f),
+ pointerVelocityControlParameters(1.0f, 500.0f, 3000.0f, 3.0f),
wheelVelocityControlParameters(1.0f, 15.0f, 50.0f, 4.0f),
pointerGestureQuietInterval(100 * 1000000LL), // 100 ms
pointerGestureDragMinSwitchSpeed(50), // 50 pixels per second
@@ -142,10 +142,10 @@ struct InputReaderConfiguration {
pointerGestureTapDragInterval(150 * 1000000LL), // 150 ms
pointerGestureTapSlop(10.0f), // 10 pixels
pointerGestureMultitouchSettleInterval(100 * 1000000LL), // 100 ms
- pointerGestureMultitouchMinSpeed(150.0f), // 150 pixels per second
+ pointerGestureMultitouchMinDistance(15), // 15 pixels
pointerGestureSwipeTransitionAngleCosine(0.5f), // cosine of 45degrees
- pointerGestureSwipeMaxWidthRatio(0.333f),
- pointerGestureMovementSpeedRatio(0.3f),
+ pointerGestureSwipeMaxWidthRatio(0.25f),
+ pointerGestureMovementSpeedRatio(0.8f),
pointerGestureZoomSpeedRatio(0.3f) { }
};
@@ -1140,12 +1140,6 @@ private:
PointerProperties lastGestureProperties[MAX_POINTERS];
PointerCoords lastGestureCoords[MAX_POINTERS];
- // Pointer coords and ids for the current spots.
- PointerControllerInterface::SpotGesture spotGesture;
- BitSet32 spotIdBits; // same set of ids as touch ids
- uint32_t spotIdToIndex[MAX_POINTER_ID + 1];
- PointerCoords spotCoords[MAX_POINTERS];
-
// Time the pointer gesture last went down.
nsecs_t downTime;
@@ -1192,8 +1186,6 @@ private:
currentGestureIdBits.clear();
lastGestureMode = NEUTRAL;
lastGestureIdBits.clear();
- spotGesture = PointerControllerInterface::SPOT_GESTURE_NEUTRAL;
- spotIdBits.clear();
downTime = 0;
velocityTracker.clear();
resetTap();
@@ -1219,7 +1211,6 @@ private:
void dispatchPointerGestures(nsecs_t when, uint32_t policyFlags, bool isTimeout);
bool preparePointerGestures(nsecs_t when,
bool* outCancelPreviousGesture, bool* outFinishPreviousGesture, bool isTimeout);
- void moveSpotsLocked();
// Dispatches a motion event.
// If the changedId is >= 0 and the action is POINTER_DOWN or POINTER_UP, the
diff --git a/services/input/PointerController.cpp b/services/input/PointerController.cpp
index c18ebcf..12c7cba 100644
--- a/services/input/PointerController.cpp
+++ b/services/input/PointerController.cpp
@@ -240,15 +240,15 @@ void PointerController::setPresentation(Presentation presentation) {
}
}
-void PointerController::setSpots(SpotGesture spotGesture,
- const PointerCoords* spotCoords, const uint32_t* spotIdToIndex, BitSet32 spotIdBits) {
+void PointerController::setSpots(const PointerCoords* spotCoords,
+ const uint32_t* spotIdToIndex, BitSet32 spotIdBits) {
#if DEBUG_POINTER_UPDATES
- LOGD("setSpots: spotGesture=%d", spotGesture);
+ LOGD("setSpots: idBits=%08x", spotIdBits.value);
for (BitSet32 idBits(spotIdBits); !idBits.isEmpty(); ) {
uint32_t id = idBits.firstMarkedBit();
idBits.clearBit(id);
const PointerCoords& c = spotCoords[spotIdToIndex[id]];
- LOGD(" spot %d: position=(%0.3f, %0.3f), pressure=%0.3f", id,
+ LOGD(" spot %d: position=(%0.3f, %0.3f), pressure=%0.3f", id,
c.getAxisValue(AMOTION_EVENT_AXIS_X),
c.getAxisValue(AMOTION_EVENT_AXIS_Y),
c.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE));
diff --git a/services/input/PointerController.h b/services/input/PointerController.h
index 1c21db1..700ef72 100644
--- a/services/input/PointerController.h
+++ b/services/input/PointerController.h
@@ -90,38 +90,6 @@ public:
/* Sets the mode of the pointer controller. */
virtual void setPresentation(Presentation presentation) = 0;
- // Describes the current gesture.
- enum SpotGesture {
- // No gesture.
- // Do not display any spots.
- SPOT_GESTURE_NEUTRAL,
- // Tap at current location.
- // Briefly display one spot at the tapped location.
- SPOT_GESTURE_TAP,
- // Drag at current location.
- // Display spot at pressed location.
- SPOT_GESTURE_DRAG,
- // Button pressed but no finger is down.
- // Display spot at pressed location.
- SPOT_GESTURE_BUTTON_CLICK,
- // Button pressed and a finger is down.
- // Display spot at pressed location.
- SPOT_GESTURE_BUTTON_DRAG,
- // One finger down and hovering.
- // Display spot at the hovered location.
- SPOT_GESTURE_HOVER,
- // Two fingers down but not sure in which direction they are moving so we consider
- // it a press at the pointer location.
- // Display two spots near the pointer location.
- SPOT_GESTURE_PRESS,
- // Two fingers down and moving in same direction.
- // Display two spots near the pointer location.
- SPOT_GESTURE_SWIPE,
- // Two or more fingers down and moving in arbitrary directions.
- // Display two or more spots near the pointer location, one for each finger.
- SPOT_GESTURE_FREEFORM,
- };
-
/* Sets the spots for the current gesture.
* The spots are not subject to the inactivity timeout like the pointer
* itself it since they are expected to remain visible for so long as
@@ -131,8 +99,7 @@ public:
* For spotCoords, pressure != 0 indicates that the spot's location is being
* pressed (not hovering).
*/
- virtual void setSpots(SpotGesture spotGesture,
- const PointerCoords* spotCoords, const uint32_t* spotIdToIndex,
+ virtual void setSpots(const PointerCoords* spotCoords, const uint32_t* spotIdToIndex,
BitSet32 spotIdBits) = 0;
/* Removes all spots. */
@@ -198,8 +165,8 @@ public:
virtual void unfade(Transition transition);
virtual void setPresentation(Presentation presentation);
- virtual void setSpots(SpotGesture spotGesture,
- const PointerCoords* spotCoords, const uint32_t* spotIdToIndex, BitSet32 spotIdBits);
+ virtual void setSpots(const PointerCoords* spotCoords,
+ const uint32_t* spotIdToIndex, BitSet32 spotIdBits);
virtual void clearSpots();
void setDisplaySize(int32_t width, int32_t height);
diff --git a/services/input/tests/InputReader_test.cpp b/services/input/tests/InputReader_test.cpp
index 00b4222..d04c9e7 100644
--- a/services/input/tests/InputReader_test.cpp
+++ b/services/input/tests/InputReader_test.cpp
@@ -101,8 +101,8 @@ private:
virtual void setPresentation(Presentation presentation) {
}
- virtual void setSpots(SpotGesture spotGesture,
- const PointerCoords* spotCoords, const uint32_t* spotIdToIndex, BitSet32 spotIdBits) {
+ virtual void setSpots(const PointerCoords* spotCoords,
+ const uint32_t* spotIdToIndex, BitSet32 spotIdBits) {
}
virtual void clearSpots() {
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index dd76eb8..b559fb9 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -458,6 +458,12 @@ public class ConnectivityService extends IConnectivityManager.Stub {
mTethering.getTetherableBluetoothRegexs().length != 0) &&
mTethering.getUpstreamIfaceRegexs().length != 0);
+ try {
+ nmService.registerObserver(mTethering);
+ } catch (RemoteException e) {
+ loge("Error registering observer :" + e);
+ }
+
if (DBG) {
mInetLog = new ArrayList();
}
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index 41ec63a..4e2501b 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -321,6 +321,13 @@ public class WifiService extends IWifiManager.Stub {
}
break;
}
+ case AsyncChannel.CMD_CHANNEL_DISCONNECTED: {
+ Slog.e(TAG, "WifiStateMachine channel lost, msg.arg1 =" + msg.arg1);
+ mWifiStateMachineChannel = null;
+ //Re-establish connection to state machine
+ mWsmChannel.connect(mContext, this, mWifiStateMachine.getHandler());
+ break;
+ }
default: {
Slog.d(TAG, "WifiStateMachineHandler.handleMessage ignoring msg=" + msg);
break;
@@ -593,7 +600,12 @@ public class WifiService extends IWifiManager.Stub {
*/
public WifiConfiguration getWifiApConfiguration() {
enforceAccessPermission();
- return mWifiStateMachine.syncGetWifiApConfiguration(mWifiStateMachineChannel);
+ if (mWifiStateMachineChannel != null) {
+ return mWifiStateMachine.syncGetWifiApConfiguration(mWifiStateMachineChannel);
+ } else {
+ Slog.e(TAG, "mWifiStateMachineChannel is not initialized");
+ return null;
+ }
}
/**
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index c2a8a1d..da9f1d6 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -92,7 +92,6 @@ import android.os.FileObserver;
import android.os.FileUtils;
import android.os.Handler;
import android.os.IBinder;
-import android.os.IInterface;
import android.os.IPermissionController;
import android.os.Looper;
import android.os.Message;
diff --git a/services/java/com/android/server/connectivity/Tethering.java b/services/java/com/android/server/connectivity/Tethering.java
index 7ea0591..5fa26ef 100644
--- a/services/java/com/android/server/connectivity/Tethering.java
+++ b/services/java/com/android/server/connectivity/Tethering.java
@@ -129,13 +129,6 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
mNMService = nmService;
mLooper = looper;
- // register for notifications from NetworkManagement Service
- try {
- mNMService.registerObserver(this);
- } catch (RemoteException e) {
- Log.e(TAG, "Error registering observer :" + e);
- }
-
mIfaces = new HashMap<String, TetherInterfaceSM>();
// make our own thread so we don't anr the system
diff --git a/services/java/com/android/server/wm/InputManager.java b/services/java/com/android/server/wm/InputManager.java
index 3095c37..ee69311 100644
--- a/services/java/com/android/server/wm/InputManager.java
+++ b/services/java/com/android/server/wm/InputManager.java
@@ -617,8 +617,13 @@ public class InputManager {
}
@SuppressWarnings("unused")
- public int getTapTimeout() {
- return ViewConfiguration.getTapTimeout();
+ public int getHoverTapTimeout() {
+ return ViewConfiguration.getHoverTapTimeout();
+ }
+
+ @SuppressWarnings("unused")
+ public int getHoverTapSlop() {
+ return ViewConfiguration.getHoverTapSlop();
}
@SuppressWarnings("unused")
@@ -632,11 +637,6 @@ public class InputManager {
}
@SuppressWarnings("unused")
- public int getTouchSlop() {
- return ViewConfiguration.get(mContext).getScaledTouchSlop();
- }
-
- @SuppressWarnings("unused")
public int getMaxEventsPerSecond() {
int result = 0;
try {
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index d95d4c5..819c16e 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -153,6 +153,7 @@ public class WindowManagerService extends IWindowManager.Stub
static final boolean DEBUG_WINDOW_MOVEMENT = false;
static final boolean DEBUG_TOKEN_MOVEMENT = false;
static final boolean DEBUG_ORIENTATION = false;
+ static final boolean DEBUG_APP_ORIENTATION = false;
static final boolean DEBUG_CONFIGURATION = false;
static final boolean DEBUG_APP_TRANSITIONS = false;
static final boolean DEBUG_STARTING_WINDOW = false;
@@ -427,6 +428,7 @@ public class WindowManagerService extends IWindowManager.Stub
boolean mWindowsFreezingScreen = false;
long mFreezeGcPending = 0;
int mAppsFreezingScreen = 0;
+ int mLastWindowForcedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
int mLayoutSeq = 0;
@@ -3187,6 +3189,15 @@ public class WindowManagerService extends IWindowManager.Stub
}
public int getOrientationFromWindowsLocked() {
+ if (mDisplayFrozen || mOpeningApps.size() > 0 || mClosingApps.size() > 0) {
+ // If the display is frozen, some activities may be in the middle
+ // of restarting, and thus have removed their old window. If the
+ // window has the flag to hide the lock screen, then the lock screen
+ // can re-appear and inflict its own orientation on us. Keep the
+ // orientation stable until this all settles down.
+ return mLastWindowForcedOrientation;
+ }
+
int pos = mWindows.size() - 1;
while (pos >= 0) {
WindowState wtoken = mWindows.get(pos);
@@ -3194,7 +3205,7 @@ public class WindowManagerService extends IWindowManager.Stub
if (wtoken.mAppToken != null) {
// We hit an application window. so the orientation will be determined by the
// app window. No point in continuing further.
- return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+ return (mLastWindowForcedOrientation=ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
}
if (!wtoken.isVisibleLw() || !wtoken.mPolicyVisibilityAfterAnim) {
continue;
@@ -3204,10 +3215,10 @@ public class WindowManagerService extends IWindowManager.Stub
(req == ActivityInfo.SCREEN_ORIENTATION_BEHIND)){
continue;
} else {
- return req;
+ return (mLastWindowForcedOrientation=req);
}
}
- return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+ return (mLastWindowForcedOrientation=ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
}
public int getOrientationFromAppTokensLocked() {
@@ -3220,16 +3231,23 @@ public class WindowManagerService extends IWindowManager.Stub
while (pos >= 0) {
AppWindowToken wtoken = mAppTokens.get(pos);
pos--;
+
+ if (DEBUG_APP_ORIENTATION) Slog.v(TAG, "Checking app orientation: " + wtoken);
+
// if we're about to tear down this window and not seek for
// the behind activity, don't use it for orientation
if (!findingBehind
&& (!wtoken.hidden && wtoken.hiddenRequested)) {
+ if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping " + wtoken
+ + " -- going to hide");
continue;
}
if (!haveGroup) {
// We ignore any hidden applications on the top.
if (wtoken.hiddenRequested || wtoken.willBeHidden) {
+ if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping " + wtoken
+ + " -- hidden on top");
continue;
}
haveGroup = true;
@@ -3243,6 +3261,8 @@ public class WindowManagerService extends IWindowManager.Stub
// user's orientation.
if (lastOrientation != ActivityInfo.SCREEN_ORIENTATION_BEHIND
&& lastFullscreen) {
+ if (DEBUG_ORIENTATION) Slog.v(TAG, "Done at " + wtoken
+ + " -- end of group, return " + lastOrientation);
return lastOrientation;
}
}
@@ -3253,16 +3273,21 @@ public class WindowManagerService extends IWindowManager.Stub
lastFullscreen = wtoken.appFullscreen;
if (lastFullscreen
&& or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
+ if (DEBUG_ORIENTATION) Slog.v(TAG, "Done at " + wtoken
+ + " -- full screen, return " + or);
return or;
}
// If this application has requested an explicit orientation,
// then use it.
if (or != ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
&& or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
+ if (DEBUG_ORIENTATION) Slog.v(TAG, "Done at " + wtoken
+ + " -- explicitly set, return " + or);
return or;
}
findingBehind |= (or == ActivityInfo.SCREEN_ORIENTATION_BEHIND);
}
+ if (DEBUG_ORIENTATION) Slog.v(TAG, "No app is requesting an orientation");
return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
}
@@ -3335,15 +3360,6 @@ public class WindowManagerService extends IWindowManager.Stub
* android.os.IBinder)
*/
boolean updateOrientationFromAppTokensLocked(boolean inTransaction) {
- if (mDisplayFrozen || mOpeningApps.size() > 0 || mClosingApps.size() > 0) {
- // If the display is frozen, some activities may be in the middle
- // of restarting, and thus have removed their old window. If the
- // window has the flag to hide the lock screen, then the lock screen
- // can re-appear and inflict its own orientation on us. Keep the
- // orientation stable until this all settles down.
- return false;
- }
-
boolean changed = false;
long ident = Binder.clearCallingIdentity();
try {
@@ -8939,9 +8955,10 @@ public class WindowManagerService extends IWindowManager.Stub
pw.print(" mAppsFreezingScreen="); pw.print(mAppsFreezingScreen);
pw.print(" mWaitingForConfig="); pw.println(mWaitingForConfig);
pw.print(" mRotation="); pw.print(mRotation);
- pw.print(" mForcedAppOrientation="); pw.print(mForcedAppOrientation);
pw.print(" mRequestedRotation="); pw.print(mRequestedRotation);
pw.print(" mAltOrientation="); pw.println(mAltOrientation);
+ pw.print(" mLastWindowForcedOrientation"); pw.print(mLastWindowForcedOrientation);
+ pw.print(" mForcedAppOrientation="); pw.println(mForcedAppOrientation);
pw.print(" mDeferredRotation="); pw.print(mDeferredRotation);
pw.print(", mDeferredRotationAnimFlags="); pw.println(mDeferredRotationAnimFlags);
pw.print(" mAnimationPending="); pw.print(mAnimationPending);
diff --git a/services/jni/com_android_server_InputManager.cpp b/services/jni/com_android_server_InputManager.cpp
index 881882f..7c5084f 100644
--- a/services/jni/com_android_server_InputManager.cpp
+++ b/services/jni/com_android_server_InputManager.cpp
@@ -56,7 +56,7 @@ namespace android {
// The exponent used to calculate the pointer speed scaling factor.
// The scaling factor is calculated as 2 ^ (speed * exponent),
// where the speed ranges from -7 to + 7 and is supplied by the user.
-static const float POINTER_SPEED_EXPONENT = 1.0f / 3;
+static const float POINTER_SPEED_EXPONENT = 1.0f / 4;
static struct {
jmethodID notifyConfigurationChanged;
@@ -76,10 +76,10 @@ static struct {
jmethodID getKeyRepeatTimeout;
jmethodID getKeyRepeatDelay;
jmethodID getMaxEventsPerSecond;
- jmethodID getTapTimeout;
+ jmethodID getHoverTapTimeout;
+ jmethodID getHoverTapSlop;
jmethodID getDoubleTapTimeout;
jmethodID getLongPressTimeout;
- jmethodID getTouchSlop;
jmethodID getPointerLayer;
jmethodID getPointerIcon;
} gCallbacksClassInfo;
@@ -410,32 +410,32 @@ void NativeInputManager::getReaderConfiguration(InputReaderConfiguration* outCon
env->DeleteLocalRef(excludedDeviceNames);
}
- jint tapTimeout = env->CallIntMethod(mCallbacksObj,
- gCallbacksClassInfo.getTapTimeout);
- if (!checkAndClearExceptionFromCallback(env, "getTapTimeout")) {
+ jint hoverTapTimeout = env->CallIntMethod(mCallbacksObj,
+ gCallbacksClassInfo.getHoverTapTimeout);
+ if (!checkAndClearExceptionFromCallback(env, "getHoverTapTimeout")) {
jint doubleTapTimeout = env->CallIntMethod(mCallbacksObj,
gCallbacksClassInfo.getDoubleTapTimeout);
if (!checkAndClearExceptionFromCallback(env, "getDoubleTapTimeout")) {
jint longPressTimeout = env->CallIntMethod(mCallbacksObj,
gCallbacksClassInfo.getLongPressTimeout);
if (!checkAndClearExceptionFromCallback(env, "getLongPressTimeout")) {
- outConfig->pointerGestureTapInterval = milliseconds_to_nanoseconds(tapTimeout);
+ outConfig->pointerGestureTapInterval = milliseconds_to_nanoseconds(hoverTapTimeout);
// We must ensure that the tap-drag interval is significantly shorter than
// the long-press timeout because the tap is held down for the entire duration
// of the double-tap timeout.
jint tapDragInterval = max(min(longPressTimeout - 100,
- doubleTapTimeout), tapTimeout);
+ doubleTapTimeout), hoverTapTimeout);
outConfig->pointerGestureTapDragInterval =
milliseconds_to_nanoseconds(tapDragInterval);
}
}
}
- jint touchSlop = env->CallIntMethod(mCallbacksObj,
- gCallbacksClassInfo.getTouchSlop);
- if (!checkAndClearExceptionFromCallback(env, "getTouchSlop")) {
- outConfig->pointerGestureTapSlop = touchSlop;
+ jint hoverTapSlop = env->CallIntMethod(mCallbacksObj,
+ gCallbacksClassInfo.getHoverTapSlop);
+ if (!checkAndClearExceptionFromCallback(env, "getHoverTapSlop")) {
+ outConfig->pointerGestureTapSlop = hoverTapSlop;
}
{ // acquire lock
@@ -1394,8 +1394,11 @@ int register_android_server_InputManager(JNIEnv* env) {
GET_METHOD_ID(gCallbacksClassInfo.getKeyRepeatDelay, clazz,
"getKeyRepeatDelay", "()I");
- GET_METHOD_ID(gCallbacksClassInfo.getTapTimeout, clazz,
- "getTapTimeout", "()I");
+ GET_METHOD_ID(gCallbacksClassInfo.getHoverTapTimeout, clazz,
+ "getHoverTapTimeout", "()I");
+
+ GET_METHOD_ID(gCallbacksClassInfo.getHoverTapSlop, clazz,
+ "getHoverTapSlop", "()I");
GET_METHOD_ID(gCallbacksClassInfo.getDoubleTapTimeout, clazz,
"getDoubleTapTimeout", "()I");
@@ -1403,9 +1406,6 @@ int register_android_server_InputManager(JNIEnv* env) {
GET_METHOD_ID(gCallbacksClassInfo.getLongPressTimeout, clazz,
"getLongPressTimeout", "()I");
- GET_METHOD_ID(gCallbacksClassInfo.getTouchSlop, clazz,
- "getTouchSlop", "()I");
-
GET_METHOD_ID(gCallbacksClassInfo.getMaxEventsPerSecond, clazz,
"getMaxEventsPerSecond", "()I");
diff --git a/telephony/java/com/android/internal/telephony/BaseCommands.java b/telephony/java/com/android/internal/telephony/BaseCommands.java
index 0c4581b..8427d14 100644
--- a/telephony/java/com/android/internal/telephony/BaseCommands.java
+++ b/telephony/java/com/android/internal/telephony/BaseCommands.java
@@ -96,8 +96,10 @@ public abstract class BaseCommands implements CommandsInterface {
protected Registrant mRestrictedStateRegistrant;
protected Registrant mGsmBroadcastSmsRegistrant;
- // Network Mode received from PhoneFactory
- protected int mNetworkMode;
+ // Preferred network type received from PhoneFactory.
+ // This is used when establishing a connection to the
+ // vendor ril so it starts up in the correct mode.
+ protected int mPreferredNetworkType;
// CDMA subscription received from PhoneFactory
protected int mCdmaSubscription;
// Type of Phone, GSM or CDMA. Set by CDMAPhone or GSMPhone.
diff --git a/telephony/java/com/android/internal/telephony/RIL.java b/telephony/java/com/android/internal/telephony/RIL.java
index 2c04b30..572bbaa 100644
--- a/telephony/java/com/android/internal/telephony/RIL.java
+++ b/telephony/java/com/android/internal/telephony/RIL.java
@@ -611,14 +611,14 @@ public final class RIL extends BaseCommands implements CommandsInterface {
//***** Constructors
- public RIL(Context context, int networkMode, int cdmaSubscription) {
+ public RIL(Context context, int preferredNetworkType, int cdmaSubscription) {
super(context);
if (RILJ_LOGD) {
- riljLog("RIL(context, networkMode=" + networkMode +
+ riljLog("RIL(context, preferredNetworkType=" + preferredNetworkType +
" cdmaSubscription=" + cdmaSubscription + ")");
}
mCdmaSubscription = cdmaSubscription;
- mNetworkMode = networkMode;
+ mPreferredNetworkType = preferredNetworkType;
mPhoneType = RILConstants.NO_PHONE;
PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
@@ -1813,6 +1813,8 @@ public final class RIL extends BaseCommands implements CommandsInterface {
rr.mp.writeInt(1);
rr.mp.writeInt(networkType);
+ mPreferredNetworkType = networkType;
+
if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
+ " : " + networkType);
@@ -2222,7 +2224,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
case RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM: ret = responseInts(p); break;
case RIL_REQUEST_EXPLICIT_CALL_TRANSFER: ret = responseVoid(p); break;
case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE: ret = responseVoid(p); break;
- case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE: ret = responseInts(p); break;
+ case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE: ret = responseGetPreferredNetworkType(p); break;
case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS: ret = responseCellList(p); break;
case RIL_REQUEST_SET_LOCATION_UPDATES: ret = responseVoid(p); break;
case RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE: ret = responseVoid(p); break;
@@ -2737,7 +2739,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
// Initial conditions
setRadioPower(false, null);
- setPreferredNetworkType(mNetworkMode, null);
+ setPreferredNetworkType(mPreferredNetworkType, null);
setCdmaSubscriptionSource(mCdmaSubscription, null);
notifyRegistrantsRilConnectionChanged(((int[])ret)[0]);
break;
@@ -3161,6 +3163,18 @@ public final class RIL extends BaseCommands implements CommandsInterface {
return response;
}
+ private Object responseGetPreferredNetworkType(Parcel p) {
+ int [] response = (int[]) responseInts(p);
+
+ if (response.length >= 1) {
+ // Since this is the response for getPreferredNetworkType
+ // we'll assume that it should be the value we want the
+ // vendor ril to take if we reestablish a connection to it.
+ mPreferredNetworkType = response[0];
+ }
+ return response;
+ }
+
private Object responseGmsBroadcastConfig(Parcel p) {
int num;
ArrayList<SmsBroadcastConfigInfo> response;
diff --git a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
index 922cd4c..8e3ed93 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
@@ -425,7 +425,7 @@ public final class Canvas_Delegate {
AffineTransform matrixTx = matrixDelegate.getAffineTransform();
// combine them so that the given matrix is applied after.
- currentTx.preConcatenate(matrixTx);
+ currentTx.concatenate(matrixTx);
// give it to the graphics2D as a new matrix replacing all previous transform
snapshot.setTransform(currentTx);
@@ -717,7 +717,7 @@ public final class Canvas_Delegate {
/*package*/ static void native_drawCircle(int nativeCanvas,
float cx, float cy, float radius, int paint) {
native_drawOval(nativeCanvas,
- new RectF(cx - radius, cy - radius, radius*2, radius*2),
+ new RectF(cx - radius, cy - radius, radius, radius),
paint);
}
diff --git a/tools/layoutlib/bridge/src/android/os/HandlerThread_Delegate.java b/tools/layoutlib/bridge/src/android/os/HandlerThread_Delegate.java
new file mode 100644
index 0000000..afbe97c
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/os/HandlerThread_Delegate.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os;
+
+import com.android.layoutlib.bridge.android.BridgeContext;
+import com.android.layoutlib.bridge.impl.RenderAction;
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Delegate overriding selected methods of android.os.HandlerThread
+ *
+ * Through the layoutlib_create tool, selected methods of Handler have been replaced
+ * by calls to methods of the same name in this delegate class.
+ *
+ *
+ */
+public class HandlerThread_Delegate {
+
+ private static Map<BridgeContext, List<HandlerThread>> sThreads =
+ new HashMap<BridgeContext, List<HandlerThread>>();
+
+ public static void cleanUp(BridgeContext context) {
+ List<HandlerThread> list = sThreads.get(context);
+ if (list != null) {
+ for (HandlerThread thread : list) {
+ thread.quit();
+ }
+
+ list.clear();
+ sThreads.remove(context);
+ }
+ }
+
+ // -------- Delegate methods
+
+ @LayoutlibDelegate
+ /*package*/ static void run(HandlerThread theThread) {
+ // record the thread so that it can be quit() on clean up.
+ BridgeContext context = RenderAction.getCurrentContext();
+ List<HandlerThread> list = sThreads.get(context);
+ if (list == null) {
+ list = new ArrayList<HandlerThread>();
+ sThreads.put(context, list);
+ }
+
+ list.add(theThread);
+
+ // ---- START DEFAULT IMPLEMENTATION.
+
+ theThread.mTid = Process.myTid();
+ Looper.prepare();
+ synchronized (theThread) {
+ theThread.mLooper = Looper.myLooper();
+ theThread.notifyAll();
+ }
+ Process.setThreadPriority(theThread.mPriority);
+ theThread.onLooperPrepared();
+ Looper.loop();
+ theThread.mTid = -1;
+ }
+}
diff --git a/tools/layoutlib/bridge/src/android/view/LayoutInflater_Delegate.java b/tools/layoutlib/bridge/src/android/view/LayoutInflater_Delegate.java
index 0f3cf57..3ef3288 100644
--- a/tools/layoutlib/bridge/src/android/view/LayoutInflater_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/view/LayoutInflater_Delegate.java
@@ -22,7 +22,10 @@ import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
+import android.content.res.TypedArray;
+import android.content.res.XmlResourceParser;
import android.util.AttributeSet;
+import android.util.Xml;
import java.io.IOException;
@@ -35,6 +38,8 @@ import java.io.IOException;
*/
public class LayoutInflater_Delegate {
+ public static boolean sIsInInclude = false;
+
/**
* Recursive method used to descend down the xml hierarchy and instantiate
* views, instantiate their children, and then call onFinishInflate().
@@ -94,4 +99,128 @@ public class LayoutInflater_Delegate {
}
}
}
+
+ @LayoutlibDelegate
+ public static void parseInclude(
+ LayoutInflater thisInflater,
+ XmlPullParser parser, View parent, AttributeSet attrs)
+ throws XmlPullParserException, IOException {
+
+ int type;
+
+ if (parent instanceof ViewGroup) {
+ final int layout = attrs.getAttributeResourceValue(null, "layout", 0);
+ if (layout == 0) {
+ final String value = attrs.getAttributeValue(null, "layout");
+ if (value == null) {
+ throw new InflateException("You must specifiy a layout in the"
+ + " include tag: <include layout=\"@layout/layoutID\" />");
+ } else {
+ throw new InflateException("You must specifiy a valid layout "
+ + "reference. The layout ID " + value + " is not valid.");
+ }
+ } else {
+ final XmlResourceParser childParser =
+ thisInflater.getContext().getResources().getLayout(layout);
+
+ try {
+ final AttributeSet childAttrs = Xml.asAttributeSet(childParser);
+
+ while ((type = childParser.next()) != XmlPullParser.START_TAG &&
+ type != XmlPullParser.END_DOCUMENT) {
+ // Empty.
+ }
+
+ if (type != XmlPullParser.START_TAG) {
+ throw new InflateException(childParser.getPositionDescription() +
+ ": No start tag found!");
+ }
+
+ final String childName = childParser.getName();
+
+ if (LayoutInflater.TAG_MERGE.equals(childName)) {
+ // Inflate all children.
+ thisInflater.rInflate(childParser, parent, childAttrs, false);
+ } else {
+ final View view = thisInflater.createViewFromTag(parent, childName, childAttrs);
+ final ViewGroup group = (ViewGroup) parent;
+
+ // We try to load the layout params set in the <include /> tag. If
+ // they don't exist, we will rely on the layout params set in the
+ // included XML file.
+ // During a layoutparams generation, a runtime exception is thrown
+ // if either layout_width or layout_height is missing. We catch
+ // this exception and set localParams accordingly: true means we
+ // successfully loaded layout params from the <include /> tag,
+ // false means we need to rely on the included layout params.
+ ViewGroup.LayoutParams params = null;
+ try {
+ // ---- START CHANGES
+ sIsInInclude = true;
+ // ---- END CHANGES
+
+ params = group.generateLayoutParams(attrs);
+
+ } catch (RuntimeException e) {
+ // ---- START CHANGES
+ sIsInInclude = false;
+ // ---- END CHANGES
+
+ params = group.generateLayoutParams(childAttrs);
+ } finally {
+ // ---- START CHANGES
+ sIsInInclude = false;
+ // ---- END CHANGES
+
+ if (params != null) {
+ view.setLayoutParams(params);
+ }
+ }
+
+ // Inflate all children.
+ thisInflater.rInflate(childParser, view, childAttrs, true);
+
+ // Attempt to override the included layout's android:id with the
+ // one set on the <include /> tag itself.
+ TypedArray a = thisInflater.mContext.obtainStyledAttributes(attrs,
+ com.android.internal.R.styleable.View, 0, 0);
+ int id = a.getResourceId(com.android.internal.R.styleable.View_id, View.NO_ID);
+ // While we're at it, let's try to override android:visibility.
+ int visibility = a.getInt(com.android.internal.R.styleable.View_visibility, -1);
+ a.recycle();
+
+ if (id != View.NO_ID) {
+ view.setId(id);
+ }
+
+ switch (visibility) {
+ case 0:
+ view.setVisibility(View.VISIBLE);
+ break;
+ case 1:
+ view.setVisibility(View.INVISIBLE);
+ break;
+ case 2:
+ view.setVisibility(View.GONE);
+ break;
+ }
+
+ group.addView(view);
+ }
+ } finally {
+ childParser.close();
+ }
+ }
+ } else {
+ throw new InflateException("<include /> can only be used inside of a ViewGroup");
+ }
+
+ final int currentDepth = parser.getDepth();
+ while (((type = parser.next()) != XmlPullParser.END_TAG ||
+ parser.getDepth() > currentDepth) && type != XmlPullParser.END_DOCUMENT) {
+ // Empty
+ }
+ }
+
+
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
index 144ec42..3ba3257 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
@@ -196,7 +196,7 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge {
Capability.UNBOUND_RENDERING,
Capability.CUSTOM_BACKGROUND_COLOR,
Capability.RENDER,
- //Capability.LAYOUT_ONLY, // disable to run on ADT 10.0 which doesn't include this.
+ Capability.LAYOUT_ONLY,
Capability.EMBEDDED_LAYOUT,
Capability.VIEW_MANIPULATION,
Capability.PLAY_ANIMATION,
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
index e536028..4fa924d 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
@@ -71,7 +71,6 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
-import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
@@ -342,7 +341,7 @@ public final class BridgeContext extends Activity {
try {
KXmlParser parser = new KXmlParser();
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
- parser.setInput(new FileReader(xml));
+ parser.setInput(new FileInputStream(xml), "UTF-8"); //$NON-NLS-1$);
// set the resource ref to have correct view cookies
mBridgeInflater.setResourceReference(resource);
@@ -514,14 +513,13 @@ public final class BridgeContext extends Activity {
BridgeTypedArray ta = ((BridgeResources) mSystemResources).newTypeArray(attrs.length,
isPlatformFile);
- // resolve the defStyleAttr value into a IStyleResourceValue
- StyleResourceValue defStyleValues = null;
-
// look for a custom style.
String customStyle = null;
if (set != null) {
customStyle = set.getAttributeValue(null /* namespace*/, "style");
}
+
+ StyleResourceValue customStyleValues = null;
if (customStyle != null) {
ResourceValue item = mRenderResources.findResValue(customStyle,
false /*forceFrameworkOnly*/);
@@ -530,75 +528,76 @@ public final class BridgeContext extends Activity {
item = mRenderResources.resolveResValue(item);
if (item instanceof StyleResourceValue) {
- defStyleValues = (StyleResourceValue)item;
+ customStyleValues = (StyleResourceValue)item;
}
}
- if (defStyleValues == null) {
- if (defStyleAttr != 0) {
- // get the name from the int.
- String defStyleName = searchAttr(defStyleAttr);
+ // resolve the defStyleAttr value into a IStyleResourceValue
+ StyleResourceValue defStyleValues = null;
- if (defaultPropMap != null) {
- defaultPropMap.put("style", defStyleName);
- }
+ if (defStyleAttr != 0) {
+ // get the name from the int.
+ String defStyleName = searchAttr(defStyleAttr);
- // look for the style in the current theme, and its parent:
- ResourceValue item = mRenderResources.findItemInTheme(defStyleName);
+ if (defaultPropMap != null) {
+ defaultPropMap.put("style", defStyleName);
+ }
- if (item != null) {
- // item is a reference to a style entry. Search for it.
- item = mRenderResources.findResValue(item.getValue(),
- false /*forceFrameworkOnly*/);
+ // look for the style in the current theme, and its parent:
+ ResourceValue item = mRenderResources.findItemInTheme(defStyleName);
- if (item instanceof StyleResourceValue) {
- defStyleValues = (StyleResourceValue)item;
- }
- } else {
- Bridge.getLog().error(null,
- String.format(
- "Failed to find style '%s' in current theme", defStyleName),
- null /*data*/);
- }
- } else if (defStyleRes != 0) {
- Pair<ResourceType, String> value = Bridge.resolveResourceId(defStyleRes);
- if (value == null) {
- value = mProjectCallback.resolveResourceId(defStyleRes);
+ if (item != null) {
+ // item is a reference to a style entry. Search for it.
+ item = mRenderResources.findResValue(item.getValue(),
+ false /*forceFrameworkOnly*/);
+
+ if (item instanceof StyleResourceValue) {
+ defStyleValues = (StyleResourceValue)item;
}
+ } else {
+ Bridge.getLog().error(null,
+ String.format(
+ "Failed to find style '%s' in current theme", defStyleName),
+ null /*data*/);
+ }
+ } else if (defStyleRes != 0) {
+ Pair<ResourceType, String> value = Bridge.resolveResourceId(defStyleRes);
+ if (value == null) {
+ value = mProjectCallback.resolveResourceId(defStyleRes);
+ }
- if (value != null) {
- if (value.getFirst() == ResourceType.STYLE) {
- // look for the style in the current theme, and its parent:
- ResourceValue item = mRenderResources.findItemInTheme(value.getSecond());
- if (item != null) {
- if (item instanceof StyleResourceValue) {
- if (defaultPropMap != null) {
- defaultPropMap.put("style", item.getName());
- }
-
- defStyleValues = (StyleResourceValue)item;
+ if (value != null) {
+ if (value.getFirst() == ResourceType.STYLE) {
+ // look for the style in the current theme, and its parent:
+ ResourceValue item = mRenderResources.findItemInTheme(value.getSecond());
+ if (item != null) {
+ if (item instanceof StyleResourceValue) {
+ if (defaultPropMap != null) {
+ defaultPropMap.put("style", item.getName());
}
- } else {
- Bridge.getLog().error(null,
- String.format(
- "Style with id 0x%x (resolved to '%s') does not exist.",
- defStyleRes, value.getSecond()),
- null /*data*/);
+
+ defStyleValues = (StyleResourceValue)item;
}
} else {
Bridge.getLog().error(null,
String.format(
- "Resouce id 0x%x is not of type STYLE (instead %s)",
- defStyleRes, value.getFirst().toString()),
+ "Style with id 0x%x (resolved to '%s') does not exist.",
+ defStyleRes, value.getSecond()),
null /*data*/);
}
} else {
Bridge.getLog().error(null,
String.format(
- "Failed to find style with id 0x%x in current theme",
- defStyleRes),
+ "Resouce id 0x%x is not of type STYLE (instead %s)",
+ defStyleRes, value.getFirst().toString()),
null /*data*/);
}
+ } else {
+ Bridge.getLog().error(null,
+ String.format(
+ "Failed to find style with id 0x%x in current theme",
+ defStyleRes),
+ null /*data*/);
}
}
@@ -623,8 +622,13 @@ public final class BridgeContext extends Activity {
if (value == null) {
ResourceValue resValue = null;
- // look for the value in the defStyle first (and its parent if needed)
- if (defStyleValues != null) {
+ // look for the value in the custom style first (and its parent if needed)
+ if (customStyleValues != null) {
+ resValue = mRenderResources.findItemInStyle(customStyleValues, name);
+ }
+
+ // then look for the value in the default Style (and its parent if needed)
+ if (resValue == null && defStyleValues != null) {
resValue = mRenderResources.findItemInStyle(defStyleValues, name);
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeInflater.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeInflater.java
index d6bbebd..7c90a31 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeInflater.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeInflater.java
@@ -36,7 +36,7 @@ import android.view.View;
import android.view.ViewGroup;
import java.io.File;
-import java.io.FileReader;
+import java.io.FileInputStream;
/**
* Custom implementation of {@link LayoutInflater} to handle custom views.
@@ -177,7 +177,7 @@ public final class BridgeInflater extends LayoutInflater {
try {
KXmlParser parser = new KXmlParser();
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
- parser.setInput(new FileReader(f));
+ parser.setInput(new FileInputStream(f), "UTF-8"); //$NON-NLS-1$
BridgeXmlBlockParser bridgeParser = new BridgeXmlBlockParser(
parser, bridgeContext, false);
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeResources.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeResources.java
index 273e493..345f053 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeResources.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeResources.java
@@ -46,7 +46,6 @@ import android.view.ViewGroup.LayoutParams;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
-import java.io.FileReader;
import java.io.InputStream;
/**
@@ -244,7 +243,7 @@ public final class BridgeResources extends Resources {
// give that to our XmlBlockParser
parser = new KXmlParser();
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
- parser.setInput(new FileReader(xml));
+ parser.setInput(new FileInputStream(xml), "UTF-8"); //$NON-NLS-1$);
}
}
@@ -282,7 +281,7 @@ public final class BridgeResources extends Resources {
// give that to our XmlBlockParser
parser = new KXmlParser();
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
- parser.setInput(new FileReader(xml));
+ parser.setInput(new FileInputStream(xml), "UTF-8"); //$NON-NLS-1$);
return new BridgeXmlBlockParser(parser, mContext, mPlatformResourceFlag[0]);
}
@@ -501,7 +500,7 @@ public final class BridgeResources extends Resources {
try {
KXmlParser parser = new KXmlParser();
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
- parser.setInput(new FileReader(f));
+ parser.setInput(new FileInputStream(f), "UTF-8"); //$NON-NLS-1$);
return new BridgeXmlBlockParser(parser, mContext, mPlatformResourceFlag[0]);
} catch (XmlPullParserException e) {
@@ -536,7 +535,7 @@ public final class BridgeResources extends Resources {
try {
KXmlParser parser = new KXmlParser();
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
- parser.setInput(new FileReader(f));
+ parser.setInput(new FileInputStream(f), "UTF-8"); //$NON-NLS-1$);
return new BridgeXmlBlockParser(parser, mContext, mPlatformResourceFlag[0]);
} catch (XmlPullParserException e) {
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeTypedArray.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeTypedArray.java
index b9f769f..d4600a1 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeTypedArray.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeTypedArray.java
@@ -36,10 +36,11 @@ import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.util.DisplayMetrics;
import android.util.TypedValue;
+import android.view.LayoutInflater_Delegate;
import android.view.ViewGroup.LayoutParams;
import java.io.File;
-import java.io.FileReader;
+import java.io.FileInputStream;
import java.util.Arrays;
import java.util.Map;
@@ -315,7 +316,7 @@ public final class BridgeTypedArray extends TypedArray {
try {
KXmlParser parser = new KXmlParser();
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
- parser.setInput(new FileReader(f));
+ parser.setInput(new FileInputStream(f), "UTF-8"); //$NON-NLS-1$);
BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser(
parser, mContext, resValue.isFramework());
@@ -471,40 +472,23 @@ public final class BridgeTypedArray extends TypedArray {
*/
@Override
public int getDimensionPixelSize(int index, int defValue) {
- if (mResourceData[index] == null) {
- return defValue;
- }
+ try {
+ return getDimension(index);
+ } catch (RuntimeException e) {
+ if (mResourceData[index] != null) {
+ String s = mResourceData[index].getValue();
- String s = mResourceData[index].getValue();
+ if (s != null) {
+ // looks like we were unable to resolve the dimension value
+ Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT,
+ String.format(
+ "\"%1$s\" in attribute \"%2$s\" is not a valid format.",
+ s, mNames[index]), null /*data*/);
+ }
+ }
- if (s == null) {
- return defValue;
- } else if (s.equals(BridgeConstants.MATCH_PARENT) ||
- s.equals(BridgeConstants.FILL_PARENT)) {
- return LayoutParams.MATCH_PARENT;
- } else if (s.equals(BridgeConstants.WRAP_CONTENT)) {
- return LayoutParams.WRAP_CONTENT;
- } else if (RenderResources.REFERENCE_NULL.equals(s)) {
return defValue;
}
-
- if (ResourceHelper.stringToFloat(s, mValue)) {
- float f = mValue.getDimension(mBridgeResources.mMetrics);
-
- final int res = (int)(f+0.5f);
- if (res != 0) return res;
- if (f == 0) return 0;
- if (f > 0) return 1;
- return defValue; // this is basically unreachable.
- }
-
- // looks like we were unable to resolve the dimension value
- Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT,
- String.format(
- "\"%1$s\" in attribute \"%2$s\" is not a valid format.",
- s, mNames[index]), null /*data*/);
-
- return defValue;
}
/**
@@ -521,7 +505,20 @@ public final class BridgeTypedArray extends TypedArray {
*/
@Override
public int getLayoutDimension(int index, String name) {
- return getDimensionPixelSize(index, 0);
+ try {
+ // this will throw an exception
+ return getDimension(index);
+ } catch (RuntimeException e) {
+
+ if (LayoutInflater_Delegate.sIsInInclude) {
+ throw new RuntimeException();
+ }
+
+ Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT,
+ "You must supply a " + name + " attribute.", null);
+
+ return 0;
+ }
}
@Override
@@ -529,6 +526,36 @@ public final class BridgeTypedArray extends TypedArray {
return getDimensionPixelSize(index, defValue);
}
+ private int getDimension(int index) {
+ if (mResourceData[index] == null) {
+ throw new RuntimeException();
+ }
+
+ String s = mResourceData[index].getValue();
+
+ if (s == null) {
+ throw new RuntimeException();
+ } else if (s.equals(BridgeConstants.MATCH_PARENT) ||
+ s.equals(BridgeConstants.FILL_PARENT)) {
+ return LayoutParams.MATCH_PARENT;
+ } else if (s.equals(BridgeConstants.WRAP_CONTENT)) {
+ return LayoutParams.WRAP_CONTENT;
+ } else if (RenderResources.REFERENCE_NULL.equals(s)) {
+ throw new RuntimeException();
+ }
+
+ if (ResourceHelper.stringToFloat(s, mValue)) {
+ float f = mValue.getDimension(mBridgeResources.mMetrics);
+
+ final int res = (int)(f+0.5f);
+ if (res != 0) return res;
+ if (f == 0) return 0;
+ if (f > 0) return 1;
+ }
+
+ throw new RuntimeException();
+ }
+
/**
* Retrieve a fractional unit attribute at <var>index</var>.
*
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
index 0c4b0d3..060e6ee 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
@@ -73,7 +73,7 @@ abstract class CustomBar extends LinearLayout {
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
parser.setInput(
getClass().getResourceAsStream(layoutPath),
- "UTF8");
+ "UTF8"); //$NON-NLS-1$
BridgeXmlBlockParser bridgeParser = new BridgeXmlBlockParser(
parser, (BridgeContext) context, false /*platformFile*/);
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java
index 8e80c21..6194f5d 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java
@@ -29,6 +29,7 @@ import com.android.layoutlib.bridge.Bridge;
import com.android.layoutlib.bridge.android.BridgeContext;
import com.android.resources.ResourceType;
+import android.os.HandlerThread_Delegate;
import android.util.DisplayMetrics;
import java.util.concurrent.TimeUnit;
@@ -228,6 +229,10 @@ public abstract class RenderAction<T extends RenderParams> extends FrameworkReso
private void tearDown() {
// Make sure to remove static references, otherwise we could not unload the lib
mContext.disposeResources();
+
+ // quit HandlerThread created during this session.
+ HandlerThread_Delegate.cleanUp(sCurrentContext);
+
sCurrentContext = null;
Bridge.setLog(null);
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java
index 96ab30f..e5efa4e 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java
@@ -44,7 +44,6 @@ import android.util.TypedValue;
import java.io.File;
import java.io.FileInputStream;
-import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
@@ -124,7 +123,7 @@ public final class ResourceHelper {
// providing an XmlPullParser
KXmlParser parser = new KXmlParser();
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
- parser.setInput(new FileReader(f));
+ parser.setInput(new FileInputStream(f), "UTF-8"); //$NON-NLS-1$);
BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser(
parser, context, resValue.isFramework());
@@ -206,7 +205,7 @@ public final class ResourceHelper {
// let the framework inflate the Drawable from the XML file.
KXmlParser parser = new KXmlParser();
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
- parser.setInput(new FileReader(f));
+ parser.setInput(new FileInputStream(f), "UTF-8"); //$NON-NLS-1$);
BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser(
parser, context, value.isFramework());
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java
index 3252fb4..70d5446 100644
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java
+++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java
@@ -44,7 +44,7 @@ public class BridgeXmlBlockParserTest extends TestCase {
InputStream input = this.getClass().getClassLoader().getResourceAsStream(
"com/android/layoutlib/testdata/layout1.xml");
- parser.setInput(input, null /*encoding*/);
+ parser.setInput(input, "UTF-8"); //$NON-NLS-1$
assertEquals(XmlPullParser.START_DOCUMENT, parser.next());
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
index eff6bbc..5c60318 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
@@ -99,8 +99,10 @@ public final class CreateInfo implements ICreateInfo {
"android.content.res.Resources$Theme#resolveAttribute",
"android.graphics.BitmapFactory#finishDecode",
"android.os.Handler#sendMessageAtTime",
+ "android.os.HandlerThread#run",
"android.os.Build#getString",
"android.view.LayoutInflater#rInflate",
+ "android.view.LayoutInflater#parseInclude",
"android.view.View#isInEditMode",
"com.android.internal.util.XmlUtils#convertValueToInt",
// TODO: comment out once DelegateClass is working