Merge "Cleanup and refactoring." into graphics-dev
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index 08d94e2..b4c38db 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -535,21 +535,6 @@
}
/**
- * If WebView only supports touch, a different navigation model will be
- * applied. Otherwise, the navigation to support both touch and keyboard
- * will be used.
- * @hide
- public void setSupportTouchOnly(boolean touchOnly) {
- mSupportTounchOnly = touchOnly;
- }
- */
-
- boolean supportTouchOnly() {
- // for debug only, use mLightTouchEnabled for mSupportTounchOnly
- return mLightTouchEnabled;
- }
-
- /**
* Set whether the WebView supports zoom
*/
public void setSupportZoom(boolean support) {
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 15b47e3..168baad 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -92,6 +92,7 @@
import android.webkit.WebViewCore.EventHub;
import android.webkit.WebViewCore.TouchEventData;
import android.webkit.WebViewCore.TouchHighlightData;
+import android.webkit.WebViewCore.WebKitHitTest;
import android.widget.AbsoluteLayout;
import android.widget.Adapter;
import android.widget.AdapterView;
@@ -699,7 +700,7 @@
private Drawable mSelectHandleLeft;
private Drawable mSelectHandleRight;
- static final boolean USE_WEBKIT_RINGS = false;
+ static boolean sDisableNavcache = false;
// the color used to highlight the touch rectangles
private static final int HIGHLIGHT_COLOR = 0x6633b5e5;
// the round corner for the highlight path
@@ -775,7 +776,7 @@
static final int REQUEST_KEYBOARD_WITH_SELECTION_MSG_ID = 128;
static final int SET_SCROLLBAR_MODES = 129;
static final int SELECTION_STRING_CHANGED = 130;
- static final int SET_TOUCH_HIGHLIGHT_RECTS = 131;
+ static final int HIT_TEST_RESULT = 131;
static final int SAVE_WEBARCHIVE_FINISHED = 132;
static final int SET_AUTOFILLABLE = 133;
@@ -788,7 +789,7 @@
static final int UPDATE_ZOOM_DENSITY = 139;
private static final int FIRST_PACKAGE_MSG_ID = SCROLL_TO_MSG_ID;
- private static final int LAST_PACKAGE_MSG_ID = SET_TOUCH_HIGHLIGHT_RECTS;
+ private static final int LAST_PACKAGE_MSG_ID = HIT_TEST_RESULT;
static final String[] HandlerPrivateDebugString = {
"REMEMBER_PASSWORD", // = 1;
@@ -1311,6 +1312,7 @@
private void init() {
OnTrimMemoryListener.init(getContext());
+ sDisableNavcache = nativeDisableNavcache();
setWillNotDraw(false);
setFocusable(true);
@@ -2618,8 +2620,8 @@
}
private HitTestResult hitTestResult(HitTestResult fallback) {
- if (mNativeClass == 0) {
- return null;
+ if (mNativeClass == 0 || sDisableNavcache) {
+ return fallback;
}
HitTestResult result = new HitTestResult();
@@ -4376,7 +4378,7 @@
|| mTouchMode == TOUCH_SHORTPRESS_MODE
|| mTouchMode == TOUCH_DONE_MODE);
boolean drawNativeRings = !drawJavaRings;
- if (USE_WEBKIT_RINGS) {
+ if (sDisableNavcache) {
drawNativeRings = !drawJavaRings && !isInTouchMode();
}
drawContent(canvas, drawNativeRings);
@@ -4431,8 +4433,8 @@
}
private void removeTouchHighlight() {
- mWebViewCore.removeMessages(EventHub.GET_TOUCH_HIGHLIGHT_RECTS);
- mPrivateHandler.removeMessages(SET_TOUCH_HIGHLIGHT_RECTS);
+ mWebViewCore.removeMessages(EventHub.HIT_TEST);
+ mPrivateHandler.removeMessages(HIT_TEST_RESULT);
setTouchHighlightRects(null);
}
@@ -6198,7 +6200,7 @@
nativeSetIsScrolling(false);
} else if (mPrivateHandler.hasMessages(RELEASE_SINGLE_TAP)) {
mPrivateHandler.removeMessages(RELEASE_SINGLE_TAP);
- if (USE_WEBKIT_RINGS || getSettings().supportTouchOnly()) {
+ if (sDisableNavcache) {
removeTouchHighlight();
}
if (deltaX * deltaX + deltaY * deltaY < mDoubleTapSlopSquare) {
@@ -6222,7 +6224,7 @@
mWebViewCore.sendMessage(
EventHub.UPDATE_FRAME_CACHE_IF_LOADING);
}
- if (USE_WEBKIT_RINGS || getSettings().supportTouchOnly()) {
+ if (sDisableNavcache) {
TouchHighlightData data = new TouchHighlightData();
data.mX = contentX;
data.mY = contentY;
@@ -6234,7 +6236,7 @@
if (!mBlockWebkitViewMessages) {
mTouchHighlightRequested = System.currentTimeMillis();
mWebViewCore.sendMessageAtFrontOfQueue(
- EventHub.GET_TOUCH_HIGHLIGHT_RECTS, data);
+ EventHub.HIT_TEST, data);
}
if (DEBUG_TOUCH_HIGHLIGHT) {
if (getSettings().getNavDump()) {
@@ -6322,7 +6324,7 @@
if (mTouchMode == TOUCH_DOUBLE_TAP_MODE) {
mTouchMode = TOUCH_INIT_MODE;
}
- if (USE_WEBKIT_RINGS || getSettings().supportTouchOnly()) {
+ if (sDisableNavcache) {
removeTouchHighlight();
}
}
@@ -6924,7 +6926,7 @@
mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS);
mPrivateHandler.removeMessages(DRAG_HELD_MOTIONLESS);
mPrivateHandler.removeMessages(AWAKEN_SCROLL_BARS);
- if (USE_WEBKIT_RINGS || getSettings().supportTouchOnly()) {
+ if (sDisableNavcache) {
removeTouchHighlight();
}
mHeldMotionless = MOTIONLESS_TRUE;
@@ -7481,7 +7483,7 @@
* and calls showCursorTimed on the native side
*/
private void updateSelection() {
- if (mNativeClass == 0) {
+ if (mNativeClass == 0 || sDisableNavcache) {
return;
}
mPrivateHandler.removeMessages(UPDATE_SELECTION);
@@ -7589,7 +7591,7 @@
int contentX = viewToContentX(mLastTouchX + mScrollX);
int contentY = viewToContentY(mLastTouchY + mScrollY);
int slop = viewToContentDimension(mNavSlop);
- if (USE_WEBKIT_RINGS && !mTouchHighlightRegion.isEmpty()) {
+ if (sDisableNavcache && !mTouchHighlightRegion.isEmpty()) {
// set mTouchHighlightRequested to 0 to cause an immediate
// drawing of the touch rings
mTouchHighlightRequested = 0;
@@ -7601,8 +7603,7 @@
}
}, ViewConfiguration.getPressedStateDuration());
}
- if (getSettings().supportTouchOnly()) {
- removeTouchHighlight();
+ if (sDisableNavcache) {
WebViewCore.TouchUpData touchUpData = new WebViewCore.TouchUpData();
// use "0" as generation id to inform WebKit to use the same x/y as
// it used when processing GET_TOUCH_HIGHLIGHT_RECTS
@@ -8487,9 +8488,8 @@
break;
}
case SWITCH_TO_SHORTPRESS: {
- mInitialHitTestResult = null; // set by updateSelection()
if (mTouchMode == TOUCH_INIT_MODE) {
- if (!getSettings().supportTouchOnly()
+ if (!sDisableNavcache
&& mPreventDefault != PREVENT_DEFAULT_YES) {
mTouchMode = TOUCH_SHORTPRESS_START_MODE;
updateSelection();
@@ -8504,7 +8504,7 @@
break;
}
case SWITCH_TO_LONGPRESS: {
- if (USE_WEBKIT_RINGS || getSettings().supportTouchOnly()) {
+ if (sDisableNavcache) {
removeTouchHighlight();
}
if (inFullScreenMode() || mDeferTouchProcess) {
@@ -8835,10 +8835,16 @@
}
break;
- case SET_TOUCH_HIGHLIGHT_RECTS:
- @SuppressWarnings("unchecked")
- ArrayList<Rect> rects = (ArrayList<Rect>) msg.obj;
- setTouchHighlightRects(rects);
+ case HIT_TEST_RESULT:
+ WebKitHitTest hit = (WebKitHitTest) msg.obj;
+ setTouchHighlightRects(hit != null ? hit.mTouchRects : null);
+ if (hit == null) {
+ mInitialHitTestResult = null;
+ } else {
+ mInitialHitTestResult = new HitTestResult();
+ mInitialHitTestResult.mType = hit.mType;
+ mInitialHitTestResult.mExtra = hit.mExtra;
+ }
break;
case SAVE_WEBARCHIVE_FINISHED:
@@ -8875,7 +8881,7 @@
}
}
- private void setTouchHighlightRects(ArrayList<Rect> rects) {
+ private void setTouchHighlightRects(Rect[] rects) {
invalidate(mTouchHighlightRegion.getBounds());
mTouchHighlightRegion.setEmpty();
if (rects != null) {
@@ -9793,4 +9799,5 @@
*/
private static native void nativeOnTrimMemory(int level);
private static native void nativeSetPauseDrawing(int instance, boolean pause);
+ private static native boolean nativeDisableNavcache();
}
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index 95533c6..824f556 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -860,6 +860,12 @@
Rect mNativeLayerRect;
}
+ static class WebKitHitTest {
+ int mType;
+ String mExtra;
+ Rect[] mTouchRects;
+ }
+
static class AutoFillData {
public AutoFillData() {
mQueryId = WebTextView.FORM_NOT_AUTOFILLABLE;
@@ -1072,7 +1078,7 @@
static final int ADD_PACKAGE_NAME = 185;
static final int REMOVE_PACKAGE_NAME = 186;
- static final int GET_TOUCH_HIGHLIGHT_RECTS = 187;
+ static final int HIT_TEST = 187;
// accessibility support
static final int MODIFY_SELECTION = 190;
@@ -1550,7 +1556,7 @@
break;
case MODIFY_SELECTION:
- String modifiedSelectionString =
+ String modifiedSelectionString =
nativeModifySelection(mNativeClass, msg.arg1,
msg.arg2);
mWebView.mPrivateHandler.obtainMessage(WebView.SELECTION_STRING_CHANGED,
@@ -1671,16 +1677,16 @@
(Set<String>) msg.obj);
break;
- case GET_TOUCH_HIGHLIGHT_RECTS:
+ case HIT_TEST:
TouchHighlightData d = (TouchHighlightData) msg.obj;
if (d.mNativeLayer != 0) {
nativeScrollLayer(mNativeClass,
d.mNativeLayer, d.mNativeLayerRect);
}
- ArrayList<Rect> rects = nativeGetTouchHighlightRects
- (mNativeClass, d.mX, d.mY, d.mSlop);
+ WebKitHitTest hit = nativeHitTest(mNativeClass,
+ d.mX, d.mY, d.mSlop);
mWebView.mPrivateHandler.obtainMessage(
- WebView.SET_TOUCH_HIGHLIGHT_RECTS, rects)
+ WebView.HIT_TEST_RESULT, hit)
.sendToTarget();
break;
@@ -2335,9 +2341,9 @@
}
// remove the touch highlight when moving to a new page
- if (WebView.USE_WEBKIT_RINGS || getSettings().supportTouchOnly()) {
+ if (WebView.sDisableNavcache) {
mWebView.mPrivateHandler.sendEmptyMessage(
- WebView.SET_TOUCH_HIGHLIGHT_RECTS);
+ WebView.HIT_TEST_RESULT);
}
// reset the scroll position, the restored offset and scales
@@ -2927,8 +2933,7 @@
private native boolean nativeValidNodeAndBounds(int nativeClass, int frame,
int node, Rect bounds);
- private native ArrayList<Rect> nativeGetTouchHighlightRects(int nativeClass,
- int x, int y, int slop);
+ private native WebKitHitTest nativeHitTest(int nativeClass, int x, int y, int slop);
private native void nativeAutoFillForm(int nativeClass, int queryId);
private native void nativeScrollLayer(int nativeClass, int layer, Rect rect);
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
index 0580ebc..d375d4c 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
@@ -249,8 +249,6 @@
sleep(SHORT_TIMEOUT);
removeConfiguredNetworksAndDisableWifi();
mWifiRegexs = mCM.getTetherableWifiRegexs();
- // after wifi is shutdown, wait for 2 minute to enable wifi
- sleep(WIFI_STOP_START_INTERVAL);
}
public List<WifiConfiguration> loadNetworkConfigurations() throws Exception {
diff --git a/docs/html/guide/topics/wireless/bluetooth.jd b/docs/html/guide/topics/wireless/bluetooth.jd
index e4c6e1b..76da08e 100644
--- a/docs/html/guide/topics/wireless/bluetooth.jd
+++ b/docs/html/guide/topics/wireless/bluetooth.jd
@@ -29,6 +29,7 @@
<li><a href="#Profiles">Working with Profiles</a>
<ol>
<li><a href="#AT-Commands">Vendor-specific AT commands</a>
+ <li><a href="#HDP">Health Device Profile</a>
</ol></li>
</ol>
@@ -43,6 +44,7 @@
<h2>Related samples</h2>
<ol>
<li><a href="{@docRoot}resources/samples/BluetoothChat/index.html">Bluetooth Chat</a></li>
+ <li><a href="{@docRoot}resources/samples/BluetoothHDP/index.html">Bluetooth HDP (Health Device Profile)</a></li>
</ol>
</div>
@@ -132,11 +134,27 @@
audio can be streamed from one device to another over a Bluetooth connection.
"A2DP" stands for Advanced Audio Distribution Profile.</dd>
-<dt>{@link android.bluetooth.BluetoothProfile.ServiceListener}</dt>
+<dt>{@link android.bluetooth.BluetoothHealth}</dt>
+<dd> Represents a Health Device Profile proxy that controls the Bluetooth service.</dd>
+
+<dt>{@link android.bluetooth.BluetoothHealthCallback}</dt>
+
+<dd>An abstract class that you use to implement {@link
+android.bluetooth.BluetoothHealth} callbacks. You must extend this class and
+implement the callback methods to receive updates about changes in the
+application’s registration state and Bluetooth channel state.</dd>
+
+<dt>{@link android.bluetooth.BluetoothHealthAppConfiguration}</dt>
+
+<dd>Represents an application configuration that the Bluetooth Health third-party
+application registers to communicate with a remote Bluetooth health
+device.</dd>
+
+<dt>{@link android.bluetooth.BluetoothProfile.ServiceListener}</dt>
<dd>An interface that notifies {@link android.bluetooth.BluetoothProfile} IPC
clients when they have been connected to or disconnected from the service (that
-is, the internal service that runs a particular profile). </dd>
+is, the internal service that runs a particular profile). </dd>
</dl>
@@ -889,7 +907,7 @@
href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#IPC">IPC</a
>). This includes both Bluetooth Headset and Hands-Free (v1.5) profiles. The
{@link android.bluetooth.BluetoothHeadset} class includes support for AT commands.
-For more discussion of this topic, see <a href="#AT-Commands">Vendor-specific AT commands</a></li>
+For more discussion of this topic, see <a href="#AT-Commands">Vendor-specific AT commands</a></li>
<li><strong>A2DP</strong>. The Advanced Audio Distribution Profile (A2DP)
profile defines how high quality audio can be streamed from one device to
@@ -897,6 +915,17 @@
android.bluetooth.BluetoothA2dp} class, which is a proxy for controlling
the Bluetooth A2DP Service via IPC.</li>
+ <li><strong>Health Device</strong>. Android 4.0 (API level 14) introduces
+support for the Bluetooth Health Device Profile (HDP). This lets you create
+applications that use Bluetooth to communicate with health devices that support
+Bluetooth, such as heart-rate monitors, blood meters, thermometers, scales, and
+so on. For a list of supported devices and their corresponding device data
+specialization codes, refer to <strong>Bluetooth Assigned Numbers</strong> at <a
+href="http://www.bluetooth.org">www.bluetooth.org</a>. Note that these values
+are also referenced in the ISO/IEEE 11073-20601 [7] specification as
+MDC_DEV_SPEC_PROFILE_* in the Nomenclature Codes Annex. For more discussion of
+HDP, see <a href="#HDP">Health Device Profile</a>.</li>
+
</ul>
<p>Here are the basic steps for working with a profile:</p>
@@ -926,7 +955,9 @@
state of the connection and perform other operations that are relevant to that
profile.</li>
</ol>
-<p> For example, this code snippet shows how to connect to a {@link android.bluetooth.BluetoothHeadset} proxy object so that you can control the
+
+<p> For example, this code snippet shows how to connect to a {@link
+android.bluetooth.BluetoothHeadset} proxy object so that you can control the
Headset profile:</p>
<pre>BluetoothHeadset mBluetoothHeadset;
@@ -956,6 +987,8 @@
mBluetoothAdapter.closeProfileProxy(mBluetoothHeadset);
</pre>
+
+
<h3 id="AT-Commands">Vendor-specific AT commands</h3>
<p>Starting in Android 3.0, applications can register to receive system
@@ -965,3 +998,81 @@
user or take other action as needed. Create a broadcast receiver for the {@link
android.bluetooth.BluetoothHeadset#ACTION_VENDOR_SPECIFIC_HEADSET_EVENT} intent
to handle vendor-specific AT commands for the headset.</p>
+
+<h3 id="HDP">Health Device Profile</h3>
+
+<p>Android 4.0 (API level 14) introduces support for the Bluetooth Health Device
+Profile (HDP). This lets you create applications that use Bluetooth to
+communicate with health devices that support Bluetooth, such as heart-rate
+monitors, blood meters, thermometers, and scales. The Bluetooth Health API
+includes the classes {@link android.bluetooth.BluetoothHealth}, {@link
+android.bluetooth.BluetoothHealthCallback}, and {@link
+android.bluetooth.BluetoothHealthAppConfiguration}, which are described in <a
+href="#TheBasics">The Basics</a>. </p>
+
+<p>In using the Bluetooth Health API, it's helpful to understand these key HDP concepts:</p>
+<table>
+ <tr>
+ <th>Concept</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td><strong>Source</strong></td>
+
+ <td>A role defined in HDP. A <em>source</em> is a health device that
+transmits medical data (weight scale, glucose meter, thermometer, etc.) to a
+smart device such as an Android phone or tablet. </td>
+ </tr>
+ <tr>
+ <td><strong>Sink</strong></td>
+
+ <td>A role defined in HDP. In HDP, a <em>sink</em> is the smart device that
+receives the medical data. In an Android HDP application, the sink is
+represented by a {@link android.bluetooth.BluetoothHealthAppConfiguration}
+object.</td>
+ </tr>
+ <tr>
+ <td><strong>Registration</strong></td>
+ <td>Refers to registering a sink for a particular health device.</td>
+ </tr>
+ <tr>
+ <td><strong>Connection</strong></td>
+
+ <td>Refers to opening a channel between a health device and a smart device
+such as an Android phone or tablet.</td>
+ </tr>
+</table>
+
+<h4>Creating an HDP Application</h4>
+
+<p>Here are the basic steps involved in creating an Android HDP application:</p>
+<ol>
+
+ <li>Get a reference to the {@link android.bluetooth.BluetoothHealth} proxy
+object. <p>Similar to regular headset and A2DP profile devices, you must call
+{@link android.bluetooth.BluetoothAdapter#getProfileProxy getProfileProxy()}
+with a {@link android.bluetooth.BluetoothProfile.ServiceListener} and the {@link
+android.bluetooth.BluetoothProfile.ServiceListener#HEALTH} profile type to
+establish a connection with the profile proxy object.</p> </li>
+
+ <li>Create a {@link android.bluetooth.BluetoothHealthCallback} and register an
+application configuration
+({@link android.bluetooth.BluetoothHealthAppConfiguration})
+that acts as a health
+sink.</li>
+
+ <li>Establish a connection to a health device. Some devices will initiate the
+connection. It is unnecessary to carry out this step for those devices.</li>
+
+ <li>When connected successfully to a health device, read/write to the health
+device using the file descriptor. <p>The received data needs to be interpreted
+using a health manager which implements the IEEE 11073-xxxxx
+specifications.</p></li>
+
+ <li>When done, close the health channel and unregister the application. The
+channel also closes when there is extended inactivity.</li>
+</ol>
+
+<p>For a complete code sample that illustrates these steps, see <a
+href="{@docRoot}resources/samples/BluetoothHDP/index.html">Bluetooth HDP (Health
+Device Profile)</a>. </p>
diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ImageProcessingTest.java b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ImageProcessingTest.java
index d2298da..f96e68b 100644
--- a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ImageProcessingTest.java
+++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ImageProcessingTest.java
@@ -41,6 +41,7 @@
public class ImageProcessingTest extends ActivityInstrumentationTestCase2<ImageProcessingActivity> {
private final String TAG = "ImageProcessingTest";
private final String RESULT_FILE = "image_processing_result.txt";
+ private int ITERATION = 5;
private ImageProcessingActivity mAct;
public ImageProcessingTest() {
@@ -63,9 +64,8 @@
*/
@LargeTest
public void testImageProcessingBench() {
- long t = mAct.getBenchmark();
- Log.v(TAG, "t = " + t);
-
+ long t = 0;
+ long sum = 0;
// write result into a file
File externalStorage = Environment.getExternalStorageDirectory();
if (!externalStorage.canWrite()) {
@@ -75,10 +75,18 @@
File resultFile = new File(externalStorage, RESULT_FILE);
resultFile.setWritable(true, false);
try {
- BufferedWriter results = new BufferedWriter(new FileWriter(resultFile));
- results.write("Renderscript frame time core: " + t + " ms");
- results.close();
+ BufferedWriter rsWriter = new BufferedWriter(new FileWriter(resultFile));
Log.v(TAG, "Saved results in: " + resultFile.getAbsolutePath());
+ for (int i = 0; i < ITERATION; i++ ) {
+ t = mAct.getBenchmark();
+ sum += t;
+ rsWriter.write("Renderscript frame time core: " + t + " ms\n");
+ Log.v(TAG, "RenderScript framew time core: " + t + " ms");
+ }
+ long avgValue = sum/ITERATION;
+ rsWriter.write("Averge frame time: " + avgValue + " ms\n");
+ Log.v(TAG, "Average frame time: " + avgValue + " ms");
+ rsWriter.close();
} catch (IOException e) {
Log.v(TAG, "Unable to write result file " + e.getMessage());
}