1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dom/system/gonk/VolumeCommand.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,204 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this file, 1.6 + * You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +#ifndef mozilla_system_volumecommand_h__ 1.9 +#define mozilla_system_volumecommand_h__ 1.10 + 1.11 +#include "nsString.h" 1.12 +#include "nsISupportsImpl.h" 1.13 +#include "mozilla/RefPtr.h" 1.14 +#include <algorithm> 1.15 +#include <vold/ResponseCode.h> 1.16 + 1.17 +namespace mozilla { 1.18 +namespace system { 1.19 + 1.20 +class Volume; 1.21 +class VolumeCommand; 1.22 + 1.23 +/*************************************************************************** 1.24 +* 1.25 +* The VolumeResponseCallback class is an abstract base class. The ResponseReceived 1.26 +* method will be called for each response received. 1.27 +* 1.28 +* Depending on the command, there may be multiple responses for the 1.29 +* command. Done() will return true if this is the last response. 1.30 +* 1.31 +* The responses from vold are all of the form: 1.32 +* 1.33 +* <ResponseCode> <String> 1.34 +* 1.35 +* Valid Response codes can be found in the vold/ResponseCode.h header. 1.36 +* 1.37 +***************************************************************************/ 1.38 + 1.39 +class VolumeResponseCallback 1.40 +{ 1.41 +protected: 1.42 + virtual ~VolumeResponseCallback() {} 1.43 + 1.44 +public: 1.45 + NS_INLINE_DECL_REFCOUNTING(VolumeResponseCallback) 1.46 + VolumeResponseCallback() 1.47 + : mResponseCode(0), mPending(false) {} 1.48 + 1.49 + bool Done() const 1.50 + { 1.51 + // Response codes from the 200, 400, and 500 series all indicated that 1.52 + // the command has completed. 1.53 + 1.54 + return (mResponseCode >= ResponseCode::CommandOkay) 1.55 + && (mResponseCode < ResponseCode::UnsolicitedInformational); 1.56 + } 1.57 + 1.58 + bool WasSuccessful() const 1.59 + { 1.60 + return mResponseCode == ResponseCode::CommandOkay; 1.61 + } 1.62 + 1.63 + bool IsPending() const { return mPending; } 1.64 + int ResponseCode() const { return mResponseCode; } 1.65 + const nsCString &ResponseStr() const { return mResponseStr; } 1.66 + 1.67 +protected: 1.68 + virtual void ResponseReceived(const VolumeCommand* aCommand) = 0; 1.69 + 1.70 +private: 1.71 + friend class VolumeCommand; // Calls HandleResponse and SetPending 1.72 + 1.73 + void HandleResponse(const VolumeCommand* aCommand, 1.74 + int aResponseCode, 1.75 + nsACString& aResponseStr) 1.76 + { 1.77 + mResponseCode = aResponseCode; 1.78 +#if ANDROID_VERSION >= 17 1.79 + // There's a sequence number here that we don't care about 1.80 + // We expect it to be 0. See VolumeCommand::SetCmd 1.81 + mResponseStr = Substring(aResponseStr, 2); 1.82 +#else 1.83 + mResponseStr = aResponseStr; 1.84 +#endif 1.85 + if (mResponseCode >= ResponseCode::CommandOkay) { 1.86 + // This is a final response. 1.87 + mPending = false; 1.88 + } 1.89 + ResponseReceived(aCommand); 1.90 + } 1.91 + 1.92 + void SetPending(bool aPending) { mPending = aPending; } 1.93 + 1.94 + int mResponseCode; // The response code parsed from vold 1.95 + nsCString mResponseStr; // The rest of the line. 1.96 + bool mPending; // Waiting for response? 1.97 +}; 1.98 + 1.99 +/*************************************************************************** 1.100 +* 1.101 +* The VolumeCommand class is an abstract base class used to encapsulate 1.102 +* volume commands send to vold. 1.103 +* 1.104 +* See VolumeManager.h for a list of the volume commands. 1.105 +* 1.106 +* Commands sent to vold need an explicit null character so we add one 1.107 +* to the command to ensure that it's included in the length. 1.108 +* 1.109 +* All of these commands are asynchronous in nature, and the 1.110 +* ResponseReceived callback will be called when a response is available. 1.111 +* 1.112 +***************************************************************************/ 1.113 + 1.114 +class VolumeCommand 1.115 +{ 1.116 +protected: 1.117 + virtual ~VolumeCommand() {} 1.118 + 1.119 +public: 1.120 + NS_INLINE_DECL_REFCOUNTING(VolumeCommand) 1.121 + 1.122 + VolumeCommand(VolumeResponseCallback* aCallback) 1.123 + : mBytesConsumed(0), 1.124 + mCallback(aCallback) 1.125 + { 1.126 + SetCmd(NS_LITERAL_CSTRING("")); 1.127 + } 1.128 + 1.129 + VolumeCommand(const nsACString& aCommand, VolumeResponseCallback* aCallback) 1.130 + : mBytesConsumed(0), 1.131 + mCallback(aCallback) 1.132 + { 1.133 + SetCmd(aCommand); 1.134 + } 1.135 + 1.136 + void SetCmd(const nsACString& aCommand) 1.137 + { 1.138 + mCmd.Truncate(); 1.139 +#if ANDROID_VERSION >= 17 1.140 + // JB requires a sequence number at the beginning of messages. 1.141 + // It doesn't matter what we use, so we use 0. 1.142 + mCmd = "0 "; 1.143 +#endif 1.144 + mCmd.Append(aCommand); 1.145 + // Add a null character. We want this to be included in the length since 1.146 + // vold uses it to determine the end of the command. 1.147 + mCmd.Append('\0'); 1.148 + } 1.149 + 1.150 + const char* CmdStr() const { return mCmd.get(); } 1.151 + const char* Data() const { return mCmd.Data() + mBytesConsumed; } 1.152 + size_t BytesConsumed() const { return mBytesConsumed; } 1.153 + 1.154 + size_t BytesRemaining() const 1.155 + { 1.156 + return mCmd.Length() - std::min(mCmd.Length(), mBytesConsumed); 1.157 + } 1.158 + 1.159 + void ConsumeBytes(size_t aNumBytes) 1.160 + { 1.161 + mBytesConsumed += std::min(BytesRemaining(), aNumBytes); 1.162 + } 1.163 + 1.164 +private: 1.165 + friend class VolumeManager; // Calls SetPending & HandleResponse 1.166 + 1.167 + void SetPending(bool aPending) 1.168 + { 1.169 + if (mCallback) { 1.170 + mCallback->SetPending(aPending); 1.171 + } 1.172 + } 1.173 + 1.174 + void HandleResponse(int aResponseCode, nsACString& aResponseStr) 1.175 + { 1.176 + if (mCallback) { 1.177 + mCallback->HandleResponse(this, aResponseCode, aResponseStr); 1.178 + } 1.179 + } 1.180 + 1.181 + nsCString mCmd; // Command being sent 1.182 + size_t mBytesConsumed; // How many bytes have been sent 1.183 + 1.184 + // Called when a response to the command is received. 1.185 + RefPtr<VolumeResponseCallback> mCallback; 1.186 +}; 1.187 + 1.188 +class VolumeActionCommand : public VolumeCommand 1.189 +{ 1.190 +public: 1.191 + VolumeActionCommand(Volume* aVolume, const char* aAction, 1.192 + const char* aExtraArgs, VolumeResponseCallback* aCallback); 1.193 + 1.194 +private: 1.195 + RefPtr<Volume> mVolume; 1.196 +}; 1.197 + 1.198 +class VolumeListCommand : public VolumeCommand 1.199 +{ 1.200 +public: 1.201 + VolumeListCommand(VolumeResponseCallback* aCallback); 1.202 +}; 1.203 + 1.204 +} // system 1.205 +} // mozilla 1.206 + 1.207 +#endif // mozilla_system_volumecommand_h__