Merge "Part of fix for bug 8629392: CTS test failures" into jb-mr2-dev
diff --git a/tests/src/android/renderscript/cts/global_sync.rs b/tests/src/android/renderscript/cts/global_sync.rs
new file mode 100644
index 0000000..c947fa2
--- /dev/null
+++ b/tests/src/android/renderscript/cts/global_sync.rs
@@ -0,0 +1,32 @@
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+int gInt;
+static int sInt;
+
+rs_allocation aFailed;
+
+void test_global(int expected) {
+    if (gInt != expected) {
+        rsSetElementAt_uchar(aFailed, 1, 0);
+    }
+}
+
+void test_static_global(int expected) {
+    if (sInt != expected) {
+        rsSetElementAt_uchar(aFailed, 1, 0);
+    }
+}
+
+void __attribute__((kernel)) write_global(int ain, uint32_t x) {
+    if (x == 0) {
+        gInt = ain;
+    }
+}
+
+void __attribute__((kernel)) write_static_global(int ain, uint32_t x) {
+    if (x == 0) {
+        sInt = ain;
+    }
+}
+
diff --git a/tests/src/android/renderscript/cts/large_global.rs b/tests/src/android/renderscript/cts/large_global.rs
new file mode 100644
index 0000000..3f2da69
--- /dev/null
+++ b/tests/src/android/renderscript/cts/large_global.rs
@@ -0,0 +1,24 @@
+// Copyright (C) 2013 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.
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+char buf[2*1024*1024];
+
+// Never called, just present to ensure that buf does not get optimized away.
+void __attribute__((kernel)) root(char c) {
+    buf[0] = c;
+}
+
diff --git a/tests/tests/media/res/raw/loudsoftaac.aac b/tests/tests/media/res/raw/loudsoftaac.aac
new file mode 100644
index 0000000..1534ef2
--- /dev/null
+++ b/tests/tests/media/res/raw/loudsoftaac.aac
Binary files differ
diff --git a/tests/tests/media/res/raw/loudsoftfaac.m4a b/tests/tests/media/res/raw/loudsoftfaac.m4a
new file mode 100644
index 0000000..b4895b5
--- /dev/null
+++ b/tests/tests/media/res/raw/loudsoftfaac.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/loudsoftitunes.m4a b/tests/tests/media/res/raw/loudsoftitunes.m4a
new file mode 100644
index 0000000..b01b36b
--- /dev/null
+++ b/tests/tests/media/res/raw/loudsoftitunes.m4a
Binary files differ
diff --git a/tests/tests/media/res/raw/loudsoftmp3.mp3 b/tests/tests/media/res/raw/loudsoftmp3.mp3
new file mode 100644
index 0000000..b32c8bd
--- /dev/null
+++ b/tests/tests/media/res/raw/loudsoftmp3.mp3
Binary files differ
diff --git a/tests/tests/media/res/raw/loudsoftogg.ogg b/tests/tests/media/res/raw/loudsoftogg.ogg
new file mode 100644
index 0000000..dc122d9
--- /dev/null
+++ b/tests/tests/media/res/raw/loudsoftogg.ogg
Binary files differ
diff --git a/tests/tests/media/res/raw/loudsoftwav.wav b/tests/tests/media/res/raw/loudsoftwav.wav
new file mode 100644
index 0000000..9930dcb
--- /dev/null
+++ b/tests/tests/media/res/raw/loudsoftwav.wav
Binary files differ
diff --git a/tests/tests/media/src/android/media/cts/DecoderTest.java b/tests/tests/media/src/android/media/cts/DecoderTest.java
index 54a670d..ab7410b 100644
--- a/tests/tests/media/src/android/media/cts/DecoderTest.java
+++ b/tests/tests/media/src/android/media/cts/DecoderTest.java
@@ -30,17 +30,37 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.nio.ByteBuffer;
+import java.util.Arrays;
 import java.util.zip.CRC32;
 
 public class DecoderTest extends MediaPlayerTestBase {
     private static final String TAG = "DecoderTest";
 
     private Resources mResources;
+    short[] mMasterBuffer;
 
     @Override
     protected void setUp() throws Exception {
         super.setUp();
         mResources = mContext.getResources();
+
+        // read master file into memory
+        AssetFileDescriptor masterFd = mResources.openRawResourceFd(R.raw.sinesweepraw);
+        long masterLength = masterFd.getLength();
+        mMasterBuffer = new short[(int) (masterLength / 2)];
+        InputStream is = masterFd.createInputStream();
+        BufferedInputStream bis = new BufferedInputStream(is);
+        for (int i = 0; i < mMasterBuffer.length; i++) {
+            int lo = bis.read();
+            int hi = bis.read();
+            if (hi >= 128) {
+                hi -= 256;
+            }
+            int sample = hi * 256 + lo;
+            mMasterBuffer[i] = (short) sample;
+        }
+        bis.close();
+        masterFd.close();
     }
 
     // The allowed errors in the following tests are the actual maximum measured
@@ -48,22 +68,22 @@
     // This should allow for some variation in decoders, while still detecting
     // phase and delay errors, channel swap, etc.
     public void testDecodeMp3Lame() throws Exception {
-        decode(R.raw.sinesweepmp3lame, R.raw.sinesweepraw, 804.f);
+        decode(R.raw.sinesweepmp3lame, 804.f);
     }
     public void testDecodeMp3Smpb() throws Exception {
-        decode(R.raw.sinesweepmp3smpb, R.raw.sinesweepraw, 413.f);
+        decode(R.raw.sinesweepmp3smpb, 413.f);
     }
     public void testDecodeM4a() throws Exception {
-        decode(R.raw.sinesweepm4a, R.raw.sinesweepraw, 124.f);
+        decode(R.raw.sinesweepm4a, 124.f);
     }
     public void testDecodeOgg() throws Exception {
-        decode(R.raw.sinesweepogg, R.raw.sinesweepraw, 168.f);
+        decode(R.raw.sinesweepogg, 168.f);
     }
     public void testDecodeWav() throws Exception {
-        decode(R.raw.sinesweepwav, R.raw.sinesweepraw, 0.0f);
+        decode(R.raw.sinesweepwav, 0.0f);
     }
     public void testDecodeFlac() throws Exception {
-        decode(R.raw.sinesweepflac, R.raw.sinesweepraw, 0.0f);
+        decode(R.raw.sinesweepflac, 0.0f);
     }
 
     /**
@@ -72,25 +92,30 @@
      * @param maxerror the maximum allowed root mean squared error
      * @throws IOException
      */
-    private void decode(int testinput, int master, float maxerror) throws IOException {
+    private void decode(int testinput, float maxerror) throws IOException {
 
-        // read master file into memory
-        AssetFileDescriptor masterFd = mResources.openRawResourceFd(master);
-        long masterLength = masterFd.getLength();
-        short[] masterBuffer = new short[(int) (masterLength / 2)];
-        InputStream is = masterFd.createInputStream();
-        BufferedInputStream bis = new BufferedInputStream(is);
-        for (int i = 0; i < masterBuffer.length; i++) {
-            int lo = bis.read();
-            int hi = bis.read();
-            if (hi >= 128) {
-                hi -= 256;
-            }
-            int sample = hi * 256 + lo;
-            masterBuffer[i] = (short) sample;
+        short [] decoded = decodeToMemory(testinput);
+
+        assertEquals("wrong data size", mMasterBuffer.length, decoded.length);
+
+        long totalErrorSquared = 0;
+
+        for (int i = 0; i < decoded.length; i++) {
+            short sample = decoded[i];
+            short mastersample = mMasterBuffer[i];
+            int d = sample - mastersample;
+            totalErrorSquared += d * d;
         }
-        bis.close();
-        masterFd.close();
+
+        long avgErrorSquared = (totalErrorSquared / decoded.length);
+        double rmse = Math.sqrt(avgErrorSquared);
+        assertTrue("decoding error too big: " + rmse, rmse <= maxerror);
+     }
+
+    private short[] decodeToMemory(int testinput) throws IOException {
+
+        short [] decoded = new short[1024];
+        int decodedIdx = 0;
 
         AssetFileDescriptor testFd = mResources.openRawResourceFd(testinput);
 
@@ -118,9 +143,6 @@
         extractor.selectTrack(0);
 
         // start decoding
-        int numBytesDecoded = 0;
-        int maxdelta = 0;
-        long totalErrorSquared = 0;
         final long kTimeOutUs = 5000;
         MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
         boolean sawInputEOS = false;
@@ -164,17 +186,13 @@
                 int outputBufIndex = res;
                 ByteBuffer buf = codecOutputBuffers[outputBufIndex];
 
-                // check the waveform matches within the specified max error
-                for (int i = 0; i < info.size; i += 2) {
-                    short sample = buf.getShort(i);
-                    int idx = (numBytesDecoded + i) / 2;
-                    assertTrue("decoder returned too much data", idx < masterBuffer.length);
-                    short mastersample = masterBuffer[idx];
-                    int d = sample - mastersample;
-                    totalErrorSquared += d * d;
+                if (decodedIdx + (info.size / 2) >= decoded.length) {
+                    decoded = Arrays.copyOf(decoded, decodedIdx + (info.size / 2));
                 }
 
-                numBytesDecoded += info.size;
+                for (int i = 0; i < info.size; i += 2) {
+                    decoded[decodedIdx++] = buf.getShort(i);
+                }
 
                 codec.releaseOutputBuffer(outputBufIndex, false /* render */);
 
@@ -195,11 +213,7 @@
 
         codec.stop();
         codec.release();
-
-        assertEquals("wrong data size", masterLength, numBytesDecoded);
-        long avgErrorSquared = (totalErrorSquared / (numBytesDecoded / 2));
-        double rmse = Math.sqrt(avgErrorSquared); 
-        assertTrue("decoding error too big: " + rmse, rmse <= maxerror);
+        return decoded;
     }
 
     public void testCodecBasicH264() throws Exception {
@@ -691,5 +705,110 @@
         return crc.getValue();
     }
 
+    public void testFlush() throws Exception {
+        testFlush(R.raw.loudsoftwav);
+        testFlush(R.raw.loudsoftogg);
+        testFlush(R.raw.loudsoftmp3);
+        testFlush(R.raw.loudsoftaac);
+        testFlush(R.raw.loudsoftfaac);
+        testFlush(R.raw.loudsoftitunes);
+    }
+
+    private void testFlush(int resource) throws Exception {
+
+        AssetFileDescriptor testFd = mResources.openRawResourceFd(resource);
+
+        MediaExtractor extractor;
+        MediaCodec codec;
+        ByteBuffer[] codecInputBuffers;
+        ByteBuffer[] codecOutputBuffers;
+
+        extractor = new MediaExtractor();
+        extractor.setDataSource(testFd.getFileDescriptor(), testFd.getStartOffset(),
+                testFd.getLength());
+        testFd.close();
+
+        assertEquals("wrong number of tracks", 1, extractor.getTrackCount());
+        MediaFormat format = extractor.getTrackFormat(0);
+        String mime = format.getString(MediaFormat.KEY_MIME);
+        assertTrue("not an audio file", mime.startsWith("audio/"));
+
+        codec = MediaCodec.createDecoderByType(mime);
+        codec.configure(format, null /* surface */, null /* crypto */, 0 /* flags */);
+        codec.start();
+        codecInputBuffers = codec.getInputBuffers();
+        codecOutputBuffers = codec.getOutputBuffers();
+
+        extractor.selectTrack(0);
+
+        // decode a bit of the first part of the file, and verify the amplitude
+        short maxvalue1 = getAmplitude(extractor, codec);
+
+        // flush the codec and seek the extractor a different position, then decode a bit more
+        // and check the amplitude
+        extractor.seekTo(8000000, 0);
+        codec.flush();
+        short maxvalue2 = getAmplitude(extractor, codec);
+
+        assertTrue(maxvalue1 > 20000);
+        assertTrue(maxvalue2 < 5000);
+        codec.stop();
+        codec.release();
+
+    }
+    
+    private short getAmplitude(MediaExtractor extractor, MediaCodec codec) {
+        short maxvalue = 0;
+        int numBytesDecoded = 0;
+        final long kTimeOutUs = 5000;
+        ByteBuffer[] codecInputBuffers = codec.getInputBuffers();
+        ByteBuffer[] codecOutputBuffers = codec.getOutputBuffers();
+        MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
+
+        while(numBytesDecoded < 44100 * 2) {
+            int inputBufIndex = codec.dequeueInputBuffer(kTimeOutUs);
+
+            if (inputBufIndex >= 0) {
+                ByteBuffer dstBuf = codecInputBuffers[inputBufIndex];
+
+                int sampleSize = extractor.readSampleData(dstBuf, 0 /* offset */);
+                long presentationTimeUs = extractor.getSampleTime();
+
+                codec.queueInputBuffer(
+                        inputBufIndex,
+                        0 /* offset */,
+                        sampleSize,
+                        presentationTimeUs,
+                        0 /* flags */);
+
+                extractor.advance();
+            }
+            int res = codec.dequeueOutputBuffer(info, kTimeOutUs);
+
+            if (res >= 0) {
+
+                int outputBufIndex = res;
+                ByteBuffer buf = codecOutputBuffers[outputBufIndex];
+
+                for (int i = 0; i < info.size; i += 2) {
+                    short sample = buf.getShort(i);
+                    if (maxvalue < sample) {
+                        maxvalue = sample;
+                    }
+                    int idx = (numBytesDecoded + i) / 2;
+                }
+
+                numBytesDecoded += info.size;
+
+                codec.releaseOutputBuffer(outputBufIndex, false /* render */);
+            } else if (res == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
+                codecOutputBuffers = codec.getOutputBuffers();
+            } else if (res == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
+                MediaFormat oformat = codec.getOutputFormat();
+            }
+        }
+        return maxvalue; 
+    }
+    
 }
 
diff --git a/tests/tests/media/src/android/media/cts/MediaDrmMockTest.java b/tests/tests/media/src/android/media/cts/MediaDrmMockTest.java
index 277b165..0bd277d 100644
--- a/tests/tests/media/src/android/media/cts/MediaDrmMockTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaDrmMockTest.java
@@ -25,6 +25,8 @@
 import android.util.Log;
 import java.util.HashMap;
 import java.util.Arrays;
+import java.util.List;
+import java.util.Iterator;
 import java.util.UUID;
 import java.lang.Thread;
 import java.lang.Object;
@@ -262,6 +264,63 @@
         md.closeSession(sessionId);
     }
 
+    public void testGetKeyRequestOffline() throws Exception {
+        if (!isMockPluginInstalled()) {
+            return;
+        }
+
+        MediaDrm md = new MediaDrm(mockScheme);
+        byte[] sessionId = md.openSession();
+
+        // Set up mock expected responses using properties
+        byte testRequest[] = {0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x10, 0x11, 0x12};
+        md.setPropertyByteArray("mock-request", testRequest);
+        String testDefaultUrl = "http://1.2.3.4:8080/blah";
+        md.setPropertyString("mock-defaultUrl", testDefaultUrl);
+
+        byte[] initData = {0x0a, 0x0b, 0x0c, 0x0d};
+
+        String mimeType = "video/iso.segment";
+        KeyRequest request = md.getKeyRequest(sessionId, initData, mimeType,
+                                              MediaDrm.MEDIA_DRM_KEY_TYPE_OFFLINE,
+                                              null);
+        assertTrue(Arrays.equals(request.data, testRequest));
+        assertTrue(request.defaultUrl.equals(testDefaultUrl));
+
+        assertTrue(Arrays.equals(initData, md.getPropertyByteArray("mock-initdata")));
+        assertTrue(mimeType.equals(md.getPropertyString("mock-mimetype")));
+        assertTrue(md.getPropertyString("mock-keytype").equals("2"));
+
+        md.closeSession(sessionId);
+    }
+
+    public void testGetKeyRequestRelease() throws Exception {
+        if (!isMockPluginInstalled()) {
+            return;
+        }
+
+        MediaDrm md = new MediaDrm(mockScheme);
+        byte[] sessionId = md.openSession();
+
+        // Set up mock expected responses using properties
+        byte testRequest[] = {0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x10, 0x11, 0x12};
+        md.setPropertyByteArray("mock-request", testRequest);
+        String testDefaultUrl = "http://1.2.3.4:8080/blah";
+        md.setPropertyString("mock-defaultUrl", testDefaultUrl);
+
+        String mimeType = "video/iso.segment";
+        KeyRequest request = md.getKeyRequest(sessionId, null, mimeType,
+                                              MediaDrm.MEDIA_DRM_KEY_TYPE_RELEASE,
+                                              null);
+        assertTrue(Arrays.equals(request.data, testRequest));
+        assertTrue(request.defaultUrl.equals(testDefaultUrl));
+
+        assertTrue(mimeType.equals(md.getPropertyString("mock-mimetype")));
+        assertTrue(md.getPropertyString("mock-keytype").equals("3"));
+
+        md.closeSession(sessionId);
+    }
+
     public void testProvideKeyResponse() throws Exception {
         if (!isMockPluginInstalled()) {
             return;
@@ -361,6 +420,45 @@
         assertTrue(Arrays.equals(testResponse, md.getPropertyByteArray("mock-response")));
     }
 
+    public void testGetSecureStops() throws Exception {
+        if (!isMockPluginInstalled()) {
+            return;
+        }
+
+        MediaDrm md = new MediaDrm(mockScheme);
+
+        // Set up mock expected responses using properties
+        byte ss1[] = {0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20};
+        byte ss2[] = {0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30};
+
+        md.setPropertyByteArray("mock-secure-stop1", ss1);
+        md.setPropertyByteArray("mock-secure-stop2", ss2);
+
+        List<byte[]> secureStopList = md.getSecureStops();
+        assertTrue(secureStopList != null);
+
+        Iterator<byte[]> iter = secureStopList.iterator();
+        assertTrue(iter.hasNext());
+        assertTrue(Arrays.equals(iter.next(), ss1));
+        assertTrue(iter.hasNext());
+        assertTrue(Arrays.equals(iter.next(), ss2));
+        assertFalse(iter.hasNext());
+    }
+
+    public void testReleaseSecureStops() throws Exception {
+        if (!isMockPluginInstalled()) {
+            return;
+        }
+
+        MediaDrm md = new MediaDrm(mockScheme);
+
+        // Set up mock expected responses using properties
+        byte ssrelease[] = {0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40};
+
+        md.releaseSecureStops(ssrelease);
+        assertTrue(Arrays.equals(ssrelease, md.getPropertyByteArray("mock-ssrelease")));
+    }
+
     public void testMultipleSessions() throws Exception {
         if (!isMockPluginInstalled()) {
             return;
diff --git a/tests/tests/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/tests/net/src/android/net/cts/ConnectivityManagerTest.java
index 4fa69a8..c244159 100644
--- a/tests/tests/net/src/android/net/cts/ConnectivityManagerTest.java
+++ b/tests/tests/net/src/android/net/cts/ConnectivityManagerTest.java
@@ -23,6 +23,7 @@
 import android.content.IntentFilter;
 import android.content.pm.PackageManager;
 import android.net.ConnectivityManager;
+import android.net.NetworkConfig;
 import android.net.NetworkInfo;
 import android.net.NetworkInfo.DetailedState;
 import android.net.NetworkInfo.State;
@@ -30,7 +31,10 @@
 import android.test.AndroidTestCase;
 import android.util.Log;
 
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Set;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
@@ -51,6 +55,9 @@
     private ConnectivityManager mCm;
     private WifiManager mWifiManager;
     private PackageManager mPackageManager;
+    private final HashMap<Integer, NetworkConfig> mNetworks =
+            new HashMap<Integer, NetworkConfig>();
+    private final List<Integer>mProtectedNetworks = new ArrayList<Integer>();
 
     @Override
     protected void setUp() throws Exception {
@@ -58,45 +65,115 @@
         mCm = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
         mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE);
         mPackageManager = getContext().getPackageManager();
-    }
 
-    public void testGetNetworkInfo() {
-        assertTrue(mCm.getAllNetworkInfo().length >= MIN_NUM_NETWORK_TYPES);
-        NetworkInfo ni = mCm.getNetworkInfo(TYPE_WIFI);
-        if (ni != null) {
-            State state = ni.getState();
-            assertTrue(State.UNKNOWN.ordinal() >= state.ordinal()
-                       && state.ordinal() >= State.CONNECTING.ordinal());
-            DetailedState ds = ni.getDetailedState();
-            assertTrue(DetailedState.FAILED.ordinal() >= ds.ordinal()
-                       && ds.ordinal() >= DetailedState.IDLE.ordinal());
+        String[] naStrings = getContext().getResources().getStringArray(
+                com.android.internal.R.array.networkAttributes);
+        for (String naString : naStrings) {
+            try {
+                NetworkConfig n = new NetworkConfig(naString);
+                mNetworks.put(n.type, n);
+            } catch (Exception e) {}
         }
-        ni = mCm.getNetworkInfo(TYPE_MOBILE);
-        if (ni != null) {
-            State state = ni.getState();
-            assertTrue(State.UNKNOWN.ordinal() >= state.ordinal()
-                    && state.ordinal() >= State.CONNECTING.ordinal());
-            DetailedState ds = ni.getDetailedState();
-            assertTrue(DetailedState.FAILED.ordinal() >= ds.ordinal()
-                    && ds.ordinal() >= DetailedState.IDLE.ordinal());
+
+        int[] protectedNetworks = getContext().getResources().getIntArray(
+                com.android.internal.R.array.config_protectedNetworks);
+        for (int p : protectedNetworks) {
+            mProtectedNetworks.add(p);
         }
-        ni = mCm.getNetworkInfo(-1);
-        assertNull(ni);
     }
 
     public void testIsNetworkTypeValid() {
+        assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_MOBILE));
+        assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_WIFI));
+        assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_MOBILE_MMS));
+        assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_MOBILE_SUPL));
+        assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_MOBILE_DUN));
+        assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_MOBILE_HIPRI));
+        assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_WIMAX));
+        assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_BLUETOOTH));
+        assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_DUMMY));
+        assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_ETHERNET));
+        assertTrue(mCm.isNetworkTypeValid(ConnectivityManager.TYPE_MOBILE_FOTA));
+        assertTrue(mCm.isNetworkTypeValid(ConnectivityManager.TYPE_MOBILE_IMS));
+        assertTrue(mCm.isNetworkTypeValid(ConnectivityManager.TYPE_MOBILE_CBS));
+        assertTrue(mCm.isNetworkTypeValid(ConnectivityManager.TYPE_WIFI_P2P));
+        assertFalse(mCm.isNetworkTypeValid(-1));
+        assertTrue(mCm.isNetworkTypeValid(0));
+        assertTrue(mCm.isNetworkTypeValid(ConnectivityManager.MAX_NETWORK_TYPE));
+        assertFalse(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.MAX_NETWORK_TYPE+1));
 
         NetworkInfo[] ni = mCm.getAllNetworkInfo();
 
