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