dom/system/gonk/VolumeCommand.h

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     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/. */
     5 #ifndef mozilla_system_volumecommand_h__
     6 #define mozilla_system_volumecommand_h__
     8 #include "nsString.h"
     9 #include "nsISupportsImpl.h"
    10 #include "mozilla/RefPtr.h"
    11 #include <algorithm>
    12 #include <vold/ResponseCode.h>
    14 namespace mozilla {
    15 namespace system {
    17 class Volume;
    18 class VolumeCommand;
    20 /***************************************************************************
    21 *
    22 *   The VolumeResponseCallback class is an abstract base class. The ResponseReceived
    23 *   method will be called for each response received.
    24 *
    25 *   Depending on the command, there may be multiple responses for the
    26 *   command. Done() will return true if this is the last response.
    27 *
    28 *   The responses from vold are all of the form:
    29 *
    30 *     <ResponseCode> <String>
    31 *
    32 *   Valid Response codes can be found in the vold/ResponseCode.h header.
    33 *
    34 ***************************************************************************/
    36 class VolumeResponseCallback
    37 {
    38 protected:
    39   virtual ~VolumeResponseCallback() {}
    41 public:
    42   NS_INLINE_DECL_REFCOUNTING(VolumeResponseCallback)
    43   VolumeResponseCallback()
    44     : mResponseCode(0), mPending(false) {}
    46   bool Done() const
    47   {
    48     // Response codes from the 200, 400, and 500 series all indicated that
    49     // the command has completed.
    51     return (mResponseCode >= ResponseCode::CommandOkay)
    52         && (mResponseCode < ResponseCode::UnsolicitedInformational);
    53   }
    55   bool WasSuccessful() const
    56   {
    57     return mResponseCode == ResponseCode::CommandOkay;
    58   }
    60   bool              IsPending() const     { return mPending; }
    61   int               ResponseCode() const  { return mResponseCode; }
    62   const nsCString  &ResponseStr() const   { return mResponseStr; }
    64 protected:
    65   virtual void ResponseReceived(const VolumeCommand* aCommand) = 0;
    67 private:
    68   friend  class VolumeCommand;  // Calls HandleResponse and SetPending
    70   void HandleResponse(const VolumeCommand* aCommand,
    71                       int aResponseCode,
    72                       nsACString& aResponseStr)
    73   {
    74     mResponseCode = aResponseCode;
    75 #if ANDROID_VERSION >= 17
    76     // There's a sequence number here that we don't care about
    77     // We expect it to be 0. See VolumeCommand::SetCmd
    78     mResponseStr = Substring(aResponseStr, 2);
    79 #else
    80     mResponseStr = aResponseStr;
    81 #endif
    82     if (mResponseCode >= ResponseCode::CommandOkay) {
    83       // This is a final response.
    84       mPending = false;
    85     }
    86     ResponseReceived(aCommand);
    87   }
    89   void SetPending(bool aPending) { mPending = aPending; }
    91   int       mResponseCode;  // The response code parsed from vold
    92   nsCString mResponseStr;   // The rest of the line.
    93   bool      mPending;       // Waiting for response?
    94 };
    96 /***************************************************************************
    97 *
    98 *   The VolumeCommand class is an abstract base class used to encapsulate
    99 *   volume commands send to vold.
   100 *
   101 *   See VolumeManager.h for a list of the volume commands.
   102 *
   103 *   Commands sent to vold need an explicit null character so we add one
   104 *   to the command to ensure that it's included in the length.
   105 *
   106 *   All of these commands are asynchronous in nature, and the
   107 *   ResponseReceived callback will be called when a response is available.
   108 *
   109 ***************************************************************************/
   111 class VolumeCommand
   112 {
   113 protected:
   114   virtual ~VolumeCommand() {}
   116 public:
   117   NS_INLINE_DECL_REFCOUNTING(VolumeCommand)
   119   VolumeCommand(VolumeResponseCallback* aCallback)
   120     : mBytesConsumed(0),
   121       mCallback(aCallback)
   122   {
   123     SetCmd(NS_LITERAL_CSTRING(""));
   124   }
   126   VolumeCommand(const nsACString& aCommand, VolumeResponseCallback* aCallback)
   127     : mBytesConsumed(0),
   128       mCallback(aCallback)
   129   {
   130     SetCmd(aCommand);
   131   }
   133   void SetCmd(const nsACString& aCommand)
   134   {
   135     mCmd.Truncate();
   136 #if ANDROID_VERSION >= 17
   137     // JB requires a sequence number at the beginning of messages.
   138     // It doesn't matter what we use, so we use 0.
   139     mCmd = "0 ";
   140 #endif
   141     mCmd.Append(aCommand);
   142     // Add a null character. We want this to be included in the length since
   143     // vold uses it to determine the end of the command.
   144     mCmd.Append('\0');
   145   }
   147   const char* CmdStr() const    { return mCmd.get(); }
   148   const char* Data() const      { return mCmd.Data() + mBytesConsumed; }
   149   size_t BytesConsumed() const  { return mBytesConsumed; }
   151   size_t BytesRemaining() const
   152   {
   153     return mCmd.Length() - std::min(mCmd.Length(), mBytesConsumed);
   154   }
   156   void ConsumeBytes(size_t aNumBytes)
   157   {
   158     mBytesConsumed += std::min(BytesRemaining(), aNumBytes);
   159   }
   161 private:
   162   friend class VolumeManager;   // Calls SetPending & HandleResponse
   164   void SetPending(bool aPending)
   165   {
   166     if (mCallback) {
   167       mCallback->SetPending(aPending);
   168     }
   169   }
   171   void HandleResponse(int aResponseCode, nsACString& aResponseStr)
   172   {
   173     if (mCallback) {
   174       mCallback->HandleResponse(this, aResponseCode, aResponseStr);
   175     }
   176   }
   178   nsCString mCmd;           // Command being sent
   179   size_t    mBytesConsumed; // How many bytes have been sent
   181   // Called when a response to the command is received.
   182   RefPtr<VolumeResponseCallback>  mCallback;
   183 };
   185 class VolumeActionCommand : public VolumeCommand
   186 {
   187 public:
   188   VolumeActionCommand(Volume* aVolume, const char* aAction,
   189                       const char* aExtraArgs, VolumeResponseCallback* aCallback);
   191 private:
   192   RefPtr<Volume>  mVolume;
   193 };
   195 class VolumeListCommand : public VolumeCommand
   196 {
   197 public:
   198   VolumeListCommand(VolumeResponseCallback* aCallback);
   199 };
   201 } // system
   202 } // mozilla
   204 #endif  // mozilla_system_volumecommand_h__

mercurial