-        for (NetworkInfo n : ni) {
+        for (NetworkInfo n: ni) {
             assertTrue(ConnectivityManager.isNetworkTypeValid(n.getType()));
         }
-        assertFalse(ConnectivityManager.isNetworkTypeValid(-1));
+
+    }
+
+    public void testSetNetworkPreference() {
+        // verify swtiching between two default networks - need to connectable networks though
+        // could use test and whatever the current active network is
+        NetworkInfo active = mCm.getActiveNetworkInfo();
+        int originalPref = mCm.getNetworkPreference();
+        int currentPref = originalPref;
+        for (int type = -1; type <= ConnectivityManager.MAX_NETWORK_TYPE+1; type++) {
+            mCm.setNetworkPreference(type);
+            NetworkConfig c = mNetworks.get(type);
+            boolean expectWorked = (c != null && c.isDefault());
+            try {
+                Thread.currentThread().sleep(100);
+            } catch (InterruptedException e) {}
+            int foundType = mCm.getNetworkPreference();
+            if (expectWorked) {
+                assertTrue("We should have been able to switch prefered type " + type,
+                        foundType == type);
+                currentPref = foundType;
+            } else {
+                assertTrue("We should not have been able to switch type " + type,
+                        foundType == currentPref);
+            }
+        }
+        mCm.setNetworkPreference(originalPref);
+    }
+
+    public void testGetActiveNetworkInfo() {
+        NetworkInfo ni = mCm.getActiveNetworkInfo();
+
+        assertTrue("You must have an active network connection to complete CTS", ni != null);
+        assertTrue(ConnectivityManager.isNetworkTypeValid(ni.getType()));
+        assertTrue(ni.getState() == State.CONNECTED);
+    }
+
+    public void testGetNetworkInfo() {
+        for (int type = -1; type <= ConnectivityManager.MAX_NETWORK_TYPE+1; type++) {
+            if (isSupported(type)) {
+                NetworkInfo ni = mCm.getNetworkInfo(type);
+                assertTrue("Info shouldn't be null for " + type, ni != null);
+                State state = ni.getState();
+                assertTrue("Bad state for " + type, State.UNKNOWN.ordinal() >= state.ordinal()
+                           && state.ordinal() >= State.CONNECTING.ordinal());
+                DetailedState ds = ni.getDetailedState();
+                assertTrue("Bad detailed state for " + type,
+                           DetailedState.FAILED.ordinal() >= ds.ordinal()
+                           && ds.ordinal() >= DetailedState.IDLE.ordinal());
+            } else {
+                assertNull("Info should be null for " + type, mCm.getNetworkInfo(type));
+            }
+        }
     }
 
     public void testGetAllNetworkInfo() {
         NetworkInfo[] ni = mCm.getAllNetworkInfo();
         assertTrue(ni.length >= MIN_NUM_NETWORK_TYPES);
+        for (int type = 0; type <= ConnectivityManager.MAX_NETWORK_TYPE; type++) {
+            int desiredFoundCount = (isSupported(type) ? 1 : 0);
+            int foundCount = 0;
+            for (NetworkInfo i : ni) {
+                if (i.getType() == type) foundCount++;
+            }
+            assertTrue("Unexpected foundCount of " + foundCount + " for type " + type,
+                    foundCount == desiredFoundCount);
+        }
     }
 
     public void testStartUsingNetworkFeature() {
@@ -130,35 +207,46 @@
         }
     }
 
