├── src ├── icon.png ├── macos │ ├── adb │ └── fastboot ├── smallicon.png ├── windows │ ├── adb.exe │ ├── fastboot.exe │ ├── AdbWinApi.dll │ └── AdbWinUsbApi.dll ├── xiaomiadbfastboottools │ ├── App.java │ ├── Uninstaller.java │ ├── XiaomiADBFastbootTools.java │ ├── Command.java │ ├── MainWindowController.java │ └── MainWindow.fxml └── dummy.img ├── .gitignore ├── README.md └── LICENSE /src/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LouWii/XiaomiADBFastbootTools/HEAD/src/icon.png -------------------------------------------------------------------------------- /src/macos/adb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LouWii/XiaomiADBFastbootTools/HEAD/src/macos/adb -------------------------------------------------------------------------------- /src/macos/fastboot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LouWii/XiaomiADBFastbootTools/HEAD/src/macos/fastboot -------------------------------------------------------------------------------- /src/smallicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LouWii/XiaomiADBFastbootTools/HEAD/src/smallicon.png -------------------------------------------------------------------------------- /src/windows/adb.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LouWii/XiaomiADBFastbootTools/HEAD/src/windows/adb.exe -------------------------------------------------------------------------------- /src/windows/fastboot.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LouWii/XiaomiADBFastbootTools/HEAD/src/windows/fastboot.exe -------------------------------------------------------------------------------- /src/windows/AdbWinApi.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LouWii/XiaomiADBFastbootTools/HEAD/src/windows/AdbWinApi.dll -------------------------------------------------------------------------------- /src/windows/AdbWinUsbApi.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LouWii/XiaomiADBFastbootTools/HEAD/src/windows/AdbWinUsbApi.dll -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.nar 17 | *.ear 18 | *.zip 19 | *.tar.gz 20 | *.rar 21 | 22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 23 | hs_err_pid* 24 | -------------------------------------------------------------------------------- /src/xiaomiadbfastboottools/App.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package xiaomiadbfastboottools; 7 | 8 | import javafx.beans.property.*; 9 | 10 | /** 11 | * 12 | * @author Saki 13 | */ 14 | public class App { 15 | private StringProperty appname = new SimpleStringProperty(); 16 | private StringProperty packagename = new SimpleStringProperty(); 17 | private BooleanProperty selected = new SimpleBooleanProperty(); 18 | 19 | public App(String a, String b) { 20 | appname.set(a); 21 | packagename.set(b); 22 | selected.set(false); 23 | } 24 | 25 | public StringProperty appnameProperty(){ 26 | return appname; 27 | } 28 | public StringProperty packagenameProperty(){ 29 | return packagename; 30 | } 31 | public BooleanProperty selectedProperty(){ 32 | return selected; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/xiaomiadbfastboottools/Uninstaller.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package xiaomiadbfastboottools; 7 | 8 | import java.io.IOException; 9 | import java.util.Arrays; 10 | import java.util.Scanner; 11 | import javafx.scene.control.TextInputControl; 12 | 13 | /** 14 | * 15 | * @author Saki 16 | */ 17 | public class Uninstaller extends Command { 18 | 19 | public Uninstaller(TextInputControl control){ 20 | super(control); 21 | tic.setText(""); 22 | } 23 | 24 | public void uninstall(App app){ 25 | pb.command(Arrays.asList((prefix + "adb shell pm uninstall --user 0 " + app.packagenameProperty().get()).split(" "))); 26 | pb.redirectErrorStream(false); 27 | output = ""; 28 | try { 29 | proc = pb.start(); 30 | } catch (IOException ex) { 31 | System.out.println("ERROR: Couldn't start process"); 32 | } 33 | scan = new Scanner(proc.getInputStream()); 34 | while (scan.hasNext()) { 35 | output += scan.nextLine() + System.lineSeparator(); 36 | } 37 | tic.appendText("App: " + app.appnameProperty().get() + System.lineSeparator()); 38 | tic.appendText("Package: " + app.packagenameProperty().get() + System.lineSeparator()); 39 | tic.appendText("Result: " + output + System.lineSeparator()); 40 | scan.close(); 41 | try { 42 | proc.waitFor(); 43 | } catch (InterruptedException ex) { 44 | System.out.println("ERROR: The process was interrupted."); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/xiaomiadbfastboottools/XiaomiADBFastbootTools.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package xiaomiadbfastboottools; 7 | 8 | import java.io.File; 9 | import java.io.IOException; 10 | import javafx.application.Application; 11 | import javafx.fxml.FXMLLoader; 12 | import javafx.scene.Parent; 13 | import javafx.scene.Scene; 14 | import javafx.scene.image.Image; 15 | import javafx.stage.Stage; 16 | import org.apache.commons.io.FileUtils; 17 | 18 | /** 19 | * 20 | * @author Saki 21 | */ 22 | public class XiaomiADBFastbootTools extends Application { 23 | 24 | @Override 25 | public void start(Stage stage) throws Exception { 26 | Parent root = FXMLLoader.load(getClass().getResource("MainWindow.fxml")); 27 | 28 | Scene scene = new Scene(root); 29 | 30 | stage.setScene(scene); 31 | stage.setTitle("Xiaomi ADB/Fastboot Tools"); 32 | stage.getIcons().add(new Image(this.getClass().getClassLoader().getResource("icon.png").toString())); 33 | stage.show(); 34 | stage.setResizable(false); 35 | } 36 | 37 | @Override 38 | public void stop(){ 39 | Command comm = new Command(); 40 | comm.exec("adb kill-server"); 41 | try { 42 | Thread.sleep(500); 43 | } catch (InterruptedException ex) { 44 | System.out.println("ERROR: Couldn't sleep!"); 45 | } 46 | try { 47 | FileUtils.deleteDirectory(new File(System.getProperty("user.dir") + "/temp")); 48 | } catch (IOException ex) { 49 | System.out.println("ERROR: Couldn't delete directory!"); 50 | } 51 | } 52 | 53 | /** 54 | * @param args the command line arguments 55 | */ 56 | public static void main(String[] args) { 57 | launch(args); 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Xiaomi ADB/Fastboot Tools 2 | 3 | **Features:** 4 | 5 | * **Debloater** \- Remove pre-installed apps and services on demand 6 | * **Camera2 & EIS Enabler** \- Enable camera2 and EIS (TWRP required) 7 | * **Read device properties** \- Retrieve tons of statistics and information about your phone 8 | * **Flasher** \- Flash any partition with an image or boot to any image (unlocked bootloader required) 9 | * **Wiper** \- Wipe the cache or perform a factory reset 10 | * **OEM Unlocker & Locker** \- Lock or unlock the bootloader \(Unlocking is supported by the Android One phones only\) 11 | * **Rebooter** \- Advanced rebooting options using ADB/Fastboot 12 | 13 | [Screenshot](https://i.imgur.com/F0Pd5l0.png) 14 | 15 | **Warning: Use the tool at your own risk. Removing factory apps which aren't in the tool may break your phone.** 16 | 17 | Download the binary and the instructions from [here](https://github.com/Saki-EU/XiaomiADBFastbootTools/releases/latest). 18 | 19 | **Frequently Asked Questions:** 20 | 21 | **Q:** The tool doesn't launch on my computer, is there anything I should have installed? 22 | 23 | * **A:** Yes, the tool was developed in Java and needs the Java Runtime Environment to run. You can download Java from [here](https://java.com/en/download/). On Linux, make sure adb and fastboot are installed system wide via APT. 24 | 25 | **Q:** The tool on Windows doesn't detect my phone even though it's connected and USB debugging is enabled. What's the problem? 26 | 27 | * **A:** Windows most likely does not recognise your phone in ADB. Install the universal ADB drivers from [here](http://dl.adbdriver.com/upload/adbdriver.zip). 28 | 29 | **Q:** Do I need an unlocked bootloader or root access to use the tool? 30 | 31 | * **A:** The Image Flasher, the Wiper and the Camera2 enabler require an unlocked bootloader but everything else works without rooting or unlocking. 32 | 33 | **Q:** Do uninstalled system apps affect OTA updates? 34 | 35 | * **A:** No, you are free to install updates without the fear of bricking your device or losing data. 36 | 37 | **Q:** The tool is called Xiaomi ADB/Fastboot Tools. Does that mean it only works with Xiaomi devices? 38 | 39 | * **A:** Well, ADB and Fastboot are universal interfaces for Android devices but some of the algorithms and methods used in the app are Xiaomi specific, so yes. 40 | 41 | **Q:** Does this replace MiFlash or MiUnlock? 42 | 43 | * **A:** No. Implementing their functionality in such a simple tool would only make it unnecessarily complex. 44 | -------------------------------------------------------------------------------- /src/xiaomiadbfastboottools/Command.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package xiaomiadbfastboottools; 7 | 8 | import java.io.File; 9 | import java.io.IOException; 10 | import java.util.Arrays; 11 | import java.util.Scanner; 12 | import javafx.scene.control.TextInputControl; 13 | 14 | /** 15 | * 16 | * @author Saki 17 | */ 18 | public class Command { 19 | protected ProcessBuilder pb; 20 | protected Process proc; 21 | protected Scanner scan; 22 | protected String output; 23 | protected TextInputControl tic; 24 | protected String prefix; 25 | 26 | public Command(){ 27 | pb = new ProcessBuilder(); 28 | pb.directory(new File(System.getProperty("user.dir") + "/temp")); 29 | tic = null; 30 | if (System.getProperty("os.name").toLowerCase().contains("linux")) 31 | prefix = ""; 32 | else if (System.getProperty("os.name").toLowerCase().contains("mac os")) 33 | prefix = "./"; 34 | else prefix = "temp/"; 35 | } 36 | 37 | public Command(TextInputControl control){ 38 | pb = new ProcessBuilder(); 39 | pb.directory(new File(System.getProperty("user.dir") + "/temp")); 40 | tic = control; 41 | if (System.getProperty("os.name").toLowerCase().contains("linux")) 42 | prefix = ""; 43 | else if (System.getProperty("os.name").toLowerCase().contains("mac os")) 44 | prefix = "./"; 45 | else prefix = "temp/"; 46 | } 47 | 48 | public String exec(String arg){ 49 | pb.command(Arrays.asList((prefix + arg).split(" "))); 50 | pb.redirectErrorStream(true); 51 | output = ""; 52 | if (tic != null) 53 | tic.setText(""); 54 | try { 55 | proc = pb.start(); 56 | } catch (IOException ex) { 57 | System.out.println("ERROR: Couldn't start process"); 58 | System.out.println(ex.getMessage()); 59 | } 60 | scan = new Scanner(proc.getInputStream()); 61 | String line; 62 | while (scan.hasNext()){ 63 | line = scan.nextLine() + System.lineSeparator(); 64 | output += line; 65 | if (tic != null) 66 | tic.appendText(line); 67 | } 68 | scan.close(); 69 | return output; 70 | } 71 | 72 | public String exec(String arg, boolean err){ 73 | pb.command(Arrays.asList((prefix + arg).split(" "))); 74 | pb.redirectErrorStream(false); 75 | output = ""; 76 | if (tic != null) 77 | tic.setText(""); 78 | try { 79 | proc = pb.start(); 80 | } catch (IOException ex) { 81 | System.out.println("ERROR: Couldn't start process"); 82 | System.out.println(ex.getMessage()); 83 | } 84 | if (err) 85 | scan = new Scanner(proc.getErrorStream()); 86 | else 87 | scan = new Scanner(proc.getInputStream()); 88 | String line; 89 | while (scan.hasNext()) { 90 | line = scan.nextLine() + System.lineSeparator(); 91 | output += line; 92 | if (tic != null) { 93 | tic.appendText(line); 94 | } 95 | } 96 | scan.close(); 97 | return output; 98 | } 99 | 100 | public String exec(String... args){ 101 | pb.redirectErrorStream(true); 102 | output = ""; 103 | if (tic != null) 104 | tic.setText(""); 105 | for (String s : args){ 106 | pb.command(Arrays.asList((prefix + s).split(" "))); 107 | try { 108 | proc = pb.start(); 109 | } catch (IOException ex) { 110 | System.out.println("ERROR: Couldn't start process"); 111 | } 112 | scan = new Scanner(proc.getInputStream()); 113 | String line; 114 | while (scan.hasNext()) { 115 | line = scan.nextLine() + System.lineSeparator(); 116 | output += line; 117 | if (tic != null) 118 | tic.appendText(line); 119 | } 120 | scan.close(); 121 | try { 122 | proc.waitFor(); 123 | } catch (InterruptedException ex) { 124 | System.out.println("ERROR: The process was interrupted."); 125 | } 126 | } 127 | return output; 128 | } 129 | 130 | public void waitFor(){ 131 | try { 132 | proc.waitFor(); 133 | } catch (InterruptedException ex) { 134 | System.out.println("ERROR: The process was interrupted."); 135 | } 136 | } 137 | 138 | public void kill(){ 139 | proc.destroy(); 140 | if (proc.isAlive()) 141 | proc.destroyForcibly(); 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /src/dummy.img: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/xiaomiadbfastboottools/MainWindowController.java: -------------------------------------------------------------------------------- 1 | package xiaomiadbfastboottools; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | import java.awt.Desktop; 6 | import java.io.*; 7 | import java.net.URI; 8 | import java.net.URISyntaxException; 9 | import java.net.URL; 10 | import java.util.Iterator; 11 | import java.util.ResourceBundle; 12 | import javafx.application.Platform; 13 | import javafx.collections.FXCollections; 14 | import javafx.collections.ObservableList; 15 | import javafx.event.ActionEvent; 16 | import javafx.event.EventHandler; 17 | import javafx.fxml.FXML; 18 | import javafx.fxml.Initializable; 19 | import javafx.geometry.Pos; 20 | import javafx.scene.Node; 21 | import javafx.scene.control.Alert; 22 | import javafx.scene.control.Alert.AlertType; 23 | import javafx.scene.control.Button; 24 | import javafx.scene.control.CheckBox; 25 | import javafx.scene.control.ComboBox; 26 | import javafx.scene.control.Hyperlink; 27 | import javafx.scene.control.Label; 28 | import javafx.scene.control.Menu; 29 | import javafx.scene.control.MenuItem; 30 | import javafx.scene.control.ProgressBar; 31 | import javafx.scene.control.Tab; 32 | import javafx.scene.control.TableColumn; 33 | import javafx.scene.control.TableView; 34 | import javafx.scene.control.TextArea; 35 | import javafx.scene.control.TextField; 36 | import javafx.scene.control.cell.CheckBoxTableCell; 37 | import javafx.scene.control.cell.PropertyValueFactory; 38 | import javafx.scene.image.Image; 39 | import javafx.scene.image.ImageView; 40 | import javafx.scene.layout.VBox; 41 | import javafx.scene.text.Font; 42 | import javafx.stage.FileChooser; 43 | import javafx.stage.StageStyle; 44 | 45 | import org.apache.commons.io.IOUtils; 46 | 47 | public class MainWindowController implements Initializable { 48 | 49 | @FXML 50 | private Menu optionsMenu; 51 | @FXML 52 | private MenuItem checkMenuItem; 53 | @FXML 54 | private Menu rebootMenu; 55 | @FXML 56 | private MenuItem systemMenuItem; 57 | @FXML 58 | private MenuItem recoveryMenuItem; 59 | @FXML 60 | private MenuItem fastbootMenuItem; 61 | @FXML 62 | private MenuItem edlMenuItem; 63 | @FXML 64 | private MenuItem aboutMenuItem; 65 | @FXML 66 | private Label serialLabel; 67 | @FXML 68 | private Label codenameLabel; 69 | @FXML 70 | private Label bootloaderLabel; 71 | @FXML 72 | private ProgressBar progressBar; 73 | @FXML 74 | private TextArea outputTextArea; 75 | @FXML 76 | private TableView debloaterTableView; 77 | @FXML 78 | private TableColumn checkTableColumn; 79 | @FXML 80 | private TableColumn appTableColumn; 81 | @FXML 82 | private TableColumn packageTableColumn; 83 | @FXML 84 | private TextField customappTextField; 85 | @FXML 86 | private Button uninstallButton; 87 | @FXML 88 | private Button addButton; 89 | @FXML 90 | private Button reboottwrpButton; 91 | @FXML 92 | private Button disableButton; 93 | @FXML 94 | private Button enableButton; 95 | @FXML 96 | private Button disableEISButton; 97 | @FXML 98 | private Button enableEISButton; 99 | @FXML 100 | private Button readpropertiesButton; 101 | @FXML 102 | private Button savepropertiesButton; 103 | @FXML 104 | private Button antirbButton; 105 | @FXML 106 | private Button browseimageButton; 107 | @FXML 108 | private ComboBox partitionComboBox; 109 | @FXML 110 | private Button flashButton; 111 | @FXML 112 | private CheckBox autobootCheckBox; 113 | @FXML 114 | private Label imageLabel; 115 | @FXML 116 | private Button bootButton; 117 | @FXML 118 | private Button cacheButton; 119 | @FXML 120 | private Button cachedataButton; 121 | @FXML 122 | private Button unlockButton; 123 | @FXML 124 | private Button lockButton; 125 | @FXML 126 | private Tab adbTab; 127 | @FXML 128 | private Tab fastbootTab; 129 | 130 | String image; 131 | Command comm; 132 | 133 | public void setupWidgets(){ 134 | serialLabel.setText("-"); 135 | codenameLabel.setText("-"); 136 | bootloaderLabel.setText("-"); 137 | partitionComboBox.getItems().addAll( 138 | "boot","cust","modem","persist","recovery","system"); 139 | image = ""; 140 | } 141 | 142 | public void setLabels(String serial, String codename, String bl){ 143 | serialLabel.setText(serial); 144 | codenameLabel.setText(codename); 145 | bootloaderLabel.setText(bl); 146 | } 147 | 148 | public void setADB(boolean adb){ 149 | adbTab.setDisable(!adb); 150 | recoveryMenuItem.setDisable(!adb); 151 | if (adb){ 152 | outputTextArea.setText("Device found!"); 153 | rebootMenu.setDisable(false); 154 | fastbootTab.setDisable(true); 155 | } else { 156 | rebootMenu.setDisable(true); 157 | outputTextArea.setText("No device found!"); 158 | setLabels("-", "-", "-"); 159 | } 160 | } 161 | 162 | public void setFastboot(boolean fastboot){ 163 | recoveryMenuItem.setDisable(fastboot); 164 | fastbootTab.setDisable(!fastboot); 165 | if (fastboot){ 166 | outputTextArea.setText("Device found!"); 167 | rebootMenu.setDisable(false); 168 | adbTab.setDisable(true); 169 | } else { 170 | rebootMenu.setDisable(true); 171 | outputTextArea.setText("No device found!"); 172 | setLabels("-", "-", "-"); 173 | } 174 | } 175 | 176 | public void createFile(String file){ 177 | createFile(file, false); 178 | } 179 | 180 | public void createFile(String file, Boolean setExecPermission){ 181 | File temp = new File(System.getProperty("user.dir") + "/temp"); 182 | temp.mkdir(); 183 | byte[] bytes = null; 184 | try { 185 | bytes = IOUtils.toByteArray(this.getClass().getClassLoader().getResourceAsStream(file)); 186 | } catch (IOException ex) { 187 | System.out.println("ERROR: Couldn't read resource."); 188 | } 189 | if (file.lastIndexOf("/") != -1) 190 | file = file.substring(file.lastIndexOf("/")+1); 191 | File newfile = new File(System.getProperty("user.dir") + "/temp/" + file); 192 | if (!newfile.exists()) { 193 | try { 194 | newfile.createNewFile(); 195 | FileOutputStream fos = new FileOutputStream(newfile); 196 | fos.write(bytes); 197 | fos.flush(); 198 | fos.close(); 199 | 200 | if (setExecPermission) { 201 | newfile = new File(System.getProperty("user.dir") + "/temp/" + file); 202 | newfile.setExecutable(true); 203 | } 204 | } catch (IOException ex) { 205 | System.out.println("ERROR: Couldn't create file."); 206 | } 207 | } 208 | } 209 | 210 | public void setupFiles(){ 211 | String os = System.getProperty("os.name").toLowerCase(); 212 | createFile("dummy.img"); 213 | if (os.contains("win")){ 214 | createFile("windows/adb.exe"); 215 | createFile("windows/fastboot.exe"); 216 | createFile("windows/AdbWinApi.dll"); 217 | createFile("windows/AdbWinUsbApi.dll"); 218 | } 219 | if (os.contains("mac")){ 220 | createFile("macos/adb", true); 221 | createFile("macos/fastboot", true); 222 | } 223 | } 224 | 225 | @Override 226 | public void initialize(URL url, ResourceBundle rb) { 227 | setupWidgets(); 228 | setupFiles(); 229 | comm = new Command(); 230 | comm.exec("adb start-server"); 231 | } 232 | 233 | public boolean checkFastboot(){ 234 | comm = new Command(); 235 | String op = comm.exec("fastboot devices", false); 236 | if (op.length() < 1) { 237 | setFastboot(false); 238 | return false; 239 | } 240 | String codename = comm.exec("fastboot getvar product", true); 241 | setFastboot(true); 242 | setLabels(op.substring(0, op.indexOf("fa")).trim(), codename.substring(9, codename.indexOf(System.lineSeparator())).trim(), "-"); 243 | op = comm.exec("fastboot oem device-info", true); 244 | if (op.contains("unlocked: true")) { 245 | bootloaderLabel.setText("unlocked"); 246 | } 247 | if (op.contains("unlocked: false")) { 248 | bootloaderLabel.setText("locked"); 249 | } 250 | return true; 251 | } 252 | 253 | public boolean checkADB(){ 254 | comm = new Command(); 255 | String op = comm.exec("adb get-serialno", true); 256 | if (op.contains("no devices")) { 257 | setADB(false); 258 | return false; 259 | } 260 | if (op.contains("unauthorized")) { 261 | setFastboot(false); 262 | outputTextArea.setText("Device unauthorised!\nPlease allow USB debugging!"); 263 | return false; 264 | } 265 | setADB(true); 266 | setLabels(comm.exec("adb get-serialno", false).trim(), comm.exec("adb shell getprop ro.product.name", false).trim(), "-"); 267 | op = comm.exec("adb shell getprop ro.boot.flash.locked", false); 268 | if (op.contains("0")) { 269 | bootloaderLabel.setText("unlocked"); 270 | } 271 | if (op.contains("1")) { 272 | bootloaderLabel.setText("locked"); 273 | } 274 | return true; 275 | } 276 | 277 | public boolean checkDevice(){ 278 | if (!checkFastboot()){ 279 | if(checkADB()){ 280 | createTable(); 281 | return true; 282 | } 283 | return false; 284 | } 285 | return true; 286 | } 287 | 288 | public boolean checkcamera2(){ 289 | comm = new Command(); 290 | return comm.exec("adb shell getprop persist.camera.HAL3.enabled").contains("1"); 291 | } 292 | 293 | public boolean checkEIS(){ 294 | comm = new Command(); 295 | return comm.exec("adb shell getprop persist.camera.eis.enable").contains("1"); 296 | } 297 | 298 | @SuppressWarnings("unchecked") 299 | public void createTable(){ 300 | debloaterTableView.setItems(getApps()); 301 | 302 | checkTableColumn.setCellValueFactory(new PropertyValueFactory<>("selected")); 303 | checkTableColumn.setCellFactory(tc -> new CheckBoxTableCell<>()); 304 | appTableColumn.setCellValueFactory(new PropertyValueFactory<>("appname")); 305 | packageTableColumn.setCellValueFactory(new PropertyValueFactory<>("packagename")); 306 | 307 | debloaterTableView.getColumns().setAll(checkTableColumn, appTableColumn, packageTableColumn); 308 | debloaterTableView.refresh(); 309 | } 310 | 311 | public ObservableList getApps(){ 312 | comm = new Command(); 313 | String installed = comm.exec("adb shell pm list packages"); 314 | ObservableList apps = FXCollections.observableArrayList(); 315 | apps.add(new App("Analytics", "com.miui.analytics")); 316 | apps.add(new App("App Vault", "com.miui.personalassistant")); 317 | apps.add(new App("App Vault", "com.mi.android.globalpersonalassistant")); 318 | apps.add(new App("Apps (Mi App Store)", "com.xiaomi.mipicks")); 319 | apps.add(new App("Browser", "com.android.browser")); 320 | apps.add(new App("Calculator", "com.google.android.calculator")); 321 | apps.add(new App("Calculator", "com.miui.calculator")); 322 | apps.add(new App("Calendar", "com.android.calendar")); 323 | apps.add(new App("Calendar", "com.google.android.calendar")); 324 | apps.add(new App("Cleaner", "com.miui.cleanmaster")); 325 | apps.add(new App("Clock", "com.android.deskclock")); 326 | apps.add(new App("Clock", "com.google.android.deskclock")); 327 | apps.add(new App("Compass", "com.miui.compass")); 328 | apps.add(new App("Direct Service / Quick Apps", "com.miui.hybrid")); 329 | apps.add(new App("Downloads", "com.android.providers.downloads.ui")); 330 | apps.add(new App("Facebook", "com.facebook.katana")); 331 | apps.add(new App("Facebook App Installer", "com.facebook.system")); 332 | apps.add(new App("Facebook App Manager", "com.facebook.appmanager")); 333 | apps.add(new App("Facebook Services", "com.facebook.services")); 334 | apps.add(new App("Feedback", "com.miui.bugreport")); 335 | apps.add(new App("File Manager", "com.mi.android.globalFileexplorer")); 336 | apps.add(new App("File Manager", "com.android.fileexplorer")); 337 | apps.add(new App("Files", "com.android.documentsui")); 338 | apps.add(new App("FM Radio", "com.miui.fm")); 339 | apps.add(new App("Gmail", "com.google.android.gm")); 340 | apps.add(new App("Google App", "com.google.android.googlequicksearchbox")); 341 | apps.add(new App("Google Assistant", "com.google.android.apps.googleassistant")); 342 | apps.add(new App("Google Chrome", "com.android.chrome")); 343 | apps.add(new App("Google Drive", "com.google.android.apps.docs")); 344 | apps.add(new App("Google Duo", "com.google.android.apps.tachyon")); 345 | apps.add(new App("Google Hangouts", "com.google.android.talk")); 346 | apps.add(new App("Google Indic Keyboard", "com.google.android.apps.inputmethod.hindi")); 347 | apps.add(new App("Google Keep", "com.google.android.keep")); 348 | apps.add(new App("Google Korean Input", "com.google.android.inputmethod.korean")); 349 | apps.add(new App("Google Maps", "com.google.android.apps.maps")); 350 | apps.add(new App("Google Photos", "com.google.android.apps.photos")); 351 | apps.add(new App("Google Pinyin Input", "com.google.android.inputmethod.pinyin")); 352 | apps.add(new App("Google Play Books", "com.google.android.apps.books")); 353 | apps.add(new App("Google Play Games", "com.google.android.play.games")); 354 | apps.add(new App("Google Play Movies", "com.google.android.videos")); 355 | apps.add(new App("Google Play Music", "com.google.android.music")); 356 | apps.add(new App("Google Zhuyin Input", "com.google.android.apps.inputmethod.zhuyin")); 357 | apps.add(new App("KLO Bugreport", "com.miui.klo.bugreport")); 358 | apps.add(new App("Mab", "com.xiaomi.ab")); 359 | apps.add(new App("Mail", "com.android.email")); 360 | apps.add(new App("Mi AI", "com.miui.voiceassist")); 361 | apps.add(new App("Mi Cloud", "com.miui.cloudservice")); 362 | apps.add(new App("Mi Cloud Backup", "com.miui.cloudbackup")); 363 | apps.add(new App("Mi Credit", "com.xiaomi.payment")); 364 | apps.add(new App("Mi Drop", "com.xiaomi.midrop")); 365 | apps.add(new App("Mi Roaming", "com.miui.virtualsim")); 366 | apps.add(new App("Mi Video", "com.miui.video")); 367 | apps.add(new App("Mi Video", "com.miui.videoplayer")); 368 | apps.add(new App("Mi Wallet", "com.mipay.wallet")); 369 | apps.add(new App("MiuiDaemon", "com.miui.daemon")); 370 | apps.add(new App("Mobile Device Information Provider", "com.amazon.appmanager")); 371 | apps.add(new App("Msa", "com.miui.msa.global")); 372 | apps.add(new App("Msa", "com.miui.systemAdSolution")); 373 | apps.add(new App("Music", "com.miui.player")); 374 | apps.add(new App("Notes", "com.miui.notes")); 375 | apps.add(new App("PAI", "android.autoinstalls.config.Xiaomi.tissot")); 376 | apps.add(new App("Recorder", "com.android.soundrecorder")); 377 | apps.add(new App("Scanner", "com.xiaomi.scanner")); 378 | apps.add(new App("Screen Recorder", "com.miui.screenrecorder")); 379 | apps.add(new App("Search", "com.android.quicksearchbox")); 380 | apps.add(new App("Weather", "com.miui.weather2")); 381 | apps.add(new App("Xiaomi Account", "com.xiaomi.vipaccount")); 382 | apps.add(new App("Xiaomi SIM Activate Service", "com.xiaomi.simactivate.service")); 383 | apps.add(new App("Yellow Pages", "com.miui.yellowpage")); 384 | apps.add(new App("YouTube", "com.google.android.youtube")); 385 | for (Iterator iterator = apps.iterator(); iterator.hasNext();) { 386 | if (!installed.contains(iterator.next().packagenameProperty().get() + System.lineSeparator())) 387 | iterator.remove(); 388 | } 389 | return apps; 390 | } 391 | 392 | @FXML 393 | private void checkMenuItemPressed(ActionEvent event) { 394 | checkDevice(); 395 | } 396 | 397 | @FXML 398 | private void reboottwrpButtonPressed(ActionEvent event) { 399 | if (checkADB()){ 400 | comm = new Command(); 401 | if (comm.exec("adb devices").contains("recovery")){ 402 | outputTextArea.setText("Device already in recovery mode!"); 403 | } else { 404 | comm = new Command(outputTextArea); 405 | comm.exec("adb reboot recovery"); 406 | } 407 | } 408 | } 409 | 410 | @FXML 411 | private void disableButtonPressed(ActionEvent event) { 412 | if (checkADB()) { 413 | comm = new Command(); 414 | if (!comm.exec("adb devices").contains("recovery")){ 415 | outputTextArea.setText("ERROR: No device found in recovery mode!"); 416 | return; 417 | } 418 | comm.exec("adb shell setprop persist.camera.HAL3.enabled 0"); 419 | if(!checkcamera2()) 420 | outputTextArea.setText("Disabled!"); 421 | else outputTextArea.setText("ERROR: Couldn't disable!"); 422 | } 423 | } 424 | 425 | @FXML 426 | private void enableButtonPressed(ActionEvent event) { 427 | if (checkADB()) { 428 | comm = new Command(); 429 | if (!comm.exec("adb devices").contains("recovery")){ 430 | outputTextArea.setText("ERROR: No device found in recovery mode!"); 431 | return; 432 | } 433 | comm.exec("adb shell setprop persist.camera.HAL3.enabled 1"); 434 | if(checkcamera2()) 435 | outputTextArea.setText("Enabled!"); 436 | else outputTextArea.setText("ERROR: Couldn't enable!"); 437 | } 438 | } 439 | 440 | @FXML 441 | private void disableEISButtonPressed(ActionEvent event) { 442 | if (checkADB()) { 443 | comm = new Command(); 444 | if (!comm.exec("adb devices").contains("recovery")){ 445 | outputTextArea.setText("ERROR: No device found in recovery mode!"); 446 | return; 447 | } 448 | comm.exec("adb shell setprop persist.camera.eis.enable 0"); 449 | if(!checkEIS()) 450 | outputTextArea.setText("Disabled!"); 451 | else outputTextArea.setText("ERROR: Couldn't disable!"); 452 | } 453 | } 454 | 455 | @FXML 456 | private void enableEISButtonPressed(ActionEvent event) { 457 | if (checkADB()) { 458 | comm = new Command(); 459 | if (!comm.exec("adb devices").contains("recovery")){ 460 | outputTextArea.setText("ERROR: No device found in recovery mode!"); 461 | return; 462 | } 463 | comm.exec("adb shell setprop persist.camera.eis.enable 1"); 464 | if(checkEIS()) 465 | outputTextArea.setText("Enabled!"); 466 | else outputTextArea.setText("ERROR: Couldn't enable!"); 467 | } 468 | } 469 | 470 | @FXML 471 | private void readpropertiesButtonPressed(ActionEvent event) { 472 | if (checkADB()){ 473 | comm = new Command(outputTextArea); 474 | comm.exec("adb shell getprop"); 475 | } 476 | } 477 | 478 | @FXML 479 | private void savepropertiesButtonPressed(ActionEvent event) { 480 | FileChooser fc = new FileChooser(); 481 | FileChooser.ExtensionFilter fileExtensions = new FileChooser.ExtensionFilter("Text File (.txt)", "*.txt"); 482 | fc.getExtensionFilters().add(fileExtensions); 483 | fc.setTitle("Save properties"); 484 | File f = fc.showSaveDialog(((Node)event.getSource()).getScene().getWindow()); 485 | if (f != null){ 486 | FileWriter fw = null; 487 | comm = new Command(); 488 | try { 489 | fw = new FileWriter(f); 490 | fw.write(comm.exec("adb shell getprop")); 491 | fw.flush(); 492 | fw.close(); 493 | } catch (IOException ex) { 494 | System.out.println("ERROR: Couldn't write file."); 495 | } 496 | } 497 | } 498 | 499 | @FXML 500 | private void antirbButtonPressed(ActionEvent event) { 501 | if (checkFastboot()) { 502 | comm = new Command(outputTextArea); 503 | comm.exec("fastboot flash antirbpass dummy.img"); 504 | } 505 | } 506 | 507 | @FXML 508 | private void browseimageButtonPressed(ActionEvent event) { 509 | FileChooser fc = new FileChooser(); 510 | FileChooser.ExtensionFilter fileExtensions = new FileChooser.ExtensionFilter("Image File", "*.*"); 511 | fc.getExtensionFilters().add(fileExtensions); 512 | fc.setTitle("Select an image"); 513 | File f = fc.showOpenDialog(((Node) event.getSource()).getScene().getWindow()); 514 | if (f != null) { 515 | image = f.getAbsolutePath(); 516 | imageLabel.setText(image.substring(image.lastIndexOf(File.separator)+1)); 517 | } 518 | } 519 | 520 | @FXML 521 | private void flashButtonPressed(ActionEvent event) { 522 | if (image.length() > 1 && partitionComboBox.getValue() != null && partitionComboBox.getValue().trim().length() > 0 && checkFastboot()) { 523 | comm = new Command(outputTextArea); 524 | if (autobootCheckBox.isSelected() && partitionComboBox.getValue().trim() == "recovery") 525 | comm.exec("fastboot flash " + partitionComboBox.getValue().trim() + " " + image, "fastboot boot " + image); 526 | else comm.exec("fastboot flash " + partitionComboBox.getValue().trim() + " " + image); 527 | } 528 | } 529 | 530 | @FXML 531 | private void bootButtonPressed(ActionEvent event) { 532 | if (image.length() > 1 && checkFastboot()) { 533 | comm = new Command(outputTextArea); 534 | comm.exec("fastboot boot " + image); 535 | } 536 | } 537 | 538 | @FXML 539 | private void cacheButtonPressed(ActionEvent event) { 540 | if (checkFastboot()) { 541 | comm = new Command(outputTextArea); 542 | comm.exec("fastboot erase cache"); 543 | } 544 | } 545 | 546 | @FXML 547 | private void cachedataButtonPressed(ActionEvent event) { 548 | if (checkFastboot()) { 549 | comm = new Command(outputTextArea); 550 | comm.exec("fastboot erase cache", "fastboot erase userdata"); 551 | } 552 | } 553 | 554 | @FXML 555 | private void lockButtonPressed(ActionEvent event) { 556 | if (checkFastboot()) { 557 | comm = new Command(outputTextArea); 558 | comm.exec("fastboot oem lock"); 559 | } 560 | } 561 | 562 | @FXML 563 | private void unlockButtonPressed(ActionEvent event) { 564 | if (checkFastboot()) { 565 | comm = new Command(outputTextArea); 566 | comm.exec("fastboot oem unlock"); 567 | } 568 | } 569 | 570 | @FXML 571 | private void systemMenuItemPressed(ActionEvent event) { 572 | if (checkADB()){ 573 | comm = new Command(outputTextArea); 574 | comm.exec("adb reboot"); 575 | } else if (checkFastboot()) { 576 | comm = new Command(outputTextArea); 577 | comm.exec("fastboot reboot"); 578 | } 579 | } 580 | 581 | @FXML 582 | private void recoveryMenuItemPressed(ActionEvent event) { 583 | if (checkADB()) { 584 | comm = new Command(outputTextArea); 585 | comm.exec("adb reboot recovery"); 586 | } 587 | } 588 | 589 | @FXML 590 | private void fastbootMenuItemPressed(ActionEvent event) { 591 | if (checkADB()) { 592 | comm = new Command(outputTextArea); 593 | comm.exec("adb reboot bootloader"); 594 | } else if (checkFastboot()) { 595 | comm = new Command(outputTextArea); 596 | comm.exec("fastboot reboot bootloader"); 597 | } 598 | } 599 | 600 | @FXML 601 | private void edlMenuItemPressed(ActionEvent event) { 602 | if (checkADB()) { 603 | comm = new Command(outputTextArea); 604 | comm.exec("adb reboot edl"); 605 | } else if (checkFastboot()) { 606 | comm = new Command(outputTextArea); 607 | comm.exec("fastboot oem edl"); 608 | } 609 | } 610 | 611 | @FXML 612 | private void uninstallButtonPressed(ActionEvent event) { 613 | if (checkADB()){ 614 | progressBar.setProgress(-1); 615 | Thread t = new Thread(() -> { 616 | Uninstaller comm = new Uninstaller(outputTextArea); 617 | for (App app : debloaterTableView.getItems()) { 618 | if (app.selectedProperty().get()) { 619 | comm.uninstall(app); 620 | } 621 | } 622 | Platform.runLater(() -> { 623 | createTable(); 624 | progressBar.setProgress(0); 625 | }); 626 | }); 627 | t.start(); 628 | } 629 | } 630 | 631 | @FXML 632 | private void addButtonPressed(ActionEvent event) { 633 | if (customappTextField.getText() != null && customappTextField.getText().trim().length() > 1) 634 | debloaterTableView.getItems().add(new App(customappTextField.getText().trim(), customappTextField.getText().trim())); 635 | customappTextField.setText(null); 636 | debloaterTableView.refresh(); 637 | } 638 | 639 | @FXML 640 | private void aboutMenuItemPressed(ActionEvent event) { 641 | Alert alert = new Alert(AlertType.INFORMATION); 642 | alert.initStyle(StageStyle.UTILITY); 643 | alert.setTitle("About"); 644 | alert.setGraphic(new ImageView(new Image(this.getClass().getClassLoader().getResource("smallicon.png").toString()))); 645 | alert.setHeaderText("Xiaomi ADB/Fastboot Tools" + System.lineSeparator() + "Version 3.0.0" + System.lineSeparator() + "Created by Saki_EU"); 646 | VBox vb = new VBox(); 647 | vb.setAlignment(Pos.CENTER); 648 | 649 | Hyperlink reddit = new Hyperlink("r/Xiaomi on Reddit"); 650 | reddit.setOnAction(new EventHandler() { 651 | @Override 652 | public void handle(ActionEvent e) { 653 | try { 654 | Desktop.getDesktop().browse(new URI("https://www.reddit.com/r/Xiaomi")); 655 | } catch (IOException | URISyntaxException e1) { 656 | System.out.println("ERROR: Couldn't open website!"); 657 | } 658 | } 659 | }); 660 | reddit.setFont(new Font(14)); 661 | Hyperlink discord = new Hyperlink("r/Xiaomi on Discord"); 662 | discord.setOnAction(new EventHandler() { 663 | @Override 664 | public void handle(ActionEvent e) { 665 | try { 666 | Desktop.getDesktop().browse(new URI("https://discord.gg/xiaomi")); 667 | } catch (IOException | URISyntaxException e1) { 668 | System.out.println("ERROR: Couldn't open website!"); 669 | } 670 | } 671 | }); 672 | discord.setFont(new Font(14)); 673 | Hyperlink github = new Hyperlink("This project on GitHub"); 674 | github.setOnAction(new EventHandler() { 675 | @Override 676 | public void handle(ActionEvent e) { 677 | try { 678 | Desktop.getDesktop().browse(new URI("https://github.com/Saki-EU/XiaomiADBFastbootTools")); 679 | } catch (IOException | URISyntaxException e1) { 680 | System.out.println("ERROR: Couldn't open website!"); 681 | } 682 | } 683 | }); 684 | github.setFont(new Font(14)); 685 | 686 | vb.getChildren().addAll(reddit, discord, github); 687 | alert.getDialogPane().setContent(vb); 688 | alert.showAndWait(); 689 | } 690 | 691 | } 692 | -------------------------------------------------------------------------------- /src/xiaomiadbfastboottools/MainWindow.fxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 71 | 76 | 81 | 86 | 91 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 |
112 |