mirror of
https://github.com/chararomandroid/android_device_samsung_a20
synced 2026-08-23 12:35:33 -04:00
universal7885: Remove useless stuffs
Also reorganize
This commit is contained in:
parent
f8f5a64999
commit
134d87b132
111 changed files with 0 additions and 72 deletions
23
universal7885-common/bin/eklogger/Android.bp
Normal file
23
universal7885-common/bin/eklogger/Android.bp
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
//
|
||||
// Copyright (C) 2021 Soo Hwan Na "Royna"
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
cc_binary {
|
||||
name: "eklogger",
|
||||
srcs: [
|
||||
"Logger.cpp",
|
||||
],
|
||||
init_rc: ["eklogger.rc"],
|
||||
}
|
||||
39
universal7885-common/bin/eklogger/Logger.cpp
Normal file
39
universal7885-common/bin/eklogger/Logger.cpp
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright 2021 Soo Hwan Na "Royna"
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <thread>
|
||||
|
||||
#define KMSG_PATH "/proc/kmsg"
|
||||
#define WRITE_KMSG "/data/debug/kmsg.txt"
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
void copy_kmsg() {
|
||||
std::ifstream readfile(KMSG_PATH);
|
||||
std::ofstream writefile(WRITE_KMSG);
|
||||
writefile << readfile.rdbuf();
|
||||
}
|
||||
void copy_logcat() {
|
||||
system("/system/bin/logcat -b all -f /data/debug/logcat.txt");
|
||||
}
|
||||
int main() {
|
||||
std::thread kmsg(copy_kmsg);
|
||||
std::thread logcat(copy_logcat);
|
||||
kmsg.join();
|
||||
logcat.join();
|
||||
return 0;
|
||||
}
|
||||
14
universal7885-common/bin/eklogger/eklogger.rc
Normal file
14
universal7885-common/bin/eklogger/eklogger.rc
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
service eureka_debugger /system/bin/eklogger
|
||||
user root
|
||||
group system
|
||||
oneshot
|
||||
disabled
|
||||
|
||||
on post-fs-data
|
||||
mkdir /data/debug 0755 root system encryption=None
|
||||
rm /data/debug/logcat.txt
|
||||
rm /data/debug/kmsg.txt
|
||||
start eureka_debugger
|
||||
|
||||
on property:sys.boot_completed=1
|
||||
stop eureka_debugger
|
||||
3
universal7885-common/bin/hardware/interfaces/Android.bp
Normal file
3
universal7885-common/bin/hardware/interfaces/Android.bp
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
hidl_package_root{
|
||||
name: "vendor.eureka",
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
hidl_interface {
|
||||
name: "vendor.eureka.hardware.fmradio@1.0",
|
||||
root: "vendor.eureka",
|
||||
srcs: [
|
||||
"types.hal",
|
||||
"IFMRadio.hal",
|
||||
],
|
||||
interfaces: [
|
||||
"android.hidl.base@1.0",
|
||||
],
|
||||
gen_java: true,
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
// Copyright (C) 2021 Eureka Team
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package vendor.eureka.hardware.fmradio@1.0;
|
||||
|
||||
interface IFMRadio {
|
||||
setManualFreq(float freq);
|
||||
adjustFreqByStep(Direction dir);
|
||||
};
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
// Copyright (C) 2021 Eureka Team
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package vendor.eureka.hardware.fmradio@1.0;
|
||||
|
||||
enum Direction : int32_t {
|
||||
UP,
|
||||
DOWN,
|
||||
};
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
hidl_interface {
|
||||
name: "vendor.eureka.hardware.fmradio@1.1",
|
||||
root: "vendor.eureka",
|
||||
srcs: [
|
||||
"types.hal",
|
||||
"IFMRadio.hal",
|
||||
],
|
||||
interfaces: [
|
||||
"android.hidl.base@1.0",
|
||||
"vendor.eureka.hardware.fmradio@1.0",
|
||||
],
|
||||
gen_java: true,
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
// Copyright (C) 2021 Eureka Team
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package vendor.eureka.hardware.fmradio@1.1;
|
||||
|
||||
import @1.0::IFMRadio;
|
||||
|
||||
interface IFMRadio extends @1.0::IFMRadio {
|
||||
getFreqFromSysfs() generates (int32_t freq);
|
||||
isAvailable() generates (Status status);
|
||||
};
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
// Copyright (C) 2021 Eureka Team
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package vendor.eureka.hardware.fmradio@1.1;
|
||||
|
||||
enum Status : int32_t {
|
||||
YES,
|
||||
NO,
|
||||
};
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
hidl_interface {
|
||||
name: "vendor.eureka.hardware.fmradio@1.2",
|
||||
root: "vendor.eureka",
|
||||
srcs: [
|
||||
"types.hal",
|
||||
"IFMRadio.hal",
|
||||
],
|
||||
interfaces: [
|
||||
"android.hidl.base@1.0",
|
||||
"vendor.eureka.hardware.fmradio@1.1",
|
||||
"vendor.eureka.hardware.fmradio@1.0",
|
||||
],
|
||||
gen_java: true,
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
// Copyright (C) 2021 Eureka Team
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package vendor.eureka.hardware.fmradio@1.2;
|
||||
|
||||
import @1.1::IFMRadio;
|
||||
|
||||
interface IFMRadio extends @1.1::IFMRadio {
|
||||
setChannelSpacing(Space space);
|
||||
getChannelSpacing() generates (Space space);
|
||||
};
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
// FIXME: your file license if you have one
|
||||
|
||||
cc_binary {
|
||||
name: "vendor.eureka.hardware.fmradio@1.2-service",
|
||||
proprietary: true,
|
||||
srcs: [
|
||||
"FMRadio.cpp",
|
||||
"service.cpp",
|
||||
],
|
||||
shared_libs: [
|
||||
"libhidlbase",
|
||||
"libutils",
|
||||
"liblog",
|
||||
"vendor.eureka.hardware.fmradio@1.0",
|
||||
"vendor.eureka.hardware.fmradio@1.1",
|
||||
"vendor.eureka.hardware.fmradio@1.2",
|
||||
],
|
||||
init_rc: [ "vendor.eureka.hardware.fmradio@1.2-service.rc" ],
|
||||
vintf_fragments: [ "vendor.eureka.hardware.fmradio@1.2.xml" ],
|
||||
}
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
// Copyright (C) 2021 Eureka Team
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "FMRadio.h"
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
static int mChannelSpacing = 3;
|
||||
|
||||
namespace vendor::eureka::hardware::fmradio::V1_2 {
|
||||
|
||||
Return<void> FMRadio::setManualFreq(float freq) {
|
||||
std::ofstream file;
|
||||
file.open("/sys/devices/virtual/s610_radio/s610_radio/radio_freq_ctrl");
|
||||
file << freq * 1000;
|
||||
file.close();
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<void> FMRadio::adjustFreqByStep(fmradio::V1_0::Direction dir) {
|
||||
std::ofstream file;
|
||||
std::string value = "";
|
||||
if (dir == V1_0::Direction::UP) {
|
||||
value = "1 " + std::to_string(mChannelSpacing * 10);
|
||||
} else if (dir == V1_0::Direction::DOWN) {
|
||||
value = "0 " + std::to_string(mChannelSpacing * 10);
|
||||
}
|
||||
file.open("/sys/devices/virtual/s610_radio/s610_radio/radio_freq_seek");
|
||||
file << value;
|
||||
file.close();
|
||||
return Void();
|
||||
}
|
||||
Return<V1_1::Status> FMRadio::isAvailable() {
|
||||
struct stat info;
|
||||
if (stat("/sys/devices/virtual/s610_radio/s610_radio/", &info) != 0) {
|
||||
return V1_1::Status::NO;
|
||||
} else {
|
||||
return V1_1::Status::YES;
|
||||
}
|
||||
}
|
||||
Return<void> FMRadio::setChannelSpacing(V1_2::Space space) {
|
||||
mChannelSpacing = (int)space;
|
||||
return Void();
|
||||
}
|
||||
Return<int32_t> FMRadio::getFreqFromSysfs() {
|
||||
std::ifstream file;
|
||||
std::string value;
|
||||
file.open("/sys/devices/virtual/s610_radio/s610_radio/radio_freq_ctrl");
|
||||
std::getline(file, value);
|
||||
file.close();
|
||||
return std::stoi(value);
|
||||
}
|
||||
Return<V1_2::Space> FMRadio::getChannelSpacing() {
|
||||
switch (mChannelSpacing) {
|
||||
case 1:
|
||||
return V1_2::Space::CHANNEL_SPACING_10HZ;
|
||||
case 2:
|
||||
return V1_2::Space::CHANNEL_SPACING_20HZ;
|
||||
case 3:
|
||||
return V1_2::Space::CHANNEL_SPACING_30HZ;
|
||||
case 4:
|
||||
return V1_2::Space::CHANNEL_SPACING_40HZ;
|
||||
case 5:
|
||||
return V1_2::Space::CHANNEL_SPACING_50HZ;
|
||||
default:
|
||||
return V1_2::Space::CHANNEL_SPACING_30HZ;
|
||||
}
|
||||
}
|
||||
IFMRadio *FMRadio::getInstance(void) { return new FMRadio(); }
|
||||
} // namespace vendor::eureka::hardware::fmradio::V1_2
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
// Copyright (C) 2021 Eureka Team
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <hidl/MQDescriptor.h>
|
||||
#include <hidl/Status.h>
|
||||
#include <vendor/eureka/hardware/fmradio/1.2/IFMRadio.h>
|
||||
|
||||
namespace vendor::eureka::hardware::fmradio::V1_2 {
|
||||
|
||||
using ::android::sp;
|
||||
using ::android::hardware::hidl_array;
|
||||
using ::android::hardware::hidl_memory;
|
||||
using ::android::hardware::hidl_string;
|
||||
using ::android::hardware::hidl_vec;
|
||||
using ::android::hardware::Return;
|
||||
using ::android::hardware::Void;
|
||||
|
||||
struct FMRadio : public IFMRadio {
|
||||
// Methods from ::vendor::eureka::hardware::fmradio::V1_0::IFMRadio follow.
|
||||
Return<void> setManualFreq(float freq);
|
||||
Return<void> adjustFreqByStep(V1_0::Direction dir);
|
||||
// Methods from ::vendor::eureka::hardware::fmradio::V1_1::IFMRadio follow.
|
||||
Return<V1_1::Status> isAvailable();
|
||||
Return<int32_t> getFreqFromSysfs();
|
||||
// Methods from ::vendor::eureka::hardware::fmradio::V1_2::IFMRadio follow.
|
||||
Return<void> setChannelSpacing(V1_2::Space space);
|
||||
Return<V1_2::Space> getChannelSpacing();
|
||||
// Methods from ::android::hidl::base::V1_0::IBase follow.
|
||||
static IFMRadio *getInstance(void);
|
||||
};
|
||||
} // namespace vendor::eureka::hardware::fmradio::V1_2
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
// Copyright (C) 2021 Eureka Team
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#define LOG_TAG "vendor.eureka.hardware.fmradio@1.2-service"
|
||||
|
||||
#include <vendor/eureka/hardware/fmradio/1.2/IFMRadio.h>
|
||||
|
||||
#include <hidl/LegacySupport.h>
|
||||
|
||||
#include "FMRadio.h"
|
||||
|
||||
using android::sp;
|
||||
using android::hardware::configureRpcThreadpool;
|
||||
using android::hardware::joinRpcThreadpool;
|
||||
using vendor::eureka::hardware::fmradio::V1_2::FMRadio;
|
||||
using vendor::eureka::hardware::fmradio::V1_2::IFMRadio;
|
||||
|
||||
int main() {
|
||||
int ret;
|
||||
android::sp<IFMRadio> mFMService = FMRadio::getInstance();
|
||||
configureRpcThreadpool(1, true /*callerWillJoin*/);
|
||||
|
||||
if (mFMService != nullptr) {
|
||||
ret = mFMService->registerAsService();
|
||||
if (ret != 0) {
|
||||
ALOGE("Can't register instance of FMRadio HAL, nullptr");
|
||||
} else {
|
||||
ALOGI("registered FMRadio HAL");
|
||||
}
|
||||
} else {
|
||||
ALOGE("Can't create instance of FMRadio HAL, nullptr");
|
||||
}
|
||||
joinRpcThreadpool();
|
||||
|
||||
return -1; // should never get here
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
service vendor.fm-hal /vendor/bin/vendor.eureka.hardware.fmradio@1.2-service
|
||||
interface vendor.eureka.hardware.fmradio@1.0::IFMRadio default
|
||||
interface vendor.eureka.hardware.fmradio@1.1::IFMRadio default
|
||||
interface vendor.eureka.hardware.fmradio@1.2::IFMRadio default
|
||||
class hal
|
||||
user root
|
||||
group root
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0"?>
|
||||
<manifest version="1.0" type="device">
|
||||
<hal format="hidl">
|
||||
<name>vendor.eureka.hardware.fmradio</name>
|
||||
<transport>hwbinder</transport>
|
||||
<version>1.2</version>
|
||||
<interface>
|
||||
<name>IFMRadio</name>
|
||||
<instance>default</instance>
|
||||
</interface>
|
||||
</hal>
|
||||
</manifest>
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
// Copyright (C) 2021 Eureka Team
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package vendor.eureka.hardware.fmradio@1.2;
|
||||
|
||||
enum Space : int32_t {
|
||||
CHANNEL_SPACING_10HZ = 1,
|
||||
CHANNEL_SPACING_20HZ,
|
||||
CHANNEL_SPACING_30HZ,
|
||||
CHANNEL_SPACING_40HZ,
|
||||
CHANNEL_SPACING_50HZ = 5,
|
||||
};
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
hidl_interface {
|
||||
name: "vendor.eureka.hardware.parts@1.0",
|
||||
root: "vendor.eureka",
|
||||
srcs: [
|
||||
"types.hal",
|
||||
"IBatteryStats.hal",
|
||||
"IFlashBrightness.hal",
|
||||
"IDisplayConfigs.hal",
|
||||
"ISwapOnData.hal",
|
||||
],
|
||||
interfaces: [ "android.hidl.base@1.0" ],
|
||||
gen_java: false,
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
// Copyright (C) 2021 Eureka Team
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package vendor.eureka.hardware.parts@1.0;
|
||||
|
||||
interface IBatteryStats {
|
||||
getBatteryStats(SysfsType stats) generates (int32_t result);
|
||||
setBatteryWritable(SysfsType stats, Number value);
|
||||
};
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
// Copyright (C) 2021 Eureka Team
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package vendor.eureka.hardware.parts@1.0;
|
||||
|
||||
interface IDisplayConfigs {
|
||||
writeDisplay(Number enable, Display type);
|
||||
};
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
// Copyright (C) 2021 Eureka Team
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package vendor.eureka.hardware.parts@1.0;
|
||||
|
||||
interface IFlashBrightness {
|
||||
setFlashlightWritable(Value value);
|
||||
setFlashlightEnable(Number enable);
|
||||
readFlashlightstats(Device device) generates (int32_t value);
|
||||
};
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
// Copyright (C) 2021 Eureka Team
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package vendor.eureka.hardware.parts@1.0;
|
||||
|
||||
interface ISwapOnData {
|
||||
setSwapSize(int32_t size /* Size in megabytes */);
|
||||
setSwapOn();
|
||||
setSwapOff();
|
||||
};
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
// FIXME: your file license if you have one
|
||||
|
||||
cc_binary {
|
||||
name: "vendor.eureka.hardware.parts@1.0-service",
|
||||
proprietary: true,
|
||||
srcs: [
|
||||
"Battery.cpp",
|
||||
"FlashLight.cpp",
|
||||
"Display.cpp",
|
||||
"Swap.cpp",
|
||||
"service.cpp",
|
||||
],
|
||||
shared_libs: [
|
||||
"libhidlbase",
|
||||
"libutils",
|
||||
"liblog",
|
||||
"vendor.eureka.hardware.parts@1.0",
|
||||
],
|
||||
init_rc: [ "vendor.eureka.hardware.parts@1.0-service.rc" ],
|
||||
vintf_fragments: [ "vendor.eureka.hardware.parts@1.0.xml" ],
|
||||
}
|
||||
|
|
@ -0,0 +1,111 @@
|
|||
// Copyright (C) 2021 Eureka Team
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "Battery.h"
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace vendor::eureka::hardware::parts::V1_0 {
|
||||
|
||||
// Methods from ::android::hardware::battery::V1_0::IBattery follow.
|
||||
Return<int32_t> BatteryStats::getBatteryStats(parts::V1_0::SysfsType stats) {
|
||||
std::ifstream file;
|
||||
std::string filename;
|
||||
switch (stats) {
|
||||
case SysfsType::CAPACITY_MAX:
|
||||
filename = "/sys/devices/platform/battery/power_supply/battery/charge_full";
|
||||
break;
|
||||
case SysfsType::TEMP:
|
||||
filename = "/sys/devices/platform/battery/power_supply/battery/batt_temp";
|
||||
break;
|
||||
case SysfsType::CAPACITY_CURRENT:
|
||||
filename = "/sys/devices/platform/battery/power_supply/battery/capacity";
|
||||
break;
|
||||
case SysfsType::CURRENT:
|
||||
filename = "/sys/devices/platform/battery/power_supply/battery/current_now";
|
||||
break;
|
||||
case SysfsType::FASTCHARGE:
|
||||
filename = "/sys/class/sec/switch/afc_disable";
|
||||
break;
|
||||
case SysfsType::CHARGE:
|
||||
filename =
|
||||
"/sys/devices/platform/battery/power_supply/battery/batt_slate_mode";
|
||||
break;
|
||||
default:
|
||||
filename = "";
|
||||
break;
|
||||
}
|
||||
std::string value;
|
||||
int32_t intvalue;
|
||||
file.open(filename);
|
||||
if (file.is_open()) {
|
||||
getline(file, value);
|
||||
file.close();
|
||||
std::stringstream val(value);
|
||||
val >> intvalue;
|
||||
return intvalue;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
Return<void> BatteryStats::setBatteryWritable(parts::V1_0::SysfsType stats,
|
||||
parts::V1_0::Number value) {
|
||||
std::ofstream file;
|
||||
std::string filename;
|
||||
bool FastCharge = false;
|
||||
switch (stats) {
|
||||
case SysfsType::CAPACITY_MAX:
|
||||
filename = "/sys/devices/platform/battery/power_supply/battery/charge_full";
|
||||
break;
|
||||
case SysfsType::TEMP:
|
||||
filename = "/sys/devices/platform/battery/power_supply/battery/batt_temp";
|
||||
break;
|
||||
case SysfsType::CAPACITY_CURRENT:
|
||||
filename = "/sys/devices/platform/battery/power_supply/battery/capacity";
|
||||
break;
|
||||
case SysfsType::CURRENT:
|
||||
filename = "/sys/devices/platform/battery/power_supply/battery/current_now";
|
||||
break;
|
||||
case SysfsType::FASTCHARGE:
|
||||
filename = "/sys/class/sec/switch/afc_disable";
|
||||
FastCharge = true;
|
||||
break;
|
||||
case SysfsType::CHARGE:
|
||||
filename =
|
||||
"/sys/devices/platform/battery/power_supply/battery/batt_slate_mode";
|
||||
break;
|
||||
default:
|
||||
filename = "";
|
||||
break;
|
||||
}
|
||||
if (FastCharge)
|
||||
seteuid(ANDROID_SYSTEM_UID);
|
||||
file.open(filename);
|
||||
int write;
|
||||
if (value == Number::ENABLE) {
|
||||
write = 1;
|
||||
} else {
|
||||
write = 0;
|
||||
}
|
||||
file << write;
|
||||
file.close();
|
||||
if (FastCharge)
|
||||
seteuid(ANDROID_ROOT_UID);
|
||||
return Void();
|
||||
}
|
||||
|
||||
IBatteryStats *BatteryStats::getInstance(void) { return new BatteryStats(); }
|
||||
} // namespace vendor::eureka::hardware::parts::V1_0
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
// Copyright (C) 2021 Eureka Team
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <hidl/MQDescriptor.h>
|
||||
#include <hidl/Status.h>
|
||||
#include <vendor/eureka/hardware/parts/1.0/IBatteryStats.h>
|
||||
|
||||
#define ANDROID_SYSTEM_UID 1000
|
||||
#define ANDROID_ROOT_UID 0
|
||||
|
||||
namespace vendor::eureka::hardware::parts::V1_0 {
|
||||
|
||||
using ::android::sp;
|
||||
using ::android::hardware::hidl_array;
|
||||
using ::android::hardware::hidl_memory;
|
||||
using ::android::hardware::hidl_string;
|
||||
using ::android::hardware::hidl_vec;
|
||||
using ::android::hardware::Return;
|
||||
using ::android::hardware::Void;
|
||||
|
||||
struct BatteryStats : public IBatteryStats {
|
||||
// Methods from ::vendor::eureka::hardware::parts::V1_0::IBatteryStats follow.
|
||||
Return<int32_t> getBatteryStats(SysfsType stats) override;
|
||||
Return<void> setBatteryWritable(SysfsType stats, Number value) override;
|
||||
|
||||
// Methods from ::android::hidl::base::V1_0::IBase follow.
|
||||
static IBatteryStats *getInstance(void);
|
||||
};
|
||||
} // namespace vendor::eureka::hardware::parts::V1_0
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
// Copyright (C) 2021 Eureka Team
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "Display.h"
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
namespace vendor::eureka::hardware::parts::V1_0 {
|
||||
|
||||
Return<void> DisplayConfigs::writeDisplay(parts::V1_0::Number enable,
|
||||
parts::V1_0::Display type) {
|
||||
std::ofstream file;
|
||||
std::string writevalue;
|
||||
if (type == Display::DOUBLE_TAP) {
|
||||
writevalue = "aot_enable";
|
||||
} else if (type == Display::GLOVE_MODE) {
|
||||
writevalue = "glove_mode";
|
||||
}
|
||||
writevalue += ",";
|
||||
if (enable == Number::ENABLE) {
|
||||
writevalue += "1";
|
||||
} else {
|
||||
writevalue += "0";
|
||||
}
|
||||
file.open("/sys/class/sec/tsp/cmd");
|
||||
file << writevalue;
|
||||
file.close();
|
||||
return Void();
|
||||
}
|
||||
|
||||
IDisplayConfigs *DisplayConfigs::getInstance(void) {
|
||||
return new DisplayConfigs();
|
||||
}
|
||||
} // namespace vendor::eureka::hardware::parts::V1_0
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
// Copyright (C) 2021 Eureka Team
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <hidl/MQDescriptor.h>
|
||||
#include <hidl/Status.h>
|
||||
#include <vendor/eureka/hardware/parts/1.0/IDisplayConfigs.h>
|
||||
|
||||
namespace vendor::eureka::hardware::parts::V1_0 {
|
||||
|
||||
using ::android::sp;
|
||||
using ::android::hardware::hidl_array;
|
||||
using ::android::hardware::hidl_memory;
|
||||
using ::android::hardware::hidl_string;
|
||||
using ::android::hardware::hidl_vec;
|
||||
using ::android::hardware::Return;
|
||||
using ::android::hardware::Void;
|
||||
|
||||
struct DisplayConfigs : public IDisplayConfigs {
|
||||
// Methods from ::vendor::eureka::hardware::parts::V1_0::IDisplayConfigs
|
||||
// follow.
|
||||
Return<void> writeDisplay(Number enable, Display type);
|
||||
// Methods from ::android::hidl::base::V1_0::IBase follow.
|
||||
static IDisplayConfigs *getInstance(void);
|
||||
};
|
||||
} // namespace vendor::eureka::hardware::parts::V1_0
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
// Copyright (C) 2021 Eureka Team
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "FlashLight.h"
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
namespace vendor::eureka::hardware::parts::V1_0 {
|
||||
|
||||
// Methods from ::android::hardware::parts::V1_0::IFlashLight follow.
|
||||
Return<void> FlashBrightness::setFlashlightEnable(parts::V1_0::Number enable) {
|
||||
std::ofstream file;
|
||||
std::string writevalue;
|
||||
switch (enable) {
|
||||
case Number::ENABLE:
|
||||
writevalue = "1";
|
||||
break;
|
||||
case Number::DISABLE:
|
||||
writevalue = "0";
|
||||
break;
|
||||
default:
|
||||
writevalue = "";
|
||||
break;
|
||||
}
|
||||
file.open("/sys/class/camera/flash/torch_brightness_lvl_enable");
|
||||
file << writevalue;
|
||||
file.close();
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<void> FlashBrightness::setFlashlightWritable(parts::V1_0::Value value) {
|
||||
std::ofstream file;
|
||||
std::string writevalue = std::to_string((int)value);
|
||||
file.open("/sys/class/camera/flash/torch_brightness_lvl");
|
||||
file << writevalue;
|
||||
file.close();
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<int32_t>
|
||||
FlashBrightness::readFlashlightstats(parts::V1_0::Device device) {
|
||||
std::ifstream file;
|
||||
std::string value;
|
||||
int32_t intvalue;
|
||||
file.open("/sys/class/camera/flash/torch_brightness_lvl");
|
||||
if (file.is_open()) {
|
||||
getline(file, value);
|
||||
file.close();
|
||||
std::stringstream val(value);
|
||||
val >> intvalue;
|
||||
if (device == Device::A10) {
|
||||
return intvalue;
|
||||
} else if (device == Device::NOTA10) {
|
||||
return intvalue / 21;
|
||||
}
|
||||
// Never Here
|
||||
return -1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
IFlashBrightness *FlashBrightness::getInstance(void) {
|
||||
return new FlashBrightness();
|
||||
}
|
||||
} // namespace vendor::eureka::hardware::parts::V1_0
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
// Copyright (C) 2021 Eureka Team
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <hidl/MQDescriptor.h>
|
||||
#include <hidl/Status.h>
|
||||
#include <vendor/eureka/hardware/parts/1.0/IFlashBrightness.h>
|
||||
|
||||
namespace vendor::eureka::hardware::parts::V1_0 {
|
||||
|
||||
using ::android::sp;
|
||||
using ::android::hardware::hidl_array;
|
||||
using ::android::hardware::hidl_memory;
|
||||
using ::android::hardware::hidl_string;
|
||||
using ::android::hardware::hidl_vec;
|
||||
using ::android::hardware::Return;
|
||||
using ::android::hardware::Void;
|
||||
|
||||
struct FlashBrightness : public IFlashBrightness {
|
||||
// Methods from ::vendor::eureka::hardware::parts::V1_0::IFlashBrightness
|
||||
// follow.
|
||||
Return<void> setFlashlightEnable(Number enable);
|
||||
Return<void> setFlashlightWritable(Value value);
|
||||
Return<int32_t> readFlashlightstats(Device device);
|
||||
// Methods from ::android::hidl::base::V1_0::IBase follow.
|
||||
static IFlashBrightness *getInstance(void);
|
||||
};
|
||||
} // namespace vendor::eureka::hardware::parts::V1_0
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
// Copyright (C) 2021 Eureka Team
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "Swap.h"
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
static int mSwapSize = 100;
|
||||
|
||||
#define SWAP_PATH "/data/swap/swapfile"
|
||||
using namespace std;
|
||||
namespace vendor::eureka::hardware::parts::V1_0 {
|
||||
|
||||
Return<void> SwapOnData::setSwapSize(int32_t size) {
|
||||
mSwapSize = size;
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<void> SwapOnData::setSwapOn(){
|
||||
string cmd = string("dd if=/dev/zero of=") + string(SWAP_PATH) + string(" bs=") + std::to_string(mSwapSize)
|
||||
+ "M count=10";
|
||||
system(cmd.c_str());
|
||||
cmd = string("mkswap ") + string(SWAP_PATH);
|
||||
system(cmd.c_str());
|
||||
cmd = string("swapon -p 99 ") + string(SWAP_PATH);
|
||||
system(cmd.c_str());
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<void> SwapOnData::setSwapOff(){
|
||||
std::string cmd = string("swapoff ") + string(SWAP_PATH);
|
||||
system(cmd.c_str());
|
||||
cmd = string("rm ") + string(SWAP_PATH);
|
||||
system(cmd.c_str());
|
||||
return Void();
|
||||
}
|
||||
|
||||
ISwapOnData *SwapOnData::getInstance(void) {
|
||||
return new SwapOnData();
|
||||
}
|
||||
} // namespace vendor::eureka::hardware::parts::V1_0
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
// Copyright (C) 2021 Eureka Team
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <hidl/MQDescriptor.h>
|
||||
#include <hidl/Status.h>
|
||||
#include <vendor/eureka/hardware/parts/1.0/ISwapOnData.h>
|
||||
|
||||
namespace vendor::eureka::hardware::parts::V1_0 {
|
||||
|
||||
using ::android::sp;
|
||||
using ::android::hardware::hidl_array;
|
||||
using ::android::hardware::hidl_memory;
|
||||
using ::android::hardware::hidl_string;
|
||||
using ::android::hardware::hidl_vec;
|
||||
using ::android::hardware::Return;
|
||||
using ::android::hardware::Void;
|
||||
|
||||
struct SwapOnData : public ISwapOnData {
|
||||
// Methods from ::vendor::eureka::hardware::parts::V1_0::ISwapOnData
|
||||
// follow.
|
||||
Return<void> setSwapSize(int32_t size);
|
||||
Return<void> setSwapOn();
|
||||
Return<void> setSwapOff();
|
||||
// Methods from ::android::hidl::base::V2_0::IBase follow.
|
||||
static ISwapOnData *getInstance(void);
|
||||
};
|
||||
} // namespace vendor::eureka::hardware::parts::V1_0
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
// Copyright (C) 2021 Eureka Team
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#define LOG_TAG "vendor.eureka.hardware.parts@1.0-service"
|
||||
|
||||
#include <hidl/LegacySupport.h>
|
||||
#include <vendor/eureka/hardware/parts/1.0/IBatteryStats.h>
|
||||
#include <vendor/eureka/hardware/parts/1.0/IDisplayConfigs.h>
|
||||
#include <vendor/eureka/hardware/parts/1.0/IFlashBrightness.h>
|
||||
#include <vendor/eureka/hardware/parts/1.0/ISwapOnData.h>
|
||||
|
||||
#include "Battery.h"
|
||||
#include "Display.h"
|
||||
#include "FlashLight.h"
|
||||
#include "Swap.h"
|
||||
|
||||
using android::sp;
|
||||
using android::hardware::configureRpcThreadpool;
|
||||
using android::hardware::joinRpcThreadpool;
|
||||
using vendor::eureka::hardware::parts::V1_0::BatteryStats;
|
||||
using vendor::eureka::hardware::parts::V1_0::DisplayConfigs;
|
||||
using vendor::eureka::hardware::parts::V1_0::FlashBrightness;
|
||||
using vendor::eureka::hardware::parts::V1_0::SwapOnData;
|
||||
using vendor::eureka::hardware::parts::V1_0::IBatteryStats;
|
||||
using vendor::eureka::hardware::parts::V1_0::IDisplayConfigs;
|
||||
using vendor::eureka::hardware::parts::V1_0::IFlashBrightness;
|
||||
using vendor::eureka::hardware::parts::V1_0::ISwapOnData;
|
||||
|
||||
int main() {
|
||||
int ret;
|
||||
android::sp<IBatteryStats> mBatteryService = BatteryStats::getInstance();
|
||||
android::sp<IFlashBrightness> mFlashLightService =
|
||||
FlashBrightness::getInstance();
|
||||
android::sp<IDisplayConfigs> mDisplayService = DisplayConfigs::getInstance();
|
||||
android::sp<ISwapOnData> mSwapService = SwapOnData::getInstance();
|
||||
configureRpcThreadpool(4, true /*callerWillJoin*/);
|
||||
|
||||
if (mBatteryService != nullptr) {
|
||||
ret = mBatteryService->registerAsService();
|
||||
if (ret != 0) {
|
||||
ALOGE("Can't register instance of Battery HAL, nullptr");
|
||||
} else {
|
||||
ALOGI("registered Battery HAL");
|
||||
}
|
||||
} else {
|
||||
ALOGE("Can't create instance of Battery HAL, nullptr");
|
||||
}
|
||||
if (mFlashLightService != nullptr) {
|
||||
ret = mFlashLightService->registerAsService();
|
||||
if (ret != 0) {
|
||||
ALOGE("Can't register instance of FlashLight HAL, nullptr");
|
||||
} else {
|
||||
ALOGI("registered FlashLight HAL");
|
||||
}
|
||||
} else {
|
||||
ALOGE("Can't create instance of FlashLight HAL, nullptr");
|
||||
}
|
||||
if (mDisplayService != nullptr) {
|
||||
ret = mDisplayService->registerAsService();
|
||||
if (ret != 0) {
|
||||
ALOGE("Can't register instance of Display HAL, nullptr");
|
||||
} else {
|
||||
ALOGI("registered Display HAL");
|
||||
}
|
||||
} else {
|
||||
ALOGE("Can't create instance of Display HAL, nullptr");
|
||||
}
|
||||
if (mSwapService != nullptr) {
|
||||
ret = mSwapService->registerAsService();
|
||||
if (ret != 0) {
|
||||
ALOGE("Can't register instance of Swap HAL, nullptr");
|
||||
} else {
|
||||
ALOGI("registered Swap HAL");
|
||||
}
|
||||
} else {
|
||||
ALOGE("Can't create instance of Swap HAL, nullptr");
|
||||
}
|
||||
joinRpcThreadpool();
|
||||
|
||||
return -1; // should never get here
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
service vendor.parts-hal /vendor/bin/vendor.eureka.hardware.parts@1.0-service
|
||||
interface vendor.eureka.hardware.parts@1.0::IBatteryStats default
|
||||
interface vendor.eureka.hardware.parts@1.0::IDisplayConfigs default
|
||||
interface vendor.eureka.hardware.parts@1.0::IFlashBrightness default
|
||||
interface vendor.eureka.hardware.parts@1.0::ISwapOnData default
|
||||
class hal
|
||||
user root
|
||||
group root
|
||||
|
||||
on post-fs-data
|
||||
mkdir /data/swap 0755 root root encryption=None
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
<?xml version="1.0"?>
|
||||
<manifest version="1.0" type="device">
|
||||
<hal format="hidl">
|
||||
<name>vendor.eureka.hardware.parts</name>
|
||||
<transport>hwbinder</transport>
|
||||
<version>1.0</version>
|
||||
<interface>
|
||||
<name>IBatteryStats</name>
|
||||
<instance>default</instance>
|
||||
</interface>
|
||||
<interface>
|
||||
<name>IFlashBrightness</name>
|
||||
<instance>default</instance>
|
||||
</interface>
|
||||
<interface>
|
||||
<name>IDisplayConfigs</name>
|
||||
<instance>default</instance>
|
||||
</interface>
|
||||
<interface>
|
||||
<name>ISwapOnData</name>
|
||||
<instance>default</instance>
|
||||
</interface>
|
||||
</hal>
|
||||
</manifest>
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
// Copyright (C) 2021 Eureka Team
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package vendor.eureka.hardware.parts@1.0;
|
||||
|
||||
enum SysfsType : int32_t {
|
||||
CAPACITY_MAX,
|
||||
TEMP,
|
||||
CAPACITY_CURRENT,
|
||||
CURRENT,
|
||||
FASTCHARGE,
|
||||
CHARGE,
|
||||
};
|
||||
|
||||
enum Display : int32_t {
|
||||
DOUBLE_TAP,
|
||||
GLOVE_MODE,
|
||||
};
|
||||
|
||||
enum Number : int32_t {
|
||||
ENABLE = 1,
|
||||
DISABLE = 0,
|
||||
};
|
||||
|
||||
enum Device : int32_t {
|
||||
A10,
|
||||
NOTA10,
|
||||
};
|
||||
|
||||
enum Value : int32_t {
|
||||
ONEUI = 1,
|
||||
TWOUI,
|
||||
THREEUI,
|
||||
FOURUI,
|
||||
FIVEUI,
|
||||
SIXUI,
|
||||
SEVENUI,
|
||||
EIGHTUI,
|
||||
NINEUI,
|
||||
TENUI = 10,
|
||||
};
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
//
|
||||
// Copyright (C) 2021 The LineageOS Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
cc_binary {
|
||||
name: "android.hardware.camera.provider@2.5-service.exynos7885",
|
||||
defaults: [
|
||||
"hidl_defaults",
|
||||
],
|
||||
compile_multilib: "32",
|
||||
proprietary: true,
|
||||
relative_install_path: "hw",
|
||||
srcs: [
|
||||
"SamsungCameraProvider.cpp",
|
||||
"service.cpp"
|
||||
],
|
||||
init_rc: ["android.hardware.camera.provider@2.5-service.exynos7885.rc"],
|
||||
shared_libs: [
|
||||
"android.hardware.camera.provider@2.4",
|
||||
"android.hardware.camera.provider@2.4-legacy",
|
||||
"android.hardware.camera.provider@2.5",
|
||||
"android.hardware.camera.provider@2.5-legacy",
|
||||
"libbinder",
|
||||
"libcamera_metadata",
|
||||
"libcutils",
|
||||
"libhardware",
|
||||
"libhidlbase",
|
||||
"liblog",
|
||||
"libutils",
|
||||
],
|
||||
static_libs: [
|
||||
"android.hardware.camera.common@1.0-helper",
|
||||
],
|
||||
}
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Copyright (C) 2021 The LineageOS Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "SamsungCameraProvider@2.5"
|
||||
|
||||
#include "SamsungCameraProvider.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
using ::android::NO_ERROR;
|
||||
using ::android::OK;
|
||||
|
||||
using ::android::hardware::hidl_string;
|
||||
using ::android::hardware::hidl_vec;
|
||||
using ::android::hardware::Void;
|
||||
|
||||
const int kMaxCameraIdLen = 16;
|
||||
|
||||
SamsungCameraProvider::SamsungCameraProvider()
|
||||
: LegacyCameraProviderImpl_2_5() {
|
||||
mExtraIDs.push_back(50);
|
||||
mDisabledIDs.push_back(2);
|
||||
if (!mInitFailed) {
|
||||
for (int i : mExtraIDs) {
|
||||
struct camera_info info;
|
||||
auto rc = mModule->getCameraInfo(i, &info);
|
||||
|
||||
if (rc != NO_ERROR) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (checkCameraVersion(i, info) != OK) {
|
||||
ALOGE("Camera version check failed!");
|
||||
mModule.clear();
|
||||
mInitFailed = true;
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef SAMSUNG_CAMERA_DEBUG
|
||||
ALOGI("ID=%d is at index %d", i, mNumberOfLegacyCameras);
|
||||
#endif
|
||||
|
||||
char cameraId[kMaxCameraIdLen];
|
||||
snprintf(cameraId, sizeof(cameraId), "%d", i);
|
||||
std::string cameraIdStr(cameraId);
|
||||
mCameraStatusMap[cameraIdStr] = CAMERA_DEVICE_STATUS_PRESENT;
|
||||
|
||||
addDeviceNames(i);
|
||||
mNumberOfLegacyCameras++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Return<void> SamsungCameraProvider::getCameraIdList(
|
||||
ICameraProvider::getCameraIdList_cb _hidl_cb) {
|
||||
std::vector<hidl_string> deviceNameList;
|
||||
for (auto const &deviceNamePair : mCameraDeviceNames) {
|
||||
int id = std::stoi(deviceNamePair.first);
|
||||
if (id >= mNumberOfLegacyCameras ||
|
||||
std::find(mDisabledIDs.begin(), mDisabledIDs.end(), id) !=
|
||||
mDisabledIDs.end()) {
|
||||
// External camera devices must be reported through the device status
|
||||
// change callback, not in this list. Linux4: Also skip disabled camera
|
||||
// IDs.
|
||||
continue;
|
||||
}
|
||||
if (mCameraStatusMap[deviceNamePair.first] ==
|
||||
CAMERA_DEVICE_STATUS_PRESENT) {
|
||||
deviceNameList.push_back(deviceNamePair.second);
|
||||
}
|
||||
}
|
||||
hidl_vec<hidl_string> hidlDeviceNameList(deviceNameList);
|
||||
_hidl_cb(::android::hardware::camera::common::V1_0::Status::OK,
|
||||
hidlDeviceNameList);
|
||||
return Void();
|
||||
}
|
||||
|
||||
SamsungCameraProvider::~SamsungCameraProvider() {}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (C) 2021 The LineageOS Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SAMSUNG_CAMERA_PROVIDER_H
|
||||
|
||||
#include "LegacyCameraProviderImpl_2_5.h"
|
||||
|
||||
#define SAMSUNG_CAMERA_DEBUG
|
||||
|
||||
using ::android::hardware::Return;
|
||||
using ::android::hardware::camera::provider::V2_5::ICameraProvider;
|
||||
using ::android::hardware::camera::provider::V2_5::implementation::
|
||||
LegacyCameraProviderImpl_2_5;
|
||||
|
||||
class SamsungCameraProvider : public LegacyCameraProviderImpl_2_5 {
|
||||
public:
|
||||
SamsungCameraProvider();
|
||||
~SamsungCameraProvider();
|
||||
|
||||
Return<void> getCameraIdList(ICameraProvider::getCameraIdList_cb _hidl_cb);
|
||||
|
||||
private:
|
||||
std::vector<int> mExtraIDs;
|
||||
std::vector<int> mDisabledIDs;
|
||||
};
|
||||
|
||||
#endif // SAMSUNG_CAMERA_PROVIDER_H
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
service vendor.camera-provider-2-5 /vendor/bin/hw/android.hardware.camera.provider@2.5-service.exynos7885
|
||||
interface android.hardware.camera.provider@2.5::ICameraProvider legacy/0
|
||||
interface android.hardware.camera.provider@2.4::ICameraProvider legacy/0
|
||||
class hal
|
||||
user cameraserver
|
||||
group audio camera input drmrpc
|
||||
ioprio rt 4
|
||||
capabilities SYS_NICE
|
||||
task_profiles CameraServiceCapacity MaxPerformance
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright 2019 The Android Open Source Project
|
||||
* Copyright 2021 The LineageOS Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "android.hardware.camera.provider@2.5-service.samsung"
|
||||
|
||||
#include <android/hardware/camera/provider/2.5/ICameraProvider.h>
|
||||
#include <binder/ProcessState.h>
|
||||
#include <hidl/HidlLazyUtils.h>
|
||||
#include <hidl/HidlTransportSupport.h>
|
||||
|
||||
#include "CameraProvider_2_5.h"
|
||||
#include "SamsungCameraProvider.h"
|
||||
|
||||
using android::status_t;
|
||||
using android::hardware::camera::provider::V2_5::ICameraProvider;
|
||||
|
||||
int main() {
|
||||
using namespace android::hardware::camera::provider::V2_5::implementation;
|
||||
|
||||
ALOGI("CameraProvider@2.5 legacy service is starting.");
|
||||
|
||||
::android::hardware::configureRpcThreadpool(/*threads*/ HWBINDER_THREAD_COUNT,
|
||||
/*willJoin*/ true);
|
||||
|
||||
::android::sp<ICameraProvider> provider =
|
||||
new CameraProvider<SamsungCameraProvider>();
|
||||
|
||||
status_t status = provider->registerAsService("legacy/0");
|
||||
LOG_ALWAYS_FATAL_IF(status != android::OK,
|
||||
"Error while registering provider service: %d", status);
|
||||
|
||||
::android::hardware::joinRpcThreadpool();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
cc_binary {
|
||||
name: "android.hardware.biometrics.fingerprint@2.3-service.samsung",
|
||||
defaults: ["hidl_defaults"],
|
||||
proprietary: true,
|
||||
init_rc: ["android.hardware.biometrics.fingerprint@2.3-service.samsung.rc"],
|
||||
vintf_fragments: ["android.hardware.biometrics.fingerprint@2.3-service.samsung.xml"],
|
||||
relative_install_path: "hw",
|
||||
cflags: ["-DHAS_FINGERPRINT_GESTURES"],
|
||||
srcs: [
|
||||
"BiometricsFingerprint.cpp",
|
||||
"service.cpp",
|
||||
],
|
||||
shared_libs: [
|
||||
"liblog",
|
||||
"libcutils",
|
||||
"libhardware",
|
||||
"libbase",
|
||||
"libutils",
|
||||
"libhidlbase",
|
||||
"android.hardware.biometrics.fingerprint@2.1",
|
||||
"android.hardware.biometrics.fingerprint@2.2",
|
||||
"android.hardware.biometrics.fingerprint@2.3",
|
||||
],
|
||||
}
|
||||
|
|
@ -0,0 +1,539 @@
|
|||
/*
|
||||
* Copyright (C) 2019 The LineageOS Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#define LOG_TAG "android.hardware.biometrics.fingerprint@2.3-service.samsung"
|
||||
|
||||
#include <android-base/logging.h>
|
||||
|
||||
#include <hardware/hw_auth_token.h>
|
||||
|
||||
#include "BiometricsFingerprint.h"
|
||||
#include <hardware/fingerprint.h>
|
||||
#include <hardware/hardware.h>
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <fstream>
|
||||
#include <inttypes.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef HAS_FINGERPRINT_GESTURES
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace biometrics {
|
||||
namespace fingerprint {
|
||||
namespace V2_3 {
|
||||
namespace implementation {
|
||||
|
||||
using RequestStatus =
|
||||
android::hardware::biometrics::fingerprint::V2_1::RequestStatus;
|
||||
|
||||
BiometricsFingerprint *BiometricsFingerprint::sInstance = nullptr;
|
||||
|
||||
BiometricsFingerprint::BiometricsFingerprint() : mClientCallback(nullptr) {
|
||||
sInstance = this; // keep track of the most recent instance
|
||||
if (!openHal()) {
|
||||
LOG(ERROR) << "Can't open HAL module";
|
||||
}
|
||||
|
||||
#ifdef HAS_FINGERPRINT_GESTURES
|
||||
request(FINGERPRINT_REQUEST_NAVIGATION_MODE_START, 1);
|
||||
|
||||
uinputFd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
|
||||
if (uinputFd < 0) {
|
||||
LOG(ERROR) << "Unable to open uinput node";
|
||||
return;
|
||||
}
|
||||
|
||||
int err = ioctl(uinputFd, UI_SET_EVBIT, EV_KEY) |
|
||||
ioctl(uinputFd, UI_SET_KEYBIT, KEY_UP) |
|
||||
ioctl(uinputFd, UI_SET_KEYBIT, KEY_DOWN);
|
||||
if (err != 0) {
|
||||
LOG(ERROR) << "Unable to enable key events";
|
||||
return;
|
||||
}
|
||||
|
||||
sprintf(uidev.name, "uinput-sec-fp");
|
||||
uidev.id.bustype = BUS_VIRTUAL;
|
||||
|
||||
err = write(uinputFd, &uidev, sizeof(uidev));
|
||||
if (err < 0) {
|
||||
LOG(ERROR) << "Write user device to uinput node failed";
|
||||
return;
|
||||
}
|
||||
|
||||
err = ioctl(uinputFd, UI_DEV_CREATE);
|
||||
if (err < 0) {
|
||||
LOG(ERROR) << "Unable to create uinput device";
|
||||
return;
|
||||
}
|
||||
|
||||
LOG(INFO) << "Successfully registered uinput-sec-fp for fingerprint gestures";
|
||||
#endif
|
||||
}
|
||||
|
||||
BiometricsFingerprint::~BiometricsFingerprint() {
|
||||
if (ss_fingerprint_close() != 0) {
|
||||
LOG(ERROR) << "Can't close HAL module";
|
||||
}
|
||||
}
|
||||
|
||||
Return<bool> BiometricsFingerprint::isUdfps(uint32_t) {
|
||||
std::ifstream in("/sys/devices/virtual/fingerprint/fingerprint/position");
|
||||
if (in) {
|
||||
in.close();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Return<void> BiometricsFingerprint::onFingerDown(uint32_t, uint32_t, float,
|
||||
float) {
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<void> BiometricsFingerprint::onFingerUp() { return Void(); }
|
||||
|
||||
Return<RequestStatus> BiometricsFingerprint::ErrorFilter(int32_t error) {
|
||||
switch (error) {
|
||||
case 0:
|
||||
return RequestStatus::SYS_OK;
|
||||
case -2:
|
||||
return RequestStatus::SYS_ENOENT;
|
||||
case -4:
|
||||
return RequestStatus::SYS_EINTR;
|
||||
case -5:
|
||||
return RequestStatus::SYS_EIO;
|
||||
case -11:
|
||||
return RequestStatus::SYS_EAGAIN;
|
||||
case -12:
|
||||
return RequestStatus::SYS_ENOMEM;
|
||||
case -13:
|
||||
return RequestStatus::SYS_EACCES;
|
||||
case -14:
|
||||
return RequestStatus::SYS_EFAULT;
|
||||
case -16:
|
||||
return RequestStatus::SYS_EBUSY;
|
||||
case -22:
|
||||
return RequestStatus::SYS_EINVAL;
|
||||
case -28:
|
||||
return RequestStatus::SYS_ENOSPC;
|
||||
case -110:
|
||||
return RequestStatus::SYS_ETIMEDOUT;
|
||||
default:
|
||||
LOG(ERROR) << "An unknown error returned from fingerprint vendor library: "
|
||||
<< error;
|
||||
return RequestStatus::SYS_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
// Translate from errors returned by traditional HAL (see fingerprint.h) to
|
||||
// HIDL-compliant FingerprintError.
|
||||
FingerprintError BiometricsFingerprint::VendorErrorFilter(int32_t error,
|
||||
int32_t *vendorCode) {
|
||||
*vendorCode = 0;
|
||||
switch (error) {
|
||||
case FINGERPRINT_ERROR_HW_UNAVAILABLE:
|
||||
return FingerprintError::ERROR_HW_UNAVAILABLE;
|
||||
case FINGERPRINT_ERROR_UNABLE_TO_PROCESS:
|
||||
return FingerprintError::ERROR_UNABLE_TO_PROCESS;
|
||||
case FINGERPRINT_ERROR_TIMEOUT:
|
||||
return FingerprintError::ERROR_TIMEOUT;
|
||||
case FINGERPRINT_ERROR_NO_SPACE:
|
||||
return FingerprintError::ERROR_NO_SPACE;
|
||||
case FINGERPRINT_ERROR_CANCELED:
|
||||
return FingerprintError::ERROR_CANCELED;
|
||||
case FINGERPRINT_ERROR_UNABLE_TO_REMOVE:
|
||||
return FingerprintError::ERROR_UNABLE_TO_REMOVE;
|
||||
case FINGERPRINT_ERROR_LOCKOUT:
|
||||
return FingerprintError::ERROR_LOCKOUT;
|
||||
default:
|
||||
if (error >= FINGERPRINT_ERROR_VENDOR_BASE) {
|
||||
// vendor specific code.
|
||||
*vendorCode = error - FINGERPRINT_ERROR_VENDOR_BASE;
|
||||
return FingerprintError::ERROR_VENDOR;
|
||||
}
|
||||
}
|
||||
LOG(ERROR) << "Unknown error from fingerprint vendor library: " << error;
|
||||
return FingerprintError::ERROR_UNABLE_TO_PROCESS;
|
||||
}
|
||||
|
||||
// Translate acquired messages returned by traditional HAL (see fingerprint.h)
|
||||
// to HIDL-compliant FingerprintAcquiredInfo.
|
||||
FingerprintAcquiredInfo
|
||||
BiometricsFingerprint::VendorAcquiredFilter(int32_t info, int32_t *vendorCode) {
|
||||
*vendorCode = 0;
|
||||
switch (info) {
|
||||
case FINGERPRINT_ACQUIRED_GOOD:
|
||||
return FingerprintAcquiredInfo::ACQUIRED_GOOD;
|
||||
case FINGERPRINT_ACQUIRED_PARTIAL:
|
||||
return FingerprintAcquiredInfo::ACQUIRED_PARTIAL;
|
||||
case FINGERPRINT_ACQUIRED_INSUFFICIENT:
|
||||
return FingerprintAcquiredInfo::ACQUIRED_INSUFFICIENT;
|
||||
case FINGERPRINT_ACQUIRED_IMAGER_DIRTY:
|
||||
return FingerprintAcquiredInfo::ACQUIRED_IMAGER_DIRTY;
|
||||
case FINGERPRINT_ACQUIRED_TOO_SLOW:
|
||||
return FingerprintAcquiredInfo::ACQUIRED_TOO_SLOW;
|
||||
case FINGERPRINT_ACQUIRED_TOO_FAST:
|
||||
return FingerprintAcquiredInfo::ACQUIRED_TOO_FAST;
|
||||
default:
|
||||
if (info >= FINGERPRINT_ACQUIRED_VENDOR_BASE) {
|
||||
// vendor specific code.
|
||||
*vendorCode = info - FINGERPRINT_ACQUIRED_VENDOR_BASE;
|
||||
return FingerprintAcquiredInfo::ACQUIRED_VENDOR;
|
||||
}
|
||||
}
|
||||
LOG(ERROR) << "Unknown acquiredmsg from fingerprint vendor library: " << info;
|
||||
return FingerprintAcquiredInfo::ACQUIRED_INSUFFICIENT;
|
||||
}
|
||||
|
||||
Return<uint64_t> BiometricsFingerprint::setNotify(
|
||||
const sp<IBiometricsFingerprintClientCallback> &clientCallback) {
|
||||
std::lock_guard<std::mutex> lock(mClientCallbackMutex);
|
||||
mClientCallback = clientCallback;
|
||||
// This is here because HAL 2.3 doesn't have a way to propagate a
|
||||
// unique token for its driver. Subsequent versions should send a unique
|
||||
// token for each call to setNotify(). This is fine as long as there's only
|
||||
// one fingerprint device on the platform.
|
||||
return reinterpret_cast<uint64_t>(this);
|
||||
}
|
||||
|
||||
Return<uint64_t> BiometricsFingerprint::preEnroll() {
|
||||
return ss_fingerprint_pre_enroll();
|
||||
}
|
||||
|
||||
Return<RequestStatus>
|
||||
BiometricsFingerprint::enroll(const hidl_array<uint8_t, 69> &hat, uint32_t gid,
|
||||
uint32_t timeoutSec) {
|
||||
const hw_auth_token_t *authToken =
|
||||
reinterpret_cast<const hw_auth_token_t *>(hat.data());
|
||||
|
||||
return ErrorFilter(ss_fingerprint_enroll(authToken, gid, timeoutSec));
|
||||
}
|
||||
|
||||
Return<RequestStatus> BiometricsFingerprint::postEnroll() {
|
||||
return ErrorFilter(ss_fingerprint_post_enroll());
|
||||
}
|
||||
|
||||
Return<uint64_t> BiometricsFingerprint::getAuthenticatorId() {
|
||||
return ss_fingerprint_get_auth_id();
|
||||
}
|
||||
|
||||
Return<RequestStatus> BiometricsFingerprint::cancel() {
|
||||
int32_t ret = ss_fingerprint_cancel();
|
||||
|
||||
#ifdef CALL_NOTIFY_ON_CANCEL
|
||||
if (ret == 0) {
|
||||
fingerprint_msg_t msg{};
|
||||
msg.type = FINGERPRINT_ERROR;
|
||||
msg.data.error = FINGERPRINT_ERROR_CANCELED;
|
||||
notify(&msg);
|
||||
}
|
||||
#endif
|
||||
|
||||
return ErrorFilter(ret);
|
||||
}
|
||||
|
||||
Return<RequestStatus> BiometricsFingerprint::enumerate() {
|
||||
if (ss_fingerprint_enumerate != nullptr) {
|
||||
return ErrorFilter(ss_fingerprint_enumerate());
|
||||
}
|
||||
|
||||
return RequestStatus::SYS_UNKNOWN;
|
||||
}
|
||||
|
||||
Return<RequestStatus> BiometricsFingerprint::remove(uint32_t gid,
|
||||
uint32_t fid) {
|
||||
return ErrorFilter(ss_fingerprint_remove(gid, fid));
|
||||
}
|
||||
|
||||
Return<RequestStatus>
|
||||
BiometricsFingerprint::setActiveGroup(uint32_t gid,
|
||||
const hidl_string &storePath) {
|
||||
if (storePath.size() >= PATH_MAX || storePath.size() <= 0) {
|
||||
LOG(ERROR) << "Bad path length: " << storePath.size();
|
||||
return RequestStatus::SYS_EINVAL;
|
||||
}
|
||||
|
||||
if (access(storePath.c_str(), W_OK)) {
|
||||
return RequestStatus::SYS_EINVAL;
|
||||
}
|
||||
|
||||
return ErrorFilter(ss_fingerprint_set_active_group(gid, storePath.c_str()));
|
||||
}
|
||||
|
||||
Return<RequestStatus> BiometricsFingerprint::authenticate(uint64_t operationId,
|
||||
uint32_t gid) {
|
||||
return ErrorFilter(ss_fingerprint_authenticate(operationId, gid));
|
||||
}
|
||||
|
||||
IBiometricsFingerprint *BiometricsFingerprint::getInstance() {
|
||||
if (!sInstance) {
|
||||
sInstance = new BiometricsFingerprint();
|
||||
}
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
bool BiometricsFingerprint::openHal() {
|
||||
void *handle = dlopen("libbauthserver.so", RTLD_NOW);
|
||||
if (handle) {
|
||||
int err;
|
||||
|
||||
ss_fingerprint_close = reinterpret_cast<typeof(ss_fingerprint_close)>(
|
||||
dlsym(handle, "ss_fingerprint_close"));
|
||||
ss_fingerprint_open = reinterpret_cast<typeof(ss_fingerprint_open)>(
|
||||
dlsym(handle, "ss_fingerprint_open"));
|
||||
|
||||
ss_set_notify_callback = reinterpret_cast<typeof(ss_set_notify_callback)>(
|
||||
dlsym(handle, "ss_set_notify_callback"));
|
||||
ss_fingerprint_pre_enroll =
|
||||
reinterpret_cast<typeof(ss_fingerprint_pre_enroll)>(
|
||||
dlsym(handle, "ss_fingerprint_pre_enroll"));
|
||||
ss_fingerprint_enroll = reinterpret_cast<typeof(ss_fingerprint_enroll)>(
|
||||
dlsym(handle, "ss_fingerprint_enroll"));
|
||||
ss_fingerprint_post_enroll =
|
||||
reinterpret_cast<typeof(ss_fingerprint_post_enroll)>(
|
||||
dlsym(handle, "ss_fingerprint_post_enroll"));
|
||||
ss_fingerprint_get_auth_id =
|
||||
reinterpret_cast<typeof(ss_fingerprint_get_auth_id)>(
|
||||
dlsym(handle, "ss_fingerprint_get_auth_id"));
|
||||
ss_fingerprint_cancel = reinterpret_cast<typeof(ss_fingerprint_cancel)>(
|
||||
dlsym(handle, "ss_fingerprint_cancel"));
|
||||
ss_fingerprint_enumerate =
|
||||
reinterpret_cast<typeof(ss_fingerprint_enumerate)>(
|
||||
dlsym(handle, "ss_fingerprint_enumerate"));
|
||||
ss_fingerprint_remove = reinterpret_cast<typeof(ss_fingerprint_remove)>(
|
||||
dlsym(handle, "ss_fingerprint_remove"));
|
||||
ss_fingerprint_set_active_group =
|
||||
reinterpret_cast<typeof(ss_fingerprint_set_active_group)>(
|
||||
dlsym(handle, "ss_fingerprint_set_active_group"));
|
||||
ss_fingerprint_authenticate =
|
||||
reinterpret_cast<typeof(ss_fingerprint_authenticate)>(
|
||||
dlsym(handle, "ss_fingerprint_authenticate"));
|
||||
ss_fingerprint_request = reinterpret_cast<typeof(ss_fingerprint_request)>(
|
||||
dlsym(handle, "ss_fingerprint_request"));
|
||||
|
||||
if ((err = ss_fingerprint_open(nullptr)) != 0) {
|
||||
LOG(ERROR) << "Can't open fingerprint, error: " << err;
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((err = ss_set_notify_callback(BiometricsFingerprint::notify)) != 0) {
|
||||
LOG(ERROR) << "Can't register fingerprint module callback, error: "
|
||||
<< err;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void BiometricsFingerprint::notify(const fingerprint_msg_t *msg) {
|
||||
BiometricsFingerprint *thisPtr = static_cast<BiometricsFingerprint *>(
|
||||
BiometricsFingerprint::getInstance());
|
||||
std::lock_guard<std::mutex> lock(thisPtr->mClientCallbackMutex);
|
||||
if (thisPtr == nullptr || thisPtr->mClientCallback == nullptr) {
|
||||
LOG(ERROR)
|
||||
<< "Receiving callbacks before the client callback is registered.";
|
||||
return;
|
||||
}
|
||||
const uint64_t devId = 1;
|
||||
switch (msg->type) {
|
||||
case FINGERPRINT_ERROR: {
|
||||
int32_t vendorCode = 0;
|
||||
FingerprintError result = VendorErrorFilter(msg->data.error, &vendorCode);
|
||||
LOG(DEBUG) << "onError(" << static_cast<int>(result) << ")";
|
||||
if (!thisPtr->mClientCallback->onError(devId, result, vendorCode).isOk()) {
|
||||
LOG(ERROR) << "failed to invoke fingerprint onError callback";
|
||||
}
|
||||
} break;
|
||||
case FINGERPRINT_ACQUIRED: {
|
||||
if (msg->data.acquired.acquired_info > SEM_FINGERPRINT_EVENT_BASE) {
|
||||
thisPtr->handleEvent(msg->data.acquired.acquired_info);
|
||||
return;
|
||||
}
|
||||
int32_t vendorCode = 0;
|
||||
FingerprintAcquiredInfo result =
|
||||
VendorAcquiredFilter(msg->data.acquired.acquired_info, &vendorCode);
|
||||
LOG(DEBUG) << "onAcquired(" << static_cast<int>(result) << ")";
|
||||
if (!thisPtr->mClientCallback->onAcquired(devId, result, vendorCode)
|
||||
.isOk()) {
|
||||
LOG(ERROR) << "failed to invoke fingerprint onAcquired callback";
|
||||
}
|
||||
} break;
|
||||
case FINGERPRINT_TEMPLATE_ENROLLING:
|
||||
#ifdef USES_PERCENTAGE_SAMPLES
|
||||
const_cast<fingerprint_msg_t *>(msg)->data.enroll.samples_remaining =
|
||||
100 - msg->data.enroll.samples_remaining;
|
||||
#endif
|
||||
#ifdef CALL_CANCEL_ON_ENROLL_COMPLETION
|
||||
if (msg->data.enroll.samples_remaining == 0) {
|
||||
thisPtr->ss_fingerprint_cancel();
|
||||
}
|
||||
#endif
|
||||
LOG(DEBUG) << "onEnrollResult(fid=" << msg->data.enroll.finger.fid
|
||||
<< ", gid=" << msg->data.enroll.finger.gid
|
||||
<< ", rem=" << msg->data.enroll.samples_remaining << ")";
|
||||
if (!thisPtr->mClientCallback
|
||||
->onEnrollResult(devId, msg->data.enroll.finger.fid,
|
||||
msg->data.enroll.finger.gid,
|
||||
msg->data.enroll.samples_remaining)
|
||||
.isOk()) {
|
||||
LOG(ERROR) << "failed to invoke fingerprint onEnrollResult callback";
|
||||
}
|
||||
break;
|
||||
case FINGERPRINT_TEMPLATE_REMOVED:
|
||||
LOG(DEBUG) << "onRemove(fid=" << msg->data.removed.finger.fid
|
||||
<< ", gid=" << msg->data.removed.finger.gid
|
||||
<< ", rem=" << msg->data.removed.remaining_templates << ")";
|
||||
if (!thisPtr->mClientCallback
|
||||
->onRemoved(devId, msg->data.removed.finger.fid,
|
||||
msg->data.removed.finger.gid,
|
||||
msg->data.removed.remaining_templates)
|
||||
.isOk()) {
|
||||
LOG(ERROR) << "failed to invoke fingerprint onRemoved callback";
|
||||
}
|
||||
break;
|
||||
case FINGERPRINT_AUTHENTICATED:
|
||||
LOG(DEBUG) << "onAuthenticated(fid=" << msg->data.authenticated.finger.fid
|
||||
<< ", gid=" << msg->data.authenticated.finger.gid << ")";
|
||||
if (msg->data.authenticated.finger.fid != 0) {
|
||||
const uint8_t *hat =
|
||||
reinterpret_cast<const uint8_t *>(&msg->data.authenticated.hat);
|
||||
const hidl_vec<uint8_t> token(
|
||||
std::vector<uint8_t>(hat, hat + sizeof(msg->data.authenticated.hat)));
|
||||
if (!thisPtr->mClientCallback
|
||||
->onAuthenticated(devId, msg->data.authenticated.finger.fid,
|
||||
msg->data.authenticated.finger.gid, token)
|
||||
.isOk()) {
|
||||
LOG(ERROR) << "failed to invoke fingerprint onAuthenticated callback";
|
||||
}
|
||||
} else {
|
||||
// Not a recognized fingerprint
|
||||
if (!thisPtr->mClientCallback
|
||||
->onAuthenticated(devId, msg->data.authenticated.finger.fid,
|
||||
msg->data.authenticated.finger.gid,
|
||||
hidl_vec<uint8_t>())
|
||||
.isOk()) {
|
||||
LOG(ERROR) << "failed to invoke fingerprint onAuthenticated callback";
|
||||
}
|
||||
}
|
||||
break;
|
||||
case FINGERPRINT_TEMPLATE_ENUMERATING:
|
||||
LOG(DEBUG) << "onEnumerate(fid=" << msg->data.enumerated.finger.fid
|
||||
<< ", gid=" << msg->data.enumerated.finger.gid
|
||||
<< ", rem=" << msg->data.enumerated.remaining_templates << ")";
|
||||
if (!thisPtr->mClientCallback
|
||||
->onEnumerate(devId, msg->data.enumerated.finger.fid,
|
||||
msg->data.enumerated.finger.gid,
|
||||
msg->data.enumerated.remaining_templates)
|
||||
.isOk()) {
|
||||
LOG(ERROR) << "failed to invoke fingerprint onEnumerate callback";
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void BiometricsFingerprint::handleEvent(int eventCode) {
|
||||
switch (eventCode) {
|
||||
#ifdef HAS_FINGERPRINT_GESTURES
|
||||
case SEM_FINGERPRINT_EVENT_GESTURE_SWIPE_DOWN:
|
||||
case SEM_FINGERPRINT_EVENT_GESTURE_SWIPE_UP:
|
||||
struct input_event event {};
|
||||
int keycode =
|
||||
eventCode == SEM_FINGERPRINT_EVENT_GESTURE_SWIPE_UP ? KEY_UP : KEY_DOWN;
|
||||
int err;
|
||||
|
||||
// Report the key
|
||||
event.type = EV_KEY;
|
||||
event.code = keycode;
|
||||
event.value = 1;
|
||||
err = write(uinputFd, &event, sizeof(event));
|
||||
if (err < 0) {
|
||||
LOG(ERROR) << "Write EV_KEY to uinput node failed";
|
||||
return;
|
||||
}
|
||||
|
||||
// Force a flush with an EV_SYN
|
||||
event.type = EV_SYN;
|
||||
event.code = SYN_REPORT;
|
||||
event.value = 0;
|
||||
err = write(uinputFd, &event, sizeof(event));
|
||||
if (err < 0) {
|
||||
LOG(ERROR) << "Write EV_SYN to uinput node failed";
|
||||
return;
|
||||
}
|
||||
|
||||
// Report the key
|
||||
event.type = EV_KEY;
|
||||
event.code = keycode;
|
||||
event.value = 0;
|
||||
err = write(uinputFd, &event, sizeof(event));
|
||||
if (err < 0) {
|
||||
LOG(ERROR) << "Write EV_KEY to uinput node failed";
|
||||
return;
|
||||
}
|
||||
|
||||
// Force a flush with an EV_SYN
|
||||
event.type = EV_SYN;
|
||||
event.code = SYN_REPORT;
|
||||
event.value = 0;
|
||||
err = write(uinputFd, &event, sizeof(event));
|
||||
if (err < 0) {
|
||||
LOG(ERROR) << "Write EV_SYN to uinput node failed";
|
||||
return;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
int BiometricsFingerprint::request(int cmd, int param) {
|
||||
// TO-DO: input, output handling not implemented
|
||||
int result = ss_fingerprint_request(cmd, nullptr, 0, nullptr, 0, param);
|
||||
LOG(INFO) << "request(cmd=" << cmd << ", param=" << param
|
||||
<< ", result=" << result << ")";
|
||||
return result;
|
||||
}
|
||||
|
||||
int BiometricsFingerprint::waitForSensor(std::chrono::milliseconds pollWait,
|
||||
std::chrono::milliseconds timeOut) {
|
||||
int sensorStatus = SEM_SENSOR_STATUS_WORKING;
|
||||
std::chrono::milliseconds timeWaited = 0ms;
|
||||
while (sensorStatus != SEM_SENSOR_STATUS_OK) {
|
||||
if (sensorStatus == SEM_SENSOR_STATUS_CALIBRATION_ERROR ||
|
||||
sensorStatus == SEM_SENSOR_STATUS_ERROR) {
|
||||
return -1;
|
||||
}
|
||||
if (timeWaited >= timeOut) {
|
||||
return -2;
|
||||
}
|
||||
sensorStatus = request(FINGERPRINT_REQUEST_GET_SENSOR_STATUS, 0);
|
||||
std::this_thread::sleep_for(pollWait);
|
||||
timeWaited += pollWait;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V2_3
|
||||
} // namespace fingerprint
|
||||
} // namespace biometrics
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
|
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
* Copyright (C) 2019 The LineageOS Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_HARDWARE_BIOMETRICS_FINGERPRINT_V2_3_BIOMETRICSFINGERPRINT_H
|
||||
#define ANDROID_HARDWARE_BIOMETRICS_FINGERPRINT_V2_3_BIOMETRICSFINGERPRINT_H
|
||||
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
|
||||
#ifdef HAS_FINGERPRINT_GESTURES
|
||||
#include <linux/uinput.h>
|
||||
#endif
|
||||
|
||||
#include <android/hardware/biometrics/fingerprint/2.1/types.h>
|
||||
#include <android/hardware/biometrics/fingerprint/2.3/IBiometricsFingerprint.h>
|
||||
#include <hardware/fingerprint.h>
|
||||
#include <hardware/hardware.h>
|
||||
#include <hidl/MQDescriptor.h>
|
||||
#include <hidl/Status.h>
|
||||
|
||||
#include "VendorConstants.h"
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace biometrics {
|
||||
namespace fingerprint {
|
||||
namespace V2_3 {
|
||||
namespace implementation {
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
using ::android::sp;
|
||||
using ::android::hardware::hidl_string;
|
||||
using ::android::hardware::hidl_vec;
|
||||
using ::android::hardware::Return;
|
||||
using ::android::hardware::Void;
|
||||
using ::android::hardware::biometrics::fingerprint::V2_1::
|
||||
FingerprintAcquiredInfo;
|
||||
using ::android::hardware::biometrics::fingerprint::V2_1::FingerprintError;
|
||||
using ::android::hardware::biometrics::fingerprint::V2_1::
|
||||
IBiometricsFingerprintClientCallback;
|
||||
using ::android::hardware::biometrics::fingerprint::V2_1::RequestStatus;
|
||||
using ::android::hardware::biometrics::fingerprint::V2_3::
|
||||
IBiometricsFingerprint;
|
||||
|
||||
struct BiometricsFingerprint : public IBiometricsFingerprint {
|
||||
BiometricsFingerprint();
|
||||
~BiometricsFingerprint();
|
||||
|
||||
// Method to wrap legacy HAL with BiometricsFingerprint class
|
||||
static IBiometricsFingerprint *getInstance();
|
||||
|
||||
// Methods from
|
||||
// ::android::hardware::biometrics::fingerprint::V2_3::IBiometricsFingerprint
|
||||
// follow.
|
||||
Return<uint64_t> setNotify(
|
||||
const sp<IBiometricsFingerprintClientCallback> &clientCallback) override;
|
||||
Return<uint64_t> preEnroll() override;
|
||||
Return<RequestStatus> enroll(const hidl_array<uint8_t, 69> &hat, uint32_t gid,
|
||||
uint32_t timeoutSec) override;
|
||||
Return<RequestStatus> postEnroll() override;
|
||||
Return<uint64_t> getAuthenticatorId() override;
|
||||
Return<RequestStatus> cancel() override;
|
||||
Return<RequestStatus> enumerate() override;
|
||||
Return<RequestStatus> remove(uint32_t gid, uint32_t fid) override;
|
||||
Return<RequestStatus> setActiveGroup(uint32_t gid,
|
||||
const hidl_string &storePath) override;
|
||||
Return<RequestStatus> authenticate(uint64_t operationId,
|
||||
uint32_t gid) override;
|
||||
Return<bool> isUdfps(uint32_t sensorID) override;
|
||||
Return<void> onFingerDown(uint32_t x, uint32_t y, float minor,
|
||||
float major) override;
|
||||
Return<void> onFingerUp() override;
|
||||
Return<void> onShowUdfpsOverlay() { return Void(); }
|
||||
Return<void> onHideUdfpsOverlay() { return Void(); }
|
||||
|
||||
private:
|
||||
bool openHal();
|
||||
int request(int cmd, int param);
|
||||
int waitForSensor(std::chrono::milliseconds pollWait,
|
||||
std::chrono::milliseconds timeOut);
|
||||
static void
|
||||
notify(const fingerprint_msg_t
|
||||
*msg); /* Static callback for legacy HAL implementation */
|
||||
void handleEvent(int eventCode);
|
||||
static Return<RequestStatus> ErrorFilter(int32_t error);
|
||||
static FingerprintError VendorErrorFilter(int32_t error, int32_t *vendorCode);
|
||||
static FingerprintAcquiredInfo VendorAcquiredFilter(int32_t error,
|
||||
int32_t *vendorCode);
|
||||
static BiometricsFingerprint *sInstance;
|
||||
|
||||
std::mutex mClientCallbackMutex;
|
||||
sp<IBiometricsFingerprintClientCallback> mClientCallback;
|
||||
#ifdef HAS_FINGERPRINT_GESTURES
|
||||
int uinputFd;
|
||||
struct uinput_user_dev uidev {};
|
||||
#endif
|
||||
|
||||
int (*ss_fingerprint_close)();
|
||||
int (*ss_fingerprint_open)(const char *id);
|
||||
|
||||
int (*ss_set_notify_callback)(fingerprint_notify_t notify);
|
||||
uint64_t (*ss_fingerprint_pre_enroll)();
|
||||
int (*ss_fingerprint_enroll)(const hw_auth_token_t *hat, uint32_t gid,
|
||||
uint32_t timeout_sec);
|
||||
int (*ss_fingerprint_post_enroll)();
|
||||
uint64_t (*ss_fingerprint_get_auth_id)();
|
||||
int (*ss_fingerprint_cancel)();
|
||||
int (*ss_fingerprint_enumerate)();
|
||||
int (*ss_fingerprint_remove)(uint32_t gid, uint32_t fid);
|
||||
int (*ss_fingerprint_set_active_group)(uint32_t gid, const char *store_path);
|
||||
int (*ss_fingerprint_authenticate)(uint64_t operation_id, uint32_t gid);
|
||||
int (*ss_fingerprint_request)(uint32_t cmd, char *inBuf,
|
||||
uint32_t inBuf_length, char *outBuf,
|
||||
uint32_t outBuf_length, uint32_t param);
|
||||
};
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V2_3
|
||||
} // namespace fingerprint
|
||||
} // namespace biometrics
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
|
||||
#endif // ANDROID_HARDWARE_BIOMETRICS_FINGERPRINT_V2_3_BIOMETRICSFINGERPRINT_H
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright (C) 2020 The LineageOS Project
|
||||
|
||||
#ifndef SAMSUNG_FINGERPRINT_CONSTANTS_H
|
||||
#define SAMSUNG_FINGERPRINT_CONSTANTS_H
|
||||
|
||||
// Fingerprint requests
|
||||
#define FINGERPRINT_REQUEST_ENROLL_SESSION 1002
|
||||
#define FINGERPRINT_REQUEST_ENROLL_TYPE 18
|
||||
#define FINGERPRINT_REQUEST_ENUMERATE 11
|
||||
#define FINGERPRINT_REQUEST_GET_FP_IDS 1003
|
||||
#define FINGERPRINT_REQUEST_GET_MAX_TEMPLATE_NUMBER 1004
|
||||
#define FINGERPRINT_REQUEST_GET_SENSOR_INFO 5
|
||||
#define FINGERPRINT_REQUEST_GET_SENSOR_STATUS 6
|
||||
#define FINGERPRINT_REQUEST_GET_TOUCH_CNT 1007
|
||||
#define FINGERPRINT_REQUEST_GET_UNIQUE_ID 7
|
||||
#define FINGERPRINT_REQUEST_GET_USERIDS 12
|
||||
#define FINGERPRINT_REQUEST_GET_VERSION 4
|
||||
#define FINGERPRINT_REQUEST_HAS_FEATURE 1006
|
||||
#define FINGERPRINT_REQUEST_LOCKOUT 1001
|
||||
#define FINGERPRINT_REQUEST_NAVIGATION_LCD_ONOFF 17
|
||||
#define FINGERPRINT_REQUEST_NAVIGATION_MODE_END 16
|
||||
#define FINGERPRINT_REQUEST_NAVIGATION_MODE_START 15
|
||||
#define FINGERPRINT_REQUEST_PAUSE 0
|
||||
#define FINGERPRINT_REQUEST_PROCESS_FIDO 9
|
||||
#define FINGERPRINT_REQUEST_REMOVE_FINGER 1000
|
||||
#define FINGERPRINT_REQUEST_RESUME 1
|
||||
#define FINGERPRINT_REQUEST_SENSOR_TEST_NORMALSCAN 3
|
||||
#define FINGERPRINT_REQUEST_SESSION_OPEN 2
|
||||
#define FINGERPRINT_REQUEST_SET_ACTIVE_GROUP 8
|
||||
#define FINGERPRINT_REQUEST_UPDATE_SID 10
|
||||
|
||||
#define SEM_REQUEST_FORCE_CBGE 21
|
||||
#define SEM_REQUEST_GET_FINGER_ICON_REMAIN_TIME 1010
|
||||
#define SEM_REQUEST_GET_SECURITY_LEVEL 30
|
||||
#define SEM_REQUEST_GET_SENSOR_TEST_RESULT 19
|
||||
#define SEM_REQUEST_GET_TA_VERSION 10000
|
||||
#define SEM_REQUEST_GET_TSP_BLOCK_STATUS 0x3F9
|
||||
#define SEM_REQUEST_HIDE_INDISPLAY_AUTH_ANIMATION 0x3F4
|
||||
#define SEM_REQUEST_INSTALL_TA 10001
|
||||
#define SEM_REQUEST_IS_NEW_MATCHER 27
|
||||
#define SEM_REQUEST_IS_TEMPLATE_CHANGED 25
|
||||
#define SEM_REQUEST_MASK_CTL 0x3F5
|
||||
#define SEM_REQUEST_MOVE_INDISPLAY_ICON 0x3F3
|
||||
#define SEM_REQUEST_OPTICAL_CALIBRATION 0x3F8
|
||||
#define SEM_REQUEST_REMOVE_ALL_USER 0x3F6
|
||||
#define SEM_REQUEST_SET_ASP_LEVEL 20
|
||||
#define SEM_REQUEST_SET_BOUNCER_SCREEN_STATUS 0x3FA
|
||||
#define SEM_REQUEST_SET_SCREEN_STATUS 0x3F0
|
||||
#define SEM_REQUEST_SHOW_INDISPLAY_AUTH_ANIMATION 1009
|
||||
#define SEM_REQUEST_TOUCH_EVENT 22
|
||||
#define SEM_REQUEST_TOUCH_SENSITIVE_CHANGE 0x3F7
|
||||
#define SEM_REQUEST_UPDATE_MATCHER 28
|
||||
#define SEM_REQUEST_VENDOR_EGIS_CALIBRATION 23
|
||||
#define SEM_REQUEST_VENDOR_QCOM_REMOVE_CBGE 24
|
||||
#define SEM_REQUEST_WIRELESS_CHARGER_STATUS 29
|
||||
|
||||
// Fingerprint aquired codes
|
||||
#define SEM_FINGERPRINT_ACQUIRED_DUPLICATED_IMAGE 1002
|
||||
#define SEM_FINGERPRINT_ACQUIRED_LIGHT_TOUCH 1003
|
||||
#define SEM_FINGERPRINT_ACQUIRED_TSP_BLOCK 1004
|
||||
#define SEM_FINGERPRINT_ACQUIRED_TSP_UNBLOCK 1005
|
||||
#define SEM_FINGERPRINT_ACQUIRED_WET_FINGER 1001
|
||||
|
||||
// Fingerprint errors
|
||||
#define SEM_FINGERPRINT_ERROR_CALIBRATION 1001
|
||||
#define SEM_FINGERPRINT_ERROR_DISABLED_BIOMETRICS 5002
|
||||
#define SEM_FINGERPRINT_ERROR_INVALID_HW 1005
|
||||
#define SEM_FINGERPRINT_ERROR_NEED_TO_RETRY 5000
|
||||
#define SEM_FINGERPRINT_ERROR_ONE_HAND_MODE 5001
|
||||
#define SEM_FINGERPRINT_ERROR_PATTERN_DETECTED 1007
|
||||
#define SEM_FINGERPRINT_ERROR_SERVICE_FAILURE 1003
|
||||
#define SEM_FINGERPRINT_ERROR_SMART_VIEW 5003
|
||||
#define SEM_FINGERPRINT_ERROR_SYSTEM_FAILURE 1002
|
||||
#define SEM_FINGERPRINT_ERROR_TA_UPDATE -100
|
||||
#define SEM_FINGERPRINT_ERROR_TEMPLATE_CORRUPTED 1004
|
||||
#define SEM_FINGERPRINT_ERROR_TEMPLATE_FORMAT_CHANGED 1006
|
||||
#define SEM_FINGERPRINT_ERROR_WIRELESS_CHARGING 5004
|
||||
|
||||
// Fingerprint events
|
||||
#define SEM_FINGERPRINT_EVENT_BASE 10000
|
||||
#define SEM_FINGERPRINT_EVENT_CAPTURE_COMPLETED 10003
|
||||
#define SEM_FINGERPRINT_EVENT_CAPTURE_FAILED 10006
|
||||
#define SEM_FINGERPRINT_EVENT_CAPTURE_READY 10001
|
||||
#define SEM_FINGERPRINT_EVENT_CAPTURE_STARTED 10002
|
||||
#define SEM_FINGERPRINT_EVENT_CAPTURE_SUCCESS 10005
|
||||
#define SEM_FINGERPRINT_EVENT_FACTORY_SNSR_SCRIPT_END 10009
|
||||
#define SEM_FINGERPRINT_EVENT_FACTORY_SNSR_SCRIPT_START 10008
|
||||
#define SEM_FINGERPRINT_EVENT_FINGER_LEAVE 10004
|
||||
#define SEM_FINGERPRINT_EVENT_FINGER_LEAVE_TIMEOUT 10007
|
||||
#define SEM_FINGERPRINT_EVENT_GESTURE_DTAP 20003
|
||||
#define SEM_FINGERPRINT_EVENT_GESTURE_LPRESS 20004
|
||||
#define SEM_FINGERPRINT_EVENT_GESTURE_SWIPE_DOWN 20002
|
||||
#define SEM_FINGERPRINT_EVENT_GESTURE_SWIPE_UP 20001
|
||||
#define SEM_FINGERPRINT_EVENT_SPEN_CONTROL_OFF 30002
|
||||
#define SEM_FINGERPRINT_EVENT_SPEN_CONTROL_ON 30001
|
||||
|
||||
// Fingerprint sensor status codes
|
||||
#define SEM_SENSOR_STATUS_CALIBRATION_ERROR 100045
|
||||
#define SEM_SENSOR_STATUS_ERROR 100042
|
||||
#define SEM_SENSOR_STATUS_OK 100040
|
||||
#define SEM_SENSOR_STATUS_WORKING 100041
|
||||
|
||||
#endif // SAMSUNG_FINGERPRINT_CONSTANTS_H
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
service vendor.fps_hal /vendor/bin/hw/android.hardware.biometrics.fingerprint@2.3-service.samsung
|
||||
# "class hal" causes a race condition on some devices due to files created
|
||||
# in /data. As a workaround, postpone startup until later in boot once
|
||||
# /data is mounted.
|
||||
class late_start
|
||||
user system
|
||||
group system input uhid
|
||||
writepid /dev/cpuset/system-background/tasks
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0"?>
|
||||
<manifest version="1.0" type="device">
|
||||
<hal format="hidl" override="true">
|
||||
<name>android.hardware.biometrics.fingerprint</name>
|
||||
<transport>hwbinder</transport>
|
||||
<version>2.3</version>
|
||||
<interface>
|
||||
<name>IBiometricsFingerprint</name>
|
||||
<instance>default</instance>
|
||||
</interface>
|
||||
</hal>
|
||||
</manifest>
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright (C) 2019 The LineageOS Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "android.hardware.biometrics.fingerprint@2.3-service.samsung"
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <hidl/HidlTransportSupport.h>
|
||||
#include <utils/Errors.h>
|
||||
|
||||
#include "BiometricsFingerprint.h"
|
||||
|
||||
using android::hardware::configureRpcThreadpool;
|
||||
using android::hardware::joinRpcThreadpool;
|
||||
|
||||
using android::hardware::biometrics::fingerprint::V2_3::IBiometricsFingerprint;
|
||||
using android::hardware::biometrics::fingerprint::V2_3::implementation::
|
||||
BiometricsFingerprint;
|
||||
|
||||
using android::OK;
|
||||
using android::sp;
|
||||
|
||||
int main() {
|
||||
android::sp<IBiometricsFingerprint> bio =
|
||||
BiometricsFingerprint::getInstance();
|
||||
|
||||
configureRpcThreadpool(1, true);
|
||||
|
||||
if (bio == nullptr || bio->registerAsService() != OK) {
|
||||
LOG(ERROR) << "Could not register service for Fingerprint HAL";
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
LOG(INFO) << "Fingerprint HAL service is Ready.";
|
||||
joinRpcThreadpool();
|
||||
|
||||
shutdown:
|
||||
// In normal operation, we don't expect the thread pool to shutdown
|
||||
LOG(ERROR) << "Fingerprint HAL failed to join thread pool.";
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
#
|
||||
# Copyright (C) 2019 The LineageOS Project
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
service.cpp
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := \
|
||||
android.hardware.keymaster@4.0 \
|
||||
libbase \
|
||||
libcutils \
|
||||
libhardware \
|
||||
libhidlbase \
|
||||
libkeymaster4 \
|
||||
liblog \
|
||||
libskeymaster4device \
|
||||
libutils
|
||||
|
||||
LOCAL_MODULE := android.hardware.keymaster@4.0-service.samsung
|
||||
LOCAL_INIT_RC := android.hardware.keymaster@4.0-service.samsung.rc
|
||||
LOCAL_MODULE_RELATIVE_PATH := hw
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
LOCAL_MODULE_OWNER := samsung
|
||||
LOCAL_VENDOR_MODULE := true
|
||||
|
||||
include $(BUILD_EXECUTABLE)
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
service vendor.keymaster-4-0 /vendor/bin/hw/android.hardware.keymaster@4.0-service.samsung
|
||||
class early_hal
|
||||
user system
|
||||
group system drmrpc
|
||||
|
||||
on post-fs-data
|
||||
mkdir /mnt/vendor/efs/DAK 0775 system system
|
||||
restorecon -R /mnt/vendor/efs/DAK
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright 2019 The LineageOS Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "android.hardware.keymaster@4.0-service.samsung"
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <android/hardware/keymaster/4.0/IKeymasterDevice.h>
|
||||
#include <hidl/HidlTransportSupport.h>
|
||||
|
||||
#include <AndroidKeymaster4Device.h>
|
||||
|
||||
using android::hardware::configureRpcThreadpool;
|
||||
using android::hardware::joinRpcThreadpool;
|
||||
|
||||
using android::hardware::keymaster::V4_0::IKeymasterDevice;
|
||||
using android::hardware::keymaster::V4_0::SecurityLevel;
|
||||
|
||||
using android::OK;
|
||||
using android::status_t;
|
||||
|
||||
namespace skeymaster {
|
||||
IKeymasterDevice *CreateSKeymasterDevice(SecurityLevel securityLevel);
|
||||
} // namespace skeymaster
|
||||
|
||||
int main() {
|
||||
IKeymasterDevice *keymaster =
|
||||
skeymaster::CreateSKeymasterDevice(SecurityLevel::TRUSTED_ENVIRONMENT);
|
||||
|
||||
configureRpcThreadpool(1, true);
|
||||
|
||||
status_t status = keymaster->registerAsService();
|
||||
|
||||
if (status != OK) {
|
||||
LOG(ERROR) << "Could not register service for Keymaster HAL";
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
LOG(INFO) << "Keymaster HAL service is Ready.";
|
||||
joinRpcThreadpool();
|
||||
|
||||
shutdown:
|
||||
// In normal operation, we don't expect the thread pool to shutdown
|
||||
LOG(ERROR) << "Keymaster HAL failed to join thread pool.";
|
||||
return -1;
|
||||
}
|
||||
23
universal7885-common/bin/hardware/samsung/light/Android.bp
Normal file
23
universal7885-common/bin/hardware/samsung/light/Android.bp
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
//
|
||||
// Copyright (C) 2021 The LineageOS Project
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
cc_binary {
|
||||
name: "android.hardware.light-service.samsung",
|
||||
relative_install_path: "hw",
|
||||
init_rc: ["android.hardware.light-service.samsung.rc"],
|
||||
vintf_fragments: ["android.hardware.light-service.samsung.xml"],
|
||||
local_include_dirs: ["include"],
|
||||
srcs: [
|
||||
"Lights.cpp",
|
||||
"service.cpp",
|
||||
],
|
||||
shared_libs: [
|
||||
"libbase",
|
||||
"libbinder_ndk",
|
||||
"android.hardware.light-V1-ndk_platform",
|
||||
],
|
||||
vendor: true,
|
||||
}
|
||||
196
universal7885-common/bin/hardware/samsung/light/Lights.cpp
Normal file
196
universal7885-common/bin/hardware/samsung/light/Lights.cpp
Normal file
|
|
@ -0,0 +1,196 @@
|
|||
/*
|
||||
* Copyright (C) 2021 The LineageOS Project
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#define LOG_TAG "android.hardware.lights-service.samsung"
|
||||
|
||||
#include <android-base/stringprintf.h>
|
||||
#include <fstream>
|
||||
|
||||
#include "Lights.h"
|
||||
|
||||
#define COLOR_MASK 0x00ffffff
|
||||
#define MAX_INPUT_BRIGHTNESS 255
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace light {
|
||||
|
||||
/*
|
||||
* Write value to path and close file.
|
||||
*/
|
||||
template <typename T> static void set(const std::string &path, const T &value) {
|
||||
std::ofstream file(path);
|
||||
file << value << std::endl;
|
||||
}
|
||||
|
||||
template <typename T> static T get(const std::string &path, const T &def) {
|
||||
std::ifstream file(path);
|
||||
T result;
|
||||
|
||||
file >> result;
|
||||
return file.fail() ? def : result;
|
||||
}
|
||||
|
||||
Lights::Lights() {
|
||||
mLights.emplace(LightType::BACKLIGHT, std::bind(&Lights::handleBacklight,
|
||||
this, std::placeholders::_1));
|
||||
#ifdef BUTTON_BRIGHTNESS_NODE
|
||||
mLights.emplace(LightType::BUTTONS, std::bind(&Lights::handleButtons, this,
|
||||
std::placeholders::_1));
|
||||
#endif /* BUTTON_BRIGHTNESS_NODE */
|
||||
#ifdef LED_BLINK_NODE
|
||||
mLights.emplace(LightType::BATTERY, std::bind(&Lights::handleBattery, this,
|
||||
std::placeholders::_1));
|
||||
mLights.emplace(
|
||||
LightType::NOTIFICATIONS,
|
||||
std::bind(&Lights::handleNotifications, this, std::placeholders::_1));
|
||||
mLights.emplace(LightType::ATTENTION, std::bind(&Lights::handleAttention,
|
||||
this, std::placeholders::_1));
|
||||
#endif /* LED_BLINK_NODE */
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Lights::setLightState(int32_t id,
|
||||
const HwLightState &state) {
|
||||
LightType type = static_cast<LightType>(id);
|
||||
auto it = mLights.find(type);
|
||||
|
||||
if (it == mLights.end()) {
|
||||
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
||||
}
|
||||
|
||||
/*
|
||||
* Lock global mutex until light state is updated.
|
||||
*/
|
||||
std::lock_guard<std::mutex> lock(mLock);
|
||||
|
||||
it->second(state);
|
||||
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
void Lights::handleBacklight(const HwLightState &state) {
|
||||
uint32_t max_brightness =
|
||||
get(PANEL_MAX_BRIGHTNESS_NODE, MAX_INPUT_BRIGHTNESS);
|
||||
uint32_t brightness = rgbToBrightness(state);
|
||||
|
||||
if (max_brightness != MAX_INPUT_BRIGHTNESS) {
|
||||
brightness = brightness * max_brightness / MAX_INPUT_BRIGHTNESS;
|
||||
}
|
||||
|
||||
set(PANEL_BRIGHTNESS_NODE, brightness);
|
||||
}
|
||||
|
||||
#ifdef BUTTON_BRIGHTNESS_NODE
|
||||
void Lights::handleButtons(const HwLightState &state) {
|
||||
#ifdef VAR_BUTTON_BRIGHTNESS
|
||||
uint32_t brightness = rgbToBrightness(state);
|
||||
#else
|
||||
uint32_t brightness = (state.color & COLOR_MASK) ? 1 : 0;
|
||||
#endif
|
||||
|
||||
set(BUTTON_BRIGHTNESS_NODE, brightness);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef LED_BLINK_NODE
|
||||
void Lights::handleBattery(const HwLightState &state) {
|
||||
mBatteryState = state;
|
||||
setNotificationLED();
|
||||
}
|
||||
|
||||
void Lights::handleNotifications(const HwLightState &state) {
|
||||
mNotificationState = state;
|
||||
setNotificationLED();
|
||||
}
|
||||
|
||||
void Lights::handleAttention(const HwLightState &state) {
|
||||
mAttentionState = state;
|
||||
setNotificationLED();
|
||||
}
|
||||
|
||||
void Lights::setNotificationLED() {
|
||||
int32_t adjusted_brightness = MAX_INPUT_BRIGHTNESS;
|
||||
HwLightState state;
|
||||
#ifdef LED_BLN_NODE
|
||||
bool bln = false;
|
||||
#endif /* LED_BLN_NODE */
|
||||
|
||||
if (mNotificationState.color & COLOR_MASK) {
|
||||
adjusted_brightness = LED_BRIGHTNESS_NOTIFICATION;
|
||||
state = mNotificationState;
|
||||
#ifdef LED_BLN_NODE
|
||||
bln = true;
|
||||
#endif /* LED_BLN_NODE */
|
||||
} else if (mAttentionState.color & COLOR_MASK) {
|
||||
adjusted_brightness = LED_BRIGHTNESS_ATTENTION;
|
||||
state = mAttentionState;
|
||||
if (state.flashMode == FlashMode::HARDWARE) {
|
||||
if (state.flashOnMs > 0 && state.flashOffMs == 0)
|
||||
state.flashMode = FlashMode::NONE;
|
||||
state.color = 0x000000ff;
|
||||
}
|
||||
if (state.flashMode == FlashMode::NONE) {
|
||||
state.color = 0;
|
||||
}
|
||||
} else if (mBatteryState.color & COLOR_MASK) {
|
||||
adjusted_brightness = LED_BRIGHTNESS_BATTERY;
|
||||
state = mBatteryState;
|
||||
} else {
|
||||
set(LED_BLINK_NODE, "0x00000000 0 0");
|
||||
return;
|
||||
}
|
||||
|
||||
if (state.flashMode == FlashMode::NONE) {
|
||||
state.flashOnMs = 0;
|
||||
state.flashOffMs = 0;
|
||||
}
|
||||
|
||||
state.color = calibrateColor(state.color & COLOR_MASK, adjusted_brightness);
|
||||
set(LED_BLINK_NODE,
|
||||
::android::base::StringPrintf("0x%08x %d %d", state.color,
|
||||
state.flashOnMs, state.flashOffMs));
|
||||
|
||||
#ifdef LED_BLN_NODE
|
||||
if (bln) {
|
||||
set(LED_BLN_NODE, (state.color & COLOR_MASK) ? 1 : 0);
|
||||
}
|
||||
#endif /* LED_BLN_NODE */
|
||||
}
|
||||
|
||||
uint32_t Lights::calibrateColor(uint32_t color, int32_t brightness) {
|
||||
uint32_t red = ((color >> 16) & 0xFF) * LED_ADJUSTMENT_R;
|
||||
uint32_t green = ((color >> 8) & 0xFF) * LED_ADJUSTMENT_G;
|
||||
uint32_t blue = (color & 0xFF) * LED_ADJUSTMENT_B;
|
||||
|
||||
return (((red * brightness) / 255) << 16) +
|
||||
(((green * brightness) / 255) << 8) + ((blue * brightness) / 255);
|
||||
}
|
||||
#endif /* LED_BLINK_NODE */
|
||||
|
||||
#define AutoHwLight(light) \
|
||||
{ .id = (int32_t)light, .type = light, .ordinal = 0 }
|
||||
|
||||
ndk::ScopedAStatus Lights::getLights(std::vector<HwLight> *_aidl_return) {
|
||||
for (auto const &light : mLights) {
|
||||
_aidl_return->push_back(AutoHwLight(light.first));
|
||||
}
|
||||
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
uint32_t Lights::rgbToBrightness(const HwLightState &state) {
|
||||
uint32_t color = state.color & COLOR_MASK;
|
||||
|
||||
return ((77 * ((color >> 16) & 0xff)) + (150 * ((color >> 8) & 0xff)) +
|
||||
(29 * (color & 0xff))) >>
|
||||
8;
|
||||
}
|
||||
|
||||
} // namespace light
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
56
universal7885-common/bin/hardware/samsung/light/Lights.h
Normal file
56
universal7885-common/bin/hardware/samsung/light/Lights.h
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (C) 2021 The LineageOS Project
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "samsung_lights.h"
|
||||
#include <aidl/android/hardware/light/BnLights.h>
|
||||
#include <unordered_map>
|
||||
|
||||
using ::aidl::android::hardware::light::HwLight;
|
||||
using ::aidl::android::hardware::light::HwLightState;
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace light {
|
||||
|
||||
class Lights : public BnLights {
|
||||
public:
|
||||
Lights();
|
||||
|
||||
ndk::ScopedAStatus setLightState(int32_t id,
|
||||
const HwLightState &state) override;
|
||||
ndk::ScopedAStatus getLights(std::vector<HwLight> *_aidl_return) override;
|
||||
|
||||
private:
|
||||
void handleBacklight(const HwLightState &state);
|
||||
#ifdef BUTTON_BRIGHTNESS_NODE
|
||||
void handleButtons(const HwLightState &state);
|
||||
#endif /* BUTTON_BRIGHTNESS_NODE */
|
||||
#ifdef LED_BLINK_NODE
|
||||
void handleBattery(const HwLightState &state);
|
||||
void handleNotifications(const HwLightState &state);
|
||||
void handleAttention(const HwLightState &state);
|
||||
void setNotificationLED();
|
||||
uint32_t calibrateColor(uint32_t color, int32_t brightness);
|
||||
|
||||
HwLightState mAttentionState;
|
||||
HwLightState mBatteryState;
|
||||
HwLightState mNotificationState;
|
||||
#endif /* LED_BLINK_NODE */
|
||||
|
||||
uint32_t rgbToBrightness(const HwLightState &state);
|
||||
|
||||
std::mutex mLock;
|
||||
std::unordered_map<LightType, std::function<void(const HwLightState &)>>
|
||||
mLights;
|
||||
};
|
||||
|
||||
} // namespace light
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
service vendor.light-default /vendor/bin/hw/android.hardware.light-service.samsung
|
||||
class hal
|
||||
user system
|
||||
group system
|
||||
shutdown critical
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0"?>
|
||||
<manifest version="1.0" type="device">
|
||||
<hal format="aidl">
|
||||
<name>android.hardware.light</name>
|
||||
<fqname>ILights/default</fqname>
|
||||
</hal>
|
||||
</manifest>
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright (C) 2016 The CyanogenMod Project
|
||||
* Copyright (C) 2017 The LineageOS Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SAMSUNG_LIGHTS_H
|
||||
#define SAMSUNG_LIGHTS_H
|
||||
|
||||
/*
|
||||
* Board specific nodes
|
||||
*
|
||||
* If your kernel exposes these controls in another place, you can either
|
||||
* symlink to the locations given here, or override this header in your
|
||||
* device tree.
|
||||
*/
|
||||
#define PANEL_BRIGHTNESS_NODE "/sys/class/backlight/panel/brightness"
|
||||
#define PANEL_MAX_BRIGHTNESS_NODE "/sys/class/backlight/panel/max_brightness"
|
||||
#define BUTTON_BRIGHTNESS_NODE "/sys/class/sec/sec_touchkey/brightness"
|
||||
#define LED_BLINK_NODE "/sys/class/sec/led/led_blink"
|
||||
#define LED_BLN_NODE "/sys/class/misc/backlightnotification/notification_led"
|
||||
|
||||
// Uncomment to enable variable button brightness
|
||||
// #define VAR_BUTTON_BRIGHTNESS 1
|
||||
|
||||
/*
|
||||
* Brightness adjustment factors
|
||||
*
|
||||
* If one of your device's LEDs is more powerful than the others, use these
|
||||
* values to equalise them. This value is in the range 0.0-1.0.
|
||||
*/
|
||||
#define LED_ADJUSTMENT_R 1.0
|
||||
#define LED_ADJUSTMENT_G 1.0
|
||||
#define LED_ADJUSTMENT_B 1.0
|
||||
|
||||
/*
|
||||
* Light brightness factors
|
||||
*
|
||||
* It might make sense for all colours to be scaled down (for example, if your
|
||||
* LED is too bright). Use these values to adjust the brightness of each
|
||||
* light. This value is within the range 0-255.
|
||||
*/
|
||||
#define LED_BRIGHTNESS_BATTERY 255
|
||||
#define LED_BRIGHTNESS_NOTIFICATION 255
|
||||
#define LED_BRIGHTNESS_ATTENTION 255
|
||||
|
||||
#endif // SAMSUNG_LIGHTS_H
|
||||
28
universal7885-common/bin/hardware/samsung/light/service.cpp
Normal file
28
universal7885-common/bin/hardware/samsung/light/service.cpp
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright (C) 2021 The LineageOS Project
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#define LOG_TAG "android.hardware.light-service.samsung"
|
||||
|
||||
#include "Lights.h"
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <android/binder_manager.h>
|
||||
#include <android/binder_process.h>
|
||||
|
||||
using ::aidl::android::hardware::light::Lights;
|
||||
|
||||
int main() {
|
||||
ABinderProcess_setThreadPoolMaxThreadCount(0);
|
||||
std::shared_ptr<Lights> lights = ndk::SharedRefBase::make<Lights>();
|
||||
|
||||
const std::string instance = std::string() + Lights::descriptor + "/default";
|
||||
binder_status_t status =
|
||||
AServiceManager_addService(lights->asBinder().get(), instance.c_str());
|
||||
CHECK(status == STATUS_OK);
|
||||
|
||||
ABinderProcess_joinThreadPool();
|
||||
return EXIT_FAILURE; // should not reach
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
//
|
||||
// Copyright (C) 2018 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
soong_namespace {
|
||||
imports: [
|
||||
"hardware/google/pixel",
|
||||
"hardware/google/interfaces",
|
||||
],
|
||||
}
|
||||
|
||||
cc_binary {
|
||||
name: "android.hardware.power-service.samsung-libperfmgr",
|
||||
relative_install_path: "hw",
|
||||
init_rc: ["android.hardware.power-service.samsung-libperfmgr.rc"],
|
||||
vintf_fragments: ["android.hardware.power-service.samsung.xml"],
|
||||
vendor: true,
|
||||
shared_libs: [
|
||||
"android.hardware.power-V1-ndk_platform",
|
||||
"libbase",
|
||||
"libcutils",
|
||||
"liblog",
|
||||
"libutils",
|
||||
"libbinder_ndk",
|
||||
"libperfmgr",
|
||||
"pixel-power-ext-V1-ndk_platform",
|
||||
],
|
||||
srcs: [
|
||||
"service.cpp",
|
||||
"Power.cpp",
|
||||
"PowerExt.cpp",
|
||||
"InteractionHandler.cpp"
|
||||
],
|
||||
}
|
||||
|
|
@ -0,0 +1,265 @@
|
|||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "android.hardware.power@-service.samsung-libperfmgr"
|
||||
#define ATRACE_TAG (ATRACE_TAG_POWER | ATRACE_TAG_HAL)
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <memory>
|
||||
#include <poll.h>
|
||||
#include <sys/eventfd.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <utils/Log.h>
|
||||
#include <utils/Trace.h>
|
||||
|
||||
#include "InteractionHandler.h"
|
||||
|
||||
#define MAX_LENGTH 64
|
||||
|
||||
#define MSINSEC 1000L
|
||||
#define USINMS 1000000L
|
||||
|
||||
static const std::vector<std::string> fb_idle_patch = {
|
||||
"/sys/class/drm/card0/device/idle_state",
|
||||
"/sys/class/graphics/fb0/idle_state"};
|
||||
|
||||
InteractionHandler::InteractionHandler(
|
||||
std::shared_ptr<HintManager> const &hint_manager)
|
||||
: mState(INTERACTION_STATE_UNINITIALIZED), mWaitMs(100),
|
||||
mMinDurationMs(1400), mMaxDurationMs(5650), mDurationMs(0),
|
||||
mHintManager(hint_manager) {}
|
||||
|
||||
InteractionHandler::~InteractionHandler() { Exit(); }
|
||||
|
||||
static int fb_idle_open(void) {
|
||||
int fd;
|
||||
for (auto &path : fb_idle_patch) {
|
||||
fd = open(path.c_str(), O_RDONLY);
|
||||
if (fd >= 0)
|
||||
return fd;
|
||||
}
|
||||
ALOGE("Unable to open fb idle state path (%d)", errno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool InteractionHandler::Init() {
|
||||
std::lock_guard<std::mutex> lk(mLock);
|
||||
|
||||
if (mState != INTERACTION_STATE_UNINITIALIZED)
|
||||
return true;
|
||||
|
||||
mIdleFd = fb_idle_open();
|
||||
|
||||
mEventFd = eventfd(0, EFD_NONBLOCK);
|
||||
if (mEventFd < 0) {
|
||||
ALOGE("Unable to create event fd (%d)", errno);
|
||||
if (mIdleFd >= 0) {
|
||||
close(mIdleFd);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
mState = INTERACTION_STATE_IDLE;
|
||||
mThread = std::unique_ptr<std::thread>(
|
||||
new std::thread(&InteractionHandler::Routine, this));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void InteractionHandler::Exit() {
|
||||
std::unique_lock<std::mutex> lk(mLock);
|
||||
if (mState == INTERACTION_STATE_UNINITIALIZED)
|
||||
return;
|
||||
|
||||
AbortWaitLocked();
|
||||
mState = INTERACTION_STATE_UNINITIALIZED;
|
||||
lk.unlock();
|
||||
|
||||
mCond.notify_all();
|
||||
mThread->join();
|
||||
|
||||
close(mEventFd);
|
||||
if (mIdleFd >= 0) {
|
||||
close(mIdleFd);
|
||||
}
|
||||
}
|
||||
|
||||
void InteractionHandler::PerfLock() {
|
||||
ALOGV("%s: acquiring perf lock", __func__);
|
||||
if (!mHintManager->DoHint("INTERACTION")) {
|
||||
ALOGE("%s: do hint INTERACTION failed", __func__);
|
||||
}
|
||||
ATRACE_INT("interaction_lock", 1);
|
||||
}
|
||||
|
||||
void InteractionHandler::PerfRel() {
|
||||
ALOGV("%s: releasing perf lock", __func__);
|
||||
if (!mHintManager->EndHint("INTERACTION")) {
|
||||
ALOGE("%s: end hint INTERACTION failed", __func__);
|
||||
}
|
||||
ATRACE_INT("interaction_lock", 0);
|
||||
}
|
||||
|
||||
size_t InteractionHandler::CalcTimespecDiffMs(struct timespec start,
|
||||
struct timespec end) {
|
||||
size_t diff_in_us = 0;
|
||||
diff_in_us += (end.tv_sec - start.tv_sec) * MSINSEC;
|
||||
diff_in_us += (end.tv_nsec - start.tv_nsec) / USINMS;
|
||||
return diff_in_us;
|
||||
}
|
||||
|
||||
void InteractionHandler::Acquire(int32_t duration) {
|
||||
ATRACE_CALL();
|
||||
|
||||
std::lock_guard<std::mutex> lk(mLock);
|
||||
if (mState == INTERACTION_STATE_UNINITIALIZED) {
|
||||
ALOGW("%s: called while uninitialized", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
int inputDuration = duration + 650;
|
||||
int finalDuration;
|
||||
if (inputDuration > mMaxDurationMs)
|
||||
finalDuration = mMaxDurationMs;
|
||||
else if (inputDuration > mMinDurationMs)
|
||||
finalDuration = inputDuration;
|
||||
else
|
||||
finalDuration = mMinDurationMs;
|
||||
|
||||
struct timespec cur_timespec;
|
||||
clock_gettime(CLOCK_MONOTONIC, &cur_timespec);
|
||||
if (mState != INTERACTION_STATE_IDLE && finalDuration <= mDurationMs) {
|
||||
size_t elapsed_time = CalcTimespecDiffMs(mLastTimespec, cur_timespec);
|
||||
// don't hint if previous hint's duration covers this hint's duration
|
||||
if (elapsed_time <= (mDurationMs - finalDuration)) {
|
||||
ALOGV("%s: Previous duration (%d) cover this (%d) elapsed: %lld",
|
||||
__func__, static_cast<int>(mDurationMs),
|
||||
static_cast<int>(finalDuration),
|
||||
static_cast<long long>(elapsed_time));
|
||||
return;
|
||||
}
|
||||
}
|
||||
mLastTimespec = cur_timespec;
|
||||
mDurationMs = finalDuration;
|
||||
|
||||
ALOGV("%s: input: %d final duration: %d", __func__, duration, finalDuration);
|
||||
|
||||
if (mState == INTERACTION_STATE_WAITING)
|
||||
AbortWaitLocked();
|
||||
else if (mState == INTERACTION_STATE_IDLE)
|
||||
PerfLock();
|
||||
|
||||
mState = INTERACTION_STATE_INTERACTION;
|
||||
mCond.notify_one();
|
||||
}
|
||||
|
||||
void InteractionHandler::Release() {
|
||||
std::lock_guard<std::mutex> lk(mLock);
|
||||
if (mState == INTERACTION_STATE_WAITING) {
|
||||
ATRACE_CALL();
|
||||
PerfRel();
|
||||
mState = INTERACTION_STATE_IDLE;
|
||||
} else {
|
||||
// clear any wait aborts pending in event fd
|
||||
uint64_t val;
|
||||
ssize_t ret = read(mEventFd, &val, sizeof(val));
|
||||
|
||||
ALOGW_IF(ret < 0, "%s: failed to clear eventfd (%zd, %d)", __func__, ret,
|
||||
errno);
|
||||
}
|
||||
}
|
||||
|
||||
// should be called while locked
|
||||
void InteractionHandler::AbortWaitLocked() {
|
||||
uint64_t val = 1;
|
||||
ssize_t ret = write(mEventFd, &val, sizeof(val));
|
||||
if (ret != sizeof(val))
|
||||
ALOGW("Unable to write to event fd (%zd)", ret);
|
||||
}
|
||||
|
||||
void InteractionHandler::WaitForIdle(int32_t wait_ms, int32_t timeout_ms) {
|
||||
char data[MAX_LENGTH];
|
||||
ssize_t ret;
|
||||
struct pollfd pfd[2];
|
||||
|
||||
ATRACE_CALL();
|
||||
|
||||
ALOGV("%s: wait:%d timeout:%d", __func__, wait_ms, timeout_ms);
|
||||
|
||||
pfd[0].fd = mEventFd;
|
||||
pfd[0].events = POLLIN;
|
||||
pfd[1].fd = mIdleFd;
|
||||
pfd[1].events = POLLPRI | POLLERR;
|
||||
|
||||
ret = poll(pfd, 1, wait_ms);
|
||||
if (ret > 0) {
|
||||
ALOGV("%s: wait aborted", __func__);
|
||||
return;
|
||||
} else if (ret < 0) {
|
||||
ALOGE("%s: error in poll while waiting", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mIdleFd < 0) {
|
||||
ret = poll(pfd, 1, timeout_ms);
|
||||
if (ret > 0) {
|
||||
ALOGV("%s: wait for duration aborted", __func__);
|
||||
return;
|
||||
} else if (ret < 0) {
|
||||
ALOGE("%s: Error on waiting for duration (%zd)", __func__, ret);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
ret = pread(mIdleFd, data, sizeof(data), 0);
|
||||
if (!ret) {
|
||||
ALOGE("%s: Unexpected EOF!", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strncmp(data, "idle", 4)) {
|
||||
ALOGV("%s: already idle", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
ret = poll(pfd, 2, timeout_ms);
|
||||
if (ret < 0)
|
||||
ALOGE("%s: Error on waiting for idle (%zd)", __func__, ret);
|
||||
else if (ret == 0)
|
||||
ALOGV("%s: timed out waiting for idle", __func__);
|
||||
else if (pfd[0].revents)
|
||||
ALOGV("%s: wait for idle aborted", __func__);
|
||||
else if (pfd[1].revents)
|
||||
ALOGV("%s: idle detected", __func__);
|
||||
}
|
||||
|
||||
void InteractionHandler::Routine() {
|
||||
std::unique_lock<std::mutex> lk(mLock, std::defer_lock);
|
||||
|
||||
while (true) {
|
||||
lk.lock();
|
||||
mCond.wait(lk, [&] { return mState != INTERACTION_STATE_IDLE; });
|
||||
if (mState == INTERACTION_STATE_UNINITIALIZED)
|
||||
return;
|
||||
mState = INTERACTION_STATE_WAITING;
|
||||
lk.unlock();
|
||||
|
||||
WaitForIdle(mWaitMs, mDurationMs);
|
||||
Release();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef POWER_LIBPERFMGR_INTERACTIONHANDLER_H_
|
||||
#define POWER_LIBPERFMGR_INTERACTIONHANDLER_H_
|
||||
|
||||
#include <condition_variable>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
|
||||
#include <perfmgr/HintManager.h>
|
||||
|
||||
using ::android::perfmgr::HintManager;
|
||||
|
||||
enum interaction_state {
|
||||
INTERACTION_STATE_UNINITIALIZED,
|
||||
INTERACTION_STATE_IDLE,
|
||||
INTERACTION_STATE_INTERACTION,
|
||||
INTERACTION_STATE_WAITING,
|
||||
};
|
||||
|
||||
class InteractionHandler {
|
||||
public:
|
||||
InteractionHandler(std::shared_ptr<HintManager> const &hint_manager);
|
||||
~InteractionHandler();
|
||||
bool Init();
|
||||
void Exit();
|
||||
void Acquire(int32_t duration);
|
||||
|
||||
private:
|
||||
void Release();
|
||||
void WaitForIdle(int32_t wait_ms, int32_t timeout_ms);
|
||||
void AbortWaitLocked();
|
||||
void Routine();
|
||||
|
||||
void PerfLock();
|
||||
void PerfRel();
|
||||
|
||||
size_t CalcTimespecDiffMs(struct timespec start, struct timespec end);
|
||||
|
||||
enum interaction_state mState;
|
||||
|
||||
int mIdleFd;
|
||||
int mEventFd;
|
||||
|
||||
int32_t mWaitMs;
|
||||
int32_t mMinDurationMs;
|
||||
int32_t mMaxDurationMs;
|
||||
int32_t mDurationMs;
|
||||
|
||||
struct timespec mLastTimespec;
|
||||
|
||||
std::unique_ptr<std::thread> mThread;
|
||||
std::mutex mLock;
|
||||
std::condition_variable mCond;
|
||||
std::shared_ptr<HintManager> mHintManager;
|
||||
};
|
||||
|
||||
#endif // POWER_LIBPERFMGR_INTERACTIONHANDLER_H_
|
||||
|
|
@ -0,0 +1,262 @@
|
|||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#define ATRACE_TAG (ATRACE_TAG_POWER | ATRACE_TAG_HAL)
|
||||
#define LOG_TAG "android.hardware.power-service.samsung-libperfmgr"
|
||||
|
||||
#include "Power.h"
|
||||
|
||||
#include <mutex>
|
||||
|
||||
#include <android-base/file.h>
|
||||
#include <android-base/logging.h>
|
||||
#include <android-base/properties.h>
|
||||
#include <android-base/stringprintf.h>
|
||||
#include <android-base/strings.h>
|
||||
|
||||
#include <utils/Log.h>
|
||||
#include <utils/Trace.h>
|
||||
|
||||
namespace aidl {
|
||||
namespace google {
|
||||
namespace hardware {
|
||||
namespace power {
|
||||
namespace impl {
|
||||
namespace pixel {
|
||||
|
||||
constexpr char kPowerHalStateProp[] = "vendor.powerhal.state";
|
||||
constexpr char kPowerHalAudioProp[] = "vendor.powerhal.audio";
|
||||
constexpr char kPowerHalRenderingProp[] = "vendor.powerhal.rendering";
|
||||
|
||||
Power::Power(std::shared_ptr<HintManager> hm)
|
||||
: mHintManager(hm), mInteractionHandler(nullptr), mVRModeOn(false),
|
||||
mSustainedPerfModeOn(false) {
|
||||
mInteractionHandler = std::make_unique<InteractionHandler>(mHintManager);
|
||||
mInteractionHandler->Init();
|
||||
|
||||
std::string state = ::android::base::GetProperty(kPowerHalStateProp, "");
|
||||
if (state == "SUSTAINED_PERFORMANCE") {
|
||||
ALOGI("Initialize with SUSTAINED_PERFORMANCE on");
|
||||
mHintManager->DoHint("SUSTAINED_PERFORMANCE");
|
||||
mSustainedPerfModeOn = true;
|
||||
} else if (state == "VR") {
|
||||
ALOGI("Initialize with VR on");
|
||||
mHintManager->DoHint(state);
|
||||
mVRModeOn = true;
|
||||
} else if (state == "VR_SUSTAINED_PERFORMANCE") {
|
||||
ALOGI("Initialize with SUSTAINED_PERFORMANCE and VR on");
|
||||
mHintManager->DoHint("VR_SUSTAINED_PERFORMANCE");
|
||||
mSustainedPerfModeOn = true;
|
||||
mVRModeOn = true;
|
||||
} else {
|
||||
ALOGI("Initialize PowerHAL");
|
||||
}
|
||||
|
||||
state = ::android::base::GetProperty(kPowerHalAudioProp, "");
|
||||
if (state == "AUDIO_STREAMING_LOW_LATENCY") {
|
||||
ALOGI("Initialize with AUDIO_LOW_LATENCY on");
|
||||
mHintManager->DoHint(state);
|
||||
}
|
||||
|
||||
state = ::android::base::GetProperty(kPowerHalRenderingProp, "");
|
||||
if (state == "EXPENSIVE_RENDERING") {
|
||||
ALOGI("Initialize with EXPENSIVE_RENDERING on");
|
||||
mHintManager->DoHint("EXPENSIVE_RENDERING");
|
||||
}
|
||||
|
||||
// Now start to take powerhint
|
||||
ALOGI("PowerHAL ready to process hints");
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Power::setMode(Mode type, bool enabled) {
|
||||
LOG(DEBUG) << "Power setMode: " << toString(type) << " to: " << enabled;
|
||||
ATRACE_INT(toString(type).c_str(), enabled);
|
||||
switch (type) {
|
||||
case Mode::LOW_POWER:
|
||||
if (enabled) {
|
||||
mHintManager->DoHint(toString(type));
|
||||
} else {
|
||||
mHintManager->EndHint(toString(type));
|
||||
}
|
||||
break;
|
||||
case Mode::SUSTAINED_PERFORMANCE:
|
||||
if (enabled && !mSustainedPerfModeOn) {
|
||||
if (!mVRModeOn) { // Sustained mode only.
|
||||
mHintManager->DoHint("SUSTAINED_PERFORMANCE");
|
||||
} else { // Sustained + VR mode.
|
||||
mHintManager->EndHint("VR");
|
||||
mHintManager->DoHint("VR_SUSTAINED_PERFORMANCE");
|
||||
}
|
||||
mSustainedPerfModeOn = true;
|
||||
} else if (!enabled && mSustainedPerfModeOn) {
|
||||
mHintManager->EndHint("VR_SUSTAINED_PERFORMANCE");
|
||||
mHintManager->EndHint("SUSTAINED_PERFORMANCE");
|
||||
if (mVRModeOn) { // Switch back to VR Mode.
|
||||
mHintManager->DoHint("VR");
|
||||
}
|
||||
mSustainedPerfModeOn = false;
|
||||
}
|
||||
break;
|
||||
case Mode::VR:
|
||||
if (enabled && !mVRModeOn) {
|
||||
if (!mSustainedPerfModeOn) { // VR mode only.
|
||||
mHintManager->DoHint("VR");
|
||||
} else { // Sustained + VR mode.
|
||||
mHintManager->EndHint("SUSTAINED_PERFORMANCE");
|
||||
mHintManager->DoHint("VR_SUSTAINED_PERFORMANCE");
|
||||
}
|
||||
mVRModeOn = true;
|
||||
} else if (!enabled && mVRModeOn) {
|
||||
mHintManager->EndHint("VR_SUSTAINED_PERFORMANCE");
|
||||
mHintManager->EndHint("VR");
|
||||
if (mSustainedPerfModeOn) { // Switch back to sustained Mode.
|
||||
mHintManager->DoHint("SUSTAINED_PERFORMANCE");
|
||||
}
|
||||
mVRModeOn = false;
|
||||
}
|
||||
break;
|
||||
case Mode::LAUNCH:
|
||||
if (mVRModeOn || mSustainedPerfModeOn) {
|
||||
break;
|
||||
}
|
||||
[[fallthrough]];
|
||||
case Mode::DOUBLE_TAP_TO_WAKE:
|
||||
[[fallthrough]];
|
||||
case Mode::FIXED_PERFORMANCE:
|
||||
[[fallthrough]];
|
||||
case Mode::EXPENSIVE_RENDERING:
|
||||
[[fallthrough]];
|
||||
case Mode::INTERACTIVE:
|
||||
[[fallthrough]];
|
||||
case Mode::DEVICE_IDLE:
|
||||
[[fallthrough]];
|
||||
case Mode::DISPLAY_INACTIVE:
|
||||
[[fallthrough]];
|
||||
case Mode::AUDIO_STREAMING_LOW_LATENCY:
|
||||
[[fallthrough]];
|
||||
case Mode::CAMERA_STREAMING_SECURE:
|
||||
[[fallthrough]];
|
||||
case Mode::CAMERA_STREAMING_LOW:
|
||||
[[fallthrough]];
|
||||
case Mode::CAMERA_STREAMING_MID:
|
||||
[[fallthrough]];
|
||||
case Mode::CAMERA_STREAMING_HIGH:
|
||||
[[fallthrough]];
|
||||
default:
|
||||
if (enabled) {
|
||||
mHintManager->DoHint(toString(type));
|
||||
} else {
|
||||
mHintManager->EndHint(toString(type));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Power::isModeSupported(Mode type, bool *_aidl_return) {
|
||||
bool supported = mHintManager->IsHintSupported(toString(type));
|
||||
switch (type) {
|
||||
case Mode::LOW_POWER: // LOW_POWER handled insides PowerHAL specifically
|
||||
supported = true;
|
||||
break;
|
||||
case Mode::DOUBLE_TAP_TO_WAKE:
|
||||
supported = true;
|
||||
break;
|
||||
case Mode::INTERACTIVE:
|
||||
supported = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
LOG(INFO) << "Power mode " << toString(type)
|
||||
<< " isModeSupported: " << supported;
|
||||
*_aidl_return = supported;
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Power::setBoost(Boost type, int32_t durationMs) {
|
||||
LOG(DEBUG) << "Power setBoost: " << toString(type)
|
||||
<< " duration: " << durationMs;
|
||||
ATRACE_INT(toString(type).c_str(), durationMs);
|
||||
switch (type) {
|
||||
case Boost::INTERACTION:
|
||||
if (mVRModeOn || mSustainedPerfModeOn) {
|
||||
break;
|
||||
}
|
||||
mInteractionHandler->Acquire(durationMs);
|
||||
break;
|
||||
case Boost::DISPLAY_UPDATE_IMMINENT:
|
||||
[[fallthrough]];
|
||||
case Boost::ML_ACC:
|
||||
[[fallthrough]];
|
||||
case Boost::AUDIO_LAUNCH:
|
||||
[[fallthrough]];
|
||||
case Boost::CAMERA_LAUNCH:
|
||||
[[fallthrough]];
|
||||
case Boost::CAMERA_SHOT:
|
||||
[[fallthrough]];
|
||||
default:
|
||||
if (mVRModeOn || mSustainedPerfModeOn) {
|
||||
break;
|
||||
}
|
||||
if (durationMs > 0) {
|
||||
mHintManager->DoHint(toString(type),
|
||||
std::chrono::milliseconds(durationMs));
|
||||
} else if (durationMs == 0) {
|
||||
mHintManager->DoHint(toString(type));
|
||||
} else {
|
||||
mHintManager->EndHint(toString(type));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Power::isBoostSupported(Boost type, bool *_aidl_return) {
|
||||
bool supported = mHintManager->IsHintSupported(toString(type));
|
||||
LOG(INFO) << "Power boost " << toString(type)
|
||||
<< " isBoostSupported: " << supported;
|
||||
*_aidl_return = supported;
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
constexpr const char *boolToString(bool b) { return b ? "true" : "false"; }
|
||||
|
||||
binder_status_t Power::dump(int fd, const char **, uint32_t) {
|
||||
std::string buf(::android::base::StringPrintf(
|
||||
"HintManager Running: %s\n"
|
||||
"VRMode: %s\n"
|
||||
"SustainedPerformanceMode: %s\n",
|
||||
boolToString(mHintManager->IsRunning()), boolToString(mVRModeOn),
|
||||
boolToString(mSustainedPerfModeOn)));
|
||||
// Dump nodes through libperfmgr
|
||||
mHintManager->DumpToFd(fd);
|
||||
if (!::android::base::WriteStringToFd(buf, fd)) {
|
||||
PLOG(ERROR) << "Failed to dump state to fd";
|
||||
}
|
||||
fsync(fd);
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
} // namespace pixel
|
||||
} // namespace impl
|
||||
} // namespace power
|
||||
} // namespace hardware
|
||||
} // namespace google
|
||||
} // namespace aidl
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
|
||||
#include <aidl/android/hardware/power/BnPower.h>
|
||||
#include <perfmgr/HintManager.h>
|
||||
|
||||
#include "InteractionHandler.h"
|
||||
|
||||
namespace aidl {
|
||||
namespace google {
|
||||
namespace hardware {
|
||||
namespace power {
|
||||
namespace impl {
|
||||
namespace pixel {
|
||||
|
||||
using ::InteractionHandler;
|
||||
using ::aidl::android::hardware::power::Boost;
|
||||
using ::aidl::android::hardware::power::Mode;
|
||||
using ::android::perfmgr::HintManager;
|
||||
|
||||
class Power : public ::aidl::android::hardware::power::BnPower {
|
||||
public:
|
||||
Power(std::shared_ptr<HintManager> hm);
|
||||
ndk::ScopedAStatus setMode(Mode type, bool enabled) override;
|
||||
ndk::ScopedAStatus isModeSupported(Mode type, bool *_aidl_return) override;
|
||||
ndk::ScopedAStatus setBoost(Boost type, int32_t durationMs) override;
|
||||
ndk::ScopedAStatus isBoostSupported(Boost type, bool *_aidl_return) override;
|
||||
binder_status_t dump(int fd, const char **args, uint32_t numArgs) override;
|
||||
|
||||
private:
|
||||
std::shared_ptr<HintManager> mHintManager;
|
||||
std::unique_ptr<InteractionHandler> mInteractionHandler;
|
||||
std::atomic<bool> mVRModeOn;
|
||||
std::atomic<bool> mSustainedPerfModeOn;
|
||||
};
|
||||
|
||||
} // namespace pixel
|
||||
} // namespace impl
|
||||
} // namespace power
|
||||
} // namespace hardware
|
||||
} // namespace google
|
||||
} // namespace aidl
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#define ATRACE_TAG (ATRACE_TAG_POWER | ATRACE_TAG_HAL)
|
||||
#define LOG_TAG "android.hardware.power-service.samsung.ext-libperfmgr"
|
||||
|
||||
#include "PowerExt.h"
|
||||
|
||||
#include <mutex>
|
||||
|
||||
#include <android-base/file.h>
|
||||
#include <android-base/logging.h>
|
||||
#include <android-base/properties.h>
|
||||
#include <android-base/stringprintf.h>
|
||||
#include <android-base/strings.h>
|
||||
|
||||
#include <utils/Log.h>
|
||||
#include <utils/Trace.h>
|
||||
|
||||
namespace aidl {
|
||||
namespace google {
|
||||
namespace hardware {
|
||||
namespace power {
|
||||
namespace impl {
|
||||
namespace pixel {
|
||||
|
||||
ndk::ScopedAStatus PowerExt::setMode(const std::string &mode, bool enabled) {
|
||||
LOG(DEBUG) << "PowerExt setMode: " << mode << " to: " << enabled;
|
||||
ATRACE_INT(mode.c_str(), enabled);
|
||||
|
||||
if (enabled) {
|
||||
mHintManager->DoHint(mode);
|
||||
} else {
|
||||
mHintManager->EndHint(mode);
|
||||
}
|
||||
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus PowerExt::isModeSupported(const std::string &mode,
|
||||
bool *_aidl_return) {
|
||||
bool supported = mHintManager->IsHintSupported(mode);
|
||||
LOG(INFO) << "PowerExt mode " << mode << " isModeSupported: " << supported;
|
||||
*_aidl_return = supported;
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus PowerExt::setBoost(const std::string &boost,
|
||||
int32_t durationMs) {
|
||||
LOG(DEBUG) << "PowerExt setBoost: " << boost << " duration: " << durationMs;
|
||||
ATRACE_INT(boost.c_str(), durationMs);
|
||||
|
||||
if (durationMs > 0) {
|
||||
mHintManager->DoHint(boost, std::chrono::milliseconds(durationMs));
|
||||
} else if (durationMs == 0) {
|
||||
mHintManager->DoHint(boost);
|
||||
} else {
|
||||
mHintManager->EndHint(boost);
|
||||
}
|
||||
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus PowerExt::isBoostSupported(const std::string &boost,
|
||||
bool *_aidl_return) {
|
||||
bool supported = mHintManager->IsHintSupported(boost);
|
||||
LOG(INFO) << "PowerExt boost " << boost << " isBoostSupported: " << supported;
|
||||
*_aidl_return = supported;
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
} // namespace pixel
|
||||
} // namespace impl
|
||||
} // namespace power
|
||||
} // namespace hardware
|
||||
} // namespace google
|
||||
} // namespace aidl
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
|
||||
#include <aidl/google/hardware/power/extension/pixel/BnPowerExt.h>
|
||||
#include <perfmgr/HintManager.h>
|
||||
|
||||
namespace aidl {
|
||||
namespace google {
|
||||
namespace hardware {
|
||||
namespace power {
|
||||
namespace impl {
|
||||
namespace pixel {
|
||||
|
||||
using ::android::perfmgr::HintManager;
|
||||
|
||||
class PowerExt
|
||||
: public ::aidl::google::hardware::power::extension::pixel::BnPowerExt {
|
||||
public:
|
||||
PowerExt(std::shared_ptr<HintManager> hm) : mHintManager(hm) {}
|
||||
ndk::ScopedAStatus setMode(const std::string &mode, bool enabled) override;
|
||||
ndk::ScopedAStatus isModeSupported(const std::string &mode,
|
||||
bool *_aidl_return) override;
|
||||
ndk::ScopedAStatus setBoost(const std::string &boost,
|
||||
int32_t durationMs) override;
|
||||
ndk::ScopedAStatus isBoostSupported(const std::string &boost,
|
||||
bool *_aidl_return) override;
|
||||
|
||||
private:
|
||||
std::shared_ptr<HintManager> mHintManager;
|
||||
};
|
||||
|
||||
} // namespace pixel
|
||||
} // namespace impl
|
||||
} // namespace power
|
||||
} // namespace hardware
|
||||
} // namespace google
|
||||
} // namespace aidl
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
service vendor.power-hal-aidl /vendor/bin/hw/android.hardware.power-service.samsung-libperfmgr
|
||||
class hal
|
||||
user root
|
||||
group system radio
|
||||
priority -20
|
||||
|
||||
on late-fs
|
||||
start vendor.power-hal-aidl
|
||||
|
||||
# restart powerHAL when framework died
|
||||
on property:init.svc.zygote=restarting && property:vendor.powerhal.state=*
|
||||
setprop vendor.powerhal.state ""
|
||||
setprop vendor.powerhal.audio ""
|
||||
setprop vendor.powerhal.rendering ""
|
||||
restart vendor.power-hal-aidl
|
||||
|
||||
# Clean up after b/163539793 resolved
|
||||
on property:vendor.powerhal.dalvik.vm.dex2oat-threads=*
|
||||
setprop dalvik.vm.dex2oat-threads ${vendor.powerhal.dalvik.vm.dex2oat-threads}
|
||||
setprop dalvik.vm.restore-dex2oat-threads ${vendor.powerhal.dalvik.vm.dex2oat-threads}
|
||||
|
||||
on property:vendor.powerhal.dalvik.vm.dex2oat-cpu-set=*
|
||||
setprop dalvik.vm.dex2oat-cpu-set ${vendor.powerhal.dalvik.vm.dex2oat-cpu-set}
|
||||
setprop dalvik.vm.restore-dex2oat-cpu-set ${vendor.powerhal.dalvik.vm.dex2oat-cpu-set}
|
||||
|
||||
# initialize powerHAL when boot is completed
|
||||
on property:sys.boot_completed=1
|
||||
setprop vendor.powerhal.init 1
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0"?>
|
||||
<manifest version="1.0" type="device">
|
||||
<hal format="aidl" override="true">
|
||||
<name>android.hardware.power</name>
|
||||
<fqname>IPower/default</fqname>
|
||||
</hal>
|
||||
</manifest>
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "android.hardware.power-service.samsung-libperfmgr"
|
||||
|
||||
#include <thread>
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <android-base/properties.h>
|
||||
#include <android/binder_manager.h>
|
||||
#include <android/binder_process.h>
|
||||
|
||||
#include "Power.h"
|
||||
#include "PowerExt.h"
|
||||
|
||||
using aidl::google::hardware::power::impl::pixel::Power;
|
||||
using aidl::google::hardware::power::impl::pixel::PowerExt;
|
||||
using ::android::perfmgr::HintManager;
|
||||
|
||||
constexpr char kPowerHalConfigPath[] = "/vendor/etc/powerhint.json";
|
||||
constexpr char kPowerHalInitProp[] = "vendor.powerhal.init";
|
||||
|
||||
int main() {
|
||||
LOG(INFO) << "Pixel Power HAL AIDL Service with Extension is starting.";
|
||||
|
||||
// Parse config but do not start the looper
|
||||
std::shared_ptr<HintManager> hm =
|
||||
HintManager::GetFromJSON(kPowerHalConfigPath, false);
|
||||
if (!hm) {
|
||||
LOG(FATAL) << "Invalid config: " << kPowerHalConfigPath;
|
||||
}
|
||||
|
||||
// single thread
|
||||
ABinderProcess_setThreadPoolMaxThreadCount(0);
|
||||
|
||||
// core service
|
||||
std::shared_ptr<Power> pw = ndk::SharedRefBase::make<Power>(hm);
|
||||
ndk::SpAIBinder pwBinder = pw->asBinder();
|
||||
|
||||
// extension service
|
||||
std::shared_ptr<PowerExt> pwExt = ndk::SharedRefBase::make<PowerExt>(hm);
|
||||
|
||||
// attach the extension to the same binder we will be registering
|
||||
CHECK(STATUS_OK ==
|
||||
AIBinder_setExtension(pwBinder.get(), pwExt->asBinder().get()));
|
||||
|
||||
const std::string instance = std::string() + Power::descriptor + "/default";
|
||||
binder_status_t status =
|
||||
AServiceManager_addService(pw->asBinder().get(), instance.c_str());
|
||||
CHECK(status == STATUS_OK);
|
||||
LOG(INFO) << "Pixel Power HAL AIDL Service with Extension is started.";
|
||||
|
||||
std::thread initThread([&]() {
|
||||
::android::base::WaitForProperty(kPowerHalInitProp, "1");
|
||||
hm->Start();
|
||||
});
|
||||
initThread.detach();
|
||||
|
||||
ABinderProcess_joinThreadPool();
|
||||
|
||||
// should not reach
|
||||
LOG(ERROR) << "Pixel Power HAL AIDL Service with Extension just died.";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
//
|
||||
// Copyright (C) 2021 The LineageOS Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
cc_binary {
|
||||
name: "secril_config_svc",
|
||||
vendor: true,
|
||||
srcs: ["secril_config_svc.cpp"],
|
||||
shared_libs: [
|
||||
"libbase",
|
||||
],
|
||||
}
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Copyright (C) 2021, The LineageOS Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "secril_config_svc"
|
||||
|
||||
#include <android-base/file.h>
|
||||
#include <android-base/logging.h>
|
||||
#include <android-base/properties.h>
|
||||
#include <android-base/strings.h>
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#define EFS_OLD "/efs/"
|
||||
#define EFS_NEW "/mnt/vendor/efs/"
|
||||
#define FACTORY_PROP "factory.prop"
|
||||
#define TELEPHONY_PROP "telephony.prop"
|
||||
|
||||
void LoadProperties(std::string data) {
|
||||
for (std::string line : android::base::Split(data, "\n")) {
|
||||
if (line == "\0")
|
||||
break;
|
||||
|
||||
std::vector<std::string> parts = android::base::Split(line, "=");
|
||||
if (parts.size() == 2) {
|
||||
LOG(INFO) << "Setting property: " << line;
|
||||
android::base::SetProperty(parts.at(0), parts.at(1));
|
||||
} else {
|
||||
LOG(ERROR) << "Invalid data: " << line;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
std::string prop = FACTORY_PROP;
|
||||
|
||||
if (argc > 1 && std::string(argv[1]) == "NetworkConfig")
|
||||
prop = TELEPHONY_PROP;
|
||||
|
||||
std::ifstream in(EFS_NEW + prop);
|
||||
if (in.good()) {
|
||||
in.close();
|
||||
prop = EFS_NEW + prop;
|
||||
} else {
|
||||
prop = EFS_OLD + prop;
|
||||
}
|
||||
|
||||
LOG(INFO) << "Loading properties from " << prop;
|
||||
|
||||
std::string content;
|
||||
if (android::base::ReadFileToString(prop, &content)) {
|
||||
LoadProperties(content.c_str());
|
||||
} else if (prop == FACTORY_PROP) {
|
||||
LOG(WARNING) << "Could not read " << prop << ", setting defaults!";
|
||||
LoadProperties("ro.vendor.multisim.simslotcount=1");
|
||||
} else {
|
||||
LOG(WARNING) << "Could not read " << prop << "!";
|
||||
}
|
||||
}
|
||||
20
universal7885-common/bin/hardware/samsung/sensors/Android.bp
Normal file
20
universal7885-common/bin/hardware/samsung/sensors/Android.bp
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
cc_library_shared {
|
||||
name: "android.hardware.sensors@1.0-impl.samsung",
|
||||
defaults: ["hidl_defaults"],
|
||||
proprietary: true,
|
||||
relative_install_path: "hw",
|
||||
srcs: ["Sensors.cpp"],
|
||||
shared_libs: [
|
||||
"liblog",
|
||||
"libcutils",
|
||||
"libhardware",
|
||||
"libbase",
|
||||
"libutils",
|
||||
"libhidlbase",
|
||||
"android.hardware.sensors@1.0",
|
||||
],
|
||||
static_libs: [
|
||||
"android.hardware.sensors@1.0-convert",
|
||||
"multihal",
|
||||
],
|
||||
}
|
||||
366
universal7885-common/bin/hardware/samsung/sensors/Sensors.cpp
Normal file
366
universal7885-common/bin/hardware/samsung/sensors/Sensors.cpp
Normal file
|
|
@ -0,0 +1,366 @@
|
|||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
// #define VERBOSE
|
||||
|
||||
#include "Sensors.h"
|
||||
#include "multihal.h"
|
||||
#include <sensors/convert.h>
|
||||
|
||||
#include <android-base/logging.h>
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace sensors {
|
||||
namespace V1_0 {
|
||||
namespace implementation {
|
||||
|
||||
/*
|
||||
* If a multi-hal configuration file exists in the proper location,
|
||||
* return true indicating we need to use multi-hal functionality.
|
||||
*/
|
||||
static bool UseMultiHal() {
|
||||
const std::string &name = MULTI_HAL_CONFIG_FILE_PATH;
|
||||
struct stat buffer;
|
||||
return (stat(name.c_str(), &buffer) == 0);
|
||||
}
|
||||
|
||||
static Result ResultFromStatus(status_t err) {
|
||||
switch (err) {
|
||||
case OK:
|
||||
return Result::OK;
|
||||
case PERMISSION_DENIED:
|
||||
return Result::PERMISSION_DENIED;
|
||||
case NO_MEMORY:
|
||||
return Result::NO_MEMORY;
|
||||
case BAD_VALUE:
|
||||
return Result::BAD_VALUE;
|
||||
default:
|
||||
return Result::INVALID_OPERATION;
|
||||
}
|
||||
}
|
||||
|
||||
Sensors::Sensors()
|
||||
: mInitCheck(NO_INIT), mSensorModule(nullptr), mSensorDevice(nullptr) {
|
||||
status_t err = OK;
|
||||
if (UseMultiHal()) {
|
||||
mSensorModule = ::get_multi_hal_module_info();
|
||||
} else {
|
||||
err = hw_get_module(SENSORS_HARDWARE_MODULE_ID,
|
||||
(hw_module_t const **)&mSensorModule);
|
||||
}
|
||||
if (mSensorModule == NULL) {
|
||||
err = UNKNOWN_ERROR;
|
||||
}
|
||||
|
||||
if (err != OK) {
|
||||
LOG(ERROR) << "Couldn't load " << SENSORS_HARDWARE_MODULE_ID << " module ("
|
||||
<< strerror(-err) << ")";
|
||||
|
||||
mInitCheck = err;
|
||||
return;
|
||||
}
|
||||
|
||||
err = sensors_open_1(&mSensorModule->common, &mSensorDevice);
|
||||
|
||||
if (err != OK) {
|
||||
LOG(ERROR) << "Couldn't open device for module "
|
||||
<< SENSORS_HARDWARE_MODULE_ID << " (" << strerror(-err) << ")";
|
||||
|
||||
mInitCheck = err;
|
||||
return;
|
||||
}
|
||||
|
||||
// Require all the old HAL APIs to be present except for injection, which
|
||||
// is considered optional.
|
||||
CHECK_GE(getHalDeviceVersion(), SENSORS_DEVICE_API_VERSION_1_3);
|
||||
|
||||
if (getHalDeviceVersion() == SENSORS_DEVICE_API_VERSION_1_4) {
|
||||
if (mSensorDevice->inject_sensor_data == nullptr) {
|
||||
LOG(ERROR) << "HAL specifies version 1.4, but does not implement "
|
||||
"inject_sensor_data()";
|
||||
}
|
||||
if (mSensorModule->set_operation_mode == nullptr) {
|
||||
LOG(ERROR) << "HAL specifies version 1.4, but does not implement "
|
||||
"set_operation_mode()";
|
||||
}
|
||||
}
|
||||
|
||||
/* Get us all sensors */
|
||||
setOperationMode(static_cast<hardware::sensors::V1_0::OperationMode>(5555));
|
||||
|
||||
mInitCheck = OK;
|
||||
}
|
||||
|
||||
status_t Sensors::initCheck() const { return mInitCheck; }
|
||||
|
||||
Return<void> Sensors::getSensorsList(getSensorsList_cb _hidl_cb) {
|
||||
sensor_t const *list;
|
||||
size_t count = mSensorModule->get_sensors_list(mSensorModule, &list);
|
||||
|
||||
hidl_vec<SensorInfo> out;
|
||||
out.resize(count);
|
||||
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
const sensor_t *src = &list[i];
|
||||
SensorInfo *dst = &out[i];
|
||||
|
||||
convertFromSensor(*src, dst);
|
||||
|
||||
if (dst->requiredPermission == "com.samsung.permission.SSENSOR") {
|
||||
dst->requiredPermission = "";
|
||||
}
|
||||
|
||||
if (dst->typeAsString == "com.samsung.sensor.physical_proximity") {
|
||||
LOG(INFO) << "Fixing com.samsung.sensor.physical_proximity";
|
||||
dst->type = SensorType::PROXIMITY;
|
||||
dst->typeAsString = SENSOR_STRING_TYPE_PROXIMITY;
|
||||
dst->maxRange = 1;
|
||||
}
|
||||
|
||||
#ifdef VERBOSE
|
||||
LOG(INFO) << "SENSOR NAME: " << dst->name;
|
||||
LOG(INFO) << " VENDOR: " << dst->name;
|
||||
LOG(INFO) << " TYPE: " << (uint32_t)dst->type;
|
||||
LOG(INFO) << " TYPE_AS_STRING: " << dst->typeAsString;
|
||||
LOG(INFO) << " FLAGS: " << std::hex << dst->flags;
|
||||
LOG(INFO) << "";
|
||||
#endif
|
||||
}
|
||||
|
||||
_hidl_cb(out);
|
||||
|
||||
return Void();
|
||||
}
|
||||
|
||||
int Sensors::getHalDeviceVersion() const {
|
||||
if (!mSensorDevice) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return mSensorDevice->common.version;
|
||||
}
|
||||
|
||||
Return<Result> Sensors::setOperationMode(OperationMode mode) {
|
||||
if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_4 ||
|
||||
mSensorModule->set_operation_mode == nullptr) {
|
||||
return Result::INVALID_OPERATION;
|
||||
}
|
||||
return ResultFromStatus(mSensorModule->set_operation_mode((uint32_t)mode));
|
||||
}
|
||||
|
||||
Return<Result> Sensors::activate(int32_t sensor_handle, bool enabled) {
|
||||
return ResultFromStatus(mSensorDevice->activate(
|
||||
reinterpret_cast<sensors_poll_device_t *>(mSensorDevice), sensor_handle,
|
||||
enabled));
|
||||
}
|
||||
|
||||
Return<void> Sensors::poll(int32_t maxCount, poll_cb _hidl_cb) {
|
||||
hidl_vec<Event> out;
|
||||
hidl_vec<SensorInfo> dynamicSensorsAdded;
|
||||
|
||||
std::unique_ptr<sensors_event_t[]> data;
|
||||
int err = android::NO_ERROR;
|
||||
|
||||
{ // scope of reentry lock
|
||||
|
||||
// This enforces a single client, meaning that a maximum of one client can
|
||||
// call poll(). If this function is re-entred, it means that we are stuck in
|
||||
// a state that may prevent the system from proceeding normally.
|
||||
//
|
||||
// Exit and let the system restart the sensor-hal-implementation hidl
|
||||
// service.
|
||||
//
|
||||
// This function must not call _hidl_cb(...) or return until there is no
|
||||
// risk of blocking.
|
||||
std::unique_lock<std::mutex> lock(mPollLock, std::try_to_lock);
|
||||
if (!lock.owns_lock()) {
|
||||
// cannot get the lock, hidl service will go into deadlock if it is not
|
||||
// restarted. This is guaranteed to not trigger in passthrough mode.
|
||||
LOG(ERROR) << "ISensors::poll() re-entry. I do not know what to do "
|
||||
"except killing myself.";
|
||||
::exit(-1);
|
||||
}
|
||||
|
||||
if (maxCount <= 0) {
|
||||
err = android::BAD_VALUE;
|
||||
} else {
|
||||
int bufferSize =
|
||||
maxCount <= kPollMaxBufferSize ? maxCount : kPollMaxBufferSize;
|
||||
data.reset(new sensors_event_t[bufferSize]);
|
||||
err = mSensorDevice->poll(
|
||||
reinterpret_cast<sensors_poll_device_t *>(mSensorDevice), data.get(),
|
||||
bufferSize);
|
||||
}
|
||||
}
|
||||
|
||||
if (err < 0) {
|
||||
_hidl_cb(ResultFromStatus(err), out, dynamicSensorsAdded);
|
||||
return Void();
|
||||
}
|
||||
|
||||
const size_t count = (size_t)err;
|
||||
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
if (data[i].type != SENSOR_TYPE_DYNAMIC_SENSOR_META) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const dynamic_sensor_meta_event_t *dyn = &data[i].dynamic_sensor_meta;
|
||||
|
||||
if (!dyn->connected) {
|
||||
continue;
|
||||
}
|
||||
|
||||
CHECK(dyn->sensor != nullptr);
|
||||
CHECK_EQ(dyn->sensor->handle, dyn->handle);
|
||||
|
||||
SensorInfo info;
|
||||
convertFromSensor(*dyn->sensor, &info);
|
||||
|
||||
size_t numDynamicSensors = dynamicSensorsAdded.size();
|
||||
dynamicSensorsAdded.resize(numDynamicSensors + 1);
|
||||
dynamicSensorsAdded[numDynamicSensors] = info;
|
||||
}
|
||||
|
||||
out.resize(count);
|
||||
convertFromSensorEvents(err, data.get(), &out);
|
||||
|
||||
_hidl_cb(Result::OK, out, dynamicSensorsAdded);
|
||||
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<Result> Sensors::batch(int32_t sensor_handle, int64_t sampling_period_ns,
|
||||
int64_t max_report_latency_ns) {
|
||||
return ResultFromStatus(
|
||||
mSensorDevice->batch(mSensorDevice, sensor_handle, 0, /*flags*/
|
||||
sampling_period_ns, max_report_latency_ns));
|
||||
}
|
||||
|
||||
Return<Result> Sensors::flush(int32_t sensor_handle) {
|
||||
return ResultFromStatus(mSensorDevice->flush(mSensorDevice, sensor_handle));
|
||||
}
|
||||
|
||||
Return<Result> Sensors::injectSensorData(const Event &event) {
|
||||
if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_4 ||
|
||||
mSensorDevice->inject_sensor_data == nullptr) {
|
||||
return Result::INVALID_OPERATION;
|
||||
}
|
||||
|
||||
sensors_event_t out;
|
||||
convertToSensorEvent(event, &out);
|
||||
|
||||
return ResultFromStatus(
|
||||
mSensorDevice->inject_sensor_data(mSensorDevice, &out));
|
||||
}
|
||||
|
||||
Return<void> Sensors::registerDirectChannel(const SharedMemInfo &mem,
|
||||
registerDirectChannel_cb _hidl_cb) {
|
||||
if (mSensorDevice->register_direct_channel == nullptr ||
|
||||
mSensorDevice->config_direct_report == nullptr) {
|
||||
// HAL does not support
|
||||
_hidl_cb(Result::INVALID_OPERATION, -1);
|
||||
return Void();
|
||||
}
|
||||
|
||||
sensors_direct_mem_t m;
|
||||
if (!convertFromSharedMemInfo(mem, &m)) {
|
||||
_hidl_cb(Result::BAD_VALUE, -1);
|
||||
return Void();
|
||||
}
|
||||
|
||||
int err = mSensorDevice->register_direct_channel(mSensorDevice, &m, -1);
|
||||
|
||||
if (err < 0) {
|
||||
_hidl_cb(ResultFromStatus(err), -1);
|
||||
} else {
|
||||
int32_t channelHandle = static_cast<int32_t>(err);
|
||||
_hidl_cb(Result::OK, channelHandle);
|
||||
}
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<Result> Sensors::unregisterDirectChannel(int32_t channelHandle) {
|
||||
if (mSensorDevice->register_direct_channel == nullptr ||
|
||||
mSensorDevice->config_direct_report == nullptr) {
|
||||
// HAL does not support
|
||||
return Result::INVALID_OPERATION;
|
||||
}
|
||||
|
||||
mSensorDevice->register_direct_channel(mSensorDevice, nullptr, channelHandle);
|
||||
|
||||
return Result::OK;
|
||||
}
|
||||
|
||||
Return<void> Sensors::configDirectReport(int32_t sensorHandle,
|
||||
int32_t channelHandle, RateLevel rate,
|
||||
configDirectReport_cb _hidl_cb) {
|
||||
if (mSensorDevice->register_direct_channel == nullptr ||
|
||||
mSensorDevice->config_direct_report == nullptr) {
|
||||
// HAL does not support
|
||||
_hidl_cb(Result::INVALID_OPERATION, -1);
|
||||
return Void();
|
||||
}
|
||||
|
||||
sensors_direct_cfg_t cfg = {.rate_level = convertFromRateLevel(rate)};
|
||||
if (cfg.rate_level < 0) {
|
||||
_hidl_cb(Result::BAD_VALUE, -1);
|
||||
return Void();
|
||||
}
|
||||
|
||||
int err = mSensorDevice->config_direct_report(mSensorDevice, sensorHandle,
|
||||
channelHandle, &cfg);
|
||||
|
||||
if (rate == RateLevel::STOP) {
|
||||
_hidl_cb(ResultFromStatus(err), -1);
|
||||
} else {
|
||||
_hidl_cb(err > 0 ? Result::OK : ResultFromStatus(err), err);
|
||||
}
|
||||
return Void();
|
||||
}
|
||||
|
||||
// static
|
||||
void Sensors::convertFromSensorEvents(size_t count,
|
||||
const sensors_event_t *srcArray,
|
||||
hidl_vec<Event> *dstVec) {
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
const sensors_event_t &src = srcArray[i];
|
||||
Event *dst = &(*dstVec)[i];
|
||||
|
||||
convertFromSensorEvent(src, dst);
|
||||
}
|
||||
}
|
||||
|
||||
ISensors *HIDL_FETCH_ISensors(const char * /* hal */) {
|
||||
Sensors *sensors = new Sensors;
|
||||
if (sensors->initCheck() != OK) {
|
||||
delete sensors;
|
||||
sensors = nullptr;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return sensors;
|
||||
}
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V1_0
|
||||
} // namespace sensors
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
85
universal7885-common/bin/hardware/samsung/sensors/Sensors.h
Normal file
85
universal7885-common/bin/hardware/samsung/sensors/Sensors.h
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef HARDWARE_INTERFACES_SENSORS_V1_0_SAMSUNG_SENSORS_H_
|
||||
|
||||
#define HARDWARE_INTERFACES_SENSORS_V1_0_SAMSUNG_SENSORS_H_
|
||||
|
||||
#include <android-base/macros.h>
|
||||
#include <android/hardware/sensors/1.0/ISensors.h>
|
||||
#include <hardware/sensors.h>
|
||||
#include <mutex>
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace sensors {
|
||||
namespace V1_0 {
|
||||
namespace implementation {
|
||||
|
||||
struct Sensors : public ::android::hardware::sensors::V1_0::ISensors {
|
||||
Sensors();
|
||||
|
||||
status_t initCheck() const;
|
||||
|
||||
Return<void> getSensorsList(getSensorsList_cb _hidl_cb) override;
|
||||
|
||||
Return<Result> setOperationMode(OperationMode mode) override;
|
||||
|
||||
Return<Result> activate(int32_t sensor_handle, bool enabled) override;
|
||||
|
||||
Return<void> poll(int32_t maxCount, poll_cb _hidl_cb) override;
|
||||
|
||||
Return<Result> batch(int32_t sensor_handle, int64_t sampling_period_ns,
|
||||
int64_t max_report_latency_ns) override;
|
||||
|
||||
Return<Result> flush(int32_t sensor_handle) override;
|
||||
|
||||
Return<Result> injectSensorData(const Event &event) override;
|
||||
|
||||
Return<void>
|
||||
registerDirectChannel(const SharedMemInfo &mem,
|
||||
registerDirectChannel_cb _hidl_cb) override;
|
||||
|
||||
Return<Result> unregisterDirectChannel(int32_t channelHandle) override;
|
||||
|
||||
Return<void> configDirectReport(int32_t sensorHandle, int32_t channelHandle,
|
||||
RateLevel rate,
|
||||
configDirectReport_cb _hidl_cb) override;
|
||||
|
||||
private:
|
||||
static constexpr int32_t kPollMaxBufferSize = 128;
|
||||
status_t mInitCheck;
|
||||
sensors_module_t *mSensorModule;
|
||||
sensors_poll_device_1_t *mSensorDevice;
|
||||
std::mutex mPollLock;
|
||||
|
||||
int getHalDeviceVersion() const;
|
||||
|
||||
static void convertFromSensorEvents(size_t count, const sensors_event_t *src,
|
||||
hidl_vec<Event> *dst);
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Sensors);
|
||||
};
|
||||
|
||||
extern "C" ISensors *HIDL_FETCH_ISensors(const char *name);
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V1_0
|
||||
} // namespace sensors
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
|
||||
#endif // HARDWARE_INTERFACES_SENSORS_V1_0_SAMSUNG_SENSORS_H_
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
//
|
||||
// Copyright (C) 2017-2018,2020 The LineageOS Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
cc_binary {
|
||||
name: "android.hardware.usb@1.0-service.a10",
|
||||
relative_install_path: "hw",
|
||||
init_rc: ["android.hardware.usb@1.0-service.a10.rc"],
|
||||
vintf_fragments: ["android.hardware.usb@1.0-service.a10.xml"],
|
||||
srcs: ["service.cpp", "Usb.cpp"],
|
||||
shared_libs: [
|
||||
"libbase",
|
||||
"libcutils",
|
||||
"libhidlbase",
|
||||
"libutils",
|
||||
"libhardware",
|
||||
"android.hardware.usb@1.0",
|
||||
],
|
||||
proprietary: true,
|
||||
}
|
||||
81
universal7885-common/bin/hardware/samsung/usb/typeb/Usb.cpp
Normal file
81
universal7885-common/bin/hardware/samsung/usb/typeb/Usb.cpp
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Copyright (C) 2017-2018 The LineageOS Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <utils/Errors.h>
|
||||
#include <utils/StrongPointer.h>
|
||||
|
||||
#include "Usb.h"
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace usb {
|
||||
namespace V1_0 {
|
||||
namespace implementation {
|
||||
|
||||
Return<void> Usb::switchRole(const hidl_string &portName __unused,
|
||||
const PortRole &newRole __unused) {
|
||||
LOG(ERROR) << __func__ << ": Not supported";
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<void> Usb::queryPortStatus() {
|
||||
hidl_vec<PortStatus> currentPortStatus;
|
||||
currentPortStatus.resize(1);
|
||||
|
||||
currentPortStatus[0].portName = "otg_default";
|
||||
currentPortStatus[0].currentDataRole = PortDataRole::DEVICE;
|
||||
currentPortStatus[0].currentPowerRole = PortPowerRole::SINK;
|
||||
currentPortStatus[0].currentMode = PortMode::UFP;
|
||||
currentPortStatus[0].canChangeMode = false;
|
||||
currentPortStatus[0].canChangeDataRole = false;
|
||||
currentPortStatus[0].canChangePowerRole = false;
|
||||
currentPortStatus[0].supportedModes = PortMode::UFP;
|
||||
|
||||
pthread_mutex_lock(&mLock);
|
||||
if (mCallback != NULL) {
|
||||
Return<void> ret =
|
||||
mCallback->notifyPortStatusChange(currentPortStatus, Status::SUCCESS);
|
||||
if (!ret.isOk()) {
|
||||
LOG(ERROR) << "queryPortStatus error " << ret.description();
|
||||
}
|
||||
} else {
|
||||
LOG(INFO) << "Notifying userspace skipped. Callback is NULL";
|
||||
}
|
||||
pthread_mutex_unlock(&mLock);
|
||||
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<void> Usb::setCallback(const sp<IUsbCallback> &callback) {
|
||||
pthread_mutex_lock(&mLock);
|
||||
|
||||
mCallback = callback;
|
||||
LOG(INFO) << "registering callback";
|
||||
|
||||
pthread_mutex_unlock(&mLock);
|
||||
return Void();
|
||||
}
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V1_0
|
||||
} // namespace usb
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
66
universal7885-common/bin/hardware/samsung/usb/typeb/Usb.h
Normal file
66
universal7885-common/bin/hardware/samsung/usb/typeb/Usb.h
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* Copyright (C) 2017-2018 The LineageOS Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_HARDWARE_USB_V1_0_USB_H
|
||||
#define ANDROID_HARDWARE_USB_V1_0_USB_H
|
||||
|
||||
#include <android/hardware/usb/1.0/IUsb.h>
|
||||
#include <hidl/MQDescriptor.h>
|
||||
#include <hidl/Status.h>
|
||||
#include <utils/Log.h>
|
||||
|
||||
#ifdef LOG_TAG
|
||||
#undef LOG_TAG
|
||||
#endif
|
||||
|
||||
#define LOG_TAG "android.hardware.usb@1.0-service-a10"
|
||||
#define UEVENT_MSG_LEN 2048
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace usb {
|
||||
namespace V1_0 {
|
||||
namespace implementation {
|
||||
|
||||
using ::android::sp;
|
||||
using ::android::hardware::hidl_array;
|
||||
using ::android::hardware::hidl_memory;
|
||||
using ::android::hardware::hidl_string;
|
||||
using ::android::hardware::hidl_vec;
|
||||
using ::android::hardware::Return;
|
||||
using ::android::hardware::Void;
|
||||
using ::android::hardware::usb::V1_0::IUsb;
|
||||
using ::android::hardware::usb::V1_0::IUsbCallback;
|
||||
using ::android::hardware::usb::V1_0::PortRole;
|
||||
using ::android::hidl::base::V1_0::IBase;
|
||||
|
||||
struct Usb : public IUsb {
|
||||
Return<void> switchRole(const hidl_string &portName,
|
||||
const PortRole &role) override;
|
||||
Return<void> setCallback(const sp<IUsbCallback> &callback) override;
|
||||
Return<void> queryPortStatus() override;
|
||||
|
||||
sp<IUsbCallback> mCallback;
|
||||
pthread_mutex_t mLock = PTHREAD_MUTEX_INITIALIZER;
|
||||
};
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V1_0
|
||||
} // namespace usb
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
|
||||
#endif // ANDROID_HARDWARE_USB_V1_0_USB_H
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
service vendor.usb-hal-1-0 /vendor/bin/hw/android.hardware.usb@1.0-service.a10
|
||||
interface android.hardware.usb@1.0::IUsb default
|
||||
class hal
|
||||
user system
|
||||
group system
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0"?>
|
||||
<manifest version="1.0" type="device">
|
||||
<hal format="hidl" override="true">
|
||||
<name>android.hardware.usb</name>
|
||||
<transport>hwbinder</transport>
|
||||
<version>1.0</version>
|
||||
<interface>
|
||||
<name>IUsb</name>
|
||||
<instance>default</instance>
|
||||
</interface>
|
||||
</hal>
|
||||
</manifest>
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (C) 2017-2018 The LineageOS Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "Usb.h"
|
||||
#include <android-base/logging.h>
|
||||
#include <hidl/HidlTransportSupport.h>
|
||||
|
||||
using android::sp;
|
||||
|
||||
// libhwbinder:
|
||||
using android::hardware::configureRpcThreadpool;
|
||||
using android::hardware::joinRpcThreadpool;
|
||||
|
||||
// Generated HIDL files
|
||||
using android::hardware::usb::V1_0::IUsb;
|
||||
using android::hardware::usb::V1_0::implementation::Usb;
|
||||
|
||||
int main() {
|
||||
android::sp<IUsb> service = new Usb();
|
||||
|
||||
configureRpcThreadpool(1, true /*callerWillJoin*/);
|
||||
android::status_t status = service->registerAsService();
|
||||
|
||||
if (status != android::OK) {
|
||||
LOG(ERROR) << "Cannot register USB HAL service";
|
||||
return 1;
|
||||
}
|
||||
|
||||
LOG(INFO) << "USB HAL Ready.";
|
||||
joinRpcThreadpool();
|
||||
// Under normal cases, execution will not reach this line.
|
||||
LOG(ERROR) << "USB HAL failed to join thread pool.";
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
//
|
||||
// Copyright (C) 2017 The Android Open Source Project
|
||||
// Copyright (C) 2022 The LineageOS Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
cc_binary {
|
||||
name: "android.hardware.usb@1.3-service.samsung",
|
||||
relative_install_path: "hw",
|
||||
init_rc: ["android.hardware.usb@1.3-service.samsung.rc"],
|
||||
vintf_fragments: [
|
||||
"android.hardware.usb@1.3-service.samsung.xml",
|
||||
],
|
||||
srcs: ["service.cpp", "Usb.cpp"],
|
||||
cflags: ["-Wall", "-Werror"],
|
||||
shared_libs: [
|
||||
"libbase",
|
||||
"libbinder",
|
||||
"libhidlbase",
|
||||
"liblog",
|
||||
"libutils",
|
||||
"libhardware",
|
||||
"android.hardware.usb@1.0",
|
||||
"android.hardware.usb@1.1",
|
||||
"android.hardware.usb@1.2",
|
||||
"android.hardware.usb@1.3",
|
||||
"libcutils",
|
||||
"libbinder_ndk",
|
||||
],
|
||||
proprietary: true,
|
||||
}
|
||||
845
universal7885-common/bin/hardware/samsung/usb/typec/Usb.cpp
Normal file
845
universal7885-common/bin/hardware/samsung/usb/typec/Usb.cpp
Normal file
|
|
@ -0,0 +1,845 @@
|
|||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
* Copyright (C) 2022 The LineageOS Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "android.hardware.usb@1.3-service.samsung"
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <android-base/properties.h>
|
||||
#include <assert.h>
|
||||
#include <chrono>
|
||||
#include <dirent.h>
|
||||
#include <pthread.h>
|
||||
#include <regex>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <thread>
|
||||
#include <unistd.h>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <cutils/uevent.h>
|
||||
#include <sys/epoll.h>
|
||||
#include <utils/Errors.h>
|
||||
#include <utils/StrongPointer.h>
|
||||
|
||||
#include "Usb.h"
|
||||
|
||||
using android::base::GetProperty;
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace usb {
|
||||
namespace V1_3 {
|
||||
namespace implementation {
|
||||
|
||||
Return<bool> Usb::enableUsbDataSignal(bool enable) {
|
||||
bool result = true;
|
||||
|
||||
ALOGI("Userspace turn %s USB data signaling", enable ? "on" : "off");
|
||||
|
||||
if (enable) {
|
||||
if (!WriteStringToFile("1", USB_DATA_PATH)) {
|
||||
ALOGE("Not able to turn on usb connection notification");
|
||||
result = false;
|
||||
}
|
||||
} else {
|
||||
if (!WriteStringToFile("0", USB_DATA_PATH)) {
|
||||
ALOGE("Not able to turn off usb connection notification");
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Set by the signal handler to destroy the thread
|
||||
volatile bool destroyThread;
|
||||
|
||||
bool moistureDetectionEnabled = true;
|
||||
constexpr char kContaminantDetectionPath[] =
|
||||
"/sys/devices/virtual/sec/ccic/water";
|
||||
constexpr char kTypecPath[] = "/sys/class/typec";
|
||||
constexpr char kDisableContaminantDetection[] = "vendor.usb.contaminantdisable";
|
||||
|
||||
int32_t readFile(const std::string &filename, std::string *contents) {
|
||||
FILE *fp;
|
||||
ssize_t read = 0;
|
||||
char *line = NULL;
|
||||
size_t len = 0;
|
||||
|
||||
fp = fopen(filename.c_str(), "r");
|
||||
if (fp != NULL) {
|
||||
if ((read = getline(&line, &len, fp)) != -1) {
|
||||
char *pos;
|
||||
if ((pos = strchr(line, '\n')) != NULL)
|
||||
*pos = '\0';
|
||||
*contents = line;
|
||||
}
|
||||
free(line);
|
||||
fclose(fp);
|
||||
return 0;
|
||||
} else {
|
||||
ALOGE("fopen failed");
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32_t writeFile(const std::string &filename, const std::string &contents) {
|
||||
FILE *fp;
|
||||
std::string written;
|
||||
|
||||
fp = fopen(filename.c_str(), "w");
|
||||
if (fp != NULL) {
|
||||
// FAILURE RETRY
|
||||
int ret = fputs(contents.c_str(), fp);
|
||||
fclose(fp);
|
||||
if ((ret != EOF) && !readFile(filename, &written) && written == contents)
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
Status
|
||||
queryMoistureDetectionStatus(hidl_vec<PortStatus> *currentPortStatus_1_2) {
|
||||
std::string enabled, status, path, DetectedPath;
|
||||
|
||||
if (currentPortStatus_1_2 == NULL || currentPortStatus_1_2->size() == 0) {
|
||||
ALOGE("currentPortStatus_1_2 is not available");
|
||||
return Status::ERROR;
|
||||
}
|
||||
|
||||
(*currentPortStatus_1_2)[0].supportedContaminantProtectionModes = 0;
|
||||
(*currentPortStatus_1_2)[0].supportedContaminantProtectionModes |=
|
||||
V1_2::ContaminantProtectionMode::FORCE_SINK;
|
||||
(*currentPortStatus_1_2)[0].contaminantProtectionStatus =
|
||||
V1_2::ContaminantProtectionStatus::NONE;
|
||||
(*currentPortStatus_1_2)[0].contaminantDetectionStatus =
|
||||
V1_2::ContaminantDetectionStatus::DISABLED;
|
||||
(*currentPortStatus_1_2)[0].supportsEnableContaminantPresenceDetection = true;
|
||||
(*currentPortStatus_1_2)[0].supportsEnableContaminantPresenceProtection =
|
||||
false;
|
||||
|
||||
if (moistureDetectionEnabled) {
|
||||
if (readFile(kContaminantDetectionPath, &status)) {
|
||||
ALOGE("Failed to open moisture_detected");
|
||||
return Status::ERROR;
|
||||
}
|
||||
if (status == "1") {
|
||||
(*currentPortStatus_1_2)[0].contaminantDetectionStatus =
|
||||
V1_2::ContaminantDetectionStatus::DETECTED;
|
||||
(*currentPortStatus_1_2)[0].contaminantProtectionStatus =
|
||||
V1_2::ContaminantProtectionStatus::FORCE_SINK;
|
||||
} else
|
||||
(*currentPortStatus_1_2)[0].contaminantDetectionStatus =
|
||||
V1_2::ContaminantDetectionStatus::NOT_DETECTED;
|
||||
}
|
||||
|
||||
ALOGI("ContaminantDetectionStatus:%d ContaminantProtectionStatus:%d",
|
||||
(*currentPortStatus_1_2)[0].contaminantDetectionStatus,
|
||||
(*currentPortStatus_1_2)[0].contaminantProtectionStatus);
|
||||
|
||||
return Status::SUCCESS;
|
||||
}
|
||||
|
||||
std::string appendRoleNodeHelper(const std::string &portName,
|
||||
PortRoleType type) {
|
||||
std::string node("/sys/class/typec/" + portName);
|
||||
|
||||
switch (type) {
|
||||
case PortRoleType::DATA_ROLE:
|
||||
return node + "/data_role";
|
||||
case PortRoleType::POWER_ROLE:
|
||||
return node + "/power_role";
|
||||
case PortRoleType::MODE:
|
||||
return node + "/port_type";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
std::string convertRoletoString(PortRole role) {
|
||||
if (role.type == PortRoleType::POWER_ROLE) {
|
||||
if (role.role == static_cast<uint32_t>(PortPowerRole::SOURCE))
|
||||
return "source";
|
||||
else if (role.role == static_cast<uint32_t>(PortPowerRole::SINK))
|
||||
return "sink";
|
||||
} else if (role.type == PortRoleType::DATA_ROLE) {
|
||||
if (role.role == static_cast<uint32_t>(PortDataRole::HOST))
|
||||
return "host";
|
||||
if (role.role == static_cast<uint32_t>(PortDataRole::DEVICE))
|
||||
return "device";
|
||||
} else if (role.type == PortRoleType::MODE) {
|
||||
if (role.role == static_cast<uint32_t>(PortMode_1_1::UFP))
|
||||
return "sink";
|
||||
if (role.role == static_cast<uint32_t>(PortMode_1_1::DFP))
|
||||
return "source";
|
||||
}
|
||||
return "none";
|
||||
}
|
||||
|
||||
void extractRole(std::string *roleName) {
|
||||
std::size_t first, last;
|
||||
|
||||
first = roleName->find("[");
|
||||
last = roleName->find("]");
|
||||
|
||||
if (first != std::string::npos && last != std::string::npos) {
|
||||
*roleName = roleName->substr(first + 1, last - first - 1);
|
||||
}
|
||||
}
|
||||
|
||||
void switchToDrp(const std::string &portName) {
|
||||
std::string filename =
|
||||
appendRoleNodeHelper(std::string(portName.c_str()), PortRoleType::MODE);
|
||||
FILE *fp;
|
||||
|
||||
if (filename != "") {
|
||||
fp = fopen(filename.c_str(), "w");
|
||||
if (fp != NULL) {
|
||||
int ret = fputs("dual", fp);
|
||||
fclose(fp);
|
||||
if (ret == EOF)
|
||||
ALOGE("Fatal: Error while switching back to drp");
|
||||
} else {
|
||||
ALOGE("Fatal: Cannot open file to switch back to drp");
|
||||
}
|
||||
} else {
|
||||
ALOGE("Fatal: invalid node type");
|
||||
}
|
||||
}
|
||||
|
||||
bool switchMode(const hidl_string &portName, const PortRole &newRole,
|
||||
struct Usb *usb) {
|
||||
std::string filename =
|
||||
appendRoleNodeHelper(std::string(portName.c_str()), newRole.type);
|
||||
std::string written;
|
||||
FILE *fp;
|
||||
bool roleSwitch = false;
|
||||
|
||||
if (filename == "") {
|
||||
ALOGE("Fatal: invalid node type");
|
||||
return false;
|
||||
}
|
||||
|
||||
fp = fopen(filename.c_str(), "w");
|
||||
if (fp != NULL) {
|
||||
// Hold the lock here to prevent loosing connected signals
|
||||
// as once the file is written the partner added signal
|
||||
// can arrive anytime.
|
||||
pthread_mutex_lock(&usb->mPartnerLock);
|
||||
usb->mPartnerUp = false;
|
||||
int ret = fputs(convertRoletoString(newRole).c_str(), fp);
|
||||
fclose(fp);
|
||||
|
||||
if (ret != EOF) {
|
||||
struct timespec to;
|
||||
struct timespec now;
|
||||
|
||||
wait_again:
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
to.tv_sec = now.tv_sec + PORT_TYPE_TIMEOUT;
|
||||
to.tv_nsec = now.tv_nsec;
|
||||
|
||||
int err =
|
||||
pthread_cond_timedwait(&usb->mPartnerCV, &usb->mPartnerLock, &to);
|
||||
// There are no uevent signals which implies role swap timed out.
|
||||
if (err == ETIMEDOUT) {
|
||||
ALOGI("uevents wait timedout");
|
||||
// Validity check.
|
||||
} else if (!usb->mPartnerUp) {
|
||||
goto wait_again;
|
||||
// Role switch succeeded since usb->mPartnerUp is true.
|
||||
} else {
|
||||
roleSwitch = true;
|
||||
}
|
||||
} else {
|
||||
ALOGI("Role switch failed while wrting to file");
|
||||
}
|
||||
pthread_mutex_unlock(&usb->mPartnerLock);
|
||||
}
|
||||
|
||||
if (!roleSwitch)
|
||||
switchToDrp(std::string(portName.c_str()));
|
||||
|
||||
return roleSwitch;
|
||||
}
|
||||
|
||||
Usb::Usb()
|
||||
: mLock(PTHREAD_MUTEX_INITIALIZER),
|
||||
mRoleSwitchLock(PTHREAD_MUTEX_INITIALIZER),
|
||||
mPartnerLock(PTHREAD_MUTEX_INITIALIZER), mPartnerUp(false) {
|
||||
pthread_condattr_t attr;
|
||||
if (pthread_condattr_init(&attr)) {
|
||||
ALOGE("pthread_condattr_init failed: %s", strerror(errno));
|
||||
abort();
|
||||
}
|
||||
if (pthread_condattr_setclock(&attr, CLOCK_MONOTONIC)) {
|
||||
ALOGE("pthread_condattr_setclock failed: %s", strerror(errno));
|
||||
abort();
|
||||
}
|
||||
if (pthread_cond_init(&mPartnerCV, &attr)) {
|
||||
ALOGE("pthread_cond_init failed: %s", strerror(errno));
|
||||
abort();
|
||||
}
|
||||
if (pthread_condattr_destroy(&attr)) {
|
||||
ALOGE("pthread_condattr_destroy failed: %s", strerror(errno));
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
Return<void> Usb::switchRole(const hidl_string &portName,
|
||||
const V1_0::PortRole &newRole) {
|
||||
std::string filename =
|
||||
appendRoleNodeHelper(std::string(portName.c_str()), newRole.type);
|
||||
std::string written;
|
||||
FILE *fp;
|
||||
bool roleSwitch = false;
|
||||
|
||||
if (filename == "") {
|
||||
ALOGE("Fatal: invalid node type");
|
||||
return Void();
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&mRoleSwitchLock);
|
||||
|
||||
ALOGI("filename write: %s role:%s", filename.c_str(),
|
||||
convertRoletoString(newRole).c_str());
|
||||
|
||||
if (newRole.type == PortRoleType::MODE) {
|
||||
roleSwitch = switchMode(portName, newRole, this);
|
||||
} else {
|
||||
fp = fopen(filename.c_str(), "w");
|
||||
if (fp != NULL) {
|
||||
int ret = fputs(convertRoletoString(newRole).c_str(), fp);
|
||||
fclose(fp);
|
||||
if ((ret != EOF) && !readFile(filename, &written)) {
|
||||
extractRole(&written);
|
||||
ALOGI("written: %s", written.c_str());
|
||||
if (written == convertRoletoString(newRole)) {
|
||||
roleSwitch = true;
|
||||
} else {
|
||||
ALOGE("Role switch failed");
|
||||
}
|
||||
} else {
|
||||
ALOGE("failed to update the new role");
|
||||
}
|
||||
} else {
|
||||
ALOGE("fopen failed");
|
||||
}
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&mLock);
|
||||
if (mCallback_1_0 != NULL) {
|
||||
Return<void> ret = mCallback_1_0->notifyRoleSwitchStatus(
|
||||
portName, newRole, roleSwitch ? Status::SUCCESS : Status::ERROR);
|
||||
if (!ret.isOk())
|
||||
ALOGE("RoleSwitchStatus error %s", ret.description().c_str());
|
||||
} else {
|
||||
ALOGE("Not notifying the userspace. Callback is not set");
|
||||
}
|
||||
pthread_mutex_unlock(&mLock);
|
||||
pthread_mutex_unlock(&mRoleSwitchLock);
|
||||
|
||||
return Void();
|
||||
}
|
||||
|
||||
Status getAccessoryConnected(const std::string &portName,
|
||||
std::string *accessory) {
|
||||
std::string filename =
|
||||
"/sys/class/typec/" + portName + "-partner/accessory_mode";
|
||||
|
||||
if (readFile(filename, accessory)) {
|
||||
ALOGE("getAccessoryConnected: Failed to open filesystem node: %s",
|
||||
filename.c_str());
|
||||
return Status::ERROR;
|
||||
}
|
||||
|
||||
return Status::SUCCESS;
|
||||
}
|
||||
|
||||
Status getCurrentRoleHelper(const std::string &portName, bool connected,
|
||||
PortRoleType type, uint32_t *currentRole) {
|
||||
std::string filename;
|
||||
std::string roleName;
|
||||
std::string accessory;
|
||||
|
||||
// Mode
|
||||
|
||||
if (type == PortRoleType::POWER_ROLE) {
|
||||
filename = "/sys/class/typec/" + portName + "/power_role";
|
||||
*currentRole = static_cast<uint32_t>(PortPowerRole::NONE);
|
||||
} else if (type == PortRoleType::DATA_ROLE) {
|
||||
filename = "/sys/class/typec/" + portName + "/data_role";
|
||||
*currentRole = static_cast<uint32_t>(PortDataRole::NONE);
|
||||
} else if (type == PortRoleType::MODE) {
|
||||
filename = "/sys/class/typec/" + portName + "/data_role";
|
||||
*currentRole = static_cast<uint32_t>(PortMode_1_1::NONE);
|
||||
} else {
|
||||
return Status::ERROR;
|
||||
}
|
||||
|
||||
if (!connected)
|
||||
return Status::SUCCESS;
|
||||
|
||||
if (type == PortRoleType::MODE) {
|
||||
if (getAccessoryConnected(portName, &accessory) != Status::SUCCESS) {
|
||||
return Status::ERROR;
|
||||
}
|
||||
if (accessory == "analog_audio") {
|
||||
*currentRole = static_cast<uint32_t>(PortMode_1_1::AUDIO_ACCESSORY);
|
||||
return Status::SUCCESS;
|
||||
} else if (accessory == "debug") {
|
||||
*currentRole = static_cast<uint32_t>(PortMode_1_1::DEBUG_ACCESSORY);
|
||||
return Status::SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
if (readFile(filename, &roleName)) {
|
||||
ALOGE("getCurrentRole: Failed to open filesystem node: %s",
|
||||
filename.c_str());
|
||||
return Status::ERROR;
|
||||
}
|
||||
|
||||
extractRole(&roleName);
|
||||
|
||||
if (roleName == "source") {
|
||||
*currentRole = static_cast<uint32_t>(PortPowerRole::SOURCE);
|
||||
} else if (roleName == "sink") {
|
||||
*currentRole = static_cast<uint32_t>(PortPowerRole::SINK);
|
||||
} else if (roleName == "host") {
|
||||
if (type == PortRoleType::DATA_ROLE)
|
||||
*currentRole = static_cast<uint32_t>(PortDataRole::HOST);
|
||||
else
|
||||
*currentRole = static_cast<uint32_t>(PortMode_1_1::DFP);
|
||||
} else if (roleName == "device") {
|
||||
if (type == PortRoleType::DATA_ROLE)
|
||||
*currentRole = static_cast<uint32_t>(PortDataRole::DEVICE);
|
||||
else
|
||||
*currentRole = static_cast<uint32_t>(PortMode_1_1::UFP);
|
||||
} else if (roleName != "none") {
|
||||
/* case for none has already been addressed.
|
||||
* so we check if the role isn't none.
|
||||
*/
|
||||
return Status::UNRECOGNIZED_ROLE;
|
||||
}
|
||||
|
||||
return Status::SUCCESS;
|
||||
}
|
||||
|
||||
Status getTypeCPortNamesHelper(std::unordered_map<std::string, bool> *names) {
|
||||
DIR *dp;
|
||||
|
||||
dp = opendir(kTypecPath);
|
||||
if (dp != NULL) {
|
||||
struct dirent *ep;
|
||||
|
||||
while ((ep = readdir(dp))) {
|
||||
if (ep->d_type == DT_LNK) {
|
||||
if (std::string::npos == std::string(ep->d_name).find("-partner")) {
|
||||
std::unordered_map<std::string, bool>::const_iterator portName =
|
||||
names->find(ep->d_name);
|
||||
if (portName == names->end()) {
|
||||
names->insert({ep->d_name, false});
|
||||
}
|
||||
} else {
|
||||
(*names)[std::strtok(ep->d_name, "-")] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir(dp);
|
||||
return Status::SUCCESS;
|
||||
}
|
||||
|
||||
ALOGE("Failed to open /sys/class/typec");
|
||||
return Status::ERROR;
|
||||
}
|
||||
|
||||
bool canSwitchRoleHelper(const std::string &portName, PortRoleType /*type*/) {
|
||||
std::string filename =
|
||||
"/sys/class/typec/" + portName + "-partner/supports_usb_power_delivery";
|
||||
std::string supportsPD;
|
||||
|
||||
if (!readFile(filename, &supportsPD)) {
|
||||
if (supportsPD == "yes") {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reuse the same method for both V1_0 and V1_1 callback objects.
|
||||
* The caller of this method would reconstruct the V1_0::PortStatus
|
||||
* object if required.
|
||||
*/
|
||||
Status getPortStatusHelper(hidl_vec<PortStatus> *currentPortStatus_1_2,
|
||||
HALVersion version) {
|
||||
std::unordered_map<std::string, bool> names;
|
||||
Status result = getTypeCPortNamesHelper(&names);
|
||||
int i = -1;
|
||||
|
||||
if (result == Status::SUCCESS) {
|
||||
currentPortStatus_1_2->resize(names.size());
|
||||
for (std::pair<std::string, bool> port : names) {
|
||||
i++;
|
||||
ALOGI("%s", port.first.c_str());
|
||||
(*currentPortStatus_1_2)[i].status_1_1.status.portName = port.first;
|
||||
|
||||
uint32_t currentRole;
|
||||
if (getCurrentRoleHelper(port.first, port.second,
|
||||
PortRoleType::POWER_ROLE,
|
||||
¤tRole) == Status::SUCCESS) {
|
||||
(*currentPortStatus_1_2)[i].status_1_1.status.currentPowerRole =
|
||||
static_cast<PortPowerRole>(currentRole);
|
||||
} else {
|
||||
ALOGE("Error while retrieving portNames");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (getCurrentRoleHelper(port.first, port.second, PortRoleType::DATA_ROLE,
|
||||
¤tRole) == Status::SUCCESS) {
|
||||
(*currentPortStatus_1_2)[i].status_1_1.status.currentDataRole =
|
||||
static_cast<PortDataRole>(currentRole);
|
||||
} else {
|
||||
ALOGE("Error while retrieving current port role");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (getCurrentRoleHelper(port.first, port.second, PortRoleType::MODE,
|
||||
¤tRole) == Status::SUCCESS) {
|
||||
(*currentPortStatus_1_2)[i].status_1_1.currentMode =
|
||||
static_cast<PortMode_1_1>(currentRole);
|
||||
(*currentPortStatus_1_2)[i].status_1_1.status.currentMode =
|
||||
static_cast<V1_0::PortMode>(currentRole);
|
||||
} else {
|
||||
ALOGE("Error while retrieving current data role");
|
||||
goto done;
|
||||
}
|
||||
|
||||
(*currentPortStatus_1_2)[i].status_1_1.status.canChangeMode = true;
|
||||
(*currentPortStatus_1_2)[i].status_1_1.status.canChangeDataRole =
|
||||
port.second ? canSwitchRoleHelper(port.first, PortRoleType::DATA_ROLE)
|
||||
: false;
|
||||
(*currentPortStatus_1_2)[i].status_1_1.status.canChangePowerRole =
|
||||
port.second
|
||||
? canSwitchRoleHelper(port.first, PortRoleType::POWER_ROLE)
|
||||
: false;
|
||||
|
||||
if (version == HALVersion::V1_0) {
|
||||
ALOGI("HAL version V1_0");
|
||||
(*currentPortStatus_1_2)[i].status_1_1.status.supportedModes =
|
||||
V1_0::PortMode::DRP;
|
||||
} else {
|
||||
if (version == HALVersion::V1_1)
|
||||
ALOGI("HAL version V1_1");
|
||||
else
|
||||
ALOGI("HAL version V1_2");
|
||||
(*currentPortStatus_1_2)[i].status_1_1.supportedModes =
|
||||
0 | PortMode_1_1::DRP;
|
||||
(*currentPortStatus_1_2)[i].status_1_1.status.supportedModes =
|
||||
V1_0::PortMode::NONE;
|
||||
(*currentPortStatus_1_2)[i].status_1_1.status.currentMode =
|
||||
V1_0::PortMode::NONE;
|
||||
}
|
||||
|
||||
ALOGI("%d:%s connected:%d canChangeMode:%d canChagedata:%d "
|
||||
"canChangePower:%d "
|
||||
"supportedModes:%d",
|
||||
i, port.first.c_str(), port.second,
|
||||
(*currentPortStatus_1_2)[i].status_1_1.status.canChangeMode,
|
||||
(*currentPortStatus_1_2)[i].status_1_1.status.canChangeDataRole,
|
||||
(*currentPortStatus_1_2)[i].status_1_1.status.canChangePowerRole,
|
||||
(*currentPortStatus_1_2)[i].status_1_1.supportedModes);
|
||||
}
|
||||
return Status::SUCCESS;
|
||||
}
|
||||
done:
|
||||
return Status::ERROR;
|
||||
}
|
||||
|
||||
void queryVersionHelper(android::hardware::usb::V1_3::implementation::Usb *usb,
|
||||
hidl_vec<PortStatus> *currentPortStatus_1_2) {
|
||||
hidl_vec<V1_1::PortStatus_1_1> currentPortStatus_1_1;
|
||||
hidl_vec<V1_0::PortStatus> currentPortStatus;
|
||||
Status status;
|
||||
sp<V1_1::IUsbCallback> callback_V1_1 =
|
||||
V1_1::IUsbCallback::castFrom(usb->mCallback_1_0);
|
||||
sp<IUsbCallback> callback_V1_2 = IUsbCallback::castFrom(usb->mCallback_1_0);
|
||||
|
||||
pthread_mutex_lock(&usb->mLock);
|
||||
if (usb->mCallback_1_0 != NULL) {
|
||||
if (callback_V1_2 != NULL) {
|
||||
status = getPortStatusHelper(currentPortStatus_1_2, HALVersion::V1_2);
|
||||
if (status == Status::SUCCESS)
|
||||
queryMoistureDetectionStatus(currentPortStatus_1_2);
|
||||
} else if (callback_V1_1 != NULL) {
|
||||
status = getPortStatusHelper(currentPortStatus_1_2, HALVersion::V1_1);
|
||||
currentPortStatus_1_1.resize(currentPortStatus_1_2->size());
|
||||
for (unsigned long i = 0; i < currentPortStatus_1_2->size(); i++)
|
||||
currentPortStatus_1_1[i] = (*currentPortStatus_1_2)[i].status_1_1;
|
||||
} else {
|
||||
status = getPortStatusHelper(currentPortStatus_1_2, HALVersion::V1_0);
|
||||
currentPortStatus.resize(currentPortStatus_1_2->size());
|
||||
for (unsigned long i = 0; i < currentPortStatus_1_2->size(); i++)
|
||||
currentPortStatus[i] = (*currentPortStatus_1_2)[i].status_1_1.status;
|
||||
}
|
||||
|
||||
Return<void> ret;
|
||||
|
||||
if (callback_V1_2 != NULL)
|
||||
ret = callback_V1_2->notifyPortStatusChange_1_2(*currentPortStatus_1_2,
|
||||
status);
|
||||
else if (callback_V1_1 != NULL)
|
||||
ret = callback_V1_1->notifyPortStatusChange_1_1(currentPortStatus_1_1,
|
||||
status);
|
||||
else
|
||||
ret =
|
||||
usb->mCallback_1_0->notifyPortStatusChange(currentPortStatus, status);
|
||||
|
||||
if (!ret.isOk())
|
||||
ALOGE("queryPortStatus_1_2 error %s", ret.description().c_str());
|
||||
} else {
|
||||
ALOGI("Notifying userspace skipped. Callback is NULL");
|
||||
}
|
||||
pthread_mutex_unlock(&usb->mLock);
|
||||
}
|
||||
|
||||
Return<void> Usb::queryPortStatus() {
|
||||
hidl_vec<PortStatus> currentPortStatus_1_2;
|
||||
|
||||
queryVersionHelper(this, ¤tPortStatus_1_2);
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<void>
|
||||
Usb::enableContaminantPresenceDetection(const hidl_string & /*portName*/,
|
||||
bool enable) {
|
||||
std::string disable = GetProperty(kDisableContaminantDetection, "");
|
||||
|
||||
if (disable != "true")
|
||||
moistureDetectionEnabled = enable;
|
||||
|
||||
hidl_vec<PortStatus> currentPortStatus_1_2;
|
||||
|
||||
queryVersionHelper(this, ¤tPortStatus_1_2);
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<void>
|
||||
Usb::enableContaminantPresenceProtection(const hidl_string & /*portName*/,
|
||||
bool /*enable*/) {
|
||||
hidl_vec<PortStatus> currentPortStatus_1_2;
|
||||
|
||||
queryVersionHelper(this, ¤tPortStatus_1_2);
|
||||
return Void();
|
||||
}
|
||||
|
||||
struct data {
|
||||
int uevent_fd;
|
||||
android::hardware::usb::V1_3::implementation::Usb *usb;
|
||||
};
|
||||
|
||||
static void uevent_event(uint32_t /*epevents*/, struct data *payload) {
|
||||
char msg[UEVENT_MSG_LEN + 2];
|
||||
char *cp;
|
||||
int n;
|
||||
|
||||
n = uevent_kernel_multicast_recv(payload->uevent_fd, msg, UEVENT_MSG_LEN);
|
||||
if (n <= 0)
|
||||
return;
|
||||
if (n >= UEVENT_MSG_LEN) /* overflow -- discard */
|
||||
return;
|
||||
|
||||
msg[n] = '\0';
|
||||
msg[n + 1] = '\0';
|
||||
cp = msg;
|
||||
|
||||
while (*cp) {
|
||||
if (std::regex_match(cp, std::regex("(add)(.*)(-partner)"))) {
|
||||
ALOGI("partner added");
|
||||
pthread_mutex_lock(&payload->usb->mPartnerLock);
|
||||
payload->usb->mPartnerUp = true;
|
||||
pthread_cond_signal(&payload->usb->mPartnerCV);
|
||||
pthread_mutex_unlock(&payload->usb->mPartnerLock);
|
||||
} else if (!strncmp(cp, "DEVTYPE=typec_", strlen("DEVTYPE=typec_")) ||
|
||||
!strncmp(cp, "CCIC=WATER", strlen("CCIC=WATER")) ||
|
||||
!strncmp(cp, "CCIC=DRY", strlen("CCIC=DRY"))) {
|
||||
hidl_vec<PortStatus> currentPortStatus_1_2;
|
||||
queryVersionHelper(payload->usb, ¤tPortStatus_1_2);
|
||||
|
||||
// Role switch is not in progress and port is in disconnected state
|
||||
if (!pthread_mutex_trylock(&payload->usb->mRoleSwitchLock)) {
|
||||
for (unsigned long i = 0; i < currentPortStatus_1_2.size(); i++) {
|
||||
DIR *dp = opendir(
|
||||
std::string("/sys/class/typec/" +
|
||||
std::string(currentPortStatus_1_2[i]
|
||||
.status_1_1.status.portName.c_str()) +
|
||||
"-partner")
|
||||
.c_str());
|
||||
if (dp == NULL) {
|
||||
// PortRole role = {.role = static_cast<uint32_t>(PortMode::UFP)};
|
||||
switchToDrp(currentPortStatus_1_2[i].status_1_1.status.portName);
|
||||
} else {
|
||||
closedir(dp);
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&payload->usb->mRoleSwitchLock);
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* advance to after the next \0 */
|
||||
while (*cp++) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void *work(void *param) {
|
||||
int epoll_fd, uevent_fd;
|
||||
struct epoll_event ev;
|
||||
int nevents = 0;
|
||||
struct data payload;
|
||||
|
||||
ALOGE("creating thread");
|
||||
|
||||
uevent_fd = uevent_open_socket(64 * 1024, true);
|
||||
|
||||
if (uevent_fd < 0) {
|
||||
ALOGE("uevent_init: uevent_open_socket failed\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
payload.uevent_fd = uevent_fd;
|
||||
payload.usb = (android::hardware::usb::V1_3::implementation::Usb *)param;
|
||||
|
||||
fcntl(uevent_fd, F_SETFL, O_NONBLOCK);
|
||||
|
||||
ev.events = EPOLLIN;
|
||||
ev.data.ptr = (void *)uevent_event;
|
||||
|
||||
epoll_fd = epoll_create(64);
|
||||
if (epoll_fd == -1) {
|
||||
ALOGE("epoll_create failed; errno=%d", errno);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, uevent_fd, &ev) == -1) {
|
||||
ALOGE("epoll_ctl failed; errno=%d", errno);
|
||||
goto error;
|
||||
}
|
||||
|
||||
while (!destroyThread) {
|
||||
struct epoll_event events[64];
|
||||
|
||||
nevents = epoll_wait(epoll_fd, events, 64, -1);
|
||||
if (nevents == -1) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
ALOGE("usb epoll_wait failed; errno=%d", errno);
|
||||
break;
|
||||
}
|
||||
|
||||
for (int n = 0; n < nevents; ++n) {
|
||||
if (events[n].data.ptr)
|
||||
(*(void (*)(int, struct data *payload))events[n].data.ptr)(
|
||||
events[n].events, &payload);
|
||||
}
|
||||
}
|
||||
|
||||
ALOGI("exiting worker thread");
|
||||
error:
|
||||
close(uevent_fd);
|
||||
|
||||
if (epoll_fd >= 0)
|
||||
close(epoll_fd);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void sighandler(int sig) {
|
||||
if (sig == SIGUSR1) {
|
||||
destroyThread = true;
|
||||
ALOGI("destroy set");
|
||||
return;
|
||||
}
|
||||
signal(SIGUSR1, sighandler);
|
||||
}
|
||||
|
||||
Return<void> Usb::setCallback(const sp<V1_0::IUsbCallback> &callback) {
|
||||
sp<V1_1::IUsbCallback> callback_V1_1 = V1_1::IUsbCallback::castFrom(callback);
|
||||
sp<IUsbCallback> callback_V1_2 = IUsbCallback::castFrom(callback);
|
||||
|
||||
if (callback != NULL) {
|
||||
if (callback_V1_2 != NULL)
|
||||
ALOGI("Registering 1.2 callback");
|
||||
else if (callback_V1_1 != NULL)
|
||||
ALOGI("Registering 1.1 callback");
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&mLock);
|
||||
/*
|
||||
* When both the old callback and new callback values are NULL,
|
||||
* there is no need to spin off the worker thread.
|
||||
* When both the values are not NULL, we would already have a
|
||||
* worker thread running, so updating the callback object would
|
||||
* be suffice.
|
||||
*/
|
||||
if ((mCallback_1_0 == NULL && callback == NULL) ||
|
||||
(mCallback_1_0 != NULL && callback != NULL)) {
|
||||
/*
|
||||
* Always store as V1_0 callback object. Type cast to V1_1
|
||||
* when the callback is actually invoked.
|
||||
*/
|
||||
mCallback_1_0 = callback;
|
||||
pthread_mutex_unlock(&mLock);
|
||||
return Void();
|
||||
}
|
||||
|
||||
mCallback_1_0 = callback;
|
||||
ALOGI("registering callback");
|
||||
|
||||
// Kill the worker thread if the new callback is NULL.
|
||||
if (mCallback_1_0 == NULL) {
|
||||
pthread_mutex_unlock(&mLock);
|
||||
if (!pthread_kill(mPoll, SIGUSR1)) {
|
||||
pthread_join(mPoll, NULL);
|
||||
ALOGI("pthread destroyed");
|
||||
}
|
||||
return Void();
|
||||
}
|
||||
|
||||
destroyThread = false;
|
||||
signal(SIGUSR1, sighandler);
|
||||
|
||||
/*
|
||||
* Create a background thread if the old callback value is NULL
|
||||
* and being updated with a new value.
|
||||
*/
|
||||
if (pthread_create(&mPoll, NULL, work, this)) {
|
||||
ALOGE("pthread creation failed %d", errno);
|
||||
mCallback_1_0 = NULL;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&mLock);
|
||||
return Void();
|
||||
}
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V1_3
|
||||
} // namespace usb
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
99
universal7885-common/bin/hardware/samsung/usb/typec/Usb.h
Normal file
99
universal7885-common/bin/hardware/samsung/usb/typec/Usb.h
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <android-base/file.h>
|
||||
#include <android/hardware/usb/1.2/IUsbCallback.h>
|
||||
#include <android/hardware/usb/1.2/types.h>
|
||||
#include <android/hardware/usb/1.3/IUsb.h>
|
||||
#include <hidl/Status.h>
|
||||
#include <utils/Log.h>
|
||||
|
||||
#define UEVENT_MSG_LEN 2048
|
||||
// The type-c stack waits for 4.5 - 5.5 secs before declaring a port non-pd.
|
||||
// The -partner directory would not be created until this is done.
|
||||
// Having a margin of ~3 secs for the directory and other related bookeeping
|
||||
// structures created and uvent fired.
|
||||
#define PORT_TYPE_TIMEOUT 8
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace usb {
|
||||
namespace V1_3 {
|
||||
namespace implementation {
|
||||
|
||||
using ::android::sp;
|
||||
using ::android::base::ReadFileToString;
|
||||
using ::android::base::WriteStringToFile;
|
||||
using ::android::hardware::hidl_array;
|
||||
using ::android::hardware::hidl_memory;
|
||||
using ::android::hardware::hidl_string;
|
||||
using ::android::hardware::hidl_vec;
|
||||
using ::android::hardware::Return;
|
||||
using ::android::hardware::Void;
|
||||
using ::android::hardware::usb::V1_0::PortDataRole;
|
||||
using ::android::hardware::usb::V1_0::PortPowerRole;
|
||||
using ::android::hardware::usb::V1_0::PortRole;
|
||||
using ::android::hardware::usb::V1_0::PortRoleType;
|
||||
using ::android::hardware::usb::V1_0::Status;
|
||||
using ::android::hardware::usb::V1_1::PortMode_1_1;
|
||||
using ::android::hardware::usb::V1_1::PortStatus_1_1;
|
||||
using ::android::hardware::usb::V1_2::IUsbCallback;
|
||||
using ::android::hardware::usb::V1_2::PortStatus;
|
||||
using ::android::hardware::usb::V1_3::IUsb;
|
||||
using ::android::hidl::base::V1_0::DebugInfo;
|
||||
using ::android::hidl::base::V1_0::IBase;
|
||||
|
||||
enum class HALVersion { V1_0, V1_1, V1_2, V1_3 };
|
||||
|
||||
#define USB_DATA_PATH \
|
||||
"/sys/devices/virtual/usb_notify/usb_control/usb_data_enabled"
|
||||
|
||||
struct Usb : public IUsb {
|
||||
Usb();
|
||||
|
||||
Return<void> switchRole(const hidl_string &portName,
|
||||
const PortRole &role) override;
|
||||
Return<void> setCallback(const sp<V1_0::IUsbCallback> &callback) override;
|
||||
Return<void> queryPortStatus() override;
|
||||
Return<void> enableContaminantPresenceDetection(const hidl_string &portName,
|
||||
bool enable);
|
||||
Return<void> enableContaminantPresenceProtection(const hidl_string &portName,
|
||||
bool enable);
|
||||
Return<bool> enableUsbDataSignal(bool enable) override;
|
||||
|
||||
sp<V1_0::IUsbCallback> mCallback_1_0;
|
||||
// Protects mCallback variable
|
||||
pthread_mutex_t mLock;
|
||||
// Protects roleSwitch operation
|
||||
pthread_mutex_t mRoleSwitchLock;
|
||||
// Threads waiting for the partner to come back wait here
|
||||
pthread_cond_t mPartnerCV;
|
||||
// lock protecting mPartnerCV
|
||||
pthread_mutex_t mPartnerLock;
|
||||
// Variable to signal partner coming back online after type switch
|
||||
bool mPartnerUp;
|
||||
|
||||
private:
|
||||
pthread_t mPoll;
|
||||
};
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V1_3
|
||||
} // namespace usb
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
service vendor.usb-hal-1-3 /vendor/bin/hw/android.hardware.usb@1.3-service.samsung
|
||||
class hal
|
||||
user system
|
||||
group system shell mtp wakelock
|
||||
capabilities WAKE_ALARM BLOCK_SUSPEND
|
||||
|
||||
on post-fs
|
||||
chown root system /sys/class/typec/port0/power_role
|
||||
chown root system /sys/class/typec/port0/data_role
|
||||
chown root system /sys/class/typec/port0/port_type
|
||||
chown root system /sys/devices/virtual/sec/ccic/water
|
||||
chown root system /sys/devices/virtual/usb_notify/usb_control/usb_data_enabled
|
||||
chmod 664 /sys/class/typec/port0/power_role
|
||||
chmod 664 /sys/class/typec/port0/data_role
|
||||
chmod 664 /sys/class/typec/port0/port_type
|
||||
chmod 664 /sys/devices/virtual/usb_notify/usb_control/usb_data_enabled
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0"?>
|
||||
<manifest version="1.0" type="device">
|
||||
<hal format="hidl">
|
||||
<name>android.hardware.usb</name>
|
||||
<transport>hwbinder</transport>
|
||||
<version>1.3</version>
|
||||
<interface>
|
||||
<name>IUsb</name>
|
||||
<instance>default</instance>
|
||||
</interface>
|
||||
</hal>
|
||||
</manifest>
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
* Copyright (C) 2022 The LineageOS Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "android.hardware.usb@1.3-service.samsung"
|
||||
|
||||
#include "Usb.h"
|
||||
#include <hidl/HidlTransportSupport.h>
|
||||
|
||||
using android::sp;
|
||||
|
||||
// libhwbinder:
|
||||
using android::hardware::configureRpcThreadpool;
|
||||
using android::hardware::joinRpcThreadpool;
|
||||
|
||||
// Generated HIDL files
|
||||
using android::hardware::usb::V1_3::IUsb;
|
||||
using android::hardware::usb::V1_3::implementation::Usb;
|
||||
|
||||
using android::OK;
|
||||
using android::status_t;
|
||||
|
||||
int main() {
|
||||
android::sp<IUsb> service = new Usb();
|
||||
|
||||
configureRpcThreadpool(1, true /*callerWillJoin*/);
|
||||
status_t status = service->registerAsService();
|
||||
|
||||
if (status != OK) {
|
||||
ALOGE("Cannot register USB HAL service");
|
||||
return 1;
|
||||
}
|
||||
|
||||
ALOGI("USB HAL Ready.");
|
||||
joinRpcThreadpool();
|
||||
// Under noraml cases, execution will not reach this line.
|
||||
ALOGI("USB HAL failed to join thread pool.");
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
//
|
||||
// Copyright (C) 2021 The LineageOS Project
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
cc_binary {
|
||||
name: "android.hardware.vibrator-service.samsung",
|
||||
relative_install_path: "hw",
|
||||
init_rc: ["android.hardware.vibrator-service.samsung.rc"],
|
||||
vintf_fragments: ["android.hardware.vibrator-service.samsung.xml"],
|
||||
srcs: [
|
||||
"Vibrator.cpp",
|
||||
"service.cpp",
|
||||
],
|
||||
shared_libs: [
|
||||
"libbase",
|
||||
"libbinder_ndk",
|
||||
"android.hardware.vibrator-V2-ndk_platform",
|
||||
],
|
||||
vendor: true,
|
||||
}
|
||||
343
universal7885-common/bin/hardware/samsung/vibrator/Vibrator.cpp
Normal file
343
universal7885-common/bin/hardware/samsung/vibrator/Vibrator.cpp
Normal file
|
|
@ -0,0 +1,343 @@
|
|||
/*
|
||||
* Copyright (C) 2021 The LineageOS Project
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "Vibrator.h"
|
||||
|
||||
#include <android-base/logging.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <thread>
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace vibrator {
|
||||
|
||||
static std::map<Effect, int> CP_TRIGGER_EFFECTS{{Effect::CLICK, 10},
|
||||
{Effect::DOUBLE_CLICK, 14},
|
||||
{Effect::HEAVY_CLICK, 23},
|
||||
{Effect::TEXTURE_TICK, 50},
|
||||
{Effect::TICK, 50}};
|
||||
|
||||
/*
|
||||
* Write value to path and close file.
|
||||
*/
|
||||
template <typename T>
|
||||
static ndk::ScopedAStatus writeNode(const std::string &path, const T &value) {
|
||||
std::ofstream node(path);
|
||||
if (!node) {
|
||||
LOG(ERROR) << "Failed to open: " << path;
|
||||
return ndk::ScopedAStatus::fromStatus(STATUS_UNKNOWN_ERROR);
|
||||
}
|
||||
|
||||
LOG(DEBUG) << "writeNode node: " << path << " value: " << value;
|
||||
|
||||
node << value << std::endl;
|
||||
if (!node) {
|
||||
LOG(ERROR) << "Failed to write: " << value;
|
||||
return ndk::ScopedAStatus::fromStatus(STATUS_UNKNOWN_ERROR);
|
||||
}
|
||||
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
static bool nodeExists(const std::string &path) {
|
||||
std::ofstream f(path.c_str());
|
||||
return f.good();
|
||||
}
|
||||
|
||||
Vibrator::Vibrator() {
|
||||
mIsTimedOutVibrator = nodeExists(VIBRATOR_TIMEOUT_PATH);
|
||||
mHasTimedOutIntensity = nodeExists(VIBRATOR_INTENSITY_PATH);
|
||||
mHasTimedOutEffect = nodeExists(VIBRATOR_CP_TRIGGER_PATH);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Vibrator::getCapabilities(int32_t *_aidl_return) {
|
||||
*_aidl_return =
|
||||
IVibrator::CAP_ON_CALLBACK | IVibrator::CAP_PERFORM_CALLBACK |
|
||||
IVibrator::CAP_EXTERNAL_CONTROL /*| IVibrator::CAP_COMPOSE_EFFECTS |
|
||||
IVibrator::CAP_ALWAYS_ON_CONTROL*/
|
||||
;
|
||||
|
||||
if (mHasTimedOutIntensity) {
|
||||
*_aidl_return = *_aidl_return | IVibrator::CAP_AMPLITUDE_CONTROL |
|
||||
IVibrator::CAP_EXTERNAL_AMPLITUDE_CONTROL;
|
||||
}
|
||||
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Vibrator::off() { return activate(0); }
|
||||
|
||||
ndk::ScopedAStatus
|
||||
Vibrator::on(int32_t timeoutMs,
|
||||
const std::shared_ptr<IVibratorCallback> &callback) {
|
||||
ndk::ScopedAStatus status;
|
||||
|
||||
if (mHasTimedOutEffect)
|
||||
writeNode(VIBRATOR_CP_TRIGGER_PATH, 0); // Clear all effects
|
||||
|
||||
status = activate(timeoutMs);
|
||||
|
||||
if (callback != nullptr) {
|
||||
std::thread([=] {
|
||||
LOG(DEBUG) << "Starting on on another thread";
|
||||
usleep(timeoutMs * 1000);
|
||||
LOG(DEBUG) << "Notifying on complete";
|
||||
if (!callback->onComplete().isOk()) {
|
||||
LOG(ERROR) << "Failed to call onComplete";
|
||||
}
|
||||
}).detach();
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus
|
||||
Vibrator::perform(Effect effect, EffectStrength strength,
|
||||
const std::shared_ptr<IVibratorCallback> &callback,
|
||||
int32_t *_aidl_return) {
|
||||
ndk::ScopedAStatus status;
|
||||
uint32_t amplitude = strengthToAmplitude(strength, &status);
|
||||
uint32_t ms = 1000;
|
||||
|
||||
if (!status.isOk())
|
||||
return status;
|
||||
|
||||
activate(0);
|
||||
setAmplitude(amplitude);
|
||||
|
||||
if (mHasTimedOutEffect &&
|
||||
CP_TRIGGER_EFFECTS.find(effect) != CP_TRIGGER_EFFECTS.end()) {
|
||||
writeNode(VIBRATOR_CP_TRIGGER_PATH, CP_TRIGGER_EFFECTS[effect]);
|
||||
} else {
|
||||
if (mHasTimedOutEffect)
|
||||
writeNode(VIBRATOR_CP_TRIGGER_PATH, 0); // Clear previous effect
|
||||
|
||||
ms = effectToMs(effect, &status);
|
||||
|
||||
if (!status.isOk())
|
||||
return status;
|
||||
}
|
||||
|
||||
status = activate(ms);
|
||||
|
||||
if (callback != nullptr) {
|
||||
std::thread([=] {
|
||||
LOG(DEBUG) << "Starting perform on another thread";
|
||||
usleep(ms * 1000);
|
||||
LOG(DEBUG) << "Notifying perform complete";
|
||||
callback->onComplete();
|
||||
}).detach();
|
||||
}
|
||||
|
||||
*_aidl_return = ms;
|
||||
return status;
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus
|
||||
Vibrator::getSupportedEffects(std::vector<Effect> *_aidl_return) {
|
||||
*_aidl_return = {
|
||||
Effect::CLICK, Effect::DOUBLE_CLICK, Effect::HEAVY_CLICK,
|
||||
Effect::TICK, Effect::TEXTURE_TICK, Effect::THUD,
|
||||
Effect::POP, Effect::RINGTONE_1, Effect::RINGTONE_2,
|
||||
Effect::RINGTONE_3, Effect::RINGTONE_4, Effect::RINGTONE_5,
|
||||
Effect::RINGTONE_6, Effect::RINGTONE_7, Effect::RINGTONE_7,
|
||||
Effect::RINGTONE_8, Effect::RINGTONE_9, Effect::RINGTONE_10,
|
||||
Effect::RINGTONE_11, Effect::RINGTONE_12, Effect::RINGTONE_13,
|
||||
Effect::RINGTONE_14, Effect::RINGTONE_15};
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Vibrator::setAmplitude(float amplitude) {
|
||||
uint32_t intensity;
|
||||
|
||||
if (amplitude == 0) {
|
||||
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
|
||||
}
|
||||
|
||||
LOG(DEBUG) << "Setting amplitude: " << (uint32_t)amplitude;
|
||||
|
||||
intensity = std::lround((amplitude - 1) * INTENSITY_MAX / 254.0);
|
||||
if (intensity > INTENSITY_MAX) {
|
||||
intensity = INTENSITY_MAX;
|
||||
}
|
||||
|
||||
if (intensity == 0) {
|
||||
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
|
||||
}
|
||||
|
||||
LOG(DEBUG) << "Setting intensity: " << intensity;
|
||||
|
||||
if (mHasTimedOutIntensity) {
|
||||
return writeNode(VIBRATOR_INTENSITY_PATH, intensity);
|
||||
}
|
||||
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Vibrator::setExternalControl(bool enabled) {
|
||||
if (mEnabled) {
|
||||
LOG(WARNING) << "Setting external control while the vibrator is enabled is "
|
||||
"unsupported!";
|
||||
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
||||
}
|
||||
|
||||
LOG(INFO) << "ExternalControl: " << mExternalControl << " -> " << enabled;
|
||||
mExternalControl = enabled;
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus
|
||||
Vibrator::getCompositionDelayMax(int32_t * /*_aidl_return*/) {
|
||||
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Vibrator::getCompositionSizeMax(int32_t * /*_aidl_return*/) {
|
||||
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Vibrator::getSupportedPrimitives(
|
||||
std::vector<CompositePrimitive> * /*_aidl_return*/) {
|
||||
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus
|
||||
Vibrator::getPrimitiveDuration(CompositePrimitive /*primitive*/,
|
||||
int32_t * /*_aidl_return*/) {
|
||||
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus
|
||||
Vibrator::compose(const std::vector<CompositeEffect> & /*composite*/,
|
||||
const std::shared_ptr<IVibratorCallback> & /*callback*/) {
|
||||
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus
|
||||
Vibrator::getSupportedAlwaysOnEffects(std::vector<Effect> * /*_aidl_return*/) {
|
||||
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Vibrator::alwaysOnEnable(int32_t /*id*/, Effect /*effect*/,
|
||||
EffectStrength /*strength*/) {
|
||||
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Vibrator::alwaysOnDisable(int32_t /*id*/) {
|
||||
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Vibrator::getResonantFrequency(float * /*_aidl_return*/) {
|
||||
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Vibrator::getQFactor(float * /*_aidl_return*/) {
|
||||
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Vibrator::getFrequencyResolution(float * /*_aidl_return*/) {
|
||||
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Vibrator::getFrequencyMinimum(float * /*_aidl_return*/) {
|
||||
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus
|
||||
Vibrator::getBandwidthAmplitudeMap(std::vector<float> * /*_aidl_return*/) {
|
||||
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus
|
||||
Vibrator::getPwlePrimitiveDurationMax(int32_t * /*_aidl_return*/) {
|
||||
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus
|
||||
Vibrator::getPwleCompositionSizeMax(int32_t * /*_aidl_return*/) {
|
||||
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus
|
||||
Vibrator::getSupportedBraking(std::vector<Braking> * /*_aidl_return*/) {
|
||||
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus
|
||||
Vibrator::composePwle(const std::vector<PrimitivePwle> & /*composite*/,
|
||||
const std::shared_ptr<IVibratorCallback> & /*callback*/) {
|
||||
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Vibrator::activate(uint32_t timeoutMs) {
|
||||
std::lock_guard<std::mutex> lock{mMutex};
|
||||
if (!mIsTimedOutVibrator) {
|
||||
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
||||
}
|
||||
|
||||
return writeNode(VIBRATOR_TIMEOUT_PATH, timeoutMs);
|
||||
}
|
||||
|
||||
uint8_t Vibrator::strengthToAmplitude(EffectStrength strength,
|
||||
ndk::ScopedAStatus *status) {
|
||||
*status = ndk::ScopedAStatus::ok();
|
||||
|
||||
switch (strength) {
|
||||
case EffectStrength::LIGHT:
|
||||
return 64;
|
||||
case EffectStrength::MEDIUM:
|
||||
return 128;
|
||||
case EffectStrength::STRONG:
|
||||
return 255;
|
||||
}
|
||||
|
||||
*status = ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t Vibrator::effectToMs(Effect effect, ndk::ScopedAStatus *status) {
|
||||
*status = ndk::ScopedAStatus::ok();
|
||||
switch (effect) {
|
||||
case Effect::CLICK:
|
||||
return 10;
|
||||
case Effect::DOUBLE_CLICK:
|
||||
return 15;
|
||||
case Effect::TICK:
|
||||
case Effect::TEXTURE_TICK:
|
||||
case Effect::THUD:
|
||||
case Effect::POP:
|
||||
return 5;
|
||||
case Effect::HEAVY_CLICK:
|
||||
return 10;
|
||||
case Effect::RINGTONE_1:
|
||||
case Effect::RINGTONE_2:
|
||||
case Effect::RINGTONE_3:
|
||||
case Effect::RINGTONE_4:
|
||||
case Effect::RINGTONE_5:
|
||||
case Effect::RINGTONE_6:
|
||||
case Effect::RINGTONE_7:
|
||||
case Effect::RINGTONE_8:
|
||||
case Effect::RINGTONE_9:
|
||||
case Effect::RINGTONE_10:
|
||||
case Effect::RINGTONE_11:
|
||||
case Effect::RINGTONE_12:
|
||||
case Effect::RINGTONE_13:
|
||||
case Effect::RINGTONE_14:
|
||||
case Effect::RINGTONE_15:
|
||||
return 30000;
|
||||
}
|
||||
*status = ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace vibrator
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Copyright (C) 2021 The LineageOS Project
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <aidl/android/hardware/vibrator/BnVibrator.h>
|
||||
|
||||
#define INTENSITY_MIN 1000
|
||||
#define INTENSITY_MAX 10000
|
||||
#define INTENSITY_DEFAULT INTENSITY_MAX
|
||||
|
||||
#define VIBRATOR_TIMEOUT_PATH "/sys/class/timed_output/vibrator/enable"
|
||||
#define VIBRATOR_INTENSITY_PATH "/sys/class/timed_output/vibrator/intensity"
|
||||
#define VIBRATOR_CP_TRIGGER_PATH \
|
||||
"/sys/class/timed_output/vibrator/cp_trigger_index"
|
||||
|
||||
using ::aidl::android::hardware::vibrator::Braking;
|
||||
using ::aidl::android::hardware::vibrator::CompositeEffect;
|
||||
using ::aidl::android::hardware::vibrator::CompositePrimitive;
|
||||
using ::aidl::android::hardware::vibrator::Effect;
|
||||
using ::aidl::android::hardware::vibrator::EffectStrength;
|
||||
using ::aidl::android::hardware::vibrator::IVibratorCallback;
|
||||
using ::aidl::android::hardware::vibrator::PrimitivePwle;
|
||||
|
||||
namespace aidl {
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace vibrator {
|
||||
|
||||
class Vibrator : public BnVibrator {
|
||||
public:
|
||||
Vibrator();
|
||||
ndk::ScopedAStatus getCapabilities(int32_t *_aidl_return) override;
|
||||
ndk::ScopedAStatus off() override;
|
||||
ndk::ScopedAStatus
|
||||
on(int32_t timeoutMs,
|
||||
const std::shared_ptr<IVibratorCallback> &callback) override;
|
||||
ndk::ScopedAStatus perform(Effect effect, EffectStrength strength,
|
||||
const std::shared_ptr<IVibratorCallback> &callback,
|
||||
int32_t *_aidl_return) override;
|
||||
ndk::ScopedAStatus
|
||||
getSupportedEffects(std::vector<Effect> *_aidl_return) override;
|
||||
ndk::ScopedAStatus setAmplitude(float amplitude) override;
|
||||
ndk::ScopedAStatus setExternalControl(bool enabled) override;
|
||||
ndk::ScopedAStatus getCompositionDelayMax(int32_t *_aidl_return) override;
|
||||
ndk::ScopedAStatus getCompositionSizeMax(int32_t *_aidl_return) override;
|
||||
ndk::ScopedAStatus getSupportedPrimitives(
|
||||
std::vector<CompositePrimitive> *_aidl_return) override;
|
||||
ndk::ScopedAStatus getPrimitiveDuration(CompositePrimitive primitive,
|
||||
int32_t *_aidl_return) override;
|
||||
ndk::ScopedAStatus
|
||||
compose(const std::vector<CompositeEffect> &composite,
|
||||
const std::shared_ptr<IVibratorCallback> &callback) override;
|
||||
ndk::ScopedAStatus
|
||||
getSupportedAlwaysOnEffects(std::vector<Effect> *_aidl_return) override;
|
||||
ndk::ScopedAStatus alwaysOnEnable(int32_t id, Effect effect,
|
||||
EffectStrength strength) override;
|
||||
ndk::ScopedAStatus alwaysOnDisable(int32_t id) override;
|
||||
ndk::ScopedAStatus getResonantFrequency(float *_aidl_return) override;
|
||||
ndk::ScopedAStatus getQFactor(float *_aidl_return) override;
|
||||
ndk::ScopedAStatus getFrequencyResolution(float *_aidl_return) override;
|
||||
ndk::ScopedAStatus getFrequencyMinimum(float *_aidl_return) override;
|
||||
ndk::ScopedAStatus
|
||||
getBandwidthAmplitudeMap(std::vector<float> *_aidl_return) override;
|
||||
ndk::ScopedAStatus
|
||||
getPwlePrimitiveDurationMax(int32_t *_aidl_return) override;
|
||||
ndk::ScopedAStatus getPwleCompositionSizeMax(int32_t *_aidl_return) override;
|
||||
ndk::ScopedAStatus
|
||||
getSupportedBraking(std::vector<Braking> *_aidl_return) override;
|
||||
ndk::ScopedAStatus
|
||||
composePwle(const std::vector<PrimitivePwle> &composite,
|
||||
const std::shared_ptr<IVibratorCallback> &callback) override;
|
||||
|
||||
private:
|
||||
ndk::ScopedAStatus activate(uint32_t ms);
|
||||
static uint32_t effectToMs(Effect effect, ndk::ScopedAStatus *status);
|
||||
static uint8_t strengthToAmplitude(EffectStrength strength,
|
||||
ndk::ScopedAStatus *status);
|
||||
|
||||
bool mEnabled{false};
|
||||
bool mExternalControl{false};
|
||||
std::mutex mMutex;
|
||||
|
||||
bool mIsTimedOutVibrator;
|
||||
bool mHasTimedOutIntensity;
|
||||
bool mHasTimedOutEffect;
|
||||
};
|
||||
|
||||
} // namespace vibrator
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
} // namespace aidl
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
on init
|
||||
chown system system /sys/class/timed_output/vibrator/cp_trigger_index
|
||||
chown system system /sys/class/timed_output/vibrator/enable
|
||||
chown system system /sys/class/timed_output/vibrator/intensity
|
||||
|
||||
service vendor.vibrator-default /vendor/bin/hw/android.hardware.vibrator-service.samsung
|
||||
class hal
|
||||
user system
|
||||
group system
|
||||
shutdown critical
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0"?>
|
||||
<manifest version="1.0" type="device">
|
||||
<hal format="aidl">
|
||||
<name>android.hardware.vibrator</name>
|
||||
<fqname>IVibrator/default</fqname>
|
||||
</hal>
|
||||
</manifest>
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright (C) 2021 The LineageOS Project
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "Vibrator.h"
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <android/binder_manager.h>
|
||||
#include <android/binder_process.h>
|
||||
|
||||
using ::aidl::android::hardware::vibrator::Vibrator;
|
||||
|
||||
int main() {
|
||||
ABinderProcess_setThreadPoolMaxThreadCount(0);
|
||||
std::shared_ptr<Vibrator> vibrator = ndk::SharedRefBase::make<Vibrator>();
|
||||
|
||||
const std::string instance =
|
||||
std::string() + Vibrator::descriptor + "/default";
|
||||
binder_status_t status =
|
||||
AServiceManager_addService(vibrator->asBinder().get(), instance.c_str());
|
||||
CHECK(status == STATUS_OK);
|
||||
|
||||
ABinderProcess_joinThreadPool();
|
||||
return EXIT_FAILURE; // should not reach
|
||||
}
|
||||
22
universal7885-common/bin/init/Android.bp
Normal file
22
universal7885-common/bin/init/Android.bp
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
// Copyright (C) 2021 The LineageOS Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
cc_library_static {
|
||||
name: "libinit_universal7885",
|
||||
recovery_available: true,
|
||||
whole_static_libs: ["libbase"],
|
||||
header_libs: ["libbase_headers"],
|
||||
srcs: ["init_universal7885.cpp"],
|
||||
include_dirs: ["system/core/init"]
|
||||
}
|
||||
94
universal7885-common/bin/init/init_universal7885.cpp
Normal file
94
universal7885-common/bin/init/init_universal7885.cpp
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
Copyright (c) 2021, The LineageOS Project
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
* Neither the name of The Linux Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <vector>
|
||||
|
||||
#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
|
||||
#include <sys/_system_properties.h>
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <android-base/properties.h>
|
||||
|
||||
#include "property_service.h"
|
||||
#include "vendor_init.h"
|
||||
|
||||
using android::base::GetProperty;
|
||||
using std::string;
|
||||
|
||||
std::vector<std::string> ro_props_default_source_order = {
|
||||
"", "odm.", "product.", "system.", "system_ext.", "vendor.", "vendor_dlkm.",
|
||||
};
|
||||
|
||||
void property_override(char const prop[], char const value[], bool add = true) {
|
||||
prop_info *pi;
|
||||
|
||||
pi = (prop_info *)__system_property_find(prop);
|
||||
if (pi)
|
||||
__system_property_update(pi, value, strlen(value));
|
||||
else if (add)
|
||||
__system_property_add(prop, strlen(prop), value, strlen(value));
|
||||
}
|
||||
|
||||
void set_ro_build_prop(const std::string &prop, const std::string &value,
|
||||
bool product = true) {
|
||||
string prop_name;
|
||||
|
||||
for (const auto &source : ro_props_default_source_order) {
|
||||
if (product)
|
||||
prop_name = "ro.product." + source + prop;
|
||||
else
|
||||
prop_name = "ro." + source + "build." + prop;
|
||||
|
||||
property_override(prop_name.c_str(), value.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
bool hasEnding(std::string const &fullString, std::string const &ending) {
|
||||
if (fullString.length() >= ending.length()) {
|
||||
return (0 == fullString.compare(fullString.length() - ending.length(),
|
||||
ending.length(), ending));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void vendor_load_properties() {
|
||||
string model;
|
||||
|
||||
model = GetProperty("ro.boot.product.model", "");
|
||||
if (model.empty()) {
|
||||
model = GetProperty("ro.boot.em.model", "");
|
||||
}
|
||||
|
||||
if (hasEnding(model, "N") || hasEnding(model, "S") || hasEnding(model, "K") ||
|
||||
model == "SM-A202F") {
|
||||
property_override("ro.boot.product.hardware.sku", "NFC");
|
||||
}
|
||||
|
||||
set_ro_build_prop("model", model);
|
||||
set_ro_build_prop("product", model, false);
|
||||
}
|
||||
35
universal7885-common/bin/libshims/camera/Android.bp
Normal file
35
universal7885-common/bin/libshims/camera/Android.bp
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright (c) 2022 Eureka Team.
|
||||
* https://github.com/eurekadevelopment
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
cc_library_shared {
|
||||
name: "libcorrectcamera",
|
||||
defaults: ["hidl_defaults"],
|
||||
proprietary: true,
|
||||
srcs: [
|
||||
"CorrectCameraID.cpp",
|
||||
],
|
||||
shared_libs: [
|
||||
"libhidlbase",
|
||||
"libhardware",
|
||||
"camera.device@3.2-impl",
|
||||
"libcamera_metadata",
|
||||
"android.hardware.camera.device@3.2",
|
||||
"android.hardware.camera.provider@2.4",
|
||||
"android.hardware.graphics.mapper@2.0",
|
||||
"android.hardware.graphics.mapper@3.0",
|
||||
"android.hardware.graphics.mapper@4.0",
|
||||
"liblog",
|
||||
"libutils",
|
||||
"libcutils",
|
||||
],
|
||||
static_libs: [
|
||||
"android.hardware.camera.common@1.0-helper",
|
||||
],
|
||||
}
|
||||
164
universal7885-common/bin/libshims/camera/CamDevice_3_2.h
Normal file
164
universal7885-common/bin/libshims/camera/CamDevice_3_2.h
Normal file
|
|
@ -0,0 +1,164 @@
|
|||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_HARDWARE_CAM_DEVICE_V3_2_CAMERADEVICE_H
|
||||
#define ANDROID_HARDWARE_CAM_DEVICE_V3_2_CAMERADEVICE_H
|
||||
|
||||
#include "CameraDeviceSession.h"
|
||||
#include "CameraMetadata.h"
|
||||
#include "CameraModule.h"
|
||||
#include "utils/Mutex.h"
|
||||
|
||||
#include <android/hardware/camera/device/3.2/ICameraDevice.h>
|
||||
#include <hidl/MQDescriptor.h>
|
||||
#include <hidl/Status.h>
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace camera {
|
||||
namespace device {
|
||||
namespace V3_2 {
|
||||
namespace implementation {
|
||||
|
||||
using ::android::Mutex;
|
||||
using ::android::sp;
|
||||
using ::android::hardware::hidl_string;
|
||||
using ::android::hardware::hidl_vec;
|
||||
using ::android::hardware::Return;
|
||||
using ::android::hardware::Void;
|
||||
using ::android::hardware::camera::common::V1_0::CameraResourceCost;
|
||||
using ::android::hardware::camera::common::V1_0::Status;
|
||||
using ::android::hardware::camera::common::V1_0::TorchMode;
|
||||
using ::android::hardware::camera::common::V1_0::helper::CameraModule;
|
||||
using ::android::hardware::camera::device::V3_2::ICameraDevice;
|
||||
using ::android::hardware::camera::device::V3_2::ICameraDeviceCallback;
|
||||
using ::android::hardware::camera::device::V3_2::ICameraDeviceSession;
|
||||
using ::android::hardware::camera::device::V3_2::RequestTemplate;
|
||||
|
||||
/*
|
||||
* The camera device HAL implementation is opened lazily (via the open call)
|
||||
*/
|
||||
struct CameraDevice : public virtual RefBase {
|
||||
// Called by provider HAL. Provider HAL must ensure the uniqueness of
|
||||
// CameraDevice object per cameraId, or there could be multiple CameraDevice
|
||||
// trying to access the same physical camera.
|
||||
// Also, provider will have to keep track of all CameraDevice objects in
|
||||
// order to notify CameraDevice when the underlying camera is detached
|
||||
CameraDevice(sp<CameraModule> module, const std::string &cameraId,
|
||||
const SortedVector<std::pair<std::string, std::string>>
|
||||
&cameraDeviceNames);
|
||||
virtual ~CameraDevice();
|
||||
|
||||
// Retrieve the HIDL interface, split into its own class to avoid inheritance
|
||||
// issues when dealing with minor version revs and simultaneous implementation
|
||||
// and interface inheritance
|
||||
virtual sp<ICameraDevice> getInterface() {
|
||||
return new TrampolineDeviceInterface_3_2(this);
|
||||
}
|
||||
|
||||
// Caller must use this method to check if CameraDevice ctor failed
|
||||
bool isInitFailed() { return mInitFail; }
|
||||
// Used by provider HAL to signal external camera disconnected
|
||||
void setConnectionStatus(bool connected);
|
||||
|
||||
/* Methods from ::android::hardware::camera::device::V3_2::ICameraDevice
|
||||
* follow. */
|
||||
// The following method can be called without opening the actual camera device
|
||||
Return<void> getResourceCost(ICameraDevice::getResourceCost_cb _hidl_cb);
|
||||
Return<void>
|
||||
getCameraCharacteristics(ICameraDevice::getCameraCharacteristics_cb _hidl_cb);
|
||||
Return<void>
|
||||
getEurekaCharacteristics(ICameraDevice::getCameraCharacteristics_cb _hidl_cb);
|
||||
Return<Status> setTorchMode(TorchMode mode);
|
||||
|
||||
// Open the device HAL and also return a default capture session
|
||||
Return<void> open(const sp<ICameraDeviceCallback> &callback,
|
||||
ICameraDevice::open_cb _hidl_cb);
|
||||
Return<void> nuke(const sp<ICameraDeviceCallback> &callback,
|
||||
ICameraDevice::open_cb _hidl_cb);
|
||||
|
||||
// Forward the dump call to the opened session, or do nothing
|
||||
Return<void> dumpState(const ::android::hardware::hidl_handle &fd);
|
||||
/* End of Methods from
|
||||
* ::android::hardware::camera::device::V3_2::ICameraDevice */
|
||||
|
||||
protected:
|
||||
// Overridden by child implementations for returning different versions of
|
||||
// CameraDeviceSession
|
||||
virtual sp<CameraDeviceSession>
|
||||
createSession(camera3_device_t *, const camera_metadata_t *deviceInfo,
|
||||
const sp<ICameraDeviceCallback> &);
|
||||
|
||||
const sp<CameraModule> mModule;
|
||||
const std::string mCameraId;
|
||||
// const after ctor
|
||||
int mCameraIdInt;
|
||||
int mDeviceVersion;
|
||||
bool mInitFail = false;
|
||||
// Set by provider (when external camera is connected/disconnected)
|
||||
bool mDisconnected;
|
||||
wp<CameraDeviceSession> mSession = nullptr;
|
||||
|
||||
const SortedVector<std::pair<std::string, std::string>> &mCameraDeviceNames;
|
||||
|
||||
// gating access to mSession and mDisconnected
|
||||
mutable Mutex mLock;
|
||||
|
||||
// convert conventional HAL status to HIDL Status
|
||||
static Status getHidlStatus(int);
|
||||
|
||||
Status initStatus() const;
|
||||
|
||||
private:
|
||||
struct TrampolineDeviceInterface_3_2 : public ICameraDevice {
|
||||
TrampolineDeviceInterface_3_2(sp<CameraDevice> parent) : mParent(parent) {}
|
||||
|
||||
virtual Return<void>
|
||||
getResourceCost(V3_2::ICameraDevice::getResourceCost_cb _hidl_cb) override {
|
||||
return mParent->getResourceCost(_hidl_cb);
|
||||
}
|
||||
|
||||
virtual Return<void> getCameraCharacteristics(
|
||||
V3_2::ICameraDevice::getCameraCharacteristics_cb _hidl_cb) override {
|
||||
return mParent->getCameraCharacteristics(_hidl_cb);
|
||||
}
|
||||
|
||||
virtual Return<Status> setTorchMode(TorchMode mode) override {
|
||||
return mParent->setTorchMode(mode);
|
||||
}
|
||||
|
||||
virtual Return<void> open(const sp<V3_2::ICameraDeviceCallback> &callback,
|
||||
V3_2::ICameraDevice::open_cb _hidl_cb) override {
|
||||
return mParent->open(callback, _hidl_cb);
|
||||
}
|
||||
|
||||
virtual Return<void> dumpState(const hidl_handle &fd) override {
|
||||
return mParent->dumpState(fd);
|
||||
}
|
||||
|
||||
private:
|
||||
sp<CameraDevice> mParent;
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V3_2
|
||||
} // namespace device
|
||||
} // namespace camera
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
|
||||
#endif // ANDROID_HARDWARE_CAM_DEVICE_V3_2_CAMERADEVICE_H
|
||||
163
universal7885-common/bin/libshims/camera/CorrectCameraID.cpp
Normal file
163
universal7885-common/bin/libshims/camera/CorrectCameraID.cpp
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
/*
|
||||
* Copyright (c) 2022 Eureka Team.
|
||||
* https://github.com/eurekadevelopment
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include "CamDevice_3_2.h"
|
||||
#include <include/convert.h>
|
||||
#include <log/log.h>
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace camera {
|
||||
namespace device {
|
||||
namespace V3_2 {
|
||||
namespace implementation {
|
||||
|
||||
using ::android::hardware::camera::common::V1_0::Status;
|
||||
|
||||
Return<void> CameraDevice::getCameraCharacteristics(
|
||||
ICameraDevice::getCameraCharacteristics_cb _hidl_cb) {
|
||||
Status status = initStatus();
|
||||
CameraMetadata cameraCharacteristics;
|
||||
if (status == Status::OK) {
|
||||
// Module 2.1+ codepath.
|
||||
struct camera_info info;
|
||||
if (mCameraIdInt == 1)
|
||||
mCameraIdInt = 2;
|
||||
int ret = mModule->getCameraInfo(mCameraIdInt, &info);
|
||||
if (ret == OK) {
|
||||
convertToHidl(info.static_camera_characteristics, &cameraCharacteristics);
|
||||
} else {
|
||||
ALOGE("%s: get camera info failed!", __FUNCTION__);
|
||||
status = Status::INTERNAL_ERROR;
|
||||
}
|
||||
}
|
||||
_hidl_cb(status, cameraCharacteristics);
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<void> CameraDevice::getEurekaCharacteristics(
|
||||
ICameraDevice::getCameraCharacteristics_cb _hidl_cb) {
|
||||
return CameraDevice::getCameraCharacteristics(_hidl_cb);
|
||||
}
|
||||
|
||||
Return<void> CameraDevice::open(const sp<ICameraDeviceCallback> &callback,
|
||||
ICameraDevice::open_cb _hidl_cb) {
|
||||
Status status = initStatus();
|
||||
sp<CameraDeviceSession> session = nullptr;
|
||||
|
||||
if (callback == nullptr) {
|
||||
ALOGE("%s: cannot open camera %s. callback is null!", __FUNCTION__,
|
||||
mCameraId.c_str());
|
||||
_hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
|
||||
return Void();
|
||||
}
|
||||
|
||||
if (status != Status::OK) {
|
||||
// Provider will never pass initFailed device to client, so
|
||||
// this must be a disconnected camera
|
||||
ALOGE("%s: cannot open camera %s. camera is disconnected!", __FUNCTION__,
|
||||
mCameraId.c_str());
|
||||
_hidl_cb(Status::CAMERA_DISCONNECTED, nullptr);
|
||||
return Void();
|
||||
} else {
|
||||
mLock.lock();
|
||||
|
||||
ALOGV("%s: Initializing device for camera %d", __FUNCTION__, mCameraIdInt);
|
||||
session = mSession.promote();
|
||||
if (session != nullptr && !session->isClosed()) {
|
||||
ALOGE("%s: cannot open an already opened camera!", __FUNCTION__);
|
||||
mLock.unlock();
|
||||
_hidl_cb(Status::CAMERA_IN_USE, nullptr);
|
||||
return Void();
|
||||
}
|
||||
|
||||
/** Open HAL device */
|
||||
status_t res;
|
||||
camera3_device_t *device;
|
||||
|
||||
std::string mCameraID = mCameraId;
|
||||
if (mCameraIdInt == 1)
|
||||
mCameraIdInt = 2;
|
||||
if (mCameraID == "1")
|
||||
mCameraID = "2";
|
||||
|
||||
res = mModule->open(mCameraID.c_str(),
|
||||
reinterpret_cast<hw_device_t **>(&device));
|
||||
if (res != OK) {
|
||||
ALOGE("%s: cannot open camera %s!", __FUNCTION__, mCameraID.c_str());
|
||||
mLock.unlock();
|
||||
_hidl_cb(getHidlStatus(res), nullptr);
|
||||
return Void();
|
||||
}
|
||||
|
||||
/** Cross-check device version */
|
||||
if (device->common.version < CAMERA_DEVICE_API_VERSION_3_2) {
|
||||
ALOGE("%s: Could not open camera: "
|
||||
"Camera device should be at least %x, reports %x instead",
|
||||
__FUNCTION__, CAMERA_DEVICE_API_VERSION_3_2,
|
||||
device->common.version);
|
||||
device->common.close(&device->common);
|
||||
mLock.unlock();
|
||||
_hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
|
||||
return Void();
|
||||
}
|
||||
|
||||
struct camera_info info;
|
||||
res = mModule->getCameraInfo(mCameraIdInt, &info);
|
||||
if (res != OK) {
|
||||
ALOGE("%s: Could not open camera: getCameraInfo failed", __FUNCTION__);
|
||||
device->common.close(&device->common);
|
||||
mLock.unlock();
|
||||
_hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
|
||||
return Void();
|
||||
}
|
||||
|
||||
session =
|
||||
createSession(device, info.static_camera_characteristics, callback);
|
||||
if (session == nullptr) {
|
||||
ALOGE("%s: camera device session allocation failed", __FUNCTION__);
|
||||
mLock.unlock();
|
||||
_hidl_cb(Status::INTERNAL_ERROR, nullptr);
|
||||
return Void();
|
||||
}
|
||||
if (session->isInitFailed()) {
|
||||
ALOGE("%s: camera device session init failed", __FUNCTION__);
|
||||
session = nullptr;
|
||||
mLock.unlock();
|
||||
_hidl_cb(Status::INTERNAL_ERROR, nullptr);
|
||||
return Void();
|
||||
}
|
||||
mSession = session;
|
||||
|
||||
IF_ALOGV() {
|
||||
session->getInterface()->interfaceChain(
|
||||
[](::android::hardware::hidl_vec<::android::hardware::hidl_string>
|
||||
interfaceChain) {
|
||||
ALOGV("Session interface chain:");
|
||||
for (const auto &iface : interfaceChain) {
|
||||
ALOGV(" %s", iface.c_str());
|
||||
}
|
||||
});
|
||||
}
|
||||
mLock.unlock();
|
||||
}
|
||||
_hidl_cb(status, session->getInterface());
|
||||
return Void();
|
||||
}
|
||||
Return<void> CameraDevice::nuke(const sp<ICameraDeviceCallback> &callback,
|
||||
ICameraDevice::open_cb _hidl_cb) {
|
||||
return CameraDevice::open(callback, _hidl_cb);
|
||||
}
|
||||
} // namespace implementation
|
||||
} // namespace V3_2
|
||||
} // namespace device
|
||||
} // namespace camera
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
12
universal7885-common/bin/libshims/fakelogprint/Android.bp
Normal file
12
universal7885-common/bin/libshims/fakelogprint/Android.bp
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
//
|
||||
// Copyright (C) 2021 The LineageOS Project
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
cc_library_shared {
|
||||
name: "fakelogprint",
|
||||
vendor: true,
|
||||
shared_libs: ["liblog"],
|
||||
srcs: ["fakelogprint.cpp"],
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
#include <log/log.h>
|
||||
|
||||
int __android_log_print(int prio, const char *tag, const char *fmt, ...) {
|
||||
return 0;
|
||||
}
|
||||
51
universal7885-common/bin/libshims/sensor/ASensorManager.cpp
Normal file
51
universal7885-common/bin/libshims/sensor/ASensorManager.cpp
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright (C) 2020 LineageOS Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <ALooper.h>
|
||||
|
||||
#define LOG_TAG "libshim_sensorndkbridge"
|
||||
#include <android-base/logging.h>
|
||||
|
||||
using android::Mutex;
|
||||
|
||||
static Mutex gLock;
|
||||
|
||||
extern "C" ALooper *ALooper_forCamera() {
|
||||
LOG(VERBOSE) << "ALooper_forCamera";
|
||||
ALooper *sLooper = NULL;
|
||||
|
||||
Mutex::Autolock autoLock(gLock);
|
||||
sLooper = new ALooper;
|
||||
|
||||
return sLooper;
|
||||
}
|
||||
|
||||
extern "C" int ALooper_release_forCamera(ALooper *sLooper) {
|
||||
if (sLooper != nullptr) {
|
||||
Mutex::Autolock autoLock(gLock);
|
||||
delete sLooper;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" int ALooper_pollOnce_camera(ALooper *sLooper, int timeoutMillis,
|
||||
int *outFd, int *outEvents,
|
||||
void **outData) {
|
||||
int res = sLooper->pollOnce(timeoutMillis, outFd, outEvents, outData);
|
||||
LOG(VERBOSE) << "ALooper_pollOnce_camera => " << res;
|
||||
return res;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue