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