1 /*
2  * Copyright (C) 2021 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 #include "Service.h"
18 
19 #include <AndroidVersionUtil.h>
20 #include <android/binder_auto_utils.h>
21 #include <android/binder_manager.h>
22 #include <android/binder_process.h>
23 
24 #include <nnapi/IDevice.h>
25 #include <nnapi/Result.h>
26 #include <nnapi/Types.h>
27 #include <nnapi/hal/ResilientDevice.h>
28 #include <string>
29 
30 #include "Device.h"
31 
32 namespace aidl::android::hardware::neuralnetworks::utils {
33 
getDevice(const std::string & instanceName)34 nn::GeneralResult<nn::SharedDevice> getDevice(const std::string& instanceName) {
35     auto fullName = std::string(IDevice::descriptor) + "/" + instanceName;
36     hal::utils::ResilientDevice::Factory makeDevice =
37             [instanceName,
38              name = std::move(fullName)](bool blocking) -> nn::GeneralResult<nn::SharedDevice> {
39         std::add_pointer_t<AIBinder*(const char*)> getService;
40         if (blocking) {
41             if (__builtin_available(android __NNAPI_AIDL_MIN_ANDROID_API__, *)) {
42                 getService = AServiceManager_waitForService;
43             } else {
44                 getService = AServiceManager_getService;
45             }
46         } else {
47             getService = AServiceManager_checkService;
48         }
49 
50         auto service = IDevice::fromBinder(ndk::SpAIBinder(getService(name.c_str())));
51         if (service == nullptr) {
52             return NN_ERROR()
53                    << (blocking ? "AServiceManager_waitForService (or AServiceManager_getService)"
54                                 : "AServiceManager_checkService")
55                    << " returned nullptr";
56         }
57         ABinderProcess_startThreadPool();
58         return Device::create(instanceName, std::move(service));
59     };
60 
61     return hal::utils::ResilientDevice::create(std::move(makeDevice));
62 }
63 
64 }  // namespace aidl::android::hardware::neuralnetworks::utils
65