diff options
231 files changed, 13194 insertions, 12835 deletions
diff --git a/Android.bp b/Android.bp index 5bd332947057..b69fa631de82 100644 --- a/Android.bp +++ b/Android.bp @@ -97,7 +97,7 @@ filegroup { ":platform-compat-native-aidl", // AIDL sources from external directories - ":android.hardware.security.keymint-V1-java-source", + ":android.hardware.security.keymint-V2-java-source", ":android.hardware.security.secureclock-V1-java-source", ":android.security.apc-java-source", ":android.security.authorization-java-source", @@ -175,7 +175,6 @@ java_defaults { "sax/java", "telecomm/java", - "apex/media/aidl/stable", // TODO(b/147699819): remove this "telephony/java", ], @@ -274,6 +273,7 @@ java_defaults { // TODO: remove when moved to the below package "frameworks/base/packages/ConnectivityT/framework-t/aidl-export", "packages/modules/Connectivity/framework/aidl-export", + "packages/modules/Media/apex/aidl/stable", ], }, dxflags: [ @@ -449,21 +449,28 @@ java_library { } // TODO(b/145644363): move this to under StubLibraries.bp or ApiDocs.bp -metalava_framework_docs_args = "--manifest $(location core/res/AndroidManifest.xml) " + - "--hide-package com.android.server " + - "--hide-package android.audio.policy.configuration.V7_0 " + - "--error UnhiddenSystemApi " + - "--hide RequiresPermission " + - "--hide CallbackInterface " + - "--hide MissingPermission --hide BroadcastBehavior " + - "--hide HiddenSuperclass --hide DeprecationMismatch --hide UnavailableSymbol " + - "--hide SdkConstant --hide HiddenTypeParameter --hide Todo --hide Typo " + - "--error NoSettingsProvider " + - "--force-convert-to-warning-nullability-annotations +*:-android.*:+android.icu.*:-dalvik.* " + +metalava_framework_docs_args = "" + "--api-lint-ignore-prefix android.icu. " + "--api-lint-ignore-prefix java. " + "--api-lint-ignore-prefix junit. " + - "--api-lint-ignore-prefix org. " + "--api-lint-ignore-prefix org. " + + "--error NoSettingsProvider " + + "--error UnhiddenSystemApi " + + "--force-convert-to-warning-nullability-annotations +*:-android.*:+android.icu.*:-dalvik.* " + + "--hide BroadcastBehavior " + + "--hide CallbackInterface " + + "--hide DeprecationMismatch " + + "--hide HiddenSuperclass " + + "--hide HiddenTypeParameter " + + "--hide MissingPermission " + + "--hide-package android.audio.policy.configuration.V7_0 " + + "--hide-package com.android.server " + + "--hide RequiresPermission " + + "--hide SdkConstant " + + "--hide Todo " + + "--hide Typo " + + "--hide UnavailableSymbol " + + "--manifest $(location core/res/AndroidManifest.xml) " packages_to_document = [ "android", @@ -549,11 +556,9 @@ stubs_defaults { stubs_defaults { name: "module-classpath-stubs-defaults", aidl: { - local_include_dirs: [ - "apex/media/aidl/stable", - ], include_dirs: [ "packages/modules/Connectivity/framework/aidl-export", + "packages/modules/Media/apex/aidl/stable", ], }, libs: [ diff --git a/Android.mk b/Android.mk index 46529eb64657..d9e202c9305c 100644 --- a/Android.mk +++ b/Android.mk @@ -15,6 +15,14 @@ # LOCAL_PATH := $(call my-dir) +$(eval $(call declare-1p-copy-files,frameworks/base,.ogg)) +$(eval $(call declare-1p-copy-files,frameworks/base,.kl)) +$(eval $(call declare-1p-copy-files,frameworks/base,.kcm)) +$(eval $(call declare-1p-copy-files,frameworks/base,.idc)) +$(eval $(call declare-1p-copy-files,frameworks/base,dirty-image-objects)) +$(eval $(call declare-1p-copy-files,frameworks/base/config,)) +$(eval $(call declare-1p-copy-files,frameworks/native/data,)) + # Load framework-specific path mappings used later in the build. include $(LOCAL_PATH)/pathmap.mk diff --git a/ApiDocs.bp b/ApiDocs.bp index 5595e95631ad..2efeab6da670 100644 --- a/ApiDocs.bp +++ b/ApiDocs.bp @@ -140,11 +140,9 @@ droidstubs { "api-versions-jars-dir", ], aidl: { - local_include_dirs: [ - "apex/media/aidl/stable", - ], include_dirs: [ "packages/modules/Connectivity/framework/aidl-export", + "packages/modules/Media/apex/aidl/stable", ], }, } diff --git a/INPUT_OWNERS b/INPUT_OWNERS new file mode 100644 index 000000000000..6041f637f9c1 --- /dev/null +++ b/INPUT_OWNERS @@ -0,0 +1,3 @@ +michaelwr@google.com +prabirmsp@google.com +svv@google.com diff --git a/StubLibraries.bp b/StubLibraries.bp index 5cb0a785bc2b..39fd511a90ca 100644 --- a/StubLibraries.bp +++ b/StubLibraries.bp @@ -365,6 +365,64 @@ java_library { }, } +//////////////////////////////////////////////////////////////////////// +// api-versions.xml generation, for public and system. This API database +// also contains the android.test.* APIs. +//////////////////////////////////////////////////////////////////////// + +java_library { + name: "android_stubs_current_with_test_libs", + static_libs: [ + "android_stubs_current", + "android.test.base.stubs", + "android.test.mock.stubs", + "android.test.runner.stubs", + ], + defaults: ["android.jar_defaults"], + visibility: [ + "//visibility:override", + "//visibility:private", + ], +} + +java_library { + name: "android_system_stubs_current_with_test_libs", + static_libs: [ + "android_system_stubs_current", + "android.test.base.stubs.system", + "android.test.mock.stubs.system", + "android.test.runner.stubs.system", + ], + defaults: ["android.jar_defaults"], + visibility: [ + "//visibility:override", + "//visibility:private", + ], +} + +droidstubs { + name: "api_versions_public", + srcs: [":android_stubs_current_with_test_libs{.jar}"], + generate_stubs: false, + api_levels_annotations_enabled: true, + api_levels_annotations_dirs: [ + "sdk-dir", + "api-versions-jars-dir", + ], +} + +droidstubs { + name: "api_versions_system", + srcs: [":android_system_stubs_current_with_test_libs{.jar}"], + generate_stubs: false, + api_levels_annotations_enabled: true, + api_levels_annotations_dirs: [ + "sdk-dir", + "api-versions-jars-dir", + ], + api_levels_sdk_type: "system", +} + ///////////////////////////////////////////////////////////////////// // hwbinder.stubs provides APIs required for building HIDL Java // libraries. diff --git a/apct-tests/perftests/core/OWNERS b/apct-tests/perftests/core/OWNERS index 18486af9d12c..2b3564eead31 100644 --- a/apct-tests/perftests/core/OWNERS +++ b/apct-tests/perftests/core/OWNERS @@ -1 +1,5 @@ include /graphics/java/android/graphics/fonts/OWNERS + +# Bug component: 568761 +per-file /apct-tests/perftests/core/res/* = felkachang@google.com,zyy@google.com + diff --git a/apct-tests/perftests/core/res/values/colors.xml b/apct-tests/perftests/core/res/values/colors.xml new file mode 100644 index 000000000000..5e56c250511f --- /dev/null +++ b/apct-tests/perftests/core/res/values/colors.xml @@ -0,0 +1,10022 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2021 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 + --> + +<resources> + <!--- The colors with prefix "i_am_color_%x" and %x is from 0 to 10000. They are used by + ResourcesPerfTest.java --> + <color name="i_am_color_0">#00000000</color> + <color name="i_am_color_1">#00000001</color> + <color name="i_am_color_2">#00000002</color> + <color name="i_am_color_3">#00000003</color> + <color name="i_am_color_4">#00000004</color> + <color name="i_am_color_5">#00000005</color> + <color name="i_am_color_6">#00000006</color> + <color name="i_am_color_7">#00000007</color> + <color name="i_am_color_8">#00000008</color> + <color name="i_am_color_9">#00000009</color> + <color name="i_am_color_a">#0000000a</color> + <color name="i_am_color_b">#0000000b</color> + <color name="i_am_color_c">#0000000c</color> + <color name="i_am_color_d">#0000000d</color> + <color name="i_am_color_e">#0000000e</color> + <color name="i_am_color_f">#0000000f</color> + <color name="i_am_color_10">#00000010</color> + <color name="i_am_color_11">#00000011</color> + <color name="i_am_color_12">#00000012</color> + <color name="i_am_color_13">#00000013</color> + <color name="i_am_color_14">#00000014</color> + <color name="i_am_color_15">#00000015</color> + <color name="i_am_color_16">#00000016</color> + <color name="i_am_color_17">#00000017</color> + <color name="i_am_color_18">#00000018</color> + <color name="i_am_color_19">#00000019</color> + <color name="i_am_color_1a">#0000001a</color> + <color name="i_am_color_1b">#0000001b</color> + <color name="i_am_color_1c">#0000001c</color> + <color name="i_am_color_1d">#0000001d</color> + <color name="i_am_color_1e">#0000001e</color> + <color name="i_am_color_1f">#0000001f</color> + <color name="i_am_color_20">#00000020</color> + <color name="i_am_color_21">#00000021</color> + <color name="i_am_color_22">#00000022</color> + <color name="i_am_color_23">#00000023</color> + <color name="i_am_color_24">#00000024</color> + <color name="i_am_color_25">#00000025</color> + <color name="i_am_color_26">#00000026</color> + <color name="i_am_color_27">#00000027</color> + <color name="i_am_color_28">#00000028</color> + <color name="i_am_color_29">#00000029</color> + <color name="i_am_color_2a">#0000002a</color> + <color name="i_am_color_2b">#0000002b</color> + <color name="i_am_color_2c">#0000002c</color> + <color name="i_am_color_2d">#0000002d</color> + <color name="i_am_color_2e">#0000002e</color> + <color name="i_am_color_2f">#0000002f</color> + <color name="i_am_color_30">#00000030</color> + <color name="i_am_color_31">#00000031</color> + <color name="i_am_color_32">#00000032</color> + <color name="i_am_color_33">#00000033</color> + <color name="i_am_color_34">#00000034</color> + <color name="i_am_color_35">#00000035</color> + <color name="i_am_color_36">#00000036</color> + <color name="i_am_color_37">#00000037</color> + <color name="i_am_color_38">#00000038</color> + <color name="i_am_color_39">#00000039</color> + <color name="i_am_color_3a">#0000003a</color> + <color name="i_am_color_3b">#0000003b</color> + <color name="i_am_color_3c">#0000003c</color> + <color name="i_am_color_3d">#0000003d</color> + <color name="i_am_color_3e">#0000003e</color> + <color name="i_am_color_3f">#0000003f</color> + <color name="i_am_color_40">#00000040</color> + <color name="i_am_color_41">#00000041</color> + <color name="i_am_color_42">#00000042</color> + <color name="i_am_color_43">#00000043</color> + <color name="i_am_color_44">#00000044</color> + <color name="i_am_color_45">#00000045</color> + <color name="i_am_color_46">#00000046</color> + <color name="i_am_color_47">#00000047</color> + <color name="i_am_color_48">#00000048</color> + <color name="i_am_color_49">#00000049</color> + <color name="i_am_color_4a">#0000004a</color> + <color name="i_am_color_4b">#0000004b</color> + <color name="i_am_color_4c">#0000004c</color> + <color name="i_am_color_4d">#0000004d</color> + <color name="i_am_color_4e">#0000004e</color> + <color name="i_am_color_4f">#0000004f</color> + <color name="i_am_color_50">#00000050</color> + <color name="i_am_color_51">#00000051</color> + <color name="i_am_color_52">#00000052</color> + <color name="i_am_color_53">#00000053</color> + <color name="i_am_color_54">#00000054</color> + <color name="i_am_color_55">#00000055</color> + <color name="i_am_color_56">#00000056</color> + <color name="i_am_color_57">#00000057</color> + <color name="i_am_color_58">#00000058</color> + <color name="i_am_color_59">#00000059</color> + <color name="i_am_color_5a">#0000005a</color> + <color name="i_am_color_5b">#0000005b</color> + <color name="i_am_color_5c">#0000005c</color> + <color name="i_am_color_5d">#0000005d</color> + <color name="i_am_color_5e">#0000005e</color> + <color name="i_am_color_5f">#0000005f</color> + <color name="i_am_color_60">#00000060</color> + <color name="i_am_color_61">#00000061</color> + <color name="i_am_color_62">#00000062</color> + <color name="i_am_color_63">#00000063</color> + <color name="i_am_color_64">#00000064</color> + <color name="i_am_color_65">#00000065</color> + <color name="i_am_color_66">#00000066</color> + <color name="i_am_color_67">#00000067</color> + <color name="i_am_color_68">#00000068</color> + <color name="i_am_color_69">#00000069</color> + <color name="i_am_color_6a">#0000006a</color> + <color name="i_am_color_6b">#0000006b</color> + <color name="i_am_color_6c">#0000006c</color> + <color name="i_am_color_6d">#0000006d</color> + <color name="i_am_color_6e">#0000006e</color> + <color name="i_am_color_6f">#0000006f</color> + <color name="i_am_color_70">#00000070</color> + <color name="i_am_color_71">#00000071</color> + <color name="i_am_color_72">#00000072</color> + <color name="i_am_color_73">#00000073</color> + <color name="i_am_color_74">#00000074</color> + <color name="i_am_color_75">#00000075</color> + <color name="i_am_color_76">#00000076</color> + <color name="i_am_color_77">#00000077</color> + <color name="i_am_color_78">#00000078</color> + <color name="i_am_color_79">#00000079</color> + <color name="i_am_color_7a">#0000007a</color> + <color name="i_am_color_7b">#0000007b</color> + <color name="i_am_color_7c">#0000007c</color> + <color name="i_am_color_7d">#0000007d</color> + <color name="i_am_color_7e">#0000007e</color> + <color name="i_am_color_7f">#0000007f</color> + <color name="i_am_color_80">#00000080</color> + <color name="i_am_color_81">#00000081</color> + <color name="i_am_color_82">#00000082</color> + <color name="i_am_color_83">#00000083</color> + <color name="i_am_color_84">#00000084</color> + <color name="i_am_color_85">#00000085</color> + <color name="i_am_color_86">#00000086</color> + <color name="i_am_color_87">#00000087</color> + <color name="i_am_color_88">#00000088</color> + <color name="i_am_color_89">#00000089</color> + <color name="i_am_color_8a">#0000008a</color> + <color name="i_am_color_8b">#0000008b</color> + <color name="i_am_color_8c">#0000008c</color> + <color name="i_am_color_8d">#0000008d</color> + <color name="i_am_color_8e">#0000008e</color> + <color name="i_am_color_8f">#0000008f</color> + <color name="i_am_color_90">#00000090</color> + <color name="i_am_color_91">#00000091</color> + <color name="i_am_color_92">#00000092</color> + <color name="i_am_color_93">#00000093</color> + <color name="i_am_color_94">#00000094</color> + <color name="i_am_color_95">#00000095</color> + <color name="i_am_color_96">#00000096</color> + <color name="i_am_color_97">#00000097</color> + <color name="i_am_color_98">#00000098</color> + <color name="i_am_color_99">#00000099</color> + <color name="i_am_color_9a">#0000009a</color> + <color name="i_am_color_9b">#0000009b</color> + <color name="i_am_color_9c">#0000009c</color> + <color name="i_am_color_9d">#0000009d</color> + <color name="i_am_color_9e">#0000009e</color> + <color name="i_am_color_9f">#0000009f</color> + <color name="i_am_color_a0">#000000a0</color> + <color name="i_am_color_a1">#000000a1</color> + <color name="i_am_color_a2">#000000a2</color> + <color name="i_am_color_a3">#000000a3</color> + <color name="i_am_color_a4">#000000a4</color> + <color name="i_am_color_a5">#000000a5</color> + <color name="i_am_color_a6">#000000a6</color> + <color name="i_am_color_a7">#000000a7</color> + <color name="i_am_color_a8">#000000a8</color> + <color name="i_am_color_a9">#000000a9</color> + <color name="i_am_color_aa">#000000aa</color> + <color name="i_am_color_ab">#000000ab</color> + <color name="i_am_color_ac">#000000ac</color> + <color name="i_am_color_ad">#000000ad</color> + <color name="i_am_color_ae">#000000ae</color> + <color name="i_am_color_af">#000000af</color> + <color name="i_am_color_b0">#000000b0</color> + <color name="i_am_color_b1">#000000b1</color> + <color name="i_am_color_b2">#000000b2</color> + <color name="i_am_color_b3">#000000b3</color> + <color name="i_am_color_b4">#000000b4</color> + <color name="i_am_color_b5">#000000b5</color> + <color name="i_am_color_b6">#000000b6</color> + <color name="i_am_color_b7">#000000b7</color> + <color name="i_am_color_b8">#000000b8</color> + <color name="i_am_color_b9">#000000b9</color> + <color name="i_am_color_ba">#000000ba</color> + <color name="i_am_color_bb">#000000bb</color> + <color name="i_am_color_bc">#000000bc</color> + <color name="i_am_color_bd">#000000bd</color> + <color name="i_am_color_be">#000000be</color> + <color name="i_am_color_bf">#000000bf</color> + <color name="i_am_color_c0">#000000c0</color> + <color name="i_am_color_c1">#000000c1</color> + <color name="i_am_color_c2">#000000c2</color> + <color name="i_am_color_c3">#000000c3</color> + <color name="i_am_color_c4">#000000c4</color> + <color name="i_am_color_c5">#000000c5</color> + <color name="i_am_color_c6">#000000c6</color> + <color name="i_am_color_c7">#000000c7</color> + <color name="i_am_color_c8">#000000c8</color> + <color name="i_am_color_c9">#000000c9</color> + <color name="i_am_color_ca">#000000ca</color> + <color name="i_am_color_cb">#000000cb</color> + <color name="i_am_color_cc">#000000cc</color> + <color name="i_am_color_cd">#000000cd</color> + <color name="i_am_color_ce">#000000ce</color> + <color name="i_am_color_cf">#000000cf</color> + <color name="i_am_color_d0">#000000d0</color> + <color name="i_am_color_d1">#000000d1</color> + <color name="i_am_color_d2">#000000d2</color> + <color name="i_am_color_d3">#000000d3</color> + <color name="i_am_color_d4">#000000d4</color> + <color name="i_am_color_d5">#000000d5</color> + <color name="i_am_color_d6">#000000d6</color> + <color name="i_am_color_d7">#000000d7</color> + <color name="i_am_color_d8">#000000d8</color> + <color name="i_am_color_d9">#000000d9</color> + <color name="i_am_color_da">#000000da</color> + <color name="i_am_color_db">#000000db</color> + <color name="i_am_color_dc">#000000dc</color> + <color name="i_am_color_dd">#000000dd</color> + <color name="i_am_color_de">#000000de</color> + <color name="i_am_color_df">#000000df</color> + <color name="i_am_color_e0">#000000e0</color> + <color name="i_am_color_e1">#000000e1</color> + <color name="i_am_color_e2">#000000e2</color> + <color name="i_am_color_e3">#000000e3</color> + <color name="i_am_color_e4">#000000e4</color> + <color name="i_am_color_e5">#000000e5</color> + <color name="i_am_color_e6">#000000e6</color> + <color name="i_am_color_e7">#000000e7</color> + <color name="i_am_color_e8">#000000e8</color> + <color name="i_am_color_e9">#000000e9</color> + <color name="i_am_color_ea">#000000ea</color> + <color name="i_am_color_eb">#000000eb</color> + <color name="i_am_color_ec">#000000ec</color> + <color name="i_am_color_ed">#000000ed</color> + <color name="i_am_color_ee">#000000ee</color> + <color name="i_am_color_ef">#000000ef</color> + <color name="i_am_color_f0">#000000f0</color> + <color name="i_am_color_f1">#000000f1</color> + <color name="i_am_color_f2">#000000f2</color> + <color name="i_am_color_f3">#000000f3</color> + <color name="i_am_color_f4">#000000f4</color> + <color name="i_am_color_f5">#000000f5</color> + <color name="i_am_color_f6">#000000f6</color> + <color name="i_am_color_f7">#000000f7</color> + <color name="i_am_color_f8">#000000f8</color> + <color name="i_am_color_f9">#000000f9</color> + <color name="i_am_color_fa">#000000fa</color> + <color name="i_am_color_fb">#000000fb</color> + <color name="i_am_color_fc">#000000fc</color> + <color name="i_am_color_fd">#000000fd</color> + <color name="i_am_color_fe">#000000fe</color> + <color name="i_am_color_ff">#000000ff</color> + <color name="i_am_color_100">#00000100</color> + <color name="i_am_color_101">#00000101</color> + <color name="i_am_color_102">#00000102</color> + <color name="i_am_color_103">#00000103</color> + <color name="i_am_color_104">#00000104</color> + <color name="i_am_color_105">#00000105</color> + <color name="i_am_color_106">#00000106</color> + <color name="i_am_color_107">#00000107</color> + <color name="i_am_color_108">#00000108</color> + <color name="i_am_color_109">#00000109</color> + <color name="i_am_color_10a">#0000010a</color> + <color name="i_am_color_10b">#0000010b</color> + <color name="i_am_color_10c">#0000010c</color> + <color name="i_am_color_10d">#0000010d</color> + <color name="i_am_color_10e">#0000010e</color> + <color name="i_am_color_10f">#0000010f</color> + <color name="i_am_color_110">#00000110</color> + <color name="i_am_color_111">#00000111</color> + <color name="i_am_color_112">#00000112</color> + <color name="i_am_color_113">#00000113</color> + <color name="i_am_color_114">#00000114</color> + <color name="i_am_color_115">#00000115</color> + <color name="i_am_color_116">#00000116</color> + <color name="i_am_color_117">#00000117</color> + <color name="i_am_color_118">#00000118</color> + <color name="i_am_color_119">#00000119</color> + <color name="i_am_color_11a">#0000011a</color> + <color name="i_am_color_11b">#0000011b</color> + <color name="i_am_color_11c">#0000011c</color> + <color name="i_am_color_11d">#0000011d</color> + <color name="i_am_color_11e">#0000011e</color> + <color name="i_am_color_11f">#0000011f</color> + <color name="i_am_color_120">#00000120</color> + <color name="i_am_color_121">#00000121</color> + <color name="i_am_color_122">#00000122</color> + <color name="i_am_color_123">#00000123</color> + <color name="i_am_color_124">#00000124</color> + <color name="i_am_color_125">#00000125</color> + <color name="i_am_color_126">#00000126</color> + <color name="i_am_color_127">#00000127</color> + <color name="i_am_color_128">#00000128</color> + <color name="i_am_color_129">#00000129</color> + <color name="i_am_color_12a">#0000012a</color> + <color name="i_am_color_12b">#0000012b</color> + <color name="i_am_color_12c">#0000012c</color> + <color name="i_am_color_12d">#0000012d</color> + <color name="i_am_color_12e">#0000012e</color> + <color name="i_am_color_12f">#0000012f</color> + <color name="i_am_color_130">#00000130</color> + <color name="i_am_color_131">#00000131</color> + <color name="i_am_color_132">#00000132</color> + <color name="i_am_color_133">#00000133</color> + <color name="i_am_color_134">#00000134</color> + <color name="i_am_color_135">#00000135</color> + <color name="i_am_color_136">#00000136</color> + <color name="i_am_color_137">#00000137</color> + <color name="i_am_color_138">#00000138</color> + <color name="i_am_color_139">#00000139</color> + <color name="i_am_color_13a">#0000013a</color> + <color name="i_am_color_13b">#0000013b</color> + <color name="i_am_color_13c">#0000013c</color> + <color name="i_am_color_13d">#0000013d</color> + <color name="i_am_color_13e">#0000013e</color> + <color name="i_am_color_13f">#0000013f</color> + <color name="i_am_color_140">#00000140</color> + <color name="i_am_color_141">#00000141</color> + <color name="i_am_color_142">#00000142</color> + <color name="i_am_color_143">#00000143</color> + <color name="i_am_color_144">#00000144</color> + <color name="i_am_color_145">#00000145</color> + <color name="i_am_color_146">#00000146</color> + <color name="i_am_color_147">#00000147</color> + <color name="i_am_color_148">#00000148</color> + <color name="i_am_color_149">#00000149</color> + <color name="i_am_color_14a">#0000014a</color> + <color name="i_am_color_14b">#0000014b</color> + <color name="i_am_color_14c">#0000014c</color> + <color name="i_am_color_14d">#0000014d</color> + <color name="i_am_color_14e">#0000014e</color> + <color name="i_am_color_14f">#0000014f</color> + <color name="i_am_color_150">#00000150</color> + <color name="i_am_color_151">#00000151</color> + <color name="i_am_color_152">#00000152</color> + <color name="i_am_color_153">#00000153</color> + <color name="i_am_color_154">#00000154</color> + <color name="i_am_color_155">#00000155</color> + <color name="i_am_color_156">#00000156</color> + <color name="i_am_color_157">#00000157</color> + <color name="i_am_color_158">#00000158</color> + <color name="i_am_color_159">#00000159</color> + <color name="i_am_color_15a">#0000015a</color> + <color name="i_am_color_15b">#0000015b</color> + <color name="i_am_color_15c">#0000015c</color> + <color name="i_am_color_15d">#0000015d</color> + <color name="i_am_color_15e">#0000015e</color> + <color name="i_am_color_15f">#0000015f</color> + <color name="i_am_color_160">#00000160</color> + <color name="i_am_color_161">#00000161</color> + <color name="i_am_color_162">#00000162</color> + <color name="i_am_color_163">#00000163</color> + <color name="i_am_color_164">#00000164</color> + <color name="i_am_color_165">#00000165</color> + <color name="i_am_color_166">#00000166</color> + <color name="i_am_color_167">#00000167</color> + <color name="i_am_color_168">#00000168</color> + <color name="i_am_color_169">#00000169</color> + <color name="i_am_color_16a">#0000016a</color> + <color name="i_am_color_16b">#0000016b</color> + <color name="i_am_color_16c">#0000016c</color> + <color name="i_am_color_16d">#0000016d</color> + <color name="i_am_color_16e">#0000016e</color> + <color name="i_am_color_16f">#0000016f</color> + <color name="i_am_color_170">#00000170</color> + <color name="i_am_color_171">#00000171</color> + <color name="i_am_color_172">#00000172</color> + <color name="i_am_color_173">#00000173</color> + <color name="i_am_color_174">#00000174</color> + <color name="i_am_color_175">#00000175</color> + <color name="i_am_color_176">#00000176</color> + <color name="i_am_color_177">#00000177</color> + <color name="i_am_color_178">#00000178</color> + <color name="i_am_color_179">#00000179</color> + <color name="i_am_color_17a">#0000017a</color> + <color name="i_am_color_17b">#0000017b</color> + <color name="i_am_color_17c">#0000017c</color> + <color name="i_am_color_17d">#0000017d</color> + <color name="i_am_color_17e">#0000017e</color> + <color name="i_am_color_17f">#0000017f</color> + <color name="i_am_color_180">#00000180</color> + <color name="i_am_color_181">#00000181</color> + <color name="i_am_color_182">#00000182</color> + <color name="i_am_color_183">#00000183</color> + <color name="i_am_color_184">#00000184</color> + <color name="i_am_color_185">#00000185</color> + <color name="i_am_color_186">#00000186</color> + <color name="i_am_color_187">#00000187</color> + <color name="i_am_color_188">#00000188</color> + <color name="i_am_color_189">#00000189</color> + <color name="i_am_color_18a">#0000018a</color> + <color name="i_am_color_18b">#0000018b</color> + <color name="i_am_color_18c">#0000018c</color> + <color name="i_am_color_18d">#0000018d</color> + <color name="i_am_color_18e">#0000018e</color> + <color name="i_am_color_18f">#0000018f</color> + <color name="i_am_color_190">#00000190</color> + <color name="i_am_color_191">#00000191</color> + <color name="i_am_color_192">#00000192</color> + <color name="i_am_color_193">#00000193</color> + <color name="i_am_color_194">#00000194</color> + <color name="i_am_color_195">#00000195</color> + <color name="i_am_color_196">#00000196</color> + <color name="i_am_color_197">#00000197</color> + <color name="i_am_color_198">#00000198</color> + <color name="i_am_color_199">#00000199</color> + <color name="i_am_color_19a">#0000019a</color> + <color name="i_am_color_19b">#0000019b</color> + <color name="i_am_color_19c">#0000019c</color> + <color name="i_am_color_19d">#0000019d</color> + <color name="i_am_color_19e">#0000019e</color> + <color name="i_am_color_19f">#0000019f</color> + <color name="i_am_color_1a0">#000001a0</color> + <color name="i_am_color_1a1">#000001a1</color> + <color name="i_am_color_1a2">#000001a2</color> + <color name="i_am_color_1a3">#000001a3</color> + <color name="i_am_color_1a4">#000001a4</color> + <color name="i_am_color_1a5">#000001a5</color> + <color name="i_am_color_1a6">#000001a6</color> + <color name="i_am_color_1a7">#000001a7</color> + <color name="i_am_color_1a8">#000001a8</color> + <color name="i_am_color_1a9">#000001a9</color> + <color name="i_am_color_1aa">#000001aa</color> + <color name="i_am_color_1ab">#000001ab</color> + <color name="i_am_color_1ac">#000001ac</color> + <color name="i_am_color_1ad">#000001ad</color> + <color name="i_am_color_1ae">#000001ae</color> + <color name="i_am_color_1af">#000001af</color> + <color name="i_am_color_1b0">#000001b0</color> + <color name="i_am_color_1b1">#000001b1</color> + <color name="i_am_color_1b2">#000001b2</color> + <color name="i_am_color_1b3">#000001b3</color> + <color name="i_am_color_1b4">#000001b4</color> + <color name="i_am_color_1b5">#000001b5</color> + <color name="i_am_color_1b6">#000001b6</color> + <color name="i_am_color_1b7">#000001b7</color> + <color name="i_am_color_1b8">#000001b8</color> + <color name="i_am_color_1b9">#000001b9</color> + <color name="i_am_color_1ba">#000001ba</color> + <color name="i_am_color_1bb">#000001bb</color> + <color name="i_am_color_1bc">#000001bc</color> + <color name="i_am_color_1bd">#000001bd</color> + <color name="i_am_color_1be">#000001be</color> + <color name="i_am_color_1bf">#000001bf</color> + <color name="i_am_color_1c0">#000001c0</color> + <color name="i_am_color_1c1">#000001c1</color> + <color name="i_am_color_1c2">#000001c2</color> + <color name="i_am_color_1c3">#000001c3</color> + <color name="i_am_color_1c4">#000001c4</color> + <color name="i_am_color_1c5">#000001c5</color> + <color name="i_am_color_1c6">#000001c6</color> + <color name="i_am_color_1c7">#000001c7</color> + <color name="i_am_color_1c8">#000001c8</color> + <color name="i_am_color_1c9">#000001c9</color> + <color name="i_am_color_1ca">#000001ca</color> + <color name="i_am_color_1cb">#000001cb</color> + <color name="i_am_color_1cc">#000001cc</color> + <color name="i_am_color_1cd">#000001cd</color> + <color name="i_am_color_1ce">#000001ce</color> + <color name="i_am_color_1cf">#000001cf</color> + <color name="i_am_color_1d0">#000001d0</color> + <color name="i_am_color_1d1">#000001d1</color> + <color name="i_am_color_1d2">#000001d2</color> + <color name="i_am_color_1d3">#000001d3</color> + <color name="i_am_color_1d4">#000001d4</color> + <color name="i_am_color_1d5">#000001d5</color> + <color name="i_am_color_1d6">#000001d6</color> + <color name="i_am_color_1d7">#000001d7</color> + <color name="i_am_color_1d8">#000001d8</color> + <color name="i_am_color_1d9">#000001d9</color> + <color name="i_am_color_1da">#000001da</color> + <color name="i_am_color_1db">#000001db</color> + <color name="i_am_color_1dc">#000001dc</color> + <color name="i_am_color_1dd">#000001dd</color> + <color name="i_am_color_1de">#000001de</color> + <color name="i_am_color_1df">#000001df</color> + <color name="i_am_color_1e0">#000001e0</color> + <color name="i_am_color_1e1">#000001e1</color> + <color name="i_am_color_1e2">#000001e2</color> + <color name="i_am_color_1e3">#000001e3</color> + <color name="i_am_color_1e4">#000001e4</color> + <color name="i_am_color_1e5">#000001e5</color> + <color name="i_am_color_1e6">#000001e6</color> + <color name="i_am_color_1e7">#000001e7</color> + <color name="i_am_color_1e8">#000001e8</color> + <color name="i_am_color_1e9">#000001e9</color> + <color name="i_am_color_1ea">#000001ea</color> + <color name="i_am_color_1eb">#000001eb</color> + <color name="i_am_color_1ec">#000001ec</color> + <color name="i_am_color_1ed">#000001ed</color> + <color name="i_am_color_1ee">#000001ee</color> + <color name="i_am_color_1ef">#000001ef</color> + <color name="i_am_color_1f0">#000001f0</color> + <color name="i_am_color_1f1">#000001f1</color> + <color name="i_am_color_1f2">#000001f2</color> + <color name="i_am_color_1f3">#000001f3</color> + <color name="i_am_color_1f4">#000001f4</color> + <color name="i_am_color_1f5">#000001f5</color> + <color name="i_am_color_1f6">#000001f6</color> + <color name="i_am_color_1f7">#000001f7</color> + <color name="i_am_color_1f8">#000001f8</color> + <color name="i_am_color_1f9">#000001f9</color> + <color name="i_am_color_1fa">#000001fa</color> + <color name="i_am_color_1fb">#000001fb</color> + <color name="i_am_color_1fc">#000001fc</color> + <color name="i_am_color_1fd">#000001fd</color> + <color name="i_am_color_1fe">#000001fe</color> + <color name="i_am_color_1ff">#000001ff</color> + <color name="i_am_color_200">#00000200</color> + <color name="i_am_color_201">#00000201</color> + <color name="i_am_color_202">#00000202</color> + <color name="i_am_color_203">#00000203</color> + <color name="i_am_color_204">#00000204</color> + <color name="i_am_color_205">#00000205</color> + <color name="i_am_color_206">#00000206</color> + <color name="i_am_color_207">#00000207</color> + <color name="i_am_color_208">#00000208</color> + <color name="i_am_color_209">#00000209</color> + <color name="i_am_color_20a">#0000020a</color> + <color name="i_am_color_20b">#0000020b</color> + <color name="i_am_color_20c">#0000020c</color> + <color name="i_am_color_20d">#0000020d</color> + <color name="i_am_color_20e">#0000020e</color> + <color name="i_am_color_20f">#0000020f</color> + <color name="i_am_color_210">#00000210</color> + <color name="i_am_color_211">#00000211</color> + <color name="i_am_color_212">#00000212</color> + <color name="i_am_color_213">#00000213</color> + <color name="i_am_color_214">#00000214</color> + <color name="i_am_color_215">#00000215</color> + <color name="i_am_color_216">#00000216</color> + <color name="i_am_color_217">#00000217</color> + <color name="i_am_color_218">#00000218</color> + <color name="i_am_color_219">#00000219</color> + <color name="i_am_color_21a">#0000021a</color> + <color name="i_am_color_21b">#0000021b</color> + <color name="i_am_color_21c">#0000021c</color> + <color name="i_am_color_21d">#0000021d</color> + <color name="i_am_color_21e">#0000021e</color> + <color name="i_am_color_21f">#0000021f</color> + <color name="i_am_color_220">#00000220</color> + <color name="i_am_color_221">#00000221</color> + <color name="i_am_color_222">#00000222</color> + <color name="i_am_color_223">#00000223</color> + <color name="i_am_color_224">#00000224</color> + <color name="i_am_color_225">#00000225</color> + <color name="i_am_color_226">#00000226</color> + <color name="i_am_color_227">#00000227</color> + <color name="i_am_color_228">#00000228</color> + <color name="i_am_color_229">#00000229</color> + <color name="i_am_color_22a">#0000022a</color> + <color name="i_am_color_22b">#0000022b</color> + <color name="i_am_color_22c">#0000022c</color> + <color name="i_am_color_22d">#0000022d</color> + <color name="i_am_color_22e">#0000022e</color> + <color name="i_am_color_22f">#0000022f</color> + <color name="i_am_color_230">#00000230</color> + <color name="i_am_color_231">#00000231</color> + <color name="i_am_color_232">#00000232</color> + <color name="i_am_color_233">#00000233</color> + <color name="i_am_color_234">#00000234</color> + <color name="i_am_color_235">#00000235</color> + <color name="i_am_color_236">#00000236</color> + <color name="i_am_color_237">#00000237</color> + <color name="i_am_color_238">#00000238</color> + <color name="i_am_color_239">#00000239</color> + <color name="i_am_color_23a">#0000023a</color> + <color name="i_am_color_23b">#0000023b</color> + <color name="i_am_color_23c">#0000023c</color> + <color name="i_am_color_23d">#0000023d</color> + <color name="i_am_color_23e">#0000023e</color> + <color name="i_am_color_23f">#0000023f</color> + <color name="i_am_color_240">#00000240</color> + <color name="i_am_color_241">#00000241</color> + <color name="i_am_color_242">#00000242</color> + <color name="i_am_color_243">#00000243</color> + <color name="i_am_color_244">#00000244</color> + <color name="i_am_color_245">#00000245</color> + <color name="i_am_color_246">#00000246</color> + <color name="i_am_color_247">#00000247</color> + <color name="i_am_color_248">#00000248</color> + <color name="i_am_color_249">#00000249</color> + <color name="i_am_color_24a">#0000024a</color> + <color name="i_am_color_24b">#0000024b</color> + <color name="i_am_color_24c">#0000024c</color> + <color name="i_am_color_24d">#0000024d</color> + <color name="i_am_color_24e">#0000024e</color> + <color name="i_am_color_24f">#0000024f</color> + <color name="i_am_color_250">#00000250</color> + <color name="i_am_color_251">#00000251</color> + <color name="i_am_color_252">#00000252</color> + <color name="i_am_color_253">#00000253</color> + <color name="i_am_color_254">#00000254</color> + <color name="i_am_color_255">#00000255</color> + <color name="i_am_color_256">#00000256</color> + <color name="i_am_color_257">#00000257</color> + <color name="i_am_color_258">#00000258</color> + <color name="i_am_color_259">#00000259</color> + <color name="i_am_color_25a">#0000025a</color> + <color name="i_am_color_25b">#0000025b</color> + <color name="i_am_color_25c">#0000025c</color> + <color name="i_am_color_25d">#0000025d</color> + <color name="i_am_color_25e">#0000025e</color> + <color name="i_am_color_25f">#0000025f</color> + <color name="i_am_color_260">#00000260</color> + <color name="i_am_color_261">#00000261</color> + <color name="i_am_color_262">#00000262</color> + <color name="i_am_color_263">#00000263</color> + <color name="i_am_color_264">#00000264</color> + <color name="i_am_color_265">#00000265</color> + <color name="i_am_color_266">#00000266</color> + <color name="i_am_color_267">#00000267</color> + <color name="i_am_color_268">#00000268</color> + <color name="i_am_color_269">#00000269</color> + <color name="i_am_color_26a">#0000026a</color> + <color name="i_am_color_26b">#0000026b</color> + <color name="i_am_color_26c">#0000026c</color> + <color name="i_am_color_26d">#0000026d</color> + <color name="i_am_color_26e">#0000026e</color> + <color name="i_am_color_26f">#0000026f</color> + <color name="i_am_color_270">#00000270</color> + <color name="i_am_color_271">#00000271</color> + <color name="i_am_color_272">#00000272</color> + <color name="i_am_color_273">#00000273</color> + <color name="i_am_color_274">#00000274</color> + <color name="i_am_color_275">#00000275</color> + <color name="i_am_color_276">#00000276</color> + <color name="i_am_color_277">#00000277</color> + <color name="i_am_color_278">#00000278</color> + <color name="i_am_color_279">#00000279</color> + <color name="i_am_color_27a">#0000027a</color> + <color name="i_am_color_27b">#0000027b</color> + <color name="i_am_color_27c">#0000027c</color> + <color name="i_am_color_27d">#0000027d</color> + <color name="i_am_color_27e">#0000027e</color> + <color name="i_am_color_27f">#0000027f</color> + <color name="i_am_color_280">#00000280</color> + <color name="i_am_color_281">#00000281</color> + <color name="i_am_color_282">#00000282</color> + <color name="i_am_color_283">#00000283</color> + <color name="i_am_color_284">#00000284</color> + <color name="i_am_color_285">#00000285</color> + <color name="i_am_color_286">#00000286</color> + <color name="i_am_color_287">#00000287</color> + <color name="i_am_color_288">#00000288</color> + <color name="i_am_color_289">#00000289</color> + <color name="i_am_color_28a">#0000028a</color> + <color name="i_am_color_28b">#0000028b</color> + <color name="i_am_color_28c">#0000028c</color> + <color name="i_am_color_28d">#0000028d</color> + <color name="i_am_color_28e">#0000028e</color> + <color name="i_am_color_28f">#0000028f</color> + <color name="i_am_color_290">#00000290</color> + <color name="i_am_color_291">#00000291</color> + <color name="i_am_color_292">#00000292</color> + <color name="i_am_color_293">#00000293</color> + <color name="i_am_color_294">#00000294</color> + <color name="i_am_color_295">#00000295</color> + <color name="i_am_color_296">#00000296</color> + <color name="i_am_color_297">#00000297</color> + <color name="i_am_color_298">#00000298</color> + <color name="i_am_color_299">#00000299</color> + <color name="i_am_color_29a">#0000029a</color> + <color name="i_am_color_29b">#0000029b</color> + <color name="i_am_color_29c">#0000029c</color> + <color name="i_am_color_29d">#0000029d</color> + <color name="i_am_color_29e">#0000029e</color> + <color name="i_am_color_29f">#0000029f</color> + <color name="i_am_color_2a0">#000002a0</color> + <color name="i_am_color_2a1">#000002a1</color> + <color name="i_am_color_2a2">#000002a2</color> + <color name="i_am_color_2a3">#000002a3</color> + <color name="i_am_color_2a4">#000002a4</color> + <color name="i_am_color_2a5">#000002a5</color> + <color name="i_am_color_2a6">#000002a6</color> + <color name="i_am_color_2a7">#000002a7</color> + <color name="i_am_color_2a8">#000002a8</color> + <color name="i_am_color_2a9">#000002a9</color> + <color name="i_am_color_2aa">#000002aa</color> + <color name="i_am_color_2ab">#000002ab</color> + <color name="i_am_color_2ac">#000002ac</color> + <color name="i_am_color_2ad">#000002ad</color> + <color name="i_am_color_2ae">#000002ae</color> + <color name="i_am_color_2af">#000002af</color> + <color name="i_am_color_2b0">#000002b0</color> + <color name="i_am_color_2b1">#000002b1</color> + <color name="i_am_color_2b2">#000002b2</color> + <color name="i_am_color_2b3">#000002b3</color> + <color name="i_am_color_2b4">#000002b4</color> + <color name="i_am_color_2b5">#000002b5</color> + <color name="i_am_color_2b6">#000002b6</color> + <color name="i_am_color_2b7">#000002b7</color> + <color name="i_am_color_2b8">#000002b8</color> + <color name="i_am_color_2b9">#000002b9</color> + <color name="i_am_color_2ba">#000002ba</color> + <color name="i_am_color_2bb">#000002bb</color> + <color name="i_am_color_2bc">#000002bc</color> + <color name="i_am_color_2bd">#000002bd</color> + <color name="i_am_color_2be">#000002be</color> + <color name="i_am_color_2bf">#000002bf</color> + <color name="i_am_color_2c0">#000002c0</color> + <color name="i_am_color_2c1">#000002c1</color> + <color name="i_am_color_2c2">#000002c2</color> + <color name="i_am_color_2c3">#000002c3</color> + <color name="i_am_color_2c4">#000002c4</color> + <color name="i_am_color_2c5">#000002c5</color> + <color name="i_am_color_2c6">#000002c6</color> + <color name="i_am_color_2c7">#000002c7</color> + <color name="i_am_color_2c8">#000002c8</color> + <color name="i_am_color_2c9">#000002c9</color> + <color name="i_am_color_2ca">#000002ca</color> + <color name="i_am_color_2cb">#000002cb</color> + <color name="i_am_color_2cc">#000002cc</color> + <color name="i_am_color_2cd">#000002cd</color> + <color name="i_am_color_2ce">#000002ce</color> + <color name="i_am_color_2cf">#000002cf</color> + <color name="i_am_color_2d0">#000002d0</color> + <color name="i_am_color_2d1">#000002d1</color> + <color name="i_am_color_2d2">#000002d2</color> + <color name="i_am_color_2d3">#000002d3</color> + <color name="i_am_color_2d4">#000002d4</color> + <color name="i_am_color_2d5">#000002d5</color> + <color name="i_am_color_2d6">#000002d6</color> + <color name="i_am_color_2d7">#000002d7</color> + <color name="i_am_color_2d8">#000002d8</color> + <color name="i_am_color_2d9">#000002d9</color> + <color name="i_am_color_2da">#000002da</color> + <color name="i_am_color_2db">#000002db</color> + <color name="i_am_color_2dc">#000002dc</color> + <color name="i_am_color_2dd">#000002dd</color> + <color name="i_am_color_2de">#000002de</color> + <color name="i_am_color_2df">#000002df</color> + <color name="i_am_color_2e0">#000002e0</color> + <color name="i_am_color_2e1">#000002e1</color> + <color name="i_am_color_2e2">#000002e2</color> + <color name="i_am_color_2e3">#000002e3</color> + <color name="i_am_color_2e4">#000002e4</color> + <color name="i_am_color_2e5">#000002e5</color> + <color name="i_am_color_2e6">#000002e6</color> + <color name="i_am_color_2e7">#000002e7</color> + <color name="i_am_color_2e8">#000002e8</color> + <color name="i_am_color_2e9">#000002e9</color> + <color name="i_am_color_2ea">#000002ea</color> + <color name="i_am_color_2eb">#000002eb</color> + <color name="i_am_color_2ec">#000002ec</color> + <color name="i_am_color_2ed">#000002ed</color> + <color name="i_am_color_2ee">#000002ee</color> + <color name="i_am_color_2ef">#000002ef</color> + <color name="i_am_color_2f0">#000002f0</color> + <color name="i_am_color_2f1">#000002f1</color> + <color name="i_am_color_2f2">#000002f2</color> + <color name="i_am_color_2f3">#000002f3</color> + <color name="i_am_color_2f4">#000002f4</color> + <color name="i_am_color_2f5">#000002f5</color> + <color name="i_am_color_2f6">#000002f6</color> + <color name="i_am_color_2f7">#000002f7</color> + <color name="i_am_color_2f8">#000002f8</color> + <color name="i_am_color_2f9">#000002f9</color> + <color name="i_am_color_2fa">#000002fa</color> + <color name="i_am_color_2fb">#000002fb</color> + <color name="i_am_color_2fc">#000002fc</color> + <color name="i_am_color_2fd">#000002fd</color> + <color name="i_am_color_2fe">#000002fe</color> + <color name="i_am_color_2ff">#000002ff</color> + <color name="i_am_color_300">#00000300</color> + <color name="i_am_color_301">#00000301</color> + <color name="i_am_color_302">#00000302</color> + <color name="i_am_color_303">#00000303</color> + <color name="i_am_color_304">#00000304</color> + <color name="i_am_color_305">#00000305</color> + <color name="i_am_color_306">#00000306</color> + <color name="i_am_color_307">#00000307</color> + <color name="i_am_color_308">#00000308</color> + <color name="i_am_color_309">#00000309</color> + <color name="i_am_color_30a">#0000030a</color> + <color name="i_am_color_30b">#0000030b</color> + <color name="i_am_color_30c">#0000030c</color> + <color name="i_am_color_30d">#0000030d</color> + <color name="i_am_color_30e">#0000030e</color> + <color name="i_am_color_30f">#0000030f</color> + <color name="i_am_color_310">#00000310</color> + <color name="i_am_color_311">#00000311</color> + <color name="i_am_color_312">#00000312</color> + <color name="i_am_color_313">#00000313</color> + <color name="i_am_color_314">#00000314</color> + <color name="i_am_color_315">#00000315</color> + <color name="i_am_color_316">#00000316</color> + <color name="i_am_color_317">#00000317</color> + <color name="i_am_color_318">#00000318</color> + <color name="i_am_color_319">#00000319</color> + <color name="i_am_color_31a">#0000031a</color> + <color name="i_am_color_31b">#0000031b</color> + <color name="i_am_color_31c">#0000031c</color> + <color name="i_am_color_31d">#0000031d</color> + <color name="i_am_color_31e">#0000031e</color> + <color name="i_am_color_31f">#0000031f</color> + <color name="i_am_color_320">#00000320</color> + <color name="i_am_color_321">#00000321</color> + <color name="i_am_color_322">#00000322</color> + <color name="i_am_color_323">#00000323</color> + <color name="i_am_color_324">#00000324</color> + <color name="i_am_color_325">#00000325</color> + <color name="i_am_color_326">#00000326</color> + <color name="i_am_color_327">#00000327</color> + <color name="i_am_color_328">#00000328</color> + <color name="i_am_color_329">#00000329</color> + <color name="i_am_color_32a">#0000032a</color> + <color name="i_am_color_32b">#0000032b</color> + <color name="i_am_color_32c">#0000032c</color> + <color name="i_am_color_32d">#0000032d</color> + <color name="i_am_color_32e">#0000032e</color> + <color name="i_am_color_32f">#0000032f</color> + <color name="i_am_color_330">#00000330</color> + <color name="i_am_color_331">#00000331</color> + <color name="i_am_color_332">#00000332</color> + <color name="i_am_color_333">#00000333</color> + <color name="i_am_color_334">#00000334</color> + <color name="i_am_color_335">#00000335</color> + <color name="i_am_color_336">#00000336</color> + <color name="i_am_color_337">#00000337</color> + <color name="i_am_color_338">#00000338</color> + <color name="i_am_color_339">#00000339</color> + <color name="i_am_color_33a">#0000033a</color> + <color name="i_am_color_33b">#0000033b</color> + <color name="i_am_color_33c">#0000033c</color> + <color name="i_am_color_33d">#0000033d</color> + <color name="i_am_color_33e">#0000033e</color> + <color name="i_am_color_33f">#0000033f</color> + <color name="i_am_color_340">#00000340</color> + <color name="i_am_color_341">#00000341</color> + <color name="i_am_color_342">#00000342</color> + <color name="i_am_color_343">#00000343</color> + <color name="i_am_color_344">#00000344</color> + <color name="i_am_color_345">#00000345</color> + <color name="i_am_color_346">#00000346</color> + <color name="i_am_color_347">#00000347</color> + <color name="i_am_color_348">#00000348</color> + <color name="i_am_color_349">#00000349</color> + <color name="i_am_color_34a">#0000034a</color> + <color name="i_am_color_34b">#0000034b</color> + <color name="i_am_color_34c">#0000034c</color> + <color name="i_am_color_34d">#0000034d</color> + <color name="i_am_color_34e">#0000034e</color> + <color name="i_am_color_34f">#0000034f</color> + <color name="i_am_color_350">#00000350</color> + <color name="i_am_color_351">#00000351</color> + <color name="i_am_color_352">#00000352</color> + <color name="i_am_color_353">#00000353</color> + <color name="i_am_color_354">#00000354</color> + <color name="i_am_color_355">#00000355</color> + <color name="i_am_color_356">#00000356</color> + <color name="i_am_color_357">#00000357</color> + <color name="i_am_color_358">#00000358</color> + <color name="i_am_color_359">#00000359</color> + <color name="i_am_color_35a">#0000035a</color> + <color name="i_am_color_35b">#0000035b</color> + <color name="i_am_color_35c">#0000035c</color> + <color name="i_am_color_35d">#0000035d</color> + <color name="i_am_color_35e">#0000035e</color> + <color name="i_am_color_35f">#0000035f</color> + <color name="i_am_color_360">#00000360</color> + <color name="i_am_color_361">#00000361</color> + <color name="i_am_color_362">#00000362</color> + <color name="i_am_color_363">#00000363</color> + <color name="i_am_color_364">#00000364</color> + <color name="i_am_color_365">#00000365</color> + <color name="i_am_color_366">#00000366</color> + <color name="i_am_color_367">#00000367</color> + <color name="i_am_color_368">#00000368</color> + <color name="i_am_color_369">#00000369</color> + <color name="i_am_color_36a">#0000036a</color> + <color name="i_am_color_36b">#0000036b</color> + <color name="i_am_color_36c">#0000036c</color> + <color name="i_am_color_36d">#0000036d</color> + <color name="i_am_color_36e">#0000036e</color> + <color name="i_am_color_36f">#0000036f</color> + <color name="i_am_color_370">#00000370</color> + <color name="i_am_color_371">#00000371</color> + <color name="i_am_color_372">#00000372</color> + <color name="i_am_color_373">#00000373</color> + <color name="i_am_color_374">#00000374</color> + <color name="i_am_color_375">#00000375</color> + <color name="i_am_color_376">#00000376</color> + <color name="i_am_color_377">#00000377</color> + <color name="i_am_color_378">#00000378</color> + <color name="i_am_color_379">#00000379</color> + <color name="i_am_color_37a">#0000037a</color> + <color name="i_am_color_37b">#0000037b</color> + <color name="i_am_color_37c">#0000037c</color> + <color name="i_am_color_37d">#0000037d</color> + <color name="i_am_color_37e">#0000037e</color> + <color name="i_am_color_37f">#0000037f</color> + <color name="i_am_color_380">#00000380</color> + <color name="i_am_color_381">#00000381</color> + <color name="i_am_color_382">#00000382</color> + <color name="i_am_color_383">#00000383</color> + <color name="i_am_color_384">#00000384</color> + <color name="i_am_color_385">#00000385</color> + <color name="i_am_color_386">#00000386</color> + <color name="i_am_color_387">#00000387</color> + <color name="i_am_color_388">#00000388</color> + <color name="i_am_color_389">#00000389</color> + <color name="i_am_color_38a">#0000038a</color> + <color name="i_am_color_38b">#0000038b</color> + <color name="i_am_color_38c">#0000038c</color> + <color name="i_am_color_38d">#0000038d</color> + <color name="i_am_color_38e">#0000038e</color> + <color name="i_am_color_38f">#0000038f</color> + <color name="i_am_color_390">#00000390</color> + <color name="i_am_color_391">#00000391</color> + <color name="i_am_color_392">#00000392</color> + <color name="i_am_color_393">#00000393</color> + <color name="i_am_color_394">#00000394</color> + <color name="i_am_color_395">#00000395</color> + <color name="i_am_color_396">#00000396</color> + <color name="i_am_color_397">#00000397</color> + <color name="i_am_color_398">#00000398</color> + <color name="i_am_color_399">#00000399</color> + <color name="i_am_color_39a">#0000039a</color> + <color name="i_am_color_39b">#0000039b</color> + <color name="i_am_color_39c">#0000039c</color> + <color name="i_am_color_39d">#0000039d</color> + <color name="i_am_color_39e">#0000039e</color> + <color name="i_am_color_39f">#0000039f</color> + <color name="i_am_color_3a0">#000003a0</color> + <color name="i_am_color_3a1">#000003a1</color> + <color name="i_am_color_3a2">#000003a2</color> + <color name="i_am_color_3a3">#000003a3</color> + <color name="i_am_color_3a4">#000003a4</color> + <color name="i_am_color_3a5">#000003a5</color> + <color name="i_am_color_3a6">#000003a6</color> + <color name="i_am_color_3a7">#000003a7</color> + <color name="i_am_color_3a8">#000003a8</color> + <color name="i_am_color_3a9">#000003a9</color> + <color name="i_am_color_3aa">#000003aa</color> + <color name="i_am_color_3ab">#000003ab</color> + <color name="i_am_color_3ac">#000003ac</color> + <color name="i_am_color_3ad">#000003ad</color> + <color name="i_am_color_3ae">#000003ae</color> + <color name="i_am_color_3af">#000003af</color> + <color name="i_am_color_3b0">#000003b0</color> + <color name="i_am_color_3b1">#000003b1</color> + <color name="i_am_color_3b2">#000003b2</color> + <color name="i_am_color_3b3">#000003b3</color> + <color name="i_am_color_3b4">#000003b4</color> + <color name="i_am_color_3b5">#000003b5</color> + <color name="i_am_color_3b6">#000003b6</color> + <color name="i_am_color_3b7">#000003b7</color> + <color name="i_am_color_3b8">#000003b8</color> + <color name="i_am_color_3b9">#000003b9</color> + <color name="i_am_color_3ba">#000003ba</color> + <color name="i_am_color_3bb">#000003bb</color> + <color name="i_am_color_3bc">#000003bc</color> + <color name="i_am_color_3bd">#000003bd</color> + <color name="i_am_color_3be">#000003be</color> + <color name="i_am_color_3bf">#000003bf</color> + <color name="i_am_color_3c0">#000003c0</color> + <color name="i_am_color_3c1">#000003c1</color> + <color name="i_am_color_3c2">#000003c2</color> + <color name="i_am_color_3c3">#000003c3</color> + <color name="i_am_color_3c4">#000003c4</color> + <color name="i_am_color_3c5">#000003c5</color> + <color name="i_am_color_3c6">#000003c6</color> + <color name="i_am_color_3c7">#000003c7</color> + <color name="i_am_color_3c8">#000003c8</color> + <color name="i_am_color_3c9">#000003c9</color> + <color name="i_am_color_3ca">#000003ca</color> + <color name="i_am_color_3cb">#000003cb</color> + <color name="i_am_color_3cc">#000003cc</color> + <color name="i_am_color_3cd">#000003cd</color> + <color name="i_am_color_3ce">#000003ce</color> + <color name="i_am_color_3cf">#000003cf</color> + <color name="i_am_color_3d0">#000003d0</color> + <color name="i_am_color_3d1">#000003d1</color> + <color name="i_am_color_3d2">#000003d2</color> + <color name="i_am_color_3d3">#000003d3</color> + <color name="i_am_color_3d4">#000003d4</color> + <color name="i_am_color_3d5">#000003d5</color> + <color name="i_am_color_3d6">#000003d6</color> + <color name="i_am_color_3d7">#000003d7</color> + <color name="i_am_color_3d8">#000003d8</color> + <color name="i_am_color_3d9">#000003d9</color> + <color name="i_am_color_3da">#000003da</color> + <color name="i_am_color_3db">#000003db</color> + <color name="i_am_color_3dc">#000003dc</color> + <color name="i_am_color_3dd">#000003dd</color> + <color name="i_am_color_3de">#000003de</color> + <color name="i_am_color_3df">#000003df</color> + <color name="i_am_color_3e0">#000003e0</color> + <color name="i_am_color_3e1">#000003e1</color> + <color name="i_am_color_3e2">#000003e2</color> + <color name="i_am_color_3e3">#000003e3</color> + <color name="i_am_color_3e4">#000003e4</color> + <color name="i_am_color_3e5">#000003e5</color> + <color name="i_am_color_3e6">#000003e6</color> + <color name="i_am_color_3e7">#000003e7</color> + <color name="i_am_color_3e8">#000003e8</color> + <color name="i_am_color_3e9">#000003e9</color> + <color name="i_am_color_3ea">#000003ea</color> + <color name="i_am_color_3eb">#000003eb</color> + <color name="i_am_color_3ec">#000003ec</color> + <color name="i_am_color_3ed">#000003ed</color> + <color name="i_am_color_3ee">#000003ee</color> + <color name="i_am_color_3ef">#000003ef</color> + <color name="i_am_color_3f0">#000003f0</color> + <color name="i_am_color_3f1">#000003f1</color> + <color name="i_am_color_3f2">#000003f2</color> + <color name="i_am_color_3f3">#000003f3</color> + <color name="i_am_color_3f4">#000003f4</color> + <color name="i_am_color_3f5">#000003f5</color> + <color name="i_am_color_3f6">#000003f6</color> + <color name="i_am_color_3f7">#000003f7</color> + <color name="i_am_color_3f8">#000003f8</color> + <color name="i_am_color_3f9">#000003f9</color> + <color name="i_am_color_3fa">#000003fa</color> + <color name="i_am_color_3fb">#000003fb</color> + <color name="i_am_color_3fc">#000003fc</color> + <color name="i_am_color_3fd">#000003fd</color> + <color name="i_am_color_3fe">#000003fe</color> + <color name="i_am_color_3ff">#000003ff</color> + <color name="i_am_color_400">#00000400</color> + <color name="i_am_color_401">#00000401</color> + <color name="i_am_color_402">#00000402</color> + <color name="i_am_color_403">#00000403</color> + <color name="i_am_color_404">#00000404</color> + <color name="i_am_color_405">#00000405</color> + <color name="i_am_color_406">#00000406</color> + <color name="i_am_color_407">#00000407</color> + <color name="i_am_color_408">#00000408</color> + <color name="i_am_color_409">#00000409</color> + <color name="i_am_color_40a">#0000040a</color> + <color name="i_am_color_40b">#0000040b</color> + <color name="i_am_color_40c">#0000040c</color> + <color name="i_am_color_40d">#0000040d</color> + <color name="i_am_color_40e">#0000040e</color> + <color name="i_am_color_40f">#0000040f</color> + <color name="i_am_color_410">#00000410</color> + <color name="i_am_color_411">#00000411</color> + <color name="i_am_color_412">#00000412</color> + <color name="i_am_color_413">#00000413</color> + <color name="i_am_color_414">#00000414</color> + <color name="i_am_color_415">#00000415</color> + <color name="i_am_color_416">#00000416</color> + <color name="i_am_color_417">#00000417</color> + <color name="i_am_color_418">#00000418</color> + <color name="i_am_color_419">#00000419</color> + <color name="i_am_color_41a">#0000041a</color> + <color name="i_am_color_41b">#0000041b</color> + <color name="i_am_color_41c">#0000041c</color> + <color name="i_am_color_41d">#0000041d</color> + <color name="i_am_color_41e">#0000041e</color> + <color name="i_am_color_41f">#0000041f</color> + <color name="i_am_color_420">#00000420</color> + <color name="i_am_color_421">#00000421</color> + <color name="i_am_color_422">#00000422</color> + <color name="i_am_color_423">#00000423</color> + <color name="i_am_color_424">#00000424</color> + <color name="i_am_color_425">#00000425</color> + <color name="i_am_color_426">#00000426</color> + <color name="i_am_color_427">#00000427</color> + <color name="i_am_color_428">#00000428</color> + <color name="i_am_color_429">#00000429</color> + <color name="i_am_color_42a">#0000042a</color> + <color name="i_am_color_42b">#0000042b</color> + <color name="i_am_color_42c">#0000042c</color> + <color name="i_am_color_42d">#0000042d</color> + <color name="i_am_color_42e">#0000042e</color> + <color name="i_am_color_42f">#0000042f</color> + <color name="i_am_color_430">#00000430</color> + <color name="i_am_color_431">#00000431</color> + <color name="i_am_color_432">#00000432</color> + <color name="i_am_color_433">#00000433</color> + <color name="i_am_color_434">#00000434</color> + <color name="i_am_color_435">#00000435</color> + <color name="i_am_color_436">#00000436</color> + <color name="i_am_color_437">#00000437</color> + <color name="i_am_color_438">#00000438</color> + <color name="i_am_color_439">#00000439</color> + <color name="i_am_color_43a">#0000043a</color> + <color name="i_am_color_43b">#0000043b</color> + <color name="i_am_color_43c">#0000043c</color> + <color name="i_am_color_43d">#0000043d</color> + <color name="i_am_color_43e">#0000043e</color> + <color name="i_am_color_43f">#0000043f</color> + <color name="i_am_color_440">#00000440</color> + <color name="i_am_color_441">#00000441</color> + <color name="i_am_color_442">#00000442</color> + <color name="i_am_color_443">#00000443</color> + <color name="i_am_color_444">#00000444</color> + <color name="i_am_color_445">#00000445</color> + <color name="i_am_color_446">#00000446</color> + <color name="i_am_color_447">#00000447</color> + <color name="i_am_color_448">#00000448</color> + <color name="i_am_color_449">#00000449</color> + <color name="i_am_color_44a">#0000044a</color> + <color name="i_am_color_44b">#0000044b</color> + <color name="i_am_color_44c">#0000044c</color> + <color name="i_am_color_44d">#0000044d</color> + <color name="i_am_color_44e">#0000044e</color> + <color name="i_am_color_44f">#0000044f</color> + <color name="i_am_color_450">#00000450</color> + <color name="i_am_color_451">#00000451</color> + <color name="i_am_color_452">#00000452</color> + <color name="i_am_color_453">#00000453</color> + <color name="i_am_color_454">#00000454</color> + <color name="i_am_color_455">#00000455</color> + <color name="i_am_color_456">#00000456</color> + <color name="i_am_color_457">#00000457</color> + <color name="i_am_color_458">#00000458</color> + <color name="i_am_color_459">#00000459</color> + <color name="i_am_color_45a">#0000045a</color> + <color name="i_am_color_45b">#0000045b</color> + <color name="i_am_color_45c">#0000045c</color> + <color name="i_am_color_45d">#0000045d</color> + <color name="i_am_color_45e">#0000045e</color> + <color name="i_am_color_45f">#0000045f</color> + <color name="i_am_color_460">#00000460</color> + <color name="i_am_color_461">#00000461</color> + <color name="i_am_color_462">#00000462</color> + <color name="i_am_color_463">#00000463</color> + <color name="i_am_color_464">#00000464</color> + <color name="i_am_color_465">#00000465</color> + <color name="i_am_color_466">#00000466</color> + <color name="i_am_color_467">#00000467</color> + <color name="i_am_color_468">#00000468</color> + <color name="i_am_color_469">#00000469</color> + <color name="i_am_color_46a">#0000046a</color> + <color name="i_am_color_46b">#0000046b</color> + <color name="i_am_color_46c">#0000046c</color> + <color name="i_am_color_46d">#0000046d</color> + <color name="i_am_color_46e">#0000046e</color> + <color name="i_am_color_46f">#0000046f</color> + <color name="i_am_color_470">#00000470</color> + <color name="i_am_color_471">#00000471</color> + <color name="i_am_color_472">#00000472</color> + <color name="i_am_color_473">#00000473</color> + <color name="i_am_color_474">#00000474</color> + <color name="i_am_color_475">#00000475</color> + <color name="i_am_color_476">#00000476</color> + <color name="i_am_color_477">#00000477</color> + <color name="i_am_color_478">#00000478</color> + <color name="i_am_color_479">#00000479</color> + <color name="i_am_color_47a">#0000047a</color> + <color name="i_am_color_47b">#0000047b</color> + <color name="i_am_color_47c">#0000047c</color> + <color name="i_am_color_47d">#0000047d</color> + <color name="i_am_color_47e">#0000047e</color> + <color name="i_am_color_47f">#0000047f</color> + <color name="i_am_color_480">#00000480</color> + <color name="i_am_color_481">#00000481</color> + <color name="i_am_color_482">#00000482</color> + <color name="i_am_color_483">#00000483</color> + <color name="i_am_color_484">#00000484</color> + <color name="i_am_color_485">#00000485</color> + <color name="i_am_color_486">#00000486</color> + <color name="i_am_color_487">#00000487</color> + <color name="i_am_color_488">#00000488</color> + <color name="i_am_color_489">#00000489</color> + <color name="i_am_color_48a">#0000048a</color> + <color name="i_am_color_48b">#0000048b</color> + <color name="i_am_color_48c">#0000048c</color> + <color name="i_am_color_48d">#0000048d</color> + <color name="i_am_color_48e">#0000048e</color> + <color name="i_am_color_48f">#0000048f</color> + <color name="i_am_color_490">#00000490</color> + <color name="i_am_color_491">#00000491</color> + <color name="i_am_color_492">#00000492</color> + <color name="i_am_color_493">#00000493</color> + <color name="i_am_color_494">#00000494</color> + <color name="i_am_color_495">#00000495</color> + <color name="i_am_color_496">#00000496</color> + <color name="i_am_color_497">#00000497</color> + <color name="i_am_color_498">#00000498</color> + <color name="i_am_color_499">#00000499</color> + <color name="i_am_color_49a">#0000049a</color> + <color name="i_am_color_49b">#0000049b</color> + <color name="i_am_color_49c">#0000049c</color> + <color name="i_am_color_49d">#0000049d</color> + <color name="i_am_color_49e">#0000049e</color> + <color name="i_am_color_49f">#0000049f</color> + <color name="i_am_color_4a0">#000004a0</color> + <color name="i_am_color_4a1">#000004a1</color> + <color name="i_am_color_4a2">#000004a2</color> + <color name="i_am_color_4a3">#000004a3</color> + <color name="i_am_color_4a4">#000004a4</color> + <color name="i_am_color_4a5">#000004a5</color> + <color name="i_am_color_4a6">#000004a6</color> + <color name="i_am_color_4a7">#000004a7</color> + <color name="i_am_color_4a8">#000004a8</color> + <color name="i_am_color_4a9">#000004a9</color> + <color name="i_am_color_4aa">#000004aa</color> + <color name="i_am_color_4ab">#000004ab</color> + <color name="i_am_color_4ac">#000004ac</color> + <color name="i_am_color_4ad">#000004ad</color> + <color name="i_am_color_4ae">#000004ae</color> + <color name="i_am_color_4af">#000004af</color> + <color name="i_am_color_4b0">#000004b0</color> + <color name="i_am_color_4b1">#000004b1</color> + <color name="i_am_color_4b2">#000004b2</color> + <color name="i_am_color_4b3">#000004b3</color> + <color name="i_am_color_4b4">#000004b4</color> + <color name="i_am_color_4b5">#000004b5</color> + <color name="i_am_color_4b6">#000004b6</color> + <color name="i_am_color_4b7">#000004b7</color> + <color name="i_am_color_4b8">#000004b8</color> + <color name="i_am_color_4b9">#000004b9</color> + <color name="i_am_color_4ba">#000004ba</color> + <color name="i_am_color_4bb">#000004bb</color> + <color name="i_am_color_4bc">#000004bc</color> + <color name="i_am_color_4bd">#000004bd</color> + <color name="i_am_color_4be">#000004be</color> + <color name="i_am_color_4bf">#000004bf</color> + <color name="i_am_color_4c0">#000004c0</color> + <color name="i_am_color_4c1">#000004c1</color> + <color name="i_am_color_4c2">#000004c2</color> + <color name="i_am_color_4c3">#000004c3</color> + <color name="i_am_color_4c4">#000004c4</color> + <color name="i_am_color_4c5">#000004c5</color> + <color name="i_am_color_4c6">#000004c6</color> + <color name="i_am_color_4c7">#000004c7</color> + <color name="i_am_color_4c8">#000004c8</color> + <color name="i_am_color_4c9">#000004c9</color> + <color name="i_am_color_4ca">#000004ca</color> + <color name="i_am_color_4cb">#000004cb</color> + <color name="i_am_color_4cc">#000004cc</color> + <color name="i_am_color_4cd">#000004cd</color> + <color name="i_am_color_4ce">#000004ce</color> + <color name="i_am_color_4cf">#000004cf</color> + <color name="i_am_color_4d0">#000004d0</color> + <color name="i_am_color_4d1">#000004d1</color> + <color name="i_am_color_4d2">#000004d2</color> + <color name="i_am_color_4d3">#000004d3</color> + <color name="i_am_color_4d4">#000004d4</color> + <color name="i_am_color_4d5">#000004d5</color> + <color name="i_am_color_4d6">#000004d6</color> + <color name="i_am_color_4d7">#000004d7</color> + <color name="i_am_color_4d8">#000004d8</color> + <color name="i_am_color_4d9">#000004d9</color> + <color name="i_am_color_4da">#000004da</color> + <color name="i_am_color_4db">#000004db</color> + <color name="i_am_color_4dc">#000004dc</color> + <color name="i_am_color_4dd">#000004dd</color> + <color name="i_am_color_4de">#000004de</color> + <color name="i_am_color_4df">#000004df</color> + <color name="i_am_color_4e0">#000004e0</color> + <color name="i_am_color_4e1">#000004e1</color> + <color name="i_am_color_4e2">#000004e2</color> + <color name="i_am_color_4e3">#000004e3</color> + <color name="i_am_color_4e4">#000004e4</color> + <color name="i_am_color_4e5">#000004e5</color> + <color name="i_am_color_4e6">#000004e6</color> + <color name="i_am_color_4e7">#000004e7</color> + <color name="i_am_color_4e8">#000004e8</color> + <color name="i_am_color_4e9">#000004e9</color> + <color name="i_am_color_4ea">#000004ea</color> + <color name="i_am_color_4eb">#000004eb</color> + <color name="i_am_color_4ec">#000004ec</color> + <color name="i_am_color_4ed">#000004ed</color> + <color name="i_am_color_4ee">#000004ee</color> + <color name="i_am_color_4ef">#000004ef</color> + <color name="i_am_color_4f0">#000004f0</color> + <color name="i_am_color_4f1">#000004f1</color> + <color name="i_am_color_4f2">#000004f2</color> + <color name="i_am_color_4f3">#000004f3</color> + <color name="i_am_color_4f4">#000004f4</color> + <color name="i_am_color_4f5">#000004f5</color> + <color name="i_am_color_4f6">#000004f6</color> + <color name="i_am_color_4f7">#000004f7</color> + <color name="i_am_color_4f8">#000004f8</color> + <color name="i_am_color_4f9">#000004f9</color> + <color name="i_am_color_4fa">#000004fa</color> + <color name="i_am_color_4fb">#000004fb</color> + <color name="i_am_color_4fc">#000004fc</color> + <color name="i_am_color_4fd">#000004fd</color> + <color name="i_am_color_4fe">#000004fe</color> + <color name="i_am_color_4ff">#000004ff</color> + <color name="i_am_color_500">#00000500</color> + <color name="i_am_color_501">#00000501</color> + <color name="i_am_color_502">#00000502</color> + <color name="i_am_color_503">#00000503</color> + <color name="i_am_color_504">#00000504</color> + <color name="i_am_color_505">#00000505</color> + <color name="i_am_color_506">#00000506</color> + <color name="i_am_color_507">#00000507</color> + <color name="i_am_color_508">#00000508</color> + <color name="i_am_color_509">#00000509</color> + <color name="i_am_color_50a">#0000050a</color> + <color name="i_am_color_50b">#0000050b</color> + <color name="i_am_color_50c">#0000050c</color> + <color name="i_am_color_50d">#0000050d</color> + <color name="i_am_color_50e">#0000050e</color> + <color name="i_am_color_50f">#0000050f</color> + <color name="i_am_color_510">#00000510</color> + <color name="i_am_color_511">#00000511</color> + <color name="i_am_color_512">#00000512</color> + <color name="i_am_color_513">#00000513</color> + <color name="i_am_color_514">#00000514</color> + <color name="i_am_color_515">#00000515</color> + <color name="i_am_color_516">#00000516</color> + <color name="i_am_color_517">#00000517</color> + <color name="i_am_color_518">#00000518</color> + <color name="i_am_color_519">#00000519</color> + <color name="i_am_color_51a">#0000051a</color> + <color name="i_am_color_51b">#0000051b</color> + <color name="i_am_color_51c">#0000051c</color> + <color name="i_am_color_51d">#0000051d</color> + <color name="i_am_color_51e">#0000051e</color> + <color name="i_am_color_51f">#0000051f</color> + <color name="i_am_color_520">#00000520</color> + <color name="i_am_color_521">#00000521</color> + <color name="i_am_color_522">#00000522</color> + <color name="i_am_color_523">#00000523</color> + <color name="i_am_color_524">#00000524</color> + <color name="i_am_color_525">#00000525</color> + <color name="i_am_color_526">#00000526</color> + <color name="i_am_color_527">#00000527</color> + <color name="i_am_color_528">#00000528</color> + <color name="i_am_color_529">#00000529</color> + <color name="i_am_color_52a">#0000052a</color> + <color name="i_am_color_52b">#0000052b</color> + <color name="i_am_color_52c">#0000052c</color> + <color name="i_am_color_52d">#0000052d</color> + <color name="i_am_color_52e">#0000052e</color> + <color name="i_am_color_52f">#0000052f</color> + <color name="i_am_color_530">#00000530</color> + <color name="i_am_color_531">#00000531</color> + <color name="i_am_color_532">#00000532</color> + <color name="i_am_color_533">#00000533</color> + <color name="i_am_color_534">#00000534</color> + <color name="i_am_color_535">#00000535</color> + <color name="i_am_color_536">#00000536</color> + <color name="i_am_color_537">#00000537</color> + <color name="i_am_color_538">#00000538</color> + <color name="i_am_color_539">#00000539</color> + <color name="i_am_color_53a">#0000053a</color> + <color name="i_am_color_53b">#0000053b</color> + <color name="i_am_color_53c">#0000053c</color> + <color name="i_am_color_53d">#0000053d</color> + <color name="i_am_color_53e">#0000053e</color> + <color name="i_am_color_53f">#0000053f</color> + <color name="i_am_color_540">#00000540</color> + <color name="i_am_color_541">#00000541</color> + <color name="i_am_color_542">#00000542</color> + <color name="i_am_color_543">#00000543</color> + <color name="i_am_color_544">#00000544</color> + <color name="i_am_color_545">#00000545</color> + <color name="i_am_color_546">#00000546</color> + <color name="i_am_color_547">#00000547</color> + <color name="i_am_color_548">#00000548</color> + <color name="i_am_color_549">#00000549</color> + <color name="i_am_color_54a">#0000054a</color> + <color name="i_am_color_54b">#0000054b</color> + <color name="i_am_color_54c">#0000054c</color> + <color name="i_am_color_54d">#0000054d</color> + <color name="i_am_color_54e">#0000054e</color> + <color name="i_am_color_54f">#0000054f</color> + <color name="i_am_color_550">#00000550</color> + <color name="i_am_color_551">#00000551</color> + <color name="i_am_color_552">#00000552</color> + <color name="i_am_color_553">#00000553</color> + <color name="i_am_color_554">#00000554</color> + <color name="i_am_color_555">#00000555</color> + <color name="i_am_color_556">#00000556</color> + <color name="i_am_color_557">#00000557</color> + <color name="i_am_color_558">#00000558</color> + <color name="i_am_color_559">#00000559</color> + <color name="i_am_color_55a">#0000055a</color> + <color name="i_am_color_55b">#0000055b</color> + <color name="i_am_color_55c">#0000055c</color> + <color name="i_am_color_55d">#0000055d</color> + <color name="i_am_color_55e">#0000055e</color> + <color name="i_am_color_55f">#0000055f</color> + <color name="i_am_color_560">#00000560</color> + <color name="i_am_color_561">#00000561</color> + <color name="i_am_color_562">#00000562</color> + <color name="i_am_color_563">#00000563</color> + <color name="i_am_color_564">#00000564</color> + <color name="i_am_color_565">#00000565</color> + <color name="i_am_color_566">#00000566</color> + <color name="i_am_color_567">#00000567</color> + <color name="i_am_color_568">#00000568</color> + <color name="i_am_color_569">#00000569</color> + <color name="i_am_color_56a">#0000056a</color> + <color name="i_am_color_56b">#0000056b</color> + <color name="i_am_color_56c">#0000056c</color> + <color name="i_am_color_56d">#0000056d</color> + <color name="i_am_color_56e">#0000056e</color> + <color name="i_am_color_56f">#0000056f</color> + <color name="i_am_color_570">#00000570</color> + <color name="i_am_color_571">#00000571</color> + <color name="i_am_color_572">#00000572</color> + <color name="i_am_color_573">#00000573</color> + <color name="i_am_color_574">#00000574</color> + <color name="i_am_color_575">#00000575</color> + <color name="i_am_color_576">#00000576</color> + <color name="i_am_color_577">#00000577</color> + <color name="i_am_color_578">#00000578</color> + <color name="i_am_color_579">#00000579</color> + <color name="i_am_color_57a">#0000057a</color> + <color name="i_am_color_57b">#0000057b</color> + <color name="i_am_color_57c">#0000057c</color> + <color name="i_am_color_57d">#0000057d</color> + <color name="i_am_color_57e">#0000057e</color> + <color name="i_am_color_57f">#0000057f</color> + <color name="i_am_color_580">#00000580</color> + <color name="i_am_color_581">#00000581</color> + <color name="i_am_color_582">#00000582</color> + <color name="i_am_color_583">#00000583</color> + <color name="i_am_color_584">#00000584</color> + <color name="i_am_color_585">#00000585</color> + <color name="i_am_color_586">#00000586</color> + <color name="i_am_color_587">#00000587</color> + <color name="i_am_color_588">#00000588</color> + <color name="i_am_color_589">#00000589</color> + <color name="i_am_color_58a">#0000058a</color> + <color name="i_am_color_58b">#0000058b</color> + <color name="i_am_color_58c">#0000058c</color> + <color name="i_am_color_58d">#0000058d</color> + <color name="i_am_color_58e">#0000058e</color> + <color name="i_am_color_58f">#0000058f</color> + <color name="i_am_color_590">#00000590</color> + <color name="i_am_color_591">#00000591</color> + <color name="i_am_color_592">#00000592</color> + <color name="i_am_color_593">#00000593</color> + <color name="i_am_color_594">#00000594</color> + <color name="i_am_color_595">#00000595</color> + <color name="i_am_color_596">#00000596</color> + <color name="i_am_color_597">#00000597</color> + <color name="i_am_color_598">#00000598</color> + <color name="i_am_color_599">#00000599</color> + <color name="i_am_color_59a">#0000059a</color> + <color name="i_am_color_59b">#0000059b</color> + <color name="i_am_color_59c">#0000059c</color> + <color name="i_am_color_59d">#0000059d</color> + <color name="i_am_color_59e">#0000059e</color> + <color name="i_am_color_59f">#0000059f</color> + <color name="i_am_color_5a0">#000005a0</color> + <color name="i_am_color_5a1">#000005a1</color> + <color name="i_am_color_5a2">#000005a2</color> + <color name="i_am_color_5a3">#000005a3</color> + <color name="i_am_color_5a4">#000005a4</color> + <color name="i_am_color_5a5">#000005a5</color> + <color name="i_am_color_5a6">#000005a6</color> + <color name="i_am_color_5a7">#000005a7</color> + <color name="i_am_color_5a8">#000005a8</color> + <color name="i_am_color_5a9">#000005a9</color> + <color name="i_am_color_5aa">#000005aa</color> + <color name="i_am_color_5ab">#000005ab</color> + <color name="i_am_color_5ac">#000005ac</color> + <color name="i_am_color_5ad">#000005ad</color> + <color name="i_am_color_5ae">#000005ae</color> + <color name="i_am_color_5af">#000005af</color> + <color name="i_am_color_5b0">#000005b0</color> + <color name="i_am_color_5b1">#000005b1</color> + <color name="i_am_color_5b2">#000005b2</color> + <color name="i_am_color_5b3">#000005b3</color> + <color name="i_am_color_5b4">#000005b4</color> + <color name="i_am_color_5b5">#000005b5</color> + <color name="i_am_color_5b6">#000005b6</color> + <color name="i_am_color_5b7">#000005b7</color> + <color name="i_am_color_5b8">#000005b8</color> + <color name="i_am_color_5b9">#000005b9</color> + <color name="i_am_color_5ba">#000005ba</color> + <color name="i_am_color_5bb">#000005bb</color> + <color name="i_am_color_5bc">#000005bc</color> + <color name="i_am_color_5bd">#000005bd</color> + <color name="i_am_color_5be">#000005be</color> + <color name="i_am_color_5bf">#000005bf</color> + <color name="i_am_color_5c0">#000005c0</color> + <color name="i_am_color_5c1">#000005c1</color> + <color name="i_am_color_5c2">#000005c2</color> + <color name="i_am_color_5c3">#000005c3</color> + <color name="i_am_color_5c4">#000005c4</color> + <color name="i_am_color_5c5">#000005c5</color> + <color name="i_am_color_5c6">#000005c6</color> + <color name="i_am_color_5c7">#000005c7</color> + <color name="i_am_color_5c8">#000005c8</color> + <color name="i_am_color_5c9">#000005c9</color> + <color name="i_am_color_5ca">#000005ca</color> + <color name="i_am_color_5cb">#000005cb</color> + <color name="i_am_color_5cc">#000005cc</color> + <color name="i_am_color_5cd">#000005cd</color> + <color name="i_am_color_5ce">#000005ce</color> + <color name="i_am_color_5cf">#000005cf</color> + <color name="i_am_color_5d0">#000005d0</color> + <color name="i_am_color_5d1">#000005d1</color> + <color name="i_am_color_5d2">#000005d2</color> + <color name="i_am_color_5d3">#000005d3</color> + <color name="i_am_color_5d4">#000005d4</color> + <color name="i_am_color_5d5">#000005d5</color> + <color name="i_am_color_5d6">#000005d6</color> + <color name="i_am_color_5d7">#000005d7</color> + <color name="i_am_color_5d8">#000005d8</color> + <color name="i_am_color_5d9">#000005d9</color> + <color name="i_am_color_5da">#000005da</color> + <color name="i_am_color_5db">#000005db</color> + <color name="i_am_color_5dc">#000005dc</color> + <color name="i_am_color_5dd">#000005dd</color> + <color name="i_am_color_5de">#000005de</color> + <color name="i_am_color_5df">#000005df</color> + <color name="i_am_color_5e0">#000005e0</color> + <color name="i_am_color_5e1">#000005e1</color> + <color name="i_am_color_5e2">#000005e2</color> + <color name="i_am_color_5e3">#000005e3</color> + <color name="i_am_color_5e4">#000005e4</color> + <color name="i_am_color_5e5">#000005e5</color> + <color name="i_am_color_5e6">#000005e6</color> + <color name="i_am_color_5e7">#000005e7</color> + <color name="i_am_color_5e8">#000005e8</color> + <color name="i_am_color_5e9">#000005e9</color> + <color name="i_am_color_5ea">#000005ea</color> + <color name="i_am_color_5eb">#000005eb</color> + <color name="i_am_color_5ec">#000005ec</color> + <color name="i_am_color_5ed">#000005ed</color> + <color name="i_am_color_5ee">#000005ee</color> + <color name="i_am_color_5ef">#000005ef</color> + <color name="i_am_color_5f0">#000005f0</color> + <color name="i_am_color_5f1">#000005f1</color> + <color name="i_am_color_5f2">#000005f2</color> + <color name="i_am_color_5f3">#000005f3</color> + <color name="i_am_color_5f4">#000005f4</color> + <color name="i_am_color_5f5">#000005f5</color> + <color name="i_am_color_5f6">#000005f6</color> + <color name="i_am_color_5f7">#000005f7</color> + <color name="i_am_color_5f8">#000005f8</color> + <color name="i_am_color_5f9">#000005f9</color> + <color name="i_am_color_5fa">#000005fa</color> + <color name="i_am_color_5fb">#000005fb</color> + <color name="i_am_color_5fc">#000005fc</color> + <color name="i_am_color_5fd">#000005fd</color> + <color name="i_am_color_5fe">#000005fe</color> + <color name="i_am_color_5ff">#000005ff</color> + <color name="i_am_color_600">#00000600</color> + <color name="i_am_color_601">#00000601</color> + <color name="i_am_color_602">#00000602</color> + <color name="i_am_color_603">#00000603</color> + <color name="i_am_color_604">#00000604</color> + <color name="i_am_color_605">#00000605</color> + <color name="i_am_color_606">#00000606</color> + <color name="i_am_color_607">#00000607</color> + <color name="i_am_color_608">#00000608</color> + <color name="i_am_color_609">#00000609</color> + <color name="i_am_color_60a">#0000060a</color> + <color name="i_am_color_60b">#0000060b</color> + <color name="i_am_color_60c">#0000060c</color> + <color name="i_am_color_60d">#0000060d</color> + <color name="i_am_color_60e">#0000060e</color> + <color name="i_am_color_60f">#0000060f</color> + <color name="i_am_color_610">#00000610</color> + <color name="i_am_color_611">#00000611</color> + <color name="i_am_color_612">#00000612</color> + <color name="i_am_color_613">#00000613</color> + <color name="i_am_color_614">#00000614</color> + <color name="i_am_color_615">#00000615</color> + <color name="i_am_color_616">#00000616</color> + <color name="i_am_color_617">#00000617</color> + <color name="i_am_color_618">#00000618</color> + <color name="i_am_color_619">#00000619</color> + <color name="i_am_color_61a">#0000061a</color> + <color name="i_am_color_61b">#0000061b</color> + <color name="i_am_color_61c">#0000061c</color> + <color name="i_am_color_61d">#0000061d</color> + <color name="i_am_color_61e">#0000061e</color> + <color name="i_am_color_61f">#0000061f</color> + <color name="i_am_color_620">#00000620</color> + <color name="i_am_color_621">#00000621</color> + <color name="i_am_color_622">#00000622</color> + <color name="i_am_color_623">#00000623</color> + <color name="i_am_color_624">#00000624</color> + <color name="i_am_color_625">#00000625</color> + <color name="i_am_color_626">#00000626</color> + <color name="i_am_color_627">#00000627</color> + <color name="i_am_color_628">#00000628</color> + <color name="i_am_color_629">#00000629</color> + <color name="i_am_color_62a">#0000062a</color> + <color name="i_am_color_62b">#0000062b</color> + <color name="i_am_color_62c">#0000062c</color> + <color name="i_am_color_62d">#0000062d</color> + <color name="i_am_color_62e">#0000062e</color> + <color name="i_am_color_62f">#0000062f</color> + <color name="i_am_color_630">#00000630</color> + <color name="i_am_color_631">#00000631</color> + <color name="i_am_color_632">#00000632</color> + <color name="i_am_color_633">#00000633</color> + <color name="i_am_color_634">#00000634</color> + <color name="i_am_color_635">#00000635</color> + <color name="i_am_color_636">#00000636</color> + <color name="i_am_color_637">#00000637</color> + <color name="i_am_color_638">#00000638</color> + <color name="i_am_color_639">#00000639</color> + <color name="i_am_color_63a">#0000063a</color> + <color name="i_am_color_63b">#0000063b</color> + <color name="i_am_color_63c">#0000063c</color> + <color name="i_am_color_63d">#0000063d</color> + <color name="i_am_color_63e">#0000063e</color> + <color name="i_am_color_63f">#0000063f</color> + <color name="i_am_color_640">#00000640</color> + <color name="i_am_color_641">#00000641</color> + <color name="i_am_color_642">#00000642</color> + <color name="i_am_color_643">#00000643</color> + <color name="i_am_color_644">#00000644</color> + <color name="i_am_color_645">#00000645</color> + <color name="i_am_color_646">#00000646</color> + <color name="i_am_color_647">#00000647</color> + <color name="i_am_color_648">#00000648</color> + <color name="i_am_color_649">#00000649</color> + <color name="i_am_color_64a">#0000064a</color> + <color name="i_am_color_64b">#0000064b</color> + <color name="i_am_color_64c">#0000064c</color> + <color name="i_am_color_64d">#0000064d</color> + <color name="i_am_color_64e">#0000064e</color> + <color name="i_am_color_64f">#0000064f</color> + <color name="i_am_color_650">#00000650</color> + <color name="i_am_color_651">#00000651</color> + <color name="i_am_color_652">#00000652</color> + <color name="i_am_color_653">#00000653</color> + <color name="i_am_color_654">#00000654</color> + <color name="i_am_color_655">#00000655</color> + <color name="i_am_color_656">#00000656</color> + <color name="i_am_color_657">#00000657</color> + <color name="i_am_color_658">#00000658</color> + <color name="i_am_color_659">#00000659</color> + <color name="i_am_color_65a">#0000065a</color> + <color name="i_am_color_65b">#0000065b</color> + <color name="i_am_color_65c">#0000065c</color> + <color name="i_am_color_65d">#0000065d</color> + <color name="i_am_color_65e">#0000065e</color> + <color name="i_am_color_65f">#0000065f</color> + <color name="i_am_color_660">#00000660</color> + <color name="i_am_color_661">#00000661</color> + <color name="i_am_color_662">#00000662</color> + <color name="i_am_color_663">#00000663</color> + <color name="i_am_color_664">#00000664</color> + <color name="i_am_color_665">#00000665</color> + <color name="i_am_color_666">#00000666</color> + <color name="i_am_color_667">#00000667</color> + <color name="i_am_color_668">#00000668</color> + <color name="i_am_color_669">#00000669</color> + <color name="i_am_color_66a">#0000066a</color> + <color name="i_am_color_66b">#0000066b</color> + <color name="i_am_color_66c">#0000066c</color> + <color name="i_am_color_66d">#0000066d</color> + <color name="i_am_color_66e">#0000066e</color> + <color name="i_am_color_66f">#0000066f</color> + <color name="i_am_color_670">#00000670</color> + <color name="i_am_color_671">#00000671</color> + <color name="i_am_color_672">#00000672</color> + <color name="i_am_color_673">#00000673</color> + <color name="i_am_color_674">#00000674</color> + <color name="i_am_color_675">#00000675</color> + <color name="i_am_color_676">#00000676</color> + <color name="i_am_color_677">#00000677</color> + <color name="i_am_color_678">#00000678</color> + <color name="i_am_color_679">#00000679</color> + <color name="i_am_color_67a">#0000067a</color> + <color name="i_am_color_67b">#0000067b</color> + <color name="i_am_color_67c">#0000067c</color> + <color name="i_am_color_67d">#0000067d</color> + <color name="i_am_color_67e">#0000067e</color> + <color name="i_am_color_67f">#0000067f</color> + <color name="i_am_color_680">#00000680</color> + <color name="i_am_color_681">#00000681</color> + <color name="i_am_color_682">#00000682</color> + <color name="i_am_color_683">#00000683</color> + <color name="i_am_color_684">#00000684</color> + <color name="i_am_color_685">#00000685</color> + <color name="i_am_color_686">#00000686</color> + <color name="i_am_color_687">#00000687</color> + <color name="i_am_color_688">#00000688</color> + <color name="i_am_color_689">#00000689</color> + <color name="i_am_color_68a">#0000068a</color> + <color name="i_am_color_68b">#0000068b</color> + <color name="i_am_color_68c">#0000068c</color> + <color name="i_am_color_68d">#0000068d</color> + <color name="i_am_color_68e">#0000068e</color> + <color name="i_am_color_68f">#0000068f</color> + <color name="i_am_color_690">#00000690</color> + <color name="i_am_color_691">#00000691</color> + <color name="i_am_color_692">#00000692</color> + <color name="i_am_color_693">#00000693</color> + <color name="i_am_color_694">#00000694</color> + <color name="i_am_color_695">#00000695</color> + <color name="i_am_color_696">#00000696</color> + <color name="i_am_color_697">#00000697</color> + <color name="i_am_color_698">#00000698</color> + <color name="i_am_color_699">#00000699</color> + <color name="i_am_color_69a">#0000069a</color> + <color name="i_am_color_69b">#0000069b</color> + <color name="i_am_color_69c">#0000069c</color> + <color name="i_am_color_69d">#0000069d</color> + <color name="i_am_color_69e">#0000069e</color> + <color name="i_am_color_69f">#0000069f</color> + <color name="i_am_color_6a0">#000006a0</color> + <color name="i_am_color_6a1">#000006a1</color> + <color name="i_am_color_6a2">#000006a2</color> + <color name="i_am_color_6a3">#000006a3</color> + <color name="i_am_color_6a4">#000006a4</color> + <color name="i_am_color_6a5">#000006a5</color> + <color name="i_am_color_6a6">#000006a6</color> + <color name="i_am_color_6a7">#000006a7</color> + <color name="i_am_color_6a8">#000006a8</color> + <color name="i_am_color_6a9">#000006a9</color> + <color name="i_am_color_6aa">#000006aa</color> + <color name="i_am_color_6ab">#000006ab</color> + <color name="i_am_color_6ac">#000006ac</color> + <color name="i_am_color_6ad">#000006ad</color> + <color name="i_am_color_6ae">#000006ae</color> + <color name="i_am_color_6af">#000006af</color> + <color name="i_am_color_6b0">#000006b0</color> + <color name="i_am_color_6b1">#000006b1</color> + <color name="i_am_color_6b2">#000006b2</color> + <color name="i_am_color_6b3">#000006b3</color> + <color name="i_am_color_6b4">#000006b4</color> + <color name="i_am_color_6b5">#000006b5</color> + <color name="i_am_color_6b6">#000006b6</color> + <color name="i_am_color_6b7">#000006b7</color> + <color name="i_am_color_6b8">#000006b8</color> + <color name="i_am_color_6b9">#000006b9</color> + <color name="i_am_color_6ba">#000006ba</color> + <color name="i_am_color_6bb">#000006bb</color> + <color name="i_am_color_6bc">#000006bc</color> + <color name="i_am_color_6bd">#000006bd</color> + <color name="i_am_color_6be">#000006be</color> + <color name="i_am_color_6bf">#000006bf</color> + <color name="i_am_color_6c0">#000006c0</color> + <color name="i_am_color_6c1">#000006c1</color> + <color name="i_am_color_6c2">#000006c2</color> + <color name="i_am_color_6c3">#000006c3</color> + <color name="i_am_color_6c4">#000006c4</color> + <color name="i_am_color_6c5">#000006c5</color> + <color name="i_am_color_6c6">#000006c6</color> + <color name="i_am_color_6c7">#000006c7</color> + <color name="i_am_color_6c8">#000006c8</color> + <color name="i_am_color_6c9">#000006c9</color> + <color name="i_am_color_6ca">#000006ca</color> + <color name="i_am_color_6cb">#000006cb</color> + <color name="i_am_color_6cc">#000006cc</color> + <color name="i_am_color_6cd">#000006cd</color> + <color name="i_am_color_6ce">#000006ce</color> + <color name="i_am_color_6cf">#000006cf</color> + <color name="i_am_color_6d0">#000006d0</color> + <color name="i_am_color_6d1">#000006d1</color> + <color name="i_am_color_6d2">#000006d2</color> + <color name="i_am_color_6d3">#000006d3</color> + <color name="i_am_color_6d4">#000006d4</color> + <color name="i_am_color_6d5">#000006d5</color> + <color name="i_am_color_6d6">#000006d6</color> + <color name="i_am_color_6d7">#000006d7</color> + <color name="i_am_color_6d8">#000006d8</color> + <color name="i_am_color_6d9">#000006d9</color> + <color name="i_am_color_6da">#000006da</color> + <color name="i_am_color_6db">#000006db</color> + <color name="i_am_color_6dc">#000006dc</color> + <color name="i_am_color_6dd">#000006dd</color> + <color name="i_am_color_6de">#000006de</color> + <color name="i_am_color_6df">#000006df</color> + <color name="i_am_color_6e0">#000006e0</color> + <color name="i_am_color_6e1">#000006e1</color> + <color name="i_am_color_6e2">#000006e2</color> + <color name="i_am_color_6e3">#000006e3</color> + <color name="i_am_color_6e4">#000006e4</color> + <color name="i_am_color_6e5">#000006e5</color> + <color name="i_am_color_6e6">#000006e6</color> + <color name="i_am_color_6e7">#000006e7</color> + <color name="i_am_color_6e8">#000006e8</color> + <color name="i_am_color_6e9">#000006e9</color> + <color name="i_am_color_6ea">#000006ea</color> + <color name="i_am_color_6eb">#000006eb</color> + <color name="i_am_color_6ec">#000006ec</color> + <color name="i_am_color_6ed">#000006ed</color> + <color name="i_am_color_6ee">#000006ee</color> + <color name="i_am_color_6ef">#000006ef</color> + <color name="i_am_color_6f0">#000006f0</color> + <color name="i_am_color_6f1">#000006f1</color> + <color name="i_am_color_6f2">#000006f2</color> + <color name="i_am_color_6f3">#000006f3</color> + <color name="i_am_color_6f4">#000006f4</color> + <color name="i_am_color_6f5">#000006f5</color> + <color name="i_am_color_6f6">#000006f6</color> + <color name="i_am_color_6f7">#000006f7</color> + <color name="i_am_color_6f8">#000006f8</color> + <color name="i_am_color_6f9">#000006f9</color> + <color name="i_am_color_6fa">#000006fa</color> + <color name="i_am_color_6fb">#000006fb</color> + <color name="i_am_color_6fc">#000006fc</color> + <color name="i_am_color_6fd">#000006fd</color> + <color name="i_am_color_6fe">#000006fe</color> + <color name="i_am_color_6ff">#000006ff</color> + <color name="i_am_color_700">#00000700</color> + <color name="i_am_color_701">#00000701</color> + <color name="i_am_color_702">#00000702</color> + <color name="i_am_color_703">#00000703</color> + <color name="i_am_color_704">#00000704</color> + <color name="i_am_color_705">#00000705</color> + <color name="i_am_color_706">#00000706</color> + <color name="i_am_color_707">#00000707</color> + <color name="i_am_color_708">#00000708</color> + <color name="i_am_color_709">#00000709</color> + <color name="i_am_color_70a">#0000070a</color> + <color name="i_am_color_70b">#0000070b</color> + <color name="i_am_color_70c">#0000070c</color> + <color name="i_am_color_70d">#0000070d</color> + <color name="i_am_color_70e">#0000070e</color> + <color name="i_am_color_70f">#0000070f</color> + <color name="i_am_color_710">#00000710</color> + <color name="i_am_color_711">#00000711</color> + <color name="i_am_color_712">#00000712</color> + <color name="i_am_color_713">#00000713</color> + <color name="i_am_color_714">#00000714</color> + <color name="i_am_color_715">#00000715</color> + <color name="i_am_color_716">#00000716</color> + <color name="i_am_color_717">#00000717</color> + <color name="i_am_color_718">#00000718</color> + <color name="i_am_color_719">#00000719</color> + <color name="i_am_color_71a">#0000071a</color> + <color name="i_am_color_71b">#0000071b</color> + <color name="i_am_color_71c">#0000071c</color> + <color name="i_am_color_71d">#0000071d</color> + <color name="i_am_color_71e">#0000071e</color> + <color name="i_am_color_71f">#0000071f</color> + <color name="i_am_color_720">#00000720</color> + <color name="i_am_color_721">#00000721</color> + <color name="i_am_color_722">#00000722</color> + <color name="i_am_color_723">#00000723</color> + <color name="i_am_color_724">#00000724</color> + <color name="i_am_color_725">#00000725</color> + <color name="i_am_color_726">#00000726</color> + <color name="i_am_color_727">#00000727</color> + <color name="i_am_color_728">#00000728</color> + <color name="i_am_color_729">#00000729</color> + <color name="i_am_color_72a">#0000072a</color> + <color name="i_am_color_72b">#0000072b</color> + <color name="i_am_color_72c">#0000072c</color> + <color name="i_am_color_72d">#0000072d</color> + <color name="i_am_color_72e">#0000072e</color> + <color name="i_am_color_72f">#0000072f</color> + <color name="i_am_color_730">#00000730</color> + <color name="i_am_color_731">#00000731</color> + <color name="i_am_color_732">#00000732</color> + <color name="i_am_color_733">#00000733</color> + <color name="i_am_color_734">#00000734</color> + <color name="i_am_color_735">#00000735</color> + <color name="i_am_color_736">#00000736</color> + <color name="i_am_color_737">#00000737</color> + <color name="i_am_color_738">#00000738</color> + <color name="i_am_color_739">#00000739</color> + <color name="i_am_color_73a">#0000073a</color> + <color name="i_am_color_73b">#0000073b</color> + <color name="i_am_color_73c">#0000073c</color> + <color name="i_am_color_73d">#0000073d</color> + <color name="i_am_color_73e">#0000073e</color> + <color name="i_am_color_73f">#0000073f</color> + <color name="i_am_color_740">#00000740</color> + <color name="i_am_color_741">#00000741</color> + <color name="i_am_color_742">#00000742</color> + <color name="i_am_color_743">#00000743</color> + <color name="i_am_color_744">#00000744</color> + <color name="i_am_color_745">#00000745</color> + <color name="i_am_color_746">#00000746</color> + <color name="i_am_color_747">#00000747</color> + <color name="i_am_color_748">#00000748</color> + <color name="i_am_color_749">#00000749</color> + <color name="i_am_color_74a">#0000074a</color> + <color name="i_am_color_74b">#0000074b</color> + <color name="i_am_color_74c">#0000074c</color> + <color name="i_am_color_74d">#0000074d</color> + <color name="i_am_color_74e">#0000074e</color> + <color name="i_am_color_74f">#0000074f</color> + <color name="i_am_color_750">#00000750</color> + <color name="i_am_color_751">#00000751</color> + <color name="i_am_color_752">#00000752</color> + <color name="i_am_color_753">#00000753</color> + <color name="i_am_color_754">#00000754</color> + <color name="i_am_color_755">#00000755</color> + <color name="i_am_color_756">#00000756</color> + <color name="i_am_color_757">#00000757</color> + <color name="i_am_color_758">#00000758</color> + <color name="i_am_color_759">#00000759</color> + <color name="i_am_color_75a">#0000075a</color> + <color name="i_am_color_75b">#0000075b</color> + <color name="i_am_color_75c">#0000075c</color> + <color name="i_am_color_75d">#0000075d</color> + <color name="i_am_color_75e">#0000075e</color> + <color name="i_am_color_75f">#0000075f</color> + <color name="i_am_color_760">#00000760</color> + <color name="i_am_color_761">#00000761</color> + <color name="i_am_color_762">#00000762</color> + <color name="i_am_color_763">#00000763</color> + <color name="i_am_color_764">#00000764</color> + <color name="i_am_color_765">#00000765</color> + <color name="i_am_color_766">#00000766</color> + <color name="i_am_color_767">#00000767</color> + <color name="i_am_color_768">#00000768</color> + <color name="i_am_color_769">#00000769</color> + <color name="i_am_color_76a">#0000076a</color> + <color name="i_am_color_76b">#0000076b</color> + <color name="i_am_color_76c">#0000076c</color> + <color name="i_am_color_76d">#0000076d</color> + <color name="i_am_color_76e">#0000076e</color> + <color name="i_am_color_76f">#0000076f</color> + <color name="i_am_color_770">#00000770</color> + <color name="i_am_color_771">#00000771</color> + <color name="i_am_color_772">#00000772</color> + <color name="i_am_color_773">#00000773</color> + <color name="i_am_color_774">#00000774</color> + <color name="i_am_color_775">#00000775</color> + <color name="i_am_color_776">#00000776</color> + <color name="i_am_color_777">#00000777</color> + <color name="i_am_color_778">#00000778</color> + <color name="i_am_color_779">#00000779</color> + <color name="i_am_color_77a">#0000077a</color> + <color name="i_am_color_77b">#0000077b</color> + <color name="i_am_color_77c">#0000077c</color> + <color name="i_am_color_77d">#0000077d</color> + <color name="i_am_color_77e">#0000077e</color> + <color name="i_am_color_77f">#0000077f</color> + <color name="i_am_color_780">#00000780</color> + <color name="i_am_color_781">#00000781</color> + <color name="i_am_color_782">#00000782</color> + <color name="i_am_color_783">#00000783</color> + <color name="i_am_color_784">#00000784</color> + <color name="i_am_color_785">#00000785</color> + <color name="i_am_color_786">#00000786</color> + <color name="i_am_color_787">#00000787</color> + <color name="i_am_color_788">#00000788</color> + <color name="i_am_color_789">#00000789</color> + <color name="i_am_color_78a">#0000078a</color> + <color name="i_am_color_78b">#0000078b</color> + <color name="i_am_color_78c">#0000078c</color> + <color name="i_am_color_78d">#0000078d</color> + <color name="i_am_color_78e">#0000078e</color> + <color name="i_am_color_78f">#0000078f</color> + <color name="i_am_color_790">#00000790</color> + <color name="i_am_color_791">#00000791</color> + <color name="i_am_color_792">#00000792</color> + <color name="i_am_color_793">#00000793</color> + <color name="i_am_color_794">#00000794</color> + <color name="i_am_color_795">#00000795</color> + <color name="i_am_color_796">#00000796</color> + <color name="i_am_color_797">#00000797</color> + <color name="i_am_color_798">#00000798</color> + <color name="i_am_color_799">#00000799</color> + <color name="i_am_color_79a">#0000079a</color> + <color name="i_am_color_79b">#0000079b</color> + <color name="i_am_color_79c">#0000079c</color> + <color name="i_am_color_79d">#0000079d</color> + <color name="i_am_color_79e">#0000079e</color> + <color name="i_am_color_79f">#0000079f</color> + <color name="i_am_color_7a0">#000007a0</color> + <color name="i_am_color_7a1">#000007a1</color> + <color name="i_am_color_7a2">#000007a2</color> + <color name="i_am_color_7a3">#000007a3</color> + <color name="i_am_color_7a4">#000007a4</color> + <color name="i_am_color_7a5">#000007a5</color> + <color name="i_am_color_7a6">#000007a6</color> + <color name="i_am_color_7a7">#000007a7</color> + <color name="i_am_color_7a8">#000007a8</color> + <color name="i_am_color_7a9">#000007a9</color> + <color name="i_am_color_7aa">#000007aa</color> + <color name="i_am_color_7ab">#000007ab</color> + <color name="i_am_color_7ac">#000007ac</color> + <color name="i_am_color_7ad">#000007ad</color> + <color name="i_am_color_7ae">#000007ae</color> + <color name="i_am_color_7af">#000007af</color> + <color name="i_am_color_7b0">#000007b0</color> + <color name="i_am_color_7b1">#000007b1</color> + <color name="i_am_color_7b2">#000007b2</color> + <color name="i_am_color_7b3">#000007b3</color> + <color name="i_am_color_7b4">#000007b4</color> + <color name="i_am_color_7b5">#000007b5</color> + <color name="i_am_color_7b6">#000007b6</color> + <color name="i_am_color_7b7">#000007b7</color> + <color name="i_am_color_7b8">#000007b8</color> + <color name="i_am_color_7b9">#000007b9</color> + <color name="i_am_color_7ba">#000007ba</color> + <color name="i_am_color_7bb">#000007bb</color> + <color name="i_am_color_7bc">#000007bc</color> + <color name="i_am_color_7bd">#000007bd</color> + <color name="i_am_color_7be">#000007be</color> + <color name="i_am_color_7bf">#000007bf</color> + <color name="i_am_color_7c0">#000007c0</color> + <color name="i_am_color_7c1">#000007c1</color> + <color name="i_am_color_7c2">#000007c2</color> + <color name="i_am_color_7c3">#000007c3</color> + <color name="i_am_color_7c4">#000007c4</color> + <color name="i_am_color_7c5">#000007c5</color> + <color name="i_am_color_7c6">#000007c6</color> + <color name="i_am_color_7c7">#000007c7</color> + <color name="i_am_color_7c8">#000007c8</color> + <color name="i_am_color_7c9">#000007c9</color> + <color name="i_am_color_7ca">#000007ca</color> + <color name="i_am_color_7cb">#000007cb</color> + <color name="i_am_color_7cc">#000007cc</color> + <color name="i_am_color_7cd">#000007cd</color> + <color name="i_am_color_7ce">#000007ce</color> + <color name="i_am_color_7cf">#000007cf</color> + <color name="i_am_color_7d0">#000007d0</color> + <color name="i_am_color_7d1">#000007d1</color> + <color name="i_am_color_7d2">#000007d2</color> + <color name="i_am_color_7d3">#000007d3</color> + <color name="i_am_color_7d4">#000007d4</color> + <color name="i_am_color_7d5">#000007d5</color> + <color name="i_am_color_7d6">#000007d6</color> + <color name="i_am_color_7d7">#000007d7</color> + <color name="i_am_color_7d8">#000007d8</color> + <color name="i_am_color_7d9">#000007d9</color> + <color name="i_am_color_7da">#000007da</color> + <color name="i_am_color_7db">#000007db</color> + <color name="i_am_color_7dc">#000007dc</color> + <color name="i_am_color_7dd">#000007dd</color> + <color name="i_am_color_7de">#000007de</color> + <color name="i_am_color_7df">#000007df</color> + <color name="i_am_color_7e0">#000007e0</color> + <color name="i_am_color_7e1">#000007e1</color> + <color name="i_am_color_7e2">#000007e2</color> + <color name="i_am_color_7e3">#000007e3</color> + <color name="i_am_color_7e4">#000007e4</color> + <color name="i_am_color_7e5">#000007e5</color> + <color name="i_am_color_7e6">#000007e6</color> + <color name="i_am_color_7e7">#000007e7</color> + <color name="i_am_color_7e8">#000007e8</color> + <color name="i_am_color_7e9">#000007e9</color> + <color name="i_am_color_7ea">#000007ea</color> + <color name="i_am_color_7eb">#000007eb</color> + <color name="i_am_color_7ec">#000007ec</color> + <color name="i_am_color_7ed">#000007ed</color> + <color name="i_am_color_7ee">#000007ee</color> + <color name="i_am_color_7ef">#000007ef</color> + <color name="i_am_color_7f0">#000007f0</color> + <color name="i_am_color_7f1">#000007f1</color> + <color name="i_am_color_7f2">#000007f2</color> + <color name="i_am_color_7f3">#000007f3</color> + <color name="i_am_color_7f4">#000007f4</color> + <color name="i_am_color_7f5">#000007f5</color> + <color name="i_am_color_7f6">#000007f6</color> + <color name="i_am_color_7f7">#000007f7</color> + <color name="i_am_color_7f8">#000007f8</color> + <color name="i_am_color_7f9">#000007f9</color> + <color name="i_am_color_7fa">#000007fa</color> + <color name="i_am_color_7fb">#000007fb</color> + <color name="i_am_color_7fc">#000007fc</color> + <color name="i_am_color_7fd">#000007fd</color> + <color name="i_am_color_7fe">#000007fe</color> + <color name="i_am_color_7ff">#000007ff</color> + <color name="i_am_color_800">#00000800</color> + <color name="i_am_color_801">#00000801</color> + <color name="i_am_color_802">#00000802</color> + <color name="i_am_color_803">#00000803</color> + <color name="i_am_color_804">#00000804</color> + <color name="i_am_color_805">#00000805</color> + <color name="i_am_color_806">#00000806</color> + <color name="i_am_color_807">#00000807</color> + <color name="i_am_color_808">#00000808</color> + <color name="i_am_color_809">#00000809</color> + <color name="i_am_color_80a">#0000080a</color> + <color name="i_am_color_80b">#0000080b</color> + <color name="i_am_color_80c">#0000080c</color> + <color name="i_am_color_80d">#0000080d</color> + <color name="i_am_color_80e">#0000080e</color> + <color name="i_am_color_80f">#0000080f</color> + <color name="i_am_color_810">#00000810</color> + <color name="i_am_color_811">#00000811</color> + <color name="i_am_color_812">#00000812</color> + <color name="i_am_color_813">#00000813</color> + <color name="i_am_color_814">#00000814</color> + <color name="i_am_color_815">#00000815</color> + <color name="i_am_color_816">#00000816</color> + <color name="i_am_color_817">#00000817</color> + <color name="i_am_color_818">#00000818</color> + <color name="i_am_color_819">#00000819</color> + <color name="i_am_color_81a">#0000081a</color> + <color name="i_am_color_81b">#0000081b</color> + <color name="i_am_color_81c">#0000081c</color> + <color name="i_am_color_81d">#0000081d</color> + <color name="i_am_color_81e">#0000081e</color> + <color name="i_am_color_81f">#0000081f</color> + <color name="i_am_color_820">#00000820</color> + <color name="i_am_color_821">#00000821</color> + <color name="i_am_color_822">#00000822</color> + <color name="i_am_color_823">#00000823</color> + <color name="i_am_color_824">#00000824</color> + <color name="i_am_color_825">#00000825</color> + <color name="i_am_color_826">#00000826</color> + <color name="i_am_color_827">#00000827</color> + <color name="i_am_color_828">#00000828</color> + <color name="i_am_color_829">#00000829</color> + <color name="i_am_color_82a">#0000082a</color> + <color name="i_am_color_82b">#0000082b</color> + <color name="i_am_color_82c">#0000082c</color> + <color name="i_am_color_82d">#0000082d</color> + <color name="i_am_color_82e">#0000082e</color> + <color name="i_am_color_82f">#0000082f</color> + <color name="i_am_color_830">#00000830</color> + <color name="i_am_color_831">#00000831</color> + <color name="i_am_color_832">#00000832</color> + <color name="i_am_color_833">#00000833</color> + <color name="i_am_color_834">#00000834</color> + <color name="i_am_color_835">#00000835</color> + <color name="i_am_color_836">#00000836</color> + <color name="i_am_color_837">#00000837</color> + <color name="i_am_color_838">#00000838</color> + <color name="i_am_color_839">#00000839</color> + <color name="i_am_color_83a">#0000083a</color> + <color name="i_am_color_83b">#0000083b</color> + <color name="i_am_color_83c">#0000083c</color> + <color name="i_am_color_83d">#0000083d</color> + <color name="i_am_color_83e">#0000083e</color> + <color name="i_am_color_83f">#0000083f</color> + <color name="i_am_color_840">#00000840</color> + <color name="i_am_color_841">#00000841</color> + <color name="i_am_color_842">#00000842</color> + <color name="i_am_color_843">#00000843</color> + <color name="i_am_color_844">#00000844</color> + <color name="i_am_color_845">#00000845</color> + <color name="i_am_color_846">#00000846</color> + <color name="i_am_color_847">#00000847</color> + <color name="i_am_color_848">#00000848</color> + <color name="i_am_color_849">#00000849</color> + <color name="i_am_color_84a">#0000084a</color> + <color name="i_am_color_84b">#0000084b</color> + <color name="i_am_color_84c">#0000084c</color> + <color name="i_am_color_84d">#0000084d</color> + <color name="i_am_color_84e">#0000084e</color> + <color name="i_am_color_84f">#0000084f</color> + <color name="i_am_color_850">#00000850</color> + <color name="i_am_color_851">#00000851</color> + <color name="i_am_color_852">#00000852</color> + <color name="i_am_color_853">#00000853</color> + <color name="i_am_color_854">#00000854</color> + <color name="i_am_color_855">#00000855</color> + <color name="i_am_color_856">#00000856</color> + <color name="i_am_color_857">#00000857</color> + <color name="i_am_color_858">#00000858</color> + <color name="i_am_color_859">#00000859</color> + <color name="i_am_color_85a">#0000085a</color> + <color name="i_am_color_85b">#0000085b</color> + <color name="i_am_color_85c">#0000085c</color> + <color name="i_am_color_85d">#0000085d</color> + <color name="i_am_color_85e">#0000085e</color> + <color name="i_am_color_85f">#0000085f</color> + <color name="i_am_color_860">#00000860</color> + <color name="i_am_color_861">#00000861</color> + <color name="i_am_color_862">#00000862</color> + <color name="i_am_color_863">#00000863</color> + <color name="i_am_color_864">#00000864</color> + <color name="i_am_color_865">#00000865</color> + <color name="i_am_color_866">#00000866</color> + <color name="i_am_color_867">#00000867</color> + <color name="i_am_color_868">#00000868</color> + <color name="i_am_color_869">#00000869</color> + <color name="i_am_color_86a">#0000086a</color> + <color name="i_am_color_86b">#0000086b</color> + <color name="i_am_color_86c">#0000086c</color> + <color name="i_am_color_86d">#0000086d</color> + <color name="i_am_color_86e">#0000086e</color> + <color name="i_am_color_86f">#0000086f</color> + <color name="i_am_color_870">#00000870</color> + <color name="i_am_color_871">#00000871</color> + <color name="i_am_color_872">#00000872</color> + <color name="i_am_color_873">#00000873</color> + <color name="i_am_color_874">#00000874</color> + <color name="i_am_color_875">#00000875</color> + <color name="i_am_color_876">#00000876</color> + <color name="i_am_color_877">#00000877</color> + <color name="i_am_color_878">#00000878</color> + <color name="i_am_color_879">#00000879</color> + <color name="i_am_color_87a">#0000087a</color> + <color name="i_am_color_87b">#0000087b</color> + <color name="i_am_color_87c">#0000087c</color> + <color name="i_am_color_87d">#0000087d</color> + <color name="i_am_color_87e">#0000087e</color> + <color name="i_am_color_87f">#0000087f</color> + <color name="i_am_color_880">#00000880</color> + <color name="i_am_color_881">#00000881</color> + <color name="i_am_color_882">#00000882</color> + <color name="i_am_color_883">#00000883</color> + <color name="i_am_color_884">#00000884</color> + <color name="i_am_color_885">#00000885</color> + <color name="i_am_color_886">#00000886</color> + <color name="i_am_color_887">#00000887</color> + <color name="i_am_color_888">#00000888</color> + <color name="i_am_color_889">#00000889</color> + <color name="i_am_color_88a">#0000088a</color> + <color name="i_am_color_88b">#0000088b</color> + <color name="i_am_color_88c">#0000088c</color> + <color name="i_am_color_88d">#0000088d</color> + <color name="i_am_color_88e">#0000088e</color> + <color name="i_am_color_88f">#0000088f</color> + <color name="i_am_color_890">#00000890</color> + <color name="i_am_color_891">#00000891</color> + <color name="i_am_color_892">#00000892</color> + <color name="i_am_color_893">#00000893</color> + <color name="i_am_color_894">#00000894</color> + <color name="i_am_color_895">#00000895</color> + <color name="i_am_color_896">#00000896</color> + <color name="i_am_color_897">#00000897</color> + <color name="i_am_color_898">#00000898</color> + <color name="i_am_color_899">#00000899</color> + <color name="i_am_color_89a">#0000089a</color> + <color name="i_am_color_89b">#0000089b</color> + <color name="i_am_color_89c">#0000089c</color> + <color name="i_am_color_89d">#0000089d</color> + <color name="i_am_color_89e">#0000089e</color> + <color name="i_am_color_89f">#0000089f</color> + <color name="i_am_color_8a0">#000008a0</color> + <color name="i_am_color_8a1">#000008a1</color> + <color name="i_am_color_8a2">#000008a2</color> + <color name="i_am_color_8a3">#000008a3</color> + <color name="i_am_color_8a4">#000008a4</color> + <color name="i_am_color_8a5">#000008a5</color> + <color name="i_am_color_8a6">#000008a6</color> + <color name="i_am_color_8a7">#000008a7</color> + <color name="i_am_color_8a8">#000008a8</color> + <color name="i_am_color_8a9">#000008a9</color> + <color name="i_am_color_8aa">#000008aa</color> + <color name="i_am_color_8ab">#000008ab</color> + <color name="i_am_color_8ac">#000008ac</color> + <color name="i_am_color_8ad">#000008ad</color> + <color name="i_am_color_8ae">#000008ae</color> + <color name="i_am_color_8af">#000008af</color> + <color name="i_am_color_8b0">#000008b0</color> + <color name="i_am_color_8b1">#000008b1</color> + <color name="i_am_color_8b2">#000008b2</color> + <color name="i_am_color_8b3">#000008b3</color> + <color name="i_am_color_8b4">#000008b4</color> + <color name="i_am_color_8b5">#000008b5</color> + <color name="i_am_color_8b6">#000008b6</color> + <color name="i_am_color_8b7">#000008b7</color> + <color name="i_am_color_8b8">#000008b8</color> + <color name="i_am_color_8b9">#000008b9</color> + <color name="i_am_color_8ba">#000008ba</color> + <color name="i_am_color_8bb">#000008bb</color> + <color name="i_am_color_8bc">#000008bc</color> + <color name="i_am_color_8bd">#000008bd</color> + <color name="i_am_color_8be">#000008be</color> + <color name="i_am_color_8bf">#000008bf</color> + <color name="i_am_color_8c0">#000008c0</color> + <color name="i_am_color_8c1">#000008c1</color> + <color name="i_am_color_8c2">#000008c2</color> + <color name="i_am_color_8c3">#000008c3</color> + <color name="i_am_color_8c4">#000008c4</color> + <color name="i_am_color_8c5">#000008c5</color> + <color name="i_am_color_8c6">#000008c6</color> + <color name="i_am_color_8c7">#000008c7</color> + <color name="i_am_color_8c8">#000008c8</color> + <color name="i_am_color_8c9">#000008c9</color> + <color name="i_am_color_8ca">#000008ca</color> + <color name="i_am_color_8cb">#000008cb</color> + <color name="i_am_color_8cc">#000008cc</color> + <color name="i_am_color_8cd">#000008cd</color> + <color name="i_am_color_8ce">#000008ce</color> + <color name="i_am_color_8cf">#000008cf</color> + <color name="i_am_color_8d0">#000008d0</color> + <color name="i_am_color_8d1">#000008d1</color> + <color name="i_am_color_8d2">#000008d2</color> + <color name="i_am_color_8d3">#000008d3</color> + <color name="i_am_color_8d4">#000008d4</color> + <color name="i_am_color_8d5">#000008d5</color> + <color name="i_am_color_8d6">#000008d6</color> + <color name="i_am_color_8d7">#000008d7</color> + <color name="i_am_color_8d8">#000008d8</color> + <color name="i_am_color_8d9">#000008d9</color> + <color name="i_am_color_8da">#000008da</color> + <color name="i_am_color_8db">#000008db</color> + <color name="i_am_color_8dc">#000008dc</color> + <color name="i_am_color_8dd">#000008dd</color> + <color name="i_am_color_8de">#000008de</color> + <color name="i_am_color_8df">#000008df</color> + <color name="i_am_color_8e0">#000008e0</color> + <color name="i_am_color_8e1">#000008e1</color> + <color name="i_am_color_8e2">#000008e2</color> + <color name="i_am_color_8e3">#000008e3</color> + <color name="i_am_color_8e4">#000008e4</color> + <color name="i_am_color_8e5">#000008e5</color> + <color name="i_am_color_8e6">#000008e6</color> + <color name="i_am_color_8e7">#000008e7</color> + <color name="i_am_color_8e8">#000008e8</color> + <color name="i_am_color_8e9">#000008e9</color> + <color name="i_am_color_8ea">#000008ea</color> + <color name="i_am_color_8eb">#000008eb</color> + <color name="i_am_color_8ec">#000008ec</color> + <color name="i_am_color_8ed">#000008ed</color> + <color name="i_am_color_8ee">#000008ee</color> + <color name="i_am_color_8ef">#000008ef</color> + <color name="i_am_color_8f0">#000008f0</color> + <color name="i_am_color_8f1">#000008f1</color> + <color name="i_am_color_8f2">#000008f2</color> + <color name="i_am_color_8f3">#000008f3</color> + <color name="i_am_color_8f4">#000008f4</color> + <color name="i_am_color_8f5">#000008f5</color> + <color name="i_am_color_8f6">#000008f6</color> + <color name="i_am_color_8f7">#000008f7</color> + <color name="i_am_color_8f8">#000008f8</color> + <color name="i_am_color_8f9">#000008f9</color> + <color name="i_am_color_8fa">#000008fa</color> + <color name="i_am_color_8fb">#000008fb</color> + <color name="i_am_color_8fc">#000008fc</color> + <color name="i_am_color_8fd">#000008fd</color> + <color name="i_am_color_8fe">#000008fe</color> + <color name="i_am_color_8ff">#000008ff</color> + <color name="i_am_color_900">#00000900</color> + <color name="i_am_color_901">#00000901</color> + <color name="i_am_color_902">#00000902</color> + <color name="i_am_color_903">#00000903</color> + <color name="i_am_color_904">#00000904</color> + <color name="i_am_color_905">#00000905</color> + <color name="i_am_color_906">#00000906</color> + <color name="i_am_color_907">#00000907</color> + <color name="i_am_color_908">#00000908</color> + <color name="i_am_color_909">#00000909</color> + <color name="i_am_color_90a">#0000090a</color> + <color name="i_am_color_90b">#0000090b</color> + <color name="i_am_color_90c">#0000090c</color> + <color name="i_am_color_90d">#0000090d</color> + <color name="i_am_color_90e">#0000090e</color> + <color name="i_am_color_90f">#0000090f</color> + <color name="i_am_color_910">#00000910</color> + <color name="i_am_color_911">#00000911</color> + <color name="i_am_color_912">#00000912</color> + <color name="i_am_color_913">#00000913</color> + <color name="i_am_color_914">#00000914</color> + <color name="i_am_color_915">#00000915</color> + <color name="i_am_color_916">#00000916</color> + <color name="i_am_color_917">#00000917</color> + <color name="i_am_color_918">#00000918</color> + <color name="i_am_color_919">#00000919</color> + <color name="i_am_color_91a">#0000091a</color> + <color name="i_am_color_91b">#0000091b</color> + <color name="i_am_color_91c">#0000091c</color> + <color name="i_am_color_91d">#0000091d</color> + <color name="i_am_color_91e">#0000091e</color> + <color name="i_am_color_91f">#0000091f</color> + <color name="i_am_color_920">#00000920</color> + <color name="i_am_color_921">#00000921</color> + <color name="i_am_color_922">#00000922</color> + <color name="i_am_color_923">#00000923</color> + <color name="i_am_color_924">#00000924</color> + <color name="i_am_color_925">#00000925</color> + <color name="i_am_color_926">#00000926</color> + <color name="i_am_color_927">#00000927</color> + <color name="i_am_color_928">#00000928</color> + <color name="i_am_color_929">#00000929</color> + <color name="i_am_color_92a">#0000092a</color> + <color name="i_am_color_92b">#0000092b</color> + <color name="i_am_color_92c">#0000092c</color> + <color name="i_am_color_92d">#0000092d</color> + <color name="i_am_color_92e">#0000092e</color> + <color name="i_am_color_92f">#0000092f</color> + <color name="i_am_color_930">#00000930</color> + <color name="i_am_color_931">#00000931</color> + <color name="i_am_color_932">#00000932</color> + <color name="i_am_color_933">#00000933</color> + <color name="i_am_color_934">#00000934</color> + <color name="i_am_color_935">#00000935</color> + <color name="i_am_color_936">#00000936</color> + <color name="i_am_color_937">#00000937</color> + <color name="i_am_color_938">#00000938</color> + <color name="i_am_color_939">#00000939</color> + <color name="i_am_color_93a">#0000093a</color> + <color name="i_am_color_93b">#0000093b</color> + <color name="i_am_color_93c">#0000093c</color> + <color name="i_am_color_93d">#0000093d</color> + <color name="i_am_color_93e">#0000093e</color> + <color name="i_am_color_93f">#0000093f</color> + <color name="i_am_color_940">#00000940</color> + <color name="i_am_color_941">#00000941</color> + <color name="i_am_color_942">#00000942</color> + <color name="i_am_color_943">#00000943</color> + <color name="i_am_color_944">#00000944</color> + <color name="i_am_color_945">#00000945</color> + <color name="i_am_color_946">#00000946</color> + <color name="i_am_color_947">#00000947</color> + <color name="i_am_color_948">#00000948</color> + <color name="i_am_color_949">#00000949</color> + <color name="i_am_color_94a">#0000094a</color> + <color name="i_am_color_94b">#0000094b</color> + <color name="i_am_color_94c">#0000094c</color> + <color name="i_am_color_94d">#0000094d</color> + <color name="i_am_color_94e">#0000094e</color> + <color name="i_am_color_94f">#0000094f</color> + <color name="i_am_color_950">#00000950</color> + <color name="i_am_color_951">#00000951</color> + <color name="i_am_color_952">#00000952</color> + <color name="i_am_color_953">#00000953</color> + <color name="i_am_color_954">#00000954</color> + <color name="i_am_color_955">#00000955</color> + <color name="i_am_color_956">#00000956</color> + <color name="i_am_color_957">#00000957</color> + <color name="i_am_color_958">#00000958</color> + <color name="i_am_color_959">#00000959</color> + <color name="i_am_color_95a">#0000095a</color> + <color name="i_am_color_95b">#0000095b</color> + <color name="i_am_color_95c">#0000095c</color> + <color name="i_am_color_95d">#0000095d</color> + <color name="i_am_color_95e">#0000095e</color> + <color name="i_am_color_95f">#0000095f</color> + <color name="i_am_color_960">#00000960</color> + <color name="i_am_color_961">#00000961</color> + <color name="i_am_color_962">#00000962</color> + <color name="i_am_color_963">#00000963</color> + <color name="i_am_color_964">#00000964</color> + <color name="i_am_color_965">#00000965</color> + <color name="i_am_color_966">#00000966</color> + <color name="i_am_color_967">#00000967</color> + <color name="i_am_color_968">#00000968</color> + <color name="i_am_color_969">#00000969</color> + <color name="i_am_color_96a">#0000096a</color> + <color name="i_am_color_96b">#0000096b</color> + <color name="i_am_color_96c">#0000096c</color> + <color name="i_am_color_96d">#0000096d</color> + <color name="i_am_color_96e">#0000096e</color> + <color name="i_am_color_96f">#0000096f</color> + <color name="i_am_color_970">#00000970</color> + <color name="i_am_color_971">#00000971</color> + <color name="i_am_color_972">#00000972</color> + <color name="i_am_color_973">#00000973</color> + <color name="i_am_color_974">#00000974</color> + <color name="i_am_color_975">#00000975</color> + <color name="i_am_color_976">#00000976</color> + <color name="i_am_color_977">#00000977</color> + <color name="i_am_color_978">#00000978</color> + <color name="i_am_color_979">#00000979</color> + <color name="i_am_color_97a">#0000097a</color> + <color name="i_am_color_97b">#0000097b</color> + <color name="i_am_color_97c">#0000097c</color> + <color name="i_am_color_97d">#0000097d</color> + <color name="i_am_color_97e">#0000097e</color> + <color name="i_am_color_97f">#0000097f</color> + <color name="i_am_color_980">#00000980</color> + <color name="i_am_color_981">#00000981</color> + <color name="i_am_color_982">#00000982</color> + <color name="i_am_color_983">#00000983</color> + <color name="i_am_color_984">#00000984</color> + <color name="i_am_color_985">#00000985</color> + <color name="i_am_color_986">#00000986</color> + <color name="i_am_color_987">#00000987</color> + <color name="i_am_color_988">#00000988</color> + <color name="i_am_color_989">#00000989</color> + <color name="i_am_color_98a">#0000098a</color> + <color name="i_am_color_98b">#0000098b</color> + <color name="i_am_color_98c">#0000098c</color> + <color name="i_am_color_98d">#0000098d</color> + <color name="i_am_color_98e">#0000098e</color> + <color name="i_am_color_98f">#0000098f</color> + <color name="i_am_color_990">#00000990</color> + <color name="i_am_color_991">#00000991</color> + <color name="i_am_color_992">#00000992</color> + <color name="i_am_color_993">#00000993</color> + <color name="i_am_color_994">#00000994</color> + <color name="i_am_color_995">#00000995</color> + <color name="i_am_color_996">#00000996</color> + <color name="i_am_color_997">#00000997</color> + <color name="i_am_color_998">#00000998</color> + <color name="i_am_color_999">#00000999</color> + <color name="i_am_color_99a">#0000099a</color> + <color name="i_am_color_99b">#0000099b</color> + <color name="i_am_color_99c">#0000099c</color> + <color name="i_am_color_99d">#0000099d</color> + <color name="i_am_color_99e">#0000099e</color> + <color name="i_am_color_99f">#0000099f</color> + <color name="i_am_color_9a0">#000009a0</color> + <color name="i_am_color_9a1">#000009a1</color> + <color name="i_am_color_9a2">#000009a2</color> + <color name="i_am_color_9a3">#000009a3</color> + <color name="i_am_color_9a4">#000009a4</color> + <color name="i_am_color_9a5">#000009a5</color> + <color name="i_am_color_9a6">#000009a6</color> + <color name="i_am_color_9a7">#000009a7</color> + <color name="i_am_color_9a8">#000009a8</color> + <color name="i_am_color_9a9">#000009a9</color> + <color name="i_am_color_9aa">#000009aa</color> + <color name="i_am_color_9ab">#000009ab</color> + <color name="i_am_color_9ac">#000009ac</color> + <color name="i_am_color_9ad">#000009ad</color> + <color name="i_am_color_9ae">#000009ae</color> + <color name="i_am_color_9af">#000009af</color> + <color name="i_am_color_9b0">#000009b0</color> + <color name="i_am_color_9b1">#000009b1</color> + <color name="i_am_color_9b2">#000009b2</color> + <color name="i_am_color_9b3">#000009b3</color> + <color name="i_am_color_9b4">#000009b4</color> + <color name="i_am_color_9b5">#000009b5</color> + <color name="i_am_color_9b6">#000009b6</color> + <color name="i_am_color_9b7">#000009b7</color> + <color name="i_am_color_9b8">#000009b8</color> + <color name="i_am_color_9b9">#000009b9</color> + <color name="i_am_color_9ba">#000009ba</color> + <color name="i_am_color_9bb">#000009bb</color> + <color name="i_am_color_9bc">#000009bc</color> + <color name="i_am_color_9bd">#000009bd</color> + <color name="i_am_color_9be">#000009be</color> + <color name="i_am_color_9bf">#000009bf</color> + <color name="i_am_color_9c0">#000009c0</color> + <color name="i_am_color_9c1">#000009c1</color> + <color name="i_am_color_9c2">#000009c2</color> + <color name="i_am_color_9c3">#000009c3</color> + <color name="i_am_color_9c4">#000009c4</color> + <color name="i_am_color_9c5">#000009c5</color> + <color name="i_am_color_9c6">#000009c6</color> + <color name="i_am_color_9c7">#000009c7</color> + <color name="i_am_color_9c8">#000009c8</color> + <color name="i_am_color_9c9">#000009c9</color> + <color name="i_am_color_9ca">#000009ca</color> + <color name="i_am_color_9cb">#000009cb</color> + <color name="i_am_color_9cc">#000009cc</color> + <color name="i_am_color_9cd">#000009cd</color> + <color name="i_am_color_9ce">#000009ce</color> + <color name="i_am_color_9cf">#000009cf</color> + <color name="i_am_color_9d0">#000009d0</color> + <color name="i_am_color_9d1">#000009d1</color> + <color name="i_am_color_9d2">#000009d2</color> + <color name="i_am_color_9d3">#000009d3</color> + <color name="i_am_color_9d4">#000009d4</color> + <color name="i_am_color_9d5">#000009d5</color> + <color name="i_am_color_9d6">#000009d6</color> + <color name="i_am_color_9d7">#000009d7</color> + <color name="i_am_color_9d8">#000009d8</color> + <color name="i_am_color_9d9">#000009d9</color> + <color name="i_am_color_9da">#000009da</color> + <color name="i_am_color_9db">#000009db</color> + <color name="i_am_color_9dc">#000009dc</color> + <color name="i_am_color_9dd">#000009dd</color> + <color name="i_am_color_9de">#000009de</color> + <color name="i_am_color_9df">#000009df</color> + <color name="i_am_color_9e0">#000009e0</color> + <color name="i_am_color_9e1">#000009e1</color> + <color name="i_am_color_9e2">#000009e2</color> + <color name="i_am_color_9e3">#000009e3</color> + <color name="i_am_color_9e4">#000009e4</color> + <color name="i_am_color_9e5">#000009e5</color> + <color name="i_am_color_9e6">#000009e6</color> + <color name="i_am_color_9e7">#000009e7</color> + <color name="i_am_color_9e8">#000009e8</color> + <color name="i_am_color_9e9">#000009e9</color> + <color name="i_am_color_9ea">#000009ea</color> + <color name="i_am_color_9eb">#000009eb</color> + <color name="i_am_color_9ec">#000009ec</color> + <color name="i_am_color_9ed">#000009ed</color> + <color name="i_am_color_9ee">#000009ee</color> + <color name="i_am_color_9ef">#000009ef</color> + <color name="i_am_color_9f0">#000009f0</color> + <color name="i_am_color_9f1">#000009f1</color> + <color name="i_am_color_9f2">#000009f2</color> + <color name="i_am_color_9f3">#000009f3</color> + <color name="i_am_color_9f4">#000009f4</color> + <color name="i_am_color_9f5">#000009f5</color> + <color name="i_am_color_9f6">#000009f6</color> + <color name="i_am_color_9f7">#000009f7</color> + <color name="i_am_color_9f8">#000009f8</color> + <color name="i_am_color_9f9">#000009f9</color> + <color name="i_am_color_9fa">#000009fa</color> + <color name="i_am_color_9fb">#000009fb</color> + <color name="i_am_color_9fc">#000009fc</color> + <color name="i_am_color_9fd">#000009fd</color> + <color name="i_am_color_9fe">#000009fe</color> + <color name="i_am_color_9ff">#000009ff</color> + <color name="i_am_color_a00">#00000a00</color> + <color name="i_am_color_a01">#00000a01</color> + <color name="i_am_color_a02">#00000a02</color> + <color name="i_am_color_a03">#00000a03</color> + <color name="i_am_color_a04">#00000a04</color> + <color name="i_am_color_a05">#00000a05</color> + <color name="i_am_color_a06">#00000a06</color> + <color name="i_am_color_a07">#00000a07</color> + <color name="i_am_color_a08">#00000a08</color> + <color name="i_am_color_a09">#00000a09</color> + <color name="i_am_color_a0a">#00000a0a</color> + <color name="i_am_color_a0b">#00000a0b</color> + <color name="i_am_color_a0c">#00000a0c</color> + <color name="i_am_color_a0d">#00000a0d</color> + <color name="i_am_color_a0e">#00000a0e</color> + <color name="i_am_color_a0f">#00000a0f</color> + <color name="i_am_color_a10">#00000a10</color> + <color name="i_am_color_a11">#00000a11</color> + <color name="i_am_color_a12">#00000a12</color> + <color name="i_am_color_a13">#00000a13</color> + <color name="i_am_color_a14">#00000a14</color> + <color name="i_am_color_a15">#00000a15</color> + <color name="i_am_color_a16">#00000a16</color> + <color name="i_am_color_a17">#00000a17</color> + <color name="i_am_color_a18">#00000a18</color> + <color name="i_am_color_a19">#00000a19</color> + <color name="i_am_color_a1a">#00000a1a</color> + <color name="i_am_color_a1b">#00000a1b</color> + <color name="i_am_color_a1c">#00000a1c</color> + <color name="i_am_color_a1d">#00000a1d</color> + <color name="i_am_color_a1e">#00000a1e</color> + <color name="i_am_color_a1f">#00000a1f</color> + <color name="i_am_color_a20">#00000a20</color> + <color name="i_am_color_a21">#00000a21</color> + <color name="i_am_color_a22">#00000a22</color> + <color name="i_am_color_a23">#00000a23</color> + <color name="i_am_color_a24">#00000a24</color> + <color name="i_am_color_a25">#00000a25</color> + <color name="i_am_color_a26">#00000a26</color> + <color name="i_am_color_a27">#00000a27</color> + <color name="i_am_color_a28">#00000a28</color> + <color name="i_am_color_a29">#00000a29</color> + <color name="i_am_color_a2a">#00000a2a</color> + <color name="i_am_color_a2b">#00000a2b</color> + <color name="i_am_color_a2c">#00000a2c</color> + <color name="i_am_color_a2d">#00000a2d</color> + <color name="i_am_color_a2e">#00000a2e</color> + <color name="i_am_color_a2f">#00000a2f</color> + <color name="i_am_color_a30">#00000a30</color> + <color name="i_am_color_a31">#00000a31</color> + <color name="i_am_color_a32">#00000a32</color> + <color name="i_am_color_a33">#00000a33</color> + <color name="i_am_color_a34">#00000a34</color> + <color name="i_am_color_a35">#00000a35</color> + <color name="i_am_color_a36">#00000a36</color> + <color name="i_am_color_a37">#00000a37</color> + <color name="i_am_color_a38">#00000a38</color> + <color name="i_am_color_a39">#00000a39</color> + <color name="i_am_color_a3a">#00000a3a</color> + <color name="i_am_color_a3b">#00000a3b</color> + <color name="i_am_color_a3c">#00000a3c</color> + <color name="i_am_color_a3d">#00000a3d</color> + <color name="i_am_color_a3e">#00000a3e</color> + <color name="i_am_color_a3f">#00000a3f</color> + <color name="i_am_color_a40">#00000a40</color> + <color name="i_am_color_a41">#00000a41</color> + <color name="i_am_color_a42">#00000a42</color> + <color name="i_am_color_a43">#00000a43</color> + <color name="i_am_color_a44">#00000a44</color> + <color name="i_am_color_a45">#00000a45</color> + <color name="i_am_color_a46">#00000a46</color> + <color name="i_am_color_a47">#00000a47</color> + <color name="i_am_color_a48">#00000a48</color> + <color name="i_am_color_a49">#00000a49</color> + <color name="i_am_color_a4a">#00000a4a</color> + <color name="i_am_color_a4b">#00000a4b</color> + <color name="i_am_color_a4c">#00000a4c</color> + <color name="i_am_color_a4d">#00000a4d</color> + <color name="i_am_color_a4e">#00000a4e</color> + <color name="i_am_color_a4f">#00000a4f</color> + <color name="i_am_color_a50">#00000a50</color> + <color name="i_am_color_a51">#00000a51</color> + <color name="i_am_color_a52">#00000a52</color> + <color name="i_am_color_a53">#00000a53</color> + <color name="i_am_color_a54">#00000a54</color> + <color name="i_am_color_a55">#00000a55</color> + <color name="i_am_color_a56">#00000a56</color> + <color name="i_am_color_a57">#00000a57</color> + <color name="i_am_color_a58">#00000a58</color> + <color name="i_am_color_a59">#00000a59</color> + <color name="i_am_color_a5a">#00000a5a</color> + <color name="i_am_color_a5b">#00000a5b</color> + <color name="i_am_color_a5c">#00000a5c</color> + <color name="i_am_color_a5d">#00000a5d</color> + <color name="i_am_color_a5e">#00000a5e</color> + <color name="i_am_color_a5f">#00000a5f</color> + <color name="i_am_color_a60">#00000a60</color> + <color name="i_am_color_a61">#00000a61</color> + <color name="i_am_color_a62">#00000a62</color> + <color name="i_am_color_a63">#00000a63</color> + <color name="i_am_color_a64">#00000a64</color> + <color name="i_am_color_a65">#00000a65</color> + <color name="i_am_color_a66">#00000a66</color> + <color name="i_am_color_a67">#00000a67</color> + <color name="i_am_color_a68">#00000a68</color> + <color name="i_am_color_a69">#00000a69</color> + <color name="i_am_color_a6a">#00000a6a</color> + <color name="i_am_color_a6b">#00000a6b</color> + <color name="i_am_color_a6c">#00000a6c</color> + <color name="i_am_color_a6d">#00000a6d</color> + <color name="i_am_color_a6e">#00000a6e</color> + <color name="i_am_color_a6f">#00000a6f</color> + <color name="i_am_color_a70">#00000a70</color> + <color name="i_am_color_a71">#00000a71</color> + <color name="i_am_color_a72">#00000a72</color> + <color name="i_am_color_a73">#00000a73</color> + <color name="i_am_color_a74">#00000a74</color> + <color name="i_am_color_a75">#00000a75</color> + <color name="i_am_color_a76">#00000a76</color> + <color name="i_am_color_a77">#00000a77</color> + <color name="i_am_color_a78">#00000a78</color> + <color name="i_am_color_a79">#00000a79</color> + <color name="i_am_color_a7a">#00000a7a</color> + <color name="i_am_color_a7b">#00000a7b</color> + <color name="i_am_color_a7c">#00000a7c</color> + <color name="i_am_color_a7d">#00000a7d</color> + <color name="i_am_color_a7e">#00000a7e</color> + <color name="i_am_color_a7f">#00000a7f</color> + <color name="i_am_color_a80">#00000a80</color> + <color name="i_am_color_a81">#00000a81</color> + <color name="i_am_color_a82">#00000a82</color> + <color name="i_am_color_a83">#00000a83</color> + <color name="i_am_color_a84">#00000a84</color> + <color name="i_am_color_a85">#00000a85</color> + <color name="i_am_color_a86">#00000a86</color> + <color name="i_am_color_a87">#00000a87</color> + <color name="i_am_color_a88">#00000a88</color> + <color name="i_am_color_a89">#00000a89</color> + <color name="i_am_color_a8a">#00000a8a</color> + <color name="i_am_color_a8b">#00000a8b</color> + <color name="i_am_color_a8c">#00000a8c</color> + <color name="i_am_color_a8d">#00000a8d</color> + <color name="i_am_color_a8e">#00000a8e</color> + <color name="i_am_color_a8f">#00000a8f</color> + <color name="i_am_color_a90">#00000a90</color> + <color name="i_am_color_a91">#00000a91</color> + <color name="i_am_color_a92">#00000a92</color> + <color name="i_am_color_a93">#00000a93</color> + <color name="i_am_color_a94">#00000a94</color> + <color name="i_am_color_a95">#00000a95</color> + <color name="i_am_color_a96">#00000a96</color> + <color name="i_am_color_a97">#00000a97</color> + <color name="i_am_color_a98">#00000a98</color> + <color name="i_am_color_a99">#00000a99</color> + <color name="i_am_color_a9a">#00000a9a</color> + <color name="i_am_color_a9b">#00000a9b</color> + <color name="i_am_color_a9c">#00000a9c</color> + <color name="i_am_color_a9d">#00000a9d</color> + <color name="i_am_color_a9e">#00000a9e</color> + <color name="i_am_color_a9f">#00000a9f</color> + <color name="i_am_color_aa0">#00000aa0</color> + <color name="i_am_color_aa1">#00000aa1</color> + <color name="i_am_color_aa2">#00000aa2</color> + <color name="i_am_color_aa3">#00000aa3</color> + <color name="i_am_color_aa4">#00000aa4</color> + <color name="i_am_color_aa5">#00000aa5</color> + <color name="i_am_color_aa6">#00000aa6</color> + <color name="i_am_color_aa7">#00000aa7</color> + <color name="i_am_color_aa8">#00000aa8</color> + <color name="i_am_color_aa9">#00000aa9</color> + <color name="i_am_color_aaa">#00000aaa</color> + <color name="i_am_color_aab">#00000aab</color> + <color name="i_am_color_aac">#00000aac</color> + <color name="i_am_color_aad">#00000aad</color> + <color name="i_am_color_aae">#00000aae</color> + <color name="i_am_color_aaf">#00000aaf</color> + <color name="i_am_color_ab0">#00000ab0</color> + <color name="i_am_color_ab1">#00000ab1</color> + <color name="i_am_color_ab2">#00000ab2</color> + <color name="i_am_color_ab3">#00000ab3</color> + <color name="i_am_color_ab4">#00000ab4</color> + <color name="i_am_color_ab5">#00000ab5</color> + <color name="i_am_color_ab6">#00000ab6</color> + <color name="i_am_color_ab7">#00000ab7</color> + <color name="i_am_color_ab8">#00000ab8</color> + <color name="i_am_color_ab9">#00000ab9</color> + <color name="i_am_color_aba">#00000aba</color> + <color name="i_am_color_abb">#00000abb</color> + <color name="i_am_color_abc">#00000abc</color> + <color name="i_am_color_abd">#00000abd</color> + <color name="i_am_color_abe">#00000abe</color> + <color name="i_am_color_abf">#00000abf</color> + <color name="i_am_color_ac0">#00000ac0</color> + <color name="i_am_color_ac1">#00000ac1</color> + <color name="i_am_color_ac2">#00000ac2</color> + <color name="i_am_color_ac3">#00000ac3</color> + <color name="i_am_color_ac4">#00000ac4</color> + <color name="i_am_color_ac5">#00000ac5</color> + <color name="i_am_color_ac6">#00000ac6</color> + <color name="i_am_color_ac7">#00000ac7</color> + <color name="i_am_color_ac8">#00000ac8</color> + <color name="i_am_color_ac9">#00000ac9</color> + <color name="i_am_color_aca">#00000aca</color> + <color name="i_am_color_acb">#00000acb</color> + <color name="i_am_color_acc">#00000acc</color> + <color name="i_am_color_acd">#00000acd</color> + <color name="i_am_color_ace">#00000ace</color> + <color name="i_am_color_acf">#00000acf</color> + <color name="i_am_color_ad0">#00000ad0</color> + <color name="i_am_color_ad1">#00000ad1</color> + <color name="i_am_color_ad2">#00000ad2</color> + <color name="i_am_color_ad3">#00000ad3</color> + <color name="i_am_color_ad4">#00000ad4</color> + <color name="i_am_color_ad5">#00000ad5</color> + <color name="i_am_color_ad6">#00000ad6</color> + <color name="i_am_color_ad7">#00000ad7</color> + <color name="i_am_color_ad8">#00000ad8</color> + <color name="i_am_color_ad9">#00000ad9</color> + <color name="i_am_color_ada">#00000ada</color> + <color name="i_am_color_adb">#00000adb</color> + <color name="i_am_color_adc">#00000adc</color> + <color name="i_am_color_add">#00000add</color> + <color name="i_am_color_ade">#00000ade</color> + <color name="i_am_color_adf">#00000adf</color> + <color name="i_am_color_ae0">#00000ae0</color> + <color name="i_am_color_ae1">#00000ae1</color> + <color name="i_am_color_ae2">#00000ae2</color> + <color name="i_am_color_ae3">#00000ae3</color> + <color name="i_am_color_ae4">#00000ae4</color> + <color name="i_am_color_ae5">#00000ae5</color> + <color name="i_am_color_ae6">#00000ae6</color> + <color name="i_am_color_ae7">#00000ae7</color> + <color name="i_am_color_ae8">#00000ae8</color> + <color name="i_am_color_ae9">#00000ae9</color> + <color name="i_am_color_aea">#00000aea</color> + <color name="i_am_color_aeb">#00000aeb</color> + <color name="i_am_color_aec">#00000aec</color> + <color name="i_am_color_aed">#00000aed</color> + <color name="i_am_color_aee">#00000aee</color> + <color name="i_am_color_aef">#00000aef</color> + <color name="i_am_color_af0">#00000af0</color> + <color name="i_am_color_af1">#00000af1</color> + <color name="i_am_color_af2">#00000af2</color> + <color name="i_am_color_af3">#00000af3</color> + <color name="i_am_color_af4">#00000af4</color> + <color name="i_am_color_af5">#00000af5</color> + <color name="i_am_color_af6">#00000af6</color> + <color name="i_am_color_af7">#00000af7</color> + <color name="i_am_color_af8">#00000af8</color> + <color name="i_am_color_af9">#00000af9</color> + <color name="i_am_color_afa">#00000afa</color> + <color name="i_am_color_afb">#00000afb</color> + <color name="i_am_color_afc">#00000afc</color> + <color name="i_am_color_afd">#00000afd</color> + <color name="i_am_color_afe">#00000afe</color> + <color name="i_am_color_aff">#00000aff</color> + <color name="i_am_color_b00">#00000b00</color> + <color name="i_am_color_b01">#00000b01</color> + <color name="i_am_color_b02">#00000b02</color> + <color name="i_am_color_b03">#00000b03</color> + <color name="i_am_color_b04">#00000b04</color> + <color name="i_am_color_b05">#00000b05</color> + <color name="i_am_color_b06">#00000b06</color> + <color name="i_am_color_b07">#00000b07</color> + <color name="i_am_color_b08">#00000b08</color> + <color name="i_am_color_b09">#00000b09</color> + <color name="i_am_color_b0a">#00000b0a</color> + <color name="i_am_color_b0b">#00000b0b</color> + <color name="i_am_color_b0c">#00000b0c</color> + <color name="i_am_color_b0d">#00000b0d</color> + <color name="i_am_color_b0e">#00000b0e</color> + <color name="i_am_color_b0f">#00000b0f</color> + <color name="i_am_color_b10">#00000b10</color> + <color name="i_am_color_b11">#00000b11</color> + <color name="i_am_color_b12">#00000b12</color> + <color name="i_am_color_b13">#00000b13</color> + <color name="i_am_color_b14">#00000b14</color> + <color name="i_am_color_b15">#00000b15</color> + <color name="i_am_color_b16">#00000b16</color> + <color name="i_am_color_b17">#00000b17</color> + <color name="i_am_color_b18">#00000b18</color> + <color name="i_am_color_b19">#00000b19</color> + <color name="i_am_color_b1a">#00000b1a</color> + <color name="i_am_color_b1b">#00000b1b</color> + <color name="i_am_color_b1c">#00000b1c</color> + <color name="i_am_color_b1d">#00000b1d</color> + <color name="i_am_color_b1e">#00000b1e</color> + <color name="i_am_color_b1f">#00000b1f</color> + <color name="i_am_color_b20">#00000b20</color> + <color name="i_am_color_b21">#00000b21</color> + <color name="i_am_color_b22">#00000b22</color> + <color name="i_am_color_b23">#00000b23</color> + <color name="i_am_color_b24">#00000b24</color> + <color name="i_am_color_b25">#00000b25</color> + <color name="i_am_color_b26">#00000b26</color> + <color name="i_am_color_b27">#00000b27</color> + <color name="i_am_color_b28">#00000b28</color> + <color name="i_am_color_b29">#00000b29</color> + <color name="i_am_color_b2a">#00000b2a</color> + <color name="i_am_color_b2b">#00000b2b</color> + <color name="i_am_color_b2c">#00000b2c</color> + <color name="i_am_color_b2d">#00000b2d</color> + <color name="i_am_color_b2e">#00000b2e</color> + <color name="i_am_color_b2f">#00000b2f</color> + <color name="i_am_color_b30">#00000b30</color> + <color name="i_am_color_b31">#00000b31</color> + <color name="i_am_color_b32">#00000b32</color> + <color name="i_am_color_b33">#00000b33</color> + <color name="i_am_color_b34">#00000b34</color> + <color name="i_am_color_b35">#00000b35</color> + <color name="i_am_color_b36">#00000b36</color> + <color name="i_am_color_b37">#00000b37</color> + <color name="i_am_color_b38">#00000b38</color> + <color name="i_am_color_b39">#00000b39</color> + <color name="i_am_color_b3a">#00000b3a</color> + <color name="i_am_color_b3b">#00000b3b</color> + <color name="i_am_color_b3c">#00000b3c</color> + <color name="i_am_color_b3d">#00000b3d</color> + <color name="i_am_color_b3e">#00000b3e</color> + <color name="i_am_color_b3f">#00000b3f</color> + <color name="i_am_color_b40">#00000b40</color> + <color name="i_am_color_b41">#00000b41</color> + <color name="i_am_color_b42">#00000b42</color> + <color name="i_am_color_b43">#00000b43</color> + <color name="i_am_color_b44">#00000b44</color> + <color name="i_am_color_b45">#00000b45</color> + <color name="i_am_color_b46">#00000b46</color> + <color name="i_am_color_b47">#00000b47</color> + <color name="i_am_color_b48">#00000b48</color> + <color name="i_am_color_b49">#00000b49</color> + <color name="i_am_color_b4a">#00000b4a</color> + <color name="i_am_color_b4b">#00000b4b</color> + <color name="i_am_color_b4c">#00000b4c</color> + <color name="i_am_color_b4d">#00000b4d</color> + <color name="i_am_color_b4e">#00000b4e</color> + <color name="i_am_color_b4f">#00000b4f</color> + <color name="i_am_color_b50">#00000b50</color> + <color name="i_am_color_b51">#00000b51</color> + <color name="i_am_color_b52">#00000b52</color> + <color name="i_am_color_b53">#00000b53</color> + <color name="i_am_color_b54">#00000b54</color> + <color name="i_am_color_b55">#00000b55</color> + <color name="i_am_color_b56">#00000b56</color> + <color name="i_am_color_b57">#00000b57</color> + <color name="i_am_color_b58">#00000b58</color> + <color name="i_am_color_b59">#00000b59</color> + <color name="i_am_color_b5a">#00000b5a</color> + <color name="i_am_color_b5b">#00000b5b</color> + <color name="i_am_color_b5c">#00000b5c</color> + <color name="i_am_color_b5d">#00000b5d</color> + <color name="i_am_color_b5e">#00000b5e</color> + <color name="i_am_color_b5f">#00000b5f</color> + <color name="i_am_color_b60">#00000b60</color> + <color name="i_am_color_b61">#00000b61</color> + <color name="i_am_color_b62">#00000b62</color> + <color name="i_am_color_b63">#00000b63</color> + <color name="i_am_color_b64">#00000b64</color> + <color name="i_am_color_b65">#00000b65</color> + <color name="i_am_color_b66">#00000b66</color> + <color name="i_am_color_b67">#00000b67</color> + <color name="i_am_color_b68">#00000b68</color> + <color name="i_am_color_b69">#00000b69</color> + <color name="i_am_color_b6a">#00000b6a</color> + <color name="i_am_color_b6b">#00000b6b</color> + <color name="i_am_color_b6c">#00000b6c</color> + <color name="i_am_color_b6d">#00000b6d</color> + <color name="i_am_color_b6e">#00000b6e</color> + <color name="i_am_color_b6f">#00000b6f</color> + <color name="i_am_color_b70">#00000b70</color> + <color name="i_am_color_b71">#00000b71</color> + <color name="i_am_color_b72">#00000b72</color> + <color name="i_am_color_b73">#00000b73</color> + <color name="i_am_color_b74">#00000b74</color> + <color name="i_am_color_b75">#00000b75</color> + <color name="i_am_color_b76">#00000b76</color> + <color name="i_am_color_b77">#00000b77</color> + <color name="i_am_color_b78">#00000b78</color> + <color name="i_am_color_b79">#00000b79</color> + <color name="i_am_color_b7a">#00000b7a</color> + <color name="i_am_color_b7b">#00000b7b</color> + <color name="i_am_color_b7c">#00000b7c</color> + <color name="i_am_color_b7d">#00000b7d</color> + <color name="i_am_color_b7e">#00000b7e</color> + <color name="i_am_color_b7f">#00000b7f</color> + <color name="i_am_color_b80">#00000b80</color> + <color name="i_am_color_b81">#00000b81</color> + <color name="i_am_color_b82">#00000b82</color> + <color name="i_am_color_b83">#00000b83</color> + <color name="i_am_color_b84">#00000b84</color> + <color name="i_am_color_b85">#00000b85</color> + <color name="i_am_color_b86">#00000b86</color> + <color name="i_am_color_b87">#00000b87</color> + <color name="i_am_color_b88">#00000b88</color> + <color name="i_am_color_b89">#00000b89</color> + <color name="i_am_color_b8a">#00000b8a</color> + <color name="i_am_color_b8b">#00000b8b</color> + <color name="i_am_color_b8c">#00000b8c</color> + <color name="i_am_color_b8d">#00000b8d</color> + <color name="i_am_color_b8e">#00000b8e</color> + <color name="i_am_color_b8f">#00000b8f</color> + <color name="i_am_color_b90">#00000b90</color> + <color name="i_am_color_b91">#00000b91</color> + <color name="i_am_color_b92">#00000b92</color> + <color name="i_am_color_b93">#00000b93</color> + <color name="i_am_color_b94">#00000b94</color> + <color name="i_am_color_b95">#00000b95</color> + <color name="i_am_color_b96">#00000b96</color> + <color name="i_am_color_b97">#00000b97</color> + <color name="i_am_color_b98">#00000b98</color> + <color name="i_am_color_b99">#00000b99</color> + <color name="i_am_color_b9a">#00000b9a</color> + <color name="i_am_color_b9b">#00000b9b</color> + <color name="i_am_color_b9c">#00000b9c</color> + <color name="i_am_color_b9d">#00000b9d</color> + <color name="i_am_color_b9e">#00000b9e</color> + <color name="i_am_color_b9f">#00000b9f</color> + <color name="i_am_color_ba0">#00000ba0</color> + <color name="i_am_color_ba1">#00000ba1</color> + <color name="i_am_color_ba2">#00000ba2</color> + <color name="i_am_color_ba3">#00000ba3</color> + <color name="i_am_color_ba4">#00000ba4</color> + <color name="i_am_color_ba5">#00000ba5</color> + <color name="i_am_color_ba6">#00000ba6</color> + <color name="i_am_color_ba7">#00000ba7</color> + <color name="i_am_color_ba8">#00000ba8</color> + <color name="i_am_color_ba9">#00000ba9</color> + <color name="i_am_color_baa">#00000baa</color> + <color name="i_am_color_bab">#00000bab</color> + <color name="i_am_color_bac">#00000bac</color> + <color name="i_am_color_bad">#00000bad</color> + <color name="i_am_color_bae">#00000bae</color> + <color name="i_am_color_baf">#00000baf</color> + <color name="i_am_color_bb0">#00000bb0</color> + <color name="i_am_color_bb1">#00000bb1</color> + <color name="i_am_color_bb2">#00000bb2</color> + <color name="i_am_color_bb3">#00000bb3</color> + <color name="i_am_color_bb4">#00000bb4</color> + <color name="i_am_color_bb5">#00000bb5</color> + <color name="i_am_color_bb6">#00000bb6</color> + <color name="i_am_color_bb7">#00000bb7</color> + <color name="i_am_color_bb8">#00000bb8</color> + <color name="i_am_color_bb9">#00000bb9</color> + <color name="i_am_color_bba">#00000bba</color> + <color name="i_am_color_bbb">#00000bbb</color> + <color name="i_am_color_bbc">#00000bbc</color> + <color name="i_am_color_bbd">#00000bbd</color> + <color name="i_am_color_bbe">#00000bbe</color> + <color name="i_am_color_bbf">#00000bbf</color> + <color name="i_am_color_bc0">#00000bc0</color> + <color name="i_am_color_bc1">#00000bc1</color> + <color name="i_am_color_bc2">#00000bc2</color> + <color name="i_am_color_bc3">#00000bc3</color> + <color name="i_am_color_bc4">#00000bc4</color> + <color name="i_am_color_bc5">#00000bc5</color> + <color name="i_am_color_bc6">#00000bc6</color> + <color name="i_am_color_bc7">#00000bc7</color> + <color name="i_am_color_bc8">#00000bc8</color> + <color name="i_am_color_bc9">#00000bc9</color> + <color name="i_am_color_bca">#00000bca</color> + <color name="i_am_color_bcb">#00000bcb</color> + <color name="i_am_color_bcc">#00000bcc</color> + <color name="i_am_color_bcd">#00000bcd</color> + <color name="i_am_color_bce">#00000bce</color> + <color name="i_am_color_bcf">#00000bcf</color> + <color name="i_am_color_bd0">#00000bd0</color> + <color name="i_am_color_bd1">#00000bd1</color> + <color name="i_am_color_bd2">#00000bd2</color> + <color name="i_am_color_bd3">#00000bd3</color> + <color name="i_am_color_bd4">#00000bd4</color> + <color name="i_am_color_bd5">#00000bd5</color> + <color name="i_am_color_bd6">#00000bd6</color> + <color name="i_am_color_bd7">#00000bd7</color> + <color name="i_am_color_bd8">#00000bd8</color> + <color name="i_am_color_bd9">#00000bd9</color> + <color name="i_am_color_bda">#00000bda</color> + <color name="i_am_color_bdb">#00000bdb</color> + <color name="i_am_color_bdc">#00000bdc</color> + <color name="i_am_color_bdd">#00000bdd</color> + <color name="i_am_color_bde">#00000bde</color> + <color name="i_am_color_bdf">#00000bdf</color> + <color name="i_am_color_be0">#00000be0</color> + <color name="i_am_color_be1">#00000be1</color> + <color name="i_am_color_be2">#00000be2</color> + <color name="i_am_color_be3">#00000be3</color> + <color name="i_am_color_be4">#00000be4</color> + <color name="i_am_color_be5">#00000be5</color> + <color name="i_am_color_be6">#00000be6</color> + <color name="i_am_color_be7">#00000be7</color> + <color name="i_am_color_be8">#00000be8</color> + <color name="i_am_color_be9">#00000be9</color> + <color name="i_am_color_bea">#00000bea</color> + <color name="i_am_color_beb">#00000beb</color> + <color name="i_am_color_bec">#00000bec</color> + <color name="i_am_color_bed">#00000bed</color> + <color name="i_am_color_bee">#00000bee</color> + <color name="i_am_color_bef">#00000bef</color> + <color name="i_am_color_bf0">#00000bf0</color> + <color name="i_am_color_bf1">#00000bf1</color> + <color name="i_am_color_bf2">#00000bf2</color> + <color name="i_am_color_bf3">#00000bf3</color> + <color name="i_am_color_bf4">#00000bf4</color> + <color name="i_am_color_bf5">#00000bf5</color> + <color name="i_am_color_bf6">#00000bf6</color> + <color name="i_am_color_bf7">#00000bf7</color> + <color name="i_am_color_bf8">#00000bf8</color> + <color name="i_am_color_bf9">#00000bf9</color> + <color name="i_am_color_bfa">#00000bfa</color> + <color name="i_am_color_bfb">#00000bfb</color> + <color name="i_am_color_bfc">#00000bfc</color> + <color name="i_am_color_bfd">#00000bfd</color> + <color name="i_am_color_bfe">#00000bfe</color> + <color name="i_am_color_bff">#00000bff</color> + <color name="i_am_color_c00">#00000c00</color> + <color name="i_am_color_c01">#00000c01</color> + <color name="i_am_color_c02">#00000c02</color> + <color name="i_am_color_c03">#00000c03</color> + <color name="i_am_color_c04">#00000c04</color> + <color name="i_am_color_c05">#00000c05</color> + <color name="i_am_color_c06">#00000c06</color> + <color name="i_am_color_c07">#00000c07</color> + <color name="i_am_color_c08">#00000c08</color> + <color name="i_am_color_c09">#00000c09</color> + <color name="i_am_color_c0a">#00000c0a</color> + <color name="i_am_color_c0b">#00000c0b</color> + <color name="i_am_color_c0c">#00000c0c</color> + <color name="i_am_color_c0d">#00000c0d</color> + <color name="i_am_color_c0e">#00000c0e</color> + <color name="i_am_color_c0f">#00000c0f</color> + <color name="i_am_color_c10">#00000c10</color> + <color name="i_am_color_c11">#00000c11</color> + <color name="i_am_color_c12">#00000c12</color> + <color name="i_am_color_c13">#00000c13</color> + <color name="i_am_color_c14">#00000c14</color> + <color name="i_am_color_c15">#00000c15</color> + <color name="i_am_color_c16">#00000c16</color> + <color name="i_am_color_c17">#00000c17</color> + <color name="i_am_color_c18">#00000c18</color> + <color name="i_am_color_c19">#00000c19</color> + <color name="i_am_color_c1a">#00000c1a</color> + <color name="i_am_color_c1b">#00000c1b</color> + <color name="i_am_color_c1c">#00000c1c</color> + <color name="i_am_color_c1d">#00000c1d</color> + <color name="i_am_color_c1e">#00000c1e</color> + <color name="i_am_color_c1f">#00000c1f</color> + <color name="i_am_color_c20">#00000c20</color> + <color name="i_am_color_c21">#00000c21</color> + <color name="i_am_color_c22">#00000c22</color> + <color name="i_am_color_c23">#00000c23</color> + <color name="i_am_color_c24">#00000c24</color> + <color name="i_am_color_c25">#00000c25</color> + <color name="i_am_color_c26">#00000c26</color> + <color name="i_am_color_c27">#00000c27</color> + <color name="i_am_color_c28">#00000c28</color> + <color name="i_am_color_c29">#00000c29</color> + <color name="i_am_color_c2a">#00000c2a</color> + <color name="i_am_color_c2b">#00000c2b</color> + <color name="i_am_color_c2c">#00000c2c</color> + <color name="i_am_color_c2d">#00000c2d</color> + <color name="i_am_color_c2e">#00000c2e</color> + <color name="i_am_color_c2f">#00000c2f</color> + <color name="i_am_color_c30">#00000c30</color> + <color name="i_am_color_c31">#00000c31</color> + <color name="i_am_color_c32">#00000c32</color> + <color name="i_am_color_c33">#00000c33</color> + <color name="i_am_color_c34">#00000c34</color> + <color name="i_am_color_c35">#00000c35</color> + <color name="i_am_color_c36">#00000c36</color> + <color name="i_am_color_c37">#00000c37</color> + <color name="i_am_color_c38">#00000c38</color> + <color name="i_am_color_c39">#00000c39</color> + <color name="i_am_color_c3a">#00000c3a</color> + <color name="i_am_color_c3b">#00000c3b</color> + <color name="i_am_color_c3c">#00000c3c</color> + <color name="i_am_color_c3d">#00000c3d</color> + <color name="i_am_color_c3e">#00000c3e</color> + <color name="i_am_color_c3f">#00000c3f</color> + <color name="i_am_color_c40">#00000c40</color> + <color name="i_am_color_c41">#00000c41</color> + <color name="i_am_color_c42">#00000c42</color> + <color name="i_am_color_c43">#00000c43</color> + <color name="i_am_color_c44">#00000c44</color> + <color name="i_am_color_c45">#00000c45</color> + <color name="i_am_color_c46">#00000c46</color> + <color name="i_am_color_c47">#00000c47</color> + <color name="i_am_color_c48">#00000c48</color> + <color name="i_am_color_c49">#00000c49</color> + <color name="i_am_color_c4a">#00000c4a</color> + <color name="i_am_color_c4b">#00000c4b</color> + <color name="i_am_color_c4c">#00000c4c</color> + <color name="i_am_color_c4d">#00000c4d</color> + <color name="i_am_color_c4e">#00000c4e</color> + <color name="i_am_color_c4f">#00000c4f</color> + <color name="i_am_color_c50">#00000c50</color> + <color name="i_am_color_c51">#00000c51</color> + <color name="i_am_color_c52">#00000c52</color> + <color name="i_am_color_c53">#00000c53</color> + <color name="i_am_color_c54">#00000c54</color> + <color name="i_am_color_c55">#00000c55</color> + <color name="i_am_color_c56">#00000c56</color> + <color name="i_am_color_c57">#00000c57</color> + <color name="i_am_color_c58">#00000c58</color> + <color name="i_am_color_c59">#00000c59</color> + <color name="i_am_color_c5a">#00000c5a</color> + <color name="i_am_color_c5b">#00000c5b</color> + <color name="i_am_color_c5c">#00000c5c</color> + <color name="i_am_color_c5d">#00000c5d</color> + <color name="i_am_color_c5e">#00000c5e</color> + <color name="i_am_color_c5f">#00000c5f</color> + <color name="i_am_color_c60">#00000c60</color> + <color name="i_am_color_c61">#00000c61</color> + <color name="i_am_color_c62">#00000c62</color> + <color name="i_am_color_c63">#00000c63</color> + <color name="i_am_color_c64">#00000c64</color> + <color name="i_am_color_c65">#00000c65</color> + <color name="i_am_color_c66">#00000c66</color> + <color name="i_am_color_c67">#00000c67</color> + <color name="i_am_color_c68">#00000c68</color> + <color name="i_am_color_c69">#00000c69</color> + <color name="i_am_color_c6a">#00000c6a</color> + <color name="i_am_color_c6b">#00000c6b</color> + <color name="i_am_color_c6c">#00000c6c</color> + <color name="i_am_color_c6d">#00000c6d</color> + <color name="i_am_color_c6e">#00000c6e</color> + <color name="i_am_color_c6f">#00000c6f</color> + <color name="i_am_color_c70">#00000c70</color> + <color name="i_am_color_c71">#00000c71</color> + <color name="i_am_color_c72">#00000c72</color> + <color name="i_am_color_c73">#00000c73</color> + <color name="i_am_color_c74">#00000c74</color> + <color name="i_am_color_c75">#00000c75</color> + <color name="i_am_color_c76">#00000c76</color> + <color name="i_am_color_c77">#00000c77</color> + <color name="i_am_color_c78">#00000c78</color> + <color name="i_am_color_c79">#00000c79</color> + <color name="i_am_color_c7a">#00000c7a</color> + <color name="i_am_color_c7b">#00000c7b</color> + <color name="i_am_color_c7c">#00000c7c</color> + <color name="i_am_color_c7d">#00000c7d</color> + <color name="i_am_color_c7e">#00000c7e</color> + <color name="i_am_color_c7f">#00000c7f</color> + <color name="i_am_color_c80">#00000c80</color> + <color name="i_am_color_c81">#00000c81</color> + <color name="i_am_color_c82">#00000c82</color> + <color name="i_am_color_c83">#00000c83</color> + <color name="i_am_color_c84">#00000c84</color> + <color name="i_am_color_c85">#00000c85</color> + <color name="i_am_color_c86">#00000c86</color> + <color name="i_am_color_c87">#00000c87</color> + <color name="i_am_color_c88">#00000c88</color> + <color name="i_am_color_c89">#00000c89</color> + <color name="i_am_color_c8a">#00000c8a</color> + <color name="i_am_color_c8b">#00000c8b</color> + <color name="i_am_color_c8c">#00000c8c</color> + <color name="i_am_color_c8d">#00000c8d</color> + <color name="i_am_color_c8e">#00000c8e</color> + <color name="i_am_color_c8f">#00000c8f</color> + <color name="i_am_color_c90">#00000c90</color> + <color name="i_am_color_c91">#00000c91</color> + <color name="i_am_color_c92">#00000c92</color> + <color name="i_am_color_c93">#00000c93</color> + <color name="i_am_color_c94">#00000c94</color> + <color name="i_am_color_c95">#00000c95</color> + <color name="i_am_color_c96">#00000c96</color> + <color name="i_am_color_c97">#00000c97</color> + <color name="i_am_color_c98">#00000c98</color> + <color name="i_am_color_c99">#00000c99</color> + <color name="i_am_color_c9a">#00000c9a</color> + <color name="i_am_color_c9b">#00000c9b</color> + <color name="i_am_color_c9c">#00000c9c</color> + <color name="i_am_color_c9d">#00000c9d</color> + <color name="i_am_color_c9e">#00000c9e</color> + <color name="i_am_color_c9f">#00000c9f</color> + <color name="i_am_color_ca0">#00000ca0</color> + <color name="i_am_color_ca1">#00000ca1</color> + <color name="i_am_color_ca2">#00000ca2</color> + <color name="i_am_color_ca3">#00000ca3</color> + <color name="i_am_color_ca4">#00000ca4</color> + <color name="i_am_color_ca5">#00000ca5</color> + <color name="i_am_color_ca6">#00000ca6</color> + <color name="i_am_color_ca7">#00000ca7</color> + <color name="i_am_color_ca8">#00000ca8</color> + <color name="i_am_color_ca9">#00000ca9</color> + <color name="i_am_color_caa">#00000caa</color> + <color name="i_am_color_cab">#00000cab</color> + <color name="i_am_color_cac">#00000cac</color> + <color name="i_am_color_cad">#00000cad</color> + <color name="i_am_color_cae">#00000cae</color> + <color name="i_am_color_caf">#00000caf</color> + <color name="i_am_color_cb0">#00000cb0</color> + <color name="i_am_color_cb1">#00000cb1</color> + <color name="i_am_color_cb2">#00000cb2</color> + <color name="i_am_color_cb3">#00000cb3</color> + <color name="i_am_color_cb4">#00000cb4</color> + <color name="i_am_color_cb5">#00000cb5</color> + <color name="i_am_color_cb6">#00000cb6</color> + <color name="i_am_color_cb7">#00000cb7</color> + <color name="i_am_color_cb8">#00000cb8</color> + <color name="i_am_color_cb9">#00000cb9</color> + <color name="i_am_color_cba">#00000cba</color> + <color name="i_am_color_cbb">#00000cbb</color> + <color name="i_am_color_cbc">#00000cbc</color> + <color name="i_am_color_cbd">#00000cbd</color> + <color name="i_am_color_cbe">#00000cbe</color> + <color name="i_am_color_cbf">#00000cbf</color> + <color name="i_am_color_cc0">#00000cc0</color> + <color name="i_am_color_cc1">#00000cc1</color> + <color name="i_am_color_cc2">#00000cc2</color> + <color name="i_am_color_cc3">#00000cc3</color> + <color name="i_am_color_cc4">#00000cc4</color> + <color name="i_am_color_cc5">#00000cc5</color> + <color name="i_am_color_cc6">#00000cc6</color> + <color name="i_am_color_cc7">#00000cc7</color> + <color name="i_am_color_cc8">#00000cc8</color> + <color name="i_am_color_cc9">#00000cc9</color> + <color name="i_am_color_cca">#00000cca</color> + <color name="i_am_color_ccb">#00000ccb</color> + <color name="i_am_color_ccc">#00000ccc</color> + <color name="i_am_color_ccd">#00000ccd</color> + <color name="i_am_color_cce">#00000cce</color> + <color name="i_am_color_ccf">#00000ccf</color> + <color name="i_am_color_cd0">#00000cd0</color> + <color name="i_am_color_cd1">#00000cd1</color> + <color name="i_am_color_cd2">#00000cd2</color> + <color name="i_am_color_cd3">#00000cd3</color> + <color name="i_am_color_cd4">#00000cd4</color> + <color name="i_am_color_cd5">#00000cd5</color> + <color name="i_am_color_cd6">#00000cd6</color> + <color name="i_am_color_cd7">#00000cd7</color> + <color name="i_am_color_cd8">#00000cd8</color> + <color name="i_am_color_cd9">#00000cd9</color> + <color name="i_am_color_cda">#00000cda</color> + <color name="i_am_color_cdb">#00000cdb</color> + <color name="i_am_color_cdc">#00000cdc</color> + <color name="i_am_color_cdd">#00000cdd</color> + <color name="i_am_color_cde">#00000cde</color> + <color name="i_am_color_cdf">#00000cdf</color> + <color name="i_am_color_ce0">#00000ce0</color> + <color name="i_am_color_ce1">#00000ce1</color> + <color name="i_am_color_ce2">#00000ce2</color> + <color name="i_am_color_ce3">#00000ce3</color> + <color name="i_am_color_ce4">#00000ce4</color> + <color name="i_am_color_ce5">#00000ce5</color> + <color name="i_am_color_ce6">#00000ce6</color> + <color name="i_am_color_ce7">#00000ce7</color> + <color name="i_am_color_ce8">#00000ce8</color> + <color name="i_am_color_ce9">#00000ce9</color> + <color name="i_am_color_cea">#00000cea</color> + <color name="i_am_color_ceb">#00000ceb</color> + <color name="i_am_color_cec">#00000cec</color> + <color name="i_am_color_ced">#00000ced</color> + <color name="i_am_color_cee">#00000cee</color> + <color name="i_am_color_cef">#00000cef</color> + <color name="i_am_color_cf0">#00000cf0</color> + <color name="i_am_color_cf1">#00000cf1</color> + <color name="i_am_color_cf2">#00000cf2</color> + <color name="i_am_color_cf3">#00000cf3</color> + <color name="i_am_color_cf4">#00000cf4</color> + <color name="i_am_color_cf5">#00000cf5</color> + <color name="i_am_color_cf6">#00000cf6</color> + <color name="i_am_color_cf7">#00000cf7</color> + <color name="i_am_color_cf8">#00000cf8</color> + <color name="i_am_color_cf9">#00000cf9</color> + <color name="i_am_color_cfa">#00000cfa</color> + <color name="i_am_color_cfb">#00000cfb</color> + <color name="i_am_color_cfc">#00000cfc</color> + <color name="i_am_color_cfd">#00000cfd</color> + <color name="i_am_color_cfe">#00000cfe</color> + <color name="i_am_color_cff">#00000cff</color> + <color name="i_am_color_d00">#00000d00</color> + <color name="i_am_color_d01">#00000d01</color> + <color name="i_am_color_d02">#00000d02</color> + <color name="i_am_color_d03">#00000d03</color> + <color name="i_am_color_d04">#00000d04</color> + <color name="i_am_color_d05">#00000d05</color> + <color name="i_am_color_d06">#00000d06</color> + <color name="i_am_color_d07">#00000d07</color> + <color name="i_am_color_d08">#00000d08</color> + <color name="i_am_color_d09">#00000d09</color> + <color name="i_am_color_d0a">#00000d0a</color> + <color name="i_am_color_d0b">#00000d0b</color> + <color name="i_am_color_d0c">#00000d0c</color> + <color name="i_am_color_d0d">#00000d0d</color> + <color name="i_am_color_d0e">#00000d0e</color> + <color name="i_am_color_d0f">#00000d0f</color> + <color name="i_am_color_d10">#00000d10</color> + <color name="i_am_color_d11">#00000d11</color> + <color name="i_am_color_d12">#00000d12</color> + <color name="i_am_color_d13">#00000d13</color> + <color name="i_am_color_d14">#00000d14</color> + <color name="i_am_color_d15">#00000d15</color> + <color name="i_am_color_d16">#00000d16</color> + <color name="i_am_color_d17">#00000d17</color> + <color name="i_am_color_d18">#00000d18</color> + <color name="i_am_color_d19">#00000d19</color> + <color name="i_am_color_d1a">#00000d1a</color> + <color name="i_am_color_d1b">#00000d1b</color> + <color name="i_am_color_d1c">#00000d1c</color> + <color name="i_am_color_d1d">#00000d1d</color> + <color name="i_am_color_d1e">#00000d1e</color> + <color name="i_am_color_d1f">#00000d1f</color> + <color name="i_am_color_d20">#00000d20</color> + <color name="i_am_color_d21">#00000d21</color> + <color name="i_am_color_d22">#00000d22</color> + <color name="i_am_color_d23">#00000d23</color> + <color name="i_am_color_d24">#00000d24</color> + <color name="i_am_color_d25">#00000d25</color> + <color name="i_am_color_d26">#00000d26</color> + <color name="i_am_color_d27">#00000d27</color> + <color name="i_am_color_d28">#00000d28</color> + <color name="i_am_color_d29">#00000d29</color> + <color name="i_am_color_d2a">#00000d2a</color> + <color name="i_am_color_d2b">#00000d2b</color> + <color name="i_am_color_d2c">#00000d2c</color> + <color name="i_am_color_d2d">#00000d2d</color> + <color name="i_am_color_d2e">#00000d2e</color> + <color name="i_am_color_d2f">#00000d2f</color> + <color name="i_am_color_d30">#00000d30</color> + <color name="i_am_color_d31">#00000d31</color> + <color name="i_am_color_d32">#00000d32</color> + <color name="i_am_color_d33">#00000d33</color> + <color name="i_am_color_d34">#00000d34</color> + <color name="i_am_color_d35">#00000d35</color> + <color name="i_am_color_d36">#00000d36</color> + <color name="i_am_color_d37">#00000d37</color> + <color name="i_am_color_d38">#00000d38</color> + <color name="i_am_color_d39">#00000d39</color> + <color name="i_am_color_d3a">#00000d3a</color> + <color name="i_am_color_d3b">#00000d3b</color> + <color name="i_am_color_d3c">#00000d3c</color> + <color name="i_am_color_d3d">#00000d3d</color> + <color name="i_am_color_d3e">#00000d3e</color> + <color name="i_am_color_d3f">#00000d3f</color> + <color name="i_am_color_d40">#00000d40</color> + <color name="i_am_color_d41">#00000d41</color> + <color name="i_am_color_d42">#00000d42</color> + <color name="i_am_color_d43">#00000d43</color> + <color name="i_am_color_d44">#00000d44</color> + <color name="i_am_color_d45">#00000d45</color> + <color name="i_am_color_d46">#00000d46</color> + <color name="i_am_color_d47">#00000d47</color> + <color name="i_am_color_d48">#00000d48</color> + <color name="i_am_color_d49">#00000d49</color> + <color name="i_am_color_d4a">#00000d4a</color> + <color name="i_am_color_d4b">#00000d4b</color> + <color name="i_am_color_d4c">#00000d4c</color> + <color name="i_am_color_d4d">#00000d4d</color> + <color name="i_am_color_d4e">#00000d4e</color> + <color name="i_am_color_d4f">#00000d4f</color> + <color name="i_am_color_d50">#00000d50</color> + <color name="i_am_color_d51">#00000d51</color> + <color name="i_am_color_d52">#00000d52</color> + <color name="i_am_color_d53">#00000d53</color> + <color name="i_am_color_d54">#00000d54</color> + <color name="i_am_color_d55">#00000d55</color> + <color name="i_am_color_d56">#00000d56</color> + <color name="i_am_color_d57">#00000d57</color> + <color name="i_am_color_d58">#00000d58</color> + <color name="i_am_color_d59">#00000d59</color> + <color name="i_am_color_d5a">#00000d5a</color> + <color name="i_am_color_d5b">#00000d5b</color> + <color name="i_am_color_d5c">#00000d5c</color> + <color name="i_am_color_d5d">#00000d5d</color> + <color name="i_am_color_d5e">#00000d5e</color> + <color name="i_am_color_d5f">#00000d5f</color> + <color name="i_am_color_d60">#00000d60</color> + <color name="i_am_color_d61">#00000d61</color> + <color name="i_am_color_d62">#00000d62</color> + <color name="i_am_color_d63">#00000d63</color> + <color name="i_am_color_d64">#00000d64</color> + <color name="i_am_color_d65">#00000d65</color> + <color name="i_am_color_d66">#00000d66</color> + <color name="i_am_color_d67">#00000d67</color> + <color name="i_am_color_d68">#00000d68</color> + <color name="i_am_color_d69">#00000d69</color> + <color name="i_am_color_d6a">#00000d6a</color> + <color name="i_am_color_d6b">#00000d6b</color> + <color name="i_am_color_d6c">#00000d6c</color> + <color name="i_am_color_d6d">#00000d6d</color> + <color name="i_am_color_d6e">#00000d6e</color> + <color name="i_am_color_d6f">#00000d6f</color> + <color name="i_am_color_d70">#00000d70</color> + <color name="i_am_color_d71">#00000d71</color> + <color name="i_am_color_d72">#00000d72</color> + <color name="i_am_color_d73">#00000d73</color> + <color name="i_am_color_d74">#00000d74</color> + <color name="i_am_color_d75">#00000d75</color> + <color name="i_am_color_d76">#00000d76</color> + <color name="i_am_color_d77">#00000d77</color> + <color name="i_am_color_d78">#00000d78</color> + <color name="i_am_color_d79">#00000d79</color> + <color name="i_am_color_d7a">#00000d7a</color> + <color name="i_am_color_d7b">#00000d7b</color> + <color name="i_am_color_d7c">#00000d7c</color> + <color name="i_am_color_d7d">#00000d7d</color> + <color name="i_am_color_d7e">#00000d7e</color> + <color name="i_am_color_d7f">#00000d7f</color> + <color name="i_am_color_d80">#00000d80</color> + <color name="i_am_color_d81">#00000d81</color> + <color name="i_am_color_d82">#00000d82</color> + <color name="i_am_color_d83">#00000d83</color> + <color name="i_am_color_d84">#00000d84</color> + <color name="i_am_color_d85">#00000d85</color> + <color name="i_am_color_d86">#00000d86</color> + <color name="i_am_color_d87">#00000d87</color> + <color name="i_am_color_d88">#00000d88</color> + <color name="i_am_color_d89">#00000d89</color> + <color name="i_am_color_d8a">#00000d8a</color> + <color name="i_am_color_d8b">#00000d8b</color> + <color name="i_am_color_d8c">#00000d8c</color> + <color name="i_am_color_d8d">#00000d8d</color> + <color name="i_am_color_d8e">#00000d8e</color> + <color name="i_am_color_d8f">#00000d8f</color> + <color name="i_am_color_d90">#00000d90</color> + <color name="i_am_color_d91">#00000d91</color> + <color name="i_am_color_d92">#00000d92</color> + <color name="i_am_color_d93">#00000d93</color> + <color name="i_am_color_d94">#00000d94</color> + <color name="i_am_color_d95">#00000d95</color> + <color name="i_am_color_d96">#00000d96</color> + <color name="i_am_color_d97">#00000d97</color> + <color name="i_am_color_d98">#00000d98</color> + <color name="i_am_color_d99">#00000d99</color> + <color name="i_am_color_d9a">#00000d9a</color> + <color name="i_am_color_d9b">#00000d9b</color> + <color name="i_am_color_d9c">#00000d9c</color> + <color name="i_am_color_d9d">#00000d9d</color> + <color name="i_am_color_d9e">#00000d9e</color> + <color name="i_am_color_d9f">#00000d9f</color> + <color name="i_am_color_da0">#00000da0</color> + <color name="i_am_color_da1">#00000da1</color> + <color name="i_am_color_da2">#00000da2</color> + <color name="i_am_color_da3">#00000da3</color> + <color name="i_am_color_da4">#00000da4</color> + <color name="i_am_color_da5">#00000da5</color> + <color name="i_am_color_da6">#00000da6</color> + <color name="i_am_color_da7">#00000da7</color> + <color name="i_am_color_da8">#00000da8</color> + <color name="i_am_color_da9">#00000da9</color> + <color name="i_am_color_daa">#00000daa</color> + <color name="i_am_color_dab">#00000dab</color> + <color name="i_am_color_dac">#00000dac</color> + <color name="i_am_color_dad">#00000dad</color> + <color name="i_am_color_dae">#00000dae</color> + <color name="i_am_color_daf">#00000daf</color> + <color name="i_am_color_db0">#00000db0</color> + <color name="i_am_color_db1">#00000db1</color> + <color name="i_am_color_db2">#00000db2</color> + <color name="i_am_color_db3">#00000db3</color> + <color name="i_am_color_db4">#00000db4</color> + <color name="i_am_color_db5">#00000db5</color> + <color name="i_am_color_db6">#00000db6</color> + <color name="i_am_color_db7">#00000db7</color> + <color name="i_am_color_db8">#00000db8</color> + <color name="i_am_color_db9">#00000db9</color> + <color name="i_am_color_dba">#00000dba</color> + <color name="i_am_color_dbb">#00000dbb</color> + <color name="i_am_color_dbc">#00000dbc</color> + <color name="i_am_color_dbd">#00000dbd</color> + <color name="i_am_color_dbe">#00000dbe</color> + <color name="i_am_color_dbf">#00000dbf</color> + <color name="i_am_color_dc0">#00000dc0</color> + <color name="i_am_color_dc1">#00000dc1</color> + <color name="i_am_color_dc2">#00000dc2</color> + <color name="i_am_color_dc3">#00000dc3</color> + <color name="i_am_color_dc4">#00000dc4</color> + <color name="i_am_color_dc5">#00000dc5</color> + <color name="i_am_color_dc6">#00000dc6</color> + <color name="i_am_color_dc7">#00000dc7</color> + <color name="i_am_color_dc8">#00000dc8</color> + <color name="i_am_color_dc9">#00000dc9</color> + <color name="i_am_color_dca">#00000dca</color> + <color name="i_am_color_dcb">#00000dcb</color> + <color name="i_am_color_dcc">#00000dcc</color> + <color name="i_am_color_dcd">#00000dcd</color> + <color name="i_am_color_dce">#00000dce</color> + <color name="i_am_color_dcf">#00000dcf</color> + <color name="i_am_color_dd0">#00000dd0</color> + <color name="i_am_color_dd1">#00000dd1</color> + <color name="i_am_color_dd2">#00000dd2</color> + <color name="i_am_color_dd3">#00000dd3</color> + <color name="i_am_color_dd4">#00000dd4</color> + <color name="i_am_color_dd5">#00000dd5</color> + <color name="i_am_color_dd6">#00000dd6</color> + <color name="i_am_color_dd7">#00000dd7</color> + <color name="i_am_color_dd8">#00000dd8</color> + <color name="i_am_color_dd9">#00000dd9</color> + <color name="i_am_color_dda">#00000dda</color> + <color name="i_am_color_ddb">#00000ddb</color> + <color name="i_am_color_ddc">#00000ddc</color> + <color name="i_am_color_ddd">#00000ddd</color> + <color name="i_am_color_dde">#00000dde</color> + <color name="i_am_color_ddf">#00000ddf</color> + <color name="i_am_color_de0">#00000de0</color> + <color name="i_am_color_de1">#00000de1</color> + <color name="i_am_color_de2">#00000de2</color> + <color name="i_am_color_de3">#00000de3</color> + <color name="i_am_color_de4">#00000de4</color> + <color name="i_am_color_de5">#00000de5</color> + <color name="i_am_color_de6">#00000de6</color> + <color name="i_am_color_de7">#00000de7</color> + <color name="i_am_color_de8">#00000de8</color> + <color name="i_am_color_de9">#00000de9</color> + <color name="i_am_color_dea">#00000dea</color> + <color name="i_am_color_deb">#00000deb</color> + <color name="i_am_color_dec">#00000dec</color> + <color name="i_am_color_ded">#00000ded</color> + <color name="i_am_color_dee">#00000dee</color> + <color name="i_am_color_def">#00000def</color> + <color name="i_am_color_df0">#00000df0</color> + <color name="i_am_color_df1">#00000df1</color> + <color name="i_am_color_df2">#00000df2</color> + <color name="i_am_color_df3">#00000df3</color> + <color name="i_am_color_df4">#00000df4</color> + <color name="i_am_color_df5">#00000df5</color> + <color name="i_am_color_df6">#00000df6</color> + <color name="i_am_color_df7">#00000df7</color> + <color name="i_am_color_df8">#00000df8</color> + <color name="i_am_color_df9">#00000df9</color> + <color name="i_am_color_dfa">#00000dfa</color> + <color name="i_am_color_dfb">#00000dfb</color> + <color name="i_am_color_dfc">#00000dfc</color> + <color name="i_am_color_dfd">#00000dfd</color> + <color name="i_am_color_dfe">#00000dfe</color> + <color name="i_am_color_dff">#00000dff</color> + <color name="i_am_color_e00">#00000e00</color> + <color name="i_am_color_e01">#00000e01</color> + <color name="i_am_color_e02">#00000e02</color> + <color name="i_am_color_e03">#00000e03</color> + <color name="i_am_color_e04">#00000e04</color> + <color name="i_am_color_e05">#00000e05</color> + <color name="i_am_color_e06">#00000e06</color> + <color name="i_am_color_e07">#00000e07</color> + <color name="i_am_color_e08">#00000e08</color> + <color name="i_am_color_e09">#00000e09</color> + <color name="i_am_color_e0a">#00000e0a</color> + <color name="i_am_color_e0b">#00000e0b</color> + <color name="i_am_color_e0c">#00000e0c</color> + <color name="i_am_color_e0d">#00000e0d</color> + <color name="i_am_color_e0e">#00000e0e</color> + <color name="i_am_color_e0f">#00000e0f</color> + <color name="i_am_color_e10">#00000e10</color> + <color name="i_am_color_e11">#00000e11</color> + <color name="i_am_color_e12">#00000e12</color> + <color name="i_am_color_e13">#00000e13</color> + <color name="i_am_color_e14">#00000e14</color> + <color name="i_am_color_e15">#00000e15</color> + <color name="i_am_color_e16">#00000e16</color> + <color name="i_am_color_e17">#00000e17</color> + <color name="i_am_color_e18">#00000e18</color> + <color name="i_am_color_e19">#00000e19</color> + <color name="i_am_color_e1a">#00000e1a</color> + <color name="i_am_color_e1b">#00000e1b</color> + <color name="i_am_color_e1c">#00000e1c</color> + <color name="i_am_color_e1d">#00000e1d</color> + <color name="i_am_color_e1e">#00000e1e</color> + <color name="i_am_color_e1f">#00000e1f</color> + <color name="i_am_color_e20">#00000e20</color> + <color name="i_am_color_e21">#00000e21</color> + <color name="i_am_color_e22">#00000e22</color> + <color name="i_am_color_e23">#00000e23</color> + <color name="i_am_color_e24">#00000e24</color> + <color name="i_am_color_e25">#00000e25</color> + <color name="i_am_color_e26">#00000e26</color> + <color name="i_am_color_e27">#00000e27</color> + <color name="i_am_color_e28">#00000e28</color> + <color name="i_am_color_e29">#00000e29</color> + <color name="i_am_color_e2a">#00000e2a</color> + <color name="i_am_color_e2b">#00000e2b</color> + <color name="i_am_color_e2c">#00000e2c</color> + <color name="i_am_color_e2d">#00000e2d</color> + <color name="i_am_color_e2e">#00000e2e</color> + <color name="i_am_color_e2f">#00000e2f</color> + <color name="i_am_color_e30">#00000e30</color> + <color name="i_am_color_e31">#00000e31</color> + <color name="i_am_color_e32">#00000e32</color> + <color name="i_am_color_e33">#00000e33</color> + <color name="i_am_color_e34">#00000e34</color> + <color name="i_am_color_e35">#00000e35</color> + <color name="i_am_color_e36">#00000e36</color> + <color name="i_am_color_e37">#00000e37</color> + <color name="i_am_color_e38">#00000e38</color> + <color name="i_am_color_e39">#00000e39</color> + <color name="i_am_color_e3a">#00000e3a</color> + <color name="i_am_color_e3b">#00000e3b</color> + <color name="i_am_color_e3c">#00000e3c</color> + <color name="i_am_color_e3d">#00000e3d</color> + <color name="i_am_color_e3e">#00000e3e</color> + <color name="i_am_color_e3f">#00000e3f</color> + <color name="i_am_color_e40">#00000e40</color> + <color name="i_am_color_e41">#00000e41</color> + <color name="i_am_color_e42">#00000e42</color> + <color name="i_am_color_e43">#00000e43</color> + <color name="i_am_color_e44">#00000e44</color> + <color name="i_am_color_e45">#00000e45</color> + <color name="i_am_color_e46">#00000e46</color> + <color name="i_am_color_e47">#00000e47</color> + <color name="i_am_color_e48">#00000e48</color> + <color name="i_am_color_e49">#00000e49</color> + <color name="i_am_color_e4a">#00000e4a</color> + <color name="i_am_color_e4b">#00000e4b</color> + <color name="i_am_color_e4c">#00000e4c</color> + <color name="i_am_color_e4d">#00000e4d</color> + <color name="i_am_color_e4e">#00000e4e</color> + <color name="i_am_color_e4f">#00000e4f</color> + <color name="i_am_color_e50">#00000e50</color> + <color name="i_am_color_e51">#00000e51</color> + <color name="i_am_color_e52">#00000e52</color> + <color name="i_am_color_e53">#00000e53</color> + <color name="i_am_color_e54">#00000e54</color> + <color name="i_am_color_e55">#00000e55</color> + <color name="i_am_color_e56">#00000e56</color> + <color name="i_am_color_e57">#00000e57</color> + <color name="i_am_color_e58">#00000e58</color> + <color name="i_am_color_e59">#00000e59</color> + <color name="i_am_color_e5a">#00000e5a</color> + <color name="i_am_color_e5b">#00000e5b</color> + <color name="i_am_color_e5c">#00000e5c</color> + <color name="i_am_color_e5d">#00000e5d</color> + <color name="i_am_color_e5e">#00000e5e</color> + <color name="i_am_color_e5f">#00000e5f</color> + <color name="i_am_color_e60">#00000e60</color> + <color name="i_am_color_e61">#00000e61</color> + <color name="i_am_color_e62">#00000e62</color> + <color name="i_am_color_e63">#00000e63</color> + <color name="i_am_color_e64">#00000e64</color> + <color name="i_am_color_e65">#00000e65</color> + <color name="i_am_color_e66">#00000e66</color> + <color name="i_am_color_e67">#00000e67</color> + <color name="i_am_color_e68">#00000e68</color> + <color name="i_am_color_e69">#00000e69</color> + <color name="i_am_color_e6a">#00000e6a</color> + <color name="i_am_color_e6b">#00000e6b</color> + <color name="i_am_color_e6c">#00000e6c</color> + <color name="i_am_color_e6d">#00000e6d</color> + <color name="i_am_color_e6e">#00000e6e</color> + <color name="i_am_color_e6f">#00000e6f</color> + <color name="i_am_color_e70">#00000e70</color> + <color name="i_am_color_e71">#00000e71</color> + <color name="i_am_color_e72">#00000e72</color> + <color name="i_am_color_e73">#00000e73</color> + <color name="i_am_color_e74">#00000e74</color> + <color name="i_am_color_e75">#00000e75</color> + <color name="i_am_color_e76">#00000e76</color> + <color name="i_am_color_e77">#00000e77</color> + <color name="i_am_color_e78">#00000e78</color> + <color name="i_am_color_e79">#00000e79</color> + <color name="i_am_color_e7a">#00000e7a</color> + <color name="i_am_color_e7b">#00000e7b</color> + <color name="i_am_color_e7c">#00000e7c</color> + <color name="i_am_color_e7d">#00000e7d</color> + <color name="i_am_color_e7e">#00000e7e</color> + <color name="i_am_color_e7f">#00000e7f</color> + <color name="i_am_color_e80">#00000e80</color> + <color name="i_am_color_e81">#00000e81</color> + <color name="i_am_color_e82">#00000e82</color> + <color name="i_am_color_e83">#00000e83</color> + <color name="i_am_color_e84">#00000e84</color> + <color name="i_am_color_e85">#00000e85</color> + <color name="i_am_color_e86">#00000e86</color> + <color name="i_am_color_e87">#00000e87</color> + <color name="i_am_color_e88">#00000e88</color> + <color name="i_am_color_e89">#00000e89</color> + <color name="i_am_color_e8a">#00000e8a</color> + <color name="i_am_color_e8b">#00000e8b</color> + <color name="i_am_color_e8c">#00000e8c</color> + <color name="i_am_color_e8d">#00000e8d</color> + <color name="i_am_color_e8e">#00000e8e</color> + <color name="i_am_color_e8f">#00000e8f</color> + <color name="i_am_color_e90">#00000e90</color> + <color name="i_am_color_e91">#00000e91</color> + <color name="i_am_color_e92">#00000e92</color> + <color name="i_am_color_e93">#00000e93</color> + <color name="i_am_color_e94">#00000e94</color> + <color name="i_am_color_e95">#00000e95</color> + <color name="i_am_color_e96">#00000e96</color> + <color name="i_am_color_e97">#00000e97</color> + <color name="i_am_color_e98">#00000e98</color> + <color name="i_am_color_e99">#00000e99</color> + <color name="i_am_color_e9a">#00000e9a</color> + <color name="i_am_color_e9b">#00000e9b</color> + <color name="i_am_color_e9c">#00000e9c</color> + <color name="i_am_color_e9d">#00000e9d</color> + <color name="i_am_color_e9e">#00000e9e</color> + <color name="i_am_color_e9f">#00000e9f</color> + <color name="i_am_color_ea0">#00000ea0</color> + <color name="i_am_color_ea1">#00000ea1</color> + <color name="i_am_color_ea2">#00000ea2</color> + <color name="i_am_color_ea3">#00000ea3</color> + <color name="i_am_color_ea4">#00000ea4</color> + <color name="i_am_color_ea5">#00000ea5</color> + <color name="i_am_color_ea6">#00000ea6</color> + <color name="i_am_color_ea7">#00000ea7</color> + <color name="i_am_color_ea8">#00000ea8</color> + <color name="i_am_color_ea9">#00000ea9</color> + <color name="i_am_color_eaa">#00000eaa</color> + <color name="i_am_color_eab">#00000eab</color> + <color name="i_am_color_eac">#00000eac</color> + <color name="i_am_color_ead">#00000ead</color> + <color name="i_am_color_eae">#00000eae</color> + <color name="i_am_color_eaf">#00000eaf</color> + <color name="i_am_color_eb0">#00000eb0</color> + <color name="i_am_color_eb1">#00000eb1</color> + <color name="i_am_color_eb2">#00000eb2</color> + <color name="i_am_color_eb3">#00000eb3</color> + <color name="i_am_color_eb4">#00000eb4</color> + <color name="i_am_color_eb5">#00000eb5</color> + <color name="i_am_color_eb6">#00000eb6</color> + <color name="i_am_color_eb7">#00000eb7</color> + <color name="i_am_color_eb8">#00000eb8</color> + <color name="i_am_color_eb9">#00000eb9</color> + <color name="i_am_color_eba">#00000eba</color> + <color name="i_am_color_ebb">#00000ebb</color> + <color name="i_am_color_ebc">#00000ebc</color> + <color name="i_am_color_ebd">#00000ebd</color> + <color name="i_am_color_ebe">#00000ebe</color> + <color name="i_am_color_ebf">#00000ebf</color> + <color name="i_am_color_ec0">#00000ec0</color> + <color name="i_am_color_ec1">#00000ec1</color> + <color name="i_am_color_ec2">#00000ec2</color> + <color name="i_am_color_ec3">#00000ec3</color> + <color name="i_am_color_ec4">#00000ec4</color> + <color name="i_am_color_ec5">#00000ec5</color> + <color name="i_am_color_ec6">#00000ec6</color> + <color name="i_am_color_ec7">#00000ec7</color> + <color name="i_am_color_ec8">#00000ec8</color> + <color name="i_am_color_ec9">#00000ec9</color> + <color name="i_am_color_eca">#00000eca</color> + <color name="i_am_color_ecb">#00000ecb</color> + <color name="i_am_color_ecc">#00000ecc</color> + <color name="i_am_color_ecd">#00000ecd</color> + <color name="i_am_color_ece">#00000ece</color> + <color name="i_am_color_ecf">#00000ecf</color> + <color name="i_am_color_ed0">#00000ed0</color> + <color name="i_am_color_ed1">#00000ed1</color> + <color name="i_am_color_ed2">#00000ed2</color> + <color name="i_am_color_ed3">#00000ed3</color> + <color name="i_am_color_ed4">#00000ed4</color> + <color name="i_am_color_ed5">#00000ed5</color> + <color name="i_am_color_ed6">#00000ed6</color> + <color name="i_am_color_ed7">#00000ed7</color> + <color name="i_am_color_ed8">#00000ed8</color> + <color name="i_am_color_ed9">#00000ed9</color> + <color name="i_am_color_eda">#00000eda</color> + <color name="i_am_color_edb">#00000edb</color> + <color name="i_am_color_edc">#00000edc</color> + <color name="i_am_color_edd">#00000edd</color> + <color name="i_am_color_ede">#00000ede</color> + <color name="i_am_color_edf">#00000edf</color> + <color name="i_am_color_ee0">#00000ee0</color> + <color name="i_am_color_ee1">#00000ee1</color> + <color name="i_am_color_ee2">#00000ee2</color> + <color name="i_am_color_ee3">#00000ee3</color> + <color name="i_am_color_ee4">#00000ee4</color> + <color name="i_am_color_ee5">#00000ee5</color> + <color name="i_am_color_ee6">#00000ee6</color> + <color name="i_am_color_ee7">#00000ee7</color> + <color name="i_am_color_ee8">#00000ee8</color> + <color name="i_am_color_ee9">#00000ee9</color> + <color name="i_am_color_eea">#00000eea</color> + <color name="i_am_color_eeb">#00000eeb</color> + <color name="i_am_color_eec">#00000eec</color> + <color name="i_am_color_eed">#00000eed</color> + <color name="i_am_color_eee">#00000eee</color> + <color name="i_am_color_eef">#00000eef</color> + <color name="i_am_color_ef0">#00000ef0</color> + <color name="i_am_color_ef1">#00000ef1</color> + <color name="i_am_color_ef2">#00000ef2</color> + <color name="i_am_color_ef3">#00000ef3</color> + <color name="i_am_color_ef4">#00000ef4</color> + <color name="i_am_color_ef5">#00000ef5</color> + <color name="i_am_color_ef6">#00000ef6</color> + <color name="i_am_color_ef7">#00000ef7</color> + <color name="i_am_color_ef8">#00000ef8</color> + <color name="i_am_color_ef9">#00000ef9</color> + <color name="i_am_color_efa">#00000efa</color> + <color name="i_am_color_efb">#00000efb</color> + <color name="i_am_color_efc">#00000efc</color> + <color name="i_am_color_efd">#00000efd</color> + <color name="i_am_color_efe">#00000efe</color> + <color name="i_am_color_eff">#00000eff</color> + <color name="i_am_color_f00">#00000f00</color> + <color name="i_am_color_f01">#00000f01</color> + <color name="i_am_color_f02">#00000f02</color> + <color name="i_am_color_f03">#00000f03</color> + <color name="i_am_color_f04">#00000f04</color> + <color name="i_am_color_f05">#00000f05</color> + <color name="i_am_color_f06">#00000f06</color> + <color name="i_am_color_f07">#00000f07</color> + <color name="i_am_color_f08">#00000f08</color> + <color name="i_am_color_f09">#00000f09</color> + <color name="i_am_color_f0a">#00000f0a</color> + <color name="i_am_color_f0b">#00000f0b</color> + <color name="i_am_color_f0c">#00000f0c</color> + <color name="i_am_color_f0d">#00000f0d</color> + <color name="i_am_color_f0e">#00000f0e</color> + <color name="i_am_color_f0f">#00000f0f</color> + <color name="i_am_color_f10">#00000f10</color> + <color name="i_am_color_f11">#00000f11</color> + <color name="i_am_color_f12">#00000f12</color> + <color name="i_am_color_f13">#00000f13</color> + <color name="i_am_color_f14">#00000f14</color> + <color name="i_am_color_f15">#00000f15</color> + <color name="i_am_color_f16">#00000f16</color> + <color name="i_am_color_f17">#00000f17</color> + <color name="i_am_color_f18">#00000f18</color> + <color name="i_am_color_f19">#00000f19</color> + <color name="i_am_color_f1a">#00000f1a</color> + <color name="i_am_color_f1b">#00000f1b</color> + <color name="i_am_color_f1c">#00000f1c</color> + <color name="i_am_color_f1d">#00000f1d</color> + <color name="i_am_color_f1e">#00000f1e</color> + <color name="i_am_color_f1f">#00000f1f</color> + <color name="i_am_color_f20">#00000f20</color> + <color name="i_am_color_f21">#00000f21</color> + <color name="i_am_color_f22">#00000f22</color> + <color name="i_am_color_f23">#00000f23</color> + <color name="i_am_color_f24">#00000f24</color> + <color name="i_am_color_f25">#00000f25</color> + <color name="i_am_color_f26">#00000f26</color> + <color name="i_am_color_f27">#00000f27</color> + <color name="i_am_color_f28">#00000f28</color> + <color name="i_am_color_f29">#00000f29</color> + <color name="i_am_color_f2a">#00000f2a</color> + <color name="i_am_color_f2b">#00000f2b</color> + <color name="i_am_color_f2c">#00000f2c</color> + <color name="i_am_color_f2d">#00000f2d</color> + <color name="i_am_color_f2e">#00000f2e</color> + <color name="i_am_color_f2f">#00000f2f</color> + <color name="i_am_color_f30">#00000f30</color> + <color name="i_am_color_f31">#00000f31</color> + <color name="i_am_color_f32">#00000f32</color> + <color name="i_am_color_f33">#00000f33</color> + <color name="i_am_color_f34">#00000f34</color> + <color name="i_am_color_f35">#00000f35</color> + <color name="i_am_color_f36">#00000f36</color> + <color name="i_am_color_f37">#00000f37</color> + <color name="i_am_color_f38">#00000f38</color> + <color name="i_am_color_f39">#00000f39</color> + <color name="i_am_color_f3a">#00000f3a</color> + <color name="i_am_color_f3b">#00000f3b</color> + <color name="i_am_color_f3c">#00000f3c</color> + <color name="i_am_color_f3d">#00000f3d</color> + <color name="i_am_color_f3e">#00000f3e</color> + <color name="i_am_color_f3f">#00000f3f</color> + <color name="i_am_color_f40">#00000f40</color> + <color name="i_am_color_f41">#00000f41</color> + <color name="i_am_color_f42">#00000f42</color> + <color name="i_am_color_f43">#00000f43</color> + <color name="i_am_color_f44">#00000f44</color> + <color name="i_am_color_f45">#00000f45</color> + <color name="i_am_color_f46">#00000f46</color> + <color name="i_am_color_f47">#00000f47</color> + <color name="i_am_color_f48">#00000f48</color> + <color name="i_am_color_f49">#00000f49</color> + <color name="i_am_color_f4a">#00000f4a</color> + <color name="i_am_color_f4b">#00000f4b</color> + <color name="i_am_color_f4c">#00000f4c</color> + <color name="i_am_color_f4d">#00000f4d</color> + <color name="i_am_color_f4e">#00000f4e</color> + <color name="i_am_color_f4f">#00000f4f</color> + <color name="i_am_color_f50">#00000f50</color> + <color name="i_am_color_f51">#00000f51</color> + <color name="i_am_color_f52">#00000f52</color> + <color name="i_am_color_f53">#00000f53</color> + <color name="i_am_color_f54">#00000f54</color> + <color name="i_am_color_f55">#00000f55</color> + <color name="i_am_color_f56">#00000f56</color> + <color name="i_am_color_f57">#00000f57</color> + <color name="i_am_color_f58">#00000f58</color> + <color name="i_am_color_f59">#00000f59</color> + <color name="i_am_color_f5a">#00000f5a</color> + <color name="i_am_color_f5b">#00000f5b</color> + <color name="i_am_color_f5c">#00000f5c</color> + <color name="i_am_color_f5d">#00000f5d</color> + <color name="i_am_color_f5e">#00000f5e</color> + <color name="i_am_color_f5f">#00000f5f</color> + <color name="i_am_color_f60">#00000f60</color> + <color name="i_am_color_f61">#00000f61</color> + <color name="i_am_color_f62">#00000f62</color> + <color name="i_am_color_f63">#00000f63</color> + <color name="i_am_color_f64">#00000f64</color> + <color name="i_am_color_f65">#00000f65</color> + <color name="i_am_color_f66">#00000f66</color> + <color name="i_am_color_f67">#00000f67</color> + <color name="i_am_color_f68">#00000f68</color> + <color name="i_am_color_f69">#00000f69</color> + <color name="i_am_color_f6a">#00000f6a</color> + <color name="i_am_color_f6b">#00000f6b</color> + <color name="i_am_color_f6c">#00000f6c</color> + <color name="i_am_color_f6d">#00000f6d</color> + <color name="i_am_color_f6e">#00000f6e</color> + <color name="i_am_color_f6f">#00000f6f</color> + <color name="i_am_color_f70">#00000f70</color> + <color name="i_am_color_f71">#00000f71</color> + <color name="i_am_color_f72">#00000f72</color> + <color name="i_am_color_f73">#00000f73</color> + <color name="i_am_color_f74">#00000f74</color> + <color name="i_am_color_f75">#00000f75</color> + <color name="i_am_color_f76">#00000f76</color> + <color name="i_am_color_f77">#00000f77</color> + <color name="i_am_color_f78">#00000f78</color> + <color name="i_am_color_f79">#00000f79</color> + <color name="i_am_color_f7a">#00000f7a</color> + <color name="i_am_color_f7b">#00000f7b</color> + <color name="i_am_color_f7c">#00000f7c</color> + <color name="i_am_color_f7d">#00000f7d</color> + <color name="i_am_color_f7e">#00000f7e</color> + <color name="i_am_color_f7f">#00000f7f</color> + <color name="i_am_color_f80">#00000f80</color> + <color name="i_am_color_f81">#00000f81</color> + <color name="i_am_color_f82">#00000f82</color> + <color name="i_am_color_f83">#00000f83</color> + <color name="i_am_color_f84">#00000f84</color> + <color name="i_am_color_f85">#00000f85</color> + <color name="i_am_color_f86">#00000f86</color> + <color name="i_am_color_f87">#00000f87</color> + <color name="i_am_color_f88">#00000f88</color> + <color name="i_am_color_f89">#00000f89</color> + <color name="i_am_color_f8a">#00000f8a</color> + <color name="i_am_color_f8b">#00000f8b</color> + <color name="i_am_color_f8c">#00000f8c</color> + <color name="i_am_color_f8d">#00000f8d</color> + <color name="i_am_color_f8e">#00000f8e</color> + <color name="i_am_color_f8f">#00000f8f</color> + <color name="i_am_color_f90">#00000f90</color> + <color name="i_am_color_f91">#00000f91</color> + <color name="i_am_color_f92">#00000f92</color> + <color name="i_am_color_f93">#00000f93</color> + <color name="i_am_color_f94">#00000f94</color> + <color name="i_am_color_f95">#00000f95</color> + <color name="i_am_color_f96">#00000f96</color> + <color name="i_am_color_f97">#00000f97</color> + <color name="i_am_color_f98">#00000f98</color> + <color name="i_am_color_f99">#00000f99</color> + <color name="i_am_color_f9a">#00000f9a</color> + <color name="i_am_color_f9b">#00000f9b</color> + <color name="i_am_color_f9c">#00000f9c</color> + <color name="i_am_color_f9d">#00000f9d</color> + <color name="i_am_color_f9e">#00000f9e</color> + <color name="i_am_color_f9f">#00000f9f</color> + <color name="i_am_color_fa0">#00000fa0</color> + <color name="i_am_color_fa1">#00000fa1</color> + <color name="i_am_color_fa2">#00000fa2</color> + <color name="i_am_color_fa3">#00000fa3</color> + <color name="i_am_color_fa4">#00000fa4</color> + <color name="i_am_color_fa5">#00000fa5</color> + <color name="i_am_color_fa6">#00000fa6</color> + <color name="i_am_color_fa7">#00000fa7</color> + <color name="i_am_color_fa8">#00000fa8</color> + <color name="i_am_color_fa9">#00000fa9</color> + <color name="i_am_color_faa">#00000faa</color> + <color name="i_am_color_fab">#00000fab</color> + <color name="i_am_color_fac">#00000fac</color> + <color name="i_am_color_fad">#00000fad</color> + <color name="i_am_color_fae">#00000fae</color> + <color name="i_am_color_faf">#00000faf</color> + <color name="i_am_color_fb0">#00000fb0</color> + <color name="i_am_color_fb1">#00000fb1</color> + <color name="i_am_color_fb2">#00000fb2</color> + <color name="i_am_color_fb3">#00000fb3</color> + <color name="i_am_color_fb4">#00000fb4</color> + <color name="i_am_color_fb5">#00000fb5</color> + <color name="i_am_color_fb6">#00000fb6</color> + <color name="i_am_color_fb7">#00000fb7</color> + <color name="i_am_color_fb8">#00000fb8</color> + <color name="i_am_color_fb9">#00000fb9</color> + <color name="i_am_color_fba">#00000fba</color> + <color name="i_am_color_fbb">#00000fbb</color> + <color name="i_am_color_fbc">#00000fbc</color> + <color name="i_am_color_fbd">#00000fbd</color> + <color name="i_am_color_fbe">#00000fbe</color> + <color name="i_am_color_fbf">#00000fbf</color> + <color name="i_am_color_fc0">#00000fc0</color> + <color name="i_am_color_fc1">#00000fc1</color> + <color name="i_am_color_fc2">#00000fc2</color> + <color name="i_am_color_fc3">#00000fc3</color> + <color name="i_am_color_fc4">#00000fc4</color> + <color name="i_am_color_fc5">#00000fc5</color> + <color name="i_am_color_fc6">#00000fc6</color> + <color name="i_am_color_fc7">#00000fc7</color> + <color name="i_am_color_fc8">#00000fc8</color> + <color name="i_am_color_fc9">#00000fc9</color> + <color name="i_am_color_fca">#00000fca</color> + <color name="i_am_color_fcb">#00000fcb</color> + <color name="i_am_color_fcc">#00000fcc</color> + <color name="i_am_color_fcd">#00000fcd</color> + <color name="i_am_color_fce">#00000fce</color> + <color name="i_am_color_fcf">#00000fcf</color> + <color name="i_am_color_fd0">#00000fd0</color> + <color name="i_am_color_fd1">#00000fd1</color> + <color name="i_am_color_fd2">#00000fd2</color> + <color name="i_am_color_fd3">#00000fd3</color> + <color name="i_am_color_fd4">#00000fd4</color> + <color name="i_am_color_fd5">#00000fd5</color> + <color name="i_am_color_fd6">#00000fd6</color> + <color name="i_am_color_fd7">#00000fd7</color> + <color name="i_am_color_fd8">#00000fd8</color> + <color name="i_am_color_fd9">#00000fd9</color> + <color name="i_am_color_fda">#00000fda</color> + <color name="i_am_color_fdb">#00000fdb</color> + <color name="i_am_color_fdc">#00000fdc</color> + <color name="i_am_color_fdd">#00000fdd</color> + <color name="i_am_color_fde">#00000fde</color> + <color name="i_am_color_fdf">#00000fdf</color> + <color name="i_am_color_fe0">#00000fe0</color> + <color name="i_am_color_fe1">#00000fe1</color> + <color name="i_am_color_fe2">#00000fe2</color> + <color name="i_am_color_fe3">#00000fe3</color> + <color name="i_am_color_fe4">#00000fe4</color> + <color name="i_am_color_fe5">#00000fe5</color> + <color name="i_am_color_fe6">#00000fe6</color> + <color name="i_am_color_fe7">#00000fe7</color> + <color name="i_am_color_fe8">#00000fe8</color> + <color name="i_am_color_fe9">#00000fe9</color> + <color name="i_am_color_fea">#00000fea</color> + <color name="i_am_color_feb">#00000feb</color> + <color name="i_am_color_fec">#00000fec</color> + <color name="i_am_color_fed">#00000fed</color> + <color name="i_am_color_fee">#00000fee</color> + <color name="i_am_color_fef">#00000fef</color> + <color name="i_am_color_ff0">#00000ff0</color> + <color name="i_am_color_ff1">#00000ff1</color> + <color name="i_am_color_ff2">#00000ff2</color> + <color name="i_am_color_ff3">#00000ff3</color> + <color name="i_am_color_ff4">#00000ff4</color> + <color name="i_am_color_ff5">#00000ff5</color> + <color name="i_am_color_ff6">#00000ff6</color> + <color name="i_am_color_ff7">#00000ff7</color> + <color name="i_am_color_ff8">#00000ff8</color> + <color name="i_am_color_ff9">#00000ff9</color> + <color name="i_am_color_ffa">#00000ffa</color> + <color name="i_am_color_ffb">#00000ffb</color> + <color name="i_am_color_ffc">#00000ffc</color> + <color name="i_am_color_ffd">#00000ffd</color> + <color name="i_am_color_ffe">#00000ffe</color> + <color name="i_am_color_fff">#00000fff</color> + <color name="i_am_color_1000">#00001000</color> + <color name="i_am_color_1001">#00001001</color> + <color name="i_am_color_1002">#00001002</color> + <color name="i_am_color_1003">#00001003</color> + <color name="i_am_color_1004">#00001004</color> + <color name="i_am_color_1005">#00001005</color> + <color name="i_am_color_1006">#00001006</color> + <color name="i_am_color_1007">#00001007</color> + <color name="i_am_color_1008">#00001008</color> + <color name="i_am_color_1009">#00001009</color> + <color name="i_am_color_100a">#0000100a</color> + <color name="i_am_color_100b">#0000100b</color> + <color name="i_am_color_100c">#0000100c</color> + <color name="i_am_color_100d">#0000100d</color> + <color name="i_am_color_100e">#0000100e</color> + <color name="i_am_color_100f">#0000100f</color> + <color name="i_am_color_1010">#00001010</color> + <color name="i_am_color_1011">#00001011</color> + <color name="i_am_color_1012">#00001012</color> + <color name="i_am_color_1013">#00001013</color> + <color name="i_am_color_1014">#00001014</color> + <color name="i_am_color_1015">#00001015</color> + <color name="i_am_color_1016">#00001016</color> + <color name="i_am_color_1017">#00001017</color> + <color name="i_am_color_1018">#00001018</color> + <color name="i_am_color_1019">#00001019</color> + <color name="i_am_color_101a">#0000101a</color> + <color name="i_am_color_101b">#0000101b</color> + <color name="i_am_color_101c">#0000101c</color> + <color name="i_am_color_101d">#0000101d</color> + <color name="i_am_color_101e">#0000101e</color> + <color name="i_am_color_101f">#0000101f</color> + <color name="i_am_color_1020">#00001020</color> + <color name="i_am_color_1021">#00001021</color> + <color name="i_am_color_1022">#00001022</color> + <color name="i_am_color_1023">#00001023</color> + <color name="i_am_color_1024">#00001024</color> + <color name="i_am_color_1025">#00001025</color> + <color name="i_am_color_1026">#00001026</color> + <color name="i_am_color_1027">#00001027</color> + <color name="i_am_color_1028">#00001028</color> + <color name="i_am_color_1029">#00001029</color> + <color name="i_am_color_102a">#0000102a</color> + <color name="i_am_color_102b">#0000102b</color> + <color name="i_am_color_102c">#0000102c</color> + <color name="i_am_color_102d">#0000102d</color> + <color name="i_am_color_102e">#0000102e</color> + <color name="i_am_color_102f">#0000102f</color> + <color name="i_am_color_1030">#00001030</color> + <color name="i_am_color_1031">#00001031</color> + <color name="i_am_color_1032">#00001032</color> + <color name="i_am_color_1033">#00001033</color> + <color name="i_am_color_1034">#00001034</color> + <color name="i_am_color_1035">#00001035</color> + <color name="i_am_color_1036">#00001036</color> + <color name="i_am_color_1037">#00001037</color> + <color name="i_am_color_1038">#00001038</color> + <color name="i_am_color_1039">#00001039</color> + <color name="i_am_color_103a">#0000103a</color> + <color name="i_am_color_103b">#0000103b</color> + <color name="i_am_color_103c">#0000103c</color> + <color name="i_am_color_103d">#0000103d</color> + <color name="i_am_color_103e">#0000103e</color> + <color name="i_am_color_103f">#0000103f</color> + <color name="i_am_color_1040">#00001040</color> + <color name="i_am_color_1041">#00001041</color> + <color name="i_am_color_1042">#00001042</color> + <color name="i_am_color_1043">#00001043</color> + <color name="i_am_color_1044">#00001044</color> + <color name="i_am_color_1045">#00001045</color> + <color name="i_am_color_1046">#00001046</color> + <color name="i_am_color_1047">#00001047</color> + <color name="i_am_color_1048">#00001048</color> + <color name="i_am_color_1049">#00001049</color> + <color name="i_am_color_104a">#0000104a</color> + <color name="i_am_color_104b">#0000104b</color> + <color name="i_am_color_104c">#0000104c</color> + <color name="i_am_color_104d">#0000104d</color> + <color name="i_am_color_104e">#0000104e</color> + <color name="i_am_color_104f">#0000104f</color> + <color name="i_am_color_1050">#00001050</color> + <color name="i_am_color_1051">#00001051</color> + <color name="i_am_color_1052">#00001052</color> + <color name="i_am_color_1053">#00001053</color> + <color name="i_am_color_1054">#00001054</color> + <color name="i_am_color_1055">#00001055</color> + <color name="i_am_color_1056">#00001056</color> + <color name="i_am_color_1057">#00001057</color> + <color name="i_am_color_1058">#00001058</color> + <color name="i_am_color_1059">#00001059</color> + <color name="i_am_color_105a">#0000105a</color> + <color name="i_am_color_105b">#0000105b</color> + <color name="i_am_color_105c">#0000105c</color> + <color name="i_am_color_105d">#0000105d</color> + <color name="i_am_color_105e">#0000105e</color> + <color name="i_am_color_105f">#0000105f</color> + <color name="i_am_color_1060">#00001060</color> + <color name="i_am_color_1061">#00001061</color> + <color name="i_am_color_1062">#00001062</color> + <color name="i_am_color_1063">#00001063</color> + <color name="i_am_color_1064">#00001064</color> + <color name="i_am_color_1065">#00001065</color> + <color name="i_am_color_1066">#00001066</color> + <color name="i_am_color_1067">#00001067</color> + <color name="i_am_color_1068">#00001068</color> + <color name="i_am_color_1069">#00001069</color> + <color name="i_am_color_106a">#0000106a</color> + <color name="i_am_color_106b">#0000106b</color> + <color name="i_am_color_106c">#0000106c</color> + <color name="i_am_color_106d">#0000106d</color> + <color name="i_am_color_106e">#0000106e</color> + <color name="i_am_color_106f">#0000106f</color> + <color name="i_am_color_1070">#00001070</color> + <color name="i_am_color_1071">#00001071</color> + <color name="i_am_color_1072">#00001072</color> + <color name="i_am_color_1073">#00001073</color> + <color name="i_am_color_1074">#00001074</color> + <color name="i_am_color_1075">#00001075</color> + <color name="i_am_color_1076">#00001076</color> + <color name="i_am_color_1077">#00001077</color> + <color name="i_am_color_1078">#00001078</color> + <color name="i_am_color_1079">#00001079</color> + <color name="i_am_color_107a">#0000107a</color> + <color name="i_am_color_107b">#0000107b</color> + <color name="i_am_color_107c">#0000107c</color> + <color name="i_am_color_107d">#0000107d</color> + <color name="i_am_color_107e">#0000107e</color> + <color name="i_am_color_107f">#0000107f</color> + <color name="i_am_color_1080">#00001080</color> + <color name="i_am_color_1081">#00001081</color> + <color name="i_am_color_1082">#00001082</color> + <color name="i_am_color_1083">#00001083</color> + <color name="i_am_color_1084">#00001084</color> + <color name="i_am_color_1085">#00001085</color> + <color name="i_am_color_1086">#00001086</color> + <color name="i_am_color_1087">#00001087</color> + <color name="i_am_color_1088">#00001088</color> + <color name="i_am_color_1089">#00001089</color> + <color name="i_am_color_108a">#0000108a</color> + <color name="i_am_color_108b">#0000108b</color> + <color name="i_am_color_108c">#0000108c</color> + <color name="i_am_color_108d">#0000108d</color> + <color name="i_am_color_108e">#0000108e</color> + <color name="i_am_color_108f">#0000108f</color> + <color name="i_am_color_1090">#00001090</color> + <color name="i_am_color_1091">#00001091</color> + <color name="i_am_color_1092">#00001092</color> + <color name="i_am_color_1093">#00001093</color> + <color name="i_am_color_1094">#00001094</color> + <color name="i_am_color_1095">#00001095</color> + <color name="i_am_color_1096">#00001096</color> + <color name="i_am_color_1097">#00001097</color> + <color name="i_am_color_1098">#00001098</color> + <color name="i_am_color_1099">#00001099</color> + <color name="i_am_color_109a">#0000109a</color> + <color name="i_am_color_109b">#0000109b</color> + <color name="i_am_color_109c">#0000109c</color> + <color name="i_am_color_109d">#0000109d</color> + <color name="i_am_color_109e">#0000109e</color> + <color name="i_am_color_109f">#0000109f</color> + <color name="i_am_color_10a0">#000010a0</color> + <color name="i_am_color_10a1">#000010a1</color> + <color name="i_am_color_10a2">#000010a2</color> + <color name="i_am_color_10a3">#000010a3</color> + <color name="i_am_color_10a4">#000010a4</color> + <color name="i_am_color_10a5">#000010a5</color> + <color name="i_am_color_10a6">#000010a6</color> + <color name="i_am_color_10a7">#000010a7</color> + <color name="i_am_color_10a8">#000010a8</color> + <color name="i_am_color_10a9">#000010a9</color> + <color name="i_am_color_10aa">#000010aa</color> + <color name="i_am_color_10ab">#000010ab</color> + <color name="i_am_color_10ac">#000010ac</color> + <color name="i_am_color_10ad">#000010ad</color> + <color name="i_am_color_10ae">#000010ae</color> + <color name="i_am_color_10af">#000010af</color> + <color name="i_am_color_10b0">#000010b0</color> + <color name="i_am_color_10b1">#000010b1</color> + <color name="i_am_color_10b2">#000010b2</color> + <color name="i_am_color_10b3">#000010b3</color> + <color name="i_am_color_10b4">#000010b4</color> + <color name="i_am_color_10b5">#000010b5</color> + <color name="i_am_color_10b6">#000010b6</color> + <color name="i_am_color_10b7">#000010b7</color> + <color name="i_am_color_10b8">#000010b8</color> + <color name="i_am_color_10b9">#000010b9</color> + <color name="i_am_color_10ba">#000010ba</color> + <color name="i_am_color_10bb">#000010bb</color> + <color name="i_am_color_10bc">#000010bc</color> + <color name="i_am_color_10bd">#000010bd</color> + <color name="i_am_color_10be">#000010be</color> + <color name="i_am_color_10bf">#000010bf</color> + <color name="i_am_color_10c0">#000010c0</color> + <color name="i_am_color_10c1">#000010c1</color> + <color name="i_am_color_10c2">#000010c2</color> + <color name="i_am_color_10c3">#000010c3</color> + <color name="i_am_color_10c4">#000010c4</color> + <color name="i_am_color_10c5">#000010c5</color> + <color name="i_am_color_10c6">#000010c6</color> + <color name="i_am_color_10c7">#000010c7</color> + <color name="i_am_color_10c8">#000010c8</color> + <color name="i_am_color_10c9">#000010c9</color> + <color name="i_am_color_10ca">#000010ca</color> + <color name="i_am_color_10cb">#000010cb</color> + <color name="i_am_color_10cc">#000010cc</color> + <color name="i_am_color_10cd">#000010cd</color> + <color name="i_am_color_10ce">#000010ce</color> + <color name="i_am_color_10cf">#000010cf</color> + <color name="i_am_color_10d0">#000010d0</color> + <color name="i_am_color_10d1">#000010d1</color> + <color name="i_am_color_10d2">#000010d2</color> + <color name="i_am_color_10d3">#000010d3</color> + <color name="i_am_color_10d4">#000010d4</color> + <color name="i_am_color_10d5">#000010d5</color> + <color name="i_am_color_10d6">#000010d6</color> + <color name="i_am_color_10d7">#000010d7</color> + <color name="i_am_color_10d8">#000010d8</color> + <color name="i_am_color_10d9">#000010d9</color> + <color name="i_am_color_10da">#000010da</color> + <color name="i_am_color_10db">#000010db</color> + <color name="i_am_color_10dc">#000010dc</color> + <color name="i_am_color_10dd">#000010dd</color> + <color name="i_am_color_10de">#000010de</color> + <color name="i_am_color_10df">#000010df</color> + <color name="i_am_color_10e0">#000010e0</color> + <color name="i_am_color_10e1">#000010e1</color> + <color name="i_am_color_10e2">#000010e2</color> + <color name="i_am_color_10e3">#000010e3</color> + <color name="i_am_color_10e4">#000010e4</color> + <color name="i_am_color_10e5">#000010e5</color> + <color name="i_am_color_10e6">#000010e6</color> + <color name="i_am_color_10e7">#000010e7</color> + <color name="i_am_color_10e8">#000010e8</color> + <color name="i_am_color_10e9">#000010e9</color> + <color name="i_am_color_10ea">#000010ea</color> + <color name="i_am_color_10eb">#000010eb</color> + <color name="i_am_color_10ec">#000010ec</color> + <color name="i_am_color_10ed">#000010ed</color> + <color name="i_am_color_10ee">#000010ee</color> + <color name="i_am_color_10ef">#000010ef</color> + <color name="i_am_color_10f0">#000010f0</color> + <color name="i_am_color_10f1">#000010f1</color> + <color name="i_am_color_10f2">#000010f2</color> + <color name="i_am_color_10f3">#000010f3</color> + <color name="i_am_color_10f4">#000010f4</color> + <color name="i_am_color_10f5">#000010f5</color> + <color name="i_am_color_10f6">#000010f6</color> + <color name="i_am_color_10f7">#000010f7</color> + <color name="i_am_color_10f8">#000010f8</color> + <color name="i_am_color_10f9">#000010f9</color> + <color name="i_am_color_10fa">#000010fa</color> + <color name="i_am_color_10fb">#000010fb</color> + <color name="i_am_color_10fc">#000010fc</color> + <color name="i_am_color_10fd">#000010fd</color> + <color name="i_am_color_10fe">#000010fe</color> + <color name="i_am_color_10ff">#000010ff</color> + <color name="i_am_color_1100">#00001100</color> + <color name="i_am_color_1101">#00001101</color> + <color name="i_am_color_1102">#00001102</color> + <color name="i_am_color_1103">#00001103</color> + <color name="i_am_color_1104">#00001104</color> + <color name="i_am_color_1105">#00001105</color> + <color name="i_am_color_1106">#00001106</color> + <color name="i_am_color_1107">#00001107</color> + <color name="i_am_color_1108">#00001108</color> + <color name="i_am_color_1109">#00001109</color> + <color name="i_am_color_110a">#0000110a</color> + <color name="i_am_color_110b">#0000110b</color> + <color name="i_am_color_110c">#0000110c</color> + <color name="i_am_color_110d">#0000110d</color> + <color name="i_am_color_110e">#0000110e</color> + <color name="i_am_color_110f">#0000110f</color> + <color name="i_am_color_1110">#00001110</color> + <color name="i_am_color_1111">#00001111</color> + <color name="i_am_color_1112">#00001112</color> + <color name="i_am_color_1113">#00001113</color> + <color name="i_am_color_1114">#00001114</color> + <color name="i_am_color_1115">#00001115</color> + <color name="i_am_color_1116">#00001116</color> + <color name="i_am_color_1117">#00001117</color> + <color name="i_am_color_1118">#00001118</color> + <color name="i_am_color_1119">#00001119</color> + <color name="i_am_color_111a">#0000111a</color> + <color name="i_am_color_111b">#0000111b</color> + <color name="i_am_color_111c">#0000111c</color> + <color name="i_am_color_111d">#0000111d</color> + <color name="i_am_color_111e">#0000111e</color> + <color name="i_am_color_111f">#0000111f</color> + <color name="i_am_color_1120">#00001120</color> + <color name="i_am_color_1121">#00001121</color> + <color name="i_am_color_1122">#00001122</color> + <color name="i_am_color_1123">#00001123</color> + <color name="i_am_color_1124">#00001124</color> + <color name="i_am_color_1125">#00001125</color> + <color name="i_am_color_1126">#00001126</color> + <color name="i_am_color_1127">#00001127</color> + <color name="i_am_color_1128">#00001128</color> + <color name="i_am_color_1129">#00001129</color> + <color name="i_am_color_112a">#0000112a</color> + <color name="i_am_color_112b">#0000112b</color> + <color name="i_am_color_112c">#0000112c</color> + <color name="i_am_color_112d">#0000112d</color> + <color name="i_am_color_112e">#0000112e</color> + <color name="i_am_color_112f">#0000112f</color> + <color name="i_am_color_1130">#00001130</color> + <color name="i_am_color_1131">#00001131</color> + <color name="i_am_color_1132">#00001132</color> + <color name="i_am_color_1133">#00001133</color> + <color name="i_am_color_1134">#00001134</color> + <color name="i_am_color_1135">#00001135</color> + <color name="i_am_color_1136">#00001136</color> + <color name="i_am_color_1137">#00001137</color> + <color name="i_am_color_1138">#00001138</color> + <color name="i_am_color_1139">#00001139</color> + <color name="i_am_color_113a">#0000113a</color> + <color name="i_am_color_113b">#0000113b</color> + <color name="i_am_color_113c">#0000113c</color> + <color name="i_am_color_113d">#0000113d</color> + <color name="i_am_color_113e">#0000113e</color> + <color name="i_am_color_113f">#0000113f</color> + <color name="i_am_color_1140">#00001140</color> + <color name="i_am_color_1141">#00001141</color> + <color name="i_am_color_1142">#00001142</color> + <color name="i_am_color_1143">#00001143</color> + <color name="i_am_color_1144">#00001144</color> + <color name="i_am_color_1145">#00001145</color> + <color name="i_am_color_1146">#00001146</color> + <color name="i_am_color_1147">#00001147</color> + <color name="i_am_color_1148">#00001148</color> + <color name="i_am_color_1149">#00001149</color> + <color name="i_am_color_114a">#0000114a</color> + <color name="i_am_color_114b">#0000114b</color> + <color name="i_am_color_114c">#0000114c</color> + <color name="i_am_color_114d">#0000114d</color> + <color name="i_am_color_114e">#0000114e</color> + <color name="i_am_color_114f">#0000114f</color> + <color name="i_am_color_1150">#00001150</color> + <color name="i_am_color_1151">#00001151</color> + <color name="i_am_color_1152">#00001152</color> + <color name="i_am_color_1153">#00001153</color> + <color name="i_am_color_1154">#00001154</color> + <color name="i_am_color_1155">#00001155</color> + <color name="i_am_color_1156">#00001156</color> + <color name="i_am_color_1157">#00001157</color> + <color name="i_am_color_1158">#00001158</color> + <color name="i_am_color_1159">#00001159</color> + <color name="i_am_color_115a">#0000115a</color> + <color name="i_am_color_115b">#0000115b</color> + <color name="i_am_color_115c">#0000115c</color> + <color name="i_am_color_115d">#0000115d</color> + <color name="i_am_color_115e">#0000115e</color> + <color name="i_am_color_115f">#0000115f</color> + <color name="i_am_color_1160">#00001160</color> + <color name="i_am_color_1161">#00001161</color> + <color name="i_am_color_1162">#00001162</color> + <color name="i_am_color_1163">#00001163</color> + <color name="i_am_color_1164">#00001164</color> + <color name="i_am_color_1165">#00001165</color> + <color name="i_am_color_1166">#00001166</color> + <color name="i_am_color_1167">#00001167</color> + <color name="i_am_color_1168">#00001168</color> + <color name="i_am_color_1169">#00001169</color> + <color name="i_am_color_116a">#0000116a</color> + <color name="i_am_color_116b">#0000116b</color> + <color name="i_am_color_116c">#0000116c</color> + <color name="i_am_color_116d">#0000116d</color> + <color name="i_am_color_116e">#0000116e</color> + <color name="i_am_color_116f">#0000116f</color> + <color name="i_am_color_1170">#00001170</color> + <color name="i_am_color_1171">#00001171</color> + <color name="i_am_color_1172">#00001172</color> + <color name="i_am_color_1173">#00001173</color> + <color name="i_am_color_1174">#00001174</color> + <color name="i_am_color_1175">#00001175</color> + <color name="i_am_color_1176">#00001176</color> + <color name="i_am_color_1177">#00001177</color> + <color name="i_am_color_1178">#00001178</color> + <color name="i_am_color_1179">#00001179</color> + <color name="i_am_color_117a">#0000117a</color> + <color name="i_am_color_117b">#0000117b</color> + <color name="i_am_color_117c">#0000117c</color> + <color name="i_am_color_117d">#0000117d</color> + <color name="i_am_color_117e">#0000117e</color> + <color name="i_am_color_117f">#0000117f</color> + <color name="i_am_color_1180">#00001180</color> + <color name="i_am_color_1181">#00001181</color> + <color name="i_am_color_1182">#00001182</color> + <color name="i_am_color_1183">#00001183</color> + <color name="i_am_color_1184">#00001184</color> + <color name="i_am_color_1185">#00001185</color> + <color name="i_am_color_1186">#00001186</color> + <color name="i_am_color_1187">#00001187</color> + <color name="i_am_color_1188">#00001188</color> + <color name="i_am_color_1189">#00001189</color> + <color name="i_am_color_118a">#0000118a</color> + <color name="i_am_color_118b">#0000118b</color> + <color name="i_am_color_118c">#0000118c</color> + <color name="i_am_color_118d">#0000118d</color> + <color name="i_am_color_118e">#0000118e</color> + <color name="i_am_color_118f">#0000118f</color> + <color name="i_am_color_1190">#00001190</color> + <color name="i_am_color_1191">#00001191</color> + <color name="i_am_color_1192">#00001192</color> + <color name="i_am_color_1193">#00001193</color> + <color name="i_am_color_1194">#00001194</color> + <color name="i_am_color_1195">#00001195</color> + <color name="i_am_color_1196">#00001196</color> + <color name="i_am_color_1197">#00001197</color> + <color name="i_am_color_1198">#00001198</color> + <color name="i_am_color_1199">#00001199</color> + <color name="i_am_color_119a">#0000119a</color> + <color name="i_am_color_119b">#0000119b</color> + <color name="i_am_color_119c">#0000119c</color> + <color name="i_am_color_119d">#0000119d</color> + <color name="i_am_color_119e">#0000119e</color> + <color name="i_am_color_119f">#0000119f</color> + <color name="i_am_color_11a0">#000011a0</color> + <color name="i_am_color_11a1">#000011a1</color> + <color name="i_am_color_11a2">#000011a2</color> + <color name="i_am_color_11a3">#000011a3</color> + <color name="i_am_color_11a4">#000011a4</color> + <color name="i_am_color_11a5">#000011a5</color> + <color name="i_am_color_11a6">#000011a6</color> + <color name="i_am_color_11a7">#000011a7</color> + <color name="i_am_color_11a8">#000011a8</color> + <color name="i_am_color_11a9">#000011a9</color> + <color name="i_am_color_11aa">#000011aa</color> + <color name="i_am_color_11ab">#000011ab</color> + <color name="i_am_color_11ac">#000011ac</color> + <color name="i_am_color_11ad">#000011ad</color> + <color name="i_am_color_11ae">#000011ae</color> + <color name="i_am_color_11af">#000011af</color> + <color name="i_am_color_11b0">#000011b0</color> + <color name="i_am_color_11b1">#000011b1</color> + <color name="i_am_color_11b2">#000011b2</color> + <color name="i_am_color_11b3">#000011b3</color> + <color name="i_am_color_11b4">#000011b4</color> + <color name="i_am_color_11b5">#000011b5</color> + <color name="i_am_color_11b6">#000011b6</color> + <color name="i_am_color_11b7">#000011b7</color> + <color name="i_am_color_11b8">#000011b8</color> + <color name="i_am_color_11b9">#000011b9</color> + <color name="i_am_color_11ba">#000011ba</color> + <color name="i_am_color_11bb">#000011bb</color> + <color name="i_am_color_11bc">#000011bc</color> + <color name="i_am_color_11bd">#000011bd</color> + <color name="i_am_color_11be">#000011be</color> + <color name="i_am_color_11bf">#000011bf</color> + <color name="i_am_color_11c0">#000011c0</color> + <color name="i_am_color_11c1">#000011c1</color> + <color name="i_am_color_11c2">#000011c2</color> + <color name="i_am_color_11c3">#000011c3</color> + <color name="i_am_color_11c4">#000011c4</color> + <color name="i_am_color_11c5">#000011c5</color> + <color name="i_am_color_11c6">#000011c6</color> + <color name="i_am_color_11c7">#000011c7</color> + <color name="i_am_color_11c8">#000011c8</color> + <color name="i_am_color_11c9">#000011c9</color> + <color name="i_am_color_11ca">#000011ca</color> + <color name="i_am_color_11cb">#000011cb</color> + <color name="i_am_color_11cc">#000011cc</color> + <color name="i_am_color_11cd">#000011cd</color> + <color name="i_am_color_11ce">#000011ce</color> + <color name="i_am_color_11cf">#000011cf</color> + <color name="i_am_color_11d0">#000011d0</color> + <color name="i_am_color_11d1">#000011d1</color> + <color name="i_am_color_11d2">#000011d2</color> + <color name="i_am_color_11d3">#000011d3</color> + <color name="i_am_color_11d4">#000011d4</color> + <color name="i_am_color_11d5">#000011d5</color> + <color name="i_am_color_11d6">#000011d6</color> + <color name="i_am_color_11d7">#000011d7</color> + <color name="i_am_color_11d8">#000011d8</color> + <color name="i_am_color_11d9">#000011d9</color> + <color name="i_am_color_11da">#000011da</color> + <color name="i_am_color_11db">#000011db</color> + <color name="i_am_color_11dc">#000011dc</color> + <color name="i_am_color_11dd">#000011dd</color> + <color name="i_am_color_11de">#000011de</color> + <color name="i_am_color_11df">#000011df</color> + <color name="i_am_color_11e0">#000011e0</color> + <color name="i_am_color_11e1">#000011e1</color> + <color name="i_am_color_11e2">#000011e2</color> + <color name="i_am_color_11e3">#000011e3</color> + <color name="i_am_color_11e4">#000011e4</color> + <color name="i_am_color_11e5">#000011e5</color> + <color name="i_am_color_11e6">#000011e6</color> + <color name="i_am_color_11e7">#000011e7</color> + <color name="i_am_color_11e8">#000011e8</color> + <color name="i_am_color_11e9">#000011e9</color> + <color name="i_am_color_11ea">#000011ea</color> + <color name="i_am_color_11eb">#000011eb</color> + <color name="i_am_color_11ec">#000011ec</color> + <color name="i_am_color_11ed">#000011ed</color> + <color name="i_am_color_11ee">#000011ee</color> + <color name="i_am_color_11ef">#000011ef</color> + <color name="i_am_color_11f0">#000011f0</color> + <color name="i_am_color_11f1">#000011f1</color> + <color name="i_am_color_11f2">#000011f2</color> + <color name="i_am_color_11f3">#000011f3</color> + <color name="i_am_color_11f4">#000011f4</color> + <color name="i_am_color_11f5">#000011f5</color> + <color name="i_am_color_11f6">#000011f6</color> + <color name="i_am_color_11f7">#000011f7</color> + <color name="i_am_color_11f8">#000011f8</color> + <color name="i_am_color_11f9">#000011f9</color> + <color name="i_am_color_11fa">#000011fa</color> + <color name="i_am_color_11fb">#000011fb</color> + <color name="i_am_color_11fc">#000011fc</color> + <color name="i_am_color_11fd">#000011fd</color> + <color name="i_am_color_11fe">#000011fe</color> + <color name="i_am_color_11ff">#000011ff</color> + <color name="i_am_color_1200">#00001200</color> + <color name="i_am_color_1201">#00001201</color> + <color name="i_am_color_1202">#00001202</color> + <color name="i_am_color_1203">#00001203</color> + <color name="i_am_color_1204">#00001204</color> + <color name="i_am_color_1205">#00001205</color> + <color name="i_am_color_1206">#00001206</color> + <color name="i_am_color_1207">#00001207</color> + <color name="i_am_color_1208">#00001208</color> + <color name="i_am_color_1209">#00001209</color> + <color name="i_am_color_120a">#0000120a</color> + <color name="i_am_color_120b">#0000120b</color> + <color name="i_am_color_120c">#0000120c</color> + <color name="i_am_color_120d">#0000120d</color> + <color name="i_am_color_120e">#0000120e</color> + <color name="i_am_color_120f">#0000120f</color> + <color name="i_am_color_1210">#00001210</color> + <color name="i_am_color_1211">#00001211</color> + <color name="i_am_color_1212">#00001212</color> + <color name="i_am_color_1213">#00001213</color> + <color name="i_am_color_1214">#00001214</color> + <color name="i_am_color_1215">#00001215</color> + <color name="i_am_color_1216">#00001216</color> + <color name="i_am_color_1217">#00001217</color> + <color name="i_am_color_1218">#00001218</color> + <color name="i_am_color_1219">#00001219</color> + <color name="i_am_color_121a">#0000121a</color> + <color name="i_am_color_121b">#0000121b</color> + <color name="i_am_color_121c">#0000121c</color> + <color name="i_am_color_121d">#0000121d</color> + <color name="i_am_color_121e">#0000121e</color> + <color name="i_am_color_121f">#0000121f</color> + <color name="i_am_color_1220">#00001220</color> + <color name="i_am_color_1221">#00001221</color> + <color name="i_am_color_1222">#00001222</color> + <color name="i_am_color_1223">#00001223</color> + <color name="i_am_color_1224">#00001224</color> + <color name="i_am_color_1225">#00001225</color> + <color name="i_am_color_1226">#00001226</color> + <color name="i_am_color_1227">#00001227</color> + <color name="i_am_color_1228">#00001228</color> + <color name="i_am_color_1229">#00001229</color> + <color name="i_am_color_122a">#0000122a</color> + <color name="i_am_color_122b">#0000122b</color> + <color name="i_am_color_122c">#0000122c</color> + <color name="i_am_color_122d">#0000122d</color> + <color name="i_am_color_122e">#0000122e</color> + <color name="i_am_color_122f">#0000122f</color> + <color name="i_am_color_1230">#00001230</color> + <color name="i_am_color_1231">#00001231</color> + <color name="i_am_color_1232">#00001232</color> + <color name="i_am_color_1233">#00001233</color> + <color name="i_am_color_1234">#00001234</color> + <color name="i_am_color_1235">#00001235</color> + <color name="i_am_color_1236">#00001236</color> + <color name="i_am_color_1237">#00001237</color> + <color name="i_am_color_1238">#00001238</color> + <color name="i_am_color_1239">#00001239</color> + <color name="i_am_color_123a">#0000123a</color> + <color name="i_am_color_123b">#0000123b</color> + <color name="i_am_color_123c">#0000123c</color> + <color name="i_am_color_123d">#0000123d</color> + <color name="i_am_color_123e">#0000123e</color> + <color name="i_am_color_123f">#0000123f</color> + <color name="i_am_color_1240">#00001240</color> + <color name="i_am_color_1241">#00001241</color> + <color name="i_am_color_1242">#00001242</color> + <color name="i_am_color_1243">#00001243</color> + <color name="i_am_color_1244">#00001244</color> + <color name="i_am_color_1245">#00001245</color> + <color name="i_am_color_1246">#00001246</color> + <color name="i_am_color_1247">#00001247</color> + <color name="i_am_color_1248">#00001248</color> + <color name="i_am_color_1249">#00001249</color> + <color name="i_am_color_124a">#0000124a</color> + <color name="i_am_color_124b">#0000124b</color> + <color name="i_am_color_124c">#0000124c</color> + <color name="i_am_color_124d">#0000124d</color> + <color name="i_am_color_124e">#0000124e</color> + <color name="i_am_color_124f">#0000124f</color> + <color name="i_am_color_1250">#00001250</color> + <color name="i_am_color_1251">#00001251</color> + <color name="i_am_color_1252">#00001252</color> + <color name="i_am_color_1253">#00001253</color> + <color name="i_am_color_1254">#00001254</color> + <color name="i_am_color_1255">#00001255</color> + <color name="i_am_color_1256">#00001256</color> + <color name="i_am_color_1257">#00001257</color> + <color name="i_am_color_1258">#00001258</color> + <color name="i_am_color_1259">#00001259</color> + <color name="i_am_color_125a">#0000125a</color> + <color name="i_am_color_125b">#0000125b</color> + <color name="i_am_color_125c">#0000125c</color> + <color name="i_am_color_125d">#0000125d</color> + <color name="i_am_color_125e">#0000125e</color> + <color name="i_am_color_125f">#0000125f</color> + <color name="i_am_color_1260">#00001260</color> + <color name="i_am_color_1261">#00001261</color> + <color name="i_am_color_1262">#00001262</color> + <color name="i_am_color_1263">#00001263</color> + <color name="i_am_color_1264">#00001264</color> + <color name="i_am_color_1265">#00001265</color> + <color name="i_am_color_1266">#00001266</color> + <color name="i_am_color_1267">#00001267</color> + <color name="i_am_color_1268">#00001268</color> + <color name="i_am_color_1269">#00001269</color> + <color name="i_am_color_126a">#0000126a</color> + <color name="i_am_color_126b">#0000126b</color> + <color name="i_am_color_126c">#0000126c</color> + <color name="i_am_color_126d">#0000126d</color> + <color name="i_am_color_126e">#0000126e</color> + <color name="i_am_color_126f">#0000126f</color> + <color name="i_am_color_1270">#00001270</color> + <color name="i_am_color_1271">#00001271</color> + <color name="i_am_color_1272">#00001272</color> + <color name="i_am_color_1273">#00001273</color> + <color name="i_am_color_1274">#00001274</color> + <color name="i_am_color_1275">#00001275</color> + <color name="i_am_color_1276">#00001276</color> + <color name="i_am_color_1277">#00001277</color> + <color name="i_am_color_1278">#00001278</color> + <color name="i_am_color_1279">#00001279</color> + <color name="i_am_color_127a">#0000127a</color> + <color name="i_am_color_127b">#0000127b</color> + <color name="i_am_color_127c">#0000127c</color> + <color name="i_am_color_127d">#0000127d</color> + <color name="i_am_color_127e">#0000127e</color> + <color name="i_am_color_127f">#0000127f</color> + <color name="i_am_color_1280">#00001280</color> + <color name="i_am_color_1281">#00001281</color> + <color name="i_am_color_1282">#00001282</color> + <color name="i_am_color_1283">#00001283</color> + <color name="i_am_color_1284">#00001284</color> + <color name="i_am_color_1285">#00001285</color> + <color name="i_am_color_1286">#00001286</color> + <color name="i_am_color_1287">#00001287</color> + <color name="i_am_color_1288">#00001288</color> + <color name="i_am_color_1289">#00001289</color> + <color name="i_am_color_128a">#0000128a</color> + <color name="i_am_color_128b">#0000128b</color> + <color name="i_am_color_128c">#0000128c</color> + <color name="i_am_color_128d">#0000128d</color> + <color name="i_am_color_128e">#0000128e</color> + <color name="i_am_color_128f">#0000128f</color> + <color name="i_am_color_1290">#00001290</color> + <color name="i_am_color_1291">#00001291</color> + <color name="i_am_color_1292">#00001292</color> + <color name="i_am_color_1293">#00001293</color> + <color name="i_am_color_1294">#00001294</color> + <color name="i_am_color_1295">#00001295</color> + <color name="i_am_color_1296">#00001296</color> + <color name="i_am_color_1297">#00001297</color> + <color name="i_am_color_1298">#00001298</color> + <color name="i_am_color_1299">#00001299</color> + <color name="i_am_color_129a">#0000129a</color> + <color name="i_am_color_129b">#0000129b</color> + <color name="i_am_color_129c">#0000129c</color> + <color name="i_am_color_129d">#0000129d</color> + <color name="i_am_color_129e">#0000129e</color> + <color name="i_am_color_129f">#0000129f</color> + <color name="i_am_color_12a0">#000012a0</color> + <color name="i_am_color_12a1">#000012a1</color> + <color name="i_am_color_12a2">#000012a2</color> + <color name="i_am_color_12a3">#000012a3</color> + <color name="i_am_color_12a4">#000012a4</color> + <color name="i_am_color_12a5">#000012a5</color> + <color name="i_am_color_12a6">#000012a6</color> + <color name="i_am_color_12a7">#000012a7</color> + <color name="i_am_color_12a8">#000012a8</color> + <color name="i_am_color_12a9">#000012a9</color> + <color name="i_am_color_12aa">#000012aa</color> + <color name="i_am_color_12ab">#000012ab</color> + <color name="i_am_color_12ac">#000012ac</color> + <color name="i_am_color_12ad">#000012ad</color> + <color name="i_am_color_12ae">#000012ae</color> + <color name="i_am_color_12af">#000012af</color> + <color name="i_am_color_12b0">#000012b0</color> + <color name="i_am_color_12b1">#000012b1</color> + <color name="i_am_color_12b2">#000012b2</color> + <color name="i_am_color_12b3">#000012b3</color> + <color name="i_am_color_12b4">#000012b4</color> + <color name="i_am_color_12b5">#000012b5</color> + <color name="i_am_color_12b6">#000012b6</color> + <color name="i_am_color_12b7">#000012b7</color> + <color name="i_am_color_12b8">#000012b8</color> + <color name="i_am_color_12b9">#000012b9</color> + <color name="i_am_color_12ba">#000012ba</color> + <color name="i_am_color_12bb">#000012bb</color> + <color name="i_am_color_12bc">#000012bc</color> + <color name="i_am_color_12bd">#000012bd</color> + <color name="i_am_color_12be">#000012be</color> + <color name="i_am_color_12bf">#000012bf</color> + <color name="i_am_color_12c0">#000012c0</color> + <color name="i_am_color_12c1">#000012c1</color> + <color name="i_am_color_12c2">#000012c2</color> + <color name="i_am_color_12c3">#000012c3</color> + <color name="i_am_color_12c4">#000012c4</color> + <color name="i_am_color_12c5">#000012c5</color> + <color name="i_am_color_12c6">#000012c6</color> + <color name="i_am_color_12c7">#000012c7</color> + <color name="i_am_color_12c8">#000012c8</color> + <color name="i_am_color_12c9">#000012c9</color> + <color name="i_am_color_12ca">#000012ca</color> + <color name="i_am_color_12cb">#000012cb</color> + <color name="i_am_color_12cc">#000012cc</color> + <color name="i_am_color_12cd">#000012cd</color> + <color name="i_am_color_12ce">#000012ce</color> + <color name="i_am_color_12cf">#000012cf</color> + <color name="i_am_color_12d0">#000012d0</color> + <color name="i_am_color_12d1">#000012d1</color> + <color name="i_am_color_12d2">#000012d2</color> + <color name="i_am_color_12d3">#000012d3</color> + <color name="i_am_color_12d4">#000012d4</color> + <color name="i_am_color_12d5">#000012d5</color> + <color name="i_am_color_12d6">#000012d6</color> + <color name="i_am_color_12d7">#000012d7</color> + <color name="i_am_color_12d8">#000012d8</color> + <color name="i_am_color_12d9">#000012d9</color> + <color name="i_am_color_12da">#000012da</color> + <color name="i_am_color_12db">#000012db</color> + <color name="i_am_color_12dc">#000012dc</color> + <color name="i_am_color_12dd">#000012dd</color> + <color name="i_am_color_12de">#000012de</color> + <color name="i_am_color_12df">#000012df</color> + <color name="i_am_color_12e0">#000012e0</color> + <color name="i_am_color_12e1">#000012e1</color> + <color name="i_am_color_12e2">#000012e2</color> + <color name="i_am_color_12e3">#000012e3</color> + <color name="i_am_color_12e4">#000012e4</color> + <color name="i_am_color_12e5">#000012e5</color> + <color name="i_am_color_12e6">#000012e6</color> + <color name="i_am_color_12e7">#000012e7</color> + <color name="i_am_color_12e8">#000012e8</color> + <color name="i_am_color_12e9">#000012e9</color> + <color name="i_am_color_12ea">#000012ea</color> + <color name="i_am_color_12eb">#000012eb</color> + <color name="i_am_color_12ec">#000012ec</color> + <color name="i_am_color_12ed">#000012ed</color> + <color name="i_am_color_12ee">#000012ee</color> + <color name="i_am_color_12ef">#000012ef</color> + <color name="i_am_color_12f0">#000012f0</color> + <color name="i_am_color_12f1">#000012f1</color> + <color name="i_am_color_12f2">#000012f2</color> + <color name="i_am_color_12f3">#000012f3</color> + <color name="i_am_color_12f4">#000012f4</color> + <color name="i_am_color_12f5">#000012f5</color> + <color name="i_am_color_12f6">#000012f6</color> + <color name="i_am_color_12f7">#000012f7</color> + <color name="i_am_color_12f8">#000012f8</color> + <color name="i_am_color_12f9">#000012f9</color> + <color name="i_am_color_12fa">#000012fa</color> + <color name="i_am_color_12fb">#000012fb</color> + <color name="i_am_color_12fc">#000012fc</color> + <color name="i_am_color_12fd">#000012fd</color> + <color name="i_am_color_12fe">#000012fe</color> + <color name="i_am_color_12ff">#000012ff</color> + <color name="i_am_color_1300">#00001300</color> + <color name="i_am_color_1301">#00001301</color> + <color name="i_am_color_1302">#00001302</color> + <color name="i_am_color_1303">#00001303</color> + <color name="i_am_color_1304">#00001304</color> + <color name="i_am_color_1305">#00001305</color> + <color name="i_am_color_1306">#00001306</color> + <color name="i_am_color_1307">#00001307</color> + <color name="i_am_color_1308">#00001308</color> + <color name="i_am_color_1309">#00001309</color> + <color name="i_am_color_130a">#0000130a</color> + <color name="i_am_color_130b">#0000130b</color> + <color name="i_am_color_130c">#0000130c</color> + <color name="i_am_color_130d">#0000130d</color> + <color name="i_am_color_130e">#0000130e</color> + <color name="i_am_color_130f">#0000130f</color> + <color name="i_am_color_1310">#00001310</color> + <color name="i_am_color_1311">#00001311</color> + <color name="i_am_color_1312">#00001312</color> + <color name="i_am_color_1313">#00001313</color> + <color name="i_am_color_1314">#00001314</color> + <color name="i_am_color_1315">#00001315</color> + <color name="i_am_color_1316">#00001316</color> + <color name="i_am_color_1317">#00001317</color> + <color name="i_am_color_1318">#00001318</color> + <color name="i_am_color_1319">#00001319</color> + <color name="i_am_color_131a">#0000131a</color> + <color name="i_am_color_131b">#0000131b</color> + <color name="i_am_color_131c">#0000131c</color> + <color name="i_am_color_131d">#0000131d</color> + <color name="i_am_color_131e">#0000131e</color> + <color name="i_am_color_131f">#0000131f</color> + <color name="i_am_color_1320">#00001320</color> + <color name="i_am_color_1321">#00001321</color> + <color name="i_am_color_1322">#00001322</color> + <color name="i_am_color_1323">#00001323</color> + <color name="i_am_color_1324">#00001324</color> + <color name="i_am_color_1325">#00001325</color> + <color name="i_am_color_1326">#00001326</color> + <color name="i_am_color_1327">#00001327</color> + <color name="i_am_color_1328">#00001328</color> + <color name="i_am_color_1329">#00001329</color> + <color name="i_am_color_132a">#0000132a</color> + <color name="i_am_color_132b">#0000132b</color> + <color name="i_am_color_132c">#0000132c</color> + <color name="i_am_color_132d">#0000132d</color> + <color name="i_am_color_132e">#0000132e</color> + <color name="i_am_color_132f">#0000132f</color> + <color name="i_am_color_1330">#00001330</color> + <color name="i_am_color_1331">#00001331</color> + <color name="i_am_color_1332">#00001332</color> + <color name="i_am_color_1333">#00001333</color> + <color name="i_am_color_1334">#00001334</color> + <color name="i_am_color_1335">#00001335</color> + <color name="i_am_color_1336">#00001336</color> + <color name="i_am_color_1337">#00001337</color> + <color name="i_am_color_1338">#00001338</color> + <color name="i_am_color_1339">#00001339</color> + <color name="i_am_color_133a">#0000133a</color> + <color name="i_am_color_133b">#0000133b</color> + <color name="i_am_color_133c">#0000133c</color> + <color name="i_am_color_133d">#0000133d</color> + <color name="i_am_color_133e">#0000133e</color> + <color name="i_am_color_133f">#0000133f</color> + <color name="i_am_color_1340">#00001340</color> + <color name="i_am_color_1341">#00001341</color> + <color name="i_am_color_1342">#00001342</color> + <color name="i_am_color_1343">#00001343</color> + <color name="i_am_color_1344">#00001344</color> + <color name="i_am_color_1345">#00001345</color> + <color name="i_am_color_1346">#00001346</color> + <color name="i_am_color_1347">#00001347</color> + <color name="i_am_color_1348">#00001348</color> + <color name="i_am_color_1349">#00001349</color> + <color name="i_am_color_134a">#0000134a</color> + <color name="i_am_color_134b">#0000134b</color> + <color name="i_am_color_134c">#0000134c</color> + <color name="i_am_color_134d">#0000134d</color> + <color name="i_am_color_134e">#0000134e</color> + <color name="i_am_color_134f">#0000134f</color> + <color name="i_am_color_1350">#00001350</color> + <color name="i_am_color_1351">#00001351</color> + <color name="i_am_color_1352">#00001352</color> + <color name="i_am_color_1353">#00001353</color> + <color name="i_am_color_1354">#00001354</color> + <color name="i_am_color_1355">#00001355</color> + <color name="i_am_color_1356">#00001356</color> + <color name="i_am_color_1357">#00001357</color> + <color name="i_am_color_1358">#00001358</color> + <color name="i_am_color_1359">#00001359</color> + <color name="i_am_color_135a">#0000135a</color> + <color name="i_am_color_135b">#0000135b</color> + <color name="i_am_color_135c">#0000135c</color> + <color name="i_am_color_135d">#0000135d</color> + <color name="i_am_color_135e">#0000135e</color> + <color name="i_am_color_135f">#0000135f</color> + <color name="i_am_color_1360">#00001360</color> + <color name="i_am_color_1361">#00001361</color> + <color name="i_am_color_1362">#00001362</color> + <color name="i_am_color_1363">#00001363</color> + <color name="i_am_color_1364">#00001364</color> + <color name="i_am_color_1365">#00001365</color> + <color name="i_am_color_1366">#00001366</color> + <color name="i_am_color_1367">#00001367</color> + <color name="i_am_color_1368">#00001368</color> + <color name="i_am_color_1369">#00001369</color> + <color name="i_am_color_136a">#0000136a</color> + <color name="i_am_color_136b">#0000136b</color> + <color name="i_am_color_136c">#0000136c</color> + <color name="i_am_color_136d">#0000136d</color> + <color name="i_am_color_136e">#0000136e</color> + <color name="i_am_color_136f">#0000136f</color> + <color name="i_am_color_1370">#00001370</color> + <color name="i_am_color_1371">#00001371</color> + <color name="i_am_color_1372">#00001372</color> + <color name="i_am_color_1373">#00001373</color> + <color name="i_am_color_1374">#00001374</color> + <color name="i_am_color_1375">#00001375</color> + <color name="i_am_color_1376">#00001376</color> + <color name="i_am_color_1377">#00001377</color> + <color name="i_am_color_1378">#00001378</color> + <color name="i_am_color_1379">#00001379</color> + <color name="i_am_color_137a">#0000137a</color> + <color name="i_am_color_137b">#0000137b</color> + <color name="i_am_color_137c">#0000137c</color> + <color name="i_am_color_137d">#0000137d</color> + <color name="i_am_color_137e">#0000137e</color> + <color name="i_am_color_137f">#0000137f</color> + <color name="i_am_color_1380">#00001380</color> + <color name="i_am_color_1381">#00001381</color> + <color name="i_am_color_1382">#00001382</color> + <color name="i_am_color_1383">#00001383</color> + <color name="i_am_color_1384">#00001384</color> + <color name="i_am_color_1385">#00001385</color> + <color name="i_am_color_1386">#00001386</color> + <color name="i_am_color_1387">#00001387</color> + <color name="i_am_color_1388">#00001388</color> + <color name="i_am_color_1389">#00001389</color> + <color name="i_am_color_138a">#0000138a</color> + <color name="i_am_color_138b">#0000138b</color> + <color name="i_am_color_138c">#0000138c</color> + <color name="i_am_color_138d">#0000138d</color> + <color name="i_am_color_138e">#0000138e</color> + <color name="i_am_color_138f">#0000138f</color> + <color name="i_am_color_1390">#00001390</color> + <color name="i_am_color_1391">#00001391</color> + <color name="i_am_color_1392">#00001392</color> + <color name="i_am_color_1393">#00001393</color> + <color name="i_am_color_1394">#00001394</color> + <color name="i_am_color_1395">#00001395</color> + <color name="i_am_color_1396">#00001396</color> + <color name="i_am_color_1397">#00001397</color> + <color name="i_am_color_1398">#00001398</color> + <color name="i_am_color_1399">#00001399</color> + <color name="i_am_color_139a">#0000139a</color> + <color name="i_am_color_139b">#0000139b</color> + <color name="i_am_color_139c">#0000139c</color> + <color name="i_am_color_139d">#0000139d</color> + <color name="i_am_color_139e">#0000139e</color> + <color name="i_am_color_139f">#0000139f</color> + <color name="i_am_color_13a0">#000013a0</color> + <color name="i_am_color_13a1">#000013a1</color> + <color name="i_am_color_13a2">#000013a2</color> + <color name="i_am_color_13a3">#000013a3</color> + <color name="i_am_color_13a4">#000013a4</color> + <color name="i_am_color_13a5">#000013a5</color> + <color name="i_am_color_13a6">#000013a6</color> + <color name="i_am_color_13a7">#000013a7</color> + <color name="i_am_color_13a8">#000013a8</color> + <color name="i_am_color_13a9">#000013a9</color> + <color name="i_am_color_13aa">#000013aa</color> + <color name="i_am_color_13ab">#000013ab</color> + <color name="i_am_color_13ac">#000013ac</color> + <color name="i_am_color_13ad">#000013ad</color> + <color name="i_am_color_13ae">#000013ae</color> + <color name="i_am_color_13af">#000013af</color> + <color name="i_am_color_13b0">#000013b0</color> + <color name="i_am_color_13b1">#000013b1</color> + <color name="i_am_color_13b2">#000013b2</color> + <color name="i_am_color_13b3">#000013b3</color> + <color name="i_am_color_13b4">#000013b4</color> + <color name="i_am_color_13b5">#000013b5</color> + <color name="i_am_color_13b6">#000013b6</color> + <color name="i_am_color_13b7">#000013b7</color> + <color name="i_am_color_13b8">#000013b8</color> + <color name="i_am_color_13b9">#000013b9</color> + <color name="i_am_color_13ba">#000013ba</color> + <color name="i_am_color_13bb">#000013bb</color> + <color name="i_am_color_13bc">#000013bc</color> + <color name="i_am_color_13bd">#000013bd</color> + <color name="i_am_color_13be">#000013be</color> + <color name="i_am_color_13bf">#000013bf</color> + <color name="i_am_color_13c0">#000013c0</color> + <color name="i_am_color_13c1">#000013c1</color> + <color name="i_am_color_13c2">#000013c2</color> + <color name="i_am_color_13c3">#000013c3</color> + <color name="i_am_color_13c4">#000013c4</color> + <color name="i_am_color_13c5">#000013c5</color> + <color name="i_am_color_13c6">#000013c6</color> + <color name="i_am_color_13c7">#000013c7</color> + <color name="i_am_color_13c8">#000013c8</color> + <color name="i_am_color_13c9">#000013c9</color> + <color name="i_am_color_13ca">#000013ca</color> + <color name="i_am_color_13cb">#000013cb</color> + <color name="i_am_color_13cc">#000013cc</color> + <color name="i_am_color_13cd">#000013cd</color> + <color name="i_am_color_13ce">#000013ce</color> + <color name="i_am_color_13cf">#000013cf</color> + <color name="i_am_color_13d0">#000013d0</color> + <color name="i_am_color_13d1">#000013d1</color> + <color name="i_am_color_13d2">#000013d2</color> + <color name="i_am_color_13d3">#000013d3</color> + <color name="i_am_color_13d4">#000013d4</color> + <color name="i_am_color_13d5">#000013d5</color> + <color name="i_am_color_13d6">#000013d6</color> + <color name="i_am_color_13d7">#000013d7</color> + <color name="i_am_color_13d8">#000013d8</color> + <color name="i_am_color_13d9">#000013d9</color> + <color name="i_am_color_13da">#000013da</color> + <color name="i_am_color_13db">#000013db</color> + <color name="i_am_color_13dc">#000013dc</color> + <color name="i_am_color_13dd">#000013dd</color> + <color name="i_am_color_13de">#000013de</color> + <color name="i_am_color_13df">#000013df</color> + <color name="i_am_color_13e0">#000013e0</color> + <color name="i_am_color_13e1">#000013e1</color> + <color name="i_am_color_13e2">#000013e2</color> + <color name="i_am_color_13e3">#000013e3</color> + <color name="i_am_color_13e4">#000013e4</color> + <color name="i_am_color_13e5">#000013e5</color> + <color name="i_am_color_13e6">#000013e6</color> + <color name="i_am_color_13e7">#000013e7</color> + <color name="i_am_color_13e8">#000013e8</color> + <color name="i_am_color_13e9">#000013e9</color> + <color name="i_am_color_13ea">#000013ea</color> + <color name="i_am_color_13eb">#000013eb</color> + <color name="i_am_color_13ec">#000013ec</color> + <color name="i_am_color_13ed">#000013ed</color> + <color name="i_am_color_13ee">#000013ee</color> + <color name="i_am_color_13ef">#000013ef</color> + <color name="i_am_color_13f0">#000013f0</color> + <color name="i_am_color_13f1">#000013f1</color> + <color name="i_am_color_13f2">#000013f2</color> + <color name="i_am_color_13f3">#000013f3</color> + <color name="i_am_color_13f4">#000013f4</color> + <color name="i_am_color_13f5">#000013f5</color> + <color name="i_am_color_13f6">#000013f6</color> + <color name="i_am_color_13f7">#000013f7</color> + <color name="i_am_color_13f8">#000013f8</color> + <color name="i_am_color_13f9">#000013f9</color> + <color name="i_am_color_13fa">#000013fa</color> + <color name="i_am_color_13fb">#000013fb</color> + <color name="i_am_color_13fc">#000013fc</color> + <color name="i_am_color_13fd">#000013fd</color> + <color name="i_am_color_13fe">#000013fe</color> + <color name="i_am_color_13ff">#000013ff</color> + <color name="i_am_color_1400">#00001400</color> + <color name="i_am_color_1401">#00001401</color> + <color name="i_am_color_1402">#00001402</color> + <color name="i_am_color_1403">#00001403</color> + <color name="i_am_color_1404">#00001404</color> + <color name="i_am_color_1405">#00001405</color> + <color name="i_am_color_1406">#00001406</color> + <color name="i_am_color_1407">#00001407</color> + <color name="i_am_color_1408">#00001408</color> + <color name="i_am_color_1409">#00001409</color> + <color name="i_am_color_140a">#0000140a</color> + <color name="i_am_color_140b">#0000140b</color> + <color name="i_am_color_140c">#0000140c</color> + <color name="i_am_color_140d">#0000140d</color> + <color name="i_am_color_140e">#0000140e</color> + <color name="i_am_color_140f">#0000140f</color> + <color name="i_am_color_1410">#00001410</color> + <color name="i_am_color_1411">#00001411</color> + <color name="i_am_color_1412">#00001412</color> + <color name="i_am_color_1413">#00001413</color> + <color name="i_am_color_1414">#00001414</color> + <color name="i_am_color_1415">#00001415</color> + <color name="i_am_color_1416">#00001416</color> + <color name="i_am_color_1417">#00001417</color> + <color name="i_am_color_1418">#00001418</color> + <color name="i_am_color_1419">#00001419</color> + <color name="i_am_color_141a">#0000141a</color> + <color name="i_am_color_141b">#0000141b</color> + <color name="i_am_color_141c">#0000141c</color> + <color name="i_am_color_141d">#0000141d</color> + <color name="i_am_color_141e">#0000141e</color> + <color name="i_am_color_141f">#0000141f</color> + <color name="i_am_color_1420">#00001420</color> + <color name="i_am_color_1421">#00001421</color> + <color name="i_am_color_1422">#00001422</color> + <color name="i_am_color_1423">#00001423</color> + <color name="i_am_color_1424">#00001424</color> + <color name="i_am_color_1425">#00001425</color> + <color name="i_am_color_1426">#00001426</color> + <color name="i_am_color_1427">#00001427</color> + <color name="i_am_color_1428">#00001428</color> + <color name="i_am_color_1429">#00001429</color> + <color name="i_am_color_142a">#0000142a</color> + <color name="i_am_color_142b">#0000142b</color> + <color name="i_am_color_142c">#0000142c</color> + <color name="i_am_color_142d">#0000142d</color> + <color name="i_am_color_142e">#0000142e</color> + <color name="i_am_color_142f">#0000142f</color> + <color name="i_am_color_1430">#00001430</color> + <color name="i_am_color_1431">#00001431</color> + <color name="i_am_color_1432">#00001432</color> + <color name="i_am_color_1433">#00001433</color> + <color name="i_am_color_1434">#00001434</color> + <color name="i_am_color_1435">#00001435</color> + <color name="i_am_color_1436">#00001436</color> + <color name="i_am_color_1437">#00001437</color> + <color name="i_am_color_1438">#00001438</color> + <color name="i_am_color_1439">#00001439</color> + <color name="i_am_color_143a">#0000143a</color> + <color name="i_am_color_143b">#0000143b</color> + <color name="i_am_color_143c">#0000143c</color> + <color name="i_am_color_143d">#0000143d</color> + <color name="i_am_color_143e">#0000143e</color> + <color name="i_am_color_143f">#0000143f</color> + <color name="i_am_color_1440">#00001440</color> + <color name="i_am_color_1441">#00001441</color> + <color name="i_am_color_1442">#00001442</color> + <color name="i_am_color_1443">#00001443</color> + <color name="i_am_color_1444">#00001444</color> + <color name="i_am_color_1445">#00001445</color> + <color name="i_am_color_1446">#00001446</color> + <color name="i_am_color_1447">#00001447</color> + <color name="i_am_color_1448">#00001448</color> + <color name="i_am_color_1449">#00001449</color> + <color name="i_am_color_144a">#0000144a</color> + <color name="i_am_color_144b">#0000144b</color> + <color name="i_am_color_144c">#0000144c</color> + <color name="i_am_color_144d">#0000144d</color> + <color name="i_am_color_144e">#0000144e</color> + <color name="i_am_color_144f">#0000144f</color> + <color name="i_am_color_1450">#00001450</color> + <color name="i_am_color_1451">#00001451</color> + <color name="i_am_color_1452">#00001452</color> + <color name="i_am_color_1453">#00001453</color> + <color name="i_am_color_1454">#00001454</color> + <color name="i_am_color_1455">#00001455</color> + <color name="i_am_color_1456">#00001456</color> + <color name="i_am_color_1457">#00001457</color> + <color name="i_am_color_1458">#00001458</color> + <color name="i_am_color_1459">#00001459</color> + <color name="i_am_color_145a">#0000145a</color> + <color name="i_am_color_145b">#0000145b</color> + <color name="i_am_color_145c">#0000145c</color> + <color name="i_am_color_145d">#0000145d</color> + <color name="i_am_color_145e">#0000145e</color> + <color name="i_am_color_145f">#0000145f</color> + <color name="i_am_color_1460">#00001460</color> + <color name="i_am_color_1461">#00001461</color> + <color name="i_am_color_1462">#00001462</color> + <color name="i_am_color_1463">#00001463</color> + <color name="i_am_color_1464">#00001464</color> + <color name="i_am_color_1465">#00001465</color> + <color name="i_am_color_1466">#00001466</color> + <color name="i_am_color_1467">#00001467</color> + <color name="i_am_color_1468">#00001468</color> + <color name="i_am_color_1469">#00001469</color> + <color name="i_am_color_146a">#0000146a</color> + <color name="i_am_color_146b">#0000146b</color> + <color name="i_am_color_146c">#0000146c</color> + <color name="i_am_color_146d">#0000146d</color> + <color name="i_am_color_146e">#0000146e</color> + <color name="i_am_color_146f">#0000146f</color> + <color name="i_am_color_1470">#00001470</color> + <color name="i_am_color_1471">#00001471</color> + <color name="i_am_color_1472">#00001472</color> + <color name="i_am_color_1473">#00001473</color> + <color name="i_am_color_1474">#00001474</color> + <color name="i_am_color_1475">#00001475</color> + <color name="i_am_color_1476">#00001476</color> + <color name="i_am_color_1477">#00001477</color> + <color name="i_am_color_1478">#00001478</color> + <color name="i_am_color_1479">#00001479</color> + <color name="i_am_color_147a">#0000147a</color> + <color name="i_am_color_147b">#0000147b</color> + <color name="i_am_color_147c">#0000147c</color> + <color name="i_am_color_147d">#0000147d</color> + <color name="i_am_color_147e">#0000147e</color> + <color name="i_am_color_147f">#0000147f</color> + <color name="i_am_color_1480">#00001480</color> + <color name="i_am_color_1481">#00001481</color> + <color name="i_am_color_1482">#00001482</color> + <color name="i_am_color_1483">#00001483</color> + <color name="i_am_color_1484">#00001484</color> + <color name="i_am_color_1485">#00001485</color> + <color name="i_am_color_1486">#00001486</color> + <color name="i_am_color_1487">#00001487</color> + <color name="i_am_color_1488">#00001488</color> + <color name="i_am_color_1489">#00001489</color> + <color name="i_am_color_148a">#0000148a</color> + <color name="i_am_color_148b">#0000148b</color> + <color name="i_am_color_148c">#0000148c</color> + <color name="i_am_color_148d">#0000148d</color> + <color name="i_am_color_148e">#0000148e</color> + <color name="i_am_color_148f">#0000148f</color> + <color name="i_am_color_1490">#00001490</color> + <color name="i_am_color_1491">#00001491</color> + <color name="i_am_color_1492">#00001492</color> + <color name="i_am_color_1493">#00001493</color> + <color name="i_am_color_1494">#00001494</color> + <color name="i_am_color_1495">#00001495</color> + <color name="i_am_color_1496">#00001496</color> + <color name="i_am_color_1497">#00001497</color> + <color name="i_am_color_1498">#00001498</color> + <color name="i_am_color_1499">#00001499</color> + <color name="i_am_color_149a">#0000149a</color> + <color name="i_am_color_149b">#0000149b</color> + <color name="i_am_color_149c">#0000149c</color> + <color name="i_am_color_149d">#0000149d</color> + <color name="i_am_color_149e">#0000149e</color> + <color name="i_am_color_149f">#0000149f</color> + <color name="i_am_color_14a0">#000014a0</color> + <color name="i_am_color_14a1">#000014a1</color> + <color name="i_am_color_14a2">#000014a2</color> + <color name="i_am_color_14a3">#000014a3</color> + <color name="i_am_color_14a4">#000014a4</color> + <color name="i_am_color_14a5">#000014a5</color> + <color name="i_am_color_14a6">#000014a6</color> + <color name="i_am_color_14a7">#000014a7</color> + <color name="i_am_color_14a8">#000014a8</color> + <color name="i_am_color_14a9">#000014a9</color> + <color name="i_am_color_14aa">#000014aa</color> + <color name="i_am_color_14ab">#000014ab</color> + <color name="i_am_color_14ac">#000014ac</color> + <color name="i_am_color_14ad">#000014ad</color> + <color name="i_am_color_14ae">#000014ae</color> + <color name="i_am_color_14af">#000014af</color> + <color name="i_am_color_14b0">#000014b0</color> + <color name="i_am_color_14b1">#000014b1</color> + <color name="i_am_color_14b2">#000014b2</color> + <color name="i_am_color_14b3">#000014b3</color> + <color name="i_am_color_14b4">#000014b4</color> + <color name="i_am_color_14b5">#000014b5</color> + <color name="i_am_color_14b6">#000014b6</color> + <color name="i_am_color_14b7">#000014b7</color> + <color name="i_am_color_14b8">#000014b8</color> + <color name="i_am_color_14b9">#000014b9</color> + <color name="i_am_color_14ba">#000014ba</color> + <color name="i_am_color_14bb">#000014bb</color> + <color name="i_am_color_14bc">#000014bc</color> + <color name="i_am_color_14bd">#000014bd</color> + <color name="i_am_color_14be">#000014be</color> + <color name="i_am_color_14bf">#000014bf</color> + <color name="i_am_color_14c0">#000014c0</color> + <color name="i_am_color_14c1">#000014c1</color> + <color name="i_am_color_14c2">#000014c2</color> + <color name="i_am_color_14c3">#000014c3</color> + <color name="i_am_color_14c4">#000014c4</color> + <color name="i_am_color_14c5">#000014c5</color> + <color name="i_am_color_14c6">#000014c6</color> + <color name="i_am_color_14c7">#000014c7</color> + <color name="i_am_color_14c8">#000014c8</color> + <color name="i_am_color_14c9">#000014c9</color> + <color name="i_am_color_14ca">#000014ca</color> + <color name="i_am_color_14cb">#000014cb</color> + <color name="i_am_color_14cc">#000014cc</color> + <color name="i_am_color_14cd">#000014cd</color> + <color name="i_am_color_14ce">#000014ce</color> + <color name="i_am_color_14cf">#000014cf</color> + <color name="i_am_color_14d0">#000014d0</color> + <color name="i_am_color_14d1">#000014d1</color> + <color name="i_am_color_14d2">#000014d2</color> + <color name="i_am_color_14d3">#000014d3</color> + <color name="i_am_color_14d4">#000014d4</color> + <color name="i_am_color_14d5">#000014d5</color> + <color name="i_am_color_14d6">#000014d6</color> + <color name="i_am_color_14d7">#000014d7</color> + <color name="i_am_color_14d8">#000014d8</color> + <color name="i_am_color_14d9">#000014d9</color> + <color name="i_am_color_14da">#000014da</color> + <color name="i_am_color_14db">#000014db</color> + <color name="i_am_color_14dc">#000014dc</color> + <color name="i_am_color_14dd">#000014dd</color> + <color name="i_am_color_14de">#000014de</color> + <color name="i_am_color_14df">#000014df</color> + <color name="i_am_color_14e0">#000014e0</color> + <color name="i_am_color_14e1">#000014e1</color> + <color name="i_am_color_14e2">#000014e2</color> + <color name="i_am_color_14e3">#000014e3</color> + <color name="i_am_color_14e4">#000014e4</color> + <color name="i_am_color_14e5">#000014e5</color> + <color name="i_am_color_14e6">#000014e6</color> + <color name="i_am_color_14e7">#000014e7</color> + <color name="i_am_color_14e8">#000014e8</color> + <color name="i_am_color_14e9">#000014e9</color> + <color name="i_am_color_14ea">#000014ea</color> + <color name="i_am_color_14eb">#000014eb</color> + <color name="i_am_color_14ec">#000014ec</color> + <color name="i_am_color_14ed">#000014ed</color> + <color name="i_am_color_14ee">#000014ee</color> + <color name="i_am_color_14ef">#000014ef</color> + <color name="i_am_color_14f0">#000014f0</color> + <color name="i_am_color_14f1">#000014f1</color> + <color name="i_am_color_14f2">#000014f2</color> + <color name="i_am_color_14f3">#000014f3</color> + <color name="i_am_color_14f4">#000014f4</color> + <color name="i_am_color_14f5">#000014f5</color> + <color name="i_am_color_14f6">#000014f6</color> + <color name="i_am_color_14f7">#000014f7</color> + <color name="i_am_color_14f8">#000014f8</color> + <color name="i_am_color_14f9">#000014f9</color> + <color name="i_am_color_14fa">#000014fa</color> + <color name="i_am_color_14fb">#000014fb</color> + <color name="i_am_color_14fc">#000014fc</color> + <color name="i_am_color_14fd">#000014fd</color> + <color name="i_am_color_14fe">#000014fe</color> + <color name="i_am_color_14ff">#000014ff</color> + <color name="i_am_color_1500">#00001500</color> + <color name="i_am_color_1501">#00001501</color> + <color name="i_am_color_1502">#00001502</color> + <color name="i_am_color_1503">#00001503</color> + <color name="i_am_color_1504">#00001504</color> + <color name="i_am_color_1505">#00001505</color> + <color name="i_am_color_1506">#00001506</color> + <color name="i_am_color_1507">#00001507</color> + <color name="i_am_color_1508">#00001508</color> + <color name="i_am_color_1509">#00001509</color> + <color name="i_am_color_150a">#0000150a</color> + <color name="i_am_color_150b">#0000150b</color> + <color name="i_am_color_150c">#0000150c</color> + <color name="i_am_color_150d">#0000150d</color> + <color name="i_am_color_150e">#0000150e</color> + <color name="i_am_color_150f">#0000150f</color> + <color name="i_am_color_1510">#00001510</color> + <color name="i_am_color_1511">#00001511</color> + <color name="i_am_color_1512">#00001512</color> + <color name="i_am_color_1513">#00001513</color> + <color name="i_am_color_1514">#00001514</color> + <color name="i_am_color_1515">#00001515</color> + <color name="i_am_color_1516">#00001516</color> + <color name="i_am_color_1517">#00001517</color> + <color name="i_am_color_1518">#00001518</color> + <color name="i_am_color_1519">#00001519</color> + <color name="i_am_color_151a">#0000151a</color> + <color name="i_am_color_151b">#0000151b</color> + <color name="i_am_color_151c">#0000151c</color> + <color name="i_am_color_151d">#0000151d</color> + <color name="i_am_color_151e">#0000151e</color> + <color name="i_am_color_151f">#0000151f</color> + <color name="i_am_color_1520">#00001520</color> + <color name="i_am_color_1521">#00001521</color> + <color name="i_am_color_1522">#00001522</color> + <color name="i_am_color_1523">#00001523</color> + <color name="i_am_color_1524">#00001524</color> + <color name="i_am_color_1525">#00001525</color> + <color name="i_am_color_1526">#00001526</color> + <color name="i_am_color_1527">#00001527</color> + <color name="i_am_color_1528">#00001528</color> + <color name="i_am_color_1529">#00001529</color> + <color name="i_am_color_152a">#0000152a</color> + <color name="i_am_color_152b">#0000152b</color> + <color name="i_am_color_152c">#0000152c</color> + <color name="i_am_color_152d">#0000152d</color> + <color name="i_am_color_152e">#0000152e</color> + <color name="i_am_color_152f">#0000152f</color> + <color name="i_am_color_1530">#00001530</color> + <color name="i_am_color_1531">#00001531</color> + <color name="i_am_color_1532">#00001532</color> + <color name="i_am_color_1533">#00001533</color> + <color name="i_am_color_1534">#00001534</color> + <color name="i_am_color_1535">#00001535</color> + <color name="i_am_color_1536">#00001536</color> + <color name="i_am_color_1537">#00001537</color> + <color name="i_am_color_1538">#00001538</color> + <color name="i_am_color_1539">#00001539</color> + <color name="i_am_color_153a">#0000153a</color> + <color name="i_am_color_153b">#0000153b</color> + <color name="i_am_color_153c">#0000153c</color> + <color name="i_am_color_153d">#0000153d</color> + <color name="i_am_color_153e">#0000153e</color> + <color name="i_am_color_153f">#0000153f</color> + <color name="i_am_color_1540">#00001540</color> + <color name="i_am_color_1541">#00001541</color> + <color name="i_am_color_1542">#00001542</color> + <color name="i_am_color_1543">#00001543</color> + <color name="i_am_color_1544">#00001544</color> + <color name="i_am_color_1545">#00001545</color> + <color name="i_am_color_1546">#00001546</color> + <color name="i_am_color_1547">#00001547</color> + <color name="i_am_color_1548">#00001548</color> + <color name="i_am_color_1549">#00001549</color> + <color name="i_am_color_154a">#0000154a</color> + <color name="i_am_color_154b">#0000154b</color> + <color name="i_am_color_154c">#0000154c</color> + <color name="i_am_color_154d">#0000154d</color> + <color name="i_am_color_154e">#0000154e</color> + <color name="i_am_color_154f">#0000154f</color> + <color name="i_am_color_1550">#00001550</color> + <color name="i_am_color_1551">#00001551</color> + <color name="i_am_color_1552">#00001552</color> + <color name="i_am_color_1553">#00001553</color> + <color name="i_am_color_1554">#00001554</color> + <color name="i_am_color_1555">#00001555</color> + <color name="i_am_color_1556">#00001556</color> + <color name="i_am_color_1557">#00001557</color> + <color name="i_am_color_1558">#00001558</color> + <color name="i_am_color_1559">#00001559</color> + <color name="i_am_color_155a">#0000155a</color> + <color name="i_am_color_155b">#0000155b</color> + <color name="i_am_color_155c">#0000155c</color> + <color name="i_am_color_155d">#0000155d</color> + <color name="i_am_color_155e">#0000155e</color> + <color name="i_am_color_155f">#0000155f</color> + <color name="i_am_color_1560">#00001560</color> + <color name="i_am_color_1561">#00001561</color> + <color name="i_am_color_1562">#00001562</color> + <color name="i_am_color_1563">#00001563</color> + <color name="i_am_color_1564">#00001564</color> + <color name="i_am_color_1565">#00001565</color> + <color name="i_am_color_1566">#00001566</color> + <color name="i_am_color_1567">#00001567</color> + <color name="i_am_color_1568">#00001568</color> + <color name="i_am_color_1569">#00001569</color> + <color name="i_am_color_156a">#0000156a</color> + <color name="i_am_color_156b">#0000156b</color> + <color name="i_am_color_156c">#0000156c</color> + <color name="i_am_color_156d">#0000156d</color> + <color name="i_am_color_156e">#0000156e</color> + <color name="i_am_color_156f">#0000156f</color> + <color name="i_am_color_1570">#00001570</color> + <color name="i_am_color_1571">#00001571</color> + <color name="i_am_color_1572">#00001572</color> + <color name="i_am_color_1573">#00001573</color> + <color name="i_am_color_1574">#00001574</color> + <color name="i_am_color_1575">#00001575</color> + <color name="i_am_color_1576">#00001576</color> + <color name="i_am_color_1577">#00001577</color> + <color name="i_am_color_1578">#00001578</color> + <color name="i_am_color_1579">#00001579</color> + <color name="i_am_color_157a">#0000157a</color> + <color name="i_am_color_157b">#0000157b</color> + <color name="i_am_color_157c">#0000157c</color> + <color name="i_am_color_157d">#0000157d</color> + <color name="i_am_color_157e">#0000157e</color> + <color name="i_am_color_157f">#0000157f</color> + <color name="i_am_color_1580">#00001580</color> + <color name="i_am_color_1581">#00001581</color> + <color name="i_am_color_1582">#00001582</color> + <color name="i_am_color_1583">#00001583</color> + <color name="i_am_color_1584">#00001584</color> + <color name="i_am_color_1585">#00001585</color> + <color name="i_am_color_1586">#00001586</color> + <color name="i_am_color_1587">#00001587</color> + <color name="i_am_color_1588">#00001588</color> + <color name="i_am_color_1589">#00001589</color> + <color name="i_am_color_158a">#0000158a</color> + <color name="i_am_color_158b">#0000158b</color> + <color name="i_am_color_158c">#0000158c</color> + <color name="i_am_color_158d">#0000158d</color> + <color name="i_am_color_158e">#0000158e</color> + <color name="i_am_color_158f">#0000158f</color> + <color name="i_am_color_1590">#00001590</color> + <color name="i_am_color_1591">#00001591</color> + <color name="i_am_color_1592">#00001592</color> + <color name="i_am_color_1593">#00001593</color> + <color name="i_am_color_1594">#00001594</color> + <color name="i_am_color_1595">#00001595</color> + <color name="i_am_color_1596">#00001596</color> + <color name="i_am_color_1597">#00001597</color> + <color name="i_am_color_1598">#00001598</color> + <color name="i_am_color_1599">#00001599</color> + <color name="i_am_color_159a">#0000159a</color> + <color name="i_am_color_159b">#0000159b</color> + <color name="i_am_color_159c">#0000159c</color> + <color name="i_am_color_159d">#0000159d</color> + <color name="i_am_color_159e">#0000159e</color> + <color name="i_am_color_159f">#0000159f</color> + <color name="i_am_color_15a0">#000015a0</color> + <color name="i_am_color_15a1">#000015a1</color> + <color name="i_am_color_15a2">#000015a2</color> + <color name="i_am_color_15a3">#000015a3</color> + <color name="i_am_color_15a4">#000015a4</color> + <color name="i_am_color_15a5">#000015a5</color> + <color name="i_am_color_15a6">#000015a6</color> + <color name="i_am_color_15a7">#000015a7</color> + <color name="i_am_color_15a8">#000015a8</color> + <color name="i_am_color_15a9">#000015a9</color> + <color name="i_am_color_15aa">#000015aa</color> + <color name="i_am_color_15ab">#000015ab</color> + <color name="i_am_color_15ac">#000015ac</color> + <color name="i_am_color_15ad">#000015ad</color> + <color name="i_am_color_15ae">#000015ae</color> + <color name="i_am_color_15af">#000015af</color> + <color name="i_am_color_15b0">#000015b0</color> + <color name="i_am_color_15b1">#000015b1</color> + <color name="i_am_color_15b2">#000015b2</color> + <color name="i_am_color_15b3">#000015b3</color> + <color name="i_am_color_15b4">#000015b4</color> + <color name="i_am_color_15b5">#000015b5</color> + <color name="i_am_color_15b6">#000015b6</color> + <color name="i_am_color_15b7">#000015b7</color> + <color name="i_am_color_15b8">#000015b8</color> + <color name="i_am_color_15b9">#000015b9</color> + <color name="i_am_color_15ba">#000015ba</color> + <color name="i_am_color_15bb">#000015bb</color> + <color name="i_am_color_15bc">#000015bc</color> + <color name="i_am_color_15bd">#000015bd</color> + <color name="i_am_color_15be">#000015be</color> + <color name="i_am_color_15bf">#000015bf</color> + <color name="i_am_color_15c0">#000015c0</color> + <color name="i_am_color_15c1">#000015c1</color> + <color name="i_am_color_15c2">#000015c2</color> + <color name="i_am_color_15c3">#000015c3</color> + <color name="i_am_color_15c4">#000015c4</color> + <color name="i_am_color_15c5">#000015c5</color> + <color name="i_am_color_15c6">#000015c6</color> + <color name="i_am_color_15c7">#000015c7</color> + <color name="i_am_color_15c8">#000015c8</color> + <color name="i_am_color_15c9">#000015c9</color> + <color name="i_am_color_15ca">#000015ca</color> + <color name="i_am_color_15cb">#000015cb</color> + <color name="i_am_color_15cc">#000015cc</color> + <color name="i_am_color_15cd">#000015cd</color> + <color name="i_am_color_15ce">#000015ce</color> + <color name="i_am_color_15cf">#000015cf</color> + <color name="i_am_color_15d0">#000015d0</color> + <color name="i_am_color_15d1">#000015d1</color> + <color name="i_am_color_15d2">#000015d2</color> + <color name="i_am_color_15d3">#000015d3</color> + <color name="i_am_color_15d4">#000015d4</color> + <color name="i_am_color_15d5">#000015d5</color> + <color name="i_am_color_15d6">#000015d6</color> + <color name="i_am_color_15d7">#000015d7</color> + <color name="i_am_color_15d8">#000015d8</color> + <color name="i_am_color_15d9">#000015d9</color> + <color name="i_am_color_15da">#000015da</color> + <color name="i_am_color_15db">#000015db</color> + <color name="i_am_color_15dc">#000015dc</color> + <color name="i_am_color_15dd">#000015dd</color> + <color name="i_am_color_15de">#000015de</color> + <color name="i_am_color_15df">#000015df</color> + <color name="i_am_color_15e0">#000015e0</color> + <color name="i_am_color_15e1">#000015e1</color> + <color name="i_am_color_15e2">#000015e2</color> + <color name="i_am_color_15e3">#000015e3</color> + <color name="i_am_color_15e4">#000015e4</color> + <color name="i_am_color_15e5">#000015e5</color> + <color name="i_am_color_15e6">#000015e6</color> + <color name="i_am_color_15e7">#000015e7</color> + <color name="i_am_color_15e8">#000015e8</color> + <color name="i_am_color_15e9">#000015e9</color> + <color name="i_am_color_15ea">#000015ea</color> + <color name="i_am_color_15eb">#000015eb</color> + <color name="i_am_color_15ec">#000015ec</color> + <color name="i_am_color_15ed">#000015ed</color> + <color name="i_am_color_15ee">#000015ee</color> + <color name="i_am_color_15ef">#000015ef</color> + <color name="i_am_color_15f0">#000015f0</color> + <color name="i_am_color_15f1">#000015f1</color> + <color name="i_am_color_15f2">#000015f2</color> + <color name="i_am_color_15f3">#000015f3</color> + <color name="i_am_color_15f4">#000015f4</color> + <color name="i_am_color_15f5">#000015f5</color> + <color name="i_am_color_15f6">#000015f6</color> + <color name="i_am_color_15f7">#000015f7</color> + <color name="i_am_color_15f8">#000015f8</color> + <color name="i_am_color_15f9">#000015f9</color> + <color name="i_am_color_15fa">#000015fa</color> + <color name="i_am_color_15fb">#000015fb</color> + <color name="i_am_color_15fc">#000015fc</color> + <color name="i_am_color_15fd">#000015fd</color> + <color name="i_am_color_15fe">#000015fe</color> + <color name="i_am_color_15ff">#000015ff</color> + <color name="i_am_color_1600">#00001600</color> + <color name="i_am_color_1601">#00001601</color> + <color name="i_am_color_1602">#00001602</color> + <color name="i_am_color_1603">#00001603</color> + <color name="i_am_color_1604">#00001604</color> + <color name="i_am_color_1605">#00001605</color> + <color name="i_am_color_1606">#00001606</color> + <color name="i_am_color_1607">#00001607</color> + <color name="i_am_color_1608">#00001608</color> + <color name="i_am_color_1609">#00001609</color> + <color name="i_am_color_160a">#0000160a</color> + <color name="i_am_color_160b">#0000160b</color> + <color name="i_am_color_160c">#0000160c</color> + <color name="i_am_color_160d">#0000160d</color> + <color name="i_am_color_160e">#0000160e</color> + <color name="i_am_color_160f">#0000160f</color> + <color name="i_am_color_1610">#00001610</color> + <color name="i_am_color_1611">#00001611</color> + <color name="i_am_color_1612">#00001612</color> + <color name="i_am_color_1613">#00001613</color> + <color name="i_am_color_1614">#00001614</color> + <color name="i_am_color_1615">#00001615</color> + <color name="i_am_color_1616">#00001616</color> + <color name="i_am_color_1617">#00001617</color> + <color name="i_am_color_1618">#00001618</color> + <color name="i_am_color_1619">#00001619</color> + <color name="i_am_color_161a">#0000161a</color> + <color name="i_am_color_161b">#0000161b</color> + <color name="i_am_color_161c">#0000161c</color> + <color name="i_am_color_161d">#0000161d</color> + <color name="i_am_color_161e">#0000161e</color> + <color name="i_am_color_161f">#0000161f</color> + <color name="i_am_color_1620">#00001620</color> + <color name="i_am_color_1621">#00001621</color> + <color name="i_am_color_1622">#00001622</color> + <color name="i_am_color_1623">#00001623</color> + <color name="i_am_color_1624">#00001624</color> + <color name="i_am_color_1625">#00001625</color> + <color name="i_am_color_1626">#00001626</color> + <color name="i_am_color_1627">#00001627</color> + <color name="i_am_color_1628">#00001628</color> + <color name="i_am_color_1629">#00001629</color> + <color name="i_am_color_162a">#0000162a</color> + <color name="i_am_color_162b">#0000162b</color> + <color name="i_am_color_162c">#0000162c</color> + <color name="i_am_color_162d">#0000162d</color> + <color name="i_am_color_162e">#0000162e</color> + <color name="i_am_color_162f">#0000162f</color> + <color name="i_am_color_1630">#00001630</color> + <color name="i_am_color_1631">#00001631</color> + <color name="i_am_color_1632">#00001632</color> + <color name="i_am_color_1633">#00001633</color> + <color name="i_am_color_1634">#00001634</color> + <color name="i_am_color_1635">#00001635</color> + <color name="i_am_color_1636">#00001636</color> + <color name="i_am_color_1637">#00001637</color> + <color name="i_am_color_1638">#00001638</color> + <color name="i_am_color_1639">#00001639</color> + <color name="i_am_color_163a">#0000163a</color> + <color name="i_am_color_163b">#0000163b</color> + <color name="i_am_color_163c">#0000163c</color> + <color name="i_am_color_163d">#0000163d</color> + <color name="i_am_color_163e">#0000163e</color> + <color name="i_am_color_163f">#0000163f</color> + <color name="i_am_color_1640">#00001640</color> + <color name="i_am_color_1641">#00001641</color> + <color name="i_am_color_1642">#00001642</color> + <color name="i_am_color_1643">#00001643</color> + <color name="i_am_color_1644">#00001644</color> + <color name="i_am_color_1645">#00001645</color> + <color name="i_am_color_1646">#00001646</color> + <color name="i_am_color_1647">#00001647</color> + <color name="i_am_color_1648">#00001648</color> + <color name="i_am_color_1649">#00001649</color> + <color name="i_am_color_164a">#0000164a</color> + <color name="i_am_color_164b">#0000164b</color> + <color name="i_am_color_164c">#0000164c</color> + <color name="i_am_color_164d">#0000164d</color> + <color name="i_am_color_164e">#0000164e</color> + <color name="i_am_color_164f">#0000164f</color> + <color name="i_am_color_1650">#00001650</color> + <color name="i_am_color_1651">#00001651</color> + <color name="i_am_color_1652">#00001652</color> + <color name="i_am_color_1653">#00001653</color> + <color name="i_am_color_1654">#00001654</color> + <color name="i_am_color_1655">#00001655</color> + <color name="i_am_color_1656">#00001656</color> + <color name="i_am_color_1657">#00001657</color> + <color name="i_am_color_1658">#00001658</color> + <color name="i_am_color_1659">#00001659</color> + <color name="i_am_color_165a">#0000165a</color> + <color name="i_am_color_165b">#0000165b</color> + <color name="i_am_color_165c">#0000165c</color> + <color name="i_am_color_165d">#0000165d</color> + <color name="i_am_color_165e">#0000165e</color> + <color name="i_am_color_165f">#0000165f</color> + <color name="i_am_color_1660">#00001660</color> + <color name="i_am_color_1661">#00001661</color> + <color name="i_am_color_1662">#00001662</color> + <color name="i_am_color_1663">#00001663</color> + <color name="i_am_color_1664">#00001664</color> + <color name="i_am_color_1665">#00001665</color> + <color name="i_am_color_1666">#00001666</color> + <color name="i_am_color_1667">#00001667</color> + <color name="i_am_color_1668">#00001668</color> + <color name="i_am_color_1669">#00001669</color> + <color name="i_am_color_166a">#0000166a</color> + <color name="i_am_color_166b">#0000166b</color> + <color name="i_am_color_166c">#0000166c</color> + <color name="i_am_color_166d">#0000166d</color> + <color name="i_am_color_166e">#0000166e</color> + <color name="i_am_color_166f">#0000166f</color> + <color name="i_am_color_1670">#00001670</color> + <color name="i_am_color_1671">#00001671</color> + <color name="i_am_color_1672">#00001672</color> + <color name="i_am_color_1673">#00001673</color> + <color name="i_am_color_1674">#00001674</color> + <color name="i_am_color_1675">#00001675</color> + <color name="i_am_color_1676">#00001676</color> + <color name="i_am_color_1677">#00001677</color> + <color name="i_am_color_1678">#00001678</color> + <color name="i_am_color_1679">#00001679</color> + <color name="i_am_color_167a">#0000167a</color> + <color name="i_am_color_167b">#0000167b</color> + <color name="i_am_color_167c">#0000167c</color> + <color name="i_am_color_167d">#0000167d</color> + <color name="i_am_color_167e">#0000167e</color> + <color name="i_am_color_167f">#0000167f</color> + <color name="i_am_color_1680">#00001680</color> + <color name="i_am_color_1681">#00001681</color> + <color name="i_am_color_1682">#00001682</color> + <color name="i_am_color_1683">#00001683</color> + <color name="i_am_color_1684">#00001684</color> + <color name="i_am_color_1685">#00001685</color> + <color name="i_am_color_1686">#00001686</color> + <color name="i_am_color_1687">#00001687</color> + <color name="i_am_color_1688">#00001688</color> + <color name="i_am_color_1689">#00001689</color> + <color name="i_am_color_168a">#0000168a</color> + <color name="i_am_color_168b">#0000168b</color> + <color name="i_am_color_168c">#0000168c</color> + <color name="i_am_color_168d">#0000168d</color> + <color name="i_am_color_168e">#0000168e</color> + <color name="i_am_color_168f">#0000168f</color> + <color name="i_am_color_1690">#00001690</color> + <color name="i_am_color_1691">#00001691</color> + <color name="i_am_color_1692">#00001692</color> + <color name="i_am_color_1693">#00001693</color> + <color name="i_am_color_1694">#00001694</color> + <color name="i_am_color_1695">#00001695</color> + <color name="i_am_color_1696">#00001696</color> + <color name="i_am_color_1697">#00001697</color> + <color name="i_am_color_1698">#00001698</color> + <color name="i_am_color_1699">#00001699</color> + <color name="i_am_color_169a">#0000169a</color> + <color name="i_am_color_169b">#0000169b</color> + <color name="i_am_color_169c">#0000169c</color> + <color name="i_am_color_169d">#0000169d</color> + <color name="i_am_color_169e">#0000169e</color> + <color name="i_am_color_169f">#0000169f</color> + <color name="i_am_color_16a0">#000016a0</color> + <color name="i_am_color_16a1">#000016a1</color> + <color name="i_am_color_16a2">#000016a2</color> + <color name="i_am_color_16a3">#000016a3</color> + <color name="i_am_color_16a4">#000016a4</color> + <color name="i_am_color_16a5">#000016a5</color> + <color name="i_am_color_16a6">#000016a6</color> + <color name="i_am_color_16a7">#000016a7</color> + <color name="i_am_color_16a8">#000016a8</color> + <color name="i_am_color_16a9">#000016a9</color> + <color name="i_am_color_16aa">#000016aa</color> + <color name="i_am_color_16ab">#000016ab</color> + <color name="i_am_color_16ac">#000016ac</color> + <color name="i_am_color_16ad">#000016ad</color> + <color name="i_am_color_16ae">#000016ae</color> + <color name="i_am_color_16af">#000016af</color> + <color name="i_am_color_16b0">#000016b0</color> + <color name="i_am_color_16b1">#000016b1</color> + <color name="i_am_color_16b2">#000016b2</color> + <color name="i_am_color_16b3">#000016b3</color> + <color name="i_am_color_16b4">#000016b4</color> + <color name="i_am_color_16b5">#000016b5</color> + <color name="i_am_color_16b6">#000016b6</color> + <color name="i_am_color_16b7">#000016b7</color> + <color name="i_am_color_16b8">#000016b8</color> + <color name="i_am_color_16b9">#000016b9</color> + <color name="i_am_color_16ba">#000016ba</color> + <color name="i_am_color_16bb">#000016bb</color> + <color name="i_am_color_16bc">#000016bc</color> + <color name="i_am_color_16bd">#000016bd</color> + <color name="i_am_color_16be">#000016be</color> + <color name="i_am_color_16bf">#000016bf</color> + <color name="i_am_color_16c0">#000016c0</color> + <color name="i_am_color_16c1">#000016c1</color> + <color name="i_am_color_16c2">#000016c2</color> + <color name="i_am_color_16c3">#000016c3</color> + <color name="i_am_color_16c4">#000016c4</color> + <color name="i_am_color_16c5">#000016c5</color> + <color name="i_am_color_16c6">#000016c6</color> + <color name="i_am_color_16c7">#000016c7</color> + <color name="i_am_color_16c8">#000016c8</color> + <color name="i_am_color_16c9">#000016c9</color> + <color name="i_am_color_16ca">#000016ca</color> + <color name="i_am_color_16cb">#000016cb</color> + <color name="i_am_color_16cc">#000016cc</color> + <color name="i_am_color_16cd">#000016cd</color> + <color name="i_am_color_16ce">#000016ce</color> + <color name="i_am_color_16cf">#000016cf</color> + <color name="i_am_color_16d0">#000016d0</color> + <color name="i_am_color_16d1">#000016d1</color> + <color name="i_am_color_16d2">#000016d2</color> + <color name="i_am_color_16d3">#000016d3</color> + <color name="i_am_color_16d4">#000016d4</color> + <color name="i_am_color_16d5">#000016d5</color> + <color name="i_am_color_16d6">#000016d6</color> + <color name="i_am_color_16d7">#000016d7</color> + <color name="i_am_color_16d8">#000016d8</color> + <color name="i_am_color_16d9">#000016d9</color> + <color name="i_am_color_16da">#000016da</color> + <color name="i_am_color_16db">#000016db</color> + <color name="i_am_color_16dc">#000016dc</color> + <color name="i_am_color_16dd">#000016dd</color> + <color name="i_am_color_16de">#000016de</color> + <color name="i_am_color_16df">#000016df</color> + <color name="i_am_color_16e0">#000016e0</color> + <color name="i_am_color_16e1">#000016e1</color> + <color name="i_am_color_16e2">#000016e2</color> + <color name="i_am_color_16e3">#000016e3</color> + <color name="i_am_color_16e4">#000016e4</color> + <color name="i_am_color_16e5">#000016e5</color> + <color name="i_am_color_16e6">#000016e6</color> + <color name="i_am_color_16e7">#000016e7</color> + <color name="i_am_color_16e8">#000016e8</color> + <color name="i_am_color_16e9">#000016e9</color> + <color name="i_am_color_16ea">#000016ea</color> + <color name="i_am_color_16eb">#000016eb</color> + <color name="i_am_color_16ec">#000016ec</color> + <color name="i_am_color_16ed">#000016ed</color> + <color name="i_am_color_16ee">#000016ee</color> + <color name="i_am_color_16ef">#000016ef</color> + <color name="i_am_color_16f0">#000016f0</color> + <color name="i_am_color_16f1">#000016f1</color> + <color name="i_am_color_16f2">#000016f2</color> + <color name="i_am_color_16f3">#000016f3</color> + <color name="i_am_color_16f4">#000016f4</color> + <color name="i_am_color_16f5">#000016f5</color> + <color name="i_am_color_16f6">#000016f6</color> + <color name="i_am_color_16f7">#000016f7</color> + <color name="i_am_color_16f8">#000016f8</color> + <color name="i_am_color_16f9">#000016f9</color> + <color name="i_am_color_16fa">#000016fa</color> + <color name="i_am_color_16fb">#000016fb</color> + <color name="i_am_color_16fc">#000016fc</color> + <color name="i_am_color_16fd">#000016fd</color> + <color name="i_am_color_16fe">#000016fe</color> + <color name="i_am_color_16ff">#000016ff</color> + <color name="i_am_color_1700">#00001700</color> + <color name="i_am_color_1701">#00001701</color> + <color name="i_am_color_1702">#00001702</color> + <color name="i_am_color_1703">#00001703</color> + <color name="i_am_color_1704">#00001704</color> + <color name="i_am_color_1705">#00001705</color> + <color name="i_am_color_1706">#00001706</color> + <color name="i_am_color_1707">#00001707</color> + <color name="i_am_color_1708">#00001708</color> + <color name="i_am_color_1709">#00001709</color> + <color name="i_am_color_170a">#0000170a</color> + <color name="i_am_color_170b">#0000170b</color> + <color name="i_am_color_170c">#0000170c</color> + <color name="i_am_color_170d">#0000170d</color> + <color name="i_am_color_170e">#0000170e</color> + <color name="i_am_color_170f">#0000170f</color> + <color name="i_am_color_1710">#00001710</color> + <color name="i_am_color_1711">#00001711</color> + <color name="i_am_color_1712">#00001712</color> + <color name="i_am_color_1713">#00001713</color> + <color name="i_am_color_1714">#00001714</color> + <color name="i_am_color_1715">#00001715</color> + <color name="i_am_color_1716">#00001716</color> + <color name="i_am_color_1717">#00001717</color> + <color name="i_am_color_1718">#00001718</color> + <color name="i_am_color_1719">#00001719</color> + <color name="i_am_color_171a">#0000171a</color> + <color name="i_am_color_171b">#0000171b</color> + <color name="i_am_color_171c">#0000171c</color> + <color name="i_am_color_171d">#0000171d</color> + <color name="i_am_color_171e">#0000171e</color> + <color name="i_am_color_171f">#0000171f</color> + <color name="i_am_color_1720">#00001720</color> + <color name="i_am_color_1721">#00001721</color> + <color name="i_am_color_1722">#00001722</color> + <color name="i_am_color_1723">#00001723</color> + <color name="i_am_color_1724">#00001724</color> + <color name="i_am_color_1725">#00001725</color> + <color name="i_am_color_1726">#00001726</color> + <color name="i_am_color_1727">#00001727</color> + <color name="i_am_color_1728">#00001728</color> + <color name="i_am_color_1729">#00001729</color> + <color name="i_am_color_172a">#0000172a</color> + <color name="i_am_color_172b">#0000172b</color> + <color name="i_am_color_172c">#0000172c</color> + <color name="i_am_color_172d">#0000172d</color> + <color name="i_am_color_172e">#0000172e</color> + <color name="i_am_color_172f">#0000172f</color> + <color name="i_am_color_1730">#00001730</color> + <color name="i_am_color_1731">#00001731</color> + <color name="i_am_color_1732">#00001732</color> + <color name="i_am_color_1733">#00001733</color> + <color name="i_am_color_1734">#00001734</color> + <color name="i_am_color_1735">#00001735</color> + <color name="i_am_color_1736">#00001736</color> + <color name="i_am_color_1737">#00001737</color> + <color name="i_am_color_1738">#00001738</color> + <color name="i_am_color_1739">#00001739</color> + <color name="i_am_color_173a">#0000173a</color> + <color name="i_am_color_173b">#0000173b</color> + <color name="i_am_color_173c">#0000173c</color> + <color name="i_am_color_173d">#0000173d</color> + <color name="i_am_color_173e">#0000173e</color> + <color name="i_am_color_173f">#0000173f</color> + <color name="i_am_color_1740">#00001740</color> + <color name="i_am_color_1741">#00001741</color> + <color name="i_am_color_1742">#00001742</color> + <color name="i_am_color_1743">#00001743</color> + <color name="i_am_color_1744">#00001744</color> + <color name="i_am_color_1745">#00001745</color> + <color name="i_am_color_1746">#00001746</color> + <color name="i_am_color_1747">#00001747</color> + <color name="i_am_color_1748">#00001748</color> + <color name="i_am_color_1749">#00001749</color> + <color name="i_am_color_174a">#0000174a</color> + <color name="i_am_color_174b">#0000174b</color> + <color name="i_am_color_174c">#0000174c</color> + <color name="i_am_color_174d">#0000174d</color> + <color name="i_am_color_174e">#0000174e</color> + <color name="i_am_color_174f">#0000174f</color> + <color name="i_am_color_1750">#00001750</color> + <color name="i_am_color_1751">#00001751</color> + <color name="i_am_color_1752">#00001752</color> + <color name="i_am_color_1753">#00001753</color> + <color name="i_am_color_1754">#00001754</color> + <color name="i_am_color_1755">#00001755</color> + <color name="i_am_color_1756">#00001756</color> + <color name="i_am_color_1757">#00001757</color> + <color name="i_am_color_1758">#00001758</color> + <color name="i_am_color_1759">#00001759</color> + <color name="i_am_color_175a">#0000175a</color> + <color name="i_am_color_175b">#0000175b</color> + <color name="i_am_color_175c">#0000175c</color> + <color name="i_am_color_175d">#0000175d</color> + <color name="i_am_color_175e">#0000175e</color> + <color name="i_am_color_175f">#0000175f</color> + <color name="i_am_color_1760">#00001760</color> + <color name="i_am_color_1761">#00001761</color> + <color name="i_am_color_1762">#00001762</color> + <color name="i_am_color_1763">#00001763</color> + <color name="i_am_color_1764">#00001764</color> + <color name="i_am_color_1765">#00001765</color> + <color name="i_am_color_1766">#00001766</color> + <color name="i_am_color_1767">#00001767</color> + <color name="i_am_color_1768">#00001768</color> + <color name="i_am_color_1769">#00001769</color> + <color name="i_am_color_176a">#0000176a</color> + <color name="i_am_color_176b">#0000176b</color> + <color name="i_am_color_176c">#0000176c</color> + <color name="i_am_color_176d">#0000176d</color> + <color name="i_am_color_176e">#0000176e</color> + <color name="i_am_color_176f">#0000176f</color> + <color name="i_am_color_1770">#00001770</color> + <color name="i_am_color_1771">#00001771</color> + <color name="i_am_color_1772">#00001772</color> + <color name="i_am_color_1773">#00001773</color> + <color name="i_am_color_1774">#00001774</color> + <color name="i_am_color_1775">#00001775</color> + <color name="i_am_color_1776">#00001776</color> + <color name="i_am_color_1777">#00001777</color> + <color name="i_am_color_1778">#00001778</color> + <color name="i_am_color_1779">#00001779</color> + <color name="i_am_color_177a">#0000177a</color> + <color name="i_am_color_177b">#0000177b</color> + <color name="i_am_color_177c">#0000177c</color> + <color name="i_am_color_177d">#0000177d</color> + <color name="i_am_color_177e">#0000177e</color> + <color name="i_am_color_177f">#0000177f</color> + <color name="i_am_color_1780">#00001780</color> + <color name="i_am_color_1781">#00001781</color> + <color name="i_am_color_1782">#00001782</color> + <color name="i_am_color_1783">#00001783</color> + <color name="i_am_color_1784">#00001784</color> + <color name="i_am_color_1785">#00001785</color> + <color name="i_am_color_1786">#00001786</color> + <color name="i_am_color_1787">#00001787</color> + <color name="i_am_color_1788">#00001788</color> + <color name="i_am_color_1789">#00001789</color> + <color name="i_am_color_178a">#0000178a</color> + <color name="i_am_color_178b">#0000178b</color> + <color name="i_am_color_178c">#0000178c</color> + <color name="i_am_color_178d">#0000178d</color> + <color name="i_am_color_178e">#0000178e</color> + <color name="i_am_color_178f">#0000178f</color> + <color name="i_am_color_1790">#00001790</color> + <color name="i_am_color_1791">#00001791</color> + <color name="i_am_color_1792">#00001792</color> + <color name="i_am_color_1793">#00001793</color> + <color name="i_am_color_1794">#00001794</color> + <color name="i_am_color_1795">#00001795</color> + <color name="i_am_color_1796">#00001796</color> + <color name="i_am_color_1797">#00001797</color> + <color name="i_am_color_1798">#00001798</color> + <color name="i_am_color_1799">#00001799</color> + <color name="i_am_color_179a">#0000179a</color> + <color name="i_am_color_179b">#0000179b</color> + <color name="i_am_color_179c">#0000179c</color> + <color name="i_am_color_179d">#0000179d</color> + <color name="i_am_color_179e">#0000179e</color> + <color name="i_am_color_179f">#0000179f</color> + <color name="i_am_color_17a0">#000017a0</color> + <color name="i_am_color_17a1">#000017a1</color> + <color name="i_am_color_17a2">#000017a2</color> + <color name="i_am_color_17a3">#000017a3</color> + <color name="i_am_color_17a4">#000017a4</color> + <color name="i_am_color_17a5">#000017a5</color> + <color name="i_am_color_17a6">#000017a6</color> + <color name="i_am_color_17a7">#000017a7</color> + <color name="i_am_color_17a8">#000017a8</color> + <color name="i_am_color_17a9">#000017a9</color> + <color name="i_am_color_17aa">#000017aa</color> + <color name="i_am_color_17ab">#000017ab</color> + <color name="i_am_color_17ac">#000017ac</color> + <color name="i_am_color_17ad">#000017ad</color> + <color name="i_am_color_17ae">#000017ae</color> + <color name="i_am_color_17af">#000017af</color> + <color name="i_am_color_17b0">#000017b0</color> + <color name="i_am_color_17b1">#000017b1</color> + <color name="i_am_color_17b2">#000017b2</color> + <color name="i_am_color_17b3">#000017b3</color> + <color name="i_am_color_17b4">#000017b4</color> + <color name="i_am_color_17b5">#000017b5</color> + <color name="i_am_color_17b6">#000017b6</color> + <color name="i_am_color_17b7">#000017b7</color> + <color name="i_am_color_17b8">#000017b8</color> + <color name="i_am_color_17b9">#000017b9</color> + <color name="i_am_color_17ba">#000017ba</color> + <color name="i_am_color_17bb">#000017bb</color> + <color name="i_am_color_17bc">#000017bc</color> + <color name="i_am_color_17bd">#000017bd</color> + <color name="i_am_color_17be">#000017be</color> + <color name="i_am_color_17bf">#000017bf</color> + <color name="i_am_color_17c0">#000017c0</color> + <color name="i_am_color_17c1">#000017c1</color> + <color name="i_am_color_17c2">#000017c2</color> + <color name="i_am_color_17c3">#000017c3</color> + <color name="i_am_color_17c4">#000017c4</color> + <color name="i_am_color_17c5">#000017c5</color> + <color name="i_am_color_17c6">#000017c6</color> + <color name="i_am_color_17c7">#000017c7</color> + <color name="i_am_color_17c8">#000017c8</color> + <color name="i_am_color_17c9">#000017c9</color> + <color name="i_am_color_17ca">#000017ca</color> + <color name="i_am_color_17cb">#000017cb</color> + <color name="i_am_color_17cc">#000017cc</color> + <color name="i_am_color_17cd">#000017cd</color> + <color name="i_am_color_17ce">#000017ce</color> + <color name="i_am_color_17cf">#000017cf</color> + <color name="i_am_color_17d0">#000017d0</color> + <color name="i_am_color_17d1">#000017d1</color> + <color name="i_am_color_17d2">#000017d2</color> + <color name="i_am_color_17d3">#000017d3</color> + <color name="i_am_color_17d4">#000017d4</color> + <color name="i_am_color_17d5">#000017d5</color> + <color name="i_am_color_17d6">#000017d6</color> + <color name="i_am_color_17d7">#000017d7</color> + <color name="i_am_color_17d8">#000017d8</color> + <color name="i_am_color_17d9">#000017d9</color> + <color name="i_am_color_17da">#000017da</color> + <color name="i_am_color_17db">#000017db</color> + <color name="i_am_color_17dc">#000017dc</color> + <color name="i_am_color_17dd">#000017dd</color> + <color name="i_am_color_17de">#000017de</color> + <color name="i_am_color_17df">#000017df</color> + <color name="i_am_color_17e0">#000017e0</color> + <color name="i_am_color_17e1">#000017e1</color> + <color name="i_am_color_17e2">#000017e2</color> + <color name="i_am_color_17e3">#000017e3</color> + <color name="i_am_color_17e4">#000017e4</color> + <color name="i_am_color_17e5">#000017e5</color> + <color name="i_am_color_17e6">#000017e6</color> + <color name="i_am_color_17e7">#000017e7</color> + <color name="i_am_color_17e8">#000017e8</color> + <color name="i_am_color_17e9">#000017e9</color> + <color name="i_am_color_17ea">#000017ea</color> + <color name="i_am_color_17eb">#000017eb</color> + <color name="i_am_color_17ec">#000017ec</color> + <color name="i_am_color_17ed">#000017ed</color> + <color name="i_am_color_17ee">#000017ee</color> + <color name="i_am_color_17ef">#000017ef</color> + <color name="i_am_color_17f0">#000017f0</color> + <color name="i_am_color_17f1">#000017f1</color> + <color name="i_am_color_17f2">#000017f2</color> + <color name="i_am_color_17f3">#000017f3</color> + <color name="i_am_color_17f4">#000017f4</color> + <color name="i_am_color_17f5">#000017f5</color> + <color name="i_am_color_17f6">#000017f6</color> + <color name="i_am_color_17f7">#000017f7</color> + <color name="i_am_color_17f8">#000017f8</color> + <color name="i_am_color_17f9">#000017f9</color> + <color name="i_am_color_17fa">#000017fa</color> + <color name="i_am_color_17fb">#000017fb</color> + <color name="i_am_color_17fc">#000017fc</color> + <color name="i_am_color_17fd">#000017fd</color> + <color name="i_am_color_17fe">#000017fe</color> + <color name="i_am_color_17ff">#000017ff</color> + <color name="i_am_color_1800">#00001800</color> + <color name="i_am_color_1801">#00001801</color> + <color name="i_am_color_1802">#00001802</color> + <color name="i_am_color_1803">#00001803</color> + <color name="i_am_color_1804">#00001804</color> + <color name="i_am_color_1805">#00001805</color> + <color name="i_am_color_1806">#00001806</color> + <color name="i_am_color_1807">#00001807</color> + <color name="i_am_color_1808">#00001808</color> + <color name="i_am_color_1809">#00001809</color> + <color name="i_am_color_180a">#0000180a</color> + <color name="i_am_color_180b">#0000180b</color> + <color name="i_am_color_180c">#0000180c</color> + <color name="i_am_color_180d">#0000180d</color> + <color name="i_am_color_180e">#0000180e</color> + <color name="i_am_color_180f">#0000180f</color> + <color name="i_am_color_1810">#00001810</color> + <color name="i_am_color_1811">#00001811</color> + <color name="i_am_color_1812">#00001812</color> + <color name="i_am_color_1813">#00001813</color> + <color name="i_am_color_1814">#00001814</color> + <color name="i_am_color_1815">#00001815</color> + <color name="i_am_color_1816">#00001816</color> + <color name="i_am_color_1817">#00001817</color> + <color name="i_am_color_1818">#00001818</color> + <color name="i_am_color_1819">#00001819</color> + <color name="i_am_color_181a">#0000181a</color> + <color name="i_am_color_181b">#0000181b</color> + <color name="i_am_color_181c">#0000181c</color> + <color name="i_am_color_181d">#0000181d</color> + <color name="i_am_color_181e">#0000181e</color> + <color name="i_am_color_181f">#0000181f</color> + <color name="i_am_color_1820">#00001820</color> + <color name="i_am_color_1821">#00001821</color> + <color name="i_am_color_1822">#00001822</color> + <color name="i_am_color_1823">#00001823</color> + <color name="i_am_color_1824">#00001824</color> + <color name="i_am_color_1825">#00001825</color> + <color name="i_am_color_1826">#00001826</color> + <color name="i_am_color_1827">#00001827</color> + <color name="i_am_color_1828">#00001828</color> + <color name="i_am_color_1829">#00001829</color> + <color name="i_am_color_182a">#0000182a</color> + <color name="i_am_color_182b">#0000182b</color> + <color name="i_am_color_182c">#0000182c</color> + <color name="i_am_color_182d">#0000182d</color> + <color name="i_am_color_182e">#0000182e</color> + <color name="i_am_color_182f">#0000182f</color> + <color name="i_am_color_1830">#00001830</color> + <color name="i_am_color_1831">#00001831</color> + <color name="i_am_color_1832">#00001832</color> + <color name="i_am_color_1833">#00001833</color> + <color name="i_am_color_1834">#00001834</color> + <color name="i_am_color_1835">#00001835</color> + <color name="i_am_color_1836">#00001836</color> + <color name="i_am_color_1837">#00001837</color> + <color name="i_am_color_1838">#00001838</color> + <color name="i_am_color_1839">#00001839</color> + <color name="i_am_color_183a">#0000183a</color> + <color name="i_am_color_183b">#0000183b</color> + <color name="i_am_color_183c">#0000183c</color> + <color name="i_am_color_183d">#0000183d</color> + <color name="i_am_color_183e">#0000183e</color> + <color name="i_am_color_183f">#0000183f</color> + <color name="i_am_color_1840">#00001840</color> + <color name="i_am_color_1841">#00001841</color> + <color name="i_am_color_1842">#00001842</color> + <color name="i_am_color_1843">#00001843</color> + <color name="i_am_color_1844">#00001844</color> + <color name="i_am_color_1845">#00001845</color> + <color name="i_am_color_1846">#00001846</color> + <color name="i_am_color_1847">#00001847</color> + <color name="i_am_color_1848">#00001848</color> + <color name="i_am_color_1849">#00001849</color> + <color name="i_am_color_184a">#0000184a</color> + <color name="i_am_color_184b">#0000184b</color> + <color name="i_am_color_184c">#0000184c</color> + <color name="i_am_color_184d">#0000184d</color> + <color name="i_am_color_184e">#0000184e</color> + <color name="i_am_color_184f">#0000184f</color> + <color name="i_am_color_1850">#00001850</color> + <color name="i_am_color_1851">#00001851</color> + <color name="i_am_color_1852">#00001852</color> + <color name="i_am_color_1853">#00001853</color> + <color name="i_am_color_1854">#00001854</color> + <color name="i_am_color_1855">#00001855</color> + <color name="i_am_color_1856">#00001856</color> + <color name="i_am_color_1857">#00001857</color> + <color name="i_am_color_1858">#00001858</color> + <color name="i_am_color_1859">#00001859</color> + <color name="i_am_color_185a">#0000185a</color> + <color name="i_am_color_185b">#0000185b</color> + <color name="i_am_color_185c">#0000185c</color> + <color name="i_am_color_185d">#0000185d</color> + <color name="i_am_color_185e">#0000185e</color> + <color name="i_am_color_185f">#0000185f</color> + <color name="i_am_color_1860">#00001860</color> + <color name="i_am_color_1861">#00001861</color> + <color name="i_am_color_1862">#00001862</color> + <color name="i_am_color_1863">#00001863</color> + <color name="i_am_color_1864">#00001864</color> + <color name="i_am_color_1865">#00001865</color> + <color name="i_am_color_1866">#00001866</color> + <color name="i_am_color_1867">#00001867</color> + <color name="i_am_color_1868">#00001868</color> + <color name="i_am_color_1869">#00001869</color> + <color name="i_am_color_186a">#0000186a</color> + <color name="i_am_color_186b">#0000186b</color> + <color name="i_am_color_186c">#0000186c</color> + <color name="i_am_color_186d">#0000186d</color> + <color name="i_am_color_186e">#0000186e</color> + <color name="i_am_color_186f">#0000186f</color> + <color name="i_am_color_1870">#00001870</color> + <color name="i_am_color_1871">#00001871</color> + <color name="i_am_color_1872">#00001872</color> + <color name="i_am_color_1873">#00001873</color> + <color name="i_am_color_1874">#00001874</color> + <color name="i_am_color_1875">#00001875</color> + <color name="i_am_color_1876">#00001876</color> + <color name="i_am_color_1877">#00001877</color> + <color name="i_am_color_1878">#00001878</color> + <color name="i_am_color_1879">#00001879</color> + <color name="i_am_color_187a">#0000187a</color> + <color name="i_am_color_187b">#0000187b</color> + <color name="i_am_color_187c">#0000187c</color> + <color name="i_am_color_187d">#0000187d</color> + <color name="i_am_color_187e">#0000187e</color> + <color name="i_am_color_187f">#0000187f</color> + <color name="i_am_color_1880">#00001880</color> + <color name="i_am_color_1881">#00001881</color> + <color name="i_am_color_1882">#00001882</color> + <color name="i_am_color_1883">#00001883</color> + <color name="i_am_color_1884">#00001884</color> + <color name="i_am_color_1885">#00001885</color> + <color name="i_am_color_1886">#00001886</color> + <color name="i_am_color_1887">#00001887</color> + <color name="i_am_color_1888">#00001888</color> + <color name="i_am_color_1889">#00001889</color> + <color name="i_am_color_188a">#0000188a</color> + <color name="i_am_color_188b">#0000188b</color> + <color name="i_am_color_188c">#0000188c</color> + <color name="i_am_color_188d">#0000188d</color> + <color name="i_am_color_188e">#0000188e</color> + <color name="i_am_color_188f">#0000188f</color> + <color name="i_am_color_1890">#00001890</color> + <color name="i_am_color_1891">#00001891</color> + <color name="i_am_color_1892">#00001892</color> + <color name="i_am_color_1893">#00001893</color> + <color name="i_am_color_1894">#00001894</color> + <color name="i_am_color_1895">#00001895</color> + <color name="i_am_color_1896">#00001896</color> + <color name="i_am_color_1897">#00001897</color> + <color name="i_am_color_1898">#00001898</color> + <color name="i_am_color_1899">#00001899</color> + <color name="i_am_color_189a">#0000189a</color> + <color name="i_am_color_189b">#0000189b</color> + <color name="i_am_color_189c">#0000189c</color> + <color name="i_am_color_189d">#0000189d</color> + <color name="i_am_color_189e">#0000189e</color> + <color name="i_am_color_189f">#0000189f</color> + <color name="i_am_color_18a0">#000018a0</color> + <color name="i_am_color_18a1">#000018a1</color> + <color name="i_am_color_18a2">#000018a2</color> + <color name="i_am_color_18a3">#000018a3</color> + <color name="i_am_color_18a4">#000018a4</color> + <color name="i_am_color_18a5">#000018a5</color> + <color name="i_am_color_18a6">#000018a6</color> + <color name="i_am_color_18a7">#000018a7</color> + <color name="i_am_color_18a8">#000018a8</color> + <color name="i_am_color_18a9">#000018a9</color> + <color name="i_am_color_18aa">#000018aa</color> + <color name="i_am_color_18ab">#000018ab</color> + <color name="i_am_color_18ac">#000018ac</color> + <color name="i_am_color_18ad">#000018ad</color> + <color name="i_am_color_18ae">#000018ae</color> + <color name="i_am_color_18af">#000018af</color> + <color name="i_am_color_18b0">#000018b0</color> + <color name="i_am_color_18b1">#000018b1</color> + <color name="i_am_color_18b2">#000018b2</color> + <color name="i_am_color_18b3">#000018b3</color> + <color name="i_am_color_18b4">#000018b4</color> + <color name="i_am_color_18b5">#000018b5</color> + <color name="i_am_color_18b6">#000018b6</color> + <color name="i_am_color_18b7">#000018b7</color> + <color name="i_am_color_18b8">#000018b8</color> + <color name="i_am_color_18b9">#000018b9</color> + <color name="i_am_color_18ba">#000018ba</color> + <color name="i_am_color_18bb">#000018bb</color> + <color name="i_am_color_18bc">#000018bc</color> + <color name="i_am_color_18bd">#000018bd</color> + <color name="i_am_color_18be">#000018be</color> + <color name="i_am_color_18bf">#000018bf</color> + <color name="i_am_color_18c0">#000018c0</color> + <color name="i_am_color_18c1">#000018c1</color> + <color name="i_am_color_18c2">#000018c2</color> + <color name="i_am_color_18c3">#000018c3</color> + <color name="i_am_color_18c4">#000018c4</color> + <color name="i_am_color_18c5">#000018c5</color> + <color name="i_am_color_18c6">#000018c6</color> + <color name="i_am_color_18c7">#000018c7</color> + <color name="i_am_color_18c8">#000018c8</color> + <color name="i_am_color_18c9">#000018c9</color> + <color name="i_am_color_18ca">#000018ca</color> + <color name="i_am_color_18cb">#000018cb</color> + <color name="i_am_color_18cc">#000018cc</color> + <color name="i_am_color_18cd">#000018cd</color> + <color name="i_am_color_18ce">#000018ce</color> + <color name="i_am_color_18cf">#000018cf</color> + <color name="i_am_color_18d0">#000018d0</color> + <color name="i_am_color_18d1">#000018d1</color> + <color name="i_am_color_18d2">#000018d2</color> + <color name="i_am_color_18d3">#000018d3</color> + <color name="i_am_color_18d4">#000018d4</color> + <color name="i_am_color_18d5">#000018d5</color> + <color name="i_am_color_18d6">#000018d6</color> + <color name="i_am_color_18d7">#000018d7</color> + <color name="i_am_color_18d8">#000018d8</color> + <color name="i_am_color_18d9">#000018d9</color> + <color name="i_am_color_18da">#000018da</color> + <color name="i_am_color_18db">#000018db</color> + <color name="i_am_color_18dc">#000018dc</color> + <color name="i_am_color_18dd">#000018dd</color> + <color name="i_am_color_18de">#000018de</color> + <color name="i_am_color_18df">#000018df</color> + <color name="i_am_color_18e0">#000018e0</color> + <color name="i_am_color_18e1">#000018e1</color> + <color name="i_am_color_18e2">#000018e2</color> + <color name="i_am_color_18e3">#000018e3</color> + <color name="i_am_color_18e4">#000018e4</color> + <color name="i_am_color_18e5">#000018e5</color> + <color name="i_am_color_18e6">#000018e6</color> + <color name="i_am_color_18e7">#000018e7</color> + <color name="i_am_color_18e8">#000018e8</color> + <color name="i_am_color_18e9">#000018e9</color> + <color name="i_am_color_18ea">#000018ea</color> + <color name="i_am_color_18eb">#000018eb</color> + <color name="i_am_color_18ec">#000018ec</color> + <color name="i_am_color_18ed">#000018ed</color> + <color name="i_am_color_18ee">#000018ee</color> + <color name="i_am_color_18ef">#000018ef</color> + <color name="i_am_color_18f0">#000018f0</color> + <color name="i_am_color_18f1">#000018f1</color> + <color name="i_am_color_18f2">#000018f2</color> + <color name="i_am_color_18f3">#000018f3</color> + <color name="i_am_color_18f4">#000018f4</color> + <color name="i_am_color_18f5">#000018f5</color> + <color name="i_am_color_18f6">#000018f6</color> + <color name="i_am_color_18f7">#000018f7</color> + <color name="i_am_color_18f8">#000018f8</color> + <color name="i_am_color_18f9">#000018f9</color> + <color name="i_am_color_18fa">#000018fa</color> + <color name="i_am_color_18fb">#000018fb</color> + <color name="i_am_color_18fc">#000018fc</color> + <color name="i_am_color_18fd">#000018fd</color> + <color name="i_am_color_18fe">#000018fe</color> + <color name="i_am_color_18ff">#000018ff</color> + <color name="i_am_color_1900">#00001900</color> + <color name="i_am_color_1901">#00001901</color> + <color name="i_am_color_1902">#00001902</color> + <color name="i_am_color_1903">#00001903</color> + <color name="i_am_color_1904">#00001904</color> + <color name="i_am_color_1905">#00001905</color> + <color name="i_am_color_1906">#00001906</color> + <color name="i_am_color_1907">#00001907</color> + <color name="i_am_color_1908">#00001908</color> + <color name="i_am_color_1909">#00001909</color> + <color name="i_am_color_190a">#0000190a</color> + <color name="i_am_color_190b">#0000190b</color> + <color name="i_am_color_190c">#0000190c</color> + <color name="i_am_color_190d">#0000190d</color> + <color name="i_am_color_190e">#0000190e</color> + <color name="i_am_color_190f">#0000190f</color> + <color name="i_am_color_1910">#00001910</color> + <color name="i_am_color_1911">#00001911</color> + <color name="i_am_color_1912">#00001912</color> + <color name="i_am_color_1913">#00001913</color> + <color name="i_am_color_1914">#00001914</color> + <color name="i_am_color_1915">#00001915</color> + <color name="i_am_color_1916">#00001916</color> + <color name="i_am_color_1917">#00001917</color> + <color name="i_am_color_1918">#00001918</color> + <color name="i_am_color_1919">#00001919</color> + <color name="i_am_color_191a">#0000191a</color> + <color name="i_am_color_191b">#0000191b</color> + <color name="i_am_color_191c">#0000191c</color> + <color name="i_am_color_191d">#0000191d</color> + <color name="i_am_color_191e">#0000191e</color> + <color name="i_am_color_191f">#0000191f</color> + <color name="i_am_color_1920">#00001920</color> + <color name="i_am_color_1921">#00001921</color> + <color name="i_am_color_1922">#00001922</color> + <color name="i_am_color_1923">#00001923</color> + <color name="i_am_color_1924">#00001924</color> + <color name="i_am_color_1925">#00001925</color> + <color name="i_am_color_1926">#00001926</color> + <color name="i_am_color_1927">#00001927</color> + <color name="i_am_color_1928">#00001928</color> + <color name="i_am_color_1929">#00001929</color> + <color name="i_am_color_192a">#0000192a</color> + <color name="i_am_color_192b">#0000192b</color> + <color name="i_am_color_192c">#0000192c</color> + <color name="i_am_color_192d">#0000192d</color> + <color name="i_am_color_192e">#0000192e</color> + <color name="i_am_color_192f">#0000192f</color> + <color name="i_am_color_1930">#00001930</color> + <color name="i_am_color_1931">#00001931</color> + <color name="i_am_color_1932">#00001932</color> + <color name="i_am_color_1933">#00001933</color> + <color name="i_am_color_1934">#00001934</color> + <color name="i_am_color_1935">#00001935</color> + <color name="i_am_color_1936">#00001936</color> + <color name="i_am_color_1937">#00001937</color> + <color name="i_am_color_1938">#00001938</color> + <color name="i_am_color_1939">#00001939</color> + <color name="i_am_color_193a">#0000193a</color> + <color name="i_am_color_193b">#0000193b</color> + <color name="i_am_color_193c">#0000193c</color> + <color name="i_am_color_193d">#0000193d</color> + <color name="i_am_color_193e">#0000193e</color> + <color name="i_am_color_193f">#0000193f</color> + <color name="i_am_color_1940">#00001940</color> + <color name="i_am_color_1941">#00001941</color> + <color name="i_am_color_1942">#00001942</color> + <color name="i_am_color_1943">#00001943</color> + <color name="i_am_color_1944">#00001944</color> + <color name="i_am_color_1945">#00001945</color> + <color name="i_am_color_1946">#00001946</color> + <color name="i_am_color_1947">#00001947</color> + <color name="i_am_color_1948">#00001948</color> + <color name="i_am_color_1949">#00001949</color> + <color name="i_am_color_194a">#0000194a</color> + <color name="i_am_color_194b">#0000194b</color> + <color name="i_am_color_194c">#0000194c</color> + <color name="i_am_color_194d">#0000194d</color> + <color name="i_am_color_194e">#0000194e</color> + <color name="i_am_color_194f">#0000194f</color> + <color name="i_am_color_1950">#00001950</color> + <color name="i_am_color_1951">#00001951</color> + <color name="i_am_color_1952">#00001952</color> + <color name="i_am_color_1953">#00001953</color> + <color name="i_am_color_1954">#00001954</color> + <color name="i_am_color_1955">#00001955</color> + <color name="i_am_color_1956">#00001956</color> + <color name="i_am_color_1957">#00001957</color> + <color name="i_am_color_1958">#00001958</color> + <color name="i_am_color_1959">#00001959</color> + <color name="i_am_color_195a">#0000195a</color> + <color name="i_am_color_195b">#0000195b</color> + <color name="i_am_color_195c">#0000195c</color> + <color name="i_am_color_195d">#0000195d</color> + <color name="i_am_color_195e">#0000195e</color> + <color name="i_am_color_195f">#0000195f</color> + <color name="i_am_color_1960">#00001960</color> + <color name="i_am_color_1961">#00001961</color> + <color name="i_am_color_1962">#00001962</color> + <color name="i_am_color_1963">#00001963</color> + <color name="i_am_color_1964">#00001964</color> + <color name="i_am_color_1965">#00001965</color> + <color name="i_am_color_1966">#00001966</color> + <color name="i_am_color_1967">#00001967</color> + <color name="i_am_color_1968">#00001968</color> + <color name="i_am_color_1969">#00001969</color> + <color name="i_am_color_196a">#0000196a</color> + <color name="i_am_color_196b">#0000196b</color> + <color name="i_am_color_196c">#0000196c</color> + <color name="i_am_color_196d">#0000196d</color> + <color name="i_am_color_196e">#0000196e</color> + <color name="i_am_color_196f">#0000196f</color> + <color name="i_am_color_1970">#00001970</color> + <color name="i_am_color_1971">#00001971</color> + <color name="i_am_color_1972">#00001972</color> + <color name="i_am_color_1973">#00001973</color> + <color name="i_am_color_1974">#00001974</color> + <color name="i_am_color_1975">#00001975</color> + <color name="i_am_color_1976">#00001976</color> + <color name="i_am_color_1977">#00001977</color> + <color name="i_am_color_1978">#00001978</color> + <color name="i_am_color_1979">#00001979</color> + <color name="i_am_color_197a">#0000197a</color> + <color name="i_am_color_197b">#0000197b</color> + <color name="i_am_color_197c">#0000197c</color> + <color name="i_am_color_197d">#0000197d</color> + <color name="i_am_color_197e">#0000197e</color> + <color name="i_am_color_197f">#0000197f</color> + <color name="i_am_color_1980">#00001980</color> + <color name="i_am_color_1981">#00001981</color> + <color name="i_am_color_1982">#00001982</color> + <color name="i_am_color_1983">#00001983</color> + <color name="i_am_color_1984">#00001984</color> + <color name="i_am_color_1985">#00001985</color> + <color name="i_am_color_1986">#00001986</color> + <color name="i_am_color_1987">#00001987</color> + <color name="i_am_color_1988">#00001988</color> + <color name="i_am_color_1989">#00001989</color> + <color name="i_am_color_198a">#0000198a</color> + <color name="i_am_color_198b">#0000198b</color> + <color name="i_am_color_198c">#0000198c</color> + <color name="i_am_color_198d">#0000198d</color> + <color name="i_am_color_198e">#0000198e</color> + <color name="i_am_color_198f">#0000198f</color> + <color name="i_am_color_1990">#00001990</color> + <color name="i_am_color_1991">#00001991</color> + <color name="i_am_color_1992">#00001992</color> + <color name="i_am_color_1993">#00001993</color> + <color name="i_am_color_1994">#00001994</color> + <color name="i_am_color_1995">#00001995</color> + <color name="i_am_color_1996">#00001996</color> + <color name="i_am_color_1997">#00001997</color> + <color name="i_am_color_1998">#00001998</color> + <color name="i_am_color_1999">#00001999</color> + <color name="i_am_color_199a">#0000199a</color> + <color name="i_am_color_199b">#0000199b</color> + <color name="i_am_color_199c">#0000199c</color> + <color name="i_am_color_199d">#0000199d</color> + <color name="i_am_color_199e">#0000199e</color> + <color name="i_am_color_199f">#0000199f</color> + <color name="i_am_color_19a0">#000019a0</color> + <color name="i_am_color_19a1">#000019a1</color> + <color name="i_am_color_19a2">#000019a2</color> + <color name="i_am_color_19a3">#000019a3</color> + <color name="i_am_color_19a4">#000019a4</color> + <color name="i_am_color_19a5">#000019a5</color> + <color name="i_am_color_19a6">#000019a6</color> + <color name="i_am_color_19a7">#000019a7</color> + <color name="i_am_color_19a8">#000019a8</color> + <color name="i_am_color_19a9">#000019a9</color> + <color name="i_am_color_19aa">#000019aa</color> + <color name="i_am_color_19ab">#000019ab</color> + <color name="i_am_color_19ac">#000019ac</color> + <color name="i_am_color_19ad">#000019ad</color> + <color name="i_am_color_19ae">#000019ae</color> + <color name="i_am_color_19af">#000019af</color> + <color name="i_am_color_19b0">#000019b0</color> + <color name="i_am_color_19b1">#000019b1</color> + <color name="i_am_color_19b2">#000019b2</color> + <color name="i_am_color_19b3">#000019b3</color> + <color name="i_am_color_19b4">#000019b4</color> + <color name="i_am_color_19b5">#000019b5</color> + <color name="i_am_color_19b6">#000019b6</color> + <color name="i_am_color_19b7">#000019b7</color> + <color name="i_am_color_19b8">#000019b8</color> + <color name="i_am_color_19b9">#000019b9</color> + <color name="i_am_color_19ba">#000019ba</color> + <color name="i_am_color_19bb">#000019bb</color> + <color name="i_am_color_19bc">#000019bc</color> + <color name="i_am_color_19bd">#000019bd</color> + <color name="i_am_color_19be">#000019be</color> + <color name="i_am_color_19bf">#000019bf</color> + <color name="i_am_color_19c0">#000019c0</color> + <color name="i_am_color_19c1">#000019c1</color> + <color name="i_am_color_19c2">#000019c2</color> + <color name="i_am_color_19c3">#000019c3</color> + <color name="i_am_color_19c4">#000019c4</color> + <color name="i_am_color_19c5">#000019c5</color> + <color name="i_am_color_19c6">#000019c6</color> + <color name="i_am_color_19c7">#000019c7</color> + <color name="i_am_color_19c8">#000019c8</color> + <color name="i_am_color_19c9">#000019c9</color> + <color name="i_am_color_19ca">#000019ca</color> + <color name="i_am_color_19cb">#000019cb</color> + <color name="i_am_color_19cc">#000019cc</color> + <color name="i_am_color_19cd">#000019cd</color> + <color name="i_am_color_19ce">#000019ce</color> + <color name="i_am_color_19cf">#000019cf</color> + <color name="i_am_color_19d0">#000019d0</color> + <color name="i_am_color_19d1">#000019d1</color> + <color name="i_am_color_19d2">#000019d2</color> + <color name="i_am_color_19d3">#000019d3</color> + <color name="i_am_color_19d4">#000019d4</color> + <color name="i_am_color_19d5">#000019d5</color> + <color name="i_am_color_19d6">#000019d6</color> + <color name="i_am_color_19d7">#000019d7</color> + <color name="i_am_color_19d8">#000019d8</color> + <color name="i_am_color_19d9">#000019d9</color> + <color name="i_am_color_19da">#000019da</color> + <color name="i_am_color_19db">#000019db</color> + <color name="i_am_color_19dc">#000019dc</color> + <color name="i_am_color_19dd">#000019dd</color> + <color name="i_am_color_19de">#000019de</color> + <color name="i_am_color_19df">#000019df</color> + <color name="i_am_color_19e0">#000019e0</color> + <color name="i_am_color_19e1">#000019e1</color> + <color name="i_am_color_19e2">#000019e2</color> + <color name="i_am_color_19e3">#000019e3</color> + <color name="i_am_color_19e4">#000019e4</color> + <color name="i_am_color_19e5">#000019e5</color> + <color name="i_am_color_19e6">#000019e6</color> + <color name="i_am_color_19e7">#000019e7</color> + <color name="i_am_color_19e8">#000019e8</color> + <color name="i_am_color_19e9">#000019e9</color> + <color name="i_am_color_19ea">#000019ea</color> + <color name="i_am_color_19eb">#000019eb</color> + <color name="i_am_color_19ec">#000019ec</color> + <color name="i_am_color_19ed">#000019ed</color> + <color name="i_am_color_19ee">#000019ee</color> + <color name="i_am_color_19ef">#000019ef</color> + <color name="i_am_color_19f0">#000019f0</color> + <color name="i_am_color_19f1">#000019f1</color> + <color name="i_am_color_19f2">#000019f2</color> + <color name="i_am_color_19f3">#000019f3</color> + <color name="i_am_color_19f4">#000019f4</color> + <color name="i_am_color_19f5">#000019f5</color> + <color name="i_am_color_19f6">#000019f6</color> + <color name="i_am_color_19f7">#000019f7</color> + <color name="i_am_color_19f8">#000019f8</color> + <color name="i_am_color_19f9">#000019f9</color> + <color name="i_am_color_19fa">#000019fa</color> + <color name="i_am_color_19fb">#000019fb</color> + <color name="i_am_color_19fc">#000019fc</color> + <color name="i_am_color_19fd">#000019fd</color> + <color name="i_am_color_19fe">#000019fe</color> + <color name="i_am_color_19ff">#000019ff</color> + <color name="i_am_color_1a00">#00001a00</color> + <color name="i_am_color_1a01">#00001a01</color> + <color name="i_am_color_1a02">#00001a02</color> + <color name="i_am_color_1a03">#00001a03</color> + <color name="i_am_color_1a04">#00001a04</color> + <color name="i_am_color_1a05">#00001a05</color> + <color name="i_am_color_1a06">#00001a06</color> + <color name="i_am_color_1a07">#00001a07</color> + <color name="i_am_color_1a08">#00001a08</color> + <color name="i_am_color_1a09">#00001a09</color> + <color name="i_am_color_1a0a">#00001a0a</color> + <color name="i_am_color_1a0b">#00001a0b</color> + <color name="i_am_color_1a0c">#00001a0c</color> + <color name="i_am_color_1a0d">#00001a0d</color> + <color name="i_am_color_1a0e">#00001a0e</color> + <color name="i_am_color_1a0f">#00001a0f</color> + <color name="i_am_color_1a10">#00001a10</color> + <color name="i_am_color_1a11">#00001a11</color> + <color name="i_am_color_1a12">#00001a12</color> + <color name="i_am_color_1a13">#00001a13</color> + <color name="i_am_color_1a14">#00001a14</color> + <color name="i_am_color_1a15">#00001a15</color> + <color name="i_am_color_1a16">#00001a16</color> + <color name="i_am_color_1a17">#00001a17</color> + <color name="i_am_color_1a18">#00001a18</color> + <color name="i_am_color_1a19">#00001a19</color> + <color name="i_am_color_1a1a">#00001a1a</color> + <color name="i_am_color_1a1b">#00001a1b</color> + <color name="i_am_color_1a1c">#00001a1c</color> + <color name="i_am_color_1a1d">#00001a1d</color> + <color name="i_am_color_1a1e">#00001a1e</color> + <color name="i_am_color_1a1f">#00001a1f</color> + <color name="i_am_color_1a20">#00001a20</color> + <color name="i_am_color_1a21">#00001a21</color> + <color name="i_am_color_1a22">#00001a22</color> + <color name="i_am_color_1a23">#00001a23</color> + <color name="i_am_color_1a24">#00001a24</color> + <color name="i_am_color_1a25">#00001a25</color> + <color name="i_am_color_1a26">#00001a26</color> + <color name="i_am_color_1a27">#00001a27</color> + <color name="i_am_color_1a28">#00001a28</color> + <color name="i_am_color_1a29">#00001a29</color> + <color name="i_am_color_1a2a">#00001a2a</color> + <color name="i_am_color_1a2b">#00001a2b</color> + <color name="i_am_color_1a2c">#00001a2c</color> + <color name="i_am_color_1a2d">#00001a2d</color> + <color name="i_am_color_1a2e">#00001a2e</color> + <color name="i_am_color_1a2f">#00001a2f</color> + <color name="i_am_color_1a30">#00001a30</color> + <color name="i_am_color_1a31">#00001a31</color> + <color name="i_am_color_1a32">#00001a32</color> + <color name="i_am_color_1a33">#00001a33</color> + <color name="i_am_color_1a34">#00001a34</color> + <color name="i_am_color_1a35">#00001a35</color> + <color name="i_am_color_1a36">#00001a36</color> + <color name="i_am_color_1a37">#00001a37</color> + <color name="i_am_color_1a38">#00001a38</color> + <color name="i_am_color_1a39">#00001a39</color> + <color name="i_am_color_1a3a">#00001a3a</color> + <color name="i_am_color_1a3b">#00001a3b</color> + <color name="i_am_color_1a3c">#00001a3c</color> + <color name="i_am_color_1a3d">#00001a3d</color> + <color name="i_am_color_1a3e">#00001a3e</color> + <color name="i_am_color_1a3f">#00001a3f</color> + <color name="i_am_color_1a40">#00001a40</color> + <color name="i_am_color_1a41">#00001a41</color> + <color name="i_am_color_1a42">#00001a42</color> + <color name="i_am_color_1a43">#00001a43</color> + <color name="i_am_color_1a44">#00001a44</color> + <color name="i_am_color_1a45">#00001a45</color> + <color name="i_am_color_1a46">#00001a46</color> + <color name="i_am_color_1a47">#00001a47</color> + <color name="i_am_color_1a48">#00001a48</color> + <color name="i_am_color_1a49">#00001a49</color> + <color name="i_am_color_1a4a">#00001a4a</color> + <color name="i_am_color_1a4b">#00001a4b</color> + <color name="i_am_color_1a4c">#00001a4c</color> + <color name="i_am_color_1a4d">#00001a4d</color> + <color name="i_am_color_1a4e">#00001a4e</color> + <color name="i_am_color_1a4f">#00001a4f</color> + <color name="i_am_color_1a50">#00001a50</color> + <color name="i_am_color_1a51">#00001a51</color> + <color name="i_am_color_1a52">#00001a52</color> + <color name="i_am_color_1a53">#00001a53</color> + <color name="i_am_color_1a54">#00001a54</color> + <color name="i_am_color_1a55">#00001a55</color> + <color name="i_am_color_1a56">#00001a56</color> + <color name="i_am_color_1a57">#00001a57</color> + <color name="i_am_color_1a58">#00001a58</color> + <color name="i_am_color_1a59">#00001a59</color> + <color name="i_am_color_1a5a">#00001a5a</color> + <color name="i_am_color_1a5b">#00001a5b</color> + <color name="i_am_color_1a5c">#00001a5c</color> + <color name="i_am_color_1a5d">#00001a5d</color> + <color name="i_am_color_1a5e">#00001a5e</color> + <color name="i_am_color_1a5f">#00001a5f</color> + <color name="i_am_color_1a60">#00001a60</color> + <color name="i_am_color_1a61">#00001a61</color> + <color name="i_am_color_1a62">#00001a62</color> + <color name="i_am_color_1a63">#00001a63</color> + <color name="i_am_color_1a64">#00001a64</color> + <color name="i_am_color_1a65">#00001a65</color> + <color name="i_am_color_1a66">#00001a66</color> + <color name="i_am_color_1a67">#00001a67</color> + <color name="i_am_color_1a68">#00001a68</color> + <color name="i_am_color_1a69">#00001a69</color> + <color name="i_am_color_1a6a">#00001a6a</color> + <color name="i_am_color_1a6b">#00001a6b</color> + <color name="i_am_color_1a6c">#00001a6c</color> + <color name="i_am_color_1a6d">#00001a6d</color> + <color name="i_am_color_1a6e">#00001a6e</color> + <color name="i_am_color_1a6f">#00001a6f</color> + <color name="i_am_color_1a70">#00001a70</color> + <color name="i_am_color_1a71">#00001a71</color> + <color name="i_am_color_1a72">#00001a72</color> + <color name="i_am_color_1a73">#00001a73</color> + <color name="i_am_color_1a74">#00001a74</color> + <color name="i_am_color_1a75">#00001a75</color> + <color name="i_am_color_1a76">#00001a76</color> + <color name="i_am_color_1a77">#00001a77</color> + <color name="i_am_color_1a78">#00001a78</color> + <color name="i_am_color_1a79">#00001a79</color> + <color name="i_am_color_1a7a">#00001a7a</color> + <color name="i_am_color_1a7b">#00001a7b</color> + <color name="i_am_color_1a7c">#00001a7c</color> + <color name="i_am_color_1a7d">#00001a7d</color> + <color name="i_am_color_1a7e">#00001a7e</color> + <color name="i_am_color_1a7f">#00001a7f</color> + <color name="i_am_color_1a80">#00001a80</color> + <color name="i_am_color_1a81">#00001a81</color> + <color name="i_am_color_1a82">#00001a82</color> + <color name="i_am_color_1a83">#00001a83</color> + <color name="i_am_color_1a84">#00001a84</color> + <color name="i_am_color_1a85">#00001a85</color> + <color name="i_am_color_1a86">#00001a86</color> + <color name="i_am_color_1a87">#00001a87</color> + <color name="i_am_color_1a88">#00001a88</color> + <color name="i_am_color_1a89">#00001a89</color> + <color name="i_am_color_1a8a">#00001a8a</color> + <color name="i_am_color_1a8b">#00001a8b</color> + <color name="i_am_color_1a8c">#00001a8c</color> + <color name="i_am_color_1a8d">#00001a8d</color> + <color name="i_am_color_1a8e">#00001a8e</color> + <color name="i_am_color_1a8f">#00001a8f</color> + <color name="i_am_color_1a90">#00001a90</color> + <color name="i_am_color_1a91">#00001a91</color> + <color name="i_am_color_1a92">#00001a92</color> + <color name="i_am_color_1a93">#00001a93</color> + <color name="i_am_color_1a94">#00001a94</color> + <color name="i_am_color_1a95">#00001a95</color> + <color name="i_am_color_1a96">#00001a96</color> + <color name="i_am_color_1a97">#00001a97</color> + <color name="i_am_color_1a98">#00001a98</color> + <color name="i_am_color_1a99">#00001a99</color> + <color name="i_am_color_1a9a">#00001a9a</color> + <color name="i_am_color_1a9b">#00001a9b</color> + <color name="i_am_color_1a9c">#00001a9c</color> + <color name="i_am_color_1a9d">#00001a9d</color> + <color name="i_am_color_1a9e">#00001a9e</color> + <color name="i_am_color_1a9f">#00001a9f</color> + <color name="i_am_color_1aa0">#00001aa0</color> + <color name="i_am_color_1aa1">#00001aa1</color> + <color name="i_am_color_1aa2">#00001aa2</color> + <color name="i_am_color_1aa3">#00001aa3</color> + <color name="i_am_color_1aa4">#00001aa4</color> + <color name="i_am_color_1aa5">#00001aa5</color> + <color name="i_am_color_1aa6">#00001aa6</color> + <color name="i_am_color_1aa7">#00001aa7</color> + <color name="i_am_color_1aa8">#00001aa8</color> + <color name="i_am_color_1aa9">#00001aa9</color> + <color name="i_am_color_1aaa">#00001aaa</color> + <color name="i_am_color_1aab">#00001aab</color> + <color name="i_am_color_1aac">#00001aac</color> + <color name="i_am_color_1aad">#00001aad</color> + <color name="i_am_color_1aae">#00001aae</color> + <color name="i_am_color_1aaf">#00001aaf</color> + <color name="i_am_color_1ab0">#00001ab0</color> + <color name="i_am_color_1ab1">#00001ab1</color> + <color name="i_am_color_1ab2">#00001ab2</color> + <color name="i_am_color_1ab3">#00001ab3</color> + <color name="i_am_color_1ab4">#00001ab4</color> + <color name="i_am_color_1ab5">#00001ab5</color> + <color name="i_am_color_1ab6">#00001ab6</color> + <color name="i_am_color_1ab7">#00001ab7</color> + <color name="i_am_color_1ab8">#00001ab8</color> + <color name="i_am_color_1ab9">#00001ab9</color> + <color name="i_am_color_1aba">#00001aba</color> + <color name="i_am_color_1abb">#00001abb</color> + <color name="i_am_color_1abc">#00001abc</color> + <color name="i_am_color_1abd">#00001abd</color> + <color name="i_am_color_1abe">#00001abe</color> + <color name="i_am_color_1abf">#00001abf</color> + <color name="i_am_color_1ac0">#00001ac0</color> + <color name="i_am_color_1ac1">#00001ac1</color> + <color name="i_am_color_1ac2">#00001ac2</color> + <color name="i_am_color_1ac3">#00001ac3</color> + <color name="i_am_color_1ac4">#00001ac4</color> + <color name="i_am_color_1ac5">#00001ac5</color> + <color name="i_am_color_1ac6">#00001ac6</color> + <color name="i_am_color_1ac7">#00001ac7</color> + <color name="i_am_color_1ac8">#00001ac8</color> + <color name="i_am_color_1ac9">#00001ac9</color> + <color name="i_am_color_1aca">#00001aca</color> + <color name="i_am_color_1acb">#00001acb</color> + <color name="i_am_color_1acc">#00001acc</color> + <color name="i_am_color_1acd">#00001acd</color> + <color name="i_am_color_1ace">#00001ace</color> + <color name="i_am_color_1acf">#00001acf</color> + <color name="i_am_color_1ad0">#00001ad0</color> + <color name="i_am_color_1ad1">#00001ad1</color> + <color name="i_am_color_1ad2">#00001ad2</color> + <color name="i_am_color_1ad3">#00001ad3</color> + <color name="i_am_color_1ad4">#00001ad4</color> + <color name="i_am_color_1ad5">#00001ad5</color> + <color name="i_am_color_1ad6">#00001ad6</color> + <color name="i_am_color_1ad7">#00001ad7</color> + <color name="i_am_color_1ad8">#00001ad8</color> + <color name="i_am_color_1ad9">#00001ad9</color> + <color name="i_am_color_1ada">#00001ada</color> + <color name="i_am_color_1adb">#00001adb</color> + <color name="i_am_color_1adc">#00001adc</color> + <color name="i_am_color_1add">#00001add</color> + <color name="i_am_color_1ade">#00001ade</color> + <color name="i_am_color_1adf">#00001adf</color> + <color name="i_am_color_1ae0">#00001ae0</color> + <color name="i_am_color_1ae1">#00001ae1</color> + <color name="i_am_color_1ae2">#00001ae2</color> + <color name="i_am_color_1ae3">#00001ae3</color> + <color name="i_am_color_1ae4">#00001ae4</color> + <color name="i_am_color_1ae5">#00001ae5</color> + <color name="i_am_color_1ae6">#00001ae6</color> + <color name="i_am_color_1ae7">#00001ae7</color> + <color name="i_am_color_1ae8">#00001ae8</color> + <color name="i_am_color_1ae9">#00001ae9</color> + <color name="i_am_color_1aea">#00001aea</color> + <color name="i_am_color_1aeb">#00001aeb</color> + <color name="i_am_color_1aec">#00001aec</color> + <color name="i_am_color_1aed">#00001aed</color> + <color name="i_am_color_1aee">#00001aee</color> + <color name="i_am_color_1aef">#00001aef</color> + <color name="i_am_color_1af0">#00001af0</color> + <color name="i_am_color_1af1">#00001af1</color> + <color name="i_am_color_1af2">#00001af2</color> + <color name="i_am_color_1af3">#00001af3</color> + <color name="i_am_color_1af4">#00001af4</color> + <color name="i_am_color_1af5">#00001af5</color> + <color name="i_am_color_1af6">#00001af6</color> + <color name="i_am_color_1af7">#00001af7</color> + <color name="i_am_color_1af8">#00001af8</color> + <color name="i_am_color_1af9">#00001af9</color> + <color name="i_am_color_1afa">#00001afa</color> + <color name="i_am_color_1afb">#00001afb</color> + <color name="i_am_color_1afc">#00001afc</color> + <color name="i_am_color_1afd">#00001afd</color> + <color name="i_am_color_1afe">#00001afe</color> + <color name="i_am_color_1aff">#00001aff</color> + <color name="i_am_color_1b00">#00001b00</color> + <color name="i_am_color_1b01">#00001b01</color> + <color name="i_am_color_1b02">#00001b02</color> + <color name="i_am_color_1b03">#00001b03</color> + <color name="i_am_color_1b04">#00001b04</color> + <color name="i_am_color_1b05">#00001b05</color> + <color name="i_am_color_1b06">#00001b06</color> + <color name="i_am_color_1b07">#00001b07</color> + <color name="i_am_color_1b08">#00001b08</color> + <color name="i_am_color_1b09">#00001b09</color> + <color name="i_am_color_1b0a">#00001b0a</color> + <color name="i_am_color_1b0b">#00001b0b</color> + <color name="i_am_color_1b0c">#00001b0c</color> + <color name="i_am_color_1b0d">#00001b0d</color> + <color name="i_am_color_1b0e">#00001b0e</color> + <color name="i_am_color_1b0f">#00001b0f</color> + <color name="i_am_color_1b10">#00001b10</color> + <color name="i_am_color_1b11">#00001b11</color> + <color name="i_am_color_1b12">#00001b12</color> + <color name="i_am_color_1b13">#00001b13</color> + <color name="i_am_color_1b14">#00001b14</color> + <color name="i_am_color_1b15">#00001b15</color> + <color name="i_am_color_1b16">#00001b16</color> + <color name="i_am_color_1b17">#00001b17</color> + <color name="i_am_color_1b18">#00001b18</color> + <color name="i_am_color_1b19">#00001b19</color> + <color name="i_am_color_1b1a">#00001b1a</color> + <color name="i_am_color_1b1b">#00001b1b</color> + <color name="i_am_color_1b1c">#00001b1c</color> + <color name="i_am_color_1b1d">#00001b1d</color> + <color name="i_am_color_1b1e">#00001b1e</color> + <color name="i_am_color_1b1f">#00001b1f</color> + <color name="i_am_color_1b20">#00001b20</color> + <color name="i_am_color_1b21">#00001b21</color> + <color name="i_am_color_1b22">#00001b22</color> + <color name="i_am_color_1b23">#00001b23</color> + <color name="i_am_color_1b24">#00001b24</color> + <color name="i_am_color_1b25">#00001b25</color> + <color name="i_am_color_1b26">#00001b26</color> + <color name="i_am_color_1b27">#00001b27</color> + <color name="i_am_color_1b28">#00001b28</color> + <color name="i_am_color_1b29">#00001b29</color> + <color name="i_am_color_1b2a">#00001b2a</color> + <color name="i_am_color_1b2b">#00001b2b</color> + <color name="i_am_color_1b2c">#00001b2c</color> + <color name="i_am_color_1b2d">#00001b2d</color> + <color name="i_am_color_1b2e">#00001b2e</color> + <color name="i_am_color_1b2f">#00001b2f</color> + <color name="i_am_color_1b30">#00001b30</color> + <color name="i_am_color_1b31">#00001b31</color> + <color name="i_am_color_1b32">#00001b32</color> + <color name="i_am_color_1b33">#00001b33</color> + <color name="i_am_color_1b34">#00001b34</color> + <color name="i_am_color_1b35">#00001b35</color> + <color name="i_am_color_1b36">#00001b36</color> + <color name="i_am_color_1b37">#00001b37</color> + <color name="i_am_color_1b38">#00001b38</color> + <color name="i_am_color_1b39">#00001b39</color> + <color name="i_am_color_1b3a">#00001b3a</color> + <color name="i_am_color_1b3b">#00001b3b</color> + <color name="i_am_color_1b3c">#00001b3c</color> + <color name="i_am_color_1b3d">#00001b3d</color> + <color name="i_am_color_1b3e">#00001b3e</color> + <color name="i_am_color_1b3f">#00001b3f</color> + <color name="i_am_color_1b40">#00001b40</color> + <color name="i_am_color_1b41">#00001b41</color> + <color name="i_am_color_1b42">#00001b42</color> + <color name="i_am_color_1b43">#00001b43</color> + <color name="i_am_color_1b44">#00001b44</color> + <color name="i_am_color_1b45">#00001b45</color> + <color name="i_am_color_1b46">#00001b46</color> + <color name="i_am_color_1b47">#00001b47</color> + <color name="i_am_color_1b48">#00001b48</color> + <color name="i_am_color_1b49">#00001b49</color> + <color name="i_am_color_1b4a">#00001b4a</color> + <color name="i_am_color_1b4b">#00001b4b</color> + <color name="i_am_color_1b4c">#00001b4c</color> + <color name="i_am_color_1b4d">#00001b4d</color> + <color name="i_am_color_1b4e">#00001b4e</color> + <color name="i_am_color_1b4f">#00001b4f</color> + <color name="i_am_color_1b50">#00001b50</color> + <color name="i_am_color_1b51">#00001b51</color> + <color name="i_am_color_1b52">#00001b52</color> + <color name="i_am_color_1b53">#00001b53</color> + <color name="i_am_color_1b54">#00001b54</color> + <color name="i_am_color_1b55">#00001b55</color> + <color name="i_am_color_1b56">#00001b56</color> + <color name="i_am_color_1b57">#00001b57</color> + <color name="i_am_color_1b58">#00001b58</color> + <color name="i_am_color_1b59">#00001b59</color> + <color name="i_am_color_1b5a">#00001b5a</color> + <color name="i_am_color_1b5b">#00001b5b</color> + <color name="i_am_color_1b5c">#00001b5c</color> + <color name="i_am_color_1b5d">#00001b5d</color> + <color name="i_am_color_1b5e">#00001b5e</color> + <color name="i_am_color_1b5f">#00001b5f</color> + <color name="i_am_color_1b60">#00001b60</color> + <color name="i_am_color_1b61">#00001b61</color> + <color name="i_am_color_1b62">#00001b62</color> + <color name="i_am_color_1b63">#00001b63</color> + <color name="i_am_color_1b64">#00001b64</color> + <color name="i_am_color_1b65">#00001b65</color> + <color name="i_am_color_1b66">#00001b66</color> + <color name="i_am_color_1b67">#00001b67</color> + <color name="i_am_color_1b68">#00001b68</color> + <color name="i_am_color_1b69">#00001b69</color> + <color name="i_am_color_1b6a">#00001b6a</color> + <color name="i_am_color_1b6b">#00001b6b</color> + <color name="i_am_color_1b6c">#00001b6c</color> + <color name="i_am_color_1b6d">#00001b6d</color> + <color name="i_am_color_1b6e">#00001b6e</color> + <color name="i_am_color_1b6f">#00001b6f</color> + <color name="i_am_color_1b70">#00001b70</color> + <color name="i_am_color_1b71">#00001b71</color> + <color name="i_am_color_1b72">#00001b72</color> + <color name="i_am_color_1b73">#00001b73</color> + <color name="i_am_color_1b74">#00001b74</color> + <color name="i_am_color_1b75">#00001b75</color> + <color name="i_am_color_1b76">#00001b76</color> + <color name="i_am_color_1b77">#00001b77</color> + <color name="i_am_color_1b78">#00001b78</color> + <color name="i_am_color_1b79">#00001b79</color> + <color name="i_am_color_1b7a">#00001b7a</color> + <color name="i_am_color_1b7b">#00001b7b</color> + <color name="i_am_color_1b7c">#00001b7c</color> + <color name="i_am_color_1b7d">#00001b7d</color> + <color name="i_am_color_1b7e">#00001b7e</color> + <color name="i_am_color_1b7f">#00001b7f</color> + <color name="i_am_color_1b80">#00001b80</color> + <color name="i_am_color_1b81">#00001b81</color> + <color name="i_am_color_1b82">#00001b82</color> + <color name="i_am_color_1b83">#00001b83</color> + <color name="i_am_color_1b84">#00001b84</color> + <color name="i_am_color_1b85">#00001b85</color> + <color name="i_am_color_1b86">#00001b86</color> + <color name="i_am_color_1b87">#00001b87</color> + <color name="i_am_color_1b88">#00001b88</color> + <color name="i_am_color_1b89">#00001b89</color> + <color name="i_am_color_1b8a">#00001b8a</color> + <color name="i_am_color_1b8b">#00001b8b</color> + <color name="i_am_color_1b8c">#00001b8c</color> + <color name="i_am_color_1b8d">#00001b8d</color> + <color name="i_am_color_1b8e">#00001b8e</color> + <color name="i_am_color_1b8f">#00001b8f</color> + <color name="i_am_color_1b90">#00001b90</color> + <color name="i_am_color_1b91">#00001b91</color> + <color name="i_am_color_1b92">#00001b92</color> + <color name="i_am_color_1b93">#00001b93</color> + <color name="i_am_color_1b94">#00001b94</color> + <color name="i_am_color_1b95">#00001b95</color> + <color name="i_am_color_1b96">#00001b96</color> + <color name="i_am_color_1b97">#00001b97</color> + <color name="i_am_color_1b98">#00001b98</color> + <color name="i_am_color_1b99">#00001b99</color> + <color name="i_am_color_1b9a">#00001b9a</color> + <color name="i_am_color_1b9b">#00001b9b</color> + <color name="i_am_color_1b9c">#00001b9c</color> + <color name="i_am_color_1b9d">#00001b9d</color> + <color name="i_am_color_1b9e">#00001b9e</color> + <color name="i_am_color_1b9f">#00001b9f</color> + <color name="i_am_color_1ba0">#00001ba0</color> + <color name="i_am_color_1ba1">#00001ba1</color> + <color name="i_am_color_1ba2">#00001ba2</color> + <color name="i_am_color_1ba3">#00001ba3</color> + <color name="i_am_color_1ba4">#00001ba4</color> + <color name="i_am_color_1ba5">#00001ba5</color> + <color name="i_am_color_1ba6">#00001ba6</color> + <color name="i_am_color_1ba7">#00001ba7</color> + <color name="i_am_color_1ba8">#00001ba8</color> + <color name="i_am_color_1ba9">#00001ba9</color> + <color name="i_am_color_1baa">#00001baa</color> + <color name="i_am_color_1bab">#00001bab</color> + <color name="i_am_color_1bac">#00001bac</color> + <color name="i_am_color_1bad">#00001bad</color> + <color name="i_am_color_1bae">#00001bae</color> + <color name="i_am_color_1baf">#00001baf</color> + <color name="i_am_color_1bb0">#00001bb0</color> + <color name="i_am_color_1bb1">#00001bb1</color> + <color name="i_am_color_1bb2">#00001bb2</color> + <color name="i_am_color_1bb3">#00001bb3</color> + <color name="i_am_color_1bb4">#00001bb4</color> + <color name="i_am_color_1bb5">#00001bb5</color> + <color name="i_am_color_1bb6">#00001bb6</color> + <color name="i_am_color_1bb7">#00001bb7</color> + <color name="i_am_color_1bb8">#00001bb8</color> + <color name="i_am_color_1bb9">#00001bb9</color> + <color name="i_am_color_1bba">#00001bba</color> + <color name="i_am_color_1bbb">#00001bbb</color> + <color name="i_am_color_1bbc">#00001bbc</color> + <color name="i_am_color_1bbd">#00001bbd</color> + <color name="i_am_color_1bbe">#00001bbe</color> + <color name="i_am_color_1bbf">#00001bbf</color> + <color name="i_am_color_1bc0">#00001bc0</color> + <color name="i_am_color_1bc1">#00001bc1</color> + <color name="i_am_color_1bc2">#00001bc2</color> + <color name="i_am_color_1bc3">#00001bc3</color> + <color name="i_am_color_1bc4">#00001bc4</color> + <color name="i_am_color_1bc5">#00001bc5</color> + <color name="i_am_color_1bc6">#00001bc6</color> + <color name="i_am_color_1bc7">#00001bc7</color> + <color name="i_am_color_1bc8">#00001bc8</color> + <color name="i_am_color_1bc9">#00001bc9</color> + <color name="i_am_color_1bca">#00001bca</color> + <color name="i_am_color_1bcb">#00001bcb</color> + <color name="i_am_color_1bcc">#00001bcc</color> + <color name="i_am_color_1bcd">#00001bcd</color> + <color name="i_am_color_1bce">#00001bce</color> + <color name="i_am_color_1bcf">#00001bcf</color> + <color name="i_am_color_1bd0">#00001bd0</color> + <color name="i_am_color_1bd1">#00001bd1</color> + <color name="i_am_color_1bd2">#00001bd2</color> + <color name="i_am_color_1bd3">#00001bd3</color> + <color name="i_am_color_1bd4">#00001bd4</color> + <color name="i_am_color_1bd5">#00001bd5</color> + <color name="i_am_color_1bd6">#00001bd6</color> + <color name="i_am_color_1bd7">#00001bd7</color> + <color name="i_am_color_1bd8">#00001bd8</color> + <color name="i_am_color_1bd9">#00001bd9</color> + <color name="i_am_color_1bda">#00001bda</color> + <color name="i_am_color_1bdb">#00001bdb</color> + <color name="i_am_color_1bdc">#00001bdc</color> + <color name="i_am_color_1bdd">#00001bdd</color> + <color name="i_am_color_1bde">#00001bde</color> + <color name="i_am_color_1bdf">#00001bdf</color> + <color name="i_am_color_1be0">#00001be0</color> + <color name="i_am_color_1be1">#00001be1</color> + <color name="i_am_color_1be2">#00001be2</color> + <color name="i_am_color_1be3">#00001be3</color> + <color name="i_am_color_1be4">#00001be4</color> + <color name="i_am_color_1be5">#00001be5</color> + <color name="i_am_color_1be6">#00001be6</color> + <color name="i_am_color_1be7">#00001be7</color> + <color name="i_am_color_1be8">#00001be8</color> + <color name="i_am_color_1be9">#00001be9</color> + <color name="i_am_color_1bea">#00001bea</color> + <color name="i_am_color_1beb">#00001beb</color> + <color name="i_am_color_1bec">#00001bec</color> + <color name="i_am_color_1bed">#00001bed</color> + <color name="i_am_color_1bee">#00001bee</color> + <color name="i_am_color_1bef">#00001bef</color> + <color name="i_am_color_1bf0">#00001bf0</color> + <color name="i_am_color_1bf1">#00001bf1</color> + <color name="i_am_color_1bf2">#00001bf2</color> + <color name="i_am_color_1bf3">#00001bf3</color> + <color name="i_am_color_1bf4">#00001bf4</color> + <color name="i_am_color_1bf5">#00001bf5</color> + <color name="i_am_color_1bf6">#00001bf6</color> + <color name="i_am_color_1bf7">#00001bf7</color> + <color name="i_am_color_1bf8">#00001bf8</color> + <color name="i_am_color_1bf9">#00001bf9</color> + <color name="i_am_color_1bfa">#00001bfa</color> + <color name="i_am_color_1bfb">#00001bfb</color> + <color name="i_am_color_1bfc">#00001bfc</color> + <color name="i_am_color_1bfd">#00001bfd</color> + <color name="i_am_color_1bfe">#00001bfe</color> + <color name="i_am_color_1bff">#00001bff</color> + <color name="i_am_color_1c00">#00001c00</color> + <color name="i_am_color_1c01">#00001c01</color> + <color name="i_am_color_1c02">#00001c02</color> + <color name="i_am_color_1c03">#00001c03</color> + <color name="i_am_color_1c04">#00001c04</color> + <color name="i_am_color_1c05">#00001c05</color> + <color name="i_am_color_1c06">#00001c06</color> + <color name="i_am_color_1c07">#00001c07</color> + <color name="i_am_color_1c08">#00001c08</color> + <color name="i_am_color_1c09">#00001c09</color> + <color name="i_am_color_1c0a">#00001c0a</color> + <color name="i_am_color_1c0b">#00001c0b</color> + <color name="i_am_color_1c0c">#00001c0c</color> + <color name="i_am_color_1c0d">#00001c0d</color> + <color name="i_am_color_1c0e">#00001c0e</color> + <color name="i_am_color_1c0f">#00001c0f</color> + <color name="i_am_color_1c10">#00001c10</color> + <color name="i_am_color_1c11">#00001c11</color> + <color name="i_am_color_1c12">#00001c12</color> + <color name="i_am_color_1c13">#00001c13</color> + <color name="i_am_color_1c14">#00001c14</color> + <color name="i_am_color_1c15">#00001c15</color> + <color name="i_am_color_1c16">#00001c16</color> + <color name="i_am_color_1c17">#00001c17</color> + <color name="i_am_color_1c18">#00001c18</color> + <color name="i_am_color_1c19">#00001c19</color> + <color name="i_am_color_1c1a">#00001c1a</color> + <color name="i_am_color_1c1b">#00001c1b</color> + <color name="i_am_color_1c1c">#00001c1c</color> + <color name="i_am_color_1c1d">#00001c1d</color> + <color name="i_am_color_1c1e">#00001c1e</color> + <color name="i_am_color_1c1f">#00001c1f</color> + <color name="i_am_color_1c20">#00001c20</color> + <color name="i_am_color_1c21">#00001c21</color> + <color name="i_am_color_1c22">#00001c22</color> + <color name="i_am_color_1c23">#00001c23</color> + <color name="i_am_color_1c24">#00001c24</color> + <color name="i_am_color_1c25">#00001c25</color> + <color name="i_am_color_1c26">#00001c26</color> + <color name="i_am_color_1c27">#00001c27</color> + <color name="i_am_color_1c28">#00001c28</color> + <color name="i_am_color_1c29">#00001c29</color> + <color name="i_am_color_1c2a">#00001c2a</color> + <color name="i_am_color_1c2b">#00001c2b</color> + <color name="i_am_color_1c2c">#00001c2c</color> + <color name="i_am_color_1c2d">#00001c2d</color> + <color name="i_am_color_1c2e">#00001c2e</color> + <color name="i_am_color_1c2f">#00001c2f</color> + <color name="i_am_color_1c30">#00001c30</color> + <color name="i_am_color_1c31">#00001c31</color> + <color name="i_am_color_1c32">#00001c32</color> + <color name="i_am_color_1c33">#00001c33</color> + <color name="i_am_color_1c34">#00001c34</color> + <color name="i_am_color_1c35">#00001c35</color> + <color name="i_am_color_1c36">#00001c36</color> + <color name="i_am_color_1c37">#00001c37</color> + <color name="i_am_color_1c38">#00001c38</color> + <color name="i_am_color_1c39">#00001c39</color> + <color name="i_am_color_1c3a">#00001c3a</color> + <color name="i_am_color_1c3b">#00001c3b</color> + <color name="i_am_color_1c3c">#00001c3c</color> + <color name="i_am_color_1c3d">#00001c3d</color> + <color name="i_am_color_1c3e">#00001c3e</color> + <color name="i_am_color_1c3f">#00001c3f</color> + <color name="i_am_color_1c40">#00001c40</color> + <color name="i_am_color_1c41">#00001c41</color> + <color name="i_am_color_1c42">#00001c42</color> + <color name="i_am_color_1c43">#00001c43</color> + <color name="i_am_color_1c44">#00001c44</color> + <color name="i_am_color_1c45">#00001c45</color> + <color name="i_am_color_1c46">#00001c46</color> + <color name="i_am_color_1c47">#00001c47</color> + <color name="i_am_color_1c48">#00001c48</color> + <color name="i_am_color_1c49">#00001c49</color> + <color name="i_am_color_1c4a">#00001c4a</color> + <color name="i_am_color_1c4b">#00001c4b</color> + <color name="i_am_color_1c4c">#00001c4c</color> + <color name="i_am_color_1c4d">#00001c4d</color> + <color name="i_am_color_1c4e">#00001c4e</color> + <color name="i_am_color_1c4f">#00001c4f</color> + <color name="i_am_color_1c50">#00001c50</color> + <color name="i_am_color_1c51">#00001c51</color> + <color name="i_am_color_1c52">#00001c52</color> + <color name="i_am_color_1c53">#00001c53</color> + <color name="i_am_color_1c54">#00001c54</color> + <color name="i_am_color_1c55">#00001c55</color> + <color name="i_am_color_1c56">#00001c56</color> + <color name="i_am_color_1c57">#00001c57</color> + <color name="i_am_color_1c58">#00001c58</color> + <color name="i_am_color_1c59">#00001c59</color> + <color name="i_am_color_1c5a">#00001c5a</color> + <color name="i_am_color_1c5b">#00001c5b</color> + <color name="i_am_color_1c5c">#00001c5c</color> + <color name="i_am_color_1c5d">#00001c5d</color> + <color name="i_am_color_1c5e">#00001c5e</color> + <color name="i_am_color_1c5f">#00001c5f</color> + <color name="i_am_color_1c60">#00001c60</color> + <color name="i_am_color_1c61">#00001c61</color> + <color name="i_am_color_1c62">#00001c62</color> + <color name="i_am_color_1c63">#00001c63</color> + <color name="i_am_color_1c64">#00001c64</color> + <color name="i_am_color_1c65">#00001c65</color> + <color name="i_am_color_1c66">#00001c66</color> + <color name="i_am_color_1c67">#00001c67</color> + <color name="i_am_color_1c68">#00001c68</color> + <color name="i_am_color_1c69">#00001c69</color> + <color name="i_am_color_1c6a">#00001c6a</color> + <color name="i_am_color_1c6b">#00001c6b</color> + <color name="i_am_color_1c6c">#00001c6c</color> + <color name="i_am_color_1c6d">#00001c6d</color> + <color name="i_am_color_1c6e">#00001c6e</color> + <color name="i_am_color_1c6f">#00001c6f</color> + <color name="i_am_color_1c70">#00001c70</color> + <color name="i_am_color_1c71">#00001c71</color> + <color name="i_am_color_1c72">#00001c72</color> + <color name="i_am_color_1c73">#00001c73</color> + <color name="i_am_color_1c74">#00001c74</color> + <color name="i_am_color_1c75">#00001c75</color> + <color name="i_am_color_1c76">#00001c76</color> + <color name="i_am_color_1c77">#00001c77</color> + <color name="i_am_color_1c78">#00001c78</color> + <color name="i_am_color_1c79">#00001c79</color> + <color name="i_am_color_1c7a">#00001c7a</color> + <color name="i_am_color_1c7b">#00001c7b</color> + <color name="i_am_color_1c7c">#00001c7c</color> + <color name="i_am_color_1c7d">#00001c7d</color> + <color name="i_am_color_1c7e">#00001c7e</color> + <color name="i_am_color_1c7f">#00001c7f</color> + <color name="i_am_color_1c80">#00001c80</color> + <color name="i_am_color_1c81">#00001c81</color> + <color name="i_am_color_1c82">#00001c82</color> + <color name="i_am_color_1c83">#00001c83</color> + <color name="i_am_color_1c84">#00001c84</color> + <color name="i_am_color_1c85">#00001c85</color> + <color name="i_am_color_1c86">#00001c86</color> + <color name="i_am_color_1c87">#00001c87</color> + <color name="i_am_color_1c88">#00001c88</color> + <color name="i_am_color_1c89">#00001c89</color> + <color name="i_am_color_1c8a">#00001c8a</color> + <color name="i_am_color_1c8b">#00001c8b</color> + <color name="i_am_color_1c8c">#00001c8c</color> + <color name="i_am_color_1c8d">#00001c8d</color> + <color name="i_am_color_1c8e">#00001c8e</color> + <color name="i_am_color_1c8f">#00001c8f</color> + <color name="i_am_color_1c90">#00001c90</color> + <color name="i_am_color_1c91">#00001c91</color> + <color name="i_am_color_1c92">#00001c92</color> + <color name="i_am_color_1c93">#00001c93</color> + <color name="i_am_color_1c94">#00001c94</color> + <color name="i_am_color_1c95">#00001c95</color> + <color name="i_am_color_1c96">#00001c96</color> + <color name="i_am_color_1c97">#00001c97</color> + <color name="i_am_color_1c98">#00001c98</color> + <color name="i_am_color_1c99">#00001c99</color> + <color name="i_am_color_1c9a">#00001c9a</color> + <color name="i_am_color_1c9b">#00001c9b</color> + <color name="i_am_color_1c9c">#00001c9c</color> + <color name="i_am_color_1c9d">#00001c9d</color> + <color name="i_am_color_1c9e">#00001c9e</color> + <color name="i_am_color_1c9f">#00001c9f</color> + <color name="i_am_color_1ca0">#00001ca0</color> + <color name="i_am_color_1ca1">#00001ca1</color> + <color name="i_am_color_1ca2">#00001ca2</color> + <color name="i_am_color_1ca3">#00001ca3</color> + <color name="i_am_color_1ca4">#00001ca4</color> + <color name="i_am_color_1ca5">#00001ca5</color> + <color name="i_am_color_1ca6">#00001ca6</color> + <color name="i_am_color_1ca7">#00001ca7</color> + <color name="i_am_color_1ca8">#00001ca8</color> + <color name="i_am_color_1ca9">#00001ca9</color> + <color name="i_am_color_1caa">#00001caa</color> + <color name="i_am_color_1cab">#00001cab</color> + <color name="i_am_color_1cac">#00001cac</color> + <color name="i_am_color_1cad">#00001cad</color> + <color name="i_am_color_1cae">#00001cae</color> + <color name="i_am_color_1caf">#00001caf</color> + <color name="i_am_color_1cb0">#00001cb0</color> + <color name="i_am_color_1cb1">#00001cb1</color> + <color name="i_am_color_1cb2">#00001cb2</color> + <color name="i_am_color_1cb3">#00001cb3</color> + <color name="i_am_color_1cb4">#00001cb4</color> + <color name="i_am_color_1cb5">#00001cb5</color> + <color name="i_am_color_1cb6">#00001cb6</color> + <color name="i_am_color_1cb7">#00001cb7</color> + <color name="i_am_color_1cb8">#00001cb8</color> + <color name="i_am_color_1cb9">#00001cb9</color> + <color name="i_am_color_1cba">#00001cba</color> + <color name="i_am_color_1cbb">#00001cbb</color> + <color name="i_am_color_1cbc">#00001cbc</color> + <color name="i_am_color_1cbd">#00001cbd</color> + <color name="i_am_color_1cbe">#00001cbe</color> + <color name="i_am_color_1cbf">#00001cbf</color> + <color name="i_am_color_1cc0">#00001cc0</color> + <color name="i_am_color_1cc1">#00001cc1</color> + <color name="i_am_color_1cc2">#00001cc2</color> + <color name="i_am_color_1cc3">#00001cc3</color> + <color name="i_am_color_1cc4">#00001cc4</color> + <color name="i_am_color_1cc5">#00001cc5</color> + <color name="i_am_color_1cc6">#00001cc6</color> + <color name="i_am_color_1cc7">#00001cc7</color> + <color name="i_am_color_1cc8">#00001cc8</color> + <color name="i_am_color_1cc9">#00001cc9</color> + <color name="i_am_color_1cca">#00001cca</color> + <color name="i_am_color_1ccb">#00001ccb</color> + <color name="i_am_color_1ccc">#00001ccc</color> + <color name="i_am_color_1ccd">#00001ccd</color> + <color name="i_am_color_1cce">#00001cce</color> + <color name="i_am_color_1ccf">#00001ccf</color> + <color name="i_am_color_1cd0">#00001cd0</color> + <color name="i_am_color_1cd1">#00001cd1</color> + <color name="i_am_color_1cd2">#00001cd2</color> + <color name="i_am_color_1cd3">#00001cd3</color> + <color name="i_am_color_1cd4">#00001cd4</color> + <color name="i_am_color_1cd5">#00001cd5</color> + <color name="i_am_color_1cd6">#00001cd6</color> + <color name="i_am_color_1cd7">#00001cd7</color> + <color name="i_am_color_1cd8">#00001cd8</color> + <color name="i_am_color_1cd9">#00001cd9</color> + <color name="i_am_color_1cda">#00001cda</color> + <color name="i_am_color_1cdb">#00001cdb</color> + <color name="i_am_color_1cdc">#00001cdc</color> + <color name="i_am_color_1cdd">#00001cdd</color> + <color name="i_am_color_1cde">#00001cde</color> + <color name="i_am_color_1cdf">#00001cdf</color> + <color name="i_am_color_1ce0">#00001ce0</color> + <color name="i_am_color_1ce1">#00001ce1</color> + <color name="i_am_color_1ce2">#00001ce2</color> + <color name="i_am_color_1ce3">#00001ce3</color> + <color name="i_am_color_1ce4">#00001ce4</color> + <color name="i_am_color_1ce5">#00001ce5</color> + <color name="i_am_color_1ce6">#00001ce6</color> + <color name="i_am_color_1ce7">#00001ce7</color> + <color name="i_am_color_1ce8">#00001ce8</color> + <color name="i_am_color_1ce9">#00001ce9</color> + <color name="i_am_color_1cea">#00001cea</color> + <color name="i_am_color_1ceb">#00001ceb</color> + <color name="i_am_color_1cec">#00001cec</color> + <color name="i_am_color_1ced">#00001ced</color> + <color name="i_am_color_1cee">#00001cee</color> + <color name="i_am_color_1cef">#00001cef</color> + <color name="i_am_color_1cf0">#00001cf0</color> + <color name="i_am_color_1cf1">#00001cf1</color> + <color name="i_am_color_1cf2">#00001cf2</color> + <color name="i_am_color_1cf3">#00001cf3</color> + <color name="i_am_color_1cf4">#00001cf4</color> + <color name="i_am_color_1cf5">#00001cf5</color> + <color name="i_am_color_1cf6">#00001cf6</color> + <color name="i_am_color_1cf7">#00001cf7</color> + <color name="i_am_color_1cf8">#00001cf8</color> + <color name="i_am_color_1cf9">#00001cf9</color> + <color name="i_am_color_1cfa">#00001cfa</color> + <color name="i_am_color_1cfb">#00001cfb</color> + <color name="i_am_color_1cfc">#00001cfc</color> + <color name="i_am_color_1cfd">#00001cfd</color> + <color name="i_am_color_1cfe">#00001cfe</color> + <color name="i_am_color_1cff">#00001cff</color> + <color name="i_am_color_1d00">#00001d00</color> + <color name="i_am_color_1d01">#00001d01</color> + <color name="i_am_color_1d02">#00001d02</color> + <color name="i_am_color_1d03">#00001d03</color> + <color name="i_am_color_1d04">#00001d04</color> + <color name="i_am_color_1d05">#00001d05</color> + <color name="i_am_color_1d06">#00001d06</color> + <color name="i_am_color_1d07">#00001d07</color> + <color name="i_am_color_1d08">#00001d08</color> + <color name="i_am_color_1d09">#00001d09</color> + <color name="i_am_color_1d0a">#00001d0a</color> + <color name="i_am_color_1d0b">#00001d0b</color> + <color name="i_am_color_1d0c">#00001d0c</color> + <color name="i_am_color_1d0d">#00001d0d</color> + <color name="i_am_color_1d0e">#00001d0e</color> + <color name="i_am_color_1d0f">#00001d0f</color> + <color name="i_am_color_1d10">#00001d10</color> + <color name="i_am_color_1d11">#00001d11</color> + <color name="i_am_color_1d12">#00001d12</color> + <color name="i_am_color_1d13">#00001d13</color> + <color name="i_am_color_1d14">#00001d14</color> + <color name="i_am_color_1d15">#00001d15</color> + <color name="i_am_color_1d16">#00001d16</color> + <color name="i_am_color_1d17">#00001d17</color> + <color name="i_am_color_1d18">#00001d18</color> + <color name="i_am_color_1d19">#00001d19</color> + <color name="i_am_color_1d1a">#00001d1a</color> + <color name="i_am_color_1d1b">#00001d1b</color> + <color name="i_am_color_1d1c">#00001d1c</color> + <color name="i_am_color_1d1d">#00001d1d</color> + <color name="i_am_color_1d1e">#00001d1e</color> + <color name="i_am_color_1d1f">#00001d1f</color> + <color name="i_am_color_1d20">#00001d20</color> + <color name="i_am_color_1d21">#00001d21</color> + <color name="i_am_color_1d22">#00001d22</color> + <color name="i_am_color_1d23">#00001d23</color> + <color name="i_am_color_1d24">#00001d24</color> + <color name="i_am_color_1d25">#00001d25</color> + <color name="i_am_color_1d26">#00001d26</color> + <color name="i_am_color_1d27">#00001d27</color> + <color name="i_am_color_1d28">#00001d28</color> + <color name="i_am_color_1d29">#00001d29</color> + <color name="i_am_color_1d2a">#00001d2a</color> + <color name="i_am_color_1d2b">#00001d2b</color> + <color name="i_am_color_1d2c">#00001d2c</color> + <color name="i_am_color_1d2d">#00001d2d</color> + <color name="i_am_color_1d2e">#00001d2e</color> + <color name="i_am_color_1d2f">#00001d2f</color> + <color name="i_am_color_1d30">#00001d30</color> + <color name="i_am_color_1d31">#00001d31</color> + <color name="i_am_color_1d32">#00001d32</color> + <color name="i_am_color_1d33">#00001d33</color> + <color name="i_am_color_1d34">#00001d34</color> + <color name="i_am_color_1d35">#00001d35</color> + <color name="i_am_color_1d36">#00001d36</color> + <color name="i_am_color_1d37">#00001d37</color> + <color name="i_am_color_1d38">#00001d38</color> + <color name="i_am_color_1d39">#00001d39</color> + <color name="i_am_color_1d3a">#00001d3a</color> + <color name="i_am_color_1d3b">#00001d3b</color> + <color name="i_am_color_1d3c">#00001d3c</color> + <color name="i_am_color_1d3d">#00001d3d</color> + <color name="i_am_color_1d3e">#00001d3e</color> + <color name="i_am_color_1d3f">#00001d3f</color> + <color name="i_am_color_1d40">#00001d40</color> + <color name="i_am_color_1d41">#00001d41</color> + <color name="i_am_color_1d42">#00001d42</color> + <color name="i_am_color_1d43">#00001d43</color> + <color name="i_am_color_1d44">#00001d44</color> + <color name="i_am_color_1d45">#00001d45</color> + <color name="i_am_color_1d46">#00001d46</color> + <color name="i_am_color_1d47">#00001d47</color> + <color name="i_am_color_1d48">#00001d48</color> + <color name="i_am_color_1d49">#00001d49</color> + <color name="i_am_color_1d4a">#00001d4a</color> + <color name="i_am_color_1d4b">#00001d4b</color> + <color name="i_am_color_1d4c">#00001d4c</color> + <color name="i_am_color_1d4d">#00001d4d</color> + <color name="i_am_color_1d4e">#00001d4e</color> + <color name="i_am_color_1d4f">#00001d4f</color> + <color name="i_am_color_1d50">#00001d50</color> + <color name="i_am_color_1d51">#00001d51</color> + <color name="i_am_color_1d52">#00001d52</color> + <color name="i_am_color_1d53">#00001d53</color> + <color name="i_am_color_1d54">#00001d54</color> + <color name="i_am_color_1d55">#00001d55</color> + <color name="i_am_color_1d56">#00001d56</color> + <color name="i_am_color_1d57">#00001d57</color> + <color name="i_am_color_1d58">#00001d58</color> + <color name="i_am_color_1d59">#00001d59</color> + <color name="i_am_color_1d5a">#00001d5a</color> + <color name="i_am_color_1d5b">#00001d5b</color> + <color name="i_am_color_1d5c">#00001d5c</color> + <color name="i_am_color_1d5d">#00001d5d</color> + <color name="i_am_color_1d5e">#00001d5e</color> + <color name="i_am_color_1d5f">#00001d5f</color> + <color name="i_am_color_1d60">#00001d60</color> + <color name="i_am_color_1d61">#00001d61</color> + <color name="i_am_color_1d62">#00001d62</color> + <color name="i_am_color_1d63">#00001d63</color> + <color name="i_am_color_1d64">#00001d64</color> + <color name="i_am_color_1d65">#00001d65</color> + <color name="i_am_color_1d66">#00001d66</color> + <color name="i_am_color_1d67">#00001d67</color> + <color name="i_am_color_1d68">#00001d68</color> + <color name="i_am_color_1d69">#00001d69</color> + <color name="i_am_color_1d6a">#00001d6a</color> + <color name="i_am_color_1d6b">#00001d6b</color> + <color name="i_am_color_1d6c">#00001d6c</color> + <color name="i_am_color_1d6d">#00001d6d</color> + <color name="i_am_color_1d6e">#00001d6e</color> + <color name="i_am_color_1d6f">#00001d6f</color> + <color name="i_am_color_1d70">#00001d70</color> + <color name="i_am_color_1d71">#00001d71</color> + <color name="i_am_color_1d72">#00001d72</color> + <color name="i_am_color_1d73">#00001d73</color> + <color name="i_am_color_1d74">#00001d74</color> + <color name="i_am_color_1d75">#00001d75</color> + <color name="i_am_color_1d76">#00001d76</color> + <color name="i_am_color_1d77">#00001d77</color> + <color name="i_am_color_1d78">#00001d78</color> + <color name="i_am_color_1d79">#00001d79</color> + <color name="i_am_color_1d7a">#00001d7a</color> + <color name="i_am_color_1d7b">#00001d7b</color> + <color name="i_am_color_1d7c">#00001d7c</color> + <color name="i_am_color_1d7d">#00001d7d</color> + <color name="i_am_color_1d7e">#00001d7e</color> + <color name="i_am_color_1d7f">#00001d7f</color> + <color name="i_am_color_1d80">#00001d80</color> + <color name="i_am_color_1d81">#00001d81</color> + <color name="i_am_color_1d82">#00001d82</color> + <color name="i_am_color_1d83">#00001d83</color> + <color name="i_am_color_1d84">#00001d84</color> + <color name="i_am_color_1d85">#00001d85</color> + <color name="i_am_color_1d86">#00001d86</color> + <color name="i_am_color_1d87">#00001d87</color> + <color name="i_am_color_1d88">#00001d88</color> + <color name="i_am_color_1d89">#00001d89</color> + <color name="i_am_color_1d8a">#00001d8a</color> + <color name="i_am_color_1d8b">#00001d8b</color> + <color name="i_am_color_1d8c">#00001d8c</color> + <color name="i_am_color_1d8d">#00001d8d</color> + <color name="i_am_color_1d8e">#00001d8e</color> + <color name="i_am_color_1d8f">#00001d8f</color> + <color name="i_am_color_1d90">#00001d90</color> + <color name="i_am_color_1d91">#00001d91</color> + <color name="i_am_color_1d92">#00001d92</color> + <color name="i_am_color_1d93">#00001d93</color> + <color name="i_am_color_1d94">#00001d94</color> + <color name="i_am_color_1d95">#00001d95</color> + <color name="i_am_color_1d96">#00001d96</color> + <color name="i_am_color_1d97">#00001d97</color> + <color name="i_am_color_1d98">#00001d98</color> + <color name="i_am_color_1d99">#00001d99</color> + <color name="i_am_color_1d9a">#00001d9a</color> + <color name="i_am_color_1d9b">#00001d9b</color> + <color name="i_am_color_1d9c">#00001d9c</color> + <color name="i_am_color_1d9d">#00001d9d</color> + <color name="i_am_color_1d9e">#00001d9e</color> + <color name="i_am_color_1d9f">#00001d9f</color> + <color name="i_am_color_1da0">#00001da0</color> + <color name="i_am_color_1da1">#00001da1</color> + <color name="i_am_color_1da2">#00001da2</color> + <color name="i_am_color_1da3">#00001da3</color> + <color name="i_am_color_1da4">#00001da4</color> + <color name="i_am_color_1da5">#00001da5</color> + <color name="i_am_color_1da6">#00001da6</color> + <color name="i_am_color_1da7">#00001da7</color> + <color name="i_am_color_1da8">#00001da8</color> + <color name="i_am_color_1da9">#00001da9</color> + <color name="i_am_color_1daa">#00001daa</color> + <color name="i_am_color_1dab">#00001dab</color> + <color name="i_am_color_1dac">#00001dac</color> + <color name="i_am_color_1dad">#00001dad</color> + <color name="i_am_color_1dae">#00001dae</color> + <color name="i_am_color_1daf">#00001daf</color> + <color name="i_am_color_1db0">#00001db0</color> + <color name="i_am_color_1db1">#00001db1</color> + <color name="i_am_color_1db2">#00001db2</color> + <color name="i_am_color_1db3">#00001db3</color> + <color name="i_am_color_1db4">#00001db4</color> + <color name="i_am_color_1db5">#00001db5</color> + <color name="i_am_color_1db6">#00001db6</color> + <color name="i_am_color_1db7">#00001db7</color> + <color name="i_am_color_1db8">#00001db8</color> + <color name="i_am_color_1db9">#00001db9</color> + <color name="i_am_color_1dba">#00001dba</color> + <color name="i_am_color_1dbb">#00001dbb</color> + <color name="i_am_color_1dbc">#00001dbc</color> + <color name="i_am_color_1dbd">#00001dbd</color> + <color name="i_am_color_1dbe">#00001dbe</color> + <color name="i_am_color_1dbf">#00001dbf</color> + <color name="i_am_color_1dc0">#00001dc0</color> + <color name="i_am_color_1dc1">#00001dc1</color> + <color name="i_am_color_1dc2">#00001dc2</color> + <color name="i_am_color_1dc3">#00001dc3</color> + <color name="i_am_color_1dc4">#00001dc4</color> + <color name="i_am_color_1dc5">#00001dc5</color> + <color name="i_am_color_1dc6">#00001dc6</color> + <color name="i_am_color_1dc7">#00001dc7</color> + <color name="i_am_color_1dc8">#00001dc8</color> + <color name="i_am_color_1dc9">#00001dc9</color> + <color name="i_am_color_1dca">#00001dca</color> + <color name="i_am_color_1dcb">#00001dcb</color> + <color name="i_am_color_1dcc">#00001dcc</color> + <color name="i_am_color_1dcd">#00001dcd</color> + <color name="i_am_color_1dce">#00001dce</color> + <color name="i_am_color_1dcf">#00001dcf</color> + <color name="i_am_color_1dd0">#00001dd0</color> + <color name="i_am_color_1dd1">#00001dd1</color> + <color name="i_am_color_1dd2">#00001dd2</color> + <color name="i_am_color_1dd3">#00001dd3</color> + <color name="i_am_color_1dd4">#00001dd4</color> + <color name="i_am_color_1dd5">#00001dd5</color> + <color name="i_am_color_1dd6">#00001dd6</color> + <color name="i_am_color_1dd7">#00001dd7</color> + <color name="i_am_color_1dd8">#00001dd8</color> + <color name="i_am_color_1dd9">#00001dd9</color> + <color name="i_am_color_1dda">#00001dda</color> + <color name="i_am_color_1ddb">#00001ddb</color> + <color name="i_am_color_1ddc">#00001ddc</color> + <color name="i_am_color_1ddd">#00001ddd</color> + <color name="i_am_color_1dde">#00001dde</color> + <color name="i_am_color_1ddf">#00001ddf</color> + <color name="i_am_color_1de0">#00001de0</color> + <color name="i_am_color_1de1">#00001de1</color> + <color name="i_am_color_1de2">#00001de2</color> + <color name="i_am_color_1de3">#00001de3</color> + <color name="i_am_color_1de4">#00001de4</color> + <color name="i_am_color_1de5">#00001de5</color> + <color name="i_am_color_1de6">#00001de6</color> + <color name="i_am_color_1de7">#00001de7</color> + <color name="i_am_color_1de8">#00001de8</color> + <color name="i_am_color_1de9">#00001de9</color> + <color name="i_am_color_1dea">#00001dea</color> + <color name="i_am_color_1deb">#00001deb</color> + <color name="i_am_color_1dec">#00001dec</color> + <color name="i_am_color_1ded">#00001ded</color> + <color name="i_am_color_1dee">#00001dee</color> + <color name="i_am_color_1def">#00001def</color> + <color name="i_am_color_1df0">#00001df0</color> + <color name="i_am_color_1df1">#00001df1</color> + <color name="i_am_color_1df2">#00001df2</color> + <color name="i_am_color_1df3">#00001df3</color> + <color name="i_am_color_1df4">#00001df4</color> + <color name="i_am_color_1df5">#00001df5</color> + <color name="i_am_color_1df6">#00001df6</color> + <color name="i_am_color_1df7">#00001df7</color> + <color name="i_am_color_1df8">#00001df8</color> + <color name="i_am_color_1df9">#00001df9</color> + <color name="i_am_color_1dfa">#00001dfa</color> + <color name="i_am_color_1dfb">#00001dfb</color> + <color name="i_am_color_1dfc">#00001dfc</color> + <color name="i_am_color_1dfd">#00001dfd</color> + <color name="i_am_color_1dfe">#00001dfe</color> + <color name="i_am_color_1dff">#00001dff</color> + <color name="i_am_color_1e00">#00001e00</color> + <color name="i_am_color_1e01">#00001e01</color> + <color name="i_am_color_1e02">#00001e02</color> + <color name="i_am_color_1e03">#00001e03</color> + <color name="i_am_color_1e04">#00001e04</color> + <color name="i_am_color_1e05">#00001e05</color> + <color name="i_am_color_1e06">#00001e06</color> + <color name="i_am_color_1e07">#00001e07</color> + <color name="i_am_color_1e08">#00001e08</color> + <color name="i_am_color_1e09">#00001e09</color> + <color name="i_am_color_1e0a">#00001e0a</color> + <color name="i_am_color_1e0b">#00001e0b</color> + <color name="i_am_color_1e0c">#00001e0c</color> + <color name="i_am_color_1e0d">#00001e0d</color> + <color name="i_am_color_1e0e">#00001e0e</color> + <color name="i_am_color_1e0f">#00001e0f</color> + <color name="i_am_color_1e10">#00001e10</color> + <color name="i_am_color_1e11">#00001e11</color> + <color name="i_am_color_1e12">#00001e12</color> + <color name="i_am_color_1e13">#00001e13</color> + <color name="i_am_color_1e14">#00001e14</color> + <color name="i_am_color_1e15">#00001e15</color> + <color name="i_am_color_1e16">#00001e16</color> + <color name="i_am_color_1e17">#00001e17</color> + <color name="i_am_color_1e18">#00001e18</color> + <color name="i_am_color_1e19">#00001e19</color> + <color name="i_am_color_1e1a">#00001e1a</color> + <color name="i_am_color_1e1b">#00001e1b</color> + <color name="i_am_color_1e1c">#00001e1c</color> + <color name="i_am_color_1e1d">#00001e1d</color> + <color name="i_am_color_1e1e">#00001e1e</color> + <color name="i_am_color_1e1f">#00001e1f</color> + <color name="i_am_color_1e20">#00001e20</color> + <color name="i_am_color_1e21">#00001e21</color> + <color name="i_am_color_1e22">#00001e22</color> + <color name="i_am_color_1e23">#00001e23</color> + <color name="i_am_color_1e24">#00001e24</color> + <color name="i_am_color_1e25">#00001e25</color> + <color name="i_am_color_1e26">#00001e26</color> + <color name="i_am_color_1e27">#00001e27</color> + <color name="i_am_color_1e28">#00001e28</color> + <color name="i_am_color_1e29">#00001e29</color> + <color name="i_am_color_1e2a">#00001e2a</color> + <color name="i_am_color_1e2b">#00001e2b</color> + <color name="i_am_color_1e2c">#00001e2c</color> + <color name="i_am_color_1e2d">#00001e2d</color> + <color name="i_am_color_1e2e">#00001e2e</color> + <color name="i_am_color_1e2f">#00001e2f</color> + <color name="i_am_color_1e30">#00001e30</color> + <color name="i_am_color_1e31">#00001e31</color> + <color name="i_am_color_1e32">#00001e32</color> + <color name="i_am_color_1e33">#00001e33</color> + <color name="i_am_color_1e34">#00001e34</color> + <color name="i_am_color_1e35">#00001e35</color> + <color name="i_am_color_1e36">#00001e36</color> + <color name="i_am_color_1e37">#00001e37</color> + <color name="i_am_color_1e38">#00001e38</color> + <color name="i_am_color_1e39">#00001e39</color> + <color name="i_am_color_1e3a">#00001e3a</color> + <color name="i_am_color_1e3b">#00001e3b</color> + <color name="i_am_color_1e3c">#00001e3c</color> + <color name="i_am_color_1e3d">#00001e3d</color> + <color name="i_am_color_1e3e">#00001e3e</color> + <color name="i_am_color_1e3f">#00001e3f</color> + <color name="i_am_color_1e40">#00001e40</color> + <color name="i_am_color_1e41">#00001e41</color> + <color name="i_am_color_1e42">#00001e42</color> + <color name="i_am_color_1e43">#00001e43</color> + <color name="i_am_color_1e44">#00001e44</color> + <color name="i_am_color_1e45">#00001e45</color> + <color name="i_am_color_1e46">#00001e46</color> + <color name="i_am_color_1e47">#00001e47</color> + <color name="i_am_color_1e48">#00001e48</color> + <color name="i_am_color_1e49">#00001e49</color> + <color name="i_am_color_1e4a">#00001e4a</color> + <color name="i_am_color_1e4b">#00001e4b</color> + <color name="i_am_color_1e4c">#00001e4c</color> + <color name="i_am_color_1e4d">#00001e4d</color> + <color name="i_am_color_1e4e">#00001e4e</color> + <color name="i_am_color_1e4f">#00001e4f</color> + <color name="i_am_color_1e50">#00001e50</color> + <color name="i_am_color_1e51">#00001e51</color> + <color name="i_am_color_1e52">#00001e52</color> + <color name="i_am_color_1e53">#00001e53</color> + <color name="i_am_color_1e54">#00001e54</color> + <color name="i_am_color_1e55">#00001e55</color> + <color name="i_am_color_1e56">#00001e56</color> + <color name="i_am_color_1e57">#00001e57</color> + <color name="i_am_color_1e58">#00001e58</color> + <color name="i_am_color_1e59">#00001e59</color> + <color name="i_am_color_1e5a">#00001e5a</color> + <color name="i_am_color_1e5b">#00001e5b</color> + <color name="i_am_color_1e5c">#00001e5c</color> + <color name="i_am_color_1e5d">#00001e5d</color> + <color name="i_am_color_1e5e">#00001e5e</color> + <color name="i_am_color_1e5f">#00001e5f</color> + <color name="i_am_color_1e60">#00001e60</color> + <color name="i_am_color_1e61">#00001e61</color> + <color name="i_am_color_1e62">#00001e62</color> + <color name="i_am_color_1e63">#00001e63</color> + <color name="i_am_color_1e64">#00001e64</color> + <color name="i_am_color_1e65">#00001e65</color> + <color name="i_am_color_1e66">#00001e66</color> + <color name="i_am_color_1e67">#00001e67</color> + <color name="i_am_color_1e68">#00001e68</color> + <color name="i_am_color_1e69">#00001e69</color> + <color name="i_am_color_1e6a">#00001e6a</color> + <color name="i_am_color_1e6b">#00001e6b</color> + <color name="i_am_color_1e6c">#00001e6c</color> + <color name="i_am_color_1e6d">#00001e6d</color> + <color name="i_am_color_1e6e">#00001e6e</color> + <color name="i_am_color_1e6f">#00001e6f</color> + <color name="i_am_color_1e70">#00001e70</color> + <color name="i_am_color_1e71">#00001e71</color> + <color name="i_am_color_1e72">#00001e72</color> + <color name="i_am_color_1e73">#00001e73</color> + <color name="i_am_color_1e74">#00001e74</color> + <color name="i_am_color_1e75">#00001e75</color> + <color name="i_am_color_1e76">#00001e76</color> + <color name="i_am_color_1e77">#00001e77</color> + <color name="i_am_color_1e78">#00001e78</color> + <color name="i_am_color_1e79">#00001e79</color> + <color name="i_am_color_1e7a">#00001e7a</color> + <color name="i_am_color_1e7b">#00001e7b</color> + <color name="i_am_color_1e7c">#00001e7c</color> + <color name="i_am_color_1e7d">#00001e7d</color> + <color name="i_am_color_1e7e">#00001e7e</color> + <color name="i_am_color_1e7f">#00001e7f</color> + <color name="i_am_color_1e80">#00001e80</color> + <color name="i_am_color_1e81">#00001e81</color> + <color name="i_am_color_1e82">#00001e82</color> + <color name="i_am_color_1e83">#00001e83</color> + <color name="i_am_color_1e84">#00001e84</color> + <color name="i_am_color_1e85">#00001e85</color> + <color name="i_am_color_1e86">#00001e86</color> + <color name="i_am_color_1e87">#00001e87</color> + <color name="i_am_color_1e88">#00001e88</color> + <color name="i_am_color_1e89">#00001e89</color> + <color name="i_am_color_1e8a">#00001e8a</color> + <color name="i_am_color_1e8b">#00001e8b</color> + <color name="i_am_color_1e8c">#00001e8c</color> + <color name="i_am_color_1e8d">#00001e8d</color> + <color name="i_am_color_1e8e">#00001e8e</color> + <color name="i_am_color_1e8f">#00001e8f</color> + <color name="i_am_color_1e90">#00001e90</color> + <color name="i_am_color_1e91">#00001e91</color> + <color name="i_am_color_1e92">#00001e92</color> + <color name="i_am_color_1e93">#00001e93</color> + <color name="i_am_color_1e94">#00001e94</color> + <color name="i_am_color_1e95">#00001e95</color> + <color name="i_am_color_1e96">#00001e96</color> + <color name="i_am_color_1e97">#00001e97</color> + <color name="i_am_color_1e98">#00001e98</color> + <color name="i_am_color_1e99">#00001e99</color> + <color name="i_am_color_1e9a">#00001e9a</color> + <color name="i_am_color_1e9b">#00001e9b</color> + <color name="i_am_color_1e9c">#00001e9c</color> + <color name="i_am_color_1e9d">#00001e9d</color> + <color name="i_am_color_1e9e">#00001e9e</color> + <color name="i_am_color_1e9f">#00001e9f</color> + <color name="i_am_color_1ea0">#00001ea0</color> + <color name="i_am_color_1ea1">#00001ea1</color> + <color name="i_am_color_1ea2">#00001ea2</color> + <color name="i_am_color_1ea3">#00001ea3</color> + <color name="i_am_color_1ea4">#00001ea4</color> + <color name="i_am_color_1ea5">#00001ea5</color> + <color name="i_am_color_1ea6">#00001ea6</color> + <color name="i_am_color_1ea7">#00001ea7</color> + <color name="i_am_color_1ea8">#00001ea8</color> + <color name="i_am_color_1ea9">#00001ea9</color> + <color name="i_am_color_1eaa">#00001eaa</color> + <color name="i_am_color_1eab">#00001eab</color> + <color name="i_am_color_1eac">#00001eac</color> + <color name="i_am_color_1ead">#00001ead</color> + <color name="i_am_color_1eae">#00001eae</color> + <color name="i_am_color_1eaf">#00001eaf</color> + <color name="i_am_color_1eb0">#00001eb0</color> + <color name="i_am_color_1eb1">#00001eb1</color> + <color name="i_am_color_1eb2">#00001eb2</color> + <color name="i_am_color_1eb3">#00001eb3</color> + <color name="i_am_color_1eb4">#00001eb4</color> + <color name="i_am_color_1eb5">#00001eb5</color> + <color name="i_am_color_1eb6">#00001eb6</color> + <color name="i_am_color_1eb7">#00001eb7</color> + <color name="i_am_color_1eb8">#00001eb8</color> + <color name="i_am_color_1eb9">#00001eb9</color> + <color name="i_am_color_1eba">#00001eba</color> + <color name="i_am_color_1ebb">#00001ebb</color> + <color name="i_am_color_1ebc">#00001ebc</color> + <color name="i_am_color_1ebd">#00001ebd</color> + <color name="i_am_color_1ebe">#00001ebe</color> + <color name="i_am_color_1ebf">#00001ebf</color> + <color name="i_am_color_1ec0">#00001ec0</color> + <color name="i_am_color_1ec1">#00001ec1</color> + <color name="i_am_color_1ec2">#00001ec2</color> + <color name="i_am_color_1ec3">#00001ec3</color> + <color name="i_am_color_1ec4">#00001ec4</color> + <color name="i_am_color_1ec5">#00001ec5</color> + <color name="i_am_color_1ec6">#00001ec6</color> + <color name="i_am_color_1ec7">#00001ec7</color> + <color name="i_am_color_1ec8">#00001ec8</color> + <color name="i_am_color_1ec9">#00001ec9</color> + <color name="i_am_color_1eca">#00001eca</color> + <color name="i_am_color_1ecb">#00001ecb</color> + <color name="i_am_color_1ecc">#00001ecc</color> + <color name="i_am_color_1ecd">#00001ecd</color> + <color name="i_am_color_1ece">#00001ece</color> + <color name="i_am_color_1ecf">#00001ecf</color> + <color name="i_am_color_1ed0">#00001ed0</color> + <color name="i_am_color_1ed1">#00001ed1</color> + <color name="i_am_color_1ed2">#00001ed2</color> + <color name="i_am_color_1ed3">#00001ed3</color> + <color name="i_am_color_1ed4">#00001ed4</color> + <color name="i_am_color_1ed5">#00001ed5</color> + <color name="i_am_color_1ed6">#00001ed6</color> + <color name="i_am_color_1ed7">#00001ed7</color> + <color name="i_am_color_1ed8">#00001ed8</color> + <color name="i_am_color_1ed9">#00001ed9</color> + <color name="i_am_color_1eda">#00001eda</color> + <color name="i_am_color_1edb">#00001edb</color> + <color name="i_am_color_1edc">#00001edc</color> + <color name="i_am_color_1edd">#00001edd</color> + <color name="i_am_color_1ede">#00001ede</color> + <color name="i_am_color_1edf">#00001edf</color> + <color name="i_am_color_1ee0">#00001ee0</color> + <color name="i_am_color_1ee1">#00001ee1</color> + <color name="i_am_color_1ee2">#00001ee2</color> + <color name="i_am_color_1ee3">#00001ee3</color> + <color name="i_am_color_1ee4">#00001ee4</color> + <color name="i_am_color_1ee5">#00001ee5</color> + <color name="i_am_color_1ee6">#00001ee6</color> + <color name="i_am_color_1ee7">#00001ee7</color> + <color name="i_am_color_1ee8">#00001ee8</color> + <color name="i_am_color_1ee9">#00001ee9</color> + <color name="i_am_color_1eea">#00001eea</color> + <color name="i_am_color_1eeb">#00001eeb</color> + <color name="i_am_color_1eec">#00001eec</color> + <color name="i_am_color_1eed">#00001eed</color> + <color name="i_am_color_1eee">#00001eee</color> + <color name="i_am_color_1eef">#00001eef</color> + <color name="i_am_color_1ef0">#00001ef0</color> + <color name="i_am_color_1ef1">#00001ef1</color> + <color name="i_am_color_1ef2">#00001ef2</color> + <color name="i_am_color_1ef3">#00001ef3</color> + <color name="i_am_color_1ef4">#00001ef4</color> + <color name="i_am_color_1ef5">#00001ef5</color> + <color name="i_am_color_1ef6">#00001ef6</color> + <color name="i_am_color_1ef7">#00001ef7</color> + <color name="i_am_color_1ef8">#00001ef8</color> + <color name="i_am_color_1ef9">#00001ef9</color> + <color name="i_am_color_1efa">#00001efa</color> + <color name="i_am_color_1efb">#00001efb</color> + <color name="i_am_color_1efc">#00001efc</color> + <color name="i_am_color_1efd">#00001efd</color> + <color name="i_am_color_1efe">#00001efe</color> + <color name="i_am_color_1eff">#00001eff</color> + <color name="i_am_color_1f00">#00001f00</color> + <color name="i_am_color_1f01">#00001f01</color> + <color name="i_am_color_1f02">#00001f02</color> + <color name="i_am_color_1f03">#00001f03</color> + <color name="i_am_color_1f04">#00001f04</color> + <color name="i_am_color_1f05">#00001f05</color> + <color name="i_am_color_1f06">#00001f06</color> + <color name="i_am_color_1f07">#00001f07</color> + <color name="i_am_color_1f08">#00001f08</color> + <color name="i_am_color_1f09">#00001f09</color> + <color name="i_am_color_1f0a">#00001f0a</color> + <color name="i_am_color_1f0b">#00001f0b</color> + <color name="i_am_color_1f0c">#00001f0c</color> + <color name="i_am_color_1f0d">#00001f0d</color> + <color name="i_am_color_1f0e">#00001f0e</color> + <color name="i_am_color_1f0f">#00001f0f</color> + <color name="i_am_color_1f10">#00001f10</color> + <color name="i_am_color_1f11">#00001f11</color> + <color name="i_am_color_1f12">#00001f12</color> + <color name="i_am_color_1f13">#00001f13</color> + <color name="i_am_color_1f14">#00001f14</color> + <color name="i_am_color_1f15">#00001f15</color> + <color name="i_am_color_1f16">#00001f16</color> + <color name="i_am_color_1f17">#00001f17</color> + <color name="i_am_color_1f18">#00001f18</color> + <color name="i_am_color_1f19">#00001f19</color> + <color name="i_am_color_1f1a">#00001f1a</color> + <color name="i_am_color_1f1b">#00001f1b</color> + <color name="i_am_color_1f1c">#00001f1c</color> + <color name="i_am_color_1f1d">#00001f1d</color> + <color name="i_am_color_1f1e">#00001f1e</color> + <color name="i_am_color_1f1f">#00001f1f</color> + <color name="i_am_color_1f20">#00001f20</color> + <color name="i_am_color_1f21">#00001f21</color> + <color name="i_am_color_1f22">#00001f22</color> + <color name="i_am_color_1f23">#00001f23</color> + <color name="i_am_color_1f24">#00001f24</color> + <color name="i_am_color_1f25">#00001f25</color> + <color name="i_am_color_1f26">#00001f26</color> + <color name="i_am_color_1f27">#00001f27</color> + <color name="i_am_color_1f28">#00001f28</color> + <color name="i_am_color_1f29">#00001f29</color> + <color name="i_am_color_1f2a">#00001f2a</color> + <color name="i_am_color_1f2b">#00001f2b</color> + <color name="i_am_color_1f2c">#00001f2c</color> + <color name="i_am_color_1f2d">#00001f2d</color> + <color name="i_am_color_1f2e">#00001f2e</color> + <color name="i_am_color_1f2f">#00001f2f</color> + <color name="i_am_color_1f30">#00001f30</color> + <color name="i_am_color_1f31">#00001f31</color> + <color name="i_am_color_1f32">#00001f32</color> + <color name="i_am_color_1f33">#00001f33</color> + <color name="i_am_color_1f34">#00001f34</color> + <color name="i_am_color_1f35">#00001f35</color> + <color name="i_am_color_1f36">#00001f36</color> + <color name="i_am_color_1f37">#00001f37</color> + <color name="i_am_color_1f38">#00001f38</color> + <color name="i_am_color_1f39">#00001f39</color> + <color name="i_am_color_1f3a">#00001f3a</color> + <color name="i_am_color_1f3b">#00001f3b</color> + <color name="i_am_color_1f3c">#00001f3c</color> + <color name="i_am_color_1f3d">#00001f3d</color> + <color name="i_am_color_1f3e">#00001f3e</color> + <color name="i_am_color_1f3f">#00001f3f</color> + <color name="i_am_color_1f40">#00001f40</color> + <color name="i_am_color_1f41">#00001f41</color> + <color name="i_am_color_1f42">#00001f42</color> + <color name="i_am_color_1f43">#00001f43</color> + <color name="i_am_color_1f44">#00001f44</color> + <color name="i_am_color_1f45">#00001f45</color> + <color name="i_am_color_1f46">#00001f46</color> + <color name="i_am_color_1f47">#00001f47</color> + <color name="i_am_color_1f48">#00001f48</color> + <color name="i_am_color_1f49">#00001f49</color> + <color name="i_am_color_1f4a">#00001f4a</color> + <color name="i_am_color_1f4b">#00001f4b</color> + <color name="i_am_color_1f4c">#00001f4c</color> + <color name="i_am_color_1f4d">#00001f4d</color> + <color name="i_am_color_1f4e">#00001f4e</color> + <color name="i_am_color_1f4f">#00001f4f</color> + <color name="i_am_color_1f50">#00001f50</color> + <color name="i_am_color_1f51">#00001f51</color> + <color name="i_am_color_1f52">#00001f52</color> + <color name="i_am_color_1f53">#00001f53</color> + <color name="i_am_color_1f54">#00001f54</color> + <color name="i_am_color_1f55">#00001f55</color> + <color name="i_am_color_1f56">#00001f56</color> + <color name="i_am_color_1f57">#00001f57</color> + <color name="i_am_color_1f58">#00001f58</color> + <color name="i_am_color_1f59">#00001f59</color> + <color name="i_am_color_1f5a">#00001f5a</color> + <color name="i_am_color_1f5b">#00001f5b</color> + <color name="i_am_color_1f5c">#00001f5c</color> + <color name="i_am_color_1f5d">#00001f5d</color> + <color name="i_am_color_1f5e">#00001f5e</color> + <color name="i_am_color_1f5f">#00001f5f</color> + <color name="i_am_color_1f60">#00001f60</color> + <color name="i_am_color_1f61">#00001f61</color> + <color name="i_am_color_1f62">#00001f62</color> + <color name="i_am_color_1f63">#00001f63</color> + <color name="i_am_color_1f64">#00001f64</color> + <color name="i_am_color_1f65">#00001f65</color> + <color name="i_am_color_1f66">#00001f66</color> + <color name="i_am_color_1f67">#00001f67</color> + <color name="i_am_color_1f68">#00001f68</color> + <color name="i_am_color_1f69">#00001f69</color> + <color name="i_am_color_1f6a">#00001f6a</color> + <color name="i_am_color_1f6b">#00001f6b</color> + <color name="i_am_color_1f6c">#00001f6c</color> + <color name="i_am_color_1f6d">#00001f6d</color> + <color name="i_am_color_1f6e">#00001f6e</color> + <color name="i_am_color_1f6f">#00001f6f</color> + <color name="i_am_color_1f70">#00001f70</color> + <color name="i_am_color_1f71">#00001f71</color> + <color name="i_am_color_1f72">#00001f72</color> + <color name="i_am_color_1f73">#00001f73</color> + <color name="i_am_color_1f74">#00001f74</color> + <color name="i_am_color_1f75">#00001f75</color> + <color name="i_am_color_1f76">#00001f76</color> + <color name="i_am_color_1f77">#00001f77</color> + <color name="i_am_color_1f78">#00001f78</color> + <color name="i_am_color_1f79">#00001f79</color> + <color name="i_am_color_1f7a">#00001f7a</color> + <color name="i_am_color_1f7b">#00001f7b</color> + <color name="i_am_color_1f7c">#00001f7c</color> + <color name="i_am_color_1f7d">#00001f7d</color> + <color name="i_am_color_1f7e">#00001f7e</color> + <color name="i_am_color_1f7f">#00001f7f</color> + <color name="i_am_color_1f80">#00001f80</color> + <color name="i_am_color_1f81">#00001f81</color> + <color name="i_am_color_1f82">#00001f82</color> + <color name="i_am_color_1f83">#00001f83</color> + <color name="i_am_color_1f84">#00001f84</color> + <color name="i_am_color_1f85">#00001f85</color> + <color name="i_am_color_1f86">#00001f86</color> + <color name="i_am_color_1f87">#00001f87</color> + <color name="i_am_color_1f88">#00001f88</color> + <color name="i_am_color_1f89">#00001f89</color> + <color name="i_am_color_1f8a">#00001f8a</color> + <color name="i_am_color_1f8b">#00001f8b</color> + <color name="i_am_color_1f8c">#00001f8c</color> + <color name="i_am_color_1f8d">#00001f8d</color> + <color name="i_am_color_1f8e">#00001f8e</color> + <color name="i_am_color_1f8f">#00001f8f</color> + <color name="i_am_color_1f90">#00001f90</color> + <color name="i_am_color_1f91">#00001f91</color> + <color name="i_am_color_1f92">#00001f92</color> + <color name="i_am_color_1f93">#00001f93</color> + <color name="i_am_color_1f94">#00001f94</color> + <color name="i_am_color_1f95">#00001f95</color> + <color name="i_am_color_1f96">#00001f96</color> + <color name="i_am_color_1f97">#00001f97</color> + <color name="i_am_color_1f98">#00001f98</color> + <color name="i_am_color_1f99">#00001f99</color> + <color name="i_am_color_1f9a">#00001f9a</color> + <color name="i_am_color_1f9b">#00001f9b</color> + <color name="i_am_color_1f9c">#00001f9c</color> + <color name="i_am_color_1f9d">#00001f9d</color> + <color name="i_am_color_1f9e">#00001f9e</color> + <color name="i_am_color_1f9f">#00001f9f</color> + <color name="i_am_color_1fa0">#00001fa0</color> + <color name="i_am_color_1fa1">#00001fa1</color> + <color name="i_am_color_1fa2">#00001fa2</color> + <color name="i_am_color_1fa3">#00001fa3</color> + <color name="i_am_color_1fa4">#00001fa4</color> + <color name="i_am_color_1fa5">#00001fa5</color> + <color name="i_am_color_1fa6">#00001fa6</color> + <color name="i_am_color_1fa7">#00001fa7</color> + <color name="i_am_color_1fa8">#00001fa8</color> + <color name="i_am_color_1fa9">#00001fa9</color> + <color name="i_am_color_1faa">#00001faa</color> + <color name="i_am_color_1fab">#00001fab</color> + <color name="i_am_color_1fac">#00001fac</color> + <color name="i_am_color_1fad">#00001fad</color> + <color name="i_am_color_1fae">#00001fae</color> + <color name="i_am_color_1faf">#00001faf</color> + <color name="i_am_color_1fb0">#00001fb0</color> + <color name="i_am_color_1fb1">#00001fb1</color> + <color name="i_am_color_1fb2">#00001fb2</color> + <color name="i_am_color_1fb3">#00001fb3</color> + <color name="i_am_color_1fb4">#00001fb4</color> + <color name="i_am_color_1fb5">#00001fb5</color> + <color name="i_am_color_1fb6">#00001fb6</color> + <color name="i_am_color_1fb7">#00001fb7</color> + <color name="i_am_color_1fb8">#00001fb8</color> + <color name="i_am_color_1fb9">#00001fb9</color> + <color name="i_am_color_1fba">#00001fba</color> + <color name="i_am_color_1fbb">#00001fbb</color> + <color name="i_am_color_1fbc">#00001fbc</color> + <color name="i_am_color_1fbd">#00001fbd</color> + <color name="i_am_color_1fbe">#00001fbe</color> + <color name="i_am_color_1fbf">#00001fbf</color> + <color name="i_am_color_1fc0">#00001fc0</color> + <color name="i_am_color_1fc1">#00001fc1</color> + <color name="i_am_color_1fc2">#00001fc2</color> + <color name="i_am_color_1fc3">#00001fc3</color> + <color name="i_am_color_1fc4">#00001fc4</color> + <color name="i_am_color_1fc5">#00001fc5</color> + <color name="i_am_color_1fc6">#00001fc6</color> + <color name="i_am_color_1fc7">#00001fc7</color> + <color name="i_am_color_1fc8">#00001fc8</color> + <color name="i_am_color_1fc9">#00001fc9</color> + <color name="i_am_color_1fca">#00001fca</color> + <color name="i_am_color_1fcb">#00001fcb</color> + <color name="i_am_color_1fcc">#00001fcc</color> + <color name="i_am_color_1fcd">#00001fcd</color> + <color name="i_am_color_1fce">#00001fce</color> + <color name="i_am_color_1fcf">#00001fcf</color> + <color name="i_am_color_1fd0">#00001fd0</color> + <color name="i_am_color_1fd1">#00001fd1</color> + <color name="i_am_color_1fd2">#00001fd2</color> + <color name="i_am_color_1fd3">#00001fd3</color> + <color name="i_am_color_1fd4">#00001fd4</color> + <color name="i_am_color_1fd5">#00001fd5</color> + <color name="i_am_color_1fd6">#00001fd6</color> + <color name="i_am_color_1fd7">#00001fd7</color> + <color name="i_am_color_1fd8">#00001fd8</color> + <color name="i_am_color_1fd9">#00001fd9</color> + <color name="i_am_color_1fda">#00001fda</color> + <color name="i_am_color_1fdb">#00001fdb</color> + <color name="i_am_color_1fdc">#00001fdc</color> + <color name="i_am_color_1fdd">#00001fdd</color> + <color name="i_am_color_1fde">#00001fde</color> + <color name="i_am_color_1fdf">#00001fdf</color> + <color name="i_am_color_1fe0">#00001fe0</color> + <color name="i_am_color_1fe1">#00001fe1</color> + <color name="i_am_color_1fe2">#00001fe2</color> + <color name="i_am_color_1fe3">#00001fe3</color> + <color name="i_am_color_1fe4">#00001fe4</color> + <color name="i_am_color_1fe5">#00001fe5</color> + <color name="i_am_color_1fe6">#00001fe6</color> + <color name="i_am_color_1fe7">#00001fe7</color> + <color name="i_am_color_1fe8">#00001fe8</color> + <color name="i_am_color_1fe9">#00001fe9</color> + <color name="i_am_color_1fea">#00001fea</color> + <color name="i_am_color_1feb">#00001feb</color> + <color name="i_am_color_1fec">#00001fec</color> + <color name="i_am_color_1fed">#00001fed</color> + <color name="i_am_color_1fee">#00001fee</color> + <color name="i_am_color_1fef">#00001fef</color> + <color name="i_am_color_1ff0">#00001ff0</color> + <color name="i_am_color_1ff1">#00001ff1</color> + <color name="i_am_color_1ff2">#00001ff2</color> + <color name="i_am_color_1ff3">#00001ff3</color> + <color name="i_am_color_1ff4">#00001ff4</color> + <color name="i_am_color_1ff5">#00001ff5</color> + <color name="i_am_color_1ff6">#00001ff6</color> + <color name="i_am_color_1ff7">#00001ff7</color> + <color name="i_am_color_1ff8">#00001ff8</color> + <color name="i_am_color_1ff9">#00001ff9</color> + <color name="i_am_color_1ffa">#00001ffa</color> + <color name="i_am_color_1ffb">#00001ffb</color> + <color name="i_am_color_1ffc">#00001ffc</color> + <color name="i_am_color_1ffd">#00001ffd</color> + <color name="i_am_color_1ffe">#00001ffe</color> + <color name="i_am_color_1fff">#00001fff</color> + <color name="i_am_color_2000">#00002000</color> + <color name="i_am_color_2001">#00002001</color> + <color name="i_am_color_2002">#00002002</color> + <color name="i_am_color_2003">#00002003</color> + <color name="i_am_color_2004">#00002004</color> + <color name="i_am_color_2005">#00002005</color> + <color name="i_am_color_2006">#00002006</color> + <color name="i_am_color_2007">#00002007</color> + <color name="i_am_color_2008">#00002008</color> + <color name="i_am_color_2009">#00002009</color> + <color name="i_am_color_200a">#0000200a</color> + <color name="i_am_color_200b">#0000200b</color> + <color name="i_am_color_200c">#0000200c</color> + <color name="i_am_color_200d">#0000200d</color> + <color name="i_am_color_200e">#0000200e</color> + <color name="i_am_color_200f">#0000200f</color> + <color name="i_am_color_2010">#00002010</color> + <color name="i_am_color_2011">#00002011</color> + <color name="i_am_color_2012">#00002012</color> + <color name="i_am_color_2013">#00002013</color> + <color name="i_am_color_2014">#00002014</color> + <color name="i_am_color_2015">#00002015</color> + <color name="i_am_color_2016">#00002016</color> + <color name="i_am_color_2017">#00002017</color> + <color name="i_am_color_2018">#00002018</color> + <color name="i_am_color_2019">#00002019</color> + <color name="i_am_color_201a">#0000201a</color> + <color name="i_am_color_201b">#0000201b</color> + <color name="i_am_color_201c">#0000201c</color> + <color name="i_am_color_201d">#0000201d</color> + <color name="i_am_color_201e">#0000201e</color> + <color name="i_am_color_201f">#0000201f</color> + <color name="i_am_color_2020">#00002020</color> + <color name="i_am_color_2021">#00002021</color> + <color name="i_am_color_2022">#00002022</color> + <color name="i_am_color_2023">#00002023</color> + <color name="i_am_color_2024">#00002024</color> + <color name="i_am_color_2025">#00002025</color> + <color name="i_am_color_2026">#00002026</color> + <color name="i_am_color_2027">#00002027</color> + <color name="i_am_color_2028">#00002028</color> + <color name="i_am_color_2029">#00002029</color> + <color name="i_am_color_202a">#0000202a</color> + <color name="i_am_color_202b">#0000202b</color> + <color name="i_am_color_202c">#0000202c</color> + <color name="i_am_color_202d">#0000202d</color> + <color name="i_am_color_202e">#0000202e</color> + <color name="i_am_color_202f">#0000202f</color> + <color name="i_am_color_2030">#00002030</color> + <color name="i_am_color_2031">#00002031</color> + <color name="i_am_color_2032">#00002032</color> + <color name="i_am_color_2033">#00002033</color> + <color name="i_am_color_2034">#00002034</color> + <color name="i_am_color_2035">#00002035</color> + <color name="i_am_color_2036">#00002036</color> + <color name="i_am_color_2037">#00002037</color> + <color name="i_am_color_2038">#00002038</color> + <color name="i_am_color_2039">#00002039</color> + <color name="i_am_color_203a">#0000203a</color> + <color name="i_am_color_203b">#0000203b</color> + <color name="i_am_color_203c">#0000203c</color> + <color name="i_am_color_203d">#0000203d</color> + <color name="i_am_color_203e">#0000203e</color> + <color name="i_am_color_203f">#0000203f</color> + <color name="i_am_color_2040">#00002040</color> + <color name="i_am_color_2041">#00002041</color> + <color name="i_am_color_2042">#00002042</color> + <color name="i_am_color_2043">#00002043</color> + <color name="i_am_color_2044">#00002044</color> + <color name="i_am_color_2045">#00002045</color> + <color name="i_am_color_2046">#00002046</color> + <color name="i_am_color_2047">#00002047</color> + <color name="i_am_color_2048">#00002048</color> + <color name="i_am_color_2049">#00002049</color> + <color name="i_am_color_204a">#0000204a</color> + <color name="i_am_color_204b">#0000204b</color> + <color name="i_am_color_204c">#0000204c</color> + <color name="i_am_color_204d">#0000204d</color> + <color name="i_am_color_204e">#0000204e</color> + <color name="i_am_color_204f">#0000204f</color> + <color name="i_am_color_2050">#00002050</color> + <color name="i_am_color_2051">#00002051</color> + <color name="i_am_color_2052">#00002052</color> + <color name="i_am_color_2053">#00002053</color> + <color name="i_am_color_2054">#00002054</color> + <color name="i_am_color_2055">#00002055</color> + <color name="i_am_color_2056">#00002056</color> + <color name="i_am_color_2057">#00002057</color> + <color name="i_am_color_2058">#00002058</color> + <color name="i_am_color_2059">#00002059</color> + <color name="i_am_color_205a">#0000205a</color> + <color name="i_am_color_205b">#0000205b</color> + <color name="i_am_color_205c">#0000205c</color> + <color name="i_am_color_205d">#0000205d</color> + <color name="i_am_color_205e">#0000205e</color> + <color name="i_am_color_205f">#0000205f</color> + <color name="i_am_color_2060">#00002060</color> + <color name="i_am_color_2061">#00002061</color> + <color name="i_am_color_2062">#00002062</color> + <color name="i_am_color_2063">#00002063</color> + <color name="i_am_color_2064">#00002064</color> + <color name="i_am_color_2065">#00002065</color> + <color name="i_am_color_2066">#00002066</color> + <color name="i_am_color_2067">#00002067</color> + <color name="i_am_color_2068">#00002068</color> + <color name="i_am_color_2069">#00002069</color> + <color name="i_am_color_206a">#0000206a</color> + <color name="i_am_color_206b">#0000206b</color> + <color name="i_am_color_206c">#0000206c</color> + <color name="i_am_color_206d">#0000206d</color> + <color name="i_am_color_206e">#0000206e</color> + <color name="i_am_color_206f">#0000206f</color> + <color name="i_am_color_2070">#00002070</color> + <color name="i_am_color_2071">#00002071</color> + <color name="i_am_color_2072">#00002072</color> + <color name="i_am_color_2073">#00002073</color> + <color name="i_am_color_2074">#00002074</color> + <color name="i_am_color_2075">#00002075</color> + <color name="i_am_color_2076">#00002076</color> + <color name="i_am_color_2077">#00002077</color> + <color name="i_am_color_2078">#00002078</color> + <color name="i_am_color_2079">#00002079</color> + <color name="i_am_color_207a">#0000207a</color> + <color name="i_am_color_207b">#0000207b</color> + <color name="i_am_color_207c">#0000207c</color> + <color name="i_am_color_207d">#0000207d</color> + <color name="i_am_color_207e">#0000207e</color> + <color name="i_am_color_207f">#0000207f</color> + <color name="i_am_color_2080">#00002080</color> + <color name="i_am_color_2081">#00002081</color> + <color name="i_am_color_2082">#00002082</color> + <color name="i_am_color_2083">#00002083</color> + <color name="i_am_color_2084">#00002084</color> + <color name="i_am_color_2085">#00002085</color> + <color name="i_am_color_2086">#00002086</color> + <color name="i_am_color_2087">#00002087</color> + <color name="i_am_color_2088">#00002088</color> + <color name="i_am_color_2089">#00002089</color> + <color name="i_am_color_208a">#0000208a</color> + <color name="i_am_color_208b">#0000208b</color> + <color name="i_am_color_208c">#0000208c</color> + <color name="i_am_color_208d">#0000208d</color> + <color name="i_am_color_208e">#0000208e</color> + <color name="i_am_color_208f">#0000208f</color> + <color name="i_am_color_2090">#00002090</color> + <color name="i_am_color_2091">#00002091</color> + <color name="i_am_color_2092">#00002092</color> + <color name="i_am_color_2093">#00002093</color> + <color name="i_am_color_2094">#00002094</color> + <color name="i_am_color_2095">#00002095</color> + <color name="i_am_color_2096">#00002096</color> + <color name="i_am_color_2097">#00002097</color> + <color name="i_am_color_2098">#00002098</color> + <color name="i_am_color_2099">#00002099</color> + <color name="i_am_color_209a">#0000209a</color> + <color name="i_am_color_209b">#0000209b</color> + <color name="i_am_color_209c">#0000209c</color> + <color name="i_am_color_209d">#0000209d</color> + <color name="i_am_color_209e">#0000209e</color> + <color name="i_am_color_209f">#0000209f</color> + <color name="i_am_color_20a0">#000020a0</color> + <color name="i_am_color_20a1">#000020a1</color> + <color name="i_am_color_20a2">#000020a2</color> + <color name="i_am_color_20a3">#000020a3</color> + <color name="i_am_color_20a4">#000020a4</color> + <color name="i_am_color_20a5">#000020a5</color> + <color name="i_am_color_20a6">#000020a6</color> + <color name="i_am_color_20a7">#000020a7</color> + <color name="i_am_color_20a8">#000020a8</color> + <color name="i_am_color_20a9">#000020a9</color> + <color name="i_am_color_20aa">#000020aa</color> + <color name="i_am_color_20ab">#000020ab</color> + <color name="i_am_color_20ac">#000020ac</color> + <color name="i_am_color_20ad">#000020ad</color> + <color name="i_am_color_20ae">#000020ae</color> + <color name="i_am_color_20af">#000020af</color> + <color name="i_am_color_20b0">#000020b0</color> + <color name="i_am_color_20b1">#000020b1</color> + <color name="i_am_color_20b2">#000020b2</color> + <color name="i_am_color_20b3">#000020b3</color> + <color name="i_am_color_20b4">#000020b4</color> + <color name="i_am_color_20b5">#000020b5</color> + <color name="i_am_color_20b6">#000020b6</color> + <color name="i_am_color_20b7">#000020b7</color> + <color name="i_am_color_20b8">#000020b8</color> + <color name="i_am_color_20b9">#000020b9</color> + <color name="i_am_color_20ba">#000020ba</color> + <color name="i_am_color_20bb">#000020bb</color> + <color name="i_am_color_20bc">#000020bc</color> + <color name="i_am_color_20bd">#000020bd</color> + <color name="i_am_color_20be">#000020be</color> + <color name="i_am_color_20bf">#000020bf</color> + <color name="i_am_color_20c0">#000020c0</color> + <color name="i_am_color_20c1">#000020c1</color> + <color name="i_am_color_20c2">#000020c2</color> + <color name="i_am_color_20c3">#000020c3</color> + <color name="i_am_color_20c4">#000020c4</color> + <color name="i_am_color_20c5">#000020c5</color> + <color name="i_am_color_20c6">#000020c6</color> + <color name="i_am_color_20c7">#000020c7</color> + <color name="i_am_color_20c8">#000020c8</color> + <color name="i_am_color_20c9">#000020c9</color> + <color name="i_am_color_20ca">#000020ca</color> + <color name="i_am_color_20cb">#000020cb</color> + <color name="i_am_color_20cc">#000020cc</color> + <color name="i_am_color_20cd">#000020cd</color> + <color name="i_am_color_20ce">#000020ce</color> + <color name="i_am_color_20cf">#000020cf</color> + <color name="i_am_color_20d0">#000020d0</color> + <color name="i_am_color_20d1">#000020d1</color> + <color name="i_am_color_20d2">#000020d2</color> + <color name="i_am_color_20d3">#000020d3</color> + <color name="i_am_color_20d4">#000020d4</color> + <color name="i_am_color_20d5">#000020d5</color> + <color name="i_am_color_20d6">#000020d6</color> + <color name="i_am_color_20d7">#000020d7</color> + <color name="i_am_color_20d8">#000020d8</color> + <color name="i_am_color_20d9">#000020d9</color> + <color name="i_am_color_20da">#000020da</color> + <color name="i_am_color_20db">#000020db</color> + <color name="i_am_color_20dc">#000020dc</color> + <color name="i_am_color_20dd">#000020dd</color> + <color name="i_am_color_20de">#000020de</color> + <color name="i_am_color_20df">#000020df</color> + <color name="i_am_color_20e0">#000020e0</color> + <color name="i_am_color_20e1">#000020e1</color> + <color name="i_am_color_20e2">#000020e2</color> + <color name="i_am_color_20e3">#000020e3</color> + <color name="i_am_color_20e4">#000020e4</color> + <color name="i_am_color_20e5">#000020e5</color> + <color name="i_am_color_20e6">#000020e6</color> + <color name="i_am_color_20e7">#000020e7</color> + <color name="i_am_color_20e8">#000020e8</color> + <color name="i_am_color_20e9">#000020e9</color> + <color name="i_am_color_20ea">#000020ea</color> + <color name="i_am_color_20eb">#000020eb</color> + <color name="i_am_color_20ec">#000020ec</color> + <color name="i_am_color_20ed">#000020ed</color> + <color name="i_am_color_20ee">#000020ee</color> + <color name="i_am_color_20ef">#000020ef</color> + <color name="i_am_color_20f0">#000020f0</color> + <color name="i_am_color_20f1">#000020f1</color> + <color name="i_am_color_20f2">#000020f2</color> + <color name="i_am_color_20f3">#000020f3</color> + <color name="i_am_color_20f4">#000020f4</color> + <color name="i_am_color_20f5">#000020f5</color> + <color name="i_am_color_20f6">#000020f6</color> + <color name="i_am_color_20f7">#000020f7</color> + <color name="i_am_color_20f8">#000020f8</color> + <color name="i_am_color_20f9">#000020f9</color> + <color name="i_am_color_20fa">#000020fa</color> + <color name="i_am_color_20fb">#000020fb</color> + <color name="i_am_color_20fc">#000020fc</color> + <color name="i_am_color_20fd">#000020fd</color> + <color name="i_am_color_20fe">#000020fe</color> + <color name="i_am_color_20ff">#000020ff</color> + <color name="i_am_color_2100">#00002100</color> + <color name="i_am_color_2101">#00002101</color> + <color name="i_am_color_2102">#00002102</color> + <color name="i_am_color_2103">#00002103</color> + <color name="i_am_color_2104">#00002104</color> + <color name="i_am_color_2105">#00002105</color> + <color name="i_am_color_2106">#00002106</color> + <color name="i_am_color_2107">#00002107</color> + <color name="i_am_color_2108">#00002108</color> + <color name="i_am_color_2109">#00002109</color> + <color name="i_am_color_210a">#0000210a</color> + <color name="i_am_color_210b">#0000210b</color> + <color name="i_am_color_210c">#0000210c</color> + <color name="i_am_color_210d">#0000210d</color> + <color name="i_am_color_210e">#0000210e</color> + <color name="i_am_color_210f">#0000210f</color> + <color name="i_am_color_2110">#00002110</color> + <color name="i_am_color_2111">#00002111</color> + <color name="i_am_color_2112">#00002112</color> + <color name="i_am_color_2113">#00002113</color> + <color name="i_am_color_2114">#00002114</color> + <color name="i_am_color_2115">#00002115</color> + <color name="i_am_color_2116">#00002116</color> + <color name="i_am_color_2117">#00002117</color> + <color name="i_am_color_2118">#00002118</color> + <color name="i_am_color_2119">#00002119</color> + <color name="i_am_color_211a">#0000211a</color> + <color name="i_am_color_211b">#0000211b</color> + <color name="i_am_color_211c">#0000211c</color> + <color name="i_am_color_211d">#0000211d</color> + <color name="i_am_color_211e">#0000211e</color> + <color name="i_am_color_211f">#0000211f</color> + <color name="i_am_color_2120">#00002120</color> + <color name="i_am_color_2121">#00002121</color> + <color name="i_am_color_2122">#00002122</color> + <color name="i_am_color_2123">#00002123</color> + <color name="i_am_color_2124">#00002124</color> + <color name="i_am_color_2125">#00002125</color> + <color name="i_am_color_2126">#00002126</color> + <color name="i_am_color_2127">#00002127</color> + <color name="i_am_color_2128">#00002128</color> + <color name="i_am_color_2129">#00002129</color> + <color name="i_am_color_212a">#0000212a</color> + <color name="i_am_color_212b">#0000212b</color> + <color name="i_am_color_212c">#0000212c</color> + <color name="i_am_color_212d">#0000212d</color> + <color name="i_am_color_212e">#0000212e</color> + <color name="i_am_color_212f">#0000212f</color> + <color name="i_am_color_2130">#00002130</color> + <color name="i_am_color_2131">#00002131</color> + <color name="i_am_color_2132">#00002132</color> + <color name="i_am_color_2133">#00002133</color> + <color name="i_am_color_2134">#00002134</color> + <color name="i_am_color_2135">#00002135</color> + <color name="i_am_color_2136">#00002136</color> + <color name="i_am_color_2137">#00002137</color> + <color name="i_am_color_2138">#00002138</color> + <color name="i_am_color_2139">#00002139</color> + <color name="i_am_color_213a">#0000213a</color> + <color name="i_am_color_213b">#0000213b</color> + <color name="i_am_color_213c">#0000213c</color> + <color name="i_am_color_213d">#0000213d</color> + <color name="i_am_color_213e">#0000213e</color> + <color name="i_am_color_213f">#0000213f</color> + <color name="i_am_color_2140">#00002140</color> + <color name="i_am_color_2141">#00002141</color> + <color name="i_am_color_2142">#00002142</color> + <color name="i_am_color_2143">#00002143</color> + <color name="i_am_color_2144">#00002144</color> + <color name="i_am_color_2145">#00002145</color> + <color name="i_am_color_2146">#00002146</color> + <color name="i_am_color_2147">#00002147</color> + <color name="i_am_color_2148">#00002148</color> + <color name="i_am_color_2149">#00002149</color> + <color name="i_am_color_214a">#0000214a</color> + <color name="i_am_color_214b">#0000214b</color> + <color name="i_am_color_214c">#0000214c</color> + <color name="i_am_color_214d">#0000214d</color> + <color name="i_am_color_214e">#0000214e</color> + <color name="i_am_color_214f">#0000214f</color> + <color name="i_am_color_2150">#00002150</color> + <color name="i_am_color_2151">#00002151</color> + <color name="i_am_color_2152">#00002152</color> + <color name="i_am_color_2153">#00002153</color> + <color name="i_am_color_2154">#00002154</color> + <color name="i_am_color_2155">#00002155</color> + <color name="i_am_color_2156">#00002156</color> + <color name="i_am_color_2157">#00002157</color> + <color name="i_am_color_2158">#00002158</color> + <color name="i_am_color_2159">#00002159</color> + <color name="i_am_color_215a">#0000215a</color> + <color name="i_am_color_215b">#0000215b</color> + <color name="i_am_color_215c">#0000215c</color> + <color name="i_am_color_215d">#0000215d</color> + <color name="i_am_color_215e">#0000215e</color> + <color name="i_am_color_215f">#0000215f</color> + <color name="i_am_color_2160">#00002160</color> + <color name="i_am_color_2161">#00002161</color> + <color name="i_am_color_2162">#00002162</color> + <color name="i_am_color_2163">#00002163</color> + <color name="i_am_color_2164">#00002164</color> + <color name="i_am_color_2165">#00002165</color> + <color name="i_am_color_2166">#00002166</color> + <color name="i_am_color_2167">#00002167</color> + <color name="i_am_color_2168">#00002168</color> + <color name="i_am_color_2169">#00002169</color> + <color name="i_am_color_216a">#0000216a</color> + <color name="i_am_color_216b">#0000216b</color> + <color name="i_am_color_216c">#0000216c</color> + <color name="i_am_color_216d">#0000216d</color> + <color name="i_am_color_216e">#0000216e</color> + <color name="i_am_color_216f">#0000216f</color> + <color name="i_am_color_2170">#00002170</color> + <color name="i_am_color_2171">#00002171</color> + <color name="i_am_color_2172">#00002172</color> + <color name="i_am_color_2173">#00002173</color> + <color name="i_am_color_2174">#00002174</color> + <color name="i_am_color_2175">#00002175</color> + <color name="i_am_color_2176">#00002176</color> + <color name="i_am_color_2177">#00002177</color> + <color name="i_am_color_2178">#00002178</color> + <color name="i_am_color_2179">#00002179</color> + <color name="i_am_color_217a">#0000217a</color> + <color name="i_am_color_217b">#0000217b</color> + <color name="i_am_color_217c">#0000217c</color> + <color name="i_am_color_217d">#0000217d</color> + <color name="i_am_color_217e">#0000217e</color> + <color name="i_am_color_217f">#0000217f</color> + <color name="i_am_color_2180">#00002180</color> + <color name="i_am_color_2181">#00002181</color> + <color name="i_am_color_2182">#00002182</color> + <color name="i_am_color_2183">#00002183</color> + <color name="i_am_color_2184">#00002184</color> + <color name="i_am_color_2185">#00002185</color> + <color name="i_am_color_2186">#00002186</color> + <color name="i_am_color_2187">#00002187</color> + <color name="i_am_color_2188">#00002188</color> + <color name="i_am_color_2189">#00002189</color> + <color name="i_am_color_218a">#0000218a</color> + <color name="i_am_color_218b">#0000218b</color> + <color name="i_am_color_218c">#0000218c</color> + <color name="i_am_color_218d">#0000218d</color> + <color name="i_am_color_218e">#0000218e</color> + <color name="i_am_color_218f">#0000218f</color> + <color name="i_am_color_2190">#00002190</color> + <color name="i_am_color_2191">#00002191</color> + <color name="i_am_color_2192">#00002192</color> + <color name="i_am_color_2193">#00002193</color> + <color name="i_am_color_2194">#00002194</color> + <color name="i_am_color_2195">#00002195</color> + <color name="i_am_color_2196">#00002196</color> + <color name="i_am_color_2197">#00002197</color> + <color name="i_am_color_2198">#00002198</color> + <color name="i_am_color_2199">#00002199</color> + <color name="i_am_color_219a">#0000219a</color> + <color name="i_am_color_219b">#0000219b</color> + <color name="i_am_color_219c">#0000219c</color> + <color name="i_am_color_219d">#0000219d</color> + <color name="i_am_color_219e">#0000219e</color> + <color name="i_am_color_219f">#0000219f</color> + <color name="i_am_color_21a0">#000021a0</color> + <color name="i_am_color_21a1">#000021a1</color> + <color name="i_am_color_21a2">#000021a2</color> + <color name="i_am_color_21a3">#000021a3</color> + <color name="i_am_color_21a4">#000021a4</color> + <color name="i_am_color_21a5">#000021a5</color> + <color name="i_am_color_21a6">#000021a6</color> + <color name="i_am_color_21a7">#000021a7</color> + <color name="i_am_color_21a8">#000021a8</color> + <color name="i_am_color_21a9">#000021a9</color> + <color name="i_am_color_21aa">#000021aa</color> + <color name="i_am_color_21ab">#000021ab</color> + <color name="i_am_color_21ac">#000021ac</color> + <color name="i_am_color_21ad">#000021ad</color> + <color name="i_am_color_21ae">#000021ae</color> + <color name="i_am_color_21af">#000021af</color> + <color name="i_am_color_21b0">#000021b0</color> + <color name="i_am_color_21b1">#000021b1</color> + <color name="i_am_color_21b2">#000021b2</color> + <color name="i_am_color_21b3">#000021b3</color> + <color name="i_am_color_21b4">#000021b4</color> + <color name="i_am_color_21b5">#000021b5</color> + <color name="i_am_color_21b6">#000021b6</color> + <color name="i_am_color_21b7">#000021b7</color> + <color name="i_am_color_21b8">#000021b8</color> + <color name="i_am_color_21b9">#000021b9</color> + <color name="i_am_color_21ba">#000021ba</color> + <color name="i_am_color_21bb">#000021bb</color> + <color name="i_am_color_21bc">#000021bc</color> + <color name="i_am_color_21bd">#000021bd</color> + <color name="i_am_color_21be">#000021be</color> + <color name="i_am_color_21bf">#000021bf</color> + <color name="i_am_color_21c0">#000021c0</color> + <color name="i_am_color_21c1">#000021c1</color> + <color name="i_am_color_21c2">#000021c2</color> + <color name="i_am_color_21c3">#000021c3</color> + <color name="i_am_color_21c4">#000021c4</color> + <color name="i_am_color_21c5">#000021c5</color> + <color name="i_am_color_21c6">#000021c6</color> + <color name="i_am_color_21c7">#000021c7</color> + <color name="i_am_color_21c8">#000021c8</color> + <color name="i_am_color_21c9">#000021c9</color> + <color name="i_am_color_21ca">#000021ca</color> + <color name="i_am_color_21cb">#000021cb</color> + <color name="i_am_color_21cc">#000021cc</color> + <color name="i_am_color_21cd">#000021cd</color> + <color name="i_am_color_21ce">#000021ce</color> + <color name="i_am_color_21cf">#000021cf</color> + <color name="i_am_color_21d0">#000021d0</color> + <color name="i_am_color_21d1">#000021d1</color> + <color name="i_am_color_21d2">#000021d2</color> + <color name="i_am_color_21d3">#000021d3</color> + <color name="i_am_color_21d4">#000021d4</color> + <color name="i_am_color_21d5">#000021d5</color> + <color name="i_am_color_21d6">#000021d6</color> + <color name="i_am_color_21d7">#000021d7</color> + <color name="i_am_color_21d8">#000021d8</color> + <color name="i_am_color_21d9">#000021d9</color> + <color name="i_am_color_21da">#000021da</color> + <color name="i_am_color_21db">#000021db</color> + <color name="i_am_color_21dc">#000021dc</color> + <color name="i_am_color_21dd">#000021dd</color> + <color name="i_am_color_21de">#000021de</color> + <color name="i_am_color_21df">#000021df</color> + <color name="i_am_color_21e0">#000021e0</color> + <color name="i_am_color_21e1">#000021e1</color> + <color name="i_am_color_21e2">#000021e2</color> + <color name="i_am_color_21e3">#000021e3</color> + <color name="i_am_color_21e4">#000021e4</color> + <color name="i_am_color_21e5">#000021e5</color> + <color name="i_am_color_21e6">#000021e6</color> + <color name="i_am_color_21e7">#000021e7</color> + <color name="i_am_color_21e8">#000021e8</color> + <color name="i_am_color_21e9">#000021e9</color> + <color name="i_am_color_21ea">#000021ea</color> + <color name="i_am_color_21eb">#000021eb</color> + <color name="i_am_color_21ec">#000021ec</color> + <color name="i_am_color_21ed">#000021ed</color> + <color name="i_am_color_21ee">#000021ee</color> + <color name="i_am_color_21ef">#000021ef</color> + <color name="i_am_color_21f0">#000021f0</color> + <color name="i_am_color_21f1">#000021f1</color> + <color name="i_am_color_21f2">#000021f2</color> + <color name="i_am_color_21f3">#000021f3</color> + <color name="i_am_color_21f4">#000021f4</color> + <color name="i_am_color_21f5">#000021f5</color> + <color name="i_am_color_21f6">#000021f6</color> + <color name="i_am_color_21f7">#000021f7</color> + <color name="i_am_color_21f8">#000021f8</color> + <color name="i_am_color_21f9">#000021f9</color> + <color name="i_am_color_21fa">#000021fa</color> + <color name="i_am_color_21fb">#000021fb</color> + <color name="i_am_color_21fc">#000021fc</color> + <color name="i_am_color_21fd">#000021fd</color> + <color name="i_am_color_21fe">#000021fe</color> + <color name="i_am_color_21ff">#000021ff</color> + <color name="i_am_color_2200">#00002200</color> + <color name="i_am_color_2201">#00002201</color> + <color name="i_am_color_2202">#00002202</color> + <color name="i_am_color_2203">#00002203</color> + <color name="i_am_color_2204">#00002204</color> + <color name="i_am_color_2205">#00002205</color> + <color name="i_am_color_2206">#00002206</color> + <color name="i_am_color_2207">#00002207</color> + <color name="i_am_color_2208">#00002208</color> + <color name="i_am_color_2209">#00002209</color> + <color name="i_am_color_220a">#0000220a</color> + <color name="i_am_color_220b">#0000220b</color> + <color name="i_am_color_220c">#0000220c</color> + <color name="i_am_color_220d">#0000220d</color> + <color name="i_am_color_220e">#0000220e</color> + <color name="i_am_color_220f">#0000220f</color> + <color name="i_am_color_2210">#00002210</color> + <color name="i_am_color_2211">#00002211</color> + <color name="i_am_color_2212">#00002212</color> + <color name="i_am_color_2213">#00002213</color> + <color name="i_am_color_2214">#00002214</color> + <color name="i_am_color_2215">#00002215</color> + <color name="i_am_color_2216">#00002216</color> + <color name="i_am_color_2217">#00002217</color> + <color name="i_am_color_2218">#00002218</color> + <color name="i_am_color_2219">#00002219</color> + <color name="i_am_color_221a">#0000221a</color> + <color name="i_am_color_221b">#0000221b</color> + <color name="i_am_color_221c">#0000221c</color> + <color name="i_am_color_221d">#0000221d</color> + <color name="i_am_color_221e">#0000221e</color> + <color name="i_am_color_221f">#0000221f</color> + <color name="i_am_color_2220">#00002220</color> + <color name="i_am_color_2221">#00002221</color> + <color name="i_am_color_2222">#00002222</color> + <color name="i_am_color_2223">#00002223</color> + <color name="i_am_color_2224">#00002224</color> + <color name="i_am_color_2225">#00002225</color> + <color name="i_am_color_2226">#00002226</color> + <color name="i_am_color_2227">#00002227</color> + <color name="i_am_color_2228">#00002228</color> + <color name="i_am_color_2229">#00002229</color> + <color name="i_am_color_222a">#0000222a</color> + <color name="i_am_color_222b">#0000222b</color> + <color name="i_am_color_222c">#0000222c</color> + <color name="i_am_color_222d">#0000222d</color> + <color name="i_am_color_222e">#0000222e</color> + <color name="i_am_color_222f">#0000222f</color> + <color name="i_am_color_2230">#00002230</color> + <color name="i_am_color_2231">#00002231</color> + <color name="i_am_color_2232">#00002232</color> + <color name="i_am_color_2233">#00002233</color> + <color name="i_am_color_2234">#00002234</color> + <color name="i_am_color_2235">#00002235</color> + <color name="i_am_color_2236">#00002236</color> + <color name="i_am_color_2237">#00002237</color> + <color name="i_am_color_2238">#00002238</color> + <color name="i_am_color_2239">#00002239</color> + <color name="i_am_color_223a">#0000223a</color> + <color name="i_am_color_223b">#0000223b</color> + <color name="i_am_color_223c">#0000223c</color> + <color name="i_am_color_223d">#0000223d</color> + <color name="i_am_color_223e">#0000223e</color> + <color name="i_am_color_223f">#0000223f</color> + <color name="i_am_color_2240">#00002240</color> + <color name="i_am_color_2241">#00002241</color> + <color name="i_am_color_2242">#00002242</color> + <color name="i_am_color_2243">#00002243</color> + <color name="i_am_color_2244">#00002244</color> + <color name="i_am_color_2245">#00002245</color> + <color name="i_am_color_2246">#00002246</color> + <color name="i_am_color_2247">#00002247</color> + <color name="i_am_color_2248">#00002248</color> + <color name="i_am_color_2249">#00002249</color> + <color name="i_am_color_224a">#0000224a</color> + <color name="i_am_color_224b">#0000224b</color> + <color name="i_am_color_224c">#0000224c</color> + <color name="i_am_color_224d">#0000224d</color> + <color name="i_am_color_224e">#0000224e</color> + <color name="i_am_color_224f">#0000224f</color> + <color name="i_am_color_2250">#00002250</color> + <color name="i_am_color_2251">#00002251</color> + <color name="i_am_color_2252">#00002252</color> + <color name="i_am_color_2253">#00002253</color> + <color name="i_am_color_2254">#00002254</color> + <color name="i_am_color_2255">#00002255</color> + <color name="i_am_color_2256">#00002256</color> + <color name="i_am_color_2257">#00002257</color> + <color name="i_am_color_2258">#00002258</color> + <color name="i_am_color_2259">#00002259</color> + <color name="i_am_color_225a">#0000225a</color> + <color name="i_am_color_225b">#0000225b</color> + <color name="i_am_color_225c">#0000225c</color> + <color name="i_am_color_225d">#0000225d</color> + <color name="i_am_color_225e">#0000225e</color> + <color name="i_am_color_225f">#0000225f</color> + <color name="i_am_color_2260">#00002260</color> + <color name="i_am_color_2261">#00002261</color> + <color name="i_am_color_2262">#00002262</color> + <color name="i_am_color_2263">#00002263</color> + <color name="i_am_color_2264">#00002264</color> + <color name="i_am_color_2265">#00002265</color> + <color name="i_am_color_2266">#00002266</color> + <color name="i_am_color_2267">#00002267</color> + <color name="i_am_color_2268">#00002268</color> + <color name="i_am_color_2269">#00002269</color> + <color name="i_am_color_226a">#0000226a</color> + <color name="i_am_color_226b">#0000226b</color> + <color name="i_am_color_226c">#0000226c</color> + <color name="i_am_color_226d">#0000226d</color> + <color name="i_am_color_226e">#0000226e</color> + <color name="i_am_color_226f">#0000226f</color> + <color name="i_am_color_2270">#00002270</color> + <color name="i_am_color_2271">#00002271</color> + <color name="i_am_color_2272">#00002272</color> + <color name="i_am_color_2273">#00002273</color> + <color name="i_am_color_2274">#00002274</color> + <color name="i_am_color_2275">#00002275</color> + <color name="i_am_color_2276">#00002276</color> + <color name="i_am_color_2277">#00002277</color> + <color name="i_am_color_2278">#00002278</color> + <color name="i_am_color_2279">#00002279</color> + <color name="i_am_color_227a">#0000227a</color> + <color name="i_am_color_227b">#0000227b</color> + <color name="i_am_color_227c">#0000227c</color> + <color name="i_am_color_227d">#0000227d</color> + <color name="i_am_color_227e">#0000227e</color> + <color name="i_am_color_227f">#0000227f</color> + <color name="i_am_color_2280">#00002280</color> + <color name="i_am_color_2281">#00002281</color> + <color name="i_am_color_2282">#00002282</color> + <color name="i_am_color_2283">#00002283</color> + <color name="i_am_color_2284">#00002284</color> + <color name="i_am_color_2285">#00002285</color> + <color name="i_am_color_2286">#00002286</color> + <color name="i_am_color_2287">#00002287</color> + <color name="i_am_color_2288">#00002288</color> + <color name="i_am_color_2289">#00002289</color> + <color name="i_am_color_228a">#0000228a</color> + <color name="i_am_color_228b">#0000228b</color> + <color name="i_am_color_228c">#0000228c</color> + <color name="i_am_color_228d">#0000228d</color> + <color name="i_am_color_228e">#0000228e</color> + <color name="i_am_color_228f">#0000228f</color> + <color name="i_am_color_2290">#00002290</color> + <color name="i_am_color_2291">#00002291</color> + <color name="i_am_color_2292">#00002292</color> + <color name="i_am_color_2293">#00002293</color> + <color name="i_am_color_2294">#00002294</color> + <color name="i_am_color_2295">#00002295</color> + <color name="i_am_color_2296">#00002296</color> + <color name="i_am_color_2297">#00002297</color> + <color name="i_am_color_2298">#00002298</color> + <color name="i_am_color_2299">#00002299</color> + <color name="i_am_color_229a">#0000229a</color> + <color name="i_am_color_229b">#0000229b</color> + <color name="i_am_color_229c">#0000229c</color> + <color name="i_am_color_229d">#0000229d</color> + <color name="i_am_color_229e">#0000229e</color> + <color name="i_am_color_229f">#0000229f</color> + <color name="i_am_color_22a0">#000022a0</color> + <color name="i_am_color_22a1">#000022a1</color> + <color name="i_am_color_22a2">#000022a2</color> + <color name="i_am_color_22a3">#000022a3</color> + <color name="i_am_color_22a4">#000022a4</color> + <color name="i_am_color_22a5">#000022a5</color> + <color name="i_am_color_22a6">#000022a6</color> + <color name="i_am_color_22a7">#000022a7</color> + <color name="i_am_color_22a8">#000022a8</color> + <color name="i_am_color_22a9">#000022a9</color> + <color name="i_am_color_22aa">#000022aa</color> + <color name="i_am_color_22ab">#000022ab</color> + <color name="i_am_color_22ac">#000022ac</color> + <color name="i_am_color_22ad">#000022ad</color> + <color name="i_am_color_22ae">#000022ae</color> + <color name="i_am_color_22af">#000022af</color> + <color name="i_am_color_22b0">#000022b0</color> + <color name="i_am_color_22b1">#000022b1</color> + <color name="i_am_color_22b2">#000022b2</color> + <color name="i_am_color_22b3">#000022b3</color> + <color name="i_am_color_22b4">#000022b4</color> + <color name="i_am_color_22b5">#000022b5</color> + <color name="i_am_color_22b6">#000022b6</color> + <color name="i_am_color_22b7">#000022b7</color> + <color name="i_am_color_22b8">#000022b8</color> + <color name="i_am_color_22b9">#000022b9</color> + <color name="i_am_color_22ba">#000022ba</color> + <color name="i_am_color_22bb">#000022bb</color> + <color name="i_am_color_22bc">#000022bc</color> + <color name="i_am_color_22bd">#000022bd</color> + <color name="i_am_color_22be">#000022be</color> + <color name="i_am_color_22bf">#000022bf</color> + <color name="i_am_color_22c0">#000022c0</color> + <color name="i_am_color_22c1">#000022c1</color> + <color name="i_am_color_22c2">#000022c2</color> + <color name="i_am_color_22c3">#000022c3</color> + <color name="i_am_color_22c4">#000022c4</color> + <color name="i_am_color_22c5">#000022c5</color> + <color name="i_am_color_22c6">#000022c6</color> + <color name="i_am_color_22c7">#000022c7</color> + <color name="i_am_color_22c8">#000022c8</color> + <color name="i_am_color_22c9">#000022c9</color> + <color name="i_am_color_22ca">#000022ca</color> + <color name="i_am_color_22cb">#000022cb</color> + <color name="i_am_color_22cc">#000022cc</color> + <color name="i_am_color_22cd">#000022cd</color> + <color name="i_am_color_22ce">#000022ce</color> + <color name="i_am_color_22cf">#000022cf</color> + <color name="i_am_color_22d0">#000022d0</color> + <color name="i_am_color_22d1">#000022d1</color> + <color name="i_am_color_22d2">#000022d2</color> + <color name="i_am_color_22d3">#000022d3</color> + <color name="i_am_color_22d4">#000022d4</color> + <color name="i_am_color_22d5">#000022d5</color> + <color name="i_am_color_22d6">#000022d6</color> + <color name="i_am_color_22d7">#000022d7</color> + <color name="i_am_color_22d8">#000022d8</color> + <color name="i_am_color_22d9">#000022d9</color> + <color name="i_am_color_22da">#000022da</color> + <color name="i_am_color_22db">#000022db</color> + <color name="i_am_color_22dc">#000022dc</color> + <color name="i_am_color_22dd">#000022dd</color> + <color name="i_am_color_22de">#000022de</color> + <color name="i_am_color_22df">#000022df</color> + <color name="i_am_color_22e0">#000022e0</color> + <color name="i_am_color_22e1">#000022e1</color> + <color name="i_am_color_22e2">#000022e2</color> + <color name="i_am_color_22e3">#000022e3</color> + <color name="i_am_color_22e4">#000022e4</color> + <color name="i_am_color_22e5">#000022e5</color> + <color name="i_am_color_22e6">#000022e6</color> + <color name="i_am_color_22e7">#000022e7</color> + <color name="i_am_color_22e8">#000022e8</color> + <color name="i_am_color_22e9">#000022e9</color> + <color name="i_am_color_22ea">#000022ea</color> + <color name="i_am_color_22eb">#000022eb</color> + <color name="i_am_color_22ec">#000022ec</color> + <color name="i_am_color_22ed">#000022ed</color> + <color name="i_am_color_22ee">#000022ee</color> + <color name="i_am_color_22ef">#000022ef</color> + <color name="i_am_color_22f0">#000022f0</color> + <color name="i_am_color_22f1">#000022f1</color> + <color name="i_am_color_22f2">#000022f2</color> + <color name="i_am_color_22f3">#000022f3</color> + <color name="i_am_color_22f4">#000022f4</color> + <color name="i_am_color_22f5">#000022f5</color> + <color name="i_am_color_22f6">#000022f6</color> + <color name="i_am_color_22f7">#000022f7</color> + <color name="i_am_color_22f8">#000022f8</color> + <color name="i_am_color_22f9">#000022f9</color> + <color name="i_am_color_22fa">#000022fa</color> + <color name="i_am_color_22fb">#000022fb</color> + <color name="i_am_color_22fc">#000022fc</color> + <color name="i_am_color_22fd">#000022fd</color> + <color name="i_am_color_22fe">#000022fe</color> + <color name="i_am_color_22ff">#000022ff</color> + <color name="i_am_color_2300">#00002300</color> + <color name="i_am_color_2301">#00002301</color> + <color name="i_am_color_2302">#00002302</color> + <color name="i_am_color_2303">#00002303</color> + <color name="i_am_color_2304">#00002304</color> + <color name="i_am_color_2305">#00002305</color> + <color name="i_am_color_2306">#00002306</color> + <color name="i_am_color_2307">#00002307</color> + <color name="i_am_color_2308">#00002308</color> + <color name="i_am_color_2309">#00002309</color> + <color name="i_am_color_230a">#0000230a</color> + <color name="i_am_color_230b">#0000230b</color> + <color name="i_am_color_230c">#0000230c</color> + <color name="i_am_color_230d">#0000230d</color> + <color name="i_am_color_230e">#0000230e</color> + <color name="i_am_color_230f">#0000230f</color> + <color name="i_am_color_2310">#00002310</color> + <color name="i_am_color_2311">#00002311</color> + <color name="i_am_color_2312">#00002312</color> + <color name="i_am_color_2313">#00002313</color> + <color name="i_am_color_2314">#00002314</color> + <color name="i_am_color_2315">#00002315</color> + <color name="i_am_color_2316">#00002316</color> + <color name="i_am_color_2317">#00002317</color> + <color name="i_am_color_2318">#00002318</color> + <color name="i_am_color_2319">#00002319</color> + <color name="i_am_color_231a">#0000231a</color> + <color name="i_am_color_231b">#0000231b</color> + <color name="i_am_color_231c">#0000231c</color> + <color name="i_am_color_231d">#0000231d</color> + <color name="i_am_color_231e">#0000231e</color> + <color name="i_am_color_231f">#0000231f</color> + <color name="i_am_color_2320">#00002320</color> + <color name="i_am_color_2321">#00002321</color> + <color name="i_am_color_2322">#00002322</color> + <color name="i_am_color_2323">#00002323</color> + <color name="i_am_color_2324">#00002324</color> + <color name="i_am_color_2325">#00002325</color> + <color name="i_am_color_2326">#00002326</color> + <color name="i_am_color_2327">#00002327</color> + <color name="i_am_color_2328">#00002328</color> + <color name="i_am_color_2329">#00002329</color> + <color name="i_am_color_232a">#0000232a</color> + <color name="i_am_color_232b">#0000232b</color> + <color name="i_am_color_232c">#0000232c</color> + <color name="i_am_color_232d">#0000232d</color> + <color name="i_am_color_232e">#0000232e</color> + <color name="i_am_color_232f">#0000232f</color> + <color name="i_am_color_2330">#00002330</color> + <color name="i_am_color_2331">#00002331</color> + <color name="i_am_color_2332">#00002332</color> + <color name="i_am_color_2333">#00002333</color> + <color name="i_am_color_2334">#00002334</color> + <color name="i_am_color_2335">#00002335</color> + <color name="i_am_color_2336">#00002336</color> + <color name="i_am_color_2337">#00002337</color> + <color name="i_am_color_2338">#00002338</color> + <color name="i_am_color_2339">#00002339</color> + <color name="i_am_color_233a">#0000233a</color> + <color name="i_am_color_233b">#0000233b</color> + <color name="i_am_color_233c">#0000233c</color> + <color name="i_am_color_233d">#0000233d</color> + <color name="i_am_color_233e">#0000233e</color> + <color name="i_am_color_233f">#0000233f</color> + <color name="i_am_color_2340">#00002340</color> + <color name="i_am_color_2341">#00002341</color> + <color name="i_am_color_2342">#00002342</color> + <color name="i_am_color_2343">#00002343</color> + <color name="i_am_color_2344">#00002344</color> + <color name="i_am_color_2345">#00002345</color> + <color name="i_am_color_2346">#00002346</color> + <color name="i_am_color_2347">#00002347</color> + <color name="i_am_color_2348">#00002348</color> + <color name="i_am_color_2349">#00002349</color> + <color name="i_am_color_234a">#0000234a</color> + <color name="i_am_color_234b">#0000234b</color> + <color name="i_am_color_234c">#0000234c</color> + <color name="i_am_color_234d">#0000234d</color> + <color name="i_am_color_234e">#0000234e</color> + <color name="i_am_color_234f">#0000234f</color> + <color name="i_am_color_2350">#00002350</color> + <color name="i_am_color_2351">#00002351</color> + <color name="i_am_color_2352">#00002352</color> + <color name="i_am_color_2353">#00002353</color> + <color name="i_am_color_2354">#00002354</color> + <color name="i_am_color_2355">#00002355</color> + <color name="i_am_color_2356">#00002356</color> + <color name="i_am_color_2357">#00002357</color> + <color name="i_am_color_2358">#00002358</color> + <color name="i_am_color_2359">#00002359</color> + <color name="i_am_color_235a">#0000235a</color> + <color name="i_am_color_235b">#0000235b</color> + <color name="i_am_color_235c">#0000235c</color> + <color name="i_am_color_235d">#0000235d</color> + <color name="i_am_color_235e">#0000235e</color> + <color name="i_am_color_235f">#0000235f</color> + <color name="i_am_color_2360">#00002360</color> + <color name="i_am_color_2361">#00002361</color> + <color name="i_am_color_2362">#00002362</color> + <color name="i_am_color_2363">#00002363</color> + <color name="i_am_color_2364">#00002364</color> + <color name="i_am_color_2365">#00002365</color> + <color name="i_am_color_2366">#00002366</color> + <color name="i_am_color_2367">#00002367</color> + <color name="i_am_color_2368">#00002368</color> + <color name="i_am_color_2369">#00002369</color> + <color name="i_am_color_236a">#0000236a</color> + <color name="i_am_color_236b">#0000236b</color> + <color name="i_am_color_236c">#0000236c</color> + <color name="i_am_color_236d">#0000236d</color> + <color name="i_am_color_236e">#0000236e</color> + <color name="i_am_color_236f">#0000236f</color> + <color name="i_am_color_2370">#00002370</color> + <color name="i_am_color_2371">#00002371</color> + <color name="i_am_color_2372">#00002372</color> + <color name="i_am_color_2373">#00002373</color> + <color name="i_am_color_2374">#00002374</color> + <color name="i_am_color_2375">#00002375</color> + <color name="i_am_color_2376">#00002376</color> + <color name="i_am_color_2377">#00002377</color> + <color name="i_am_color_2378">#00002378</color> + <color name="i_am_color_2379">#00002379</color> + <color name="i_am_color_237a">#0000237a</color> + <color name="i_am_color_237b">#0000237b</color> + <color name="i_am_color_237c">#0000237c</color> + <color name="i_am_color_237d">#0000237d</color> + <color name="i_am_color_237e">#0000237e</color> + <color name="i_am_color_237f">#0000237f</color> + <color name="i_am_color_2380">#00002380</color> + <color name="i_am_color_2381">#00002381</color> + <color name="i_am_color_2382">#00002382</color> + <color name="i_am_color_2383">#00002383</color> + <color name="i_am_color_2384">#00002384</color> + <color name="i_am_color_2385">#00002385</color> + <color name="i_am_color_2386">#00002386</color> + <color name="i_am_color_2387">#00002387</color> + <color name="i_am_color_2388">#00002388</color> + <color name="i_am_color_2389">#00002389</color> + <color name="i_am_color_238a">#0000238a</color> + <color name="i_am_color_238b">#0000238b</color> + <color name="i_am_color_238c">#0000238c</color> + <color name="i_am_color_238d">#0000238d</color> + <color name="i_am_color_238e">#0000238e</color> + <color name="i_am_color_238f">#0000238f</color> + <color name="i_am_color_2390">#00002390</color> + <color name="i_am_color_2391">#00002391</color> + <color name="i_am_color_2392">#00002392</color> + <color name="i_am_color_2393">#00002393</color> + <color name="i_am_color_2394">#00002394</color> + <color name="i_am_color_2395">#00002395</color> + <color name="i_am_color_2396">#00002396</color> + <color name="i_am_color_2397">#00002397</color> + <color name="i_am_color_2398">#00002398</color> + <color name="i_am_color_2399">#00002399</color> + <color name="i_am_color_239a">#0000239a</color> + <color name="i_am_color_239b">#0000239b</color> + <color name="i_am_color_239c">#0000239c</color> + <color name="i_am_color_239d">#0000239d</color> + <color name="i_am_color_239e">#0000239e</color> + <color name="i_am_color_239f">#0000239f</color> + <color name="i_am_color_23a0">#000023a0</color> + <color name="i_am_color_23a1">#000023a1</color> + <color name="i_am_color_23a2">#000023a2</color> + <color name="i_am_color_23a3">#000023a3</color> + <color name="i_am_color_23a4">#000023a4</color> + <color name="i_am_color_23a5">#000023a5</color> + <color name="i_am_color_23a6">#000023a6</color> + <color name="i_am_color_23a7">#000023a7</color> + <color name="i_am_color_23a8">#000023a8</color> + <color name="i_am_color_23a9">#000023a9</color> + <color name="i_am_color_23aa">#000023aa</color> + <color name="i_am_color_23ab">#000023ab</color> + <color name="i_am_color_23ac">#000023ac</color> + <color name="i_am_color_23ad">#000023ad</color> + <color name="i_am_color_23ae">#000023ae</color> + <color name="i_am_color_23af">#000023af</color> + <color name="i_am_color_23b0">#000023b0</color> + <color name="i_am_color_23b1">#000023b1</color> + <color name="i_am_color_23b2">#000023b2</color> + <color name="i_am_color_23b3">#000023b3</color> + <color name="i_am_color_23b4">#000023b4</color> + <color name="i_am_color_23b5">#000023b5</color> + <color name="i_am_color_23b6">#000023b6</color> + <color name="i_am_color_23b7">#000023b7</color> + <color name="i_am_color_23b8">#000023b8</color> + <color name="i_am_color_23b9">#000023b9</color> + <color name="i_am_color_23ba">#000023ba</color> + <color name="i_am_color_23bb">#000023bb</color> + <color name="i_am_color_23bc">#000023bc</color> + <color name="i_am_color_23bd">#000023bd</color> + <color name="i_am_color_23be">#000023be</color> + <color name="i_am_color_23bf">#000023bf</color> + <color name="i_am_color_23c0">#000023c0</color> + <color name="i_am_color_23c1">#000023c1</color> + <color name="i_am_color_23c2">#000023c2</color> + <color name="i_am_color_23c3">#000023c3</color> + <color name="i_am_color_23c4">#000023c4</color> + <color name="i_am_color_23c5">#000023c5</color> + <color name="i_am_color_23c6">#000023c6</color> + <color name="i_am_color_23c7">#000023c7</color> + <color name="i_am_color_23c8">#000023c8</color> + <color name="i_am_color_23c9">#000023c9</color> + <color name="i_am_color_23ca">#000023ca</color> + <color name="i_am_color_23cb">#000023cb</color> + <color name="i_am_color_23cc">#000023cc</color> + <color name="i_am_color_23cd">#000023cd</color> + <color name="i_am_color_23ce">#000023ce</color> + <color name="i_am_color_23cf">#000023cf</color> + <color name="i_am_color_23d0">#000023d0</color> + <color name="i_am_color_23d1">#000023d1</color> + <color name="i_am_color_23d2">#000023d2</color> + <color name="i_am_color_23d3">#000023d3</color> + <color name="i_am_color_23d4">#000023d4</color> + <color name="i_am_color_23d5">#000023d5</color> + <color name="i_am_color_23d6">#000023d6</color> + <color name="i_am_color_23d7">#000023d7</color> + <color name="i_am_color_23d8">#000023d8</color> + <color name="i_am_color_23d9">#000023d9</color> + <color name="i_am_color_23da">#000023da</color> + <color name="i_am_color_23db">#000023db</color> + <color name="i_am_color_23dc">#000023dc</color> + <color name="i_am_color_23dd">#000023dd</color> + <color name="i_am_color_23de">#000023de</color> + <color name="i_am_color_23df">#000023df</color> + <color name="i_am_color_23e0">#000023e0</color> + <color name="i_am_color_23e1">#000023e1</color> + <color name="i_am_color_23e2">#000023e2</color> + <color name="i_am_color_23e3">#000023e3</color> + <color name="i_am_color_23e4">#000023e4</color> + <color name="i_am_color_23e5">#000023e5</color> + <color name="i_am_color_23e6">#000023e6</color> + <color name="i_am_color_23e7">#000023e7</color> + <color name="i_am_color_23e8">#000023e8</color> + <color name="i_am_color_23e9">#000023e9</color> + <color name="i_am_color_23ea">#000023ea</color> + <color name="i_am_color_23eb">#000023eb</color> + <color name="i_am_color_23ec">#000023ec</color> + <color name="i_am_color_23ed">#000023ed</color> + <color name="i_am_color_23ee">#000023ee</color> + <color name="i_am_color_23ef">#000023ef</color> + <color name="i_am_color_23f0">#000023f0</color> + <color name="i_am_color_23f1">#000023f1</color> + <color name="i_am_color_23f2">#000023f2</color> + <color name="i_am_color_23f3">#000023f3</color> + <color name="i_am_color_23f4">#000023f4</color> + <color name="i_am_color_23f5">#000023f5</color> + <color name="i_am_color_23f6">#000023f6</color> + <color name="i_am_color_23f7">#000023f7</color> + <color name="i_am_color_23f8">#000023f8</color> + <color name="i_am_color_23f9">#000023f9</color> + <color name="i_am_color_23fa">#000023fa</color> + <color name="i_am_color_23fb">#000023fb</color> + <color name="i_am_color_23fc">#000023fc</color> + <color name="i_am_color_23fd">#000023fd</color> + <color name="i_am_color_23fe">#000023fe</color> + <color name="i_am_color_23ff">#000023ff</color> + <color name="i_am_color_2400">#00002400</color> + <color name="i_am_color_2401">#00002401</color> + <color name="i_am_color_2402">#00002402</color> + <color name="i_am_color_2403">#00002403</color> + <color name="i_am_color_2404">#00002404</color> + <color name="i_am_color_2405">#00002405</color> + <color name="i_am_color_2406">#00002406</color> + <color name="i_am_color_2407">#00002407</color> + <color name="i_am_color_2408">#00002408</color> + <color name="i_am_color_2409">#00002409</color> + <color name="i_am_color_240a">#0000240a</color> + <color name="i_am_color_240b">#0000240b</color> + <color name="i_am_color_240c">#0000240c</color> + <color name="i_am_color_240d">#0000240d</color> + <color name="i_am_color_240e">#0000240e</color> + <color name="i_am_color_240f">#0000240f</color> + <color name="i_am_color_2410">#00002410</color> + <color name="i_am_color_2411">#00002411</color> + <color name="i_am_color_2412">#00002412</color> + <color name="i_am_color_2413">#00002413</color> + <color name="i_am_color_2414">#00002414</color> + <color name="i_am_color_2415">#00002415</color> + <color name="i_am_color_2416">#00002416</color> + <color name="i_am_color_2417">#00002417</color> + <color name="i_am_color_2418">#00002418</color> + <color name="i_am_color_2419">#00002419</color> + <color name="i_am_color_241a">#0000241a</color> + <color name="i_am_color_241b">#0000241b</color> + <color name="i_am_color_241c">#0000241c</color> + <color name="i_am_color_241d">#0000241d</color> + <color name="i_am_color_241e">#0000241e</color> + <color name="i_am_color_241f">#0000241f</color> + <color name="i_am_color_2420">#00002420</color> + <color name="i_am_color_2421">#00002421</color> + <color name="i_am_color_2422">#00002422</color> + <color name="i_am_color_2423">#00002423</color> + <color name="i_am_color_2424">#00002424</color> + <color name="i_am_color_2425">#00002425</color> + <color name="i_am_color_2426">#00002426</color> + <color name="i_am_color_2427">#00002427</color> + <color name="i_am_color_2428">#00002428</color> + <color name="i_am_color_2429">#00002429</color> + <color name="i_am_color_242a">#0000242a</color> + <color name="i_am_color_242b">#0000242b</color> + <color name="i_am_color_242c">#0000242c</color> + <color name="i_am_color_242d">#0000242d</color> + <color name="i_am_color_242e">#0000242e</color> + <color name="i_am_color_242f">#0000242f</color> + <color name="i_am_color_2430">#00002430</color> + <color name="i_am_color_2431">#00002431</color> + <color name="i_am_color_2432">#00002432</color> + <color name="i_am_color_2433">#00002433</color> + <color name="i_am_color_2434">#00002434</color> + <color name="i_am_color_2435">#00002435</color> + <color name="i_am_color_2436">#00002436</color> + <color name="i_am_color_2437">#00002437</color> + <color name="i_am_color_2438">#00002438</color> + <color name="i_am_color_2439">#00002439</color> + <color name="i_am_color_243a">#0000243a</color> + <color name="i_am_color_243b">#0000243b</color> + <color name="i_am_color_243c">#0000243c</color> + <color name="i_am_color_243d">#0000243d</color> + <color name="i_am_color_243e">#0000243e</color> + <color name="i_am_color_243f">#0000243f</color> + <color name="i_am_color_2440">#00002440</color> + <color name="i_am_color_2441">#00002441</color> + <color name="i_am_color_2442">#00002442</color> + <color name="i_am_color_2443">#00002443</color> + <color name="i_am_color_2444">#00002444</color> + <color name="i_am_color_2445">#00002445</color> + <color name="i_am_color_2446">#00002446</color> + <color name="i_am_color_2447">#00002447</color> + <color name="i_am_color_2448">#00002448</color> + <color name="i_am_color_2449">#00002449</color> + <color name="i_am_color_244a">#0000244a</color> + <color name="i_am_color_244b">#0000244b</color> + <color name="i_am_color_244c">#0000244c</color> + <color name="i_am_color_244d">#0000244d</color> + <color name="i_am_color_244e">#0000244e</color> + <color name="i_am_color_244f">#0000244f</color> + <color name="i_am_color_2450">#00002450</color> + <color name="i_am_color_2451">#00002451</color> + <color name="i_am_color_2452">#00002452</color> + <color name="i_am_color_2453">#00002453</color> + <color name="i_am_color_2454">#00002454</color> + <color name="i_am_color_2455">#00002455</color> + <color name="i_am_color_2456">#00002456</color> + <color name="i_am_color_2457">#00002457</color> + <color name="i_am_color_2458">#00002458</color> + <color name="i_am_color_2459">#00002459</color> + <color name="i_am_color_245a">#0000245a</color> + <color name="i_am_color_245b">#0000245b</color> + <color name="i_am_color_245c">#0000245c</color> + <color name="i_am_color_245d">#0000245d</color> + <color name="i_am_color_245e">#0000245e</color> + <color name="i_am_color_245f">#0000245f</color> + <color name="i_am_color_2460">#00002460</color> + <color name="i_am_color_2461">#00002461</color> + <color name="i_am_color_2462">#00002462</color> + <color name="i_am_color_2463">#00002463</color> + <color name="i_am_color_2464">#00002464</color> + <color name="i_am_color_2465">#00002465</color> + <color name="i_am_color_2466">#00002466</color> + <color name="i_am_color_2467">#00002467</color> + <color name="i_am_color_2468">#00002468</color> + <color name="i_am_color_2469">#00002469</color> + <color name="i_am_color_246a">#0000246a</color> + <color name="i_am_color_246b">#0000246b</color> + <color name="i_am_color_246c">#0000246c</color> + <color name="i_am_color_246d">#0000246d</color> + <color name="i_am_color_246e">#0000246e</color> + <color name="i_am_color_246f">#0000246f</color> + <color name="i_am_color_2470">#00002470</color> + <color name="i_am_color_2471">#00002471</color> + <color name="i_am_color_2472">#00002472</color> + <color name="i_am_color_2473">#00002473</color> + <color name="i_am_color_2474">#00002474</color> + <color name="i_am_color_2475">#00002475</color> + <color name="i_am_color_2476">#00002476</color> + <color name="i_am_color_2477">#00002477</color> + <color name="i_am_color_2478">#00002478</color> + <color name="i_am_color_2479">#00002479</color> + <color name="i_am_color_247a">#0000247a</color> + <color name="i_am_color_247b">#0000247b</color> + <color name="i_am_color_247c">#0000247c</color> + <color name="i_am_color_247d">#0000247d</color> + <color name="i_am_color_247e">#0000247e</color> + <color name="i_am_color_247f">#0000247f</color> + <color name="i_am_color_2480">#00002480</color> + <color name="i_am_color_2481">#00002481</color> + <color name="i_am_color_2482">#00002482</color> + <color name="i_am_color_2483">#00002483</color> + <color name="i_am_color_2484">#00002484</color> + <color name="i_am_color_2485">#00002485</color> + <color name="i_am_color_2486">#00002486</color> + <color name="i_am_color_2487">#00002487</color> + <color name="i_am_color_2488">#00002488</color> + <color name="i_am_color_2489">#00002489</color> + <color name="i_am_color_248a">#0000248a</color> + <color name="i_am_color_248b">#0000248b</color> + <color name="i_am_color_248c">#0000248c</color> + <color name="i_am_color_248d">#0000248d</color> + <color name="i_am_color_248e">#0000248e</color> + <color name="i_am_color_248f">#0000248f</color> + <color name="i_am_color_2490">#00002490</color> + <color name="i_am_color_2491">#00002491</color> + <color name="i_am_color_2492">#00002492</color> + <color name="i_am_color_2493">#00002493</color> + <color name="i_am_color_2494">#00002494</color> + <color name="i_am_color_2495">#00002495</color> + <color name="i_am_color_2496">#00002496</color> + <color name="i_am_color_2497">#00002497</color> + <color name="i_am_color_2498">#00002498</color> + <color name="i_am_color_2499">#00002499</color> + <color name="i_am_color_249a">#0000249a</color> + <color name="i_am_color_249b">#0000249b</color> + <color name="i_am_color_249c">#0000249c</color> + <color name="i_am_color_249d">#0000249d</color> + <color name="i_am_color_249e">#0000249e</color> + <color name="i_am_color_249f">#0000249f</color> + <color name="i_am_color_24a0">#000024a0</color> + <color name="i_am_color_24a1">#000024a1</color> + <color name="i_am_color_24a2">#000024a2</color> + <color name="i_am_color_24a3">#000024a3</color> + <color name="i_am_color_24a4">#000024a4</color> + <color name="i_am_color_24a5">#000024a5</color> + <color name="i_am_color_24a6">#000024a6</color> + <color name="i_am_color_24a7">#000024a7</color> + <color name="i_am_color_24a8">#000024a8</color> + <color name="i_am_color_24a9">#000024a9</color> + <color name="i_am_color_24aa">#000024aa</color> + <color name="i_am_color_24ab">#000024ab</color> + <color name="i_am_color_24ac">#000024ac</color> + <color name="i_am_color_24ad">#000024ad</color> + <color name="i_am_color_24ae">#000024ae</color> + <color name="i_am_color_24af">#000024af</color> + <color name="i_am_color_24b0">#000024b0</color> + <color name="i_am_color_24b1">#000024b1</color> + <color name="i_am_color_24b2">#000024b2</color> + <color name="i_am_color_24b3">#000024b3</color> + <color name="i_am_color_24b4">#000024b4</color> + <color name="i_am_color_24b5">#000024b5</color> + <color name="i_am_color_24b6">#000024b6</color> + <color name="i_am_color_24b7">#000024b7</color> + <color name="i_am_color_24b8">#000024b8</color> + <color name="i_am_color_24b9">#000024b9</color> + <color name="i_am_color_24ba">#000024ba</color> + <color name="i_am_color_24bb">#000024bb</color> + <color name="i_am_color_24bc">#000024bc</color> + <color name="i_am_color_24bd">#000024bd</color> + <color name="i_am_color_24be">#000024be</color> + <color name="i_am_color_24bf">#000024bf</color> + <color name="i_am_color_24c0">#000024c0</color> + <color name="i_am_color_24c1">#000024c1</color> + <color name="i_am_color_24c2">#000024c2</color> + <color name="i_am_color_24c3">#000024c3</color> + <color name="i_am_color_24c4">#000024c4</color> + <color name="i_am_color_24c5">#000024c5</color> + <color name="i_am_color_24c6">#000024c6</color> + <color name="i_am_color_24c7">#000024c7</color> + <color name="i_am_color_24c8">#000024c8</color> + <color name="i_am_color_24c9">#000024c9</color> + <color name="i_am_color_24ca">#000024ca</color> + <color name="i_am_color_24cb">#000024cb</color> + <color name="i_am_color_24cc">#000024cc</color> + <color name="i_am_color_24cd">#000024cd</color> + <color name="i_am_color_24ce">#000024ce</color> + <color name="i_am_color_24cf">#000024cf</color> + <color name="i_am_color_24d0">#000024d0</color> + <color name="i_am_color_24d1">#000024d1</color> + <color name="i_am_color_24d2">#000024d2</color> + <color name="i_am_color_24d3">#000024d3</color> + <color name="i_am_color_24d4">#000024d4</color> + <color name="i_am_color_24d5">#000024d5</color> + <color name="i_am_color_24d6">#000024d6</color> + <color name="i_am_color_24d7">#000024d7</color> + <color name="i_am_color_24d8">#000024d8</color> + <color name="i_am_color_24d9">#000024d9</color> + <color name="i_am_color_24da">#000024da</color> + <color name="i_am_color_24db">#000024db</color> + <color name="i_am_color_24dc">#000024dc</color> + <color name="i_am_color_24dd">#000024dd</color> + <color name="i_am_color_24de">#000024de</color> + <color name="i_am_color_24df">#000024df</color> + <color name="i_am_color_24e0">#000024e0</color> + <color name="i_am_color_24e1">#000024e1</color> + <color name="i_am_color_24e2">#000024e2</color> + <color name="i_am_color_24e3">#000024e3</color> + <color name="i_am_color_24e4">#000024e4</color> + <color name="i_am_color_24e5">#000024e5</color> + <color name="i_am_color_24e6">#000024e6</color> + <color name="i_am_color_24e7">#000024e7</color> + <color name="i_am_color_24e8">#000024e8</color> + <color name="i_am_color_24e9">#000024e9</color> + <color name="i_am_color_24ea">#000024ea</color> + <color name="i_am_color_24eb">#000024eb</color> + <color name="i_am_color_24ec">#000024ec</color> + <color name="i_am_color_24ed">#000024ed</color> + <color name="i_am_color_24ee">#000024ee</color> + <color name="i_am_color_24ef">#000024ef</color> + <color name="i_am_color_24f0">#000024f0</color> + <color name="i_am_color_24f1">#000024f1</color> + <color name="i_am_color_24f2">#000024f2</color> + <color name="i_am_color_24f3">#000024f3</color> + <color name="i_am_color_24f4">#000024f4</color> + <color name="i_am_color_24f5">#000024f5</color> + <color name="i_am_color_24f6">#000024f6</color> + <color name="i_am_color_24f7">#000024f7</color> + <color name="i_am_color_24f8">#000024f8</color> + <color name="i_am_color_24f9">#000024f9</color> + <color name="i_am_color_24fa">#000024fa</color> + <color name="i_am_color_24fb">#000024fb</color> + <color name="i_am_color_24fc">#000024fc</color> + <color name="i_am_color_24fd">#000024fd</color> + <color name="i_am_color_24fe">#000024fe</color> + <color name="i_am_color_24ff">#000024ff</color> + <color name="i_am_color_2500">#00002500</color> + <color name="i_am_color_2501">#00002501</color> + <color name="i_am_color_2502">#00002502</color> + <color name="i_am_color_2503">#00002503</color> + <color name="i_am_color_2504">#00002504</color> + <color name="i_am_color_2505">#00002505</color> + <color name="i_am_color_2506">#00002506</color> + <color name="i_am_color_2507">#00002507</color> + <color name="i_am_color_2508">#00002508</color> + <color name="i_am_color_2509">#00002509</color> + <color name="i_am_color_250a">#0000250a</color> + <color name="i_am_color_250b">#0000250b</color> + <color name="i_am_color_250c">#0000250c</color> + <color name="i_am_color_250d">#0000250d</color> + <color name="i_am_color_250e">#0000250e</color> + <color name="i_am_color_250f">#0000250f</color> + <color name="i_am_color_2510">#00002510</color> + <color name="i_am_color_2511">#00002511</color> + <color name="i_am_color_2512">#00002512</color> + <color name="i_am_color_2513">#00002513</color> + <color name="i_am_color_2514">#00002514</color> + <color name="i_am_color_2515">#00002515</color> + <color name="i_am_color_2516">#00002516</color> + <color name="i_am_color_2517">#00002517</color> + <color name="i_am_color_2518">#00002518</color> + <color name="i_am_color_2519">#00002519</color> + <color name="i_am_color_251a">#0000251a</color> + <color name="i_am_color_251b">#0000251b</color> + <color name="i_am_color_251c">#0000251c</color> + <color name="i_am_color_251d">#0000251d</color> + <color name="i_am_color_251e">#0000251e</color> + <color name="i_am_color_251f">#0000251f</color> + <color name="i_am_color_2520">#00002520</color> + <color name="i_am_color_2521">#00002521</color> + <color name="i_am_color_2522">#00002522</color> + <color name="i_am_color_2523">#00002523</color> + <color name="i_am_color_2524">#00002524</color> + <color name="i_am_color_2525">#00002525</color> + <color name="i_am_color_2526">#00002526</color> + <color name="i_am_color_2527">#00002527</color> + <color name="i_am_color_2528">#00002528</color> + <color name="i_am_color_2529">#00002529</color> + <color name="i_am_color_252a">#0000252a</color> + <color name="i_am_color_252b">#0000252b</color> + <color name="i_am_color_252c">#0000252c</color> + <color name="i_am_color_252d">#0000252d</color> + <color name="i_am_color_252e">#0000252e</color> + <color name="i_am_color_252f">#0000252f</color> + <color name="i_am_color_2530">#00002530</color> + <color name="i_am_color_2531">#00002531</color> + <color name="i_am_color_2532">#00002532</color> + <color name="i_am_color_2533">#00002533</color> + <color name="i_am_color_2534">#00002534</color> + <color name="i_am_color_2535">#00002535</color> + <color name="i_am_color_2536">#00002536</color> + <color name="i_am_color_2537">#00002537</color> + <color name="i_am_color_2538">#00002538</color> + <color name="i_am_color_2539">#00002539</color> + <color name="i_am_color_253a">#0000253a</color> + <color name="i_am_color_253b">#0000253b</color> + <color name="i_am_color_253c">#0000253c</color> + <color name="i_am_color_253d">#0000253d</color> + <color name="i_am_color_253e">#0000253e</color> + <color name="i_am_color_253f">#0000253f</color> + <color name="i_am_color_2540">#00002540</color> + <color name="i_am_color_2541">#00002541</color> + <color name="i_am_color_2542">#00002542</color> + <color name="i_am_color_2543">#00002543</color> + <color name="i_am_color_2544">#00002544</color> + <color name="i_am_color_2545">#00002545</color> + <color name="i_am_color_2546">#00002546</color> + <color name="i_am_color_2547">#00002547</color> + <color name="i_am_color_2548">#00002548</color> + <color name="i_am_color_2549">#00002549</color> + <color name="i_am_color_254a">#0000254a</color> + <color name="i_am_color_254b">#0000254b</color> + <color name="i_am_color_254c">#0000254c</color> + <color name="i_am_color_254d">#0000254d</color> + <color name="i_am_color_254e">#0000254e</color> + <color name="i_am_color_254f">#0000254f</color> + <color name="i_am_color_2550">#00002550</color> + <color name="i_am_color_2551">#00002551</color> + <color name="i_am_color_2552">#00002552</color> + <color name="i_am_color_2553">#00002553</color> + <color name="i_am_color_2554">#00002554</color> + <color name="i_am_color_2555">#00002555</color> + <color name="i_am_color_2556">#00002556</color> + <color name="i_am_color_2557">#00002557</color> + <color name="i_am_color_2558">#00002558</color> + <color name="i_am_color_2559">#00002559</color> + <color name="i_am_color_255a">#0000255a</color> + <color name="i_am_color_255b">#0000255b</color> + <color name="i_am_color_255c">#0000255c</color> + <color name="i_am_color_255d">#0000255d</color> + <color name="i_am_color_255e">#0000255e</color> + <color name="i_am_color_255f">#0000255f</color> + <color name="i_am_color_2560">#00002560</color> + <color name="i_am_color_2561">#00002561</color> + <color name="i_am_color_2562">#00002562</color> + <color name="i_am_color_2563">#00002563</color> + <color name="i_am_color_2564">#00002564</color> + <color name="i_am_color_2565">#00002565</color> + <color name="i_am_color_2566">#00002566</color> + <color name="i_am_color_2567">#00002567</color> + <color name="i_am_color_2568">#00002568</color> + <color name="i_am_color_2569">#00002569</color> + <color name="i_am_color_256a">#0000256a</color> + <color name="i_am_color_256b">#0000256b</color> + <color name="i_am_color_256c">#0000256c</color> + <color name="i_am_color_256d">#0000256d</color> + <color name="i_am_color_256e">#0000256e</color> + <color name="i_am_color_256f">#0000256f</color> + <color name="i_am_color_2570">#00002570</color> + <color name="i_am_color_2571">#00002571</color> + <color name="i_am_color_2572">#00002572</color> + <color name="i_am_color_2573">#00002573</color> + <color name="i_am_color_2574">#00002574</color> + <color name="i_am_color_2575">#00002575</color> + <color name="i_am_color_2576">#00002576</color> + <color name="i_am_color_2577">#00002577</color> + <color name="i_am_color_2578">#00002578</color> + <color name="i_am_color_2579">#00002579</color> + <color name="i_am_color_257a">#0000257a</color> + <color name="i_am_color_257b">#0000257b</color> + <color name="i_am_color_257c">#0000257c</color> + <color name="i_am_color_257d">#0000257d</color> + <color name="i_am_color_257e">#0000257e</color> + <color name="i_am_color_257f">#0000257f</color> + <color name="i_am_color_2580">#00002580</color> + <color name="i_am_color_2581">#00002581</color> + <color name="i_am_color_2582">#00002582</color> + <color name="i_am_color_2583">#00002583</color> + <color name="i_am_color_2584">#00002584</color> + <color name="i_am_color_2585">#00002585</color> + <color name="i_am_color_2586">#00002586</color> + <color name="i_am_color_2587">#00002587</color> + <color name="i_am_color_2588">#00002588</color> + <color name="i_am_color_2589">#00002589</color> + <color name="i_am_color_258a">#0000258a</color> + <color name="i_am_color_258b">#0000258b</color> + <color name="i_am_color_258c">#0000258c</color> + <color name="i_am_color_258d">#0000258d</color> + <color name="i_am_color_258e">#0000258e</color> + <color name="i_am_color_258f">#0000258f</color> + <color name="i_am_color_2590">#00002590</color> + <color name="i_am_color_2591">#00002591</color> + <color name="i_am_color_2592">#00002592</color> + <color name="i_am_color_2593">#00002593</color> + <color name="i_am_color_2594">#00002594</color> + <color name="i_am_color_2595">#00002595</color> + <color name="i_am_color_2596">#00002596</color> + <color name="i_am_color_2597">#00002597</color> + <color name="i_am_color_2598">#00002598</color> + <color name="i_am_color_2599">#00002599</color> + <color name="i_am_color_259a">#0000259a</color> + <color name="i_am_color_259b">#0000259b</color> + <color name="i_am_color_259c">#0000259c</color> + <color name="i_am_color_259d">#0000259d</color> + <color name="i_am_color_259e">#0000259e</color> + <color name="i_am_color_259f">#0000259f</color> + <color name="i_am_color_25a0">#000025a0</color> + <color name="i_am_color_25a1">#000025a1</color> + <color name="i_am_color_25a2">#000025a2</color> + <color name="i_am_color_25a3">#000025a3</color> + <color name="i_am_color_25a4">#000025a4</color> + <color name="i_am_color_25a5">#000025a5</color> + <color name="i_am_color_25a6">#000025a6</color> + <color name="i_am_color_25a7">#000025a7</color> + <color name="i_am_color_25a8">#000025a8</color> + <color name="i_am_color_25a9">#000025a9</color> + <color name="i_am_color_25aa">#000025aa</color> + <color name="i_am_color_25ab">#000025ab</color> + <color name="i_am_color_25ac">#000025ac</color> + <color name="i_am_color_25ad">#000025ad</color> + <color name="i_am_color_25ae">#000025ae</color> + <color name="i_am_color_25af">#000025af</color> + <color name="i_am_color_25b0">#000025b0</color> + <color name="i_am_color_25b1">#000025b1</color> + <color name="i_am_color_25b2">#000025b2</color> + <color name="i_am_color_25b3">#000025b3</color> + <color name="i_am_color_25b4">#000025b4</color> + <color name="i_am_color_25b5">#000025b5</color> + <color name="i_am_color_25b6">#000025b6</color> + <color name="i_am_color_25b7">#000025b7</color> + <color name="i_am_color_25b8">#000025b8</color> + <color name="i_am_color_25b9">#000025b9</color> + <color name="i_am_color_25ba">#000025ba</color> + <color name="i_am_color_25bb">#000025bb</color> + <color name="i_am_color_25bc">#000025bc</color> + <color name="i_am_color_25bd">#000025bd</color> + <color name="i_am_color_25be">#000025be</color> + <color name="i_am_color_25bf">#000025bf</color> + <color name="i_am_color_25c0">#000025c0</color> + <color name="i_am_color_25c1">#000025c1</color> + <color name="i_am_color_25c2">#000025c2</color> + <color name="i_am_color_25c3">#000025c3</color> + <color name="i_am_color_25c4">#000025c4</color> + <color name="i_am_color_25c5">#000025c5</color> + <color name="i_am_color_25c6">#000025c6</color> + <color name="i_am_color_25c7">#000025c7</color> + <color name="i_am_color_25c8">#000025c8</color> + <color name="i_am_color_25c9">#000025c9</color> + <color name="i_am_color_25ca">#000025ca</color> + <color name="i_am_color_25cb">#000025cb</color> + <color name="i_am_color_25cc">#000025cc</color> + <color name="i_am_color_25cd">#000025cd</color> + <color name="i_am_color_25ce">#000025ce</color> + <color name="i_am_color_25cf">#000025cf</color> + <color name="i_am_color_25d0">#000025d0</color> + <color name="i_am_color_25d1">#000025d1</color> + <color name="i_am_color_25d2">#000025d2</color> + <color name="i_am_color_25d3">#000025d3</color> + <color name="i_am_color_25d4">#000025d4</color> + <color name="i_am_color_25d5">#000025d5</color> + <color name="i_am_color_25d6">#000025d6</color> + <color name="i_am_color_25d7">#000025d7</color> + <color name="i_am_color_25d8">#000025d8</color> + <color name="i_am_color_25d9">#000025d9</color> + <color name="i_am_color_25da">#000025da</color> + <color name="i_am_color_25db">#000025db</color> + <color name="i_am_color_25dc">#000025dc</color> + <color name="i_am_color_25dd">#000025dd</color> + <color name="i_am_color_25de">#000025de</color> + <color name="i_am_color_25df">#000025df</color> + <color name="i_am_color_25e0">#000025e0</color> + <color name="i_am_color_25e1">#000025e1</color> + <color name="i_am_color_25e2">#000025e2</color> + <color name="i_am_color_25e3">#000025e3</color> + <color name="i_am_color_25e4">#000025e4</color> + <color name="i_am_color_25e5">#000025e5</color> + <color name="i_am_color_25e6">#000025e6</color> + <color name="i_am_color_25e7">#000025e7</color> + <color name="i_am_color_25e8">#000025e8</color> + <color name="i_am_color_25e9">#000025e9</color> + <color name="i_am_color_25ea">#000025ea</color> + <color name="i_am_color_25eb">#000025eb</color> + <color name="i_am_color_25ec">#000025ec</color> + <color name="i_am_color_25ed">#000025ed</color> + <color name="i_am_color_25ee">#000025ee</color> + <color name="i_am_color_25ef">#000025ef</color> + <color name="i_am_color_25f0">#000025f0</color> + <color name="i_am_color_25f1">#000025f1</color> + <color name="i_am_color_25f2">#000025f2</color> + <color name="i_am_color_25f3">#000025f3</color> + <color name="i_am_color_25f4">#000025f4</color> + <color name="i_am_color_25f5">#000025f5</color> + <color name="i_am_color_25f6">#000025f6</color> + <color name="i_am_color_25f7">#000025f7</color> + <color name="i_am_color_25f8">#000025f8</color> + <color name="i_am_color_25f9">#000025f9</color> + <color name="i_am_color_25fa">#000025fa</color> + <color name="i_am_color_25fb">#000025fb</color> + <color name="i_am_color_25fc">#000025fc</color> + <color name="i_am_color_25fd">#000025fd</color> + <color name="i_am_color_25fe">#000025fe</color> + <color name="i_am_color_25ff">#000025ff</color> + <color name="i_am_color_2600">#00002600</color> + <color name="i_am_color_2601">#00002601</color> + <color name="i_am_color_2602">#00002602</color> + <color name="i_am_color_2603">#00002603</color> + <color name="i_am_color_2604">#00002604</color> + <color name="i_am_color_2605">#00002605</color> + <color name="i_am_color_2606">#00002606</color> + <color name="i_am_color_2607">#00002607</color> + <color name="i_am_color_2608">#00002608</color> + <color name="i_am_color_2609">#00002609</color> + <color name="i_am_color_260a">#0000260a</color> + <color name="i_am_color_260b">#0000260b</color> + <color name="i_am_color_260c">#0000260c</color> + <color name="i_am_color_260d">#0000260d</color> + <color name="i_am_color_260e">#0000260e</color> + <color name="i_am_color_260f">#0000260f</color> + <color name="i_am_color_2610">#00002610</color> + <color name="i_am_color_2611">#00002611</color> + <color name="i_am_color_2612">#00002612</color> + <color name="i_am_color_2613">#00002613</color> + <color name="i_am_color_2614">#00002614</color> + <color name="i_am_color_2615">#00002615</color> + <color name="i_am_color_2616">#00002616</color> + <color name="i_am_color_2617">#00002617</color> + <color name="i_am_color_2618">#00002618</color> + <color name="i_am_color_2619">#00002619</color> + <color name="i_am_color_261a">#0000261a</color> + <color name="i_am_color_261b">#0000261b</color> + <color name="i_am_color_261c">#0000261c</color> + <color name="i_am_color_261d">#0000261d</color> + <color name="i_am_color_261e">#0000261e</color> + <color name="i_am_color_261f">#0000261f</color> + <color name="i_am_color_2620">#00002620</color> + <color name="i_am_color_2621">#00002621</color> + <color name="i_am_color_2622">#00002622</color> + <color name="i_am_color_2623">#00002623</color> + <color name="i_am_color_2624">#00002624</color> + <color name="i_am_color_2625">#00002625</color> + <color name="i_am_color_2626">#00002626</color> + <color name="i_am_color_2627">#00002627</color> + <color name="i_am_color_2628">#00002628</color> + <color name="i_am_color_2629">#00002629</color> + <color name="i_am_color_262a">#0000262a</color> + <color name="i_am_color_262b">#0000262b</color> + <color name="i_am_color_262c">#0000262c</color> + <color name="i_am_color_262d">#0000262d</color> + <color name="i_am_color_262e">#0000262e</color> + <color name="i_am_color_262f">#0000262f</color> + <color name="i_am_color_2630">#00002630</color> + <color name="i_am_color_2631">#00002631</color> + <color name="i_am_color_2632">#00002632</color> + <color name="i_am_color_2633">#00002633</color> + <color name="i_am_color_2634">#00002634</color> + <color name="i_am_color_2635">#00002635</color> + <color name="i_am_color_2636">#00002636</color> + <color name="i_am_color_2637">#00002637</color> + <color name="i_am_color_2638">#00002638</color> + <color name="i_am_color_2639">#00002639</color> + <color name="i_am_color_263a">#0000263a</color> + <color name="i_am_color_263b">#0000263b</color> + <color name="i_am_color_263c">#0000263c</color> + <color name="i_am_color_263d">#0000263d</color> + <color name="i_am_color_263e">#0000263e</color> + <color name="i_am_color_263f">#0000263f</color> + <color name="i_am_color_2640">#00002640</color> + <color name="i_am_color_2641">#00002641</color> + <color name="i_am_color_2642">#00002642</color> + <color name="i_am_color_2643">#00002643</color> + <color name="i_am_color_2644">#00002644</color> + <color name="i_am_color_2645">#00002645</color> + <color name="i_am_color_2646">#00002646</color> + <color name="i_am_color_2647">#00002647</color> + <color name="i_am_color_2648">#00002648</color> + <color name="i_am_color_2649">#00002649</color> + <color name="i_am_color_264a">#0000264a</color> + <color name="i_am_color_264b">#0000264b</color> + <color name="i_am_color_264c">#0000264c</color> + <color name="i_am_color_264d">#0000264d</color> + <color name="i_am_color_264e">#0000264e</color> + <color name="i_am_color_264f">#0000264f</color> + <color name="i_am_color_2650">#00002650</color> + <color name="i_am_color_2651">#00002651</color> + <color name="i_am_color_2652">#00002652</color> + <color name="i_am_color_2653">#00002653</color> + <color name="i_am_color_2654">#00002654</color> + <color name="i_am_color_2655">#00002655</color> + <color name="i_am_color_2656">#00002656</color> + <color name="i_am_color_2657">#00002657</color> + <color name="i_am_color_2658">#00002658</color> + <color name="i_am_color_2659">#00002659</color> + <color name="i_am_color_265a">#0000265a</color> + <color name="i_am_color_265b">#0000265b</color> + <color name="i_am_color_265c">#0000265c</color> + <color name="i_am_color_265d">#0000265d</color> + <color name="i_am_color_265e">#0000265e</color> + <color name="i_am_color_265f">#0000265f</color> + <color name="i_am_color_2660">#00002660</color> + <color name="i_am_color_2661">#00002661</color> + <color name="i_am_color_2662">#00002662</color> + <color name="i_am_color_2663">#00002663</color> + <color name="i_am_color_2664">#00002664</color> + <color name="i_am_color_2665">#00002665</color> + <color name="i_am_color_2666">#00002666</color> + <color name="i_am_color_2667">#00002667</color> + <color name="i_am_color_2668">#00002668</color> + <color name="i_am_color_2669">#00002669</color> + <color name="i_am_color_266a">#0000266a</color> + <color name="i_am_color_266b">#0000266b</color> + <color name="i_am_color_266c">#0000266c</color> + <color name="i_am_color_266d">#0000266d</color> + <color name="i_am_color_266e">#0000266e</color> + <color name="i_am_color_266f">#0000266f</color> + <color name="i_am_color_2670">#00002670</color> + <color name="i_am_color_2671">#00002671</color> + <color name="i_am_color_2672">#00002672</color> + <color name="i_am_color_2673">#00002673</color> + <color name="i_am_color_2674">#00002674</color> + <color name="i_am_color_2675">#00002675</color> + <color name="i_am_color_2676">#00002676</color> + <color name="i_am_color_2677">#00002677</color> + <color name="i_am_color_2678">#00002678</color> + <color name="i_am_color_2679">#00002679</color> + <color name="i_am_color_267a">#0000267a</color> + <color name="i_am_color_267b">#0000267b</color> + <color name="i_am_color_267c">#0000267c</color> + <color name="i_am_color_267d">#0000267d</color> + <color name="i_am_color_267e">#0000267e</color> + <color name="i_am_color_267f">#0000267f</color> + <color name="i_am_color_2680">#00002680</color> + <color name="i_am_color_2681">#00002681</color> + <color name="i_am_color_2682">#00002682</color> + <color name="i_am_color_2683">#00002683</color> + <color name="i_am_color_2684">#00002684</color> + <color name="i_am_color_2685">#00002685</color> + <color name="i_am_color_2686">#00002686</color> + <color name="i_am_color_2687">#00002687</color> + <color name="i_am_color_2688">#00002688</color> + <color name="i_am_color_2689">#00002689</color> + <color name="i_am_color_268a">#0000268a</color> + <color name="i_am_color_268b">#0000268b</color> + <color name="i_am_color_268c">#0000268c</color> + <color name="i_am_color_268d">#0000268d</color> + <color name="i_am_color_268e">#0000268e</color> + <color name="i_am_color_268f">#0000268f</color> + <color name="i_am_color_2690">#00002690</color> + <color name="i_am_color_2691">#00002691</color> + <color name="i_am_color_2692">#00002692</color> + <color name="i_am_color_2693">#00002693</color> + <color name="i_am_color_2694">#00002694</color> + <color name="i_am_color_2695">#00002695</color> + <color name="i_am_color_2696">#00002696</color> + <color name="i_am_color_2697">#00002697</color> + <color name="i_am_color_2698">#00002698</color> + <color name="i_am_color_2699">#00002699</color> + <color name="i_am_color_269a">#0000269a</color> + <color name="i_am_color_269b">#0000269b</color> + <color name="i_am_color_269c">#0000269c</color> + <color name="i_am_color_269d">#0000269d</color> + <color name="i_am_color_269e">#0000269e</color> + <color name="i_am_color_269f">#0000269f</color> + <color name="i_am_color_26a0">#000026a0</color> + <color name="i_am_color_26a1">#000026a1</color> + <color name="i_am_color_26a2">#000026a2</color> + <color name="i_am_color_26a3">#000026a3</color> + <color name="i_am_color_26a4">#000026a4</color> + <color name="i_am_color_26a5">#000026a5</color> + <color name="i_am_color_26a6">#000026a6</color> + <color name="i_am_color_26a7">#000026a7</color> + <color name="i_am_color_26a8">#000026a8</color> + <color name="i_am_color_26a9">#000026a9</color> + <color name="i_am_color_26aa">#000026aa</color> + <color name="i_am_color_26ab">#000026ab</color> + <color name="i_am_color_26ac">#000026ac</color> + <color name="i_am_color_26ad">#000026ad</color> + <color name="i_am_color_26ae">#000026ae</color> + <color name="i_am_color_26af">#000026af</color> + <color name="i_am_color_26b0">#000026b0</color> + <color name="i_am_color_26b1">#000026b1</color> + <color name="i_am_color_26b2">#000026b2</color> + <color name="i_am_color_26b3">#000026b3</color> + <color name="i_am_color_26b4">#000026b4</color> + <color name="i_am_color_26b5">#000026b5</color> + <color name="i_am_color_26b6">#000026b6</color> + <color name="i_am_color_26b7">#000026b7</color> + <color name="i_am_color_26b8">#000026b8</color> + <color name="i_am_color_26b9">#000026b9</color> + <color name="i_am_color_26ba">#000026ba</color> + <color name="i_am_color_26bb">#000026bb</color> + <color name="i_am_color_26bc">#000026bc</color> + <color name="i_am_color_26bd">#000026bd</color> + <color name="i_am_color_26be">#000026be</color> + <color name="i_am_color_26bf">#000026bf</color> + <color name="i_am_color_26c0">#000026c0</color> + <color name="i_am_color_26c1">#000026c1</color> + <color name="i_am_color_26c2">#000026c2</color> + <color name="i_am_color_26c3">#000026c3</color> + <color name="i_am_color_26c4">#000026c4</color> + <color name="i_am_color_26c5">#000026c5</color> + <color name="i_am_color_26c6">#000026c6</color> + <color name="i_am_color_26c7">#000026c7</color> + <color name="i_am_color_26c8">#000026c8</color> + <color name="i_am_color_26c9">#000026c9</color> + <color name="i_am_color_26ca">#000026ca</color> + <color name="i_am_color_26cb">#000026cb</color> + <color name="i_am_color_26cc">#000026cc</color> + <color name="i_am_color_26cd">#000026cd</color> + <color name="i_am_color_26ce">#000026ce</color> + <color name="i_am_color_26cf">#000026cf</color> + <color name="i_am_color_26d0">#000026d0</color> + <color name="i_am_color_26d1">#000026d1</color> + <color name="i_am_color_26d2">#000026d2</color> + <color name="i_am_color_26d3">#000026d3</color> + <color name="i_am_color_26d4">#000026d4</color> + <color name="i_am_color_26d5">#000026d5</color> + <color name="i_am_color_26d6">#000026d6</color> + <color name="i_am_color_26d7">#000026d7</color> + <color name="i_am_color_26d8">#000026d8</color> + <color name="i_am_color_26d9">#000026d9</color> + <color name="i_am_color_26da">#000026da</color> + <color name="i_am_color_26db">#000026db</color> + <color name="i_am_color_26dc">#000026dc</color> + <color name="i_am_color_26dd">#000026dd</color> + <color name="i_am_color_26de">#000026de</color> + <color name="i_am_color_26df">#000026df</color> + <color name="i_am_color_26e0">#000026e0</color> + <color name="i_am_color_26e1">#000026e1</color> + <color name="i_am_color_26e2">#000026e2</color> + <color name="i_am_color_26e3">#000026e3</color> + <color name="i_am_color_26e4">#000026e4</color> + <color name="i_am_color_26e5">#000026e5</color> + <color name="i_am_color_26e6">#000026e6</color> + <color name="i_am_color_26e7">#000026e7</color> + <color name="i_am_color_26e8">#000026e8</color> + <color name="i_am_color_26e9">#000026e9</color> + <color name="i_am_color_26ea">#000026ea</color> + <color name="i_am_color_26eb">#000026eb</color> + <color name="i_am_color_26ec">#000026ec</color> + <color name="i_am_color_26ed">#000026ed</color> + <color name="i_am_color_26ee">#000026ee</color> + <color name="i_am_color_26ef">#000026ef</color> + <color name="i_am_color_26f0">#000026f0</color> + <color name="i_am_color_26f1">#000026f1</color> + <color name="i_am_color_26f2">#000026f2</color> + <color name="i_am_color_26f3">#000026f3</color> + <color name="i_am_color_26f4">#000026f4</color> + <color name="i_am_color_26f5">#000026f5</color> + <color name="i_am_color_26f6">#000026f6</color> + <color name="i_am_color_26f7">#000026f7</color> + <color name="i_am_color_26f8">#000026f8</color> + <color name="i_am_color_26f9">#000026f9</color> + <color name="i_am_color_26fa">#000026fa</color> + <color name="i_am_color_26fb">#000026fb</color> + <color name="i_am_color_26fc">#000026fc</color> + <color name="i_am_color_26fd">#000026fd</color> + <color name="i_am_color_26fe">#000026fe</color> + <color name="i_am_color_26ff">#000026ff</color> + <color name="i_am_color_2700">#00002700</color> + <color name="i_am_color_2701">#00002701</color> + <color name="i_am_color_2702">#00002702</color> + <color name="i_am_color_2703">#00002703</color> + <color name="i_am_color_2704">#00002704</color> + <color name="i_am_color_2705">#00002705</color> + <color name="i_am_color_2706">#00002706</color> + <color name="i_am_color_2707">#00002707</color> + <color name="i_am_color_2708">#00002708</color> + <color name="i_am_color_2709">#00002709</color> + <color name="i_am_color_270a">#0000270a</color> + <color name="i_am_color_270b">#0000270b</color> + <color name="i_am_color_270c">#0000270c</color> + <color name="i_am_color_270d">#0000270d</color> + <color name="i_am_color_270e">#0000270e</color> + <color name="i_am_color_270f">#0000270f</color> + <color name="i_am_color_2710">#00002710</color> +</resources> diff --git a/apct-tests/perftests/core/src/android/app/ResourcesPerfTest.java b/apct-tests/perftests/core/src/android/app/ResourcesPerfTest.java index 72162448a2e0..54b79b4fb926 100644 --- a/apct-tests/perftests/core/src/android/app/ResourcesPerfTest.java +++ b/apct-tests/perftests/core/src/android/app/ResourcesPerfTest.java @@ -37,6 +37,7 @@ import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; +import java.util.Random; /** * Benchmarks for {@link android.content.res.Resources}. @@ -222,4 +223,24 @@ public class ResourcesPerfTest { state.resumeTiming(); } } -}
\ No newline at end of file + + @Test + public void getIdentifier() { + final BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); + final Random random = new Random(System.currentTimeMillis()); + final Context context = InstrumentationRegistry.getTargetContext(); + final String packageName = context.getPackageName(); + while (state.keepRunning()) { + state.pauseTiming(); + final int expectedInteger = random.nextInt(10001); + final String expectedString = Integer.toHexString(expectedInteger); + final String entryName = "i_am_color_" + expectedString; + state.resumeTiming(); + + final int resIdentifier = mRes.getIdentifier(entryName, "color", packageName); + if (resIdentifier == 0) { + fail("Color \"" + entryName + "\" is not found"); + } + } + } +} diff --git a/apex/OWNERS b/apex/OWNERS index b3e81b925ddc..e867586c11f9 100644 --- a/apex/OWNERS +++ b/apex/OWNERS @@ -1 +1 @@ -file:platform/packages/modules/common:/OWNERS +file:platform/packages/modules/common:/OWNERS #{LAST_RESORT_SUGGESTION} diff --git a/apex/media/Android.bp b/apex/media/Android.bp deleted file mode 100644 index 1a710a98b0a9..000000000000 --- a/apex/media/Android.bp +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (C) 2020 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 { - default_visibility: [ - ":__subpackages__", - "//frameworks/av/apex", - "//frameworks/av/apex/testing", - ], - // See: http://go/android-license-faq - // A large-scale-change added 'default_applicable_licenses' to import - // all of the 'license_kinds' from "frameworks_base_license" - // to get the below license kinds: - // SPDX-license-identifier-Apache-2.0 - default_applicable_licenses: ["frameworks_base_license"], -} - -sdk { - name: "media-module-sdk", - bootclasspath_fragments: ["com.android.media-bootclasspath-fragment"], - systemserverclasspath_fragments: ["com.android.media-systemserverclasspath-fragment"], - java_sdk_libs: [ - "framework-media", - ], -} diff --git a/apex/media/OWNERS b/apex/media/OWNERS deleted file mode 100644 index 2c5965c300e3..000000000000 --- a/apex/media/OWNERS +++ /dev/null @@ -1,12 +0,0 @@ -# Bug component: 1344 -hdmoon@google.com -jinpark@google.com -klhyun@google.com -lnilsson@google.com -sungsoo@google.com - -# go/android-fwk-media-solutions for info on areas of ownership. -include platform/frameworks/av:/media/janitors/media_solutions_OWNERS - -# media reliability team packages/delivers the media mainline builds. -include platform/frameworks/av:/media/janitors/reliability_mainline_OWNERS diff --git a/apex/media/aidl/Android.bp b/apex/media/aidl/Android.bp deleted file mode 100644 index 545a0cd884dc..000000000000 --- a/apex/media/aidl/Android.bp +++ /dev/null @@ -1,44 +0,0 @@ -// -// Copyright 2020 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 { - // See: http://go/android-license-faq - // A large-scale-change added 'default_applicable_licenses' to import - // all of the 'license_kinds' from "frameworks_base_license" - // to get the below license kinds: - // SPDX-license-identifier-Apache-2.0 - default_applicable_licenses: ["frameworks_base_license"], -} - -filegroup { - name: "stable-media-aidl-srcs", - srcs: ["stable/**/*.aidl"], - path: "stable", -} - -filegroup { - name: "private-media-aidl-srcs", - srcs: ["private/**/I*.aidl"], - path: "private", -} - -filegroup { - name: "media-aidl-srcs", - srcs: [ - ":private-media-aidl-srcs", - ":stable-media-aidl-srcs", - ], -} diff --git a/apex/media/aidl/private/android/media/Controller2Link.aidl b/apex/media/aidl/private/android/media/Controller2Link.aidl deleted file mode 100644 index 64edafcb11fc..000000000000 --- a/apex/media/aidl/private/android/media/Controller2Link.aidl +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright 2018 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.media; - -parcelable Controller2Link; diff --git a/apex/media/aidl/private/android/media/IMediaCommunicationService.aidl b/apex/media/aidl/private/android/media/IMediaCommunicationService.aidl deleted file mode 100644 index fb3172b8c764..000000000000 --- a/apex/media/aidl/private/android/media/IMediaCommunicationService.aidl +++ /dev/null @@ -1,31 +0,0 @@ -/** - * Copyright 2020 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.media; - -import android.media.Session2Token; -import android.media.IMediaCommunicationServiceCallback; -import android.media.MediaParceledListSlice; - -/** {@hide} */ -interface IMediaCommunicationService { - void notifySession2Created(in Session2Token sessionToken); - boolean isTrusted(String controllerPackageName, int controllerPid, int controllerUid); - MediaParceledListSlice getSession2Tokens(int userId); - - void registerCallback(IMediaCommunicationServiceCallback callback, String packageName); - void unregisterCallback(IMediaCommunicationServiceCallback callback); -} - diff --git a/apex/media/aidl/private/android/media/IMediaCommunicationServiceCallback.aidl b/apex/media/aidl/private/android/media/IMediaCommunicationServiceCallback.aidl deleted file mode 100644 index e347ebf4a983..000000000000 --- a/apex/media/aidl/private/android/media/IMediaCommunicationServiceCallback.aidl +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Copyright 2021 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.media; - -import android.media.Session2Token; -import android.media.MediaParceledListSlice; - -/** {@hide} */ -oneway interface IMediaCommunicationServiceCallback { - void onSession2Created(in Session2Token token); - void onSession2Changed(in MediaParceledListSlice tokens); -} - diff --git a/apex/media/aidl/private/android/media/IMediaController2.aidl b/apex/media/aidl/private/android/media/IMediaController2.aidl deleted file mode 100644 index 42c6e70529ec..000000000000 --- a/apex/media/aidl/private/android/media/IMediaController2.aidl +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2018 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.media; - -import android.os.Bundle; -import android.os.ResultReceiver; -import android.media.Session2Command; - -/** - * Interface from MediaSession2 to MediaController2. - * <p> - * Keep this interface oneway. Otherwise a malicious app may implement fake version of this, - * and holds calls from session to make session owner(s) frozen. - * @hide - */ - // Code for AML only -oneway interface IMediaController2 { - void notifyConnected(int seq, in Bundle connectionResult) = 0; - void notifyDisconnected(int seq) = 1; - void notifyPlaybackActiveChanged(int seq, boolean playbackActive) = 2; - void sendSessionCommand(int seq, in Session2Command command, in Bundle args, - in ResultReceiver resultReceiver) = 3; - void cancelSessionCommand(int seq) = 4; - // Next Id : 5 -} diff --git a/apex/media/aidl/private/android/media/IMediaSession2.aidl b/apex/media/aidl/private/android/media/IMediaSession2.aidl deleted file mode 100644 index 26e717b39afc..000000000000 --- a/apex/media/aidl/private/android/media/IMediaSession2.aidl +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2018 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.media; - -import android.os.Bundle; -import android.os.ResultReceiver; -import android.media.Controller2Link; -import android.media.Session2Command; - -/** - * Interface from MediaController2 to MediaSession2. - * <p> - * Keep this interface oneway. Otherwise a malicious app may implement fake version of this, - * and holds calls from session to make session owner(s) frozen. - * @hide - */ - // Code for AML only -oneway interface IMediaSession2 { - void connect(in Controller2Link caller, int seq, in Bundle connectionRequest) = 0; - void disconnect(in Controller2Link caller, int seq) = 1; - void sendSessionCommand(in Controller2Link caller, int seq, in Session2Command sessionCommand, - in Bundle args, in ResultReceiver resultReceiver) = 2; - void cancelSessionCommand(in Controller2Link caller, int seq) = 3; - // Next Id : 4 -} diff --git a/apex/media/aidl/private/android/media/IMediaSession2Service.aidl b/apex/media/aidl/private/android/media/IMediaSession2Service.aidl deleted file mode 100644 index 10ac1be0a36e..000000000000 --- a/apex/media/aidl/private/android/media/IMediaSession2Service.aidl +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2019 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.media; - -import android.os.Bundle; -import android.media.Controller2Link; - -/** - * Interface from MediaController2 to MediaSession2Service. - * <p> - * Keep this interface oneway. Otherwise a malicious app may implement fake version of this, - * and holds calls from controller to make controller owner(s) frozen. - * @hide - */ -oneway interface IMediaSession2Service { - void connect(in Controller2Link caller, int seq, in Bundle connectionRequest) = 0; - // Next Id : 1 -} diff --git a/apex/media/aidl/private/android/media/Session2Command.aidl b/apex/media/aidl/private/android/media/Session2Command.aidl deleted file mode 100644 index 43a7b123ed29..000000000000 --- a/apex/media/aidl/private/android/media/Session2Command.aidl +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright 2018 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.media; - -parcelable Session2Command; diff --git a/apex/media/aidl/stable/android/media/MediaParceledListSlice.aidl b/apex/media/aidl/stable/android/media/MediaParceledListSlice.aidl deleted file mode 100644 index 92d673fd25cb..000000000000 --- a/apex/media/aidl/stable/android/media/MediaParceledListSlice.aidl +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright 2020, 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.media; - -parcelable MediaParceledListSlice<T>; diff --git a/apex/media/framework/Android.bp b/apex/media/framework/Android.bp deleted file mode 100644 index 6195f257ecd9..000000000000 --- a/apex/media/framework/Android.bp +++ /dev/null @@ -1,164 +0,0 @@ -// Copyright (C) 2020 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 { - // See: http://go/android-license-faq - // A large-scale-change added 'default_applicable_licenses' to import - // all of the 'license_kinds' from "frameworks_base_license" - // to get the below license kinds: - // SPDX-license-identifier-Apache-2.0 - default_applicable_licenses: ["frameworks_base_license"], -} - -java_library { - name: "updatable-media", - - srcs: [ - ":updatable-media-srcs", - ], - - permitted_packages: [ - "android.media", - ], - - optimize: { - enabled: true, - shrink: true, - proguard_flags_files: ["updatable-media-proguard.flags"], - }, - - installable: true, - - sdk_version: "module_current", - libs: [ - "androidx.annotation_annotation", - "framework-annotations-lib", - ], - static_libs: [ - "exoplayer2-extractor", - "mediatranscoding_aidl_interface-java", - "modules-annotation-minsdk", - "modules-utils-build", - ], - jarjar_rules: "jarjar_rules.txt", - - plugins: ["java_api_finder"], - - hostdex: true, // for hiddenapi check - apex_available: [ - "com.android.media", - "test_com.android.media", - ], - min_sdk_version: "29", - visibility: [ - "//frameworks/av/apex:__subpackages__", - "//frameworks/base/apex/media/service", - "//frameworks/base/api", // For framework-all - ], -} - -filegroup { - name: "updatable-media-srcs", - srcs: [ - "java/android/media/MediaFrameworkInitializer.java", - ":media-aidl-srcs", - ":mediaparceledlistslice-java-srcs", - ":mediaparser-srcs", - ":mediasession2-java-srcs", - ":mediatranscoding-srcs", - ], - visibility: ["//frameworks/base"], -} - -filegroup { - name: "mediasession2-java-srcs", - srcs: [ - "java/android/media/Controller2Link.java", - "java/android/media/MediaConstants.java", - "java/android/media/MediaController2.java", - "java/android/media/MediaSession2.java", - "java/android/media/MediaSession2Service.java", - "java/android/media/Session2Command.java", - "java/android/media/Session2CommandGroup.java", - "java/android/media/Session2Link.java", - "java/android/media/Session2Token.java", - "java/android/media/MediaCommunicationManager.java", - ], - path: "java", -} - -filegroup { - name: "mediaparceledlistslice-java-srcs", - srcs: [ - "java/android/media/MediaParceledListSlice.java", - "java/android/media/BaseMediaParceledListSlice.java", - ], - path: "java", -} - -filegroup { - name: "mediaparser-srcs", - srcs: [ - "java/android/media/MediaParser.java", - ], - path: "java", -} - -filegroup { - name: "mediatranscoding-srcs", - srcs: [ - "java/android/media/ApplicationMediaCapabilities.java", - "java/android/media/MediaFeature.java", - "java/android/media/MediaTranscodingManager.java", - ], - path: "java", -} - -java_sdk_library { - name: "framework-media", - defaults: ["framework-module-defaults"], - - // This is only used to define the APIs for updatable-media. - api_only: true, - - srcs: [ - ":updatable-media-srcs", - ], - - impl_library_visibility: ["//frameworks/av/apex:__subpackages__"], -} - -cc_library_shared { - name: "libmediaparser-jni", - srcs: [ - "jni/android_media_MediaParserJNI.cpp", - ], - header_libs: ["jni_headers"], - shared_libs: [ - "libandroid", - "liblog", - "libmediametrics", - ], - cflags: [ - "-Wall", - "-Werror", - "-Wno-unused-parameter", - "-Wunreachable-code", - "-Wunused", - ], - apex_available: [ - "com.android.media", - ], - min_sdk_version: "29", -} diff --git a/apex/media/framework/TEST_MAPPING b/apex/media/framework/TEST_MAPPING deleted file mode 100644 index 3d2191410413..000000000000 --- a/apex/media/framework/TEST_MAPPING +++ /dev/null @@ -1,10 +0,0 @@ -{ - "presubmit": [ - { - "name": "CtsMediaParserTestCases" - }, - { - "name": "CtsMediaParserHostTestCases" - } - ] -} diff --git a/apex/media/framework/api/current.txt b/apex/media/framework/api/current.txt deleted file mode 100644 index b7d7ed866c89..000000000000 --- a/apex/media/framework/api/current.txt +++ /dev/null @@ -1,267 +0,0 @@ -// Signature format: 2.0 -package android.media { - - public final class ApplicationMediaCapabilities implements android.os.Parcelable { - method @NonNull public static android.media.ApplicationMediaCapabilities createFromXml(@NonNull org.xmlpull.v1.XmlPullParser); - method public int describeContents(); - method @NonNull public java.util.List<java.lang.String> getSupportedHdrTypes(); - method @NonNull public java.util.List<java.lang.String> getSupportedVideoMimeTypes(); - method @NonNull public java.util.List<java.lang.String> getUnsupportedHdrTypes(); - method @NonNull public java.util.List<java.lang.String> getUnsupportedVideoMimeTypes(); - method public boolean isFormatSpecified(@NonNull String); - method public boolean isHdrTypeSupported(@NonNull String); - method public boolean isVideoMimeTypeSupported(@NonNull String); - method public void writeToParcel(@NonNull android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.media.ApplicationMediaCapabilities> CREATOR; - } - - public static final class ApplicationMediaCapabilities.Builder { - ctor public ApplicationMediaCapabilities.Builder(); - method @NonNull public android.media.ApplicationMediaCapabilities.Builder addSupportedHdrType(@NonNull String); - method @NonNull public android.media.ApplicationMediaCapabilities.Builder addSupportedVideoMimeType(@NonNull String); - method @NonNull public android.media.ApplicationMediaCapabilities.Builder addUnsupportedHdrType(@NonNull String); - method @NonNull public android.media.ApplicationMediaCapabilities.Builder addUnsupportedVideoMimeType(@NonNull String); - method @NonNull public android.media.ApplicationMediaCapabilities build(); - } - - public class MediaCommunicationManager { - method @NonNull public java.util.List<android.media.Session2Token> getSession2Tokens(); - method @IntRange(from=1) public int getVersion(); - } - - public class MediaController2 implements java.lang.AutoCloseable { - method public void cancelSessionCommand(@NonNull Object); - method public void close(); - method @Nullable public android.media.Session2Token getConnectedToken(); - method public boolean isPlaybackActive(); - method @NonNull public Object sendSessionCommand(@NonNull android.media.Session2Command, @Nullable android.os.Bundle); - } - - public static final class MediaController2.Builder { - ctor public MediaController2.Builder(@NonNull android.content.Context, @NonNull android.media.Session2Token); - method @NonNull public android.media.MediaController2 build(); - method @NonNull public android.media.MediaController2.Builder setConnectionHints(@NonNull android.os.Bundle); - method @NonNull public android.media.MediaController2.Builder setControllerCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.MediaController2.ControllerCallback); - } - - public abstract static class MediaController2.ControllerCallback { - ctor public MediaController2.ControllerCallback(); - method public void onCommandResult(@NonNull android.media.MediaController2, @NonNull Object, @NonNull android.media.Session2Command, @NonNull android.media.Session2Command.Result); - method public void onConnected(@NonNull android.media.MediaController2, @NonNull android.media.Session2CommandGroup); - method public void onDisconnected(@NonNull android.media.MediaController2); - method public void onPlaybackActiveChanged(@NonNull android.media.MediaController2, boolean); - method @Nullable public android.media.Session2Command.Result onSessionCommand(@NonNull android.media.MediaController2, @NonNull android.media.Session2Command, @Nullable android.os.Bundle); - } - - public final class MediaFeature { - ctor public MediaFeature(); - } - - public static final class MediaFeature.HdrType { - field public static final String DOLBY_VISION = "android.media.feature.hdr.dolby_vision"; - field public static final String HDR10 = "android.media.feature.hdr.hdr10"; - field public static final String HDR10_PLUS = "android.media.feature.hdr.hdr10_plus"; - field public static final String HLG = "android.media.feature.hdr.hlg"; - } - - public final class MediaParser { - method public boolean advance(@NonNull android.media.MediaParser.SeekableInputReader) throws java.io.IOException; - method @NonNull public static android.media.MediaParser create(@NonNull android.media.MediaParser.OutputConsumer, @NonNull java.lang.String...); - method @NonNull public static android.media.MediaParser createByName(@NonNull String, @NonNull android.media.MediaParser.OutputConsumer); - method @NonNull public android.media.metrics.LogSessionId getLogSessionId(); - method @NonNull public String getParserName(); - method @NonNull public static java.util.List<java.lang.String> getParserNames(@NonNull android.media.MediaFormat); - method public void release(); - method public void seek(@NonNull android.media.MediaParser.SeekPoint); - method public void setLogSessionId(@NonNull android.media.metrics.LogSessionId); - method @NonNull public android.media.MediaParser setParameter(@NonNull String, @NonNull Object); - method public boolean supportsParameter(@NonNull String); - field public static final String PARAMETER_ADTS_ENABLE_CBR_SEEKING = "android.media.mediaparser.adts.enableCbrSeeking"; - field public static final String PARAMETER_AMR_ENABLE_CBR_SEEKING = "android.media.mediaparser.amr.enableCbrSeeking"; - field public static final String PARAMETER_FLAC_DISABLE_ID3 = "android.media.mediaparser.flac.disableId3"; - field public static final String PARAMETER_MATROSKA_DISABLE_CUES_SEEKING = "android.media.mediaparser.matroska.disableCuesSeeking"; - field public static final String PARAMETER_MP3_DISABLE_ID3 = "android.media.mediaparser.mp3.disableId3"; - field public static final String PARAMETER_MP3_ENABLE_CBR_SEEKING = "android.media.mediaparser.mp3.enableCbrSeeking"; - field public static final String PARAMETER_MP3_ENABLE_INDEX_SEEKING = "android.media.mediaparser.mp3.enableIndexSeeking"; - field public static final String PARAMETER_MP4_IGNORE_EDIT_LISTS = "android.media.mediaparser.mp4.ignoreEditLists"; - field public static final String PARAMETER_MP4_IGNORE_TFDT_BOX = "android.media.mediaparser.mp4.ignoreTfdtBox"; - field public static final String PARAMETER_MP4_TREAT_VIDEO_FRAMES_AS_KEYFRAMES = "android.media.mediaparser.mp4.treatVideoFramesAsKeyframes"; - field public static final String PARAMETER_TS_ALLOW_NON_IDR_AVC_KEYFRAMES = "android.media.mediaparser.ts.allowNonIdrAvcKeyframes"; - field public static final String PARAMETER_TS_DETECT_ACCESS_UNITS = "android.media.mediaparser.ts.ignoreDetectAccessUnits"; - field public static final String PARAMETER_TS_ENABLE_HDMV_DTS_AUDIO_STREAMS = "android.media.mediaparser.ts.enableHdmvDtsAudioStreams"; - field public static final String PARAMETER_TS_IGNORE_AAC_STREAM = "android.media.mediaparser.ts.ignoreAacStream"; - field public static final String PARAMETER_TS_IGNORE_AVC_STREAM = "android.media.mediaparser.ts.ignoreAvcStream"; - field public static final String PARAMETER_TS_IGNORE_SPLICE_INFO_STREAM = "android.media.mediaparser.ts.ignoreSpliceInfoStream"; - field public static final String PARAMETER_TS_MODE = "android.media.mediaparser.ts.mode"; - field public static final String PARSER_NAME_AC3 = "android.media.mediaparser.Ac3Parser"; - field public static final String PARSER_NAME_AC4 = "android.media.mediaparser.Ac4Parser"; - field public static final String PARSER_NAME_ADTS = "android.media.mediaparser.AdtsParser"; - field public static final String PARSER_NAME_AMR = "android.media.mediaparser.AmrParser"; - field public static final String PARSER_NAME_FLAC = "android.media.mediaparser.FlacParser"; - field public static final String PARSER_NAME_FLV = "android.media.mediaparser.FlvParser"; - field public static final String PARSER_NAME_FMP4 = "android.media.mediaparser.FragmentedMp4Parser"; - field public static final String PARSER_NAME_MATROSKA = "android.media.mediaparser.MatroskaParser"; - field public static final String PARSER_NAME_MP3 = "android.media.mediaparser.Mp3Parser"; - field public static final String PARSER_NAME_MP4 = "android.media.mediaparser.Mp4Parser"; - field public static final String PARSER_NAME_OGG = "android.media.mediaparser.OggParser"; - field public static final String PARSER_NAME_PS = "android.media.mediaparser.PsParser"; - field public static final String PARSER_NAME_TS = "android.media.mediaparser.TsParser"; - field public static final String PARSER_NAME_UNKNOWN = "android.media.mediaparser.UNKNOWN"; - field public static final String PARSER_NAME_WAV = "android.media.mediaparser.WavParser"; - field public static final int SAMPLE_FLAG_DECODE_ONLY = -2147483648; // 0x80000000 - field public static final int SAMPLE_FLAG_ENCRYPTED = 1073741824; // 0x40000000 - field public static final int SAMPLE_FLAG_HAS_SUPPLEMENTAL_DATA = 268435456; // 0x10000000 - field public static final int SAMPLE_FLAG_KEY_FRAME = 1; // 0x1 - field public static final int SAMPLE_FLAG_LAST_SAMPLE = 536870912; // 0x20000000 - } - - public static interface MediaParser.InputReader { - method public long getLength(); - method public long getPosition(); - method public int read(@NonNull byte[], int, int) throws java.io.IOException; - } - - public static interface MediaParser.OutputConsumer { - method public void onSampleCompleted(int, long, int, int, int, @Nullable android.media.MediaCodec.CryptoInfo); - method public void onSampleDataFound(int, @NonNull android.media.MediaParser.InputReader) throws java.io.IOException; - method public void onSeekMapFound(@NonNull android.media.MediaParser.SeekMap); - method public void onTrackCountFound(int); - method public void onTrackDataFound(int, @NonNull android.media.MediaParser.TrackData); - } - - public static final class MediaParser.ParsingException extends java.io.IOException { - } - - public static final class MediaParser.SeekMap { - method public long getDurationMicros(); - method @NonNull public android.util.Pair<android.media.MediaParser.SeekPoint,android.media.MediaParser.SeekPoint> getSeekPoints(long); - method public boolean isSeekable(); - field public static final int UNKNOWN_DURATION = -2147483648; // 0x80000000 - } - - public static final class MediaParser.SeekPoint { - field @NonNull public static final android.media.MediaParser.SeekPoint START; - field public final long position; - field public final long timeMicros; - } - - public static interface MediaParser.SeekableInputReader extends android.media.MediaParser.InputReader { - method public void seekToPosition(long); - } - - public static final class MediaParser.TrackData { - field @Nullable public final android.media.DrmInitData drmInitData; - field @NonNull public final android.media.MediaFormat mediaFormat; - } - - public static final class MediaParser.UnrecognizedInputFormatException extends java.io.IOException { - } - - public class MediaSession2 implements java.lang.AutoCloseable { - method public void broadcastSessionCommand(@NonNull android.media.Session2Command, @Nullable android.os.Bundle); - method public void cancelSessionCommand(@NonNull android.media.MediaSession2.ControllerInfo, @NonNull Object); - method public void close(); - method @NonNull public java.util.List<android.media.MediaSession2.ControllerInfo> getConnectedControllers(); - method @NonNull public String getId(); - method @NonNull public android.media.Session2Token getToken(); - method public boolean isPlaybackActive(); - method @NonNull public Object sendSessionCommand(@NonNull android.media.MediaSession2.ControllerInfo, @NonNull android.media.Session2Command, @Nullable android.os.Bundle); - method public void setPlaybackActive(boolean); - } - - public static final class MediaSession2.Builder { - ctor public MediaSession2.Builder(@NonNull android.content.Context); - method @NonNull public android.media.MediaSession2 build(); - method @NonNull public android.media.MediaSession2.Builder setExtras(@NonNull android.os.Bundle); - method @NonNull public android.media.MediaSession2.Builder setId(@NonNull String); - method @NonNull public android.media.MediaSession2.Builder setSessionActivity(@Nullable android.app.PendingIntent); - method @NonNull public android.media.MediaSession2.Builder setSessionCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.MediaSession2.SessionCallback); - } - - public static final class MediaSession2.ControllerInfo { - method @NonNull public android.os.Bundle getConnectionHints(); - method @NonNull public String getPackageName(); - method @NonNull public android.media.session.MediaSessionManager.RemoteUserInfo getRemoteUserInfo(); - method public int getUid(); - } - - public abstract static class MediaSession2.SessionCallback { - ctor public MediaSession2.SessionCallback(); - method public void onCommandResult(@NonNull android.media.MediaSession2, @NonNull android.media.MediaSession2.ControllerInfo, @NonNull Object, @NonNull android.media.Session2Command, @NonNull android.media.Session2Command.Result); - method @Nullable public android.media.Session2CommandGroup onConnect(@NonNull android.media.MediaSession2, @NonNull android.media.MediaSession2.ControllerInfo); - method public void onDisconnected(@NonNull android.media.MediaSession2, @NonNull android.media.MediaSession2.ControllerInfo); - method public void onPostConnect(@NonNull android.media.MediaSession2, @NonNull android.media.MediaSession2.ControllerInfo); - method @Nullable public android.media.Session2Command.Result onSessionCommand(@NonNull android.media.MediaSession2, @NonNull android.media.MediaSession2.ControllerInfo, @NonNull android.media.Session2Command, @Nullable android.os.Bundle); - } - - public abstract class MediaSession2Service extends android.app.Service { - ctor public MediaSession2Service(); - method public final void addSession(@NonNull android.media.MediaSession2); - method @NonNull public final java.util.List<android.media.MediaSession2> getSessions(); - method @CallSuper @Nullable public android.os.IBinder onBind(@NonNull android.content.Intent); - method @Nullable public abstract android.media.MediaSession2 onGetSession(@NonNull android.media.MediaSession2.ControllerInfo); - method @Nullable public abstract android.media.MediaSession2Service.MediaNotification onUpdateNotification(@NonNull android.media.MediaSession2); - method public final void removeSession(@NonNull android.media.MediaSession2); - field public static final String SERVICE_INTERFACE = "android.media.MediaSession2Service"; - } - - public static class MediaSession2Service.MediaNotification { - ctor public MediaSession2Service.MediaNotification(int, @NonNull android.app.Notification); - method @NonNull public android.app.Notification getNotification(); - method public int getNotificationId(); - } - - public final class Session2Command implements android.os.Parcelable { - ctor public Session2Command(int); - ctor public Session2Command(@NonNull String, @Nullable android.os.Bundle); - method public int describeContents(); - method public int getCommandCode(); - method @Nullable public String getCustomAction(); - method @Nullable public android.os.Bundle getCustomExtras(); - method public void writeToParcel(@NonNull android.os.Parcel, int); - field public static final int COMMAND_CODE_CUSTOM = 0; // 0x0 - field @NonNull public static final android.os.Parcelable.Creator<android.media.Session2Command> CREATOR; - } - - public static final class Session2Command.Result { - ctor public Session2Command.Result(int, @Nullable android.os.Bundle); - method public int getResultCode(); - method @Nullable public android.os.Bundle getResultData(); - field public static final int RESULT_ERROR_UNKNOWN_ERROR = -1; // 0xffffffff - field public static final int RESULT_INFO_SKIPPED = 1; // 0x1 - field public static final int RESULT_SUCCESS = 0; // 0x0 - } - - public final class Session2CommandGroup implements android.os.Parcelable { - method public int describeContents(); - method @NonNull public java.util.Set<android.media.Session2Command> getCommands(); - method public boolean hasCommand(@NonNull android.media.Session2Command); - method public boolean hasCommand(int); - method public void writeToParcel(@NonNull android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.media.Session2CommandGroup> CREATOR; - } - - public static final class Session2CommandGroup.Builder { - ctor public Session2CommandGroup.Builder(); - ctor public Session2CommandGroup.Builder(@NonNull android.media.Session2CommandGroup); - method @NonNull public android.media.Session2CommandGroup.Builder addCommand(@NonNull android.media.Session2Command); - method @NonNull public android.media.Session2CommandGroup build(); - method @NonNull public android.media.Session2CommandGroup.Builder removeCommand(@NonNull android.media.Session2Command); - } - - public final class Session2Token implements android.os.Parcelable { - ctor public Session2Token(@NonNull android.content.Context, @NonNull android.content.ComponentName); - method public int describeContents(); - method @NonNull public android.os.Bundle getExtras(); - method @NonNull public String getPackageName(); - method @Nullable public String getServiceName(); - method public int getType(); - method public int getUid(); - method public void writeToParcel(android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.media.Session2Token> CREATOR; - field public static final int TYPE_SESSION = 0; // 0x0 - field public static final int TYPE_SESSION_SERVICE = 1; // 0x1 - } - -} - diff --git a/apex/media/framework/api/module-lib-current.txt b/apex/media/framework/api/module-lib-current.txt deleted file mode 100644 index eb6397a1826b..000000000000 --- a/apex/media/framework/api/module-lib-current.txt +++ /dev/null @@ -1,30 +0,0 @@ -// Signature format: 2.0 -package android.media { - - public class MediaCommunicationManager { - method @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public void registerSessionCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.MediaCommunicationManager.SessionCallback); - method public void unregisterSessionCallback(@NonNull android.media.MediaCommunicationManager.SessionCallback); - } - - public static interface MediaCommunicationManager.SessionCallback { - method public default void onSession2TokenCreated(@NonNull android.media.Session2Token); - method public default void onSession2TokensChanged(@NonNull java.util.List<android.media.Session2Token>); - } - - public class MediaFrameworkInitializer { - method public static void registerServiceWrappers(); - method public static void setMediaServiceManager(@NonNull android.media.MediaServiceManager); - } - - @Deprecated public final class MediaParceledListSlice<T extends android.os.Parcelable> implements android.os.Parcelable { - ctor @Deprecated public MediaParceledListSlice(@NonNull java.util.List<T>); - method @Deprecated public int describeContents(); - method @Deprecated @NonNull public static <T extends android.os.Parcelable> android.media.MediaParceledListSlice<T> emptyList(); - method @Deprecated public java.util.List<T> getList(); - method @Deprecated public void setInlineCountLimit(int); - method @Deprecated public void writeToParcel(android.os.Parcel, int); - field @Deprecated @NonNull public static final android.os.Parcelable.ClassLoaderCreator<android.media.MediaParceledListSlice> CREATOR; - } - -} - diff --git a/apex/media/framework/api/module-lib-removed.txt b/apex/media/framework/api/module-lib-removed.txt deleted file mode 100644 index d802177e249b..000000000000 --- a/apex/media/framework/api/module-lib-removed.txt +++ /dev/null @@ -1 +0,0 @@ -// Signature format: 2.0 diff --git a/apex/media/framework/api/system-current.txt b/apex/media/framework/api/system-current.txt deleted file mode 100644 index 6eea769d9f57..000000000000 --- a/apex/media/framework/api/system-current.txt +++ /dev/null @@ -1,68 +0,0 @@ -// Signature format: 2.0 -package android.media { - - public final class MediaTranscodingManager { - method @Nullable public android.media.MediaTranscodingManager.TranscodingSession enqueueRequest(@NonNull android.media.MediaTranscodingManager.TranscodingRequest, @NonNull java.util.concurrent.Executor, @NonNull android.media.MediaTranscodingManager.OnTranscodingFinishedListener); - } - - @java.lang.FunctionalInterface public static interface MediaTranscodingManager.OnTranscodingFinishedListener { - method public void onTranscodingFinished(@NonNull android.media.MediaTranscodingManager.TranscodingSession); - } - - public abstract static class MediaTranscodingManager.TranscodingRequest { - method public int getClientPid(); - method public int getClientUid(); - method @Nullable public android.os.ParcelFileDescriptor getDestinationFileDescriptor(); - method @NonNull public android.net.Uri getDestinationUri(); - method @Nullable public android.os.ParcelFileDescriptor getSourceFileDescriptor(); - method @NonNull public android.net.Uri getSourceUri(); - } - - public static class MediaTranscodingManager.TranscodingRequest.VideoFormatResolver { - ctor public MediaTranscodingManager.TranscodingRequest.VideoFormatResolver(@NonNull android.media.ApplicationMediaCapabilities, @NonNull android.media.MediaFormat); - method @Nullable public android.media.MediaFormat resolveVideoFormat(); - method public boolean shouldTranscode(); - } - - public static final class MediaTranscodingManager.TranscodingSession { - method public boolean addClientUid(int); - method public void cancel(); - method @NonNull public java.util.List<java.lang.Integer> getClientUids(); - method public int getErrorCode(); - method @IntRange(from=0, to=100) public int getProgress(); - method public int getResult(); - method public int getSessionId(); - method public int getStatus(); - method public void setOnProgressUpdateListener(@NonNull java.util.concurrent.Executor, @Nullable android.media.MediaTranscodingManager.TranscodingSession.OnProgressUpdateListener); - field public static final int ERROR_DROPPED_BY_SERVICE = 1; // 0x1 - field public static final int ERROR_NONE = 0; // 0x0 - field public static final int ERROR_SERVICE_DIED = 2; // 0x2 - field public static final int RESULT_CANCELED = 4; // 0x4 - field public static final int RESULT_ERROR = 3; // 0x3 - field public static final int RESULT_NONE = 1; // 0x1 - field public static final int RESULT_SUCCESS = 2; // 0x2 - field public static final int STATUS_FINISHED = 3; // 0x3 - field public static final int STATUS_PAUSED = 4; // 0x4 - field public static final int STATUS_PENDING = 1; // 0x1 - field public static final int STATUS_RUNNING = 2; // 0x2 - } - - @java.lang.FunctionalInterface public static interface MediaTranscodingManager.TranscodingSession.OnProgressUpdateListener { - method public void onProgressUpdate(@NonNull android.media.MediaTranscodingManager.TranscodingSession, @IntRange(from=0, to=100) int); - } - - public static final class MediaTranscodingManager.VideoTranscodingRequest extends android.media.MediaTranscodingManager.TranscodingRequest { - method @NonNull public android.media.MediaFormat getVideoTrackFormat(); - } - - public static final class MediaTranscodingManager.VideoTranscodingRequest.Builder { - ctor public MediaTranscodingManager.VideoTranscodingRequest.Builder(@NonNull android.net.Uri, @NonNull android.net.Uri, @NonNull android.media.MediaFormat); - method @NonNull public android.media.MediaTranscodingManager.VideoTranscodingRequest build(); - method @NonNull public android.media.MediaTranscodingManager.VideoTranscodingRequest.Builder setClientPid(int); - method @NonNull public android.media.MediaTranscodingManager.VideoTranscodingRequest.Builder setClientUid(int); - method @NonNull public android.media.MediaTranscodingManager.VideoTranscodingRequest.Builder setDestinationFileDescriptor(@NonNull android.os.ParcelFileDescriptor); - method @NonNull public android.media.MediaTranscodingManager.VideoTranscodingRequest.Builder setSourceFileDescriptor(@NonNull android.os.ParcelFileDescriptor); - } - -} - diff --git a/apex/media/framework/api/system-removed.txt b/apex/media/framework/api/system-removed.txt deleted file mode 100644 index d802177e249b..000000000000 --- a/apex/media/framework/api/system-removed.txt +++ /dev/null @@ -1 +0,0 @@ -// Signature format: 2.0 diff --git a/apex/media/framework/jarjar_rules.txt b/apex/media/framework/jarjar_rules.txt deleted file mode 100644 index 91489dcee0a1..000000000000 --- a/apex/media/framework/jarjar_rules.txt +++ /dev/null @@ -1,2 +0,0 @@ -rule com.android.modules.** android.media.internal.@1 -rule com.google.android.exoplayer2.** android.media.internal.exo.@1 diff --git a/apex/media/framework/java/android/media/ApplicationMediaCapabilities.java b/apex/media/framework/java/android/media/ApplicationMediaCapabilities.java deleted file mode 100644 index 97fa0eca0862..000000000000 --- a/apex/media/framework/java/android/media/ApplicationMediaCapabilities.java +++ /dev/null @@ -1,626 +0,0 @@ -/* - * Copyright (C) 2020 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.media; - -import android.annotation.NonNull; -import android.content.ContentResolver; -import android.net.Uri; -import android.os.Build; -import android.os.Bundle; -import android.os.Parcel; -import android.os.Parcelable; -import android.util.Log; - -import com.android.modules.annotation.MinSdk; - -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - ApplicationMediaCapabilities is an immutable class that encapsulates an application's capabilities - for handling newer video codec format and media features. - - <p> - Android 12 introduces Compatible media transcoding feature. See - <a href="https://developer.android.com/about/versions/12/features#compatible_media_transcoding"> - Compatible media transcoding</a>. By default, Android assumes apps can support playback of all - media formats. Apps that would like to request that media be transcoded into a more compatible - format should declare their media capabilities in a media_capabilities.xml resource file and add it - as a property tag in the AndroidManifest.xml file. Here is a example: - <pre> - {@code - <media-capabilities xmlns:android="http://schemas.android.com/apk/res/android"> - <format android:name="HEVC" supported="true"/> - <format android:name="HDR10" supported="false"/> - <format android:name="HDR10Plus" supported="false"/> - </media-capabilities> - } - </pre> - The ApplicationMediaCapabilities class is generated from this xml and used by the platform to - represent an application's media capabilities in order to determine whether modern media files need - to be transcoded for that application. - </p> - - <p> - ApplicationMediaCapabilities objects can also be built by applications at runtime for use with - {@link ContentResolver#openTypedAssetFileDescriptor(Uri, String, Bundle)} to provide more - control over the transcoding that is built into the platform. ApplicationMediaCapabilities - provided by applications at runtime like this override the default manifest capabilities for that - media access.The object could be build either through {@link #createFromXml(XmlPullParser)} or - through the builder class {@link ApplicationMediaCapabilities.Builder} - - <h3> Video Codec Support</h3> - <p> - Newer video codes include HEVC, VP9 and AV1. Application only needs to indicate their support - for newer format with this class as they are assumed to support older format like h.264. - - <h3>Capability of handling HDR(high dynamic range) video</h3> - <p> - There are four types of HDR video(Dolby-Vision, HDR10, HDR10+, HLG) supported by the platform, - application will only need to specify individual types they supported. - */ -@MinSdk(Build.VERSION_CODES.S) -public final class ApplicationMediaCapabilities implements Parcelable { - private static final String TAG = "ApplicationMediaCapabilities"; - - /** List of supported video codec mime types. */ - private Set<String> mSupportedVideoMimeTypes = new HashSet<>(); - - /** List of unsupported video codec mime types. */ - private Set<String> mUnsupportedVideoMimeTypes = new HashSet<>(); - - /** List of supported hdr types. */ - private Set<String> mSupportedHdrTypes = new HashSet<>(); - - /** List of unsupported hdr types. */ - private Set<String> mUnsupportedHdrTypes = new HashSet<>(); - - private boolean mIsSlowMotionSupported = false; - - private ApplicationMediaCapabilities(Builder b) { - mSupportedVideoMimeTypes.addAll(b.getSupportedVideoMimeTypes()); - mUnsupportedVideoMimeTypes.addAll(b.getUnsupportedVideoMimeTypes()); - mSupportedHdrTypes.addAll(b.getSupportedHdrTypes()); - mUnsupportedHdrTypes.addAll(b.getUnsupportedHdrTypes()); - mIsSlowMotionSupported = b.mIsSlowMotionSupported; - } - - /** - * Query if a video codec format is supported by the application. - * <p> - * If the application has not specified supporting the format or not, this will return false. - * Use {@link #isFormatSpecified(String)} to query if a format is specified or not. - * - * @param videoMime The mime type of the video codec format. Must be the one used in - * {@link MediaFormat#KEY_MIME}. - * @return true if application supports the video codec format, false otherwise. - */ - public boolean isVideoMimeTypeSupported( - @NonNull String videoMime) { - if (mSupportedVideoMimeTypes.contains(videoMime.toLowerCase())) { - return true; - } - return false; - } - - /** - * Query if a HDR type is supported by the application. - * <p> - * If the application has not specified supporting the format or not, this will return false. - * Use {@link #isFormatSpecified(String)} to query if a format is specified or not. - * - * @param hdrType The type of the HDR format. - * @return true if application supports the HDR format, false otherwise. - */ - public boolean isHdrTypeSupported( - @NonNull @MediaFeature.MediaHdrType String hdrType) { - if (mSupportedHdrTypes.contains(hdrType)) { - return true; - } - return false; - } - - /** - * Query if a format is specified by the application. - * <p> - * The format could be either the video format or the hdr format. - * - * @param format The name of the format. - * @return true if application specifies the format, false otherwise. - */ - public boolean isFormatSpecified(@NonNull String format) { - if (mSupportedVideoMimeTypes.contains(format) || mUnsupportedVideoMimeTypes.contains(format) - || mSupportedHdrTypes.contains(format) || mUnsupportedHdrTypes.contains(format)) { - return true; - - } - return false; - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(@NonNull Parcel dest, int flags) { - // Write out the supported video mime types. - dest.writeInt(mSupportedVideoMimeTypes.size()); - for (String cap : mSupportedVideoMimeTypes) { - dest.writeString(cap); - } - // Write out the unsupported video mime types. - dest.writeInt(mUnsupportedVideoMimeTypes.size()); - for (String cap : mUnsupportedVideoMimeTypes) { - dest.writeString(cap); - } - // Write out the supported hdr types. - dest.writeInt(mSupportedHdrTypes.size()); - for (String cap : mSupportedHdrTypes) { - dest.writeString(cap); - } - // Write out the unsupported hdr types. - dest.writeInt(mUnsupportedHdrTypes.size()); - for (String cap : mUnsupportedHdrTypes) { - dest.writeString(cap); - } - // Write out the supported slow motion. - dest.writeBoolean(mIsSlowMotionSupported); - } - - @Override - public String toString() { - String caps = new String( - "Supported Video MimeTypes: " + mSupportedVideoMimeTypes.toString()); - caps += "Unsupported Video MimeTypes: " + mUnsupportedVideoMimeTypes.toString(); - caps += "Supported HDR types: " + mSupportedHdrTypes.toString(); - caps += "Unsupported HDR types: " + mUnsupportedHdrTypes.toString(); - caps += "Supported slow motion: " + mIsSlowMotionSupported; - return caps; - } - - @NonNull - public static final Creator<ApplicationMediaCapabilities> CREATOR = - new Creator<ApplicationMediaCapabilities>() { - public ApplicationMediaCapabilities createFromParcel(Parcel in) { - ApplicationMediaCapabilities.Builder builder = - new ApplicationMediaCapabilities.Builder(); - - // Parse supported video codec mime types. - int count = in.readInt(); - for (int readCount = 0; readCount < count; ++readCount) { - builder.addSupportedVideoMimeType(in.readString()); - } - - // Parse unsupported video codec mime types. - count = in.readInt(); - for (int readCount = 0; readCount < count; ++readCount) { - builder.addUnsupportedVideoMimeType(in.readString()); - } - - // Parse supported hdr types. - count = in.readInt(); - for (int readCount = 0; readCount < count; ++readCount) { - builder.addSupportedHdrType(in.readString()); - } - - // Parse unsupported hdr types. - count = in.readInt(); - for (int readCount = 0; readCount < count; ++readCount) { - builder.addUnsupportedHdrType(in.readString()); - } - - boolean supported = in.readBoolean(); - builder.setSlowMotionSupported(supported); - - return builder.build(); - } - - public ApplicationMediaCapabilities[] newArray(int size) { - return new ApplicationMediaCapabilities[size]; - } - }; - - /** - * Query the video codec mime types supported by the application. - * @return List of supported video codec mime types. The list will be empty if there are none. - */ - @NonNull - public List<String> getSupportedVideoMimeTypes() { - return new ArrayList<>(mSupportedVideoMimeTypes); - } - - /** - * Query the video codec mime types that are not supported by the application. - * @return List of unsupported video codec mime types. The list will be empty if there are none. - */ - @NonNull - public List<String> getUnsupportedVideoMimeTypes() { - return new ArrayList<>(mUnsupportedVideoMimeTypes); - } - - /** - * Query all hdr types that are supported by the application. - * @return List of supported hdr types. The list will be empty if there are none. - */ - @NonNull - public List<String> getSupportedHdrTypes() { - return new ArrayList<>(mSupportedHdrTypes); - } - - /** - * Query all hdr types that are not supported by the application. - * @return List of unsupported hdr types. The list will be empty if there are none. - */ - @NonNull - public List<String> getUnsupportedHdrTypes() { - return new ArrayList<>(mUnsupportedHdrTypes); - } - - /** - * Whether handling of slow-motion video is supported - * @hide - */ - public boolean isSlowMotionSupported() { - return mIsSlowMotionSupported; - } - - /** - * Creates {@link ApplicationMediaCapabilities} from an xml. - * - * The xml's syntax is the same as the media_capabilities.xml used by the AndroidManifest.xml. - * <p> Here is an example: - * - * <pre> - * {@code - * <media-capabilities xmlns:android="http://schemas.android.com/apk/res/android"> - * <format android:name="HEVC" supported="true"/> - * <format android:name="HDR10" supported="false"/> - * <format android:name="HDR10Plus" supported="false"/> - * </media-capabilities> - * } - * </pre> - * <p> - * - * @param xmlParser The underlying {@link XmlPullParser} that will read the xml. - * @return An ApplicationMediaCapabilities object. - * @throws UnsupportedOperationException if the capabilities in xml config are invalid or - * incompatible. - */ - // TODO: Add developer.android.com link for the format of the xml. - @NonNull - public static ApplicationMediaCapabilities createFromXml(@NonNull XmlPullParser xmlParser) { - ApplicationMediaCapabilities.Builder builder = new ApplicationMediaCapabilities.Builder(); - builder.parseXml(xmlParser); - return builder.build(); - } - - /** - * Builder class for {@link ApplicationMediaCapabilities} objects. - * Use this class to configure and create an ApplicationMediaCapabilities instance. Builder - * could be created from an existing ApplicationMediaCapabilities object, from a xml file or - * MediaCodecList. - * //TODO(hkuang): Add xml parsing support to the builder. - */ - public final static class Builder { - /** List of supported video codec mime types. */ - private Set<String> mSupportedVideoMimeTypes = new HashSet<>(); - - /** List of supported hdr types. */ - private Set<String> mSupportedHdrTypes = new HashSet<>(); - - /** List of unsupported video codec mime types. */ - private Set<String> mUnsupportedVideoMimeTypes = new HashSet<>(); - - /** List of unsupported hdr types. */ - private Set<String> mUnsupportedHdrTypes = new HashSet<>(); - - private boolean mIsSlowMotionSupported = false; - - /* Map to save the format read from the xml. */ - private Map<String, Boolean> mFormatSupportedMap = new HashMap<String, Boolean>(); - - /** - * Constructs a new Builder with all the supports default to false. - */ - public Builder() { - } - - private void parseXml(@NonNull XmlPullParser xmlParser) - throws UnsupportedOperationException { - if (xmlParser == null) { - throw new IllegalArgumentException("XmlParser must not be null"); - } - - try { - while (xmlParser.next() != XmlPullParser.START_TAG) { - continue; - } - - // Validates the tag is "media-capabilities". - if (!xmlParser.getName().equals("media-capabilities")) { - throw new UnsupportedOperationException("Invalid tag"); - } - - xmlParser.next(); - while (xmlParser.getEventType() != XmlPullParser.END_TAG) { - while (xmlParser.getEventType() != XmlPullParser.START_TAG) { - if (xmlParser.getEventType() == XmlPullParser.END_DOCUMENT) { - return; - } - xmlParser.next(); - } - - // Validates the tag is "format". - if (xmlParser.getName().equals("format")) { - parseFormatTag(xmlParser); - } else { - throw new UnsupportedOperationException("Invalid tag"); - } - while (xmlParser.getEventType() != XmlPullParser.END_TAG) { - xmlParser.next(); - } - xmlParser.next(); - } - } catch (XmlPullParserException xppe) { - throw new UnsupportedOperationException("Ill-formatted xml file"); - } catch (java.io.IOException ioe) { - throw new UnsupportedOperationException("Unable to read xml file"); - } - } - - private void parseFormatTag(XmlPullParser xmlParser) { - String name = null; - String supported = null; - for (int i = 0; i < xmlParser.getAttributeCount(); i++) { - String attrName = xmlParser.getAttributeName(i); - if (attrName.equals("name")) { - name = xmlParser.getAttributeValue(i); - } else if (attrName.equals("supported")) { - supported = xmlParser.getAttributeValue(i); - } else { - throw new UnsupportedOperationException("Invalid attribute name " + attrName); - } - } - - if (name != null && supported != null) { - if (!supported.equals("true") && !supported.equals("false")) { - throw new UnsupportedOperationException( - ("Supported value must be either true or false")); - } - boolean isSupported = Boolean.parseBoolean(supported); - - // Check if the format is already found before. - if (mFormatSupportedMap.get(name) != null && mFormatSupportedMap.get(name) - != isSupported) { - throw new UnsupportedOperationException( - "Format: " + name + " has conflict supported value"); - } - - switch (name) { - case "HEVC": - if (isSupported) { - mSupportedVideoMimeTypes.add(MediaFormat.MIMETYPE_VIDEO_HEVC); - } else { - mUnsupportedVideoMimeTypes.add(MediaFormat.MIMETYPE_VIDEO_HEVC); - } - break; - case "VP9": - if (isSupported) { - mSupportedVideoMimeTypes.add(MediaFormat.MIMETYPE_VIDEO_VP9); - } else { - mUnsupportedVideoMimeTypes.add(MediaFormat.MIMETYPE_VIDEO_VP9); - } - break; - case "AV1": - if (isSupported) { - mSupportedVideoMimeTypes.add(MediaFormat.MIMETYPE_VIDEO_AV1); - } else { - mUnsupportedVideoMimeTypes.add(MediaFormat.MIMETYPE_VIDEO_AV1); - } - break; - case "HDR10": - if (isSupported) { - mSupportedHdrTypes.add(MediaFeature.HdrType.HDR10); - } else { - mUnsupportedHdrTypes.add(MediaFeature.HdrType.HDR10); - } - break; - case "HDR10Plus": - if (isSupported) { - mSupportedHdrTypes.add(MediaFeature.HdrType.HDR10_PLUS); - } else { - mUnsupportedHdrTypes.add(MediaFeature.HdrType.HDR10_PLUS); - } - break; - case "Dolby-Vision": - if (isSupported) { - mSupportedHdrTypes.add(MediaFeature.HdrType.DOLBY_VISION); - } else { - mUnsupportedHdrTypes.add(MediaFeature.HdrType.DOLBY_VISION); - } - break; - case "HLG": - if (isSupported) { - mSupportedHdrTypes.add(MediaFeature.HdrType.HLG); - } else { - mUnsupportedHdrTypes.add(MediaFeature.HdrType.HLG); - } - break; - case "SlowMotion": - mIsSlowMotionSupported = isSupported; - break; - default: - Log.w(TAG, "Invalid format name " + name); - } - // Save the name and isSupported into the map for validate later. - mFormatSupportedMap.put(name, isSupported); - } else { - throw new UnsupportedOperationException( - "Format name and supported must both be specified"); - } - } - - /** - * Builds a {@link ApplicationMediaCapabilities} object. - * - * @return a new {@link ApplicationMediaCapabilities} instance successfully initialized - * with all the parameters set on this <code>Builder</code>. - * @throws UnsupportedOperationException if the parameters set on the - * <code>Builder</code> were incompatible, or if they - * are not supported by the - * device. - */ - @NonNull - public ApplicationMediaCapabilities build() { - Log.d(TAG, - "Building ApplicationMediaCapabilities with: (Supported HDR: " - + mSupportedHdrTypes.toString() + " Unsupported HDR: " - + mUnsupportedHdrTypes.toString() + ") (Supported Codec: " - + " " + mSupportedVideoMimeTypes.toString() + " Unsupported Codec:" - + mUnsupportedVideoMimeTypes.toString() + ") " - + mIsSlowMotionSupported); - - // If hdr is supported, application must also support hevc. - if (!mSupportedHdrTypes.isEmpty() && !mSupportedVideoMimeTypes.contains( - MediaFormat.MIMETYPE_VIDEO_HEVC)) { - throw new UnsupportedOperationException("Only support HEVC mime type"); - } - return new ApplicationMediaCapabilities(this); - } - - /** - * Adds a supported video codec mime type. - * - * @param codecMime Supported codec mime types. Must be one of the mime type defined - * in {@link MediaFormat}. - * @throws IllegalArgumentException if mime type is not valid. - */ - @NonNull - public Builder addSupportedVideoMimeType( - @NonNull String codecMime) { - mSupportedVideoMimeTypes.add(codecMime); - return this; - } - - private List<String> getSupportedVideoMimeTypes() { - return new ArrayList<>(mSupportedVideoMimeTypes); - } - - private boolean isValidVideoCodecMimeType(@NonNull String codecMime) { - if (!codecMime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_HEVC) - && !codecMime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_VP9) - && !codecMime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_AV1)) { - return false; - } - return true; - } - - /** - * Adds an unsupported video codec mime type. - * - * @param codecMime Unsupported codec mime type. Must be one of the mime type defined - * in {@link MediaFormat}. - * @throws IllegalArgumentException if mime type is not valid. - */ - @NonNull - public Builder addUnsupportedVideoMimeType( - @NonNull String codecMime) { - if (!isValidVideoCodecMimeType(codecMime)) { - throw new IllegalArgumentException("Invalid codec mime type: " + codecMime); - } - mUnsupportedVideoMimeTypes.add(codecMime); - return this; - } - - private List<String> getUnsupportedVideoMimeTypes() { - return new ArrayList<>(mUnsupportedVideoMimeTypes); - } - - /** - * Adds a supported hdr type. - * - * @param hdrType Supported hdr type. Must be one of the String defined in - * {@link MediaFeature.HdrType}. - * @throws IllegalArgumentException if hdrType is not valid. - */ - @NonNull - public Builder addSupportedHdrType( - @NonNull @MediaFeature.MediaHdrType String hdrType) { - if (!isValidVideoCodecHdrType(hdrType)) { - throw new IllegalArgumentException("Invalid hdr type: " + hdrType); - } - mSupportedHdrTypes.add(hdrType); - return this; - } - - private List<String> getSupportedHdrTypes() { - return new ArrayList<>(mSupportedHdrTypes); - } - - private boolean isValidVideoCodecHdrType(@NonNull String hdrType) { - if (!hdrType.equals(MediaFeature.HdrType.DOLBY_VISION) - && !hdrType.equals(MediaFeature.HdrType.HDR10) - && !hdrType.equals(MediaFeature.HdrType.HDR10_PLUS) - && !hdrType.equals(MediaFeature.HdrType.HLG)) { - return false; - } - return true; - } - - /** - * Adds an unsupported hdr type. - * - * @param hdrType Unsupported hdr type. Must be one of the String defined in - * {@link MediaFeature.HdrType}. - * @throws IllegalArgumentException if hdrType is not valid. - */ - @NonNull - public Builder addUnsupportedHdrType( - @NonNull @MediaFeature.MediaHdrType String hdrType) { - if (!isValidVideoCodecHdrType(hdrType)) { - throw new IllegalArgumentException("Invalid hdr type: " + hdrType); - } - mUnsupportedHdrTypes.add(hdrType); - return this; - } - - private List<String> getUnsupportedHdrTypes() { - return new ArrayList<>(mUnsupportedHdrTypes); - } - - /** - * Sets whether slow-motion video is supported. - * If an application indicates support for slow-motion, it is application's responsibility - * to parse the slow-motion videos using their own parser or using support library. - * @see android.media.MediaFormat#KEY_SLOW_MOTION_MARKERS - * @hide - */ - @NonNull - public Builder setSlowMotionSupported(boolean slowMotionSupported) { - mIsSlowMotionSupported = slowMotionSupported; - return this; - } - } -} diff --git a/apex/media/framework/java/android/media/BaseMediaParceledListSlice.java b/apex/media/framework/java/android/media/BaseMediaParceledListSlice.java deleted file mode 100644 index fb666098301a..000000000000 --- a/apex/media/framework/java/android/media/BaseMediaParceledListSlice.java +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright 2020 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.media; - -import android.os.Binder; -import android.os.IBinder; -import android.os.Parcel; -import android.os.Parcelable; -import android.os.RemoteException; -import android.util.Log; - -import java.util.ArrayList; -import java.util.List; - -/** - * This is a copied version of BaseParceledListSlice in framework with hidden API usages - * removed. - * - * Transfer a large list of Parcelable objects across an IPC. Splits into - * multiple transactions if needed. - * - * Caveat: for efficiency and security, all elements must be the same concrete type. - * In order to avoid writing the class name of each object, we must ensure that - * each object is the same type, or else unparceling then reparceling the data may yield - * a different result if the class name encoded in the Parcelable is a Base type. - * See b/17671747. - * - * @hide - */ -abstract class BaseMediaParceledListSlice<T> implements Parcelable { - private static String TAG = "BaseMediaParceledListSlice"; - private static boolean DEBUG = false; - - /* - * TODO get this number from somewhere else. For now set it to a quarter of - * the 1MB limit. - */ - // private static final int MAX_IPC_SIZE = IBinder.getSuggestedMaxIpcSizeBytes(); - private static final int MAX_IPC_SIZE = 64 * 1024; - - private final List<T> mList; - - private int mInlineCountLimit = Integer.MAX_VALUE; - - public BaseMediaParceledListSlice(List<T> list) { - mList = list; - } - - @SuppressWarnings("unchecked") - BaseMediaParceledListSlice(Parcel p, ClassLoader loader) { - final int N = p.readInt(); - mList = new ArrayList<T>(N); - if (DEBUG) Log.d(TAG, "Retrieving " + N + " items"); - if (N <= 0) { - return; - } - - Parcelable.Creator<?> creator = readParcelableCreator(p, loader); - Class<?> listElementClass = null; - - int i = 0; - while (i < N) { - if (p.readInt() == 0) { - break; - } - - final T parcelable = readCreator(creator, p, loader); - if (listElementClass == null) { - listElementClass = parcelable.getClass(); - } else { - verifySameType(listElementClass, parcelable.getClass()); - } - - mList.add(parcelable); - - if (DEBUG) Log.d(TAG, "Read inline #" + i + ": " + mList.get(mList.size()-1)); - i++; - } - if (i >= N) { - return; - } - final IBinder retriever = p.readStrongBinder(); - while (i < N) { - if (DEBUG) Log.d(TAG, "Reading more @" + i + " of " + N + ": retriever=" + retriever); - Parcel data = Parcel.obtain(); - Parcel reply = Parcel.obtain(); - data.writeInt(i); - try { - retriever.transact(IBinder.FIRST_CALL_TRANSACTION, data, reply, 0); - } catch (RemoteException e) { - Log.w(TAG, "Failure retrieving array; only received " + i + " of " + N, e); - return; - } - while (i < N && reply.readInt() != 0) { - final T parcelable = readCreator(creator, reply, loader); - verifySameType(listElementClass, parcelable.getClass()); - - mList.add(parcelable); - - if (DEBUG) Log.d(TAG, "Read extra #" + i + ": " + mList.get(mList.size()-1)); - i++; - } - reply.recycle(); - data.recycle(); - } - } - - private T readCreator(Parcelable.Creator<?> creator, Parcel p, ClassLoader loader) { - if (creator instanceof Parcelable.ClassLoaderCreator<?>) { - Parcelable.ClassLoaderCreator<?> classLoaderCreator = - (Parcelable.ClassLoaderCreator<?>) creator; - return (T) classLoaderCreator.createFromParcel(p, loader); - } - return (T) creator.createFromParcel(p); - } - - private static void verifySameType(final Class<?> expected, final Class<?> actual) { - if (!actual.equals(expected)) { - throw new IllegalArgumentException("Can't unparcel type " - + (actual == null ? null : actual.getName()) + " in list of type " - + (expected == null ? null : expected.getName())); - } - } - - public List<T> getList() { - return mList; - } - - /** - * Set a limit on the maximum number of entries in the array that will be included - * inline in the initial parcelling of this object. - */ - public void setInlineCountLimit(int maxCount) { - mInlineCountLimit = maxCount; - } - - /** - * Write this to another Parcel. Note that this discards the internal Parcel - * and should not be used anymore. This is so we can pass this to a Binder - * where we won't have a chance to call recycle on this. - */ - @Override - public void writeToParcel(Parcel dest, int flags) { - final int N = mList.size(); - final int callFlags = flags; - dest.writeInt(N); - if (DEBUG) Log.d(TAG, "Writing " + N + " items"); - if (N > 0) { - final Class<?> listElementClass = mList.get(0).getClass(); - writeParcelableCreator(mList.get(0), dest); - int i = 0; - while (i < N && i < mInlineCountLimit && dest.dataSize() < MAX_IPC_SIZE) { - dest.writeInt(1); - - final T parcelable = mList.get(i); - verifySameType(listElementClass, parcelable.getClass()); - writeElement(parcelable, dest, callFlags); - - if (DEBUG) Log.d(TAG, "Wrote inline #" + i + ": " + mList.get(i)); - i++; - } - if (i < N) { - dest.writeInt(0); - Binder retriever = new Binder() { - @Override - protected boolean onTransact(int code, Parcel data, Parcel reply, int flags) - throws RemoteException { - if (code != FIRST_CALL_TRANSACTION) { - return super.onTransact(code, data, reply, flags); - } - int i = data.readInt(); - if (DEBUG) Log.d(TAG, "Writing more @" + i + " of " + N); - while (i < N && reply.dataSize() < MAX_IPC_SIZE) { - reply.writeInt(1); - - final T parcelable = mList.get(i); - verifySameType(listElementClass, parcelable.getClass()); - writeElement(parcelable, reply, callFlags); - - if (DEBUG) Log.d(TAG, "Wrote extra #" + i + ": " + mList.get(i)); - i++; - } - if (i < N) { - if (DEBUG) Log.d(TAG, "Breaking @" + i + " of " + N); - reply.writeInt(0); - } - return true; - } - }; - if (DEBUG) Log.d(TAG, "Breaking @" + i + " of " + N + ": retriever=" + retriever); - dest.writeStrongBinder(retriever); - } - } - } - - abstract void writeElement(T parcelable, Parcel reply, int callFlags); - - abstract void writeParcelableCreator(T parcelable, Parcel dest); - - abstract Parcelable.Creator<?> readParcelableCreator(Parcel from, ClassLoader loader); -} diff --git a/apex/media/framework/java/android/media/BufferingParams.java b/apex/media/framework/java/android/media/BufferingParams.java deleted file mode 100644 index 04af02874bbd..000000000000 --- a/apex/media/framework/java/android/media/BufferingParams.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright 2017 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.media; - -import android.os.Parcel; -import android.os.Parcelable; - -/** - * Structure for source buffering management params. - * - * Used by {@link MediaPlayer#getBufferingParams()} and - * {@link MediaPlayer#setBufferingParams(BufferingParams)} - * to control source buffering behavior. - * - * <p>There are two stages of source buffering in {@link MediaPlayer}: initial buffering - * (when {@link MediaPlayer} is being prepared) and rebuffering (when {@link MediaPlayer} - * is playing back source). {@link BufferingParams} includes corresponding marks for each - * stage of source buffering. The marks are time based (in milliseconds). - * - * <p>{@link MediaPlayer} source component has default marks which can be queried by - * calling {@link MediaPlayer#getBufferingParams()} before any change is made by - * {@link MediaPlayer#setBufferingParams()}. - * <ul> - * <li><strong>initial buffering:</strong> initialMarkMs is used when - * {@link MediaPlayer} is being prepared. When cached data amount exceeds this mark - * {@link MediaPlayer} is prepared. </li> - * <li><strong>rebuffering during playback:</strong> resumePlaybackMarkMs is used when - * {@link MediaPlayer} is playing back content. - * <ul> - * <li> {@link MediaPlayer} has internal mark, namely pausePlaybackMarkMs, to decide when - * to pause playback if cached data amount runs low. This internal mark varies based on - * type of data source. </li> - * <li> When cached data amount exceeds resumePlaybackMarkMs, {@link MediaPlayer} will - * resume playback if it has been paused due to low cached data amount. The internal mark - * pausePlaybackMarkMs shall be less than resumePlaybackMarkMs. </li> - * <li> {@link MediaPlayer} has internal mark, namely pauseRebufferingMarkMs, to decide - * when to pause rebuffering. Apparently, this internal mark shall be no less than - * resumePlaybackMarkMs. </li> - * <li> {@link MediaPlayer} has internal mark, namely resumeRebufferingMarkMs, to decide - * when to resume buffering. This internal mark varies based on type of data source. This - * mark shall be larger than pausePlaybackMarkMs, and less than pauseRebufferingMarkMs. - * </li> - * </ul> </li> - * </ul> - * <p>Users should use {@link Builder} to change {@link BufferingParams}. - * @hide - */ -public final class BufferingParams implements Parcelable { - private static final int BUFFERING_NO_MARK = -1; - - // params - private int mInitialMarkMs = BUFFERING_NO_MARK; - - private int mResumePlaybackMarkMs = BUFFERING_NO_MARK; - - private BufferingParams() { - } - - /** - * Return initial buffering mark in milliseconds. - * @return initial buffering mark in milliseconds - */ - public int getInitialMarkMs() { - return mInitialMarkMs; - } - - /** - * Return the mark in milliseconds for resuming playback. - * @return the mark for resuming playback in milliseconds - */ - public int getResumePlaybackMarkMs() { - return mResumePlaybackMarkMs; - } - - /** - * Builder class for {@link BufferingParams} objects. - * <p> Here is an example where <code>Builder</code> is used to define the - * {@link BufferingParams} to be used by a {@link MediaPlayer} instance: - * - * <pre class="prettyprint"> - * BufferingParams myParams = mediaplayer.getDefaultBufferingParams(); - * myParams = new BufferingParams.Builder(myParams) - * .setInitialMarkMs(10000) - * .setResumePlaybackMarkMs(15000) - * .build(); - * mediaplayer.setBufferingParams(myParams); - * </pre> - */ - public static class Builder { - private int mInitialMarkMs = BUFFERING_NO_MARK; - private int mResumePlaybackMarkMs = BUFFERING_NO_MARK; - - /** - * Constructs a new Builder with the defaults. - * By default, all marks are -1. - */ - public Builder() { - } - - /** - * Constructs a new Builder from a given {@link BufferingParams} instance - * @param bp the {@link BufferingParams} object whose data will be reused - * in the new Builder. - */ - public Builder(BufferingParams bp) { - mInitialMarkMs = bp.mInitialMarkMs; - mResumePlaybackMarkMs = bp.mResumePlaybackMarkMs; - } - - /** - * Combines all of the fields that have been set and return a new - * {@link BufferingParams} object. <code>IllegalStateException</code> will be - * thrown if there is conflict between fields. - * @return a new {@link BufferingParams} object - */ - public BufferingParams build() { - BufferingParams bp = new BufferingParams(); - bp.mInitialMarkMs = mInitialMarkMs; - bp.mResumePlaybackMarkMs = mResumePlaybackMarkMs; - - return bp; - } - - /** - * Sets the time based mark in milliseconds for initial buffering. - * @param markMs time based mark in milliseconds - * @return the same Builder instance. - */ - public Builder setInitialMarkMs(int markMs) { - mInitialMarkMs = markMs; - return this; - } - - /** - * Sets the time based mark in milliseconds for resuming playback. - * @param markMs time based mark in milliseconds for resuming playback - * @return the same Builder instance. - */ - public Builder setResumePlaybackMarkMs(int markMs) { - mResumePlaybackMarkMs = markMs; - return this; - } - } - - private BufferingParams(Parcel in) { - mInitialMarkMs = in.readInt(); - mResumePlaybackMarkMs = in.readInt(); - } - - public static final @android.annotation.NonNull Parcelable.Creator<BufferingParams> CREATOR = - new Parcelable.Creator<BufferingParams>() { - @Override - public BufferingParams createFromParcel(Parcel in) { - return new BufferingParams(in); - } - - @Override - public BufferingParams[] newArray(int size) { - return new BufferingParams[size]; - } - }; - - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(mInitialMarkMs); - dest.writeInt(mResumePlaybackMarkMs); - } -} diff --git a/apex/media/framework/java/android/media/Controller2Link.java b/apex/media/framework/java/android/media/Controller2Link.java deleted file mode 100644 index 8eefec73194c..000000000000 --- a/apex/media/framework/java/android/media/Controller2Link.java +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Copyright 2018 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.media; - -import android.os.Binder; -import android.os.Bundle; -import android.os.Parcel; -import android.os.Parcelable; -import android.os.RemoteException; -import android.os.ResultReceiver; - -import java.util.Objects; - -/** - * Handles incoming commands from {@link MediaSession2} to {@link MediaController2}. - * @hide - */ -// @SystemApi -public final class Controller2Link implements Parcelable { - private static final String TAG = "Controller2Link"; - private static final boolean DEBUG = MediaController2.DEBUG; - - public static final @android.annotation.NonNull Parcelable.Creator<Controller2Link> CREATOR = - new Parcelable.Creator<Controller2Link>() { - @Override - public Controller2Link createFromParcel(Parcel in) { - return new Controller2Link(in); - } - - @Override - public Controller2Link[] newArray(int size) { - return new Controller2Link[size]; - } - }; - - - private final MediaController2 mController; - private final IMediaController2 mIController; - - public Controller2Link(MediaController2 controller) { - mController = controller; - mIController = new Controller2Stub(); - } - - Controller2Link(Parcel in) { - mController = null; - mIController = IMediaController2.Stub.asInterface(in.readStrongBinder()); - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeStrongBinder(mIController.asBinder()); - } - - @Override - public int hashCode() { - return mIController.asBinder().hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (!(obj instanceof Controller2Link)) { - return false; - } - Controller2Link other = (Controller2Link) obj; - return Objects.equals(mIController.asBinder(), other.mIController.asBinder()); - } - - /** Interface method for IMediaController2.notifyConnected */ - public void notifyConnected(int seq, Bundle connectionResult) { - try { - mIController.notifyConnected(seq, connectionResult); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - - /** Interface method for IMediaController2.notifyDisonnected */ - public void notifyDisconnected(int seq) { - try { - mIController.notifyDisconnected(seq); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - - /** Interface method for IMediaController2.notifyPlaybackActiveChanged */ - public void notifyPlaybackActiveChanged(int seq, boolean playbackActive) { - try { - mIController.notifyPlaybackActiveChanged(seq, playbackActive); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - - /** Interface method for IMediaController2.sendSessionCommand */ - public void sendSessionCommand(int seq, Session2Command command, Bundle args, - ResultReceiver resultReceiver) { - try { - mIController.sendSessionCommand(seq, command, args, resultReceiver); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - - /** Interface method for IMediaController2.cancelSessionCommand */ - public void cancelSessionCommand(int seq) { - try { - mIController.cancelSessionCommand(seq); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - - /** Stub implementation for IMediaController2.notifyConnected */ - public void onConnected(int seq, Bundle connectionResult) { - if (connectionResult == null) { - onDisconnected(seq); - return; - } - mController.onConnected(seq, connectionResult); - } - - /** Stub implementation for IMediaController2.notifyDisonnected */ - public void onDisconnected(int seq) { - mController.onDisconnected(seq); - } - - /** Stub implementation for IMediaController2.notifyPlaybackActiveChanged */ - public void onPlaybackActiveChanged(int seq, boolean playbackActive) { - mController.onPlaybackActiveChanged(seq, playbackActive); - } - - /** Stub implementation for IMediaController2.sendSessionCommand */ - public void onSessionCommand(int seq, Session2Command command, Bundle args, - ResultReceiver resultReceiver) { - mController.onSessionCommand(seq, command, args, resultReceiver); - } - - /** Stub implementation for IMediaController2.cancelSessionCommand */ - public void onCancelCommand(int seq) { - mController.onCancelCommand(seq); - } - - private class Controller2Stub extends IMediaController2.Stub { - @Override - public void notifyConnected(int seq, Bundle connectionResult) { - final long token = Binder.clearCallingIdentity(); - try { - Controller2Link.this.onConnected(seq, connectionResult); - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override - public void notifyDisconnected(int seq) { - final long token = Binder.clearCallingIdentity(); - try { - Controller2Link.this.onDisconnected(seq); - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override - public void notifyPlaybackActiveChanged(int seq, boolean playbackActive) { - final long token = Binder.clearCallingIdentity(); - try { - Controller2Link.this.onPlaybackActiveChanged(seq, playbackActive); - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override - public void sendSessionCommand(int seq, Session2Command command, Bundle args, - ResultReceiver resultReceiver) { - final long token = Binder.clearCallingIdentity(); - try { - Controller2Link.this.onSessionCommand(seq, command, args, resultReceiver); - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override - public void cancelSessionCommand(int seq) { - final long token = Binder.clearCallingIdentity(); - try { - Controller2Link.this.onCancelCommand(seq); - } finally { - Binder.restoreCallingIdentity(token); - } - } - } -} diff --git a/apex/media/framework/java/android/media/DataSourceCallback.java b/apex/media/framework/java/android/media/DataSourceCallback.java deleted file mode 100644 index c297ecda249c..000000000000 --- a/apex/media/framework/java/android/media/DataSourceCallback.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2017 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.media; - -import android.annotation.NonNull; - -import java.io.Closeable; -import java.io.IOException; - -/** - * For supplying media data to the framework. Implement this if your app has - * special requirements for the way media data is obtained. - * - * <p class="note">Methods of this interface may be called on multiple different - * threads. There will be a thread synchronization point between each call to ensure that - * modifications to the state of your DataSourceCallback are visible to future calls. This means - * you don't need to do your own synchronization unless you're modifying the - * DataSourceCallback from another thread while it's being used by the framework.</p> - * - * @hide - */ -public abstract class DataSourceCallback implements Closeable { - - public static final int END_OF_STREAM = -1; - - /** - * Called to request data from the given position. - * - * Implementations should should write up to {@code size} bytes into - * {@code buffer}, and return the number of bytes written. - * - * Return {@code 0} if size is zero (thus no bytes are read). - * - * Return {@code -1} to indicate that end of stream is reached. - * - * @param position the position in the data source to read from. - * @param buffer the buffer to read the data into. - * @param offset the offset within buffer to read the data into. - * @param size the number of bytes to read. - * @throws IOException on fatal errors. - * @return the number of bytes read, or {@link #END_OF_STREAM} if end of stream is reached. - */ - public abstract int readAt(long position, @NonNull byte[] buffer, int offset, int size) - throws IOException; - - /** - * Called to get the size of the data source. - * - * @throws IOException on fatal errors - * @return the size of data source in bytes, or -1 if the size is unknown. - */ - public abstract long getSize() throws IOException; -} diff --git a/apex/media/framework/java/android/media/MediaCommunicationManager.java b/apex/media/framework/java/android/media/MediaCommunicationManager.java deleted file mode 100644 index f39bcfb267bf..000000000000 --- a/apex/media/framework/java/android/media/MediaCommunicationManager.java +++ /dev/null @@ -1,288 +0,0 @@ -/* - * Copyright 2020 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.media; - -import static android.Manifest.permission.MEDIA_CONTENT_CONTROL; -import static android.annotation.SystemApi.Client.MODULE_LIBRARIES; - -import android.annotation.CallbackExecutor; -import android.annotation.IntRange; -import android.annotation.NonNull; -import android.annotation.RequiresPermission; -import android.annotation.SystemApi; -import android.annotation.SystemService; -import android.content.Context; -import android.media.session.MediaSession; -import android.media.session.MediaSessionManager; -import android.os.Build; -import android.os.RemoteException; -import android.os.UserHandle; -import android.service.media.MediaBrowserService; -import android.util.Log; - -import com.android.internal.annotations.GuardedBy; -import com.android.modules.annotation.MinSdk; -import com.android.modules.utils.build.SdkLevel; - -import java.util.Collections; -import java.util.List; -import java.util.Objects; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.Executor; - -/** - * Provides support for interacting with {@link android.media.MediaSession2 MediaSession2s} - * that applications have published to express their ongoing media playback state. - */ -@MinSdk(Build.VERSION_CODES.S) -@SystemService(Context.MEDIA_COMMUNICATION_SERVICE) -public class MediaCommunicationManager { - private static final String TAG = "MediaCommunicationManager"; - - /** - * The manager version used from beginning. - */ - private static final int VERSION_1 = 1; - - /** - * Current manager version. - */ - private static final int CURRENT_VERSION = VERSION_1; - - private final Context mContext; - private final IMediaCommunicationService mService; - - private final Object mLock = new Object(); - private final CopyOnWriteArrayList<SessionCallbackRecord> mTokenCallbackRecords = - new CopyOnWriteArrayList<>(); - - @GuardedBy("mLock") - private MediaCommunicationServiceCallbackStub mCallbackStub; - - /** - * @hide - */ - public MediaCommunicationManager(@NonNull Context context) { - if (!SdkLevel.isAtLeastS()) { - throw new UnsupportedOperationException("Android version must be S or greater."); - } - mContext = context; - mService = IMediaCommunicationService.Stub.asInterface( - MediaFrameworkInitializer.getMediaServiceManager() - .getMediaCommunicationServiceRegisterer() - .get()); - } - - /** - * Gets the version of this {@link MediaCommunicationManager}. - */ - public @IntRange(from = 1) int getVersion() { - return CURRENT_VERSION; - } - - /** - * Notifies that a new {@link MediaSession2} with type {@link Session2Token#TYPE_SESSION} is - * created. - * @param token newly created session2 token - * @hide - */ - public void notifySession2Created(@NonNull Session2Token token) { - Objects.requireNonNull(token, "token shouldn't be null"); - if (token.getType() != Session2Token.TYPE_SESSION) { - throw new IllegalArgumentException("token's type should be TYPE_SESSION"); - } - try { - mService.notifySession2Created(token); - } catch (RemoteException e) { - e.rethrowFromSystemServer(); - } - } - - /** - * Checks whether the remote user is a trusted app. - * <p> - * An app is trusted if the app holds the - * {@link android.Manifest.permission#MEDIA_CONTENT_CONTROL} permission or has an enabled - * notification listener. - * - * @param userInfo The remote user info from either - * {@link MediaSession#getCurrentControllerInfo()} or - * {@link MediaBrowserService#getCurrentBrowserInfo()}. - * @return {@code true} if the remote user is trusted or {@code false} otherwise. - * @hide - */ - public boolean isTrustedForMediaControl(@NonNull MediaSessionManager.RemoteUserInfo userInfo) { - Objects.requireNonNull(userInfo, "userInfo shouldn't be null"); - if (userInfo.getPackageName() == null) { - return false; - } - try { - return mService.isTrusted( - userInfo.getPackageName(), userInfo.getPid(), userInfo.getUid()); - } catch (RemoteException e) { - Log.w(TAG, "Cannot communicate with the service.", e); - } - return false; - } - - /** - * This API is not generally intended for third party application developers. - * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a> - * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session - * Library</a> for consistent behavior across all devices. - * <p> - * Gets a list of {@link Session2Token} with type {@link Session2Token#TYPE_SESSION} for the - * current user. - * <p> - * Although this API can be used without any restriction, each session owners can accept or - * reject your uses of {@link MediaSession2}. - * - * @return A list of {@link Session2Token}. - */ - @NonNull - public List<Session2Token> getSession2Tokens() { - return getSession2Tokens(UserHandle.myUserId()); - } - - /** - * Adds a callback to be notified when the list of active sessions changes. - * <p> - * This requires the {@link android.Manifest.permission#MEDIA_CONTENT_CONTROL} permission be - * held by the calling app. - * </p> - * @hide - */ - @SystemApi(client = MODULE_LIBRARIES) - @RequiresPermission(MEDIA_CONTENT_CONTROL) - public void registerSessionCallback(@CallbackExecutor @NonNull Executor executor, - @NonNull SessionCallback callback) { - Objects.requireNonNull(executor, "executor must not be null"); - Objects.requireNonNull(callback, "callback must not be null"); - - if (!mTokenCallbackRecords.addIfAbsent( - new SessionCallbackRecord(executor, callback))) { - Log.w(TAG, "registerSession2TokenCallback: Ignoring the same callback"); - return; - } - synchronized (mLock) { - if (mCallbackStub == null) { - MediaCommunicationServiceCallbackStub callbackStub = - new MediaCommunicationServiceCallbackStub(); - try { - mService.registerCallback(callbackStub, mContext.getPackageName()); - mCallbackStub = callbackStub; - } catch (RemoteException ex) { - Log.e(TAG, "Failed to register callback.", ex); - } - } - } - } - - /** - * Stops receiving active sessions updates on the specified callback. - * @hide - */ - @SystemApi(client = MODULE_LIBRARIES) - public void unregisterSessionCallback(@NonNull SessionCallback callback) { - if (!mTokenCallbackRecords.remove( - new SessionCallbackRecord(null, callback))) { - Log.w(TAG, "unregisterSession2TokenCallback: Ignoring an unknown callback."); - return; - } - synchronized (mLock) { - if (mCallbackStub != null && mTokenCallbackRecords.isEmpty()) { - try { - mService.unregisterCallback(mCallbackStub); - } catch (RemoteException ex) { - Log.e(TAG, "Failed to unregister callback.", ex); - } - mCallbackStub = null; - } - } - } - - private List<Session2Token> getSession2Tokens(int userId) { - try { - MediaParceledListSlice slice = mService.getSession2Tokens(userId); - return slice == null ? Collections.emptyList() : slice.getList(); - } catch (RemoteException e) { - Log.e(TAG, "Failed to get session tokens", e); - } - return Collections.emptyList(); - } - - /** - * Callback for listening to changes to the sessions. - * @see #registerSessionCallback(Executor, SessionCallback) - * @hide - */ - @SystemApi(client = MODULE_LIBRARIES) - public interface SessionCallback { - /** - * Called when a new {@link MediaSession2 media session2} is created. - * @param token the newly created token - */ - default void onSession2TokenCreated(@NonNull Session2Token token) {} - - /** - * Called when {@link #getSession2Tokens() session tokens} are changed. - */ - default void onSession2TokensChanged(@NonNull List<Session2Token> tokens) {} - } - - private static final class SessionCallbackRecord { - public final Executor executor; - public final SessionCallback callback; - - SessionCallbackRecord(Executor executor, SessionCallback callback) { - this.executor = executor; - this.callback = callback; - } - - @Override - public int hashCode() { - return Objects.hash(callback); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!(obj instanceof SessionCallbackRecord)) { - return false; - } - return Objects.equals(this.callback, ((SessionCallbackRecord) obj).callback); - } - } - - class MediaCommunicationServiceCallbackStub extends IMediaCommunicationServiceCallback.Stub { - @Override - public void onSession2Created(Session2Token token) throws RemoteException { - for (SessionCallbackRecord record : mTokenCallbackRecords) { - record.executor.execute(() -> record.callback.onSession2TokenCreated(token)); - } - } - - @Override - public void onSession2Changed(MediaParceledListSlice tokens) throws RemoteException { - List<Session2Token> tokenList = tokens.getList(); - for (SessionCallbackRecord record : mTokenCallbackRecords) { - record.executor.execute(() -> record.callback.onSession2TokensChanged(tokenList)); - } - } - } -} diff --git a/apex/media/framework/java/android/media/MediaConstants.java b/apex/media/framework/java/android/media/MediaConstants.java deleted file mode 100644 index ce108894b9a5..000000000000 --- a/apex/media/framework/java/android/media/MediaConstants.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2018 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.media; - -class MediaConstants { - // Bundle key for int - static final String KEY_PID = "android.media.key.PID"; - - // Bundle key for String - static final String KEY_PACKAGE_NAME = "android.media.key.PACKAGE_NAME"; - - // Bundle key for Parcelable - static final String KEY_SESSION2LINK = "android.media.key.SESSION2LINK"; - static final String KEY_ALLOWED_COMMANDS = "android.media.key.ALLOWED_COMMANDS"; - static final String KEY_PLAYBACK_ACTIVE = "android.media.key.PLAYBACK_ACTIVE"; - static final String KEY_TOKEN_EXTRAS = "android.media.key.TOKEN_EXTRAS"; - static final String KEY_CONNECTION_HINTS = "android.media.key.CONNECTION_HINTS"; - - private MediaConstants() { - } -} diff --git a/apex/media/framework/java/android/media/MediaController2.java b/apex/media/framework/java/android/media/MediaController2.java deleted file mode 100644 index 159e8e551d11..000000000000 --- a/apex/media/framework/java/android/media/MediaController2.java +++ /dev/null @@ -1,637 +0,0 @@ -/* - * Copyright 2018 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.media; - -import static android.media.MediaConstants.KEY_ALLOWED_COMMANDS; -import static android.media.MediaConstants.KEY_CONNECTION_HINTS; -import static android.media.MediaConstants.KEY_PACKAGE_NAME; -import static android.media.MediaConstants.KEY_PID; -import static android.media.MediaConstants.KEY_PLAYBACK_ACTIVE; -import static android.media.MediaConstants.KEY_SESSION2LINK; -import static android.media.MediaConstants.KEY_TOKEN_EXTRAS; -import static android.media.Session2Command.Result.RESULT_ERROR_UNKNOWN_ERROR; -import static android.media.Session2Command.Result.RESULT_INFO_SKIPPED; -import static android.media.Session2Token.TYPE_SESSION; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.ServiceConnection; -import android.os.Bundle; -import android.os.Handler; -import android.os.IBinder; -import android.os.Process; -import android.os.RemoteException; -import android.os.ResultReceiver; -import android.util.ArrayMap; -import android.util.ArraySet; -import android.util.Log; - -import java.util.concurrent.Executor; - -/** - * This API is not generally intended for third party application developers. - * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a> - * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session - * Library</a> for consistent behavior across all devices. - * - * Allows an app to interact with an active {@link MediaSession2} or a - * {@link MediaSession2Service} which would provide {@link MediaSession2}. Media buttons and other - * commands can be sent to the session. - */ -public class MediaController2 implements AutoCloseable { - static final String TAG = "MediaController2"; - static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); - - @SuppressWarnings("WeakerAccess") /* synthetic access */ - final ControllerCallback mCallback; - - private final IBinder.DeathRecipient mDeathRecipient = () -> close(); - private final Context mContext; - private final Session2Token mSessionToken; - private final Executor mCallbackExecutor; - private final Controller2Link mControllerStub; - private final Handler mResultHandler; - private final SessionServiceConnection mServiceConnection; - - private final Object mLock = new Object(); - //@GuardedBy("mLock") - private boolean mClosed; - //@GuardedBy("mLock") - private int mNextSeqNumber; - //@GuardedBy("mLock") - private Session2Link mSessionBinder; - //@GuardedBy("mLock") - private Session2CommandGroup mAllowedCommands; - //@GuardedBy("mLock") - private Session2Token mConnectedToken; - //@GuardedBy("mLock") - private ArrayMap<ResultReceiver, Integer> mPendingCommands; - //@GuardedBy("mLock") - private ArraySet<Integer> mRequestedCommandSeqNumbers; - //@GuardedBy("mLock") - private boolean mPlaybackActive; - - /** - * Create a {@link MediaController2} from the {@link Session2Token}. - * This connects to the session and may wake up the service if it's not available. - * - * @param context context - * @param token token to connect to - * @param connectionHints a session-specific argument to send to the session when connecting. - * The contents of this bundle may affect the connection result. - * @param executor executor to run callbacks on. - * @param callback controller callback to receive changes in. - */ - MediaController2(@NonNull Context context, @NonNull Session2Token token, - @NonNull Bundle connectionHints, @NonNull Executor executor, - @NonNull ControllerCallback callback) { - if (context == null) { - throw new IllegalArgumentException("context shouldn't be null"); - } - if (token == null) { - throw new IllegalArgumentException("token shouldn't be null"); - } - mContext = context; - mSessionToken = token; - mCallbackExecutor = (executor == null) ? context.getMainExecutor() : executor; - mCallback = (callback == null) ? new ControllerCallback() {} : callback; - mControllerStub = new Controller2Link(this); - // NOTE: mResultHandler uses main looper, so this MUST NOT be blocked. - mResultHandler = new Handler(context.getMainLooper()); - - mNextSeqNumber = 0; - mPendingCommands = new ArrayMap<>(); - mRequestedCommandSeqNumbers = new ArraySet<>(); - - boolean connectRequested; - if (token.getType() == TYPE_SESSION) { - mServiceConnection = null; - connectRequested = requestConnectToSession(connectionHints); - } else { - mServiceConnection = new SessionServiceConnection(connectionHints); - connectRequested = requestConnectToService(); - } - if (!connectRequested) { - close(); - } - } - - @Override - public void close() { - synchronized (mLock) { - if (mClosed) { - // Already closed. Ignore rest of clean up code. - // Note: unbindService() throws IllegalArgumentException when it's called twice. - return; - } - if (DEBUG) { - Log.d(TAG, "closing " + this); - } - mClosed = true; - if (mServiceConnection != null) { - // Note: This should be called even when the bindService() has returned false. - mContext.unbindService(mServiceConnection); - } - if (mSessionBinder != null) { - try { - mSessionBinder.disconnect(mControllerStub, getNextSeqNumber()); - mSessionBinder.unlinkToDeath(mDeathRecipient, 0); - } catch (RuntimeException e) { - // No-op - } - } - mConnectedToken = null; - mPendingCommands.clear(); - mRequestedCommandSeqNumbers.clear(); - mCallbackExecutor.execute(() -> { - mCallback.onDisconnected(MediaController2.this); - }); - mSessionBinder = null; - } - } - - /** - * Returns {@link Session2Token} of the connected session. - * If it is not connected yet, it returns {@code null}. - * <p> - * This may differ with the {@link Session2Token} from the constructor. For example, if the - * controller is created with the token for {@link MediaSession2Service}, this would return - * token for the {@link MediaSession2} in the service. - * - * @return Session2Token of the connected session, or {@code null} if not connected - */ - @Nullable - public Session2Token getConnectedToken() { - synchronized (mLock) { - return mConnectedToken; - } - } - - /** - * Returns whether the session's playback is active. - * - * @return {@code true} if playback active. {@code false} otherwise. - * @see ControllerCallback#onPlaybackActiveChanged(MediaController2, boolean) - */ - public boolean isPlaybackActive() { - synchronized (mLock) { - return mPlaybackActive; - } - } - - /** - * Sends a session command to the session - * <p> - * @param command the session command - * @param args optional arguments - * @return a token which will be sent together in {@link ControllerCallback#onCommandResult} - * when its result is received. - */ - @NonNull - public Object sendSessionCommand(@NonNull Session2Command command, @Nullable Bundle args) { - if (command == null) { - throw new IllegalArgumentException("command shouldn't be null"); - } - - ResultReceiver resultReceiver = new ResultReceiver(mResultHandler) { - protected void onReceiveResult(int resultCode, Bundle resultData) { - synchronized (mLock) { - mPendingCommands.remove(this); - } - mCallbackExecutor.execute(() -> { - mCallback.onCommandResult(MediaController2.this, this, - command, new Session2Command.Result(resultCode, resultData)); - }); - } - }; - - synchronized (mLock) { - if (mSessionBinder != null) { - int seq = getNextSeqNumber(); - mPendingCommands.put(resultReceiver, seq); - try { - mSessionBinder.sendSessionCommand(mControllerStub, seq, command, args, - resultReceiver); - } catch (RuntimeException e) { - mPendingCommands.remove(resultReceiver); - resultReceiver.send(RESULT_ERROR_UNKNOWN_ERROR, null); - } - } - } - return resultReceiver; - } - - /** - * Cancels the session command previously sent. - * - * @param token the token which is returned from {@link #sendSessionCommand}. - */ - public void cancelSessionCommand(@NonNull Object token) { - if (token == null) { - throw new IllegalArgumentException("token shouldn't be null"); - } - synchronized (mLock) { - if (mSessionBinder == null) return; - Integer seq = mPendingCommands.remove(token); - if (seq != null) { - mSessionBinder.cancelSessionCommand(mControllerStub, seq); - } - } - } - - // Called by Controller2Link.onConnected - void onConnected(int seq, Bundle connectionResult) { - Session2Link sessionBinder = connectionResult.getParcelable(KEY_SESSION2LINK); - Session2CommandGroup allowedCommands = - connectionResult.getParcelable(KEY_ALLOWED_COMMANDS); - boolean playbackActive = connectionResult.getBoolean(KEY_PLAYBACK_ACTIVE); - - Bundle tokenExtras = connectionResult.getBundle(KEY_TOKEN_EXTRAS); - if (tokenExtras == null) { - Log.w(TAG, "extras shouldn't be null."); - tokenExtras = Bundle.EMPTY; - } else if (MediaSession2.hasCustomParcelable(tokenExtras)) { - Log.w(TAG, "extras contain custom parcelable. Ignoring."); - tokenExtras = Bundle.EMPTY; - } - - if (DEBUG) { - Log.d(TAG, "notifyConnected sessionBinder=" + sessionBinder - + ", allowedCommands=" + allowedCommands); - } - if (sessionBinder == null || allowedCommands == null) { - // Connection rejected. - close(); - return; - } - synchronized (mLock) { - mSessionBinder = sessionBinder; - mAllowedCommands = allowedCommands; - mPlaybackActive = playbackActive; - - // Implementation for the local binder is no-op, - // so can be used without worrying about deadlock. - sessionBinder.linkToDeath(mDeathRecipient, 0); - mConnectedToken = new Session2Token(mSessionToken.getUid(), TYPE_SESSION, - mSessionToken.getPackageName(), sessionBinder, tokenExtras); - } - mCallbackExecutor.execute(() -> { - mCallback.onConnected(MediaController2.this, allowedCommands); - }); - } - - // Called by Controller2Link.onDisconnected - void onDisconnected(int seq) { - // close() will call mCallback.onDisconnected - close(); - } - - // Called by Controller2Link.onPlaybackActiveChanged - void onPlaybackActiveChanged(int seq, boolean playbackActive) { - synchronized (mLock) { - mPlaybackActive = playbackActive; - } - mCallbackExecutor.execute(() -> { - mCallback.onPlaybackActiveChanged(MediaController2.this, playbackActive); - }); - } - - // Called by Controller2Link.onSessionCommand - void onSessionCommand(int seq, Session2Command command, Bundle args, - @Nullable ResultReceiver resultReceiver) { - synchronized (mLock) { - mRequestedCommandSeqNumbers.add(seq); - } - mCallbackExecutor.execute(() -> { - boolean isCanceled; - synchronized (mLock) { - isCanceled = !mRequestedCommandSeqNumbers.remove(seq); - } - if (isCanceled) { - if (resultReceiver != null) { - resultReceiver.send(RESULT_INFO_SKIPPED, null); - } - return; - } - Session2Command.Result result = mCallback.onSessionCommand( - MediaController2.this, command, args); - if (resultReceiver != null) { - if (result == null) { - resultReceiver.send(RESULT_INFO_SKIPPED, null); - } else { - resultReceiver.send(result.getResultCode(), result.getResultData()); - } - } - }); - } - - // Called by Controller2Link.onSessionCommand - void onCancelCommand(int seq) { - synchronized (mLock) { - mRequestedCommandSeqNumbers.remove(seq); - } - } - - private int getNextSeqNumber() { - synchronized (mLock) { - return mNextSeqNumber++; - } - } - - private Bundle createConnectionRequest(@NonNull Bundle connectionHints) { - Bundle connectionRequest = new Bundle(); - connectionRequest.putString(KEY_PACKAGE_NAME, mContext.getPackageName()); - connectionRequest.putInt(KEY_PID, Process.myPid()); - connectionRequest.putBundle(KEY_CONNECTION_HINTS, connectionHints); - return connectionRequest; - } - - private boolean requestConnectToSession(@NonNull Bundle connectionHints) { - Session2Link sessionBinder = mSessionToken.getSessionLink(); - Bundle connectionRequest = createConnectionRequest(connectionHints); - try { - sessionBinder.connect(mControllerStub, getNextSeqNumber(), connectionRequest); - } catch (RuntimeException e) { - Log.w(TAG, "Failed to call connection request", e); - return false; - } - return true; - } - - private boolean requestConnectToService() { - // Service. Needs to get fresh binder whenever connection is needed. - final Intent intent = new Intent(MediaSession2Service.SERVICE_INTERFACE); - intent.setClassName(mSessionToken.getPackageName(), mSessionToken.getServiceName()); - - // Use bindService() instead of startForegroundService() to start session service for three - // reasons. - // 1. Prevent session service owner's stopSelf() from destroying service. - // With the startForegroundService(), service's call of stopSelf() will trigger immediate - // onDestroy() calls on the main thread even when onConnect() is running in another - // thread. - // 2. Minimize APIs for developers to take care about. - // With bindService(), developers only need to take care about Service.onBind() - // but Service.onStartCommand() should be also taken care about with the - // startForegroundService(). - // 3. Future support for UI-less playback - // If a service wants to keep running, it should be either foreground service or - // bound service. But there had been request for the feature for system apps - // and using bindService() will be better fit with it. - synchronized (mLock) { - boolean result = mContext.bindService( - intent, mServiceConnection, Context.BIND_AUTO_CREATE); - if (!result) { - Log.w(TAG, "bind to " + mSessionToken + " failed"); - return false; - } else if (DEBUG) { - Log.d(TAG, "bind to " + mSessionToken + " succeeded"); - } - } - return true; - } - - /** - * This API is not generally intended for third party application developers. - * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a> - * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session - * Library</a> for consistent behavior across all devices. - * <p> - * Builder for {@link MediaController2}. - * <p> - * Any incoming event from the {@link MediaSession2} will be handled on the callback - * executor. If it's not set, {@link Context#getMainExecutor()} will be used by default. - */ - public static final class Builder { - private Context mContext; - private Session2Token mToken; - private Bundle mConnectionHints; - private Executor mCallbackExecutor; - private ControllerCallback mCallback; - - /** - * Creates a builder for {@link MediaController2}. - * - * @param context context - * @param token token of the session to connect to - */ - public Builder(@NonNull Context context, @NonNull Session2Token token) { - if (context == null) { - throw new IllegalArgumentException("context shouldn't be null"); - } - if (token == null) { - throw new IllegalArgumentException("token shouldn't be null"); - } - mContext = context; - mToken = token; - } - - /** - * Set the connection hints for the controller. - * <p> - * {@code connectionHints} is a session-specific argument to send to the session when - * connecting. The contents of this bundle may affect the connection result. - * <p> - * An {@link IllegalArgumentException} will be thrown if the bundle contains any - * non-framework Parcelable objects. - * - * @param connectionHints a bundle which contains the connection hints - * @return The Builder to allow chaining - */ - @NonNull - public Builder setConnectionHints(@NonNull Bundle connectionHints) { - if (connectionHints == null) { - throw new IllegalArgumentException("connectionHints shouldn't be null"); - } - if (MediaSession2.hasCustomParcelable(connectionHints)) { - throw new IllegalArgumentException("connectionHints shouldn't contain any custom " - + "parcelables"); - } - mConnectionHints = new Bundle(connectionHints); - return this; - } - - /** - * Set callback for the controller and its executor. - * - * @param executor callback executor - * @param callback session callback. - * @return The Builder to allow chaining - */ - @NonNull - public Builder setControllerCallback(@NonNull Executor executor, - @NonNull ControllerCallback callback) { - if (executor == null) { - throw new IllegalArgumentException("executor shouldn't be null"); - } - if (callback == null) { - throw new IllegalArgumentException("callback shouldn't be null"); - } - mCallbackExecutor = executor; - mCallback = callback; - return this; - } - - /** - * Build {@link MediaController2}. - * - * @return a new controller - */ - @NonNull - public MediaController2 build() { - if (mCallbackExecutor == null) { - mCallbackExecutor = mContext.getMainExecutor(); - } - if (mCallback == null) { - mCallback = new ControllerCallback() {}; - } - if (mConnectionHints == null) { - mConnectionHints = Bundle.EMPTY; - } - return new MediaController2( - mContext, mToken, mConnectionHints, mCallbackExecutor, mCallback); - } - } - - /** - * This API is not generally intended for third party application developers. - * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a> - * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session - * Library</a> for consistent behavior across all devices. - * <p> - * Interface for listening to change in activeness of the {@link MediaSession2}. - */ - public abstract static class ControllerCallback { - /** - * Called when the controller is successfully connected to the session. The controller - * becomes available afterwards. - * - * @param controller the controller for this event - * @param allowedCommands commands that's allowed by the session. - */ - public void onConnected(@NonNull MediaController2 controller, - @NonNull Session2CommandGroup allowedCommands) {} - - /** - * Called when the session refuses the controller or the controller is disconnected from - * the session. The controller becomes unavailable afterwards and the callback wouldn't - * be called. - * <p> - * It will be also called after the {@link #close()}, so you can put clean up code here. - * You don't need to call {@link #close()} after this. - * - * @param controller the controller for this event - */ - public void onDisconnected(@NonNull MediaController2 controller) {} - - /** - * Called when the session's playback activeness is changed. - * - * @param controller the controller for this event - * @param playbackActive {@code true} if the session's playback is active. - * {@code false} otherwise. - * @see MediaController2#isPlaybackActive() - */ - public void onPlaybackActiveChanged(@NonNull MediaController2 controller, - boolean playbackActive) {} - - /** - * Called when the connected session sent a session command. - * - * @param controller the controller for this event - * @param command the session command - * @param args optional arguments - * @return the result for the session command. If {@code null}, RESULT_INFO_SKIPPED - * will be sent to the session. - */ - @Nullable - public Session2Command.Result onSessionCommand(@NonNull MediaController2 controller, - @NonNull Session2Command command, @Nullable Bundle args) { - return null; - } - - /** - * Called when the command sent to the connected session is finished. - * - * @param controller the controller for this event - * @param token the token got from {@link MediaController2#sendSessionCommand} - * @param command the session command - * @param result the result of the session command - */ - public void onCommandResult(@NonNull MediaController2 controller, @NonNull Object token, - @NonNull Session2Command command, @NonNull Session2Command.Result result) {} - } - - // This will be called on the main thread. - private class SessionServiceConnection implements ServiceConnection { - private final Bundle mConnectionHints; - - SessionServiceConnection(@Nullable Bundle connectionHints) { - mConnectionHints = connectionHints; - } - - @Override - public void onServiceConnected(ComponentName name, IBinder service) { - // Note that it's always main-thread. - boolean connectRequested = false; - try { - if (DEBUG) { - Log.d(TAG, "onServiceConnected " + name + " " + this); - } - if (!mSessionToken.getPackageName().equals(name.getPackageName())) { - Log.wtf(TAG, "Expected connection to " + mSessionToken.getPackageName() - + " but is connected to " + name); - return; - } - IMediaSession2Service iService = IMediaSession2Service.Stub.asInterface(service); - if (iService == null) { - Log.wtf(TAG, "Service interface is missing."); - return; - } - Bundle connectionRequest = createConnectionRequest(mConnectionHints); - iService.connect(mControllerStub, getNextSeqNumber(), connectionRequest); - connectRequested = true; - } catch (RemoteException e) { - Log.w(TAG, "Service " + name + " has died prematurely", e); - } finally { - if (!connectRequested) { - close(); - } - } - } - - @Override - public void onServiceDisconnected(ComponentName name) { - // Temporal lose of the binding because of the service crash. System will automatically - // rebind, so just no-op. - if (DEBUG) { - Log.w(TAG, "Session service " + name + " is disconnected."); - } - close(); - } - - @Override - public void onBindingDied(ComponentName name) { - // Permanent lose of the binding because of the service package update or removed. - // This SessionServiceRecord will be removed accordingly, but forget session binder here - // for sure. - close(); - } - } -} diff --git a/apex/media/framework/java/android/media/MediaFeature.java b/apex/media/framework/java/android/media/MediaFeature.java deleted file mode 100644 index 8d1b159cd70b..000000000000 --- a/apex/media/framework/java/android/media/MediaFeature.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2020 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.media; - -import android.annotation.StringDef; -import android.os.Build; - -import com.android.modules.annotation.MinSdk; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -/** - * MediaFeature defines various media features, e.g. hdr type. - */ -@MinSdk(Build.VERSION_CODES.S) -public final class MediaFeature { - /** - * Defines tye type of HDR(high dynamic range) video. - */ - public static final class HdrType { - private HdrType() { - } - - /** - * HDR type for dolby-vision. - */ - public static final String DOLBY_VISION = "android.media.feature.hdr.dolby_vision"; - /** - * HDR type for hdr10. - */ - public static final String HDR10 = "android.media.feature.hdr.hdr10"; - /** - * HDR type for hdr10+. - */ - public static final String HDR10_PLUS = "android.media.feature.hdr.hdr10_plus"; - /** - * HDR type for hlg. - */ - public static final String HLG = "android.media.feature.hdr.hlg"; - } - - /** @hide */ - @StringDef({ - HdrType.DOLBY_VISION, - HdrType.HDR10, - HdrType.HDR10_PLUS, - HdrType.HLG, - }) - @Retention(RetentionPolicy.SOURCE) - public @interface MediaHdrType { - } -} diff --git a/apex/media/framework/java/android/media/MediaFrameworkInitializer.java b/apex/media/framework/java/android/media/MediaFrameworkInitializer.java deleted file mode 100644 index 75a56b7231d9..000000000000 --- a/apex/media/framework/java/android/media/MediaFrameworkInitializer.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2020 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.media; - -import android.annotation.NonNull; -import android.annotation.SystemApi; -import android.annotation.SystemApi.Client; -import android.app.SystemServiceRegistry; -import android.content.Context; -import android.os.Build; - -import com.android.modules.annotation.MinSdk; -import com.android.modules.utils.build.SdkLevel; - -/** - * Class for performing registration for all media services on com.android.media apex. - * - * @hide - */ -@MinSdk(Build.VERSION_CODES.S) -@SystemApi(client = Client.MODULE_LIBRARIES) -public class MediaFrameworkInitializer { - private MediaFrameworkInitializer() { - } - - private static volatile MediaServiceManager sMediaServiceManager; - - /** - * Sets an instance of {@link MediaServiceManager} that allows - * the media mainline module to register/obtain media binder services. This is called - * by the platform during the system initialization. - * - * @param mediaServiceManager instance of {@link MediaServiceManager} that allows - * the media mainline module to register/obtain media binder services. - */ - public static void setMediaServiceManager( - @NonNull MediaServiceManager mediaServiceManager) { - if (sMediaServiceManager != null) { - throw new IllegalStateException("setMediaServiceManager called twice!"); - } - - if (mediaServiceManager == null) { - throw new NullPointerException("mediaServiceManager is null!"); - } - - sMediaServiceManager = mediaServiceManager; - } - - /** @hide */ - public static MediaServiceManager getMediaServiceManager() { - return sMediaServiceManager; - } - - /** - * Called by {@link SystemServiceRegistry}'s static initializer and registers all media - * services to {@link Context}, so that {@link Context#getSystemService} can return them. - * - * @throws IllegalStateException if this is called from anywhere besides - * {@link SystemServiceRegistry} - */ - public static void registerServiceWrappers() { - SystemServiceRegistry.registerContextAwareService( - Context.MEDIA_TRANSCODING_SERVICE, - MediaTranscodingManager.class, - context -> new MediaTranscodingManager(context) - ); - if (SdkLevel.isAtLeastS()) { - SystemServiceRegistry.registerContextAwareService( - Context.MEDIA_COMMUNICATION_SERVICE, - MediaCommunicationManager.class, - context -> new MediaCommunicationManager(context) - ); - } - } -} diff --git a/apex/media/framework/java/android/media/MediaParceledListSlice.java b/apex/media/framework/java/android/media/MediaParceledListSlice.java deleted file mode 100644 index 47ac193231a0..000000000000 --- a/apex/media/framework/java/android/media/MediaParceledListSlice.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright 2020 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.media; - -import android.annotation.NonNull; -import android.annotation.SystemApi; -import android.os.Parcel; -import android.os.Parcelable; - -import java.util.Collections; -import java.util.List; - -/** - * This is a copied version of MediaParceledListSlice in framework with hidden API usages removed, - * and also with some lint error fixed. - * - * Transfer a large list of Parcelable objects across an IPC. Splits into - * multiple transactions if needed. - * - * TODO: Remove this from @SystemApi once all the MediaSession related classes are moved - * to apex (or ParceledListSlice moved to apex). This class is temporaily added to system API - * for moving classes step by step. - * - * @param <T> The type of the elements in the list. - * @see BaseMediaParceledListSlice - * @deprecated This is temporary marked as @SystemApi. Should be removed from the API surface. - * @hide - */ -@Deprecated -@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) -public final class MediaParceledListSlice<T extends Parcelable> - extends BaseMediaParceledListSlice<T> { - public MediaParceledListSlice(@NonNull List<T> list) { - super(list); - } - - private MediaParceledListSlice(Parcel in, ClassLoader loader) { - super(in, loader); - } - - @NonNull - public static <T extends Parcelable> MediaParceledListSlice<T> emptyList() { - return new MediaParceledListSlice<T>(Collections.<T> emptyList()); - } - - @Override - public int describeContents() { - int contents = 0; - final List<T> list = getList(); - for (int i=0; i<list.size(); i++) { - contents |= list.get(i).describeContents(); - } - return contents; - } - - @Override - void writeElement(T parcelable, Parcel dest, int callFlags) { - parcelable.writeToParcel(dest, callFlags); - } - - @Override - void writeParcelableCreator(T parcelable, Parcel dest) { - dest.writeParcelableCreator((Parcelable) parcelable); - } - - @Override - Parcelable.Creator<?> readParcelableCreator(Parcel from, ClassLoader loader) { - return from.readParcelableCreator(loader); - } - - @NonNull - @SuppressWarnings("unchecked") - public static final Parcelable.ClassLoaderCreator<MediaParceledListSlice> CREATOR = - new Parcelable.ClassLoaderCreator<MediaParceledListSlice>() { - public MediaParceledListSlice createFromParcel(Parcel in) { - return new MediaParceledListSlice(in, null); - } - - @Override - public MediaParceledListSlice createFromParcel(Parcel in, ClassLoader loader) { - return new MediaParceledListSlice(in, loader); - } - - @Override - public MediaParceledListSlice[] newArray(int size) { - return new MediaParceledListSlice[size]; - } - }; -} diff --git a/apex/media/framework/java/android/media/MediaParser.java b/apex/media/framework/java/android/media/MediaParser.java deleted file mode 100644 index 8cc3bc08dfb5..000000000000 --- a/apex/media/framework/java/android/media/MediaParser.java +++ /dev/null @@ -1,2292 +0,0 @@ -/* - * Copyright (C) 2019 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.media; - -import android.annotation.CheckResult; -import android.annotation.IntDef; -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.StringDef; -import android.media.MediaCodec.CryptoInfo; -import android.media.metrics.LogSessionId; -import android.os.Build; -import android.text.TextUtils; -import android.util.Log; -import android.util.Pair; -import android.util.SparseArray; - -import androidx.annotation.RequiresApi; - -import com.android.modules.utils.build.SdkLevel; - -import com.google.android.exoplayer2.C; -import com.google.android.exoplayer2.Format; -import com.google.android.exoplayer2.ParserException; -import com.google.android.exoplayer2.drm.DrmInitData.SchemeData; -import com.google.android.exoplayer2.extractor.ChunkIndex; -import com.google.android.exoplayer2.extractor.DefaultExtractorInput; -import com.google.android.exoplayer2.extractor.Extractor; -import com.google.android.exoplayer2.extractor.ExtractorInput; -import com.google.android.exoplayer2.extractor.ExtractorOutput; -import com.google.android.exoplayer2.extractor.PositionHolder; -import com.google.android.exoplayer2.extractor.SeekMap.SeekPoints; -import com.google.android.exoplayer2.extractor.TrackOutput; -import com.google.android.exoplayer2.extractor.amr.AmrExtractor; -import com.google.android.exoplayer2.extractor.flac.FlacExtractor; -import com.google.android.exoplayer2.extractor.flv.FlvExtractor; -import com.google.android.exoplayer2.extractor.mkv.MatroskaExtractor; -import com.google.android.exoplayer2.extractor.mp3.Mp3Extractor; -import com.google.android.exoplayer2.extractor.mp4.FragmentedMp4Extractor; -import com.google.android.exoplayer2.extractor.mp4.Mp4Extractor; -import com.google.android.exoplayer2.extractor.ogg.OggExtractor; -import com.google.android.exoplayer2.extractor.ts.Ac3Extractor; -import com.google.android.exoplayer2.extractor.ts.Ac4Extractor; -import com.google.android.exoplayer2.extractor.ts.AdtsExtractor; -import com.google.android.exoplayer2.extractor.ts.DefaultTsPayloadReaderFactory; -import com.google.android.exoplayer2.extractor.ts.PsExtractor; -import com.google.android.exoplayer2.extractor.ts.TsExtractor; -import com.google.android.exoplayer2.extractor.wav.WavExtractor; -import com.google.android.exoplayer2.upstream.DataReader; -import com.google.android.exoplayer2.util.ParsableByteArray; -import com.google.android.exoplayer2.util.TimestampAdjuster; -import com.google.android.exoplayer2.util.Util; -import com.google.android.exoplayer2.video.ColorInfo; - -import java.io.EOFException; -import java.io.IOException; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.UUID; -import java.util.concurrent.ThreadLocalRandom; -import java.util.function.Function; - -/** - * Parses media container formats and extracts contained media samples and metadata. - * - * <p>This class provides access to a battery of low-level media container parsers. Each instance of - * this class is associated to a specific media parser implementation which is suitable for - * extraction from a specific media container format. The media parser implementation assignment - * depends on the factory method (see {@link #create} and {@link #createByName}) used to create the - * instance. - * - * <p>Users must implement the following to use this class. - * - * <ul> - * <li>{@link InputReader}: Provides the media container's bytes to parse. - * <li>{@link OutputConsumer}: Provides a sink for all extracted data and metadata. - * </ul> - * - * <p>The following code snippet includes a usage example: - * - * <pre> - * MyOutputConsumer myOutputConsumer = new MyOutputConsumer(); - * MyInputReader myInputReader = new MyInputReader("www.example.com"); - * MediaParser mediaParser = MediaParser.create(myOutputConsumer); - * - * while (mediaParser.advance(myInputReader)) {} - * - * mediaParser.release(); - * mediaParser = null; - * </pre> - * - * <p>The following code snippet provides a rudimentary {@link OutputConsumer} sample implementation - * which extracts and publishes all video samples: - * - * <pre> - * class VideoOutputConsumer implements MediaParser.OutputConsumer { - * - * private byte[] sampleDataBuffer = new byte[4096]; - * private byte[] discardedDataBuffer = new byte[4096]; - * private int videoTrackIndex = -1; - * private int bytesWrittenCount = 0; - * - * @Override - * public void onSeekMapFound(int i, @NonNull MediaFormat mediaFormat) { - * // Do nothing. - * } - * - * @Override - * public void onTrackDataFound(int i, @NonNull TrackData trackData) { - * MediaFormat mediaFormat = trackData.mediaFormat; - * if (videoTrackIndex == -1 && - * mediaFormat - * .getString(MediaFormat.KEY_MIME, /* defaultValue= */ "") - * .startsWith("video/")) { - * videoTrackIndex = i; - * } - * } - * - * @Override - * public void onSampleDataFound(int trackIndex, @NonNull InputReader inputReader) - * throws IOException { - * int numberOfBytesToRead = (int) inputReader.getLength(); - * if (videoTrackIndex != trackIndex) { - * // Discard contents. - * inputReader.read( - * discardedDataBuffer, - * /* offset= */ 0, - * Math.min(discardDataBuffer.length, numberOfBytesToRead)); - * } else { - * ensureSpaceInBuffer(numberOfBytesToRead); - * int bytesRead = inputReader.read( - * sampleDataBuffer, bytesWrittenCount, numberOfBytesToRead); - * bytesWrittenCount += bytesRead; - * } - * } - * - * @Override - * public void onSampleCompleted( - * int trackIndex, - * long timeMicros, - * int flags, - * int size, - * int offset, - * @Nullable CryptoInfo cryptoData) { - * if (videoTrackIndex != trackIndex) { - * return; // It's not the video track. Ignore. - * } - * byte[] sampleData = new byte[size]; - * int sampleStartOffset = bytesWrittenCount - size - offset; - * System.arraycopy( - * sampleDataBuffer, - * sampleStartOffset, - * sampleData, - * /* destPos= */ 0, - * size); - * // Place trailing bytes at the start of the buffer. - * System.arraycopy( - * sampleDataBuffer, - * bytesWrittenCount - offset, - * sampleDataBuffer, - * /* destPos= */ 0, - * /* size= */ offset); - * bytesWrittenCount = bytesWrittenCount - offset; - * publishSample(sampleData, timeMicros, flags); - * } - * - * private void ensureSpaceInBuffer(int numberOfBytesToRead) { - * int requiredLength = bytesWrittenCount + numberOfBytesToRead; - * if (requiredLength > sampleDataBuffer.length) { - * sampleDataBuffer = Arrays.copyOf(sampleDataBuffer, requiredLength); - * } - * } - * - * } - * - * </pre> - */ -public final class MediaParser { - - /** - * Maps seek positions to {@link SeekPoint SeekPoints} in the stream. - * - * <p>A {@link SeekPoint} is a position in the stream from which a player may successfully start - * playing media samples. - */ - public static final class SeekMap { - - /** Returned by {@link #getDurationMicros()} when the duration is unknown. */ - public static final int UNKNOWN_DURATION = Integer.MIN_VALUE; - - /** - * For each {@link #getSeekPoints} call, returns a single {@link SeekPoint} whose {@link - * SeekPoint#timeMicros} matches the requested timestamp, and whose {@link - * SeekPoint#position} is 0. - * - * @hide - */ - public static final SeekMap DUMMY = new SeekMap(new DummyExoPlayerSeekMap()); - - private final com.google.android.exoplayer2.extractor.SeekMap mExoPlayerSeekMap; - - private SeekMap(com.google.android.exoplayer2.extractor.SeekMap exoplayerSeekMap) { - mExoPlayerSeekMap = exoplayerSeekMap; - } - - /** Returns whether seeking is supported. */ - public boolean isSeekable() { - return mExoPlayerSeekMap.isSeekable(); - } - - /** - * Returns the duration of the stream in microseconds or {@link #UNKNOWN_DURATION} if the - * duration is unknown. - */ - public long getDurationMicros() { - long durationUs = mExoPlayerSeekMap.getDurationUs(); - return durationUs != C.TIME_UNSET ? durationUs : UNKNOWN_DURATION; - } - - /** - * Obtains {@link SeekPoint SeekPoints} for the specified seek time in microseconds. - * - * <p>{@code getSeekPoints(timeMicros).first} contains the latest seek point for samples - * with timestamp equal to or smaller than {@code timeMicros}. - * - * <p>{@code getSeekPoints(timeMicros).second} contains the earliest seek point for samples - * with timestamp equal to or greater than {@code timeMicros}. If a seek point exists for - * {@code timeMicros}, the returned pair will contain the same {@link SeekPoint} twice. - * - * @param timeMicros A seek time in microseconds. - * @return The corresponding {@link SeekPoint SeekPoints}. - */ - @NonNull - public Pair<SeekPoint, SeekPoint> getSeekPoints(long timeMicros) { - SeekPoints seekPoints = mExoPlayerSeekMap.getSeekPoints(timeMicros); - return new Pair<>(toSeekPoint(seekPoints.first), toSeekPoint(seekPoints.second)); - } - } - - /** Holds information associated with a track. */ - public static final class TrackData { - - /** Holds {@link MediaFormat} information for the track. */ - @NonNull public final MediaFormat mediaFormat; - - /** - * Holds {@link DrmInitData} necessary to acquire keys associated with the track, or null if - * the track has no encryption data. - */ - @Nullable public final DrmInitData drmInitData; - - private TrackData(MediaFormat mediaFormat, DrmInitData drmInitData) { - this.mediaFormat = mediaFormat; - this.drmInitData = drmInitData; - } - } - - /** Defines a seek point in a media stream. */ - public static final class SeekPoint { - - /** A {@link SeekPoint} whose time and byte offset are both set to 0. */ - @NonNull public static final SeekPoint START = new SeekPoint(0, 0); - - /** The time of the seek point, in microseconds. */ - public final long timeMicros; - - /** The byte offset of the seek point. */ - public final long position; - - /** - * @param timeMicros The time of the seek point, in microseconds. - * @param position The byte offset of the seek point. - */ - private SeekPoint(long timeMicros, long position) { - this.timeMicros = timeMicros; - this.position = position; - } - - @Override - @NonNull - public String toString() { - return "[timeMicros=" + timeMicros + ", position=" + position + "]"; - } - - @Override - public boolean equals(@Nullable Object obj) { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - SeekPoint other = (SeekPoint) obj; - return timeMicros == other.timeMicros && position == other.position; - } - - @Override - public int hashCode() { - int result = (int) timeMicros; - result = 31 * result + (int) position; - return result; - } - } - - /** Provides input data to {@link MediaParser}. */ - public interface InputReader { - - /** - * Reads up to {@code readLength} bytes of data and stores them into {@code buffer}, - * starting at index {@code offset}. - * - * <p>This method blocks until at least one byte is read, the end of input is detected, or - * an exception is thrown. The read position advances to the first unread byte. - * - * @param buffer The buffer into which the read data should be stored. - * @param offset The start offset into {@code buffer} at which data should be written. - * @param readLength The maximum number of bytes to read. - * @return The non-zero number of bytes read, or -1 if no data is available because the end - * of the input has been reached. - * @throws java.io.IOException If an error occurs reading from the source. - */ - int read(@NonNull byte[] buffer, int offset, int readLength) throws IOException; - - /** Returns the current read position (byte offset) in the stream. */ - long getPosition(); - - /** Returns the length of the input in bytes, or -1 if the length is unknown. */ - long getLength(); - } - - /** {@link InputReader} that allows setting the read position. */ - public interface SeekableInputReader extends InputReader { - - /** - * Sets the read position at the given {@code position}. - * - * <p>{@link #advance} will immediately return after calling this method. - * - * @param position The position to seek to, in bytes. - */ - void seekToPosition(long position); - } - - /** Receives extracted media sample data and metadata from {@link MediaParser}. */ - public interface OutputConsumer { - - /** - * Called when a {@link SeekMap} has been extracted from the stream. - * - * <p>This method is called at least once before any samples are {@link #onSampleCompleted - * complete}. May be called multiple times after that in order to add {@link SeekPoint - * SeekPoints}. - * - * @param seekMap The extracted {@link SeekMap}. - */ - void onSeekMapFound(@NonNull SeekMap seekMap); - - /** - * Called when the number of tracks is found. - * - * @param numberOfTracks The number of tracks in the stream. - */ - void onTrackCountFound(int numberOfTracks); - - /** - * Called when new {@link TrackData} is found in the stream. - * - * @param trackIndex The index of the track for which the {@link TrackData} was extracted. - * @param trackData The extracted {@link TrackData}. - */ - void onTrackDataFound(int trackIndex, @NonNull TrackData trackData); - - /** - * Called when sample data is found in the stream. - * - * <p>If the invocation of this method returns before the entire {@code inputReader} {@link - * InputReader#getLength() length} is consumed, the method will be called again for the - * implementer to read the remaining data. Implementers should surface any thrown {@link - * IOException} caused by reading from {@code input}. - * - * @param trackIndex The index of the track to which the sample data corresponds. - * @param inputReader The {@link InputReader} from which to read the data. - * @throws IOException If an exception occurs while reading from {@code inputReader}. - */ - void onSampleDataFound(int trackIndex, @NonNull InputReader inputReader) throws IOException; - - /** - * Called once all the data of a sample has been passed to {@link #onSampleDataFound}. - * - * <p>Includes sample metadata, like presentation timestamp and flags. - * - * @param trackIndex The index of the track to which the sample corresponds. - * @param timeMicros The media timestamp associated with the sample, in microseconds. - * @param flags Flags associated with the sample. See the {@code SAMPLE_FLAG_*} constants. - * @param size The size of the sample data, in bytes. - * @param offset The number of bytes that have been consumed by {@code - * onSampleDataFound(int, MediaParser.InputReader)} for the specified track, since the - * last byte belonging to the sample whose metadata is being passed. - * @param cryptoInfo Encryption data required to decrypt the sample. May be null for - * unencrypted samples. Implementors should treat any output {@link CryptoInfo} - * instances as immutable. MediaParser will not modify any output {@code cryptoInfos} - * and implementors should not modify them either. - */ - void onSampleCompleted( - int trackIndex, - long timeMicros, - @SampleFlags int flags, - int size, - int offset, - @Nullable CryptoInfo cryptoInfo); - } - - /** - * Thrown if all parser implementations provided to {@link #create} failed to sniff the input - * content. - */ - public static final class UnrecognizedInputFormatException extends IOException { - - /** - * Creates a new instance which signals that the parsers with the given names failed to - * parse the input. - */ - @NonNull - @CheckResult - private static UnrecognizedInputFormatException createForExtractors( - @NonNull String... extractorNames) { - StringBuilder builder = new StringBuilder(); - builder.append("None of the available parsers ( "); - builder.append(extractorNames[0]); - for (int i = 1; i < extractorNames.length; i++) { - builder.append(", "); - builder.append(extractorNames[i]); - } - builder.append(") could read the stream."); - return new UnrecognizedInputFormatException(builder.toString()); - } - - private UnrecognizedInputFormatException(String extractorNames) { - super(extractorNames); - } - } - - /** Thrown when an error occurs while parsing a media stream. */ - public static final class ParsingException extends IOException { - - private ParsingException(ParserException cause) { - super(cause); - } - } - - // Sample flags. - - /** @hide */ - @Retention(RetentionPolicy.SOURCE) - @IntDef( - flag = true, - value = { - SAMPLE_FLAG_KEY_FRAME, - SAMPLE_FLAG_HAS_SUPPLEMENTAL_DATA, - SAMPLE_FLAG_LAST_SAMPLE, - SAMPLE_FLAG_ENCRYPTED, - SAMPLE_FLAG_DECODE_ONLY - }) - public @interface SampleFlags {} - /** Indicates that the sample holds a synchronization sample. */ - public static final int SAMPLE_FLAG_KEY_FRAME = MediaCodec.BUFFER_FLAG_KEY_FRAME; - /** - * Indicates that the sample has supplemental data. - * - * <p>Samples will not have this flag set unless the {@code - * "android.media.mediaparser.includeSupplementalData"} parameter is set to {@code true} via - * {@link #setParameter}. - * - * <p>Samples with supplemental data have the following sample data format: - * - * <ul> - * <li>If the {@code "android.media.mediaparser.inBandCryptoInfo"} parameter is set, all - * encryption information. - * <li>(4 bytes) {@code sample_data_size}: The size of the actual sample data, not including - * supplemental data or encryption information. - * <li>({@code sample_data_size} bytes): The media sample data. - * <li>(remaining bytes) The supplemental data. - * </ul> - */ - public static final int SAMPLE_FLAG_HAS_SUPPLEMENTAL_DATA = 1 << 28; - /** Indicates that the sample is known to contain the last media sample of the stream. */ - public static final int SAMPLE_FLAG_LAST_SAMPLE = 1 << 29; - /** Indicates that the sample is (at least partially) encrypted. */ - public static final int SAMPLE_FLAG_ENCRYPTED = 1 << 30; - /** Indicates that the sample should be decoded but not rendered. */ - public static final int SAMPLE_FLAG_DECODE_ONLY = 1 << 31; - - // Parser implementation names. - - /** @hide */ - @Retention(RetentionPolicy.SOURCE) - @StringDef( - prefix = {"PARSER_NAME_"}, - value = { - PARSER_NAME_UNKNOWN, - PARSER_NAME_MATROSKA, - PARSER_NAME_FMP4, - PARSER_NAME_MP4, - PARSER_NAME_MP3, - PARSER_NAME_ADTS, - PARSER_NAME_AC3, - PARSER_NAME_TS, - PARSER_NAME_FLV, - PARSER_NAME_OGG, - PARSER_NAME_PS, - PARSER_NAME_WAV, - PARSER_NAME_AMR, - PARSER_NAME_AC4, - PARSER_NAME_FLAC - }) - public @interface ParserName {} - - /** Parser name returned by {@link #getParserName()} when no parser has been selected yet. */ - public static final String PARSER_NAME_UNKNOWN = "android.media.mediaparser.UNKNOWN"; - /** - * Parser for the Matroska container format, as defined in the <a - * href="https://matroska.org/technical/specs/">spec</a>. - */ - public static final String PARSER_NAME_MATROSKA = "android.media.mediaparser.MatroskaParser"; - /** - * Parser for fragmented files using the MP4 container format, as defined in ISO/IEC 14496-12. - */ - public static final String PARSER_NAME_FMP4 = "android.media.mediaparser.FragmentedMp4Parser"; - /** - * Parser for non-fragmented files using the MP4 container format, as defined in ISO/IEC - * 14496-12. - */ - public static final String PARSER_NAME_MP4 = "android.media.mediaparser.Mp4Parser"; - /** Parser for the MP3 container format, as defined in ISO/IEC 11172-3. */ - public static final String PARSER_NAME_MP3 = "android.media.mediaparser.Mp3Parser"; - /** Parser for the ADTS container format, as defined in ISO/IEC 13818-7. */ - public static final String PARSER_NAME_ADTS = "android.media.mediaparser.AdtsParser"; - /** - * Parser for the AC-3 container format, as defined in Digital Audio Compression Standard - * (AC-3). - */ - public static final String PARSER_NAME_AC3 = "android.media.mediaparser.Ac3Parser"; - /** Parser for the TS container format, as defined in ISO/IEC 13818-1. */ - public static final String PARSER_NAME_TS = "android.media.mediaparser.TsParser"; - /** - * Parser for the FLV container format, as defined in Adobe Flash Video File Format - * Specification. - */ - public static final String PARSER_NAME_FLV = "android.media.mediaparser.FlvParser"; - /** Parser for the OGG container format, as defined in RFC 3533. */ - public static final String PARSER_NAME_OGG = "android.media.mediaparser.OggParser"; - /** Parser for the PS container format, as defined in ISO/IEC 11172-1. */ - public static final String PARSER_NAME_PS = "android.media.mediaparser.PsParser"; - /** - * Parser for the WAV container format, as defined in Multimedia Programming Interface and Data - * Specifications. - */ - public static final String PARSER_NAME_WAV = "android.media.mediaparser.WavParser"; - /** Parser for the AMR container format, as defined in RFC 4867. */ - public static final String PARSER_NAME_AMR = "android.media.mediaparser.AmrParser"; - /** - * Parser for the AC-4 container format, as defined by Dolby AC-4: Audio delivery for - * Next-Generation Entertainment Services. - */ - public static final String PARSER_NAME_AC4 = "android.media.mediaparser.Ac4Parser"; - /** - * Parser for the FLAC container format, as defined in the <a - * href="https://xiph.org/flac/">spec</a>. - */ - public static final String PARSER_NAME_FLAC = "android.media.mediaparser.FlacParser"; - - // MediaParser parameters. - - /** @hide */ - @Retention(RetentionPolicy.SOURCE) - @StringDef( - prefix = {"PARAMETER_"}, - value = { - PARAMETER_ADTS_ENABLE_CBR_SEEKING, - PARAMETER_AMR_ENABLE_CBR_SEEKING, - PARAMETER_FLAC_DISABLE_ID3, - PARAMETER_MP4_IGNORE_EDIT_LISTS, - PARAMETER_MP4_IGNORE_TFDT_BOX, - PARAMETER_MP4_TREAT_VIDEO_FRAMES_AS_KEYFRAMES, - PARAMETER_MATROSKA_DISABLE_CUES_SEEKING, - PARAMETER_MP3_DISABLE_ID3, - PARAMETER_MP3_ENABLE_CBR_SEEKING, - PARAMETER_MP3_ENABLE_INDEX_SEEKING, - PARAMETER_TS_MODE, - PARAMETER_TS_ALLOW_NON_IDR_AVC_KEYFRAMES, - PARAMETER_TS_IGNORE_AAC_STREAM, - PARAMETER_TS_IGNORE_AVC_STREAM, - PARAMETER_TS_IGNORE_SPLICE_INFO_STREAM, - PARAMETER_TS_DETECT_ACCESS_UNITS, - PARAMETER_TS_ENABLE_HDMV_DTS_AUDIO_STREAMS, - PARAMETER_IN_BAND_CRYPTO_INFO, - PARAMETER_INCLUDE_SUPPLEMENTAL_DATA - }) - public @interface ParameterName {} - - /** - * Sets whether constant bitrate seeking should be enabled for ADTS parsing. {@code boolean} - * expected. Default value is {@code false}. - */ - public static final String PARAMETER_ADTS_ENABLE_CBR_SEEKING = - "android.media.mediaparser.adts.enableCbrSeeking"; - /** - * Sets whether constant bitrate seeking should be enabled for AMR. {@code boolean} expected. - * Default value is {@code false}. - */ - public static final String PARAMETER_AMR_ENABLE_CBR_SEEKING = - "android.media.mediaparser.amr.enableCbrSeeking"; - /** - * Sets whether the ID3 track should be disabled for FLAC. {@code boolean} expected. Default - * value is {@code false}. - */ - public static final String PARAMETER_FLAC_DISABLE_ID3 = - "android.media.mediaparser.flac.disableId3"; - /** - * Sets whether MP4 parsing should ignore edit lists. {@code boolean} expected. Default value is - * {@code false}. - */ - public static final String PARAMETER_MP4_IGNORE_EDIT_LISTS = - "android.media.mediaparser.mp4.ignoreEditLists"; - /** - * Sets whether MP4 parsing should ignore the tfdt box. {@code boolean} expected. Default value - * is {@code false}. - */ - public static final String PARAMETER_MP4_IGNORE_TFDT_BOX = - "android.media.mediaparser.mp4.ignoreTfdtBox"; - /** - * Sets whether MP4 parsing should treat all video frames as key frames. {@code boolean} - * expected. Default value is {@code false}. - */ - public static final String PARAMETER_MP4_TREAT_VIDEO_FRAMES_AS_KEYFRAMES = - "android.media.mediaparser.mp4.treatVideoFramesAsKeyframes"; - /** - * Sets whether Matroska parsing should avoid seeking to the cues element. {@code boolean} - * expected. Default value is {@code false}. - * - * <p>If this flag is enabled and the cues element occurs after the first cluster, then the - * media is treated as unseekable. - */ - public static final String PARAMETER_MATROSKA_DISABLE_CUES_SEEKING = - "android.media.mediaparser.matroska.disableCuesSeeking"; - /** - * Sets whether the ID3 track should be disabled for MP3. {@code boolean} expected. Default - * value is {@code false}. - */ - public static final String PARAMETER_MP3_DISABLE_ID3 = - "android.media.mediaparser.mp3.disableId3"; - /** - * Sets whether constant bitrate seeking should be enabled for MP3. {@code boolean} expected. - * Default value is {@code false}. - */ - public static final String PARAMETER_MP3_ENABLE_CBR_SEEKING = - "android.media.mediaparser.mp3.enableCbrSeeking"; - /** - * Sets whether MP3 parsing should generate a time-to-byte mapping. {@code boolean} expected. - * Default value is {@code false}. - * - * <p>Enabling this flag may require to scan a significant portion of the file to compute a seek - * point. Therefore, it should only be used if: - * - * <ul> - * <li>the file is small, or - * <li>the bitrate is variable (or the type of bitrate is unknown) and the seeking metadata - * provided in the file is not precise enough (or is not present). - * </ul> - */ - public static final String PARAMETER_MP3_ENABLE_INDEX_SEEKING = - "android.media.mediaparser.mp3.enableIndexSeeking"; - /** - * Sets the operation mode for TS parsing. {@code String} expected. Valid values are {@code - * "single_pmt"}, {@code "multi_pmt"}, and {@code "hls"}. Default value is {@code "single_pmt"}. - * - * <p>The operation modes alter the way TS behaves so that it can handle certain kinds of - * commonly-occurring malformed media. - * - * <ul> - * <li>{@code "single_pmt"}: Only the first found PMT is parsed. Others are ignored, even if - * more PMTs are declared in the PAT. - * <li>{@code "multi_pmt"}: Behave as described in ISO/IEC 13818-1. - * <li>{@code "hls"}: Enable {@code "single_pmt"} mode, and ignore continuity counters. - * </ul> - */ - public static final String PARAMETER_TS_MODE = "android.media.mediaparser.ts.mode"; - /** - * Sets whether TS should treat samples consisting of non-IDR I slices as synchronization - * samples (key-frames). {@code boolean} expected. Default value is {@code false}. - */ - public static final String PARAMETER_TS_ALLOW_NON_IDR_AVC_KEYFRAMES = - "android.media.mediaparser.ts.allowNonIdrAvcKeyframes"; - /** - * Sets whether TS parsing should ignore AAC elementary streams. {@code boolean} expected. - * Default value is {@code false}. - */ - public static final String PARAMETER_TS_IGNORE_AAC_STREAM = - "android.media.mediaparser.ts.ignoreAacStream"; - /** - * Sets whether TS parsing should ignore AVC elementary streams. {@code boolean} expected. - * Default value is {@code false}. - */ - public static final String PARAMETER_TS_IGNORE_AVC_STREAM = - "android.media.mediaparser.ts.ignoreAvcStream"; - /** - * Sets whether TS parsing should ignore splice information streams. {@code boolean} expected. - * Default value is {@code false}. - */ - public static final String PARAMETER_TS_IGNORE_SPLICE_INFO_STREAM = - "android.media.mediaparser.ts.ignoreSpliceInfoStream"; - /** - * Sets whether TS parsing should split AVC stream into access units based on slice headers. - * {@code boolean} expected. Default value is {@code false}. - * - * <p>This flag should be left disabled if the stream contains access units delimiters in order - * to avoid unnecessary computational costs. - */ - public static final String PARAMETER_TS_DETECT_ACCESS_UNITS = - "android.media.mediaparser.ts.ignoreDetectAccessUnits"; - /** - * Sets whether TS parsing should handle HDMV DTS audio streams. {@code boolean} expected. - * Default value is {@code false}. - * - * <p>Enabling this flag will disable the detection of SCTE subtitles. - */ - public static final String PARAMETER_TS_ENABLE_HDMV_DTS_AUDIO_STREAMS = - "android.media.mediaparser.ts.enableHdmvDtsAudioStreams"; - /** - * Sets whether encryption data should be sent in-band with the sample data, as per {@link - * OutputConsumer#onSampleDataFound}. {@code boolean} expected. Default value is {@code false}. - * - * <p>If this parameter is set, encrypted samples' data will be prefixed with the encryption - * information bytes. The format for in-band encryption information is: - * - * <ul> - * <li>(1 byte) {@code encryption_signal_byte}: Most significant bit signals whether the - * encryption data contains subsample encryption data. The remaining bits contain {@code - * initialization_vector_size}. - * <li>({@code initialization_vector_size} bytes) Initialization vector. - * <li>If subsample encryption data is present, as per {@code encryption_signal_byte}, the - * encryption data also contains: - * <ul> - * <li>(2 bytes) {@code subsample_encryption_data_length}. - * <li>({@code subsample_encryption_data_length * 6} bytes) Subsample encryption data - * (repeated {@code subsample_encryption_data_length} times): - * <ul> - * <li>(2 bytes) Size of a clear section in sample. - * <li>(4 bytes) Size of an encryption section in sample. - * </ul> - * </ul> - * </ul> - * - * @hide - */ - public static final String PARAMETER_IN_BAND_CRYPTO_INFO = - "android.media.mediaparser.inBandCryptoInfo"; - /** - * Sets whether supplemental data should be included as part of the sample data. {@code boolean} - * expected. Default value is {@code false}. See {@link #SAMPLE_FLAG_HAS_SUPPLEMENTAL_DATA} for - * information about the sample data format. - * - * @hide - */ - public static final String PARAMETER_INCLUDE_SUPPLEMENTAL_DATA = - "android.media.mediaparser.includeSupplementalData"; - /** - * Sets whether sample timestamps may start from non-zero offsets. {@code boolean} expected. - * Default value is {@code false}. - * - * <p>When set to true, sample timestamps will not be offset to start from zero, and the media - * provided timestamps will be used instead. For example, transport stream sample timestamps - * will not be converted to a zero-based timebase. - * - * @hide - */ - public static final String PARAMETER_IGNORE_TIMESTAMP_OFFSET = - "android.media.mediaparser.ignoreTimestampOffset"; - /** - * Sets whether each track type should be eagerly exposed. {@code boolean} expected. Default - * value is {@code false}. - * - * <p>When set to true, each track type will be eagerly exposed through a call to {@link - * OutputConsumer#onTrackDataFound} containing a single-value {@link MediaFormat}. The key for - * the track type is {@code "track-type-string"}, and the possible values are {@code "video"}, - * {@code "audio"}, {@code "text"}, {@code "metadata"}, and {@code "unknown"}. - * - * @hide - */ - public static final String PARAMETER_EAGERLY_EXPOSE_TRACKTYPE = - "android.media.mediaparser.eagerlyExposeTrackType"; - /** - * Sets whether a dummy {@link SeekMap} should be exposed before starting extraction. {@code - * boolean} expected. Default value is {@code false}. - * - * <p>For each {@link SeekMap#getSeekPoints} call, the dummy {@link SeekMap} returns a single - * {@link SeekPoint} whose {@link SeekPoint#timeMicros} matches the requested timestamp, and - * whose {@link SeekPoint#position} is 0. - * - * @hide - */ - public static final String PARAMETER_EXPOSE_DUMMY_SEEKMAP = - "android.media.mediaparser.exposeDummySeekMap"; - - /** - * Sets whether chunk indices available in the extracted media should be exposed as {@link - * MediaFormat MediaFormats}. {@code boolean} expected. Default value is {@link false}. - * - * <p>When set to true, any information about media segmentation will be exposed as a {@link - * MediaFormat} (with track index 0) containing four {@link ByteBuffer} elements under the - * following keys: - * - * <ul> - * <li>"chunk-index-int-sizes": Contains {@code ints} representing the sizes in bytes of each - * of the media segments. - * <li>"chunk-index-long-offsets": Contains {@code longs} representing the byte offsets of - * each segment in the stream. - * <li>"chunk-index-long-us-durations": Contains {@code longs} representing the media duration - * of each segment, in microseconds. - * <li>"chunk-index-long-us-times": Contains {@code longs} representing the start time of each - * segment, in microseconds. - * </ul> - * - * @hide - */ - public static final String PARAMETER_EXPOSE_CHUNK_INDEX_AS_MEDIA_FORMAT = - "android.media.mediaParser.exposeChunkIndexAsMediaFormat"; - /** - * Sets a list of closed-caption {@link MediaFormat MediaFormats} that should be exposed as part - * of the extracted media. {@code List<MediaFormat>} expected. Default value is an empty list. - * - * <p>Expected keys in the {@link MediaFormat} are: - * - * <ul> - * <p>{@link MediaFormat#KEY_MIME}: Determine the type of captions (for example, - * application/cea-608). Mandatory. - * <p>{@link MediaFormat#KEY_CAPTION_SERVICE_NUMBER}: Determine the channel on which the - * captions are transmitted. Optional. - * </ul> - * - * @hide - */ - public static final String PARAMETER_EXPOSE_CAPTION_FORMATS = - "android.media.mediaParser.exposeCaptionFormats"; - /** - * Sets whether the value associated with {@link #PARAMETER_EXPOSE_CAPTION_FORMATS} should - * override any in-band caption service declarations. {@code boolean} expected. Default value is - * {@link false}. - * - * <p>When {@code false}, any present in-band caption services information will override the - * values associated with {@link #PARAMETER_EXPOSE_CAPTION_FORMATS}. - * - * @hide - */ - public static final String PARAMETER_OVERRIDE_IN_BAND_CAPTION_DECLARATIONS = - "android.media.mediaParser.overrideInBandCaptionDeclarations"; - /** - * Sets whether a track for EMSG events should be exposed in case of parsing a container that - * supports them. {@code boolean} expected. Default value is {@link false}. - * - * @hide - */ - public static final String PARAMETER_EXPOSE_EMSG_TRACK = - "android.media.mediaParser.exposeEmsgTrack"; - - // Private constants. - - private static final String TAG = "MediaParser"; - private static final String JNI_LIBRARY_NAME = "mediaparser-jni"; - private static final Map<String, ExtractorFactory> EXTRACTOR_FACTORIES_BY_NAME; - private static final Map<String, Class> EXPECTED_TYPE_BY_PARAMETER_NAME; - private static final String TS_MODE_SINGLE_PMT = "single_pmt"; - private static final String TS_MODE_MULTI_PMT = "multi_pmt"; - private static final String TS_MODE_HLS = "hls"; - private static final int BYTES_PER_SUBSAMPLE_ENCRYPTION_ENTRY = 6; - private static final byte[] EMPTY_BYTE_ARRAY = new byte[0]; - private static final String MEDIAMETRICS_ELEMENT_SEPARATOR = "|"; - private static final int MEDIAMETRICS_MAX_STRING_SIZE = 200; - private static final int MEDIAMETRICS_PARAMETER_LIST_MAX_LENGTH; - /** - * Intentional error introduced to reported metrics to prevent identification of the parsed - * media. Note: Increasing this value may cause older hostside CTS tests to fail. - */ - private static final float MEDIAMETRICS_DITHER = .02f; - - @IntDef( - value = { - STATE_READING_SIGNAL_BYTE, - STATE_READING_INIT_VECTOR, - STATE_READING_SUBSAMPLE_ENCRYPTION_SIZE, - STATE_READING_SUBSAMPLE_ENCRYPTION_DATA - }) - private @interface EncryptionDataReadState {} - - private static final int STATE_READING_SIGNAL_BYTE = 0; - private static final int STATE_READING_INIT_VECTOR = 1; - private static final int STATE_READING_SUBSAMPLE_ENCRYPTION_SIZE = 2; - private static final int STATE_READING_SUBSAMPLE_ENCRYPTION_DATA = 3; - - // Instance creation methods. - - /** - * Creates an instance backed by the parser with the given {@code name}. The returned instance - * will attempt parsing without sniffing the content. - * - * @param name The name of the parser that will be associated with the created instance. - * @param outputConsumer The {@link OutputConsumer} to which track data and samples are pushed. - * @return A new instance. - * @throws IllegalArgumentException If an invalid name is provided. - */ - @NonNull - public static MediaParser createByName( - @NonNull @ParserName String name, @NonNull OutputConsumer outputConsumer) { - String[] nameAsArray = new String[] {name}; - assertValidNames(nameAsArray); - return new MediaParser(outputConsumer, /* createdByName= */ true, name); - } - - /** - * Creates an instance whose backing parser will be selected by sniffing the content during the - * first {@link #advance} call. Parser implementations will sniff the content in order of - * appearance in {@code parserNames}. - * - * @param outputConsumer The {@link OutputConsumer} to which extracted data is output. - * @param parserNames The names of the parsers to sniff the content with. If empty, a default - * array of names is used. - * @return A new instance. - */ - @NonNull - public static MediaParser create( - @NonNull OutputConsumer outputConsumer, @NonNull @ParserName String... parserNames) { - assertValidNames(parserNames); - if (parserNames.length == 0) { - parserNames = EXTRACTOR_FACTORIES_BY_NAME.keySet().toArray(new String[0]); - } - return new MediaParser(outputConsumer, /* createdByName= */ false, parserNames); - } - - // Misc static methods. - - /** - * Returns an immutable list with the names of the parsers that are suitable for container - * formats with the given {@link MediaFormat}. - * - * <p>A parser supports a {@link MediaFormat} if the mime type associated with {@link - * MediaFormat#KEY_MIME} corresponds to the supported container format. - * - * @param mediaFormat The {@link MediaFormat} to check support for. - * @return The parser names that support the given {@code mediaFormat}, or the list of all - * parsers available if no container specific format information is provided. - */ - @NonNull - @ParserName - public static List<String> getParserNames(@NonNull MediaFormat mediaFormat) { - String mimeType = mediaFormat.getString(MediaFormat.KEY_MIME); - mimeType = mimeType == null ? null : Util.toLowerInvariant(mimeType.trim()); - if (TextUtils.isEmpty(mimeType)) { - // No MIME type provided. Return all. - return Collections.unmodifiableList( - new ArrayList<>(EXTRACTOR_FACTORIES_BY_NAME.keySet())); - } - ArrayList<String> result = new ArrayList<>(); - switch (mimeType) { - case "video/x-matroska": - case "audio/x-matroska": - case "video/x-webm": - case "audio/x-webm": - result.add(PARSER_NAME_MATROSKA); - break; - case "video/mp4": - case "audio/mp4": - case "application/mp4": - result.add(PARSER_NAME_MP4); - result.add(PARSER_NAME_FMP4); - break; - case "audio/mpeg": - result.add(PARSER_NAME_MP3); - break; - case "audio/aac": - result.add(PARSER_NAME_ADTS); - break; - case "audio/ac3": - result.add(PARSER_NAME_AC3); - break; - case "video/mp2t": - case "audio/mp2t": - result.add(PARSER_NAME_TS); - break; - case "video/x-flv": - result.add(PARSER_NAME_FLV); - break; - case "video/ogg": - case "audio/ogg": - case "application/ogg": - result.add(PARSER_NAME_OGG); - break; - case "video/mp2p": - case "video/mp1s": - result.add(PARSER_NAME_PS); - break; - case "audio/vnd.wave": - case "audio/wav": - case "audio/wave": - case "audio/x-wav": - result.add(PARSER_NAME_WAV); - break; - case "audio/amr": - result.add(PARSER_NAME_AMR); - break; - case "audio/ac4": - result.add(PARSER_NAME_AC4); - break; - case "audio/flac": - case "audio/x-flac": - result.add(PARSER_NAME_FLAC); - break; - default: - // No parsers support the given mime type. Do nothing. - break; - } - return Collections.unmodifiableList(result); - } - - // Private fields. - - private final Map<String, Object> mParserParameters; - private final OutputConsumer mOutputConsumer; - private final String[] mParserNamesPool; - private final PositionHolder mPositionHolder; - private final InputReadingDataReader mExoDataReader; - private final DataReaderAdapter mScratchDataReaderAdapter; - private final ParsableByteArrayAdapter mScratchParsableByteArrayAdapter; - @Nullable private final Constructor<DrmInitData.SchemeInitData> mSchemeInitDataConstructor; - private final ArrayList<Format> mMuxedCaptionFormats; - private boolean mInBandCryptoInfo; - private boolean mIncludeSupplementalData; - private boolean mIgnoreTimestampOffset; - private boolean mEagerlyExposeTrackType; - private boolean mExposeDummySeekMap; - private boolean mExposeChunkIndexAsMediaFormat; - private String mParserName; - private Extractor mExtractor; - private ExtractorInput mExtractorInput; - private boolean mPendingExtractorInit; - private long mPendingSeekPosition; - private long mPendingSeekTimeMicros; - private boolean mLoggedSchemeInitDataCreationException; - private boolean mReleased; - - // MediaMetrics fields. - @Nullable private LogSessionId mLogSessionId; - private final boolean mCreatedByName; - private final SparseArray<Format> mTrackFormats; - private String mLastObservedExceptionName; - private long mDurationMillis; - private long mResourceByteCount; - - // Public methods. - - /** - * Sets parser-specific parameters which allow customizing behavior. - * - * <p>Must be called before the first call to {@link #advance}. - * - * @param parameterName The name of the parameter to set. See {@code PARAMETER_*} constants for - * documentation on possible values. - * @param value The value to set for the given {@code parameterName}. See {@code PARAMETER_*} - * constants for documentation on the expected types. - * @return This instance, for convenience. - * @throws IllegalStateException If called after calling {@link #advance} on the same instance. - */ - @NonNull - public MediaParser setParameter( - @NonNull @ParameterName String parameterName, @NonNull Object value) { - if (mExtractor != null) { - throw new IllegalStateException( - "setParameters() must be called before the first advance() call."); - } - Class expectedType = EXPECTED_TYPE_BY_PARAMETER_NAME.get(parameterName); - // Ignore parameter names that are not contained in the map, in case the client is passing - // a parameter that is being added in a future version of this library. - if (expectedType != null && !expectedType.isInstance(value)) { - throw new IllegalArgumentException( - parameterName - + " expects a " - + expectedType.getSimpleName() - + " but a " - + value.getClass().getSimpleName() - + " was passed."); - } - if (PARAMETER_TS_MODE.equals(parameterName) - && !TS_MODE_SINGLE_PMT.equals(value) - && !TS_MODE_HLS.equals(value) - && !TS_MODE_MULTI_PMT.equals(value)) { - throw new IllegalArgumentException(PARAMETER_TS_MODE + " does not accept: " + value); - } - if (PARAMETER_IN_BAND_CRYPTO_INFO.equals(parameterName)) { - mInBandCryptoInfo = (boolean) value; - } - if (PARAMETER_INCLUDE_SUPPLEMENTAL_DATA.equals(parameterName)) { - mIncludeSupplementalData = (boolean) value; - } - if (PARAMETER_IGNORE_TIMESTAMP_OFFSET.equals(parameterName)) { - mIgnoreTimestampOffset = (boolean) value; - } - if (PARAMETER_EAGERLY_EXPOSE_TRACKTYPE.equals(parameterName)) { - mEagerlyExposeTrackType = (boolean) value; - } - if (PARAMETER_EXPOSE_DUMMY_SEEKMAP.equals(parameterName)) { - mExposeDummySeekMap = (boolean) value; - } - if (PARAMETER_EXPOSE_CHUNK_INDEX_AS_MEDIA_FORMAT.equals(parameterName)) { - mExposeChunkIndexAsMediaFormat = (boolean) value; - } - if (PARAMETER_EXPOSE_CAPTION_FORMATS.equals(parameterName)) { - setMuxedCaptionFormats((List<MediaFormat>) value); - } - mParserParameters.put(parameterName, value); - return this; - } - - /** - * Returns whether the given {@code parameterName} is supported by this parser. - * - * @param parameterName The parameter name to check support for. One of the {@code PARAMETER_*} - * constants. - * @return Whether the given {@code parameterName} is supported. - */ - public boolean supportsParameter(@NonNull @ParameterName String parameterName) { - return EXPECTED_TYPE_BY_PARAMETER_NAME.containsKey(parameterName); - } - - /** - * Returns the name of the backing parser implementation. - * - * <p>If this instance was creating using {@link #createByName}, the provided name is returned. - * If this instance was created using {@link #create}, this method will return {@link - * #PARSER_NAME_UNKNOWN} until the first call to {@link #advance}, after which the name of the - * backing parser implementation is returned. - * - * @return The name of the backing parser implementation, or null if the backing parser - * implementation has not yet been selected. - */ - @NonNull - @ParserName - public String getParserName() { - return mParserName; - } - - /** - * Makes progress in the extraction of the input media stream, unless the end of the input has - * been reached. - * - * <p>This method will block until some progress has been made. - * - * <p>If this instance was created using {@link #create}, the first call to this method will - * sniff the content using the selected parser implementations. - * - * @param seekableInputReader The {@link SeekableInputReader} from which to obtain the media - * container data. - * @return Whether there is any data left to extract. Returns false if the end of input has been - * reached. - * @throws IOException If an error occurs while reading from the {@link SeekableInputReader}. - * @throws UnrecognizedInputFormatException If the format cannot be recognized by any of the - * underlying parser implementations. - */ - public boolean advance(@NonNull SeekableInputReader seekableInputReader) throws IOException { - if (mExtractorInput == null) { - // TODO: For efficiency, the same implementation should be used, by providing a - // clearBuffers() method, or similar. - long resourceLength = seekableInputReader.getLength(); - if (mResourceByteCount == 0) { - // For resource byte count metric collection, we only take into account the length - // of the first provided input reader. - mResourceByteCount = resourceLength; - } - mExtractorInput = - new DefaultExtractorInput( - mExoDataReader, seekableInputReader.getPosition(), resourceLength); - } - mExoDataReader.mInputReader = seekableInputReader; - - if (mExtractor == null) { - mPendingExtractorInit = true; - if (!mParserName.equals(PARSER_NAME_UNKNOWN)) { - mExtractor = createExtractor(mParserName); - } else { - for (String parserName : mParserNamesPool) { - Extractor extractor = createExtractor(parserName); - try { - if (extractor.sniff(mExtractorInput)) { - mParserName = parserName; - mExtractor = extractor; - mPendingExtractorInit = true; - break; - } - } catch (EOFException e) { - // Do nothing. - } finally { - mExtractorInput.resetPeekPosition(); - } - } - if (mExtractor == null) { - UnrecognizedInputFormatException exception = - UnrecognizedInputFormatException.createForExtractors(mParserNamesPool); - mLastObservedExceptionName = exception.getClass().getName(); - throw exception; - } - return true; - } - } - - if (mPendingExtractorInit) { - if (mExposeDummySeekMap) { - // We propagate the dummy seek map before initializing the extractor, in case the - // extractor initialization outputs a seek map. - mOutputConsumer.onSeekMapFound(SeekMap.DUMMY); - } - mExtractor.init(new ExtractorOutputAdapter()); - mPendingExtractorInit = false; - // We return after initialization to allow clients use any output information before - // starting actual extraction. - return true; - } - - if (isPendingSeek()) { - mExtractor.seek(mPendingSeekPosition, mPendingSeekTimeMicros); - removePendingSeek(); - } - - mPositionHolder.position = seekableInputReader.getPosition(); - int result; - try { - result = mExtractor.read(mExtractorInput, mPositionHolder); - } catch (Exception e) { - mLastObservedExceptionName = e.getClass().getName(); - if (e instanceof ParserException) { - throw new ParsingException((ParserException) e); - } else { - throw e; - } - } - if (result == Extractor.RESULT_END_OF_INPUT) { - mExtractorInput = null; - return false; - } - if (result == Extractor.RESULT_SEEK) { - mExtractorInput = null; - seekableInputReader.seekToPosition(mPositionHolder.position); - } - return true; - } - - /** - * Seeks within the media container being extracted. - * - * <p>{@link SeekPoint SeekPoints} can be obtained from the {@link SeekMap} passed to {@link - * OutputConsumer#onSeekMapFound(SeekMap)}. - * - * <p>Following a call to this method, the {@link InputReader} passed to the next invocation of - * {@link #advance} must provide data starting from {@link SeekPoint#position} in the stream. - * - * @param seekPoint The {@link SeekPoint} to seek to. - */ - public void seek(@NonNull SeekPoint seekPoint) { - if (mExtractor == null) { - mPendingSeekPosition = seekPoint.position; - mPendingSeekTimeMicros = seekPoint.timeMicros; - } else { - mExtractor.seek(seekPoint.position, seekPoint.timeMicros); - } - } - - /** - * Releases any acquired resources. - * - * <p>After calling this method, this instance becomes unusable and no other methods should be - * invoked. - */ - public void release() { - mExtractorInput = null; - mExtractor = null; - if (mReleased) { - // Nothing to do. - return; - } - mReleased = true; - - String trackMimeTypes = buildMediaMetricsString(format -> format.sampleMimeType); - String trackCodecs = buildMediaMetricsString(format -> format.codecs); - int videoWidth = -1; - int videoHeight = -1; - for (int i = 0; i < mTrackFormats.size(); i++) { - Format format = mTrackFormats.valueAt(i); - if (format.width != Format.NO_VALUE && format.height != Format.NO_VALUE) { - videoWidth = format.width; - videoHeight = format.height; - break; - } - } - - String alteredParameters = - String.join( - MEDIAMETRICS_ELEMENT_SEPARATOR, - mParserParameters.keySet().toArray(new String[0])); - alteredParameters = - alteredParameters.substring( - 0, - Math.min( - alteredParameters.length(), - MEDIAMETRICS_PARAMETER_LIST_MAX_LENGTH)); - - nativeSubmitMetrics( - SdkLevel.isAtLeastS() ? getLogSessionIdStringV31() : "", - mParserName, - mCreatedByName, - String.join(MEDIAMETRICS_ELEMENT_SEPARATOR, mParserNamesPool), - mLastObservedExceptionName, - addDither(mResourceByteCount), - addDither(mDurationMillis), - trackMimeTypes, - trackCodecs, - alteredParameters, - videoWidth, - videoHeight); - } - - @RequiresApi(31) - public void setLogSessionId(@NonNull LogSessionId logSessionId) { - this.mLogSessionId = Objects.requireNonNull(logSessionId); - } - - @RequiresApi(31) - @NonNull - public LogSessionId getLogSessionId() { - return mLogSessionId != null ? mLogSessionId : LogSessionId.LOG_SESSION_ID_NONE; - } - - // Private methods. - - private MediaParser( - OutputConsumer outputConsumer, boolean createdByName, String... parserNamesPool) { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) { - throw new UnsupportedOperationException("Android version must be R or greater."); - } - mParserParameters = new HashMap<>(); - mOutputConsumer = outputConsumer; - mParserNamesPool = parserNamesPool; - mCreatedByName = createdByName; - mParserName = createdByName ? parserNamesPool[0] : PARSER_NAME_UNKNOWN; - mPositionHolder = new PositionHolder(); - mExoDataReader = new InputReadingDataReader(); - removePendingSeek(); - mScratchDataReaderAdapter = new DataReaderAdapter(); - mScratchParsableByteArrayAdapter = new ParsableByteArrayAdapter(); - mSchemeInitDataConstructor = getSchemeInitDataConstructor(); - mMuxedCaptionFormats = new ArrayList<>(); - - // MediaMetrics. - mTrackFormats = new SparseArray<>(); - mLastObservedExceptionName = ""; - mDurationMillis = -1; - } - - private String buildMediaMetricsString(Function<Format, String> formatFieldGetter) { - StringBuilder stringBuilder = new StringBuilder(); - for (int i = 0; i < mTrackFormats.size(); i++) { - if (i > 0) { - stringBuilder.append(MEDIAMETRICS_ELEMENT_SEPARATOR); - } - String fieldValue = formatFieldGetter.apply(mTrackFormats.valueAt(i)); - stringBuilder.append(fieldValue != null ? fieldValue : ""); - } - return stringBuilder.substring( - 0, Math.min(stringBuilder.length(), MEDIAMETRICS_MAX_STRING_SIZE)); - } - - private void setMuxedCaptionFormats(List<MediaFormat> mediaFormats) { - mMuxedCaptionFormats.clear(); - for (MediaFormat mediaFormat : mediaFormats) { - mMuxedCaptionFormats.add(toExoPlayerCaptionFormat(mediaFormat)); - } - } - - private boolean isPendingSeek() { - return mPendingSeekPosition >= 0; - } - - private void removePendingSeek() { - mPendingSeekPosition = -1; - mPendingSeekTimeMicros = -1; - } - - private Extractor createExtractor(String parserName) { - int flags = 0; - TimestampAdjuster timestampAdjuster = null; - if (mIgnoreTimestampOffset) { - timestampAdjuster = new TimestampAdjuster(TimestampAdjuster.DO_NOT_OFFSET); - } - switch (parserName) { - case PARSER_NAME_MATROSKA: - flags = - getBooleanParameter(PARAMETER_MATROSKA_DISABLE_CUES_SEEKING) - ? MatroskaExtractor.FLAG_DISABLE_SEEK_FOR_CUES - : 0; - return new MatroskaExtractor(flags); - case PARSER_NAME_FMP4: - flags |= - getBooleanParameter(PARAMETER_EXPOSE_EMSG_TRACK) - ? FragmentedMp4Extractor.FLAG_ENABLE_EMSG_TRACK - : 0; - flags |= - getBooleanParameter(PARAMETER_MP4_IGNORE_EDIT_LISTS) - ? FragmentedMp4Extractor.FLAG_WORKAROUND_IGNORE_EDIT_LISTS - : 0; - flags |= - getBooleanParameter(PARAMETER_MP4_IGNORE_TFDT_BOX) - ? FragmentedMp4Extractor.FLAG_WORKAROUND_IGNORE_TFDT_BOX - : 0; - flags |= - getBooleanParameter(PARAMETER_MP4_TREAT_VIDEO_FRAMES_AS_KEYFRAMES) - ? FragmentedMp4Extractor - .FLAG_WORKAROUND_EVERY_VIDEO_FRAME_IS_SYNC_FRAME - : 0; - return new FragmentedMp4Extractor( - flags, - timestampAdjuster, - /* sideloadedTrack= */ null, - mMuxedCaptionFormats); - case PARSER_NAME_MP4: - flags |= - getBooleanParameter(PARAMETER_MP4_IGNORE_EDIT_LISTS) - ? Mp4Extractor.FLAG_WORKAROUND_IGNORE_EDIT_LISTS - : 0; - return new Mp4Extractor(flags); - case PARSER_NAME_MP3: - flags |= - getBooleanParameter(PARAMETER_MP3_DISABLE_ID3) - ? Mp3Extractor.FLAG_DISABLE_ID3_METADATA - : 0; - flags |= - getBooleanParameter(PARAMETER_MP3_ENABLE_CBR_SEEKING) - ? Mp3Extractor.FLAG_ENABLE_CONSTANT_BITRATE_SEEKING - : 0; - // TODO: Add index seeking once we update the ExoPlayer version. - return new Mp3Extractor(flags); - case PARSER_NAME_ADTS: - flags |= - getBooleanParameter(PARAMETER_ADTS_ENABLE_CBR_SEEKING) - ? AdtsExtractor.FLAG_ENABLE_CONSTANT_BITRATE_SEEKING - : 0; - return new AdtsExtractor(flags); - case PARSER_NAME_AC3: - return new Ac3Extractor(); - case PARSER_NAME_TS: - flags |= - getBooleanParameter(PARAMETER_TS_ALLOW_NON_IDR_AVC_KEYFRAMES) - ? DefaultTsPayloadReaderFactory.FLAG_ALLOW_NON_IDR_KEYFRAMES - : 0; - flags |= - getBooleanParameter(PARAMETER_TS_DETECT_ACCESS_UNITS) - ? DefaultTsPayloadReaderFactory.FLAG_DETECT_ACCESS_UNITS - : 0; - flags |= - getBooleanParameter(PARAMETER_TS_ENABLE_HDMV_DTS_AUDIO_STREAMS) - ? DefaultTsPayloadReaderFactory.FLAG_ENABLE_HDMV_DTS_AUDIO_STREAMS - : 0; - flags |= - getBooleanParameter(PARAMETER_TS_IGNORE_AAC_STREAM) - ? DefaultTsPayloadReaderFactory.FLAG_IGNORE_AAC_STREAM - : 0; - flags |= - getBooleanParameter(PARAMETER_TS_IGNORE_AVC_STREAM) - ? DefaultTsPayloadReaderFactory.FLAG_IGNORE_H264_STREAM - : 0; - flags |= - getBooleanParameter(PARAMETER_TS_IGNORE_SPLICE_INFO_STREAM) - ? DefaultTsPayloadReaderFactory.FLAG_IGNORE_SPLICE_INFO_STREAM - : 0; - flags |= - getBooleanParameter(PARAMETER_OVERRIDE_IN_BAND_CAPTION_DECLARATIONS) - ? DefaultTsPayloadReaderFactory.FLAG_OVERRIDE_CAPTION_DESCRIPTORS - : 0; - String tsMode = getStringParameter(PARAMETER_TS_MODE, TS_MODE_SINGLE_PMT); - int hlsMode = - TS_MODE_SINGLE_PMT.equals(tsMode) - ? TsExtractor.MODE_SINGLE_PMT - : TS_MODE_HLS.equals(tsMode) - ? TsExtractor.MODE_HLS - : TsExtractor.MODE_MULTI_PMT; - return new TsExtractor( - hlsMode, - timestampAdjuster != null - ? timestampAdjuster - : new TimestampAdjuster(/* firstSampleTimestampUs= */ 0), - new DefaultTsPayloadReaderFactory(flags, mMuxedCaptionFormats)); - case PARSER_NAME_FLV: - return new FlvExtractor(); - case PARSER_NAME_OGG: - return new OggExtractor(); - case PARSER_NAME_PS: - return new PsExtractor(); - case PARSER_NAME_WAV: - return new WavExtractor(); - case PARSER_NAME_AMR: - flags |= - getBooleanParameter(PARAMETER_AMR_ENABLE_CBR_SEEKING) - ? AmrExtractor.FLAG_ENABLE_CONSTANT_BITRATE_SEEKING - : 0; - return new AmrExtractor(flags); - case PARSER_NAME_AC4: - return new Ac4Extractor(); - case PARSER_NAME_FLAC: - flags |= - getBooleanParameter(PARAMETER_FLAC_DISABLE_ID3) - ? FlacExtractor.FLAG_DISABLE_ID3_METADATA - : 0; - return new FlacExtractor(flags); - default: - // Should never happen. - throw new IllegalStateException("Unexpected attempt to create: " + parserName); - } - } - - private boolean getBooleanParameter(String name) { - return (boolean) mParserParameters.getOrDefault(name, false); - } - - private String getStringParameter(String name, String defaultValue) { - return (String) mParserParameters.getOrDefault(name, defaultValue); - } - - @RequiresApi(31) - private String getLogSessionIdStringV31() { - return mLogSessionId != null ? mLogSessionId.getStringId() : ""; - } - - // Private classes. - - private static final class InputReadingDataReader implements DataReader { - - public InputReader mInputReader; - - @Override - public int read(byte[] buffer, int offset, int readLength) throws IOException { - return mInputReader.read(buffer, offset, readLength); - } - } - - private final class MediaParserDrmInitData extends DrmInitData { - - private final SchemeInitData[] mSchemeDatas; - - private MediaParserDrmInitData(com.google.android.exoplayer2.drm.DrmInitData exoDrmInitData) - throws IllegalAccessException, InstantiationException, InvocationTargetException { - mSchemeDatas = new SchemeInitData[exoDrmInitData.schemeDataCount]; - for (int i = 0; i < mSchemeDatas.length; i++) { - mSchemeDatas[i] = toFrameworkSchemeInitData(exoDrmInitData.get(i)); - } - } - - @Override - @Nullable - public SchemeInitData get(UUID schemeUuid) { - for (SchemeInitData schemeInitData : mSchemeDatas) { - if (schemeInitData.uuid.equals(schemeUuid)) { - return schemeInitData; - } - } - return null; - } - - @Override - public SchemeInitData getSchemeInitDataAt(int index) { - return mSchemeDatas[index]; - } - - @Override - public int getSchemeInitDataCount() { - return mSchemeDatas.length; - } - - private DrmInitData.SchemeInitData toFrameworkSchemeInitData(SchemeData exoSchemeData) - throws IllegalAccessException, InvocationTargetException, InstantiationException { - return mSchemeInitDataConstructor.newInstance( - exoSchemeData.uuid, exoSchemeData.mimeType, exoSchemeData.data); - } - } - - private final class ExtractorOutputAdapter implements ExtractorOutput { - - private final SparseArray<TrackOutput> mTrackOutputAdapters; - private boolean mTracksEnded; - - private ExtractorOutputAdapter() { - mTrackOutputAdapters = new SparseArray<>(); - } - - @Override - public TrackOutput track(int id, int type) { - TrackOutput trackOutput = mTrackOutputAdapters.get(id); - if (trackOutput == null) { - int trackIndex = mTrackOutputAdapters.size(); - trackOutput = new TrackOutputAdapter(trackIndex); - mTrackOutputAdapters.put(id, trackOutput); - if (mEagerlyExposeTrackType) { - MediaFormat mediaFormat = new MediaFormat(); - mediaFormat.setString("track-type-string", toTypeString(type)); - mOutputConsumer.onTrackDataFound( - trackIndex, new TrackData(mediaFormat, /* drmInitData= */ null)); - } - } - return trackOutput; - } - - @Override - public void endTracks() { - mOutputConsumer.onTrackCountFound(mTrackOutputAdapters.size()); - } - - @Override - public void seekMap(com.google.android.exoplayer2.extractor.SeekMap exoplayerSeekMap) { - long durationUs = exoplayerSeekMap.getDurationUs(); - if (durationUs != C.TIME_UNSET) { - mDurationMillis = C.usToMs(durationUs); - } - if (mExposeChunkIndexAsMediaFormat && exoplayerSeekMap instanceof ChunkIndex) { - ChunkIndex chunkIndex = (ChunkIndex) exoplayerSeekMap; - MediaFormat mediaFormat = new MediaFormat(); - mediaFormat.setByteBuffer("chunk-index-int-sizes", toByteBuffer(chunkIndex.sizes)); - mediaFormat.setByteBuffer( - "chunk-index-long-offsets", toByteBuffer(chunkIndex.offsets)); - mediaFormat.setByteBuffer( - "chunk-index-long-us-durations", toByteBuffer(chunkIndex.durationsUs)); - mediaFormat.setByteBuffer( - "chunk-index-long-us-times", toByteBuffer(chunkIndex.timesUs)); - mOutputConsumer.onTrackDataFound( - /* trackIndex= */ 0, new TrackData(mediaFormat, /* drmInitData= */ null)); - } - mOutputConsumer.onSeekMapFound(new SeekMap(exoplayerSeekMap)); - } - } - - private class TrackOutputAdapter implements TrackOutput { - - private final int mTrackIndex; - - private CryptoInfo mLastOutputCryptoInfo; - private CryptoInfo.Pattern mLastOutputEncryptionPattern; - private CryptoData mLastReceivedCryptoData; - - @EncryptionDataReadState private int mEncryptionDataReadState; - private int mEncryptionDataSizeToSubtractFromSampleDataSize; - private int mEncryptionVectorSize; - private byte[] mScratchIvSpace; - private int mSubsampleEncryptionDataSize; - private int[] mScratchSubsampleEncryptedBytesCount; - private int[] mScratchSubsampleClearBytesCount; - private boolean mHasSubsampleEncryptionData; - private int mSkippedSupplementalDataBytes; - - private TrackOutputAdapter(int trackIndex) { - mTrackIndex = trackIndex; - mScratchIvSpace = new byte[16]; // Size documented in CryptoInfo. - mScratchSubsampleEncryptedBytesCount = new int[32]; - mScratchSubsampleClearBytesCount = new int[32]; - mEncryptionDataReadState = STATE_READING_SIGNAL_BYTE; - mLastOutputEncryptionPattern = - new CryptoInfo.Pattern(/* blocksToEncrypt= */ 0, /* blocksToSkip= */ 0); - } - - @Override - public void format(Format format) { - mTrackFormats.put(mTrackIndex, format); - mOutputConsumer.onTrackDataFound( - mTrackIndex, - new TrackData( - toMediaFormat(format), toFrameworkDrmInitData(format.drmInitData))); - } - - @Override - public int sampleData( - DataReader input, - int length, - boolean allowEndOfInput, - @SampleDataPart int sampleDataPart) - throws IOException { - mScratchDataReaderAdapter.setDataReader(input, length); - long positionBeforeReading = mScratchDataReaderAdapter.getPosition(); - mOutputConsumer.onSampleDataFound(mTrackIndex, mScratchDataReaderAdapter); - return (int) (mScratchDataReaderAdapter.getPosition() - positionBeforeReading); - } - - @Override - public void sampleData( - ParsableByteArray data, int length, @SampleDataPart int sampleDataPart) { - if (sampleDataPart == SAMPLE_DATA_PART_ENCRYPTION && !mInBandCryptoInfo) { - while (length > 0) { - switch (mEncryptionDataReadState) { - case STATE_READING_SIGNAL_BYTE: - int encryptionSignalByte = data.readUnsignedByte(); - length--; - mHasSubsampleEncryptionData = ((encryptionSignalByte >> 7) & 1) != 0; - mEncryptionVectorSize = encryptionSignalByte & 0x7F; - mEncryptionDataSizeToSubtractFromSampleDataSize = - mEncryptionVectorSize + 1; // Signal byte. - mEncryptionDataReadState = STATE_READING_INIT_VECTOR; - break; - case STATE_READING_INIT_VECTOR: - Arrays.fill(mScratchIvSpace, (byte) 0); // Ensure 0-padding. - data.readBytes(mScratchIvSpace, /* offset= */ 0, mEncryptionVectorSize); - length -= mEncryptionVectorSize; - if (mHasSubsampleEncryptionData) { - mEncryptionDataReadState = STATE_READING_SUBSAMPLE_ENCRYPTION_SIZE; - } else { - mSubsampleEncryptionDataSize = 0; - mEncryptionDataReadState = STATE_READING_SIGNAL_BYTE; - } - break; - case STATE_READING_SUBSAMPLE_ENCRYPTION_SIZE: - mSubsampleEncryptionDataSize = data.readUnsignedShort(); - if (mScratchSubsampleClearBytesCount.length - < mSubsampleEncryptionDataSize) { - mScratchSubsampleClearBytesCount = - new int[mSubsampleEncryptionDataSize]; - mScratchSubsampleEncryptedBytesCount = - new int[mSubsampleEncryptionDataSize]; - } - length -= 2; - mEncryptionDataSizeToSubtractFromSampleDataSize += - 2 - + mSubsampleEncryptionDataSize - * BYTES_PER_SUBSAMPLE_ENCRYPTION_ENTRY; - mEncryptionDataReadState = STATE_READING_SUBSAMPLE_ENCRYPTION_DATA; - break; - case STATE_READING_SUBSAMPLE_ENCRYPTION_DATA: - for (int i = 0; i < mSubsampleEncryptionDataSize; i++) { - mScratchSubsampleClearBytesCount[i] = data.readUnsignedShort(); - mScratchSubsampleEncryptedBytesCount[i] = data.readInt(); - } - length -= - mSubsampleEncryptionDataSize - * BYTES_PER_SUBSAMPLE_ENCRYPTION_ENTRY; - mEncryptionDataReadState = STATE_READING_SIGNAL_BYTE; - if (length != 0) { - throw new IllegalStateException(); - } - break; - default: - // Never happens. - throw new IllegalStateException(); - } - } - } else if (sampleDataPart == SAMPLE_DATA_PART_SUPPLEMENTAL - && !mIncludeSupplementalData) { - mSkippedSupplementalDataBytes += length; - data.skipBytes(length); - } else { - outputSampleData(data, length); - } - } - - @Override - public void sampleMetadata( - long timeUs, int flags, int size, int offset, @Nullable CryptoData cryptoData) { - size -= mSkippedSupplementalDataBytes; - mSkippedSupplementalDataBytes = 0; - mOutputConsumer.onSampleCompleted( - mTrackIndex, - timeUs, - getMediaParserFlags(flags), - size - mEncryptionDataSizeToSubtractFromSampleDataSize, - offset, - getPopulatedCryptoInfo(cryptoData)); - mEncryptionDataReadState = STATE_READING_SIGNAL_BYTE; - mEncryptionDataSizeToSubtractFromSampleDataSize = 0; - } - - @Nullable - private CryptoInfo getPopulatedCryptoInfo(@Nullable CryptoData cryptoData) { - if (cryptoData == null) { - // The sample is not encrypted. - return null; - } else if (mInBandCryptoInfo) { - if (cryptoData != mLastReceivedCryptoData) { - mLastOutputCryptoInfo = - createNewCryptoInfoAndPopulateWithCryptoData(cryptoData); - // We are using in-band crypto info, so the IV will be ignored. But we prevent - // it from being null because toString assumes it non-null. - mLastOutputCryptoInfo.iv = EMPTY_BYTE_ARRAY; - } - } else /* We must populate the full CryptoInfo. */ { - // CryptoInfo.pattern is not accessible to the user, so the user needs to feed - // this CryptoInfo directly to MediaCodec. We need to create a new CryptoInfo per - // sample because of per-sample initialization vector changes. - CryptoInfo newCryptoInfo = createNewCryptoInfoAndPopulateWithCryptoData(cryptoData); - newCryptoInfo.iv = Arrays.copyOf(mScratchIvSpace, mScratchIvSpace.length); - boolean canReuseSubsampleInfo = - mLastOutputCryptoInfo != null - && mLastOutputCryptoInfo.numSubSamples - == mSubsampleEncryptionDataSize; - for (int i = 0; i < mSubsampleEncryptionDataSize && canReuseSubsampleInfo; i++) { - canReuseSubsampleInfo = - mLastOutputCryptoInfo.numBytesOfClearData[i] - == mScratchSubsampleClearBytesCount[i] - && mLastOutputCryptoInfo.numBytesOfEncryptedData[i] - == mScratchSubsampleEncryptedBytesCount[i]; - } - newCryptoInfo.numSubSamples = mSubsampleEncryptionDataSize; - if (canReuseSubsampleInfo) { - newCryptoInfo.numBytesOfClearData = mLastOutputCryptoInfo.numBytesOfClearData; - newCryptoInfo.numBytesOfEncryptedData = - mLastOutputCryptoInfo.numBytesOfEncryptedData; - } else { - newCryptoInfo.numBytesOfClearData = - Arrays.copyOf( - mScratchSubsampleClearBytesCount, mSubsampleEncryptionDataSize); - newCryptoInfo.numBytesOfEncryptedData = - Arrays.copyOf( - mScratchSubsampleEncryptedBytesCount, - mSubsampleEncryptionDataSize); - } - mLastOutputCryptoInfo = newCryptoInfo; - } - mLastReceivedCryptoData = cryptoData; - return mLastOutputCryptoInfo; - } - - private CryptoInfo createNewCryptoInfoAndPopulateWithCryptoData(CryptoData cryptoData) { - CryptoInfo cryptoInfo = new CryptoInfo(); - cryptoInfo.key = cryptoData.encryptionKey; - cryptoInfo.mode = cryptoData.cryptoMode; - if (cryptoData.clearBlocks != mLastOutputEncryptionPattern.getSkipBlocks() - || cryptoData.encryptedBlocks - != mLastOutputEncryptionPattern.getEncryptBlocks()) { - mLastOutputEncryptionPattern = - new CryptoInfo.Pattern(cryptoData.encryptedBlocks, cryptoData.clearBlocks); - } - cryptoInfo.setPattern(mLastOutputEncryptionPattern); - return cryptoInfo; - } - - private void outputSampleData(ParsableByteArray data, int length) { - mScratchParsableByteArrayAdapter.resetWithByteArray(data, length); - try { - // Read all bytes from data. ExoPlayer extractors expect all sample data to be - // consumed by TrackOutput implementations when passing a ParsableByteArray. - while (mScratchParsableByteArrayAdapter.getLength() > 0) { - mOutputConsumer.onSampleDataFound( - mTrackIndex, mScratchParsableByteArrayAdapter); - } - } catch (IOException e) { - // Unexpected. - throw new RuntimeException(e); - } - } - } - - private static final class DataReaderAdapter implements InputReader { - - private DataReader mDataReader; - private int mCurrentPosition; - private long mLength; - - public void setDataReader(DataReader dataReader, long length) { - mDataReader = dataReader; - mCurrentPosition = 0; - mLength = length; - } - - // Input implementation. - - @Override - public int read(byte[] buffer, int offset, int readLength) throws IOException { - int readBytes = 0; - readBytes = mDataReader.read(buffer, offset, readLength); - mCurrentPosition += readBytes; - return readBytes; - } - - @Override - public long getPosition() { - return mCurrentPosition; - } - - @Override - public long getLength() { - return mLength - mCurrentPosition; - } - } - - private static final class ParsableByteArrayAdapter implements InputReader { - - private ParsableByteArray mByteArray; - private long mLength; - private int mCurrentPosition; - - public void resetWithByteArray(ParsableByteArray byteArray, long length) { - mByteArray = byteArray; - mCurrentPosition = 0; - mLength = length; - } - - // Input implementation. - - @Override - public int read(byte[] buffer, int offset, int readLength) { - mByteArray.readBytes(buffer, offset, readLength); - mCurrentPosition += readLength; - return readLength; - } - - @Override - public long getPosition() { - return mCurrentPosition; - } - - @Override - public long getLength() { - return mLength - mCurrentPosition; - } - } - - private static final class DummyExoPlayerSeekMap - implements com.google.android.exoplayer2.extractor.SeekMap { - - @Override - public boolean isSeekable() { - return true; - } - - @Override - public long getDurationUs() { - return C.TIME_UNSET; - } - - @Override - public SeekPoints getSeekPoints(long timeUs) { - com.google.android.exoplayer2.extractor.SeekPoint seekPoint = - new com.google.android.exoplayer2.extractor.SeekPoint( - timeUs, /* position= */ 0); - return new SeekPoints(seekPoint, seekPoint); - } - } - - /** Creates extractor instances. */ - private interface ExtractorFactory { - - /** Returns a new extractor instance. */ - Extractor createInstance(); - } - - // Private static methods. - - private static Format toExoPlayerCaptionFormat(MediaFormat mediaFormat) { - Format.Builder formatBuilder = - new Format.Builder().setSampleMimeType(mediaFormat.getString(MediaFormat.KEY_MIME)); - if (mediaFormat.containsKey(MediaFormat.KEY_CAPTION_SERVICE_NUMBER)) { - formatBuilder.setAccessibilityChannel( - mediaFormat.getInteger(MediaFormat.KEY_CAPTION_SERVICE_NUMBER)); - } - return formatBuilder.build(); - } - - private static MediaFormat toMediaFormat(Format format) { - MediaFormat result = new MediaFormat(); - setOptionalMediaFormatInt(result, MediaFormat.KEY_BIT_RATE, format.bitrate); - setOptionalMediaFormatInt(result, MediaFormat.KEY_CHANNEL_COUNT, format.channelCount); - - ColorInfo colorInfo = format.colorInfo; - if (colorInfo != null) { - setOptionalMediaFormatInt( - result, MediaFormat.KEY_COLOR_TRANSFER, colorInfo.colorTransfer); - setOptionalMediaFormatInt(result, MediaFormat.KEY_COLOR_RANGE, colorInfo.colorRange); - setOptionalMediaFormatInt(result, MediaFormat.KEY_COLOR_STANDARD, colorInfo.colorSpace); - - if (format.colorInfo.hdrStaticInfo != null) { - result.setByteBuffer( - MediaFormat.KEY_HDR_STATIC_INFO, - ByteBuffer.wrap(format.colorInfo.hdrStaticInfo)); - } - } - - setOptionalMediaFormatString(result, MediaFormat.KEY_MIME, format.sampleMimeType); - setOptionalMediaFormatString(result, MediaFormat.KEY_CODECS_STRING, format.codecs); - if (format.frameRate != Format.NO_VALUE) { - result.setFloat(MediaFormat.KEY_FRAME_RATE, format.frameRate); - } - setOptionalMediaFormatInt(result, MediaFormat.KEY_WIDTH, format.width); - setOptionalMediaFormatInt(result, MediaFormat.KEY_HEIGHT, format.height); - - List<byte[]> initData = format.initializationData; - for (int i = 0; i < initData.size(); i++) { - result.setByteBuffer("csd-" + i, ByteBuffer.wrap(initData.get(i))); - } - setPcmEncoding(format, result); - setOptionalMediaFormatString(result, MediaFormat.KEY_LANGUAGE, format.language); - setOptionalMediaFormatInt(result, MediaFormat.KEY_MAX_INPUT_SIZE, format.maxInputSize); - setOptionalMediaFormatInt(result, MediaFormat.KEY_ROTATION, format.rotationDegrees); - setOptionalMediaFormatInt(result, MediaFormat.KEY_SAMPLE_RATE, format.sampleRate); - setOptionalMediaFormatInt( - result, MediaFormat.KEY_CAPTION_SERVICE_NUMBER, format.accessibilityChannel); - - int selectionFlags = format.selectionFlags; - result.setInteger( - MediaFormat.KEY_IS_AUTOSELECT, selectionFlags & C.SELECTION_FLAG_AUTOSELECT); - result.setInteger(MediaFormat.KEY_IS_DEFAULT, selectionFlags & C.SELECTION_FLAG_DEFAULT); - result.setInteger( - MediaFormat.KEY_IS_FORCED_SUBTITLE, selectionFlags & C.SELECTION_FLAG_FORCED); - - setOptionalMediaFormatInt(result, MediaFormat.KEY_ENCODER_DELAY, format.encoderDelay); - setOptionalMediaFormatInt(result, MediaFormat.KEY_ENCODER_PADDING, format.encoderPadding); - - if (format.pixelWidthHeightRatio != Format.NO_VALUE && format.pixelWidthHeightRatio != 0) { - int parWidth = 1; - int parHeight = 1; - if (format.pixelWidthHeightRatio < 1.0f) { - parHeight = 1 << 30; - parWidth = (int) (format.pixelWidthHeightRatio * parHeight); - } else if (format.pixelWidthHeightRatio > 1.0f) { - parWidth = 1 << 30; - parHeight = (int) (parWidth / format.pixelWidthHeightRatio); - } - result.setInteger(MediaFormat.KEY_PIXEL_ASPECT_RATIO_WIDTH, parWidth); - result.setInteger(MediaFormat.KEY_PIXEL_ASPECT_RATIO_HEIGHT, parHeight); - result.setFloat("pixel-width-height-ratio-float", format.pixelWidthHeightRatio); - } - if (format.drmInitData != null) { - // The crypto mode is propagated along with sample metadata. We also include it in the - // format for convenient use from ExoPlayer. - result.setString("crypto-mode-fourcc", format.drmInitData.schemeType); - } - if (format.subsampleOffsetUs != Format.OFFSET_SAMPLE_RELATIVE) { - result.setLong("subsample-offset-us-long", format.subsampleOffsetUs); - } - // LACK OF SUPPORT FOR: - // format.id; - // format.metadata; - // format.stereoMode; - return result; - } - - private static ByteBuffer toByteBuffer(long[] longArray) { - ByteBuffer byteBuffer = ByteBuffer.allocateDirect(longArray.length * Long.BYTES); - for (long element : longArray) { - byteBuffer.putLong(element); - } - byteBuffer.flip(); - return byteBuffer; - } - - private static ByteBuffer toByteBuffer(int[] intArray) { - ByteBuffer byteBuffer = ByteBuffer.allocateDirect(intArray.length * Integer.BYTES); - for (int element : intArray) { - byteBuffer.putInt(element); - } - byteBuffer.flip(); - return byteBuffer; - } - - private static String toTypeString(int type) { - switch (type) { - case C.TRACK_TYPE_VIDEO: - return "video"; - case C.TRACK_TYPE_AUDIO: - return "audio"; - case C.TRACK_TYPE_TEXT: - return "text"; - case C.TRACK_TYPE_METADATA: - return "metadata"; - default: - return "unknown"; - } - } - - private static void setPcmEncoding(Format format, MediaFormat result) { - int exoPcmEncoding = format.pcmEncoding; - setOptionalMediaFormatInt(result, "exo-pcm-encoding", format.pcmEncoding); - int mediaFormatPcmEncoding; - switch (exoPcmEncoding) { - case C.ENCODING_PCM_8BIT: - mediaFormatPcmEncoding = AudioFormat.ENCODING_PCM_8BIT; - break; - case C.ENCODING_PCM_16BIT: - mediaFormatPcmEncoding = AudioFormat.ENCODING_PCM_16BIT; - break; - case C.ENCODING_PCM_FLOAT: - mediaFormatPcmEncoding = AudioFormat.ENCODING_PCM_FLOAT; - break; - default: - // No matching value. Do nothing. - return; - } - result.setInteger(MediaFormat.KEY_PCM_ENCODING, mediaFormatPcmEncoding); - } - - private static void setOptionalMediaFormatInt(MediaFormat mediaFormat, String key, int value) { - if (value != Format.NO_VALUE) { - mediaFormat.setInteger(key, value); - } - } - - private static void setOptionalMediaFormatString( - MediaFormat mediaFormat, String key, @Nullable String value) { - if (value != null) { - mediaFormat.setString(key, value); - } - } - - private DrmInitData toFrameworkDrmInitData( - com.google.android.exoplayer2.drm.DrmInitData exoDrmInitData) { - try { - return exoDrmInitData != null && mSchemeInitDataConstructor != null - ? new MediaParserDrmInitData(exoDrmInitData) - : null; - } catch (Throwable e) { - if (!mLoggedSchemeInitDataCreationException) { - mLoggedSchemeInitDataCreationException = true; - Log.e(TAG, "Unable to create SchemeInitData instance."); - } - return null; - } - } - - /** Returns a new {@link SeekPoint} equivalent to the given {@code exoPlayerSeekPoint}. */ - private static SeekPoint toSeekPoint( - com.google.android.exoplayer2.extractor.SeekPoint exoPlayerSeekPoint) { - return new SeekPoint(exoPlayerSeekPoint.timeUs, exoPlayerSeekPoint.position); - } - - /** - * Introduces random error to the given metric value in order to prevent the identification of - * the parsed media. - */ - private static long addDither(long value) { - // Generate a random in [0, 1]. - double randomDither = ThreadLocalRandom.current().nextFloat(); - // Clamp the random number to [0, 2 * MEDIAMETRICS_DITHER]. - randomDither *= 2 * MEDIAMETRICS_DITHER; - // Translate the random number to [1 - MEDIAMETRICS_DITHER, 1 + MEDIAMETRICS_DITHER]. - randomDither += 1 - MEDIAMETRICS_DITHER; - return value != -1 ? (long) (value * randomDither) : -1; - } - - private static void assertValidNames(@NonNull String[] names) { - for (String name : names) { - if (!EXTRACTOR_FACTORIES_BY_NAME.containsKey(name)) { - throw new IllegalArgumentException( - "Invalid extractor name: " - + name - + ". Supported parsers are: " - + TextUtils.join(", ", EXTRACTOR_FACTORIES_BY_NAME.keySet()) - + "."); - } - } - } - - private int getMediaParserFlags(int flags) { - @SampleFlags int result = 0; - result |= (flags & C.BUFFER_FLAG_ENCRYPTED) != 0 ? SAMPLE_FLAG_ENCRYPTED : 0; - result |= (flags & C.BUFFER_FLAG_KEY_FRAME) != 0 ? SAMPLE_FLAG_KEY_FRAME : 0; - result |= (flags & C.BUFFER_FLAG_DECODE_ONLY) != 0 ? SAMPLE_FLAG_DECODE_ONLY : 0; - result |= - (flags & C.BUFFER_FLAG_HAS_SUPPLEMENTAL_DATA) != 0 && mIncludeSupplementalData - ? SAMPLE_FLAG_HAS_SUPPLEMENTAL_DATA - : 0; - result |= (flags & C.BUFFER_FLAG_LAST_SAMPLE) != 0 ? SAMPLE_FLAG_LAST_SAMPLE : 0; - return result; - } - - @Nullable - private static Constructor<DrmInitData.SchemeInitData> getSchemeInitDataConstructor() { - // TODO: Use constructor statically when available. - Constructor<DrmInitData.SchemeInitData> constructor; - try { - return DrmInitData.SchemeInitData.class.getConstructor( - UUID.class, String.class, byte[].class); - } catch (Throwable e) { - Log.e(TAG, "Unable to get SchemeInitData constructor."); - return null; - } - } - - // Native methods. - - private native void nativeSubmitMetrics( - String logSessionId, - String parserName, - boolean createdByName, - String parserPool, - String lastObservedExceptionName, - long resourceByteCount, - long durationMillis, - String trackMimeTypes, - String trackCodecs, - String alteredParameters, - int videoWidth, - int videoHeight); - - // Static initialization. - - static { - System.loadLibrary(JNI_LIBRARY_NAME); - - // Using a LinkedHashMap to keep the insertion order when iterating over the keys. - LinkedHashMap<String, ExtractorFactory> extractorFactoriesByName = new LinkedHashMap<>(); - // Parsers are ordered to match ExoPlayer's DefaultExtractorsFactory extractor ordering, - // which in turn aims to minimize the chances of incorrect extractor selections. - extractorFactoriesByName.put(PARSER_NAME_MATROSKA, MatroskaExtractor::new); - extractorFactoriesByName.put(PARSER_NAME_FMP4, FragmentedMp4Extractor::new); - extractorFactoriesByName.put(PARSER_NAME_MP4, Mp4Extractor::new); - extractorFactoriesByName.put(PARSER_NAME_MP3, Mp3Extractor::new); - extractorFactoriesByName.put(PARSER_NAME_ADTS, AdtsExtractor::new); - extractorFactoriesByName.put(PARSER_NAME_AC3, Ac3Extractor::new); - extractorFactoriesByName.put(PARSER_NAME_TS, TsExtractor::new); - extractorFactoriesByName.put(PARSER_NAME_FLV, FlvExtractor::new); - extractorFactoriesByName.put(PARSER_NAME_OGG, OggExtractor::new); - extractorFactoriesByName.put(PARSER_NAME_PS, PsExtractor::new); - extractorFactoriesByName.put(PARSER_NAME_WAV, WavExtractor::new); - extractorFactoriesByName.put(PARSER_NAME_AMR, AmrExtractor::new); - extractorFactoriesByName.put(PARSER_NAME_AC4, Ac4Extractor::new); - extractorFactoriesByName.put(PARSER_NAME_FLAC, FlacExtractor::new); - EXTRACTOR_FACTORIES_BY_NAME = Collections.unmodifiableMap(extractorFactoriesByName); - - HashMap<String, Class> expectedTypeByParameterName = new HashMap<>(); - expectedTypeByParameterName.put(PARAMETER_ADTS_ENABLE_CBR_SEEKING, Boolean.class); - expectedTypeByParameterName.put(PARAMETER_AMR_ENABLE_CBR_SEEKING, Boolean.class); - expectedTypeByParameterName.put(PARAMETER_FLAC_DISABLE_ID3, Boolean.class); - expectedTypeByParameterName.put(PARAMETER_MP4_IGNORE_EDIT_LISTS, Boolean.class); - expectedTypeByParameterName.put(PARAMETER_MP4_IGNORE_TFDT_BOX, Boolean.class); - expectedTypeByParameterName.put( - PARAMETER_MP4_TREAT_VIDEO_FRAMES_AS_KEYFRAMES, Boolean.class); - expectedTypeByParameterName.put(PARAMETER_MATROSKA_DISABLE_CUES_SEEKING, Boolean.class); - expectedTypeByParameterName.put(PARAMETER_MP3_DISABLE_ID3, Boolean.class); - expectedTypeByParameterName.put(PARAMETER_MP3_ENABLE_CBR_SEEKING, Boolean.class); - expectedTypeByParameterName.put(PARAMETER_MP3_ENABLE_INDEX_SEEKING, Boolean.class); - expectedTypeByParameterName.put(PARAMETER_TS_MODE, String.class); - expectedTypeByParameterName.put(PARAMETER_TS_ALLOW_NON_IDR_AVC_KEYFRAMES, Boolean.class); - expectedTypeByParameterName.put(PARAMETER_TS_IGNORE_AAC_STREAM, Boolean.class); - expectedTypeByParameterName.put(PARAMETER_TS_IGNORE_AVC_STREAM, Boolean.class); - expectedTypeByParameterName.put(PARAMETER_TS_IGNORE_SPLICE_INFO_STREAM, Boolean.class); - expectedTypeByParameterName.put(PARAMETER_TS_DETECT_ACCESS_UNITS, Boolean.class); - expectedTypeByParameterName.put(PARAMETER_TS_ENABLE_HDMV_DTS_AUDIO_STREAMS, Boolean.class); - expectedTypeByParameterName.put(PARAMETER_IN_BAND_CRYPTO_INFO, Boolean.class); - expectedTypeByParameterName.put(PARAMETER_INCLUDE_SUPPLEMENTAL_DATA, Boolean.class); - expectedTypeByParameterName.put(PARAMETER_IGNORE_TIMESTAMP_OFFSET, Boolean.class); - expectedTypeByParameterName.put(PARAMETER_EAGERLY_EXPOSE_TRACKTYPE, Boolean.class); - expectedTypeByParameterName.put(PARAMETER_EXPOSE_DUMMY_SEEKMAP, Boolean.class); - expectedTypeByParameterName.put( - PARAMETER_EXPOSE_CHUNK_INDEX_AS_MEDIA_FORMAT, Boolean.class); - expectedTypeByParameterName.put( - PARAMETER_OVERRIDE_IN_BAND_CAPTION_DECLARATIONS, Boolean.class); - expectedTypeByParameterName.put(PARAMETER_EXPOSE_EMSG_TRACK, Boolean.class); - // We do not check PARAMETER_EXPOSE_CAPTION_FORMATS here, and we do it in setParameters - // instead. Checking that the value is a List is insufficient to catch wrong parameter - // value types. - int sumOfParameterNameLengths = - expectedTypeByParameterName.keySet().stream() - .map(String::length) - .reduce(0, Integer::sum); - sumOfParameterNameLengths += PARAMETER_EXPOSE_CAPTION_FORMATS.length(); - // Add space for any required separators. - MEDIAMETRICS_PARAMETER_LIST_MAX_LENGTH = - sumOfParameterNameLengths + expectedTypeByParameterName.size(); - - EXPECTED_TYPE_BY_PARAMETER_NAME = Collections.unmodifiableMap(expectedTypeByParameterName); - } -} diff --git a/apex/media/framework/java/android/media/MediaSession2.java b/apex/media/framework/java/android/media/MediaSession2.java deleted file mode 100644 index e76d61cf8965..000000000000 --- a/apex/media/framework/java/android/media/MediaSession2.java +++ /dev/null @@ -1,931 +0,0 @@ -/* - * Copyright 2018 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.media; - -import static android.media.MediaConstants.KEY_ALLOWED_COMMANDS; -import static android.media.MediaConstants.KEY_CONNECTION_HINTS; -import static android.media.MediaConstants.KEY_PACKAGE_NAME; -import static android.media.MediaConstants.KEY_PID; -import static android.media.MediaConstants.KEY_PLAYBACK_ACTIVE; -import static android.media.MediaConstants.KEY_SESSION2LINK; -import static android.media.MediaConstants.KEY_TOKEN_EXTRAS; -import static android.media.Session2Command.Result.RESULT_ERROR_UNKNOWN_ERROR; -import static android.media.Session2Command.Result.RESULT_INFO_SKIPPED; -import static android.media.Session2Token.TYPE_SESSION; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.app.PendingIntent; -import android.content.Context; -import android.content.Intent; -import android.media.session.MediaSessionManager; -import android.media.session.MediaSessionManager.RemoteUserInfo; -import android.os.BadParcelableException; -import android.os.Bundle; -import android.os.Handler; -import android.os.Parcel; -import android.os.Process; -import android.os.ResultReceiver; -import android.util.ArrayMap; -import android.util.ArraySet; -import android.util.Log; - -import com.android.modules.utils.build.SdkLevel; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.concurrent.Executor; - -/** - * This API is not generally intended for third party application developers. - * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a> - * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session - * Library</a> for consistent behavior across all devices. - * <p> - * Allows a media app to expose its transport controls and playback information in a process to - * other processes including the Android framework and other apps. - */ -public class MediaSession2 implements AutoCloseable { - static final String TAG = "MediaSession2"; - static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); - - // Note: This checks the uniqueness of a session ID only in a single process. - // When the framework becomes able to check the uniqueness, this logic should be removed. - //@GuardedBy("MediaSession.class") - private static final List<String> SESSION_ID_LIST = new ArrayList<>(); - - @SuppressWarnings("WeakerAccess") /* synthetic access */ - final Object mLock = new Object(); - //@GuardedBy("mLock") - @SuppressWarnings("WeakerAccess") /* synthetic access */ - final Map<Controller2Link, ControllerInfo> mConnectedControllers = new HashMap<>(); - - @SuppressWarnings("WeakerAccess") /* synthetic access */ - final Context mContext; - @SuppressWarnings("WeakerAccess") /* synthetic access */ - final Executor mCallbackExecutor; - @SuppressWarnings("WeakerAccess") /* synthetic access */ - final SessionCallback mCallback; - @SuppressWarnings("WeakerAccess") /* synthetic access */ - final Session2Link mSessionStub; - - private final String mSessionId; - private final PendingIntent mSessionActivity; - private final Session2Token mSessionToken; - private final MediaSessionManager mMediaSessionManager; - private final MediaCommunicationManager mCommunicationManager; - private final Handler mResultHandler; - - //@GuardedBy("mLock") - private boolean mClosed; - //@GuardedBy("mLock") - private boolean mPlaybackActive; - //@GuardedBy("mLock") - private ForegroundServiceEventCallback mForegroundServiceEventCallback; - - MediaSession2(@NonNull Context context, @NonNull String id, PendingIntent sessionActivity, - @NonNull Executor callbackExecutor, @NonNull SessionCallback callback, - @NonNull Bundle tokenExtras) { - synchronized (MediaSession2.class) { - if (SESSION_ID_LIST.contains(id)) { - throw new IllegalStateException("Session ID must be unique. ID=" + id); - } - SESSION_ID_LIST.add(id); - } - - mContext = context; - mSessionId = id; - mSessionActivity = sessionActivity; - mCallbackExecutor = callbackExecutor; - mCallback = callback; - mSessionStub = new Session2Link(this); - mSessionToken = new Session2Token(Process.myUid(), TYPE_SESSION, context.getPackageName(), - mSessionStub, tokenExtras); - if (SdkLevel.isAtLeastS()) { - mCommunicationManager = mContext.getSystemService(MediaCommunicationManager.class); - mMediaSessionManager = null; - } else { - mMediaSessionManager = mContext.getSystemService(MediaSessionManager.class); - mCommunicationManager = null; - } - // NOTE: mResultHandler uses main looper, so this MUST NOT be blocked. - mResultHandler = new Handler(context.getMainLooper()); - mClosed = false; - } - - @Override - public void close() { - try { - List<ControllerInfo> controllerInfos; - ForegroundServiceEventCallback callback; - synchronized (mLock) { - if (mClosed) { - return; - } - mClosed = true; - controllerInfos = getConnectedControllers(); - mConnectedControllers.clear(); - callback = mForegroundServiceEventCallback; - mForegroundServiceEventCallback = null; - } - synchronized (MediaSession2.class) { - SESSION_ID_LIST.remove(mSessionId); - } - if (callback != null) { - callback.onSessionClosed(this); - } - for (ControllerInfo info : controllerInfos) { - info.notifyDisconnected(); - } - } catch (Exception e) { - // Should not be here. - } - } - - /** - * Returns the session ID - */ - @NonNull - public String getId() { - return mSessionId; - } - - /** - * Returns the {@link Session2Token} for creating {@link MediaController2}. - */ - @NonNull - public Session2Token getToken() { - return mSessionToken; - } - - /** - * Broadcasts a session command to all the connected controllers - * <p> - * @param command the session command - * @param args optional arguments - */ - public void broadcastSessionCommand(@NonNull Session2Command command, @Nullable Bundle args) { - if (command == null) { - throw new IllegalArgumentException("command shouldn't be null"); - } - List<ControllerInfo> controllerInfos = getConnectedControllers(); - for (ControllerInfo controller : controllerInfos) { - controller.sendSessionCommand(command, args, null); - } - } - - /** - * Sends a session command to a specific controller - * <p> - * @param controller the controller to get the session command - * @param command the session command - * @param args optional arguments - * @return a token which will be sent together in {@link SessionCallback#onCommandResult} - * when its result is received. - */ - @NonNull - public Object sendSessionCommand(@NonNull ControllerInfo controller, - @NonNull Session2Command command, @Nullable Bundle args) { - if (controller == null) { - throw new IllegalArgumentException("controller shouldn't be null"); - } - if (command == null) { - throw new IllegalArgumentException("command shouldn't be null"); - } - ResultReceiver resultReceiver = new ResultReceiver(mResultHandler) { - protected void onReceiveResult(int resultCode, Bundle resultData) { - controller.receiveCommandResult(this); - mCallbackExecutor.execute(() -> { - mCallback.onCommandResult(MediaSession2.this, controller, this, - command, new Session2Command.Result(resultCode, resultData)); - }); - } - }; - controller.sendSessionCommand(command, args, resultReceiver); - return resultReceiver; - } - - /** - * Cancels the session command previously sent. - * - * @param controller the controller to get the session command - * @param token the token which is returned from {@link #sendSessionCommand}. - */ - public void cancelSessionCommand(@NonNull ControllerInfo controller, @NonNull Object token) { - if (controller == null) { - throw new IllegalArgumentException("controller shouldn't be null"); - } - if (token == null) { - throw new IllegalArgumentException("token shouldn't be null"); - } - controller.cancelSessionCommand(token); - } - - /** - * Sets whether the playback is active (i.e. playing something) - * - * @param playbackActive {@code true} if the playback active, {@code false} otherwise. - **/ - public void setPlaybackActive(boolean playbackActive) { - final ForegroundServiceEventCallback serviceCallback; - synchronized (mLock) { - if (mPlaybackActive == playbackActive) { - return; - } - mPlaybackActive = playbackActive; - serviceCallback = mForegroundServiceEventCallback; - } - if (serviceCallback != null) { - serviceCallback.onPlaybackActiveChanged(this, playbackActive); - } - List<ControllerInfo> controllerInfos = getConnectedControllers(); - for (ControllerInfo controller : controllerInfos) { - controller.notifyPlaybackActiveChanged(playbackActive); - } - } - - /** - * Returns whehther the playback is active (i.e. playing something) - * - * @return {@code true} if the playback active, {@code false} otherwise. - */ - public boolean isPlaybackActive() { - synchronized (mLock) { - return mPlaybackActive; - } - } - - /** - * Gets the list of the connected controllers - * - * @return list of the connected controllers. - */ - @NonNull - public List<ControllerInfo> getConnectedControllers() { - List<ControllerInfo> controllers = new ArrayList<>(); - synchronized (mLock) { - controllers.addAll(mConnectedControllers.values()); - } - return controllers; - } - - /** - * Returns whether the given bundle includes non-framework Parcelables. - */ - static boolean hasCustomParcelable(@Nullable Bundle bundle) { - if (bundle == null) { - return false; - } - - // Try writing the bundle to parcel, and read it with framework classloader. - Parcel parcel = null; - try { - parcel = Parcel.obtain(); - parcel.writeBundle(bundle); - parcel.setDataPosition(0); - Bundle out = parcel.readBundle(null); - - // Calling Bundle#size() will trigger Bundle#unparcel(). - out.size(); - } catch (BadParcelableException e) { - Log.d(TAG, "Custom parcelable in bundle.", e); - return true; - } finally { - if (parcel != null) { - parcel.recycle(); - } - } - return false; - } - - boolean isClosed() { - synchronized (mLock) { - return mClosed; - } - } - - SessionCallback getCallback() { - return mCallback; - } - - boolean isTrustedForMediaControl(RemoteUserInfo remoteUserInfo) { - if (SdkLevel.isAtLeastS()) { - return mCommunicationManager.isTrustedForMediaControl(remoteUserInfo); - } else { - return mMediaSessionManager.isTrustedForMediaControl(remoteUserInfo); - } - } - - void setForegroundServiceEventCallback(ForegroundServiceEventCallback callback) { - synchronized (mLock) { - if (mForegroundServiceEventCallback == callback) { - return; - } - if (mForegroundServiceEventCallback != null && callback != null) { - throw new IllegalStateException("A session cannot be added to multiple services"); - } - mForegroundServiceEventCallback = callback; - } - } - - // Called by Session2Link.onConnect and MediaSession2Service.MediaSession2ServiceStub.connect - void onConnect(final Controller2Link controller, int callingPid, int callingUid, int seq, - Bundle connectionRequest) { - if (callingPid == 0) { - // The pid here is from Binder.getCallingPid(), which can be 0 for an oneway call from - // the remote process. If it's the case, use PID from the connectionRequest. - callingPid = connectionRequest.getInt(KEY_PID); - } - String callingPkg = connectionRequest.getString(KEY_PACKAGE_NAME); - - RemoteUserInfo remoteUserInfo = new RemoteUserInfo(callingPkg, callingPid, callingUid); - - Bundle connectionHints = connectionRequest.getBundle(KEY_CONNECTION_HINTS); - if (connectionHints == null) { - Log.w(TAG, "connectionHints shouldn't be null."); - connectionHints = Bundle.EMPTY; - } else if (hasCustomParcelable(connectionHints)) { - Log.w(TAG, "connectionHints contain custom parcelable. Ignoring."); - connectionHints = Bundle.EMPTY; - } - - final ControllerInfo controllerInfo = new ControllerInfo( - remoteUserInfo, - isTrustedForMediaControl(remoteUserInfo), - controller, - connectionHints); - mCallbackExecutor.execute(() -> { - boolean connected = false; - try { - if (isClosed()) { - return; - } - controllerInfo.mAllowedCommands = - mCallback.onConnect(MediaSession2.this, controllerInfo); - // Don't reject connection for the request from trusted app. - // Otherwise server will fail to retrieve session's information to dispatch - // media keys to. - if (controllerInfo.mAllowedCommands == null && !controllerInfo.isTrusted()) { - return; - } - if (controllerInfo.mAllowedCommands == null) { - // For trusted apps, send non-null allowed commands to keep - // connection. - controllerInfo.mAllowedCommands = - new Session2CommandGroup.Builder().build(); - } - if (DEBUG) { - Log.d(TAG, "Accepting connection: " + controllerInfo); - } - // If connection is accepted, notify the current state to the controller. - // It's needed because we cannot call synchronous calls between - // session/controller. - Bundle connectionResult = new Bundle(); - connectionResult.putParcelable(KEY_SESSION2LINK, mSessionStub); - connectionResult.putParcelable(KEY_ALLOWED_COMMANDS, - controllerInfo.mAllowedCommands); - connectionResult.putBoolean(KEY_PLAYBACK_ACTIVE, isPlaybackActive()); - connectionResult.putBundle(KEY_TOKEN_EXTRAS, mSessionToken.getExtras()); - - // Double check if session is still there, because close() can be called in - // another thread. - if (isClosed()) { - return; - } - controllerInfo.notifyConnected(connectionResult); - synchronized (mLock) { - if (mConnectedControllers.containsKey(controller)) { - Log.w(TAG, "Controller " + controllerInfo + " has sent connection" - + " request multiple times"); - } - mConnectedControllers.put(controller, controllerInfo); - } - mCallback.onPostConnect(MediaSession2.this, controllerInfo); - connected = true; - } finally { - if (!connected || isClosed()) { - if (DEBUG) { - Log.d(TAG, "Rejecting connection or notifying that session is closed" - + ", controllerInfo=" + controllerInfo); - } - synchronized (mLock) { - mConnectedControllers.remove(controller); - } - controllerInfo.notifyDisconnected(); - } - } - }); - } - - // Called by Session2Link.onDisconnect - void onDisconnect(@NonNull final Controller2Link controller, int seq) { - final ControllerInfo controllerInfo; - synchronized (mLock) { - controllerInfo = mConnectedControllers.remove(controller); - } - if (controllerInfo == null) { - return; - } - mCallbackExecutor.execute(() -> { - mCallback.onDisconnected(MediaSession2.this, controllerInfo); - }); - } - - // Called by Session2Link.onSessionCommand - void onSessionCommand(@NonNull final Controller2Link controller, final int seq, - final Session2Command command, final Bundle args, - @Nullable ResultReceiver resultReceiver) { - if (controller == null) { - return; - } - final ControllerInfo controllerInfo; - synchronized (mLock) { - controllerInfo = mConnectedControllers.get(controller); - } - if (controllerInfo == null) { - return; - } - - // TODO: check allowed commands. - synchronized (mLock) { - controllerInfo.addRequestedCommandSeqNumber(seq); - } - mCallbackExecutor.execute(() -> { - if (!controllerInfo.removeRequestedCommandSeqNumber(seq)) { - if (resultReceiver != null) { - resultReceiver.send(RESULT_INFO_SKIPPED, null); - } - return; - } - Session2Command.Result result = mCallback.onSessionCommand( - MediaSession2.this, controllerInfo, command, args); - if (resultReceiver != null) { - if (result == null) { - resultReceiver.send(RESULT_INFO_SKIPPED, null); - } else { - resultReceiver.send(result.getResultCode(), result.getResultData()); - } - } - }); - } - - // Called by Session2Link.onCancelCommand - void onCancelCommand(@NonNull final Controller2Link controller, final int seq) { - final ControllerInfo controllerInfo; - synchronized (mLock) { - controllerInfo = mConnectedControllers.get(controller); - } - if (controllerInfo == null) { - return; - } - controllerInfo.removeRequestedCommandSeqNumber(seq); - } - - /** - * This API is not generally intended for third party application developers. - * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a> - * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session - * Library</a> for consistent behavior across all devices. - * <p> - * Builder for {@link MediaSession2}. - * <p> - * Any incoming event from the {@link MediaController2} will be handled on the callback - * executor. If it's not set, {@link Context#getMainExecutor()} will be used by default. - */ - public static final class Builder { - private Context mContext; - private String mId; - private PendingIntent mSessionActivity; - private Executor mCallbackExecutor; - private SessionCallback mCallback; - private Bundle mExtras; - - /** - * Creates a builder for {@link MediaSession2}. - * - * @param context Context - * @throws IllegalArgumentException if context is {@code null}. - */ - public Builder(@NonNull Context context) { - if (context == null) { - throw new IllegalArgumentException("context shouldn't be null"); - } - mContext = context; - } - - /** - * Set an intent for launching UI for this Session. This can be used as a - * quick link to an ongoing media screen. The intent should be for an - * activity that may be started using {@link Context#startActivity(Intent)}. - * - * @param pi The intent to launch to show UI for this session. - * @return The Builder to allow chaining - */ - @NonNull - public Builder setSessionActivity(@Nullable PendingIntent pi) { - mSessionActivity = pi; - return this; - } - - /** - * Set ID of the session. If it's not set, an empty string will be used to create a session. - * <p> - * Use this if and only if your app supports multiple playback at the same time and also - * wants to provide external apps to have finer controls of them. - * - * @param id id of the session. Must be unique per package. - * @throws IllegalArgumentException if id is {@code null}. - * @return The Builder to allow chaining - */ - @NonNull - public Builder setId(@NonNull String id) { - if (id == null) { - throw new IllegalArgumentException("id shouldn't be null"); - } - mId = id; - return this; - } - - /** - * Set callback for the session and its executor. - * - * @param executor callback executor - * @param callback session callback. - * @return The Builder to allow chaining - */ - @NonNull - public Builder setSessionCallback(@NonNull Executor executor, - @NonNull SessionCallback callback) { - mCallbackExecutor = executor; - mCallback = callback; - return this; - } - - /** - * Set extras for the session token. If null or not set, {@link Session2Token#getExtras()} - * will return an empty {@link Bundle}. An {@link IllegalArgumentException} will be thrown - * if the bundle contains any non-framework Parcelable objects. - * - * @return The Builder to allow chaining - * @see Session2Token#getExtras() - */ - @NonNull - public Builder setExtras(@NonNull Bundle extras) { - if (extras == null) { - throw new NullPointerException("extras shouldn't be null"); - } - if (hasCustomParcelable(extras)) { - throw new IllegalArgumentException( - "extras shouldn't contain any custom parcelables"); - } - mExtras = new Bundle(extras); - return this; - } - - /** - * Build {@link MediaSession2}. - * - * @return a new session - * @throws IllegalStateException if the session with the same id is already exists for the - * package. - */ - @NonNull - public MediaSession2 build() { - if (mCallbackExecutor == null) { - mCallbackExecutor = mContext.getMainExecutor(); - } - if (mCallback == null) { - mCallback = new SessionCallback() {}; - } - if (mId == null) { - mId = ""; - } - if (mExtras == null) { - mExtras = Bundle.EMPTY; - } - MediaSession2 session2 = new MediaSession2(mContext, mId, mSessionActivity, - mCallbackExecutor, mCallback, mExtras); - - // Notify framework about the newly create session after the constructor is finished. - // Otherwise, framework may access the session before the initialization is finished. - try { - if (SdkLevel.isAtLeastS()) { - MediaCommunicationManager manager = - mContext.getSystemService(MediaCommunicationManager.class); - manager.notifySession2Created(session2.getToken()); - } else { - MediaSessionManager manager = - mContext.getSystemService(MediaSessionManager.class); - manager.notifySession2Created(session2.getToken()); - } - } catch (Exception e) { - session2.close(); - throw e; - } - - return session2; - } - } - - /** - * This API is not generally intended for third party application developers. - * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a> - * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session - * Library</a> for consistent behavior across all devices. - * <p> - * Information of a controller. - */ - public static final class ControllerInfo { - private final RemoteUserInfo mRemoteUserInfo; - private final boolean mIsTrusted; - private final Controller2Link mControllerBinder; - private final Bundle mConnectionHints; - private final Object mLock = new Object(); - //@GuardedBy("mLock") - private int mNextSeqNumber; - //@GuardedBy("mLock") - private ArrayMap<ResultReceiver, Integer> mPendingCommands; - //@GuardedBy("mLock") - private ArraySet<Integer> mRequestedCommandSeqNumbers; - - @SuppressWarnings("WeakerAccess") /* synthetic access */ - Session2CommandGroup mAllowedCommands; - - /** - * @param remoteUserInfo remote user info - * @param trusted {@code true} if trusted, {@code false} otherwise - * @param controllerBinder Controller2Link for the connected controller. - * @param connectionHints a session-specific argument sent from the controller for the - * connection. The contents of this bundle may affect the - * connection result. - */ - ControllerInfo(@NonNull RemoteUserInfo remoteUserInfo, boolean trusted, - @Nullable Controller2Link controllerBinder, @NonNull Bundle connectionHints) { - mRemoteUserInfo = remoteUserInfo; - mIsTrusted = trusted; - mControllerBinder = controllerBinder; - mConnectionHints = connectionHints; - mPendingCommands = new ArrayMap<>(); - mRequestedCommandSeqNumbers = new ArraySet<>(); - } - - /** - * @return remote user info of the controller. - */ - @NonNull - public RemoteUserInfo getRemoteUserInfo() { - return mRemoteUserInfo; - } - - /** - * @return package name of the controller. - */ - @NonNull - public String getPackageName() { - return mRemoteUserInfo.getPackageName(); - } - - /** - * @return uid of the controller. Can be a negative value if the uid cannot be obtained. - */ - public int getUid() { - return mRemoteUserInfo.getUid(); - } - - /** - * @return connection hints sent from controller. - */ - @NonNull - public Bundle getConnectionHints() { - return new Bundle(mConnectionHints); - } - - /** - * Return if the controller has granted {@code android.permission.MEDIA_CONTENT_CONTROL} or - * has a enabled notification listener so can be trusted to accept connection and incoming - * command request. - * - * @return {@code true} if the controller is trusted. - * @hide - */ - public boolean isTrusted() { - return mIsTrusted; - } - - @Override - public int hashCode() { - return Objects.hash(mControllerBinder, mRemoteUserInfo); - } - - @Override - public boolean equals(@Nullable Object obj) { - if (!(obj instanceof ControllerInfo)) return false; - if (this == obj) return true; - - ControllerInfo other = (ControllerInfo) obj; - if (mControllerBinder != null || other.mControllerBinder != null) { - return Objects.equals(mControllerBinder, other.mControllerBinder); - } - return mRemoteUserInfo.equals(other.mRemoteUserInfo); - } - - @Override - @NonNull - public String toString() { - return "ControllerInfo {pkg=" + mRemoteUserInfo.getPackageName() + ", uid=" - + mRemoteUserInfo.getUid() + ", allowedCommands=" + mAllowedCommands + "})"; - } - - void notifyConnected(Bundle connectionResult) { - if (mControllerBinder == null) return; - - try { - mControllerBinder.notifyConnected(getNextSeqNumber(), connectionResult); - } catch (RuntimeException e) { - // Controller may be died prematurely. - } - } - - void notifyDisconnected() { - if (mControllerBinder == null) return; - - try { - mControllerBinder.notifyDisconnected(getNextSeqNumber()); - } catch (RuntimeException e) { - // Controller may be died prematurely. - } - } - - void notifyPlaybackActiveChanged(boolean playbackActive) { - if (mControllerBinder == null) return; - - try { - mControllerBinder.notifyPlaybackActiveChanged(getNextSeqNumber(), playbackActive); - } catch (RuntimeException e) { - // Controller may be died prematurely. - } - } - - void sendSessionCommand(Session2Command command, Bundle args, - ResultReceiver resultReceiver) { - if (mControllerBinder == null) return; - - try { - int seq = getNextSeqNumber(); - synchronized (mLock) { - mPendingCommands.put(resultReceiver, seq); - } - mControllerBinder.sendSessionCommand(seq, command, args, resultReceiver); - } catch (RuntimeException e) { - // Controller may be died prematurely. - synchronized (mLock) { - mPendingCommands.remove(resultReceiver); - } - resultReceiver.send(RESULT_ERROR_UNKNOWN_ERROR, null); - } - } - - void cancelSessionCommand(@NonNull Object token) { - if (mControllerBinder == null) return; - Integer seq; - synchronized (mLock) { - seq = mPendingCommands.remove(token); - } - if (seq != null) { - mControllerBinder.cancelSessionCommand(seq); - } - } - - void receiveCommandResult(ResultReceiver resultReceiver) { - synchronized (mLock) { - mPendingCommands.remove(resultReceiver); - } - } - - void addRequestedCommandSeqNumber(int seq) { - synchronized (mLock) { - mRequestedCommandSeqNumbers.add(seq); - } - } - - boolean removeRequestedCommandSeqNumber(int seq) { - synchronized (mLock) { - return mRequestedCommandSeqNumbers.remove(seq); - } - } - - private int getNextSeqNumber() { - synchronized (mLock) { - return mNextSeqNumber++; - } - } - } - - /** - * This API is not generally intended for third party application developers. - * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a> - * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session - * Library</a> for consistent behavior across all devices. - * <p> - * Callback to be called for all incoming commands from {@link MediaController2}s. - */ - public abstract static class SessionCallback { - /** - * Called when a controller is created for this session. Return allowed commands for - * controller. By default it returns {@code null}. - * <p> - * You can reject the connection by returning {@code null}. In that case, controller - * receives {@link MediaController2.ControllerCallback#onDisconnected(MediaController2)} - * and cannot be used. - * <p> - * The controller hasn't connected yet in this method, so calls to the controller - * (e.g. {@link #sendSessionCommand}) would be ignored. Override {@link #onPostConnect} for - * the custom initialization for the controller instead. - * - * @param session the session for this event - * @param controller controller information. - * @return allowed commands. Can be {@code null} to reject connection. - */ - @Nullable - public Session2CommandGroup onConnect(@NonNull MediaSession2 session, - @NonNull ControllerInfo controller) { - return null; - } - - /** - * Called immediately after a controller is connected. This is a convenient method to add - * custom initialization between the session and a controller. - * <p> - * Note that calls to the controller (e.g. {@link #sendSessionCommand}) work here but don't - * work in {@link #onConnect} because the controller hasn't connected yet in - * {@link #onConnect}. - * - * @param session the session for this event - * @param controller controller information. - */ - public void onPostConnect(@NonNull MediaSession2 session, - @NonNull ControllerInfo controller) { - } - - /** - * Called when a controller is disconnected - * - * @param session the session for this event - * @param controller controller information - */ - public void onDisconnected(@NonNull MediaSession2 session, - @NonNull ControllerInfo controller) {} - - /** - * Called when a controller sent a session command. - * - * @param session the session for this event - * @param controller controller information - * @param command the session command - * @param args optional arguments - * @return the result for the session command. If {@code null}, RESULT_INFO_SKIPPED - * will be sent to the session. - */ - @Nullable - public Session2Command.Result onSessionCommand(@NonNull MediaSession2 session, - @NonNull ControllerInfo controller, @NonNull Session2Command command, - @Nullable Bundle args) { - return null; - } - - /** - * Called when the command sent to the controller is finished. - * - * @param session the session for this event - * @param controller controller information - * @param token the token got from {@link MediaSession2#sendSessionCommand} - * @param command the session command - * @param result the result of the session command - */ - public void onCommandResult(@NonNull MediaSession2 session, - @NonNull ControllerInfo controller, @NonNull Object token, - @NonNull Session2Command command, @NonNull Session2Command.Result result) {} - } - - abstract static class ForegroundServiceEventCallback { - public void onPlaybackActiveChanged(MediaSession2 session, boolean playbackActive) {} - public void onSessionClosed(MediaSession2 session) {} - } -} diff --git a/apex/media/framework/java/android/media/MediaSession2Service.java b/apex/media/framework/java/android/media/MediaSession2Service.java deleted file mode 100644 index f6fd509fd245..000000000000 --- a/apex/media/framework/java/android/media/MediaSession2Service.java +++ /dev/null @@ -1,452 +0,0 @@ -/* - * Copyright 2019 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.media; - -import static android.media.MediaConstants.KEY_CONNECTION_HINTS; -import static android.media.MediaConstants.KEY_PACKAGE_NAME; -import static android.media.MediaConstants.KEY_PID; - -import android.annotation.CallSuper; -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.app.Notification; -import android.app.NotificationManager; -import android.app.Service; -import android.content.Context; -import android.content.Intent; -import android.media.MediaSession2.ControllerInfo; -import android.media.session.MediaSessionManager; -import android.media.session.MediaSessionManager.RemoteUserInfo; -import android.os.Binder; -import android.os.Bundle; -import android.os.Handler; -import android.os.IBinder; -import android.util.ArrayMap; -import android.util.Log; - -import java.lang.ref.WeakReference; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -/** - * This API is not generally intended for third party application developers. - * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a> - * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session - * Library</a> for consistent behavior across all devices. - * <p> - * Service containing {@link MediaSession2}. - */ -public abstract class MediaSession2Service extends Service { - /** - * The {@link Intent} that must be declared as handled by the service. - */ - public static final String SERVICE_INTERFACE = "android.media.MediaSession2Service"; - - private static final String TAG = "MediaSession2Service"; - private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); - - private final MediaSession2.ForegroundServiceEventCallback mForegroundServiceEventCallback = - new MediaSession2.ForegroundServiceEventCallback() { - @Override - public void onPlaybackActiveChanged(MediaSession2 session, boolean playbackActive) { - MediaSession2Service.this.onPlaybackActiveChanged(session, playbackActive); - } - - @Override - public void onSessionClosed(MediaSession2 session) { - removeSession(session); - } - }; - - private final Object mLock = new Object(); - //@GuardedBy("mLock") - private NotificationManager mNotificationManager; - //@GuardedBy("mLock") - private MediaSessionManager mMediaSessionManager; - //@GuardedBy("mLock") - private Intent mStartSelfIntent; - //@GuardedBy("mLock") - private Map<String, MediaSession2> mSessions = new ArrayMap<>(); - //@GuardedBy("mLock") - private Map<MediaSession2, MediaNotification> mNotifications = new ArrayMap<>(); - //@GuardedBy("mLock") - private MediaSession2ServiceStub mStub; - - /** - * Called by the system when the service is first created. Do not call this method directly. - * <p> - * Override this method if you need your own initialization. Derived classes MUST call through - * to the super class's implementation of this method. - */ - @CallSuper - @Override - public void onCreate() { - super.onCreate(); - synchronized (mLock) { - mStub = new MediaSession2ServiceStub(this); - mStartSelfIntent = new Intent(this, this.getClass()); - mNotificationManager = - (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); - mMediaSessionManager = - (MediaSessionManager) getSystemService(Context.MEDIA_SESSION_SERVICE); - } - } - - @CallSuper - @Override - @Nullable - public IBinder onBind(@NonNull Intent intent) { - if (SERVICE_INTERFACE.equals(intent.getAction())) { - synchronized (mLock) { - return mStub; - } - } - return null; - } - - /** - * Called by the system to notify that it is no longer used and is being removed. Do not call - * this method directly. - * <p> - * Override this method if you need your own clean up. Derived classes MUST call through - * to the super class's implementation of this method. - */ - @CallSuper - @Override - public void onDestroy() { - super.onDestroy(); - synchronized (mLock) { - List<MediaSession2> sessions = getSessions(); - for (MediaSession2 session : sessions) { - removeSession(session); - } - mSessions.clear(); - mNotifications.clear(); - } - mStub.close(); - } - - /** - * Called when a {@link MediaController2} is created with the this service's - * {@link Session2Token}. Return the session for telling the controller which session to - * connect. Return {@code null} to reject the connection from this controller. - * <p> - * Session returned here will be added to this service automatically. You don't need to call - * {@link #addSession(MediaSession2)} for that. - * <p> - * This method is always called on the main thread. - * - * @param controllerInfo information of the controller which is trying to connect. - * @return a {@link MediaSession2} instance for the controller to connect to, or {@code null} - * to reject connection - * @see MediaSession2.Builder - * @see #getSessions() - */ - @Nullable - public abstract MediaSession2 onGetSession(@NonNull ControllerInfo controllerInfo); - - /** - * Called when notification UI needs update. Override this method to show or cancel your own - * notification UI. - * <p> - * This would be called on {@link MediaSession2}'s callback executor when playback state is - * changed. - * <p> - * With the notification returned here, the service becomes foreground service when the playback - * is started. Apps must request the permission - * {@link android.Manifest.permission#FOREGROUND_SERVICE} in order to use this API. It becomes - * background service after the playback is stopped. - * - * @param session a session that needs notification update. - * @return a {@link MediaNotification}. Can be {@code null}. - */ - @Nullable - public abstract MediaNotification onUpdateNotification(@NonNull MediaSession2 session); - - /** - * Adds a session to this service. - * <p> - * Added session will be removed automatically when it's closed, or removed when - * {@link #removeSession} is called. - * - * @param session a session to be added. - * @see #removeSession(MediaSession2) - */ - public final void addSession(@NonNull MediaSession2 session) { - if (session == null) { - throw new IllegalArgumentException("session shouldn't be null"); - } - if (session.isClosed()) { - throw new IllegalArgumentException("session is already closed"); - } - synchronized (mLock) { - MediaSession2 previousSession = mSessions.get(session.getId()); - if (previousSession != null) { - if (previousSession != session) { - Log.w(TAG, "Session ID should be unique, ID=" + session.getId() - + ", previous=" + previousSession + ", session=" + session); - } - return; - } - mSessions.put(session.getId(), session); - session.setForegroundServiceEventCallback(mForegroundServiceEventCallback); - } - } - - /** - * Removes a session from this service. - * - * @param session a session to be removed. - * @see #addSession(MediaSession2) - */ - public final void removeSession(@NonNull MediaSession2 session) { - if (session == null) { - throw new IllegalArgumentException("session shouldn't be null"); - } - MediaNotification notification; - synchronized (mLock) { - if (mSessions.get(session.getId()) != session) { - // Session isn't added or removed already. - return; - } - mSessions.remove(session.getId()); - notification = mNotifications.remove(session); - } - session.setForegroundServiceEventCallback(null); - if (notification != null) { - mNotificationManager.cancel(notification.getNotificationId()); - } - if (getSessions().isEmpty()) { - stopForeground(false); - } - } - - /** - * Gets the list of {@link MediaSession2}s that you've added to this service. - * - * @return sessions - */ - public final @NonNull List<MediaSession2> getSessions() { - List<MediaSession2> list = new ArrayList<>(); - synchronized (mLock) { - list.addAll(mSessions.values()); - } - return list; - } - - /** - * Returns the {@link MediaSessionManager}. - */ - @NonNull - MediaSessionManager getMediaSessionManager() { - synchronized (mLock) { - return mMediaSessionManager; - } - } - - /** - * Called by registered {@link MediaSession2.ForegroundServiceEventCallback} - * - * @param session session with change - * @param playbackActive {@code true} if playback is active. - */ - void onPlaybackActiveChanged(MediaSession2 session, boolean playbackActive) { - MediaNotification mediaNotification = onUpdateNotification(session); - if (mediaNotification == null) { - // The service implementation doesn't want to use the automatic start/stopForeground - // feature. - return; - } - synchronized (mLock) { - mNotifications.put(session, mediaNotification); - } - int id = mediaNotification.getNotificationId(); - Notification notification = mediaNotification.getNotification(); - if (!playbackActive) { - mNotificationManager.notify(id, notification); - return; - } - // playbackActive == true - startForegroundService(mStartSelfIntent); - startForeground(id, notification); - } - - /** - * This API is not generally intended for third party application developers. - * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a> - * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session - * Library</a> for consistent behavior across all devices. - * <p> - * Returned by {@link #onUpdateNotification(MediaSession2)} for making session service - * foreground service to keep playback running in the background. It's highly recommended to - * show media style notification here. - */ - public static class MediaNotification { - private final int mNotificationId; - private final Notification mNotification; - - /** - * Default constructor - * - * @param notificationId notification id to be used for - * {@link NotificationManager#notify(int, Notification)}. - * @param notification a notification to make session service run in the foreground. Media - * style notification is recommended here. - */ - public MediaNotification(int notificationId, @NonNull Notification notification) { - if (notification == null) { - throw new IllegalArgumentException("notification shouldn't be null"); - } - mNotificationId = notificationId; - mNotification = notification; - } - - /** - * Gets the id of the notification. - * - * @return the notification id - */ - public int getNotificationId() { - return mNotificationId; - } - - /** - * Gets the notification. - * - * @return the notification - */ - @NonNull - public Notification getNotification() { - return mNotification; - } - } - - private static final class MediaSession2ServiceStub extends IMediaSession2Service.Stub - implements AutoCloseable { - final WeakReference<MediaSession2Service> mService; - final Handler mHandler; - - MediaSession2ServiceStub(MediaSession2Service service) { - mService = new WeakReference<>(service); - mHandler = new Handler(service.getMainLooper()); - } - - @Override - public void connect(Controller2Link caller, int seq, Bundle connectionRequest) { - if (mService.get() == null) { - if (DEBUG) { - Log.d(TAG, "Service is already destroyed"); - } - return; - } - if (caller == null || connectionRequest == null) { - if (DEBUG) { - Log.d(TAG, "Ignoring calls with illegal arguments, caller=" + caller - + ", connectionRequest=" + connectionRequest); - } - return; - } - final int pid = Binder.getCallingPid(); - final int uid = Binder.getCallingUid(); - final long token = Binder.clearCallingIdentity(); - try { - mHandler.post(() -> { - boolean shouldNotifyDisconnected = true; - try { - final MediaSession2Service service = mService.get(); - if (service == null) { - if (DEBUG) { - Log.d(TAG, "Service isn't available"); - } - return; - } - - String callingPkg = connectionRequest.getString(KEY_PACKAGE_NAME); - // The Binder.getCallingPid() can be 0 for an oneway call from the - // remote process. If it's the case, use PID from the connectionRequest. - RemoteUserInfo remoteUserInfo = new RemoteUserInfo( - callingPkg, - pid == 0 ? connectionRequest.getInt(KEY_PID) : pid, - uid); - - Bundle connectionHints = connectionRequest.getBundle(KEY_CONNECTION_HINTS); - if (connectionHints == null) { - Log.w(TAG, "connectionHints shouldn't be null."); - connectionHints = Bundle.EMPTY; - } else if (MediaSession2.hasCustomParcelable(connectionHints)) { - Log.w(TAG, "connectionHints contain custom parcelable. Ignoring."); - connectionHints = Bundle.EMPTY; - } - - final ControllerInfo controllerInfo = new ControllerInfo( - remoteUserInfo, - service.getMediaSessionManager() - .isTrustedForMediaControl(remoteUserInfo), - caller, - connectionHints); - - if (DEBUG) { - Log.d(TAG, "Handling incoming connection request from the" - + " controller=" + controllerInfo); - } - - final MediaSession2 session; - session = service.onGetSession(controllerInfo); - - if (session == null) { - if (DEBUG) { - Log.d(TAG, "Rejecting incoming connection request from the" - + " controller=" + controllerInfo); - } - // Note: Trusted controllers also can be rejected according to the - // service implementation. - return; - } - service.addSession(session); - shouldNotifyDisconnected = false; - session.onConnect(caller, pid, uid, seq, connectionRequest); - } catch (Exception e) { - // Don't propagate exception in service to the controller. - Log.w(TAG, "Failed to add a session to session service", e); - } finally { - // Trick to call onDisconnected() in one place. - if (shouldNotifyDisconnected) { - if (DEBUG) { - Log.d(TAG, "Notifying the controller of its disconnection"); - } - try { - caller.notifyDisconnected(0); - } catch (RuntimeException e) { - // Controller may be died prematurely. - // Not an issue because we'll ignore it anyway. - } - } - } - }); - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override - public void close() { - mHandler.removeCallbacksAndMessages(null); - mService.clear(); - } - } -} diff --git a/apex/media/framework/java/android/media/MediaTranscodingManager.java b/apex/media/framework/java/android/media/MediaTranscodingManager.java deleted file mode 100644 index 1a84929c678f..000000000000 --- a/apex/media/framework/java/android/media/MediaTranscodingManager.java +++ /dev/null @@ -1,1752 +0,0 @@ -/* - * Copyright (C) 2019 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.media; - -import android.annotation.CallbackExecutor; -import android.annotation.IntDef; -import android.annotation.IntRange; -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.SystemApi; -import android.app.ActivityManager; -import android.content.ContentResolver; -import android.content.Context; -import android.content.res.AssetFileDescriptor; -import android.net.Uri; -import android.os.Build; -import android.os.ParcelFileDescriptor; -import android.os.RemoteException; -import android.os.ServiceSpecificException; -import android.system.Os; -import android.util.Log; - -import com.android.internal.annotations.GuardedBy; -import com.android.internal.annotations.VisibleForTesting; -import com.android.modules.annotation.MinSdk; -import com.android.modules.utils.build.SdkLevel; - -import java.io.FileNotFoundException; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.concurrent.Executor; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -/** - Android 12 introduces Compatible media transcoding feature. See - <a href="https://developer.android.com/about/versions/12/features#compatible_media_transcoding"> - Compatible media transcoding</a>. MediaTranscodingManager provides an interface to the system's media - transcoding service and can be used to transcode media files, e.g. transcoding a video from HEVC to - AVC. - - <h3>Transcoding Types</h3> - <h4>Video Transcoding</h4> - When transcoding a video file, the video track will be transcoded based on the desired track format - and the audio track will be pass through without any modification. - <p class=note> - Note that currently only support transcoding video file in mp4 format and with single video track. - - <h3>Transcoding Request</h3> - <p> - To transcode a media file, first create a {@link TranscodingRequest} through its builder class - {@link VideoTranscodingRequest.Builder}. Transcode requests are then enqueue to the manager through - {@link MediaTranscodingManager#enqueueRequest( - TranscodingRequest, Executor, OnTranscodingFinishedListener)} - TranscodeRequest are processed based on client process's priority and request priority. When a - transcode operation is completed the caller is notified via its - {@link OnTranscodingFinishedListener}. - In the meantime the caller may use the returned TranscodingSession object to cancel or check the - status of a specific transcode operation. - <p> - Here is an example where <code>Builder</code> is used to specify all parameters - - <pre class=prettyprint> - VideoTranscodingRequest request = - new VideoTranscodingRequest.Builder(srcUri, dstUri, videoFormat).build(); - }</pre> - @hide - */ -@MinSdk(Build.VERSION_CODES.S) -@SystemApi -public final class MediaTranscodingManager { - private static final String TAG = "MediaTranscodingManager"; - - /** Maximum number of retry to connect to the service. */ - private static final int CONNECT_SERVICE_RETRY_COUNT = 100; - - /** Interval between trying to reconnect to the service. */ - private static final int INTERVAL_CONNECT_SERVICE_RETRY_MS = 40; - - /** Default bpp(bits-per-pixel) to use for calculating default bitrate. */ - private static final float BPP = 0.25f; - - /** - * Listener that gets notified when a transcoding operation has finished. - * This listener gets notified regardless of how the operation finished. It is up to the - * listener implementation to check the result and take appropriate action. - */ - @FunctionalInterface - public interface OnTranscodingFinishedListener { - /** - * Called when the transcoding operation has finished. The receiver may use the - * TranscodingSession to check the result, i.e. whether the operation succeeded, was - * canceled or if an error occurred. - * - * @param session The TranscodingSession instance for the finished transcoding operation. - */ - void onTranscodingFinished(@NonNull TranscodingSession session); - } - - private final Context mContext; - private ContentResolver mContentResolver; - private final String mPackageName; - private final int mPid; - private final int mUid; - private final boolean mIsLowRamDevice; - private final ExecutorService mExecutor = Executors.newSingleThreadExecutor(); - private final HashMap<Integer, TranscodingSession> mPendingTranscodingSessions = new HashMap(); - private final Object mLock = new Object(); - @GuardedBy("mLock") - @NonNull private ITranscodingClient mTranscodingClient = null; - private static MediaTranscodingManager sMediaTranscodingManager; - - private void handleTranscodingFinished(int sessionId, TranscodingResultParcel result) { - synchronized (mPendingTranscodingSessions) { - // Gets the session associated with the sessionId and removes it from - // mPendingTranscodingSessions. - final TranscodingSession session = mPendingTranscodingSessions.remove(sessionId); - - if (session == null) { - // This should not happen in reality. - Log.e(TAG, "Session " + sessionId + " is not in Pendingsessions"); - return; - } - - // Updates the session status and result. - session.updateStatusAndResult(TranscodingSession.STATUS_FINISHED, - TranscodingSession.RESULT_SUCCESS, - TranscodingSession.ERROR_NONE); - - // Notifies client the session is done. - if (session.mListener != null && session.mListenerExecutor != null) { - session.mListenerExecutor.execute( - () -> session.mListener.onTranscodingFinished(session)); - } - } - } - - private void handleTranscodingFailed(int sessionId, int errorCode) { - synchronized (mPendingTranscodingSessions) { - // Gets the session associated with the sessionId and removes it from - // mPendingTranscodingSessions. - final TranscodingSession session = mPendingTranscodingSessions.remove(sessionId); - - if (session == null) { - // This should not happen in reality. - Log.e(TAG, "Session " + sessionId + " is not in Pendingsessions"); - return; - } - - // Updates the session status and result. - session.updateStatusAndResult(TranscodingSession.STATUS_FINISHED, - TranscodingSession.RESULT_ERROR, errorCode); - - // Notifies client the session failed. - if (session.mListener != null && session.mListenerExecutor != null) { - session.mListenerExecutor.execute( - () -> session.mListener.onTranscodingFinished(session)); - } - } - } - - private void handleTranscodingProgressUpdate(int sessionId, int newProgress) { - synchronized (mPendingTranscodingSessions) { - // Gets the session associated with the sessionId. - final TranscodingSession session = mPendingTranscodingSessions.get(sessionId); - - if (session == null) { - // This should not happen in reality. - Log.e(TAG, "Session " + sessionId + " is not in Pendingsessions"); - return; - } - - // Updates the session progress. - session.updateProgress(newProgress); - - // Notifies client the progress update. - if (session.mProgressUpdateExecutor != null - && session.mProgressUpdateListener != null) { - session.mProgressUpdateExecutor.execute( - () -> session.mProgressUpdateListener.onProgressUpdate(session, - newProgress)); - } - } - } - - private IMediaTranscodingService getService(boolean retry) { - // Do not try to get the service on pre-S. The service is lazy-start and getting the - // service could block. - if (!SdkLevel.isAtLeastS()) { - return null; - } - // Do not try to get the service on AndroidGo (low-ram) devices. - if (mIsLowRamDevice) { - return null; - } - int retryCount = !retry ? 1 : CONNECT_SERVICE_RETRY_COUNT; - Log.i(TAG, "get service with retry " + retryCount); - for (int count = 1; count <= retryCount; count++) { - Log.d(TAG, "Trying to connect to service. Try count: " + count); - IMediaTranscodingService service = IMediaTranscodingService.Stub.asInterface( - MediaFrameworkInitializer - .getMediaServiceManager() - .getMediaTranscodingServiceRegisterer() - .get()); - if (service != null) { - return service; - } - try { - // Sleep a bit before retry. - Thread.sleep(INTERVAL_CONNECT_SERVICE_RETRY_MS); - } catch (InterruptedException ie) { - /* ignore */ - } - } - Log.w(TAG, "Failed to get service"); - return null; - } - - /* - * Handle client binder died event. - * Upon receiving a binder died event of the client, we will do the following: - * 1) For the session that is running, notify the client that the session is failed with - * error code, so client could choose to retry the session or not. - * TODO(hkuang): Add a new error code to signal service died error. - * 2) For the sessions that is still pending or paused, we will resubmit the session - * once we successfully reconnect to the service and register a new client. - * 3) When trying to connect to the service and register a new client. The service may need time - * to reboot or never boot up again. So we will retry for a number of times. If we still - * could not connect, we will notify client session failure for the pending and paused - * sessions. - */ - private void onClientDied() { - synchronized (mLock) { - mTranscodingClient = null; - } - - // Delegates the session notification and retry to the executor as it may take some time. - mExecutor.execute(() -> { - // List to track the sessions that we want to retry. - List<TranscodingSession> retrySessions = new ArrayList<TranscodingSession>(); - - // First notify the client of session failure for all the running sessions. - synchronized (mPendingTranscodingSessions) { - for (Map.Entry<Integer, TranscodingSession> entry : - mPendingTranscodingSessions.entrySet()) { - TranscodingSession session = entry.getValue(); - - if (session.getStatus() == TranscodingSession.STATUS_RUNNING) { - session.updateStatusAndResult(TranscodingSession.STATUS_FINISHED, - TranscodingSession.RESULT_ERROR, - TranscodingSession.ERROR_SERVICE_DIED); - - // Remove the session from pending sessions. - mPendingTranscodingSessions.remove(entry.getKey()); - - if (session.mListener != null && session.mListenerExecutor != null) { - Log.i(TAG, "Notify client session failed"); - session.mListenerExecutor.execute( - () -> session.mListener.onTranscodingFinished(session)); - } - } else if (session.getStatus() == TranscodingSession.STATUS_PENDING - || session.getStatus() == TranscodingSession.STATUS_PAUSED) { - // Add the session to retrySessions to handle them later. - retrySessions.add(session); - } - } - } - - // Try to register with the service once it boots up. - IMediaTranscodingService service = getService(true /*retry*/); - boolean haveTranscodingClient = false; - if (service != null) { - synchronized (mLock) { - mTranscodingClient = registerClient(service); - if (mTranscodingClient != null) { - haveTranscodingClient = true; - } - } - } - - for (TranscodingSession session : retrySessions) { - // Notify the session failure if we fails to connect to the service or fail - // to retry the session. - if (!haveTranscodingClient) { - // TODO(hkuang): Return correct error code to the client. - handleTranscodingFailed(session.getSessionId(), 0 /*unused */); - } - - try { - // Do not set hasRetried for retry initiated by MediaTranscodingManager. - session.retryInternal(false /*setHasRetried*/); - } catch (Exception re) { - // TODO(hkuang): Return correct error code to the client. - handleTranscodingFailed(session.getSessionId(), 0 /*unused */); - } - } - }); - } - - private void updateStatus(int sessionId, int status) { - synchronized (mPendingTranscodingSessions) { - final TranscodingSession session = mPendingTranscodingSessions.get(sessionId); - - if (session == null) { - // This should not happen in reality. - Log.e(TAG, "Session " + sessionId + " is not in Pendingsessions"); - return; - } - - // Updates the session status. - session.updateStatus(status); - } - } - - // Just forwards all the events to the event handler. - private ITranscodingClientCallback mTranscodingClientCallback = - new ITranscodingClientCallback.Stub() { - // TODO(hkuang): Add more unit test to test difference file open mode. - @Override - public ParcelFileDescriptor openFileDescriptor(String fileUri, String mode) - throws RemoteException { - if (!mode.equals("r") && !mode.equals("w") && !mode.equals("rw")) { - Log.e(TAG, "Unsupport mode: " + mode); - return null; - } - - Uri uri = Uri.parse(fileUri); - try { - AssetFileDescriptor afd = mContentResolver.openAssetFileDescriptor(uri, - mode); - if (afd != null) { - return afd.getParcelFileDescriptor(); - } - } catch (FileNotFoundException e) { - Log.w(TAG, "Cannot find content uri: " + uri, e); - } catch (SecurityException e) { - Log.w(TAG, "Cannot open content uri: " + uri, e); - } catch (Exception e) { - Log.w(TAG, "Unknown content uri: " + uri, e); - } - return null; - } - - @Override - public void onTranscodingStarted(int sessionId) throws RemoteException { - updateStatus(sessionId, TranscodingSession.STATUS_RUNNING); - } - - @Override - public void onTranscodingPaused(int sessionId) throws RemoteException { - updateStatus(sessionId, TranscodingSession.STATUS_PAUSED); - } - - @Override - public void onTranscodingResumed(int sessionId) throws RemoteException { - updateStatus(sessionId, TranscodingSession.STATUS_RUNNING); - } - - @Override - public void onTranscodingFinished(int sessionId, TranscodingResultParcel result) - throws RemoteException { - handleTranscodingFinished(sessionId, result); - } - - @Override - public void onTranscodingFailed(int sessionId, int errorCode) - throws RemoteException { - handleTranscodingFailed(sessionId, errorCode); - } - - @Override - public void onAwaitNumberOfSessionsChanged(int sessionId, int oldAwaitNumber, - int newAwaitNumber) throws RemoteException { - //TODO(hkuang): Implement this. - } - - @Override - public void onProgressUpdate(int sessionId, int newProgress) - throws RemoteException { - handleTranscodingProgressUpdate(sessionId, newProgress); - } - }; - - private ITranscodingClient registerClient(IMediaTranscodingService service) { - synchronized (mLock) { - try { - // Registers the client with MediaTranscoding service. - mTranscodingClient = service.registerClient( - mTranscodingClientCallback, - mPackageName, - mPackageName); - - if (mTranscodingClient != null) { - mTranscodingClient.asBinder().linkToDeath(() -> onClientDied(), /* flags */ 0); - } - } catch (Exception ex) { - Log.e(TAG, "Failed to register new client due to exception " + ex); - mTranscodingClient = null; - } - } - return mTranscodingClient; - } - - /** - * @hide - */ - public MediaTranscodingManager(@NonNull Context context) { - mContext = context; - mContentResolver = mContext.getContentResolver(); - mPackageName = mContext.getPackageName(); - mUid = Os.getuid(); - mPid = Os.getpid(); - mIsLowRamDevice = mContext.getSystemService(ActivityManager.class).isLowRamDevice(); - } - - /** - * Abstract base class for all the TranscodingRequest. - * <p> TranscodingRequest encapsulates the desired configuration for the transcoding. - */ - public abstract static class TranscodingRequest { - /** - * - * Default transcoding type. - * @hide - */ - public static final int TRANSCODING_TYPE_UNKNOWN = 0; - - /** - * TRANSCODING_TYPE_VIDEO indicates that client wants to perform transcoding on a video. - * <p>Note that currently only support transcoding video file in mp4 format. - * @hide - */ - public static final int TRANSCODING_TYPE_VIDEO = 1; - - /** - * TRANSCODING_TYPE_IMAGE indicates that client wants to perform transcoding on an image. - * @hide - */ - public static final int TRANSCODING_TYPE_IMAGE = 2; - - /** @hide */ - @IntDef(prefix = {"TRANSCODING_TYPE_"}, value = { - TRANSCODING_TYPE_UNKNOWN, - TRANSCODING_TYPE_VIDEO, - TRANSCODING_TYPE_IMAGE, - }) - @Retention(RetentionPolicy.SOURCE) - public @interface TranscodingType {} - - /** - * Default value. - * - * @hide - */ - public static final int PRIORITY_UNKNOWN = 0; - /** - * PRIORITY_REALTIME indicates that the transcoding request is time-critical and that the - * client wants the transcoding result as soon as possible. - * <p> Set PRIORITY_REALTIME only if the transcoding is time-critical as it will involve - * performance penalty due to resource reallocation to prioritize the sessions with higher - * priority. - * - * @hide - */ - public static final int PRIORITY_REALTIME = 1; - - /** - * PRIORITY_OFFLINE indicates the transcoding is not time-critical and the client does not - * need the transcoding result as soon as possible. - * <p>Sessions with PRIORITY_OFFLINE will be scheduled behind PRIORITY_REALTIME. Always set - * to - * PRIORITY_OFFLINE if client does not need the result as soon as possible and could accept - * delay of the transcoding result. - * - * @hide - * - */ - public static final int PRIORITY_OFFLINE = 2; - - /** @hide */ - @IntDef(prefix = {"PRIORITY_"}, value = { - PRIORITY_UNKNOWN, - PRIORITY_REALTIME, - PRIORITY_OFFLINE, - }) - @Retention(RetentionPolicy.SOURCE) - public @interface TranscodingPriority {} - - /** Uri of the source media file. */ - private @NonNull Uri mSourceUri; - - /** Uri of the destination media file. */ - private @NonNull Uri mDestinationUri; - - /** FileDescriptor of the source media file. */ - private @Nullable ParcelFileDescriptor mSourceFileDescriptor; - - /** FileDescriptor of the destination media file. */ - private @Nullable ParcelFileDescriptor mDestinationFileDescriptor; - - /** - * The UID of the client that the TranscodingRequest is for. Only privileged caller could - * set this Uid as only they could do the transcoding on behalf of the client. - * -1 means not available. - */ - private int mClientUid = -1; - - /** - * The Pid of the client that the TranscodingRequest is for. Only privileged caller could - * set this Uid as only they could do the transcoding on behalf of the client. - * -1 means not available. - */ - private int mClientPid = -1; - - /** Type of the transcoding. */ - private @TranscodingType int mType = TRANSCODING_TYPE_UNKNOWN; - - /** Priority of the transcoding. */ - private @TranscodingPriority int mPriority = PRIORITY_UNKNOWN; - - /** - * Desired image format for the destination file. - * <p> If this is null, source file's image track will be passed through and copied to the - * destination file. - * @hide - */ - private @Nullable MediaFormat mImageFormat = null; - - @VisibleForTesting - private TranscodingTestConfig mTestConfig = null; - - /** - * Prevent public constructor access. - */ - /* package private */ TranscodingRequest() { - } - - private TranscodingRequest(Builder b) { - mSourceUri = b.mSourceUri; - mSourceFileDescriptor = b.mSourceFileDescriptor; - mDestinationUri = b.mDestinationUri; - mDestinationFileDescriptor = b.mDestinationFileDescriptor; - mClientUid = b.mClientUid; - mClientPid = b.mClientPid; - mPriority = b.mPriority; - mType = b.mType; - mTestConfig = b.mTestConfig; - } - - /** - * Return the type of the transcoding. - * @hide - */ - @TranscodingType - public int getType() { - return mType; - } - - /** Return source uri of the transcoding. */ - @NonNull - public Uri getSourceUri() { - return mSourceUri; - } - - /** - * Return source file descriptor of the transcoding. - * This will be null if client has not provided it. - */ - @Nullable - public ParcelFileDescriptor getSourceFileDescriptor() { - return mSourceFileDescriptor; - } - - /** Return the UID of the client that this request is for. -1 means not available. */ - public int getClientUid() { - return mClientUid; - } - - /** Return the PID of the client that this request is for. -1 means not available. */ - public int getClientPid() { - return mClientPid; - } - - /** Return destination uri of the transcoding. */ - @NonNull - public Uri getDestinationUri() { - return mDestinationUri; - } - - /** - * Return destination file descriptor of the transcoding. - * This will be null if client has not provided it. - */ - @Nullable - public ParcelFileDescriptor getDestinationFileDescriptor() { - return mDestinationFileDescriptor; - } - - /** - * Return priority of the transcoding. - * @hide - */ - @TranscodingPriority - public int getPriority() { - return mPriority; - } - - /** - * Return TestConfig of the transcoding. - * @hide - */ - @Nullable - public TranscodingTestConfig getTestConfig() { - return mTestConfig; - } - - abstract void writeFormatToParcel(TranscodingRequestParcel parcel); - - /* Writes the TranscodingRequest to a parcel. */ - private TranscodingRequestParcel writeToParcel(@NonNull Context context) { - TranscodingRequestParcel parcel = new TranscodingRequestParcel(); - switch (mPriority) { - case PRIORITY_OFFLINE: - parcel.priority = TranscodingSessionPriority.kUnspecified; - break; - case PRIORITY_REALTIME: - case PRIORITY_UNKNOWN: - default: - parcel.priority = TranscodingSessionPriority.kNormal; - break; - } - parcel.transcodingType = mType; - parcel.sourceFilePath = mSourceUri.toString(); - parcel.sourceFd = mSourceFileDescriptor; - parcel.destinationFilePath = mDestinationUri.toString(); - parcel.destinationFd = mDestinationFileDescriptor; - parcel.clientUid = mClientUid; - parcel.clientPid = mClientPid; - if (mClientUid < 0) { - parcel.clientPackageName = context.getPackageName(); - } else { - String packageName = context.getPackageManager().getNameForUid(mClientUid); - // PackageName is optional as some uid does not have package name. Set to - // "Unavailable" string in this case. - if (packageName == null) { - Log.w(TAG, "Failed to find package for uid: " + mClientUid); - packageName = "Unavailable"; - } - parcel.clientPackageName = packageName; - } - writeFormatToParcel(parcel); - if (mTestConfig != null) { - parcel.isForTesting = true; - parcel.testConfig = mTestConfig; - } - return parcel; - } - - /** - * Builder to build a {@link TranscodingRequest} object. - * - * @param <T> The subclass to be built. - */ - abstract static class Builder<T extends Builder<T>> { - private @NonNull Uri mSourceUri; - private @NonNull Uri mDestinationUri; - private @Nullable ParcelFileDescriptor mSourceFileDescriptor = null; - private @Nullable ParcelFileDescriptor mDestinationFileDescriptor = null; - private int mClientUid = -1; - private int mClientPid = -1; - private @TranscodingType int mType = TRANSCODING_TYPE_UNKNOWN; - private @TranscodingPriority int mPriority = PRIORITY_UNKNOWN; - private TranscodingTestConfig mTestConfig; - - abstract T self(); - - /** - * Creates a builder for building {@link TranscodingRequest}s. - * - * Client must set the source Uri. If client also provides the source fileDescriptor - * through is provided by {@link #setSourceFileDescriptor(ParcelFileDescriptor)}, - * TranscodingSession will use the fd instead of calling back to the client to open the - * sourceUri. - * - * - * @param type The transcoding type. - * @param sourceUri Content uri for the source media file. - * @param destinationUri Content uri for the destination media file. - * - */ - private Builder(@TranscodingType int type, @NonNull Uri sourceUri, - @NonNull Uri destinationUri) { - mType = type; - - if (sourceUri == null || Uri.EMPTY.equals(sourceUri)) { - throw new IllegalArgumentException( - "You must specify a non-empty source Uri."); - } - mSourceUri = sourceUri; - - if (destinationUri == null || Uri.EMPTY.equals(destinationUri)) { - throw new IllegalArgumentException( - "You must specify a non-empty destination Uri."); - } - mDestinationUri = destinationUri; - } - - /** - * Specifies the fileDescriptor opened from the source media file. - * - * This call is optional. If the source fileDescriptor is provided, TranscodingSession - * will use it directly instead of opening the uri from {@link #Builder(int, Uri, Uri)}. - * It is client's responsibility to make sure the fileDescriptor is opened from the - * source uri. - * @param fileDescriptor a {@link ParcelFileDescriptor} opened from source media file. - * @return The same builder instance. - * @throws IllegalArgumentException if fileDescriptor is invalid. - */ - @NonNull - public T setSourceFileDescriptor(@NonNull ParcelFileDescriptor fileDescriptor) { - if (fileDescriptor == null || fileDescriptor.getFd() < 0) { - throw new IllegalArgumentException( - "Invalid source descriptor."); - } - mSourceFileDescriptor = fileDescriptor; - return self(); - } - - /** - * Specifies the fileDescriptor opened from the destination media file. - * - * This call is optional. If the destination fileDescriptor is provided, - * TranscodingSession will use it directly instead of opening the source uri from - * {@link #Builder(int, Uri, Uri)} upon transcoding starts. It is client's - * responsibility to make sure the fileDescriptor is opened from the destination uri. - * @param fileDescriptor a {@link ParcelFileDescriptor} opened from destination media - * file. - * @return The same builder instance. - * @throws IllegalArgumentException if fileDescriptor is invalid. - */ - @NonNull - public T setDestinationFileDescriptor( - @NonNull ParcelFileDescriptor fileDescriptor) { - if (fileDescriptor == null || fileDescriptor.getFd() < 0) { - throw new IllegalArgumentException( - "Invalid destination descriptor."); - } - mDestinationFileDescriptor = fileDescriptor; - return self(); - } - - /** - * Specify the UID of the client that this request is for. - * <p> - * Only privilege caller with android.permission.WRITE_MEDIA_STORAGE could forward the - * pid. Note that the permission check happens on the service side upon starting the - * transcoding. If the client does not have the permission, the transcoding will fail. - * - * @param uid client Uid. - * @return The same builder instance. - * @throws IllegalArgumentException if uid is invalid. - */ - @NonNull - public T setClientUid(int uid) { - if (uid < 0) { - throw new IllegalArgumentException("Invalid Uid"); - } - mClientUid = uid; - return self(); - } - - /** - * Specify the pid of the client that this request is for. - * <p> - * Only privilege caller with android.permission.WRITE_MEDIA_STORAGE could forward the - * pid. Note that the permission check happens on the service side upon starting the - * transcoding. If the client does not have the permission, the transcoding will fail. - * - * @param pid client Pid. - * @return The same builder instance. - * @throws IllegalArgumentException if pid is invalid. - */ - @NonNull - public T setClientPid(int pid) { - if (pid < 0) { - throw new IllegalArgumentException("Invalid pid"); - } - mClientPid = pid; - return self(); - } - - /** - * Specifies the priority of the transcoding. - * - * @param priority Must be one of the {@code PRIORITY_*} - * @return The same builder instance. - * @throws IllegalArgumentException if flags is invalid. - * @hide - */ - @NonNull - public T setPriority(@TranscodingPriority int priority) { - if (priority != PRIORITY_OFFLINE && priority != PRIORITY_REALTIME) { - throw new IllegalArgumentException("Invalid priority: " + priority); - } - mPriority = priority; - return self(); - } - - /** - * Sets the delay in processing this request. - * @param config test config. - * @return The same builder instance. - * @hide - */ - @VisibleForTesting - @NonNull - public T setTestConfig(@NonNull TranscodingTestConfig config) { - mTestConfig = config; - return self(); - } - } - - /** - * Abstract base class for all the format resolvers. - */ - abstract static class MediaFormatResolver { - private @NonNull ApplicationMediaCapabilities mClientCaps; - - /** - * Prevents public constructor access. - */ - /* package private */ MediaFormatResolver() { - } - - /** - * Constructs MediaFormatResolver object. - * - * @param clientCaps An ApplicationMediaCapabilities object containing the client's - * capabilities. - */ - MediaFormatResolver(@NonNull ApplicationMediaCapabilities clientCaps) { - if (clientCaps == null) { - throw new IllegalArgumentException("Client capabilities must not be null"); - } - mClientCaps = clientCaps; - } - - /** - * Returns the client capabilities. - */ - @NonNull - /* package */ ApplicationMediaCapabilities getClientCapabilities() { - return mClientCaps; - } - - abstract boolean shouldTranscode(); - } - - /** - * VideoFormatResolver for deciding if video transcoding is needed, and if so, the track - * formats to use. - */ - public static class VideoFormatResolver extends MediaFormatResolver { - private static final int BIT_RATE = 20000000; // 20Mbps - - private MediaFormat mSrcVideoFormatHint; - private MediaFormat mSrcAudioFormatHint; - - /** - * Constructs a new VideoFormatResolver object. - * - * @param clientCaps An ApplicationMediaCapabilities object containing the client's - * capabilities. - * @param srcVideoFormatHint A MediaFormat object containing information about the - * source's video track format that could affect the - * transcoding decision. Such information could include video - * codec types, color spaces, whether special format info (eg. - * slow-motion markers) are present, etc.. If a particular - * information is not present, it will not be used to make the - * decision. - */ - public VideoFormatResolver(@NonNull ApplicationMediaCapabilities clientCaps, - @NonNull MediaFormat srcVideoFormatHint) { - super(clientCaps); - mSrcVideoFormatHint = srcVideoFormatHint; - } - - /** - * Constructs a new VideoFormatResolver object. - * - * @param clientCaps An ApplicationMediaCapabilities object containing the client's - * capabilities. - * @param srcVideoFormatHint A MediaFormat object containing information about the - * source's video track format that could affect the - * transcoding decision. Such information could include video - * codec types, color spaces, whether special format info (eg. - * slow-motion markers) are present, etc.. If a particular - * information is not present, it will not be used to make the - * decision. - * @param srcAudioFormatHint A MediaFormat object containing information about the - * source's audio track format that could affect the - * transcoding decision. - * @hide - */ - VideoFormatResolver(@NonNull ApplicationMediaCapabilities clientCaps, - @NonNull MediaFormat srcVideoFormatHint, - @NonNull MediaFormat srcAudioFormatHint) { - super(clientCaps); - mSrcVideoFormatHint = srcVideoFormatHint; - mSrcAudioFormatHint = srcAudioFormatHint; - } - - /** - * Returns whether the source content should be transcoded. - * - * @return true if the source should be transcoded. - */ - public boolean shouldTranscode() { - boolean supportHevc = getClientCapabilities().isVideoMimeTypeSupported( - MediaFormat.MIMETYPE_VIDEO_HEVC); - if (!supportHevc && MediaFormat.MIMETYPE_VIDEO_HEVC.equals( - mSrcVideoFormatHint.getString(MediaFormat.KEY_MIME))) { - return true; - } - // TODO: add more checks as needed below. - return false; - } - - /** - * Retrieves the video track format to be used on - * {@link VideoTranscodingRequest.Builder#setVideoTrackFormat(MediaFormat)} for this - * configuration. - * - * @return the video track format to be used if transcoding should be performed, - * and null otherwise. - * @throws IllegalArgumentException if the hinted source video format contains invalid - * parameters. - */ - @Nullable - public MediaFormat resolveVideoFormat() { - if (!shouldTranscode()) { - return null; - } - - MediaFormat videoTrackFormat = new MediaFormat(mSrcVideoFormatHint); - videoTrackFormat.setString(MediaFormat.KEY_MIME, MediaFormat.MIMETYPE_VIDEO_AVC); - - int width = mSrcVideoFormatHint.getInteger(MediaFormat.KEY_WIDTH, -1); - int height = mSrcVideoFormatHint.getInteger(MediaFormat.KEY_HEIGHT, -1); - if (width <= 0 || height <= 0) { - throw new IllegalArgumentException( - "Source Width and height must be larger than 0"); - } - - float frameRate = - mSrcVideoFormatHint.getNumber(MediaFormat.KEY_FRAME_RATE, 30.0) - .floatValue(); - if (frameRate <= 0) { - throw new IllegalArgumentException( - "frameRate must be larger than 0"); - } - - int bitrate = getAVCBitrate(width, height, frameRate); - videoTrackFormat.setInteger(MediaFormat.KEY_BIT_RATE, bitrate); - return videoTrackFormat; - } - - /** - * Generate a default bitrate with the fixed bpp(bits-per-pixel) 0.25. - * This maps to: - * 1080P@30fps -> 16Mbps - * 1080P@60fps-> 32Mbps - * 4K@30fps -> 62Mbps - */ - private static int getDefaultBitrate(int width, int height, float frameRate) { - return (int) (width * height * frameRate * BPP); - } - - /** - * Query the bitrate from CamcorderProfile. If there are two profiles that match the - * width/height/framerate, we will use the higher one to get better quality. - * Return default bitrate if could not find any match profile. - */ - private static int getAVCBitrate(int width, int height, float frameRate) { - int bitrate = -1; - int[] cameraIds = {0, 1}; - - // Profiles ordered in decreasing order of preference. - int[] preferQualities = { - CamcorderProfile.QUALITY_2160P, - CamcorderProfile.QUALITY_1080P, - CamcorderProfile.QUALITY_720P, - CamcorderProfile.QUALITY_480P, - CamcorderProfile.QUALITY_LOW, - }; - - for (int cameraId : cameraIds) { - for (int quality : preferQualities) { - // Check if camera id has profile for the quality level. - if (!CamcorderProfile.hasProfile(cameraId, quality)) { - continue; - } - CamcorderProfile profile = CamcorderProfile.get(cameraId, quality); - // Check the width/height/framerate/codec, also consider portrait case. - if (((width == profile.videoFrameWidth - && height == profile.videoFrameHeight) - || (height == profile.videoFrameWidth - && width == profile.videoFrameHeight)) - && (int) frameRate == profile.videoFrameRate - && profile.videoCodec == MediaRecorder.VideoEncoder.H264) { - if (bitrate < profile.videoBitRate) { - bitrate = profile.videoBitRate; - } - break; - } - } - } - - if (bitrate == -1) { - Log.w(TAG, "Failed to find CamcorderProfile for w: " + width + "h: " + height - + " fps: " - + frameRate); - bitrate = getDefaultBitrate(width, height, frameRate); - } - Log.d(TAG, "Using bitrate " + bitrate + " for " + width + " " + height + " " - + frameRate); - return bitrate; - } - - /** - * Retrieves the audio track format to be used for transcoding. - * - * @return the audio track format to be used if transcoding should be performed, and - * null otherwise. - * @hide - */ - @Nullable - public MediaFormat resolveAudioFormat() { - if (!shouldTranscode()) { - return null; - } - // Audio transcoding is not supported yet, always return null. - return null; - } - } - } - - /** - * VideoTranscodingRequest encapsulates the configuration for transcoding a video. - */ - public static final class VideoTranscodingRequest extends TranscodingRequest { - /** - * Desired output video format of the destination file. - * <p> If this is null, source file's video track will be passed through and copied to the - * destination file. - */ - private @Nullable MediaFormat mVideoTrackFormat = null; - - /** - * Desired output audio format of the destination file. - * <p> If this is null, source file's audio track will be passed through and copied to the - * destination file. - */ - private @Nullable MediaFormat mAudioTrackFormat = null; - - private VideoTranscodingRequest(VideoTranscodingRequest.Builder builder) { - super(builder); - mVideoTrackFormat = builder.mVideoTrackFormat; - mAudioTrackFormat = builder.mAudioTrackFormat; - } - - /** - * Return the video track format of the transcoding. - * This will be null if client has not specified the video track format. - */ - @NonNull - public MediaFormat getVideoTrackFormat() { - return mVideoTrackFormat; - } - - @Override - void writeFormatToParcel(TranscodingRequestParcel parcel) { - parcel.requestedVideoTrackFormat = convertToVideoTrackFormat(mVideoTrackFormat); - } - - /* Converts the MediaFormat to TranscodingVideoTrackFormat. */ - private static TranscodingVideoTrackFormat convertToVideoTrackFormat(MediaFormat format) { - if (format == null) { - throw new IllegalArgumentException("Invalid MediaFormat"); - } - - TranscodingVideoTrackFormat trackFormat = new TranscodingVideoTrackFormat(); - - if (format.containsKey(MediaFormat.KEY_MIME)) { - String mime = format.getString(MediaFormat.KEY_MIME); - if (MediaFormat.MIMETYPE_VIDEO_AVC.equals(mime)) { - trackFormat.codecType = TranscodingVideoCodecType.kAvc; - } else if (MediaFormat.MIMETYPE_VIDEO_HEVC.equals(mime)) { - trackFormat.codecType = TranscodingVideoCodecType.kHevc; - } else { - throw new UnsupportedOperationException("Only support transcode to avc/hevc"); - } - } - - if (format.containsKey(MediaFormat.KEY_BIT_RATE)) { - int bitrateBps = format.getInteger(MediaFormat.KEY_BIT_RATE); - if (bitrateBps <= 0) { - throw new IllegalArgumentException("Bitrate must be larger than 0"); - } - trackFormat.bitrateBps = bitrateBps; - } - - if (format.containsKey(MediaFormat.KEY_WIDTH) && format.containsKey( - MediaFormat.KEY_HEIGHT)) { - int width = format.getInteger(MediaFormat.KEY_WIDTH); - int height = format.getInteger(MediaFormat.KEY_HEIGHT); - if (width <= 0 || height <= 0) { - throw new IllegalArgumentException("Width and height must be larger than 0"); - } - // TODO: Validate the aspect ratio after adding scaling. - trackFormat.width = width; - trackFormat.height = height; - } - - if (format.containsKey(MediaFormat.KEY_PROFILE)) { - int profile = format.getInteger(MediaFormat.KEY_PROFILE); - if (profile <= 0) { - throw new IllegalArgumentException("Invalid codec profile"); - } - // TODO: Validate the profile according to codec type. - trackFormat.profile = profile; - } - - if (format.containsKey(MediaFormat.KEY_LEVEL)) { - int level = format.getInteger(MediaFormat.KEY_LEVEL); - if (level <= 0) { - throw new IllegalArgumentException("Invalid codec level"); - } - // TODO: Validate the level according to codec type. - trackFormat.level = level; - } - - return trackFormat; - } - - /** - * Builder class for {@link VideoTranscodingRequest}. - */ - public static final class Builder extends - TranscodingRequest.Builder<VideoTranscodingRequest.Builder> { - /** - * Desired output video format of the destination file. - * <p> If this is null, source file's video track will be passed through and - * copied to the destination file. - */ - private @Nullable MediaFormat mVideoTrackFormat = null; - - /** - * Desired output audio format of the destination file. - * <p> If this is null, source file's audio track will be passed through and copied - * to the destination file. - */ - private @Nullable MediaFormat mAudioTrackFormat = null; - - /** - * Creates a builder for building {@link VideoTranscodingRequest}s. - * - * <p> Client could only specify the settings that matters to them, e.g. codec format or - * bitrate. And by default, transcoding will preserve the original video's settings - * (bitrate, framerate, resolution) if not provided. - * <p>Note that some settings may silently fail to apply if the device does not support - * them. - * @param sourceUri Content uri for the source media file. - * @param destinationUri Content uri for the destination media file. - * @param videoFormat MediaFormat containing the settings that client wants override in - * the original video's video track. - * @throws IllegalArgumentException if videoFormat is invalid. - */ - public Builder(@NonNull Uri sourceUri, @NonNull Uri destinationUri, - @NonNull MediaFormat videoFormat) { - super(TRANSCODING_TYPE_VIDEO, sourceUri, destinationUri); - setVideoTrackFormat(videoFormat); - } - - @Override - @NonNull - public Builder setClientUid(int uid) { - super.setClientUid(uid); - return self(); - } - - @Override - @NonNull - public Builder setClientPid(int pid) { - super.setClientPid(pid); - return self(); - } - - @Override - @NonNull - public Builder setSourceFileDescriptor(@NonNull ParcelFileDescriptor fd) { - super.setSourceFileDescriptor(fd); - return self(); - } - - @Override - @NonNull - public Builder setDestinationFileDescriptor(@NonNull ParcelFileDescriptor fd) { - super.setDestinationFileDescriptor(fd); - return self(); - } - - private void setVideoTrackFormat(@NonNull MediaFormat videoFormat) { - if (videoFormat == null) { - throw new IllegalArgumentException("videoFormat must not be null"); - } - - // Check if the MediaFormat is for video by looking at the MIME type. - String mime = videoFormat.containsKey(MediaFormat.KEY_MIME) - ? videoFormat.getString(MediaFormat.KEY_MIME) : null; - if (mime == null || !mime.startsWith("video/")) { - throw new IllegalArgumentException("Invalid video format: wrong mime type"); - } - - mVideoTrackFormat = videoFormat; - } - - /** - * @return a new {@link TranscodingRequest} instance successfully initialized - * with all the parameters set on this <code>Builder</code>. - * @throws UnsupportedOperationException if the parameters set on the - * <code>Builder</code> were incompatible, or - * if they are not supported by the - * device. - */ - @NonNull - public VideoTranscodingRequest build() { - return new VideoTranscodingRequest(this); - } - - @Override - VideoTranscodingRequest.Builder self() { - return this; - } - } - } - - /** - * Handle to an enqueued transcoding operation. An instance of this class represents a single - * enqueued transcoding operation. The caller can use that instance to query the status or - * progress, and to get the result once the operation has completed. - */ - public static final class TranscodingSession { - /** The session is enqueued but not yet running. */ - public static final int STATUS_PENDING = 1; - /** The session is currently running. */ - public static final int STATUS_RUNNING = 2; - /** The session is finished. */ - public static final int STATUS_FINISHED = 3; - /** The session is paused. */ - public static final int STATUS_PAUSED = 4; - - /** @hide */ - @IntDef(prefix = { "STATUS_" }, value = { - STATUS_PENDING, - STATUS_RUNNING, - STATUS_FINISHED, - STATUS_PAUSED, - }) - @Retention(RetentionPolicy.SOURCE) - public @interface Status {} - - /** The session does not have a result yet. */ - public static final int RESULT_NONE = 1; - /** The session completed successfully. */ - public static final int RESULT_SUCCESS = 2; - /** The session encountered an error while running. */ - public static final int RESULT_ERROR = 3; - /** The session was canceled by the caller. */ - public static final int RESULT_CANCELED = 4; - - /** @hide */ - @IntDef(prefix = { "RESULT_" }, value = { - RESULT_NONE, - RESULT_SUCCESS, - RESULT_ERROR, - RESULT_CANCELED, - }) - @Retention(RetentionPolicy.SOURCE) - public @interface Result {} - - - // The error code exposed here should be in sync with: - // frameworks/av/media/libmediatranscoding/aidl/android/media/TranscodingErrorCode.aidl - /** @hide */ - @IntDef(prefix = { "TRANSCODING_SESSION_ERROR_" }, value = { - ERROR_NONE, - ERROR_DROPPED_BY_SERVICE, - ERROR_SERVICE_DIED}) - @Retention(RetentionPolicy.SOURCE) - public @interface TranscodingSessionErrorCode{} - /** - * Constant indicating that no error occurred. - */ - public static final int ERROR_NONE = 0; - - /** - * Constant indicating that the session is dropped by Transcoding service due to hitting - * the limit, e.g. too many back to back transcoding happen in a short time frame. - */ - public static final int ERROR_DROPPED_BY_SERVICE = 1; - - /** - * Constant indicating the backing transcoding service is died. Client should enqueue the - * the request again. - */ - public static final int ERROR_SERVICE_DIED = 2; - - /** Listener that gets notified when the progress changes. */ - @FunctionalInterface - public interface OnProgressUpdateListener { - /** - * Called when the progress changes. The progress is in percentage between 0 and 1, - * where 0 means the session has not yet started and 100 means that it has finished. - * - * @param session The session associated with the progress. - * @param progress The new progress ranging from 0 ~ 100 inclusive. - */ - void onProgressUpdate(@NonNull TranscodingSession session, - @IntRange(from = 0, to = 100) int progress); - } - - private final MediaTranscodingManager mManager; - private Executor mListenerExecutor; - private OnTranscodingFinishedListener mListener; - private int mSessionId = -1; - // Lock for internal state. - private final Object mLock = new Object(); - @GuardedBy("mLock") - private Executor mProgressUpdateExecutor = null; - @GuardedBy("mLock") - private OnProgressUpdateListener mProgressUpdateListener = null; - @GuardedBy("mLock") - private int mProgress = 0; - @GuardedBy("mLock") - private int mProgressUpdateInterval = 0; - @GuardedBy("mLock") - private @Status int mStatus = STATUS_PENDING; - @GuardedBy("mLock") - private @Result int mResult = RESULT_NONE; - @GuardedBy("mLock") - private @TranscodingSessionErrorCode int mErrorCode = ERROR_NONE; - @GuardedBy("mLock") - private boolean mHasRetried = false; - // The original request that associated with this session. - private final TranscodingRequest mRequest; - - private TranscodingSession( - @NonNull MediaTranscodingManager manager, - @NonNull TranscodingRequest request, - @NonNull TranscodingSessionParcel parcel, - @NonNull @CallbackExecutor Executor executor, - @NonNull OnTranscodingFinishedListener listener) { - Objects.requireNonNull(manager, "manager must not be null"); - Objects.requireNonNull(parcel, "parcel must not be null"); - Objects.requireNonNull(executor, "listenerExecutor must not be null"); - Objects.requireNonNull(listener, "listener must not be null"); - mManager = manager; - mSessionId = parcel.sessionId; - mListenerExecutor = executor; - mListener = listener; - mRequest = request; - } - - /** - * Set a progress listener. - * @param executor The executor on which listener will be invoked. - * @param listener The progress listener. - */ - public void setOnProgressUpdateListener( - @NonNull @CallbackExecutor Executor executor, - @Nullable OnProgressUpdateListener listener) { - synchronized (mLock) { - Objects.requireNonNull(executor, "listenerExecutor must not be null"); - Objects.requireNonNull(listener, "listener must not be null"); - mProgressUpdateExecutor = executor; - mProgressUpdateListener = listener; - } - } - - private void updateStatusAndResult(@Status int sessionStatus, - @Result int sessionResult, @TranscodingSessionErrorCode int errorCode) { - synchronized (mLock) { - mStatus = sessionStatus; - mResult = sessionResult; - mErrorCode = errorCode; - } - } - - /** - * Retrieve the error code associated with the RESULT_ERROR. - */ - public @TranscodingSessionErrorCode int getErrorCode() { - synchronized (mLock) { - return mErrorCode; - } - } - - /** - * Resubmit the transcoding session to the service. - * Note that only the session that fails or gets cancelled could be retried and each session - * could be retried only once. After that, Client need to enqueue a new request if they want - * to try again. - * - * @return true if successfully resubmit the job to service. False otherwise. - * @throws UnsupportedOperationException if the retry could not be fulfilled. - * @hide - */ - public boolean retry() { - return retryInternal(true /*setHasRetried*/); - } - - // TODO(hkuang): Add more test for it. - private boolean retryInternal(boolean setHasRetried) { - synchronized (mLock) { - if (mStatus == STATUS_PENDING || mStatus == STATUS_RUNNING) { - throw new UnsupportedOperationException( - "Failed to retry as session is in processing"); - } - - if (mHasRetried) { - throw new UnsupportedOperationException("Session has been retried already"); - } - - // Get the client interface. - ITranscodingClient client = mManager.getTranscodingClient(); - if (client == null) { - Log.e(TAG, "Service rebooting. Try again later"); - return false; - } - - synchronized (mManager.mPendingTranscodingSessions) { - try { - // Submits the request to MediaTranscoding service. - TranscodingSessionParcel sessionParcel = new TranscodingSessionParcel(); - if (!client.submitRequest(mRequest.writeToParcel(mManager.mContext), - sessionParcel)) { - mHasRetried = true; - throw new UnsupportedOperationException("Failed to enqueue request"); - } - - // Replace the old session id wit the new one. - mSessionId = sessionParcel.sessionId; - // Adds the new session back into pending sessions. - mManager.mPendingTranscodingSessions.put(mSessionId, this); - } catch (RemoteException re) { - return false; - } - mStatus = STATUS_PENDING; - mHasRetried = setHasRetried ? true : false; - } - } - return true; - } - - /** - * Cancels the transcoding session and notify the listener. - * If the session happened to finish before being canceled this call is effectively a no-op - * and will not update the result in that case. - */ - public void cancel() { - synchronized (mLock) { - // Check if the session is finished already. - if (mStatus != STATUS_FINISHED) { - try { - ITranscodingClient client = mManager.getTranscodingClient(); - // The client may be gone. - if (client != null) { - client.cancelSession(mSessionId); - } - } catch (RemoteException re) { - //TODO(hkuang): Find out what to do if failing to cancel the session. - Log.e(TAG, "Failed to cancel the session due to exception: " + re); - } - mStatus = STATUS_FINISHED; - mResult = RESULT_CANCELED; - - // Notifies client the session is canceled. - mListenerExecutor.execute(() -> mListener.onTranscodingFinished(this)); - } - } - } - - /** - * Gets the progress of the transcoding session. The progress is between 0 and 100, where 0 - * means that the session has not yet started and 100 means that it is finished. For the - * cancelled session, the progress will be the last updated progress before it is cancelled. - * @return The progress. - */ - @IntRange(from = 0, to = 100) - public int getProgress() { - synchronized (mLock) { - return mProgress; - } - } - - /** - * Gets the status of the transcoding session. - * @return The status. - */ - public @Status int getStatus() { - synchronized (mLock) { - return mStatus; - } - } - - /** - * Adds a client uid that is also waiting for this transcoding session. - * <p> - * Only privilege caller with android.permission.WRITE_MEDIA_STORAGE could add the - * uid. Note that the permission check happens on the service side upon starting the - * transcoding. If the client does not have the permission, the transcoding will fail. - * @param uid the additional client uid to be added. - * @return true if successfully added, false otherwise. - */ - public boolean addClientUid(int uid) { - if (uid < 0) { - throw new IllegalArgumentException("Invalid Uid"); - } - - // Get the client interface. - ITranscodingClient client = mManager.getTranscodingClient(); - if (client == null) { - Log.e(TAG, "Service is dead..."); - return false; - } - - try { - if (!client.addClientUid(mSessionId, uid)) { - Log.e(TAG, "Failed to add client uid"); - return false; - } - } catch (Exception ex) { - Log.e(TAG, "Failed to get client uids due to " + ex); - return false; - } - return true; - } - - /** - * Query all the client that waiting for this transcoding session - * @return a list containing all the client uids. - */ - @NonNull - public List<Integer> getClientUids() { - List<Integer> uidList = new ArrayList<Integer>(); - - // Get the client interface. - ITranscodingClient client = mManager.getTranscodingClient(); - if (client == null) { - Log.e(TAG, "Service is dead..."); - return uidList; - } - - try { - int[] clientUids = client.getClientUids(mSessionId); - for (int i : clientUids) { - uidList.add(i); - } - } catch (Exception ex) { - Log.e(TAG, "Failed to get client uids due to " + ex); - } - - return uidList; - } - - /** - * Gets sessionId of the transcoding session. - * @return session id. - */ - public int getSessionId() { - return mSessionId; - } - - /** - * Gets the result of the transcoding session. - * @return The result. - */ - public @Result int getResult() { - synchronized (mLock) { - return mResult; - } - } - - @Override - public String toString() { - String result; - String status; - - switch (mResult) { - case RESULT_NONE: - result = "RESULT_NONE"; - break; - case RESULT_SUCCESS: - result = "RESULT_SUCCESS"; - break; - case RESULT_ERROR: - result = "RESULT_ERROR(" + mErrorCode + ")"; - break; - case RESULT_CANCELED: - result = "RESULT_CANCELED"; - break; - default: - result = String.valueOf(mResult); - break; - } - - switch (mStatus) { - case STATUS_PENDING: - status = "STATUS_PENDING"; - break; - case STATUS_PAUSED: - status = "STATUS_PAUSED"; - break; - case STATUS_RUNNING: - status = "STATUS_RUNNING"; - break; - case STATUS_FINISHED: - status = "STATUS_FINISHED"; - break; - default: - status = String.valueOf(mStatus); - break; - } - return String.format(" session: {id: %d, status: %s, result: %s, progress: %d}", - mSessionId, status, result, mProgress); - } - - private void updateProgress(int newProgress) { - synchronized (mLock) { - mProgress = newProgress; - } - } - - private void updateStatus(int newStatus) { - synchronized (mLock) { - mStatus = newStatus; - } - } - } - - private ITranscodingClient getTranscodingClient() { - synchronized (mLock) { - return mTranscodingClient; - } - } - - /** - * Enqueues a TranscodingRequest for execution. - * <p> Upon successfully accepting the request, MediaTranscodingManager will return a - * {@link TranscodingSession} to the client. Client should use {@link TranscodingSession} to - * track the progress and get the result. - * <p> MediaTranscodingManager will return null if fails to accept the request due to service - * rebooting. Client could retry again after receiving null. - * - * @param transcodingRequest The TranscodingRequest to enqueue. - * @param listenerExecutor Executor on which the listener is notified. - * @param listener Listener to get notified when the transcoding session is finished. - * @return A TranscodingSession for this operation. - * @throws UnsupportedOperationException if the request could not be fulfilled. - */ - @Nullable - public TranscodingSession enqueueRequest( - @NonNull TranscodingRequest transcodingRequest, - @NonNull @CallbackExecutor Executor listenerExecutor, - @NonNull OnTranscodingFinishedListener listener) { - Log.i(TAG, "enqueueRequest called."); - Objects.requireNonNull(transcodingRequest, "transcodingRequest must not be null"); - Objects.requireNonNull(listenerExecutor, "listenerExecutor must not be null"); - Objects.requireNonNull(listener, "listener must not be null"); - - // Converts the request to TranscodingRequestParcel. - TranscodingRequestParcel requestParcel = transcodingRequest.writeToParcel(mContext); - - Log.i(TAG, "Getting transcoding request " + transcodingRequest.getSourceUri()); - - // Submits the request to MediaTranscoding service. - try { - TranscodingSessionParcel sessionParcel = new TranscodingSessionParcel(); - // Synchronizes the access to mPendingTranscodingSessions to make sure the session Id is - // inserted in the mPendingTranscodingSessions in the callback handler. - synchronized (mPendingTranscodingSessions) { - synchronized (mLock) { - if (mTranscodingClient == null) { - // Try to register with the service again. - IMediaTranscodingService service = getService(false /*retry*/); - if (service == null) { - Log.w(TAG, "Service rebooting. Try again later"); - return null; - } - mTranscodingClient = registerClient(service); - // If still fails, throws an exception to tell client to try later. - if (mTranscodingClient == null) { - Log.w(TAG, "Service rebooting. Try again later"); - return null; - } - } - - if (!mTranscodingClient.submitRequest(requestParcel, sessionParcel)) { - throw new UnsupportedOperationException("Failed to enqueue request"); - } - } - - // Wraps the TranscodingSessionParcel into a TranscodingSession and returns it to - // client for tracking. - TranscodingSession session = new TranscodingSession(this, transcodingRequest, - sessionParcel, - listenerExecutor, - listener); - - // Adds the new session into pending sessions. - mPendingTranscodingSessions.put(session.getSessionId(), session); - return session; - } - } catch (RemoteException ex) { - Log.w(TAG, "Service rebooting. Try again later"); - return null; - } catch (ServiceSpecificException ex) { - throw new UnsupportedOperationException( - "Failed to submit request to Transcoding service. Error: " + ex); - } - } -} diff --git a/apex/media/framework/java/android/media/ProxyDataSourceCallback.java b/apex/media/framework/java/android/media/ProxyDataSourceCallback.java deleted file mode 100644 index 14d3ce87f03d..000000000000 --- a/apex/media/framework/java/android/media/ProxyDataSourceCallback.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2019 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.media; - -import android.os.ParcelFileDescriptor; -import android.system.ErrnoException; -import android.system.Os; -import android.system.OsConstants; -import android.util.Log; - -import java.io.FileDescriptor; -import java.io.IOException; - -/** - * A DataSourceCallback that is backed by a ParcelFileDescriptor. - */ -class ProxyDataSourceCallback extends DataSourceCallback { - private static final String TAG = "TestDataSourceCallback"; - - ParcelFileDescriptor mPFD; - FileDescriptor mFD; - - ProxyDataSourceCallback(ParcelFileDescriptor pfd) throws IOException { - mPFD = pfd.dup(); - mFD = mPFD.getFileDescriptor(); - } - - @Override - public synchronized int readAt(long position, byte[] buffer, int offset, int size) - throws IOException { - try { - Os.lseek(mFD, position, OsConstants.SEEK_SET); - int ret = Os.read(mFD, buffer, offset, size); - return (ret == 0) ? END_OF_STREAM : ret; - } catch (ErrnoException e) { - throw new IOException(e); - } - } - - @Override - public synchronized long getSize() throws IOException { - return mPFD.getStatSize(); - } - - @Override - public synchronized void close() { - try { - mPFD.close(); - } catch (IOException e) { - Log.e(TAG, "Failed to close the PFD.", e); - } - } -} - diff --git a/apex/media/framework/java/android/media/RoutingDelegate.java b/apex/media/framework/java/android/media/RoutingDelegate.java deleted file mode 100644 index 23598130f391..000000000000 --- a/apex/media/framework/java/android/media/RoutingDelegate.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2018 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.media; - -import android.os.Handler; - -class RoutingDelegate implements AudioRouting.OnRoutingChangedListener { - private AudioRouting mAudioRouting; - private AudioRouting.OnRoutingChangedListener mOnRoutingChangedListener; - private Handler mHandler; - - RoutingDelegate(final AudioRouting audioRouting, - final AudioRouting.OnRoutingChangedListener listener, - Handler handler) { - mAudioRouting = audioRouting; - mOnRoutingChangedListener = listener; - mHandler = handler; - } - - public AudioRouting.OnRoutingChangedListener getListener() { - return mOnRoutingChangedListener; - } - - public Handler getHandler() { - return mHandler; - } - - @Override - public void onRoutingChanged(AudioRouting router) { - if (mOnRoutingChangedListener != null) { - mOnRoutingChangedListener.onRoutingChanged(mAudioRouting); - } - } -} diff --git a/apex/media/framework/java/android/media/Session2Command.java b/apex/media/framework/java/android/media/Session2Command.java deleted file mode 100644 index 26f4568fa7e5..000000000000 --- a/apex/media/framework/java/android/media/Session2Command.java +++ /dev/null @@ -1,218 +0,0 @@ -/* - * Copyright 2018 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.media; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.os.Bundle; -import android.os.Parcel; -import android.os.Parcelable; -import android.text.TextUtils; - -import java.util.Objects; - -/** - * This API is not generally intended for third party application developers. - * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a> - * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session - * Library</a> for consistent behavior across all devices. - * <p> - * Define a command that a {@link MediaController2} can send to a {@link MediaSession2}. - * <p> - * If {@link #getCommandCode()} isn't {@link #COMMAND_CODE_CUSTOM}), it's predefined command. - * If {@link #getCommandCode()} is {@link #COMMAND_CODE_CUSTOM}), it's custom command and - * {@link #getCustomAction()} shouldn't be {@code null}. - * <p> - * Refer to the - * <a href="{@docRoot}reference/androidx/media2/SessionCommand2.html">AndroidX SessionCommand</a> - * class for the list of valid commands. - */ -public final class Session2Command implements Parcelable { - /** - * Command code for the custom command which can be defined by string action in the - * {@link Session2Command}. - */ - public static final int COMMAND_CODE_CUSTOM = 0; - - public static final @android.annotation.NonNull Parcelable.Creator<Session2Command> CREATOR = - new Parcelable.Creator<Session2Command>() { - @Override - public Session2Command createFromParcel(Parcel in) { - return new Session2Command(in); - } - - @Override - public Session2Command[] newArray(int size) { - return new Session2Command[size]; - } - }; - - private final int mCommandCode; - // Nonnull if it's custom command - private final String mCustomAction; - private final Bundle mCustomExtras; - - /** - * Constructor for creating a command predefined in AndroidX media2. - * - * @param commandCode A command code for a command predefined in AndroidX media2. - */ - public Session2Command(int commandCode) { - if (commandCode == COMMAND_CODE_CUSTOM) { - throw new IllegalArgumentException("commandCode shouldn't be COMMAND_CODE_CUSTOM"); - } - mCommandCode = commandCode; - mCustomAction = null; - mCustomExtras = null; - } - - /** - * Constructor for creating a custom command. - * - * @param action The action of this custom command. - * @param extras An extra bundle for this custom command. - */ - public Session2Command(@NonNull String action, @Nullable Bundle extras) { - if (action == null) { - throw new IllegalArgumentException("action shouldn't be null"); - } - mCommandCode = COMMAND_CODE_CUSTOM; - mCustomAction = action; - mCustomExtras = extras; - } - - /** - * Used by parcelable creator. - */ - @SuppressWarnings("WeakerAccess") /* synthetic access */ - Session2Command(Parcel in) { - mCommandCode = in.readInt(); - mCustomAction = in.readString(); - mCustomExtras = in.readBundle(); - } - - /** - * Gets the command code of a predefined command. - * This will return {@link #COMMAND_CODE_CUSTOM} for a custom command. - */ - public int getCommandCode() { - return mCommandCode; - } - - /** - * Gets the action of a custom command. - * This will return {@code null} for a predefined command. - */ - @Nullable - public String getCustomAction() { - return mCustomAction; - } - - /** - * Gets the extra bundle of a custom command. - * This will return {@code null} for a predefined command. - */ - @Nullable - public Bundle getCustomExtras() { - return mCustomExtras; - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(@NonNull Parcel dest, int flags) { - if (dest == null) { - throw new IllegalArgumentException("parcel shouldn't be null"); - } - dest.writeInt(mCommandCode); - dest.writeString(mCustomAction); - dest.writeBundle(mCustomExtras); - } - - @Override - public boolean equals(@Nullable Object obj) { - if (!(obj instanceof Session2Command)) { - return false; - } - Session2Command other = (Session2Command) obj; - return mCommandCode == other.mCommandCode - && TextUtils.equals(mCustomAction, other.mCustomAction); - } - - @Override - public int hashCode() { - return Objects.hash(mCustomAction, mCommandCode); - } - - /** - * This API is not generally intended for third party application developers. - * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a> - * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session - * Library</a> for consistent behavior across all devices. - * <p> - * Contains the result of {@link Session2Command}. - */ - public static final class Result { - private final int mResultCode; - private final Bundle mResultData; - - /** - * Result code representing that the command is skipped or canceled. For an example, a seek - * command can be skipped if it is followed by another seek command. - */ - public static final int RESULT_INFO_SKIPPED = 1; - - /** - * Result code representing that the command is successfully completed. - */ - public static final int RESULT_SUCCESS = 0; - - /** - * Result code represents that call is ended with an unknown error. - */ - public static final int RESULT_ERROR_UNKNOWN_ERROR = -1; - - /** - * Constructor of {@link Result}. - * - * @param resultCode result code - * @param resultData result data - */ - public Result(int resultCode, @Nullable Bundle resultData) { - mResultCode = resultCode; - mResultData = resultData; - } - - /** - * Returns the result code. - */ - public int getResultCode() { - return mResultCode; - } - - /** - * Returns the result data. - */ - @Nullable - public Bundle getResultData() { - return mResultData; - } - } -} diff --git a/apex/media/framework/java/android/media/Session2CommandGroup.java b/apex/media/framework/java/android/media/Session2CommandGroup.java deleted file mode 100644 index 13aabfc45ab7..000000000000 --- a/apex/media/framework/java/android/media/Session2CommandGroup.java +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright 2018 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.media; - -import static android.media.Session2Command.COMMAND_CODE_CUSTOM; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.os.Parcel; -import android.os.Parcelable; - -import java.util.Collection; -import java.util.HashSet; -import java.util.Set; - -/** - * This API is not generally intended for third party application developers. - * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a> - * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session - * Library</a> for consistent behavior across all devices. - * <p> - * A set of {@link Session2Command} which represents a command group. - */ -public final class Session2CommandGroup implements Parcelable { - private static final String TAG = "Session2CommandGroup"; - - public static final @android.annotation.NonNull Parcelable.Creator<Session2CommandGroup> - CREATOR = new Parcelable.Creator<Session2CommandGroup>() { - @Override - public Session2CommandGroup createFromParcel(Parcel in) { - return new Session2CommandGroup(in); - } - - @Override - public Session2CommandGroup[] newArray(int size) { - return new Session2CommandGroup[size]; - } - }; - - Set<Session2Command> mCommands = new HashSet<>(); - - /** - * Creates a new Session2CommandGroup with commands copied from another object. - * - * @param commands The collection of commands to copy. - */ - @SuppressWarnings("WeakerAccess") /* synthetic access */ - Session2CommandGroup(@Nullable Collection<Session2Command> commands) { - if (commands != null) { - mCommands.addAll(commands); - } - } - - /** - * Used by parcelable creator. - */ - @SuppressWarnings("WeakerAccess") /* synthetic access */ - Session2CommandGroup(Parcel in) { - Parcelable[] commands = in.readParcelableArray(Session2Command.class.getClassLoader()); - if (commands != null) { - for (Parcelable command : commands) { - mCommands.add((Session2Command) command); - } - } - } - - /** - * Checks whether this command group has a command that matches given {@code command}. - * - * @param command A command to find. Shouldn't be {@code null}. - */ - public boolean hasCommand(@NonNull Session2Command command) { - if (command == null) { - throw new IllegalArgumentException("command shouldn't be null"); - } - return mCommands.contains(command); - } - - /** - * Checks whether this command group has a command that matches given {@code commandCode}. - * - * @param commandCode A command code to find. - * Shouldn't be {@link Session2Command#COMMAND_CODE_CUSTOM}. - */ - public boolean hasCommand(int commandCode) { - if (commandCode == COMMAND_CODE_CUSTOM) { - throw new IllegalArgumentException("Use hasCommand(Command) for custom command"); - } - for (Session2Command command : mCommands) { - if (command.getCommandCode() == commandCode) { - return true; - } - } - return false; - } - - /** - * Gets all commands of this command group. - */ - @NonNull - public Set<Session2Command> getCommands() { - return new HashSet<>(mCommands); - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(@NonNull Parcel dest, int flags) { - if (dest == null) { - throw new IllegalArgumentException("parcel shouldn't be null"); - } - dest.writeParcelableArray(mCommands.toArray(new Session2Command[0]), 0); - } - - /** - * This API is not generally intended for third party application developers. - * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a> - * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session - * Library</a> for consistent behavior across all devices. - * <p> - * Builds a {@link Session2CommandGroup} object. - */ - public static final class Builder { - private Set<Session2Command> mCommands; - - public Builder() { - mCommands = new HashSet<>(); - } - - /** - * Creates a new builder for {@link Session2CommandGroup} with commands copied from another - * {@link Session2CommandGroup} object. - * @param commandGroup - */ - public Builder(@NonNull Session2CommandGroup commandGroup) { - if (commandGroup == null) { - throw new IllegalArgumentException("command group shouldn't be null"); - } - mCommands = commandGroup.getCommands(); - } - - /** - * Adds a command to this command group. - * - * @param command A command to add. Shouldn't be {@code null}. - */ - @NonNull - public Builder addCommand(@NonNull Session2Command command) { - if (command == null) { - throw new IllegalArgumentException("command shouldn't be null"); - } - mCommands.add(command); - return this; - } - - /** - * Removes a command from this group which matches given {@code command}. - * - * @param command A command to find. Shouldn't be {@code null}. - */ - @NonNull - public Builder removeCommand(@NonNull Session2Command command) { - if (command == null) { - throw new IllegalArgumentException("command shouldn't be null"); - } - mCommands.remove(command); - return this; - } - - /** - * Builds {@link Session2CommandGroup}. - * - * @return a new {@link Session2CommandGroup}. - */ - @NonNull - public Session2CommandGroup build() { - return new Session2CommandGroup(mCommands); - } - } -} diff --git a/apex/media/framework/java/android/media/Session2Link.java b/apex/media/framework/java/android/media/Session2Link.java deleted file mode 100644 index 6e550e86a9fe..000000000000 --- a/apex/media/framework/java/android/media/Session2Link.java +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Copyright 2018 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.media; - -import android.annotation.NonNull; -import android.os.Binder; -import android.os.Bundle; -import android.os.IBinder; -import android.os.Parcel; -import android.os.Parcelable; -import android.os.RemoteException; -import android.os.ResultReceiver; -import android.util.Log; - -import java.util.Objects; - -/** - * Handles incoming commands from {@link MediaController2} to {@link MediaSession2}. - * @hide - */ -// @SystemApi -public final class Session2Link implements Parcelable { - private static final String TAG = "Session2Link"; - private static final boolean DEBUG = MediaSession2.DEBUG; - - public static final @android.annotation.NonNull Parcelable.Creator<Session2Link> CREATOR = - new Parcelable.Creator<Session2Link>() { - @Override - public Session2Link createFromParcel(Parcel in) { - return new Session2Link(in); - } - - @Override - public Session2Link[] newArray(int size) { - return new Session2Link[size]; - } - }; - - private final MediaSession2 mSession; - private final IMediaSession2 mISession; - - public Session2Link(MediaSession2 session) { - mSession = session; - mISession = new Session2Stub(); - } - - Session2Link(Parcel in) { - mSession = null; - mISession = IMediaSession2.Stub.asInterface(in.readStrongBinder()); - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeStrongBinder(mISession.asBinder()); - } - - @Override - public int hashCode() { - return mISession.asBinder().hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (!(obj instanceof Session2Link)) { - return false; - } - Session2Link other = (Session2Link) obj; - return Objects.equals(mISession.asBinder(), other.mISession.asBinder()); - } - - /** Link to death with mISession */ - public void linkToDeath(@NonNull IBinder.DeathRecipient recipient, int flags) { - if (mISession != null) { - try { - mISession.asBinder().linkToDeath(recipient, flags); - } catch (RemoteException e) { - if (DEBUG) { - Log.d(TAG, "Session died too early.", e); - } - } - } - } - - /** Unlink to death with mISession */ - public boolean unlinkToDeath(@NonNull IBinder.DeathRecipient recipient, int flags) { - if (mISession != null) { - return mISession.asBinder().unlinkToDeath(recipient, flags); - } - return true; - } - - /** Interface method for IMediaSession2.connect */ - public void connect(final Controller2Link caller, int seq, Bundle connectionRequest) { - try { - mISession.connect(caller, seq, connectionRequest); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - - /** Interface method for IMediaSession2.disconnect */ - public void disconnect(final Controller2Link caller, int seq) { - try { - mISession.disconnect(caller, seq); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - - /** Interface method for IMediaSession2.sendSessionCommand */ - public void sendSessionCommand(final Controller2Link caller, final int seq, - final Session2Command command, final Bundle args, ResultReceiver resultReceiver) { - try { - mISession.sendSessionCommand(caller, seq, command, args, resultReceiver); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - - /** Interface method for IMediaSession2.sendSessionCommand */ - public void cancelSessionCommand(final Controller2Link caller, final int seq) { - try { - mISession.cancelSessionCommand(caller, seq); - } catch (RemoteException e) { - throw new RuntimeException(e); - } - } - - /** Stub implementation for IMediaSession2.connect */ - public void onConnect(final Controller2Link caller, int pid, int uid, int seq, - Bundle connectionRequest) { - mSession.onConnect(caller, pid, uid, seq, connectionRequest); - } - - /** Stub implementation for IMediaSession2.disconnect */ - public void onDisconnect(final Controller2Link caller, int seq) { - mSession.onDisconnect(caller, seq); - } - - /** Stub implementation for IMediaSession2.sendSessionCommand */ - public void onSessionCommand(final Controller2Link caller, final int seq, - final Session2Command command, final Bundle args, ResultReceiver resultReceiver) { - mSession.onSessionCommand(caller, seq, command, args, resultReceiver); - } - - /** Stub implementation for IMediaSession2.cancelSessionCommand */ - public void onCancelCommand(final Controller2Link caller, final int seq) { - mSession.onCancelCommand(caller, seq); - } - - private class Session2Stub extends IMediaSession2.Stub { - @Override - public void connect(final Controller2Link caller, int seq, Bundle connectionRequest) { - if (caller == null || connectionRequest == null) { - return; - } - final int pid = Binder.getCallingPid(); - final int uid = Binder.getCallingUid(); - final long token = Binder.clearCallingIdentity(); - try { - Session2Link.this.onConnect(caller, pid, uid, seq, connectionRequest); - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override - public void disconnect(final Controller2Link caller, int seq) { - if (caller == null) { - return; - } - final long token = Binder.clearCallingIdentity(); - try { - Session2Link.this.onDisconnect(caller, seq); - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override - public void sendSessionCommand(final Controller2Link caller, final int seq, - final Session2Command command, final Bundle args, ResultReceiver resultReceiver) { - if (caller == null) { - return; - } - final long token = Binder.clearCallingIdentity(); - try { - Session2Link.this.onSessionCommand(caller, seq, command, args, resultReceiver); - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override - public void cancelSessionCommand(final Controller2Link caller, final int seq) { - if (caller == null) { - return; - } - final long token = Binder.clearCallingIdentity(); - try { - Session2Link.this.onCancelCommand(caller, seq); - } finally { - Binder.restoreCallingIdentity(token); - } - } - } -} diff --git a/apex/media/framework/java/android/media/Session2Token.java b/apex/media/framework/java/android/media/Session2Token.java deleted file mode 100644 index aae2e1bcb6df..000000000000 --- a/apex/media/framework/java/android/media/Session2Token.java +++ /dev/null @@ -1,272 +0,0 @@ -/* - * Copyright 2018 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.media; - -import android.annotation.IntDef; -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.os.Bundle; -import android.os.Parcel; -import android.os.Parcelable; -import android.text.TextUtils; -import android.util.Log; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.util.List; -import java.util.Objects; - -/** - * This API is not generally intended for third party application developers. - * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a> - * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session - * Library</a> for consistent behavior across all devices. - * <p> - * Represents an ongoing {@link MediaSession2} or a {@link MediaSession2Service}. - * If it's representing a session service, it may not be ongoing. - * <p> - * This may be passed to apps by the session owner to allow them to create a - * {@link MediaController2} to communicate with the session. - * <p> - * It can be also obtained by {@link android.media.session.MediaSessionManager}. - */ -public final class Session2Token implements Parcelable { - private static final String TAG = "Session2Token"; - - public static final @android.annotation.NonNull Creator<Session2Token> CREATOR = - new Creator<Session2Token>() { - @Override - public Session2Token createFromParcel(Parcel p) { - return new Session2Token(p); - } - - @Override - public Session2Token[] newArray(int size) { - return new Session2Token[size]; - } - }; - - /** - * @hide - */ - @Retention(RetentionPolicy.SOURCE) - @IntDef(prefix = "TYPE_", value = {TYPE_SESSION, TYPE_SESSION_SERVICE}) - public @interface TokenType { - } - - /** - * Type for {@link MediaSession2}. - */ - public static final int TYPE_SESSION = 0; - - /** - * Type for {@link MediaSession2Service}. - */ - public static final int TYPE_SESSION_SERVICE = 1; - - private final int mUid; - @TokenType - private final int mType; - private final String mPackageName; - private final String mServiceName; - private final Session2Link mSessionLink; - private final ComponentName mComponentName; - private final Bundle mExtras; - - /** - * Constructor for the token with type {@link #TYPE_SESSION_SERVICE}. - * - * @param context The context. - * @param serviceComponent The component name of the service. - */ - public Session2Token(@NonNull Context context, @NonNull ComponentName serviceComponent) { - if (context == null) { - throw new IllegalArgumentException("context shouldn't be null"); - } - if (serviceComponent == null) { - throw new IllegalArgumentException("serviceComponent shouldn't be null"); - } - - final PackageManager manager = context.getPackageManager(); - final int uid = getUid(manager, serviceComponent.getPackageName()); - - if (!isInterfaceDeclared(manager, MediaSession2Service.SERVICE_INTERFACE, - serviceComponent)) { - Log.w(TAG, serviceComponent + " doesn't implement MediaSession2Service."); - } - mComponentName = serviceComponent; - mPackageName = serviceComponent.getPackageName(); - mServiceName = serviceComponent.getClassName(); - mUid = uid; - mType = TYPE_SESSION_SERVICE; - mSessionLink = null; - mExtras = Bundle.EMPTY; - } - - Session2Token(int uid, int type, String packageName, Session2Link sessionLink, - @NonNull Bundle tokenExtras) { - mUid = uid; - mType = type; - mPackageName = packageName; - mServiceName = null; - mComponentName = null; - mSessionLink = sessionLink; - mExtras = tokenExtras; - } - - Session2Token(Parcel in) { - mUid = in.readInt(); - mType = in.readInt(); - mPackageName = in.readString(); - mServiceName = in.readString(); - mSessionLink = in.readParcelable(null); - mComponentName = ComponentName.unflattenFromString(in.readString()); - - Bundle extras = in.readBundle(); - if (extras == null) { - Log.w(TAG, "extras shouldn't be null."); - extras = Bundle.EMPTY; - } else if (MediaSession2.hasCustomParcelable(extras)) { - Log.w(TAG, "extras contain custom parcelable. Ignoring."); - extras = Bundle.EMPTY; - } - mExtras = extras; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(mUid); - dest.writeInt(mType); - dest.writeString(mPackageName); - dest.writeString(mServiceName); - dest.writeParcelable(mSessionLink, flags); - dest.writeString(mComponentName == null ? "" : mComponentName.flattenToString()); - dest.writeBundle(mExtras); - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public int hashCode() { - return Objects.hash(mType, mUid, mPackageName, mServiceName, mSessionLink); - } - - @Override - public boolean equals(Object obj) { - if (!(obj instanceof Session2Token)) { - return false; - } - Session2Token other = (Session2Token) obj; - return mUid == other.mUid - && TextUtils.equals(mPackageName, other.mPackageName) - && TextUtils.equals(mServiceName, other.mServiceName) - && mType == other.mType - && Objects.equals(mSessionLink, other.mSessionLink); - } - - @Override - public String toString() { - return "Session2Token {pkg=" + mPackageName + " type=" + mType - + " service=" + mServiceName + " Session2Link=" + mSessionLink + "}"; - } - - /** - * @return uid of the session - */ - public int getUid() { - return mUid; - } - - /** - * @return package name of the session - */ - @NonNull - public String getPackageName() { - return mPackageName; - } - - /** - * @return service name of the session. Can be {@code null} for {@link #TYPE_SESSION}. - */ - @Nullable - public String getServiceName() { - return mServiceName; - } - - /** - * @return type of the token - * @see #TYPE_SESSION - * @see #TYPE_SESSION_SERVICE - */ - public @TokenType int getType() { - return mType; - } - - /** - * @return extras of the token - * @see MediaSession2.Builder#setExtras(Bundle) - */ - @NonNull - public Bundle getExtras() { - return new Bundle(mExtras); - } - - Session2Link getSessionLink() { - return mSessionLink; - } - - private static boolean isInterfaceDeclared(PackageManager manager, String serviceInterface, - ComponentName serviceComponent) { - Intent serviceIntent = new Intent(serviceInterface); - // Use queryIntentServices to find services with MediaSession2Service.SERVICE_INTERFACE. - // We cannot use resolveService with intent specified class name, because resolveService - // ignores actions if Intent.setClassName() is specified. - serviceIntent.setPackage(serviceComponent.getPackageName()); - - List<ResolveInfo> list = manager.queryIntentServices( - serviceIntent, PackageManager.GET_META_DATA); - if (list != null) { - for (int i = 0; i < list.size(); i++) { - ResolveInfo resolveInfo = list.get(i); - if (resolveInfo == null || resolveInfo.serviceInfo == null) { - continue; - } - if (TextUtils.equals( - resolveInfo.serviceInfo.name, serviceComponent.getClassName())) { - return true; - } - } - } - return false; - } - - private static int getUid(PackageManager manager, String packageName) { - try { - return manager.getApplicationInfo(packageName, 0).uid; - } catch (PackageManager.NameNotFoundException e) { - throw new IllegalArgumentException("Cannot find package " + packageName); - } - } -} diff --git a/apex/media/framework/jni/android_media_MediaParserJNI.cpp b/apex/media/framework/jni/android_media_MediaParserJNI.cpp deleted file mode 100644 index c81152c0954c..000000000000 --- a/apex/media/framework/jni/android_media_MediaParserJNI.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2020, 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. - */ - -#include <jni.h> -#include <media/MediaMetrics.h> - -#define JNI_FUNCTION(RETURN_TYPE, NAME, ...) \ - extern "C" { \ - JNIEXPORT RETURN_TYPE Java_android_media_MediaParser_##NAME(JNIEnv* env, jobject thiz, \ - ##__VA_ARGS__); \ - } \ - JNIEXPORT RETURN_TYPE Java_android_media_MediaParser_##NAME(JNIEnv* env, jobject thiz, \ - ##__VA_ARGS__) - -namespace { - -constexpr char kMediaMetricsKey[] = "mediaparser"; - -constexpr char kAttributeLogSessionId[] = "android.media.mediaparser.logSessionId"; -constexpr char kAttributeParserName[] = "android.media.mediaparser.parserName"; -constexpr char kAttributeCreatedByName[] = "android.media.mediaparser.createdByName"; -constexpr char kAttributeParserPool[] = "android.media.mediaparser.parserPool"; -constexpr char kAttributeLastException[] = "android.media.mediaparser.lastException"; -constexpr char kAttributeResourceByteCount[] = "android.media.mediaparser.resourceByteCount"; -constexpr char kAttributeDurationMillis[] = "android.media.mediaparser.durationMillis"; -constexpr char kAttributeTrackMimeTypes[] = "android.media.mediaparser.trackMimeTypes"; -constexpr char kAttributeTrackCodecs[] = "android.media.mediaparser.trackCodecs"; -constexpr char kAttributeAlteredParameters[] = "android.media.mediaparser.alteredParameters"; -constexpr char kAttributeVideoWidth[] = "android.media.mediaparser.videoWidth"; -constexpr char kAttributeVideoHeight[] = "android.media.mediaparser.videoHeight"; - -// Util class to handle string resource management. -class JstringHandle { -public: - JstringHandle(JNIEnv* env, jstring value) : mEnv(env), mJstringValue(value) { - mCstringValue = env->GetStringUTFChars(value, /* isCopy= */ nullptr); - } - - ~JstringHandle() { - if (mCstringValue != nullptr) { - mEnv->ReleaseStringUTFChars(mJstringValue, mCstringValue); - } - } - - [[nodiscard]] const char* value() const { - return mCstringValue != nullptr ? mCstringValue : ""; - } - - JNIEnv* mEnv; - jstring mJstringValue; - const char* mCstringValue; -}; - -} // namespace - -JNI_FUNCTION(void, nativeSubmitMetrics, jstring logSessionIdJstring, jstring parserNameJstring, - jboolean createdByName, jstring parserPoolJstring, jstring lastExceptionJstring, - jlong resourceByteCount, jlong durationMillis, jstring trackMimeTypesJstring, - jstring trackCodecsJstring, jstring alteredParameters, jint videoWidth, - jint videoHeight) { - mediametrics_handle_t item(mediametrics_create(kMediaMetricsKey)); - mediametrics_setCString(item, kAttributeLogSessionId, - JstringHandle(env, logSessionIdJstring).value()); - mediametrics_setCString(item, kAttributeParserName, - JstringHandle(env, parserNameJstring).value()); - mediametrics_setInt32(item, kAttributeCreatedByName, createdByName ? 1 : 0); - mediametrics_setCString(item, kAttributeParserPool, - JstringHandle(env, parserPoolJstring).value()); - mediametrics_setCString(item, kAttributeLastException, - JstringHandle(env, lastExceptionJstring).value()); - mediametrics_setInt64(item, kAttributeResourceByteCount, resourceByteCount); - mediametrics_setInt64(item, kAttributeDurationMillis, durationMillis); - mediametrics_setCString(item, kAttributeTrackMimeTypes, - JstringHandle(env, trackMimeTypesJstring).value()); - mediametrics_setCString(item, kAttributeTrackCodecs, - JstringHandle(env, trackCodecsJstring).value()); - mediametrics_setCString(item, kAttributeAlteredParameters, - JstringHandle(env, alteredParameters).value()); - mediametrics_setInt32(item, kAttributeVideoWidth, videoWidth); - mediametrics_setInt32(item, kAttributeVideoHeight, videoHeight); - mediametrics_selfRecord(item); - mediametrics_delete(item); -} diff --git a/apex/media/framework/lint-baseline.xml b/apex/media/framework/lint-baseline.xml deleted file mode 100644 index e1b145083f80..000000000000 --- a/apex/media/framework/lint-baseline.xml +++ /dev/null @@ -1,312 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0"> - - <issue - id="NewApi" - message="Call requires API level 31 (current min is 29): `new android.media.ApplicationMediaCapabilities.Builder`" - errorLine1=" new ApplicationMediaCapabilities.Builder();" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="frameworks/base/apex/media/framework/java/android/media/ApplicationMediaCapabilities.java" - line="208" - column="29"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 31 (current min is 29): `new android.media.ApplicationMediaCapabilities.Builder`" - errorLine1=" ApplicationMediaCapabilities.Builder builder = new ApplicationMediaCapabilities.Builder();" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="frameworks/base/apex/media/framework/java/android/media/ApplicationMediaCapabilities.java" - line="314" - column="56"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 29): `android.os.RemoteException#rethrowFromSystemServer`" - errorLine1=" e.rethrowFromSystemServer();" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="frameworks/base/apex/media/framework/java/android/media/MediaCommunicationManager.java" - line="110" - column="15"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 29): `android.os.Parcel#writeParcelableCreator`" - errorLine1=" dest.writeParcelableCreator((Parcelable) parcelable);" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="frameworks/base/apex/media/framework/java/android/media/MediaParceledListSlice.java" - line="77" - column="14"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 29): `android.os.Parcel#readParcelableCreator`" - errorLine1=" return from.readParcelableCreator(loader);" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~"> - <location - file="frameworks/base/apex/media/framework/java/android/media/MediaParceledListSlice.java" - line="82" - column="21"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level R (current min is 29): `android.media.MediaParser.TrackData#mediaFormat`" - errorLine1=" this.mediaFormat = mediaFormat;" - errorLine2=" ~~~~~~~~~~~~~~~~"> - <location - file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java" - line="273" - column="13"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level R (current min is 29): `android.media.MediaParser.TrackData#drmInitData`" - errorLine1=" this.drmInitData = drmInitData;" - errorLine2=" ~~~~~~~~~~~~~~~~"> - <location - file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java" - line="274" - column="13"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#timeMicros`" - errorLine1=" this.timeMicros = timeMicros;" - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java" - line="295" - column="13"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#position`" - errorLine1=" this.position = position;" - errorLine2=" ~~~~~~~~~~~~~"> - <location - file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java" - line="296" - column="13"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#position`" - errorLine1=" return "[timeMicros=" + timeMicros + ", position=" + position + "]";" - errorLine2=" ~~~~~~~~"> - <location - file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java" - line="302" - column="66"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#timeMicros`" - errorLine1=" return "[timeMicros=" + timeMicros + ", position=" + position + "]";" - errorLine2=" ~~~~~~~~~~"> - <location - file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java" - line="302" - column="37"/> - </issue> - - <issue - id="NewApi" - message="Class requires API level R (current min is 29): `android.media.MediaParser.SeekPoint`" - errorLine1=" SeekPoint other = (SeekPoint) obj;" - errorLine2=" ~~~~~~~~~"> - <location - file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java" - line="313" - column="32"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#position`" - errorLine1=" return timeMicros == other.timeMicros && position == other.position;" - errorLine2=" ~~~~~~~~"> - <location - file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java" - line="314" - column="54"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#position`" - errorLine1=" return timeMicros == other.timeMicros && position == other.position;" - errorLine2=" ~~~~~~~~~~~~~~"> - <location - file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java" - line="314" - column="66"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#timeMicros`" - errorLine1=" return timeMicros == other.timeMicros && position == other.position;" - errorLine2=" ~~~~~~~~~~"> - <location - file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java" - line="314" - column="20"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#timeMicros`" - errorLine1=" return timeMicros == other.timeMicros && position == other.position;" - errorLine2=" ~~~~~~~~~~~~~~~~"> - <location - file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java" - line="314" - column="34"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#timeMicros`" - errorLine1=" int result = (int) timeMicros;" - errorLine2=" ~~~~~~~~~~"> - <location - file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java" - line="319" - column="32"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#position`" - errorLine1=" result = 31 * result + (int) position;" - errorLine2=" ~~~~~~~~"> - <location - file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java" - line="320" - column="42"/> - </issue> - - <issue - id="NewApi" - message="Class requires API level R (current min is 29): `android.media.MediaParser.InputReader`" - errorLine1=" public interface SeekableInputReader extends InputReader {" - errorLine2=" ~~~~~~~~~~~"> - <location - file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java" - line="352" - column="50"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 31 (current min is 29): `android.media.metrics.LogSessionId#LOG_SESSION_ID_NONE`" - errorLine1=" @NonNull private LogSessionId mLogSessionId = LogSessionId.LOG_SESSION_ID_NONE;" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java" - line="1071" - column="51"/> - </issue> - - <issue - id="NewApi" - message="Cast from `SeekableInputReader` to `InputReader` requires API level 30 (current min is 29)" - errorLine1=" mExoDataReader.mInputReader = seekableInputReader;" - errorLine2=" ~~~~~~~~~~~~~~~~~~~"> - <location - file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java" - line="1201" - column="39"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#position`" - errorLine1=" mPendingSeekPosition = seekPoint.position;" - errorLine2=" ~~~~~~~~~~~~~~~~~~"> - <location - file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java" - line="1287" - column="36"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#timeMicros`" - errorLine1=" mPendingSeekTimeMicros = seekPoint.timeMicros;" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~"> - <location - file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java" - line="1288" - column="38"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#position`" - errorLine1=" mExtractor.seek(seekPoint.position, seekPoint.timeMicros);" - errorLine2=" ~~~~~~~~~~~~~~~~~~"> - <location - file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java" - line="1290" - column="29"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#timeMicros`" - errorLine1=" mExtractor.seek(seekPoint.position, seekPoint.timeMicros);" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~"> - <location - file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java" - line="1290" - column="49"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level R (current min is 29): `android.media.DrmInitData.SchemeInitData#uuid`" - errorLine1=" if (schemeInitData.uuid.equals(schemeUuid)) {" - errorLine2=" ~~~~~~~~~~~~~~~~~~~"> - <location - file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java" - line="1579" - column="21"/> - </issue> - - <issue - id="NewApi" - message="Class requires API level R (current min is 29): `android.media.MediaParser.InputReader`" - errorLine1=" private static final class DataReaderAdapter implements InputReader {" - errorLine2=" ~~~~~~~~~~~"> - <location - file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java" - line="1872" - column="61"/> - </issue> - - <issue - id="NewApi" - message="Class requires API level R (current min is 29): `android.media.MediaParser.InputReader`" - errorLine1=" private static final class ParsableByteArrayAdapter implements InputReader {" - errorLine2=" ~~~~~~~~~~~"> - <location - file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java" - line="1905" - column="68"/> - </issue> - -</issues> diff --git a/apex/media/framework/updatable-media-proguard.flags b/apex/media/framework/updatable-media-proguard.flags deleted file mode 100644 index 4e7d8422bf44..000000000000 --- a/apex/media/framework/updatable-media-proguard.flags +++ /dev/null @@ -1,2 +0,0 @@ -# Keep all symbols in android.media. --keep class android.media.* {*;} diff --git a/apex/media/service/Android.bp b/apex/media/service/Android.bp deleted file mode 100644 index 271fc5312f8f..000000000000 --- a/apex/media/service/Android.bp +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2020 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 { - // See: http://go/android-license-faq - // A large-scale-change added 'default_applicable_licenses' to import - // all of the 'license_kinds' from "frameworks_base_license" - // to get the below license kinds: - // SPDX-license-identifier-Apache-2.0 - default_applicable_licenses: ["frameworks_base_license"], -} - -filegroup { - name: "service-media-s-sources", - srcs: [ - "java/**/*.java", - ], - path: "java", - visibility: ["//visibility:private"], -} - -java_sdk_library { - name: "service-media-s", - permitted_packages: [ - "com.android.server.media", - ], - defaults: ["framework-system-server-module-defaults"], - srcs: [ - ":service-media-s-sources", - ], - libs: [ - "updatable-media", - ], - sdk_version: "system_server_current", - min_sdk_version: "29", // TODO: We may need to bump this at some point. - apex_available: [ - "com.android.media", - ], -} diff --git a/apex/media/service/api/current.txt b/apex/media/service/api/current.txt deleted file mode 100644 index d802177e249b..000000000000 --- a/apex/media/service/api/current.txt +++ /dev/null @@ -1 +0,0 @@ -// Signature format: 2.0 diff --git a/apex/media/service/api/removed.txt b/apex/media/service/api/removed.txt deleted file mode 100644 index d802177e249b..000000000000 --- a/apex/media/service/api/removed.txt +++ /dev/null @@ -1 +0,0 @@ -// Signature format: 2.0 diff --git a/apex/media/service/api/system-server-current.txt b/apex/media/service/api/system-server-current.txt deleted file mode 100644 index d802177e249b..000000000000 --- a/apex/media/service/api/system-server-current.txt +++ /dev/null @@ -1 +0,0 @@ -// Signature format: 2.0 diff --git a/apex/media/service/api/system-server-removed.txt b/apex/media/service/api/system-server-removed.txt deleted file mode 100644 index d802177e249b..000000000000 --- a/apex/media/service/api/system-server-removed.txt +++ /dev/null @@ -1 +0,0 @@ -// Signature format: 2.0 diff --git a/apex/media/service/java/com/android/server/media/MediaCommunicationService.java b/apex/media/service/java/com/android/server/media/MediaCommunicationService.java deleted file mode 100644 index ed31aa3d2a39..000000000000 --- a/apex/media/service/java/com/android/server/media/MediaCommunicationService.java +++ /dev/null @@ -1,620 +0,0 @@ -/* - * Copyright 2020 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 com.android.server.media; - -import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; -import static android.os.UserHandle.ALL; -import static android.os.UserHandle.getUserHandleForUid; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.app.ActivityManager; -import android.app.NotificationManager; -import android.content.Context; -import android.content.pm.PackageManager; -import android.media.IMediaCommunicationService; -import android.media.IMediaCommunicationServiceCallback; -import android.media.MediaController2; -import android.media.MediaParceledListSlice; -import android.media.Session2CommandGroup; -import android.media.Session2Token; -import android.os.Binder; -import android.os.Handler; -import android.os.IBinder; -import android.os.Looper; -import android.os.Process; -import android.os.RemoteException; -import android.os.UserHandle; -import android.os.UserManager; -import android.util.Log; -import android.util.SparseArray; -import android.util.SparseIntArray; - -import com.android.internal.annotations.GuardedBy; -import com.android.server.SystemService; - -import java.lang.ref.WeakReference; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.concurrent.Executor; -import java.util.concurrent.Executors; -import java.util.stream.Collectors; - -/** - * A system service that manages {@link android.media.MediaSession2} creations - * and their ongoing media playback state. - * @hide - */ -public class MediaCommunicationService extends SystemService { - private static final String TAG = "MediaCommunicationService"; - private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); - - final Context mContext; - - final Object mLock = new Object(); - final Handler mHandler = new Handler(Looper.getMainLooper()); - - @GuardedBy("mLock") - private final SparseIntArray mFullUserIds = new SparseIntArray(); - @GuardedBy("mLock") - private final SparseArray<FullUserRecord> mUserRecords = new SparseArray<>(); - - final Executor mRecordExecutor = Executors.newSingleThreadExecutor(); - @GuardedBy("mLock") - final List<CallbackRecord> mCallbackRecords = new ArrayList<>(); - final NotificationManager mNotificationManager; - - public MediaCommunicationService(Context context) { - super(context); - mContext = context; - mNotificationManager = context.getSystemService(NotificationManager.class); - } - - @Override - public void onStart() { - publishBinderService(Context.MEDIA_COMMUNICATION_SERVICE, new Stub()); - updateUser(); - } - - @Override - public void onUserStarting(@NonNull TargetUser user) { - if (DEBUG) Log.d(TAG, "onUserStarting: " + user); - updateUser(); - } - - @Override - public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) { - if (DEBUG) Log.d(TAG, "onUserSwitching: " + to); - updateUser(); - } - - @Override - public void onUserStopped(@NonNull TargetUser targetUser) { - int userId = targetUser.getUserHandle().getIdentifier(); - - if (DEBUG) Log.d(TAG, "onUserStopped: " + userId); - synchronized (mLock) { - FullUserRecord user = getFullUserRecordLocked(userId); - if (user != null) { - if (user.getFullUserId() == userId) { - user.destroyAllSessions(); - mUserRecords.remove(userId); - } else { - user.destroySessionsForUser(userId); - } - } - } - updateUser(); - } - - @Nullable - CallbackRecord findCallbackRecordLocked(@Nullable IMediaCommunicationServiceCallback callback) { - if (callback == null) { - return null; - } - for (CallbackRecord record : mCallbackRecords) { - if (Objects.equals(callback.asBinder(), record.mCallback.asBinder())) { - return record; - } - } - return null; - } - - List<Session2Token> getSession2TokensLocked(int userId) { - List<Session2Token> list = new ArrayList<>(); - if (userId == ALL.getIdentifier()) { - int size = mUserRecords.size(); - for (int i = 0; i < size; i++) { - list.addAll(mUserRecords.valueAt(i).getAllSession2Tokens()); - } - } else { - FullUserRecord user = getFullUserRecordLocked(userId); - if (user != null) { - list.addAll(user.getSession2Tokens(userId)); - } - } - return list; - } - - private FullUserRecord getFullUserRecordLocked(int userId) { - int fullUserId = mFullUserIds.get(userId, -1); - if (fullUserId < 0) { - return null; - } - return mUserRecords.get(fullUserId); - } - - private boolean hasMediaControlPermission(int pid, int uid) { - // Check if it's system server or has MEDIA_CONTENT_CONTROL. - // Note that system server doesn't have MEDIA_CONTENT_CONTROL, so we need extra - // check here. - if (uid == Process.SYSTEM_UID || mContext.checkPermission( - android.Manifest.permission.MEDIA_CONTENT_CONTROL, pid, uid) - == PackageManager.PERMISSION_GRANTED) { - return true; - } else if (DEBUG) { - Log.d(TAG, "uid(" + uid + ") hasn't granted MEDIA_CONTENT_CONTROL"); - } - return false; - } - - private void updateUser() { - UserManager manager = mContext.getSystemService(UserManager.class); - List<UserHandle> allUsers = manager.getUserHandles(/*excludeDying=*/false); - - synchronized (mLock) { - mFullUserIds.clear(); - if (allUsers != null) { - for (UserHandle user : allUsers) { - UserHandle parent = manager.getProfileParent(user); - if (parent != null) { - mFullUserIds.put(user.getIdentifier(), parent.getIdentifier()); - } else { - mFullUserIds.put(user.getIdentifier(), user.getIdentifier()); - if (mUserRecords.get(user.getIdentifier()) == null) { - mUserRecords.put(user.getIdentifier(), - new FullUserRecord(user.getIdentifier())); - } - } - } - } - // Ensure that the current full user exists. - int currentFullUserId = ActivityManager.getCurrentUser(); - FullUserRecord currentFullUserRecord = mUserRecords.get(currentFullUserId); - if (currentFullUserRecord == null) { - Log.w(TAG, "Cannot find FullUserInfo for the current user " + currentFullUserId); - currentFullUserRecord = new FullUserRecord(currentFullUserId); - mUserRecords.put(currentFullUserId, currentFullUserRecord); - } - mFullUserIds.put(currentFullUserId, currentFullUserId); - } - } - - void dispatchSession2Created(Session2Token token) { - synchronized (mLock) { - for (CallbackRecord record : mCallbackRecords) { - if (record.mUserId != ALL.getIdentifier() - && record.mUserId != getUserHandleForUid(token.getUid()).getIdentifier()) { - continue; - } - try { - record.mCallback.onSession2Created(token); - } catch (RemoteException e) { - Log.w(TAG, "Failed to notify session2 token created " + record); - } - } - } - } - - void dispatchSession2Changed(int userId) { - MediaParceledListSlice<Session2Token> allSession2Tokens; - MediaParceledListSlice<Session2Token> userSession2Tokens; - - synchronized (mLock) { - allSession2Tokens = - new MediaParceledListSlice<>(getSession2TokensLocked(ALL.getIdentifier())); - userSession2Tokens = new MediaParceledListSlice<>(getSession2TokensLocked(userId)); - } - allSession2Tokens.setInlineCountLimit(1); - userSession2Tokens.setInlineCountLimit(1); - - synchronized (mLock) { - for (CallbackRecord record : mCallbackRecords) { - if (record.mUserId == ALL.getIdentifier()) { - try { - record.mCallback.onSession2Changed(allSession2Tokens); - } catch (RemoteException e) { - Log.w(TAG, "Failed to notify session2 tokens changed " + record); - } - } else if (record.mUserId == userId) { - try { - record.mCallback.onSession2Changed(userSession2Tokens); - } catch (RemoteException e) { - Log.w(TAG, "Failed to notify session2 tokens changed " + record); - } - } - } - } - } - - void onSessionDied(Session2Record session) { - if (DEBUG) { - Log.d(TAG, "Destroying " + session); - } - if (session.isClosed()) { - Log.w(TAG, "Destroying already destroyed session. Ignoring."); - return; - } - - FullUserRecord user = session.getFullUser(); - if (user != null) { - user.removeSession(session); - } - session.close(); - } - - private class Stub extends IMediaCommunicationService.Stub { - @Override - public void notifySession2Created(Session2Token sessionToken) { - final int pid = Binder.getCallingPid(); - final int uid = Binder.getCallingUid(); - final long token = Binder.clearCallingIdentity(); - - try { - if (DEBUG) { - Log.d(TAG, "Session2 is created " + sessionToken); - } - if (uid != sessionToken.getUid()) { - throw new SecurityException("Unexpected Session2Token's UID, expected=" + uid - + " but actually=" + sessionToken.getUid()); - } - FullUserRecord user; - int userId = getUserHandleForUid(sessionToken.getUid()).getIdentifier(); - synchronized (mLock) { - user = getFullUserRecordLocked(userId); - } - if (user == null) { - Log.w(TAG, "notifySession2Created: Ignore session of an unknown user"); - return; - } - user.addSession(new Session2Record(MediaCommunicationService.this, - user, sessionToken, mRecordExecutor)); - } finally { - Binder.restoreCallingIdentity(token); - } - } - - /** - * Returns if the controller's package is trusted (i.e. has either MEDIA_CONTENT_CONTROL - * permission or an enabled notification listener) - * - * @param controllerPackageName package name of the controller app - * @param controllerPid pid of the controller app - * @param controllerUid uid of the controller app - */ - @Override - public boolean isTrusted(String controllerPackageName, int controllerPid, - int controllerUid) { - final int uid = Binder.getCallingUid(); - final int userId = UserHandle.getUserHandleForUid(uid).getIdentifier(); - final long token = Binder.clearCallingIdentity(); - try { - // Don't perform check between controllerPackageName and controllerUid. - // When an (activity|service) runs on the another apps process by specifying - // android:process in the AndroidManifest.xml, then PID and UID would have the - // running process' information instead of the (activity|service) that has created - // MediaController. - // Note that we can use Context#getOpPackageName() instead of - // Context#getPackageName() for getting package name that matches with the PID/UID, - // but it doesn't tell which package has created the MediaController, so useless. - return hasMediaControlPermission(controllerPid, controllerUid) - || hasEnabledNotificationListener( - userId, controllerPackageName, controllerUid); - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override - public MediaParceledListSlice getSession2Tokens(int userId) { - final int pid = Binder.getCallingPid(); - final int uid = Binder.getCallingUid(); - final long token = Binder.clearCallingIdentity(); - - try { - // Check that they can make calls on behalf of the user and get the final user id - int resolvedUserId = handleIncomingUser(pid, uid, userId, null); - List<Session2Token> result; - synchronized (mLock) { - result = getSession2TokensLocked(resolvedUserId); - } - MediaParceledListSlice parceledListSlice = new MediaParceledListSlice<>(result); - parceledListSlice.setInlineCountLimit(1); - return parceledListSlice; - } finally { - Binder.restoreCallingIdentity(token); - } - } - - @Override - public void registerCallback(IMediaCommunicationServiceCallback callback, - String packageName) throws RemoteException { - Objects.requireNonNull(callback, "callback should not be null"); - Objects.requireNonNull(packageName, "packageName should not be null"); - - synchronized (mLock) { - if (findCallbackRecordLocked(callback) == null) { - - CallbackRecord record = new CallbackRecord(callback, packageName, - Binder.getCallingUid(), Binder.getCallingPid()); - mCallbackRecords.add(record); - try { - callback.asBinder().linkToDeath(record, 0); - } catch (RemoteException e) { - Log.w(TAG, "Failed to register callback", e); - mCallbackRecords.remove(record); - } - } else { - Log.e(TAG, "registerCallback is called with already registered callback. " - + "packageName=" + packageName); - } - } - } - - @Override - public void unregisterCallback(IMediaCommunicationServiceCallback callback) - throws RemoteException { - synchronized (mLock) { - CallbackRecord existingRecord = findCallbackRecordLocked(callback); - if (existingRecord != null) { - mCallbackRecords.remove(existingRecord); - callback.asBinder().unlinkToDeath(existingRecord, 0); - } else { - Log.e(TAG, "unregisterCallback is called with unregistered callback."); - } - } - } - - private boolean hasEnabledNotificationListener(int callingUserId, - String controllerPackageName, int controllerUid) { - int controllerUserId = UserHandle.getUserHandleForUid(controllerUid).getIdentifier(); - if (callingUserId != controllerUserId) { - // Enabled notification listener only works within the same user. - return false; - } - - if (mNotificationManager.hasEnabledNotificationListener(controllerPackageName, - UserHandle.getUserHandleForUid(controllerUid))) { - return true; - } - if (DEBUG) { - Log.d(TAG, controllerPackageName + " (uid=" + controllerUid - + ") doesn't have an enabled notification listener"); - } - return false; - } - - // Handles incoming user by checking whether the caller has permission to access the - // given user id's information or not. Permission is not necessary if the given user id is - // equal to the caller's user id, but if not, the caller needs to have the - // INTERACT_ACROSS_USERS_FULL permission. Otherwise, a security exception will be thrown. - // The return value will be the given user id, unless the given user id is - // UserHandle.CURRENT, which will return the ActivityManager.getCurrentUser() value instead. - private int handleIncomingUser(int pid, int uid, int userId, String packageName) { - int callingUserId = UserHandle.getUserHandleForUid(uid).getIdentifier(); - if (userId == callingUserId) { - return userId; - } - - boolean canInteractAcrossUsersFull = mContext.checkPermission( - INTERACT_ACROSS_USERS_FULL, pid, uid) == PackageManager.PERMISSION_GRANTED; - if (canInteractAcrossUsersFull) { - if (userId == UserHandle.CURRENT.getIdentifier()) { - return ActivityManager.getCurrentUser(); - } - return userId; - } - - throw new SecurityException("Permission denied while calling from " + packageName - + " with user id: " + userId + "; Need to run as either the calling user id (" - + callingUserId + "), or with " + INTERACT_ACROSS_USERS_FULL + " permission"); - } - } - - final class CallbackRecord implements IBinder.DeathRecipient { - private final IMediaCommunicationServiceCallback mCallback; - private final String mPackageName; - private final int mUid; - private int mPid; - private final int mUserId; - - CallbackRecord(IMediaCommunicationServiceCallback callback, - String packageName, int uid, int pid) { - mCallback = callback; - mPackageName = packageName; - mUid = uid; - mPid = pid; - mUserId = (mContext.checkPermission( - INTERACT_ACROSS_USERS_FULL, pid, uid) == PackageManager.PERMISSION_GRANTED) - ? ALL.getIdentifier() : UserHandle.getUserHandleForUid(mUid).getIdentifier(); - } - - @Override - public String toString() { - return "CallbackRecord[callback=" + mCallback + ", pkg=" + mPackageName - + ", uid=" + mUid + ", pid=" + mPid + "]"; - } - - @Override - public void binderDied() { - synchronized (mLock) { - mCallbackRecords.remove(this); - } - } - } - - final class FullUserRecord { - private final int mFullUserId; - private final Object mUserLock = new Object(); - @GuardedBy("mUserLock") - private final List<Session2Record> mSessionRecords = new ArrayList<>(); - - FullUserRecord(int fullUserId) { - mFullUserId = fullUserId; - } - - public void addSession(Session2Record record) { - synchronized (mUserLock) { - mSessionRecords.add(record); - } - mHandler.post(() -> dispatchSession2Created(record.mSessionToken)); - mHandler.post(() -> dispatchSession2Changed(mFullUserId)); - } - - private void removeSession(Session2Record record) { - synchronized (mUserLock) { - mSessionRecords.remove(record); - } - mHandler.post(() -> dispatchSession2Changed(mFullUserId)); - //TODO: Handle if the removed session was the media button session. - } - - public int getFullUserId() { - return mFullUserId; - } - - public List<Session2Token> getAllSession2Tokens() { - synchronized (mUserLock) { - return mSessionRecords.stream() - .map(Session2Record::getSessionToken) - .collect(Collectors.toList()); - } - } - - public List<Session2Token> getSession2Tokens(int userId) { - synchronized (mUserLock) { - return mSessionRecords.stream() - .filter(record -> record.getUserId() == userId) - .map(Session2Record::getSessionToken) - .collect(Collectors.toList()); - } - } - - public void destroyAllSessions() { - synchronized (mUserLock) { - for (Session2Record session : mSessionRecords) { - session.close(); - } - mSessionRecords.clear(); - } - mHandler.post(() -> dispatchSession2Changed(mFullUserId)); - } - - public void destroySessionsForUser(int userId) { - boolean changed = false; - synchronized (mUserLock) { - for (int i = mSessionRecords.size() - 1; i >= 0; i--) { - Session2Record session = mSessionRecords.get(i); - if (session.getUserId() == userId) { - mSessionRecords.remove(i); - session.close(); - changed = true; - } - } - } - if (changed) { - mHandler.post(() -> dispatchSession2Changed(mFullUserId)); - } - } - } - - static final class Session2Record { - final Session2Token mSessionToken; - final Object mSession2RecordLock = new Object(); - final WeakReference<MediaCommunicationService> mServiceRef; - final WeakReference<FullUserRecord> mFullUserRef; - @GuardedBy("mSession2RecordLock") - private final MediaController2 mController; - - @GuardedBy("mSession2RecordLock") - boolean mIsConnected; - @GuardedBy("mSession2RecordLock") - private boolean mIsClosed; - - Session2Record(MediaCommunicationService service, FullUserRecord fullUser, - Session2Token token, Executor controllerExecutor) { - mServiceRef = new WeakReference<>(service); - mFullUserRef = new WeakReference<>(fullUser); - mSessionToken = token; - mController = new MediaController2.Builder(service.getContext(), token) - .setControllerCallback(controllerExecutor, new Controller2Callback()) - .build(); - } - - public int getUserId() { - return UserHandle.getUserHandleForUid(mSessionToken.getUid()).getIdentifier(); - } - - public FullUserRecord getFullUser() { - return mFullUserRef.get(); - } - - public boolean isClosed() { - synchronized (mSession2RecordLock) { - return mIsClosed; - } - } - - public void close() { - synchronized (mSession2RecordLock) { - mIsClosed = true; - mController.close(); - } - } - - public Session2Token getSessionToken() { - return mSessionToken; - } - - private class Controller2Callback extends MediaController2.ControllerCallback { - @Override - public void onConnected(MediaController2 controller, - Session2CommandGroup allowedCommands) { - if (DEBUG) { - Log.d(TAG, "connected to " + mSessionToken + ", allowed=" + allowedCommands); - } - synchronized (mSession2RecordLock) { - mIsConnected = true; - } - } - - @Override - public void onDisconnected(MediaController2 controller) { - if (DEBUG) { - Log.d(TAG, "disconnected from " + mSessionToken); - } - synchronized (mSession2RecordLock) { - mIsConnected = false; - } - MediaCommunicationService service = mServiceRef.get(); - if (service != null) { - service.onSessionDied(Session2Record.this); - } - } - } - } -} diff --git a/api/Android.bp b/api/Android.bp index 15356bdc0797..7c1065fd7587 100644 --- a/api/Android.bp +++ b/api/Android.bp @@ -178,8 +178,10 @@ genrule { cmd: metalava_cmd + "--check-compatibility:api:released $(location :android.api.module-lib.latest) " + // Note: having "public" be the base of module-lib is not perfect -- it should - // ideally be a merged public+system), but this will help when migrating from - // MODULE_LIBS -> public. + // ideally be a merged public+system (which metalava is not currently able to generate). + // This "base" will help when migrating from MODULE_LIBS -> public, but not when + // migrating from MODULE_LIBS -> system (where it needs to instead be listed as + // an incompatibility). "--check-compatibility:base $(location :frameworks-base-api-current.txt) " + "--baseline:compatibility:released $(location :android-incompatibilities.api.module-lib.latest) " + "--update-baseline:compatibility:released $(genDir)/updated-baseline.txt " + diff --git a/boot/hiddenapi/hiddenapi-max-target-o.txt b/boot/hiddenapi/hiddenapi-max-target-o.txt index 9153426b29ab..50e0a1b45c9d 100644 --- a/boot/hiddenapi/hiddenapi-max-target-o.txt +++ b/boot/hiddenapi/hiddenapi-max-target-o.txt @@ -35446,51 +35446,6 @@ Landroid/net/IIpConnectivityMetrics$Stub;->TRANSACTION_removeNetdEventCallback:I Landroid/net/IIpConnectivityMetrics;->addNetdEventCallback(ILandroid/net/INetdEventCallback;)Z Landroid/net/IIpConnectivityMetrics;->logEvent(Landroid/net/ConnectivityMetricsEvent;)I Landroid/net/IIpConnectivityMetrics;->removeNetdEventCallback(I)Z -Landroid/net/IIpSecService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V -Landroid/net/IIpSecService$Stub$Proxy;->addAddressToTunnelInterface(ILandroid/net/LinkAddress;Ljava/lang/String;)V -Landroid/net/IIpSecService$Stub$Proxy;->allocateSecurityParameterIndex(Ljava/lang/String;ILandroid/os/IBinder;)Landroid/net/IpSecSpiResponse; -Landroid/net/IIpSecService$Stub$Proxy;->applyTransportModeTransform(Landroid/os/ParcelFileDescriptor;II)V -Landroid/net/IIpSecService$Stub$Proxy;->applyTunnelModeTransform(IIILjava/lang/String;)V -Landroid/net/IIpSecService$Stub$Proxy;->closeUdpEncapsulationSocket(I)V -Landroid/net/IIpSecService$Stub$Proxy;->createTransform(Landroid/net/IpSecConfig;Landroid/os/IBinder;Ljava/lang/String;)Landroid/net/IpSecTransformResponse; -Landroid/net/IIpSecService$Stub$Proxy;->createTunnelInterface(Ljava/lang/String;Ljava/lang/String;Landroid/net/Network;Landroid/os/IBinder;Ljava/lang/String;)Landroid/net/IpSecTunnelInterfaceResponse; -Landroid/net/IIpSecService$Stub$Proxy;->deleteTransform(I)V -Landroid/net/IIpSecService$Stub$Proxy;->deleteTunnelInterface(ILjava/lang/String;)V -Landroid/net/IIpSecService$Stub$Proxy;->getInterfaceDescriptor()Ljava/lang/String; -Landroid/net/IIpSecService$Stub$Proxy;->mRemote:Landroid/os/IBinder; -Landroid/net/IIpSecService$Stub$Proxy;->openUdpEncapsulationSocket(ILandroid/os/IBinder;)Landroid/net/IpSecUdpEncapResponse; -Landroid/net/IIpSecService$Stub$Proxy;->releaseSecurityParameterIndex(I)V -Landroid/net/IIpSecService$Stub$Proxy;->removeAddressFromTunnelInterface(ILandroid/net/LinkAddress;Ljava/lang/String;)V -Landroid/net/IIpSecService$Stub$Proxy;->removeTransportModeTransforms(Landroid/os/ParcelFileDescriptor;)V -Landroid/net/IIpSecService$Stub;-><init>()V -Landroid/net/IIpSecService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/IIpSecService; -Landroid/net/IIpSecService$Stub;->DESCRIPTOR:Ljava/lang/String; -Landroid/net/IIpSecService$Stub;->TRANSACTION_addAddressToTunnelInterface:I -Landroid/net/IIpSecService$Stub;->TRANSACTION_allocateSecurityParameterIndex:I -Landroid/net/IIpSecService$Stub;->TRANSACTION_applyTransportModeTransform:I -Landroid/net/IIpSecService$Stub;->TRANSACTION_applyTunnelModeTransform:I -Landroid/net/IIpSecService$Stub;->TRANSACTION_closeUdpEncapsulationSocket:I -Landroid/net/IIpSecService$Stub;->TRANSACTION_createTransform:I -Landroid/net/IIpSecService$Stub;->TRANSACTION_createTunnelInterface:I -Landroid/net/IIpSecService$Stub;->TRANSACTION_deleteTransform:I -Landroid/net/IIpSecService$Stub;->TRANSACTION_deleteTunnelInterface:I -Landroid/net/IIpSecService$Stub;->TRANSACTION_openUdpEncapsulationSocket:I -Landroid/net/IIpSecService$Stub;->TRANSACTION_releaseSecurityParameterIndex:I -Landroid/net/IIpSecService$Stub;->TRANSACTION_removeAddressFromTunnelInterface:I -Landroid/net/IIpSecService$Stub;->TRANSACTION_removeTransportModeTransforms:I -Landroid/net/IIpSecService;->addAddressToTunnelInterface(ILandroid/net/LinkAddress;Ljava/lang/String;)V -Landroid/net/IIpSecService;->allocateSecurityParameterIndex(Ljava/lang/String;ILandroid/os/IBinder;)Landroid/net/IpSecSpiResponse; -Landroid/net/IIpSecService;->applyTransportModeTransform(Landroid/os/ParcelFileDescriptor;II)V -Landroid/net/IIpSecService;->applyTunnelModeTransform(IIILjava/lang/String;)V -Landroid/net/IIpSecService;->closeUdpEncapsulationSocket(I)V -Landroid/net/IIpSecService;->createTransform(Landroid/net/IpSecConfig;Landroid/os/IBinder;Ljava/lang/String;)Landroid/net/IpSecTransformResponse; -Landroid/net/IIpSecService;->createTunnelInterface(Ljava/lang/String;Ljava/lang/String;Landroid/net/Network;Landroid/os/IBinder;Ljava/lang/String;)Landroid/net/IpSecTunnelInterfaceResponse; -Landroid/net/IIpSecService;->deleteTransform(I)V -Landroid/net/IIpSecService;->deleteTunnelInterface(ILjava/lang/String;)V -Landroid/net/IIpSecService;->openUdpEncapsulationSocket(ILandroid/os/IBinder;)Landroid/net/IpSecUdpEncapResponse; -Landroid/net/IIpSecService;->releaseSecurityParameterIndex(I)V -Landroid/net/IIpSecService;->removeAddressFromTunnelInterface(ILandroid/net/LinkAddress;Ljava/lang/String;)V -Landroid/net/IIpSecService;->removeTransportModeTransforms(Landroid/os/ParcelFileDescriptor;)V Landroid/net/INetd$Stub$Proxy;-><init>(Landroid/os/IBinder;)V Landroid/net/INetd$Stub$Proxy;->addVirtualTunnelInterface(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;II)V Landroid/net/INetd$Stub$Proxy;->bandwidthEnableDataSaver(Z)Z @@ -35914,174 +35869,6 @@ Landroid/net/InterfaceConfiguration;->mFlags:Ljava/util/HashSet; Landroid/net/InterfaceConfiguration;->mHwAddr:Ljava/lang/String; Landroid/net/InterfaceConfiguration;->setHardwareAddress(Ljava/lang/String;)V Landroid/net/InterfaceConfiguration;->validateFlag(Ljava/lang/String;)V -Landroid/net/IpSecAlgorithm;->checkValidOrThrow(Ljava/lang/String;II)V -Landroid/net/IpSecAlgorithm;->CRYPT_NULL:Ljava/lang/String; -Landroid/net/IpSecAlgorithm;->equals(Landroid/net/IpSecAlgorithm;Landroid/net/IpSecAlgorithm;)Z -Landroid/net/IpSecAlgorithm;->isAead()Z -Landroid/net/IpSecAlgorithm;->isAuthentication()Z -Landroid/net/IpSecAlgorithm;->isEncryption()Z -Landroid/net/IpSecAlgorithm;->isUnsafeBuild()Z -Landroid/net/IpSecAlgorithm;->mKey:[B -Landroid/net/IpSecAlgorithm;->mName:Ljava/lang/String; -Landroid/net/IpSecAlgorithm;->mTruncLenBits:I -Landroid/net/IpSecAlgorithm;->TAG:Ljava/lang/String; -Landroid/net/IpSecConfig;-><init>()V -Landroid/net/IpSecConfig;-><init>(Landroid/net/IpSecConfig;)V -Landroid/net/IpSecConfig;-><init>(Landroid/os/Parcel;)V -Landroid/net/IpSecConfig;->CREATOR:Landroid/os/Parcelable$Creator; -Landroid/net/IpSecConfig;->equals(Landroid/net/IpSecConfig;Landroid/net/IpSecConfig;)Z -Landroid/net/IpSecConfig;->getAuthenticatedEncryption()Landroid/net/IpSecAlgorithm; -Landroid/net/IpSecConfig;->getAuthentication()Landroid/net/IpSecAlgorithm; -Landroid/net/IpSecConfig;->getDestinationAddress()Ljava/lang/String; -Landroid/net/IpSecConfig;->getEncapRemotePort()I -Landroid/net/IpSecConfig;->getEncapSocketResourceId()I -Landroid/net/IpSecConfig;->getEncapType()I -Landroid/net/IpSecConfig;->getEncryption()Landroid/net/IpSecAlgorithm; -Landroid/net/IpSecConfig;->getMarkMask()I -Landroid/net/IpSecConfig;->getMarkValue()I -Landroid/net/IpSecConfig;->getMode()I -Landroid/net/IpSecConfig;->getNattKeepaliveInterval()I -Landroid/net/IpSecConfig;->getNetwork()Landroid/net/Network; -Landroid/net/IpSecConfig;->getSourceAddress()Ljava/lang/String; -Landroid/net/IpSecConfig;->getSpiResourceId()I -Landroid/net/IpSecConfig;->mAuthenticatedEncryption:Landroid/net/IpSecAlgorithm; -Landroid/net/IpSecConfig;->mAuthentication:Landroid/net/IpSecAlgorithm; -Landroid/net/IpSecConfig;->mDestinationAddress:Ljava/lang/String; -Landroid/net/IpSecConfig;->mEncapRemotePort:I -Landroid/net/IpSecConfig;->mEncapSocketResourceId:I -Landroid/net/IpSecConfig;->mEncapType:I -Landroid/net/IpSecConfig;->mEncryption:Landroid/net/IpSecAlgorithm; -Landroid/net/IpSecConfig;->mMarkMask:I -Landroid/net/IpSecConfig;->mMarkValue:I -Landroid/net/IpSecConfig;->mMode:I -Landroid/net/IpSecConfig;->mNattKeepaliveInterval:I -Landroid/net/IpSecConfig;->mNetwork:Landroid/net/Network; -Landroid/net/IpSecConfig;->mSourceAddress:Ljava/lang/String; -Landroid/net/IpSecConfig;->mSpiResourceId:I -Landroid/net/IpSecConfig;->setAuthenticatedEncryption(Landroid/net/IpSecAlgorithm;)V -Landroid/net/IpSecConfig;->setAuthentication(Landroid/net/IpSecAlgorithm;)V -Landroid/net/IpSecConfig;->setDestinationAddress(Ljava/lang/String;)V -Landroid/net/IpSecConfig;->setEncapRemotePort(I)V -Landroid/net/IpSecConfig;->setEncapSocketResourceId(I)V -Landroid/net/IpSecConfig;->setEncapType(I)V -Landroid/net/IpSecConfig;->setEncryption(Landroid/net/IpSecAlgorithm;)V -Landroid/net/IpSecConfig;->setMarkMask(I)V -Landroid/net/IpSecConfig;->setMarkValue(I)V -Landroid/net/IpSecConfig;->setMode(I)V -Landroid/net/IpSecConfig;->setNattKeepaliveInterval(I)V -Landroid/net/IpSecConfig;->setNetwork(Landroid/net/Network;)V -Landroid/net/IpSecConfig;->setSourceAddress(Ljava/lang/String;)V -Landroid/net/IpSecConfig;->setSpiResourceId(I)V -Landroid/net/IpSecConfig;->TAG:Ljava/lang/String; -Landroid/net/IpSecManager$IpSecTunnelInterface;-><init>(Landroid/content/Context;Landroid/net/IIpSecService;Ljava/net/InetAddress;Ljava/net/InetAddress;Landroid/net/Network;)V -Landroid/net/IpSecManager$IpSecTunnelInterface;->addAddress(Ljava/net/InetAddress;I)V -Landroid/net/IpSecManager$IpSecTunnelInterface;->getInterfaceName()Ljava/lang/String; -Landroid/net/IpSecManager$IpSecTunnelInterface;->getResourceId()I -Landroid/net/IpSecManager$IpSecTunnelInterface;->mCloseGuard:Ldalvik/system/CloseGuard; -Landroid/net/IpSecManager$IpSecTunnelInterface;->mInterfaceName:Ljava/lang/String; -Landroid/net/IpSecManager$IpSecTunnelInterface;->mLocalAddress:Ljava/net/InetAddress; -Landroid/net/IpSecManager$IpSecTunnelInterface;->mOpPackageName:Ljava/lang/String; -Landroid/net/IpSecManager$IpSecTunnelInterface;->mRemoteAddress:Ljava/net/InetAddress; -Landroid/net/IpSecManager$IpSecTunnelInterface;->mResourceId:I -Landroid/net/IpSecManager$IpSecTunnelInterface;->mService:Landroid/net/IIpSecService; -Landroid/net/IpSecManager$IpSecTunnelInterface;->mUnderlyingNetwork:Landroid/net/Network; -Landroid/net/IpSecManager$IpSecTunnelInterface;->removeAddress(Ljava/net/InetAddress;I)V -Landroid/net/IpSecManager$ResourceUnavailableException;-><init>(Ljava/lang/String;)V -Landroid/net/IpSecManager$SecurityParameterIndex;-><init>(Landroid/net/IIpSecService;Ljava/net/InetAddress;I)V -Landroid/net/IpSecManager$SecurityParameterIndex;->getResourceId()I -Landroid/net/IpSecManager$SecurityParameterIndex;->mCloseGuard:Ldalvik/system/CloseGuard; -Landroid/net/IpSecManager$SecurityParameterIndex;->mDestinationAddress:Ljava/net/InetAddress; -Landroid/net/IpSecManager$SecurityParameterIndex;->mResourceId:I -Landroid/net/IpSecManager$SecurityParameterIndex;->mService:Landroid/net/IIpSecService; -Landroid/net/IpSecManager$SecurityParameterIndex;->mSpi:I -Landroid/net/IpSecManager$SpiUnavailableException;-><init>(Ljava/lang/String;I)V -Landroid/net/IpSecManager$SpiUnavailableException;->mSpi:I -Landroid/net/IpSecManager$Status;->OK:I -Landroid/net/IpSecManager$Status;->RESOURCE_UNAVAILABLE:I -Landroid/net/IpSecManager$Status;->SPI_UNAVAILABLE:I -Landroid/net/IpSecManager$UdpEncapsulationSocket;-><init>(Landroid/net/IIpSecService;I)V -Landroid/net/IpSecManager$UdpEncapsulationSocket;->getResourceId()I -Landroid/net/IpSecManager$UdpEncapsulationSocket;->mCloseGuard:Ldalvik/system/CloseGuard; -Landroid/net/IpSecManager$UdpEncapsulationSocket;->mPfd:Landroid/os/ParcelFileDescriptor; -Landroid/net/IpSecManager$UdpEncapsulationSocket;->mPort:I -Landroid/net/IpSecManager$UdpEncapsulationSocket;->mResourceId:I -Landroid/net/IpSecManager$UdpEncapsulationSocket;->mService:Landroid/net/IIpSecService; -Landroid/net/IpSecManager;-><init>(Landroid/content/Context;Landroid/net/IIpSecService;)V -Landroid/net/IpSecManager;->applyTunnelModeTransform(Landroid/net/IpSecManager$IpSecTunnelInterface;ILandroid/net/IpSecTransform;)V -Landroid/net/IpSecManager;->createIpSecTunnelInterface(Ljava/net/InetAddress;Ljava/net/InetAddress;Landroid/net/Network;)Landroid/net/IpSecManager$IpSecTunnelInterface; -Landroid/net/IpSecManager;->INVALID_RESOURCE_ID:I -Landroid/net/IpSecManager;->maybeHandleServiceSpecificException(Landroid/os/ServiceSpecificException;)V -Landroid/net/IpSecManager;->mContext:Landroid/content/Context; -Landroid/net/IpSecManager;->mService:Landroid/net/IIpSecService; -Landroid/net/IpSecManager;->removeTunnelModeTransform(Landroid/net/Network;Landroid/net/IpSecTransform;)V -Landroid/net/IpSecManager;->rethrowCheckedExceptionFromServiceSpecificException(Landroid/os/ServiceSpecificException;)Ljava/io/IOException; -Landroid/net/IpSecManager;->rethrowUncheckedExceptionFromServiceSpecificException(Landroid/os/ServiceSpecificException;)Ljava/lang/RuntimeException; -Landroid/net/IpSecManager;->TAG:Ljava/lang/String; -Landroid/net/IpSecSpiResponse;-><init>(I)V -Landroid/net/IpSecSpiResponse;-><init>(III)V -Landroid/net/IpSecSpiResponse;-><init>(Landroid/os/Parcel;)V -Landroid/net/IpSecSpiResponse;->CREATOR:Landroid/os/Parcelable$Creator; -Landroid/net/IpSecSpiResponse;->resourceId:I -Landroid/net/IpSecSpiResponse;->spi:I -Landroid/net/IpSecSpiResponse;->status:I -Landroid/net/IpSecSpiResponse;->TAG:Ljava/lang/String; -Landroid/net/IpSecTransform$Builder;->buildTunnelModeTransform(Ljava/net/InetAddress;Landroid/net/IpSecManager$SecurityParameterIndex;)Landroid/net/IpSecTransform; -Landroid/net/IpSecTransform$Builder;->mConfig:Landroid/net/IpSecConfig; -Landroid/net/IpSecTransform$Builder;->mContext:Landroid/content/Context; -Landroid/net/IpSecTransform$NattKeepaliveCallback;-><init>()V -Landroid/net/IpSecTransform$NattKeepaliveCallback;->ERROR_HARDWARE_ERROR:I -Landroid/net/IpSecTransform$NattKeepaliveCallback;->ERROR_HARDWARE_UNSUPPORTED:I -Landroid/net/IpSecTransform$NattKeepaliveCallback;->ERROR_INVALID_NETWORK:I -Landroid/net/IpSecTransform$NattKeepaliveCallback;->onError(I)V -Landroid/net/IpSecTransform$NattKeepaliveCallback;->onStarted()V -Landroid/net/IpSecTransform$NattKeepaliveCallback;->onStopped()V -Landroid/net/IpSecTransform;-><init>(Landroid/content/Context;Landroid/net/IpSecConfig;)V -Landroid/net/IpSecTransform;->activate()Landroid/net/IpSecTransform; -Landroid/net/IpSecTransform;->checkResultStatus(I)V -Landroid/net/IpSecTransform;->ENCAP_ESPINUDP:I -Landroid/net/IpSecTransform;->ENCAP_ESPINUDP_NON_IKE:I -Landroid/net/IpSecTransform;->ENCAP_NONE:I -Landroid/net/IpSecTransform;->equals(Landroid/net/IpSecTransform;Landroid/net/IpSecTransform;)Z -Landroid/net/IpSecTransform;->getConfig()Landroid/net/IpSecConfig; -Landroid/net/IpSecTransform;->getIpSecService()Landroid/net/IIpSecService; -Landroid/net/IpSecTransform;->getResourceId()I -Landroid/net/IpSecTransform;->mCallbackHandler:Landroid/os/Handler; -Landroid/net/IpSecTransform;->mCloseGuard:Ldalvik/system/CloseGuard; -Landroid/net/IpSecTransform;->mConfig:Landroid/net/IpSecConfig; -Landroid/net/IpSecTransform;->mContext:Landroid/content/Context; -Landroid/net/IpSecTransform;->mKeepalive:Landroid/net/ConnectivityManager$PacketKeepalive; -Landroid/net/IpSecTransform;->mKeepaliveCallback:Landroid/net/ConnectivityManager$PacketKeepaliveCallback; -Landroid/net/IpSecTransform;->MODE_TRANSPORT:I -Landroid/net/IpSecTransform;->MODE_TUNNEL:I -Landroid/net/IpSecTransform;->mResourceId:I -Landroid/net/IpSecTransform;->mUserKeepaliveCallback:Landroid/net/IpSecTransform$NattKeepaliveCallback; -Landroid/net/IpSecTransform;->startNattKeepalive(Landroid/net/IpSecTransform$NattKeepaliveCallback;ILandroid/os/Handler;)V -Landroid/net/IpSecTransform;->stopNattKeepalive()V -Landroid/net/IpSecTransform;->TAG:Ljava/lang/String; -Landroid/net/IpSecTransformResponse;-><init>(I)V -Landroid/net/IpSecTransformResponse;-><init>(II)V -Landroid/net/IpSecTransformResponse;-><init>(Landroid/os/Parcel;)V -Landroid/net/IpSecTransformResponse;->CREATOR:Landroid/os/Parcelable$Creator; -Landroid/net/IpSecTransformResponse;->resourceId:I -Landroid/net/IpSecTransformResponse;->status:I -Landroid/net/IpSecTransformResponse;->TAG:Ljava/lang/String; -Landroid/net/IpSecTunnelInterfaceResponse;-><init>(I)V -Landroid/net/IpSecTunnelInterfaceResponse;-><init>(IILjava/lang/String;)V -Landroid/net/IpSecTunnelInterfaceResponse;-><init>(Landroid/os/Parcel;)V -Landroid/net/IpSecTunnelInterfaceResponse;->CREATOR:Landroid/os/Parcelable$Creator; -Landroid/net/IpSecTunnelInterfaceResponse;->interfaceName:Ljava/lang/String; -Landroid/net/IpSecTunnelInterfaceResponse;->resourceId:I -Landroid/net/IpSecTunnelInterfaceResponse;->status:I -Landroid/net/IpSecTunnelInterfaceResponse;->TAG:Ljava/lang/String; -Landroid/net/IpSecUdpEncapResponse;-><init>(I)V -Landroid/net/IpSecUdpEncapResponse;-><init>(IIILjava/io/FileDescriptor;)V -Landroid/net/IpSecUdpEncapResponse;-><init>(Landroid/os/Parcel;)V -Landroid/net/IpSecUdpEncapResponse;->CREATOR:Landroid/os/Parcelable$Creator; -Landroid/net/IpSecUdpEncapResponse;->fileDescriptor:Landroid/os/ParcelFileDescriptor; -Landroid/net/IpSecUdpEncapResponse;->port:I -Landroid/net/IpSecUdpEncapResponse;->resourceId:I -Landroid/net/IpSecUdpEncapResponse;->status:I -Landroid/net/IpSecUdpEncapResponse;->TAG:Ljava/lang/String; Landroid/net/ITetheringStatsProvider$Stub$Proxy;-><init>(Landroid/os/IBinder;)V Landroid/net/ITetheringStatsProvider$Stub$Proxy;->getInterfaceDescriptor()Ljava/lang/String; Landroid/net/ITetheringStatsProvider$Stub$Proxy;->getTetherStats(I)Landroid/net/NetworkStats; diff --git a/cmds/idmap2/Android.bp b/cmds/idmap2/Android.bp index c134822585e0..c202f6f03b5b 100644 --- a/cmds/idmap2/Android.bp +++ b/cmds/idmap2/Android.bp @@ -39,6 +39,7 @@ cc_defaults { "-modernize-pass-by-value", "-modernize-replace-disallow-copy-and-assign-macro", "-modernize-return-braced-init-list", + "-modernize-use-default-member-init", "-modernize-use-equals-default", "-modernize-use-nodiscard", "-modernize-use-override", diff --git a/cmds/idmap2/idmap2d/Idmap2Service.cpp b/cmds/idmap2/idmap2d/Idmap2Service.cpp index a8d648917b08..1b2d905aec0a 100644 --- a/cmds/idmap2/idmap2d/Idmap2Service.cpp +++ b/cmds/idmap2/idmap2d/Idmap2Service.cpp @@ -39,11 +39,9 @@ #include "idmap2/Result.h" #include "idmap2/SysTrace.h" -using android::IPCThreadState; using android::base::StringPrintf; using android::binder::Status; using android::idmap2::BinaryStreamVisitor; -using android::idmap2::FabricatedOverlay; using android::idmap2::FabricatedOverlayContainer; using android::idmap2::Idmap; using android::idmap2::IdmapHeader; diff --git a/cmds/idmap2/tests/IdmapTests.cpp b/cmds/idmap2/tests/IdmapTests.cpp index 9c6402a6e36e..738b9cf237c9 100644 --- a/cmds/idmap2/tests/IdmapTests.cpp +++ b/cmds/idmap2/tests/IdmapTests.cpp @@ -37,7 +37,6 @@ #include "idmap2/Idmap.h" #include "idmap2/LogInfo.h" -using android::Res_value; using ::testing::NotNull; using PolicyFlags = android::ResTable_overlayable_policy_header::PolicyFlags; diff --git a/cmds/idmap2/tests/ResourceMappingTests.cpp b/cmds/idmap2/tests/ResourceMappingTests.cpp index 5a1d808af06f..32b3d1326d92 100644 --- a/cmds/idmap2/tests/ResourceMappingTests.cpp +++ b/cmds/idmap2/tests/ResourceMappingTests.cpp @@ -29,8 +29,6 @@ #include "idmap2/LogInfo.h" #include "idmap2/ResourceMapping.h" -using android::Res_value; - using PolicyFlags = android::ResTable_overlayable_policy_header::PolicyFlags; namespace android::idmap2 { diff --git a/core/api/current.txt b/core/api/current.txt index 235c496e999b..b5066d9a8cb0 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -19114,6 +19114,7 @@ package android.media { method public boolean isSink(); method public boolean isSource(); field public static final int TYPE_AUX_LINE = 19; // 0x13 + field public static final int TYPE_BLE_BROADCAST = 30; // 0x1e field public static final int TYPE_BLE_HEADSET = 26; // 0x1a field public static final int TYPE_BLE_SPEAKER = 27; // 0x1b field public static final int TYPE_BLUETOOTH_A2DP = 8; // 0x8 @@ -25198,6 +25199,14 @@ package android.net { method public int getUid(); } + public final class EthernetNetworkSpecifier extends android.net.NetworkSpecifier implements android.os.Parcelable { + ctor public EthernetNetworkSpecifier(@NonNull String); + method public int describeContents(); + method @Nullable public String getInterfaceName(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.net.EthernetNetworkSpecifier> CREATOR; + } + public final class Ikev2VpnProfile extends android.net.PlatformVpnProfile { method @NonNull public java.util.List<java.lang.String> getAllowedAlgorithms(); method public int getMaxMtu(); @@ -25223,82 +25232,13 @@ package android.net { method @NonNull public android.net.Ikev2VpnProfile.Builder setAuthPsk(@NonNull byte[]); method @NonNull public android.net.Ikev2VpnProfile.Builder setAuthUsernamePassword(@NonNull String, @NonNull String, @Nullable java.security.cert.X509Certificate); method @NonNull public android.net.Ikev2VpnProfile.Builder setBypassable(boolean); - method @NonNull public android.net.Ikev2VpnProfile.Builder setExcludeLocalRoutes(boolean); + method @NonNull public android.net.Ikev2VpnProfile.Builder setLocalRoutesExcluded(boolean); method @NonNull public android.net.Ikev2VpnProfile.Builder setMaxMtu(int); method @NonNull public android.net.Ikev2VpnProfile.Builder setMetered(boolean); method @NonNull public android.net.Ikev2VpnProfile.Builder setProxy(@Nullable android.net.ProxyInfo); method @NonNull public android.net.Ikev2VpnProfile.Builder setRequiresInternetValidation(boolean); } - public final class IpSecAlgorithm implements android.os.Parcelable { - ctor public IpSecAlgorithm(@NonNull String, @NonNull byte[]); - ctor public IpSecAlgorithm(@NonNull String, @NonNull byte[], int); - method public int describeContents(); - method @NonNull public byte[] getKey(); - method @NonNull public String getName(); - method @NonNull public static java.util.Set<java.lang.String> getSupportedAlgorithms(); - method public int getTruncationLengthBits(); - method public void writeToParcel(android.os.Parcel, int); - field public static final String AUTH_AES_CMAC = "cmac(aes)"; - field public static final String AUTH_AES_XCBC = "xcbc(aes)"; - field public static final String AUTH_CRYPT_AES_GCM = "rfc4106(gcm(aes))"; - field public static final String AUTH_CRYPT_CHACHA20_POLY1305 = "rfc7539esp(chacha20,poly1305)"; - field public static final String AUTH_HMAC_MD5 = "hmac(md5)"; - field public static final String AUTH_HMAC_SHA1 = "hmac(sha1)"; - field public static final String AUTH_HMAC_SHA256 = "hmac(sha256)"; - field public static final String AUTH_HMAC_SHA384 = "hmac(sha384)"; - field public static final String AUTH_HMAC_SHA512 = "hmac(sha512)"; - field @NonNull public static final android.os.Parcelable.Creator<android.net.IpSecAlgorithm> CREATOR; - field public static final String CRYPT_AES_CBC = "cbc(aes)"; - field public static final String CRYPT_AES_CTR = "rfc3686(ctr(aes))"; - } - - public final class IpSecManager { - method @NonNull public android.net.IpSecManager.SecurityParameterIndex allocateSecurityParameterIndex(@NonNull java.net.InetAddress) throws android.net.IpSecManager.ResourceUnavailableException; - method @NonNull public android.net.IpSecManager.SecurityParameterIndex allocateSecurityParameterIndex(@NonNull java.net.InetAddress, int) throws android.net.IpSecManager.ResourceUnavailableException, android.net.IpSecManager.SpiUnavailableException; - method public void applyTransportModeTransform(@NonNull java.net.Socket, int, @NonNull android.net.IpSecTransform) throws java.io.IOException; - method public void applyTransportModeTransform(@NonNull java.net.DatagramSocket, int, @NonNull android.net.IpSecTransform) throws java.io.IOException; - method public void applyTransportModeTransform(@NonNull java.io.FileDescriptor, int, @NonNull android.net.IpSecTransform) throws java.io.IOException; - method @NonNull public android.net.IpSecManager.UdpEncapsulationSocket openUdpEncapsulationSocket(int) throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException; - method @NonNull public android.net.IpSecManager.UdpEncapsulationSocket openUdpEncapsulationSocket() throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException; - method public void removeTransportModeTransforms(@NonNull java.net.Socket) throws java.io.IOException; - method public void removeTransportModeTransforms(@NonNull java.net.DatagramSocket) throws java.io.IOException; - method public void removeTransportModeTransforms(@NonNull java.io.FileDescriptor) throws java.io.IOException; - field public static final int DIRECTION_IN = 0; // 0x0 - field public static final int DIRECTION_OUT = 1; // 0x1 - } - - public static final class IpSecManager.ResourceUnavailableException extends android.util.AndroidException { - } - - public static final class IpSecManager.SecurityParameterIndex implements java.lang.AutoCloseable { - method public void close(); - method public int getSpi(); - } - - public static final class IpSecManager.SpiUnavailableException extends android.util.AndroidException { - method public int getSpi(); - } - - public static final class IpSecManager.UdpEncapsulationSocket implements java.lang.AutoCloseable { - method public void close() throws java.io.IOException; - method public java.io.FileDescriptor getFileDescriptor(); - method public int getPort(); - } - - public final class IpSecTransform implements java.lang.AutoCloseable { - method public void close(); - } - - public static class IpSecTransform.Builder { - ctor public IpSecTransform.Builder(@NonNull android.content.Context); - method @NonNull public android.net.IpSecTransform buildTransportModeTransform(@NonNull java.net.InetAddress, @NonNull android.net.IpSecManager.SecurityParameterIndex) throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException, android.net.IpSecManager.SpiUnavailableException; - method @NonNull public android.net.IpSecTransform.Builder setAuthenticatedEncryption(@NonNull android.net.IpSecAlgorithm); - method @NonNull public android.net.IpSecTransform.Builder setAuthentication(@NonNull android.net.IpSecAlgorithm); - method @NonNull public android.net.IpSecTransform.Builder setEncryption(@NonNull android.net.IpSecAlgorithm); - method @NonNull public android.net.IpSecTransform.Builder setIpv4Encapsulation(@NonNull android.net.IpSecManager.UdpEncapsulationSocket, int); - } - public class LocalServerSocket implements java.io.Closeable { ctor public LocalServerSocket(String) throws java.io.IOException; ctor public LocalServerSocket(java.io.FileDescriptor) throws java.io.IOException; @@ -25370,7 +25310,7 @@ package android.net { } public abstract class PlatformVpnProfile { - method public final boolean getExcludeLocalRoutes(); + method public final boolean areLocalRoutesExcluded(); method public final boolean getRequiresInternetValidation(); method public final int getType(); method @NonNull public final String getTypeString(); @@ -25611,6 +25551,23 @@ package android.net { method @Deprecated public void startProvisionedVpnProfile(); method @NonNull public String startProvisionedVpnProfileSession(); method public void stopProvisionedVpnProfile(); + field public static final String ACTION_VPN_MANAGER_EVENT = "android.net.action.VPN_MANAGER_EVENT"; + field public static final String CATEGORY_EVENT_DEACTIVATED_BY_USER = "android.net.category.EVENT_DEACTIVATED_BY_USER"; + field public static final String CATEGORY_EVENT_IKE_ERROR = "android.net.category.EVENT_IKE_ERROR"; + field public static final String CATEGORY_EVENT_NETWORK_ERROR = "android.net.category.EVENT_NETWORK_ERROR"; + field public static final int ERROR_CLASS_NOT_RECOVERABLE = 1; // 0x1 + field public static final int ERROR_CLASS_RECOVERABLE = 2; // 0x2 + field public static final int ERROR_CODE_NETWORK_IO = 3; // 0x3 + field public static final int ERROR_CODE_NETWORK_LOST = 2; // 0x2 + field public static final int ERROR_CODE_NETWORK_PROTOCOL_TIMEOUT = 1; // 0x1 + field public static final int ERROR_CODE_NETWORK_UNKNOWN_HOST = 0; // 0x0 + field public static final String EXTRA_ERROR_CLASS = "android.net.extra.ERROR_CLASS"; + field public static final String EXTRA_ERROR_CODE = "android.net.extra.ERROR_CODE"; + field public static final String EXTRA_SESSION_KEY = "android.net.extra.SESSION_KEY"; + field public static final String EXTRA_TIMESTAMP = "android.net.extra.TIMESTAMP"; + field public static final String EXTRA_UNDERLYING_LINK_PROPERTIES = "android.net.extra.UNDERLYING_LINK_PROPERTIES"; + field public static final String EXTRA_UNDERLYING_NETWORK = "android.net.extra.UNDERLYING_NETWORK"; + field public static final String EXTRA_UNDERLYING_NETWORK_CAPABILITIES = "android.net.extra.UNDERLYING_NETWORK_CAPABILITIES"; } public class VpnService extends android.app.Service { @@ -26232,7 +26189,6 @@ package android.nfc.cardemulation { field public static final String CATEGORY_PAYMENT = "payment"; field public static final String EXTRA_CATEGORY = "category"; field public static final String EXTRA_SERVICE_COMPONENT = "component"; - field public static final String EXTRA_USERID = "android.nfc.cardemulation.extra.USERID"; field public static final int SELECTION_MODE_ALWAYS_ASK = 1; // 0x1 field public static final int SELECTION_MODE_ASK_IF_CONFLICT = 2; // 0x2 field public static final int SELECTION_MODE_PREFER_DEFAULT = 0; // 0x0 @@ -29467,7 +29423,7 @@ package android.os { public class BaseBundle { method public void clear(); method public boolean containsKey(String); - method @Nullable public Object get(String); + method @Deprecated @Nullable public Object get(String); method public boolean getBoolean(String); method public boolean getBoolean(String, boolean); method @Nullable public boolean[] getBooleanArray(@Nullable String); @@ -29708,16 +29664,21 @@ package android.os { method public float getFloat(String, float); method @Nullable public float[] getFloatArray(@Nullable String); method @Nullable public java.util.ArrayList<java.lang.Integer> getIntegerArrayList(@Nullable String); - method @Nullable public <T extends android.os.Parcelable> T getParcelable(@Nullable String); - method @Nullable public android.os.Parcelable[] getParcelableArray(@Nullable String); - method @Nullable public <T extends android.os.Parcelable> java.util.ArrayList<T> getParcelableArrayList(@Nullable String); - method @Nullable public java.io.Serializable getSerializable(@Nullable String); + method @Deprecated @Nullable public <T extends android.os.Parcelable> T getParcelable(@Nullable String); + method @Nullable public <T> T getParcelable(@Nullable String, @NonNull Class<T>); + method @Deprecated @Nullable public android.os.Parcelable[] getParcelableArray(@Nullable String); + method @Nullable public <T> T[] getParcelableArray(@Nullable String, @NonNull Class<T>); + method @Deprecated @Nullable public <T extends android.os.Parcelable> java.util.ArrayList<T> getParcelableArrayList(@Nullable String); + method @Nullable public <T> java.util.ArrayList<T> getParcelableArrayList(@Nullable String, @NonNull Class<T>); + method @Deprecated @Nullable public java.io.Serializable getSerializable(@Nullable String); + method @Nullable public <T extends java.io.Serializable> T getSerializable(@Nullable String, @NonNull Class<T>); method public short getShort(String); method public short getShort(String, short); method @Nullable public short[] getShortArray(@Nullable String); method @Nullable public android.util.Size getSize(@Nullable String); method @Nullable public android.util.SizeF getSizeF(@Nullable String); - method @Nullable public <T extends android.os.Parcelable> android.util.SparseArray<T> getSparseParcelableArray(@Nullable String); + method @Deprecated @Nullable public <T extends android.os.Parcelable> android.util.SparseArray<T> getSparseParcelableArray(@Nullable String); + method @Nullable public <T> android.util.SparseArray<T> getSparseParcelableArray(@Nullable String, @NonNull Class<T>); method @Nullable public java.util.ArrayList<java.lang.String> getStringArrayList(@Nullable String); method public boolean hasFileDescriptors(); method public void putAll(android.os.Bundle); @@ -40006,13 +39967,13 @@ package android.telephony { } public static final class CarrierConfigManager.Ims { - field public static final String KEY_CAPABILITY_CALL_COMPOSER_INT_ARRAY = "ims.key_capability_type_call_composer_int_array"; - field public static final String KEY_CAPABILITY_TYPE_OPTIONS_UCE_INT_ARRAY = "ims.key_capability_type_options_uce_int_array"; - field public static final String KEY_CAPABILITY_TYPE_PRESENCE_UCE_INT_ARRAY = "ims.key_capability_type_presence_uce_int_array"; - field public static final String KEY_CAPABILITY_TYPE_SMS_INT_ARRAY = "ims.key_capability_type_sms_int_array"; - field public static final String KEY_CAPABILITY_TYPE_UT_INT_ARRAY = "ims.key_capability_type_ut_int_array"; - field public static final String KEY_CAPABILITY_TYPE_VIDEO_INT_ARRAY = "ims.key_capability_type_video_int_array"; - field public static final String KEY_CAPABILITY_TYPE_VOICE_INT_ARRAY = "ims.key_capability_type_voice_int_array"; + field public static final String KEY_CAPABILITY_TYPE_CALL_COMPOSER_INT_ARRAY = "ims.capability_type_call_composer_int_array"; + field public static final String KEY_CAPABILITY_TYPE_OPTIONS_UCE_INT_ARRAY = "ims.capability_type_options_uce_int_array"; + field public static final String KEY_CAPABILITY_TYPE_PRESENCE_UCE_INT_ARRAY = "ims.capability_type_presence_uce_int_array"; + field public static final String KEY_CAPABILITY_TYPE_SMS_INT_ARRAY = "ims.capability_type_sms_int_array"; + field public static final String KEY_CAPABILITY_TYPE_UT_INT_ARRAY = "ims.capability_type_ut_int_array"; + field public static final String KEY_CAPABILITY_TYPE_VIDEO_INT_ARRAY = "ims.capability_type_video_int_array"; + field public static final String KEY_CAPABILITY_TYPE_VOICE_INT_ARRAY = "ims.capability_type_voice_int_array"; field public static final String KEY_ENABLE_PRESENCE_CAPABILITY_EXCHANGE_BOOL = "ims.enable_presence_capability_exchange_bool"; field public static final String KEY_ENABLE_PRESENCE_GROUP_SUBSCRIBE_BOOL = "ims.enable_presence_group_subscribe_bool"; field public static final String KEY_ENABLE_PRESENCE_PUBLISH_BOOL = "ims.enable_presence_publish_bool"; @@ -40023,6 +39984,7 @@ package android.telephony { field public static final String KEY_RCS_BULK_CAPABILITY_EXCHANGE_BOOL = "ims.rcs_bulk_capability_exchange_bool"; field public static final String KEY_RCS_FEATURE_TAG_ALLOWED_STRING_ARRAY = "ims.rcs_feature_tag_allowed_string_array"; field public static final String KEY_RCS_REQUIRES_PROVISIONING_BUNDLE = "ims.rcs_requires_provisioning_bundle"; + field public static final String KEY_USE_SIP_URI_FOR_PRESENCE_SUBSCRIBE_BOOL = "ims.use_sip_uri_for_presence_subscribe_bool"; field public static final String KEY_WIFI_OFF_DEFERRING_TIME_MILLIS_INT = "ims.wifi_off_deferring_time_millis_int"; } @@ -41099,16 +41061,16 @@ package android.telephony { ctor @Deprecated public ServiceState(android.os.Parcel); method protected void copyFrom(android.telephony.ServiceState); method public int describeContents(); - method public int getCdmaNetworkId(); - method public int getCdmaSystemId(); + method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_COARSE_LOCATION}) public int getCdmaNetworkId(); + method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_COARSE_LOCATION}) public int getCdmaSystemId(); method public int[] getCellBandwidths(); method public int getChannelNumber(); method public int getDuplexMode(); method public boolean getIsManualSelection(); method @NonNull public java.util.List<android.telephony.NetworkRegistrationInfo> getNetworkRegistrationInfoList(); - method public String getOperatorAlphaLong(); - method public String getOperatorAlphaShort(); - method public String getOperatorNumeric(); + method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_COARSE_LOCATION}) public String getOperatorAlphaLong(); + method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_COARSE_LOCATION}) public String getOperatorAlphaShort(); + method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_COARSE_LOCATION}) public String getOperatorNumeric(); method public boolean getRoaming(); method public int getState(); method public boolean isSearching(); diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt index 1e4e787aefa3..bcdd0a4664d7 100644 --- a/core/api/module-lib-current.txt +++ b/core/api/module-lib-current.txt @@ -218,20 +218,20 @@ package android.media.session { package android.net { - public final class EthernetNetworkSpecifier extends android.net.NetworkSpecifier implements android.os.Parcelable { - ctor public EthernetNetworkSpecifier(@NonNull String); - method public int describeContents(); - method @Nullable public String getInterfaceName(); - method public void writeToParcel(@NonNull android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.net.EthernetNetworkSpecifier> CREATOR; - } - - public final class IpSecManager { - field public static final int DIRECTION_FWD = 2; // 0x2 - } - - public static final class IpSecManager.UdpEncapsulationSocket implements java.lang.AutoCloseable { - method public int getResourceId(); + public class EthernetManager { + method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public void addInterfaceStateListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.EthernetManager.InterfaceStateListener); + method public void removeInterfaceStateListener(@NonNull android.net.EthernetManager.InterfaceStateListener); + method public void setIncludeTestInterfaces(boolean); + field public static final int ROLE_CLIENT = 1; // 0x1 + field public static final int ROLE_NONE = 0; // 0x0 + field public static final int ROLE_SERVER = 2; // 0x2 + field public static final int STATE_ABSENT = 0; // 0x0 + field public static final int STATE_LINK_DOWN = 1; // 0x1 + field public static final int STATE_LINK_UP = 2; // 0x2 + } + + public static interface EthernetManager.InterfaceStateListener { + method public void onInterfaceStateChanged(@NonNull String, int, int, @Nullable android.net.IpConfiguration); } public class LocalSocket implements java.io.Closeable { diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 7d68ee1c1ad6..5c6076be4dc9 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -7054,23 +7054,6 @@ package android.net { field @NonNull public static final android.os.Parcelable.Creator<android.net.EthernetNetworkUpdateRequest> CREATOR; } - public final class IpSecManager { - method @RequiresPermission(android.Manifest.permission.MANAGE_IPSEC_TUNNELS) public void applyTunnelModeTransform(@NonNull android.net.IpSecManager.IpSecTunnelInterface, int, @NonNull android.net.IpSecTransform) throws java.io.IOException; - method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_IPSEC_TUNNELS) public android.net.IpSecManager.IpSecTunnelInterface createIpSecTunnelInterface(@NonNull java.net.InetAddress, @NonNull java.net.InetAddress, @NonNull android.net.Network) throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException; - } - - public static final class IpSecManager.IpSecTunnelInterface implements java.lang.AutoCloseable { - method @RequiresPermission(android.Manifest.permission.MANAGE_IPSEC_TUNNELS) public void addAddress(@NonNull java.net.InetAddress, int) throws java.io.IOException; - method public void close(); - method @NonNull public String getInterfaceName(); - method @RequiresPermission(android.Manifest.permission.MANAGE_IPSEC_TUNNELS) public void removeAddress(@NonNull java.net.InetAddress, int) throws java.io.IOException; - method @RequiresPermission(android.Manifest.permission.MANAGE_IPSEC_TUNNELS) public void setUnderlyingNetwork(@NonNull android.net.Network) throws java.io.IOException; - } - - public static class IpSecTransform.Builder { - method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_IPSEC_TUNNELS) public android.net.IpSecTransform buildTunnelModeTransform(@NonNull java.net.InetAddress, @NonNull android.net.IpSecManager.SecurityParameterIndex) throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException, android.net.IpSecManager.SpiUnavailableException; - } - public final class MatchAllNetworkSpecifier extends android.net.NetworkSpecifier implements android.os.Parcelable { ctor public MatchAllNetworkSpecifier(); method public int describeContents(); @@ -10148,8 +10131,6 @@ package android.service.tracing { public class TraceReportService extends android.app.Service { ctor public TraceReportService(); - method @Nullable public android.os.IBinder onBind(@NonNull android.content.Intent); - method public boolean onMessage(@NonNull android.os.Message); method public void onReportTrace(@NonNull android.service.tracing.TraceReportService.TraceParams); } @@ -13258,6 +13239,7 @@ package android.telephony.ims { method @Nullable public android.telephony.ims.RcsContactPresenceTuple getCapabilityTuple(@NonNull String); method @NonNull public java.util.List<android.telephony.ims.RcsContactPresenceTuple> getCapabilityTuples(); method @NonNull public android.net.Uri getContactUri(); + method @Nullable public android.net.Uri getEntityUri(); method @NonNull public java.util.Set<java.lang.String> getFeatureTags(); method public int getRequestResult(); method public int getSourceType(); @@ -13286,6 +13268,7 @@ package android.telephony.ims { method @NonNull public android.telephony.ims.RcsContactUceCapability.PresenceBuilder addCapabilityTuple(@NonNull android.telephony.ims.RcsContactPresenceTuple); method @NonNull public android.telephony.ims.RcsContactUceCapability.PresenceBuilder addCapabilityTuples(@NonNull java.util.List<android.telephony.ims.RcsContactPresenceTuple>); method @NonNull public android.telephony.ims.RcsContactUceCapability build(); + method @NonNull public android.telephony.ims.RcsContactUceCapability.PresenceBuilder setEntityUri(@NonNull android.net.Uri); } public class RcsUceAdapter { diff --git a/core/api/system-lint-baseline.txt b/core/api/system-lint-baseline.txt index b435acfccde8..97eda7aee535 100644 --- a/core/api/system-lint-baseline.txt +++ b/core/api/system-lint-baseline.txt @@ -1,12 +1,6 @@ // Baseline format: 1.0 ArrayReturn: android.view.contentcapture.ViewNode#getAutofillOptions(): - - -BuilderSetStyle: android.net.IpSecTransform.Builder#buildTunnelModeTransform(java.net.InetAddress, android.net.IpSecManager.SecurityParameterIndex): - Builder methods names should use setFoo() / addFoo() / clearFoo() style: method android.net.IpSecTransform.Builder.buildTunnelModeTransform(java.net.InetAddress,android.net.IpSecManager.SecurityParameterIndex) - - ExecutorRegistration: android.media.MediaPlayer#setOnRtpRxNoticeListener(android.content.Context, android.media.MediaPlayer.OnRtpRxNoticeListener, android.os.Handler): Registration methods should have overload that accepts delivery Executor: `setOnRtpRxNoticeListener` @@ -15,8 +9,6 @@ GenericException: android.app.prediction.AppPredictor#finalize(): GenericException: android.hardware.location.ContextHubClient#finalize(): -GenericException: android.net.IpSecManager.IpSecTunnelInterface#finalize(): - GenericException: android.service.autofill.augmented.FillWindow#finalize(): diff --git a/core/api/test-current.txt b/core/api/test-current.txt index ae7265726331..a0b35800d4a2 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -1573,14 +1573,6 @@ package android.media.tv.tuner { package android.net { - public class EthernetManager { - method public void setIncludeTestInterfaces(boolean); - } - - public final class IpSecManager { - field public static final int INVALID_SECURITY_PARAMETER_INDEX = 0; // 0x0 - } - public class NetworkPolicyManager { method public boolean getRestrictBackground(); method @RequiresPermission(android.Manifest.permission.OBSERVE_NETWORK_POLICY) public boolean isUidNetworkingBlocked(int, boolean); diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java index f9739a489453..3766dc8a66f6 100644 --- a/core/java/android/app/SystemServiceRegistry.java +++ b/core/java/android/app/SystemServiceRegistry.java @@ -128,12 +128,10 @@ import android.net.ConnectivityFrameworkInitializer; import android.net.ConnectivityFrameworkInitializerTiramisu; import android.net.EthernetManager; import android.net.IEthernetManager; -import android.net.IIpSecService; import android.net.INetworkPolicyManager; import android.net.INetworkStatsService; import android.net.IPacProxyManager; import android.net.IVpnManager; -import android.net.IpSecManager; import android.net.NetworkPolicyManager; import android.net.NetworkScoreManager; import android.net.NetworkWatchlistManager; @@ -420,15 +418,6 @@ public final class SystemServiceRegistry { return new VcnManager(ctx, service); }}); - registerService(Context.IPSEC_SERVICE, IpSecManager.class, - new CachedServiceFetcher<IpSecManager>() { - @Override - public IpSecManager createService(ContextImpl ctx) throws ServiceNotFoundException { - IBinder b = ServiceManager.getService(Context.IPSEC_SERVICE); - IIpSecService service = IIpSecService.Stub.asInterface(b); - return new IpSecManager(ctx, service); - }}); - registerService(Context.COUNTRY_DETECTOR, CountryDetector.class, new StaticServiceFetcher<CountryDetector>() { @Override diff --git a/core/java/android/app/assist/OWNERS b/core/java/android/app/assist/OWNERS index 46b5ea03c545..e857c72bb28e 100644 --- a/core/java/android/app/assist/OWNERS +++ b/core/java/android/app/assist/OWNERS @@ -1,7 +1,5 @@ +augale@google.com joannechung@google.com -adamhe@google.com -tymtsai@google.com +markpun@google.com lpeter@google.com -augale@google.com -svetoslavganov@android.com -svetoslavganov@google.com +tymtsai@google.com diff --git a/core/java/android/app/contentsuggestions/OWNERS b/core/java/android/app/contentsuggestions/OWNERS index 482abb2d94e9..cf54c2a6fcbc 100644 --- a/core/java/android/app/contentsuggestions/OWNERS +++ b/core/java/android/app/contentsuggestions/OWNERS @@ -1,9 +1,7 @@ # Bug component: 643919 +augale@google.com joannechung@google.com -adamhe@google.com -tymtsai@google.com +markpun@google.com lpeter@google.com -augale@google.com -svetoslavganov@android.com -svetoslavganov@google.com +tymtsai@google.com diff --git a/core/java/android/app/time/ExternalTimeSuggestion.java b/core/java/android/app/time/ExternalTimeSuggestion.java index 8e281c07c45d..a7c0e5c79607 100644 --- a/core/java/android/app/time/ExternalTimeSuggestion.java +++ b/core/java/android/app/time/ExternalTimeSuggestion.java @@ -50,16 +50,17 @@ import java.util.Objects; * <p>The creator of an external suggestion is expected to be separate Android process, e.g. a * process integrating with the external time source via a HAL or local network. The creator must * capture the elapsed realtime reference clock, e.g. via {@link SystemClock#elapsedRealtime()}, - * when the UTC time is first obtained (usually under a wakelock). This enables Android to adjust - * for latency introduced between suggestion creation and eventual use. Adjustments for other + * when the Unix epoch time is first obtained (usually under a wakelock). This enables Android to + * adjust for latency introduced between suggestion creation and eventual use. Adjustments for other * sources of latency, i.e. those before the external time suggestion is created, must be handled by * the creator. * * <p>{@code elapsedRealtimeMillis} and {@code suggestionMillis} represent the suggested time. - * {@code suggestionMillis} is the number of milliseconds elapsed since 1/1/1970 00:00:00 UTC. - * {@code elapsedRealtimeMillis} is the value of the elapsed realtime clock when {@code - * suggestionMillis} was established. Note that the elapsed realtime clock is considered accurate - * but it is volatile, so time suggestions cannot be persisted across device resets. + * {@code suggestionMillis} is the number of milliseconds elapsed since 1/1/1970 00:00:00 UTC + * according to the Unix time scale. {@code elapsedRealtimeMillis} is the value of the elapsed + * realtime clock when {@code suggestionMillis} was established. Note that the elapsed realtime + * clock is considered accurate but it is volatile, so time suggestions cannot be persisted across + * device resets. * * <p>{@code debugInfo} contains debugging metadata associated with the suggestion. This is used to * record why the suggestion exists and how it was entered. This information exists only to aid in @@ -83,7 +84,7 @@ public final class ExternalTimeSuggestion implements Parcelable { }; @NonNull - private final TimestampedValue<Long> mUtcTime; + private final TimestampedValue<Long> mUnixEpochTime; @Nullable private ArrayList<String> mDebugInfo; @@ -92,12 +93,12 @@ public final class ExternalTimeSuggestion implements Parcelable { * ExternalTimeSuggestion} for more details. * * @param elapsedRealtimeMillis the elapsed realtime clock reference for the suggestion - * @param suggestionMillis the suggested UTC time in milliseconds since the start of the + * @param suggestionMillis the suggested time in milliseconds since the start of the * Unix epoch */ public ExternalTimeSuggestion(@ElapsedRealtimeLong long elapsedRealtimeMillis, @CurrentTimeMillisLong long suggestionMillis) { - mUtcTime = new TimestampedValue(elapsedRealtimeMillis, suggestionMillis); + mUnixEpochTime = new TimestampedValue(elapsedRealtimeMillis, suggestionMillis); } private static ExternalTimeSuggestion createFromParcel(Parcel in) { @@ -117,7 +118,7 @@ public final class ExternalTimeSuggestion implements Parcelable { @Override public void writeToParcel(@NonNull Parcel dest, int flags) { - dest.writeParcelable(mUtcTime, 0); + dest.writeParcelable(mUnixEpochTime, 0); dest.writeList(mDebugInfo); } @@ -125,8 +126,8 @@ public final class ExternalTimeSuggestion implements Parcelable { * {@hide} */ @NonNull - public TimestampedValue<Long> getUtcTime() { - return mUtcTime; + public TimestampedValue<Long> getUnixEpochTime() { + return mUnixEpochTime; } /** @@ -160,17 +161,18 @@ public final class ExternalTimeSuggestion implements Parcelable { return false; } ExternalTimeSuggestion that = (ExternalTimeSuggestion) o; - return Objects.equals(mUtcTime, that.mUtcTime); + return Objects.equals(mUnixEpochTime, that.mUnixEpochTime); } @Override public int hashCode() { - return Objects.hash(mUtcTime); + return Objects.hash(mUnixEpochTime); } @Override public String toString() { - return "ExternalTimeSuggestion{" + "mUtcTime=" + mUtcTime + ", mDebugInfo=" + mDebugInfo + return "ExternalTimeSuggestion{" + "mUnixEpochTime=" + mUnixEpochTime + + ", mDebugInfo=" + mDebugInfo + '}'; } } diff --git a/core/java/android/app/timedetector/GnssTimeSuggestion.java b/core/java/android/app/timedetector/GnssTimeSuggestion.java index 6478a2dd2aa9..34f4565fb410 100644 --- a/core/java/android/app/timedetector/GnssTimeSuggestion.java +++ b/core/java/android/app/timedetector/GnssTimeSuggestion.java @@ -31,11 +31,11 @@ import java.util.Objects; /** * A time signal from a GNSS source. * - * <p>{@code utcTime} is the suggested time. The {@code utcTime.value} is the number of milliseconds - * elapsed since 1/1/1970 00:00:00 UTC. The {@code utcTime.referenceTimeMillis} is the value of the - * elapsed realtime clock when the {@code utcTime.value} was established. - * Note that the elapsed realtime clock is considered accurate but it is volatile, so time - * suggestions cannot be persisted across device resets. + * <p>{@code unixEpochTime} is the suggested time. The {@code unixEpochTime.value} is the number of + * milliseconds elapsed since 1/1/1970 00:00:00 UTC according to the Unix time system. The {@code + * unixEpochTime.referenceTimeMillis} is the value of the elapsed realtime clock when the {@code + * unixEpochTime.value} was established. Note that the elapsed realtime clock is considered accurate + * but it is volatile, so time suggestions cannot be persisted across device resets. * * <p>{@code debugInfo} contains debugging metadata associated with the suggestion. This is used to * record why the suggestion exists and how it was entered. This information exists only to aid in @@ -57,17 +57,17 @@ public final class GnssTimeSuggestion implements Parcelable { } }; - @NonNull private final TimestampedValue<Long> mUtcTime; + @NonNull private final TimestampedValue<Long> mUnixEpochTime; @Nullable private ArrayList<String> mDebugInfo; - public GnssTimeSuggestion(@NonNull TimestampedValue<Long> utcTime) { - mUtcTime = Objects.requireNonNull(utcTime); - Objects.requireNonNull(utcTime.getValue()); + public GnssTimeSuggestion(@NonNull TimestampedValue<Long> unixEpochTime) { + mUnixEpochTime = Objects.requireNonNull(unixEpochTime); + Objects.requireNonNull(unixEpochTime.getValue()); } private static GnssTimeSuggestion createFromParcel(Parcel in) { - TimestampedValue<Long> utcTime = in.readParcelable(null /* classLoader */); - GnssTimeSuggestion suggestion = new GnssTimeSuggestion(utcTime); + TimestampedValue<Long> unixEpochTime = in.readParcelable(null /* classLoader */); + GnssTimeSuggestion suggestion = new GnssTimeSuggestion(unixEpochTime); @SuppressWarnings("unchecked") ArrayList<String> debugInfo = (ArrayList<String>) in.readArrayList(null /* classLoader */); suggestion.mDebugInfo = debugInfo; @@ -81,13 +81,13 @@ public final class GnssTimeSuggestion implements Parcelable { @Override public void writeToParcel(@NonNull Parcel dest, int flags) { - dest.writeParcelable(mUtcTime, 0); + dest.writeParcelable(mUnixEpochTime, 0); dest.writeList(mDebugInfo); } @NonNull - public TimestampedValue<Long> getUtcTime() { - return mUtcTime; + public TimestampedValue<Long> getUnixEpochTime() { + return mUnixEpochTime; } @NonNull @@ -117,18 +117,18 @@ public final class GnssTimeSuggestion implements Parcelable { return false; } GnssTimeSuggestion that = (GnssTimeSuggestion) o; - return Objects.equals(mUtcTime, that.mUtcTime); + return Objects.equals(mUnixEpochTime, that.mUnixEpochTime); } @Override public int hashCode() { - return Objects.hash(mUtcTime); + return Objects.hash(mUnixEpochTime); } @Override public String toString() { return "GnssTimeSuggestion{" - + "mUtcTime=" + mUtcTime + + "mUnixEpochTime=" + mUnixEpochTime + ", mDebugInfo=" + mDebugInfo + '}'; } diff --git a/core/java/android/app/timedetector/ManualTimeSuggestion.java b/core/java/android/app/timedetector/ManualTimeSuggestion.java index 299e9518e329..76db33b1c32b 100644 --- a/core/java/android/app/timedetector/ManualTimeSuggestion.java +++ b/core/java/android/app/timedetector/ManualTimeSuggestion.java @@ -31,9 +31,9 @@ import java.util.Objects; /** * A time signal from a manual (user provided) source. * - * <p>{@code utcTime} is the suggested time. The {@code utcTime.value} is the number of milliseconds - * elapsed since 1/1/1970 00:00:00 UTC. The {@code utcTime.referenceTimeMillis} is the value of the - * elapsed realtime clock when the {@code utcTime.value} was established. + * <p>{@code unixEpochTime} is the suggested time. The {@code unixEpochTime.value} is the number of + * milliseconds elapsed since 1/1/1970 00:00:00 UTC. The {@code unixEpochTime.referenceTimeMillis} + * is the value of the elapsed realtime clock when the {@code unixEpochTime.value} was established. * Note that the elapsed realtime clock is considered accurate but it is volatile, so time * suggestions cannot be persisted across device resets. * @@ -57,17 +57,17 @@ public final class ManualTimeSuggestion implements Parcelable { } }; - @NonNull private final TimestampedValue<Long> mUtcTime; + @NonNull private final TimestampedValue<Long> mUnixEpochTime; @Nullable private ArrayList<String> mDebugInfo; - public ManualTimeSuggestion(@NonNull TimestampedValue<Long> utcTime) { - mUtcTime = Objects.requireNonNull(utcTime); - Objects.requireNonNull(utcTime.getValue()); + public ManualTimeSuggestion(@NonNull TimestampedValue<Long> unixEpochTime) { + mUnixEpochTime = Objects.requireNonNull(unixEpochTime); + Objects.requireNonNull(unixEpochTime.getValue()); } private static ManualTimeSuggestion createFromParcel(Parcel in) { - TimestampedValue<Long> utcTime = in.readParcelable(null /* classLoader */); - ManualTimeSuggestion suggestion = new ManualTimeSuggestion(utcTime); + TimestampedValue<Long> unixEpochTime = in.readParcelable(null /* classLoader */); + ManualTimeSuggestion suggestion = new ManualTimeSuggestion(unixEpochTime); @SuppressWarnings("unchecked") ArrayList<String> debugInfo = (ArrayList<String>) in.readArrayList(null /* classLoader */); suggestion.mDebugInfo = debugInfo; @@ -81,13 +81,13 @@ public final class ManualTimeSuggestion implements Parcelable { @Override public void writeToParcel(@NonNull Parcel dest, int flags) { - dest.writeParcelable(mUtcTime, 0); + dest.writeParcelable(mUnixEpochTime, 0); dest.writeList(mDebugInfo); } @NonNull - public TimestampedValue<Long> getUtcTime() { - return mUtcTime; + public TimestampedValue<Long> getUnixEpochTime() { + return mUnixEpochTime; } @NonNull @@ -117,18 +117,18 @@ public final class ManualTimeSuggestion implements Parcelable { return false; } ManualTimeSuggestion that = (ManualTimeSuggestion) o; - return Objects.equals(mUtcTime, that.mUtcTime); + return Objects.equals(mUnixEpochTime, that.mUnixEpochTime); } @Override public int hashCode() { - return Objects.hash(mUtcTime); + return Objects.hash(mUnixEpochTime); } @Override public String toString() { return "ManualTimeSuggestion{" - + "mUtcTime=" + mUtcTime + + "mUnixEpochTime=" + mUnixEpochTime + ", mDebugInfo=" + mDebugInfo + '}'; } diff --git a/core/java/android/app/timedetector/NetworkTimeSuggestion.java b/core/java/android/app/timedetector/NetworkTimeSuggestion.java index a5259c27ec42..e22f1d6ea8be 100644 --- a/core/java/android/app/timedetector/NetworkTimeSuggestion.java +++ b/core/java/android/app/timedetector/NetworkTimeSuggestion.java @@ -31,11 +31,12 @@ import java.util.Objects; /** * A time signal from a network time source like NTP. * - * <p>{@code utcTime} contains the suggested time. The {@code utcTime.value} is the number of - * milliseconds elapsed since 1/1/1970 00:00:00 UTC. The {@code utcTime.referenceTimeMillis} is the - * value of the elapsed realtime clock when the {@code utcTime.value} was established. - * Note that the elapsed realtime clock is considered accurate but it is volatile, so time - * suggestions cannot be persisted across device resets. + * <p>{@code unixEpochTime} contains the suggested time. The {@code unixEpochTime.value} is the + * number of milliseconds elapsed since 1/1/1970 00:00:00 UTC according to the Unix time system. + * The {@code unixEpochTime.referenceTimeMillis} is the value of the elapsed realtime clock when + * the {@code unixEpochTime.value} was established. Note that the elapsed realtime clock is + * considered accurate but it is volatile, so time suggestions cannot be persisted across device + * resets. * * <p>{@code debugInfo} contains debugging metadata associated with the suggestion. This is used to * record why the suggestion exists and how it was determined. This information exists only to aid @@ -57,17 +58,17 @@ public final class NetworkTimeSuggestion implements Parcelable { } }; - @NonNull private final TimestampedValue<Long> mUtcTime; + @NonNull private final TimestampedValue<Long> mUnixEpochTime; @Nullable private ArrayList<String> mDebugInfo; - public NetworkTimeSuggestion(@NonNull TimestampedValue<Long> utcTime) { - mUtcTime = Objects.requireNonNull(utcTime); - Objects.requireNonNull(utcTime.getValue()); + public NetworkTimeSuggestion(@NonNull TimestampedValue<Long> unixEpochTime) { + mUnixEpochTime = Objects.requireNonNull(unixEpochTime); + Objects.requireNonNull(unixEpochTime.getValue()); } private static NetworkTimeSuggestion createFromParcel(Parcel in) { - TimestampedValue<Long> utcTime = in.readParcelable(null /* classLoader */); - NetworkTimeSuggestion suggestion = new NetworkTimeSuggestion(utcTime); + TimestampedValue<Long> unixEpochTime = in.readParcelable(null /* classLoader */); + NetworkTimeSuggestion suggestion = new NetworkTimeSuggestion(unixEpochTime); @SuppressWarnings("unchecked") ArrayList<String> debugInfo = (ArrayList<String>) in.readArrayList(null /* classLoader */); suggestion.mDebugInfo = debugInfo; @@ -81,13 +82,13 @@ public final class NetworkTimeSuggestion implements Parcelable { @Override public void writeToParcel(@NonNull Parcel dest, int flags) { - dest.writeParcelable(mUtcTime, 0); + dest.writeParcelable(mUnixEpochTime, 0); dest.writeList(mDebugInfo); } @NonNull - public TimestampedValue<Long> getUtcTime() { - return mUtcTime; + public TimestampedValue<Long> getUnixEpochTime() { + return mUnixEpochTime; } @NonNull @@ -117,18 +118,18 @@ public final class NetworkTimeSuggestion implements Parcelable { return false; } NetworkTimeSuggestion that = (NetworkTimeSuggestion) o; - return Objects.equals(mUtcTime, that.mUtcTime); + return Objects.equals(mUnixEpochTime, that.mUnixEpochTime); } @Override public int hashCode() { - return Objects.hash(mUtcTime); + return Objects.hash(mUnixEpochTime); } @Override public String toString() { return "NetworkTimeSuggestion{" - + "mUtcTime=" + mUtcTime + + "mUnixEpochTime=" + mUnixEpochTime + ", mDebugInfo=" + mDebugInfo + '}'; } diff --git a/core/java/android/app/timedetector/TelephonyTimeSuggestion.java b/core/java/android/app/timedetector/TelephonyTimeSuggestion.java index 6c3a304ed3a7..4ff75174ab57 100644 --- a/core/java/android/app/timedetector/TelephonyTimeSuggestion.java +++ b/core/java/android/app/timedetector/TelephonyTimeSuggestion.java @@ -34,12 +34,12 @@ import java.util.Objects; * <p>{@code slotIndex} identifies the suggestion source. This enables detection logic to identify * suggestions from the same source when there are several in use. * - * <p>{@code utcTime}. When not {@code null}, the {@code utcTime.value} is the number of - * milliseconds elapsed since 1/1/1970 00:00:00 UTC. The {@code utcTime.referenceTimeMillis} is the - * value of the elapsed realtime clock when the {@code utcTime.value} was established. + * <p>{@code unixEpochTime}. When not {@code null}, the {@code unixEpochTime.value} is the number of + * milliseconds elapsed since 1/1/1970 00:00:00 UTC. The {@code unixEpochTime.referenceTimeMillis} + * is the value of the elapsed realtime clock when the {@code unixEpochTime.value} was established. * Note that the elapsed realtime clock is considered accurate but it is volatile, so time - * suggestions cannot be persisted across device resets. {@code utcTime} can be {@code null} to - * indicate that the telephony source has entered an "un-opinionated" state and any previous + * suggestions cannot be persisted across device resets. {@code unixEpochTime} can be {@code null} + * to indicate that the telephony source has entered an "un-opinionated" state and any previous * suggestion from the source is being withdrawn. * * <p>{@code debugInfo} contains debugging metadata associated with the suggestion. This is used to @@ -65,19 +65,20 @@ public final class TelephonyTimeSuggestion implements Parcelable { }; private final int mSlotIndex; - @Nullable private final TimestampedValue<Long> mUtcTime; + @Nullable private final TimestampedValue<Long> mUnixEpochTime; @Nullable private ArrayList<String> mDebugInfo; private TelephonyTimeSuggestion(Builder builder) { mSlotIndex = builder.mSlotIndex; - mUtcTime = builder.mUtcTime; + mUnixEpochTime = builder.mUnixEpochTime; mDebugInfo = builder.mDebugInfo != null ? new ArrayList<>(builder.mDebugInfo) : null; } private static TelephonyTimeSuggestion createFromParcel(Parcel in) { int slotIndex = in.readInt(); + TimestampedValue<Long> unixEpochTime = in.readParcelable(null /* classLoader */); TelephonyTimeSuggestion suggestion = new TelephonyTimeSuggestion.Builder(slotIndex) - .setUtcTime(in.readParcelable(null /* classLoader */)) + .setUnixEpochTime(unixEpochTime) .build(); @SuppressWarnings("unchecked") ArrayList<String> debugInfo = (ArrayList<String>) in.readArrayList(null /* classLoader */); @@ -95,7 +96,7 @@ public final class TelephonyTimeSuggestion implements Parcelable { @Override public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeInt(mSlotIndex); - dest.writeParcelable(mUtcTime, 0); + dest.writeParcelable(mUnixEpochTime, 0); dest.writeList(mDebugInfo); } @@ -111,11 +112,11 @@ public final class TelephonyTimeSuggestion implements Parcelable { /** * Returns the suggested time or {@code null} if there isn't one. * - * <p>See {@link TelephonyTimeSuggestion} for more information about {@code utcTime}. + * <p>See {@link TelephonyTimeSuggestion} for more information about {@code unixEpochTime}. */ @Nullable - public TimestampedValue<Long> getUtcTime() { - return mUtcTime; + public TimestampedValue<Long> getUnixEpochTime() { + return mUnixEpochTime; } /** @@ -163,19 +164,19 @@ public final class TelephonyTimeSuggestion implements Parcelable { } TelephonyTimeSuggestion that = (TelephonyTimeSuggestion) o; return mSlotIndex == that.mSlotIndex - && Objects.equals(mUtcTime, that.mUtcTime); + && Objects.equals(mUnixEpochTime, that.mUnixEpochTime); } @Override public int hashCode() { - return Objects.hash(mSlotIndex, mUtcTime); + return Objects.hash(mSlotIndex, mUnixEpochTime); } @Override public String toString() { return "TelephonyTimeSuggestion{" + "mSlotIndex='" + mSlotIndex + '\'' - + ", mUtcTime=" + mUtcTime + + ", mUnixEpochTime=" + mUnixEpochTime + ", mDebugInfo=" + mDebugInfo + '}'; } @@ -187,7 +188,7 @@ public final class TelephonyTimeSuggestion implements Parcelable { */ public static final class Builder { private final int mSlotIndex; - @Nullable private TimestampedValue<Long> mUtcTime; + @Nullable private TimestampedValue<Long> mUnixEpochTime; @Nullable private List<String> mDebugInfo; /** @@ -202,16 +203,16 @@ public final class TelephonyTimeSuggestion implements Parcelable { /** * Returns the builder for call chaining. * - * <p>See {@link TelephonyTimeSuggestion} for more information about {@code utcTime}. + * <p>See {@link TelephonyTimeSuggestion} for more information about {@code unixEpochTime}. */ @NonNull - public Builder setUtcTime(@Nullable TimestampedValue<Long> utcTime) { - if (utcTime != null) { - // utcTime can be null, but the value it holds cannot. - Objects.requireNonNull(utcTime.getValue()); + public Builder setUnixEpochTime(@Nullable TimestampedValue<Long> unixEpochTime) { + if (unixEpochTime != null) { + // unixEpochTime can be null, but the value it holds cannot. + Objects.requireNonNull(unixEpochTime.getValue()); } - mUtcTime = utcTime; + mUnixEpochTime = unixEpochTime; return this; } diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 30850e3ba06c..7cb093421417 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -3434,7 +3434,7 @@ public abstract class Context { public abstract boolean stopServiceAsUser(Intent service, UserHandle user); /** - * Connect to an application service, creating it if needed. This defines + * Connects to an application service, creating it if needed. This defines * a dependency between your application and the service. The given * <var>conn</var> will receive the service object when it is created and be * told if it dies and restarts. The service will be considered required @@ -3449,11 +3449,8 @@ public abstract class Context { * will be invoked instead of * {@link ServiceConnection#onServiceConnected(ComponentName, IBinder) onServiceConnected()}. * - * <p>This method will throw {@link SecurityException} if the calling app does not - * have permission to bind to the given service. - * - * <p class="note">Note: this method <em>cannot be called from a - * {@link BroadcastReceiver} component</em>. A pattern you can use to + * <p class="note"><b>Note:</b> This method <em>cannot</em> be called from a + * {@link BroadcastReceiver} component. A pattern you can use to * communicate from a BroadcastReceiver to a Service is to call * {@link #startService} with the arguments containing the command to be * sent, with the service calling its @@ -3468,43 +3465,49 @@ public abstract class Context { * specify an explicit component name. * @param conn Receives information as the service is started and stopped. * This must be a valid ServiceConnection object; it must not be null. - * @param flags Operation options for the binding. May be 0, - * {@link #BIND_AUTO_CREATE}, {@link #BIND_DEBUG_UNBIND}, - * {@link #BIND_NOT_FOREGROUND}, {@link #BIND_ABOVE_CLIENT}, - * {@link #BIND_ALLOW_OOM_MANAGEMENT}, {@link #BIND_WAIVE_PRIORITY}. - * {@link #BIND_IMPORTANT}, {@link #BIND_ADJUST_WITH_ACTIVITY}, - * {@link #BIND_NOT_PERCEPTIBLE}, or {@link #BIND_INCLUDE_CAPABILITIES}. + * @param flags Operation options for the binding. Can be: + * <ul> + * <li>0 + * <li>{@link #BIND_AUTO_CREATE} + * <li>{@link #BIND_DEBUG_UNBIND} + * <li>{@link #BIND_NOT_FOREGROUND} + * <li>{@link #BIND_ABOVE_CLIENT} + * <li>{@link #BIND_ALLOW_OOM_MANAGEMENT} + * <li>{@link #BIND_WAIVE_PRIORITY} + * <li>{@link #BIND_IMPORTANT} + * <li>{@link #BIND_ADJUST_WITH_ACTIVITY} + * <li>{@link #BIND_NOT_PERCEPTIBLE} + * <li>{@link #BIND_INCLUDE_CAPABILITIES} + * </ul> + * * @return {@code true} if the system is in the process of bringing up a - * service that your client has permission to bind to; {@code false} - * if the system couldn't find the service or if your client doesn't - * have permission to bind to it. If this value is {@code true}, you - * should later call {@link #unbindService} to release the - * connection. + * service that your client has permission to bind to; {@code false} + * if the system couldn't find the service or if your client doesn't + * have permission to bind to it. Regardless of the return value, you + * should later call {@link #unbindService} to release the connection. * - * @throws SecurityException If the caller does not have permission to access the service - * or the service can not be found. + * @throws SecurityException If the caller does not have permission to + * access the service or the service cannot be found. Call + * {@link #unbindService} to release the connection when this exception + * is thrown. * * @see #unbindService * @see #startService - * @see #BIND_AUTO_CREATE - * @see #BIND_DEBUG_UNBIND - * @see #BIND_NOT_FOREGROUND - * @see #BIND_ABOVE_CLIENT - * @see #BIND_ALLOW_OOM_MANAGEMENT - * @see #BIND_WAIVE_PRIORITY - * @see #BIND_IMPORTANT - * @see #BIND_ADJUST_WITH_ACTIVITY - * @see #BIND_NOT_PERCEPTIBLE - * @see #BIND_INCLUDE_CAPABILITIES */ public abstract boolean bindService(@RequiresPermission Intent service, @NonNull ServiceConnection conn, @BindServiceFlags int flags); /** - * Same as {@link #bindService(Intent, ServiceConnection, int)} with executor to control - * ServiceConnection callbacks. + * Same as {@link #bindService(Intent, ServiceConnection, int) + * bindService(Intent, ServiceConnection, int)} with executor to control ServiceConnection + * callbacks. + * * @param executor Callbacks on ServiceConnection will be called on executor. Must use same * instance for the same instance of ServiceConnection. + * + * @return The result of the binding as described in + * {@link #bindService(Intent, ServiceConnection, int) + * bindService(Intent, ServiceConnection, int)}. */ public boolean bindService(@RequiresPermission @NonNull Intent service, @BindServiceFlags int flags, @NonNull @CallbackExecutor Executor executor, @@ -3530,12 +3533,13 @@ public abstract class Context { * @param instanceName Unique identifier for the service instance. Each unique * name here will result in a different service instance being created. Identifiers * must only contain ASCII letters, digits, underscores, and periods. - * @return Returns success of binding as per {@link #bindService}. * @param executor Callbacks on ServiceConnection will be called on executor. * Must use same instance for the same instance of ServiceConnection. * @param conn Receives information as the service is started and stopped. * This must be a valid ServiceConnection object; it must not be null. * + * @return Returns success of binding as per {@link #bindService}. + * * @throws SecurityException If the caller does not have permission to access the service * @throws IllegalArgumentException If the instanceName is invalid. * @@ -3550,8 +3554,7 @@ public abstract class Context { } /** - * Binds to a service in the given {@code user} in the same manner as - * {@link #bindService(Intent, ServiceConnection, int)}. + * Binds to a service in the given {@code user} in the same manner as {@link #bindService}. * * <p>If the given {@code user} is in the same profile group and the target package is the * same as the caller, {@code android.Manifest.permission.INTERACT_ACROSS_PROFILES} is diff --git a/core/java/android/content/ServiceConnection.java b/core/java/android/content/ServiceConnection.java index 21398f6e6473..660a7f0acbba 100644 --- a/core/java/android/content/ServiceConnection.java +++ b/core/java/android/content/ServiceConnection.java @@ -63,8 +63,12 @@ public interface ServiceConnection { * happen, for example, if the application hosting the service it is bound to * has been updated. * - * @param name The concrete component name of the service whose - * connection is dead. + * <p class="note"><b>Note:</b> The app that requested the binding must call + * {@link Context#unbindService(ServiceConnection)} to release the tracking + * resources associated with this ServiceConnection even if this callback was + * invoked following {@link Context#bindService Context.bindService() bindService()}. + * + * @param name The concrete component name of the service whose connection is dead. */ default void onBindingDied(ComponentName name) { } @@ -72,10 +76,10 @@ public interface ServiceConnection { /** * Called when the service being bound has returned {@code null} from its * {@link android.app.Service#onBind(Intent) onBind()} method. This indicates - * that the attempting service binding represented by this ServiceConnection + * that the attempted service binding represented by this ServiceConnection * will never become usable. * - * <p class="note">The app which requested the binding must still call + * <p class="note"><b>Note:</b> The app that requested the binding must still call * {@link Context#unbindService(ServiceConnection)} to release the tracking * resources associated with this ServiceConnection even if this callback was * invoked following {@link Context#bindService Context.bindService() bindService()}. diff --git a/core/java/android/hardware/SensorManager.java b/core/java/android/hardware/SensorManager.java index e3ff0891cc95..ee62170dbfd5 100644 --- a/core/java/android/hardware/SensorManager.java +++ b/core/java/android/hardware/SensorManager.java @@ -638,7 +638,7 @@ public abstract class SensorManager { /** * Unregisters a listener for the sensors with which it is registered. * - * <p class="note"></p> + * <p class="note"> * Note: Don't use this method with a one shot trigger sensor such as * {@link Sensor#TYPE_SIGNIFICANT_MOTION}. * Use {@link #cancelTriggerSensor(TriggerEventListener, Sensor)} instead. diff --git a/core/java/android/net/Ikev2VpnProfile.java b/core/java/android/net/Ikev2VpnProfile.java index ec752fdbf45f..0fd3e034291b 100644 --- a/core/java/android/net/Ikev2VpnProfile.java +++ b/core/java/android/net/Ikev2VpnProfile.java @@ -547,7 +547,8 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { if (profile.excludeLocalRoutes && !profile.isBypassable) { Log.w(TAG, "ExcludeLocalRoutes should only be set in the bypassable VPN"); } - builder.setExcludeLocalRoutes(profile.excludeLocalRoutes && profile.isBypassable); + + builder.setLocalRoutesExcluded(profile.excludeLocalRoutes && profile.isBypassable); builder.setRequiresInternetValidation(profile.requiresInternetValidation); return builder.build(); @@ -1104,7 +1105,7 @@ public final class Ikev2VpnProfile extends PlatformVpnProfile { */ @NonNull @RequiresFeature(PackageManager.FEATURE_IPSEC_TUNNELS) - public Builder setExcludeLocalRoutes(boolean excludeLocalRoutes) { + public Builder setLocalRoutesExcluded(boolean excludeLocalRoutes) { mExcludeLocalRoutes = excludeLocalRoutes; return this; } diff --git a/core/java/android/net/NetworkPolicy.java b/core/java/android/net/NetworkPolicy.java index ab1f5420fb3f..4b35b0d773d5 100644 --- a/core/java/android/net/NetworkPolicy.java +++ b/core/java/android/net/NetworkPolicy.java @@ -338,7 +338,9 @@ public class NetworkPolicy implements Parcelable, Comparable<NetworkPolicy> { out.writeInt(TEMPLATE_BACKUP_VERSION_LATEST); out.writeInt(template.getMatchRule()); - BackupUtils.writeString(out, template.getSubscriberIds().iterator().next()); + final Set<String> subscriberIds = template.getSubscriberIds(); + BackupUtils.writeString(out, subscriberIds.isEmpty() + ? null : subscriberIds.iterator().next()); BackupUtils.writeString(out, template.getWifiNetworkKeys().isEmpty() ? null : template.getWifiNetworkKeys().iterator().next()); out.writeInt(template.getMeteredness()); diff --git a/core/java/android/net/NetworkPolicyManager.java b/core/java/android/net/NetworkPolicyManager.java index c936bfa05118..0e39f425c0fa 100644 --- a/core/java/android/net/NetworkPolicyManager.java +++ b/core/java/android/net/NetworkPolicyManager.java @@ -167,6 +167,8 @@ public class NetworkPolicyManager { public static final String FIREWALL_CHAIN_NAME_POWERSAVE = "powersave"; /** @hide */ public static final String FIREWALL_CHAIN_NAME_RESTRICTED = "restricted"; + /** @hide */ + public static final String FIREWALL_CHAIN_NAME_LOW_POWER_STANDBY = "low_power_standby"; private static final boolean ALLOW_PLATFORM_APP_POLICY = true; diff --git a/core/java/android/net/PlatformVpnProfile.java b/core/java/android/net/PlatformVpnProfile.java index 8bd1c8d07017..c0fb4cf4f3dd 100644 --- a/core/java/android/net/PlatformVpnProfile.java +++ b/core/java/android/net/PlatformVpnProfile.java @@ -83,7 +83,7 @@ public abstract class PlatformVpnProfile { /** * Returns whether the local traffic is exempted from the VPN. */ - public final boolean getExcludeLocalRoutes() { + public final boolean areLocalRoutesExcluded() { return mExcludeLocalRoutes; } diff --git a/core/java/android/net/VpnManager.java b/core/java/android/net/VpnManager.java index 5aad997af8c1..779d931245c8 100644 --- a/core/java/android/net/VpnManager.java +++ b/core/java/android/net/VpnManager.java @@ -24,6 +24,7 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; +import android.annotation.SdkConstant; import android.annotation.SystemApi; import android.annotation.UserIdInt; import android.app.Activity; @@ -52,7 +53,7 @@ import java.util.List; * app (unlike VpnService). * * <p>VPN apps using supported protocols should preferentially use this API over the {@link - * VpnService} API for ease-of-development and reduced maintainance burden. This also give the user + * VpnService} API for ease-of-development and reduced maintenance burden. This also give the user * the guarantee that VPN network traffic is not subjected to on-device packet interception. * * @see Ikev2VpnProfile @@ -97,130 +98,173 @@ public class VpnManager { public static final String NOTIFICATION_CHANNEL_VPN = "VPN"; /** - * Action sent in the intent when an error occurred. + * Action sent in {@link android.content.Intent}s to VpnManager clients when an event occurred. * - * @hide + * This action will have a category of either {@link #CATEGORY_EVENT_IKE_ERROR}, + * {@link #CATEGORY_EVENT_NETWORK_ERROR}, or {@link #CATEGORY_EVENT_DEACTIVATED_BY_USER}, + * that the app can use to filter events it's interested in reacting to. + * + * It will also contain the following extras : + * <ul> + * <li>{@link #EXTRA_SESSION_KEY}, a {@code String} for the session key, as returned by + * {@link #startProvisionedVpnProfileSession}. + * <li>{@link #EXTRA_TIMESTAMP}, a long for the timestamp at which the error occurred, + * in milliseconds since the epoch, as returned by + * {@link java.lang.System#currentTimeMillis}. + * <li>{@link #EXTRA_UNDERLYING_NETWORK}, a {@link Network} containing the underlying + * network at the time the error occurred, or null if none. Note that this network + * may have disconnected already. + * <li>{@link #EXTRA_UNDERLYING_NETWORK_CAPABILITIES}, a {@link NetworkCapabilities} for + * the underlying network at the time the error occurred. + * <li>{@link #EXTRA_UNDERLYING_LINK_PROPERTIES}, a {@link LinkProperties} for the underlying + * network at the time the error occurred. + * </ul> + * When this event is an error, either {@link #CATEGORY_EVENT_IKE_ERROR} or + * {@link #CATEGORY_EVENT_NETWORK_ERROR}, the following extras will be populated : + * <ul> + * <li>{@link #EXTRA_ERROR_CLASS}, an {@code int} for the class of error, either + * {@link #ERROR_CLASS_RECOVERABLE} or {@link #ERROR_CLASS_NOT_RECOVERABLE}. + * <li>{@link #EXTRA_ERROR_CODE}, an {@code int} error code specific to the error. See + * {@link #EXTRA_ERROR_CODE} for details. + * </ul> */ - public static final String ACTION_VPN_MANAGER_ERROR = "android.net.action.VPN_MANAGER_ERROR"; + @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION) + public static final String ACTION_VPN_MANAGER_EVENT = "android.net.action.VPN_MANAGER_EVENT"; /** - * An IKE protocol error. Codes are the codes from IkeProtocolException, RFC 7296. + * An IKE protocol error occurred. * - * @hide + * Codes (in {@link #EXTRA_ERROR_CODE}) are the codes from + * {@link android.net.ipsec.ike.exceptions.IkeProtocolException}, as defined by IANA in + * "IKEv2 Notify Message Types - Error Types". */ - public static final String CATEGORY_ERROR_IKE = "android.net.category.ERROR_IKE"; + @SdkConstant(SdkConstant.SdkConstantType.INTENT_CATEGORY) + public static final String CATEGORY_EVENT_IKE_ERROR = "android.net.category.EVENT_IKE_ERROR"; /** - * User deactivated the VPN, either by turning it off or selecting a different VPN provider. - * The error code is always 0. + * A network error occurred. * - * @hide + * Error codes (in {@link #EXTRA_ERROR_CODE}) are ERROR_CODE_NETWORK_*. */ - public static final String CATEGORY_ERROR_USER_DEACTIVATED = - "android.net.category.ERROR_USER_DEACTIVATED"; + @SdkConstant(SdkConstant.SdkConstantType.INTENT_CATEGORY) + public static final String CATEGORY_EVENT_NETWORK_ERROR = + "android.net.category.EVENT_NETWORK_ERROR"; /** - * Network error. Error codes are ERROR_CODE_NETWORK_*. + * The user deactivated the VPN. * - * @hide + * This can happen either when the user turns the VPN off explicitly, or when they select + * a different VPN provider. */ - public static final String CATEGORY_ERROR_NETWORK = "android.net.category.ERROR_NETWORK"; + @SdkConstant(SdkConstant.SdkConstantType.INTENT_CATEGORY) + public static final String CATEGORY_EVENT_DEACTIVATED_BY_USER = + "android.net.category.EVENT_DEACTIVATED_BY_USER"; /** - * The key of the session that experienced this error, as returned by - * startProvisionedVpnProfileSession. + * The key of the session that experienced this event, as a {@code String}. * - * @hide + * This is the same key that was returned by {@link #startProvisionedVpnProfileSession}. */ public static final String EXTRA_SESSION_KEY = "android.net.extra.SESSION_KEY"; /** - * Extra for the Network object that was the underlying network at the time of the failure, or - * null if none. + * The network that was underlying the VPN when the event occurred, as a {@link Network}. * - * @hide + * This extra will be null if there was no underlying network at the time of the event. */ public static final String EXTRA_UNDERLYING_NETWORK = "android.net.extra.UNDERLYING_NETWORK"; /** - * The NetworkCapabilities of the underlying network. + * The {@link NetworkCapabilities} of the underlying network when the event occurred. * - * @hide + * This extra will be null if there was no underlying network at the time of the event. */ public static final String EXTRA_UNDERLYING_NETWORK_CAPABILITIES = "android.net.extra.UNDERLYING_NETWORK_CAPABILITIES"; /** - * The LinkProperties of the underlying network. + * The {@link LinkProperties} of the underlying network when the event occurred. * - * @hide + * This extra will be null if there was no underlying network at the time of the event. */ public static final String EXTRA_UNDERLYING_LINK_PROPERTIES = "android.net.extra.UNDERLYING_LINK_PROPERTIES"; /** - * A long timestamp with SystemClock.elapsedRealtime base for when the event happened. + * A {@code long} timestamp containing the time at which the event occurred. * - * @hide + * This is a number of milliseconds since the epoch, suitable to be compared with + * {@link java.lang.System#currentTimeMillis}. */ public static final String EXTRA_TIMESTAMP = "android.net.extra.TIMESTAMP"; /** - * Extra for the error type. This is ERROR_NOT_RECOVERABLE or ERROR_RECOVERABLE. + * Extra for the error class, as an {@code int}. * - * @hide + * This is always either {@link #ERROR_CLASS_NOT_RECOVERABLE} or + * {@link #ERROR_CLASS_RECOVERABLE}. This extra is only populated for error categories. */ - public static final String EXTRA_ERROR_TYPE = "android.net.extra.ERROR_TYPE"; + public static final String EXTRA_ERROR_CLASS = "android.net.extra.ERROR_CLASS"; /** - * Extra for the error code. The value will be 0 for CATEGORY_ERROR_USER_DEACTIVATED, one of - * ERROR_CODE_NETWORK_* for ERROR_CATEGORY_NETWORK or one of values defined in - * IkeProtocolException#ErrorType for CATEGORY_ERROR_IKE. + * Extra for an error code, as an {@code int}. * - * @hide + * <ul> + * <li>For {@link #CATEGORY_EVENT_NETWORK_ERROR}, this is one of the + * {@code ERROR_CODE_NETWORK_*} constants. + * <li>For {@link #CATEGORY_EVENT_IKE_ERROR}, this is one of values defined in + * {@link android.net.ipsec.ike.exceptions.IkeProtocolException}.ERROR_TYPE_*. + * </ul> + * For non-error categories, this extra is not populated. */ public static final String EXTRA_ERROR_CODE = "android.net.extra.ERROR_CODE"; /** - * This error is fatal, e.g. the VPN was disabled or configuration error. The stack will not - * retry connection. + * {@link #EXTRA_ERROR_CLASS} coding for a non-recoverable error. * - * @hide + * This error is fatal, e.g. configuration error. The stack will not retry connection. */ - public static final int ERROR_NOT_RECOVERABLE = 1; + public static final int ERROR_CLASS_NOT_RECOVERABLE = 1; /** - * The stack experienced an error but will retry with exponential backoff, e.g. network timeout. + * {@link #EXTRA_ERROR_CLASS} coding for a recoverable error. * - * @hide + * The stack experienced an error but will retry with exponential backoff, e.g. network timeout. */ - public static final int ERROR_RECOVERABLE = 2; + public static final int ERROR_CLASS_RECOVERABLE = 2; /** - * An error code to indicate that there was an UnknownHostException. + * An {@link #EXTRA_ERROR_CODE} for {@link #CATEGORY_EVENT_NETWORK_ERROR} to indicate that the + * network host isn't known. * - * @hide + * This happens when domain name resolution could not resolve an IP address for the + * specified host. {@see java.net.UnknownHostException} */ public static final int ERROR_CODE_NETWORK_UNKNOWN_HOST = 0; /** - * An error code to indicate that there is a SocketTimeoutException. + * An {@link #EXTRA_ERROR_CODE} for {@link #CATEGORY_EVENT_NETWORK_ERROR} indicating a timeout. * - * @hide + * For Ikev2 VPNs, this happens typically after a retransmission failure. + * {@see android.net.ipsec.ike.exceptions.IkeTimeoutException} */ - public static final int ERROR_CODE_NETWORK_TIMEOUT = 1; + public static final int ERROR_CODE_NETWORK_PROTOCOL_TIMEOUT = 1; /** - * An error code to indicate the connection was reset. (e.g. SocketException) + * An {@link #EXTRA_ERROR_CODE} for {@link #CATEGORY_EVENT_NETWORK_ERROR} indicating that + * network connectivity was lost. * - * @hide + * The most common reason for this error is that the underlying network was disconnected, + * {@see android.net.ipsec.ike.exceptions.IkeNetworkLostException}. */ - public static final int ERROR_CODE_NETWORK_RESET = 2; + public static final int ERROR_CODE_NETWORK_LOST = 2; /** - * An error code to indicate that there is an IOException. + * An {@link #EXTRA_ERROR_CODE} for {@link #CATEGORY_EVENT_NETWORK_ERROR} indicating an + * input/output error. * - * @hide + * This code happens when reading or writing to sockets on the underlying networks was + * terminated by an I/O error. {@see IOException}. */ public static final int ERROR_CODE_NETWORK_IO = 3; diff --git a/core/java/android/nfc/cardemulation/CardEmulation.java b/core/java/android/nfc/cardemulation/CardEmulation.java index 0a9fe90f2524..9a780c8a2935 100644 --- a/core/java/android/nfc/cardemulation/CardEmulation.java +++ b/core/java/android/nfc/cardemulation/CardEmulation.java @@ -84,13 +84,6 @@ public final class CardEmulation { public static final String EXTRA_SERVICE_COMPONENT = "component"; /** - * The caller userId extra for {@link #ACTION_CHANGE_DEFAULT}. - * - * @see #ACTION_CHANGE_DEFAULT - */ - public static final String EXTRA_USERID = "android.nfc.cardemulation.extra.USERID"; - - /** * Category used for NFC payment services. */ public static final String CATEGORY_PAYMENT = "payment"; diff --git a/apex/media/aidl/stable/android/media/Session2Token.aidl b/core/java/android/os/BadTypeParcelableException.java index c5980e9e77fd..2ca3bd2adca1 100644 --- a/apex/media/aidl/stable/android/media/Session2Token.aidl +++ b/core/java/android/os/BadTypeParcelableException.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 The Android Open Source Project + * Copyright (C) 2022 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. @@ -14,6 +14,17 @@ * limitations under the License. */ -package android.media; +package android.os; -parcelable Session2Token; +/** Used by Parcel to signal that the type on the payload was not expected by the caller. */ +class BadTypeParcelableException extends BadParcelableException { + BadTypeParcelableException(String msg) { + super(msg); + } + BadTypeParcelableException(Exception cause) { + super(cause); + } + BadTypeParcelableException(String msg, Throwable cause) { + super(msg, cause); + } +} diff --git a/core/java/android/os/BaseBundle.java b/core/java/android/os/BaseBundle.java index ad3de25fecc2..45812e551618 100644 --- a/core/java/android/os/BaseBundle.java +++ b/core/java/android/os/BaseBundle.java @@ -16,6 +16,8 @@ package android.os; +import static java.util.Objects.requireNonNull; + import android.annotation.NonNull; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; @@ -31,7 +33,7 @@ import com.android.internal.util.IndentingPrintWriter; import java.io.Serializable; import java.util.ArrayList; import java.util.Set; -import java.util.function.Supplier; +import java.util.function.BiFunction; /** * A mapping from String keys to values of various types. In most cases, you @@ -252,11 +254,10 @@ public class BaseBundle { if (size == 0) { return null; } - Object o = getValueAt(0); try { - return (String) o; - } catch (ClassCastException e) { - typeWarning("getPairValue()", o, "String", e); + return getValueAt(0, String.class); + } catch (ClassCastException | BadTypeParcelableException e) { + typeWarning("getPairValue()", "String", e); return null; } } @@ -309,7 +310,7 @@ public class BaseBundle { } for (int i = 0, n = mMap.size(); i < n; i++) { // Triggers deserialization of i-th item, if needed - getValueAt(i); + getValueAt(i, /* clazz */ null); } } } @@ -321,26 +322,59 @@ public class BaseBundle { * This call should always be made after {@link #unparcel()} or inside a lock after making sure * {@code mMap} is not null. * + * @deprecated Use {@link #getValue(String, Class, Class[])}. This method should only be used in + * other deprecated APIs. + * * @hide */ + @Deprecated + @Nullable final Object getValue(String key) { + return getValue(key, /* clazz */ null); + } + + /** Same as {@link #getValue(String, Class, Class[])} with no item types. */ + @Nullable + final <T> T getValue(String key, @Nullable Class<T> clazz) { + // Avoids allocating Class[0] array + return getValue(key, clazz, (Class<?>[]) null); + } + + /** + * Returns the value for key {@code key} for expected return type {@code clazz} (or pass {@code + * null} for no type check). + * + * For {@code itemTypes}, see {@link Parcel#readValue(int, ClassLoader, Class, Class[])}. + * + * This call should always be made after {@link #unparcel()} or inside a lock after making sure + * {@code mMap} is not null. + * + * @hide + */ + @Nullable + final <T> T getValue(String key, @Nullable Class<T> clazz, @Nullable Class<?>... itemTypes) { int i = mMap.indexOfKey(key); - return (i >= 0) ? getValueAt(i) : null; + return (i >= 0) ? getValueAt(i, clazz, itemTypes) : null; } /** - * Returns the value for a certain position in the array map. + * Returns the value for a certain position in the array map for expected return type {@code + * clazz} (or pass {@code null} for no type check). + * + * For {@code itemTypes}, see {@link Parcel#readValue(int, ClassLoader, Class, Class[])}. * * This call should always be made after {@link #unparcel()} or inside a lock after making sure * {@code mMap} is not null. * * @hide */ - final Object getValueAt(int i) { + @SuppressWarnings("unchecked") + @Nullable + final <T> T getValueAt(int i, @Nullable Class<T> clazz, @Nullable Class<?>... itemTypes) { Object object = mMap.valueAt(i); - if (object instanceof Supplier<?>) { + if (object instanceof BiFunction<?, ?, ?>) { try { - object = ((Supplier<?>) object).get(); + object = ((BiFunction<Class<?>, Class<?>[], ?>) object).apply(clazz, itemTypes); } catch (BadParcelableException e) { if (sShouldDefuse) { Log.w(TAG, "Failed to parse item " + mMap.keyAt(i) + ", returning null.", e); @@ -351,7 +385,7 @@ public class BaseBundle { } mMap.setValueAt(i, object); } - return object; + return (clazz != null) ? clazz.cast(object) : (T) object; } private void initializeFromParcelLocked(@NonNull Parcel parcelledData, boolean recycleParcel, @@ -528,7 +562,7 @@ public class BaseBundle { } else { // Following semantic above of failing in case we get a serialized value vs a // deserialized one, we'll compare the map. If a certain element hasn't been - // deserialized yet, it's a Supplier (or more specifically a LazyValue, but let's + // deserialized yet, it's a function object (or more specifically a LazyValue, but let's // pretend we don't know that here :P), we'll use that element's equality comparison as // map naturally does. That will takes care of comparing the payload if needed (see // Parcel.readLazyValue() for details). @@ -602,7 +636,11 @@ public class BaseBundle { * * @param key a String key * @return an Object, or null + * + * @deprecated Use the type-safe specific APIs depending on the type of the item to be + * retrieved, eg. {@link #getString(String)}. */ + @Deprecated @Nullable public Object get(String key) { unparcel(); @@ -610,6 +648,32 @@ public class BaseBundle { } /** + * Returns the object of type {@code clazz} for the given {@code key}, or {@code null} if: + * <ul> + * <li>No mapping of the desired type exists for the given key. + * <li>A {@code null} value is explicitly associated with the key. + * <li>The object is not of type {@code clazz}. + * </ul> + * + * <p>Use the more specific APIs where possible, especially in the case of containers such as + * lists, since those APIs allow you to specify the type of the items. + * + * @param key String key + * @param clazz The type of the object expected + * @return an Object, or null + */ + @Nullable + <T> T get(@Nullable String key, @NonNull Class<T> clazz) { + unparcel(); + try { + return getValue(key, requireNonNull(clazz)); + } catch (ClassCastException | BadTypeParcelableException e) { + typeWarning(key, clazz.getCanonicalName(), e); + return null; + } + } + + /** * Removes any entry with the given key from the mapping of this Bundle. * * @param key a String key @@ -982,15 +1046,19 @@ public class BaseBundle { } // Log a message if the value was non-null but not of the expected type - void typeWarning(String key, Object value, String className, - Object defaultValue, ClassCastException e) { + void typeWarning(String key, @Nullable Object value, String className, + Object defaultValue, RuntimeException e) { StringBuilder sb = new StringBuilder(); sb.append("Key "); sb.append(key); sb.append(" expected "); sb.append(className); - sb.append(" but value was a "); - sb.append(value.getClass().getName()); + if (value != null) { + sb.append(" but value was a "); + sb.append(value.getClass().getName()); + } else { + sb.append(" but value was of a different type"); + } sb.append(". The default value "); sb.append(defaultValue); sb.append(" was returned."); @@ -998,11 +1066,14 @@ public class BaseBundle { Log.w(TAG, "Attempt to cast generated internal exception:", e); } - void typeWarning(String key, Object value, String className, - ClassCastException e) { + void typeWarning(String key, @Nullable Object value, String className, RuntimeException e) { typeWarning(key, value, className, "<null>", e); } + void typeWarning(String key, String className, RuntimeException e) { + typeWarning(key, /* value */ null, className, "<null>", e); + } + /** * Returns the value associated with the given key, or defaultValue if * no mapping of the desired type exists for the given key. @@ -1342,7 +1413,11 @@ public class BaseBundle { * * @param key a String, or null * @return a Serializable value, or null + * + * @deprecated Use {@link #getSerializable(String, Class)}. This method should only be used in + * other deprecated APIs. */ + @Deprecated @Nullable Serializable getSerializable(@Nullable String key) { unparcel(); @@ -1359,6 +1434,36 @@ public class BaseBundle { } /** + * Returns the value associated with the given key, or {@code null} if: + * <ul> + * <li>No mapping of the desired type exists for the given key. + * <li>A {@code null} value is explicitly associated with the key. + * <li>The object is not of type {@code clazz}. + * </ul> + * + * @param key a String, or null + * @param clazz The expected class of the returned type + * @return a Serializable value, or null + */ + @Nullable + <T extends Serializable> T getSerializable(@Nullable String key, @NonNull Class<T> clazz) { + return get(key, clazz); + } + + + @SuppressWarnings("unchecked") + @Nullable + <T> ArrayList<T> getArrayList(@Nullable String key, @NonNull Class<T> clazz) { + unparcel(); + try { + return getValue(key, ArrayList.class, requireNonNull(clazz)); + } catch (ClassCastException | BadTypeParcelableException e) { + typeWarning(key, "ArrayList<" + clazz.getCanonicalName() + ">", e); + return null; + } + } + + /** * Returns the value associated with the given key, or null if * no mapping of the desired type exists for the given key or a null * value is explicitly associated with the key. @@ -1368,17 +1473,7 @@ public class BaseBundle { */ @Nullable ArrayList<Integer> getIntegerArrayList(@Nullable String key) { - unparcel(); - Object o = getValue(key); - if (o == null) { - return null; - } - try { - return (ArrayList<Integer>) o; - } catch (ClassCastException e) { - typeWarning(key, o, "ArrayList<Integer>", e); - return null; - } + return getArrayList(key, Integer.class); } /** @@ -1391,17 +1486,7 @@ public class BaseBundle { */ @Nullable ArrayList<String> getStringArrayList(@Nullable String key) { - unparcel(); - Object o = getValue(key); - if (o == null) { - return null; - } - try { - return (ArrayList<String>) o; - } catch (ClassCastException e) { - typeWarning(key, o, "ArrayList<String>", e); - return null; - } + return getArrayList(key, String.class); } /** @@ -1414,17 +1499,7 @@ public class BaseBundle { */ @Nullable ArrayList<CharSequence> getCharSequenceArrayList(@Nullable String key) { - unparcel(); - Object o = getValue(key); - if (o == null) { - return null; - } - try { - return (ArrayList<CharSequence>) o; - } catch (ClassCastException e) { - typeWarning(key, o, "ArrayList<CharSequence>", e); - return null; - } + return getArrayList(key, CharSequence.class); } /** diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java index f46f45228f07..545ae38c38c0 100755 --- a/core/java/android/os/Build.java +++ b/core/java/android/os/Build.java @@ -401,13 +401,18 @@ public class Build { /** * All known codenames starting from {@link VERSION_CODES.Q}. * - * <p>This includes in development codenames as well. + * <p>This includes in development codenames as well, i.e. if {@link #CODENAME} is not "REL" + * then the value of that is present in this set. + * + * <p>If a particular string is not present in this set, then it is either not a codename + * or a codename for a future release. For example, during Android R development, "Tiramisu" + * was not a known codename. * * @hide */ @SystemApi @NonNull public static final Set<String> KNOWN_CODENAMES = - new ArraySet<>(new String[]{"Q", "R", "S", "Sv2", "Tiramisu"}); + new ArraySet<>(getStringList("ro.build.version.known_codenames", ",")); private static final String[] ALL_CODENAMES = getStringList("ro.build.version.all_codenames", ","); diff --git a/core/java/android/os/Bundle.java b/core/java/android/os/Bundle.java index b2bbfd6c163d..edbbb59ac77d 100644 --- a/core/java/android/os/Bundle.java +++ b/core/java/android/os/Bundle.java @@ -16,7 +16,11 @@ package android.os; +import static java.util.Objects.requireNonNull; + +import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.SuppressLint; import android.compat.annotation.UnsupportedAppUsage; import android.util.ArrayMap; import android.util.Size; @@ -873,7 +877,7 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable { @Nullable public Bundle getBundle(@Nullable String key) { unparcel(); - Object o = getValue(key); + Object o = mMap.get(key); if (o == null) { return null; } @@ -896,7 +900,11 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable { * * @param key a String, or {@code null} * @return a Parcelable value, or {@code null} + * + * @deprecated Use the type-safer {@link #getParcelable(String, Class)} starting from Android + * {@link Build.VERSION_CODES#TIRAMISU}. */ + @Deprecated @Nullable public <T extends Parcelable> T getParcelable(@Nullable String key) { unparcel(); @@ -913,6 +921,31 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable { } /** + * Returns the value associated with the given key or {@code null} if: + * <ul> + * <li>No mapping of the desired type exists for the given key. + * <li>A {@code null} value is explicitly associated with the key. + * <li>The object is not of type {@code clazz}. + * </ul> + * + * <p><b>Note: </b> if the expected value is not a class provided by the Android platform, + * you must call {@link #setClassLoader(ClassLoader)} with the proper {@link ClassLoader} first. + * Otherwise, this method might throw an exception or return {@code null}. + * + * @param key a String, or {@code null} + * @param clazz The type of the object expected + * @return a Parcelable value, or {@code null} + */ + @SuppressWarnings("unchecked") + @Nullable + public <T> T getParcelable(@Nullable String key, @NonNull Class<T> clazz) { + // The reason for not using <T extends Parcelable> is because the caller could provide a + // super class to restrict the children that doesn't implement Parcelable itself while the + // children do, more details at b/210800751 (same reasoning applies here). + return get(key, clazz); + } + + /** * Returns the value associated with the given key, or {@code null} if * no mapping of the desired type exists for the given key or a null * value is explicitly associated with the key. @@ -923,7 +956,11 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable { * * @param key a String, or {@code null} * @return a Parcelable[] value, or {@code null} + * + * @deprecated Use the type-safer {@link #getParcelableArray(String, Class)} starting from + * Android {@link Build.VERSION_CODES#TIRAMISU}. */ + @Deprecated @Nullable public Parcelable[] getParcelableArray(@Nullable String key) { unparcel(); @@ -940,6 +977,39 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable { } /** + * Returns the value associated with the given key, or {@code null} if: + * <ul> + * <li>No mapping of the desired type exists for the given key. + * <li>A {@code null} value is explicitly associated with the key. + * <li>The object is not of type {@code clazz}. + * </ul> + * + * <p><b>Note: </b> if the expected value is not a class provided by the Android platform, + * you must call {@link #setClassLoader(ClassLoader)} with the proper {@link ClassLoader} first. + * Otherwise, this method might throw an exception or return {@code null}. + * + * @param key a String, or {@code null} + * @param clazz The type of the items inside the array + * @return a Parcelable[] value, or {@code null} + */ + @SuppressLint({"ArrayReturn", "NullableCollection"}) + @SuppressWarnings("unchecked") + @Nullable + public <T> T[] getParcelableArray(@Nullable String key, @NonNull Class<T> clazz) { + // The reason for not using <T extends Parcelable> is because the caller could provide a + // super class to restrict the children that doesn't implement Parcelable itself while the + // children do, more details at b/210800751 (same reasoning applies here). + unparcel(); + try { + // In Java 12, we can pass clazz.arrayType() instead of Parcelable[] and later casting. + return (T[]) getValue(key, Parcelable[].class, requireNonNull(clazz)); + } catch (ClassCastException | BadTypeParcelableException e) { + typeWarning(key, clazz.getCanonicalName() + "[]", e); + return null; + } + } + + /** * Returns the value associated with the given key, or {@code null} if * no mapping of the desired type exists for the given key or a {@code null} * value is explicitly associated with the key. @@ -950,7 +1020,11 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable { * * @param key a String, or {@code null} * @return an ArrayList<T> value, or {@code null} + * + * @deprecated Use the type-safer {@link #getParcelable(String, Class)} starting from Android + * {@link Build.VERSION_CODES#TIRAMISU}. */ + @Deprecated @Nullable public <T extends Parcelable> ArrayList<T> getParcelableArrayList(@Nullable String key) { unparcel(); @@ -967,14 +1041,43 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable { } /** + * Returns the value associated with the given key, or {@code null} if: + * <ul> + * <li>No mapping of the desired type exists for the given key. + * <li>A {@code null} value is explicitly associated with the key. + * <li>The object is not of type {@code clazz}. + * </ul> + * + * <p><b>Note: </b> if the expected value is not a class provided by the Android platform, + * you must call {@link #setClassLoader(ClassLoader)} with the proper {@link ClassLoader} first. + * Otherwise, this method might throw an exception or return {@code null}. + * + * @param key a String, or {@code null} + * @param clazz The type of the items inside the array list + * @return an ArrayList<T> value, or {@code null} + */ + @SuppressLint("NullableCollection") + @SuppressWarnings("unchecked") + @Nullable + public <T> ArrayList<T> getParcelableArrayList(@Nullable String key, @NonNull Class<T> clazz) { + // The reason for not using <T extends Parcelable> is because the caller could provide a + // super class to restrict the children that doesn't implement Parcelable itself while the + // children do, more details at b/210800751 (same reasoning applies here). + return getArrayList(key, clazz); + } + + /** * Returns the value associated with the given key, or null if * no mapping of the desired type exists for the given key or a null * value is explicitly associated with the key. * * @param key a String, or null - * * @return a SparseArray of T values, or null + * + * @deprecated Use the type-safer {@link #getSparseParcelableArray(String, Class)} starting from + * Android {@link Build.VERSION_CODES#TIRAMISU}. */ + @Deprecated @Nullable public <T extends Parcelable> SparseArray<T> getSparseParcelableArray(@Nullable String key) { unparcel(); @@ -991,13 +1094,44 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable { } /** + * Returns the value associated with the given key, or {@code null} if: + * <ul> + * <li>No mapping of the desired type exists for the given key. + * <li>A {@code null} value is explicitly associated with the key. + * <li>The object is not of type {@code clazz}. + * </ul> + * + * @param key a String, or null + * @return a SparseArray of T values, or null + */ + @SuppressWarnings("unchecked") + @Nullable + public <T> SparseArray<T> getSparseParcelableArray(@Nullable String key, + @NonNull Class<T> clazz) { + // The reason for not using <T extends Parcelable> is because the caller could provide a + // super class to restrict the children that doesn't implement Parcelable itself while the + // children do, more details at b/210800751 (same reasoning applies here). + unparcel(); + try { + return (SparseArray<T>) getValue(key, SparseArray.class, requireNonNull(clazz)); + } catch (ClassCastException | BadTypeParcelableException e) { + typeWarning(key, "SparseArray<" + clazz.getCanonicalName() + ">", e); + return null; + } + } + + /** * Returns the value associated with the given key, or null if * no mapping of the desired type exists for the given key or a null * value is explicitly associated with the key. * * @param key a String, or null * @return a Serializable value, or null + * + * @deprecated Use the type-safer {@link #getSerializable(String, Class)} starting from Android + * {@link Build.VERSION_CODES#TIRAMISU}. */ + @Deprecated @Override @Nullable public Serializable getSerializable(@Nullable String key) { @@ -1005,6 +1139,24 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable { } /** + * Returns the value associated with the given key, or {@code null} if: + * <ul> + * <li>No mapping of the desired type exists for the given key. + * <li>A {@code null} value is explicitly associated with the key. + * <li>The object is not of type {@code clazz}. + * </ul> + * + * @param key a String, or null + * @param clazz The expected class of the returned type + * @return a Serializable value, or null + */ + @Nullable + public <T extends Serializable> T getSerializable(@Nullable String key, + @NonNull Class<T> clazz) { + return super.getSerializable(key, requireNonNull(clazz)); + } + + /** * Returns the value associated with the given key, or null if * no mapping of the desired type exists for the given key or a null * value is explicitly associated with the key. diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java index eed7571b663d..f0fdc9b3b0f3 100644 --- a/core/java/android/os/Parcel.java +++ b/core/java/android/os/Parcel.java @@ -16,6 +16,8 @@ package android.os; +import static com.android.internal.util.Preconditions.checkArgument; + import static java.util.Objects.requireNonNull; import android.annotation.IntDef; @@ -65,6 +67,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; +import java.util.function.BiFunction; import java.util.function.Function; import java.util.function.IntFunction; import java.util.function.Supplier; @@ -300,26 +303,26 @@ public final class Parcel { private static final int VAL_NULL = -1; private static final int VAL_STRING = 0; private static final int VAL_INTEGER = 1; - private static final int VAL_MAP = 2; + private static final int VAL_MAP = 2; // length-prefixed private static final int VAL_BUNDLE = 3; - private static final int VAL_PARCELABLE = 4; + private static final int VAL_PARCELABLE = 4; // length-prefixed private static final int VAL_SHORT = 5; private static final int VAL_LONG = 6; private static final int VAL_FLOAT = 7; private static final int VAL_DOUBLE = 8; private static final int VAL_BOOLEAN = 9; private static final int VAL_CHARSEQUENCE = 10; - private static final int VAL_LIST = 11; - private static final int VAL_SPARSEARRAY = 12; + private static final int VAL_LIST = 11; // length-prefixed + private static final int VAL_SPARSEARRAY = 12; // length-prefixed private static final int VAL_BYTEARRAY = 13; private static final int VAL_STRINGARRAY = 14; private static final int VAL_IBINDER = 15; - private static final int VAL_PARCELABLEARRAY = 16; - private static final int VAL_OBJECTARRAY = 17; + private static final int VAL_PARCELABLEARRAY = 16; // length-prefixed + private static final int VAL_OBJECTARRAY = 17; // length-prefixed private static final int VAL_INTARRAY = 18; private static final int VAL_LONGARRAY = 19; private static final int VAL_BYTE = 20; - private static final int VAL_SERIALIZABLE = 21; + private static final int VAL_SERIALIZABLE = 21; // length-prefixed private static final int VAL_SPARSEBOOLEANARRAY = 22; private static final int VAL_BOOLEANARRAY = 23; private static final int VAL_CHARSEQUENCEARRAY = 24; @@ -3183,8 +3186,7 @@ public final class Parcel { */ @Deprecated public final void readMap(@NonNull Map outVal, @Nullable ClassLoader loader) { - int n = readInt(); - readMapInternal(outVal, n, loader, /* clazzKey */ null, /* clazzValue */ null); + readMapInternal(outVal, loader, /* clazzKey */ null, /* clazzValue */ null); } /** @@ -3199,8 +3201,7 @@ public final class Parcel { @NonNull Class<V> clazzValue) { Objects.requireNonNull(clazzKey); Objects.requireNonNull(clazzValue); - int n = readInt(); - readMapInternal(outVal, n, loader, clazzKey, clazzValue); + readMapInternal(outVal, loader, clazzKey, clazzValue); } /** @@ -3249,13 +3250,7 @@ public final class Parcel { @Deprecated @Nullable public HashMap readHashMap(@Nullable ClassLoader loader) { - int n = readInt(); - if (n < 0) { - return null; - } - HashMap m = new HashMap(n); - readMapInternal(m, n, loader, /* clazzKey */ null, /* clazzValue */ null); - return m; + return readHashMapInternal(loader, /* clazzKey */ null, /* clazzValue */ null); } /** @@ -3271,13 +3266,7 @@ public final class Parcel { @NonNull Class<? extends K> clazzKey, @NonNull Class<? extends V> clazzValue) { Objects.requireNonNull(clazzKey); Objects.requireNonNull(clazzValue); - int n = readInt(); - if (n < 0) { - return null; - } - HashMap<K, V> map = new HashMap<>(n); - readMapInternal(map, n, loader, clazzKey, clazzValue); - return map; + return readHashMapInternal(loader, clazzKey, clazzValue); } /** @@ -4302,16 +4291,17 @@ public final class Parcel { /** - * @param clazz The type of the object expected or {@code null} for performing no checks. + * @see #readValue(int, ClassLoader, Class, Class[]) */ @Nullable - private <T> T readValue(@Nullable ClassLoader loader, @Nullable Class<T> clazz) { + private <T> T readValue(@Nullable ClassLoader loader, @Nullable Class<T> clazz, + @Nullable Class<?>... itemTypes) { int type = readInt(); final T object; if (isLengthPrefixed(type)) { int length = readInt(); int start = dataPosition(); - object = readValue(type, loader, clazz); + object = readValue(type, loader, clazz, itemTypes); int actual = dataPosition() - start; if (actual != length) { Slog.wtfStack(TAG, @@ -4319,24 +4309,26 @@ public final class Parcel { + " consumed " + actual + " bytes, but " + length + " expected."); } } else { - object = readValue(type, loader, clazz); + object = readValue(type, loader, clazz, itemTypes); } return object; } /** - * This will return a {@link Supplier} for length-prefixed types that deserializes the object - * when {@link Supplier#get()} is called, for other types it will return the object itself. + * This will return a {@link BiFunction} for length-prefixed types that deserializes the object + * when {@link BiFunction#apply} is called (the arguments correspond to the ones of {@link + * #readValue(int, ClassLoader, Class, Class[])} after the class loader), for other types it + * will return the object itself. * - * <p>After calling {@link Supplier#get()} the parcel cursor will not change. Note that you + * <p>After calling {@link BiFunction#apply} the parcel cursor will not change. Note that you * shouldn't recycle the parcel, not at least until all objects have been retrieved. No * synchronization attempts are made. * - * </p>The supplier returned implements {@link #equals(Object)} and {@link #hashCode()}. Two - * suppliers are equal if either of the following is true: + * </p>The function returned implements {@link #equals(Object)} and {@link #hashCode()}. Two + * function objects are equal if either of the following is true: * <ul> - * <li>{@link Supplier#get()} has been called on both and both objects returned are equal. - * <li>{@link Supplier#get()} hasn't been called on either one and everything below is true: + * <li>{@link BiFunction#apply} has been called on both and both objects returned are equal. + * <li>{@link BiFunction#apply} hasn't been called on either one and everything below is true: * <ul> * <li>The {@code loader} parameters used to retrieve each are equal. * <li>They both have the same type. @@ -4363,7 +4355,7 @@ public final class Parcel { } - private static final class LazyValue implements Supplier<Object> { + private static final class LazyValue implements BiFunction<Class<?>, Class<?>[], Object> { /** * | 4B | 4B | * mSource = Parcel{... | type | length | object | ...} @@ -4395,7 +4387,7 @@ public final class Parcel { } @Override - public Object get() { + public Object apply(@Nullable Class<?> clazz, @Nullable Class<?>[] itemTypes) { Parcel source = mSource; if (source != null) { synchronized (source) { @@ -4404,7 +4396,7 @@ public final class Parcel { int restore = source.dataPosition(); try { source.setDataPosition(mPosition); - mObject = source.readValue(mLoader); + mObject = source.readValue(mLoader, clazz, itemTypes); } finally { source.setDataPosition(restore); } @@ -4484,14 +4476,25 @@ public final class Parcel { } } + /** Same as {@link #readValue(ClassLoader, Class, Class[])} without any item types. */ + private <T> T readValue(int type, @Nullable ClassLoader loader, @Nullable Class<T> clazz) { + // Avoids allocating Class[0] array + return readValue(type, loader, clazz, (Class<?>[]) null); + } + /** * Reads a value from the parcel of type {@code type}. Does NOT read the int representing the * type first. + * * @param clazz The type of the object expected or {@code null} for performing no checks. + * @param itemTypes If the value is a container, these represent the item types (eg. for a list + * it's the item type, for a map, it's the key type, followed by the value + * type). */ @SuppressWarnings("unchecked") @Nullable - private <T> T readValue(int type, @Nullable ClassLoader loader, @Nullable Class<T> clazz) { + private <T> T readValue(int type, @Nullable ClassLoader loader, @Nullable Class<T> clazz, + @Nullable Class<?>... itemTypes) { final Object object; switch (type) { case VAL_NULL: @@ -4507,7 +4510,11 @@ public final class Parcel { break; case VAL_MAP: - object = readHashMap(loader); + checkTypeToUnparcel(clazz, HashMap.class); + Class<?> keyType = ArrayUtils.getOrNull(itemTypes, 0); + Class<?> valueType = ArrayUtils.getOrNull(itemTypes, 1); + checkArgument((keyType == null) == (valueType == null)); + object = readHashMapInternal(loader, keyType, valueType); break; case VAL_PARCELABLE: @@ -4538,10 +4545,12 @@ public final class Parcel { object = readCharSequence(); break; - case VAL_LIST: - object = readArrayList(loader); + case VAL_LIST: { + checkTypeToUnparcel(clazz, ArrayList.class); + Class<?> itemType = ArrayUtils.getOrNull(itemTypes, 0); + object = readArrayListInternal(loader, itemType); break; - + } case VAL_BOOLEANARRAY: object = createBooleanArray(); break; @@ -4562,10 +4571,12 @@ public final class Parcel { object = readStrongBinder(); break; - case VAL_OBJECTARRAY: - object = readArray(loader); + case VAL_OBJECTARRAY: { + Class<?> itemType = ArrayUtils.getOrNull(itemTypes, 0); + checkArrayTypeToUnparcel(clazz, (itemType != null) ? itemType : Object.class); + object = readArrayInternal(loader, itemType); break; - + } case VAL_INTARRAY: object = createIntArray(); break; @@ -4582,14 +4593,18 @@ public final class Parcel { object = readSerializableInternal(loader, clazz); break; - case VAL_PARCELABLEARRAY: - object = readParcelableArray(loader); + case VAL_PARCELABLEARRAY: { + Class<?> itemType = ArrayUtils.getOrNull(itemTypes, 0); + checkArrayTypeToUnparcel(clazz, (itemType != null) ? itemType : Parcelable.class); + object = readParcelableArrayInternal(loader, itemType); break; - - case VAL_SPARSEARRAY: - object = readSparseArray(loader); + } + case VAL_SPARSEARRAY: { + checkTypeToUnparcel(clazz, SparseArray.class); + Class<?> itemType = ArrayUtils.getOrNull(itemTypes, 0); + object = readSparseArrayInternal(loader, itemType); break; - + } case VAL_SPARSEBOOLEANARRAY: object = readSparseBooleanArray(); break; @@ -4637,7 +4652,7 @@ public final class Parcel { + " at offset " + off); } if (object != null && clazz != null && !clazz.isInstance(object)) { - throw new BadParcelableException("Unparcelled object " + object + throw new BadTypeParcelableException("Unparcelled object " + object + " is not an instance of required class " + clazz.getName() + " provided in the parameter"); } @@ -4664,6 +4679,38 @@ public final class Parcel { } /** + * Checks that an array of type T[], where T is {@code componentTypeToUnparcel}, is a subtype of + * {@code requiredArrayType}. + */ + private void checkArrayTypeToUnparcel(@Nullable Class<?> requiredArrayType, + Class<?> componentTypeToUnparcel) { + if (requiredArrayType != null) { + // In Java 12, we could use componentTypeToUnparcel.arrayType() for the check + Class<?> requiredComponentType = requiredArrayType.getComponentType(); + if (requiredComponentType == null) { + throw new BadTypeParcelableException( + "About to unparcel an array but type " + + requiredArrayType.getCanonicalName() + + " required by caller is not an array."); + } + checkTypeToUnparcel(requiredComponentType, componentTypeToUnparcel); + } + } + + /** + * Checks that {@code typeToUnparcel} is a subtype of {@code requiredType}, if {@code + * requiredType} is not {@code null}. + */ + private void checkTypeToUnparcel(@Nullable Class<?> requiredType, Class<?> typeToUnparcel) { + if (requiredType != null && !requiredType.isAssignableFrom(typeToUnparcel)) { + throw new BadTypeParcelableException( + "About to unparcel a " + typeToUnparcel.getCanonicalName() + + ", which is not a subtype of type " + requiredType.getCanonicalName() + + " required by caller."); + } + } + + /** * Read and return a new Parcelable from the parcel. The given class loader * will be used to load any enclosed Parcelables. If it is null, the default * class loader will be used. @@ -4793,7 +4840,7 @@ public final class Parcel { if (clazz != null) { Class<?> parcelableClass = creator.getClass().getEnclosingClass(); if (!clazz.isAssignableFrom(parcelableClass)) { - throw new BadParcelableException("Parcelable creator " + name + " is not " + throw new BadTypeParcelableException("Parcelable creator " + name + " is not " + "a subclass of required class " + clazz.getName() + " provided in the parameter"); } @@ -4816,7 +4863,7 @@ public final class Parcel { } if (clazz != null) { if (!clazz.isAssignableFrom(parcelableClass)) { - throw new BadParcelableException("Parcelable creator " + name + " is not " + throw new BadTypeParcelableException("Parcelable creator " + name + " is not " + "a subclass of required class " + clazz.getName() + " provided in the parameter"); } @@ -4877,15 +4924,7 @@ public final class Parcel { @Deprecated @Nullable public Parcelable[] readParcelableArray(@Nullable ClassLoader loader) { - int N = readInt(); - if (N < 0) { - return null; - } - Parcelable[] p = new Parcelable[N]; - for (int i = 0; i < N; i++) { - p[i] = readParcelable(loader); - } - return p; + return readParcelableArrayInternal(loader, /* clazz */ null); } /** @@ -4897,14 +4936,20 @@ public final class Parcel { * trying to instantiate an element. */ @SuppressLint({"ArrayReturn", "NullableCollection"}) - @SuppressWarnings("unchecked") @Nullable public <T> T[] readParcelableArray(@Nullable ClassLoader loader, @NonNull Class<T> clazz) { + return readParcelableArrayInternal(loader, requireNonNull(clazz)); + } + + @SuppressWarnings("unchecked") + @Nullable + private <T> T[] readParcelableArrayInternal(@Nullable ClassLoader loader, + @Nullable Class<T> clazz) { int n = readInt(); if (n < 0) { return null; } - T[] p = (T[]) Array.newInstance(clazz, n); + T[] p = (T[]) ((clazz == null) ? new Parcelable[n] : Array.newInstance(clazz, n)); for (int i = 0; i < n; i++) { p[i] = readParcelableInternal(loader, clazz); } @@ -4967,7 +5012,7 @@ public final class Parcel { // the class the same way as ObjectInputStream, using the provided classloader. Class<?> cl = Class.forName(name, false, loader); if (!clazz.isAssignableFrom(cl)) { - throw new BadParcelableException("Serializable object " + throw new BadTypeParcelableException("Serializable object " + cl.getName() + " is not a subclass of required class " + clazz.getName() + " provided in the parameter"); } @@ -4992,7 +5037,7 @@ public final class Parcel { // the deserialized object, as we cannot resolve the class the same way as // ObjectInputStream. if (!clazz.isAssignableFrom(object.getClass())) { - throw new BadParcelableException("Serializable object " + throw new BadTypeParcelableException("Serializable object " + object.getClass().getName() + " is not a subclass of required class " + clazz.getName() + " provided in the parameter"); } @@ -5102,7 +5147,26 @@ public final class Parcel { readMapInternal(outVal, n, loader, /* clazzKey */null, /* clazzValue */null); } - /* package */ <K, V> void readMapInternal(@NonNull Map<? super K, ? super V> outVal, int n, + @Nullable + private <K, V> HashMap<K, V> readHashMapInternal(@Nullable ClassLoader loader, + @NonNull Class<? extends K> clazzKey, @NonNull Class<? extends V> clazzValue) { + int n = readInt(); + if (n < 0) { + return null; + } + HashMap<K, V> map = new HashMap<>(n); + readMapInternal(map, n, loader, clazzKey, clazzValue); + return map; + } + + private <K, V> void readMapInternal(@NonNull Map<? super K, ? super V> outVal, + @Nullable ClassLoader loader, @Nullable Class<K> clazzKey, + @Nullable Class<V> clazzValue) { + int n = readInt(); + readMapInternal(outVal, n, loader, clazzKey, clazzValue); + } + + private <K, V> void readMapInternal(@NonNull Map<? super K, ? super V> outVal, int n, @Nullable ClassLoader loader, @Nullable Class<K> clazzKey, @Nullable Class<V> clazzValue) { while (n > 0) { @@ -5113,7 +5177,7 @@ public final class Parcel { } } - /* package */ void readArrayMapInternal(@NonNull ArrayMap<? super String, Object> outVal, + private void readArrayMapInternal(@NonNull ArrayMap<? super String, Object> outVal, int size, @Nullable ClassLoader loader) { readArrayMap(outVal, size, /* sorted */ true, /* lazy */ false, loader); } diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java index 944b71700450..a3b836adfc8b 100644 --- a/core/java/android/os/RecoverySystem.java +++ b/core/java/android/os/RecoverySystem.java @@ -674,10 +674,12 @@ public class RecoverySystem { } try { if (!rs.allocateSpaceForUpdate(packageFile)) { + rs.clearBcb(); throw new IOException("Failed to allocate space for update " + packageFile.getAbsolutePath()); } } catch (RemoteException e) { + rs.clearBcb(); e.rethrowAsRuntimeException(); } diff --git a/core/java/android/service/autofill/OWNERS b/core/java/android/service/autofill/OWNERS index a08863276da7..9a30e826a24f 100644 --- a/core/java/android/service/autofill/OWNERS +++ b/core/java/android/service/autofill/OWNERS @@ -1,9 +1,3 @@ # Bug component: 351486 -joannechung@google.com -adamhe@google.com -tymtsai@google.com -lpeter@google.com -augale@google.com -svetoslavganov@android.com -svetoslavganov@google.com +include /core/java/android/view/autofill/OWNERS diff --git a/core/java/android/service/contentcapture/OWNERS b/core/java/android/service/contentcapture/OWNERS index 6337327cec25..24561c59bba6 100644 --- a/core/java/android/service/contentcapture/OWNERS +++ b/core/java/android/service/contentcapture/OWNERS @@ -1,9 +1,3 @@ # Bug component: 544200 -joannechung@google.com -adamhe@google.com -tymtsai@google.com -lpeter@google.com -augale@google.com -svetoslavganov@android.com -svetoslavganov@google.com +include /core/java/android/view/contentcapture/OWNERS diff --git a/core/java/android/service/contentsuggestions/OWNERS b/core/java/android/service/contentsuggestions/OWNERS index 46b5ea03c545..72fe0b1c6392 100644 --- a/core/java/android/service/contentsuggestions/OWNERS +++ b/core/java/android/service/contentsuggestions/OWNERS @@ -1,7 +1,2 @@ -joannechung@google.com -adamhe@google.com -tymtsai@google.com -lpeter@google.com -augale@google.com -svetoslavganov@android.com -svetoslavganov@google.com + +include /core/java/android/app/contentsuggestions/OWNERS diff --git a/core/java/android/service/resumeonreboot/OWNERS b/core/java/android/service/resumeonreboot/OWNERS index 3a127d5a2c12..721fbaf2d4ed 100644 --- a/core/java/android/service/resumeonreboot/OWNERS +++ b/core/java/android/service/resumeonreboot/OWNERS @@ -1,2 +1 @@ -xunchang@google.com -zhaojiac@google.com +ejyzhang@google.com
\ No newline at end of file diff --git a/core/java/android/service/textclassifier/OWNERS b/core/java/android/service/textclassifier/OWNERS index a535f5258732..c85c69ef14df 100644 --- a/core/java/android/service/textclassifier/OWNERS +++ b/core/java/android/service/textclassifier/OWNERS @@ -1,9 +1,3 @@ # Bug component: 709498 -joannechung@google.com -adamhe@google.com -tymtsai@google.com -lpeter@google.com -augale@google.com -svetoslavganov@android.com -svetoslavganov@google.com +include /core/java/android/view/textclassifier/OWNERS diff --git a/core/java/android/service/tracing/TraceReportService.java b/core/java/android/service/tracing/TraceReportService.java index 3d16a3d41ea3..6fdc8e8eb961 100644 --- a/core/java/android/service/tracing/TraceReportService.java +++ b/core/java/android/service/tracing/TraceReportService.java @@ -112,7 +112,6 @@ public class TraceReportService extends Service { } } - // Methods to override. /** * Called when a trace is reported and sent to this class. * @@ -123,15 +122,10 @@ public class TraceReportService extends Service { public void onReportTrace(@NonNull TraceParams args) { } - // Optional methods to override. - // Realistically, these methods are internal implementation details but since this class is - // a SystemApi, it's better to err on the side of flexibility just in-case we need to override - // these methods down the line. - /** * Handles binder calls from system_server. */ - public boolean onMessage(@NonNull Message msg) { + private boolean onMessage(@NonNull Message msg) { if (msg.what == MSG_REPORT_TRACE) { if (!(msg.obj instanceof TraceReportParams)) { Log.e(TAG, "Received invalid type for report trace message."); @@ -153,10 +147,12 @@ public class TraceReportService extends Service { /** * Returns an IBinder for handling binder calls from system_server. + * + * @hide */ @Nullable @Override - public IBinder onBind(@NonNull Intent intent) { + public final IBinder onBind(@NonNull Intent intent) { if (mMessenger == null) { mMessenger = new Messenger(new Handler(Looper.getMainLooper(), this::onMessage)); } diff --git a/core/java/android/service/translation/OWNERS b/core/java/android/service/translation/OWNERS index a1e663aa8ff7..440f9a840057 100644 --- a/core/java/android/service/translation/OWNERS +++ b/core/java/android/service/translation/OWNERS @@ -1,8 +1,3 @@ # Bug component: 994311 -adamhe@google.com -augale@google.com -joannechung@google.com -lpeter@google.com -svetoslavganov@google.com -tymtsai@google.com +include /core/java/android/view/translation/OWNERS diff --git a/core/java/android/service/voice/OWNERS b/core/java/android/service/voice/OWNERS index 46b5ea03c545..59a0c2e36612 100644 --- a/core/java/android/service/voice/OWNERS +++ b/core/java/android/service/voice/OWNERS @@ -1,7 +1,3 @@ -joannechung@google.com -adamhe@google.com -tymtsai@google.com -lpeter@google.com -augale@google.com -svetoslavganov@android.com -svetoslavganov@google.com +# Bug component: 533220 + +include /core/java/android/app/assist/OWNERS diff --git a/core/java/android/telephony/TelephonyRegistryManager.java b/core/java/android/telephony/TelephonyRegistryManager.java index 542de3fad8b0..c1fcd664f6fa 100644 --- a/core/java/android/telephony/TelephonyRegistryManager.java +++ b/core/java/android/telephony/TelephonyRegistryManager.java @@ -239,8 +239,10 @@ public class TelephonyRegistryManager { * @param events Events * @param notifyNow Whether to notify instantly */ - public void listenFromListener(int subId, @NonNull String pkg, @NonNull String featureId, - @NonNull PhoneStateListener listener, @NonNull int events, boolean notifyNow) { + public void listenFromListener(int subId, @NonNull boolean renounceFineLocationAccess, + @NonNull boolean renounceCoarseLocationAccess, @NonNull String pkg, + @NonNull String featureId, @NonNull PhoneStateListener listener, + @NonNull int events, boolean notifyNow) { if (listener == null) { throw new IllegalStateException("telephony service is null."); } @@ -257,8 +259,8 @@ public class TelephonyRegistryManager { } else if (listener.mSubId != null) { subId = listener.mSubId; } - sRegistry.listenWithEventList(false, false, subId, pkg, featureId, - listener.callback, eventsList, notifyNow); + sRegistry.listenWithEventList(renounceFineLocationAccess, renounceCoarseLocationAccess, + subId, pkg, featureId, listener.callback, eventsList, notifyNow); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/android/tracing/OWNERS b/core/java/android/tracing/OWNERS index f5de4eb05c54..7d1b48b69c9e 100644 --- a/core/java/android/tracing/OWNERS +++ b/core/java/android/tracing/OWNERS @@ -1,2 +1,2 @@ -cfijalkovich@google.com carmenjackson@google.com +include platform/external/perfetto:/OWNERS diff --git a/core/java/android/util/OWNERS b/core/java/android/util/OWNERS index 28c078e45347..d4cf6e6e90c2 100644 --- a/core/java/android/util/OWNERS +++ b/core/java/android/util/OWNERS @@ -6,3 +6,7 @@ per-file AttributeSet.java = file:/core/java/android/content/res/OWNERS per-file TypedValue.java = file:/core/java/android/content/res/OWNERS per-file PackageUtils.java = file:/core/java/android/content/pm/OWNERS + +per-file NtpTrustedTime.java = file:/services/core/java/com/android/server/timezonedetector/OWNERS +per-file TimeUtils.java = file:/services/core/java/com/android/server/timezonedetector/OWNERS +per-file TrustedTime.java = file:/services/core/java/com/android/server/timezonedetector/OWNERS diff --git a/core/java/android/view/OWNERS b/core/java/android/view/OWNERS index c74e42850365..b166fa626034 100644 --- a/core/java/android/view/OWNERS +++ b/core/java/android/view/OWNERS @@ -11,6 +11,9 @@ jjaggi@google.com roosa@google.com jreck@google.com +# Autofill +per-file ViewStructure.java = file:/core/java/android/service/autofill/OWNERS + # Display per-file Display*.java = file:/services/core/java/com/android/server/display/OWNERS per-file Display*.aidl = file:/services/core/java/com/android/server/display/OWNERS diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java index 00f4eb83bdaa..5b0bc4ad1aec 100644 --- a/core/java/android/view/WindowManager.java +++ b/core/java/android/view/WindowManager.java @@ -3128,7 +3128,8 @@ public interface WindowManager extends ViewManager { /** * The window is allowed to extend into the {@link DisplayCutout} area, only if the - * {@link DisplayCutout} is fully contained within a system bar. Otherwise, the window is + * {@link DisplayCutout} is fully contained within a system bar or the {@link DisplayCutout} + * is not deeper than 16 dp, but this depends on the OEM choice. Otherwise, the window is * laid out such that it does not overlap with the {@link DisplayCutout} area. * * <p> @@ -3143,6 +3144,13 @@ public interface WindowManager extends ViewManager { * The usual precautions for not overlapping with the status and navigation bar are * sufficient for ensuring that no important content overlaps with the DisplayCutout. * + * <p> + * Note: OEMs can have an option to allow the window to always extend into the + * {@link DisplayCutout} area, no matter the cutout flag set, when the {@link DisplayCutout} + * is on the different side from system bars, only if the {@link DisplayCutout} overlaps at + * most 16dp with the windows. + * In such case, OEMs must provide an opt-in/out affordance for users. + * * @see DisplayCutout * @see WindowInsets * @see #layoutInDisplayCutoutMode @@ -3155,8 +3163,16 @@ public interface WindowManager extends ViewManager { * The window is always allowed to extend into the {@link DisplayCutout} areas on the short * edges of the screen. * + * <p> * The window will never extend into a {@link DisplayCutout} area on the long edges of the - * screen. + * screen, unless the {@link DisplayCutout} is not deeper than 16 dp, but this depends on + * the OEM choice. + * + * <p> + * Note: OEMs can have an option to allow the window to extend into the + * {@link DisplayCutout} area on the long edge side, only if the cutout overlaps at most + * 16dp with the windows. In such case, OEMs must provide an opt-in/out affordance for + * users. * * <p> * The window must make sure that no important content overlaps with the diff --git a/core/java/android/view/autofill/OWNERS b/core/java/android/view/autofill/OWNERS index a08863276da7..108c42cdde2a 100644 --- a/core/java/android/view/autofill/OWNERS +++ b/core/java/android/view/autofill/OWNERS @@ -1,9 +1,7 @@ # Bug component: 351486 +augale@google.com joannechung@google.com -adamhe@google.com -tymtsai@google.com +markpun@google.com lpeter@google.com -augale@google.com -svetoslavganov@android.com -svetoslavganov@google.com +tymtsai@google.com diff --git a/core/java/android/view/contentcapture/OWNERS b/core/java/android/view/contentcapture/OWNERS index 6337327cec25..1a5cb1e4ca4a 100644 --- a/core/java/android/view/contentcapture/OWNERS +++ b/core/java/android/view/contentcapture/OWNERS @@ -1,9 +1,7 @@ # Bug component: 544200 +augale@google.com joannechung@google.com -adamhe@google.com -tymtsai@google.com +markpun@google.com lpeter@google.com -augale@google.com -svetoslavganov@android.com -svetoslavganov@google.com +tymtsai@google.com diff --git a/core/java/android/view/inputmethod/OWNERS b/core/java/android/view/inputmethod/OWNERS index d7db7c741364..9fa7e8f11364 100644 --- a/core/java/android/view/inputmethod/OWNERS +++ b/core/java/android/view/inputmethod/OWNERS @@ -3,4 +3,4 @@ set noparent include /services/core/java/com/android/server/inputmethod/OWNERS -per-file *InlineSuggestion* = file:/core/java/android/service/autofill/OWNERS +per-file *InlineSuggestion* = file:/core/java/android/view/autofill/OWNERS diff --git a/core/java/android/view/textclassifier/OWNERS b/core/java/android/view/textclassifier/OWNERS index 4bcdeea472e3..a205be2f39d0 100644 --- a/core/java/android/view/textclassifier/OWNERS +++ b/core/java/android/view/textclassifier/OWNERS @@ -2,8 +2,6 @@ mns@google.com toki@google.com -svetoslavganov@android.com -svetoslavganov@google.com augale@google.com joannechung@google.com tonymak@google.com diff --git a/core/java/android/view/textclassifier/logging/OWNERS b/core/java/android/view/textclassifier/logging/OWNERS deleted file mode 100644 index ac80d9f4cdd0..000000000000 --- a/core/java/android/view/textclassifier/logging/OWNERS +++ /dev/null @@ -1,8 +0,0 @@ -# Bug component: 709498 - -mns@google.com -toki@google.com -svetoslavganov@android.com -svetoslavganov@google.com -augale@google.com -joannechung@google.com diff --git a/core/java/android/view/translation/OWNERS b/core/java/android/view/translation/OWNERS index a1e663aa8ff7..b772ad3f7cab 100644 --- a/core/java/android/view/translation/OWNERS +++ b/core/java/android/view/translation/OWNERS @@ -1,8 +1,7 @@ # Bug component: 994311 -adamhe@google.com augale@google.com joannechung@google.com +markpun@google.com lpeter@google.com -svetoslavganov@google.com tymtsai@google.com diff --git a/core/java/android/widget/SelectionActionModeHelper.java b/core/java/android/widget/SelectionActionModeHelper.java index 2d1f17a420fa..a0ec48bc6beb 100644 --- a/core/java/android/widget/SelectionActionModeHelper.java +++ b/core/java/android/widget/SelectionActionModeHelper.java @@ -297,12 +297,12 @@ public final class SelectionActionModeHelper { } else { mTextClassification = null; } - final SelectionModifierCursorController controller = mEditor.getSelectionController(); - if (controller != null - && (mTextView.isTextSelectable() || mTextView.isTextEditable())) { - controller.show(); - } if (mEditor.startActionModeInternal(actionMode)) { + final SelectionModifierCursorController controller = mEditor.getSelectionController(); + if (controller != null + && (mTextView.isTextSelectable() || mTextView.isTextEditable())) { + controller.show(); + } if (result != null) { switch (actionMode) { case Editor.TextActionMode.SELECTION: diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index 452dad3b79db..9791da5f41eb 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -12521,7 +12521,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener /** * Called when a context menu option for the text view is selected. Currently * this will be one of {@link android.R.id#selectAll}, {@link android.R.id#cut}, - * {@link android.R.id#copy}, {@link android.R.id#paste} or {@link android.R.id#shareText}. + * {@link android.R.id#copy}, {@link android.R.id#paste}, + * {@link android.R.id#pasteAsPlainText} (starting at API level 23) or + * {@link android.R.id#shareText}. * * @return true if the context menu item action was performed. */ @@ -12712,6 +12714,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * method. The default actions can also be removed from the menu using * {@link android.view.Menu#removeItem(int)} and passing {@link android.R.id#selectAll}, * {@link android.R.id#cut}, {@link android.R.id#copy}, {@link android.R.id#paste}, + * {@link android.R.id#pasteAsPlainText} (starting at API level 23), * {@link android.R.id#replaceText} or {@link android.R.id#shareText} ids as parameters. * * <p>Returning false from @@ -12750,7 +12753,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * {@link android.view.ActionMode.Callback#onPrepareActionMode(android.view.ActionMode, * android.view.Menu)} method. The default actions can also be removed from the menu using * {@link android.view.Menu#removeItem(int)} and passing {@link android.R.id#selectAll}, - * {@link android.R.id#paste} or {@link android.R.id#replaceText} ids as parameters.</p> + * {@link android.R.id#paste}, {@link android.R.id#pasteAsPlainText} (starting at API + * level 23) or {@link android.R.id#replaceText} ids as parameters.</p> * * <p>Returning false from * {@link android.view.ActionMode.Callback#onCreateActionMode(android.view.ActionMode, diff --git a/core/java/android/widget/inline/OWNERS b/core/java/android/widget/inline/OWNERS new file mode 100644 index 000000000000..9a30e826a24f --- /dev/null +++ b/core/java/android/widget/inline/OWNERS @@ -0,0 +1,3 @@ +# Bug component: 351486 + +include /core/java/android/view/autofill/OWNERS diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index 58a0622ba53b..a234743b9cc0 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -12003,59 +12003,57 @@ public class BatteryStatsImpl extends BatteryStats { long totalRxPackets = 0; long totalTxPackets = 0; if (delta != null) { - NetworkStats.Entry entry = new NetworkStats.Entry(); - final int size = delta.size(); - for (int i = 0; i < size; i++) { - entry = delta.getValues(i, entry); - if (entry.rxPackets == 0 && entry.txPackets == 0) { + for (NetworkStats.Entry entry : delta) { + if (entry.getRxPackets() == 0 && entry.getTxPackets() == 0) { continue; } if (DEBUG_ENERGY) { - Slog.d(TAG, "Mobile uid " + entry.uid + ": delta rx=" + entry.rxBytes - + " tx=" + entry.txBytes + " rxPackets=" + entry.rxPackets - + " txPackets=" + entry.txPackets); + Slog.d(TAG, "Mobile uid " + entry.getUid() + ": delta rx=" + + entry.getRxBytes() + " tx=" + entry.getTxBytes() + + " rxPackets=" + entry.getRxPackets() + + " txPackets=" + entry.getTxPackets()); } - totalRxPackets += entry.rxPackets; - totalTxPackets += entry.txPackets; + totalRxPackets += entry.getRxPackets(); + totalTxPackets += entry.getTxPackets(); - final Uid u = getUidStatsLocked(mapUid(entry.uid), elapsedRealtimeMs, uptimeMs); - u.noteNetworkActivityLocked(NETWORK_MOBILE_RX_DATA, entry.rxBytes, - entry.rxPackets); - u.noteNetworkActivityLocked(NETWORK_MOBILE_TX_DATA, entry.txBytes, - entry.txPackets); - if (entry.set == NetworkStats.SET_DEFAULT) { // Background transfers + final Uid u = getUidStatsLocked( + mapUid(entry.getUid()), elapsedRealtimeMs, uptimeMs); + u.noteNetworkActivityLocked(NETWORK_MOBILE_RX_DATA, entry.getRxBytes(), + entry.getRxPackets()); + u.noteNetworkActivityLocked(NETWORK_MOBILE_TX_DATA, entry.getTxBytes(), + entry.getTxPackets()); + if (entry.getSet() == NetworkStats.SET_DEFAULT) { // Background transfers u.noteNetworkActivityLocked(NETWORK_MOBILE_BG_RX_DATA, - entry.rxBytes, entry.rxPackets); + entry.getRxBytes(), entry.getRxPackets()); u.noteNetworkActivityLocked(NETWORK_MOBILE_BG_TX_DATA, - entry.txBytes, entry.txPackets); + entry.getTxBytes(), entry.getTxPackets()); } mNetworkByteActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked( - entry.rxBytes); + entry.getRxBytes()); mNetworkByteActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked( - entry.txBytes); + entry.getTxBytes()); mNetworkPacketActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked( - entry.rxPackets); + entry.getRxPackets()); mNetworkPacketActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked( - entry.txPackets); + entry.getTxPackets()); } // Now distribute proportional blame to the apps that did networking. long totalPackets = totalRxPackets + totalTxPackets; if (totalPackets > 0) { - for (int i = 0; i < size; i++) { - entry = delta.getValues(i, entry); - if (entry.rxPackets == 0 && entry.txPackets == 0) { + for (NetworkStats.Entry entry : delta) { + if (entry.getRxPackets() == 0 && entry.getTxPackets() == 0) { continue; } - final Uid u = getUidStatsLocked(mapUid(entry.uid), + final Uid u = getUidStatsLocked(mapUid(entry.getUid()), elapsedRealtimeMs, uptimeMs); // Distribute total radio active time in to this app. - final long appPackets = entry.rxPackets + entry.txPackets; + final long appPackets = entry.getRxPackets() + entry.getTxPackets(); final long appRadioTimeUs = (totalAppRadioTimeUs * appPackets) / totalPackets; u.noteMobileRadioActiveTimeLocked(appRadioTimeUs); @@ -12076,16 +12074,16 @@ public class BatteryStatsImpl extends BatteryStats { if (deltaInfo != null) { ControllerActivityCounterImpl activityCounter = u.getOrCreateModemControllerActivityLocked(); - if (totalRxPackets > 0 && entry.rxPackets > 0) { - final long rxMs = (entry.rxPackets + if (totalRxPackets > 0 && entry.getRxPackets() > 0) { + final long rxMs = (entry.getRxPackets() * deltaInfo.getReceiveTimeMillis()) / totalRxPackets; activityCounter.getRxTimeCounter().addCountLocked(rxMs); } - if (totalTxPackets > 0 && entry.txPackets > 0) { + if (totalTxPackets > 0 && entry.getTxPackets() > 0) { for (int lvl = 0; lvl < ModemActivityInfo.getNumTxPowerLevels(); lvl++) { - long txMs = entry.txPackets + long txMs = entry.getTxPackets() * deltaInfo.getTransmitDurationMillisAtPowerLevel(lvl); txMs /= totalTxPackets; activityCounter.getTxTimeCounters()[lvl].addCountLocked(txMs); diff --git a/core/java/com/android/internal/os/SystemServerClassLoaderFactory.java b/core/java/com/android/internal/os/SystemServerClassLoaderFactory.java index 615e4b793752..a03bac45d14f 100644 --- a/core/java/com/android/internal/os/SystemServerClassLoaderFactory.java +++ b/core/java/com/android/internal/os/SystemServerClassLoaderFactory.java @@ -29,22 +29,66 @@ public final class SystemServerClassLoaderFactory { private static final ArrayMap<String, PathClassLoader> sLoadedPaths = new ArrayMap<>(); /** - * Creates and caches a ClassLoader for the jar at the given path, or returns a cached - * ClassLoader if it exists. + * Creates and caches a ClassLoader for the jar at the given path. + * + * This method should only be called by ZygoteInit to prefetch jars. For other users, use + * {@link getOrCreateClassLoader} instead. * * The parent class loader should always be the system server class loader. Changing it has * implications that require discussion with the mainline team. * * @hide for internal use only */ - public static PathClassLoader getOrCreateClassLoader(String path, ClassLoader parent) { - PathClassLoader pathClassLoader = sLoadedPaths.get(path); - if (pathClassLoader == null) { - pathClassLoader = (PathClassLoader) ClassLoaderFactory.createClassLoader( - path, /*librarySearchPath=*/null, /*libraryPermittedPath=*/null, parent, - Build.VERSION.SDK_INT, /*isNamespaceShared=*/true , /*classLoaderName=*/null); - sLoadedPaths.put(path, pathClassLoader); + /* package */ static PathClassLoader createClassLoader(String path, ClassLoader parent) { + if (sLoadedPaths.containsKey(path)) { + throw new IllegalStateException("A ClassLoader for " + path + " already exists"); } + PathClassLoader pathClassLoader = (PathClassLoader) ClassLoaderFactory.createClassLoader( + path, /*librarySearchPath=*/null, /*libraryPermittedPath=*/null, parent, + Build.VERSION.SDK_INT, /*isNamespaceShared=*/true , /*classLoaderName=*/null); + sLoadedPaths.put(path, pathClassLoader); return pathClassLoader; } + + /** + * Returns a cached ClassLoader to be used at runtime for the jar at the given path. Or, creates + * one if it is not prefetched and is allowed to be created at runtime. + * + * The parent class loader should always be the system server class loader. Changing it has + * implications that require discussion with the mainline team. + * + * @hide for internal use only + */ + public static PathClassLoader getOrCreateClassLoader( + String path, ClassLoader parent, boolean isTestOnly) { + PathClassLoader pathClassLoader = sLoadedPaths.get(path); + if (pathClassLoader != null) { + return pathClassLoader; + } + if (!allowClassLoaderCreation(path, isTestOnly)) { + throw new RuntimeException("Creating a ClassLoader from " + path + " is not allowed. " + + "Please make sure that the jar is listed in " + + "`PRODUCT_APEX_STANDALONE_SYSTEM_SERVER_JARS` in the Makefile and added as a " + + "`standalone_contents` of a `systemserverclasspath_fragment` in " + + "`Android.bp`."); + } + return createClassLoader(path, parent); + } + + /** + * Returns whether a class loader for the jar is allowed to be created at runtime. + */ + private static boolean allowClassLoaderCreation(String path, boolean isTestOnly) { + // Currently, we only enforce prefetching for APEX jars. + if (!path.startsWith("/apex/")) { + return true; + } + // APEXes for testing only are okay to ignore. + if (isTestOnly) { + return true; + } + return false; + } + + } diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java index f258f84c5e3e..e5e6949851b9 100644 --- a/core/java/com/android/internal/os/ZygoteInit.java +++ b/core/java/com/android/internal/os/ZygoteInit.java @@ -586,7 +586,7 @@ public class ZygoteInit { } for (String jar : envStr.split(":")) { try { - SystemServerClassLoaderFactory.getOrCreateClassLoader( + SystemServerClassLoaderFactory.createClassLoader( jar, getOrCreateSystemServerClassLoader()); } catch (Error e) { // We don't want the process to crash for this error because prefetching is just an diff --git a/core/java/com/android/internal/util/ArrayUtils.java b/core/java/com/android/internal/util/ArrayUtils.java index c6fd6eec2f91..55df09a95838 100644 --- a/core/java/com/android/internal/util/ArrayUtils.java +++ b/core/java/com/android/internal/util/ArrayUtils.java @@ -888,6 +888,15 @@ public class ArrayUtils { } } + /** + * Returns the {@code i}-th item in {@code items}, if it exists and {@code items} is not {@code + * null}, otherwise returns {@code null}. + */ + @Nullable + public static <T> T getOrNull(@Nullable T[] items, int i) { + return (items != null && items.length > i) ? items[i] : null; + } + public static @Nullable <T> T firstOrNull(T[] items) { return items.length > 0 ? items[0] : null; } diff --git a/core/jni/Android.bp b/core/jni/Android.bp index dd2015dd7c6d..57a0b488f692 100644 --- a/core/jni/Android.bp +++ b/core/jni/Android.bp @@ -243,7 +243,6 @@ cc_library_shared { "android.hardware.camera.device@3.2", "libandroid_net", "libandroidicu", - "libbpf_android", "libnetdutils", "libmemtrack", "libandroidfw", diff --git a/core/jni/OWNERS b/core/jni/OWNERS index a17d807f946b..3a9957bcffee 100644 --- a/core/jni/OWNERS +++ b/core/jni/OWNERS @@ -63,6 +63,7 @@ per-file com_android_internal_net_* = file:/services/core/java/com/android/serve ### Graphics ### per-file android_graphics_* = file:/graphics/java/android/graphics/OWNERS per-file android_hardware_HardwareBuffer.cpp = file:/graphics/java/android/graphics/OWNERS +per-file android_hardware_SyncFence.cpp = file:/graphics/java/android/graphics/OWNERS ### Text ### per-file android_text_* = file:/core/java/android/text/OWNERS diff --git a/core/jni/android_os_HwRemoteBinder.cpp b/core/jni/android_os_HwRemoteBinder.cpp index 3af55fe810fc..d2d7213e5761 100644 --- a/core/jni/android_os_HwRemoteBinder.cpp +++ b/core/jni/android_os_HwRemoteBinder.cpp @@ -81,27 +81,37 @@ public: void binderDied(const wp<hardware::IBinder>& who) { - if (mObject != NULL) { - JNIEnv* env = javavm_to_jnienv(mVM); + JNIEnv* env = javavm_to_jnienv(mVM); + + // Serialize with our containing HwBinderDeathRecipientList so that we can't + // delete the global ref on object while the list is being iterated. + sp<HwBinderDeathRecipientList> list = mList.promote(); + if (list == nullptr) return; - env->CallStaticVoidMethod(gProxyOffsets.proxy_class, gProxyOffsets.sendDeathNotice, mObject, mCookie); + jobject object; + { + AutoMutex _l(list->lock()); + + // this function now owns the global ref - to the rest of the code, it looks like + // this binder already died, but we won't actually delete the reference until + // the Java code has processed the death + object = mObject; + + // Demote from strong ref to weak for after binderDied() has been delivered, + // to allow the DeathRecipient and BinderProxy to be GC'd if no longer needed. + mObjectWeak = env->NewWeakGlobalRef(mObject); + mObject = nullptr; + } + + if (object != nullptr) { + env->CallStaticVoidMethod(gProxyOffsets.proxy_class, gProxyOffsets.sendDeathNotice, + object, mCookie); if (env->ExceptionCheck()) { ALOGE("Uncaught exception returned from death notification."); env->ExceptionClear(); } - // Serialize with our containing HwBinderDeathRecipientList so that we can't - // delete the global ref on mObject while the list is being iterated. - sp<HwBinderDeathRecipientList> list = mList.promote(); - if (list != NULL) { - AutoMutex _l(list->lock()); - - // Demote from strong ref to weak after binderDied() has been delivered, - // to allow the DeathRecipient and BinderProxy to be GC'd if no longer needed. - mObjectWeak = env->NewWeakGlobalRef(mObject); - env->DeleteGlobalRef(mObject); - mObject = NULL; - } + env->DeleteGlobalRef(object); } } @@ -115,7 +125,7 @@ public: } } - bool matches(jobject obj) { + bool matchesLocked(jobject obj) { bool result; JNIEnv* env = javavm_to_jnienv(mVM); @@ -129,7 +139,7 @@ public: return result; } - void warnIfStillLive() { + void warnIfStillLiveLocked() { if (mObject != NULL) { // Okay, something is wrong -- we have a hard reference to a live death // recipient on the VM side, but the list is being torn down. @@ -176,7 +186,7 @@ HwBinderDeathRecipientList::~HwBinderDeathRecipientList() { AutoMutex _l(mLock); for (const sp<HwBinderDeathRecipient>& deathRecipient : mList) { - deathRecipient->warnIfStillLive(); + deathRecipient->warnIfStillLiveLocked(); } } @@ -201,7 +211,7 @@ sp<HwBinderDeathRecipient> HwBinderDeathRecipientList::find(jobject recipient) { AutoMutex _l(mLock); for(auto iter = mList.rbegin(); iter != mList.rend(); iter++) { - if ((*iter)->matches(recipient)) { + if ((*iter)->matchesLocked(recipient)) { return (*iter); } } diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp index 5efc4db52623..597167026d19 100644 --- a/core/jni/com_android_internal_os_Zygote.cpp +++ b/core/jni/com_android_internal_os_Zygote.cpp @@ -1626,7 +1626,7 @@ static void SpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray gids, } // Also prefetch standalone system server jars. The reason for doing this here is the same // as above. - env->CallStaticObjectMethod(gZygoteInitClass, gPrefetchStandaloneSystemServerJars); + env->CallStaticVoidMethod(gZygoteInitClass, gPrefetchStandaloneSystemServerJars); if (env->ExceptionCheck()) { env->ExceptionClear(); } diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 590fcf46f373..ad368a819bd4 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -1277,6 +1277,8 @@ <java-symbol type="array" name="vendor_required_apps_managed_user" /> <java-symbol type="array" name="vendor_required_apps_managed_profile" /> <java-symbol type="array" name="vendor_required_apps_managed_device" /> + <java-symbol type="array" name="vendor_required_attestation_certificates" /> + <java-symbol type="string" name="vendor_required_attestation_revocation_list_url" /> <java-symbol type="array" name="vendor_disallowed_apps_managed_user" /> <java-symbol type="array" name="vendor_disallowed_apps_managed_profile" /> <java-symbol type="array" name="vendor_disallowed_apps_managed_device" /> diff --git a/core/res/res/values/vendor_required_attestation_certificates.xml b/core/res/res/values/vendor_required_attestation_certificates.xml new file mode 100644 index 000000000000..ff7313ed1b4d --- /dev/null +++ b/core/res/res/values/vendor_required_attestation_certificates.xml @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (C) 2022 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. + */ +--> +<resources> + <!-- The PEM-encoded certificates added here are used for verifying attestations. + The trustworthiness of the attestation depends on the root certificate of the chain. + + Certificates that can be used can be retrieved from: + https://developer.android.com/training/articles/security-key-attestation#root_certificate. + + If not already present in resource overlay, please add + vendor_required_attestation_certificates.xml (matching this file) in vendor overlay + with <item></item> of the PEM-encoded root certificates. + --> + <string-array translatable="false" name="vendor_required_attestation_certificates"> + </string-array> + + <!-- Url to mapping of revoked certificates' hex encoded serial numbers. Example format + can be found at: + https://developer.android.com/training/articles/security-key-attestation#certificate_status + --> + <string translatable="false" name="vendor_required_attestation_revocation_list_url"></string> +</resources> diff --git a/core/tests/bandwidthtests/Android.bp b/core/tests/bandwidthtests/Android.bp index f1ecd45073eb..d0b42f783bef 100644 --- a/core/tests/bandwidthtests/Android.bp +++ b/core/tests/bandwidthtests/Android.bp @@ -23,6 +23,7 @@ package { android_test { name: "BandwidthTests", + defaults: ["framework-connectivity-test-defaults"], // Include all test java files. srcs: ["src/**/*.java"], libs: [ diff --git a/core/tests/benchmarks/Android.bp b/core/tests/benchmarks/Android.bp index 4cd546753dbf..0888776f1683 100644 --- a/core/tests/benchmarks/Android.bp +++ b/core/tests/benchmarks/Android.bp @@ -27,6 +27,7 @@ package { java_library { name: "frameworks-base-core-benchmarks", + defaults: ["framework-connectivity-test-defaults"], installable: true, srcs: ["src/**/*.java"], libs: ["caliper-api-target"], diff --git a/core/tests/coretests/src/android/app/timedetector/TelephonyTimeSuggestionTest.java b/core/tests/coretests/src/android/app/timedetector/TelephonyTimeSuggestionTest.java index 4b64dfc84fb7..cc7557977e80 100644 --- a/core/tests/coretests/src/android/app/timedetector/TelephonyTimeSuggestionTest.java +++ b/core/tests/coretests/src/android/app/timedetector/TelephonyTimeSuggestionTest.java @@ -45,13 +45,13 @@ public class TelephonyTimeSuggestionTest { assertEquals(two, one); } - builder1.setUtcTime(new TimestampedValue<>(1111L, 2222L)); + builder1.setUnixEpochTime(new TimestampedValue<>(1111L, 2222L)); { TelephonyTimeSuggestion one = builder1.build(); assertEquals(one, one); } - builder2.setUtcTime(new TimestampedValue<>(1111L, 2222L)); + builder2.setUnixEpochTime(new TimestampedValue<>(1111L, 2222L)); { TelephonyTimeSuggestion one = builder1.build(); TelephonyTimeSuggestion two = builder2.build(); @@ -61,7 +61,7 @@ public class TelephonyTimeSuggestionTest { TelephonyTimeSuggestion.Builder builder3 = new TelephonyTimeSuggestion.Builder(SLOT_INDEX + 1); - builder3.setUtcTime(new TimestampedValue<>(1111L, 2222L)); + builder3.setUnixEpochTime(new TimestampedValue<>(1111L, 2222L)); { TelephonyTimeSuggestion one = builder1.build(); TelephonyTimeSuggestion three = builder3.build(); @@ -84,7 +84,7 @@ public class TelephonyTimeSuggestionTest { TelephonyTimeSuggestion.Builder builder = new TelephonyTimeSuggestion.Builder(SLOT_INDEX); assertRoundTripParcelable(builder.build()); - builder.setUtcTime(new TimestampedValue<>(1111L, 2222L)); + builder.setUnixEpochTime(new TimestampedValue<>(1111L, 2222L)); assertRoundTripParcelable(builder.build()); // DebugInfo should also be stored (but is not checked by equals() diff --git a/core/tests/coretests/src/android/content/OWNERS b/core/tests/coretests/src/android/content/OWNERS index 0b945895ad7f..a69c6ffef8d8 100644 --- a/core/tests/coretests/src/android/content/OWNERS +++ b/core/tests/coretests/src/android/content/OWNERS @@ -1,6 +1,7 @@ per-file AssetTest.java = file:/core/java/android/content/res/OWNERS -per-file ContextTest.java = file:/services/core/java/com/android/server/wm/OWNERS +per-file Context* = file:/services/core/java/com/android/server/wm/OWNERS +per-file Context* = charlesccchen@google.com per-file *Launcher* = file:/core/java/android/content/pm/LAUNCHER_OWNERS per-file *Shortcut* = file:/core/java/android/content/pm/SHORTCUT_OWNERS -per-file ComponentCallbacksControllerTest = file:/services/core/java/com/android/server/wm/OWNERS -per-file ComponentCallbacksControllerTest = charlesccchen@google.com +per-file *ComponentCallbacks* = file:/services/core/java/com/android/server/wm/OWNERS +per-file *ComponentCallbacks* = charlesccchen@google.com diff --git a/core/tests/coretests/src/android/net/NetworkPolicyTest.kt b/core/tests/coretests/src/android/net/NetworkPolicyTest.kt index 3c8f90c9c0f8..6360a2deb544 100644 --- a/core/tests/coretests/src/android/net/NetworkPolicyTest.kt +++ b/core/tests/coretests/src/android/net/NetworkPolicyTest.kt @@ -16,7 +16,9 @@ package android.net +import android.net.NetworkStats.METERED_YES import android.net.NetworkTemplate.MATCH_BLUETOOTH +import android.net.NetworkTemplate.MATCH_CARRIER import android.net.NetworkTemplate.MATCH_ETHERNET import android.net.NetworkTemplate.MATCH_MOBILE import android.net.NetworkTemplate.MATCH_WIFI @@ -39,11 +41,19 @@ class NetworkPolicyTest { @Test fun testTemplateBackupRestore() { assertPolicyBackupRestore(createTestPolicyForTemplate( - NetworkTemplate.buildTemplateWifi(TEST_WIFI_NETWORK_KEY1))) + NetworkTemplate.Builder(MATCH_WIFI) + .setWifiNetworkKeys(setOf(TEST_WIFI_NETWORK_KEY1)) + .build())) assertPolicyBackupRestore(createTestPolicyForTemplate( - NetworkTemplate.buildTemplateMobileAll(TEST_IMSI1))) + NetworkTemplate.Builder(MATCH_MOBILE) + .setSubscriberIds(setOf(TEST_IMSI1)) + .setMeteredness(METERED_YES) + .build())) assertPolicyBackupRestore(createTestPolicyForTemplate( - NetworkTemplate.buildTemplateCarrierMetered(TEST_IMSI1))) + NetworkTemplate.Builder(MATCH_CARRIER) + .setSubscriberIds(setOf(TEST_IMSI1)) + .setMeteredness(METERED_YES) + .build())) } private fun createTestPolicyForTemplate(template: NetworkTemplate): NetworkPolicy { diff --git a/core/tests/coretests/src/android/widget/OWNERS b/core/tests/coretests/src/android/widget/OWNERS new file mode 100644 index 000000000000..5a9aed334035 --- /dev/null +++ b/core/tests/coretests/src/android/widget/OWNERS @@ -0,0 +1,5 @@ +include /core/java/android/widget/OWNERS + +per-file *SuggestionsPopup* = file:/core/java/android/text/OWNERS + +per-file *FloatingToolbar*, *SelectionToolbar* = file:/core/java/android/view/textclassifier/OWNERS
\ No newline at end of file diff --git a/core/tests/coretests/src/android/widget/TextViewActivityTest.java b/core/tests/coretests/src/android/widget/TextViewActivityTest.java index 40ef04a5e369..152992cc57a4 100644 --- a/core/tests/coretests/src/android/widget/TextViewActivityTest.java +++ b/core/tests/coretests/src/android/widget/TextViewActivityTest.java @@ -17,6 +17,7 @@ package android.widget; import static android.widget.espresso.CustomViewActions.longPressAtRelativeCoordinates; +import static android.widget.espresso.DragHandleUtils.assertNoSelectionHandles; import static android.widget.espresso.DragHandleUtils.onHandleView; import static android.widget.espresso.FloatingToolbarEspressoUtils.assertFloatingToolbarContainsItem; import static android.widget.espresso.FloatingToolbarEspressoUtils.assertFloatingToolbarDoesNotContainItem; @@ -426,6 +427,41 @@ public class TextViewActivityTest { } @Test + public void testSelectionOnCreateActionModeReturnsFalse() throws Throwable { + final String text = "hello world"; + mActivityRule.runOnUiThread(() -> { + final TextView textView = mActivity.findViewById(R.id.textview); + textView.setText(text); + textView.setCustomSelectionActionModeCallback( + new ActionMode.Callback() { + @Override + public boolean onCreateActionMode(ActionMode mode, Menu menu) { + return false; + } + + @Override + public boolean onPrepareActionMode(ActionMode mode, Menu menu) { + return false; + } + + @Override + public boolean onActionItemClicked(ActionMode mode, MenuItem item) { + return false; + } + + + @Override + public void onDestroyActionMode(ActionMode mode) { + } + }); + }); + mInstrumentation.waitForIdleSync(); + onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(text.indexOf("d"))); + mInstrumentation.waitForIdleSync(); + assertNoSelectionHandles(); + } + + @Test public void testSelectionRemovedWhenNonselectableTextLosesFocus() throws Throwable { final TextLinks.TextLink textLink = addLinkifiedTextToTextView(R.id.nonselectable_textview); final int position = (textLink.getStart() + textLink.getEnd()) / 2; diff --git a/core/tests/coretests/src/com/android/internal/os/MobileRadioPowerCalculatorTest.java b/core/tests/coretests/src/com/android/internal/os/MobileRadioPowerCalculatorTest.java index 1cc1894a916a..a48a8822f4c0 100644 --- a/core/tests/coretests/src/com/android/internal/os/MobileRadioPowerCalculatorTest.java +++ b/core/tests/coretests/src/com/android/internal/os/MobileRadioPowerCalculatorTest.java @@ -16,6 +16,9 @@ package com.android.internal.os; +import static android.net.NetworkStats.DEFAULT_NETWORK_NO; +import static android.net.NetworkStats.METERED_NO; +import static android.net.NetworkStats.ROAMING_NO; import static android.os.BatteryStats.POWER_DATA_UNAVAILABLE; import static com.google.common.truth.Truth.assertThat; @@ -89,7 +92,8 @@ public class MobileRadioPowerCalculatorTest { // Note application network activity NetworkStats networkStats = new NetworkStats(10000, 1) - .insertEntry("cellular", APP_UID, 0, 0, 1000, 100, 2000, 20, 100); + .addEntry(new NetworkStats.Entry("cellular", APP_UID, 0, 0, + METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 1000, 100, 2000, 20, 100)); mStatsRule.setNetworkStats(networkStats); ModemActivityInfo mai = new ModemActivityInfo(10000, 2000, 3000, @@ -150,7 +154,8 @@ public class MobileRadioPowerCalculatorTest { // Note application network activity NetworkStats networkStats = new NetworkStats(10000, 1) - .insertEntry("cellular", APP_UID, 0, 0, 1000, 100, 2000, 20, 100); + .addEntry(new NetworkStats.Entry("cellular", APP_UID, 0, 0, + METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 1000, 100, 2000, 20, 100)); mStatsRule.setNetworkStats(networkStats); ModemActivityInfo mai = new ModemActivityInfo(10000, 2000, 3000, diff --git a/core/tests/coretests/src/com/android/internal/os/WifiPowerCalculatorTest.java b/core/tests/coretests/src/com/android/internal/os/WifiPowerCalculatorTest.java index e7ce9a03f18a..0d944e961d1e 100644 --- a/core/tests/coretests/src/com/android/internal/os/WifiPowerCalculatorTest.java +++ b/core/tests/coretests/src/com/android/internal/os/WifiPowerCalculatorTest.java @@ -16,7 +16,9 @@ package com.android.internal.os; - +import static android.net.NetworkStats.DEFAULT_NETWORK_NO; +import static android.net.NetworkStats.METERED_NO; +import static android.net.NetworkStats.ROAMING_NO; import static android.os.BatteryStats.POWER_DATA_UNAVAILABLE; import static com.google.common.truth.Truth.assertThat; @@ -67,8 +69,10 @@ public class WifiPowerCalculatorTest { new int[]{NetworkCapabilities.TRANSPORT_WIFI}); NetworkStats networkStats = new NetworkStats(10000, 1) - .insertEntry("wifi", APP_UID, 0, 0, 1000, 100, 2000, 20, 100) - .insertEntry("wifi", Process.WIFI_UID, 0, 0, 1111, 111, 2222, 22, 111); + .addEntry(new NetworkStats.Entry("wifi", APP_UID, 0, 0, METERED_NO, + ROAMING_NO, DEFAULT_NETWORK_NO, 1000, 100, 2000, 20, 100)) + .addEntry(new NetworkStats.Entry("wifi", Process.WIFI_UID, 0, 0, METERED_NO, + ROAMING_NO, DEFAULT_NETWORK_NO, 1111, 111, 2222, 22, 111)); mStatsRule.setNetworkStats(networkStats); return batteryStats; diff --git a/core/tests/utillib/Android.bp b/core/tests/utillib/Android.bp index d40d1d2bb6e2..1d5c16c7a536 100644 --- a/core/tests/utillib/Android.bp +++ b/core/tests/utillib/Android.bp @@ -23,6 +23,7 @@ package { java_library { name: "frameworks-core-util-lib", + defaults: ["framework-connectivity-test-defaults"], srcs: ["**/*.java"], diff --git a/data/etc/Android.bp b/data/etc/Android.bp index be1e2b2247fb..dc077583963e 100644 --- a/data/etc/Android.bp +++ b/data/etc/Android.bp @@ -1,4 +1,4 @@ -// Copyright (C} 2018 The Android Open Source Project +// Copyright (C) 2018 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. @@ -12,7 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. - // Sysconfig files package { @@ -134,13 +133,6 @@ prebuilt_etc { } prebuilt_etc { - name: "privapp_whitelist_com.android.networkstack.tethering", - sub_dir: "permissions", - src: "com.android.networkstack.tethering.xml", - filename_from_src: true, -} - -prebuilt_etc { name: "privapp_whitelist_com.android.provision", system_ext_specific: true, sub_dir: "permissions", diff --git a/data/etc/com.android.networkstack.tethering.xml b/data/etc/com.android.networkstack.tethering.xml deleted file mode 100644 index f26a9616e07a..000000000000 --- a/data/etc/com.android.networkstack.tethering.xml +++ /dev/null @@ -1,28 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - ~ Copyright (C) 2021 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 ---> - -<permissions> - <privapp-permissions package="com.android.networkstack.tethering"> - <permission name="android.permission.BLUETOOTH_PRIVILEGED" /> - <permission name="android.permission.MANAGE_USB"/> - <permission name="android.permission.MODIFY_PHONE_STATE"/> - <permission name="android.permission.READ_NETWORK_USAGE_HISTORY"/> - <permission name="android.permission.TETHER_PRIVILEGED"/> - <permission name="android.permission.UPDATE_APP_OPS_STATS"/> - <permission name="android.permission.UPDATE_DEVICE_STATS"/> - </privapp-permissions> -</permissions> diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml index fcd179912800..191d4005e575 100644 --- a/data/etc/privapp-permissions-platform.xml +++ b/data/etc/privapp-permissions-platform.xml @@ -464,6 +464,9 @@ applications that come with the platform <permission name="android.permission.WIFI_UPDATE_COEX_UNSAFE_CHANNELS" /> <permission name="android.permission.NEARBY_WIFI_DEVICES" /> <permission name="android.permission.OVERRIDE_WIFI_CONFIG" /> + <!-- Permission needed for CTS test - ConcurrencyTest#testP2pExternalApprover + P2P external approver API sets require MANAGE_WIFI_AUTO_JOIN permission. --> + <permission name="android.permission.MANAGE_WIFI_AUTO_JOIN" /> <!-- Permission required for CTS test CarrierMessagingServiceWrapperTest --> <permission name="android.permission.BIND_CARRIER_SERVICES"/> <!-- Permission required for CTS test - MusicRecognitionManagerTest --> @@ -521,17 +524,6 @@ applications that come with the platform <permission name="android.permission.INTERACT_ACROSS_USERS"/> </privapp-permissions> - <privapp-permissions package="com.android.traceur"> - <!-- Permissions required to receive BUGREPORT_STARTED intent --> - <permission name="android.permission.DUMP"/> - <!-- Permissions required to start/stop tracing --> - <permission name="android.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND"/> - <!-- Permissions required for quick settings tile --> - <permission name="android.permission.STATUS_BAR"/> - <!-- Permissions required to query Betterbug --> - <permission name="android.permission.QUERY_ALL_PACKAGES"/> - </privapp-permissions> - <privapp-permissions package="com.android.tv"> <permission name="android.permission.CHANGE_HDMI_CEC_ACTIVE_SOURCE"/> <permission name="android.permission.DVB_DEVICE"/> diff --git a/graphics/java/android/graphics/SurfaceTexture.java b/graphics/java/android/graphics/SurfaceTexture.java index 9b2effcde1d3..0fadae23556d 100644 --- a/graphics/java/android/graphics/SurfaceTexture.java +++ b/graphics/java/android/graphics/SurfaceTexture.java @@ -288,7 +288,7 @@ public class SurfaceTexture { * context at a time. * * @param texName The name of the OpenGL ES texture that will be created. This texture name - * must be unusued in the OpenGL ES context that is current on the calling thread. + * must be unused in the OpenGL ES context that is current on the calling thread. */ public void attachToGLContext(int texName) { int err = nativeAttachToGLContext(texName); diff --git a/libs/androidfw/tests/BackupHelpers_test.cpp b/libs/androidfw/tests/BackupHelpers_test.cpp index 86b7fb361228..c2fcb6990f90 100644 --- a/libs/androidfw/tests/BackupHelpers_test.cpp +++ b/libs/androidfw/tests/BackupHelpers_test.cpp @@ -50,7 +50,7 @@ TEST_F(BackupHelpersTest, WriteTarFileWithSizeLessThan2GB) { TEST_F(BackupHelpersTest, WriteTarFileWithSizeGreaterThan2GB) { TemporaryFile tf; // Allocate a 2 GB file. - off64_t fileSize = 2ll * 1024ll * 1024ll * 1024ll + 512ll; + off64_t fileSize = 2LL * 1024LL * 1024LL * 1024LL + 512LL; ASSERT_EQ(0, posix_fallocate64(tf.fd, 0, fileSize)); off64_t tarSize = 0; int err = write_tarfile(/* packageName */ String8("test-pkg"), /* domain */ String8(""), /* rootpath */ String8(""), /* filePath */ String8(tf.path), /* outSize */ &tarSize, /* writer */ NULL); diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h index 2fed4686f16e..00561be3c1c4 100644 --- a/libs/hwui/renderthread/CanvasContext.h +++ b/libs/hwui/renderthread/CanvasContext.h @@ -287,7 +287,7 @@ private: }; // Need at least 4 because we do quad buffer. Add a 5th for good measure. - RingBuffer<SwapHistory, 5> mSwapHistory; + RingBuffer<SwapHistory, 7> mSwapHistory; int64_t mFrameNumber = -1; int64_t mDamageId = 0; diff --git a/media/java/android/media/AudioDeviceInfo.java b/media/java/android/media/AudioDeviceInfo.java index a186566aec0b..3edb10108497 100644 --- a/media/java/android/media/AudioDeviceInfo.java +++ b/media/java/android/media/AudioDeviceInfo.java @@ -177,6 +177,11 @@ public final class AudioDeviceInfo { */ public static final int TYPE_HDMI_EARC = 29; + /** + * A device type describing a Bluetooth Low Energy (BLE) broadcast group. + */ + public static final int TYPE_BLE_BROADCAST = 30; + /** @hide */ @IntDef(flag = false, prefix = "TYPE", value = { TYPE_BUILTIN_EARPIECE, @@ -207,7 +212,8 @@ public final class AudioDeviceInfo { TYPE_REMOTE_SUBMIX, TYPE_BLE_HEADSET, TYPE_BLE_SPEAKER, - TYPE_ECHO_REFERENCE} + TYPE_ECHO_REFERENCE, + TYPE_BLE_BROADCAST} ) @Retention(RetentionPolicy.SOURCE) public @interface AudioDeviceType {} @@ -264,7 +270,8 @@ public final class AudioDeviceInfo { TYPE_HEARING_AID, TYPE_BUILTIN_SPEAKER_SAFE, TYPE_BLE_HEADSET, - TYPE_BLE_SPEAKER} + TYPE_BLE_SPEAKER, + TYPE_BLE_BROADCAST} ) @Retention(RetentionPolicy.SOURCE) public @interface AudioDeviceTypeOut {} @@ -296,6 +303,7 @@ public final class AudioDeviceInfo { case TYPE_BUILTIN_SPEAKER_SAFE: case TYPE_BLE_HEADSET: case TYPE_BLE_SPEAKER: + case TYPE_BLE_BROADCAST: return true; default: return false; @@ -627,6 +635,7 @@ public final class AudioDeviceInfo { INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX, TYPE_REMOTE_SUBMIX); INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_BLE_HEADSET, TYPE_BLE_HEADSET); INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_BLE_SPEAKER, TYPE_BLE_SPEAKER); + INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_BLE_BROADCAST, TYPE_BLE_BROADCAST); INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_BUILTIN_MIC, TYPE_BUILTIN_MIC); INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_BLUETOOTH_SCO_HEADSET, TYPE_BLUETOOTH_SCO); @@ -684,6 +693,7 @@ public final class AudioDeviceInfo { EXT_TO_INT_DEVICE_MAPPING.put(TYPE_REMOTE_SUBMIX, AudioSystem.DEVICE_OUT_REMOTE_SUBMIX); EXT_TO_INT_DEVICE_MAPPING.put(TYPE_BLE_HEADSET, AudioSystem.DEVICE_OUT_BLE_HEADSET); EXT_TO_INT_DEVICE_MAPPING.put(TYPE_BLE_SPEAKER, AudioSystem.DEVICE_OUT_BLE_SPEAKER); + EXT_TO_INT_DEVICE_MAPPING.put(TYPE_BLE_BROADCAST, AudioSystem.DEVICE_OUT_BLE_BROADCAST); // privileges mapping to input device EXT_TO_INT_INPUT_DEVICE_MAPPING = new SparseIntArray(); diff --git a/media/java/android/media/AudioDevicePort.java b/media/java/android/media/AudioDevicePort.java index ebe08822a0c9..9211c53a17bc 100644 --- a/media/java/android/media/AudioDevicePort.java +++ b/media/java/android/media/AudioDevicePort.java @@ -90,7 +90,8 @@ public class AudioDevicePort extends AudioPort { * {@link AudioManager#DEVICE_OUT_BLE_HEADSET}, {@link AudioManager#DEVICE_OUT_BLE_SPEAKER}) * use the MAC address of the bluetooth device in the form "00:11:22:AA:BB:CC" as reported by * {@link BluetoothDevice#getAddress()}. - * - Deivces that do not have an address will indicate an empty string "". + * - Bluetooth LE broadcast group ({@link AudioManager#DEVICE_OUT_BLE_BROADCAST} use the group number. + * - Devices that do not have an address will indicate an empty string "". */ public String address() { return mAddress; diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java index d8893cbd87ee..ce2bccfb1059 100644 --- a/media/java/android/media/AudioManager.java +++ b/media/java/android/media/AudioManager.java @@ -5404,6 +5404,10 @@ public class AudioManager { */ public static final int DEVICE_OUT_BLE_SPEAKER = AudioSystem.DEVICE_OUT_BLE_SPEAKER; /** @hide + * The audio output device code for a BLE audio brodcast group. + */ + public static final int DEVICE_OUT_BLE_BROADCAST = AudioSystem.DEVICE_OUT_BLE_BROADCAST; + /** @hide * This is not used as a returned value from {@link #getDevicesForStream}, but could be * used in the future in a set method to select whatever default device is chosen by the * platform-specific implementation. diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java index 143b11f76f23..33b877c6a958 100644 --- a/media/java/android/media/AudioSystem.java +++ b/media/java/android/media/AudioSystem.java @@ -982,6 +982,8 @@ public class AudioSystem public static final int DEVICE_OUT_BLE_HEADSET = 0x20000000; /** @hide */ public static final int DEVICE_OUT_BLE_SPEAKER = 0x20000001; + /** @hide */ + public static final int DEVICE_OUT_BLE_BROADCAST = 0x20000002; /** @hide */ public static final int DEVICE_OUT_DEFAULT = DEVICE_BIT_DEFAULT; @@ -1042,6 +1044,7 @@ public class AudioSystem DEVICE_OUT_ALL_SET.add(DEVICE_OUT_ECHO_CANCELLER); DEVICE_OUT_ALL_SET.add(DEVICE_OUT_BLE_HEADSET); DEVICE_OUT_ALL_SET.add(DEVICE_OUT_BLE_SPEAKER); + DEVICE_OUT_ALL_SET.add(DEVICE_OUT_BLE_BROADCAST); DEVICE_OUT_ALL_SET.add(DEVICE_OUT_DEFAULT); DEVICE_OUT_ALL_A2DP_SET = new HashSet<>(); @@ -1072,6 +1075,7 @@ public class AudioSystem DEVICE_OUT_ALL_BLE_SET = new HashSet<>(); DEVICE_OUT_ALL_BLE_SET.add(DEVICE_OUT_BLE_HEADSET); DEVICE_OUT_ALL_BLE_SET.add(DEVICE_OUT_BLE_SPEAKER); + DEVICE_OUT_ALL_BLE_SET.add(DEVICE_OUT_BLE_BROADCAST); } // input devices @@ -1255,6 +1259,7 @@ public class AudioSystem /** @hide */ public static final String DEVICE_OUT_ECHO_CANCELLER_NAME = "echo_canceller"; /** @hide */ public static final String DEVICE_OUT_BLE_HEADSET_NAME = "ble_headset"; /** @hide */ public static final String DEVICE_OUT_BLE_SPEAKER_NAME = "ble_speaker"; + /** @hide */ public static final String DEVICE_OUT_BLE_BROADCAST_NAME = "ble_broadcast"; /** @hide */ public static final String DEVICE_IN_COMMUNICATION_NAME = "communication"; /** @hide */ public static final String DEVICE_IN_AMBIENT_NAME = "ambient"; @@ -1354,6 +1359,8 @@ public class AudioSystem return DEVICE_OUT_BLE_HEADSET_NAME; case DEVICE_OUT_BLE_SPEAKER: return DEVICE_OUT_BLE_SPEAKER_NAME; + case DEVICE_OUT_BLE_BROADCAST: + return DEVICE_OUT_BLE_BROADCAST_NAME; case DEVICE_OUT_DEFAULT: default: return Integer.toString(device); diff --git a/media/java/android/media/session/MediaController.java b/media/java/android/media/session/MediaController.java index 1da41fb87b40..33bc84636624 100644 --- a/media/java/android/media/session/MediaController.java +++ b/media/java/android/media/session/MediaController.java @@ -407,7 +407,7 @@ public final class MediaController { /** * Get the session owner's package name. * - * @return The package name of of the session owner. + * @return The package name of the session owner. */ public String getPackageName() { if (mPackageName == null) { diff --git a/native/android/OWNERS b/native/android/OWNERS index 8b35f8d38691..3fb524d1e8c6 100644 --- a/native/android/OWNERS +++ b/native/android/OWNERS @@ -1,14 +1,23 @@ -jreck@google.com +jreck@google.com #{LAST_RESORT_SUGGESTION} +# General NDK API reviewers +per-file libandroid.map.txt = danalbert@google.com, etalvala@google.com, michaelwr@google.com +per-file libandroid.map.txt = jreck@google.com, zyy@google.com + +# Networking per-file libandroid_net.map.txt, net.c = set noparent per-file libandroid_net.map.txt, net.c = jchalard@google.com, junyulai@google.com per-file libandroid_net.map.txt, net.c = lorenzo@google.com, reminv@google.com, satk@google.com + +# Fonts per-file system_fonts.cpp = file:/graphics/java/android/graphics/fonts/OWNERS +# Window manager per-file native_window_jni.cpp = file:/services/core/java/com/android/server/wm/OWNERS per-file native_activity.cpp = file:/services/core/java/com/android/server/wm/OWNERS per-file surface_control.cpp = file:/services/core/java/com/android/server/wm/OWNERS +# Graphics per-file choreographer.cpp = file:/graphics/java/android/graphics/OWNERS per-file hardware_buffer_jni.cpp = file:/graphics/java/android/graphics/OWNERS per-file native_window_jni.cpp = file:/graphics/java/android/graphics/OWNERS diff --git a/omapi/aidl/vts/functional/config/Android.bp b/omapi/aidl/vts/functional/config/Android.bp new file mode 100644 index 000000000000..7c08257bf828 --- /dev/null +++ b/omapi/aidl/vts/functional/config/Android.bp @@ -0,0 +1,26 @@ +// +// Copyright (C) 2022 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 { + default_applicable_licenses: ["Android-Apache-2.0"], +} + +xsd_config { + name: "omapi_uuid_map_config", + srcs: ["omapi_uuid_map_config.xsd"], + api_dir: "schema", + package_name: "omapi.uuid.map.config", +} diff --git a/omapi/aidl/vts/functional/config/omapi_uuid_map_config.xsd b/omapi/aidl/vts/functional/config/omapi_uuid_map_config.xsd new file mode 100644 index 000000000000..ffeb7a032c38 --- /dev/null +++ b/omapi/aidl/vts/functional/config/omapi_uuid_map_config.xsd @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2022 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. +--> +<xs:schema version="2.0" + attributeFormDefault="unqualified" + elementFormDefault="qualified" + xmlns:xs="http://www.w3.org/2001/XMLSchema"> + <xs:element name="ref_do"> + <xs:complexType> + <xs:sequence> + <xs:element name="uuid_ref_do" maxOccurs="unbounded" minOccurs="0"> + <xs:complexType> + <xs:sequence> + <xs:element name="uids"> + <xs:complexType> + <xs:sequence> + <xs:element type="xs:short" name="uid" maxOccurs="unbounded" minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element type="xs:string" name="uuid"/> + </xs:sequence> + </xs:complexType> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> +</xs:schema> diff --git a/omapi/aidl/vts/functional/config/schema/current.txt b/omapi/aidl/vts/functional/config/schema/current.txt new file mode 100644 index 000000000000..c2e930b949d9 --- /dev/null +++ b/omapi/aidl/vts/functional/config/schema/current.txt @@ -0,0 +1,30 @@ +// Signature format: 2.0 +package omapi.uuid.map.config { + + public class RefDo { + ctor public RefDo(); + method public java.util.List<omapi.uuid.map.config.RefDo.UuidRefDo> getUuid_ref_do(); + } + + public static class RefDo.UuidRefDo { + ctor public RefDo.UuidRefDo(); + method public omapi.uuid.map.config.RefDo.UuidRefDo.Uids getUids(); + method public String getUuid(); + method public void setUids(omapi.uuid.map.config.RefDo.UuidRefDo.Uids); + method public void setUuid(String); + } + + public static class RefDo.UuidRefDo.Uids { + ctor public RefDo.UuidRefDo.Uids(); + method public java.util.List<java.lang.Short> getUid(); + } + + public class XmlParser { + ctor public XmlParser(); + method public static omapi.uuid.map.config.RefDo read(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException; + method public static String readText(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException; + method public static void skip(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException; + } + +} + diff --git a/omapi/aidl/vts/functional/config/schema/last_current.txt b/omapi/aidl/vts/functional/config/schema/last_current.txt new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/omapi/aidl/vts/functional/config/schema/last_current.txt diff --git a/omapi/aidl/vts/functional/config/schema/last_removed.txt b/omapi/aidl/vts/functional/config/schema/last_removed.txt new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/omapi/aidl/vts/functional/config/schema/last_removed.txt diff --git a/apex/media/framework/api/removed.txt b/omapi/aidl/vts/functional/config/schema/removed.txt index d802177e249b..d802177e249b 100644 --- a/apex/media/framework/api/removed.txt +++ b/omapi/aidl/vts/functional/config/schema/removed.txt diff --git a/omapi/aidl/vts/functional/omapi/Android.bp b/omapi/aidl/vts/functional/omapi/Android.bp index c3ab8d13920c..c41479f9e9cf 100644 --- a/omapi/aidl/vts/functional/omapi/Android.bp +++ b/omapi/aidl/vts/functional/omapi/Android.bp @@ -39,6 +39,11 @@ cc_test { static_libs: [ "VtsHalHidlTargetTestBase", "android.se.omapi-V1-ndk", + "android.hardware.audio.common.test.utility", + "libxml2", + ], + data: [ + ":omapi_uuid_map_config", ], cflags: [ "-O0", @@ -51,4 +56,5 @@ cc_test { "general-tests", "vts", ], + test_config: "VtsHalOmapiSeServiceV1_TargetTest.xml", } diff --git a/omapi/aidl/vts/functional/omapi/VtsHalOmapiSeServiceV1_TargetTest.cpp b/omapi/aidl/vts/functional/omapi/VtsHalOmapiSeServiceV1_TargetTest.cpp index 319cb7e70884..5303651b4b22 100644 --- a/omapi/aidl/vts/functional/omapi/VtsHalOmapiSeServiceV1_TargetTest.cpp +++ b/omapi/aidl/vts/functional/omapi/VtsHalOmapiSeServiceV1_TargetTest.cpp @@ -32,6 +32,7 @@ #include <hidl/GtestPrinter.h> #include <hidl/ServiceManagement.h> #include <utils/String16.h> +#include "utility/ValidateXml.h" using namespace std; using namespace ::testing; @@ -176,6 +177,25 @@ class OMAPISEServiceHalTest : public TestWithParam<std::string> { return (deviceSupportsFeature(FEATURE_SE_OMAPI_ESE.c_str())); } + std::optional<std::string> getUuidMappingFile() { + char value[PROPERTY_VALUE_MAX] = {0}; + int len = property_get("ro.boot.product.hardware.sku", value, "config"); + std::string uuidMappingConfigFile = UUID_MAPPING_CONFIG_PREFIX + + std::string(value, len) + + UUID_MAPPING_CONFIG_EXT; + std::string uuidMapConfigPath; + // Search in predefined folders + for (auto path : UUID_MAPPING_CONFIG_PATHS) { + uuidMapConfigPath = path + uuidMappingConfigFile; + auto confFile = fopen(uuidMapConfigPath.c_str(), "r"); + if (confFile) { + fclose(confFile); + return uuidMapConfigPath; + } + } + return std::optional<std::string>(); + } + void SetUp() override { LOG(INFO) << "get OMAPI service with name:" << GetParam(); ::ndk::SpAIBinder ks2Binder(AServiceManager_getService(GetParam().c_str())); @@ -300,6 +320,10 @@ class OMAPISEServiceHalTest : public TestWithParam<std::string> { std::map<std::string, std::shared_ptr<aidl::android::se::omapi::ISecureElementReader>> mVSReaders = {}; + + std::string UUID_MAPPING_CONFIG_PREFIX = "hal_uuid_map_"; + std::string UUID_MAPPING_CONFIG_EXT = ".xml"; + std::string UUID_MAPPING_CONFIG_PATHS[3] = {"/odm/etc/", "/vendor/etc/", "/etc/"}; }; /** Tests getReaders API */ @@ -600,6 +624,14 @@ TEST_P(OMAPISEServiceHalTest, TestP2Value) { } } +TEST_P(OMAPISEServiceHalTest, TestUuidMappingConfig) { + constexpr const char* xsd = "/data/local/tmp/omapi_uuid_map_config.xsd"; + auto uuidMappingFile = getUuidMappingFile(); + ASSERT_TRUE(uuidMappingFile.has_value()) << "Unable to determine UUID mapping config file path"; + LOG(INFO) << "UUID Mapping config file: " << uuidMappingFile.value(); + EXPECT_VALID_XML(uuidMappingFile->c_str(), xsd); +} + INSTANTIATE_TEST_SUITE_P(PerInstance, OMAPISEServiceHalTest, testing::ValuesIn(::android::getAidlHalInstanceNames( aidl::android::se::omapi::ISecureElementService::descriptor)), diff --git a/omapi/aidl/vts/functional/omapi/VtsHalOmapiSeServiceV1_TargetTest.xml b/omapi/aidl/vts/functional/omapi/VtsHalOmapiSeServiceV1_TargetTest.xml new file mode 100644 index 000000000000..3ee0414711f3 --- /dev/null +++ b/omapi/aidl/vts/functional/omapi/VtsHalOmapiSeServiceV1_TargetTest.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2022 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. +--> +<configuration description="Runs VtsHalOmapiSeServiceV1_TargetTest."> + <option name="test-suite-tag" value="apct" /> + <option name="test-suite-tag" value="apct-native" /> + + <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"> + </target_preparer> + + <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer"> + <option name="cleanup" value="true" /> + <option name="push" + value="omapi_uuid_map_config.xsd->/data/local/tmp/omapi_uuid_map_config.xsd" /> + <option name="push" + value="VtsHalOmapiSeServiceV1_TargetTest->/data/local/tmp/VtsHalOmapiSeServiceV1_TargetTest" /> + </target_preparer> + + <test class="com.android.tradefed.testtype.GTest" > + <option name="native-test-device-path" value="/data/local/tmp" /> + <option name="module-name" value="VtsHalOmapiSeServiceV1_TargetTest" /> + </test> +</configuration> diff --git a/packages/ConnectivityT/framework-t/Android.bp b/packages/ConnectivityT/framework-t/Android.bp index 54538d91a5cf..6329565ca567 100644 --- a/packages/ConnectivityT/framework-t/Android.bp +++ b/packages/ConnectivityT/framework-t/Android.bp @@ -158,7 +158,6 @@ filegroup { name: "framework-connectivity-tiramisu-sources", srcs: [ ":framework-connectivity-ethernet-sources", - ":framework-connectivity-ipsec-sources", ":framework-connectivity-netstats-sources", ], visibility: ["//frameworks/base"], @@ -167,6 +166,7 @@ filegroup { filegroup { name: "framework-connectivity-tiramisu-updatable-sources", srcs: [ + ":framework-connectivity-ipsec-sources", ":framework-connectivity-nsd-sources", ":framework-connectivity-tiramisu-internal-sources", ], diff --git a/packages/ConnectivityT/framework-t/src/android/net/ConnectivityFrameworkInitializerTiramisu.java b/packages/ConnectivityT/framework-t/src/android/net/ConnectivityFrameworkInitializerTiramisu.java index 630f902ecfd7..577ac5466692 100644 --- a/packages/ConnectivityT/framework-t/src/android/net/ConnectivityFrameworkInitializerTiramisu.java +++ b/packages/ConnectivityT/framework-t/src/android/net/ConnectivityFrameworkInitializerTiramisu.java @@ -48,5 +48,14 @@ public final class ConnectivityFrameworkInitializerTiramisu { return new NsdManager(context, service); } ); + + SystemServiceRegistry.registerContextAwareService( + Context.IPSEC_SERVICE, + IpSecManager.class, + (context, serviceBinder) -> { + IIpSecService service = IIpSecService.Stub.asInterface(serviceBinder); + return new IpSecManager(context, service); + } + ); } } diff --git a/packages/ConnectivityT/framework-t/src/android/net/EthernetManager.java b/packages/ConnectivityT/framework-t/src/android/net/EthernetManager.java index 1f67f6d654e1..72243f9e87d9 100644 --- a/packages/ConnectivityT/framework-t/src/android/net/EthernetManager.java +++ b/packages/ConnectivityT/framework-t/src/android/net/EthernetManager.java @@ -16,14 +16,16 @@ package android.net; +import static android.annotation.SystemApi.Client.MODULE_LIBRARIES; + import android.annotation.CallbackExecutor; +import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresFeature; import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.SystemService; -import android.annotation.TestApi; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.PackageManager; @@ -33,13 +35,15 @@ import android.os.RemoteException; import com.android.internal.annotations.GuardedBy; import com.android.internal.os.BackgroundThread; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Objects; import java.util.concurrent.Executor; import java.util.function.BiConsumer; /** - * A class representing the IP configuration of the Ethernet network. + * A class that manages and configures Ethernet interfaces. * * @hide */ @@ -54,11 +58,13 @@ public class EthernetManager { private final IEthernetServiceListener.Stub mServiceListener = new IEthernetServiceListener.Stub() { @Override - public void onAvailabilityChanged(String iface, boolean isAvailable) { + public void onInterfaceStateChanged(String iface, int state, int role, + IpConfiguration configuration) { synchronized (mListeners) { for (ListenerInfo li : mListeners) { li.executor.execute(() -> - li.listener.onAvailabilityChanged(iface, isAvailable)); + li.listener.onInterfaceStateChanged(iface, state, role, + configuration)); } } } @@ -68,19 +74,93 @@ public class EthernetManager { @NonNull public final Executor executor; @NonNull - public final Listener listener; + public final InterfaceStateListener listener; - private ListenerInfo(@NonNull Executor executor, @NonNull Listener listener) { + private ListenerInfo(@NonNull Executor executor, @NonNull InterfaceStateListener listener) { this.executor = executor; this.listener = listener; } } /** + * The interface is absent. + * @hide + */ + @SystemApi(client = MODULE_LIBRARIES) + public static final int STATE_ABSENT = 0; + + /** + * The interface is present but link is down. + * @hide + */ + @SystemApi(client = MODULE_LIBRARIES) + public static final int STATE_LINK_DOWN = 1; + + /** + * The interface is present and link is up. + * @hide + */ + @SystemApi(client = MODULE_LIBRARIES) + public static final int STATE_LINK_UP = 2; + + /** @hide */ + @IntDef(prefix = "STATE_", value = {STATE_ABSENT, STATE_LINK_DOWN, STATE_LINK_UP}) + @Retention(RetentionPolicy.SOURCE) + public @interface InterfaceState {} + + /** + * The interface currently does not have any specific role. + * @hide + */ + @SystemApi(client = MODULE_LIBRARIES) + public static final int ROLE_NONE = 0; + + /** + * The interface is in client mode (e.g., connected to the Internet). + * @hide + */ + @SystemApi(client = MODULE_LIBRARIES) + public static final int ROLE_CLIENT = 1; + + /** + * Ethernet interface is in server mode (e.g., providing Internet access to tethered devices). + * @hide + */ + @SystemApi(client = MODULE_LIBRARIES) + public static final int ROLE_SERVER = 2; + + /** @hide */ + @IntDef(prefix = "ROLE_", value = {ROLE_NONE, ROLE_CLIENT, ROLE_SERVER}) + @Retention(RetentionPolicy.SOURCE) + public @interface Role {} + + /** + * A listener that receives notifications about the state of Ethernet interfaces on the system. + * @hide + */ + @SystemApi(client = MODULE_LIBRARIES) + public interface InterfaceStateListener { + /** + * Called when an Ethernet interface changes state. + * + * @param iface the name of the interface. + * @param state the current state of the interface, or {@link #STATE_ABSENT} if the + * interface was removed. + * @param role whether the interface is in client mode or server mode. + * @param configuration the current IP configuration of the interface. + * @hide + */ + @SystemApi(client = MODULE_LIBRARIES) + void onInterfaceStateChanged(@NonNull String iface, @InterfaceState int state, + @Role int role, @Nullable IpConfiguration configuration); + } + + /** * A listener interface to receive notification on changes in Ethernet. + * This has never been a supported API. Use {@link InterfaceStateListener} instead. * @hide */ - public interface Listener { + public interface Listener extends InterfaceStateListener { /** * Called when Ethernet port's availability is changed. * @param iface Ethernet interface name @@ -89,6 +169,13 @@ public class EthernetManager { */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) void onAvailabilityChanged(String iface, boolean isAvailable); + + /** Default implementation for backwards compatibility. Only calls the legacy listener. */ + default void onInterfaceStateChanged(@NonNull String iface, @InterfaceState int state, + @Role int role, @Nullable IpConfiguration configuration) { + onAvailabilityChanged(iface, (state >= STATE_LINK_UP)); + } + } /** @@ -121,7 +208,7 @@ public class EthernetManager { * @hide */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - public void setConfiguration(String iface, IpConfiguration config) { + public void setConfiguration(@NonNull String iface, @NonNull IpConfiguration config) { try { mService.setConfiguration(iface, config); } catch (RemoteException e) { @@ -155,9 +242,8 @@ public class EthernetManager { /** * Adds a listener. + * This has never been a supported API. Use {@link #addInterfaceStateListener} instead. * - * Consider using {@link #addListener(Listener, Executor)} instead: this method uses a default - * executor that may have higher latency than a provided executor. * @param listener A {@link Listener} to add. * @throws IllegalArgumentException If the listener is null. * @hide @@ -169,6 +255,8 @@ public class EthernetManager { /** * Adds a listener. + * This has never been a supported API. Use {@link #addInterfaceStateListener} instead. + * * @param listener A {@link Listener} to add. * @param executor Executor to run callbacks on. * @throws IllegalArgumentException If the listener or executor is null. @@ -176,6 +264,28 @@ public class EthernetManager { */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void addListener(@NonNull Listener listener, @NonNull Executor executor) { + addInterfaceStateListener(executor, listener); + } + + /** + * Listen to changes in the state of Ethernet interfaces. + * + * Adds a listener to receive notification for any state change of all existing Ethernet + * interfaces. + * <p>{@link Listener#onInterfaceStateChanged} will be triggered immediately for all + * existing interfaces upon adding a listener. The same method will be called on the + * listener every time any of the interface changes state. In particular, if an + * interface is removed, it will be called with state {@link #STATE_ABSENT}. + * <p>Use {@link #removeInterfaceStateListener} with the same object to stop listening. + * + * @param executor Executor to run callbacks on. + * @param listener A {@link Listener} to add. + * @hide + */ + @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) + @SystemApi(client = MODULE_LIBRARIES) + public void addInterfaceStateListener(@NonNull Executor executor, + @NonNull InterfaceStateListener listener) { if (listener == null || executor == null) { throw new NullPointerException("listener and executor must not be null"); } @@ -206,15 +316,13 @@ public class EthernetManager { /** * Removes a listener. + * * @param listener A {@link Listener} to remove. - * @throws IllegalArgumentException If the listener is null. * @hide */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - public void removeListener(@NonNull Listener listener) { - if (listener == null) { - throw new IllegalArgumentException("listener must not be null"); - } + @SystemApi(client = MODULE_LIBRARIES) + public void removeInterfaceStateListener(@NonNull InterfaceStateListener listener) { + Objects.requireNonNull(listener); synchronized (mListeners) { mListeners.removeIf(l -> l.listener == listener); if (mListeners.isEmpty()) { @@ -228,12 +336,26 @@ public class EthernetManager { } /** + * Removes a listener. + * This has never been a supported API. Use {@link #removeInterfaceStateListener} instead. + * @param listener A {@link Listener} to remove. + * @hide + */ + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + public void removeListener(@NonNull Listener listener) { + if (listener == null) { + throw new IllegalArgumentException("listener must not be null"); + } + removeInterfaceStateListener(listener); + } + + /** * Whether to treat interfaces created by {@link TestNetworkManager#createTapInterface} * as Ethernet interfaces. The effects of this method apply to any test interfaces that are * already present on the system. * @hide */ - @TestApi + @SystemApi(client = MODULE_LIBRARIES) public void setIncludeTestInterfaces(boolean include) { try { mService.setIncludeTestInterfaces(include); diff --git a/packages/ConnectivityT/framework-t/src/android/net/EthernetNetworkSpecifier.java b/packages/ConnectivityT/framework-t/src/android/net/EthernetNetworkSpecifier.java index 925d12b574a6..e4d6e248d48a 100644 --- a/packages/ConnectivityT/framework-t/src/android/net/EthernetNetworkSpecifier.java +++ b/packages/ConnectivityT/framework-t/src/android/net/EthernetNetworkSpecifier.java @@ -18,7 +18,6 @@ package android.net; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; @@ -29,9 +28,7 @@ import java.util.Objects; * A {@link NetworkSpecifier} used to identify ethernet interfaces. * * @see EthernetManager - * @hide */ -@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public final class EthernetNetworkSpecifier extends NetworkSpecifier implements Parcelable { /** @@ -61,6 +58,7 @@ public final class EthernetNetworkSpecifier extends NetworkSpecifier implements return mInterfaceName; } + /** @hide */ @Override public boolean canBeSatisfiedBy(@Nullable NetworkSpecifier other) { return equals(other); diff --git a/packages/ConnectivityT/framework-t/src/android/net/IEthernetServiceListener.aidl b/packages/ConnectivityT/framework-t/src/android/net/IEthernetServiceListener.aidl index 782fa19d9df7..6d2ba03f78d4 100644 --- a/packages/ConnectivityT/framework-t/src/android/net/IEthernetServiceListener.aidl +++ b/packages/ConnectivityT/framework-t/src/android/net/IEthernetServiceListener.aidl @@ -16,8 +16,11 @@ package android.net; +import android.net.IpConfiguration; + /** @hide */ oneway interface IEthernetServiceListener { - void onAvailabilityChanged(String iface, boolean isAvailable); + void onInterfaceStateChanged(String iface, int state, int role, + in IpConfiguration configuration); } diff --git a/packages/ConnectivityT/framework-t/src/android/net/IpSecManager.java b/packages/ConnectivityT/framework-t/src/android/net/IpSecManager.java index a423783bc1ca..9cb0947b2370 100644 --- a/packages/ConnectivityT/framework-t/src/android/net/IpSecManager.java +++ b/packages/ConnectivityT/framework-t/src/android/net/IpSecManager.java @@ -61,7 +61,7 @@ import java.util.Objects; * Internet Protocol</a> */ @SystemService(Context.IPSEC_SERVICE) -public final class IpSecManager { +public class IpSecManager { private static final String TAG = "IpSecManager"; /** diff --git a/packages/ConnectivityT/framework-t/src/android/net/NetworkStateSnapshot.aidl b/packages/ConnectivityT/framework-t/src/android/net/NetworkStateSnapshot.aidl deleted file mode 100644 index cb602d7927ce..000000000000 --- a/packages/ConnectivityT/framework-t/src/android/net/NetworkStateSnapshot.aidl +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Copyright (c) 2021, 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.net; - -parcelable NetworkStateSnapshot; diff --git a/packages/ConnectivityT/framework-t/src/android/net/NetworkStats.java b/packages/ConnectivityT/framework-t/src/android/net/NetworkStats.java index 9175809d9c7c..f681ba1c3853 100644 --- a/packages/ConnectivityT/framework-t/src/android/net/NetworkStats.java +++ b/packages/ConnectivityT/framework-t/src/android/net/NetworkStats.java @@ -28,6 +28,7 @@ import android.os.Parcel; import android.os.Parcelable; import android.os.Process; import android.os.SystemClock; +import android.text.TextUtils; import android.util.SparseBooleanArray; import com.android.internal.annotations.VisibleForTesting; @@ -500,7 +501,7 @@ public final class NetworkStats implements Parcelable, Iterable<NetworkStats.Ent && roaming == e.roaming && defaultNetwork == e.defaultNetwork && rxBytes == e.rxBytes && rxPackets == e.rxPackets && txBytes == e.txBytes && txPackets == e.txPackets - && operations == e.operations && iface.equals(e.iface); + && operations == e.operations && TextUtils.equals(iface, e.iface); } return false; } diff --git a/packages/ConnectivityT/service/Android.bp b/packages/ConnectivityT/service/Android.bp index d05370f9ba60..c3049dabefc2 100644 --- a/packages/ConnectivityT/service/Android.bp +++ b/packages/ConnectivityT/service/Android.bp @@ -88,7 +88,6 @@ filegroup { name: "services.connectivity-tiramisu-sources", srcs: [ ":services.connectivity-ethernet-sources", - ":services.connectivity-ipsec-sources", ":services.connectivity-netstats-sources", ], path: "src", @@ -98,6 +97,7 @@ filegroup { filegroup { name: "services.connectivity-tiramisu-updatable-sources", srcs: [ + ":services.connectivity-ipsec-sources", ":services.connectivity-nsd-sources", ], path: "src", diff --git a/packages/ConnectivityT/service/src/com/android/server/IpSecService.java b/packages/ConnectivityT/service/src/com/android/server/IpSecService.java index 179d9459fd84..4bc40eae4404 100644 --- a/packages/ConnectivityT/service/src/com/android/server/IpSecService.java +++ b/packages/ConnectivityT/service/src/com/android/server/IpSecService.java @@ -1008,16 +1008,10 @@ public class IpSecService extends IIpSecService.Stub { * * @param context Binder context for this service */ - private IpSecService(Context context) { + public IpSecService(Context context) { this(context, new Dependencies()); } - static IpSecService create(Context context) - throws InterruptedException { - final IpSecService service = new IpSecService(context); - return service; - } - @NonNull private AppOpsManager getAppOpsManager() { AppOpsManager appOps = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE); @@ -1054,26 +1048,6 @@ public class IpSecService extends IIpSecService.Stub { } } - /** Called by system server when system is ready. */ - public void systemReady() { - if (isNetdAlive()) { - Log.d(TAG, "IpSecService is ready"); - } else { - Log.wtf(TAG, "IpSecService not ready: failed to connect to NetD Native Service!"); - } - } - - synchronized boolean isNetdAlive() { - try { - if (mNetd == null) { - return false; - } - return mNetd.isAlive(); - } catch (RemoteException re) { - return false; - } - } - /** * Checks that the provided InetAddress is valid for use in an IPsec SA. The address must not be * a wildcard address and must be in a numeric form such as 1.2.3.4 or 2001::1. @@ -1896,7 +1870,6 @@ public class IpSecService extends IIpSecService.Stub { mContext.enforceCallingOrSelfPermission(DUMP, TAG); pw.println("IpSecService dump:"); - pw.println("NetdNativeService Connection: " + (isNetdAlive() ? "alive" : "dead")); pw.println(); pw.println("mUserResourceTracker:"); diff --git a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsService.java b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsService.java index 9f3371b724cf..b1936231148c 100644 --- a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsService.java +++ b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsService.java @@ -51,6 +51,7 @@ import static android.net.netstats.NetworkStatsDataMigrationUtils.PREFIX_UID; import static android.net.netstats.NetworkStatsDataMigrationUtils.PREFIX_UID_TAG; import static android.net.netstats.NetworkStatsDataMigrationUtils.PREFIX_XT; import static android.os.Trace.TRACE_TAG_NETWORK; +import static android.system.OsConstants.ENOENT; import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID; import static android.text.format.DateUtils.DAY_IN_MILLIS; import static android.text.format.DateUtils.HOUR_IN_MILLIS; @@ -120,7 +121,6 @@ import android.provider.Settings.Global; import android.service.NetworkInterfaceProto; import android.service.NetworkStatsServiceDumpProto; import android.system.ErrnoException; -import android.system.Os; import android.telephony.PhoneStateListener; import android.telephony.SubscriptionPlan; import android.text.TextUtils; @@ -214,6 +214,14 @@ public class NetworkStatsService extends INetworkStatsService.Stub { // This is current path but may be changed soon. private static final String UID_COUNTERSET_MAP_PATH = "/sys/fs/bpf/map_netd_uid_counterset_map"; + private static final String COOKIE_TAG_MAP_PATH = + "/sys/fs/bpf/map_netd_cookie_tag_map"; + private static final String APP_UID_STATS_MAP_PATH = + "/sys/fs/bpf/map_netd_app_uid_stats_map"; + private static final String STATS_MAP_A_PATH = + "/sys/fs/bpf/map_netd_stats_map_A"; + private static final String STATS_MAP_B_PATH = + "/sys/fs/bpf/map_netd_stats_map_B"; private final Context mContext; private final NetworkStatsFactory mStatsFactory; @@ -341,6 +349,10 @@ public class NetworkStatsService extends INetworkStatsService.Stub { */ private SparseIntArray mActiveUidCounterSet = new SparseIntArray(); private final IBpfMap<U32, U8> mUidCounterSetMap; + private final IBpfMap<CookieTagMapKey, CookieTagMapValue> mCookieTagMap; + private final IBpfMap<StatsMapKey, StatsMapValue> mStatsMapA; + private final IBpfMap<StatsMapKey, StatsMapValue> mStatsMapB; + private final IBpfMap<UidStatsMapKey, StatsMapValue> mAppUidStatsMap; /** Data layer operation counters for splicing into other structures. */ private NetworkStats mUidOperations = new NetworkStats(0L, 10); @@ -474,6 +486,10 @@ public class NetworkStatsService extends INetworkStatsService.Stub { mInterfaceMapUpdater = mDeps.makeBpfInterfaceMapUpdater(mContext, mHandler); mInterfaceMapUpdater.start(); mUidCounterSetMap = mDeps.getUidCounterSetMap(); + mCookieTagMap = mDeps.getCookieTagMap(); + mStatsMapA = mDeps.getStatsMapA(); + mStatsMapB = mDeps.getStatsMapB(); + mAppUidStatsMap = mDeps.getAppUidStatsMap(); } /** @@ -547,8 +563,48 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } } - public TagStatsDeleter getTagStatsDeleter() { - return NetworkStatsService::nativeDeleteTagData; + /** Gets the cookie tag map */ + public IBpfMap<CookieTagMapKey, CookieTagMapValue> getCookieTagMap() { + try { + return new BpfMap<CookieTagMapKey, CookieTagMapValue>(COOKIE_TAG_MAP_PATH, + BpfMap.BPF_F_RDWR, CookieTagMapKey.class, CookieTagMapValue.class); + } catch (ErrnoException e) { + Log.wtf(TAG, "Cannot create cookie tag map: " + e); + return null; + } + } + + /** Gets stats map A */ + public IBpfMap<StatsMapKey, StatsMapValue> getStatsMapA() { + try { + return new BpfMap<StatsMapKey, StatsMapValue>(STATS_MAP_A_PATH, + BpfMap.BPF_F_RDWR, StatsMapKey.class, StatsMapValue.class); + } catch (ErrnoException e) { + Log.wtf(TAG, "Cannot create stats map A: " + e); + return null; + } + } + + /** Gets stats map B */ + public IBpfMap<StatsMapKey, StatsMapValue> getStatsMapB() { + try { + return new BpfMap<StatsMapKey, StatsMapValue>(STATS_MAP_B_PATH, + BpfMap.BPF_F_RDWR, StatsMapKey.class, StatsMapValue.class); + } catch (ErrnoException e) { + Log.wtf(TAG, "Cannot create stats map B: " + e); + return null; + } + } + + /** Gets the uid stats map */ + public IBpfMap<UidStatsMapKey, StatsMapValue> getAppUidStatsMap() { + try { + return new BpfMap<UidStatsMapKey, StatsMapValue>(APP_UID_STATS_MAP_PATH, + BpfMap.BPF_F_RDWR, UidStatsMapKey.class, StatsMapValue.class); + } catch (ErrnoException e) { + Log.wtf(TAG, "Cannot create app uid stats map: " + e); + return null; + } } } @@ -1790,6 +1846,69 @@ public class NetworkStatsService extends INetworkStatsService.Stub { currentTime); } + // deleteKernelTagData can ignore ENOENT; otherwise we should log an error + private void logErrorIfNotErrNoent(final ErrnoException e, final String msg) { + if (e.errno != ENOENT) Log.e(TAG, msg, e); + } + + private <K extends StatsMapKey, V extends StatsMapValue> void deleteStatsMapTagData( + IBpfMap<K, V> statsMap, int uid) { + try { + statsMap.forEach((key, value) -> { + if (key.uid == uid) { + try { + statsMap.deleteEntry(key); + } catch (ErrnoException e) { + logErrorIfNotErrNoent(e, "Failed to delete data(uid = " + key.uid + ")"); + } + } + }); + } catch (ErrnoException e) { + Log.e(TAG, "FAILED to delete tag data from stats map", e); + } + } + + /** + * Deletes uid tag data from CookieTagMap, StatsMapA, StatsMapB, and UidStatsMap + * @param uid + */ + private void deleteKernelTagData(int uid) { + try { + mCookieTagMap.forEach((key, value) -> { + // If SkDestroyListener deletes the socket tag while this code is running, + // forEach will either restart iteration from the beginning or return null, + // depending on when the deletion happens. + // If it returns null, continue iteration to delete the data and in fact it would + // just iterate from first key because BpfMap#getNextKey would return first key + // if the current key is not exist. + if (value != null && value.uid == uid) { + try { + mCookieTagMap.deleteEntry(key); + } catch (ErrnoException e) { + logErrorIfNotErrNoent(e, "Failed to delete data(cookie = " + key + ")"); + } + } + }); + } catch (ErrnoException e) { + Log.e(TAG, "Failed to delete tag data from cookie tag map", e); + } + + deleteStatsMapTagData(mStatsMapA, uid); + deleteStatsMapTagData(mStatsMapB, uid); + + try { + mUidCounterSetMap.deleteEntry(new U32(uid)); + } catch (ErrnoException e) { + logErrorIfNotErrNoent(e, "Failed to delete tag data from uid counter set map"); + } + + try { + mAppUidStatsMap.deleteEntry(new UidStatsMapKey(uid)); + } catch (ErrnoException e) { + logErrorIfNotErrNoent(e, "Failed to delete tag data from app uid stats map"); + } + } + /** * Clean up {@link #mUidRecorder} after UID is removed. */ @@ -1805,10 +1924,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { // Clear kernel stats associated with UID for (int uid : uids) { - final int ret = mDeps.getTagStatsDeleter().deleteTagData(uid); - if (ret < 0) { - Log.w(TAG, "problem clearing counters for uid " + uid + ": " + Os.strerror(-ret)); - } + deleteKernelTagData(uid); } } @@ -2387,12 +2503,4 @@ public class NetworkStatsService extends INetworkStatsService.Stub { private static native long nativeGetTotalStat(int type); private static native long nativeGetIfaceStat(String iface, int type); private static native long nativeGetUidStat(int uid, int type); - - // TODO: use BpfNetMaps to delete tag data and remove this. - @VisibleForTesting - interface TagStatsDeleter { - int deleteTagData(int uid); - } - - private static native int nativeDeleteTagData(int uid); } diff --git a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/SparseInputStream.java b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/SparseInputStream.java index 72230b4062e1..4117d0f07e0f 100644 --- a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/SparseInputStream.java +++ b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/SparseInputStream.java @@ -177,7 +177,7 @@ public class SparseInputStream extends InputStream { ret = 0; break; case SparseChunk.FILL: - ret = mCur.fill[(4 - ((int) mLeft & 0x3)) & 0x3]; + ret = Byte.toUnsignedInt(mCur.fill[(4 - ((int) mLeft & 0x3)) & 0x3]); break; default: throw new IOException("Unsupported Chunk:" + mCur.toString()); diff --git a/packages/SettingsLib/src/com/android/settingslib/devicestate/OWNERS b/packages/SettingsLib/src/com/android/settingslib/devicestate/OWNERS new file mode 100644 index 000000000000..98f41234feb1 --- /dev/null +++ b/packages/SettingsLib/src/com/android/settingslib/devicestate/OWNERS @@ -0,0 +1,3 @@ +# Default reviewers for this and subdirectories. +alexflo@google.com +chrisgollner@google.com diff --git a/packages/SettingsLib/src/com/android/settingslib/license/LicenseHtmlGeneratorFromXml.java b/packages/SettingsLib/src/com/android/settingslib/license/LicenseHtmlGeneratorFromXml.java index b4c95e6ee2df..2c2be0394b6e 100644 --- a/packages/SettingsLib/src/com/android/settingslib/license/LicenseHtmlGeneratorFromXml.java +++ b/packages/SettingsLib/src/com/android/settingslib/license/LicenseHtmlGeneratorFromXml.java @@ -39,6 +39,8 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.SortedMap; +import java.util.TreeMap; import java.util.zip.GZIPInputStream; /** @@ -54,6 +56,7 @@ class LicenseHtmlGeneratorFromXml { private static final String TAG_FILE_NAME = "file-name"; private static final String TAG_FILE_CONTENT = "file-content"; private static final String ATTR_CONTENT_ID = "contentId"; + private static final String ATTR_LIBRARY_NAME = "lib"; private static final String HTML_HEAD_STRING = "<html><head>\n" @@ -67,8 +70,12 @@ class LicenseHtmlGeneratorFromXml { + "</style>\n" + "</head>" + "<body topmargin=\"0\" leftmargin=\"0\" rightmargin=\"0\" bottommargin=\"0\">\n" - + "<div class=\"toc\">\n" - + "<ul>"; + + "<div class=\"toc\">\n"; + private static final String LIBRARY_HEAD_STRING = + "<strong>Libraries</strong>\n<ul class=\"libraries\">"; + private static final String LIBRARY_TAIL_STRING = "</ul>\n<strong>Files</strong>"; + + private static final String FILES_HEAD_STRING = "<ul class=\"files\">"; private static final String HTML_MIDDLE_STRING = "</ul>\n" @@ -81,12 +88,14 @@ class LicenseHtmlGeneratorFromXml { private final List<File> mXmlFiles; /* - * A map from a file name to a content id (MD5 sum of file content) for its license. - * For example, "/system/priv-app/TeleService/TeleService.apk" maps to + * A map from a file name to a library name (may be empty) to a content id (MD5 sum of file + * content) for its license. + * For example, "/system/priv-app/TeleService/TeleService.apk" maps to "service/Telephony" to * "9645f39e9db895a4aa6e02cb57294595". Here "9645f39e9db895a4aa6e02cb57294595" is a MD5 sum * of the content of packages/services/Telephony/MODULE_LICENSE_APACHE2. */ - private final Map<String, Set<String>> mFileNameToContentIdMap = new HashMap(); + private final Map<String, Map<String, Set<String>>> mFileNameToLibraryToContentIdMap = + new HashMap(); /* * A map from a content id (MD5 sum of file content) to a license file content. @@ -98,7 +107,7 @@ class LicenseHtmlGeneratorFromXml { static class ContentIdAndFileNames { final String mContentId; - final List<String> mFileNameList = new ArrayList(); + final Map<String, List<String>> mLibraryToFileNameMap = new TreeMap(); ContentIdAndFileNames(String contentId) { mContentId = contentId; @@ -120,7 +129,7 @@ class LicenseHtmlGeneratorFromXml { parse(xmlFile); } - if (mFileNameToContentIdMap.isEmpty() || mContentIdToFileContentMap.isEmpty()) { + if (mFileNameToLibraryToContentIdMap.isEmpty() || mContentIdToFileContentMap.isEmpty()) { return false; } @@ -128,7 +137,7 @@ class LicenseHtmlGeneratorFromXml { try { writer = new PrintWriter(outputFile); - generateHtml(mFileNameToContentIdMap, mContentIdToFileContentMap, writer, + generateHtml(mFileNameToLibraryToContentIdMap, mContentIdToFileContentMap, writer, noticeHeader); writer.flush(); @@ -157,7 +166,7 @@ class LicenseHtmlGeneratorFromXml { in = new FileReader(xmlFile); } - parse(in, mFileNameToContentIdMap, mContentIdToFileContentMap); + parse(in, mFileNameToLibraryToContentIdMap, mContentIdToFileContentMap); in.close(); } catch (XmlPullParserException | IOException e) { @@ -180,7 +189,8 @@ class LicenseHtmlGeneratorFromXml { * * <licenses> * <file-name contentId="content_id_of_license1">file1</file-name> - * <file-name contentId="content_id_of_license2">file2</file-name> + * <file-name contentId="content_id_of_license2" lib="name of library">file2</file-name> + * <file-name contentId="content_id_of_license2" lib="another library">file2</file-name> * ... * <file-content contentId="content_id_of_license1">license1 file contents</file-content> * <file-content contentId="content_id_of_license2">license2 file contents</file-content> @@ -188,10 +198,12 @@ class LicenseHtmlGeneratorFromXml { * </licenses> */ @VisibleForTesting - static void parse(InputStreamReader in, Map<String, Set<String>> outFileNameToContentIdMap, + static void parse(InputStreamReader in, + Map<String, Map<String, Set<String>>> outFileNameToLibraryToContentIdMap, Map<String, String> outContentIdToFileContentMap) throws XmlPullParserException, IOException { - Map<String, Set<String>> fileNameToContentIdMap = new HashMap<String, Set<String>>(); + Map<String, Map<String, Set<String>>> fileNameToLibraryToContentIdMap = + new HashMap<String, Map<String, Set<String>>>(); Map<String, String> contentIdToFileContentMap = new HashMap<String, String>(); XmlPullParser parser = Xml.newPullParser(); @@ -205,12 +217,15 @@ class LicenseHtmlGeneratorFromXml { if (state == XmlPullParser.START_TAG) { if (TAG_FILE_NAME.equals(parser.getName())) { String contentId = parser.getAttributeValue("", ATTR_CONTENT_ID); + String libraryName = parser.getAttributeValue("", ATTR_LIBRARY_NAME); if (!TextUtils.isEmpty(contentId)) { String fileName = readText(parser).trim(); if (!TextUtils.isEmpty(fileName)) { - Set<String> contentIds = - fileNameToContentIdMap.computeIfAbsent( - fileName, k -> new HashSet<>()); + Map<String, Set<String>> libs = + fileNameToLibraryToContentIdMap.computeIfAbsent( + fileName, k -> new HashMap<>()); + Set<String> contentIds = libs.computeIfAbsent( + libraryName, k -> new HashSet<>()); contentIds.add(contentId); } } @@ -229,11 +244,17 @@ class LicenseHtmlGeneratorFromXml { state = parser.next(); } - for (Map.Entry<String, Set<String>> entry : fileNameToContentIdMap.entrySet()) { - outFileNameToContentIdMap.merge( - entry.getKey(), entry.getValue(), (s1, s2) -> { - s1.addAll(s2); - return s1; + for (Map.Entry<String, Map<String, Set<String>>> mapEntry : + fileNameToLibraryToContentIdMap.entrySet()) { + outFileNameToLibraryToContentIdMap.merge( + mapEntry.getKey(), mapEntry.getValue(), (m1, m2) -> { + for (Map.Entry<String, Set<String>> entry : m2.entrySet()) { + m1.merge(entry.getKey(), entry.getValue(), (s1, s2) -> { + s1.addAll(s2); + return s1; + }); + } + return m1; }); } outContentIdToFileContentMap.putAll(contentIdToFileContentMap); @@ -251,13 +272,28 @@ class LicenseHtmlGeneratorFromXml { } @VisibleForTesting - static void generateHtml(Map<String, Set<String>> fileNameToContentIdMap, + static void generateHtml(Map<String, Map<String, Set<String>>> fileNameToLibraryToContentIdMap, Map<String, String> contentIdToFileContentMap, PrintWriter writer, String noticeHeader) { List<String> fileNameList = new ArrayList(); - fileNameList.addAll(fileNameToContentIdMap.keySet()); + fileNameList.addAll(fileNameToLibraryToContentIdMap.keySet()); Collections.sort(fileNameList); + SortedMap<String, Set<String>> libraryToContentIdMap = new TreeMap(); + for (Map<String, Set<String>> libraryToContentValue : + fileNameToLibraryToContentIdMap.values()) { + for (Map.Entry<String, Set<String>> entry : libraryToContentValue.entrySet()) { + if (TextUtils.isEmpty(entry.getKey())) { + continue; + } + libraryToContentIdMap.merge( + entry.getKey(), entry.getValue(), (s1, s2) -> { + s1.addAll(s2); + return s1; + }); + } + } + writer.println(HTML_HEAD_STRING); if (!TextUtils.isEmpty(noticeHeader)) { @@ -268,21 +304,56 @@ class LicenseHtmlGeneratorFromXml { Map<String, Integer> contentIdToOrderMap = new HashMap(); List<ContentIdAndFileNames> contentIdAndFileNamesList = new ArrayList(); + if (!libraryToContentIdMap.isEmpty()) { + writer.println(LIBRARY_HEAD_STRING); + for (Map.Entry<String, Set<String>> entry: libraryToContentIdMap.entrySet()) { + String libraryName = entry.getKey(); + for (String contentId : entry.getValue()) { + // Assigns an id to a newly referred license file content. + if (!contentIdToOrderMap.containsKey(contentId)) { + contentIdToOrderMap.put(contentId, count); + + // An index in contentIdAndFileNamesList is the order of each element. + contentIdAndFileNamesList.add(new ContentIdAndFileNames(contentId)); + count++; + } + int id = contentIdToOrderMap.get(contentId); + writer.format("<li><a href=\"#id%d\">%s</a></li>\n", id, libraryName); + } + } + writer.println(LIBRARY_TAIL_STRING); + } + // Prints all the file list with a link to its license file content. for (String fileName : fileNameList) { - for (String contentId : fileNameToContentIdMap.get(fileName)) { - // Assigns an id to a newly referred license file content. - if (!contentIdToOrderMap.containsKey(contentId)) { - contentIdToOrderMap.put(contentId, count); - - // An index in contentIdAndFileNamesList is the order of each element. - contentIdAndFileNamesList.add(new ContentIdAndFileNames(contentId)); - count++; + for (Map.Entry<String, Set<String>> libToContentId : + fileNameToLibraryToContentIdMap.get(fileName).entrySet()) { + String libraryName = libToContentId.getKey(); + if (libraryName == null) { + libraryName = ""; } + for (String contentId : libToContentId.getValue()) { + // Assigns an id to a newly referred license file content. + if (!contentIdToOrderMap.containsKey(contentId)) { + contentIdToOrderMap.put(contentId, count); + + // An index in contentIdAndFileNamesList is the order of each element. + contentIdAndFileNamesList.add(new ContentIdAndFileNames(contentId)); + count++; + } - int id = contentIdToOrderMap.get(contentId); - contentIdAndFileNamesList.get(id).mFileNameList.add(fileName); - writer.format("<li><a href=\"#id%d\">%s</a></li>\n", id, fileName); + int id = contentIdToOrderMap.get(contentId); + ContentIdAndFileNames elem = contentIdAndFileNamesList.get(id); + List<String> files = elem.mLibraryToFileNameMap.computeIfAbsent( + libraryName, k -> new ArrayList()); + files.add(fileName); + if (TextUtils.isEmpty(libraryName)) { + writer.format("<li><a href=\"#id%d\">%s</a></li>\n", id, fileName); + } else { + writer.format("<li><a href=\"#id%d\">%s - %s</a></li>\n", + id, fileName, libraryName); + } + } } } @@ -292,19 +363,27 @@ class LicenseHtmlGeneratorFromXml { // Prints all contents of the license files in order of id. for (ContentIdAndFileNames contentIdAndFileNames : contentIdAndFileNamesList) { writer.format("<tr id=\"id%d\"><td class=\"same-license\">\n", count); - writer.println("<div class=\"label\">Notices for file(s):</div>"); - writer.println("<div class=\"file-list\">"); - for (String fileName : contentIdAndFileNames.mFileNameList) { - writer.format("%s <br/>\n", fileName); + for (Map.Entry<String, List<String>> libraryFiles : + contentIdAndFileNames.mLibraryToFileNameMap.entrySet()) { + String libraryName = libraryFiles.getKey(); + if (TextUtils.isEmpty(libraryName)) { + writer.println("<div class=\"label\">Notices for file(s):</div>"); + } else { + writer.format("<div class=\"label\"><strong>%s</strong> used by:</div>\n", + libraryName); + } + writer.println("<div class=\"file-list\">"); + for (String fileName : libraryFiles.getValue()) { + writer.format("%s <br/>\n", fileName); + } + writer.println("</div><!-- file-list -->"); + count++; } - writer.println("</div><!-- file-list -->"); writer.println("<pre class=\"license-text\">"); writer.println(contentIdToFileContentMap.get( contentIdAndFileNames.mContentId)); writer.println("</pre><!-- license-text -->"); writer.println("</td></tr><!-- same-license -->"); - - count++; } writer.println(HTML_REAR_STRING); diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/devicestate/OWNERS b/packages/SettingsLib/tests/integ/src/com/android/settingslib/devicestate/OWNERS new file mode 100644 index 000000000000..98f41234feb1 --- /dev/null +++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/devicestate/OWNERS @@ -0,0 +1,3 @@ +# Default reviewers for this and subdirectories. +alexflo@google.com +chrisgollner@google.com diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpProfileTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpProfileTest.java index d7b366e60a1d..bb6b293b0c27 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpProfileTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpProfileTest.java @@ -206,9 +206,8 @@ public class A2dpProfileTest { when(config.isMandatoryCodec()).thenReturn(false); when(config.getCodecType()).thenReturn(4); - when(config.getCodecName()).thenReturn("LDAC"); assertThat(mProfile.getHighQualityAudioOptionLabel(mDevice)).isEqualTo( - String.format(KNOWN_CODEC_LABEL, config.getCodecName())); + String.format(KNOWN_CODEC_LABEL, "LDAC")); } @Test diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java index d53a3e896868..298ee90d311d 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java @@ -28,6 +28,7 @@ import android.bluetooth.BluetoothClass; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothUuid; import android.content.Context; +import android.os.Parcel; import android.os.ParcelUuid; import org.junit.Before; @@ -60,9 +61,9 @@ public class CachedBluetoothDeviceManagerTest { private final static Map<Integer, ParcelUuid> CAP_GROUP2 = Map.of(2, BluetoothUuid.CAP); private final BluetoothClass DEVICE_CLASS_1 = - new BluetoothClass(BluetoothClass.Device.AUDIO_VIDEO_HEADPHONES); + createBtClass(BluetoothClass.Device.AUDIO_VIDEO_HEADPHONES); private final BluetoothClass DEVICE_CLASS_2 = - new BluetoothClass(BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE); + createBtClass(BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE); @Mock private LocalBluetoothProfileManager mLocalProfileManager; @Mock @@ -92,6 +93,16 @@ public class CachedBluetoothDeviceManagerTest { private HearingAidDeviceManager mHearingAidDeviceManager; private Context mContext; + private BluetoothClass createBtClass(int deviceClass) { + Parcel p = Parcel.obtain(); + p.writeInt(deviceClass); + p.setDataPosition(0); // reset position of parcel before passing to constructor + + BluetoothClass bluetoothClass = BluetoothClass.CREATOR.createFromParcel(p); + p.recycle(); + return bluetoothClass; + } + @Before public void setUp() { MockitoAnnotations.initMocks(this); diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidDeviceManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidDeviceManagerTest.java index 7be176a37bb4..a8e607549ab1 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidDeviceManagerTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidDeviceManagerTest.java @@ -28,6 +28,7 @@ import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothHearingAid; import android.bluetooth.BluetoothProfile; import android.content.Context; +import android.os.Parcel; import org.junit.Before; import org.junit.Test; @@ -48,7 +49,7 @@ public class HearingAidDeviceManagerTest { private final static String DEVICE_ADDRESS_1 = "AA:BB:CC:DD:EE:11"; private final static String DEVICE_ADDRESS_2 = "AA:BB:CC:DD:EE:22"; private final BluetoothClass DEVICE_CLASS = - new BluetoothClass(BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE); + createBtClass(BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE); @Mock private LocalBluetoothProfileManager mLocalProfileManager; @Mock @@ -67,6 +68,16 @@ public class HearingAidDeviceManagerTest { private HearingAidDeviceManager mHearingAidDeviceManager; private Context mContext; + private BluetoothClass createBtClass(int deviceClass) { + Parcel p = Parcel.obtain(); + p.writeInt(deviceClass); + p.setDataPosition(0); // reset position of parcel before passing to constructor + + BluetoothClass bluetoothClass = BluetoothClass.CREATOR.createFromParcel(p); + p.recycle(); + return bluetoothClass; + } + @Before public void setUp() { MockitoAnnotations.initMocks(this); diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/license/LicenseHtmlGeneratorFromXmlTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/license/LicenseHtmlGeneratorFromXmlTest.java index e87461f85762..e348865019ec 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/license/LicenseHtmlGeneratorFromXmlTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/license/LicenseHtmlGeneratorFromXmlTest.java @@ -36,7 +36,7 @@ import java.util.Set; @RunWith(RobolectricTestRunner.class) public class LicenseHtmlGeneratorFromXmlTest { - private static final String VALILD_XML_STRING = + private static final String VALID_OLD_XML_STRING = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" + "<licenses>\n" + "<file-name contentId=\"0\">/file0</file-name>\n" @@ -44,7 +44,15 @@ public class LicenseHtmlGeneratorFromXmlTest { + "<file-content contentId=\"0\"><![CDATA[license content #0]]></file-content>\n" + "</licenses>"; - private static final String INVALILD_XML_STRING = + private static final String VALID_NEW_XML_STRING = + "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" + + "<licenses>\n" + + "<file-name contentId=\"0\" lib=\"libA\">/file0</file-name>\n" + + "<file-name contentId=\"0\" lib=\"libB\">/file1</file-name>\n" + + "<file-content contentId=\"0\"><![CDATA[license content #0]]></file-content>\n" + + "</licenses>"; + + private static final String INVALID_XML_STRING = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" + "<licenses2>\n" + "<file-name contentId=\"0\">/file0</file-name>\n" @@ -64,13 +72,13 @@ public class LicenseHtmlGeneratorFromXmlTest { + "</style>\n" + "</head>" + "<body topmargin=\"0\" leftmargin=\"0\" rightmargin=\"0\" bottommargin=\"0\">\n" - + "<div class=\"toc\">\n" - + "<ul>\n"; + + "<div class=\"toc\">\n"; private static final String HTML_CUSTOM_HEADING = "Custom heading"; - private static final String HTML_BODY_STRING = - "<li><a href=\"#id0\">/file0</a></li>\n" + private static final String HTML_OLD_BODY_STRING = + "<ul class=\"files\">\n" + + "<li><a href=\"#id0\">/file0</a></li>\n" + "<li><a href=\"#id1\">/file0</a></li>\n" + "<li><a href=\"#id0\">/file1</a></li>\n" + "</ul>\n" @@ -97,66 +105,181 @@ public class LicenseHtmlGeneratorFromXmlTest { + "</td></tr><!-- same-license -->\n" + "</table></body></html>\n"; - private static final String EXPECTED_HTML_STRING = HTML_HEAD_STRING + HTML_BODY_STRING; + private static final String HTML_NEW_BODY_STRING = + "<strong>Libraries</strong>\n" + + "<ul class=\"libraries\">\n" + + "<li><a href=\"#id0\">libA</a></li>\n" + + "<li><a href=\"#id1\">libB</a></li>\n" + + "</ul>\n" + + "<strong>Files</strong>\n" + + "<ul class=\"files\">\n" + + "<li><a href=\"#id0\">/file0 - libA</a></li>\n" + + "<li><a href=\"#id1\">/file0 - libB</a></li>\n" + + "<li><a href=\"#id0\">/file1 - libA</a></li>\n" + + "</ul>\n" + + "</div><!-- table of contents -->\n" + + "<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\">\n" + + "<tr id=\"id0\"><td class=\"same-license\">\n" + + "<div class=\"label\">Notices for file(s):</div>\n" + + "<div class=\"file-list\">\n" + + "/file0 <br/>\n" + + "/file1 <br/>\n" + + "</div><!-- file-list -->\n" + + "<pre class=\"license-text\">\n" + + "license content #0\n" + + "</pre><!-- license-text -->\n" + + "</td></tr><!-- same-license -->\n" + + "<tr id=\"id1\"><td class=\"same-license\">\n" + + "<div class=\"label\">Notices for file(s):</div>\n" + + "<div class=\"file-list\">\n" + + "/file0 <br/>\n" + + "</div><!-- file-list -->\n" + + "<pre class=\"license-text\">\n" + + "license content #1\n" + + "</pre><!-- license-text -->\n" + + "</td></tr><!-- same-license -->\n" + + "</table></body></html>\n"; + + private static final String EXPECTED_OLD_HTML_STRING = HTML_HEAD_STRING + HTML_OLD_BODY_STRING; + + private static final String EXPECTED_NEW_HTML_STRING = HTML_HEAD_STRING + HTML_NEW_BODY_STRING; + + private static final String EXPECTED_OLD_HTML_STRING_WITH_CUSTOM_HEADING = + HTML_HEAD_STRING + HTML_CUSTOM_HEADING + "\n" + HTML_OLD_BODY_STRING; - private static final String EXPECTED_HTML_STRING_WITH_CUSTOM_HEADING = - HTML_HEAD_STRING + HTML_CUSTOM_HEADING + "\n" + HTML_BODY_STRING; + private static final String EXPECTED_NEW_HTML_STRING_WITH_CUSTOM_HEADING = + HTML_HEAD_STRING + HTML_CUSTOM_HEADING + "\n" + HTML_NEW_BODY_STRING; @Test public void testParseValidXmlStream() throws XmlPullParserException, IOException { - Map<String, Set<String>> fileNameToContentIdMap = new HashMap<>(); + Map<String, Map<String, Set<String>>> fileNameToLibraryToContentIdMap = new HashMap<>(); Map<String, String> contentIdToFileContentMap = new HashMap<>(); LicenseHtmlGeneratorFromXml.parse( - new InputStreamReader(new ByteArrayInputStream(VALILD_XML_STRING.getBytes())), - fileNameToContentIdMap, contentIdToFileContentMap); - assertThat(fileNameToContentIdMap.size()).isEqualTo(2); - assertThat(fileNameToContentIdMap.get("/file0")).containsExactly("0"); - assertThat(fileNameToContentIdMap.get("/file1")).containsExactly("0"); + new InputStreamReader(new ByteArrayInputStream(VALID_OLD_XML_STRING.getBytes())), + fileNameToLibraryToContentIdMap, contentIdToFileContentMap); + assertThat(fileNameToLibraryToContentIdMap.size()).isEqualTo(1); + assertThat(fileNameToLibraryToContentIdMap.get("").size()).isEqualTo(2); + assertThat(fileNameToLibraryToContentIdMap.get("").get("/file0")).containsExactly("0"); + assertThat(fileNameToLibraryToContentIdMap.get("").get("/file1")).containsExactly("0"); + assertThat(contentIdToFileContentMap.size()).isEqualTo(1); + assertThat(contentIdToFileContentMap.get("0")).isEqualTo("license content #0"); + } + + @Test + public void testParseNewValidXmlStream() throws XmlPullParserException, IOException { + Map<String, Map<String, Set<String>>> fileNameToLibraryToContentIdMap = new HashMap<>(); + Map<String, String> contentIdToFileContentMap = new HashMap<>(); + + LicenseHtmlGeneratorFromXml.parse( + new InputStreamReader(new ByteArrayInputStream(VALID_NEW_XML_STRING.getBytes())), + fileNameToLibraryToContentIdMap, contentIdToFileContentMap); + assertThat(fileNameToLibraryToContentIdMap.size()).isEqualTo(2); + assertThat(fileNameToLibraryToContentIdMap.get("libA").size()).isEqualTo(1); + assertThat(fileNameToLibraryToContentIdMap.get("libB").size()).isEqualTo(1); + assertThat(fileNameToLibraryToContentIdMap.get("libA").get("/file0")).containsExactly("0"); + assertThat(fileNameToLibraryToContentIdMap.get("libB").get("/file1")).containsExactly("0"); assertThat(contentIdToFileContentMap.size()).isEqualTo(1); assertThat(contentIdToFileContentMap.get("0")).isEqualTo("license content #0"); } @Test(expected = XmlPullParserException.class) public void testParseInvalidXmlStream() throws XmlPullParserException, IOException { - Map<String, Set<String>> fileNameToContentIdMap = new HashMap<>(); + Map<String, Map<String, Set<String>>> fileNameToLibraryToContentIdMap = new HashMap<>(); Map<String, String> contentIdToFileContentMap = new HashMap<>(); LicenseHtmlGeneratorFromXml.parse( - new InputStreamReader(new ByteArrayInputStream(INVALILD_XML_STRING.getBytes())), - fileNameToContentIdMap, contentIdToFileContentMap); + new InputStreamReader(new ByteArrayInputStream(INVALID_XML_STRING.getBytes())), + fileNameToLibraryToContentIdMap, contentIdToFileContentMap); } @Test public void testGenerateHtml() { - Map<String, Set<String>> fileNameToContentIdMap = new HashMap<>(); + Map<String, Map<String, Set<String>>> fileNameToLibraryToContentIdMap = new HashMap<>(); + Map<String, String> contentIdToFileContentMap = new HashMap<>(); + Map<String, Set<String>> toBoth = new HashMap<>(); + Map<String, Set<String>> toOne = new HashMap<>(); + + toBoth.put("", new HashSet<String>(Arrays.asList("0", "1"))); + toOne.put("", new HashSet<String>(Arrays.asList("0"))); + + fileNameToLibraryToContentIdMap.put("/file0", toBoth); + fileNameToLibraryToContentIdMap.put("/file1", toOne); + contentIdToFileContentMap.put("0", "license content #0"); + contentIdToFileContentMap.put("1", "license content #1"); + + StringWriter output = new StringWriter(); + LicenseHtmlGeneratorFromXml.generateHtml( + fileNameToLibraryToContentIdMap, contentIdToFileContentMap, + new PrintWriter(output), ""); + assertThat(output.toString()).isEqualTo(EXPECTED_OLD_HTML_STRING); + } + + @Test + public void testGenerateNewHtml() { + Map<String, Map<String, Set<String>>> fileNameToLibraryToContentIdMap = new HashMap<>(); Map<String, String> contentIdToFileContentMap = new HashMap<>(); + Map<String, Set<String>> toBoth = new HashMap<>(); + Map<String, Set<String>> toOne = new HashMap<>(); + + toBoth.put("libA", new HashSet<String>(Arrays.asList("0"))); + toBoth.put("libB", new HashSet<String>(Arrays.asList("1"))); + toOne.put("libA", new HashSet<String>(Arrays.asList("0"))); - fileNameToContentIdMap.put("/file0", new HashSet<String>(Arrays.asList("0", "1"))); - fileNameToContentIdMap.put("/file1", new HashSet<String>(Arrays.asList("0"))); + fileNameToLibraryToContentIdMap.put("/file0", toBoth); + fileNameToLibraryToContentIdMap.put("/file1", toOne); contentIdToFileContentMap.put("0", "license content #0"); contentIdToFileContentMap.put("1", "license content #1"); StringWriter output = new StringWriter(); LicenseHtmlGeneratorFromXml.generateHtml( - fileNameToContentIdMap, contentIdToFileContentMap, new PrintWriter(output), ""); - assertThat(output.toString()).isEqualTo(EXPECTED_HTML_STRING); + fileNameToLibraryToContentIdMap, contentIdToFileContentMap, + new PrintWriter(output), ""); + assertThat(output.toString()).isEqualTo(EXPECTED_NEW_HTML_STRING); } @Test public void testGenerateHtmlWithCustomHeading() { - Map<String, Set<String>> fileNameToContentIdMap = new HashMap<>(); + Map<String, Map<String, Set<String>>> fileNameToLibraryToContentIdMap = new HashMap<>(); + Map<String, String> contentIdToFileContentMap = new HashMap<>(); + Map<String, Set<String>> toBoth = new HashMap<>(); + Map<String, Set<String>> toOne = new HashMap<>(); + + toBoth.put("", new HashSet<String>(Arrays.asList("0", "1"))); + toOne.put("", new HashSet<String>(Arrays.asList("0"))); + + fileNameToLibraryToContentIdMap.put("/file0", toBoth); + fileNameToLibraryToContentIdMap.put("/file1", toOne); + contentIdToFileContentMap.put("0", "license content #0"); + contentIdToFileContentMap.put("1", "license content #1"); + + StringWriter output = new StringWriter(); + LicenseHtmlGeneratorFromXml.generateHtml( + fileNameToLibraryToContentIdMap, contentIdToFileContentMap, + new PrintWriter(output), HTML_CUSTOM_HEADING); + assertThat(output.toString()).isEqualTo(EXPECTED_OLD_HTML_STRING_WITH_CUSTOM_HEADING); + } + + @Test + public void testGenerateNewHtmlWithCustomHeading() { + Map<String, Map<String, Set<String>>> fileNameToLibraryToContentIdMap = new HashMap<>(); Map<String, String> contentIdToFileContentMap = new HashMap<>(); + Map<String, Set<String>> toBoth = new HashMap<>(); + Map<String, Set<String>> toOne = new HashMap<>(); + + toBoth.put("libA", new HashSet<String>(Arrays.asList("0"))); + toBoth.put("libB", new HashSet<String>(Arrays.asList("1"))); + toOne.put("libA", new HashSet<String>(Arrays.asList("0"))); - fileNameToContentIdMap.put("/file0", new HashSet<String>(Arrays.asList("0", "1"))); - fileNameToContentIdMap.put("/file1", new HashSet<String>(Arrays.asList("0"))); + fileNameToLibraryToContentIdMap.put("/file0", toBoth); + fileNameToLibraryToContentIdMap.put("/file1", toOne); contentIdToFileContentMap.put("0", "license content #0"); contentIdToFileContentMap.put("1", "license content #1"); StringWriter output = new StringWriter(); LicenseHtmlGeneratorFromXml.generateHtml( - fileNameToContentIdMap, contentIdToFileContentMap, new PrintWriter(output), - HTML_CUSTOM_HEADING); - assertThat(output.toString()).isEqualTo(EXPECTED_HTML_STRING_WITH_CUSTOM_HEADING); + fileNameToLibraryToContentIdMap, contentIdToFileContentMap, + new PrintWriter(output), HTML_CUSTOM_HEADING); + assertThat(output.toString()).isEqualTo(EXPECTED_NEW_HTML_STRING_WITH_CUSTOM_HEADING); } } diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/MediaDeviceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/MediaDeviceTest.java index 6f7f73a3e79b..c122a37d0f79 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/MediaDeviceTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/MediaDeviceTest.java @@ -31,6 +31,7 @@ import android.bluetooth.BluetoothDevice; import android.content.Context; import android.media.MediaRoute2Info; import android.media.MediaRouter2Manager; +import android.os.Parcel; import com.android.settingslib.bluetooth.A2dpProfile; import com.android.settingslib.bluetooth.CachedBluetoothDevice; @@ -65,9 +66,9 @@ public class MediaDeviceTest { private static final String ROUTER_ID_3 = "RouterId_3"; private static final String TEST_PACKAGE_NAME = "com.test.playmusic"; private final BluetoothClass mHeadreeClass = - new BluetoothClass(BluetoothClass.Device.AUDIO_VIDEO_HEADPHONES); + createBtClass(BluetoothClass.Device.AUDIO_VIDEO_HEADPHONES); private final BluetoothClass mCarkitClass = - new BluetoothClass(BluetoothClass.Device.AUDIO_VIDEO_CAR_AUDIO); + createBtClass(BluetoothClass.Device.AUDIO_VIDEO_CAR_AUDIO); @Mock private BluetoothDevice mDevice1; @@ -118,6 +119,16 @@ public class MediaDeviceTest { private List<MediaDevice> mMediaDevices = new ArrayList<>(); private PhoneMediaDevice mPhoneMediaDevice; + private BluetoothClass createBtClass(int deviceClass) { + Parcel p = Parcel.obtain(); + p.writeInt(deviceClass); + p.setDataPosition(0); // reset position of parcel before passing to constructor + + BluetoothClass bluetoothClass = BluetoothClass.CREATOR.createFromParcel(p); + p.recycle(); + return bluetoothClass; + } + @Before public void setUp() { MockitoAnnotations.initMocks(this); diff --git a/packages/SettingsLib/tests/robotests/testutils/com/android/settingslib/testutils/shadow/ShadowBluetoothAdapter.java b/packages/SettingsLib/tests/robotests/testutils/com/android/settingslib/testutils/shadow/ShadowBluetoothAdapter.java index 3b7fbc73522f..c7e96bcdb856 100644 --- a/packages/SettingsLib/tests/robotests/testutils/com/android/settingslib/testutils/shadow/ShadowBluetoothAdapter.java +++ b/packages/SettingsLib/tests/robotests/testutils/com/android/settingslib/testutils/shadow/ShadowBluetoothAdapter.java @@ -69,7 +69,7 @@ public class ShadowBluetoothAdapter extends org.robolectric.shadows.ShadowBlueto } @Implementation - protected boolean removeActiveDevice(@BluetoothAdapter.ActiveDeviceUse int profiles) { + protected boolean removeActiveDevice(int profiles) { if (profiles != ACTIVE_DEVICE_AUDIO && profiles != ACTIVE_DEVICE_PHONE_CALL && profiles != ACTIVE_DEVICE_ALL) { return false; @@ -78,8 +78,7 @@ public class ShadowBluetoothAdapter extends org.robolectric.shadows.ShadowBlueto } @Implementation - protected boolean setActiveDevice(BluetoothDevice device, - @BluetoothAdapter.ActiveDeviceUse int profiles) { + protected boolean setActiveDevice(BluetoothDevice device, int profiles) { if (device == null) { return false; } diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml index 074d85c1007e..ca4dcbbf230e 100644 --- a/packages/Shell/AndroidManifest.xml +++ b/packages/Shell/AndroidManifest.xml @@ -509,6 +509,9 @@ <uses-permission android:name="android.permission.WIFI_UPDATE_COEX_UNSAFE_CHANNELS" /> <uses-permission android:name="android.permission.NEARBY_WIFI_DEVICES" /> <uses-permission android:name="android.permission.OVERRIDE_WIFI_CONFIG" /> + <!-- Permission needed for CTS test - ConcurrencyTest#testP2pExternalApprover + P2P external approver API sets require MANAGE_WIFI_AUTO_JOIN permission. --> + <uses-permission android:name="android.permission.MANAGE_WIFI_AUTO_JOIN" /> <!-- Permission required for CTS tests to enable/disable rate limiting toasts. --> <uses-permission android:name="android.permission.MANAGE_TOAST_RATE_LIMITING" /> @@ -556,6 +559,9 @@ <uses-permission android:name="android.permission.MANAGE_APP_HIBERNATION"/> + <!-- Permission required for CTS test - MediaCodecResourceTest --> + <uses-permission android:name="android.permission.MEDIA_RESOURCE_OVERRIDE_PID" /> + <!-- Permission required for CTS test - ResourceObserverNativeTest --> <uses-permission android:name="android.permission.REGISTER_MEDIA_RESOURCE_OBSERVER" /> diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/InstantAppNotifier.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/InstantAppNotifier.java index e58ea7b8b5f3..eddc347dad45 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/InstantAppNotifier.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/InstantAppNotifier.java @@ -234,7 +234,7 @@ public class InstantAppNotifier extends SystemUI ApplicationInfo appInfo = pm.getApplicationInfo( pkg, PackageManager.MATCH_UNINSTALLED_PACKAGES, info.userId); - if (appInfo.isInstantApp()) { + if (appInfo != null && appInfo.isInstantApp()) { postInstantAppNotif( pkg, info.userId, diff --git a/services/Android.bp b/services/Android.bp index 8947393849c1..536dc5d8ccd6 100644 --- a/services/Android.bp +++ b/services/Android.bp @@ -42,7 +42,9 @@ system_optimized_java_defaults { SYSTEM_OPTIMIZE_JAVA: { optimize: { enabled: true, - optimize: true, + // TODO(b/210510433): Enable optimizations after improving + // retracing infra. + optimize: false, shrink: true, proguard_flags_files: ["proguard.flags"], }, diff --git a/services/autofill/OWNERS b/services/autofill/OWNERS index c52751d79227..edfb2112198a 100644 --- a/services/autofill/OWNERS +++ b/services/autofill/OWNERS @@ -1 +1 @@ -include /core/java/android/service/autofill/OWNERS +include /core/java/android/view/autofill/OWNERS diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java index 30de4b416410..f6d05fa468e1 100644 --- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java +++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java @@ -1569,7 +1569,7 @@ public class CompanionDeviceManagerService extends SystemService implements Bind } @Override - public void onDeviceDisconnected(BluetoothDevice device, @DisconnectReason int reason) { + public void onDeviceDisconnected(BluetoothDevice device, int reason) { Slog.d(LOG_TAG, device.getAddress() + " disconnected w/ reason: (" + reason + ") " + BluetoothAdapter.BluetoothConnectionCallback.disconnectReasonText(reason)); CompanionDeviceManagerService.this.onDeviceDisconnected(device.getAddress()); diff --git a/services/core/java/com/android/server/BootReceiver.java b/services/core/java/com/android/server/BootReceiver.java index a0575cf6bab9..26d76a848a02 100644 --- a/services/core/java/com/android/server/BootReceiver.java +++ b/services/core/java/com/android/server/BootReceiver.java @@ -51,15 +51,12 @@ import com.android.internal.util.XmlUtils; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; -import java.io.BufferedReader; import java.io.File; import java.io.FileDescriptor; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; -import java.io.InputStreamReader; -import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.regex.Matcher; @@ -128,11 +125,9 @@ public class BootReceiver extends BroadcastReceiver { // Location of ftrace pipe for notifications from kernel memory tools like KFENCE and KASAN. private static final String ERROR_REPORT_TRACE_PIPE = "/sys/kernel/tracing/instances/bootreceiver/trace_pipe"; - // Stop after sending this many reports. See http://b/182159975. + // Stop after sending too many reports. See http://b/182159975. private static final int MAX_ERROR_REPORTS = 8; private static int sSentReports = 0; - // Avoid reporing the same bug from processDmesg() twice. - private static String sLastReportedBug = null; @Override public void onReceive(final Context context, Intent intent) { @@ -175,7 +170,8 @@ public class BootReceiver extends BroadcastReceiver { * We read from /sys/kernel/tracing/instances/bootreceiver/trace_pipe (set up by the * system), which will print an ftrace event when a memory corruption is detected in the * kernel. - * When an error is detected, we run the dmesg shell command and process its output. + * When an error is detected, we set the dmesg.start system property to notify dmesgd + * about a new error. */ OnFileDescriptorEventListener traceCallback = new OnFileDescriptorEventListener() { final int mBufferSize = 1024; @@ -191,8 +187,7 @@ public class BootReceiver extends BroadcastReceiver { * line, but to be on the safe side we keep reading until the buffer * contains a '\n' character. In the unlikely case of a very buggy kernel * the buffer may contain multiple tracing events that cannot be attributed - * to particular error reports. In that case the latest error report - * residing in dmesg is picked. + * to particular error reports. dmesgd will take care of all errors. */ try { int nbytes = Os.read(fd, mTraceBuffer, 0, mBufferSize); @@ -201,10 +196,13 @@ public class BootReceiver extends BroadcastReceiver { if (readStr.indexOf("\n") == -1) { return OnFileDescriptorEventListener.EVENT_INPUT; } - processDmesg(context); + if (sSentReports < MAX_ERROR_REPORTS) { + SystemProperties.set("dmesgd.start", "1"); + sSentReports++; + } } } catch (Exception e) { - Slog.wtf(TAG, "Error processing dmesg output", e); + Slog.wtf(TAG, "Error watching for trace events", e); return 0; // Unregister the handler. } return OnFileDescriptorEventListener.EVENT_INPUT; @@ -216,157 +214,6 @@ public class BootReceiver extends BroadcastReceiver { } - /** - * Check whether it is safe to collect this dmesg line or not. - * - * We only consider lines belonging to KASAN or KFENCE reports, but those may still contain - * user information, namely the process name: - * - * [ 69.547684] [ T6006]c7 6006 CPU: 7 PID: 6006 Comm: sh Tainted: G S C O ... - * - * hardware information: - * - * [ 69.558923] [ T6006]c7 6006 Hardware name: <REDACTED> - * - * or register dump (in KASAN reports only): - * - * ... RIP: 0033:0x7f96443109da - * ... RSP: 002b:00007ffcf0b51b08 EFLAGS: 00000202 ORIG_RAX: 00000000000000af - * ... RAX: ffffffffffffffda RBX: 000055dc3ee521a0 RCX: 00007f96443109da - * - * (on x86_64) - * - * ... pc : lpm_cpuidle_enter+0x258/0x384 - * ... lr : lpm_cpuidle_enter+0x1d4/0x384 - * ... sp : ffffff800820bea0 - * ... x29: ffffff800820bea0 x28: ffffffc2305f3ce0 - * ... ... - * ... x9 : 0000000000000001 x8 : 0000000000000000 - * (on ARM64) - * - * We therefore omit the lines that contain "Comm:", "Hardware name:", or match the general - * purpose register regexp. - * - * @param line single line of `dmesg` output. - * @return updated line with sensitive data removed, or null if the line must be skipped. - */ - public static String stripSensitiveData(String line) { - /* - * General purpose register names begin with "R" on x86_64 and "x" on ARM64. The letter is - * followed by two symbols (numbers, letters or spaces) and a colon, which is followed by a - * 16-digit hex number. The optional "_" prefix accounts for ORIG_RAX on x86. - */ - final String registerRegex = "[ _][Rx]..: [0-9a-f]{16}"; - final Pattern registerPattern = Pattern.compile(registerRegex); - - final String corruptionRegex = "Detected corrupted memory at 0x[0-9a-f]+"; - final Pattern corruptionPattern = Pattern.compile(corruptionRegex); - - if (line.contains("Comm: ") || line.contains("Hardware name: ")) return null; - if (registerPattern.matcher(line).find()) return null; - - Matcher cm = corruptionPattern.matcher(line); - if (cm.find()) return cm.group(0); - return line; - } - - /* - * Search dmesg output for the last error report from KFENCE or KASAN and copy it to Dropbox. - * - * Example report printed by the kernel (redacted to fit into 100 column limit): - * [ 69.236673] [ T6006]c7 6006 ========================================================= - * [ 69.245688] [ T6006]c7 6006 BUG: KFENCE: out-of-bounds in kfence_handle_page_fault - * [ 69.245688] [ T6006]c7 6006 - * [ 69.257816] [ T6006]c7 6006 Out-of-bounds access at 0xffffffca75c45000 (...) - * [ 69.267102] [ T6006]c7 6006 kfence_handle_page_fault+0x1bc/0x208 - * [ 69.273536] [ T6006]c7 6006 __do_kernel_fault+0xa8/0x11c - * ... - * [ 69.355427] [ T6006]c7 6006 kfence-#2 [0xffffffca75c46f30-0xffffffca75c46fff, ... - * [ 69.366938] [ T6006]c7 6006 __d_alloc+0x3c/0x1b4 - * [ 69.371946] [ T6006]c7 6006 d_alloc_parallel+0x48/0x538 - * [ 69.377578] [ T6006]c7 6006 __lookup_slow+0x60/0x15c - * ... - * [ 69.547684] [ T6006]c7 6006 CPU: 7 PID: 6006 Comm: sh Tainted: G S C O ... - * [ 69.558923] [ T6006]c7 6006 Hardware name: <REDACTED> - * [ 69.567059] [ T6006]c7 6006 ========================================================= - * - * We rely on the kernel printing task/CPU ID for every log line (CONFIG_PRINTK_CALLER=y). - * E.g. for the above report the task ID is T6006. Report lines may interleave with lines - * printed by other kernel tasks, which will have different task IDs, so in order to collect - * the report we: - * - find the next occurrence of the "BUG: " line in the kernel log, parse it to obtain the - * task ID and the tool name; - * - scan the rest of dmesg output and pick every line that has the same task ID, until we - * encounter a horizontal ruler, i.e.: - * [ 69.567059] [ T6006]c7 6006 ====================================================== - * - add that line to the error report, unless it contains sensitive information (see - * logLinePotentiallySensitive()) - * - repeat the above steps till the last report is found. - */ - private void processDmesg(Context ctx) throws IOException { - if (sSentReports == MAX_ERROR_REPORTS) return; - /* - * Only SYSTEM_KASAN_ERROR_REPORT and SYSTEM_KFENCE_ERROR_REPORT are supported at the - * moment. - */ - final String[] bugTypes = new String[] { "KASAN", "KFENCE" }; - final String tsRegex = "^\\[[^]]+\\] "; - final String bugRegex = - tsRegex + "\\[([^]]+)\\].*BUG: (" + String.join("|", bugTypes) + "):"; - final Pattern bugPattern = Pattern.compile(bugRegex); - - Process p = new ProcessBuilder("/system/bin/timeout", "-k", "90s", "60s", - "dmesg").redirectErrorStream(true).start(); - BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream())); - String line = null; - String task = null; - String tool = null; - String bugTitle = null; - Pattern reportPattern = null; - ArrayList<String> currentReport = null; - String lastReport = null; - - while ((line = reader.readLine()) != null) { - if (currentReport == null) { - Matcher bm = bugPattern.matcher(line); - if (!bm.find()) continue; - task = bm.group(1); - tool = bm.group(2); - bugTitle = line; - currentReport = new ArrayList<String>(); - currentReport.add(line); - String reportRegex = tsRegex + "\\[" + task + "\\].*"; - reportPattern = Pattern.compile(reportRegex); - continue; - } - Matcher rm = reportPattern.matcher(line); - if (!rm.matches()) continue; - if ((line = stripSensitiveData(line)) == null) continue; - if (line.contains("================================")) { - lastReport = String.join("\n", currentReport); - currentReport = null; - continue; - } - currentReport.add(line); - } - if (lastReport == null) { - Slog.w(TAG, "Could not find report in dmesg."); - return; - } - - // Avoid sending the same bug report twice. - if (bugTitle.equals(sLastReportedBug)) return; - - final String reportTag = "SYSTEM_" + tool + "_ERROR_REPORT"; - final DropBoxManager db = ctx.getSystemService(DropBoxManager.class); - final String headers = getCurrentBootHeaders(); - final String reportText = headers + lastReport; - - addTextToDropBox(db, reportTag, reportText, "/dev/kmsg", LOG_SIZE); - sLastReportedBug = bugTitle; - sSentReports++; - } - private void removeOldUpdatePackages(Context context) { Downloads.removeAllDownloadsByPackage(context, OLD_UPDATER_PACKAGE, OLD_UPDATER_CLASS); } diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java index 39ac5effe6fa..b59cd4c0f212 100644 --- a/services/core/java/com/android/server/NetworkManagementService.java +++ b/services/core/java/com/android/server/NetworkManagementService.java @@ -21,6 +21,7 @@ import static android.Manifest.permission.NETWORK_SETTINGS; import static android.Manifest.permission.OBSERVE_NETWORK_POLICY; import static android.Manifest.permission.SHUTDOWN; import static android.net.ConnectivityManager.FIREWALL_CHAIN_DOZABLE; +import static android.net.ConnectivityManager.FIREWALL_CHAIN_LOW_POWER_STANDBY; import static android.net.ConnectivityManager.FIREWALL_CHAIN_POWERSAVE; import static android.net.ConnectivityManager.FIREWALL_CHAIN_RESTRICTED; import static android.net.ConnectivityManager.FIREWALL_CHAIN_STANDBY; @@ -30,6 +31,7 @@ import static android.net.INetd.FIREWALL_DENYLIST; import static android.net.INetd.FIREWALL_RULE_ALLOW; import static android.net.INetd.FIREWALL_RULE_DENY; import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_DOZABLE; +import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_LOW_POWER_STANDBY; import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_POWERSAVE; import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_RESTRICTED; import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_STANDBY; @@ -206,6 +208,11 @@ public class NetworkManagementService extends INetworkManagementService.Stub { */ @GuardedBy("mRulesLock") private SparseIntArray mUidFirewallRestrictedRules = new SparseIntArray(); + /** + * Contains the per-UID firewall rules that are used when Low Power Standby is enabled. + */ + @GuardedBy("mRulesLock") + private SparseIntArray mUidFirewallLowPowerStandbyRules = new SparseIntArray(); /** Set of states for the child firewall chains. True if the chain is active. */ @GuardedBy("mRulesLock") final SparseBooleanArray mFirewallChainStates = new SparseBooleanArray(); @@ -506,12 +513,14 @@ public class NetworkManagementService extends INetworkManagementService.Stub { syncFirewallChainLocked(FIREWALL_CHAIN_DOZABLE, "dozable "); syncFirewallChainLocked(FIREWALL_CHAIN_POWERSAVE, "powersave "); syncFirewallChainLocked(FIREWALL_CHAIN_RESTRICTED, "restricted "); + syncFirewallChainLocked(FIREWALL_CHAIN_LOW_POWER_STANDBY, "low power standby "); final int[] chains = { FIREWALL_CHAIN_STANDBY, FIREWALL_CHAIN_DOZABLE, FIREWALL_CHAIN_POWERSAVE, - FIREWALL_CHAIN_RESTRICTED + FIREWALL_CHAIN_RESTRICTED, + FIREWALL_CHAIN_LOW_POWER_STANDBY }; for (int chain : chains) { @@ -1438,6 +1447,8 @@ public class NetworkManagementService extends INetworkManagementService.Stub { return FIREWALL_CHAIN_NAME_POWERSAVE; case FIREWALL_CHAIN_RESTRICTED: return FIREWALL_CHAIN_NAME_RESTRICTED; + case FIREWALL_CHAIN_LOW_POWER_STANDBY: + return FIREWALL_CHAIN_NAME_LOW_POWER_STANDBY; default: throw new IllegalArgumentException("Bad child chain: " + chain); } @@ -1453,6 +1464,8 @@ public class NetworkManagementService extends INetworkManagementService.Stub { return FIREWALL_ALLOWLIST; case FIREWALL_CHAIN_RESTRICTED: return FIREWALL_ALLOWLIST; + case FIREWALL_CHAIN_LOW_POWER_STANDBY: + return FIREWALL_ALLOWLIST; default: return isFirewallEnabled() ? FIREWALL_ALLOWLIST : FIREWALL_DENYLIST; } @@ -1571,6 +1584,8 @@ public class NetworkManagementService extends INetworkManagementService.Stub { return mUidFirewallPowerSaveRules; case FIREWALL_CHAIN_RESTRICTED: return mUidFirewallRestrictedRules; + case FIREWALL_CHAIN_LOW_POWER_STANDBY: + return mUidFirewallLowPowerStandbyRules; case FIREWALL_CHAIN_NONE: return mUidFirewallRules; default: @@ -1626,6 +1641,11 @@ public class NetworkManagementService extends INetworkManagementService.Stub { pw.println(getFirewallChainState(FIREWALL_CHAIN_RESTRICTED)); dumpUidFirewallRule(pw, FIREWALL_CHAIN_NAME_RESTRICTED, mUidFirewallRestrictedRules); + + pw.print("UID firewall low power standby chain enabled: "); + pw.println(getFirewallChainState(FIREWALL_CHAIN_LOW_POWER_STANDBY)); + dumpUidFirewallRule(pw, FIREWALL_CHAIN_NAME_LOW_POWER_STANDBY, + mUidFirewallLowPowerStandbyRules); } pw.print("Firewall enabled: "); pw.println(mFirewallEnabled); @@ -1749,6 +1769,11 @@ public class NetworkManagementService extends INetworkManagementService.Stub { if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of restricted mode"); return true; } + if (getFirewallChainState(FIREWALL_CHAIN_LOW_POWER_STANDBY) + && mUidFirewallLowPowerStandbyRules.get(uid) != FIREWALL_RULE_ALLOW) { + if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of low power standby"); + return true; + } if (mUidRejectOnMetered.get(uid)) { if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of no metered data" + " in the background"); diff --git a/services/core/java/com/android/server/SystemServiceManager.java b/services/core/java/com/android/server/SystemServiceManager.java index 3cc8e7672557..f36d11eac8f2 100644 --- a/services/core/java/com/android/server/SystemServiceManager.java +++ b/services/core/java/com/android/server/SystemServiceManager.java @@ -20,6 +20,8 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.content.Context; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageInfo; import android.content.pm.UserInfo; import android.os.Environment; import android.os.SystemClock; @@ -34,6 +36,7 @@ import com.android.internal.os.SystemServerClassLoaderFactory; import com.android.internal.util.Preconditions; import com.android.server.SystemService.TargetUser; import com.android.server.am.EventLogTags; +import com.android.server.pm.ApexManager; import com.android.server.pm.UserManagerInternal; import com.android.server.utils.TimingsTraceAndSlog; @@ -42,6 +45,8 @@ import dalvik.system.PathClassLoader; import java.io.File; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.ArrayList; /** @@ -114,12 +119,31 @@ public final class SystemServiceManager implements Dumpable { * @return The service instance. */ public SystemService startServiceFromJar(String className, String path) { - PathClassLoader pathClassLoader = SystemServerClassLoaderFactory.getOrCreateClassLoader( - path, this.getClass().getClassLoader()); + PathClassLoader pathClassLoader = + SystemServerClassLoaderFactory.getOrCreateClassLoader( + path, this.getClass().getClassLoader(), isJarInTestApex(path)); final Class<SystemService> serviceClass = loadClassFromLoader(className, pathClassLoader); return startService(serviceClass); } + /** + * Returns true if the jar is in a test APEX. + */ + private static boolean isJarInTestApex(String pathStr) { + Path path = Paths.get(pathStr); + if (path.getNameCount() >= 2 && path.getName(0).toString().equals("apex")) { + String apexModuleName = path.getName(1).toString(); + ApexManager apexManager = ApexManager.getInstance(); + String packageName = apexManager.getActivePackageNameForApexModuleName(apexModuleName); + PackageInfo packageInfo = apexManager.getPackageInfo( + packageName, ApexManager.MATCH_ACTIVE_PACKAGE); + if (packageInfo != null) { + return (packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_TEST_ONLY) != 0; + } + } + return false; + } + /* * Loads and initializes a class from the given classLoader. Returns the class. */ diff --git a/services/core/java/com/android/server/am/CachedAppOptimizer.java b/services/core/java/com/android/server/am/CachedAppOptimizer.java index 6230919d8d2d..583fb8950ccf 100644 --- a/services/core/java/com/android/server/am/CachedAppOptimizer.java +++ b/services/core/java/com/android/server/am/CachedAppOptimizer.java @@ -191,7 +191,9 @@ public final class CachedAppOptimizer { } else if (KEY_COMPACT_THROTTLE_1.equals(name) || KEY_COMPACT_THROTTLE_2.equals(name) || KEY_COMPACT_THROTTLE_3.equals(name) - || KEY_COMPACT_THROTTLE_4.equals(name)) { + || KEY_COMPACT_THROTTLE_4.equals(name) + || KEY_COMPACT_THROTTLE_5.equals(name) + || KEY_COMPACT_THROTTLE_6.equals(name)) { updateCompactionThrottles(); } else if (KEY_COMPACT_STATSD_SAMPLE_RATE.equals(name)) { updateCompactStatsdSampleRate(); diff --git a/services/core/java/com/android/server/am/DataConnectionStats.java b/services/core/java/com/android/server/am/DataConnectionStats.java index 6e39a4c802d9..651e98c602d9 100644 --- a/services/core/java/com/android/server/am/DataConnectionStats.java +++ b/services/core/java/com/android/server/am/DataConnectionStats.java @@ -73,7 +73,8 @@ public class DataConnectionStats extends BroadcastReceiver { IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_SIM_STATE_CHANGED); - mContext.registerReceiver(this, filter, null /* broadcastPermission */, mListenerHandler); + mContext.registerReceiver(this, filter, null /* broadcastPermission */, mListenerHandler, + Context.RECEIVER_NOT_EXPORTED); } @Override diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index 070725ed0603..4c56381bbeec 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -2817,8 +2817,9 @@ public class AudioService extends IAudioService.Stub int step; // skip a2dp absolute volume control request when the device - // is not an a2dp device - if (!AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device) + // is neither an a2dp device nor BLE device + if ((!AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device) + && !AudioSystem.DEVICE_OUT_ALL_BLE_SET.contains(device)) && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) != 0) { return; } @@ -2958,7 +2959,8 @@ public class AudioService extends IAudioService.Stub } if (device == AudioSystem.DEVICE_OUT_BLE_HEADSET - && streamType == getBluetoothContextualVolumeStream()) { + && streamType == getBluetoothContextualVolumeStream() + && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) { if (DEBUG_VOL) { Log.d(TAG, "adjustSreamVolume postSetLeAudioVolumeIndex index=" + newIndex + " stream=" + streamType); @@ -3559,8 +3561,9 @@ public class AudioService extends IAudioService.Stub int oldIndex; // skip a2dp absolute volume control request when the device - // is not an a2dp device - if (!AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device) + // is neither an a2dp device nor BLE device + if ((!AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device) + && !AudioSystem.DEVICE_OUT_ALL_BLE_SET.contains(device)) && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) != 0) { return; } @@ -3602,7 +3605,8 @@ public class AudioService extends IAudioService.Stub } if (device == AudioSystem.DEVICE_OUT_BLE_HEADSET - && streamType == getBluetoothContextualVolumeStream()) { + && streamType == getBluetoothContextualVolumeStream() + && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) { if (DEBUG_VOL) { Log.d(TAG, "adjustSreamVolume postSetLeAudioVolumeIndex index=" + index + " stream=" + streamType); diff --git a/services/core/java/com/android/server/audio/BtHelper.java b/services/core/java/com/android/server/audio/BtHelper.java index 1c299356a48c..b8ca7c7b67e1 100644 --- a/services/core/java/com/android/server/audio/BtHelper.java +++ b/services/core/java/com/android/server/audio/BtHelper.java @@ -482,6 +482,8 @@ public class BtHelper { } if (profile == BluetoothProfile.A2DP) { mA2dp = (BluetoothA2dp) proxy; + } else if (profile == BluetoothProfile.HEARING_AID) { + mHearingAid = (BluetoothHearingAid) proxy; } else if (profile == BluetoothProfile.LE_AUDIO) { mLeAudio = (BluetoothLeAudio) proxy; } @@ -490,9 +492,7 @@ public class BtHelper { return; } final BluetoothDevice btDevice = deviceList.get(0); - final @BluetoothProfile.BtProfileState int state = - proxy.getConnectionState(btDevice); - if (state == BluetoothProfile.STATE_CONNECTED) { + if (proxy.getConnectionState(btDevice) == BluetoothProfile.STATE_CONNECTED) { mDeviceBroker.queueOnBluetoothActiveDeviceChanged( new AudioDeviceBroker.BtDeviceChangedData(btDevice, null, new BluetoothProfileConnectionInfo(profile), diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java index 3fb49e412ed2..30ae7d6b8d21 100644 --- a/services/core/java/com/android/server/connectivity/Vpn.java +++ b/services/core/java/com/android/server/connectivity/Vpn.java @@ -2006,7 +2006,8 @@ public class Vpn { .setCategory(Notification.CATEGORY_SYSTEM) .setVisibility(Notification.VISIBILITY_PUBLIC) .setOngoing(true) - .setColor(mContext.getColor(R.color.system_notification_accent_color)); + .setColor(mContext.getColor( + android.R.color.system_notification_accent_color)); notificationManager.notify(TAG, SystemMessage.NOTE_VPN_DISCONNECTED, builder.build()); } finally { Binder.restoreCallingIdentity(token); diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java index 4822d6a62ac7..b482d1869c66 100644 --- a/services/core/java/com/android/server/media/MediaSessionRecord.java +++ b/services/core/java/com/android/server/media/MediaSessionRecord.java @@ -62,6 +62,7 @@ import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; +import java.util.NoSuchElementException; /** * This is the system implementation of a Session. Apps will interact with the @@ -792,7 +793,10 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR } for (ISessionControllerCallbackHolder holder : mControllerCallbackHolders) { try { + holder.mCallback.asBinder().unlinkToDeath(holder.mDeathMonitor, 0); holder.mCallback.onSessionDestroyed(); + } catch (NoSuchElementException e) { + logCallbackException("error unlinking to binder death", holder, e); } catch (DeadObjectException e) { logCallbackException("Removing dead callback in pushSessionDestroyed", holder, e); } catch (RemoteException e) { @@ -1375,12 +1379,22 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR return; } if (getControllerHolderIndexForCb(cb) < 0) { - mControllerCallbackHolders.add(new ISessionControllerCallbackHolder(cb, - packageName, Binder.getCallingUid())); + ISessionControllerCallbackHolder holder = new ISessionControllerCallbackHolder( + cb, packageName, Binder.getCallingUid(), () -> unregisterCallback(cb)); + mControllerCallbackHolders.add(holder); if (DEBUG) { Log.d(TAG, "registering controller callback " + cb + " from controller" + packageName); } + // Avoid callback leaks + try { + // cb is not referenced outside of the MediaSessionRecord, so the death + // handler won't prevent MediaSessionRecord to be garbage collected. + cb.asBinder().linkToDeath(holder.mDeathMonitor, 0); + } catch (RemoteException e) { + unregisterCallback(cb); + Log.w(TAG, "registerCallback failed to linkToDeath", e); + } } } } @@ -1390,6 +1404,12 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR synchronized (mLock) { int index = getControllerHolderIndexForCb(cb); if (index != -1) { + try { + cb.asBinder().unlinkToDeath( + mControllerCallbackHolders.get(index).mDeathMonitor, 0); + } catch (NoSuchElementException e) { + Log.w(TAG, "error unlinking to binder death", e); + } mControllerCallbackHolders.remove(index); } if (DEBUG) { @@ -1600,12 +1620,14 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR private final ISessionControllerCallback mCallback; private final String mPackageName; private final int mUid; + private final IBinder.DeathRecipient mDeathMonitor; ISessionControllerCallbackHolder(ISessionControllerCallback callback, String packageName, - int uid) { + int uid, IBinder.DeathRecipient deathMonitor) { mCallback = callback; mPackageName = packageName; mUid = uid; + mDeathMonitor = deathMonitor; } } diff --git a/services/core/java/com/android/server/net/LockdownVpnTracker.java b/services/core/java/com/android/server/net/LockdownVpnTracker.java index 851ea3d01085..1b7d1ba59b06 100644 --- a/services/core/java/com/android/server/net/LockdownVpnTracker.java +++ b/services/core/java/com/android/server/net/LockdownVpnTracker.java @@ -293,7 +293,7 @@ public class LockdownVpnTracker { .addAction(R.drawable.ic_menu_refresh, mContext.getString(R.string.reset), mResetIntent) .setColor(mContext.getColor( - com.android.internal.R.color.system_notification_accent_color)); + android.R.color.system_notification_accent_color)); mNotificationManager.notify(null /* tag */, SystemMessage.NOTE_VPN_STATUS, builder.build()); diff --git a/services/core/java/com/android/server/net/NetworkPolicyLogger.java b/services/core/java/com/android/server/net/NetworkPolicyLogger.java index b66c4668f2a0..33ac6cdb269e 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyLogger.java +++ b/services/core/java/com/android/server/net/NetworkPolicyLogger.java @@ -16,14 +16,16 @@ package com.android.server.net; import static android.net.ConnectivityManager.BLOCKED_REASON_NONE; -import static android.net.INetd.FIREWALL_CHAIN_DOZABLE; -import static android.net.INetd.FIREWALL_CHAIN_POWERSAVE; -import static android.net.INetd.FIREWALL_CHAIN_RESTRICTED; -import static android.net.INetd.FIREWALL_CHAIN_STANDBY; +import static android.net.ConnectivityManager.FIREWALL_CHAIN_DOZABLE; +import static android.net.ConnectivityManager.FIREWALL_CHAIN_LOW_POWER_STANDBY; +import static android.net.ConnectivityManager.FIREWALL_CHAIN_POWERSAVE; +import static android.net.ConnectivityManager.FIREWALL_CHAIN_RESTRICTED; +import static android.net.ConnectivityManager.FIREWALL_CHAIN_STANDBY; import static android.net.INetd.FIREWALL_RULE_ALLOW; import static android.net.INetd.FIREWALL_RULE_DENY; import static android.net.NetworkPolicyManager.ALLOWED_REASON_NONE; import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_DOZABLE; +import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_LOW_POWER_STANDBY; import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_POWERSAVE; import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_RESTRICTED; import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_STANDBY; @@ -328,6 +330,8 @@ public class NetworkPolicyLogger { return FIREWALL_CHAIN_NAME_POWERSAVE; case FIREWALL_CHAIN_RESTRICTED: return FIREWALL_CHAIN_NAME_RESTRICTED; + case FIREWALL_CHAIN_LOW_POWER_STANDBY: + return FIREWALL_CHAIN_NAME_LOW_POWER_STANDBY; default: return String.valueOf(chain); } diff --git a/services/core/java/com/android/server/pm/ApexManager.java b/services/core/java/com/android/server/pm/ApexManager.java index 31b186091f39..e7e691c9c654 100644 --- a/services/core/java/com/android/server/pm/ApexManager.java +++ b/services/core/java/com/android/server/pm/ApexManager.java @@ -343,6 +343,13 @@ public abstract class ApexManager { public abstract String getApexModuleNameForPackageName(String apexPackageName); /** + * Returns the package name of the active APEX whose name is {@code apexModuleName}. If not + * found, returns {@code null}. + */ + @Nullable + public abstract String getActivePackageNameForApexModuleName(String apexModuleName); + + /** * Copies the CE apex data directory for the given {@code userId} to a backup location, for use * in case of rollback. * @@ -467,6 +474,12 @@ public abstract class ApexManager { private ArrayMap<String, String> mPackageNameToApexModuleName; /** + * Reverse mapping of {@link #mPackageNameToApexModuleName}, for active packages only. + */ + @GuardedBy("mLock") + private ArrayMap<String, String> mApexModuleNameToActivePackageName; + + /** * Whether an APEX package is active or not. * * @param packageInfo the package to check @@ -534,6 +547,7 @@ public abstract class ApexManager { try { mAllPackagesCache = new ArrayList<>(); mPackageNameToApexModuleName = new ArrayMap<>(); + mApexModuleNameToActivePackageName = new ArrayMap<>(); allPkgs = waitForApexService().getAllPackages(); } catch (RemoteException re) { Slog.e(TAG, "Unable to retrieve packages from apexservice: " + re.toString()); @@ -580,6 +594,13 @@ public abstract class ApexManager { + packageInfo.packageName); } activePackagesSet.add(packageInfo.packageName); + if (mApexModuleNameToActivePackageName.containsKey(ai.moduleName)) { + throw new IllegalStateException( + "Two active packages have the same APEX module name: " + + ai.moduleName); + } + mApexModuleNameToActivePackageName.put( + ai.moduleName, packageInfo.packageName); } if (ai.isFactory) { // Don't throw when the duplicating APEX is VNDK APEX @@ -913,6 +934,16 @@ public abstract class ApexManager { } @Override + @Nullable + public String getActivePackageNameForApexModuleName(String apexModuleName) { + synchronized (mLock) { + Preconditions.checkState(mApexModuleNameToActivePackageName != null, + "APEX packages have not been scanned"); + return mApexModuleNameToActivePackageName.get(apexModuleName); + } + } + + @Override public boolean snapshotCeData(int userId, int rollbackId, String apexPackageName) { String apexModuleName; synchronized (mLock) { @@ -1330,6 +1361,12 @@ public abstract class ApexManager { } @Override + @Nullable + public String getActivePackageNameForApexModuleName(String apexModuleName) { + return null; + } + + @Override public boolean snapshotCeData(int userId, int rollbackId, String apexPackageName) { throw new UnsupportedOperationException(); } diff --git a/services/core/java/com/android/server/policy/KeyCombinationManager.java b/services/core/java/com/android/server/policy/KeyCombinationManager.java index 268de3e2182b..68e078c519ba 100644 --- a/services/core/java/com/android/server/policy/KeyCombinationManager.java +++ b/services/core/java/com/android/server/policy/KeyCombinationManager.java @@ -17,11 +17,13 @@ package com.android.server.policy; import static android.view.KeyEvent.KEYCODE_POWER; +import android.os.Handler; import android.os.SystemClock; import android.util.Log; import android.util.SparseLongArray; import android.view.KeyEvent; +import com.android.internal.annotations.GuardedBy; import com.android.internal.util.ToBooleanFunction; import java.io.PrintWriter; @@ -35,13 +37,18 @@ public class KeyCombinationManager { private static final String TAG = "KeyCombinationManager"; // Store the received down time of keycode. + @GuardedBy("mLock") private final SparseLongArray mDownTimes = new SparseLongArray(2); private final ArrayList<TwoKeysCombinationRule> mRules = new ArrayList(); // Selected rules according to current key down. + private final Object mLock = new Object(); + @GuardedBy("mLock") private final ArrayList<TwoKeysCombinationRule> mActiveRules = new ArrayList(); // The rule has been triggered by current keys. + @GuardedBy("mLock") private TwoKeysCombinationRule mTriggeredRule; + private final Handler mHandler = new Handler(); // Keys in a key combination must be pressed within this interval of each other. private static final long COMBINE_KEY_DELAY_MILLIS = 150; @@ -109,6 +116,12 @@ public class KeyCombinationManager { * Return true if any active rule could be triggered by the key event, otherwise false. */ boolean interceptKey(KeyEvent event, boolean interactive) { + synchronized (mLock) { + return interceptKeyLocked(event, interactive); + } + } + + private boolean interceptKeyLocked(KeyEvent event, boolean interactive) { final boolean down = event.getAction() == KeyEvent.ACTION_DOWN; final int keyCode = event.getKeyCode(); final int count = mActiveRules.size(); @@ -154,7 +167,7 @@ public class KeyCombinationManager { return false; } Log.v(TAG, "Performing combination rule : " + rule); - rule.execute(); + mHandler.post(rule::execute); mTriggeredRule = rule; return true; }); @@ -169,7 +182,7 @@ public class KeyCombinationManager { for (int index = count - 1; index >= 0; index--) { final TwoKeysCombinationRule rule = mActiveRules.get(index); if (rule.shouldInterceptKey(keyCode)) { - rule.cancel(); + mHandler.post(rule::cancel); mActiveRules.remove(index); } } @@ -181,31 +194,37 @@ public class KeyCombinationManager { * Return the interceptTimeout to tell InputDispatcher when is ready to deliver to window. */ long getKeyInterceptTimeout(int keyCode) { - if (forAllActiveRules((rule) -> rule.shouldInterceptKey(keyCode))) { - return mDownTimes.get(keyCode) + COMBINE_KEY_DELAY_MILLIS; + synchronized (mLock) { + if (forAllActiveRules((rule) -> rule.shouldInterceptKey(keyCode))) { + return mDownTimes.get(keyCode) + COMBINE_KEY_DELAY_MILLIS; + } + return 0; } - return 0; } /** * True if the key event had been handled. */ boolean isKeyConsumed(KeyEvent event) { - if ((event.getFlags() & KeyEvent.FLAG_FALLBACK) != 0) { - return false; + synchronized (mLock) { + if ((event.getFlags() & KeyEvent.FLAG_FALLBACK) != 0) { + return false; + } + return mTriggeredRule != null && mTriggeredRule.shouldInterceptKey(event.getKeyCode()); } - return mTriggeredRule != null && mTriggeredRule.shouldInterceptKey(event.getKeyCode()); } /** * True if power key is the candidate. */ boolean isPowerKeyIntercepted() { - if (forAllActiveRules((rule) -> rule.shouldInterceptKey(KEYCODE_POWER))) { - // return false if only if power key pressed. - return mDownTimes.size() > 1 || mDownTimes.get(KEYCODE_POWER) == 0; + synchronized (mLock) { + if (forAllActiveRules((rule) -> rule.shouldInterceptKey(KEYCODE_POWER))) { + // return false if only if power key pressed. + return mDownTimes.size() > 1 || mDownTimes.get(KEYCODE_POWER) == 0; + } + return false; } - return false; } /** diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java b/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java index 357c23222658..ae4d46c387b9 100644 --- a/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java +++ b/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java @@ -69,7 +69,7 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { * Telephony and network suggestions older than this value are considered too old to be used. */ @VisibleForTesting - static final long MAX_UTC_TIME_AGE_MILLIS = + static final long MAX_SUGGESTION_TIME_AGE_MILLIS = TELEPHONY_BUCKET_COUNT * TELEPHONY_BUCKET_SIZE_MILLIS; /** @@ -204,9 +204,9 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { @Override public synchronized void suggestExternalTime(@NonNull ExternalTimeSuggestion timeSuggestion) { - final TimestampedValue<Long> newUtcTime = timeSuggestion.getUtcTime(); + final TimestampedValue<Long> newUnixEpochTime = timeSuggestion.getUnixEpochTime(); - if (!validateAutoSuggestionTime(newUtcTime, timeSuggestion)) { + if (!validateAutoSuggestionTime(newUnixEpochTime, timeSuggestion)) { return; } @@ -218,9 +218,9 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { @Override public synchronized void suggestGnssTime(@NonNull GnssTimeSuggestion timeSuggestion) { - final TimestampedValue<Long> newUtcTime = timeSuggestion.getUtcTime(); + final TimestampedValue<Long> newUnixEpochTime = timeSuggestion.getUnixEpochTime(); - if (!validateAutoSuggestionTime(newUtcTime, timeSuggestion)) { + if (!validateAutoSuggestionTime(newUnixEpochTime, timeSuggestion)) { return; } @@ -232,19 +232,19 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { @Override public synchronized boolean suggestManualTime(@NonNull ManualTimeSuggestion suggestion) { - final TimestampedValue<Long> newUtcTime = suggestion.getUtcTime(); + final TimestampedValue<Long> newUnixEpochTime = suggestion.getUnixEpochTime(); - if (!validateSuggestionTime(newUtcTime, suggestion)) { + if (!validateSuggestionTime(newUnixEpochTime, suggestion)) { return false; } String cause = "Manual time suggestion received: suggestion=" + suggestion; - return setSystemClockIfRequired(ORIGIN_MANUAL, newUtcTime, cause); + return setSystemClockIfRequired(ORIGIN_MANUAL, newUnixEpochTime, cause); } @Override public synchronized void suggestNetworkTime(@NonNull NetworkTimeSuggestion timeSuggestion) { - if (!validateAutoSuggestionTime(timeSuggestion.getUtcTime(), timeSuggestion)) { + if (!validateAutoSuggestionTime(timeSuggestion.getUnixEpochTime(), timeSuggestion)) { return; } @@ -274,11 +274,11 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { // unlike time zone, where a user may lose connectivity when boarding a flight and where we // do want to "forget" old signals. Suggestions that are too old are discarded later in the // detection algorithm. - if (timeSuggestion.getUtcTime() == null) { + if (timeSuggestion.getUnixEpochTime() == null) { return; } - if (!validateAutoSuggestionTime(timeSuggestion.getUtcTime(), timeSuggestion)) { + if (!validateAutoSuggestionTime(timeSuggestion.getUnixEpochTime(), timeSuggestion)) { return; } @@ -365,14 +365,14 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { @GuardedBy("this") private boolean storeTelephonySuggestion( @NonNull TelephonyTimeSuggestion suggestion) { - TimestampedValue<Long> newUtcTime = suggestion.getUtcTime(); + TimestampedValue<Long> newUnixEpochTime = suggestion.getUnixEpochTime(); int slotIndex = suggestion.getSlotIndex(); TelephonyTimeSuggestion previousSuggestion = mSuggestionBySlotIndex.get(slotIndex); if (previousSuggestion != null) { // We can log / discard suggestions with obvious issues with the reference time clock. - if (previousSuggestion.getUtcTime() == null - || previousSuggestion.getUtcTime().getValue() == null) { + if (previousSuggestion.getUnixEpochTime() == null + || previousSuggestion.getUnixEpochTime().getValue() == null) { // This should be impossible given we only store validated suggestions. Slog.w(LOG_TAG, "Previous suggestion is null or has a null time." + " previousSuggestion=" + previousSuggestion @@ -381,7 +381,7 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { } long referenceTimeDifference = TimestampedValue.referenceTimeDifference( - newUtcTime, previousSuggestion.getUtcTime()); + newUnixEpochTime, previousSuggestion.getUnixEpochTime()); if (referenceTimeDifference < 0) { // The reference time is before the previously received suggestion. Ignore it. Slog.w(LOG_TAG, "Out of order telephony suggestion received." @@ -398,15 +398,15 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { } private boolean validateSuggestionTime( - @NonNull TimestampedValue<Long> newUtcTime, @NonNull Object suggestion) { - if (newUtcTime.getValue() == null) { + @NonNull TimestampedValue<Long> newUnixEpochTime, @NonNull Object suggestion) { + if (newUnixEpochTime.getValue() == null) { Slog.w(LOG_TAG, "Suggested time value is null. suggestion=" + suggestion); return false; } // We can validate the suggestion against the reference time clock. long elapsedRealtimeMillis = mEnvironment.elapsedRealtimeMillis(); - if (elapsedRealtimeMillis < newUtcTime.getReferenceTimeMillis()) { + if (elapsedRealtimeMillis < newUnixEpochTime.getReferenceTimeMillis()) { // elapsedRealtime clock went backwards? Slog.w(LOG_TAG, "New reference time is in the future? Ignoring." + " elapsedRealtimeMillis=" + elapsedRealtimeMillis @@ -417,17 +417,17 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { } private boolean validateAutoSuggestionTime( - @NonNull TimestampedValue<Long> newUtcTime, @NonNull Object suggestion) { - return validateSuggestionTime(newUtcTime, suggestion) - && validateSuggestionAgainstLowerBound(newUtcTime, suggestion); + @NonNull TimestampedValue<Long> newUnixEpochTime, @NonNull Object suggestion) { + return validateSuggestionTime(newUnixEpochTime, suggestion) + && validateSuggestionAgainstLowerBound(newUnixEpochTime, suggestion); } private boolean validateSuggestionAgainstLowerBound( - @NonNull TimestampedValue<Long> newUtcTime, @NonNull Object suggestion) { + @NonNull TimestampedValue<Long> newUnixEpochTime, @NonNull Object suggestion) { Instant lowerBound = mEnvironment.autoTimeLowerBound(); // Suggestion is definitely wrong if it comes before lower time bound. - if (lowerBound.isAfter(Instant.ofEpochMilli(newUtcTime.getValue()))) { + if (lowerBound.isAfter(Instant.ofEpochMilli(newUnixEpochTime.getValue()))) { Slog.w(LOG_TAG, "Suggestion points to time before lower bound, skipping it. " + "suggestion=" + suggestion + ", lower bound=" + lowerBound); return false; @@ -446,12 +446,12 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { // Try the different origins one at a time. int[] originPriorities = mEnvironment.autoOriginPriorities(); for (int origin : originPriorities) { - TimestampedValue<Long> newUtcTime = null; + TimestampedValue<Long> newUnixEpochTime = null; String cause = null; if (origin == ORIGIN_TELEPHONY) { TelephonyTimeSuggestion bestTelephonySuggestion = findBestTelephonySuggestion(); if (bestTelephonySuggestion != null) { - newUtcTime = bestTelephonySuggestion.getUtcTime(); + newUnixEpochTime = bestTelephonySuggestion.getUnixEpochTime(); cause = "Found good telephony suggestion." + ", bestTelephonySuggestion=" + bestTelephonySuggestion + ", detectionReason=" + detectionReason; @@ -459,7 +459,7 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { } else if (origin == ORIGIN_NETWORK) { NetworkTimeSuggestion networkSuggestion = findLatestValidNetworkSuggestion(); if (networkSuggestion != null) { - newUtcTime = networkSuggestion.getUtcTime(); + newUnixEpochTime = networkSuggestion.getUnixEpochTime(); cause = "Found good network suggestion." + ", networkSuggestion=" + networkSuggestion + ", detectionReason=" + detectionReason; @@ -467,7 +467,7 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { } else if (origin == ORIGIN_GNSS) { GnssTimeSuggestion gnssTimeSuggestion = findLatestValidGnssSuggestion(); if (gnssTimeSuggestion != null) { - newUtcTime = gnssTimeSuggestion.getUtcTime(); + newUnixEpochTime = gnssTimeSuggestion.getUnixEpochTime(); cause = "Found good gnss suggestion." + ", gnssTimeSuggestion=" + gnssTimeSuggestion + ", detectionReason=" + detectionReason; @@ -475,7 +475,7 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { } else if (origin == ORIGIN_EXTERNAL) { ExternalTimeSuggestion externalTimeSuggestion = findLatestValidExternalSuggestion(); if (externalTimeSuggestion != null) { - newUtcTime = externalTimeSuggestion.getUtcTime(); + newUnixEpochTime = externalTimeSuggestion.getUnixEpochTime(); cause = "Found good external suggestion." + ", externalTimeSuggestion=" + externalTimeSuggestion + ", detectionReason=" + detectionReason; @@ -487,8 +487,8 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { } // Update the system clock if a good suggestion has been found. - if (newUtcTime != null) { - setSystemClockIfRequired(origin, newUtcTime, cause); + if (newUnixEpochTime != null) { + setSystemClockIfRequired(origin, newUnixEpochTime, cause); return; } } @@ -545,7 +545,7 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { Slog.w(LOG_TAG, "Latest suggestion unexpectedly null for slotIndex." + " slotIndex=" + slotIndex); continue; - } else if (candidateSuggestion.getUtcTime() == null) { + } else if (candidateSuggestion.getUnixEpochTime() == null) { // Unexpected - we do not store empty suggestions. Slog.w(LOG_TAG, "Latest suggestion unexpectedly empty. " + " candidateSuggestion=" + candidateSuggestion); @@ -579,8 +579,8 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { long elapsedRealtimeMillis, @NonNull TelephonyTimeSuggestion timeSuggestion) { // Validate first. - TimestampedValue<Long> utcTime = timeSuggestion.getUtcTime(); - if (!validateSuggestionUtcTime(elapsedRealtimeMillis, utcTime)) { + TimestampedValue<Long> unixEpochTime = timeSuggestion.getUnixEpochTime(); + if (!validateSuggestionUnixEpochTime(elapsedRealtimeMillis, unixEpochTime)) { Slog.w(LOG_TAG, "Existing suggestion found to be invalid" + " elapsedRealtimeMillis=" + elapsedRealtimeMillis + ", timeSuggestion=" + timeSuggestion); @@ -589,7 +589,7 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { // The score is based on the age since receipt. Suggestions are bucketed so two // suggestions in the same bucket from different slotIndexs are scored the same. - long ageMillis = elapsedRealtimeMillis - utcTime.getReferenceTimeMillis(); + long ageMillis = elapsedRealtimeMillis - unixEpochTime.getReferenceTimeMillis(); // Turn the age into a discrete value: 0 <= bucketIndex < TELEPHONY_BUCKET_COUNT. int bucketIndex = (int) (ageMillis / TELEPHONY_BUCKET_SIZE_MILLIS); @@ -611,9 +611,9 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { return null; } - TimestampedValue<Long> utcTime = networkSuggestion.getUtcTime(); + TimestampedValue<Long> unixEpochTime = networkSuggestion.getUnixEpochTime(); long elapsedRealTimeMillis = mEnvironment.elapsedRealtimeMillis(); - if (!validateSuggestionUtcTime(elapsedRealTimeMillis, utcTime)) { + if (!validateSuggestionUnixEpochTime(elapsedRealTimeMillis, unixEpochTime)) { // The latest suggestion is not valid, usually due to its age. return null; } @@ -631,9 +631,9 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { return null; } - TimestampedValue<Long> utcTime = gnssTimeSuggestion.getUtcTime(); + TimestampedValue<Long> unixEpochTime = gnssTimeSuggestion.getUnixEpochTime(); long elapsedRealTimeMillis = mEnvironment.elapsedRealtimeMillis(); - if (!validateSuggestionUtcTime(elapsedRealTimeMillis, utcTime)) { + if (!validateSuggestionUnixEpochTime(elapsedRealTimeMillis, unixEpochTime)) { // The latest suggestion is not valid, usually due to its age. return null; } @@ -651,9 +651,9 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { return null; } - TimestampedValue<Long> utcTime = externalTimeSuggestion.getUtcTime(); + TimestampedValue<Long> unixEpochTime = externalTimeSuggestion.getUnixEpochTime(); long elapsedRealTimeMillis = mEnvironment.elapsedRealtimeMillis(); - if (!validateSuggestionUtcTime(elapsedRealTimeMillis, utcTime)) { + if (!validateSuggestionUnixEpochTime(elapsedRealTimeMillis, unixEpochTime)) { // The latest suggestion is not valid, usually due to its age. return null; } @@ -844,9 +844,9 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { return mLastExternalSuggestion.get(); } - private static boolean validateSuggestionUtcTime( - long elapsedRealtimeMillis, TimestampedValue<Long> utcTime) { - long referenceTimeMillis = utcTime.getReferenceTimeMillis(); + private static boolean validateSuggestionUnixEpochTime( + long elapsedRealtimeMillis, TimestampedValue<Long> unixEpochTime) { + long referenceTimeMillis = unixEpochTime.getReferenceTimeMillis(); if (referenceTimeMillis > elapsedRealtimeMillis) { // Future reference times are ignored. They imply the reference time was wrong, or the // elapsed realtime clock used to derive it has gone backwards, neither of which are @@ -860,6 +860,6 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy { // made and never replaced, it could also mean that the time detection code remains // opinionated using a bad invalid suggestion. This caps that edge case at MAX_AGE_MILLIS. long ageMillis = elapsedRealtimeMillis - referenceTimeMillis; - return ageMillis <= MAX_UTC_TIME_AGE_MILLIS; + return ageMillis <= MAX_SUGGESTION_TIME_AGE_MILLIS; } } diff --git a/services/core/java/com/android/server/tracing/TracingServiceProxy.java b/services/core/java/com/android/server/tracing/TracingServiceProxy.java index 27c0beee9c27..10e868d06766 100644 --- a/services/core/java/com/android/server/tracing/TracingServiceProxy.java +++ b/services/core/java/com/android/server/tracing/TracingServiceProxy.java @@ -15,6 +15,13 @@ */ package com.android.server.tracing; +import static com.android.internal.util.FrameworkStatsLog.TRACING_SERVICE_REPORT_EVENT; +import static com.android.internal.util.FrameworkStatsLog.TRACING_SERVICE_REPORT_EVENT__EVENT__TRACING_SERVICE_REPORT_BEGIN; +import static com.android.internal.util.FrameworkStatsLog.TRACING_SERVICE_REPORT_EVENT__EVENT__TRACING_SERVICE_REPORT_BIND_PERM_INCORRECT; +import static com.android.internal.util.FrameworkStatsLog.TRACING_SERVICE_REPORT_EVENT__EVENT__TRACING_SERVICE_REPORT_SVC_COMM_ERROR; +import static com.android.internal.util.FrameworkStatsLog.TRACING_SERVICE_REPORT_EVENT__EVENT__TRACING_SERVICE_REPORT_SVC_HANDOFF; +import static com.android.internal.util.FrameworkStatsLog.TRACING_SERVICE_REPORT_EVENT__EVENT__TRACING_SERVICE_REPORT_SVC_PERM_MISSING; + import android.Manifest; import android.annotation.NonNull; import android.content.ComponentName; @@ -39,6 +46,7 @@ import android.util.LruCache; import android.util.Slog; import com.android.internal.infra.ServiceConnector; +import com.android.internal.util.FrameworkStatsLog; import com.android.server.SystemService; import java.io.IOException; @@ -71,6 +79,17 @@ public class TracingServiceProxy extends SystemService { private static final String INTENT_ACTION_NOTIFY_SESSION_STOLEN = "com.android.traceur.NOTIFY_SESSION_STOLEN"; + private static final int REPORT_BEGIN = + TRACING_SERVICE_REPORT_EVENT__EVENT__TRACING_SERVICE_REPORT_BEGIN; + private static final int REPORT_SVC_HANDOFF = + TRACING_SERVICE_REPORT_EVENT__EVENT__TRACING_SERVICE_REPORT_SVC_HANDOFF; + private static final int REPORT_BIND_PERM_INCORRECT = + TRACING_SERVICE_REPORT_EVENT__EVENT__TRACING_SERVICE_REPORT_BIND_PERM_INCORRECT; + private static final int REPORT_SVC_PERM_MISSING = + TRACING_SERVICE_REPORT_EVENT__EVENT__TRACING_SERVICE_REPORT_SVC_PERM_MISSING; + private static final int REPORT_SVC_COMM_ERROR = + TRACING_SERVICE_REPORT_EVENT__EVENT__TRACING_SERVICE_REPORT_SVC_COMM_ERROR; + private final Context mContext; private final PackageManager mPackageManager; private final LruCache<ComponentName, ServiceConnector<IMessenger>> mCachedReporterServices; @@ -134,17 +153,24 @@ public class TracingServiceProxy extends SystemService { } private void reportTrace(@NonNull TraceReportParams params) { + FrameworkStatsLog.write(TRACING_SERVICE_REPORT_EVENT, REPORT_BEGIN, + params.uuidLsb, params.uuidMsb); + // We don't need to do any permission checks on the caller because access // to this service is guarded by SELinux. ComponentName component = new ComponentName(params.reporterPackageName, params.reporterClassName); if (!hasBindServicePermission(component)) { + FrameworkStatsLog.write(TRACING_SERVICE_REPORT_EVENT, REPORT_BIND_PERM_INCORRECT, + params.uuidLsb, params.uuidMsb); return; } boolean hasDumpPermission = hasPermission(component, Manifest.permission.DUMP); boolean hasUsageStatsPermission = hasPermission(component, Manifest.permission.PACKAGE_USAGE_STATS); if (!hasDumpPermission || !hasUsageStatsPermission) { + FrameworkStatsLog.write(TRACING_SERVICE_REPORT_EVENT, REPORT_SVC_PERM_MISSING, + params.uuidLsb, params.uuidMsb); return; } final long ident = Binder.clearCallingIdentity(); @@ -178,8 +204,13 @@ public class TracingServiceProxy extends SystemService { message.what = TraceReportService.MSG_REPORT_TRACE; message.obj = params; messenger.send(message); + + FrameworkStatsLog.write(TRACING_SERVICE_REPORT_EVENT, REPORT_SVC_HANDOFF, + params.uuidLsb, params.uuidMsb); }).whenComplete((res, err) -> { if (err != null) { + FrameworkStatsLog.write(TRACING_SERVICE_REPORT_EVENT, REPORT_SVC_COMM_ERROR, + params.uuidLsb, params.uuidMsb); Slog.e(TAG, "Failed to report trace", err); } try { diff --git a/services/core/java/com/android/server/vcn/TelephonySubscriptionTracker.java b/services/core/java/com/android/server/vcn/TelephonySubscriptionTracker.java index a17e79273e41..30e261725a73 100644 --- a/services/core/java/com/android/server/vcn/TelephonySubscriptionTracker.java +++ b/services/core/java/com/android/server/vcn/TelephonySubscriptionTracker.java @@ -146,7 +146,7 @@ public class TelephonySubscriptionTracker extends BroadcastReceiver { filter.addAction(ACTION_CARRIER_CONFIG_CHANGED); filter.addAction(ACTION_MULTI_SIM_CONFIG_CHANGED); - mContext.registerReceiver(this, filter, null, mHandler); + mContext.registerReceiver(this, filter, null, mHandler, Context.RECEIVER_NOT_EXPORTED); mSubscriptionManager.addOnSubscriptionsChangedListener( executor, mSubscriptionChangedListener); mTelephonyManager.registerTelephonyCallback(executor, mActiveDataSubIdListener); diff --git a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java b/services/core/java/com/android/server/vcn/VcnGatewayConnection.java index 8b80b4a0b21e..597f7f284730 100644 --- a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java +++ b/services/core/java/com/android/server/vcn/VcnGatewayConnection.java @@ -78,6 +78,7 @@ import android.os.PowerManager.WakeLock; import android.os.Process; import android.os.SystemClock; import android.provider.Settings; +import android.telephony.TelephonyManager; import android.util.ArraySet; import android.util.Slog; @@ -163,6 +164,14 @@ import java.util.function.Consumer; public class VcnGatewayConnection extends StateMachine { private static final String TAG = VcnGatewayConnection.class.getSimpleName(); + // Matches DataConnection.NETWORK_TYPE private constant, and magic string from + // ConnectivityManager#getNetworkTypeName() + @VisibleForTesting(visibility = Visibility.PRIVATE) + static final String NETWORK_INFO_NETWORK_TYPE_STRING = "MOBILE"; + + @VisibleForTesting(visibility = Visibility.PRIVATE) + static final String NETWORK_INFO_EXTRA_INFO = "VCN"; + @VisibleForTesting(visibility = Visibility.PRIVATE) static final InetAddress DUMMY_ADDR = InetAddresses.parseNumericAddress("192.0.2.0"); @@ -1631,6 +1640,12 @@ public class VcnGatewayConnection extends StateMachine { final NetworkAgentConfig nac = new NetworkAgentConfig.Builder() .setLegacyType(ConnectivityManager.TYPE_MOBILE) + .setLegacyTypeName(NETWORK_INFO_NETWORK_TYPE_STRING) + .setLegacySubType(TelephonyManager.NETWORK_TYPE_UNKNOWN) + .setLegacySubTypeName( + TelephonyManager.getNetworkTypeName( + TelephonyManager.NETWORK_TYPE_UNKNOWN)) + .setLegacyExtraInfo(NETWORK_INFO_EXTRA_INFO) .build(); final VcnNetworkAgent agent = diff --git a/services/core/java/com/android/server/wm/DisplayAreaOrganizerController.java b/services/core/java/com/android/server/wm/DisplayAreaOrganizerController.java index f61cc94b6181..a83a033985c5 100644 --- a/services/core/java/com/android/server/wm/DisplayAreaOrganizerController.java +++ b/services/core/java/com/android/server/wm/DisplayAreaOrganizerController.java @@ -65,7 +65,16 @@ public class DisplayAreaOrganizerController extends IDisplayAreaOrganizerControl @Override public void binderDied() { synchronized (mGlobalLock) { - mOrganizersByFeatureIds.remove(mFeature).destroy(); + IDisplayAreaOrganizer featureOrganizer = getOrganizerByFeature(mFeature); + if (featureOrganizer != null) { + IBinder organizerBinder = featureOrganizer.asBinder(); + if (!organizerBinder.equals(mOrganizer.asBinder()) && + organizerBinder.isBinderAlive()) { + Slog.d(TAG, "Dead organizer replaced for feature=" + mFeature); + return; + } + mOrganizersByFeatureIds.remove(mFeature).destroy(); + } } } } @@ -172,7 +181,7 @@ public class DisplayAreaOrganizerController extends IDisplayAreaOrganizerControl organizer.asBinder(), uid); mOrganizersByFeatureIds.entrySet().removeIf((entry) -> { final boolean matches = entry.getValue().mOrganizer.asBinder() - == organizer.asBinder(); + .equals(organizer.asBinder()); if (matches) { entry.getValue().destroy(); } diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java index ee4c629189dc..152b4bcffc4e 100644 --- a/services/core/java/com/android/server/wm/TaskDisplayArea.java +++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java @@ -42,13 +42,12 @@ import static com.android.server.wm.Task.TASK_VISIBILITY_VISIBLE; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ROOT_TASK; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; -import static java.lang.Integer.MIN_VALUE; - import android.annotation.ColorInt; import android.annotation.Nullable; import android.app.ActivityOptions; import android.app.WindowConfiguration; import android.content.res.Configuration; +import android.graphics.Color; import android.os.UserHandle; import android.util.IntArray; import android.util.Slog; @@ -83,9 +82,9 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> { DisplayContent mDisplayContent; /** - * A color layer that serves as a solid color background to certain animations. + * Keeps track of the last set color layer so that it can be reset during surface migrations. */ - private SurfaceControl mColorBackgroundLayer; + private @ColorInt int mBackgroundColor = 0; /** * This counter is used to make sure we don't prematurely clear the background color in the @@ -367,6 +366,14 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> { } @Override + void setInitialSurfaceControlProperties(SurfaceControl.Builder b) { + // We want an effect layer instead of the default container layer so that we can set a + // background color on it for task animations. + b.setEffectLayer(); + super.setInitialSurfaceControlProperties(b); + } + + @Override void addChild(WindowContainer child, int position) { if (child.asTaskDisplayArea() != null) { if (DEBUG_ROOT_TASK) { @@ -980,11 +987,6 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> { void onParentChanged(ConfigurationContainer newParent, ConfigurationContainer oldParent) { if (getParent() != null) { super.onParentChanged(newParent, oldParent, () -> { - mColorBackgroundLayer = makeChildSurface(null) - .setColorLayer() - .setName("colorBackgroundLayer") - .setCallsite("TaskDisplayArea.onParentChanged") - .build(); mAppAnimationLayer = makeChildSurface(null) .setName("animationLayer") .setCallsite("TaskDisplayArea.onParentChanged") @@ -1011,13 +1013,11 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> { } else { super.onParentChanged(newParent, oldParent); mWmService.mTransactionFactory.get() - .remove(mColorBackgroundLayer) .remove(mAppAnimationLayer) .remove(mBoostedAppAnimationLayer) .remove(mHomeAppAnimationLayer) .remove(mSplitScreenDividerAnchor) .apply(); - mColorBackgroundLayer = null; mAppAnimationLayer = null; mBoostedAppAnimationLayer = null; mHomeAppAnimationLayer = null; @@ -1025,35 +1025,29 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> { } } - void setBackgroundColor(@ColorInt int color) { - if (mColorBackgroundLayer == null) { - return; - } - - float r = ((color >> 16) & 0xff) / 255.0f; - float g = ((color >> 8) & 0xff) / 255.0f; - float b = ((color >> 0) & 0xff) / 255.0f; - float a = ((color >> 24) & 0xff) / 255.0f; - + void setBackgroundColor(@ColorInt int colorInt) { + mBackgroundColor = colorInt; + Color color = Color.valueOf(colorInt); mColorLayerCounter++; - getPendingTransaction().setLayer(mColorBackgroundLayer, MIN_VALUE) - .setColor(mColorBackgroundLayer, new float[]{r, g, b}) - .setAlpha(mColorBackgroundLayer, a) - .setWindowCrop(mColorBackgroundLayer, getSurfaceWidth(), getSurfaceHeight()) - .setPosition(mColorBackgroundLayer, 0, 0) - .show(mColorBackgroundLayer); - - scheduleAnimation(); + // Only apply the background color if the TDA is actually attached and has a valid surface + // to set the background color on. We still want to keep track of the background color state + // even if we are not showing it for when/if the TDA is reattached and gets a valid surface + if (mSurfaceControl != null) { + getPendingTransaction() + .setColor(mSurfaceControl, + new float[]{color.red(), color.green(), color.blue()}); + scheduleAnimation(); + } } void clearBackgroundColor() { mColorLayerCounter--; // Only clear the color layer if we have received the same amounts of clear as set - // requests. - if (mColorLayerCounter == 0) { - getPendingTransaction().hide(mColorBackgroundLayer); + // requests and TDA has a non null surface control (i.e. is attached) + if (mColorLayerCounter == 0 && mSurfaceControl != null) { + getPendingTransaction().unsetColor(mSurfaceControl); scheduleAnimation(); } } @@ -1061,12 +1055,16 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> { @Override void migrateToNewSurfaceControl(SurfaceControl.Transaction t) { super.migrateToNewSurfaceControl(t); + + if (mColorLayerCounter > 0) { + setBackgroundColor(mBackgroundColor); + } + if (mAppAnimationLayer == null) { return; } // As TaskDisplayArea is getting a new surface, reparent and reorder the child surfaces. - t.reparent(mColorBackgroundLayer, mSurfaceControl); t.reparent(mAppAnimationLayer, mSurfaceControl); t.reparent(mBoostedAppAnimationLayer, mSurfaceControl); t.reparent(mHomeAppAnimationLayer, mSurfaceControl); diff --git a/services/core/java/com/android/server/wm/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java index a518222c3bde..71893f49481f 100644 --- a/services/core/java/com/android/server/wm/TaskSnapshotController.java +++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java @@ -288,7 +288,7 @@ class TaskSnapshotController { } final ActivityRecord activity = result.first; final WindowState mainWindow = result.second; - final Rect contentInsets = getSystemBarInsets(task.getBounds(), + final Rect contentInsets = getSystemBarInsets(mainWindow.getFrame(), mainWindow.getInsetsStateWithVisibilityOverride()); InsetUtils.addInsets(contentInsets, activity.getLetterboxInsets()); @@ -554,7 +554,7 @@ class TaskSnapshotController { final LayoutParams attrs = mainWindow.getAttrs(); final Rect taskBounds = task.getBounds(); final InsetsState insetsState = mainWindow.getInsetsStateWithVisibilityOverride(); - final Rect systemBarInsets = getSystemBarInsets(taskBounds, insetsState); + final Rect systemBarInsets = getSystemBarInsets(mainWindow.getFrame(), insetsState); final SystemBarBackgroundPainter decorPainter = new SystemBarBackgroundPainter(attrs.flags, attrs.privateFlags, attrs.insetsFlags.appearance, task.getTaskDescription(), mHighResTaskSnapshotScale, insetsState); diff --git a/services/core/jni/BroadcastRadio/types.h b/services/core/jni/BroadcastRadio/types.h index 910bb7c0a4d1..4d286bf05650 100644 --- a/services/core/jni/BroadcastRadio/types.h +++ b/services/core/jni/BroadcastRadio/types.h @@ -30,13 +30,13 @@ namespace BroadcastRadio { // Keep in sync with STATUS_* constants from RadioManager.java. enum class Status : jint { OK = 0, - ERROR = -0x80000000ll, // Integer.MIN_VALUE + ERROR = -0x80000000LL, // Integer.MIN_VALUE PERMISSION_DENIED = -1, // -EPERM - NO_INIT = -19, // -ENODEV - BAD_VALUE = -22, // -EINVAL - DEAD_OBJECT = -32, // -EPIPE - INVALID_OPERATION = -38, // -ENOSYS - TIMED_OUT = -110, // -ETIMEDOUT + NO_INIT = -19, // -ENODEV + BAD_VALUE = -22, // -EINVAL + DEAD_OBJECT = -32, // -EPIPE + INVALID_OPERATION = -38, // -ENOSYS + TIMED_OUT = -110, // -ETIMEDOUT }; // Keep in sync with REGION_* constants from RadioManager.java. diff --git a/services/core/jni/com_android_server_net_NetworkStatsService.cpp b/services/core/jni/com_android_server_net_NetworkStatsService.cpp index f8a81682bdcf..39cbaf716fc0 100644 --- a/services/core/jni/com_android_server_net_NetworkStatsService.cpp +++ b/services/core/jni/com_android_server_net_NetworkStatsService.cpp @@ -102,15 +102,10 @@ static jlong getUidStat(JNIEnv* env, jclass clazz, jint uid, jint type) { } } -static int deleteTagData(JNIEnv* /* env */, jclass /* clazz */, jint uid) { - return qtaguid_deleteTagData(0, uid); -} - static const JNINativeMethod gMethods[] = { {"nativeGetTotalStat", "(I)J", (void*)getTotalStat}, {"nativeGetIfaceStat", "(Ljava/lang/String;I)J", (void*)getIfaceStat}, {"nativeGetUidStat", "(II)J", (void*)getUidStat}, - {"nativeDeleteTagData", "(I)I", (void*)deleteTagData}, }; int register_android_server_net_NetworkStatsService(JNIEnv* env) { diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index 710a9cf74112..ad97dd19c2e6 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -1334,7 +1334,6 @@ public final class SystemServer implements Dumpable { DynamicSystemService dynamicSystem = null; IStorageManager storageManager = null; NetworkManagementService networkManagement = null; - IpSecService ipSecService = null; VpnManagerService vpnManager = null; VcnManagementService vcnManagement = null; NetworkStatsService networkStats = null; @@ -1806,16 +1805,6 @@ public final class SystemServer implements Dumpable { } t.traceEnd(); - - t.traceBegin("StartIpSecService"); - try { - ipSecService = IpSecService.create(context); - ServiceManager.addService(Context.IPSEC_SERVICE, ipSecService); - } catch (Throwable e) { - reportWtf("starting IpSec Service", e); - } - t.traceEnd(); - t.traceBegin("StartFontManagerService"); mSystemServiceManager.startService(new FontManagerService.Lifecycle(context, safeMode)); t.traceEnd(); @@ -2667,7 +2656,6 @@ public final class SystemServer implements Dumpable { final TelephonyRegistry telephonyRegistryF = telephonyRegistry; final MediaRouterService mediaRouterF = mediaRouter; final MmsServiceBroker mmsServiceF = mmsService; - final IpSecService ipSecServiceF = ipSecService; final VpnManagerService vpnManagerF = vpnManager; final VcnManagementService vcnManagementF = vcnManagement; final WindowManagerService windowManagerF = wm; @@ -2757,15 +2745,6 @@ public final class SystemServer implements Dumpable { .networkScoreAndNetworkManagementServiceReady(); } t.traceEnd(); - t.traceBegin("MakeIpSecServiceReady"); - try { - if (ipSecServiceF != null) { - ipSecServiceF.systemReady(); - } - } catch (Throwable e) { - reportWtf("making IpSec Service ready", e); - } - t.traceEnd(); t.traceBegin("MakeNetworkStatsServiceReady"); try { if (networkStatsF != null) { diff --git a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java index 62a16f7f24fd..c5f990d52b82 100644 --- a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java +++ b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java @@ -60,6 +60,12 @@ public final class ProfcollectForwardingService extends SystemService { private static ProfcollectForwardingService sSelfService; private final Handler mHandler = new ProfcollectdHandler(IoThread.getHandler().getLooper()); + private IProviderStatusCallback mProviderStatusCallback = new IProviderStatusCallback.Stub() { + public void onProviderReady() { + mHandler.sendEmptyMessage(ProfcollectdHandler.MESSAGE_REGISTER_SCHEDULERS); + } + }; + public ProfcollectForwardingService(Context context) { super(context); @@ -93,13 +99,23 @@ public final class ProfcollectForwardingService extends SystemService { } BackgroundThread.get().getThreadHandler().post(() -> { if (serviceHasSupportedTraceProvider()) { - registerObservers(); - ProfcollectBGJobService.schedule(getContext()); + registerProviderStatusCallback(); } }); } } + private void registerProviderStatusCallback() { + if (mIProfcollect == null) { + return; + } + try { + mIProfcollect.registerProviderStatusCallback(mProviderStatusCallback); + } catch (RemoteException e) { + Log.e(LOG_TAG, e.getMessage()); + } + } + private boolean serviceHasSupportedTraceProvider() { if (mIProfcollect == null) { return false; @@ -141,6 +157,7 @@ public final class ProfcollectForwardingService extends SystemService { } public static final int MESSAGE_BINDER_CONNECT = 0; + public static final int MESSAGE_REGISTER_SCHEDULERS = 1; @Override public void handleMessage(android.os.Message message) { @@ -148,6 +165,10 @@ public final class ProfcollectForwardingService extends SystemService { case MESSAGE_BINDER_CONNECT: connectNativeService(); break; + case MESSAGE_REGISTER_SCHEDULERS: + registerObservers(); + ProfcollectBGJobService.schedule(getContext()); + break; default: throw new AssertionError("Unknown message: " + message); } diff --git a/services/proguard.flags b/services/proguard.flags index 5d01d3e7f85c..0e081f182d0d 100644 --- a/services/proguard.flags +++ b/services/proguard.flags @@ -1,21 +1,105 @@ -# TODO(b/196084106): Refine and optimize this configuration. Note that this +# TODO(b/210510433): Refine and optimize this configuration. Note that this # configuration is only used when `SOONG_CONFIG_ANDROID_SYSTEM_OPTIMIZE_JAVA=true`. --keep,allowoptimization,allowaccessmodification class ** { - !synthetic *; + +# Preserve line number information for debugging stack traces. +-keepattributes SourceFile,LineNumberTable + +# Allows making private and protected methods/fields public as part of +# optimization. This enables inlining of trivial getter/setter methods. +-allowaccessmodification + +# Process entrypoint +-keep class com.android.server.SystemServer { + public static void main(java.lang.String[]); } -# Various classes subclassed in ethernet-service (avoid marking final). +# APIs referenced by dependent JAR files and modules +-keep @interface android.annotation.SystemApi +-keep @android.annotation.SystemApi class * { + public protected *; +} +-keepclasseswithmembers class * { + @android.annotation.SystemApi *; +} + +# Derivatives of SystemService and other services created via reflection +-keep,allowoptimization,allowaccessmodification class * extends com.android.server.SystemService { + public <methods>; +} +-keep,allowoptimization,allowaccessmodification class * extends com.android.server.devicepolicy.BaseIDevicePolicyManager { + public <init>(...); +} +-keep,allowoptimization,allowaccessmodification class com.android.server.wallpaper.WallpaperManagerService { + public <init>(...); +} + +# Binder interfaces +-keep,allowoptimization,allowaccessmodification class * extends android.os.IInterface +-keep,allowoptimization,allowaccessmodification class * extends android.os.IHwInterface + +# Global entities normally kept through explicit Manifest entries +# TODO(b/210510433): Revisit and consider generating from frameworks/base/core/res/AndroidManifest.xml, +# by including that manifest with the library rule that triggers optimization. +-keep,allowoptimization,allowaccessmodification class * extends android.app.backup.BackupAgent +-keep,allowoptimization,allowaccessmodification class * extends android.content.BroadcastReceiver +-keep,allowoptimization,allowaccessmodification class * extends android.content.ContentProvider + +# Various classes subclassed in or referenced via JNI in ethernet-service -keep public class android.net.** { *; } +-keep,allowoptimization,allowaccessmodification class com.android.net.module.util.* { *; } +-keep,allowoptimization,allowaccessmodification public class com.android.server.net.IpConfigStore { *; } +-keep,allowoptimization,allowaccessmodification public class com.android.server.net.BaseNetworkObserver { *; } -# Referenced via CarServiceHelperService in car-frameworks-service (avoid removing). +# Referenced via CarServiceHelperService in car-frameworks-service (avoid removing) -keep public class com.android.server.utils.Slogf { *; } -# Allows making private and protected methods/fields public as part of -# optimization. This enables inlining of trivial getter/setter methods. --allowaccessmodification +# Notification extractors +# TODO(b/210510433): Revisit and consider generating from frameworks/base/core/res/res/values/config.xml. +-keep,allowoptimization,allowaccessmodification public class com.android.server.notification.** implements com.android.server.notification.NotificationSignalExtractor -# Disallow accessmodification for soundtrigger classes. Logging via reflective -# public member traversal can cause infinite loops. See b/210901706. --keep,allowoptimization class com.android.server.soundtrigger_middleware.** { - !synthetic *; +# JNI keep rules +# TODO(b/210510433): Revisit and fix with @Keep, or consider auto-generating from +# frameworks/base/services/core/jni/onload.cpp. +-keep,allowoptimization,allowaccessmodification class com.android.server.broadcastradio.hal1.BroadcastRadioService { *; } +-keep,allowoptimization,allowaccessmodification class com.android.server.broadcastradio.hal1.Convert { *; } +-keep,allowoptimization,allowaccessmodification class com.android.server.broadcastradio.hal1.Tuner { *; } +-keep,allowoptimization,allowaccessmodification class com.android.server.broadcastradio.hal1.TunerCallback { *; } +-keep,allowoptimization,allowaccessmodification class com.android.server.location.gnss.GnssConfiguration$HalInterfaceVersion { *; } +-keep,allowoptimization,allowaccessmodification class com.android.server.location.gnss.GnssPowerStats { *; } +-keep,allowoptimization,allowaccessmodification class com.android.server.location.gnss.hal.GnssNative { *; } +-keep,allowoptimization,allowaccessmodification class com.android.server.sensors.SensorManagerInternal$ProximityActiveListener { *; } +-keep,allowoptimization,allowaccessmodification class com.android.server.sensors.SensorService { *; } +-keep,allowoptimization,allowaccessmodification class com.android.server.soundtrigger_middleware.SoundTriggerMiddlewareImpl$AudioSessionProvider$AudioSession { *; } +-keep,allowoptimization,allowaccessmodification class com.android.server.soundtrigger_middleware.ExternalCaptureStateTracker { *; } +-keep,allowoptimization,allowaccessmodification class com.android.server.storage.AppFuseBridge { *; } +-keep,allowoptimization,allowaccessmodification class com.android.server.tv.TvInputHal { *; } +-keep,allowoptimization,allowaccessmodification class com.android.server.usb.UsbAlsaJackDetector { *; } +-keep,allowoptimization,allowaccessmodification class com.android.server.usb.UsbMidiDevice { *; } +-keep,allowoptimization,allowaccessmodification class com.android.server.vibrator.VibratorController$OnVibrationCompleteListener { *; } +-keep,allowoptimization,allowaccessmodification class com.android.server.vibrator.VibratorManagerService$OnSyncedVibrationCompleteListener { *; } +-keepclasseswithmembers,allowoptimization,allowaccessmodification class com.android.server.** { + *** *FromNative(...); } +-keep,allowoptimization,allowaccessmodification class com.android.server.input.InputManagerService { + <methods>; +} +-keep,allowoptimization,allowaccessmodification class com.android.server.usb.UsbHostManager { + *** usbDeviceRemoved(...); + *** usbDeviceAdded(...); +} +-keep,allowoptimization,allowaccessmodification class **.*NativeWrapper* { *; } + +# Miscellaneous reflection keep rules +# TODO(b/210510433): Revisit and fix with @Keep. +-keep,allowoptimization,allowaccessmodification class com.android.server.usage.AppStandbyController { + public <init>(...); +} +-keep,allowoptimization,allowaccessmodification class android.hardware.usb.gadget.** { *; } + +# Needed when optimizations enabled +# TODO(b/210510433): Revisit and fix with @Keep. +-keep,allowoptimization,allowaccessmodification class com.android.server.SystemService { *; } +-keep,allowoptimization,allowaccessmodification class com.android.server.SystemService$TargetUser { *; } +-keep,allowoptimization,allowaccessmodification class com.android.server.usage.StorageStatsManagerLocal { *; } +-keep,allowoptimization,allowaccessmodification class com.android.internal.util.** { *; } +-keep,allowoptimization,allowaccessmodification class android.os.** { *; } diff --git a/services/tests/servicestests/src/com/android/server/BootReceiverTest.java b/services/tests/servicestests/src/com/android/server/BootReceiverTest.java deleted file mode 100644 index 489e2f769a3d..000000000000 --- a/services/tests/servicestests/src/com/android/server/BootReceiverTest.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) 2021 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 com.android.server; - -import android.test.AndroidTestCase; - -/** - * Tests for {@link com.android.server.BootReceiver} - */ -public class BootReceiverTest extends AndroidTestCase { - public void testLogLinePotentiallySensitive() throws Exception { - /* - * Strings to be dropped from the log as potentially sensitive: register dumps, process - * names, hardware info. - */ - final String[] becomeNull = { - "CPU: 4 PID: 120 Comm: kunit_try_catch Tainted: G W 5.8.0-rc6+ #7", - "Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1 04/01/2014", - "[ 0.083207] RSP: 0000:ffffffff8fe07ca8 EFLAGS: 00010046 ORIG_RAX: 0000000000000000", - "[ 0.084709] RAX: 0000000000000000 RBX: ffffffffff240000 RCX: ffffffff815fcf01", - "[ 0.086109] RDX: dffffc0000000000 RSI: 0000000000000001 RDI: ffffffffff240004", - "[ 0.087509] RBP: ffffffff8fe07d60 R08: fffffbfff1fc0f21 R09: fffffbfff1fc0f21", - "[ 0.088911] R10: ffffffff8fe07907 R11: fffffbfff1fc0f20 R12: ffffffff8fe07d38", - "R13: 0000000000000001 R14: 0000000000000001 R15: ffffffff8fe07e80", - "x29: ffff00003ce07150 x28: ffff80001aa29cc0", - "x1 : 0000000000000000 x0 : ffff00000f628000", - }; - - /* Strings to be left unchanged, including non-sensitive registers and parts of reports. */ - final String[] leftAsIs = { - "FS: 0000000000000000(0000) GS:ffffffff92409000(0000) knlGS:0000000000000000", - "[ 69.2366] [ T6006]c7 6006 =======================================================", - "[ 69.245688] [ T6006] BUG: KFENCE: out-of-bounds in kfence_handle_page_fault", - "[ 69.257816] [ T6006]c7 6006 Out-of-bounds access at 0xffffffca75c45000 ", - "[ 69.273536] [ T6006]c7 6006 __do_kernel_fault+0xa8/0x11c", - "pc : __mutex_lock+0x428/0x99c ", - "sp : ffff00003ce07150", - "Call trace:", - "", - }; - - final String[][] stripped = { - { "Detected corrupted memory at 0xffffffffb6797ff9 [ 0xac . . . . . . ]:", - "Detected corrupted memory at 0xffffffffb6797ff9" }, - }; - for (int i = 0; i < becomeNull.length; i++) { - assertEquals(BootReceiver.stripSensitiveData(becomeNull[i]), null); - } - - for (int i = 0; i < leftAsIs.length; i++) { - assertEquals(BootReceiver.stripSensitiveData(leftAsIs[i]), leftAsIs[i]); - } - - for (int i = 0; i < stripped.length; i++) { - assertEquals(BootReceiver.stripSensitiveData(stripped[i][0]), stripped[i][1]); - } - } -} diff --git a/services/tests/servicestests/src/com/android/server/OWNERS b/services/tests/servicestests/src/com/android/server/OWNERS index 6a7d298514c5..68994e6b5a6f 100644 --- a/services/tests/servicestests/src/com/android/server/OWNERS +++ b/services/tests/servicestests/src/com/android/server/OWNERS @@ -1,6 +1,6 @@ per-file *Alarm* = file:/apex/jobscheduler/OWNERS per-file *AppOp* = file:/core/java/android/permission/OWNERS -per-file *Bluetooth* = file:/core/java/android/bluetooth/OWNERS +per-file *Bluetooth* = file:platform/packages/modules/Bluetooth:master:/framework/java/android/bluetooth/OWNERS per-file *Gnss* = file:/services/core/java/com/android/server/location/OWNERS per-file *Network* = file:/services/core/java/com/android/server/net/OWNERS per-file BatteryServiceTest.java = file:platform/hardware/interfaces:/health/aidl/OWNERS diff --git a/services/tests/servicestests/src/com/android/server/pm/ApexManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/ApexManagerTest.java index 2bda120afb9d..f99f65eaad08 100644 --- a/services/tests/servicestests/src/com/android/server/pm/ApexManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/ApexManagerTest.java @@ -489,6 +489,20 @@ public class ApexManagerTest { assertThat(e).hasMessageThat().contains("Failed to collect certificates from "); } + @Test + public void testGetActivePackageNameForApexModuleName() throws Exception { + final String moduleName = "com.android.module_name"; + + ApexInfo[] apexInfo = createApexInfoForTestPkg(true, false); + apexInfo[0].moduleName = moduleName; + when(mApexService.getAllPackages()).thenReturn(apexInfo); + mApexManager.scanApexPackagesTraced(mPackageParser2, + ParallelPackageParser.makeExecutorService()); + + assertThat(mApexManager.getActivePackageNameForApexModuleName(moduleName)) + .isEqualTo(TEST_APEX_PKG); + } + private ApexInfo[] createApexInfoForTestPkg(boolean isActive, boolean isFactory) { File apexFile = extractResource(TEST_APEX_PKG, TEST_APEX_FILE_NAME); ApexInfo apexInfo = new ApexInfo(); diff --git a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java index 32fed3bc3dc1..4519890e72a1 100644 --- a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java @@ -252,7 +252,7 @@ public class TimeDetectorServiceTest { int slotIndex = 1234; TimestampedValue<Long> timeValue = new TimestampedValue<>(100L, 1_000_000L); return new TelephonyTimeSuggestion.Builder(slotIndex) - .setUtcTime(timeValue) + .setUnixEpochTime(timeValue) .build(); } diff --git a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java index 0d5b5a565d5a..2d9903f9cf60 100644 --- a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java +++ b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java @@ -52,12 +52,12 @@ import java.util.Objects; @RunWith(AndroidJUnit4.class) public class TimeDetectorStrategyImplTest { - private static final Instant TIME_LOWER_BOUND = createUtcTime(2009, 1, 1, 12, 0, 0); + private static final Instant TIME_LOWER_BOUND = createUnixEpochTime(2009, 1, 1, 12, 0, 0); private static final TimestampedValue<Instant> ARBITRARY_CLOCK_INITIALIZATION_INFO = new TimestampedValue<>( 123456789L /* realtimeClockMillis */, - createUtcTime(2010, 5, 23, 12, 0, 0)); + createUnixEpochTime(2010, 5, 23, 12, 0, 0)); // This is the traditional ordering for time detection on Android. private static final @Origin int [] PROVIDERS_PRIORITY = { ORIGIN_TELEPHONY, ORIGIN_NETWORK }; @@ -66,7 +66,7 @@ public class TimeDetectorStrategyImplTest { * An arbitrary time, very different from the {@link #ARBITRARY_CLOCK_INITIALIZATION_INFO} * time. Can be used as the basis for time suggestions. */ - private static final Instant ARBITRARY_TEST_TIME = createUtcTime(2018, 1, 1, 12, 0, 0); + private static final Instant ARBITRARY_TEST_TIME = createUnixEpochTime(2018, 1, 1, 12, 0, 0); private static final int ARBITRARY_SLOT_INDEX = 123456; @@ -91,7 +91,7 @@ public class TimeDetectorStrategyImplTest { .simulateTelephonyTimeSuggestion(timeSuggestion); long expectedSystemClockMillis = - mScript.calculateTimeInMillisForNow(timeSuggestion.getUtcTime()); + mScript.calculateTimeInMillisForNow(timeSuggestion.getUnixEpochTime()); mScript.verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis) .assertLatestTelephonySuggestion(slotIndex, timeSuggestion); } @@ -128,7 +128,7 @@ public class TimeDetectorStrategyImplTest { mScript.simulateTimePassing(clockIncrementMillis); long expectedSystemClockMillis1 = - mScript.calculateTimeInMillisForNow(timeSuggestion1.getUtcTime()); + mScript.calculateTimeInMillisForNow(timeSuggestion1.getUnixEpochTime()); mScript.simulateTelephonyTimeSuggestion(timeSuggestion1) .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis1) @@ -155,7 +155,7 @@ public class TimeDetectorStrategyImplTest { mScript.simulateTimePassing(clockIncrementMillis); long expectedSystemClockMillis3 = - mScript.calculateTimeInMillisForNow(timeSuggestion3.getUtcTime()); + mScript.calculateTimeInMillisForNow(timeSuggestion3.getUnixEpochTime()); mScript.simulateTelephonyTimeSuggestion(timeSuggestion3) .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis3) @@ -182,8 +182,8 @@ public class TimeDetectorStrategyImplTest { mScript.generateTelephonyTimeSuggestion(slotIndex2, slotIndex2Time); mScript.simulateTimePassing(); - long expectedSystemClockMillis = - mScript.calculateTimeInMillisForNow(slotIndex2TimeSuggestion.getUtcTime()); + long expectedSystemClockMillis = mScript.calculateTimeInMillisForNow( + slotIndex2TimeSuggestion.getUnixEpochTime()); mScript.simulateTelephonyTimeSuggestion(slotIndex2TimeSuggestion) .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis) @@ -199,8 +199,8 @@ public class TimeDetectorStrategyImplTest { mScript.generateTelephonyTimeSuggestion(slotIndex1, slotIndex1Time); mScript.simulateTimePassing(); - long expectedSystemClockMillis = - mScript.calculateTimeInMillisForNow(slotIndex1TimeSuggestion.getUtcTime()); + long expectedSystemClockMillis = mScript.calculateTimeInMillisForNow( + slotIndex1TimeSuggestion.getUnixEpochTime()); mScript.simulateTelephonyTimeSuggestion(slotIndex1TimeSuggestion) .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis) @@ -232,8 +232,8 @@ public class TimeDetectorStrategyImplTest { mScript.generateTelephonyTimeSuggestion(slotIndex2, slotIndex2Time); mScript.simulateTimePassing(); - long expectedSystemClockMillis = - mScript.calculateTimeInMillisForNow(slotIndex2TimeSuggestion.getUtcTime()); + long expectedSystemClockMillis = mScript.calculateTimeInMillisForNow( + slotIndex2TimeSuggestion.getUnixEpochTime()); mScript.simulateTelephonyTimeSuggestion(slotIndex2TimeSuggestion) .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis) @@ -267,26 +267,27 @@ public class TimeDetectorStrategyImplTest { TelephonyTimeSuggestion timeSuggestion1 = mScript.generateTelephonyTimeSuggestion(slotIndex, testTime); - TimestampedValue<Long> utcTime1 = timeSuggestion1.getUtcTime(); + TimestampedValue<Long> unixEpochTime1 = timeSuggestion1.getUnixEpochTime(); // Initialize the strategy / device with a time set from a telephony suggestion. mScript.simulateTimePassing(); - long expectedSystemClockMillis1 = mScript.calculateTimeInMillisForNow(utcTime1); + long expectedSystemClockMillis1 = mScript.calculateTimeInMillisForNow(unixEpochTime1); mScript.simulateTelephonyTimeSuggestion(timeSuggestion1) .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis1) .assertLatestTelephonySuggestion(slotIndex, timeSuggestion1); - // The UTC time increment should be larger than the system clock update threshold so we - // know it shouldn't be ignored for other reasons. - long validUtcTimeMillis = utcTime1.getValue() + (2 * systemClockUpdateThreshold); + // The Unix epoch time increment should be larger than the system clock update threshold so + // we know it shouldn't be ignored for other reasons. + long validUnixEpochTimeMillis = unixEpochTime1.getValue() + + (2 * systemClockUpdateThreshold); // Now supply a new signal that has an obviously bogus reference time : older than the last // one. - long referenceTimeBeforeLastSignalMillis = utcTime1.getReferenceTimeMillis() - 1; - TimestampedValue<Long> utcTime2 = new TimestampedValue<>( - referenceTimeBeforeLastSignalMillis, validUtcTimeMillis); + long referenceTimeBeforeLastSignalMillis = unixEpochTime1.getReferenceTimeMillis() - 1; + TimestampedValue<Long> unixEpochTime2 = new TimestampedValue<>( + referenceTimeBeforeLastSignalMillis, validUnixEpochTimeMillis); TelephonyTimeSuggestion timeSuggestion2 = - createTelephonyTimeSuggestion(slotIndex, utcTime2); + createTelephonyTimeSuggestion(slotIndex, unixEpochTime2); mScript.simulateTelephonyTimeSuggestion(timeSuggestion2) .verifySystemClockWasNotSetAndResetCallTracking() .assertLatestTelephonySuggestion(slotIndex, timeSuggestion1); @@ -294,22 +295,22 @@ public class TimeDetectorStrategyImplTest { // Now supply a new signal that has an obviously bogus reference time : substantially in the // future. long referenceTimeInFutureMillis = - utcTime1.getReferenceTimeMillis() + Integer.MAX_VALUE + 1; - TimestampedValue<Long> utcTime3 = new TimestampedValue<>( - referenceTimeInFutureMillis, validUtcTimeMillis); + unixEpochTime1.getReferenceTimeMillis() + Integer.MAX_VALUE + 1; + TimestampedValue<Long> unixEpochTime3 = new TimestampedValue<>( + referenceTimeInFutureMillis, validUnixEpochTimeMillis); TelephonyTimeSuggestion timeSuggestion3 = - createTelephonyTimeSuggestion(slotIndex, utcTime3); + createTelephonyTimeSuggestion(slotIndex, unixEpochTime3); mScript.simulateTelephonyTimeSuggestion(timeSuggestion3) .verifySystemClockWasNotSetAndResetCallTracking() .assertLatestTelephonySuggestion(slotIndex, timeSuggestion1); - // Just to prove validUtcTimeMillis is valid. - long validReferenceTimeMillis = utcTime1.getReferenceTimeMillis() + 100; - TimestampedValue<Long> utcTime4 = new TimestampedValue<>( - validReferenceTimeMillis, validUtcTimeMillis); - long expectedSystemClockMillis4 = mScript.calculateTimeInMillisForNow(utcTime4); + // Just to prove validUnixEpochTimeMillis is valid. + long validReferenceTimeMillis = unixEpochTime1.getReferenceTimeMillis() + 100; + TimestampedValue<Long> unixEpochTime4 = new TimestampedValue<>( + validReferenceTimeMillis, validUnixEpochTimeMillis); + long expectedSystemClockMillis4 = mScript.calculateTimeInMillisForNow(unixEpochTime4); TelephonyTimeSuggestion timeSuggestion4 = - createTelephonyTimeSuggestion(slotIndex, utcTime4); + createTelephonyTimeSuggestion(slotIndex, unixEpochTime4); mScript.simulateTelephonyTimeSuggestion(timeSuggestion4) .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis4) .assertLatestTelephonySuggestion(slotIndex, timeSuggestion4); @@ -344,7 +345,7 @@ public class TimeDetectorStrategyImplTest { Instant testTime = ARBITRARY_TEST_TIME; TelephonyTimeSuggestion timeSuggestion1 = mScript.generateTelephonyTimeSuggestion(slotIndex, testTime); - TimestampedValue<Long> utcTime1 = timeSuggestion1.getUtcTime(); + TimestampedValue<Long> unixEpochTime1 = timeSuggestion1.getUnixEpochTime(); // Simulate time passing. mScript.simulateTimePassing(clockIncrementMillis); @@ -358,7 +359,7 @@ public class TimeDetectorStrategyImplTest { // Simulate more time passing. mScript.simulateTimePassing(clockIncrementMillis); - long expectedSystemClockMillis1 = mScript.calculateTimeInMillisForNow(utcTime1); + long expectedSystemClockMillis1 = mScript.calculateTimeInMillisForNow(unixEpochTime1); // Turn on auto time detection. mScript.simulateAutoTimeDetectionToggle() @@ -379,7 +380,7 @@ public class TimeDetectorStrategyImplTest { mScript.simulateTimePassing(clockIncrementMillis); long expectedSystemClockMillis2 = - mScript.calculateTimeInMillisForNow(timeSuggestion2.getUtcTime()); + mScript.calculateTimeInMillisForNow(timeSuggestion2.getUnixEpochTime()); // The new time, though valid, should not be set in the system clock because auto time is // disabled. @@ -406,7 +407,7 @@ public class TimeDetectorStrategyImplTest { mScript.simulateTimePassing(); long expectedSystemClockMillis = - mScript.calculateTimeInMillisForNow(telephonySuggestion.getUtcTime()); + mScript.calculateTimeInMillisForNow(telephonySuggestion.getUnixEpochTime()); mScript.simulateTelephonyTimeSuggestion(telephonySuggestion) .verifySystemClockWasSetAndResetCallTracking( expectedSystemClockMillis /* expectedNetworkBroadcast */) @@ -416,7 +417,7 @@ public class TimeDetectorStrategyImplTest { assertEquals(telephonySuggestion, mScript.peekBestTelephonySuggestion()); // Simulate time passing, long enough that telephonySuggestion is now too old. - mScript.simulateTimePassing(TimeDetectorStrategyImpl.MAX_UTC_TIME_AGE_MILLIS); + mScript.simulateTimePassing(TimeDetectorStrategyImpl.MAX_SUGGESTION_TIME_AGE_MILLIS); // Look inside and check what the strategy considers the current best telephony suggestion. // It should still be the, it's just no longer used. @@ -435,7 +436,7 @@ public class TimeDetectorStrategyImplTest { mScript.simulateTimePassing(); long expectedSystemClockMillis = - mScript.calculateTimeInMillisForNow(timeSuggestion.getUtcTime()); + mScript.calculateTimeInMillisForNow(timeSuggestion.getUnixEpochTime()); mScript.simulateManualTimeSuggestion(timeSuggestion, true /* expectedResult */) .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis); } @@ -457,7 +458,7 @@ public class TimeDetectorStrategyImplTest { mScript.simulateTimePassing(); long expectedAutoClockMillis = - mScript.calculateTimeInMillisForNow(telephonyTimeSuggestion.getUtcTime()); + mScript.calculateTimeInMillisForNow(telephonyTimeSuggestion.getUnixEpochTime()); mScript.simulateTelephonyTimeSuggestion(telephonyTimeSuggestion) .verifySystemClockWasSetAndResetCallTracking(expectedAutoClockMillis) .assertLatestTelephonySuggestion(slotIndex, telephonyTimeSuggestion); @@ -480,7 +481,7 @@ public class TimeDetectorStrategyImplTest { mScript.simulateTimePassing(); long expectedManualClockMillis = - mScript.calculateTimeInMillisForNow(manualTimeSuggestion.getUtcTime()); + mScript.calculateTimeInMillisForNow(manualTimeSuggestion.getUnixEpochTime()); mScript.simulateManualTimeSuggestion(manualTimeSuggestion, true /* expectedResult */) .verifySystemClockWasSetAndResetCallTracking(expectedManualClockMillis) .assertLatestTelephonySuggestion(slotIndex, telephonyTimeSuggestion); @@ -492,7 +493,7 @@ public class TimeDetectorStrategyImplTest { mScript.simulateAutoTimeDetectionToggle(); expectedAutoClockMillis = - mScript.calculateTimeInMillisForNow(telephonyTimeSuggestion.getUtcTime()); + mScript.calculateTimeInMillisForNow(telephonyTimeSuggestion.getUnixEpochTime()); mScript.verifySystemClockWasSetAndResetCallTracking(expectedAutoClockMillis) .assertLatestTelephonySuggestion(slotIndex, telephonyTimeSuggestion); @@ -540,7 +541,7 @@ public class TimeDetectorStrategyImplTest { mScript.simulateTimePassing(); long expectedSystemClockMillis = - mScript.calculateTimeInMillisForNow(timeSuggestion.getUtcTime()); + mScript.calculateTimeInMillisForNow(timeSuggestion.getUnixEpochTime()); mScript.simulateNetworkTimeSuggestion(timeSuggestion) .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis); } @@ -586,7 +587,7 @@ public class TimeDetectorStrategyImplTest { mScript.simulateTimePassing(); long expectedSystemClockMillis = - mScript.calculateTimeInMillisForNow(timeSuggestion.getUtcTime()); + mScript.calculateTimeInMillisForNow(timeSuggestion.getUnixEpochTime()); mScript.simulateGnssTimeSuggestion(timeSuggestion) .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis); } @@ -617,7 +618,7 @@ public class TimeDetectorStrategyImplTest { mScript.simulateTimePassing(); long expectedSystemClockMillis = - mScript.calculateTimeInMillisForNow(timeSuggestion.getUtcTime()); + mScript.calculateTimeInMillisForNow(timeSuggestion.getUnixEpochTime()); mScript.simulateExternalTimeSuggestion(timeSuggestion) .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis); } @@ -671,7 +672,8 @@ public class TimeDetectorStrategyImplTest { mScript.simulateTimePassing(smallTimeIncrementMillis) .simulateNetworkTimeSuggestion(networkTimeSuggestion1) .verifySystemClockWasSetAndResetCallTracking( - mScript.calculateTimeInMillisForNow(networkTimeSuggestion1.getUtcTime())); + mScript.calculateTimeInMillisForNow( + networkTimeSuggestion1.getUnixEpochTime())); // Check internal state. mScript.assertLatestTelephonySuggestion(ARBITRARY_SLOT_INDEX, null) @@ -690,7 +692,8 @@ public class TimeDetectorStrategyImplTest { mScript.simulateTimePassing(smallTimeIncrementMillis) .simulateTelephonyTimeSuggestion(telephonyTimeSuggestion) .verifySystemClockWasSetAndResetCallTracking( - mScript.calculateTimeInMillisForNow(telephonyTimeSuggestion.getUtcTime())); + mScript.calculateTimeInMillisForNow( + telephonyTimeSuggestion.getUnixEpochTime())); // Check internal state. mScript.assertLatestTelephonySuggestion(ARBITRARY_SLOT_INDEX, telephonyTimeSuggestion) @@ -700,7 +703,7 @@ public class TimeDetectorStrategyImplTest { // Simulate some significant time passing: half the time allowed before a time signal // becomes "too old to use". - mScript.simulateTimePassing(TimeDetectorStrategyImpl.MAX_UTC_TIME_AGE_MILLIS / 2) + mScript.simulateTimePassing(TimeDetectorStrategyImpl.MAX_SUGGESTION_TIME_AGE_MILLIS / 2) .verifySystemClockWasNotSetAndResetCallTracking(); // Now another network suggestion is made. Telephony suggestions are prioritized over @@ -720,7 +723,7 @@ public class TimeDetectorStrategyImplTest { // Simulate some significant time passing: half the time allowed before a time signal // becomes "too old to use". This should mean that telephonyTimeSuggestion is now too old to // be used but networkTimeSuggestion2 is not. - mScript.simulateTimePassing(TimeDetectorStrategyImpl.MAX_UTC_TIME_AGE_MILLIS / 2); + mScript.simulateTimePassing(TimeDetectorStrategyImpl.MAX_SUGGESTION_TIME_AGE_MILLIS / 2); // NOTE: The TimeDetectorStrategyImpl doesn't set an alarm for the point when the last // suggestion it used becomes too old: it requires a new suggestion or an auto-time toggle @@ -743,7 +746,7 @@ public class TimeDetectorStrategyImplTest { // Verify the latest network time now wins. mScript.verifySystemClockWasSetAndResetCallTracking( - mScript.calculateTimeInMillisForNow(networkTimeSuggestion2.getUtcTime())); + mScript.calculateTimeInMillisForNow(networkTimeSuggestion2.getUnixEpochTime())); // Check internal state. mScript.assertLatestTelephonySuggestion(ARBITRARY_SLOT_INDEX, telephonyTimeSuggestion) @@ -774,7 +777,8 @@ public class TimeDetectorStrategyImplTest { mScript.simulateTimePassing(smallTimeIncrementMillis) .simulateGnssTimeSuggestion(gnssTimeSuggestion1) .verifySystemClockWasSetAndResetCallTracking( - mScript.calculateTimeInMillisForNow(gnssTimeSuggestion1.getUtcTime())); + mScript.calculateTimeInMillisForNow( + gnssTimeSuggestion1.getUnixEpochTime())); // Check internal state. mScript.assertLatestNetworkSuggestion(null) @@ -793,7 +797,8 @@ public class TimeDetectorStrategyImplTest { mScript.simulateTimePassing(smallTimeIncrementMillis) .simulateNetworkTimeSuggestion(networkTimeSuggestion) .verifySystemClockWasSetAndResetCallTracking( - mScript.calculateTimeInMillisForNow(networkTimeSuggestion.getUtcTime())); + mScript.calculateTimeInMillisForNow( + networkTimeSuggestion.getUnixEpochTime())); // Check internal state. mScript.assertLatestNetworkSuggestion(networkTimeSuggestion) @@ -803,7 +808,7 @@ public class TimeDetectorStrategyImplTest { // Simulate some significant time passing: half the time allowed before a time signal // becomes "too old to use". - mScript.simulateTimePassing(TimeDetectorStrategyImpl.MAX_UTC_TIME_AGE_MILLIS / 2) + mScript.simulateTimePassing(TimeDetectorStrategyImpl.MAX_SUGGESTION_TIME_AGE_MILLIS / 2) .verifySystemClockWasNotSetAndResetCallTracking(); // Now another gnss suggestion is made. Network suggestions are prioritized over @@ -823,7 +828,7 @@ public class TimeDetectorStrategyImplTest { // Simulate some significant time passing: half the time allowed before a time signal // becomes "too old to use". This should mean that telephonyTimeSuggestion is now too old to // be used but networkTimeSuggestion2 is not. - mScript.simulateTimePassing(TimeDetectorStrategyImpl.MAX_UTC_TIME_AGE_MILLIS / 2); + mScript.simulateTimePassing(TimeDetectorStrategyImpl.MAX_SUGGESTION_TIME_AGE_MILLIS / 2); // NOTE: The TimeDetectorStrategyImpl doesn't set an alarm for the point when the last // suggestion it used becomes too old: it requires a new suggestion or an auto-time toggle @@ -846,7 +851,7 @@ public class TimeDetectorStrategyImplTest { // Verify the latest gnss time now wins. mScript.verifySystemClockWasSetAndResetCallTracking( - mScript.calculateTimeInMillisForNow(gnssTimeSuggestion2.getUtcTime())); + mScript.calculateTimeInMillisForNow(gnssTimeSuggestion2.getUnixEpochTime())); // Check internal state. mScript.assertLatestNetworkSuggestion(networkTimeSuggestion) @@ -877,7 +882,8 @@ public class TimeDetectorStrategyImplTest { mScript.simulateTimePassing(smallTimeIncrementMillis) .simulateExternalTimeSuggestion(externalTimeSuggestion1) .verifySystemClockWasSetAndResetCallTracking( - mScript.calculateTimeInMillisForNow(externalTimeSuggestion1.getUtcTime())); + mScript.calculateTimeInMillisForNow( + externalTimeSuggestion1.getUnixEpochTime())); // Check internal state. mScript.assertLatestNetworkSuggestion(null) @@ -896,7 +902,8 @@ public class TimeDetectorStrategyImplTest { mScript.simulateTimePassing(smallTimeIncrementMillis) .simulateNetworkTimeSuggestion(networkTimeSuggestion) .verifySystemClockWasSetAndResetCallTracking( - mScript.calculateTimeInMillisForNow(networkTimeSuggestion.getUtcTime())); + mScript.calculateTimeInMillisForNow( + networkTimeSuggestion.getUnixEpochTime())); // Check internal state. mScript.assertLatestNetworkSuggestion(networkTimeSuggestion) @@ -906,7 +913,7 @@ public class TimeDetectorStrategyImplTest { // Simulate some significant time passing: half the time allowed before a time signal // becomes "too old to use". - mScript.simulateTimePassing(TimeDetectorStrategyImpl.MAX_UTC_TIME_AGE_MILLIS / 2) + mScript.simulateTimePassing(TimeDetectorStrategyImpl.MAX_SUGGESTION_TIME_AGE_MILLIS / 2) .verifySystemClockWasNotSetAndResetCallTracking(); // Now another external suggestion is made. Network suggestions are prioritized over @@ -926,7 +933,7 @@ public class TimeDetectorStrategyImplTest { // Simulate some significant time passing: half the time allowed before a time signal // becomes "too old to use". This should mean that networkTimeSuggestion is now too old to // be used but externalTimeSuggestion2 is not. - mScript.simulateTimePassing(TimeDetectorStrategyImpl.MAX_UTC_TIME_AGE_MILLIS / 2); + mScript.simulateTimePassing(TimeDetectorStrategyImpl.MAX_SUGGESTION_TIME_AGE_MILLIS / 2); // NOTE: The TimeDetectorStrategyImpl doesn't set an alarm for the point when the last // suggestion it used becomes too old: it requires a new suggestion or an auto-time toggle @@ -949,7 +956,7 @@ public class TimeDetectorStrategyImplTest { // Verify the latest external time now wins. mScript.verifySystemClockWasSetAndResetCallTracking( - mScript.calculateTimeInMillisForNow(externalTimeSuggestion2.getUtcTime())); + mScript.calculateTimeInMillisForNow(externalTimeSuggestion2.getUnixEpochTime())); // Check internal state. mScript.assertLatestNetworkSuggestion(networkTimeSuggestion) @@ -1438,11 +1445,11 @@ public class TimeDetectorStrategyImplTest { * reference time. */ ManualTimeSuggestion generateManualTimeSuggestion(Instant suggestedTime) { - TimestampedValue<Long> utcTime = + TimestampedValue<Long> unixEpochTime = new TimestampedValue<>( mFakeEnvironment.peekElapsedRealtimeMillis(), suggestedTime.toEpochMilli()); - return new ManualTimeSuggestion(utcTime); + return new ManualTimeSuggestion(unixEpochTime); } /** @@ -1472,11 +1479,11 @@ public class TimeDetectorStrategyImplTest { * reference time. */ NetworkTimeSuggestion generateNetworkTimeSuggestion(Instant suggestedTime) { - TimestampedValue<Long> utcTime = + TimestampedValue<Long> unixEpochTime = new TimestampedValue<>( mFakeEnvironment.peekElapsedRealtimeMillis(), suggestedTime.toEpochMilli()); - return new NetworkTimeSuggestion(utcTime); + return new NetworkTimeSuggestion(unixEpochTime); } /** @@ -1484,11 +1491,11 @@ public class TimeDetectorStrategyImplTest { * reference time. */ GnssTimeSuggestion generateGnssTimeSuggestion(Instant suggestedTime) { - TimestampedValue<Long> utcTime = + TimestampedValue<Long> unixEpochTime = new TimestampedValue<>( mFakeEnvironment.peekElapsedRealtimeMillis(), suggestedTime.toEpochMilli()); - return new GnssTimeSuggestion(utcTime); + return new GnssTimeSuggestion(unixEpochTime); } /** @@ -1504,19 +1511,19 @@ public class TimeDetectorStrategyImplTest { * Calculates what the supplied time would be when adjusted for the movement of the fake * elapsed realtime clock. */ - long calculateTimeInMillisForNow(TimestampedValue<Long> utcTime) { - return TimeDetectorStrategy.getTimeAt(utcTime, peekElapsedRealtimeMillis()); + long calculateTimeInMillisForNow(TimestampedValue<Long> unixEpochTime) { + return TimeDetectorStrategy.getTimeAt(unixEpochTime, peekElapsedRealtimeMillis()); } } private static TelephonyTimeSuggestion createTelephonyTimeSuggestion(int slotIndex, - TimestampedValue<Long> utcTime) { + TimestampedValue<Long> unixEpochTime) { return new TelephonyTimeSuggestion.Builder(slotIndex) - .setUtcTime(utcTime) + .setUnixEpochTime(unixEpochTime) .build(); } - private static Instant createUtcTime(int year, int monthInYear, int day, int hourOfDay, + private static Instant createUnixEpochTime(int year, int monthInYear, int day, int hourOfDay, int minute, int second) { return LocalDateTime.of(year, monthInYear, day, hourOfDay, minute, second) .toInstant(ZoneOffset.UTC); diff --git a/services/translation/OWNERS b/services/translation/OWNERS index a1e663aa8ff7..440f9a840057 100644 --- a/services/translation/OWNERS +++ b/services/translation/OWNERS @@ -1,8 +1,3 @@ # Bug component: 994311 -adamhe@google.com -augale@google.com -joannechung@google.com -lpeter@google.com -svetoslavganov@google.com -tymtsai@google.com +include /core/java/android/view/translation/OWNERS diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java index 8cb0909def5d..21f789f4e735 100644 --- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java +++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java @@ -492,6 +492,7 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser // current USB state private boolean mHostConnected; + private boolean mUsbAccessoryConnected; private boolean mSourcePower; private boolean mSinkPower; private boolean mConfigured; @@ -961,10 +962,10 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser break; case MSG_UPDATE_HOST_STATE: Iterator devices = (Iterator) msg.obj; - boolean connected = (msg.arg1 == 1); + mUsbAccessoryConnected = (msg.arg1 == 1); if (DEBUG) { - Slog.i(TAG, "HOST_STATE connected:" + connected); + Slog.i(TAG, "HOST_STATE connected:" + mUsbAccessoryConnected); } mHideUsbNotification = false; @@ -1218,7 +1219,7 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser } else if (mSourcePower) { titleRes = com.android.internal.R.string.usb_supplying_notification_title; id = SystemMessage.NOTE_USB_SUPPLYING; - } else if (mHostConnected && mSinkPower && mUsbCharging) { + } else if (mHostConnected && mSinkPower && (mUsbCharging || mUsbAccessoryConnected)) { titleRes = com.android.internal.R.string.usb_charging_notification_title; id = SystemMessage.NOTE_USB_CHARGING; } diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index d7135a57aafd..8d3eee08f087 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -3723,7 +3723,7 @@ public class CarrierConfigManager { /** * SMDP+ server address for downloading opportunistic eSIM profile. * FQDN (Fully Qualified Domain Name) of the SM-DP+ (e.g., smdp.gsma.com) restricted to the - * Alphanumeric mode character set defined in table 5 of ISO/IEC 18004 [15] excluding '$'. + * Alphanumeric mode character set defined in table 5 of ISO/IEC 18004 excluding '$'. */ public static final String KEY_SMDP_SERVER_ADDRESS_STRING = "smdp_server_address_string"; @@ -3767,6 +3767,17 @@ public class CarrierConfigManager { "opportunistic_carrier_ids_int_array"; /** + * Boolean configuration to control auto provisioning eSIM download in + * OpportunisticNetworkService using only WiFi or both WiFi/Data. + * True will download esim only via WiFi. + * False will use both WiFi and Data connection. + * + * @hide + */ + public static final String KEY_OPPORTUNISTIC_ESIM_DOWNLOAD_VIA_WIFI_ONLY_BOOL = + "opportunistic_esim_download_via_wifi_only_bool"; + + /** * Controls RSRP threshold at which OpportunisticNetworkService will decide whether * the opportunistic network is good enough for internet data. */ @@ -3873,101 +3884,242 @@ public class CarrierConfigManager { public static final String KEY_OPPORTUNISTIC_NETWORK_MAX_BACKOFF_TIME_LONG = "opportunistic_network_max_backoff_time_long"; - /** - * Controls SS-RSRP threshold in dBm at which 5G opportunistic network will be considered good - * enough for internet data. - * - * @hide - */ - public static final String KEY_OPPORTUNISTIC_NETWORK_ENTRY_THRESHOLD_SS_RSRP_INT = - "opportunistic_network_entry_threshold_ss_rsrp_int"; + /** @hide */ + public static class OpportunisticNetwork { + /** + * Prefix of all {@code OpportunisticNetwork.KEY_*} constants. + * + * @hide + */ + public static final String PREFIX = "opportunistic."; - /** - * Controls SS-RSRQ threshold in dB at which 5G opportunistic network will be considered good - * enough for internet data. - * - * @hide - */ - public static final String KEY_OPPORTUNISTIC_NETWORK_ENTRY_THRESHOLD_SS_RSRQ_DOUBLE = - "opportunistic_network_entry_threshold_ss_rsrq_double"; + /** + * Controls SS-RSRP threshold in dBm at which 5G opportunistic network will be considered + * good enough for internet data. Note other factors may be considered for the final + * decision. + * + * <p>The value of {@link CellSignalStrengthNr#getSsRsrp} will be compared with this + * threshold. + * + * @hide + */ + public static final String KEY_ENTRY_THRESHOLD_SS_RSRP_INT = + PREFIX + "entry_threshold_ss_rsrp_int"; - /** - * Controls SS-RSRP threshold in dBm below which 5G opportunistic network available will not - * be considered good enough for internet data. - * - * @hide - */ - public static final String KEY_OPPORTUNISTIC_NETWORK_EXIT_THRESHOLD_SS_RSRP_INT = - "opportunistic_network_exit_threshold_ss_rsrp_int"; + /** + * Similar to {@link #KEY_ENTRY_THRESHOLD_SS_RSRP_INT} but supports different + * thresholds for different 5G bands. For bands not specified here, the threshold + * will be {@link #KEY_ENTRY_THRESHOLD_SS_RSRP_INT}. + * + * <p>For each key-value in the bundle: the key is the band number in string, which + * shall be a decimal integer as defined in {@code NgranBands.BAND_*} constants; + * the value is the threshold in int. + * + * @hide + */ + public static final String KEY_ENTRY_THRESHOLD_SS_RSRP_INT_BUNDLE = + PREFIX + "entry_threshold_ss_rsrp_int_bundle"; - /** - * Controls SS-RSRQ threshold in dB below which 5G opportunistic network available will not - * be considered good enough for internet data. - * - * @hide - */ - public static final String KEY_OPPORTUNISTIC_NETWORK_EXIT_THRESHOLD_SS_RSRQ_DOUBLE = - "opportunistic_network_exit_threshold_ss_rsrq_double"; + /** + * Controls SS-RSRQ threshold in dB at which 5G opportunistic network will be considered + * good enough for internet data. Note other factors may be considered for the final + * decision. + * + * <p>The value of {@link CellSignalStrengthNr#getSsRsrq} will be compared with this + * threshold. + * + * @hide + */ + public static final String KEY_ENTRY_THRESHOLD_SS_RSRQ_DOUBLE = + PREFIX + "entry_threshold_ss_rsrq_double"; - /** - * Controls back off time in milliseconds for switching back to - * 5G opportunistic subscription. This time will be added to - * {@link CarrierConfigManager#KEY_OPPORTUNISTIC_NETWORK_5G_DATA_SWITCH_HYSTERESIS_TIME_LONG} to - * determine hysteresis time if there is ping pong situation - * (determined by system app or 1st party app) between primary and 5G opportunistic - * subscription. Ping ping situation is defined in - * #KEY_OPPORTUNISTIC_NETWORK_5G_PING_PONG_TIME_LONG. - * If ping pong situation continuous #KEY_OPPORTUNISTIC_5G_NETWORK_BACKOFF_TIME_LONG - * will be added to previously determined hysteresis time. - * - * @hide - */ - public static final String KEY_OPPORTUNISTIC_NETWORK_5G_BACKOFF_TIME_LONG = - "opportunistic_network_5g_backoff_time_long"; + /** + * Similar to {@link #KEY_ENTRY_THRESHOLD_SS_RSRQ_DOUBLE} but supports different + * thresholds for different 5G bands. For bands not specified here, the threshold + * will be {@link #KEY_ENTRY_THRESHOLD_SS_RSRQ_DOUBLE}. + * + * <p>For each key-value in the bundle: the key is the band number in string, which + * shall be a decimal integer as defined in {@code NgranBands.BAND_*} constants; + * the value is the threshold in double. + * + * @hide + */ + public static final String KEY_ENTRY_THRESHOLD_SS_RSRQ_DOUBLE_BUNDLE = + PREFIX + "entry_threshold_ss_rsrq_double_bundle"; - /** - * Controls the max back off time in milliseconds for switching back to - * 5G opportunistic subscription. - * This time will be the max hysteresis that can be determined irrespective of there is - * continuous ping pong situation or not as described in - * #KEY_OPPORTUNISTIC_NETWORK_5G_PING_PONG_TIME_LONG and - * #KEY_OPPORTUNISTIC_NETWORK_5G_BACKOFF_TIME_LONG. - * - * @hide - */ - public static final String KEY_OPPORTUNISTIC_NETWORK_5G_MAX_BACKOFF_TIME_LONG = - "opportunistic_network_5g_max_backoff_time_long"; + /** + * Controls SS-RSRP threshold in dBm below which 5G opportunistic network available will not + * be considered good enough for internet data. Note other factors may be considered + * for the final decision. + * + * @hide + */ + public static final String KEY_EXIT_THRESHOLD_SS_RSRP_INT = + PREFIX + "exit_threshold_ss_rsrp_int"; - /** - * Controls the ping pong determination of 5G opportunistic network. - * If opportunistic network is determined as out of service or below - * #KEY_OPPORTUNISTIC_NETWORK_EXIT_THRESHOLD_SS_RSRP_INT or - * #KEY_OPPORTUNISTIC_NETWORK_EXIT_THRESHOLD_SS_RSRQ_INT within - * #KEY_OPPORTUNISTIC_NETWORK_5G_PING_PONG_TIME_LONG of switching to opportunistic network, - * it will be determined as ping pong situation by system app or 1st party app. - * - * @hide - */ - public static final String KEY_OPPORTUNISTIC_NETWORK_5G_PING_PONG_TIME_LONG = - "opportunistic_network_5g_ping_pong_time_long"; + /** + * Similar to {@link #KEY_EXIT_THRESHOLD_SS_RSRP_INT} but supports different + * thresholds for different 5G bands. For bands not specified here, the threshold + * will be {@link #KEY_EXIT_THRESHOLD_SS_RSRP_INT}. + * + * <p>The syntax of its value is similar to + * {@link #KEY_ENTRY_THRESHOLD_SS_RSRP_INT_BUNDLE}. + * + * @hide + */ + public static final String KEY_EXIT_THRESHOLD_SS_RSRP_INT_BUNDLE = + PREFIX + "exit_threshold_ss_rsrp_int_bundle"; - /** - * Controls hysteresis time in milliseconds for which will be waited before switching - * data to a 5G opportunistic network. - * - * @hide - */ - public static final String KEY_OPPORTUNISTIC_NETWORK_5G_DATA_SWITCH_HYSTERESIS_TIME_LONG = - "opportunistic_network_5g_data_switch_hysteresis_time_long"; + /** + * Controls SS-RSRQ threshold in dB below which 5G opportunistic network available will not + * be considered good enough for internet data. Note other factors may be considered + * for the final decision. + * + * @hide + */ + public static final String KEY_EXIT_THRESHOLD_SS_RSRQ_DOUBLE = + PREFIX + "exit_threshold_ss_rsrq_double"; + + /** + * Similar to {@link #KEY_EXIT_THRESHOLD_SS_RSRQ_DOUBLE} but supports different + * thresholds for different 5G bands. For bands not specified here, the threshold + * will be {@link #KEY_EXIT_THRESHOLD_SS_RSRQ_DOUBLE}. + * + * <p>The syntax of its value is similar to + * {@link #KEY_ENTRY_THRESHOLD_SS_RSRQ_DOUBLE_BUNDLE}. + * + * @hide + */ + public static final String KEY_EXIT_THRESHOLD_SS_RSRQ_DOUBLE_BUNDLE = + PREFIX + "exit_threshold_ss_rsrq_double_bundle"; + + /** + * Controls hysteresis time in milliseconds for which will be waited before switching + * data to a 5G opportunistic network. + * + * @hide + */ + public static final String KEY_5G_DATA_SWITCH_HYSTERESIS_TIME_LONG = + PREFIX + "5g_data_switch_hysteresis_time_long"; + + /** + * Similar to {@link #KEY_5G_DATA_SWITCH_HYSTERESIS_TIME_LONG} but supports + * different values for different 5G bands. For bands not specified here, the threshold + * will be {@link #KEY_5G_DATA_SWITCH_HYSTERESIS_TIME_LONG}. + * + * <p>For each key-value in the bundle: the key is the band number in string, which + * shall be a decimal integer as defined in {@code NgranBands.BAND_*} constants; + * the value is the time in long. + * + * @hide + */ + public static final String KEY_5G_DATA_SWITCH_HYSTERESIS_TIME_LONG_BUNDLE = + PREFIX + "5g_data_switch_hysteresis_time_long_bundle"; + + /** + * Controls hysteresis time in milliseconds for which will be waited before switching from + * 5G opportunistic network to primary network. + * + * @hide + */ + public static final String KEY_5G_DATA_SWITCH_EXIT_HYSTERESIS_TIME_LONG = + PREFIX + "5g_data_switch_exit_hysteresis_time_long"; + + /** + * Similar to {@link #KEY_5G_DATA_SWITCH_EXIT_HYSTERESIS_TIME_LONG} but supports + * different values for different 5G bands. For bands not specified here, the threshold + * will be {@link #KEY_5G_DATA_SWITCH_EXIT_HYSTERESIS_TIME_LONG}. + * + * <p>The syntax is similar to + * {@link KEY_5G_DATA_SWITCH_HYSTERESIS_TIME_LONG_BUNDLE}. + * + * @hide + */ + public static final String KEY_5G_DATA_SWITCH_EXIT_HYSTERESIS_TIME_LONG_BUNDLE = + PREFIX + "5g_data_switch_exit_hysteresis_time_long_bundle"; + + /** + * Controls back off time in milliseconds for switching back to + * 5G opportunistic subscription. This time will be added to + * {@link #KEY_5G_DATA_SWITCH_HYSTERESIS_TIME_LONG} to + * determine hysteresis time if there is ping pong situation + * (determined by system app or 1st party app) between primary and 5G opportunistic + * subscription. Ping ping situation is defined in + * {@link #KEY_5G_PING_PONG_TIME_LONG}. + * If ping pong situation continuous {@link #KEY_5G_NETWORK_BACKOFF_TIME_LONG} + * will be added to previously determined hysteresis time. + * + * @hide + */ + public static final String KEY_5G_BACKOFF_TIME_LONG = + PREFIX + "5g_backoff_time_long"; + + /** + * Controls the max back off time in milliseconds for switching back to + * 5G opportunistic subscription. + * This time will be the max hysteresis that can be determined irrespective of there is + * continuous ping pong situation or not as described in + * {@link #KEY_5G_PING_PONG_TIME_LONG} and + * {@link #KEY_5G_BACKOFF_TIME_LONG}. + * + * @hide + */ + public static final String KEY_5G_MAX_BACKOFF_TIME_LONG = + PREFIX + "5g_max_backoff_time_long"; + + /** + * Controls the ping pong determination of 5G opportunistic network. + * If opportunistic network is determined as out of service or below + * {@link #KEY_EXIT_THRESHOLD_SS_RSRP_INT} or + * {@link #KEY_EXIT_THRESHOLD_SS_RSRQ_DOUBLE} within + * {@link #KEY_5G_PING_PONG_TIME_LONG} of switching to opportunistic network, + * it will be determined as ping pong situation by system app or 1st party app. + * + * @hide + */ + public static final String KEY_5G_PING_PONG_TIME_LONG = + PREFIX + "5g_ping_pong_time_long"; + + private static PersistableBundle getDefaults() { + PersistableBundle defaults = new PersistableBundle(); + // Default value is -111 dBm for all bands. + sDefaults.putInt(KEY_ENTRY_THRESHOLD_SS_RSRP_INT, -111); + sDefaults.putPersistableBundle(KEY_ENTRY_THRESHOLD_SS_RSRP_INT_BUNDLE, + PersistableBundle.EMPTY); + // Default value is -18.5 dB for all bands. + sDefaults.putDouble(KEY_ENTRY_THRESHOLD_SS_RSRQ_DOUBLE, -18.5); + sDefaults.putPersistableBundle( + KEY_ENTRY_THRESHOLD_SS_RSRQ_DOUBLE_BUNDLE, + PersistableBundle.EMPTY); + // Default value is -120 dBm for all bands. + sDefaults.putInt(KEY_EXIT_THRESHOLD_SS_RSRP_INT, -120); + sDefaults.putPersistableBundle(KEY_EXIT_THRESHOLD_SS_RSRP_INT_BUNDLE, + PersistableBundle.EMPTY); + // Default value is -18.5 dB for all bands. + sDefaults.putDouble(KEY_EXIT_THRESHOLD_SS_RSRQ_DOUBLE, -18.5); + sDefaults.putPersistableBundle( + KEY_EXIT_THRESHOLD_SS_RSRQ_DOUBLE_BUNDLE, + PersistableBundle.EMPTY); + // Default value is 2 seconds for all bands. + defaults.putLong(KEY_5G_DATA_SWITCH_HYSTERESIS_TIME_LONG, 2000); + defaults.putPersistableBundle( + KEY_5G_DATA_SWITCH_HYSTERESIS_TIME_LONG_BUNDLE, + PersistableBundle.EMPTY); + // Default value is 2 seconds for all bands. + defaults.putLong(KEY_5G_DATA_SWITCH_EXIT_HYSTERESIS_TIME_LONG, 2000); + defaults.putPersistableBundle( + KEY_5G_DATA_SWITCH_EXIT_HYSTERESIS_TIME_LONG_BUNDLE, + PersistableBundle.EMPTY); + // Default value is 10 seconds. + sDefaults.putLong(KEY_5G_BACKOFF_TIME_LONG, 10000); + // Default value is 60 seconds. + sDefaults.putLong(KEY_5G_MAX_BACKOFF_TIME_LONG, 60000); + // Default value is 60 seconds. + sDefaults.putLong(KEY_5G_PING_PONG_TIME_LONG, 60000); + return defaults; + } + } - /** - * Controls hysteresis time in milliseconds for which will be waited before switching from - * 5G opportunistic network to primary network. - * - * @hide - */ - public static final String KEY_OPPORTUNISTIC_NETWORK_5G_DATA_SWITCH_EXIT_HYSTERESIS_TIME_LONG = - "opportunistic_network_5g_data_switch_exit_hysteresis_time_long"; /** * Controls whether 4G opportunistic networks should be scanned for possible data switch. * @@ -4608,6 +4760,15 @@ public class CarrierConfigManager { KEY_PREFIX + "enable_presence_group_subscribe_bool"; /** + * Flag indicating whether or not to use SIP URI when send a presence subscribe. + * When {@code true}, the device sets the To and Contact header to be SIP URI using + * the TelephonyManager#getIsimDomain" API. + * If {@code false}, the device uses a TEL URI. + */ + public static final String KEY_USE_SIP_URI_FOR_PRESENCE_SUBSCRIBE_BOOL = + KEY_PREFIX + "use_sip_uri_for_presence_subscribe_bool"; + + /** * An integer key associated with the period of time in seconds the non-rcs capability * information of each contact is cached on the device. * <p> @@ -4660,7 +4821,7 @@ public class CarrierConfigManager { * <li>{@link #KEY_CAPABILITY_TYPE_VIDEO_INT_ARRAY}</li> * <li>{@link #KEY_CAPABILITY_TYPE_UT_INT_ARRAY}</li> * <li>{@link #KEY_CAPABILITY_TYPE_SMS_INT_ARRAY}</li> - * <li>{@link #KEY_CAPABILITY_CALL_COMPOSER_INT_ARRAY}</li> + * <li>{@link #KEY_CAPABILITY_TYPE_CALL_COMPOSER_INT_ARRAY}</li> * </ul> * <p> The values are defined in * {@link android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationTech} @@ -4669,39 +4830,68 @@ public class CarrierConfigManager { KEY_PREFIX + "mmtel_requires_provisioning_bundle"; /** - * This MmTelFeature supports Voice calling (IR.92) + * List of different RAT technologies on which Provisioning for Voice calling (IR.92) + * is supported. * @see MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_VOICE + * <p>Possible values are, + * {@link android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_LTE} + * {@link android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_IWLAN} + * {@link android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_CROSS_SIM} + * {@link android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_NR} */ public static final String KEY_CAPABILITY_TYPE_VOICE_INT_ARRAY = - KEY_PREFIX + "key_capability_type_voice_int_array"; + KEY_PREFIX + "capability_type_voice_int_array"; /** - * This MmTelFeature supports Video (IR.94) + * List of different RAT technologies on which Provisioning for Video Telephony (IR.94) + * is supported. * @see MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_VIDEO + * <p>Possible values are, + * {@link android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_LTE} + * {@link android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_IWLAN} + * {@link android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_CROSS_SIM} + * {@link android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_NR} */ public static final String KEY_CAPABILITY_TYPE_VIDEO_INT_ARRAY = - KEY_PREFIX + "key_capability_type_video_int_array"; + KEY_PREFIX + "capability_type_video_int_array"; /** - * This MmTelFeature supports XCAP over Ut for supplementary services. (IR.92) + * List of different RAT technologies on which Provisioning for XCAP over Ut for + * supplementary services. (IR.92) is supported. * @see MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_UT + * <p>Possible values are, + * {@link android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_LTE} + * {@link android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_IWLAN} + * {@link android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_CROSS_SIM} + * {@link android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_NR} */ public static final String KEY_CAPABILITY_TYPE_UT_INT_ARRAY = - KEY_PREFIX + "key_capability_type_ut_int_array"; + KEY_PREFIX + "capability_type_ut_int_array"; /** - * This MmTelFeature supports SMS (IR.92) + * List of different RAT technologies on which Provisioning for SMS (IR.92) is supported. * @see MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_SMS + * <p>Possible values are, + * {@link android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_LTE} + * {@link android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_IWLAN} + * {@link android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_CROSS_SIM} + * {@link android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_NR} */ public static final String KEY_CAPABILITY_TYPE_SMS_INT_ARRAY = - KEY_PREFIX + "key_capability_type_sms_int_array"; + KEY_PREFIX + "capability_type_sms_int_array"; /** - * This MmTelFeature supports Call Composer (section 2.4 of RCC.20) + * List of different RAT technologies on which Provisioning for Call Composer + * (section 2.4 of RCC.20) is supported. * @see MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_CALL_COMPOSER + * <p>Possible values are, + * {@link android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_LTE} + * {@link android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_IWLAN} + * {@link android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_CROSS_SIM} + * {@link android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_NR} */ - public static final String KEY_CAPABILITY_CALL_COMPOSER_INT_ARRAY = - KEY_PREFIX + "key_capability_type_call_composer_int_array"; + public static final String KEY_CAPABILITY_TYPE_CALL_COMPOSER_INT_ARRAY = + KEY_PREFIX + "capability_type_call_composer_int_array"; /** * A bundle which specifies the RCS capability and registration technology @@ -4724,9 +4914,14 @@ public class CarrierConfigManager { * framework. If set, the RcsFeature should support capability exchange using SIP OPTIONS. * If not set, this RcsFeature should not service capability requests. * @see RcsFeature.RcsImsCapabilities#CAPABILITY_TYPE_OPTIONS_UCE + * <p>Possible values are, + * {@link android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_LTE} + * {@link android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_IWLAN} + * {@link android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_CROSS_SIM} + * {@link android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_NR} */ public static final String KEY_CAPABILITY_TYPE_OPTIONS_UCE_INT_ARRAY = - KEY_PREFIX + "key_capability_type_options_uce_int_array"; + KEY_PREFIX + "capability_type_options_uce_int_array"; /** * This carrier supports User Capability Exchange using a presence server as defined by the @@ -4734,9 +4929,14 @@ public class CarrierConfigManager { * server. If not set, this RcsFeature should not publish capabilities or service capability * requests using presence. * @see RcsFeature.RcsImsCapabilities#CAPABILITY_TYPE_PRESENCE_UCE + * <p>Possible values are, + * {@link android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_LTE} + * {@link android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_IWLAN} + * {@link android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_CROSS_SIM} + * {@link android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationImplBase.ImsRegistrationTech#REGISTRATION_TECH_NR} */ public static final String KEY_CAPABILITY_TYPE_PRESENCE_UCE_INT_ARRAY = - KEY_PREFIX + "key_capability_type_presence_uce_int_array"; + KEY_PREFIX + "capability_type_presence_uce_int_array"; private Ims() {} @@ -4750,6 +4950,7 @@ public class CarrierConfigManager { defaults.putBoolean(KEY_ENABLE_PRESENCE_CAPABILITY_EXCHANGE_BOOL, false); defaults.putBoolean(KEY_RCS_BULK_CAPABILITY_EXCHANGE_BOOL, false); defaults.putBoolean(KEY_ENABLE_PRESENCE_GROUP_SUBSCRIBE_BOOL, false); + defaults.putBoolean(KEY_USE_SIP_URI_FOR_PRESENCE_SUBSCRIBE_BOOL, false); defaults.putInt(KEY_NON_RCS_CAPABILITIES_CACHE_EXPIRATION_SEC_INT, 30 * 24 * 60 * 60); defaults.putBoolean(KEY_RCS_REQUEST_FORBIDDEN_BY_SIP_489_BOOL, false); defaults.putLong(KEY_RCS_REQUEST_RETRY_INTERVAL_MILLIS_LONG, 20 * 60 * 1000); @@ -4777,16 +4978,13 @@ public class CarrierConfigManager { /** * @see #KEY_MMTEL_REQUIRES_PROVISIONING_BUNDLE */ - PersistableBundle mmtel_requires_provisioning_int_array = new PersistableBundle(); defaults.putPersistableBundle( - KEY_MMTEL_REQUIRES_PROVISIONING_BUNDLE, mmtel_requires_provisioning_int_array); - + KEY_MMTEL_REQUIRES_PROVISIONING_BUNDLE, new PersistableBundle()); /** * @see #KEY_RCS_REQUIRES_PROVISIONING_BUNDLE */ - PersistableBundle rcs_requires_provisioning_int_array = new PersistableBundle(); defaults.putPersistableBundle( - KEY_RCS_REQUIRES_PROVISIONING_BUNDLE, rcs_requires_provisioning_int_array); + KEY_RCS_REQUIRES_PROVISIONING_BUNDLE, new PersistableBundle()); return defaults; } @@ -5931,6 +6129,7 @@ public class CarrierConfigManager { sDefaults.putInt(KEY_ESIM_MAX_DOWNLOAD_RETRY_ATTEMPTS_INT, 5); sDefaults.putInt(KEY_ESIM_DOWNLOAD_RETRY_BACKOFF_TIMER_SEC_INT, 60); sDefaults.putIntArray(KEY_OPPORTUNISTIC_CARRIER_IDS_INT_ARRAY, new int[] {0}); + sDefaults.putBoolean(KEY_OPPORTUNISTIC_ESIM_DOWNLOAD_VIA_WIFI_ONLY_BOOL, false); /* Default value is minimum RSRP level needed for SIGNAL_STRENGTH_GOOD */ sDefaults.putInt(KEY_OPPORTUNISTIC_NETWORK_ENTRY_THRESHOLD_RSRP_INT, -108); /* Default value is minimum RSRP level needed for SIGNAL_STRENGTH_MODERATE */ @@ -5947,6 +6146,7 @@ public class CarrierConfigManager { sDefaults.putLong(KEY_OPPORTUNISTIC_NETWORK_DATA_SWITCH_HYSTERESIS_TIME_LONG, 10000); /* Default value is 3 seconds. */ sDefaults.putLong(KEY_OPPORTUNISTIC_NETWORK_DATA_SWITCH_EXIT_HYSTERESIS_TIME_LONG, 3000); + sDefaults.putAll(OpportunisticNetwork.getDefaults()); sDefaults.putBoolean(KEY_PING_TEST_BEFORE_DATA_SWITCH_BOOL, true); sDefaults.putBoolean(KEY_SWITCH_DATA_TO_PRIMARY_IF_PRIMARY_IS_OOS_BOOL, true); /* Default value is 60 seconds. */ @@ -5955,24 +6155,6 @@ public class CarrierConfigManager { sDefaults.putLong(KEY_OPPORTUNISTIC_NETWORK_BACKOFF_TIME_LONG, 10000); /* Default value is 60 seconds. */ sDefaults.putLong(KEY_OPPORTUNISTIC_NETWORK_MAX_BACKOFF_TIME_LONG, 60000); - /* Default value is -111 dBm. */ - sDefaults.putInt(KEY_OPPORTUNISTIC_NETWORK_ENTRY_THRESHOLD_SS_RSRP_INT, -111); - /* Default value is -18.5 dB. */ - sDefaults.putDouble(KEY_OPPORTUNISTIC_NETWORK_ENTRY_THRESHOLD_SS_RSRQ_DOUBLE, -18.5); - /* Default value is -120 dBm. */ - sDefaults.putInt(KEY_OPPORTUNISTIC_NETWORK_EXIT_THRESHOLD_SS_RSRP_INT, -120); - /* Default value is -18.5 dB. */ - sDefaults.putDouble(KEY_OPPORTUNISTIC_NETWORK_EXIT_THRESHOLD_SS_RSRQ_DOUBLE, -18.5); - /* Default value is 10 seconds. */ - sDefaults.putLong(KEY_OPPORTUNISTIC_NETWORK_5G_BACKOFF_TIME_LONG, 10000); - /* Default value is 60 seconds. */ - sDefaults.putLong(KEY_OPPORTUNISTIC_NETWORK_5G_MAX_BACKOFF_TIME_LONG, 60000); - /* Default value is 60 seconds. */ - sDefaults.putLong(KEY_OPPORTUNISTIC_NETWORK_5G_PING_PONG_TIME_LONG, 60000); - /* Default value is 2 seconds. */ - sDefaults.putLong(KEY_OPPORTUNISTIC_NETWORK_5G_DATA_SWITCH_HYSTERESIS_TIME_LONG, 2000); - /* Default value is 2 seconds. */ - sDefaults.putLong(KEY_OPPORTUNISTIC_NETWORK_5G_DATA_SWITCH_EXIT_HYSTERESIS_TIME_LONG, 2000); sDefaults.putBoolean(KEY_ENABLE_4G_OPPORTUNISTIC_NETWORK_SCAN_BOOL, true); sDefaults.putLong(KEY_TIME_TO_SWITCH_BACK_TO_PRIMARY_IF_OPPORTUNISTIC_OOS_LONG, 60000L); sDefaults.putLong( diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java index 846e6f3c5800..9fd2ae46b0bc 100644 --- a/telephony/java/android/telephony/ServiceState.java +++ b/telephony/java/android/telephony/ServiceState.java @@ -19,6 +19,7 @@ package android.telephony; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.TestApi; import android.compat.annotation.UnsupportedAppUsage; @@ -767,6 +768,10 @@ public class ServiceState implements Parcelable { * * @return long name of operator, null if unregistered or unknown */ + @RequiresPermission(anyOf = { + android.Manifest.permission.ACCESS_FINE_LOCATION, + android.Manifest.permission.ACCESS_COARSE_LOCATION + }) public String getOperatorAlphaLong() { return mOperatorAlphaLong; } @@ -782,6 +787,10 @@ public class ServiceState implements Parcelable { * @return long name of operator * @hide */ + @RequiresPermission(anyOf = { + android.Manifest.permission.ACCESS_FINE_LOCATION, + android.Manifest.permission.ACCESS_COARSE_LOCATION + }) @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "Use {@link #getOperatorAlphaLong} instead.") public String getVoiceOperatorAlphaLong() { @@ -800,6 +809,10 @@ public class ServiceState implements Parcelable { * * @return short name of operator, null if unregistered or unknown */ + @RequiresPermission(anyOf = { + android.Manifest.permission.ACCESS_FINE_LOCATION, + android.Manifest.permission.ACCESS_COARSE_LOCATION + }) public String getOperatorAlphaShort() { return mOperatorAlphaShort; } @@ -815,6 +828,10 @@ public class ServiceState implements Parcelable { * @return short name of operator, null if unregistered or unknown * @hide */ + @RequiresPermission(anyOf = { + android.Manifest.permission.ACCESS_FINE_LOCATION, + android.Manifest.permission.ACCESS_COARSE_LOCATION + }) @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "Use {@link #getOperatorAlphaShort} instead.") public String getVoiceOperatorAlphaShort() { @@ -832,6 +849,10 @@ public class ServiceState implements Parcelable { * @return short name of operator, null if unregistered or unknown * @hide */ + @RequiresPermission(anyOf = { + android.Manifest.permission.ACCESS_FINE_LOCATION, + android.Manifest.permission.ACCESS_COARSE_LOCATION + }) @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "Use {@link #getOperatorAlphaShort} instead.") public String getDataOperatorAlphaShort() { @@ -853,6 +874,10 @@ public class ServiceState implements Parcelable { * @return name of operator, null if unregistered or unknown * @hide */ + @RequiresPermission(anyOf = { + android.Manifest.permission.ACCESS_FINE_LOCATION, + android.Manifest.permission.ACCESS_COARSE_LOCATION + }) public String getOperatorAlpha() { if (TextUtils.isEmpty(mOperatorAlphaLong)) { return mOperatorAlphaShort; @@ -878,6 +903,10 @@ public class ServiceState implements Parcelable { * The country code can be decoded using * {@link com.android.internal.telephony.MccTable#countryCodeForMcc(int)}. */ + @RequiresPermission(anyOf = { + android.Manifest.permission.ACCESS_FINE_LOCATION, + android.Manifest.permission.ACCESS_COARSE_LOCATION + }) public String getOperatorNumeric() { return mOperatorNumeric; } @@ -893,6 +922,10 @@ public class ServiceState implements Parcelable { * @return numeric format of operator, null if unregistered or unknown * @hide */ + @RequiresPermission(anyOf = { + android.Manifest.permission.ACCESS_FINE_LOCATION, + android.Manifest.permission.ACCESS_COARSE_LOCATION + }) @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) public String getVoiceOperatorNumeric() { return mOperatorNumeric; @@ -909,6 +942,10 @@ public class ServiceState implements Parcelable { * @return numeric format of operator, null if unregistered or unknown * @hide */ + @RequiresPermission(anyOf = { + android.Manifest.permission.ACCESS_FINE_LOCATION, + android.Manifest.permission.ACCESS_COARSE_LOCATION + }) @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "Use {@link #getOperatorNumeric} instead.") public String getDataOperatorNumeric() { @@ -1758,8 +1795,17 @@ public class ServiceState implements Parcelable { /** * Get the CDMA NID (Network Identification Number), a number uniquely identifying a network * within a wireless system. (Defined in 3GPP2 C.S0023 3.4.8) + * + * <p>Require at least {@link android.Manifest.permission#ACCESS_FINE_LOCATION} or + * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}. Otherwise return + * {@link #UNKNOWN_ID}. + * * @return The CDMA NID or {@link #UNKNOWN_ID} if not available. */ + @RequiresPermission(anyOf = { + android.Manifest.permission.ACCESS_FINE_LOCATION, + android.Manifest.permission.ACCESS_COARSE_LOCATION + }) public int getCdmaNetworkId() { return this.mNetworkId; } @@ -1767,8 +1813,17 @@ public class ServiceState implements Parcelable { /** * Get the CDMA SID (System Identification Number), a number uniquely identifying a wireless * system. (Defined in 3GPP2 C.S0023 3.4.8) + * + * <p>Require at least {@link android.Manifest.permission#ACCESS_FINE_LOCATION} or + * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}. Otherwise return + * {@link #UNKNOWN_ID}. + * * @return The CDMA SID or {@link #UNKNOWN_ID} if not available. */ + @RequiresPermission(anyOf = { + android.Manifest.permission.ACCESS_FINE_LOCATION, + android.Manifest.permission.ACCESS_COARSE_LOCATION + }) public int getCdmaSystemId() { return this.mSystemId; } @@ -2069,6 +2124,8 @@ public class ServiceState implements Parcelable { state.mOperatorAlphaLong = null; state.mOperatorAlphaShort = null; state.mOperatorNumeric = null; + state.mSystemId = UNKNOWN_ID; + state.mNetworkId = UNKNOWN_ID; return state; } diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 4934f11f4097..c26cb6842ade 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -48,6 +48,7 @@ import android.compat.annotation.EnabledAfter; import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; +import android.content.ContextParams; import android.content.Intent; import android.database.Cursor; import android.net.ConnectivityManager; @@ -140,6 +141,7 @@ import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Objects; +import java.util.Set; import java.util.UUID; import java.util.concurrent.Executor; import java.util.concurrent.RejectedExecutionException; @@ -377,16 +379,8 @@ public class TelephonyManager { @UnsupportedAppUsage public TelephonyManager(Context context, int subId) { mSubId = subId; - Context appContext = context.getApplicationContext(); - if (appContext != null) { - if (Objects.equals(context.getAttributionTag(), appContext.getAttributionTag())) { - mContext = appContext; - } else { - mContext = appContext.createAttributionContext(context.getAttributionTag()); - } - } else { - mContext = context; - } + mContext = mergeAttributionAndRenouncedPermissions(context.getApplicationContext(), + context); mSubscriptionManager = SubscriptionManager.from(mContext); } @@ -407,6 +401,34 @@ public class TelephonyManager { return sInstance; } + // This method takes the Application context and adds the attributionTag + // and renouncedPermissions from the given context. + private Context mergeAttributionAndRenouncedPermissions(Context to, Context from) { + Context contextToReturn = from; + if (to != null) { + if (!Objects.equals(from.getAttributionTag(), to.getAttributionTag())) { + contextToReturn = to.createAttributionContext(from.getAttributionTag()); + } else { + contextToReturn = to; + } + + Set<String> renouncedPermissions = + from.getAttributionSource().getRenouncedPermissions(); + if (!renouncedPermissions.isEmpty()) { + if (to.getParams() != null) { + contextToReturn = contextToReturn.createContext( + new ContextParams.Builder(to.getParams()) + .setRenouncedPermissions(renouncedPermissions).build()); + } else { + contextToReturn = contextToReturn.createContext( + new ContextParams.Builder() + .setRenouncedPermissions(renouncedPermissions).build()); + } + } + } + return contextToReturn; + } + private String getOpPackageName() { // For legacy reasons the TelephonyManager has API for getting // a static instance with no context set preventing us from @@ -437,6 +459,16 @@ public class TelephonyManager { return null; } + private Set<String> getRenouncedPermissions() { + // For legacy reasons the TelephonyManager has API for getting + // a static instance with no context set preventing us from + // getting the attribution source. + if (mContext != null) { + return mContext.getAttributionSource().getRenouncedPermissions(); + } + return Collections.emptySet(); + } + /** * Post a runnable to the BackgroundThread. * @@ -6138,8 +6170,14 @@ public class TelephonyManager { (TelephonyRegistryManager) mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE); if (telephonyRegistry != null) { - telephonyRegistry.listenFromListener(mSubId, getOpPackageName(), - getAttributionTag(), listener, events, notifyNow); + Set<String> renouncedPermissions = getRenouncedPermissions(); + boolean renounceFineLocationAccess = renouncedPermissions + .contains(Manifest.permission.ACCESS_FINE_LOCATION); + boolean renounceCoarseLocationAccess = renouncedPermissions + .contains(Manifest.permission.ACCESS_COARSE_LOCATION); + telephonyRegistry.listenFromListener(mSubId, renounceFineLocationAccess, + renounceCoarseLocationAccess, getOpPackageName(), getAttributionTag(), + listener, events, notifyNow); } else { Rlog.w(TAG, "telephony registry not ready."); } @@ -11602,7 +11640,10 @@ public class TelephonyManager { Manifest.permission.ACCESS_COARSE_LOCATION }) public @Nullable ServiceState getServiceState() { - return getServiceState(false, false); + return getServiceState(getRenouncedPermissions() + .contains(Manifest.permission.ACCESS_FINE_LOCATION), + getRenouncedPermissions() + .contains(Manifest.permission.ACCESS_COARSE_LOCATION)); } /** @@ -11614,6 +11655,11 @@ public class TelephonyManager { * If you want continuous updates of service state info, register a {@link PhoneStateListener} * via {@link #listen} with the {@link PhoneStateListener#LISTEN_SERVICE_STATE} event. * + * There's another way to renounce permissions with a custom context + * {@link AttributionSource.Builder#setRenouncedPermissions(Set<String>)} but only for system + * apps. To avoid confusion, calling this method supersede renouncing permissions with a + * custom context. + * * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} * or that the calling app has carrier privileges (see {@link #hasCarrierPrivileges}) * and {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}. @@ -11657,8 +11703,7 @@ public class TelephonyManager { ITelephony service = getITelephony(); if (service != null) { return service.getServiceStateForSubscriber(subId, renounceFineLocationAccess, - renounceCoarseLocationAccess, - getOpPackageName(), getAttributionTag()); + renounceCoarseLocationAccess, getOpPackageName(), getAttributionTag()); } } catch (RemoteException e) { Log.e(TAG, "Error calling ITelephony#getServiceStateForSubscriber", e); @@ -12111,12 +12156,15 @@ public class TelephonyManager { if (carriers == null || !SubscriptionManager.isValidPhoneId(slotIndex)) { return -1; } - // Execute the method setCarrierRestrictionRules with an empty excluded list and - // indicating priority for the allowed list. + // Execute the method setCarrierRestrictionRules with an empty excluded list. + // If the allowed list is empty, it means that all carriers are allowed (default allowed), + // otherwise it means that only specified carriers are allowed (default not allowed). CarrierRestrictionRules carrierRestrictionRules = CarrierRestrictionRules.newBuilder() .setAllowedCarriers(carriers) .setDefaultCarrierRestriction( - CarrierRestrictionRules.CARRIER_RESTRICTION_DEFAULT_NOT_ALLOWED) + carriers.isEmpty() + ? CarrierRestrictionRules.CARRIER_RESTRICTION_DEFAULT_ALLOWED + : CarrierRestrictionRules.CARRIER_RESTRICTION_DEFAULT_NOT_ALLOWED) .build(); int result = setCarrierRestrictionRules(carrierRestrictionRules); @@ -15491,7 +15539,10 @@ public class TelephonyManager { */ public void registerTelephonyCallback(@NonNull @CallbackExecutor Executor executor, @NonNull TelephonyCallback callback) { - registerTelephonyCallback(false, false, executor, callback); + registerTelephonyCallback( + getRenouncedPermissions().contains(Manifest.permission.ACCESS_FINE_LOCATION), + getRenouncedPermissions().contains(Manifest.permission.ACCESS_COARSE_LOCATION), + executor, callback); } /** @@ -15521,6 +15572,12 @@ public class TelephonyManager { * instability. If a process has registered too many callbacks without unregistering them, it * may encounter an {@link IllegalStateException} when trying to register more callbacks. * + * <p> + * There's another way to renounce permissions with a custom context + * {@link AttributionSource.Builder#setRenouncedPermissions(Set<String>)} but only for system + * apps. To avoid confusion, calling this method supersede renouncing permissions with a + * custom context. + * * @param renounceFineLocationAccess Set this to true if the caller would not like to receive * location related information which will be sent if the caller already possess * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} and do not renounce the permissions. diff --git a/telephony/java/android/telephony/ims/RcsContactUceCapability.java b/telephony/java/android/telephony/ims/RcsContactUceCapability.java index 91121187a19a..9c36db8176b9 100644 --- a/telephony/java/android/telephony/ims/RcsContactUceCapability.java +++ b/telephony/java/android/telephony/ims/RcsContactUceCapability.java @@ -221,6 +221,15 @@ public final class RcsContactUceCapability implements Parcelable { } /** + * Set the entity URI related to the contact whose capabilities were requested. + * @param entityUri the 'pres' URL of the PRESENTITY publishing presence document. + */ + public @NonNull PresenceBuilder setEntityUri(@NonNull Uri entityUri) { + mCapabilities.mEntityUri = entityUri; + return this; + } + + /** * @return the RcsContactUceCapability instance. */ public @NonNull RcsContactUceCapability build() { @@ -232,6 +241,7 @@ public final class RcsContactUceCapability implements Parcelable { private @SourceType int mSourceType; private @CapabilityMechanism int mCapabilityMechanism; private @RequestResult int mRequestResult; + private Uri mEntityUri; private final Set<String> mFeatureTags = new HashSet<>(); private final List<RcsContactPresenceTuple> mPresenceTuples = new ArrayList<>(); @@ -248,6 +258,7 @@ public final class RcsContactUceCapability implements Parcelable { mCapabilityMechanism = in.readInt(); mSourceType = in.readInt(); mRequestResult = in.readInt(); + mEntityUri = in.readParcelable(Uri.class.getClassLoader(), android.net.Uri.class); List<String> featureTagList = new ArrayList<>(); in.readStringList(featureTagList); mFeatureTags.addAll(featureTagList); @@ -260,6 +271,7 @@ public final class RcsContactUceCapability implements Parcelable { out.writeInt(mCapabilityMechanism); out.writeInt(mSourceType); out.writeInt(mRequestResult); + out.writeParcelable(mEntityUri, flags); out.writeStringList(new ArrayList<>(mFeatureTags)); out.writeParcelableList(mPresenceTuples, flags); } @@ -361,6 +373,15 @@ public final class RcsContactUceCapability implements Parcelable { return mContactUri; } + /** + * Retrieve the entity URI of the contact whose presence information is being requested for. + * @return the URI representing the 'pres' URL of the PRESENTITY publishing presence document + * or {@code null} if the entity uri does not exist in the presence document. + */ + public @Nullable Uri getEntityUri() { + return mEntityUri; + } + @Override public String toString() { StringBuilder builder = new StringBuilder("RcsContactUceCapability"); @@ -382,6 +403,13 @@ public final class RcsContactUceCapability implements Parcelable { builder.append(mSourceType); builder.append(", requestResult="); builder.append(mRequestResult); + if (Build.IS_ENG) { + builder.append("entity uri="); + builder.append(mEntityUri != null ? mEntityUri : "null"); + } else { + builder.append("entity uri (isNull)="); + builder.append(mEntityUri != null ? "XXX" : "null"); + } if (mCapabilityMechanism == CAPABILITY_MECHANISM_PRESENCE) { builder.append(", presenceTuples={"); diff --git a/test-base/Android.bp b/test-base/Android.bp index 8be732452228..527159a78ebf 100644 --- a/test-base/Android.bp +++ b/test-base/Android.bp @@ -72,11 +72,16 @@ java_sdk_library { // Build the android.test.base_static library // ========================================== -// This is only intended for inclusion in the android.test.runner-minus-junit, -// robolectric_android-all-stub and repackaged.android.test.* libraries. +// This is only intended for use by the android.test.runner-minus-junit +// library. +// // Must not be used elsewhere. +// java_library_static { name: "android.test.base_static", + visibility: [ + "//frameworks/base/test-runner", + ], installable: false, srcs: [":android-test-base-sources"], @@ -91,28 +96,10 @@ java_library_static { sdk_version: "current", } -// Build the repackaged.android.test.base library -// ============================================== -// This contains repackaged versions of the classes from -// android.test.base. -java_library_static { - name: "repackaged.android.test.base", - - sdk_version: "current", - static_libs: ["android.test.base_static"], - - jarjar_rules: "jarjar-rules.txt", - // Pin java_version until jarjar is certified to support later versions. http://b/72703434 - java_version: "1.8", -} - // Build the android.test.base-minus-junit library // =============================================== // This contains the android.test classes from android.test.base plus -// the com.android.internal.util.Predicate[s] classes. This is only -// intended for inclusion in android.test.legacy and in -// android.test.base-hiddenapi-annotations to avoid a dependency cycle and must -// not be used elsewhere. +// the com.android.internal.util.Predicate[s] classes. java_library_static { name: "android.test.base-minus-junit", diff --git a/test-base/jarjar-rules.txt b/test-base/jarjar-rules.txt deleted file mode 100644 index fd8555c8931c..000000000000 --- a/test-base/jarjar-rules.txt +++ /dev/null @@ -1,3 +0,0 @@ -rule junit.** repackaged.junit.@1 -rule android.test.** repackaged.android.test.@1 -rule com.android.internal.util.** repackaged.com.android.internal.util.@1 diff --git a/test-runner/Android.bp b/test-runner/Android.bp index 2a19af9f8cd2..13a5dac9eb38 100644 --- a/test-runner/Android.bp +++ b/test-runner/Android.bp @@ -79,32 +79,6 @@ java_library { ], } -// Build the repackaged.android.test.runner library -// ================================================ -java_library_static { - name: "repackaged.android.test.runner", - - srcs: [":android-test-runner-sources"], - exclude_srcs: [ - "src/android/test/ActivityUnitTestCase.java", - "src/android/test/ApplicationTestCase.java", - "src/android/test/IsolatedContext.java", - "src/android/test/ProviderTestCase.java", - "src/android/test/ProviderTestCase2.java", - "src/android/test/RenamingDelegatingContext.java", - "src/android/test/ServiceTestCase.java", - ], - - sdk_version: "current", - libs: [ - "android.test.base_static", - ], - - jarjar_rules: "jarjar-rules.txt", - // Pin java_version until jarjar is certified to support later versions. http://b/72703434 - java_version: "1.8", -} - // Make the current.txt available for use by the cts/tests/signature tests. // ======================================================================== filegroup { diff --git a/test-runner/jarjar-rules.txt b/test-runner/jarjar-rules.txt deleted file mode 120000 index f6f79139d511..000000000000 --- a/test-runner/jarjar-rules.txt +++ /dev/null @@ -1 +0,0 @@ -../test-base/jarjar-rules.txt
\ No newline at end of file diff --git a/tests/Camera2Tests/SmartCamera/SimpleCamera/Android.bp b/tests/Camera2Tests/SmartCamera/SimpleCamera/Android.bp new file mode 100644 index 000000000000..4fff969359c8 --- /dev/null +++ b/tests/Camera2Tests/SmartCamera/SimpleCamera/Android.bp @@ -0,0 +1,34 @@ +// 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 { + // See: http://go/android-license-faq + default_applicable_licenses: [ + "frameworks_base_license", + ], +} + +android_test { + name: "SmartCamera", + optimize: { + enabled: false, + }, + // comment it out for now since we need use some hidden APIs + sdk_version: "current", + static_libs: ["android-ex-camera2"], + srcs: [ + "src/**/*.java", + ], + jni_libs: ["libsmartcamera_jni"], +} diff --git a/tests/Camera2Tests/SmartCamera/SimpleCamera/Android.mk b/tests/Camera2Tests/SmartCamera/SimpleCamera/Android.mk deleted file mode 100644 index 6003628ffb0d..000000000000 --- a/tests/Camera2Tests/SmartCamera/SimpleCamera/Android.mk +++ /dev/null @@ -1,45 +0,0 @@ -# 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. - -ifneq ($(TARGET_BUILD_JAVA_SUPPORT_LEVEL),) - -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) - -LOCAL_MODULE_TAGS := tests - -LOCAL_PROGUARD_ENABLED := disabled - -# comment it out for now since we need use some hidden APIs -LOCAL_SDK_VERSION := current - -LOCAL_STATIC_JAVA_LIBRARIES := android-ex-camera2 - -LOCAL_SRC_FILES := \ - $(call all-java-files-under, src) \ - $(call all-renderscript-files-under, src) - -LOCAL_PACKAGE_NAME := SmartCamera -LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 -LOCAL_LICENSE_CONDITIONS := notice -LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../../../../NOTICE -LOCAL_JNI_SHARED_LIBRARIES := libsmartcamera_jni - -include $(BUILD_PACKAGE) - -# Include packages in subdirectories -include $(call all-makefiles-under,$(LOCAL_PATH)) - -endif diff --git a/tests/Camera2Tests/SmartCamera/SimpleCamera/tests/Android.bp b/tests/Camera2Tests/SmartCamera/SimpleCamera/tests/Android.bp new file mode 100644 index 000000000000..5edb1de9586e --- /dev/null +++ b/tests/Camera2Tests/SmartCamera/SimpleCamera/tests/Android.bp @@ -0,0 +1,36 @@ +// 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 { + // See: http://go/android-license-faq + default_applicable_licenses: [ + "frameworks_base_license", + ], +} + +android_test { + name: "SmartCamera-tests", + platform_apis: true, + srcs: ["src/**/*.java"], + libs: ["android.test.base"], + static_libs: [ + "guava", + "junit", + ], + optimize: { + enabled: false, + }, + instrumentation_for: "SmartCamera", +} diff --git a/tests/Camera2Tests/SmartCamera/SimpleCamera/tests/Android.mk b/tests/Camera2Tests/SmartCamera/SimpleCamera/tests/Android.mk deleted file mode 100644 index c23d593d4f86..000000000000 --- a/tests/Camera2Tests/SmartCamera/SimpleCamera/tests/Android.mk +++ /dev/null @@ -1,38 +0,0 @@ -# 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. -# - -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_MODULE_TAGS := tests - -# LOCAL_SDK_VERSION := current -LOCAL_PRIVATE_PLATFORM_APIS := true - -LOCAL_PACKAGE_NAME := SmartCamera-tests -LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 -LOCAL_LICENSE_CONDITIONS := notice -LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../../../../../NOTICE - -LOCAL_SRC_FILES += $(call all-java-files-under, src) - -LOCAL_JAVA_LIBRARIES := android.test.base -LOCAL_STATIC_JAVA_LIBRARIES := guava junit - -LOCAL_PROGUARD_ENABLED := disabled - -LOCAL_INSTRUMENTATION_FOR := SmartCamera - -include $(BUILD_PACKAGE) diff --git a/tests/CanvasCompare/Android.bp b/tests/CanvasCompare/Android.bp new file mode 100644 index 000000000000..98831154ddc2 --- /dev/null +++ b/tests/CanvasCompare/Android.bp @@ -0,0 +1,63 @@ +// +// Copyright (C) 2012 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 { + // See: http://go/android-license-faq + default_applicable_licenses: [ + "frameworks_base_license", + ], +} + +android_test { + name: "CanvasCompare", + srcs: [ + "src/**/*.java", + ":CanvasCompare-rscript{CanvasCompare.srcjar}", + ], + resource_zips: [ + ":CanvasCompare-rscript{CanvasCompare.res.zip}", + ], + platform_apis: true, + libs: [ + "android.test.runner", + "android.test.base", + ], + static_libs: ["junit"], +} + +genrule { + name: "CanvasCompare-rscript", + srcs: [ + "src/**/*.rscript", + ":rs_script_api", + ":rs_clang_headers", + ], + tools: [ + "llvm-rs-cc", + "soong_zip", + ], + out: [ + "CanvasCompare.srcjar", + "CanvasCompare.res.zip", + ], + cmd: "for f in $(locations src/**/*.rscript); do " + + " $(location llvm-rs-cc) -o $(genDir)/res/raw -p $(genDir)/src " + + " -I $$(dirname $$(echo $(locations :rs_script_api) | awk '{ print $$1 }')) " + + " -I $$(dirname $$(echo $(locations :rs_clang_headers) | awk '{ print $$1 }')) $${f}; " + + "done && " + + "$(location soong_zip) -srcjar -o $(location CanvasCompare.srcjar) -C $(genDir)/src -D $(genDir)/src &&" + + "$(location soong_zip) -o $(location CanvasCompare.res.zip) -C $(genDir)/res -D $(genDir)/res", +} diff --git a/tests/CanvasCompare/Android.mk b/tests/CanvasCompare/Android.mk deleted file mode 100644 index b82ae65b4356..000000000000 --- a/tests/CanvasCompare/Android.mk +++ /dev/null @@ -1,33 +0,0 @@ -# -# Copyright (C) 2012 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. -# - -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-renderscript-files-under, src) - -LOCAL_PACKAGE_NAME := CanvasCompare -LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 -LOCAL_LICENSE_CONDITIONS := notice -LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../../NOTICE -LOCAL_PRIVATE_PLATFORM_APIS := true - -LOCAL_MODULE_TAGS := tests - -LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base -LOCAL_STATIC_JAVA_LIBRARIES := junit - -include $(BUILD_PACKAGE) diff --git a/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java b/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java index 978bf3ed2e92..7b1f7a599519 100644 --- a/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java +++ b/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java @@ -174,7 +174,7 @@ public class TelephonySubscriptionTrackerTest { private IntentFilter getIntentFilter() { final ArgumentCaptor<IntentFilter> captor = ArgumentCaptor.forClass(IntentFilter.class); - verify(mContext).registerReceiver(any(), captor.capture(), any(), any()); + verify(mContext).registerReceiver(any(), captor.capture(), any(), any(), anyInt()); return captor.getValue(); } @@ -258,7 +258,8 @@ public class TelephonySubscriptionTrackerTest { eq(mTelephonySubscriptionTracker), any(IntentFilter.class), any(), - eq(mHandler)); + eq(mHandler), + eq(Context.RECEIVER_NOT_EXPORTED)); final IntentFilter filter = getIntentFilter(); assertEquals(2, filter.countActions()); assertTrue(filter.hasAction(ACTION_CARRIER_CONFIG_CHANGED)); diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java index e547400fff73..4cfa93b4ecf9 100644 --- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java +++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java @@ -307,7 +307,10 @@ public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnection ncCaptor.capture(), lpCaptor.capture(), any(), - argThat(nac -> nac.getLegacyType() == ConnectivityManager.TYPE_MOBILE), + // Subtype integer/name and extras do not have getters; cannot be tested. + argThat(nac -> nac.getLegacyType() == ConnectivityManager.TYPE_MOBILE + && nac.getLegacyTypeName().equals( + VcnGatewayConnection.NETWORK_INFO_NETWORK_TYPE_STRING)), any(), any(), any()); diff --git a/tools/bit/command.cpp b/tools/bit/command.cpp index f95ea117a96e..6c68e0b0ff6b 100644 --- a/tools/bit/command.cpp +++ b/tools/bit/command.cpp @@ -192,10 +192,11 @@ exec_with_path_search(const char* prog, char const* const* argv, char const* con if (strchr(prog, '/') != NULL) { return execve(prog, (char*const*)argv, (char*const*)envp); } else { - char* pathEnv = strdup(getenv("PATH")); - if (pathEnv == NULL) { + const char* pathEnvRaw = getenv("PATH"); + if (pathEnvRaw == NULL) { return 1; } + char* pathEnv = strdup(pathEnvRaw); char* dir = pathEnv; while (dir) { char* next = strchr(dir, ':'); diff --git a/tools/streaming_proto/Android.bp b/tools/streaming_proto/Android.bp index 1ec83a360048..b18bdff7263f 100644 --- a/tools/streaming_proto/Android.bp +++ b/tools/streaming_proto/Android.bp @@ -69,7 +69,6 @@ java_library { "test/**/*.proto", ], proto: { - plugin: "javastream", + type: "stream", }, - static_libs: ["libprotobuf-java-lite"], } |