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 17package com.android.commands.sm; 18 19import android.os.RemoteException; 20import android.os.ServiceManager; 21import android.os.SystemProperties; 22import android.os.storage.DiskInfo; 23import android.os.storage.IMountService; 24import android.os.storage.StorageManager; 25import android.os.storage.VolumeInfo; 26import android.util.Log; 27 28public final class Sm { 29 private static final String TAG = "Sm"; 30 31 IMountService mSm; 32 33 private String[] mArgs; 34 private int mNextArg; 35 private String mCurArgData; 36 37 public static void main(String[] args) { 38 boolean success = false; 39 try { 40 new Sm().run(args); 41 success = true; 42 } catch (Exception e) { 43 if (e instanceof IllegalArgumentException) { 44 showUsage(); 45 System.exit(1); 46 } 47 Log.e(TAG, "Error", e); 48 System.err.println("Error: " + e); 49 } 50 System.exit(success ? 0 : 1); 51 } 52 53 public void run(String[] args) throws Exception { 54 if (args.length < 1) { 55 throw new IllegalArgumentException(); 56 } 57 58 mSm = IMountService.Stub.asInterface(ServiceManager.getService("mount")); 59 if (mSm == null) { 60 throw new RemoteException("Failed to find running mount service"); 61 } 62 63 mArgs = args; 64 String op = args[0]; 65 mNextArg = 1; 66 67 if ("list-disks".equals(op)) { 68 runListDisks(); 69 } else if ("list-volumes".equals(op)) { 70 runListVolumes(); 71 } else if ("has-adoptable".equals(op)) { 72 runHasAdoptable(); 73 } else if ("get-primary-storage-uuid".equals(op)) { 74 runGetPrimaryStorageUuid(); 75 } else if ("set-force-adoptable".equals(op)) { 76 runSetForceAdoptable(); 77 } else if ("set-sdcardfs".equals(op)) { 78 runSetSdcardfs(); 79 } else if ("partition".equals(op)) { 80 runPartition(); 81 } else if ("mount".equals(op)) { 82 runMount(); 83 } else if ("unmount".equals(op)) { 84 runUnmount(); 85 } else if ("format".equals(op)) { 86 runFormat(); 87 } else if ("benchmark".equals(op)) { 88 runBenchmark(); 89 } else if ("forget".equals(op)) { 90 runForget(); 91 } else if ("set-emulate-fbe".equals(op)) { 92 runSetEmulateFbe(); 93 } else if ("get-fbe-mode".equals(op)) { 94 runGetFbeMode(); 95 } else { 96 throw new IllegalArgumentException(); 97 } 98 } 99 100 public void runListDisks() throws RemoteException { 101 final boolean onlyAdoptable = "adoptable".equals(nextArg()); 102 final DiskInfo[] disks = mSm.getDisks(); 103 for (DiskInfo disk : disks) { 104 if (!onlyAdoptable || disk.isAdoptable()) { 105 System.out.println(disk.getId()); 106 } 107 } 108 } 109 110 public void runListVolumes() throws RemoteException { 111 final String filter = nextArg(); 112 final int filterType; 113 if ("public".equals(filter)) { 114 filterType = VolumeInfo.TYPE_PUBLIC; 115 } else if ("private".equals(filter)) { 116 filterType = VolumeInfo.TYPE_PRIVATE; 117 } else if ("emulated".equals(filter)) { 118 filterType = VolumeInfo.TYPE_EMULATED; 119 } else { 120 filterType = -1; 121 } 122 123 final VolumeInfo[] vols = mSm.getVolumes(0); 124 for (VolumeInfo vol : vols) { 125 if (filterType == -1 || filterType == vol.getType()) { 126 final String envState = VolumeInfo.getEnvironmentForState(vol.getState()); 127 System.out.println(vol.getId() + " " + envState + " " + vol.getFsUuid()); 128 } 129 } 130 } 131 132 public void runHasAdoptable() { 133 System.out.println(SystemProperties.getBoolean(StorageManager.PROP_HAS_ADOPTABLE, false)); 134 } 135 136 public void runGetPrimaryStorageUuid() throws RemoteException { 137 System.out.println(mSm.getPrimaryStorageUuid()); 138 } 139 140 public void runSetForceAdoptable() throws RemoteException { 141 final boolean forceAdoptable = Boolean.parseBoolean(nextArg()); 142 mSm.setDebugFlags(forceAdoptable ? StorageManager.DEBUG_FORCE_ADOPTABLE : 0, 143 StorageManager.DEBUG_FORCE_ADOPTABLE); 144 } 145 146 public void runSetSdcardfs() throws RemoteException { 147 final int mask = StorageManager.DEBUG_SDCARDFS_FORCE_ON 148 | StorageManager.DEBUG_SDCARDFS_FORCE_OFF; 149 switch (nextArg()) { 150 case "on": 151 mSm.setDebugFlags(StorageManager.DEBUG_SDCARDFS_FORCE_ON, mask); 152 break; 153 case "off": 154 mSm.setDebugFlags(StorageManager.DEBUG_SDCARDFS_FORCE_OFF, mask); 155 break; 156 case "default": 157 mSm.setDebugFlags(0, mask); 158 break; 159 } 160 } 161 162 public void runSetEmulateFbe() throws RemoteException { 163 final boolean emulateFbe = Boolean.parseBoolean(nextArg()); 164 mSm.setDebugFlags(emulateFbe ? StorageManager.DEBUG_EMULATE_FBE : 0, 165 StorageManager.DEBUG_EMULATE_FBE); 166 } 167 168 public void runGetFbeMode() { 169 if (StorageManager.isFileEncryptedNativeOnly()) { 170 System.out.println("native"); 171 } else if (StorageManager.isFileEncryptedEmulatedOnly()) { 172 System.out.println("emulated"); 173 } else { 174 System.out.println("none"); 175 } 176 } 177 178 public void runPartition() throws RemoteException { 179 final String diskId = nextArg(); 180 final String type = nextArg(); 181 if ("public".equals(type)) { 182 mSm.partitionPublic(diskId); 183 } else if ("private".equals(type)) { 184 mSm.partitionPrivate(diskId); 185 } else if ("mixed".equals(type)) { 186 final int ratio = Integer.parseInt(nextArg()); 187 mSm.partitionMixed(diskId, ratio); 188 } else { 189 throw new IllegalArgumentException("Unsupported partition type " + type); 190 } 191 } 192 193 public void runMount() throws RemoteException { 194 final String volId = nextArg(); 195 mSm.mount(volId); 196 } 197 198 public void runUnmount() throws RemoteException { 199 final String volId = nextArg(); 200 mSm.unmount(volId); 201 } 202 203 public void runFormat() throws RemoteException { 204 final String volId = nextArg(); 205 mSm.format(volId); 206 } 207 208 public void runBenchmark() throws RemoteException { 209 final String volId = nextArg(); 210 mSm.benchmark(volId); 211 } 212 213 public void runForget() throws RemoteException{ 214 final String fsUuid = nextArg(); 215 if ("all".equals(fsUuid)) { 216 mSm.forgetAllVolumes(); 217 } else { 218 mSm.forgetVolume(fsUuid); 219 } 220 } 221 222 private String nextArg() { 223 if (mNextArg >= mArgs.length) { 224 return null; 225 } 226 String arg = mArgs[mNextArg]; 227 mNextArg++; 228 return arg; 229 } 230 231 private static int showUsage() { 232 System.err.println("usage: sm list-disks [adoptable]"); 233 System.err.println(" sm list-volumes [public|private|emulated|all]"); 234 System.err.println(" sm has-adoptable"); 235 System.err.println(" sm get-primary-storage-uuid"); 236 System.err.println(" sm set-force-adoptable [true|false]"); 237 System.err.println(""); 238 System.err.println(" sm partition DISK [public|private|mixed] [ratio]"); 239 System.err.println(" sm mount VOLUME"); 240 System.err.println(" sm unmount VOLUME"); 241 System.err.println(" sm format VOLUME"); 242 System.err.println(" sm benchmark VOLUME"); 243 System.err.println(""); 244 System.err.println(" sm forget [UUID|all]"); 245 System.err.println(""); 246 System.err.println(" sm set-emulate-fbe [true|false]"); 247 System.err.println(""); 248 return 1; 249 } 250} 251