diff --git a/tests/res/drawable/baseline_jpeg.jpg b/tests/res/drawable/baseline_jpeg.jpg
new file mode 100644
index 0000000..ed5251c
--- /dev/null
+++ b/tests/res/drawable/baseline_jpeg.jpg
Binary files differ
diff --git a/tests/res/drawable/bmp_test.bmp b/tests/res/drawable/bmp_test.bmp
new file mode 100644
index 0000000..5ec6dd4
--- /dev/null
+++ b/tests/res/drawable/bmp_test.bmp
Binary files differ
diff --git a/tests/res/drawable/gif_test.gif b/tests/res/drawable/gif_test.gif
new file mode 100644
index 0000000..d1c2815
--- /dev/null
+++ b/tests/res/drawable/gif_test.gif
Binary files differ
diff --git a/tests/res/drawable/png_test.png b/tests/res/drawable/png_test.png
new file mode 100644
index 0000000..5230051
--- /dev/null
+++ b/tests/res/drawable/png_test.png
Binary files differ
diff --git a/tests/res/drawable/progressive_jpeg.jpg b/tests/res/drawable/progressive_jpeg.jpg
new file mode 100644
index 0000000..6b58be4
--- /dev/null
+++ b/tests/res/drawable/progressive_jpeg.jpg
Binary files differ
diff --git a/tests/tests/app/src/android/app/cts/ActivityManagerTest.java b/tests/tests/app/src/android/app/cts/ActivityManagerTest.java
index 5b1c2b3..217a17c 100644
--- a/tests/tests/app/src/android/app/cts/ActivityManagerTest.java
+++ b/tests/tests/app/src/android/app/cts/ActivityManagerTest.java
@@ -305,4 +305,21 @@
         ConfigurationInfo conInf = mActivityManager.getDeviceConfigurationInfo();
         assertNotNull(conInf);
     }
+
+    /**
+     * Simple test for {@link ActivityManager.isUserAMonkey()} - verifies its false.
+     *
+     * TODO: test positive case
+     */
+    public void testIsUserAMonkey() {
+        assertFalse(ActivityManager.isUserAMonkey());
+    }
+
+    /**
+     * Verify that {@link ActivityManager.isRunningInTestHarness()} is false.
+     */
+    public void testIsRunningInTestHarness() {
+        assertFalse("isRunningInTestHarness must be false in production builds",
+                ActivityManager.isRunningInTestHarness());
+    }
 }
