Move SkBitmapRegionCodec into client_utils/android

Bug: skia:10154

This will make it clear that these files are for Android use and
avoid compiling them for other clients.

Update testing tools to use android::skia::BitmapRegionDecoder, but
only if SK_ENABLE_ANDROID_UTILS is defined.

Take this opportunity to clean up the class:
- The base class, which was originally designed to allow switching
  amongst different implementations, is no longer needed. Rename
  SkBitmapRegionCodec to android::skia::BitmapRegionDecoder
  (following the new convention and matching the Java API name).
  Continue to inherit from SkBitmapRegionDecoder temporarily, to
  allow Android to switch to the new API.
- Use std::unique_ptr instead of passing raw pointers.

Add a test to verify that we only create a BitmapRegionDecoder if
it is one of the supported types.

Change-Id: Ied13fc8acb105fde042553331846d95ae15d6b57
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/287498
Commit-Queue: Leon Scroggins <scroggo@google.com>
Reviewed-by: Derek Sollenberger <djsollen@google.com>
diff --git a/BUILD.gn b/BUILD.gn
index 33dbc35..333995d 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -275,9 +275,16 @@
 optional("android_utils") {
   enabled = skia_enable_android_utils
 
-  public = [ "client_utils/android/FrontBufferedStream.h" ]
+  public = [
+    "client_utils/android/BRDAllocator.h",
+    "client_utils/android/BitmapRegionDecoder.h",
+    "client_utils/android/FrontBufferedStream.h",
+  ]
   public_defines = [ "SK_ENABLE_ANDROID_UTILS" ]
-  sources = [ "client_utils/android/FrontBufferedStream.cpp" ]
+  sources = [
+    "client_utils/android/BitmapRegionDecoder.cpp",
+    "client_utils/android/FrontBufferedStream.cpp",
+  ]
 }
 
 optional("fontmgr_android") {
@@ -922,7 +929,6 @@
   sources += [
     "src/android/SkAndroidFrameworkUtils.cpp",
     "src/android/SkAnimatedImage.cpp",
-    "src/android/SkBitmapRegionCodec.cpp",
     "src/android/SkBitmapRegionDecoder.cpp",
     "src/codec/SkAndroidCodec.cpp",
     "src/codec/SkAndroidCodecAdapter.cpp",
diff --git a/bench/BitmapRegionDecoderBench.cpp b/bench/BitmapRegionDecoderBench.cpp
index 52014b9..c762373 100644
--- a/bench/BitmapRegionDecoderBench.cpp
+++ b/bench/BitmapRegionDecoderBench.cpp
@@ -6,7 +6,9 @@
  */
 
 #include "bench/BitmapRegionDecoderBench.h"
+#ifdef SK_ENABLE_ANDROID_UTILS
 #include "bench/CodecBenchPriv.h"
+#include "client_utils/android/BitmapRegionDecoder.h"
 #include "include/core/SkBitmap.h"
 #include "src/core/SkOSFile.h"
 
@@ -36,7 +38,7 @@
 }
 
 void BitmapRegionDecoderBench::onDelayedSetup() {
-    fBRD.reset(SkBitmapRegionDecoder::Create(fData, SkBitmapRegionDecoder::kAndroidCodec_Strategy));
+    fBRD = android::skia::BitmapRegionDecoder::Make(fData);
 }
 
 void BitmapRegionDecoderBench::onDraw(int n, SkCanvas* canvas) {
@@ -47,3 +49,4 @@
         SkAssertResult(fBRD->decodeRegion(&bm, nullptr, fSubset, fSampleSize, ct, false, cs));
     }
 }
+#endif // SK_ENABLE_ANDROID_UTILS
diff --git a/bench/BitmapRegionDecoderBench.h b/bench/BitmapRegionDecoderBench.h
index 3d3372f..5e87ea8 100644
--- a/bench/BitmapRegionDecoderBench.h
+++ b/bench/BitmapRegionDecoderBench.h
@@ -9,12 +9,18 @@
 #define BitmapRegionDecoderBench_DEFINED
 
 #include "bench/Benchmark.h"
-#include "include/android/SkBitmapRegionDecoder.h"
+#ifdef SK_ENABLE_ANDROID_UTILS
 #include "include/core/SkData.h"
 #include "include/core/SkImageInfo.h"
 #include "include/core/SkRefCnt.h"
 #include "include/core/SkString.h"
 
