1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.commands.sm; 18 19 import android.os.IVoldTaskListener; 20 import android.os.PersistableBundle; 21 import android.os.RemoteException; 22 import android.os.ServiceManager; 23 import android.os.storage.DiskInfo; 24 import android.os.storage.IStorageManager; 25 import android.os.storage.StorageManager; 26 import android.os.storage.VolumeInfo; 27 import android.util.Log; 28 29 import java.util.concurrent.CompletableFuture; 30 31 public final class Sm { 32 private static final String TAG = "Sm"; 33 34 IStorageManager mSm; 35 36 private String[] mArgs; 37 private int mNextArg; 38 private String mCurArgData; 39 main(String[] args)40 public static void main(String[] args) { 41 boolean success = false; 42 try { 43 new Sm().run(args); 44 success = true; 45 } catch (Exception e) { 46 if (e instanceof IllegalArgumentException) { 47 showUsage(); 48 System.exit(1); 49 } 50 Log.e(TAG, "Error", e); 51 System.err.println("Error: " + e); 52 } 53 System.exit(success ? 0 : 1); 54 } 55 run(String[] args)56 public void run(String[] args) throws Exception { 57 if (args.length < 1) { 58 throw new IllegalArgumentException(); 59 } 60 61 mSm = IStorageManager.Stub.asInterface(ServiceManager.getService("mount")); 62 if (mSm == null) { 63 throw new RemoteException("Failed to find running mount service"); 64 } 65 66 mArgs = args; 67 String op = args[0]; 68 mNextArg = 1; 69 70 if ("list-disks".equals(op)) { 71 runListDisks(); 72 } else if ("list-volumes".equals(op)) { 73 runListVolumes(); 74 } else if ("has-adoptable".equals(op)) { 75 runHasAdoptable(); 76 } else if ("get-primary-storage-uuid".equals(op)) { 77 runGetPrimaryStorageUuid(); 78 } else if ("set-force-adoptable".equals(op)) { 79 runSetForceAdoptable(); 80 } else if ("set-sdcardfs".equals(op)) { 81 runSetSdcardfs(); 82 } else if ("partition".equals(op)) { 83 runPartition(); 84 } else if ("mount".equals(op)) { 85 runMount(); 86 } else if ("unmount".equals(op)) { 87 runUnmount(); 88 } else if ("format".equals(op)) { 89 runFormat(); 90 } else if ("benchmark".equals(op)) { 91 runBenchmark(); 92 } else if ("forget".equals(op)) { 93 runForget(); 94 } else if ("set-emulate-fbe".equals(op)) { 95 runSetEmulateFbe(); 96 } else if ("get-fbe-mode".equals(op)) { 97 runGetFbeMode(); 98 } else if ("idle-maint".equals(op)) { 99 runIdleMaint(); 100 } else if ("fstrim".equals(op)) { 101 runFstrim(); 102 } else if ("set-virtual-disk".equals(op)) { 103 runSetVirtualDisk(); 104 } else if ("set-isolated-storage".equals(op)) { 105 runIsolatedStorage(); 106 } else { 107 throw new IllegalArgumentException(); 108 } 109 } 110 runListDisks()111 public void runListDisks() throws RemoteException { 112 final boolean onlyAdoptable = "adoptable".equals(nextArg()); 113 final DiskInfo[] disks = mSm.getDisks(); 114 for (DiskInfo disk : disks) { 115 if (!onlyAdoptable || disk.isAdoptable()) { 116 System.out.println(disk.getId()); 117 } 118 } 119 } 120 runListVolumes()121 public void runListVolumes() throws RemoteException { 122 final String filter = nextArg(); 123 final int filterType; 124 if ("public".equals(filter)) { 125 filterType = VolumeInfo.TYPE_PUBLIC; 126 } else if ("private".equals(filter)) { 127 filterType = VolumeInfo.TYPE_PRIVATE; 128 } else if ("emulated".equals(filter)) { 129 filterType = VolumeInfo.TYPE_EMULATED; 130 } else if ("stub".equals(filter)) { 131 filterType = VolumeInfo.TYPE_STUB; 132 } else { 133 filterType = -1; 134 } 135 136 final VolumeInfo[] vols = mSm.getVolumes(0); 137 for (VolumeInfo vol : vols) { 138 if (filterType == -1 || filterType == vol.getType()) { 139 final String envState = VolumeInfo.getEnvironmentForState(vol.getState()); 140 System.out.println(vol.getId() + " " + envState + " " + vol.getFsUuid()); 141 } 142 } 143 } 144 runHasAdoptable()145 public void runHasAdoptable() { 146 System.out.println(StorageManager.hasAdoptable()); 147 } 148 runGetPrimaryStorageUuid()149 public void runGetPrimaryStorageUuid() throws RemoteException { 150 System.out.println(mSm.getPrimaryStorageUuid()); 151 } 152 runSetForceAdoptable()153 public void runSetForceAdoptable() throws RemoteException { 154 final int mask = StorageManager.DEBUG_ADOPTABLE_FORCE_ON 155 | StorageManager.DEBUG_ADOPTABLE_FORCE_OFF; 156 switch (nextArg()) { 157 case "on": 158 case "true": 159 mSm.setDebugFlags(StorageManager.DEBUG_ADOPTABLE_FORCE_ON, mask); 160 break; 161 case "off": 162 mSm.setDebugFlags(StorageManager.DEBUG_ADOPTABLE_FORCE_OFF, mask); 163 break; 164 case "default": 165 case "false": 166 mSm.setDebugFlags(0, mask); 167 break; 168 } 169 } 170 runSetSdcardfs()171 public void runSetSdcardfs() throws RemoteException { 172 final int mask = StorageManager.DEBUG_SDCARDFS_FORCE_ON 173 | StorageManager.DEBUG_SDCARDFS_FORCE_OFF; 174 switch (nextArg()) { 175 case "on": 176 mSm.setDebugFlags(StorageManager.DEBUG_SDCARDFS_FORCE_ON, mask); 177 break; 178 case "off": 179 mSm.setDebugFlags(StorageManager.DEBUG_SDCARDFS_FORCE_OFF, mask); 180 break; 181 case "default": 182 mSm.setDebugFlags(0, mask); 183 break; 184 } 185 } 186 runSetEmulateFbe()187 public void runSetEmulateFbe() throws RemoteException { 188 final boolean emulateFbe = Boolean.parseBoolean(nextArg()); 189 mSm.setDebugFlags(emulateFbe ? StorageManager.DEBUG_EMULATE_FBE : 0, 190 StorageManager.DEBUG_EMULATE_FBE); 191 } 192 runGetFbeMode()193 public void runGetFbeMode() { 194 if (StorageManager.isFileEncryptedNativeOnly()) { 195 System.out.println("native"); 196 } else if (StorageManager.isFileEncryptedEmulatedOnly()) { 197 System.out.println("emulated"); 198 } else { 199 System.out.println("none"); 200 } 201 } 202 runPartition()203 public void runPartition() throws RemoteException { 204 final String diskId = nextArg(); 205 final String type = nextArg(); 206 if ("public".equals(type)) { 207 mSm.partitionPublic(diskId); 208 } else if ("private".equals(type)) { 209 mSm.partitionPrivate(diskId); 210 } else if ("mixed".equals(type)) { 211 final int ratio = Integer.parseInt(nextArg()); 212 mSm.partitionMixed(diskId, ratio); 213 } else { 214 throw new IllegalArgumentException("Unsupported partition type " + type); 215 } 216 } 217 runMount()218 public void runMount() throws RemoteException { 219 final String volId = nextArg(); 220 mSm.mount(volId); 221 } 222 runUnmount()223 public void runUnmount() throws RemoteException { 224 final String volId = nextArg(); 225 mSm.unmount(volId); 226 } 227 runFormat()228 public void runFormat() throws RemoteException { 229 final String volId = nextArg(); 230 mSm.format(volId); 231 } 232 runBenchmark()233 public void runBenchmark() throws Exception { 234 final String volId = nextArg(); 235 final CompletableFuture<PersistableBundle> result = new CompletableFuture<>(); 236 mSm.benchmark(volId, new IVoldTaskListener.Stub() { 237 @Override 238 public void onStatus(int status, PersistableBundle extras) { 239 // Ignored 240 } 241 242 @Override 243 public void onFinished(int status, PersistableBundle extras) { 244 // Touch to unparcel 245 extras.size(); 246 result.complete(extras); 247 } 248 }); 249 System.out.println(result.get()); 250 } 251 runForget()252 public void runForget() throws RemoteException { 253 final String fsUuid = nextArg(); 254 if ("all".equals(fsUuid)) { 255 mSm.forgetAllVolumes(); 256 } else { 257 mSm.forgetVolume(fsUuid); 258 } 259 } 260 runFstrim()261 public void runFstrim() throws Exception { 262 final CompletableFuture<PersistableBundle> result = new CompletableFuture<>(); 263 mSm.fstrim(0, new IVoldTaskListener.Stub() { 264 @Override 265 public void onStatus(int status, PersistableBundle extras) { 266 // Ignored 267 } 268 269 @Override 270 public void onFinished(int status, PersistableBundle extras) { 271 // Touch to unparcel 272 extras.size(); 273 result.complete(extras); 274 } 275 }); 276 System.out.println(result.get()); 277 } 278 runSetVirtualDisk()279 public void runSetVirtualDisk() throws RemoteException { 280 final boolean virtualDisk = Boolean.parseBoolean(nextArg()); 281 mSm.setDebugFlags(virtualDisk ? StorageManager.DEBUG_VIRTUAL_DISK : 0, 282 StorageManager.DEBUG_VIRTUAL_DISK); 283 } 284 runIsolatedStorage()285 public void runIsolatedStorage() throws RemoteException { 286 final int value; 287 final int mask = StorageManager.DEBUG_ISOLATED_STORAGE_FORCE_ON 288 | StorageManager.DEBUG_ISOLATED_STORAGE_FORCE_OFF; 289 switch (nextArg()) { 290 case "on": 291 case "true": 292 value = StorageManager.DEBUG_ISOLATED_STORAGE_FORCE_ON; 293 break; 294 case "off": 295 value = StorageManager.DEBUG_ISOLATED_STORAGE_FORCE_OFF; 296 break; 297 case "default": 298 case "false": 299 value = 0; 300 break; 301 default: 302 return; 303 } 304 mSm.setDebugFlags(value, mask); 305 } 306 runIdleMaint()307 public void runIdleMaint() throws RemoteException { 308 final boolean im_run = "run".equals(nextArg()); 309 if (im_run) { 310 mSm.runIdleMaintenance(); 311 } else { 312 mSm.abortIdleMaintenance(); 313 } 314 } 315 nextArg()316 private String nextArg() { 317 if (mNextArg >= mArgs.length) { 318 return null; 319 } 320 String arg = mArgs[mNextArg]; 321 mNextArg++; 322 return arg; 323 } 324 showUsage()325 private static int showUsage() { 326 System.err.println("usage: sm list-disks [adoptable]"); 327 System.err.println(" sm list-volumes [public|private|emulated|stub|all]"); 328 System.err.println(" sm has-adoptable"); 329 System.err.println(" sm get-primary-storage-uuid"); 330 System.err.println(" sm set-force-adoptable [on|off|default]"); 331 System.err.println(" sm set-virtual-disk [true|false]"); 332 System.err.println(""); 333 System.err.println(" sm partition DISK [public|private|mixed] [ratio]"); 334 System.err.println(" sm mount VOLUME"); 335 System.err.println(" sm unmount VOLUME"); 336 System.err.println(" sm format VOLUME"); 337 System.err.println(" sm benchmark VOLUME"); 338 System.err.println(" sm idle-maint [run|abort]"); 339 System.err.println(" sm fstrim"); 340 System.err.println(""); 341 System.err.println(" sm forget [UUID|all]"); 342 System.err.println(""); 343 System.err.println(" sm set-emulate-fbe [true|false]"); 344 System.err.println(""); 345 System.err.println(" sm set-isolated-storage [on|off|default]"); 346 System.err.println(""); 347 return 1; 348 } 349 } 350