-    public void testRequestRouteToHost() {
-        Set<Integer> exceptionFreeTypes = new HashSet<Integer>();
-        exceptionFreeTypes.add(ConnectivityManager.TYPE_BLUETOOTH);
-        exceptionFreeTypes.add(ConnectivityManager.TYPE_ETHERNET);
-        exceptionFreeTypes.add(ConnectivityManager.TYPE_MOBILE);
-        exceptionFreeTypes.add(ConnectivityManager.TYPE_MOBILE_DUN);
-        exceptionFreeTypes.add(ConnectivityManager.TYPE_MOBILE_HIPRI);
-        exceptionFreeTypes.add(ConnectivityManager.TYPE_MOBILE_MMS);
-        exceptionFreeTypes.add(ConnectivityManager.TYPE_MOBILE_SUPL);
+    private boolean isSupported(int networkType) {
+        return mNetworks.containsKey(networkType);
+    }
 
-        NetworkInfo[] ni = mCm.getAllNetworkInfo();
-        for (NetworkInfo n : ni) {
-            if (n.isConnected() && exceptionFreeTypes.contains(n.getType())) {
-                assertTrue("Network type: " + n.getType(), mCm.requestRouteToHost(n.getType(),
-                        HOST_ADDRESS));
+    // true if only the system can turn it on
+    private boolean isNetworkProtected(int networkType) {
+        return mProtectedNetworks.contains(networkType);
+    }
+
+    public void testIsNetworkSupported() {
+        for (int type = -1; type <= ConnectivityManager.MAX_NETWORK_TYPE; type++) {
+            boolean supported = mCm.isNetworkSupported(type);
+            if (isSupported(type)) {
+                assertTrue(supported);
+            } else {
+                assertFalse(supported);
             }
         }
+    }
+
+    public void testRequestRouteToHost() {
+        for (int type = -1 ; type <= ConnectivityManager.MAX_NETWORK_TYPE; type++) {
+            NetworkInfo ni = mCm.getNetworkInfo(type);
+            boolean expectToWork = isSupported(type) && !isNetworkProtected(type) &&
+                    ni != null && ni.isConnected();
+
+            try {
+                assertTrue("Network type " + type,
+                        mCm.requestRouteToHost(type, HOST_ADDRESS) == expectToWork);
+            } catch (Exception e) {
+                Log.d(TAG, "got exception in requestRouteToHost for type " + type);
+                assertFalse("Exception received for type " + type, expectToWork);
+            }
+
+            //TODO verify route table
+        }
 
         assertFalse(mCm.requestRouteToHost(-1, HOST_ADDRESS));
     }
 
-    public void testGetActiveNetworkInfo() {
-        NetworkInfo ni = mCm.getActiveNetworkInfo();
-
-        if (ni != null) {
-            assertTrue(ni.getType() >= 0);
-        }
-    }
-
     public void testTest() {
         mCm.getBackgroundDataSetting();
     }
@@ -197,12 +285,16 @@
 
             assertTrue("Couldn't requestRouteToHost using HIPRI.",
                     mCm.requestRouteToHost(ConnectivityManager.TYPE_MOBILE_HIPRI, HOST_ADDRESS));
-
+            // TODO check dns selection
+            // TODO check routes
         } catch (InterruptedException e) {
             fail("Broadcast receiver waiting for ConnectivityManager interrupted.");
         } finally {
             mCm.stopUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE,
                     FEATURE_ENABLE_HIPRI);
+            // TODO wait for HIPRI to go
+            // TODO check dns selection
+            // TODO check routes
             if (!isWifiConnected) {
                 mWifiManager.setWifiEnabled(false);
             }
diff --git a/tests/tests/provider/src/android/provider/cts/ContactsContract_DataTest.java b/tests/tests/provider/src/android/provider/cts/ContactsContract_DataTest.java
index 612163c..51d62a3 100644
--- a/tests/tests/provider/src/android/provider/cts/ContactsContract_DataTest.java
+++ b/tests/tests/provider/src/android/provider/cts/ContactsContract_DataTest.java
@@ -22,9 +22,16 @@
 import android.content.ContentProviderClient;
 import android.content.ContentResolver;
 import android.content.ContentValues;
+import android.database.Cursor;
 import android.net.Uri;
 import android.os.SystemClock;
 import android.provider.ContactsContract;
+import android.provider.ContactsContract.CommonDataKinds.Contactables;
+import android.provider.ContactsContract.CommonDataKinds.Email;
+import android.provider.ContactsContract.CommonDataKinds.Organization;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.provider.ContactsContract.CommonDataKinds.StructuredName;
+import android.provider.ContactsContract.Contacts;
 import android.provider.ContactsContract.Data;
 import android.provider.ContactsContract.RawContacts;
 import android.provider.cts.ContactsContract_TestDataBuilder.TestContact;
@@ -36,6 +43,8 @@
 import android.provider.cts.contacts.RawContactUtil;
 import android.test.InstrumentationTestCase;
 
+import java.util.ArrayList;
+
 public class ContactsContract_DataTest extends InstrumentationTestCase {
     private ContentResolver mResolver;
     private ContactsContract_TestDataBuilder mBuilder;
@@ -93,6 +102,86 @@
                 lookupContact.getId(), data.load().getRawContact().load().getContactId());
     }
 
+    public void testContactablesUri() throws Exception {
+        TestRawContact rawContact = mBuilder.newRawContact()
+                .with(RawContacts.ACCOUNT_TYPE, "test_account")
+                .with(RawContacts.ACCOUNT_NAME, "test_name")
+                .insert();
+        rawContact.newDataRow(CommonDataKinds.Email.CONTENT_ITEM_TYPE)
+                .with(Email.DATA, "test@test.com")
+                .with(Email.TYPE, Email.TYPE_WORK)
+                .insert();
+        ContentValues cv = new ContentValues();
+        cv.put(Email.DATA, "test@test.com");
+        cv.put(Email.TYPE, Email.TYPE_WORK);
+
+        Uri contentUri = ContactsContract.CommonDataKinds.Contactables.CONTENT_URI;
+        try {
+            assertCursorStoredValuesWithRawContactsFilter(contentUri,
+                    new long[] {rawContact.getId()}, cv);
+            rawContact.newDataRow(CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE)
+                    .with(CommonDataKinds.StructuredPostal.DATA1, "100 Sesame Street")
+                    .insert();
+
+            rawContact.newDataRow(Phone.CONTENT_ITEM_TYPE)
+                    .with(Phone.DATA, "123456789")
+                    .with(Phone.TYPE, Phone.TYPE_MOBILE)
+                    .insert();
+
+            ContentValues cv2 = new ContentValues();
+            cv.put(Phone.DATA, "123456789");
+            cv.put(Phone.TYPE, Phone.TYPE_MOBILE);
+
+            // Contactables Uri should return only email and phone data items.
+            DatabaseAsserts.assertStoredValuesInUriMatchExactly(mResolver, contentUri, null,
+                    Data.RAW_CONTACT_ID + "=?", new String[] {String.valueOf(rawContact.getId())},
+                    null, cv, cv2);
+        } finally {
+            // Clean up
+            rawContact.delete();
+        }
+    }
+
+    public void testContactablesFilterByLastName_returnsCorrectDataRows() throws Exception {
+        long[] ids = setupContactablesTestData();
+        Uri filterUri = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI, "tamale");
+        assertCursorStoredValuesWithRawContactsFilter(filterUri, ids,
+                ContactablesTestHelper.getContentValues(0));
+    }
+
+    public void testContactablesFilterByFirstName_returnsCorrectDataRows() throws Exception {
+        long[] ids = setupContactablesTestData();
+        Uri filterUri = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI, "hot");
+        assertCursorStoredValuesWithRawContactsFilter(filterUri, ids,
+                ContactablesTestHelper.getContentValues(0));
+        Uri filterUri2 = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI, "tam");
+        assertCursorStoredValuesWithRawContactsFilter(filterUri2, ids,
+                ContactablesTestHelper.getContentValues(0, 1));
+    }
+
+    public void testContactablesFilterByPhonePrefix_returnsCorrectDataRows() throws Exception {
+        long[] ids = setupContactablesTestData();
+        Uri filterUri = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI, "518");
+        assertCursorStoredValuesWithRawContactsFilter(filterUri, ids,
+                ContactablesTestHelper.getContentValues(2));
+        Uri filterUri2 = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI, "51");
+        assertCursorStoredValuesWithRawContactsFilter(filterUri2, ids,
+                ContactablesTestHelper.getContentValues(0, 2));
+    }
+
+    public void testContactablesFilterByEmailPrefix_returnsCorrectDataRows() throws Exception {
+        long[] ids = setupContactablesTestData();
+        Uri filterUri = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI, "doeassoc");
+        assertCursorStoredValuesWithRawContactsFilter(filterUri, ids,
+                ContactablesTestHelper.getContentValues(2));
+    }
+
+    public void testContactablesFilter_doesNotExist_returnsCorrectDataRows() throws Exception {
+        long[] ids = setupContactablesTestData();
+        Uri filterUri = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI, "doesnotexist");
+        assertCursorStoredValuesWithRawContactsFilter(filterUri, ids, new ContentValues[0]);
+    }
+
     public void testDataInsert_updatesContactLastUpdatedTimestamp() {
         DatabaseAsserts.ContactIdPair ids = DatabaseAsserts.assertAndCreateContact(mResolver);
         long baseTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
@@ -151,5 +240,155 @@
         values.put(CommonDataKinds.Phone.LABEL, "free directory assistance");
         return DataUtil.insertData(mResolver, rawContactId, values);
     }
