@@ -95,14 +95,26 @@ def init_visuals(
9595 # initialize file pickers
9696 self .pick_image_dialog = FilePicker (on_result = self .pick_image_result )
9797 self .pick_recovery_dialog = FilePicker (on_result = self .pick_recovery_result )
98+ self .pick_dtbo_dialog = FilePicker (on_result = self .pick_dtbo_result )
99+ self .pick_vbmeta_dialog = FilePicker (on_result = self .pick_vbmeta_result )
100+ self .pick_super_empty_dialog = FilePicker (
101+ on_result = self .pick_super_empty_result
102+ )
103+
98104 self .selected_image = Text ("Selected image: " )
99105 self .selected_recovery = Text ("Selected recovery: " )
106+ self .selected_dtbo = Text ("Selected dtbo: " )
107+ self .selected_vbmeta = Text ("Selected vbmeta: " )
108+ self .selected_super_empty = Text ("Selected super_empty: " )
100109
101110 # initialize and manage button state.
102111 self .confirm_button = confirm_button (self .on_confirm )
103112 self .confirm_button .disabled = True
104113 self .pick_recovery_dialog .on_result = self .enable_button_if_ready
105114 self .pick_image_dialog .on_result = self .enable_button_if_ready
115+ self .pick_dtbo_dialog .on_result = self .enable_button_if_ready
116+ self .pick_vbmeta_dialog .on_result = self .enable_button_if_ready
117+ self .pick_super_empty_dialog .on_result = self .enable_button_if_ready
106118 # back button
107119 self .back_button = ElevatedButton (
108120 "Back" ,
@@ -122,6 +134,9 @@ def build(self):
122134 # attach hidden dialogues
123135 self .right_view .controls .append (self .pick_image_dialog )
124136 self .right_view .controls .append (self .pick_recovery_dialog )
137+ self .right_view .controls .append (self .pick_dtbo_dialog )
138+ self .right_view .controls .append (self .pick_vbmeta_dialog )
139+ self .right_view .controls .append (self .pick_super_empty_dialog )
125140
126141 # create help/info button to show the help dialog
127142 info_button = OutlinedButton (
@@ -226,6 +241,83 @@ def build(self):
226241 ),
227242 self .selected_recovery ,
228243 Divider (),
244+ ]
245+ )
246+
247+ # attach the controls for uploading others partitions, like dtbo, vbmeta & super_empty
248+ if "dtbo" in self .state .config .metadata ["additional_steps" ]:
249+ self .right_view .controls .extend (
250+ [
251+ Text ("Select other specific images:" , style = "titleSmall" ),
252+ Markdown (
253+ """
254+ Depending of the ROM, OpenAndroidInstaller may have to install additional images.
255+ These images are usually needed for Android 13 ROM.
256+ Make sure the file is for **your exact phone model!**
257+ """
258+ ),
259+ Row (
260+ [
261+ FilledButton (
262+ "Pick `dtbo.img` image" ,
263+ icon = icons .UPLOAD_FILE ,
264+ on_click = lambda _ : self .pick_dtbo_dialog .pick_files (
265+ allow_multiple = False ,
266+ file_type = "custom" ,
267+ allowed_extensions = ["img" ],
268+ ),
269+ expand = True ,
270+ ),
271+ ]
272+ ),
273+ self .selected_dtbo ,
274+ ]
275+ )
276+ if "vbmeta" in self .state .config .metadata ["additional_steps" ]:
277+ self .right_view .controls .extend (
278+ [
279+ Row (
280+ [
281+ FilledButton (
282+ "Pick `vbmeta.img` image" ,
283+ icon = icons .UPLOAD_FILE ,
284+ on_click = lambda _ : self .pick_vbmeta_dialog .pick_files (
285+ allow_multiple = False ,
286+ file_type = "custom" ,
287+ allowed_extensions = ["img" ],
288+ ),
289+ expand = True ,
290+ ),
291+ ]
292+ ),
293+ self .selected_vbmeta ,
294+ ]
295+ )
296+ if "super_empty" in self .state .config .metadata ["additional_steps" ]:
297+ self .right_view .controls .extend (
298+ [
299+ Row (
300+ [
301+ FilledButton (
302+ "Pick `super_empty.img` image" ,
303+ icon = icons .UPLOAD_FILE ,
304+ on_click = lambda _ : self .pick_super_empty_dialog .pick_files (
305+ allow_multiple = False ,
306+ file_type = "custom" ,
307+ allowed_extensions = ["img" ],
308+ ),
309+ expand = True ,
310+ ),
311+ ]
312+ ),
313+ self .selected_super_empty ,
314+ Divider (),
315+ ]
316+ )
317+
318+ # attach the bottom buttons
319+ self .right_view .controls .extend (
320+ [
229321 self .info_field ,
230322 Row ([self .back_button , self .confirm_button ]),
231323 ]
@@ -291,6 +383,61 @@ def pick_recovery_result(self, e: FilePickerResultEvent):
291383 # update
292384 self .selected_recovery .update ()
293385
386+ def pick_dtbo_result (self , e : FilePickerResultEvent ):
387+ path = ", " .join (map (lambda f : f .name , e .files )) if e .files else "Cancelled!"
388+ # update the textfield with the name of the file
389+ self .selected_dtbo .value = self .selected_dtbo .value .split (":" )[0 ] + f": { path } "
390+ if e .files :
391+ # check if the dtbo works with the device and show the filename in different colors accordingly
392+ if path == "dtbo.img" :
393+ self .selected_dtbo .color = colors .GREEN
394+ self .state .dtbo_path = e .files [0 ].path
395+ logger .info (f"Selected dtbo from { self .state .dtbo_path } " )
396+ else :
397+ self .selected_dtbo .color = colors .RED
398+ else :
399+ logger .info ("No image selected." )
400+ # update
401+ self .selected_dtbo .update ()
402+
403+ def pick_vbmeta_result (self , e : FilePickerResultEvent ):
404+ path = ", " .join (map (lambda f : f .name , e .files )) if e .files else "Cancelled!"
405+ # update the textfield with the name of the file
406+ self .selected_vbmeta .value = (
407+ self .selected_vbmeta .value .split (":" )[0 ] + f": { path } "
408+ )
409+ if e .files :
410+ # check if the vbmeta works with the device and show the filename in different colors accordingly
411+ if path == "vbmeta.img" :
412+ self .selected_vbmeta .color = colors .GREEN
413+ self .state .vbmeta_path = e .files [0 ].path
414+ logger .info (f"Selected vbmeta from { self .state .vbmeta_path } " )
415+ else :
416+ self .selected_vbmeta .color = colors .RED
417+ else :
418+ logger .info ("No image selected." )
419+ # update
420+ self .selected_vbmeta .update ()
421+
422+ def pick_super_empty_result (self , e : FilePickerResultEvent ):
423+ path = ", " .join (map (lambda f : f .name , e .files )) if e .files else "Cancelled!"
424+ # update the textfield with the name of the file
425+ self .selected_super_empty .value = (
426+ self .selected_super_empty .value .split (":" )[0 ] + f": { path } "
427+ )
428+ if e .files :
429+ # check if the super_empty works with the device and show the filename in different colors accordingly
430+ if path == "super_empty.img" :
431+ self .selected_super_empty .color = colors .GREEN
432+ self .state .super_empty_path = e .files [0 ].path
433+ logger .info (f"Selected super_empty from { self .state .super_empty_path } " )
434+ else :
435+ self .selected_super_empty .color = colors .RED
436+ else :
437+ logger .info ("No image selected." )
438+ # update
439+ self .selected_super_empty .update ()
440+
294441 def enable_button_if_ready (self , e ):
295442 """Enable the confirm button if both files have been selected."""
296443 if (".zip" in self .selected_image .value ) and (
@@ -320,6 +467,29 @@ def enable_button_if_ready(self, e):
320467 self .confirm_button .disabled = True
321468 self .right_view .update ()
322469 return
470+
471+ if (
472+ (self .selected_dtbo .color and self .selected_dtbo .color == "red" )
473+ or (self .selected_vbmeta .color and self .selected_vbmeta .color == "red" )
474+ or (
475+ self .selected_super_empty .color
476+ and self .selected_super_empty .color == "red"
477+ )
478+ ):
479+ logger .error (
480+ "Some additional images don't match. Please select different ones."
481+ )
482+ self .info_field .controls = [
483+ Text (
484+ "Some additional images don't match. Select right ones or unselect them." ,
485+ color = colors .RED ,
486+ weight = "bold" ,
487+ )
488+ ]
489+ self .confirm_button .disabled = True
490+ self .right_view .update ()
491+ return
492+
323493 logger .info ("Image and recovery work with the device. You can continue." )
324494 self .info_field .controls = []
325495 self .confirm_button .disabled = False
0 commit comments