+namespace android {
+namespace skia {
+class BitmapRegionDecoder;
+}
+}
+
 /**
  *  Benchmark Android's BitmapRegionDecoder for a particular colorType, sampleSize, and subset.
  *
@@ -34,12 +40,13 @@
     void onDelayedSetup() override;
 
 private:
-    SkString                                       fName;
-    std::unique_ptr<SkBitmapRegionDecoder>         fBRD;
-    sk_sp<SkData>                                  fData;
-    const SkColorType                              fColorType;
-    const uint32_t                                 fSampleSize;
-    const SkIRect                                  fSubset;
+    SkString                                            fName;
+    std::unique_ptr<android::skia::BitmapRegionDecoder> fBRD;
+    sk_sp<SkData>                                       fData;
+    const SkColorType                                   fColorType;
+    const uint32_t                                      fSampleSize;
+    const SkIRect                                       fSubset;
     typedef Benchmark INHERITED;
 };
+#endif // SK_ENABLE_ANDROID_UTILS
 #endif // BitmapRegionDecoderBench_DEFINED
diff --git a/bench/nanobench.cpp b/bench/nanobench.cpp
index 81e1c35..b734b8a 100644
--- a/bench/nanobench.cpp
+++ b/bench/nanobench.cpp
@@ -11,7 +11,6 @@
 
 #include "bench/AndroidCodecBench.h"
 #include "bench/Benchmark.h"
-#include "bench/BitmapRegionDecoderBench.h"
 #include "bench/CodecBench.h"
 #include "bench/CodecBenchPriv.h"
 #include "bench/GMBench.h"
@@ -20,7 +19,6 @@
 #include "bench/SKPAnimationBench.h"
 #include "bench/SKPBench.h"
 #include "bench/SkGlyphCacheBench.h"
-#include "include/android/SkBitmapRegionDecoder.h"
 #include "include/codec/SkAndroidCodec.h"
 #include "include/codec/SkCodec.h"
 #include "include/core/SkCanvas.h"
@@ -52,6 +50,11 @@
 #include "experimental/svg/model/SkSVGDOM.h"
 #endif  // SK_XML
 
+#ifdef SK_ENABLE_ANDROID_UTILS
+#include "bench/BitmapRegionDecoderBench.h"
+#include "client_utils/android/BitmapRegionDecoder.h"
+#endif
+
 #include <cinttypes>
 #include <stdlib.h>
 #include <thread>
@@ -586,10 +589,10 @@
 #pragma warning ( pop )
 #endif
 
+#ifdef SK_ENABLE_ANDROID_UTILS
 static bool valid_brd_bench(sk_sp<SkData> encoded, SkColorType colorType, uint32_t sampleSize,
         uint32_t minOutputSize, int* width, int* height) {
-    std::unique_ptr<SkBitmapRegionDecoder> brd(
-            SkBitmapRegionDecoder::Create(encoded, SkBitmapRegionDecoder::kAndroidCodec_Strategy));
+    auto brd = android::skia::BitmapRegionDecoder::Make(encoded);
     if (nullptr == brd.get()) {
         // This is indicates that subset decoding is not supported for a particular image format.
         return false;
@@ -607,6 +610,7 @@
     *height = brd->height();
     return true;
 }
+#endif
 
 static void cleanup_run(Target* target) {
     delete target;
@@ -967,6 +971,7 @@
             fCurrentSampleSize = 0;
         }
 
+#ifdef SK_ENABLE_ANDROID_UTILS
         // Run the BRDBenches
         // We intend to create benchmarks that model the use cases in
         // android/libraries/social/tiledimage.  In this library, an image is decoded in 512x512
@@ -1050,6 +1055,7 @@
             }
             fCurrentColorType = 0;
         }
+#endif // SK_ENABLE_ANDROID_UTILS
 
         return nullptr;
     }
@@ -1079,6 +1085,7 @@
     }
 
 private:
+#ifdef SK_ENABLE_ANDROID_UTILS
     enum SubsetType {
         kTopLeft_SubsetType     = 0,
         kTopRight_SubsetType    = 1,
@@ -1090,6 +1097,7 @@
         kLast_SubsetType        = kZoom_SubsetType,
         kLastSingle_SubsetType  = kBottomRight_SubsetType,
     };
+#endif
 
     const BenchRegistry* fBenches;
     const skiagm::GMRegistry* fGMs;
@@ -1117,10 +1125,12 @@
     int fCurrentUseMPD = 0;
     int fCurrentCodec = 0;
     int fCurrentAndroidCodec = 0;
+#ifdef SK_ENABLE_ANDROID_UTILS
     int fCurrentBRDImage = 0;
+    int fCurrentSubsetType = 0;
+#endif
     int fCurrentColorType = 0;
     int fCurrentAlphaType = 0;
-    int fCurrentSubsetType = 0;
     int fCurrentSampleSize = 0;
     int fCurrentAnimSKP = 0;
 };
diff --git a/client_utils/android/BRDAllocator.h b/client_utils/android/BRDAllocator.h
new file mode 100644
index 0000000..904676d
--- /dev/null
+++ b/client_utils/android/BRDAllocator.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef BRDAllocator_DEFINED
+#define BRDAllocator_DEFINED
+
+#include "include/codec/SkCodec.h"
+#include "include/core/SkBitmap.h"
+
+namespace android {
+namespace skia {
+
+/**
+ *  Abstract subclass of SkBitmap's allocator.
+ *  Allows the allocator to indicate if the memory it allocates
+ *  is zero initialized.
+ */
+class BRDAllocator : public SkBitmap::Allocator {
+public:
+
+    /**
+     *  Indicates if the memory allocated by this allocator is
+     *  zero initialized.
+     */
+    virtual SkCodec::ZeroInitialized zeroInit() const = 0;
+};
+
+} // namespace skia
+} // namespace android
+
+#endif // BRDAllocator_DEFINED
diff --git a/src/android/SkBitmapRegionCodec.cpp b/client_utils/android/BitmapRegionDecoder.cpp
similarity index 81%
rename from src/android/SkBitmapRegionCodec.cpp
rename to client_utils/android/BitmapRegionDecoder.cpp
index 081d0bb..ec6151e 100644
--- a/src/android/SkBitmapRegionCodec.cpp
+++ b/client_utils/android/BitmapRegionDecoder.cpp
@@ -5,17 +5,40 @@
  * found in the LICENSE file.
  */
 
