summaryrefslogtreecommitdiffstats
path: root/dom/system/gonk/VolumeCommand.h
diff options
context:
space:
mode:
Diffstat (limited to 'dom/system/gonk/VolumeCommand.h')
-rw-r--r--dom/system/gonk/VolumeCommand.h204
1 files changed, 204 insertions, 0 deletions
diff --git a/dom/system/gonk/VolumeCommand.h b/dom/system/gonk/VolumeCommand.h
new file mode 100644
index 000000000..022965b5e
--- /dev/null
+++ b/dom/system/gonk/VolumeCommand.h
@@ -0,0 +1,204 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_system_volumecommand_h__
+#define mozilla_system_volumecommand_h__
+
+#include "nsString.h"
+#include "nsISupportsImpl.h"
+#include "mozilla/RefPtr.h"
+#include <algorithm>
+#include <vold/ResponseCode.h>
+
+namespace mozilla {
+namespace system {
+
+class Volume;
+class VolumeCommand;
+
+/***************************************************************************
+*
+* The VolumeResponseCallback class is an abstract base class. The ResponseReceived
+* method will be called for each response received.
+*
+* Depending on the command, there may be multiple responses for the
+* command. Done() will return true if this is the last response.
+*
+* The responses from vold are all of the form:
+*
+* <ResponseCode> <String>
+*
+* Valid Response codes can be found in the vold/ResponseCode.h header.
+*
+***************************************************************************/
+
+class VolumeResponseCallback
+{
+protected:
+ virtual ~VolumeResponseCallback() {}
+
+public:
+ NS_INLINE_DECL_REFCOUNTING(VolumeResponseCallback)
+ VolumeResponseCallback()
+ : mResponseCode(0), mPending(false) {}
+
+ bool Done() const
+ {
+ // Response codes from the 200, 400, and 500 series all indicated that
+ // the command has completed.
+
+ return (mResponseCode >= ::ResponseCode::CommandOkay)
+ && (mResponseCode < ::ResponseCode::UnsolicitedInformational);
+ }
+
+ bool WasSuccessful() const
+ {
+ return mResponseCode == ::ResponseCode::CommandOkay;
+ }
+
+ bool IsPending() const { return mPending; }
+ int ResponseCode() const { return mResponseCode; }
+ const nsCString &ResponseStr() const { return mResponseStr; }
+
+protected:
+ virtual void ResponseReceived(const VolumeCommand* aCommand) = 0;
+
+private:
+ friend class VolumeCommand; // Calls HandleResponse and SetPending
+
+ void HandleResponse(const VolumeCommand* aCommand,
+ int aResponseCode,
+ nsACString& aResponseStr)
+ {
+ mResponseCode = aResponseCode;
+#if ANDROID_VERSION >= 17
+ // There's a sequence number here that we don't care about
+ // We expect it to be 0. See VolumeCommand::SetCmd
+ mResponseStr = Substring(aResponseStr, 2);
+#else
+ mResponseStr = aResponseStr;
+#endif
+ if (mResponseCode >= ::ResponseCode::CommandOkay) {
+ // This is a final response.
+ mPending = false;
+ }
+ ResponseReceived(aCommand);
+ }
+
+ void SetPending(bool aPending) { mPending = aPending; }
+
+ int mResponseCode; // The response code parsed from vold
+ nsCString mResponseStr; // The rest of the line.
+ bool mPending; // Waiting for response?
+};
+
+/***************************************************************************
+*
+* The VolumeCommand class is an abstract base class used to encapsulate
+* volume commands send to vold.
+*
+* See VolumeManager.h for a list of the volume commands.
+*
+* Commands sent to vold need an explicit null character so we add one
+* to the command to ensure that it's included in the length.
+*
+* All of these commands are asynchronous in nature, and the
+* ResponseReceived callback will be called when a response is available.
+*
+***************************************************************************/
+
+class VolumeCommand
+{
+protected:
+ virtual ~VolumeCommand() {}
+
+public:
+ NS_INLINE_DECL_REFCOUNTING(VolumeCommand)
+
+ VolumeCommand(VolumeResponseCallback* aCallback)
+ : mBytesConsumed(0),
+ mCallback(aCallback)
+ {
+ SetCmd(NS_LITERAL_CSTRING(""));
+ }
+
+ VolumeCommand(const nsACString& aCommand, VolumeResponseCallback* aCallback)
+ : mBytesConsumed(0),
+ mCallback(aCallback)
+ {
+ SetCmd(aCommand);
+ }
+
+ void SetCmd(const nsACString& aCommand)
+ {
+ mCmd.Truncate();
+#if ANDROID_VERSION >= 17
+ // JB requires a sequence number at the beginning of messages.
+ // It doesn't matter what we use, so we use 0.
+ mCmd = "0 ";
+#endif
+ mCmd.Append(aCommand);
+ // Add a null character. We want this to be included in the length since
+ // vold uses it to determine the end of the command.
+ mCmd.Append('\0');
+ }
+
+ const char* CmdStr() const { return mCmd.get(); }
+ const char* Data() const { return mCmd.Data() + mBytesConsumed; }
+ size_t BytesConsumed() const { return mBytesConsumed; }
+
+ size_t BytesRemaining() const
+ {
+ return mCmd.Length() - std::min(mCmd.Length(), mBytesConsumed);
+ }
+
+ void ConsumeBytes(size_t aNumBytes)
+ {
+ mBytesConsumed += std::min(BytesRemaining(), aNumBytes);
+ }
+
+private:
+ friend class VolumeManager; // Calls SetPending & HandleResponse
+
+ void SetPending(bool aPending)
+ {
+ if (mCallback) {
+ mCallback->SetPending(aPending);
+ }
+ }
+
+ void HandleResponse(int aResponseCode, nsACString& aResponseStr)
+ {
+ if (mCallback) {
+ mCallback->HandleResponse(this, aResponseCode, aResponseStr);
+ }
+ }
+
+ nsCString mCmd; // Command being sent
+ size_t mBytesConsumed; // How many bytes have been sent
+
+ // Called when a response to the command is received.
+ RefPtr<VolumeResponseCallback> mCallback;
+};
+
+class VolumeActionCommand : public VolumeCommand
+{
+public:
+ VolumeActionCommand(Volume* aVolume, const char* aAction,
+ const char* aExtraArgs, VolumeResponseCallback* aCallback);
+
+private:
+ RefPtr<Volume> mVolume;
+};
+
+class VolumeListCommand : public VolumeCommand
+{
+public:
+ VolumeListCommand(VolumeResponseCallback* aCallback);
+};
+
+} // system
+} // mozilla
+
+#endif // mozilla_system_volumecommand_h__