Merge "create setChargingPolicy" into main
diff --git a/native/graphics/jni/Android.bp b/native/graphics/jni/Android.bp
index 8ea4632..746c280 100644
--- a/native/graphics/jni/Android.bp
+++ b/native/graphics/jni/Android.bp
@@ -111,6 +111,7 @@
             "allocator_may_return_null = 1",
         ],
     },
+    dictionary: "fuzz/imagedecoder_fuzzer.dict",
     host_supported: true,
 }
 
diff --git a/native/graphics/jni/fuzz/fuzz_imagedecoder.cpp b/native/graphics/jni/fuzz/fuzz_imagedecoder.cpp
index 838bf3f..6743997 100644
--- a/native/graphics/jni/fuzz/fuzz_imagedecoder.cpp
+++ b/native/graphics/jni/fuzz/fuzz_imagedecoder.cpp
@@ -15,32 +15,15 @@
  */
 
 #include <android/imagedecoder.h>
-
 #include <binder/IPCThreadState.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <cstdlib>
-#include <memory>
+#include <fuzzer/FuzzedDataProvider.h>
 
 #ifdef PNG_MUTATOR_DEFINE_LIBFUZZER_CUSTOM_MUTATOR
 #include <fuzz/png_mutator.h>
 #endif
 
-struct DecoderDeleter {
-    void operator()(AImageDecoder* decoder) const { AImageDecoder_delete(decoder); }
-};
-
-using DecoderPointer = std::unique_ptr<AImageDecoder, DecoderDeleter>;
-
-static DecoderPointer makeDecoder(const uint8_t* data, size_t size) {
-    AImageDecoder* decoder = nullptr;
-    int result = AImageDecoder_createFromBuffer(data, size, &decoder);
-    if (result != ANDROID_IMAGE_DECODER_SUCCESS) {
-        // This was not a valid image.
-        return nullptr;
-    }
-    return DecoderPointer(decoder);
-}
+constexpr int32_t kMaxDimension = 5000;
+constexpr int32_t kMinDimension = 0;
 
 struct PixelFreer {
     void operator()(void* pixels) const { std::free(pixels); }
@@ -48,41 +31,113 @@
 
 using PixelPointer = std::unique_ptr<void, PixelFreer>;
 
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
-    // Without this call, decoding HEIF may time out on binder IPC calls.
-    android::ProcessState::self()->startThreadPool();
+AImageDecoder* init(const uint8_t* data, size_t size, bool useFileDescriptor) {
+    AImageDecoder* decoder = nullptr;
+    if (useFileDescriptor) {
+        constexpr char testFd[] = "tempFd";
+        int32_t fileDesc = open(testFd, O_RDWR | O_CREAT | O_TRUNC);
+        write(fileDesc, data, size);
+        AImageDecoder_createFromFd(fileDesc, &decoder);
+        close(fileDesc);
+    } else {
+        AImageDecoder_createFromBuffer(data, size, &decoder);
+    }
+    return decoder;
+}
 
-    DecoderPointer decoder = makeDecoder(data, size);
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    FuzzedDataProvider dataProvider = FuzzedDataProvider(data, size);
+    /**
+     * Use maximum of 80% of buffer for creating decoder and save at least
+     * 20% buffer for fuzzing other APIs
+     */
+    const int32_t dataSize = dataProvider.ConsumeIntegralInRange<int32_t>(0, (size * 80) / 100);
+    std::vector<uint8_t> inputBuffer = dataProvider.ConsumeBytes<uint8_t>(dataSize);
+    AImageDecoder* decoder =
+            init(inputBuffer.data(), inputBuffer.size(), dataProvider.ConsumeBool());
     if (!decoder) {
         return 0;
     }
-
-    const AImageDecoderHeaderInfo* info = AImageDecoder_getHeaderInfo(decoder.get());
-    int32_t width = AImageDecoderHeaderInfo_getWidth(info);
-    int32_t height = AImageDecoderHeaderInfo_getHeight(info);
-
-    // Set an arbitrary limit on the size of an image. The fuzzer runs with a
-    // limited amount of memory, and keeping this allocation small allows the
-    // fuzzer to continue running to try to find more serious problems. This
-    // size is large enough to hold a photo taken by a current gen phone.
-    constexpr int32_t kMaxDimension = 5000;
-    if (width > kMaxDimension || height > kMaxDimension) {
-        return 0;
+    const AImageDecoderHeaderInfo* headerInfo = AImageDecoder_getHeaderInfo(decoder);
+    AImageDecoderFrameInfo* frameInfo = AImageDecoderFrameInfo_create();
+    int32_t height = AImageDecoderHeaderInfo_getHeight(headerInfo);
+    int32_t width = AImageDecoderHeaderInfo_getWidth(headerInfo);
+    while (dataProvider.remaining_bytes()) {
+        auto invokeImageApi = dataProvider.PickValueInArray<const std::function<void()>>({
+                [&]() {
+                    int32_t testHeight =
+                            dataProvider.ConsumeIntegralInRange<int32_t>(kMinDimension,
+                                                                         kMaxDimension);
+                    int32_t testWidth = dataProvider.ConsumeIntegralInRange<int32_t>(kMinDimension,
+                                                                                     kMaxDimension);
+                    int32_t result = AImageDecoder_setTargetSize(decoder, testHeight, testWidth);
+                    if (result == ANDROID_IMAGE_DECODER_SUCCESS) {
+                        height = testHeight;
+                        width = testWidth;
+                    }
+                },
+                [&]() {
+                    const bool required = dataProvider.ConsumeBool();
+                    AImageDecoder_setUnpremultipliedRequired(decoder, required);
+                },
+                [&]() {
+                    AImageDecoder_setAndroidBitmapFormat(
+                            decoder,
+                            dataProvider.ConsumeIntegralInRange<
+                                    int32_t>(ANDROID_BITMAP_FORMAT_NONE,
+                                             ANDROID_BITMAP_FORMAT_RGBA_1010102) /* format */);
+                },
+                [&]() {
+                    AImageDecoder_setDataSpace(decoder,
+                                               dataProvider
+                                                       .ConsumeIntegral<int32_t>() /* dataspace */);
+                },
+                [&]() {
+                    ARect rect{dataProvider.ConsumeIntegral<int32_t>() /* left */,
+                               dataProvider.ConsumeIntegral<int32_t>() /* top */,
+                               dataProvider.ConsumeIntegral<int32_t>() /* right */,
+                               dataProvider.ConsumeIntegral<int32_t>() /* bottom */};
+                    AImageDecoder_setCrop(decoder, rect);
+                },
+                [&]() { AImageDecoderHeaderInfo_getWidth(headerInfo); },
+                [&]() { AImageDecoderHeaderInfo_getMimeType(headerInfo); },
+                [&]() { AImageDecoderHeaderInfo_getAlphaFlags(headerInfo); },
+                [&]() { AImageDecoderHeaderInfo_getAndroidBitmapFormat(headerInfo); },
+                [&]() {
+                    int32_t tempHeight;
+                    int32_t tempWidth;
+                    AImageDecoder_computeSampledSize(decoder,
+                                                     dataProvider.ConsumeIntegral<
+                                                             int>() /* sampleSize */,
+                                                     &tempWidth, &tempHeight);
+                },
+                [&]() { AImageDecoderHeaderInfo_getDataSpace(headerInfo); },
+                [&]() { AImageDecoder_getRepeatCount(decoder); },
+                [&]() { AImageDecoder_getFrameInfo(decoder, frameInfo); },
+                [&]() { AImageDecoderFrameInfo_getDuration(frameInfo); },
+                [&]() { AImageDecoderFrameInfo_hasAlphaWithinBounds(frameInfo); },
+                [&]() { AImageDecoderFrameInfo_getDisposeOp(frameInfo); },
+                [&]() { AImageDecoderFrameInfo_getBlendOp(frameInfo); },
+                [&]() {
+                    AImageDecoder_setInternallyHandleDisposePrevious(
+                            decoder, dataProvider.ConsumeBool() /* handle */);
+                },
+                [&]() { AImageDecoder_rewind(decoder); },
+                [&]() { AImageDecoder_advanceFrame(decoder); },
+                [&]() {
+                    size_t stride = AImageDecoder_getMinimumStride(decoder);
+                    size_t pixelSize = height * stride;
+                    auto pixels = PixelPointer(std::malloc(pixelSize));
+                    if (!pixels.get()) {
+                        return;
+                    }
+                    AImageDecoder_decodeImage(decoder, pixels.get(), stride, pixelSize);
+                },
+        });
+        invokeImageApi();
     }
 
-    size_t stride = AImageDecoder_getMinimumStride(decoder.get());
-    size_t pixelSize = height * stride;
-    auto pixels = PixelPointer(std::malloc(pixelSize));
-    if (!pixels.get()) {
-        return 0;
-    }
-
-    while (true) {
-        int result = AImageDecoder_decodeImage(decoder.get(), pixels.get(), stride, pixelSize);
-        if (result != ANDROID_IMAGE_DECODER_SUCCESS) break;
-
-        result = AImageDecoder_advanceFrame(decoder.get());
-        if (result != ANDROID_IMAGE_DECODER_SUCCESS) break;
-    }
+    AImageDecoderFrameInfo_delete(frameInfo);
+    AImageDecoder_delete(decoder);
     return 0;
 }
diff --git a/native/graphics/jni/fuzz/imagedecoder_fuzzer.dict b/native/graphics/jni/fuzz/imagedecoder_fuzzer.dict
new file mode 100644
index 0000000..5b54a0e
--- /dev/null
+++ b/native/graphics/jni/fuzz/imagedecoder_fuzzer.dict
@@ -0,0 +1,7 @@
+kw1="\x89\x50\x4E\x47"
+kw2="\xff\xD8\xFF"
+kw4="\x52\x49\x46\x46"
+kw5="\x00\x00\x01\x00"
+kw6="\x47\x49\x46\x08"
+kw7="ftyp"
+kw8="\x04\x00\x00\x00"
diff --git a/tools/localedata/extract_icu_data.py b/tools/localedata/extract_icu_data.py
index 81ac897..8f67fa8 100755
--- a/tools/localedata/extract_icu_data.py
+++ b/tools/localedata/extract_icu_data.py
@@ -22,6 +22,8 @@
 import os.path
 import sys
 
+import xml.etree.ElementTree as ElementTree
+
 
 def get_locale_parts(locale):
     """Split a locale into three parts, for langauge, script, and region."""
@@ -40,42 +42,43 @@
 
 def read_likely_subtags(input_file_name):
     """Read and parse ICU's likelySubtags.txt."""
-    with open(input_file_name) as input_file:
-        likely_script_dict = {
-            # Android's additions for pseudo-locales. These internal codes make
-            # sure that the pseudo-locales would not match other English or
-            # Arabic locales. (We can't use private-use ISO 15924 codes, since
-            # they may be used by apps for other purposes.)
-            "en_XA": "~~~A",
-            "ar_XB": "~~~B",
-            # Removed data from later versions of ICU
-            "ji": "Hebr", # Old code for Yiddish, still used in Java and Android
-        }
-        representative_locales = {
-            # Android's additions
-            "en_Latn_GB", # representative for en_Latn_001
-            "es_Latn_MX", # representative for es_Latn_419
-            "es_Latn_US", # representative for es_Latn_419 (not the best idea,
-                          # but Android has been shipping with it for quite a
-                          # while. Fortunately, MX < US, so if both exist, MX
-                          # would be chosen.)
-        }
-        for line in input_file:
-            line = line.strip(u' \n\uFEFF')
-            if line.startswith('//'):
-                continue
-            if '{' in line and '}' in line:
-                from_locale = line[:line.index('{')]
-                to_locale = line[line.index('"')+1:line.rindex('"')]
-                from_lang, from_scr, from_region = get_locale_parts(from_locale)
-                _, to_scr, to_region = get_locale_parts(to_locale)
-                if from_lang == 'und':
-                    continue  # not very useful for our purposes
-                if from_region is None and to_region not in ['001', 'ZZ']:
-                    representative_locales.add(to_locale)
-                if from_scr is None:
-                    likely_script_dict[from_locale] = to_scr
-        return likely_script_dict, frozenset(representative_locales)
+    likely_script_dict = {
+        # Android's additions for pseudo-locales. These internal codes make
+        # sure that the pseudo-locales would not match other English or
+        # Arabic locales. (We can't use private-use ISO 15924 codes, since
+        # they may be used by apps for other purposes.)
+        "en_XA": "~~~A",
+        "ar_XB": "~~~B",
+        # Removed data from later versions of ICU
+        "ji": "Hebr", # Old code for Yiddish, still used in Java and Android
+    }
+    representative_locales = {
+        # Android's additions
+        "en_Latn_GB", # representative for en_Latn_001
+        "es_Latn_MX", # representative for es_Latn_419
+        "es_Latn_US", # representative for es_Latn_419 (not the best idea,
+        # but Android has been shipping with it for quite a
+        # while. Fortunately, MX < US, so if both exist, MX
+        # would be chosen.)
+    }
+    xml_tree = ElementTree.parse(input_file_name)
+    likely_subtags = xml_tree.find('likelySubtags')
+    for child in likely_subtags:
+        from_locale = child.get('from')
+        to_locale = child.get('to')
+        # print(f'from: {from_locale} to: {to_locale}')
+        from_lang, from_scr, from_region = get_locale_parts(from_locale)
+        _, to_scr, to_region = get_locale_parts(to_locale)
+        if to_locale == "FAIL":
+            continue # "FAIL" cases are not useful here.
+        if from_lang == 'und':
+            continue  # not very useful for our purposes
+        if from_region is None and to_region not in ['001', 'ZZ']:
+            representative_locales.add(to_locale)
+        if from_scr is None:
+            likely_script_dict[from_locale] = to_scr
+
+    return likely_script_dict, frozenset(representative_locales)
 
 
 # From packLanguageOrRegion() in ResourceTypes.cpp
@@ -86,7 +89,7 @@
     elif len(inp) == 2:
         return ord(inp[0]), ord(inp[1])
     else:
-        assert len(inp) == 3
+        assert len(inp) == 3, f'Expects a 3-character string, but "{inp}" '
         base = ord(base)
         first = ord(inp[0]) - base
         second = ord(inp[1]) - base
@@ -161,9 +164,10 @@
     print('});')
 
 
-def read_and_dump_likely_data(icu_data_dir):
+def read_and_dump_likely_data(cldr_source_dir):
     """Read and dump the likely-script data."""
-    likely_subtags_txt = os.path.join(icu_data_dir, 'misc', 'likelySubtags.txt')
+    likely_subtags_txt = os.path.join(cldr_source_dir,
+                                      'common', 'supplemental', 'likelySubtags.xml')
     likely_script_dict, representative_locales = read_likely_subtags(
         likely_subtags_txt)
 
@@ -280,10 +284,11 @@
     icu_data_dir = os.path.join(
         source_root,
         'external', 'icu', 'icu4c', 'source', 'data')
+    cldr_source_dir = os.path.join(source_root, 'external', 'cldr')
 
     print('// Auto-generated by %s' % sys.argv[0])
     print()
-    likely_script_dict = read_and_dump_likely_data(icu_data_dir)
+    likely_script_dict = read_and_dump_likely_data(cldr_source_dir)
     read_and_dump_parent_data(icu_data_dir, likely_script_dict)