+#include "client_utils/android/BitmapRegionDecoder.h"
+#include "client_utils/android/BitmapRegionDecoderPriv.h"
 #include "include/codec/SkAndroidCodec.h"
-#include "src/android/SkBitmapRegionCodec.h"
-#include "src/android/SkBitmapRegionDecoderPriv.h"
 #include "src/codec/SkCodecPriv.h"
 
-SkBitmapRegionCodec::SkBitmapRegionCodec(SkAndroidCodec* codec)
+namespace android {
+namespace skia {
+
+std::unique_ptr<BitmapRegionDecoder> BitmapRegionDecoder::Make(sk_sp<SkData> data) {
+    auto codec = SkAndroidCodec::MakeFromData(std::move(data));
+    if (nullptr == codec) {
+        SkCodecPrintf("Error: Failed to create codec.\n");
+        return nullptr;
+    }
+
+    switch (codec->getEncodedFormat()) {
+        case SkEncodedImageFormat::kJPEG:
+        case SkEncodedImageFormat::kPNG:
+        case SkEncodedImageFormat::kWEBP:
+        case SkEncodedImageFormat::kHEIF:
+            break;
+        default:
+            return nullptr;
+    }
+
+    return std::unique_ptr<BitmapRegionDecoder>(new BitmapRegionDecoder(std::move(codec)));
+}
+
+BitmapRegionDecoder::BitmapRegionDecoder(std::unique_ptr<SkAndroidCodec> codec)
     : INHERITED(codec->getInfo().width(), codec->getInfo().height())
-    , fCodec(codec)
+    , fCodec(std::move(codec))
 {}
 
-bool SkBitmapRegionCodec::decodeRegion(SkBitmap* bitmap, SkBRDAllocator* allocator,
+bool BitmapRegionDecoder::decodeRegion(SkBitmap* bitmap, BRDAllocator* allocator,
         const SkIRect& desiredSubset, int sampleSize, SkColorType dstColorType,
         bool requireUnpremul, sk_sp<SkColorSpace> dstColorSpace) {
 
@@ -116,3 +139,6 @@
             return false;
     }
 }
+
+} // namespace skia
+} // namespace android
diff --git a/src/android/SkBitmapRegionCodec.h b/client_utils/android/BitmapRegionDecoder.h
similarity index 63%
rename from src/android/SkBitmapRegionCodec.h
rename to client_utils/android/BitmapRegionDecoder.h
index 2185951..cbd9745 100644
--- a/src/android/SkBitmapRegionCodec.h
+++ b/client_utils/android/BitmapRegionDecoder.h
@@ -5,25 +5,24 @@
  * found in the LICENSE file.
  */
 
