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());
         }