1 /*
2 * Copyright (C) 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define LOG_TAG "android.hardware.usb.gadget.aidl-service"
18
19 #include "UsbGadget.h"
20 #include <fcntl.h>
21 #include <stdio.h>
22 #include <sys/inotify.h>
23 #include <sys/mount.h>
24 #include <sys/stat.h>
25 #include <sys/types.h>
26 #include <unistd.h>
27
28 #include<android-base/properties.h>
29
30 #include <aidl/android/frameworks/stats/IStats.h>
31 #include <pixelusb/I2cHelper.h>
32
33 namespace aidl {
34 namespace android {
35 namespace hardware {
36 namespace usb {
37 namespace gadget {
38 #define NUM_HSI2C_PATHS 2
39
40 using ::android::hardware::google::pixel::usb::getI2cClientPath;
41
42 using ::android::base::GetBoolProperty;
43 using ::android::hardware::google::pixel::usb::kUvcEnabled;
44
45 string enabledPath;
46 constexpr char* kHsi2cPaths[] = { (char *) "/sys/devices/platform/108d0000.hsi2c",
47 (char *) "/sys/devices/platform/10cb0000.hsi2c" };
48 constexpr char kTcpcDevName[] = "i2c-max77759tcpc";
49 constexpr char kI2cClientId[] = "0025";
50 constexpr char kAccessoryLimitCurrent[] = "usb_limit_accessory_current";
51 constexpr char kAccessoryLimitCurrentEnable[] = "usb_limit_accessory_enable";
52 constexpr char kUpdateSdpEnumTimeout[] = "update_sdp_enum_timeout";
53
UsbGadget()54 UsbGadget::UsbGadget() : mGadgetIrqPath(""),
55 mI2cClientPath("") {
56 if (access(OS_DESC_PATH, R_OK) != 0) {
57 ALOGE("configfs setup not done yet");
58 abort();
59 }
60 }
61
getUsbGadgetIrqPath()62 Status UsbGadget::getUsbGadgetIrqPath() {
63 std::string irqs;
64 size_t read_pos = 0;
65 size_t found_pos = 0;
66
67 if (!ReadFileToString(kProcInterruptsPath, &irqs)) {
68 ALOGE("cannot read all interrupts");
69 return Status::ERROR;
70 }
71
72 while (true) {
73 found_pos = irqs.find_first_of("\n", read_pos);
74 if (found_pos == std::string::npos) {
75 ALOGI("the string of all interrupts is unexpected");
76 return Status::ERROR;
77 }
78
79 std::string single_irq = irqs.substr(read_pos, found_pos - read_pos);
80
81 if (single_irq.find("dwc3", 0) != std::string::npos) {
82 unsigned int dwc3_irq_number;
83 size_t dwc3_pos = single_irq.find_first_of(":");
84 if (!ParseUint(single_irq.substr(0, dwc3_pos), &dwc3_irq_number)) {
85 ALOGI("unknown IRQ strings");
86 return Status::ERROR;
87 }
88
89 mGadgetIrqPath = kProcIrqPath + single_irq.substr(0, dwc3_pos) + kSmpAffinityList;
90 break;
91 }
92
93 if (found_pos == irqs.npos) {
94 ALOGI("USB gadget doesn't start");
95 return Status::ERROR;
96 }
97
98 read_pos = found_pos + 1;
99 }
100
101 return Status::SUCCESS;
102 }
103
currentFunctionsAppliedCallback(bool functionsApplied,void * payload)104 void currentFunctionsAppliedCallback(bool functionsApplied, void *payload) {
105 UsbGadget *gadget = (UsbGadget *)payload;
106 gadget->mCurrentUsbFunctionsApplied = functionsApplied;
107 gadget->updateSdpEnumTimeout();
108 }
109
getCurrentUsbFunctions(const shared_ptr<IUsbGadgetCallback> & callback,int64_t in_transactionId)110 ScopedAStatus UsbGadget::getCurrentUsbFunctions(const shared_ptr<IUsbGadgetCallback> &callback,
111 int64_t in_transactionId) {
112 ScopedAStatus ret = callback->getCurrentUsbFunctionsCb(
113 mCurrentUsbFunctions,
114 mCurrentUsbFunctionsApplied ? Status::FUNCTIONS_APPLIED : Status::FUNCTIONS_NOT_APPLIED,
115 in_transactionId);
116 if (!ret.isOk())
117 ALOGE("Call to getCurrentUsbFunctionsCb failed %s", ret.getDescription().c_str());
118
119 return ScopedAStatus::ok();
120 }
121
getUsbSpeed(const shared_ptr<IUsbGadgetCallback> & callback,int64_t in_transactionId)122 ScopedAStatus UsbGadget::getUsbSpeed(const shared_ptr<IUsbGadgetCallback> &callback,
123 int64_t in_transactionId) {
124 std::string current_speed;
125 if (ReadFileToString(SPEED_PATH, ¤t_speed)) {
126 current_speed = Trim(current_speed);
127 ALOGI("current USB speed is %s", current_speed.c_str());
128 if (current_speed == "low-speed")
129 mUsbSpeed = UsbSpeed::LOWSPEED;
130 else if (current_speed == "full-speed")
131 mUsbSpeed = UsbSpeed::FULLSPEED;
132 else if (current_speed == "high-speed")
133 mUsbSpeed = UsbSpeed::HIGHSPEED;
134 else if (current_speed == "super-speed")
135 mUsbSpeed = UsbSpeed::SUPERSPEED;
136 else if (current_speed == "super-speed-plus")
137 mUsbSpeed = UsbSpeed::SUPERSPEED_10Gb;
138 else if (current_speed == "UNKNOWN")
139 mUsbSpeed = UsbSpeed::UNKNOWN;
140 else
141 mUsbSpeed = UsbSpeed::UNKNOWN;
142 } else {
143 ALOGE("Fail to read current speed");
144 mUsbSpeed = UsbSpeed::UNKNOWN;
145 }
146
147 if (callback) {
148 ScopedAStatus ret = callback->getUsbSpeedCb(mUsbSpeed, in_transactionId);
149
150 if (!ret.isOk())
151 ALOGE("Call to getUsbSpeedCb failed %s", ret.getDescription().c_str());
152 }
153
154 return ScopedAStatus::ok();
155 }
156
tearDownGadget()157 Status UsbGadget::tearDownGadget() {
158 if (Status(resetGadget()) != Status::SUCCESS){
159 return Status::ERROR;
160 }
161
162 if (monitorFfs.isMonitorRunning()) {
163 monitorFfs.reset();
164 } else {
165 ALOGI("mMonitor not running");
166 }
167 return Status::SUCCESS;
168 }
169
validateAndSetVidPid(uint64_t functions)170 static Status validateAndSetVidPid(uint64_t functions) {
171 Status ret = Status::SUCCESS;
172 std::string vendorFunctions = getVendorFunctions();
173
174 switch (functions) {
175 case GadgetFunction::MTP:
176 if (!(vendorFunctions == "user" || vendorFunctions == "")) {
177 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
178 ret = Status::CONFIGURATION_NOT_SUPPORTED;
179 } else {
180 ret = Status(setVidPid("0x18d1", "0x4ee1"));
181 }
182 break;
183 case GadgetFunction::ADB |
184 GadgetFunction::MTP:
185 if (!(vendorFunctions == "user" || vendorFunctions == "")) {
186 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
187 ret = Status::CONFIGURATION_NOT_SUPPORTED;
188 } else {
189 ret = Status(setVidPid("0x18d1", "0x4ee2"));
190 }
191 break;
192 case GadgetFunction::RNDIS:
193 case GadgetFunction::RNDIS |
194 GadgetFunction::NCM:
195 if (!(vendorFunctions == "user" || vendorFunctions == "")) {
196 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
197 ret = Status::CONFIGURATION_NOT_SUPPORTED;
198 } else {
199 ret = Status(setVidPid("0x18d1", "0x4ee3"));
200 }
201 break;
202 case GadgetFunction::ADB |
203 GadgetFunction::RNDIS:
204 case GadgetFunction::ADB |
205 GadgetFunction::RNDIS |
206 GadgetFunction::NCM:
207 if (vendorFunctions == "dm") {
208 ret = Status(setVidPid("0x04e8", "0x6862"));
209 } else {
210 if (!(vendorFunctions == "user" || vendorFunctions == "")) {
211 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
212 ret = Status::CONFIGURATION_NOT_SUPPORTED;
213 } else {
214 ret = Status(setVidPid("0x18d1", "0x4ee4"));
215 }
216 }
217 break;
218 case GadgetFunction::PTP:
219 if (!(vendorFunctions == "user" || vendorFunctions == "")) {
220 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
221 ret = Status::CONFIGURATION_NOT_SUPPORTED;
222 } else {
223 ret = Status(setVidPid("0x18d1", "0x4ee5"));
224 }
225 break;
226 case GadgetFunction::ADB |
227 GadgetFunction::PTP:
228 if (!(vendorFunctions == "user" || vendorFunctions == "")) {
229 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
230 ret = Status::CONFIGURATION_NOT_SUPPORTED;
231 } else {
232 ret = Status(setVidPid("0x18d1", "0x4ee6"));
233 }
234 break;
235 case GadgetFunction::ADB:
236 if (vendorFunctions == "dm") {
237 ret = Status(setVidPid("0x04e8", "0x6862"));
238 } else if (vendorFunctions == "etr_miu") {
239 ret = Status(setVidPid("0x18d1", "0x4ee2"));
240 } else if (vendorFunctions == "uwb_acm"){
241 ret = Status(setVidPid("0x18d1", "0x4ee2"));
242 } else {
243 if (!(vendorFunctions == "user" || vendorFunctions == "")) {
244 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
245 ret = Status::CONFIGURATION_NOT_SUPPORTED;
246 } else {
247 ret = Status(setVidPid("0x18d1", "0x4ee7"));
248 }
249 }
250 break;
251 case GadgetFunction::MIDI:
252 if (!(vendorFunctions == "user" || vendorFunctions == "")) {
253 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
254 ret = Status::CONFIGURATION_NOT_SUPPORTED;
255 } else {
256 ret = Status(setVidPid("0x18d1", "0x4ee8"));
257 }
258 break;
259 case GadgetFunction::ADB |
260 GadgetFunction::MIDI:
261 if (!(vendorFunctions == "user" || vendorFunctions == "")) {
262 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
263 ret = Status::CONFIGURATION_NOT_SUPPORTED;
264 } else {
265 ret = Status(setVidPid("0x18d1", "0x4ee9"));
266 }
267 break;
268 case GadgetFunction::ACCESSORY:
269 if (!(vendorFunctions == "user" || vendorFunctions == ""))
270 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
271 ret = Status(setVidPid("0x18d1", "0x2d00"));
272 break;
273 case GadgetFunction::ADB |
274 GadgetFunction::ACCESSORY:
275 if (!(vendorFunctions == "user" || vendorFunctions == ""))
276 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
277 ret = Status(setVidPid("0x18d1", "0x2d01"));
278 break;
279 case GadgetFunction::AUDIO_SOURCE:
280 if (!(vendorFunctions == "user" || vendorFunctions == ""))
281 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
282 ret = Status(setVidPid("0x18d1", "0x2d02"));
283 break;
284 case GadgetFunction::ADB |
285 GadgetFunction::AUDIO_SOURCE:
286 if (!(vendorFunctions == "user" || vendorFunctions == ""))
287 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
288 ret = Status(setVidPid("0x18d1", "0x2d03"));
289 break;
290 case GadgetFunction::ACCESSORY |
291 GadgetFunction::AUDIO_SOURCE:
292 if (!(vendorFunctions == "user" || vendorFunctions == ""))
293 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
294 ret = Status(setVidPid("0x18d1", "0x2d04"));
295 break;
296 case GadgetFunction::ADB |
297 GadgetFunction::ACCESSORY |
298 GadgetFunction::AUDIO_SOURCE:
299 if (!(vendorFunctions == "user" || vendorFunctions == ""))
300 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
301 ret = Status(setVidPid("0x18d1", "0x2d05"));
302 break;
303 case GadgetFunction::NCM:
304 if (!(vendorFunctions == "user" || vendorFunctions == ""))
305 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
306 ret = Status(setVidPid("0x18d1", "0x4eeb"));
307 break;
308 case GadgetFunction::ADB |
309 GadgetFunction::NCM:
310 if (vendorFunctions == "dm") {
311 ret = Status(setVidPid("0x04e8", "0x6862"));
312 } else {
313 if (!(vendorFunctions == "user" || vendorFunctions == ""))
314 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
315 ret = Status(setVidPid("0x18d1", "0x4eec"));
316 }
317 break;
318 case GadgetFunction::UVC:
319 if (!(vendorFunctions == "user" || vendorFunctions == "")) {
320 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
321 ret = Status::CONFIGURATION_NOT_SUPPORTED;
322 } else if (!GetBoolProperty(kUvcEnabled, false)) {
323 ALOGE("UVC function not enabled by config");
324 ret = Status::CONFIGURATION_NOT_SUPPORTED;
325 } else {
326 ret = Status(setVidPid("0x18d1", "0x4eed"));
327 }
328 break;
329 case GadgetFunction::ADB | GadgetFunction::UVC:
330 if (!(vendorFunctions == "user" || vendorFunctions == "")) {
331 ALOGE("Invalid vendorFunctions set: %s", vendorFunctions.c_str());
332 ret = Status::CONFIGURATION_NOT_SUPPORTED;
333 } else if (!GetBoolProperty(kUvcEnabled, false)) {
334 ALOGE("UVC function not enabled by config");
335 ret = Status::CONFIGURATION_NOT_SUPPORTED;
336 } else {
337 ret = Status(setVidPid("0x18d1", "0x4eee"));
338 }
339 break;
340 default:
341 ALOGE("Combination not supported");
342 ret = Status::CONFIGURATION_NOT_SUPPORTED;
343 }
344 return ret;
345 }
346
reset(const shared_ptr<IUsbGadgetCallback> & callback,int64_t in_transactionId)347 ScopedAStatus UsbGadget::reset(const shared_ptr<IUsbGadgetCallback> &callback,
348 int64_t in_transactionId) {
349 ALOGI("USB Gadget reset");
350
351 if (!WriteStringToFile("none", PULLUP_PATH)) {
352 ALOGI("Gadget cannot be pulled down");
353 if (callback)
354 callback->resetCb(Status::ERROR, in_transactionId);
355 return ScopedAStatus::fromServiceSpecificErrorWithMessage(
356 -1, "Gadget cannot be pulled down");
357 }
358
359 usleep(kDisconnectWaitUs);
360
361 if (!WriteStringToFile(kGadgetName, PULLUP_PATH)) {
362 ALOGI("Gadget cannot be pulled up");
363 if (callback)
364 callback->resetCb(Status::ERROR, in_transactionId);
365 return ScopedAStatus::fromServiceSpecificErrorWithMessage(
366 -1, "Gadget cannot be pulled up");
367 }
368 if (callback)
369 callback->resetCb(Status::SUCCESS, in_transactionId);
370
371 return ScopedAStatus::ok();
372 }
373
updateSdpEnumTimeout()374 void UsbGadget::updateSdpEnumTimeout() {
375 string update_sdp_enum_timeout_path;
376
377 if (mI2cClientPath.empty()) {
378 for (int i = 0; i < NUM_HSI2C_PATHS; ++i) {
379 mI2cClientPath = getI2cClientPath(kHsi2cPaths[i], kTcpcDevName, kI2cClientId);
380 if (mI2cClientPath.empty()) {
381 ALOGE("%s: Unable to locate i2c bus node", __func__);
382 } else {
383 break;
384 }
385 }
386 }
387
388 update_sdp_enum_timeout_path = mI2cClientPath + kUpdateSdpEnumTimeout;
389 if (!WriteStringToFile("1", update_sdp_enum_timeout_path)) {
390 ALOGE("%s: Unable to write to %s.", __func__, update_sdp_enum_timeout_path.c_str());
391 } else {
392 ALOGI("%s: Updated SDP enumeration timeout value.", __func__);
393 }
394 }
395
setupFunctions(long functions,const shared_ptr<IUsbGadgetCallback> & callback,uint64_t timeout,int64_t in_transactionId)396 Status UsbGadget::setupFunctions(long functions,
397 const shared_ptr<IUsbGadgetCallback> &callback, uint64_t timeout,
398 int64_t in_transactionId) {
399 bool ffsEnabled = false;
400 int i = 0;
401
402 if (Status(addGenericAndroidFunctions(&monitorFfs, functions, &ffsEnabled, &i)) !=
403 Status::SUCCESS)
404 return Status::ERROR;
405
406 std::string vendorFunctions = getVendorFunctions();
407
408 if (((functions & GadgetFunction::NCM) != 0) && (vendorFunctions != "dm")) {
409 if (linkFunction("ncm.gs9", i++))
410 return Status::ERROR;
411 }
412
413 if (vendorFunctions == "dm") {
414 ALOGI("enable usbradio debug functions");
415 if ((functions & GadgetFunction::RNDIS) != 0) {
416 if (linkFunction("acm.gs6", i++))
417 return Status::ERROR;
418 if (linkFunction("dm.gs7", i++))
419 return Status::ERROR;
420 } else {
421 if (linkFunction("dm.gs7", i++))
422 return Status::ERROR;
423 if (linkFunction("acm.gs6", i++))
424 return Status::ERROR;
425 }
426 } else if (vendorFunctions == "etr_miu") {
427 ALOGI("enable etr_miu functions");
428 if (linkFunction("etr_miu.gs11", i++))
429 return Status::ERROR;
430 } else if (vendorFunctions == "uwb_acm") {
431 ALOGI("enable uwb acm function");
432 if (linkFunction("acm.uwb0", i++))
433 return Status::ERROR;
434 }
435
436 if ((functions & GadgetFunction::ADB) != 0) {
437 ffsEnabled = true;
438 if (Status(addAdb(&monitorFfs, &i)) != Status::SUCCESS)
439 return Status::ERROR;
440 }
441
442 if (((functions & GadgetFunction::NCM) != 0) && (vendorFunctions == "dm")) {
443 if (linkFunction("ncm.gs9", i++))
444 return Status::ERROR;
445 }
446
447 // Pull up the gadget right away when there are no ffs functions.
448 if (!ffsEnabled) {
449 if (!WriteStringToFile(kGadgetName, PULLUP_PATH))
450 return Status::ERROR;
451 mCurrentUsbFunctionsApplied = true;
452 if (callback)
453 callback->setCurrentUsbFunctionsCb(functions, Status::SUCCESS, in_transactionId);
454 updateSdpEnumTimeout();
455 return Status::SUCCESS;
456 }
457
458 monitorFfs.registerFunctionsAppliedCallback(¤tFunctionsAppliedCallback, this);
459 // Monitors the ffs paths to pull up the gadget when descriptors are written.
460 // Also takes of the pulling up the gadget again if the userspace process
461 // dies and restarts.
462 monitorFfs.startMonitor();
463
464 if (kDebug)
465 ALOGI("Mainthread in Cv");
466
467 if (callback) {
468 bool pullup = monitorFfs.waitForPullUp(timeout);
469 ScopedAStatus ret = callback->setCurrentUsbFunctionsCb(
470 functions, pullup ? Status::SUCCESS : Status::ERROR, in_transactionId);
471 if (!ret.isOk()) {
472 ALOGE("setCurrentUsbFunctionsCb error %s", ret.getDescription().c_str());
473 return Status::ERROR;
474 }
475 }
476 return Status::SUCCESS;
477 }
478
setCurrentUsbFunctions(long functions,const shared_ptr<IUsbGadgetCallback> & callback,int64_t timeout,int64_t in_transactionId)479 ScopedAStatus UsbGadget::setCurrentUsbFunctions(long functions,
480 const shared_ptr<IUsbGadgetCallback> &callback,
481 int64_t timeout,
482 int64_t in_transactionId) {
483 std::unique_lock<std::mutex> lk(mLockSetCurrentFunction);
484 std::string current_usb_power_operation_mode, current_usb_type;
485 std::string usb_limit_sink_enable;
486 std::string accessoryCurrentLimitEnablePath, accessoryCurrentLimitPath;
487
488 mCurrentUsbFunctions = functions;
489 mCurrentUsbFunctionsApplied = false;
490
491 if (mI2cClientPath.empty()) {
492 for (int i = 0; i < NUM_HSI2C_PATHS; i++) {
493 mI2cClientPath = getI2cClientPath(kHsi2cPaths[i], kTcpcDevName, kI2cClientId);
494 if (mI2cClientPath.empty()) {
495 ALOGE("%s: Unable to locate i2c bus node", __func__);
496 } else {
497 break;
498 }
499 }
500 }
501 accessoryCurrentLimitPath = mI2cClientPath + kAccessoryLimitCurrent;
502 accessoryCurrentLimitEnablePath = mI2cClientPath + kAccessoryLimitCurrentEnable;
503
504 // Get the gadget IRQ number before tearDownGadget()
505 if (mGadgetIrqPath.empty())
506 getUsbGadgetIrqPath();
507
508 // Unlink the gadget and stop the monitor if running.
509 Status status = tearDownGadget();
510 if (status != Status::SUCCESS) {
511 goto error;
512 }
513
514 ALOGI("Returned from tearDown gadget");
515
516 // Leave the gadget pulled down to give time for the host to sense disconnect.
517 usleep(kDisconnectWaitUs);
518
519 if (functions == GadgetFunction::NONE) {
520 if (callback == NULL)
521 return ScopedAStatus::fromServiceSpecificErrorWithMessage(
522 -1, "callback == NULL");
523 ScopedAStatus ret = callback->setCurrentUsbFunctionsCb(functions, Status::SUCCESS, in_transactionId);
524 if (!ret.isOk())
525 ALOGE("Error while calling setCurrentUsbFunctionsCb %s", ret.getDescription().c_str());
526 return ScopedAStatus::fromServiceSpecificErrorWithMessage(
527 -1, "Error while calling setCurrentUsbFunctionsCb");
528 }
529
530 status = validateAndSetVidPid(functions);
531
532 if (status != Status::SUCCESS) {
533 goto error;
534 }
535
536 status = setupFunctions(functions, callback, timeout, in_transactionId);
537 if (status != Status::SUCCESS) {
538 goto error;
539 }
540
541 if (functions & GadgetFunction::NCM) {
542 if (!mGadgetIrqPath.empty()) {
543 if (!WriteStringToFile(BIG_CORE, mGadgetIrqPath))
544 ALOGI("Cannot move gadget IRQ to big core, path:%s", mGadgetIrqPath.c_str());
545 }
546 } else {
547 if (!mGadgetIrqPath.empty()) {
548 if (!WriteStringToFile(MEDIUM_CORE, mGadgetIrqPath))
549 ALOGI("Cannot move gadget IRQ to medium core, path:%s", mGadgetIrqPath.c_str());
550 }
551 }
552
553 if (ReadFileToString(CURRENT_USB_TYPE_PATH, ¤t_usb_type))
554 current_usb_type = Trim(current_usb_type);
555
556 if (ReadFileToString(CURRENT_USB_POWER_OPERATION_MODE_PATH, ¤t_usb_power_operation_mode))
557 current_usb_power_operation_mode = Trim(current_usb_power_operation_mode);
558
559 if (functions & GadgetFunction::ACCESSORY &&
560 current_usb_type == "Unknown SDP [CDP] DCP" &&
561 (current_usb_power_operation_mode == "default" ||
562 current_usb_power_operation_mode == "1.5A")) {
563 if (!WriteStringToFile("1300000", accessoryCurrentLimitPath)) {
564 ALOGI("Write 1.3A to limit current fail");
565 } else {
566 if (!WriteStringToFile("1", accessoryCurrentLimitEnablePath)) {
567 ALOGI("Enable limit current fail");
568 }
569 }
570 } else {
571 if (!WriteStringToFile("0", accessoryCurrentLimitEnablePath))
572 ALOGI("unvote accessory limit current failed");
573 }
574
575 ALOGI("Usb Gadget setcurrent functions called successfully");
576 return ScopedAStatus::ok();
577
578 error:
579 ALOGI("Usb Gadget setcurrent functions failed");
580 if (callback == NULL)
581 return ScopedAStatus::fromServiceSpecificErrorWithMessage(
582 -1, "Usb Gadget setcurrent functions failed");
583 ScopedAStatus ret = callback->setCurrentUsbFunctionsCb(functions, status, in_transactionId);
584 if (!ret.isOk())
585 ALOGE("Error while calling setCurrentUsbFunctionsCb %s", ret.getDescription().c_str());
586 return ScopedAStatus::fromServiceSpecificErrorWithMessage(
587 -1, "Error while calling setCurrentUsbFunctionsCb");
588 }
589 } // namespace gadget
590 } // namespace usb
591 } // namespace hardware
592 } // namespace android
593 } // aidl
594