michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this file, michael@0: * You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef mozilla_system_volumemanager_h__ michael@0: #define mozilla_system_volumemanager_h__ michael@0: michael@0: #include michael@0: #include michael@0: michael@0: #include "base/message_loop.h" michael@0: #include "mozilla/FileUtils.h" michael@0: #include "mozilla/Observer.h" michael@0: #include "nsISupportsImpl.h" michael@0: #include "nsString.h" michael@0: #include "nsTArray.h" michael@0: michael@0: #include "Volume.h" michael@0: #include "VolumeCommand.h" michael@0: michael@0: namespace mozilla { michael@0: namespace system { michael@0: michael@0: /*************************************************************************** michael@0: * michael@0: * All of the public API mentioned in this file (unless otherwise michael@0: * mentioned) must run from the IOThread. michael@0: * michael@0: ***************************************************************************/ michael@0: michael@0: /*************************************************************************** michael@0: * michael@0: * The VolumeManager class is a front-end for android's vold service. michael@0: * michael@0: * Vold uses a unix socket interface and accepts null-terminated string michael@0: * commands. The following commands were determined by examining the vold michael@0: * source code: michael@0: * michael@0: * volume list michael@0: * volume mount michael@0: * volume unmount [force] michael@0: * volume debug [on|off] michael@0: * volume format michael@0: * volume share michael@0: * volume unshare michael@0: * volume shared michael@0: * michael@0: * is the name of the volume as used in /system/etc/vold.fstab michael@0: * is ums michael@0: * michael@0: * dump michael@0: * michael@0: * share status (Determines if a particular sharing method is available) michael@0: * (GB only - not available in ICS) michael@0: * michael@0: * storage users (??? always crashes vold ???) michael@0: * michael@0: * asec list michael@0: * asec ...lots more... michael@0: * michael@0: * obb list michael@0: * obb ...lots more... michael@0: * michael@0: * xwarp enable michael@0: * xwarp disable michael@0: * xwarp status michael@0: * michael@0: * There is also a command line tool called vdc, which can be used to send michael@0: * the above commands to vold. michael@0: * michael@0: * Currently, only the volume list, share/unshare, and mount/unmount michael@0: * commands are being used. michael@0: * michael@0: ***************************************************************************/ michael@0: michael@0: class VolumeManager MOZ_FINAL : public MessageLoopForIO::LineWatcher michael@0: { michael@0: virtual ~VolumeManager(); michael@0: michael@0: public: michael@0: NS_INLINE_DECL_REFCOUNTING(VolumeManager) michael@0: michael@0: typedef nsTArray> VolumeArray; michael@0: michael@0: VolumeManager(); michael@0: michael@0: //----------------------------------------------------------------------- michael@0: // michael@0: // State related methods. michael@0: // michael@0: // The VolumeManager starts off in the STARTING state. Once a connection michael@0: // is established with vold, it asks for a list of volumes, and once the michael@0: // volume list has been received, then the VolumeManager enters the michael@0: // VOLUMES_READY state. michael@0: // michael@0: // If vold crashes, then the VolumeManager will once again enter the michael@0: // STARTING state and try to reestablish a connection with vold. michael@0: michael@0: enum STATE michael@0: { michael@0: UNINITIALIZED, michael@0: STARTING, michael@0: VOLUMES_READY michael@0: }; michael@0: michael@0: static STATE State(); michael@0: static const char* StateStr(STATE aState); michael@0: static const char* StateStr() { return StateStr(State()); } michael@0: michael@0: class StateChangedEvent michael@0: { michael@0: public: michael@0: StateChangedEvent() {} michael@0: }; michael@0: michael@0: typedef mozilla::Observer StateObserver; michael@0: typedef mozilla::ObserverList StateObserverList; michael@0: michael@0: static void RegisterStateObserver(StateObserver* aObserver); michael@0: static void UnregisterStateObserver(StateObserver* aObserver); michael@0: michael@0: //----------------------------------------------------------------------- michael@0: michael@0: static void Start(); michael@0: michael@0: static VolumeArray::size_type NumVolumes(); michael@0: static TemporaryRef GetVolume(VolumeArray::index_type aIndex); michael@0: static TemporaryRef FindVolumeByName(const nsCSubstring& aName); michael@0: static TemporaryRef FindAddVolumeByName(const nsCSubstring& aName); michael@0: michael@0: static void PostCommand(VolumeCommand* aCommand); michael@0: michael@0: protected: michael@0: michael@0: virtual void OnLineRead(int aFd, nsDependentCSubstring& aMessage); michael@0: virtual void OnFileCanWriteWithoutBlocking(int aFd); michael@0: virtual void OnError(); michael@0: michael@0: private: michael@0: bool OpenSocket(); michael@0: michael@0: friend class VolumeListCallback; // Calls SetState michael@0: michael@0: static void SetState(STATE aNewState); michael@0: michael@0: void Restart(); michael@0: void WriteCommandData(); michael@0: void HandleBroadcast(int aResponseCode, nsCString& aResponseLine); michael@0: michael@0: typedef std::queue > CommandQueue; michael@0: michael@0: static STATE mState; michael@0: static StateObserverList mStateObserverList; michael@0: michael@0: static const int kRcvBufSize = 1024; michael@0: ScopedClose mSocket; michael@0: VolumeArray mVolumeArray; michael@0: CommandQueue mCommands; michael@0: bool mCommandPending; michael@0: MessageLoopForIO::FileDescriptorWatcher mReadWatcher; michael@0: MessageLoopForIO::FileDescriptorWatcher mWriteWatcher; michael@0: RefPtr mBroadcastCallback; michael@0: }; michael@0: michael@0: /*************************************************************************** michael@0: * michael@0: * The initialization/shutdown functions do not need to be called from michael@0: * the IOThread context. michael@0: * michael@0: ***************************************************************************/ michael@0: michael@0: /** michael@0: * Initialize the Volume Manager. On initialization, the VolumeManager will michael@0: * attempt to connect with vold and collect the list of volumes that vold michael@0: * knows about. michael@0: */ michael@0: void InitVolumeManager(); michael@0: michael@0: /** michael@0: * Shuts down the Volume Manager. michael@0: */ michael@0: void ShutdownVolumeManager(); michael@0: michael@0: } // system michael@0: } // mozilla michael@0: michael@0: #endif // mozilla_system_volumemanager_h__