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, &current_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(&currentFunctionsAppliedCallback, 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, &current_usb_type))
554         current_usb_type = Trim(current_usb_type);
555 
556     if (ReadFileToString(CURRENT_USB_POWER_OPERATION_MODE_PATH, &current_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