1 | /**************************************************************************/ |
2 | /* export_plugin.h */ |
3 | /**************************************************************************/ |
4 | /* This file is part of: */ |
5 | /* GODOT ENGINE */ |
6 | /* https://godotengine.org */ |
7 | /**************************************************************************/ |
8 | /* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ |
9 | /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ |
10 | /* */ |
11 | /* Permission is hereby granted, free of charge, to any person obtaining */ |
12 | /* a copy of this software and associated documentation files (the */ |
13 | /* "Software"), to deal in the Software without restriction, including */ |
14 | /* without limitation the rights to use, copy, modify, merge, publish, */ |
15 | /* distribute, sublicense, and/or sell copies of the Software, and to */ |
16 | /* permit persons to whom the Software is furnished to do so, subject to */ |
17 | /* the following conditions: */ |
18 | /* */ |
19 | /* The above copyright notice and this permission notice shall be */ |
20 | /* included in all copies or substantial portions of the Software. */ |
21 | /* */ |
22 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ |
23 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ |
24 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ |
25 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ |
26 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ |
27 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ |
28 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ |
29 | /**************************************************************************/ |
30 | |
31 | #ifndef ANDROID_EXPORT_PLUGIN_H |
32 | #define ANDROID_EXPORT_PLUGIN_H |
33 | |
34 | #ifndef DISABLE_DEPRECATED |
35 | #include "godot_plugin_config.h" |
36 | #endif // DISABLE_DEPRECATED |
37 | |
38 | #include "core/io/zip_io.h" |
39 | #include "core/os/os.h" |
40 | #include "editor/export/editor_export_platform.h" |
41 | |
42 | const String SPLASH_CONFIG_XML_CONTENT = R"SPLASH(<?xml version="1.0" encoding="utf-8"?> |
43 | <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> |
44 | <item android:drawable="@drawable/splash_bg_color" /> |
45 | <item> |
46 | <bitmap |
47 | android:gravity="center" |
48 | android:filter="%s" |
49 | android:src="@drawable/splash" /> |
50 | </item> |
51 | </layer-list> |
52 | )SPLASH" ; |
53 | |
54 | // Optional environment variables for defining confidential information. If any |
55 | // of these is set, they will override the values set in the credentials file. |
56 | const String ENV_ANDROID_KEYSTORE_DEBUG_PATH = "GODOT_ANDROID_KEYSTORE_DEBUG_PATH" ; |
57 | const String ENV_ANDROID_KEYSTORE_DEBUG_USER = "GODOT_ANDROID_KEYSTORE_DEBUG_USER" ; |
58 | const String ENV_ANDROID_KEYSTORE_DEBUG_PASS = "GODOT_ANDROID_KEYSTORE_DEBUG_PASSWORD" ; |
59 | const String ENV_ANDROID_KEYSTORE_RELEASE_PATH = "GODOT_ANDROID_KEYSTORE_RELEASE_PATH" ; |
60 | const String ENV_ANDROID_KEYSTORE_RELEASE_USER = "GODOT_ANDROID_KEYSTORE_RELEASE_USER" ; |
61 | const String ENV_ANDROID_KEYSTORE_RELEASE_PASS = "GODOT_ANDROID_KEYSTORE_RELEASE_PASSWORD" ; |
62 | |
63 | struct LauncherIcon { |
64 | const char *export_path; |
65 | int dimensions = 0; |
66 | }; |
67 | |
68 | class EditorExportPlatformAndroid : public EditorExportPlatform { |
69 | GDCLASS(EditorExportPlatformAndroid, EditorExportPlatform); |
70 | |
71 | Ref<ImageTexture> logo; |
72 | Ref<ImageTexture> run_icon; |
73 | |
74 | struct Device { |
75 | String id; |
76 | String name; |
77 | String description; |
78 | int api_level = 0; |
79 | }; |
80 | |
81 | struct APKExportData { |
82 | zipFile apk; |
83 | EditorProgress *ep = nullptr; |
84 | }; |
85 | |
86 | #ifndef DISABLE_DEPRECATED |
87 | mutable Vector<PluginConfigAndroid> android_plugins; |
88 | mutable SafeFlag android_plugins_changed; |
89 | Mutex android_plugins_lock; |
90 | #endif // DISABLE_DEPRECATED |
91 | String last_plugin_names; |
92 | uint64_t last_gradle_build_time = 0; |
93 | |
94 | Vector<Device> devices; |
95 | SafeFlag devices_changed; |
96 | Mutex device_lock; |
97 | #ifndef ANDROID_ENABLED |
98 | Thread check_for_changes_thread; |
99 | SafeFlag quit_request; |
100 | |
101 | static void _check_for_changes_poll_thread(void *ud); |
102 | #endif |
103 | |
104 | String get_project_name(const String &p_name) const; |
105 | |
106 | String get_package_name(const String &p_package) const; |
107 | |
108 | String get_valid_basename() const; |
109 | |
110 | String get_assets_directory(const Ref<EditorExportPreset> &p_preset, int p_export_format) const; |
111 | |
112 | bool is_package_name_valid(const String &p_package, String *r_error = nullptr) const; |
113 | bool is_project_name_valid() const; |
114 | |
115 | static bool _should_compress_asset(const String &p_path, const Vector<uint8_t> &p_data); |
116 | |
117 | static zip_fileinfo get_zip_fileinfo(); |
118 | |
119 | struct ABI { |
120 | String abi; |
121 | String arch; |
122 | |
123 | bool operator==(const ABI &p_a) const { |
124 | return p_a.abi == abi; |
125 | } |
126 | |
127 | ABI(const String &p_abi, const String &p_arch) { |
128 | abi = p_abi; |
129 | arch = p_arch; |
130 | } |
131 | ABI() {} |
132 | }; |
133 | |
134 | static Vector<ABI> get_abis(); |
135 | |
136 | #ifndef DISABLE_DEPRECATED |
137 | /// List the gdap files in the directory specified by the p_path parameter. |
138 | static Vector<String> list_gdap_files(const String &p_path); |
139 | |
140 | static Vector<PluginConfigAndroid> get_plugins(); |
141 | |
142 | static Vector<PluginConfigAndroid> get_enabled_plugins(const Ref<EditorExportPreset> &p_presets); |
143 | #endif // DISABLE_DEPRECATED |
144 | |
145 | static Error store_in_apk(APKExportData *ed, const String &p_path, const Vector<uint8_t> &p_data, int compression_method = Z_DEFLATED); |
146 | |
147 | static Error save_apk_so(void *p_userdata, const SharedObject &p_so); |
148 | |
149 | static Error save_apk_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key); |
150 | |
151 | static Error ignore_apk_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key); |
152 | |
153 | static Error copy_gradle_so(void *p_userdata, const SharedObject &p_so); |
154 | |
155 | bool _has_read_write_storage_permission(const Vector<String> &p_permissions); |
156 | |
157 | bool _has_manage_external_storage_permission(const Vector<String> &p_permissions); |
158 | |
159 | void _get_permissions(const Ref<EditorExportPreset> &p_preset, bool p_give_internet, Vector<String> &r_permissions); |
160 | |
161 | void _write_tmp_manifest(const Ref<EditorExportPreset> &p_preset, bool p_give_internet, bool p_debug); |
162 | |
163 | void _fix_manifest(const Ref<EditorExportPreset> &p_preset, Vector<uint8_t> &p_manifest, bool p_give_internet); |
164 | |
165 | static String _parse_string(const uint8_t *p_bytes, bool p_utf8); |
166 | |
167 | void _fix_resources(const Ref<EditorExportPreset> &p_preset, Vector<uint8_t> &r_manifest); |
168 | |
169 | void _load_image_data(const Ref<Image> &p_splash_image, Vector<uint8_t> &p_data); |
170 | |
171 | void _process_launcher_icons(const String &p_file_name, const Ref<Image> &p_source_image, int dimension, Vector<uint8_t> &p_data); |
172 | |
173 | String load_splash_refs(Ref<Image> &splash_image, Ref<Image> &splash_bg_color_image); |
174 | |
175 | void load_icon_refs(const Ref<EditorExportPreset> &p_preset, Ref<Image> &icon, Ref<Image> &foreground, Ref<Image> &background); |
176 | |
177 | void store_image(const LauncherIcon launcher_icon, const Vector<uint8_t> &data); |
178 | |
179 | void store_image(const String &export_path, const Vector<uint8_t> &data); |
180 | |
181 | void _copy_icons_to_gradle_project(const Ref<EditorExportPreset> &p_preset, |
182 | const String &processed_splash_config_xml, |
183 | const Ref<Image> &splash_image, |
184 | const Ref<Image> &splash_bg_color_image, |
185 | const Ref<Image> &main_image, |
186 | const Ref<Image> &foreground, |
187 | const Ref<Image> &background); |
188 | |
189 | static Vector<ABI> get_enabled_abis(const Ref<EditorExportPreset> &p_preset); |
190 | |
191 | static bool _uses_vulkan(); |
192 | |
193 | public: |
194 | typedef Error (*EditorExportSaveFunction)(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key); |
195 | |
196 | public: |
197 | virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) const override; |
198 | |
199 | virtual void get_export_options(List<ExportOption> *r_options) const override; |
200 | |
201 | virtual String get_export_option_warning(const EditorExportPreset *p_preset, const StringName &p_name) const override; |
202 | |
203 | virtual String get_name() const override; |
204 | |
205 | virtual String get_os_name() const override; |
206 | |
207 | virtual Ref<Texture2D> get_logo() const override; |
208 | |
209 | virtual bool should_update_export_options() override; |
210 | |
211 | virtual bool poll_export() override; |
212 | |
213 | virtual int get_options_count() const override; |
214 | |
215 | virtual String get_options_tooltip() const override; |
216 | |
217 | virtual String get_option_label(int p_index) const override; |
218 | |
219 | virtual String get_option_tooltip(int p_index) const override; |
220 | |
221 | virtual Error run(const Ref<EditorExportPreset> &p_preset, int p_device, int p_debug_flags) override; |
222 | |
223 | virtual Ref<Texture2D> get_run_icon() const override; |
224 | |
225 | static String get_adb_path(); |
226 | |
227 | static String get_apksigner_path(int p_target_sdk = -1, bool p_check_executes = false); |
228 | |
229 | virtual bool has_valid_export_configuration(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates, bool p_debug = false) const override; |
230 | virtual bool has_valid_project_configuration(const Ref<EditorExportPreset> &p_preset, String &r_error) const override; |
231 | |
232 | virtual List<String> get_binary_extensions(const Ref<EditorExportPreset> &p_preset) const override; |
233 | |
234 | String _get_plugins_names(const Ref<EditorExportPreset> &p_preset) const; |
235 | |
236 | String _resolve_export_plugin_android_library_path(const String &p_android_library_path) const; |
237 | |
238 | bool _is_clean_build_required(const Ref<EditorExportPreset> &p_preset); |
239 | |
240 | String get_apk_expansion_fullpath(const Ref<EditorExportPreset> &p_preset, const String &p_path); |
241 | |
242 | Error save_apk_expansion_file(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path); |
243 | |
244 | void get_command_line_flags(const Ref<EditorExportPreset> &p_preset, const String &p_path, int p_flags, Vector<uint8_t> &r_command_line_flags); |
245 | |
246 | Error sign_apk(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &export_path, EditorProgress &ep); |
247 | |
248 | void _clear_assets_directory(); |
249 | |
250 | void _remove_copied_libs(); |
251 | |
252 | static String join_list(const List<String> &p_parts, const String &p_separator); |
253 | static String join_abis(const Vector<ABI> &p_parts, const String &p_separator, bool p_use_arch); |
254 | |
255 | virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0) override; |
256 | |
257 | Error export_project_helper(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int export_format, bool should_sign, int p_flags); |
258 | |
259 | virtual void get_platform_features(List<String> *r_features) const override; |
260 | |
261 | virtual void resolve_platform_feature_priorities(const Ref<EditorExportPreset> &p_preset, HashSet<String> &p_features) override; |
262 | |
263 | EditorExportPlatformAndroid(); |
264 | |
265 | ~EditorExportPlatformAndroid(); |
266 | }; |
267 | |
268 | #endif // ANDROID_EXPORT_PLUGIN_H |
269 | |