-#ifndef SkBitmapRegionCodec_DEFINED
-#define SkBitmapRegionCodec_DEFINED
+#ifndef BitmapRegionDecoder_DEFINED
+#define BitmapRegionDecoder_DEFINED
 
+#include "client_utils/android/BRDAllocator.h"
+// Temporary, until Android switches to the new class.
 #include "include/android/SkBitmapRegionDecoder.h"
 #include "include/codec/SkAndroidCodec.h"
 #include "include/core/SkBitmap.h"
+#include "include/core/SkData.h"
 
-/*
- * This class implements SkBitmapRegionDecoder using an SkAndroidCodec.
- */
-class SkBitmapRegionCodec : public SkBitmapRegionDecoder {
+namespace android {
+namespace skia {
+
+class BitmapRegionDecoder final : public SkBitmapRegionDecoder {
 public:
+    static std::unique_ptr<BitmapRegionDecoder> Make(sk_sp<SkData> data);
 
-    /*
-     * Takes ownership of pointer to codec
-     */
-    SkBitmapRegionCodec(SkAndroidCodec* codec);
-
-    bool decodeRegion(SkBitmap* bitmap, SkBRDAllocator* allocator,
+    bool decodeRegion(SkBitmap* bitmap, BRDAllocator* allocator,
                       const SkIRect& desiredSubset, int sampleSize,
                       SkColorType colorType, bool requireUnpremul,
                       sk_sp<SkColorSpace> prefColorSpace) override;
@@ -40,10 +39,14 @@
     }
 
 private:
+    BitmapRegionDecoder(std::unique_ptr<SkAndroidCodec> codec);
 
     std::unique_ptr<SkAndroidCodec> fCodec;
 
     typedef SkBitmapRegionDecoder INHERITED;
 
 };
-#endif  // SkBitmapRegionCodec_DEFINED
+
+} // namespace skia
+} // namespace android
+#endif  // BitmapRegionDecoder_DEFINED
diff --git a/src/android/SkBitmapRegionDecoderPriv.h b/client_utils/android/BitmapRegionDecoderPriv.h
similarity index 93%
rename from src/android/SkBitmapRegionDecoderPriv.h
rename to client_utils/android/BitmapRegionDecoderPriv.h
index 905d460..d63d4ef 100644
--- a/src/android/SkBitmapRegionDecoderPriv.h
+++ b/client_utils/android/BitmapRegionDecoderPriv.h
@@ -5,8 +5,8 @@
  * found in the LICENSE file.
  */
 
-#ifndef SkBitmapRegionDecoderPriv_DEFINED
-#define SkBitmapRegionDecoderPriv_DEFINED
+#ifndef BitmapRegionDecoderPriv_DEFINED
+#define BitmapRegionDecoderPriv_DEFINED
 
 #include "include/core/SkRect.h"
 
@@ -58,4 +58,4 @@
     return SubsetType::kFullyInside_SubsetType;
 }
 
-#endif // SkBitmapRegionDecoderPriv_DEFINED
+#endif // BitmapRegionDecoderPriv_DEFINED
diff --git a/dm/DM.cpp b/dm/DM.cpp
index d4df03d..828f55b 100644
--- a/dm/DM.cpp
+++ b/dm/DM.cpp
@@ -611,6 +611,7 @@
     push_src("image", folder, src);
 }
 
+#ifdef SK_ENABLE_ANDROID_UTILS
 static void push_brd_src(Path path, CodecSrc::DstColorType dstColorType, BRDSrc::Mode mode,
         uint32_t sampleSize) {
     SkString folder("brd_android_codec");
@@ -669,6 +670,7 @@
         }
     }
 }
+#endif // SK_ENABLE_ANDROID_UTILS
 
 static void push_codec_srcs(Path path) {
     sk_sp<SkData> encoded(SkData::MakeFromFileName(path.c_str()));
@@ -797,6 +799,7 @@
             }
         }
 
+#ifdef SK_ENABLE_ANDROID_UTILS
         static const char* const brdExts[] = {
             "jpg", "jpeg", "png", "webp",
             "JPG", "JPEG", "PNG", "WEBP",
@@ -808,6 +811,7 @@
                 break;
             }
         }