+
+    private void assertCursorStoredValuesWithRawContactsFilter(Uri uri, long[] rawContactsId,
+            ContentValues... expected) {
+        // We need this helper function to add a filter for specific raw contacts because
+        // otherwise tests will fail if performed on a device with existing contacts data
+        StringBuilder sb = new StringBuilder();
+        sb.append(Data.RAW_CONTACT_ID + " in ");
+        sb.append("(");
+        for (int i = 0; i < rawContactsId.length; i++) {
+            if (i != 0) sb.append(",");
+            sb.append(rawContactsId[i]);
+        }
+        sb.append(")");
+        DatabaseAsserts.assertStoredValuesInUriMatchExactly(mResolver, uri, null, sb.toString(),
+                null, null, expected);
+    }
+
+
+    private long[] setupContactablesTestData() throws Exception {
+        TestRawContact rawContact = mBuilder.newRawContact()
+                .with(RawContacts.ACCOUNT_TYPE, "test_account")
+                .with(RawContacts.ACCOUNT_NAME, "test_name")
+                .insert();
+        rawContact.newDataRow(StructuredName.CONTENT_ITEM_TYPE)
+                .with(StructuredName.DISPLAY_NAME, "Hot Tamale")
+                .insert();
+        rawContact.newDataRow(Email.CONTENT_ITEM_TYPE)
+                .with(Email.DATA, "tamale@acme.com")
+                .with(Email.TYPE, Email.TYPE_HOME)
+                .insert();
+        rawContact.newDataRow(Email.CONTENT_ITEM_TYPE)
+                .with(Email.DATA, "hot@google.com")
+                .with(Email.TYPE, Email.TYPE_WORK)
+                .insert();
+        rawContact.newDataRow(Phone.CONTENT_ITEM_TYPE)
+                .with(Phone.DATA, "510-123-5769")
+                .with(Email.TYPE, Phone.TYPE_HOME)
+                .insert();
+
+        TestRawContact rawContact2 = mBuilder.newRawContact()
+                .with(RawContacts.ACCOUNT_TYPE, "test_account")
+                .with(RawContacts.ACCOUNT_NAME, "test_name")
+                .insert();
+        rawContact2.newDataRow(StructuredName.CONTENT_ITEM_TYPE)
+                .with(StructuredName.DISPLAY_NAME, "Cold Tamago")
+                .insert();
+        rawContact2.newDataRow(Email.CONTENT_ITEM_TYPE)
+                .with(Email.DATA, "eggs@farmers.org")
+                .with(Email.TYPE, Email.TYPE_HOME)
+                .insert();
+
+        TestRawContact rawContact3 = mBuilder.newRawContact()
+                .with(RawContacts.ACCOUNT_TYPE, "test_account")
+                .with(RawContacts.ACCOUNT_NAME, "test_name")
+                .insert();
+        rawContact3.newDataRow(StructuredName.CONTENT_ITEM_TYPE)
+                .with(StructuredName.DISPLAY_NAME, "John Doe")
+                .insert();
+        rawContact3.newDataRow(Email.CONTENT_ITEM_TYPE)
+                .with(Email.DATA, "doeassociates@deer.com")
+                .with(Email.TYPE, Email.TYPE_WORK)
+                .insert();
+        rawContact3.newDataRow(Phone.CONTENT_ITEM_TYPE)
+                .with(Phone.DATA, "518-354-1111")
+                .with(Phone.TYPE, Phone.TYPE_HOME)
+                .insert();
+        rawContact3.newDataRow(Organization.CONTENT_ITEM_TYPE)
+                .with(Organization.DATA, "Doe Industries")
+                .insert();
+        return new long[] {rawContact.getId(), rawContact2.getId(), rawContact3.getId()};
+    }
+
+    // Provides functionality to set up content values for the Contactables tests
+    private static class ContactablesTestHelper {
+        private static ContentValues[] sContentValues = new ContentValues[6];
+        static {
+            ContentValues cv1 = new ContentValues();
+            cv1.put(Contacts.DISPLAY_NAME, "Hot Tamale");
+            cv1.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
+            cv1.put(Email.DATA, "tamale@acme.com");
+            cv1.put(Email.TYPE, Email.TYPE_HOME);
+            sContentValues[0] = cv1;
+
+            ContentValues cv2 = new ContentValues();
+            cv2.put(Contacts.DISPLAY_NAME, "Hot Tamale");
+            cv2.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
+            cv2.put(Phone.DATA, "510-123-5769");
+            cv2.put(Phone.TYPE, Phone.TYPE_HOME);
+            sContentValues[1] = cv2;
+
+            ContentValues cv3 = new ContentValues();
+            cv3.put(Contacts.DISPLAY_NAME, "Hot Tamale");
+            cv3.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
+            cv3.put(Email.DATA, "hot@google.com");
+            cv3.put(Email.TYPE, Email.TYPE_WORK);
+            sContentValues[2] = cv3;
+
+            ContentValues cv4 = new ContentValues();
+            cv4.put(Contacts.DISPLAY_NAME, "Cold Tamago");
+            cv4.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
+            cv4.put(Email.DATA, "eggs@farmers.org");
+            cv4.put(Email.TYPE, Email.TYPE_HOME);
+            sContentValues[3] = cv4;
+
+            ContentValues cv5 = new ContentValues();
+            cv5.put(Contacts.DISPLAY_NAME, "John Doe");
+            cv5.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
+            cv5.put(Email.DATA, "doeassociates@deer.com");
+            cv5.put(Email.TYPE, Email.TYPE_WORK);
+            sContentValues[4] = cv5;
+
+            ContentValues cv6 = new ContentValues();
+            cv6.put(Contacts.DISPLAY_NAME, "John Doe");
+            cv6.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
+            cv6.put(Phone.DATA, "518-354-1111");
+            cv6.put(Phone.TYPE, Phone.TYPE_HOME);
+            sContentValues[5] = cv6;
+        }
+
+        /**
+         * @return An arraylist of contentValues that correspond to the provided raw contacts
+         */
+        public static ContentValues[] getContentValues(int... rawContacts) {
+            ArrayList<ContentValues> cv = new ArrayList<ContentValues>();
+            for (int i = 0; i < rawContacts.length; i++) {
+                switch (rawContacts[i]) {
+                    case 0:
+                        // rawContact 0 "Hot Tamale" contains ContentValues 0, 1, and 2
+                        cv.add(sContentValues[0]);
+                        cv.add(sContentValues[1]);
+                        cv.add(sContentValues[2]);
+                        break;
+                    case 1:
+                        // rawContact 1 "Cold Tamago" contains ContentValues 3
+                        cv.add(sContentValues[3]);
+                        break;
+                    case 2:
+                        // rawContact 1 "John Doe" contains ContentValues 4, 5
+                        cv.add(sContentValues[4]);
+                        cv.add(sContentValues[5]);
+                        break;
+                }
+            }
+            ContentValues[] toReturn = new ContentValues[cv.size()];
+            for (int i = 0; i < cv.size(); i++) {
+                toReturn[i] = cv.get(i);
+            }
+            return toReturn;
+        }
+    }
 }
 