diff --git a/tests/tests/graphics/src/android/graphics/cts/BitmapRegionDecoderTest.java b/tests/tests/graphics/src/android/graphics/cts/BitmapRegionDecoderTest.java
new file mode 100644
index 0000000..32cc0cc
--- /dev/null
+++ b/tests/tests/graphics/src/android/graphics/cts/BitmapRegionDecoderTest.java
@@ -0,0 +1,402 @@
+/*
+ * Copyright (C) 2010 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.graphics.cts;
+
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.Bitmap.Config;
+import android.graphics.BitmapFactory;
+import android.graphics.BitmapFactory.Options;
+import android.graphics.BitmapRegionDecoder;
+import android.graphics.Color;
+import android.graphics.Rect;
+import android.os.ParcelFileDescriptor;
+import android.test.InstrumentationTestCase;
+import android.util.Log;
+
+import com.android.cts.stub.R;
+
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+
+@TestTargetClass(BitmapRegionDecoder.class)
+public class BitmapRegionDecoderTest extends InstrumentationTestCase {
+    private static final String TAG = "BitmapRegionDecoder";
+    private ArrayList<File> mFilesCreated = new ArrayList<File>(
+            NAMES_TEMP_FILES.length);
+
+    private Resources mRes;
+
+    // The test images, including a baseline JPEG, progressive JPEG, a PNG,
+    // a GIF and a BMP.
+    private static int[] RES_IDS = new int[] {
+            R.drawable.baseline_jpeg, R.drawable.progressive_jpeg,
+            R.drawable.png_test, R.drawable.gif_test, R.drawable.bmp_test
+    };
+    private static String[] NAMES_TEMP_FILES = new String[] {
+        "baseline_temp.jpg", "progressive_temp.jpg", "png_temp.png",
+        "gif_temp.gif", "bmp_temp.bmp"
+    };
+
+    // The width and height of the above image.
+    // -1 denotes that the image format is not supported by BitmapRegionDecoder
+    private static int WIDTHS[] = new int[] {1280, 1280, 640, -1, -1};
+    private static int HEIGHTS[] = new int[] {960, 960, 480, -1, -1};
+
+    // The number of test images, format of which is supported by BitmapRegionDecoder
+    private static int NUM_TEST_IMAGES = 3;
+
+    private static int TILE_SIZE = 256;
+
+    // Configurations for BitmapFactory.Options
+    private static Config[] COLOR_CONFIGS = new Config[] {Config.ARGB_8888,
+            Config.RGB_565};
+    private static int[] SAMPLESIZES = new int[] {1, 4};
+
+    private int[] mExpectedColors = new int [TILE_SIZE * TILE_SIZE];
+    private int[] mActualColors = new int [TILE_SIZE * TILE_SIZE];
+
+    // We allow a certain degree of discrepancy between the tile-based decoding
+    // result and the regular decoding result, because the two decoders may have
+    // different implementations. The allowable discrepancy is set to a mean
+    // square error of 3 * (1 * 1) among the RGB values.
+    private int mMseMargin = 3 * (1 * 1);
+
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mRes = getInstrumentation().getTargetContext().getResources();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        for (File file : mFilesCreated) {
+            file.delete();
+        }
+        super.tearDown();
+    }
+
+    @TestTargetNew(
+        level = TestLevel.COMPLETE,
+        method = "newInstance",
+        args = {java.lang.String.class, boolean.class}
+    )
+    public void testNewInstanceInputStream() throws IOException {
+        for (int i = 0; i < RES_IDS.length; ++i) {
+            InputStream is = obtainInputStream(RES_IDS[i]);
+            try {
+                BitmapRegionDecoder decoder =
+                        BitmapRegionDecoder.newInstance(is, false);
+                assertEquals(WIDTHS[i], decoder.getWidth());
+                assertEquals(HEIGHTS[i], decoder.getHeight());
+            } catch (IOException e) {
+                assertEquals(WIDTHS[i], -1);
+                assertEquals(HEIGHTS[i], -1);
+            } finally {
+                if (is != null) {
+                    is.close();
+                }
+            }
+        }
+    }
+
+    @TestTargetNew(
+            level = TestLevel.COMPLETE,
+            method = "newInstance",
+            args = {byte[].class, int.class, int.class, boolean.class}
+    )
+    public void testNewInstanceByteArray() throws IOException {
+        for (int i = 0; i < RES_IDS.length; ++i) {
+            byte[] imageData = obtainByteArray(RES_IDS[i]);
+            try {
+                BitmapRegionDecoder decoder = BitmapRegionDecoder
+                        .newInstance(imageData, 0, imageData.length, false);
+                assertEquals(WIDTHS[i], decoder.getWidth());
+                assertEquals(HEIGHTS[i], decoder.getHeight());
+            } catch (IOException e) {
+                assertEquals(WIDTHS[i], -1);
+                assertEquals(HEIGHTS[i], -1);
+            }
+        }
+    }
+
+    @TestTargetNew(
+            level = TestLevel.COMPLETE,
+            method = "newInstance",
+            args = {java.io.FileDescriptor.class, boolean.class}
+    )
+    public void testNewInstanceStringAndFileDescriptor() throws IOException {
+        for (int i = 0; i < RES_IDS.length; ++i) {
+            String filepath = obtainPath(i);
+            FileDescriptor fd = obtainDescriptor(filepath);
+            try {
+                BitmapRegionDecoder decoder1 =
+                        BitmapRegionDecoder.newInstance(filepath, false);
+                assertEquals(WIDTHS[i], decoder1.getWidth());
+                assertEquals(HEIGHTS[i], decoder1.getHeight());
+
+                BitmapRegionDecoder decoder2 =
+                        BitmapRegionDecoder.newInstance(fd, false);
+                assertEquals(WIDTHS[i], decoder2.getWidth());
+                assertEquals(HEIGHTS[i], decoder2.getHeight());
+            } catch (IOException e) {
+                assertEquals(WIDTHS[i], -1);
+                assertEquals(HEIGHTS[i], -1);
+            }
+        }
+    }
+
+    @TestTargetNew(
+            level = TestLevel.PARTIAL_COMPLETE,
+            method = "decodeRegion",
+            args = {android.graphics.Rect.class, android.graphics.BitmapFactory.Options.class}
+    )
+    public void testDecodeRegionInputStream() throws IOException {
+        Options opts = new BitmapFactory.Options();
+        for (int i = 0; i < NUM_TEST_IMAGES; ++i) {
+            for (int j = 0; j < SAMPLESIZES.length; ++j) {
+                for (int k = 0; k < COLOR_CONFIGS.length; ++k) {
+                    opts.inSampleSize = SAMPLESIZES[j];
+                    opts.inPreferredConfig = COLOR_CONFIGS[k];
+
+                    InputStream is1 = obtainInputStream(RES_IDS[i]);
+                    BitmapRegionDecoder decoder = BitmapRegionDecoder.newInstance(is1, false);
+                    InputStream is2 = obtainInputStream(RES_IDS[i]);
+                    Bitmap wholeImage = BitmapFactory.decodeStream(is2, null, opts);
+
+                    compareRegionByRegion(decoder, opts, wholeImage);
+                    wholeImage.recycle();
+                }
+            }
+        }
+    }
+
+    @TestTargetNew(
+            level = TestLevel.PARTIAL_COMPLETE,
+            method = "decodeRegion",
+            args = {android.graphics.Rect.class, android.graphics.BitmapFactory.Options.class}
+    )
+    public void testDecodeRegionByteArray() throws IOException {
+        Options opts = new BitmapFactory.Options();
+        for (int i = 0; i < NUM_TEST_IMAGES; ++i) {
+            for (int j = 0; j < SAMPLESIZES.length; ++j) {
+                for (int k = 0; k < COLOR_CONFIGS.length; ++k) {
+                    opts.inSampleSize = SAMPLESIZES[j];
+                    opts.inPreferredConfig = COLOR_CONFIGS[k];
+
+                    byte[] imageData = obtainByteArray(RES_IDS[i]);
+                    BitmapRegionDecoder decoder = BitmapRegionDecoder
+                            .newInstance(imageData, 0, imageData.length, false);
+                    Bitmap wholeImage = BitmapFactory.decodeByteArray(imageData,
+                            0, imageData.length, opts);
+
+                    compareRegionByRegion(decoder, opts, wholeImage);
+                    wholeImage.recycle();
+                }
+            }
+        }
+    }
+
+    @TestTargetNew(
+            level = TestLevel.PARTIAL_COMPLETE,
+            method = "decodeRegion",
+            args = {android.graphics.Rect.class, android.graphics.BitmapFactory.Options.class}
+    )
+    public void testDecodeRegionStringAndFileDescriptor() throws IOException {
+        Options opts = new BitmapFactory.Options();
+        for (int i = 0; i < NUM_TEST_IMAGES; ++i) {
+            String filepath = obtainPath(i);
+            for (int j = 0; j < SAMPLESIZES.length; ++j) {
+                for (int k = 0; k < COLOR_CONFIGS.length; ++k) {
+                    opts.inSampleSize = SAMPLESIZES[j];
+                    opts.inPreferredConfig = COLOR_CONFIGS[k];
+
+                    BitmapRegionDecoder decoder =
+                        BitmapRegionDecoder.newInstance(filepath, false);
+                    Bitmap wholeImage = BitmapFactory.decodeFile(filepath, opts);
+                    compareRegionByRegion(decoder, opts, wholeImage);
+
+                    FileDescriptor fd1 = obtainDescriptor(filepath);
+                    decoder = BitmapRegionDecoder.newInstance(fd1, false);
+                    FileDescriptor fd2 = obtainDescriptor(filepath);
+                    compareRegionByRegion(decoder, opts, wholeImage);
+                    wholeImage.recycle();
+                }
+            }
+        }
+    }
+
+    @TestTargetNew(
+            level = TestLevel.COMPLETE,
+            method = "recycle",
+            args = {}
+    )
+    public void testRecycle() throws IOException {
+        InputStream is = obtainInputStream(RES_IDS[0]);
+        BitmapRegionDecoder decoder = BitmapRegionDecoder.newInstance(is, false);
+        decoder.recycle();
+        try {
+            decoder.getWidth();
+            fail("Should throw an exception!");
+        } catch (Exception e) {
+        }
+
+        try {
+            decoder.getHeight();
+            fail("Should throw an exception!");
+        } catch (Exception e) {
+        }
+
+        Rect rect = new Rect(0, 0, WIDTHS[0], HEIGHTS[0]);
+        BitmapFactory.Options opts = new BitmapFactory.Options();
+        try {
+            decoder.decodeRegion(rect, opts);
+            fail("Should throw an exception!");
+        } catch (Exception e) {
+        }
+    }
+
+    private void compareRegionByRegion(BitmapRegionDecoder decoder,
+            Options opts, Bitmap wholeImage) {
+        int width = decoder.getWidth();
+        int height = decoder.getHeight();
+        Rect rect = new Rect(0, 0, width, height);
+        int numCols = (width + TILE_SIZE - 1) / TILE_SIZE;
+        int numRows = (height + TILE_SIZE - 1) / TILE_SIZE;
+        Bitmap actual;
+        Bitmap expected;
+
+        for (int i = 0; i < numCols; ++i) {
+            for (int j = 0; j < numRows; ++j) {
+                Rect rect1 = new Rect(i * TILE_SIZE, j * TILE_SIZE,
+                        (i + 1) * TILE_SIZE, (j + 1) * TILE_SIZE);
+                rect1.intersect(rect);
+                actual = decoder.decodeRegion(rect1, opts);
+                int left = rect1.left / opts.inSampleSize;
+                int top = rect1.top / opts.inSampleSize;
+                Rect rect2 = new Rect(left, top, left + actual.getWidth(),
+                        top + actual.getHeight());
+                expected = Bitmap.createBitmap(wholeImage, rect2.left,
+                        rect2.top, rect2.width(), rect2.height(), null, false);
+                compareBitmaps(expected, actual, mMseMargin, true);
+                actual.recycle();
+                expected.recycle();
+            }
+        }
+    }
+
+    private InputStream obtainInputStream(int resId) {
+        return mRes.openRawResource(resId);
+    }
+
+    private byte[] obtainByteArray(int resId) throws IOException {
+        InputStream is = obtainInputStream(resId);
+        ByteArrayOutputStream os = new ByteArrayOutputStream();
+        byte[] buffer = new byte[1024];
+        int readLength;
+        while ((readLength = is.read(buffer)) != -1) {
+            os.write(buffer, 0, readLength);
+        }
+        byte[] data = os.toByteArray();
+        is.close();
+        os.close();
+        return data;
+    }
+
+    private String obtainPath(int idx) throws IOException {
+        File dir = getInstrumentation().getTargetContext().getFilesDir();
+        dir.mkdirs();
+        File file = new File(dir, NAMES_TEMP_FILES[idx]);
+        InputStream is = obtainInputStream(RES_IDS[idx]);
+        FileOutputStream fOutput = new FileOutputStream(file);
+        mFilesCreated.add(file);
+        byte[] dataBuffer = new byte[1024];
+        int readLength = 0;
+        while ((readLength = is.read(dataBuffer)) != -1) {
+            fOutput.write(dataBuffer, 0, readLength);
+        }
+        is.close();
+        fOutput.close();
+        return (file.getPath());
+    }
+
+    private FileDescriptor obtainDescriptor(String path) throws IOException {
+        File file = new File(path);
+        return(ParcelFileDescriptor.open(file,
+                ParcelFileDescriptor.MODE_READ_ONLY).getFileDescriptor());
+    }
+
+    // Compare expected to actual to see if their diff is less then mseMargin.
+    // lessThanMargin is to indicate whether we expect the diff to be
+    // "less than" or "no less than".
+    private void compareBitmaps(Bitmap expected, Bitmap actual,
+            int mseMargin, boolean lessThanMargin) {
+        assertEquals("mismatching widths", expected.getWidth(),
+                actual.getWidth());
+        assertEquals("mismatching heights", expected.getHeight(),
+                actual.getHeight());
+
+        double mse = 0;
+        int width = expected.getWidth();
+        int height = expected.getHeight();
+        int[] expectedColors;
+        int[] actualColors;
+        if (width == TILE_SIZE && height == TILE_SIZE) {
+            expectedColors = mExpectedColors;
+            actualColors = mActualColors;
+        } else {
+            expectedColors = new int [width * height];
+            actualColors = new int [width * height];
+        }
+
+        expected.getPixels(expectedColors, 0, width, 0, 0, width, height);
+        actual.getPixels(actualColors, 0, width, 0, 0, width, height);
+
+        for (int row = 0; row < height; ++row) {
+            for (int col = 0; col < width; ++col) {
+                int idx = row * width + col;
+                mse += distance(expectedColors[idx], actualColors[idx]);
+            }
+        }
+        mse /= width * height;
+
+        if (lessThanMargin) {
+            assertTrue("MSE too large for normal case: " + mse,
+                    mse <= mseMargin);
+        } else {
+            assertFalse("MSE too small for abnormal case: " + mse,
+                    mse <= mseMargin);
+        }
+    }
+
+    private double distance(int exp, int actual) {
+        int r = Color.red(actual) - Color.red(exp);
+        int g = Color.green(actual) - Color.green(exp);
+        int b = Color.blue(actual) - Color.blue(exp);
+        return r * r + g * g + b * b;
+    }
+}
