|
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_volumecommand_h__ |
|
6 #define mozilla_system_volumecommand_h__ |
|
7 |
|
8 #include "nsString.h" |
|
9 #include "nsISupportsImpl.h" |
|
10 #include "mozilla/RefPtr.h" |
|
11 #include <algorithm> |
|
12 #include <vold/ResponseCode.h> |
|
13 |
|
14 namespace mozilla { |
|
15 namespace system { |
|
16 |
|
17 class Volume; |
|
18 class VolumeCommand; |
|
19 |
|
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 ***************************************************************************/ |
|
35 |
|
36 class VolumeResponseCallback |
|
37 { |
|
38 protected: |
|
39 virtual ~VolumeResponseCallback() {} |
|
40 |
|
41 public: |
|
42 NS_INLINE_DECL_REFCOUNTING(VolumeResponseCallback) |
|
43 VolumeResponseCallback() |
|
44 : mResponseCode(0), mPending(false) {} |
|
45 |
|
46 bool Done() const |
|
47 { |
|
48 // Response codes from the 200, 400, and 500 series all indicated that |
|
49 // the command has completed. |
|
50 |
|
51 return (mResponseCode >= ResponseCode::CommandOkay) |
|
52 && (mResponseCode < ResponseCode::UnsolicitedInformational); |
|
53 } |
|
54 |
|
55 bool WasSuccessful() const |
|
56 { |
|
57 return mResponseCode == ResponseCode::CommandOkay; |
|
58 } |
|
59 |
|
60 bool IsPending() const { return mPending; } |
|
61 int ResponseCode() const { return mResponseCode; } |
|
62 const nsCString &ResponseStr() const { return mResponseStr; } |
|
63 |
|
64 protected: |
|
65 virtual void ResponseReceived(const VolumeCommand* aCommand) = 0; |
|
66 |
|
67 private: |
|
68 friend class VolumeCommand; // Calls HandleResponse and SetPending |
|
69 |
|
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 } |
|
88 |
|
89 void SetPending(bool aPending) { mPending = aPending; } |
|
90 |
|
91 int mResponseCode; // The response code parsed from vold |
|
92 nsCString mResponseStr; // The rest of the line. |
|
93 bool mPending; // Waiting for response? |
|
94 }; |
|
95 |
|
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 ***************************************************************************/ |
|
110 |
|
111 class VolumeCommand |
|
112 { |
|
113 protected: |
|
114 virtual ~VolumeCommand() {} |
|
115 |
|
116 public: |
|
117 NS_INLINE_DECL_REFCOUNTING(VolumeCommand) |
|
118 |
|
119 VolumeCommand(VolumeResponseCallback* aCallback) |
|
120 : mBytesConsumed(0), |
|
121 mCallback(aCallback) |
|
122 { |
|
123 SetCmd(NS_LITERAL_CSTRING("")); |
|
124 } |
|
125 |
|
126 VolumeCommand(const nsACString& aCommand, VolumeResponseCallback* aCallback) |
|
127 : mBytesConsumed(0), |
|
128 mCallback(aCallback) |
|
129 { |
|
130 SetCmd(aCommand); |
|
131 } |
|
132 |
|
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 } |
|
146 |
|
147 const char* CmdStr() const { return mCmd.get(); } |
|
148 const char* Data() const { return mCmd.Data() + mBytesConsumed; } |
|
149 size_t BytesConsumed() const { return mBytesConsumed; } |
|
150 |
|
151 size_t BytesRemaining() const |
|
152 { |
|
153 return mCmd.Length() - std::min(mCmd.Length(), mBytesConsumed); |
|
154 } |
|
155 |
|
156 void ConsumeBytes(size_t aNumBytes) |
|
157 { |
|
158 mBytesConsumed += std::min(BytesRemaining(), aNumBytes); |
|
159 } |
|
160 |
|
161 private: |
|
162 friend class VolumeManager; // Calls SetPending & HandleResponse |
|
163 |
|
164 void SetPending(bool aPending) |
|
165 { |
|
166 if (mCallback) { |
|
167 mCallback->SetPending(aPending); |
|
168 } |
|
169 } |
|
170 |
|
171 void HandleResponse(int aResponseCode, nsACString& aResponseStr) |
|
172 { |
|
173 if (mCallback) { |
|
174 mCallback->HandleResponse(this, aResponseCode, aResponseStr); |
|
175 } |
|
176 } |
|
177 |
|
178 nsCString mCmd; // Command being sent |
|
179 size_t mBytesConsumed; // How many bytes have been sent |
|
180 |
|
181 // Called when a response to the command is received. |
|
182 RefPtr<VolumeResponseCallback> mCallback; |
|
183 }; |
|
184 |
|
185 class VolumeActionCommand : public VolumeCommand |
|
186 { |
|
187 public: |
|
188 VolumeActionCommand(Volume* aVolume, const char* aAction, |
|
189 const char* aExtraArgs, VolumeResponseCallback* aCallback); |
|
190 |
|
191 private: |
|
192 RefPtr<Volume> mVolume; |
|
193 }; |
|
194 |
|
195 class VolumeListCommand : public VolumeCommand |
|
196 { |
|
197 public: |
|
198 VolumeListCommand(VolumeResponseCallback* aCallback); |
|
199 }; |
|
200 |
|
201 } // system |
|
202 } // mozilla |
|
203 |
|
204 #endif // mozilla_system_volumecommand_h__ |