diff --git a/tests/tests/provider/src/android/provider/cts/ContactsContract_DataUsageTest.java b/tests/tests/provider/src/android/provider/cts/ContactsContract_DataUsageTest.java
new file mode 100644
index 0000000..a684e41
--- /dev/null
+++ b/tests/tests/provider/src/android/provider/cts/ContactsContract_DataUsageTest.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2013 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.provider.cts;
+
+import static android.provider.ContactsContract.CommonDataKinds;
+import static android.provider.ContactsContract.DataUsageFeedback;
+
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.net.Uri;
+import android.provider.ContactsContract;
+import android.provider.cts.contacts.DataUtil;
+import android.provider.cts.contacts.DatabaseAsserts;
+import android.provider.cts.contacts.RawContactUtil;
+import android.test.AndroidTestCase;
+import android.text.TextUtils;
+
+public class ContactsContract_DataUsageTest extends AndroidTestCase {
+
+    private ContentResolver mResolver;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mResolver = getContext().getContentResolver();
+    }
+
+    public void testSingleDataUsageFeedback_incrementsCorrectDataItems() {
+        DatabaseAsserts.ContactIdPair ids = DatabaseAsserts.assertAndCreateContact(mResolver);
+
+        long[] dataIds = setupRawContactDataItems(ids.mRawContactId);
+
+        // Update just 1 data item at a time.
+        updateDataUsageAndAssert(dataIds[1], 1);
+        updateDataUsageAndAssert(dataIds[1], 2);
+
+        updateDataUsageAndAssert(dataIds[2], 1);
+        updateDataUsageAndAssert(dataIds[2], 2);
+        updateDataUsageAndAssert(dataIds[2], 3);
+
+        // Go back and update the previous data item again.
+        updateDataUsageAndAssert(dataIds[1], 3);
+
+        deleteDataUsage();
+        RawContactUtil.delete(mResolver, ids.mRawContactId, true);
+    }
+
+    public void testMultiIdDataUsageFeedback_incrementsCorrectDataItems() {
+        DatabaseAsserts.ContactIdPair ids = DatabaseAsserts.assertAndCreateContact(mResolver);
+
+        long[] dataIds = setupRawContactDataItems(ids.mRawContactId);
+
+        assertDataUsageEquals(dataIds, 0, 0, 0, 0);
+
+        updateMultipleAndAssertUpdateSuccess(new long[] {dataIds[1], dataIds[2]});
+        assertDataUsageEquals(dataIds, 0, 1, 1, 0);
+
+        updateMultipleAndAssertUpdateSuccess(new long[]{dataIds[1], dataIds[2]});
+        assertDataUsageEquals(dataIds, 0, 2, 2, 0);
+
+        updateDataUsageAndAssert(dataIds[1], 3);
+        assertDataUsageEquals(dataIds, 0, 3, 2, 0);
+
+        updateMultipleAndAssertUpdateSuccess(new long[]{dataIds[0], dataIds[1]});
+        assertDataUsageEquals(dataIds, 1, 4, 2, 0);
+
+        deleteDataUsage();
+        RawContactUtil.delete(mResolver, ids.mRawContactId, true);
+    }
+
+    private long[] setupRawContactDataItems(long rawContactId) {
+        // Create 4 data items.
+        long[] dataIds = new long[4];
+
+        ContentValues values = new ContentValues();
+        values.put(ContactsContract.Data.MIMETYPE, CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
+        values.put(CommonDataKinds.Phone.NUMBER, "555-5555");
+        dataIds[0] = DataUtil.insertData(mResolver, rawContactId, values);
+
+        values.clear();
+        values.put(ContactsContract.Data.MIMETYPE, CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
+        values.put(CommonDataKinds.Phone.NUMBER, "555-5554");
+        dataIds[1] = DataUtil.insertData(mResolver, rawContactId, values);
+
+        values.clear();
+        values.put(ContactsContract.Data.MIMETYPE, CommonDataKinds.Email.CONTENT_ITEM_TYPE);
+        values.put(CommonDataKinds.Email.ADDRESS, "test@thisisfake.com");
+        dataIds[2] = DataUtil.insertData(mResolver, rawContactId, values);
+
+        values.clear();
+        values.put(ContactsContract.Data.MIMETYPE, CommonDataKinds.Email.CONTENT_ITEM_TYPE);
+        values.put(CommonDataKinds.Phone.NUMBER, "555-5556");
+        dataIds[3] = DataUtil.insertData(mResolver, rawContactId, values);
+
+        return dataIds;
+    }
+
+    /**
+     * Updates multiple data ids at once.  And asserts the update returned success.
+     */
+    private void updateMultipleAndAssertUpdateSuccess(long[] dataIds) {
+        String[] ids = new String[dataIds.length];
+        for (int i = 0; i < dataIds.length; i++) {
+            ids[i] = String.valueOf(dataIds[i]);
+        }
+        Uri uri = DataUsageFeedback.FEEDBACK_URI.buildUpon().appendPath(TextUtils.join(",", ids))
+                .appendQueryParameter(DataUsageFeedback.USAGE_TYPE,
+                        DataUsageFeedback.USAGE_TYPE_CALL).build();
+        int result = mResolver.update(uri, new ContentValues(), null, null);
+        assertTrue(result > 0);
+    }
+
+    /**
+     * Updates a single data item usage.  Asserts the update was successful.  Asserts the usage
+     * number is equal to expected value.
+     */
+    private void updateDataUsageAndAssert(long dataId, int assertValue) {
+        Uri uri = DataUsageFeedback.FEEDBACK_URI.buildUpon().appendPath(String.valueOf(dataId))
+                .appendQueryParameter(DataUsageFeedback.USAGE_TYPE,
+                        DataUsageFeedback.USAGE_TYPE_CALL).build();
+        int result = mResolver.update(uri, new ContentValues(), null, null);
+        assertTrue(result > 0);
+
+        assertDataUsageEquals(dataId, assertValue);
+    }
+
+    /**
+     * Assert that the given data ids have usage values in the respective order.
+     */
+    private void assertDataUsageEquals(long[] dataIds, int... expectedValues) {
+        if (dataIds.length != expectedValues.length) {
+            throw new IllegalArgumentException("dataIds and expectedValues must be the same size");
+        }
+
+        for (int i = 0; i < dataIds.length; i++) {
+            assertDataUsageEquals(dataIds[i], expectedValues[i]);
+        }
+    }
+
+    /**
+     * Assert a single data item has a specific usage value.
+     */
+    private void assertDataUsageEquals(long dataId, int expectedValue) {
+        // Query and assert value is expected.
+        String[] projection = new String[]{ContactsContract.Data.TIMES_USED};
+        String[] record = DataUtil.queryById(mResolver, dataId, projection);
+        assertNotNull(record);
+        long actual = 0;
+        // Tread null as 0
+        if (record[0] != null) {
+            actual = Long.parseLong(record[0]);
+        }
+        assertEquals(expectedValue, actual);
+    }
+
+    private void deleteDataUsage() {
+        mResolver.delete(DataUsageFeedback.DELETE_USAGE_URI, null, null);
+    }
+}
diff --git a/tests/tests/provider/src/android/provider/cts/contacts/DataUtil.java b/tests/tests/provider/src/android/provider/cts/contacts/DataUtil.java
index adb253c..ae2812e 100644
--- a/tests/tests/provider/src/android/provider/cts/contacts/DataUtil.java
+++ b/tests/tests/provider/src/android/provider/cts/contacts/DataUtil.java
@@ -19,6 +19,7 @@
 import android.content.ContentResolver;
 import android.content.ContentUris;
 import android.content.ContentValues;
+import android.database.Cursor;
 import android.net.Uri;
 import android.provider.ContactsContract;
 
@@ -29,6 +30,12 @@
 
     private static final Uri URI = ContactsContract.Data.CONTENT_URI;
 
+    public static String[] queryById(ContentResolver resolver, long dataId, String[] projection) {
+        Uri uri = ContentUris.withAppendedId(URI, dataId);
+        Cursor cursor = resolver.query(uri, projection, null, null, null);
+        return CommonDatabaseUtils.singleRecordToArray(cursor);
+    }
+
     public static void insertName(ContentResolver resolver, long rawContactId) {
         ContentValues values = new ContentValues();
         values.put(ContactsContract.Data.MIMETYPE,
diff --git a/tests/tests/provider/src/android/provider/cts/contacts/DatabaseAsserts.java b/tests/tests/provider/src/android/provider/cts/contacts/DatabaseAsserts.java
index a163960..80a0a65 100644
--- a/tests/tests/provider/src/android/provider/cts/contacts/DatabaseAsserts.java
+++ b/tests/tests/provider/src/android/provider/cts/contacts/DatabaseAsserts.java
@@ -18,11 +18,14 @@
 
 import android.content.ContentResolver;
 import android.content.ContentValues;
+import android.database.Cursor;
 import android.net.Uri;
 import android.test.MoreAsserts;
 
 import junit.framework.Assert;
 
+import java.util.BitSet;
+
 /**
  * Common methods for asserting database related operations.
  */
@@ -92,4 +95,107 @@
             this.mRawContactId = rawContactId;
         }
     }
+
+    /**
+     * Queries for a given {@link Uri} against a provided {@link ContentResolver}, and
+     * ensures that the returned cursor contains exactly the expected values.
+     *
+     * @param resolver - ContentResolver to query against
+     * @param uri - {@link Uri} to perform the query for
+     * contained in <code>expectedValues</code> in order for the assert to pass.
+     * @param expectedValues - Array of {@link ContentValues} which the cursor returned from the
+     * query should contain.
+     */
+    public static void assertStoredValuesInUriMatchExactly(ContentResolver resolver, Uri uri,
+            ContentValues... expectedValues) {
+        assertStoredValuesInUriMatchExactly(resolver, uri, null, null, null, null, expectedValues);
+    }
+
+    /**
+     * Queries for a given {@link Uri} against a provided {@link ContentResolver}, and
+     * ensures that the returned cursor contains exactly the expected values.
+     *
+     * @param resolver - ContentResolver to query against
+     * @param uri - {@link Uri} to perform the query for
+     * @param projection - Projection to use for the query. Must contain at least the columns
+     * contained in <code>expectedValues</code> in order for the assert to pass.
+     * @param selection - Selection string to use for the query.
+     * @param selectionArgs - Selection arguments to use for the query.
+     * @param sortOrder - Sort order to use for the query.
+     * @param expectedValues - Array of {@link ContentValues} which the cursor returned from the
+     * query should contain.
+     */
+    public static void assertStoredValuesInUriMatchExactly(ContentResolver resolver, Uri uri, String[] projection,
+            String selection, String[] selectionArgs, String sortOrder,
+            ContentValues... expectedValues) {
+        final Cursor cursor = resolver.query(uri, projection, selection, selectionArgs, sortOrder);
+        try {
+            assertCursorValuesMatchExactly(cursor, expectedValues);
+        } finally {
+            cursor.close();
+        }
+    }
+
+    /**
+     * Ensures that the rows in the cursor match the rows in the expected values exactly. However,
+     * does not require that the rows in the cursor are ordered the same way as those in the
+     * expected values.
+     *
+     * @param cursor - Cursor containing the values to check for
+     * @param expectedValues - Array of ContentValues that the cursor should be expected to
+     * contain.
+     */
+    public static void assertCursorValuesMatchExactly(Cursor cursor,
+            ContentValues... expectedValues) {
+        Assert.assertEquals("Cursor does not contain the number of expected rows",
+                expectedValues.length, cursor.getCount());
+        StringBuilder message = new StringBuilder();
+        // In case if expectedValues contains multiple identical values, remember which cursor
+        // rows are "consumed" to prevent multiple ContentValues from hitting the same row.
+        final BitSet used = new BitSet(cursor.getCount());
+
+        for (ContentValues v : expectedValues) {
+            boolean found = false;
+            cursor.moveToPosition(-1);
+            while (cursor.moveToNext()) {
+                final int pos = cursor.getPosition();
+                if (used.get(pos)) continue;
+                found = equalsWithExpectedValues(cursor, v, message);
+                if (found) {
+                    used.set(pos);
+                    break;
+                }
+            }
+            Assert.assertTrue("Expected values can not be found " + v + "," + message.toString(),
+                    found);
+        }
+    }
+
+    private static boolean equalsWithExpectedValues(Cursor cursor, ContentValues expectedValues,
+            StringBuilder msgBuffer) {
+        for (String column : expectedValues.keySet()) {
+            int index = cursor.getColumnIndex(column);
+            if (index == -1) {
+                msgBuffer.append(" No such column: ").append(column);
+                return false;
+            }
+            Object expectedValue = expectedValues.get(column);
+            String value;
+            expectedValue = expectedValues.getAsString(column);
+            value = cursor.getString(cursor.getColumnIndex(column));
+            if (expectedValue != null && !expectedValue.equals(value) || value != null
+                    && !value.equals(expectedValue)) {
+                msgBuffer
+                        .append(" Column value ")
+                        .append(column)
+                        .append(" expected <")
+                        .append(expectedValue)
+                        .append(">, but was <")
+                        .append(value)
+                        .append('>');
+                return false;
+            }
+        }
+        return true;
+    }
 }