+#endif
     }
 
     // Push image generator GPU test.
diff --git a/dm/DMSrcSink.cpp b/dm/DMSrcSink.cpp
index e5eb975..d16ed14 100644
--- a/dm/DMSrcSink.cpp
+++ b/dm/DMSrcSink.cpp
@@ -68,6 +68,10 @@
     #include "include/svg/SkSVGCanvas.h"
     #include "src/xml/SkXMLWriter.h"
 #endif
+
+#if defined(SK_ENABLE_ANDROID_UTILS)
+    #include "client_utils/android/BitmapRegionDecoder.h"
+#endif
 #include "tests/TestUtils.h"
 
 #include <cmath>
@@ -120,6 +124,11 @@
 
 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
+static SkString get_scaled_name(const Path& path, float scale) {
+    return SkStringPrintf("%s_%.3f", SkOSPath::Basename(path.c_str()).c_str(), scale);
+}
+
+#ifdef SK_ENABLE_ANDROID_UTILS
 BRDSrc::BRDSrc(Path path, Mode mode, CodecSrc::DstColorType dstColorType, uint32_t sampleSize)
     : fPath(path)
     , fMode(mode)
@@ -133,12 +142,9 @@
         || flags.approach != SinkFlags::kDirect;
 }
 
-static SkBitmapRegionDecoder* create_brd(Path path) {
+static std::unique_ptr<android::skia::BitmapRegionDecoder> create_brd(Path path) {
     sk_sp<SkData> encoded(SkData::MakeFromFileName(path.c_str()));
-    if (!encoded) {
-        return nullptr;
-    }
-    return SkBitmapRegionDecoder::Create(encoded, SkBitmapRegionDecoder::kAndroidCodec_Strategy);
+    return android::skia::BitmapRegionDecoder::Make(encoded);
 }
 
 static inline void alpha8_to_gray8(SkBitmap* bitmap) {
@@ -169,7 +175,7 @@
             break;
     }
 
-    std::unique_ptr<SkBitmapRegionDecoder> brd(create_brd(fPath));
+    auto brd = create_brd(fPath);
     if (nullptr == brd.get()) {
         return Result::Skip("Could not create brd for %s.", fPath.c_str());
     }
@@ -273,7 +279,7 @@
 }
 
 SkISize BRDSrc::size() const {
-    std::unique_ptr<SkBitmapRegionDecoder> brd(create_brd(fPath));
+    auto brd = create_brd(fPath);
     if (brd) {
         return {std::max(1, brd->width() / (int)fSampleSize),
                 std::max(1, brd->height() / (int)fSampleSize)};
@@ -281,10 +287,6 @@
     return {0, 0};
 }
 
-static SkString get_scaled_name(const Path& path, float scale) {
-    return SkStringPrintf("%s_%.3f", SkOSPath::Basename(path.c_str()).c_str(), scale);
-}
-
 Name BRDSrc::name() const {
     // We will replicate the names used by CodecSrc so that images can
     // be compared in Gold.
@@ -294,6 +296,8 @@
     return get_scaled_name(fPath, 1.0f / (float) fSampleSize);
 }
 
+#endif // SK_ENABLE_ANDROID_UTILS
+
 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
 static bool serial_from_path_name(const SkString& path) {
diff --git a/dm/DMSrcSink.h b/dm/DMSrcSink.h
index 3dd109b..0aa348c 100644
--- a/dm/DMSrcSink.h
+++ b/dm/DMSrcSink.h
@@ -9,7 +9,6 @@
 #define DMSrcSink_DEFINED
 
 #include "gm/gm.h"
-#include "include/android/SkBitmapRegionDecoder.h"
 #include "include/core/SkBBHFactory.h"
 #include "include/core/SkBitmap.h"
 #include "include/core/SkCanvas.h"
@@ -194,6 +193,7 @@
     bool                    fRunSerially;
 };
 
+#ifdef SK_ENABLE_ANDROID_UTILS
 // Allows for testing of various implementations of Android's BitmapRegionDecoder
 class BRDSrc : public Src {
 public:
@@ -219,6 +219,7 @@
     CodecSrc::DstColorType                   fDstColorType;
     uint32_t                                 fSampleSize;
 };
+#endif
 
 class ImageGenSrc : public Src {
 public:
diff --git a/gn/tests.gni b/gn/tests.gni
index 63354fc..e460148 100644
--- a/gn/tests.gni
+++ b/gn/tests.gni
@@ -15,6 +15,7 @@
   "$_tests/ApplyGammaTest.cpp",
   "$_tests/ArenaAllocTest.cpp",
   "$_tests/AsADashTest.cpp",
+  "$_tests/BRDTest.cpp",
   "$_tests/BackendAllocationTest.cpp",
   "$_tests/BadIcoTest.cpp",
   "$_tests/BitSetTest.cpp",
diff --git a/include/android/SkBRDAllocator.h b/include/android/SkBRDAllocator.h
index ae842b7..4af39f9 100644
--- a/include/android/SkBRDAllocator.h
+++ b/include/android/SkBRDAllocator.h
@@ -8,22 +8,9 @@
 #ifndef SkBRDAllocator_DEFINED
 #define SkBRDAllocator_DEFINED
 
-#include "include/codec/SkCodec.h"
-#include "include/core/SkBitmap.h"
+#include "client_utils/android/BRDAllocator.h"
 
-/**
- *  Abstract subclass of SkBitmap's allocator.
- *  Allows the allocator to indicate if the memory it allocates
- *  is zero initialized.
- */
-class SkBRDAllocator : public SkBitmap::Allocator {
-public:
-
-    /**
-     *  Indicates if the memory allocated by this allocator is
-     *  zero initialized.
-     */
-    virtual SkCodec::ZeroInitialized zeroInit() const = 0;
-};
+// Temporary until Android switches over to BRDAllocator directly.
+class SkBRDAllocator : public android::skia::BRDAllocator {};
 
 #endif // SkBRDAllocator_DEFINED
diff --git a/include/android/SkBitmapRegionDecoder.h b/include/android/SkBitmapRegionDecoder.h
index 18ba90b..86e6bf8 100644
--- a/include/android/SkBitmapRegionDecoder.h
+++ b/include/android/SkBitmapRegionDecoder.h
@@ -25,13 +25,6 @@
     };
 
     /*
-     * @param data     Refs the data while this object exists, unrefs on destruction
-     * @param strategy Strategy used for scaling and subsetting
-     * @return         Tries to create an SkBitmapRegionDecoder, returns NULL on failure
-     */
-    static SkBitmapRegionDecoder* Create(sk_sp<SkData>, Strategy strategy);
-
-    /*
      * @param stream   Takes ownership of the stream
      * @param strategy Strategy used for scaling and subsetting
      * @return         Tries to create an SkBitmapRegionDecoder, returns NULL on failure
@@ -59,7 +52,7 @@
      *                        decode into.  Otherwise, we will choose a default.
      *
      */
-    virtual bool decodeRegion(SkBitmap* bitmap, SkBRDAllocator* allocator,
+    virtual bool decodeRegion(SkBitmap* bitmap, android::skia::BRDAllocator* allocator,
                               const SkIRect& desiredSubset, int sampleSize,
                               SkColorType colorType, bool requireUnpremul,
                               sk_sp<SkColorSpace> prefColorSpace = nullptr) = 0;
diff --git a/infra/bots/compile.isolate b/infra/bots/compile.isolate
index 68df0d0..c223893 100644
--- a/infra/bots/compile.isolate
+++ b/infra/bots/compile.isolate
@@ -15,8 +15,7 @@
       '../../build/fuchsia',
       '../../build_overrides',
       '../../buildtools',
-      '../../client_utils/android/FrontBufferedStream.cpp',
-      '../../client_utils/android/FrontBufferedStream.h',
+      '../../client_utils/android',
       '../../dm',
       '../../docs/examples',
       '../../example',
diff --git a/src/android/SkBitmapRegionDecoder.cpp b/src/android/SkBitmapRegionDecoder.cpp
index 328daa3..9cb764c 100644
--- a/src/android/SkBitmapRegionDecoder.cpp
+++ b/src/android/SkBitmapRegionDecoder.cpp
@@ -5,43 +5,43 @@
  * found in the LICENSE file.
  */
 
+#include "include/core/SkTypes.h"
+#ifdef SK_ENABLE_ANDROID_UTILS
+#include "client_utils/android/BitmapRegionDecoder.h"
 #include "include/android/SkBitmapRegionDecoder.h"
 #include "include/codec/SkAndroidCodec.h"
 #include "include/codec/SkCodec.h"
-#include "src/android/SkBitmapRegionCodec.h"
+#include "include/core/SkData.h"
+#include "include/core/SkStream.h"
 #include "src/codec/SkCodecPriv.h"
 
-SkBitmapRegionDecoder* SkBitmapRegionDecoder::Create(
-        sk_sp<SkData> data, Strategy strategy) {
-    return SkBitmapRegionDecoder::Create(new SkMemoryStream(data),
-            strategy);
+// Note: This file is only temporary while we switch Android over to BitmapRegionDecoder
+// directly.
+
+namespace {
+struct Context {
+    std::unique_ptr<SkStreamRewindable> stream;
+};
+}
+
+void release_proc(const void* ptr, void* context) {
+    delete reinterpret_cast<Context*>(context);
 }
 
 SkBitmapRegionDecoder* SkBitmapRegionDecoder::Create(
         SkStreamRewindable* stream, Strategy strategy) {
     std::unique_ptr<SkStreamRewindable> streamDeleter(stream);
-    switch (strategy) {
-        case kAndroidCodec_Strategy: {
-            auto codec = SkAndroidCodec::MakeFromStream(std::move(streamDeleter));
-            if (nullptr == codec) {
-                SkCodecPrintf("Error: Failed to create codec.\n");
-                return nullptr;
-            }
-
-            switch ((SkEncodedImageFormat)codec->getEncodedFormat()) {
-                case SkEncodedImageFormat::kJPEG:
-                case SkEncodedImageFormat::kPNG:
-                case SkEncodedImageFormat::kWEBP:
-                case SkEncodedImageFormat::kHEIF:
-                    break;
-                default:
-                    return nullptr;
-            }
-
-            return new SkBitmapRegionCodec(codec.release());
-        }
-        default:
-            SkASSERT(false);
-            return nullptr;
+    const void* memoryBase = streamDeleter->getMemoryBase();
+    if (!memoryBase) {
+        // All existing clients use an SkMemoryStream.
+        SkASSERT(false);
+        SkCodecPrintf("Error: Need an SkMemoryStream to create an SkBitmapRegionDecoder!");
+        return nullptr;
     }
+    Context* context = new Context;
+    context->stream = std::move(streamDeleter);
+    auto data = SkData::MakeWithProc(memoryBase, context->stream->getLength(), release_proc,
+                                     context);
+    return android::skia::BitmapRegionDecoder::Make(std::move(data)).release();
 }
+#endif // SK_ENABLE_ANDROID_UTILS
diff --git a/tests/BRDTest.cpp b/tests/BRDTest.cpp
new file mode 100644
index 0000000..59b1284
--- /dev/null
+++ b/tests/BRDTest.cpp
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2020 Google LLC
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+// Make sure SkUserConfig.h is included so #defines are available on
+// Android.
+#include "include/core/SkTypes.h"
+#ifdef SK_ENABLE_ANDROID_UTILS
+#include "client_utils/android/BitmapRegionDecoder.h"
+#include "include/codec/SkAndroidCodec.h"
+#include "include/codec/SkCodec.h"
+#include "tests/Test.h"
+#include "tools/Resources.h"
+
+DEF_TEST(BRD_types, r) {
+    static const struct {
+        const char* name;
+        bool supported;
+    } gRec[] = {
+        { "images/arrow.png", true },
+        { "images/box.gif", false },
+        { "images/baby_tux.webp", true },
+        { "images/brickwork-texture.jpg", true },
+        { "images/color_wheel.ico", false },
+#ifdef SK_CODEC_DECODES_RAW
+        { "images/sample_1mp.dng", false },
+#endif
+        { "images/mandrill.wbmp", false },
+        { "images/randPixels.bmp", false },
+    };
+
+    for (const auto& rec : gRec) {
+        auto data = GetResourceAsData(rec.name);
+        if (!data) return;
+
+        REPORTER_ASSERT(r, SkCodec::MakeFromData(data) != nullptr);
+        REPORTER_ASSERT(r, SkAndroidCodec::MakeFromData(data) != nullptr);
+
+        auto brd = android::skia::BitmapRegionDecoder::Make(data);
+        if (rec.supported) {
+            if (!brd) ERRORF(r, "Failed to create BRD from %s", rec.name);
+        } else {
+            if (brd) ERRORF(r, "Should *not* create BRD from %s", rec.name);
+        }
+    }
+}
+#endif // SK_ENABLE_ANDROID_UTILS