Skip to content

Commit 4a994e7

Browse files
Add support for pulling files and directories (SAVE_AS)
1 parent 3286134 commit 4a994e7

1 file changed

Lines changed: 58 additions & 1 deletion

File tree

addons/android_device_explorer/device_explorer.gd

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,16 @@ func _on_menu_item_pressed(id: int) -> void:
181181
menu_button.get_popup().set_item_checked(0, show_all)
182182
_load_root()
183183

184+
func _show_save_as_dialog(remote_path: String, is_dir: bool) -> void:
185+
var file_dialog = EditorFileDialog.new()
186+
file_dialog.access = FileDialog.ACCESS_FILESYSTEM
187+
file_dialog.file_mode = FileDialog.FILE_MODE_OPEN_DIR if is_dir else FileDialog.FILE_MODE_SAVE_FILE
188+
file_dialog.current_file = remote_path.get_file()
189+
file_dialog.file_selected.connect(_pull_single_file.bind(remote_path))
190+
file_dialog.dir_selected.connect(_pull_dir.bind(remote_path))
191+
add_child(file_dialog)
192+
file_dialog.popup_file_dialog()
193+
184194

185195
# ADB Handling--------------------------------------------------------------------------------------
186196

@@ -192,6 +202,7 @@ func _run_adb(p_args: PackedStringArray) -> String:
192202

193203
var output := []
194204
OS.execute(ADB_PATH, args, output, true)
205+
#print(output)
195206
return output[0] if output.size() > 0 else ""
196207

197208

@@ -224,6 +235,49 @@ func _list_dir(path: String) -> Array:
224235
return files
225236

226237

238+
func _pull_dir(local_path: String, remote_path: String) -> void:
239+
if not remote_path.begins_with(DATA_ROOT):
240+
_run_adb(["pull", remote_path, local_path])
241+
return
242+
243+
# special handling for app's private data dir
244+
var ls_cmd = "ls -1 -F '%s'" % remote_path
245+
var output = _run_adb(["shell", "run-as", PACKAGE_NAME, ls_cmd])
246+
247+
local_path = local_path.path_join(remote_path.get_file()) # Create the base directory in local path
248+
if not DirAccess.dir_exists_absolute(local_path):
249+
DirAccess.make_dir_recursive_absolute(local_path)
250+
251+
for line in output.split("\n"):
252+
line = line.strip_edges()
253+
if line == "" or line.begins_with("total"): continue
254+
255+
var is_dir = line.ends_with("/")
256+
var item_name = line.trim_suffix("/")
257+
var item_remote_path = remote_path.path_join(item_name)
258+
var item_local_path = local_path.path_join(item_name)
259+
260+
if is_dir:
261+
_pull_dir(item_local_path, item_remote_path)
262+
else:
263+
_pull_single_file(item_local_path, item_remote_path)
264+
265+
266+
func _pull_single_file(local_path: String, remote_path: String) -> void:
267+
if not remote_path.begins_with(DATA_ROOT):
268+
_run_adb(["pull", remote_path, local_path])
269+
return
270+
271+
# special handling for app's private data dir
272+
var temp_name = "temp_" + str(Time.get_ticks_usec())
273+
var temp_path = PULL_PUSH_TEMP.path_join(temp_name)
274+
275+
_run_adb(["shell", "touch", temp_path])
276+
var cp_cmd = "cp '%s' '%s'" % [remote_path, temp_path]
277+
_run_adb(["shell", "run-as", PACKAGE_NAME, cp_cmd])
278+
_run_adb(["pull", temp_path, local_path])
279+
_run_adb(["shell", "rm", temp_path])
280+
227281
#---------------------------------------------------------------------------------------------------
228282

229283
func _get_icon_for_ext(path: String) -> String:
@@ -270,5 +324,8 @@ func create_context_menu() -> void:
270324
func _on_context_menu_item_pressed(id: int) -> void:
271325
var item = tree.get_selected()
272326
if not item: return
273-
print("context menu pressed: ", id)
327+
match id:
328+
ContextMenu.SAVE_AS:
329+
var meta = item.get_metadata(0)
330+
_show_save_as_dialog(meta.path, meta.is_dir)
274331

0 commit comments

Comments
 (0)