diff --git a/tests/tests/provider/src/android/provider/cts/contacts/RawContactUtil.java b/tests/tests/provider/src/android/provider/cts/contacts/RawContactUtil.java
index 8f9e7bd..c87dc01 100644
--- a/tests/tests/provider/src/android/provider/cts/contacts/RawContactUtil.java
+++ b/tests/tests/provider/src/android/provider/cts/contacts/RawContactUtil.java
@@ -49,14 +49,13 @@
         ContentValues values = new ContentValues();
         values.put(ContactsContract.RawContacts.ACCOUNT_NAME, StaticAccountAuthenticator.NAME);
         values.put(ContactsContract.RawContacts.ACCOUNT_TYPE, StaticAccountAuthenticator.TYPE);
-        Uri uri = resolver.insert(ContactsContract.RawContacts.CONTENT_URI, values);
+        Uri uri = resolver.insert(URI, values);
         return ContentUris.parseId(uri);
     }
 
     public static String[] queryByRawContactId(ContentResolver resolver,
             long rawContactId, String[] projection) {
-        Uri uri = ContentUris.withAppendedId(ContactsContract.RawContacts.CONTENT_URI,
-                rawContactId);
+        Uri uri = ContentUris.withAppendedId(URI, rawContactId);
         Cursor cursor = resolver.query(uri, projection, null, null, null);
         return CommonDatabaseUtils.singleRecordToArray(cursor);
     }
