Home | History | Annotate | Download | only in sm
      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 
     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 
     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 {
    105             throw new IllegalArgumentException();
    106         }
    107     }
    108 
    109     public void runListDisks() throws RemoteException {
    110         final boolean onlyAdoptable = "adoptable".equals(nextArg());
    111         final DiskInfo[] disks = mSm.getDisks();
    112         for (DiskInfo disk : disks) {
    113             if (!onlyAdoptable || disk.isAdoptable()) {
    114                 System.out.println(disk.getId());
    115             }
    116         }
    117     }
    118 
    119     public void runListVolumes() throws RemoteException {
    120         final String filter = nextArg();
    121         final int filterType;
    122         if ("public".equals(filter)) {
    123             filterType = VolumeInfo.TYPE_PUBLIC;
    124         } else if ("private".equals(filter)) {
    125             filterType = VolumeInfo.TYPE_PRIVATE;
    126         } else if ("emulated".equals(filter)) {
    127             filterType = VolumeInfo.TYPE_EMULATED;
    128         } else {
    129             filterType = -1;
    130         }
    131 
    132         final VolumeInfo[] vols = mSm.getVolumes(0);
    133         for (VolumeInfo vol : vols) {
    134             if (filterType == -1 || filterType == vol.getType()) {
    135                 final String envState = VolumeInfo.getEnvironmentForState(vol.getState());
    136                 System.out.println(vol.getId() + " " + envState + " " + vol.getFsUuid());
    137             }
    138         }
    139     }
    140 
    141     public void runHasAdoptable() {
    142         System.out.println(StorageManager.hasAdoptable());
    143     }
    144 
    145     public void runGetPrimaryStorageUuid() throws RemoteException {
    146         System.out.println(mSm.getPrimaryStorageUuid());
    147     }
    148 
    149     public void runSetForceAdoptable() throws RemoteException {
    150         final int mask = StorageManager.DEBUG_ADOPTABLE_FORCE_ON
    151                 | StorageManager.DEBUG_ADOPTABLE_FORCE_OFF;
    152         switch (nextArg()) {
    153             case "on":
    154             case "true":
    155                 mSm.setDebugFlags(StorageManager.DEBUG_ADOPTABLE_FORCE_ON, mask);
    156                 break;
    157             case "off":
    158                 mSm.setDebugFlags(StorageManager.DEBUG_ADOPTABLE_FORCE_OFF, mask);
    159                 break;
    160             case "default":
    161             case "false":
    162                 mSm.setDebugFlags(0, mask);
    163                 break;
    164         }
    165     }
    166 
    167     public void runSetSdcardfs() throws RemoteException {
    168         final int mask = StorageManager.DEBUG_SDCARDFS_FORCE_ON
    169                 | StorageManager.DEBUG_SDCARDFS_FORCE_OFF;
    170         switch (nextArg()) {
    171             case "on":
    172                 mSm.setDebugFlags(StorageManager.DEBUG_SDCARDFS_FORCE_ON, mask);
    173                 break;
    174             case "off":
    175                 mSm.setDebugFlags(StorageManager.DEBUG_SDCARDFS_FORCE_OFF, mask);
    176                 break;
    177             case "default":
    178                 mSm.setDebugFlags(0, mask);
    179                 break;
    180         }
    181     }
    182 
    183     public void runSetEmulateFbe() throws RemoteException {
    184         final boolean emulateFbe = Boolean.parseBoolean(nextArg());
    185         mSm.setDebugFlags(emulateFbe ? StorageManager.DEBUG_EMULATE_FBE : 0,
    186                 StorageManager.DEBUG_EMULATE_FBE);
    187     }
    188 
    189     public void runGetFbeMode() {
    190         if (StorageManager.isFileEncryptedNativeOnly()) {
    191             System.out.println("native");
    192         } else if (StorageManager.isFileEncryptedEmulatedOnly()) {
    193             System.out.println("emulated");
    194         } else {
    195             System.out.println("none");
    196         }
    197     }
    198 
    199     public void runPartition() throws RemoteException {
    200         final String diskId = nextArg();
    201         final String type = nextArg();
    202         if ("public".equals(type)) {
    203             mSm.partitionPublic(diskId);
    204         } else if ("private".equals(type)) {
    205             mSm.partitionPrivate(diskId);
    206         } else if ("mixed".equals(type)) {
    207             final int ratio = Integer.parseInt(nextArg());
    208             mSm.partitionMixed(diskId, ratio);
    209         } else {
    210             throw new IllegalArgumentException("Unsupported partition type " + type);
    211         }
    212     }
    213 
    214     public void runMount() throws RemoteException {
    215         final String volId = nextArg();
    216         mSm.mount(volId);
    217     }
    218 
    219     public void runUnmount() throws RemoteException {
    220         final String volId = nextArg();
    221         mSm.unmount(volId);
    222     }
    223 
    224     public void runFormat() throws RemoteException {
    225         final String volId = nextArg();
    226         mSm.format(volId);
    227     }
    228 
    229     public void runBenchmark() throws Exception {
    230         final String volId = nextArg();
    231         final CompletableFuture<PersistableBundle> result = new CompletableFuture<>();
    232         mSm.benchmark(volId, new IVoldTaskListener.Stub() {
    233             @Override
    234             public void onStatus(int status, PersistableBundle extras) {
    235                 // Ignored
    236             }
    237 
    238             @Override
    239             public void onFinished(int status, PersistableBundle extras) {
    240                 // Touch to unparcel
    241                 extras.size();
    242                 result.complete(extras);
    243             }
    244         });
    245         System.out.println(result.get());
    246     }
    247 
    248     public void runForget() throws RemoteException {
    249         final String fsUuid = nextArg();
    250         if ("all".equals(fsUuid)) {
    251             mSm.forgetAllVolumes();
    252         } else {
    253             mSm.forgetVolume(fsUuid);
    254         }
    255     }
    256 
    257     public void runFstrim() throws Exception {
    258         final CompletableFuture<PersistableBundle> result = new CompletableFuture<>();
    259         mSm.fstrim(0, new IVoldTaskListener.Stub() {
    260             @Override
    261             public void onStatus(int status, PersistableBundle extras) {
    262                 // Ignored
    263             }
    264 
    265             @Override
    266             public void onFinished(int status, PersistableBundle extras) {
    267                 // Touch to unparcel
    268                 extras.size();
    269                 result.complete(extras);
    270             }
    271         });
    272         System.out.println(result.get());
    273     }
    274 
    275     public void runSetVirtualDisk() throws RemoteException {
    276         final boolean virtualDisk = Boolean.parseBoolean(nextArg());
    277         mSm.setDebugFlags(virtualDisk ? StorageManager.DEBUG_VIRTUAL_DISK : 0,
    278                 StorageManager.DEBUG_VIRTUAL_DISK);
    279     }
    280 
    281     public void runIdleMaint() throws RemoteException {
    282         final boolean im_run = "run".equals(nextArg());
    283         if (im_run) {
    284             mSm.runIdleMaintenance();
    285         } else {
    286             mSm.abortIdleMaintenance();
    287         }
    288     }
    289 
    290     private String nextArg() {
    291         if (mNextArg >= mArgs.length) {
    292             return null;
    293         }
    294         String arg = mArgs[mNextArg];
    295         mNextArg++;
    296         return arg;
    297     }
    298 
    299     private static int showUsage() {
    300         System.err.println("usage: sm list-disks [adoptable]");
    301         System.err.println("       sm list-volumes [public|private|emulated|all]");
    302         System.err.println("       sm has-adoptable");
    303         System.err.println("       sm get-primary-storage-uuid");
    304         System.err.println("       sm set-force-adoptable [on|off|default]");
    305         System.err.println("       sm set-virtual-disk [true|false]");
    306         System.err.println("");
    307         System.err.println("       sm partition DISK [public|private|mixed] [ratio]");
    308         System.err.println("       sm mount VOLUME");
    309         System.err.println("       sm unmount VOLUME");
    310         System.err.println("       sm format VOLUME");
    311         System.err.println("       sm benchmark VOLUME");
    312         System.err.println("       sm idle-maint [run|abort]");
    313         System.err.println("       sm fstrim");
    314         System.err.println("");
    315         System.err.println("       sm forget [UUID|all]");
    316         System.err.println("");
    317         System.err.println("       sm set-emulate-fbe [true|false]");
    318         System.err.println("");
    319         return 1;
    320     }
    321 }
    322