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.RemoteException;
20 import android.os.ServiceManager;
21 import android.os.SystemProperties;
22 import android.os.storage.DiskInfo;
23 import android.os.storage.IMountService;
24 import android.os.storage.StorageManager;
25 import android.os.storage.VolumeInfo;
26 import android.util.Log;
27 
28 public 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 
main(String[] args)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             }
46             Log.e(TAG, "Error", e);
47             System.err.println("Error: " + e);
48         }
49         System.exit(success ? 0 : 1);
50     }
51 
run(String[] args)52     public void run(String[] args) throws Exception {
53         if (args.length < 1) {
54             throw new IllegalArgumentException();
55         }
56 
57         mSm = IMountService.Stub.asInterface(ServiceManager.getService("mount"));
58         if (mSm == null) {
59             throw new RemoteException("Failed to find running mount service");
60         }
61 
62         mArgs = args;
63         String op = args[0];
64         mNextArg = 1;
65 
66         if ("list-disks".equals(op)) {
67             runListDisks();
68         } else if ("list-volumes".equals(op)) {
69             runListVolumes();
70         } else if ("has-adoptable".equals(op)) {
71             runHasAdoptable();
72         } else if ("get-primary-storage-uuid".equals(op)) {
73             runGetPrimaryStorageUuid();
74         } else if ("set-force-adoptable".equals(op)) {
75             runSetForceAdoptable();
76         } else if ("partition".equals(op)) {
77             runPartition();
78         } else if ("mount".equals(op)) {
79             runMount();
80         } else if ("unmount".equals(op)) {
81             runUnmount();
82         } else if ("format".equals(op)) {
83             runFormat();
84         } else if ("benchmark".equals(op)) {
85             runBenchmark();
86         } else if ("forget".equals(op)) {
87             runForget();
88         } else {
89             throw new IllegalArgumentException();
90         }
91     }
92 
runListDisks()93     public void runListDisks() throws RemoteException {
94         final boolean onlyAdoptable = "adoptable".equals(nextArg());
95         final DiskInfo[] disks = mSm.getDisks();
96         for (DiskInfo disk : disks) {
97             if (!onlyAdoptable || disk.isAdoptable()) {
98                 System.out.println(disk.getId());
99             }
100         }
101     }
102 
runListVolumes()103     public void runListVolumes() throws RemoteException {
104         final String filter = nextArg();
105         final int filterType;
106         if ("public".equals(filter)) {
107             filterType = VolumeInfo.TYPE_PUBLIC;
108         } else if ("private".equals(filter)) {
109             filterType = VolumeInfo.TYPE_PRIVATE;
110         } else if ("emulated".equals(filter)) {
111             filterType = VolumeInfo.TYPE_EMULATED;
112         } else {
113             filterType = -1;
114         }
115 
116         final VolumeInfo[] vols = mSm.getVolumes(0);
117         for (VolumeInfo vol : vols) {
118             if (filterType == -1 || filterType == vol.getType()) {
119                 final String envState = VolumeInfo.getEnvironmentForState(vol.getState());
120                 System.out.println(vol.getId() + " " + envState + " " + vol.getFsUuid());
121             }
122         }
123     }
124 
runHasAdoptable()125     public void runHasAdoptable() {
126         System.out.println(SystemProperties.getBoolean(StorageManager.PROP_HAS_ADOPTABLE, false));
127     }
128 
runGetPrimaryStorageUuid()129     public void runGetPrimaryStorageUuid() throws RemoteException {
130         System.out.println(mSm.getPrimaryStorageUuid());
131     }
132 
runSetForceAdoptable()133     public void runSetForceAdoptable() throws RemoteException {
134         final boolean forceAdoptable = Boolean.parseBoolean(nextArg());
135         mSm.setDebugFlags(forceAdoptable ? StorageManager.DEBUG_FORCE_ADOPTABLE : 0,
136                 StorageManager.DEBUG_FORCE_ADOPTABLE);
137     }
138 
runPartition()139     public void runPartition() throws RemoteException {
140         final String diskId = nextArg();
141         final String type = nextArg();
142         if ("public".equals(type)) {
143             mSm.partitionPublic(diskId);
144         } else if ("private".equals(type)) {
145             mSm.partitionPrivate(diskId);
146         } else if ("mixed".equals(type)) {
147             final int ratio = Integer.parseInt(nextArg());
148             mSm.partitionMixed(diskId, ratio);
149         } else {
150             throw new IllegalArgumentException("Unsupported partition type " + type);
151         }
152     }
153 
runMount()154     public void runMount() throws RemoteException {
155         final String volId = nextArg();
156         mSm.mount(volId);
157     }
158 
runUnmount()159     public void runUnmount() throws RemoteException {
160         final String volId = nextArg();
161         mSm.unmount(volId);
162     }
163 
runFormat()164     public void runFormat() throws RemoteException {
165         final String volId = nextArg();
166         mSm.format(volId);
167     }
168 
runBenchmark()169     public void runBenchmark() throws RemoteException {
170         final String volId = nextArg();
171         mSm.benchmark(volId);
172     }
173 
runForget()174     public void runForget() throws RemoteException{
175         final String fsUuid = nextArg();
176         if ("all".equals(fsUuid)) {
177             mSm.forgetAllVolumes();
178         } else {
179             mSm.forgetVolume(fsUuid);
180         }
181     }
182 
nextArg()183     private String nextArg() {
184         if (mNextArg >= mArgs.length) {
185             return null;
186         }
187         String arg = mArgs[mNextArg];
188         mNextArg++;
189         return arg;
190     }
191 
showUsage()192     private static int showUsage() {
193         System.err.println("usage: sm list-disks [adoptable]");
194         System.err.println("       sm list-volumes [public|private|emulated|all]");
195         System.err.println("       sm has-adoptable");
196         System.err.println("       sm get-primary-storage-uuid");
197         System.err.println("       sm set-force-adoptable [true|false]");
198         System.err.println("");
199         System.err.println("       sm partition DISK [public|private|mixed] [ratio]");
200         System.err.println("       sm mount VOLUME");
201         System.err.println("       sm unmount VOLUME");
202         System.err.println("       sm format VOLUME");
203         System.err.println("       sm benchmark VOLUME");
204         System.err.println("");
205         System.err.println("       sm forget [UUID|all]");
206         System.err.println("");
207         return 1;
208     }
209 }
210