@@ -68,14 +67,14 @@
      */
     public static List<String[]> queryByContactId(ContentResolver resolver, long contactId,
             String[] projection) {
-        Uri uri = ContentUris.withAppendedId(ContactsContract.RawContacts.CONTENT_URI, contactId);
+        Uri uri = ContentUris.withAppendedId(URI, contactId);
         Cursor cursor = resolver.query(uri, projection, null, null, null);
         return CommonDatabaseUtils.multiRecordToArray(cursor);
     }
 
     public static void delete(ContentResolver resolver, long rawContactId,
             boolean isSyncAdapter) {
-        Uri uri = ContentUris.withAppendedId(ContactsContract.RawContacts.CONTENT_URI, rawContactId)
+        Uri uri = ContentUris.withAppendedId(URI, rawContactId)
                 .buildUpon()
                 .appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, isSyncAdapter + "")
                 .build();
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/GlobalSync.java b/tests/tests/renderscript/src/android/renderscript/cts/GlobalSync.java
new file mode 100644
index 0000000..f895661
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/GlobalSync.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2013 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.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.Element;
+import android.renderscript.RenderScript;
+import android.renderscript.Type;
+
+public class GlobalSync extends RSBaseCompute {
+    Allocation AFailed;
+    int [] Failed;
+    Allocation AIn;
+
+    protected void setupGlobalSync(RenderScript mRS, ScriptC_global_sync gs, int v) {
+        Type.Builder typeBuilder = new Type.Builder(mRS, Element.I32(mRS));
+        Type t = typeBuilder.setX(1).create();
+
+        AFailed = Allocation.createTyped(mRS, t);
+        Failed = new int [1];
+        Failed[0] = 0;
+        AFailed.copyFrom(Failed);
+        gs.set_aFailed(AFailed);
+
+        AIn = Allocation.createTyped(mRS, t);
+        int [] In = new int [1];
+        In[0] = v;
+        AIn.copyFrom(In);
+
+    }
+
+    /**
+     * Test whether we are properly synchronizing extern global data
+     * when dealing with mixed kernels/invokables.
+     */
+    public void testGlobalSync() {
+        ScriptC_global_sync gs = new ScriptC_global_sync(mRS);
+
+        int v = 7;
+        setupGlobalSync(mRS, gs, v);
+        gs.forEach_write_global(AIn);
+        gs.invoke_test_global(v);
+
+        AFailed.copyTo(Failed);
+        if (Failed[0] != 0) {
+            FoundError = true;
+        }
+
+        gs.destroy();
+        checkForErrors();
+    }
+
+    /**
+     * Test whether we are properly synchronizing static global data
+     * when dealing with mixed kernels/invokables.
+     */
+    public void testStaticGlobalSync() {
+        ScriptC_global_sync gs = new ScriptC_global_sync(mRS);
+
+        int v = 9;
+        setupGlobalSync(mRS, gs, v);
+        gs.forEach_write_static_global(AIn);
+        gs.invoke_test_static_global(v);
+
+        AFailed.copyTo(Failed);
+        if (Failed[0] != 0) {
+            FoundError = true;
+        }
+
+        gs.destroy();
+        checkForErrors();
+    }
+}
+
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/GlobalTest.java b/tests/tests/renderscript/src/android/renderscript/cts/GlobalTest.java
new file mode 100644
index 0000000..b0c3b63
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/GlobalTest.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2013 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.renderscript.cts;
+
+public class GlobalTest extends RSBaseCompute {
+    /**
+     * Test whether we properly clean up after large global arrays are
+     * allocated/deallocated.
+     */
+    public void testLargeGlobal() {
+        for (int i = 0; i < 1000; i++) {
+            ScriptC_large_global lg = new ScriptC_large_global(mRS);
+            lg.destroy();
+        }
+        checkForErrors();
+    }
+}
diff --git a/tests/tests/text/src/android/text/format/cts/DateUtilsTest.java b/tests/tests/text/src/android/text/format/cts/DateUtilsTest.java
index 52f0d3f..14e01e8 100644
--- a/tests/tests/text/src/android/text/format/cts/DateUtilsTest.java
+++ b/tests/tests/text/src/android/text/format/cts/DateUtilsTest.java
@@ -189,11 +189,11 @@
                 fixedTime, java.text.DateFormat.SHORT, java.text.DateFormat.FULL));
 
         final long HOUR_DURATION = 2 * 60 * 60 * 1000;
