1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 3 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 #ifndef mozilla_system_volumemanager_h__ 6 #define mozilla_system_volumemanager_h__ 7 8 #include <vector> 9 #include <queue> 10 11 #include "base/message_loop.h" 12 #include "mozilla/FileUtils.h" 13 #include "mozilla/Observer.h" 14 #include "nsISupportsImpl.h" 15 #include "nsString.h" 16 #include "nsTArray.h" 17 18 #include "Volume.h" 19 #include "VolumeCommand.h" 20 21 namespace mozilla { 22 namespace system { 23 24 /*************************************************************************** 25 * 26 * All of the public API mentioned in this file (unless otherwise 27 * mentioned) must run from the IOThread. 28 * 29 ***************************************************************************/ 30 31 /*************************************************************************** 32 * 33 * The VolumeManager class is a front-end for android's vold service. 34 * 35 * Vold uses a unix socket interface and accepts null-terminated string 36 * commands. The following commands were determined by examining the vold 37 * source code: 38 * 39 * volume list 40 * volume mount <volname> 41 * volume unmount <volname> [force] 42 * volume debug [on|off] 43 * volume format <volname> 44 * volume share <volname> <method> 45 * volume unshare <volname> <method> 46 * volume shared <volname> <method> 47 * 48 * <volname> is the name of the volume as used in /system/etc/vold.fstab 49 * <method> is ums 50 * 51 * dump 52 * 53 * share status <method> (Determines if a particular sharing method is available) 54 * (GB only - not available in ICS) 55 * 56 * storage users (??? always crashes vold ???) 57 * 58 * asec list 59 * asec ...lots more... 60 * 61 * obb list 62 * obb ...lots more... 63 * 64 * xwarp enable 65 * xwarp disable 66 * xwarp status 67 * 68 * There is also a command line tool called vdc, which can be used to send 69 * the above commands to vold. 70 * 71 * Currently, only the volume list, share/unshare, and mount/unmount 72 * commands are being used. 73 * 74 ***************************************************************************/ 75 76 class VolumeManager final : public MessageLoopForIO::LineWatcher 77 { 78 virtual ~VolumeManager(); 79 80 public: 81 NS_INLINE_DECL_REFCOUNTING(VolumeManager) 82 83 typedef nsTArray<RefPtr<Volume>> VolumeArray; 84 85 VolumeManager(); 86 87 //----------------------------------------------------------------------- 88 // 89 // State related methods. 90 // 91 // The VolumeManager starts off in the STARTING state. Once a connection 92 // is established with vold, it asks for a list of volumes, and once the 93 // volume list has been received, then the VolumeManager enters the 94 // VOLUMES_READY state. 95 // 96 // If vold crashes, then the VolumeManager will once again enter the 97 // STARTING state and try to reestablish a connection with vold. 98 99 enum STATE 100 { 101 UNINITIALIZED, 102 STARTING, 103 VOLUMES_READY 104 }; 105 106 static STATE State(); 107 static const char* StateStr(STATE aState); StateStr()108 static const char* StateStr() { return StateStr(State()); } 109 110 class StateChangedEvent 111 { 112 public: StateChangedEvent()113 StateChangedEvent() {} 114 }; 115 116 typedef mozilla::Observer<StateChangedEvent> StateObserver; 117 typedef mozilla::ObserverList<StateChangedEvent> StateObserverList; 118 119 static void RegisterStateObserver(StateObserver* aObserver); 120 static void UnregisterStateObserver(StateObserver* aObserver); 121 122 //----------------------------------------------------------------------- 123 124 static void Start(); 125 static void Dump(const char* aLabel); 126 127 static VolumeArray::size_type NumVolumes(); 128 static already_AddRefed<Volume> GetVolume(VolumeArray::index_type aIndex); 129 static already_AddRefed<Volume> FindVolumeByName(const nsCSubstring& aName); 130 static already_AddRefed<Volume> FindAddVolumeByName(const nsCSubstring& aName); 131 static bool RemoveVolumeByName(const nsCSubstring& aName); 132 static void InitConfig(); 133 134 static void PostCommand(VolumeCommand* aCommand); 135 136 protected: 137 138 virtual void OnLineRead(int aFd, nsDependentCSubstring& aMessage); 139 virtual void OnFileCanWriteWithoutBlocking(int aFd); 140 virtual void OnError(); 141 142 static void DefaultConfig(); 143 144 private: 145 bool OpenSocket(); 146 147 friend class VolumeListCallback; // Calls SetState 148 149 static void SetState(STATE aNewState); 150 151 void Restart(); 152 void WriteCommandData(); 153 void HandleBroadcast(int aResponseCode, nsCString& aResponseLine); 154 155 typedef std::queue<RefPtr<VolumeCommand> > CommandQueue; 156 157 static STATE mState; 158 static StateObserverList mStateObserverList; 159 160 static const int kRcvBufSize = 1024; 161 ScopedClose mSocket; 162 VolumeArray mVolumeArray; 163 CommandQueue mCommands; 164 bool mCommandPending; 165 MessageLoopForIO::FileDescriptorWatcher mReadWatcher; 166 MessageLoopForIO::FileDescriptorWatcher mWriteWatcher; 167 RefPtr<VolumeResponseCallback> mBroadcastCallback; 168 }; 169 170 /*************************************************************************** 171 * 172 * The initialization/shutdown functions do not need to be called from 173 * the IOThread context. 174 * 175 ***************************************************************************/ 176 177 /** 178 * Initialize the Volume Manager. On initialization, the VolumeManager will 179 * attempt to connect with vold and collect the list of volumes that vold 180 * knows about. 181 */ 182 void InitVolumeManager(); 183 184 /** 185 * Shuts down the Volume Manager. 186 */ 187 void ShutdownVolumeManager(); 188 189 } // system 190 } // mozilla 191 192 #endif // mozilla_system_volumemanager_h__ 193