-        assertEquals("5:30:15 AM GMT", DateUtils.formatSameDayTime(fixedTime + HOUR_DURATION,
+        assertEquals("5:30:15 AM GMT+00:00", DateUtils.formatSameDayTime(fixedTime + HOUR_DURATION,
                 fixedTime, java.text.DateFormat.FULL, java.text.DateFormat.FULL));
         assertEquals("5:30:15 AM", DateUtils.formatSameDayTime(fixedTime + HOUR_DURATION,
                 fixedTime, java.text.DateFormat.FULL, java.text.DateFormat.DEFAULT));
-        assertEquals("5:30:15 AM GMT", DateUtils.formatSameDayTime(fixedTime + HOUR_DURATION,
+        assertEquals("5:30:15 AM GMT+00:00", DateUtils.formatSameDayTime(fixedTime + HOUR_DURATION,
                 fixedTime, java.text.DateFormat.FULL, java.text.DateFormat.LONG));
         assertEquals("5:30:15 AM", DateUtils.formatSameDayTime(fixedTime + HOUR_DURATION,
                 fixedTime, java.text.DateFormat.FULL, java.text.DateFormat.MEDIUM));
diff --git a/tests/tests/widget/src/android/widget/cts/TextViewTest.java b/tests/tests/widget/src/android/widget/cts/TextViewTest.java
index 18f573b..8255897 100755
--- a/tests/tests/widget/src/android/widget/cts/TextViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/TextViewTest.java
@@ -1422,8 +1422,13 @@
         mInstrumentation.waitForIdleSync();
         mTextView.getFocusedRect(rc);
         assertNotNull(mTextView.getLayout());
-        assertEquals(mTextView.getLayout().getPrimaryHorizontal(3), (float) rc.left);
-        assertEquals(mTextView.getLayout().getPrimaryHorizontal(13), (float) rc.right);
+        /* Cursor coordinates from getPrimaryHorizontal() may have a fractional
+         * component, while the result of getFocusedRect is in int coordinates.
+         * It's not practical for these to match exactly, so we compare that the
+         * integer components match - there can be a fractional pixel
+         * discrepancy, which should be okay for all practical applications. */
+        assertEquals((int) mTextView.getLayout().getPrimaryHorizontal(3), rc.left);
+        assertEquals((int) mTextView.getLayout().getPrimaryHorizontal(13), rc.right);
         assertEquals(mTextView.getLayout().getLineTop(0), rc.top);
         assertEquals(mTextView.getLayout().getLineBottom(0), rc.bottom);
 
@@ -1438,8 +1443,8 @@
         mInstrumentation.waitForIdleSync();
         mTextView.getFocusedRect(rc);
         assertNotNull(mTextView.getLayout());
-        assertEquals(mTextView.getLayout().getPrimaryHorizontal(3) - 2, (float) rc.left);
-        assertEquals(mTextView.getLayout().getPrimaryHorizontal(3) + 2, (float) rc.right);
+        assertEquals((int) mTextView.getLayout().getPrimaryHorizontal(3) - 2, rc.left);
+        assertEquals((int) mTextView.getLayout().getPrimaryHorizontal(3) + 2, rc.right);
         assertEquals(mTextView.getLayout().getLineTop(0), rc.top);
         assertEquals(mTextView.getLayout().getLineBottom(0), rc.bottom);
 
@@ -1462,8 +1467,8 @@
         mInstrumentation.waitForIdleSync();
         mTextView.getFocusedRect(rc);
         assertNotNull(mTextView.getLayout());
-        assertEquals(mTextView.getLayout().getPrimaryHorizontal(2), (float) rc.left);
-        assertEquals(mTextView.getLayout().getPrimaryHorizontal(4), (float) rc.right);
+        assertEquals((int) mTextView.getLayout().getPrimaryHorizontal(2), rc.left);
+        assertEquals((int) mTextView.getLayout().getPrimaryHorizontal(4), rc.right);
         assertEquals(mTextView.getLayout().getLineTop(0), rc.top);
         assertEquals(mTextView.getLayout().getLineBottom(0), rc.bottom);