sdm660: Add support for folio cases
Bug: 35243564 Test: Used magnet to wake and lock device. Also tested during suspend. Change-Id: I4b819e12cc23a3d7a8ce048e208c15eac4f8d6c5
This commit is contained in:
parent
702f8d64b9
commit
f08faed4c3
6 changed files with 192 additions and 0 deletions
22
folio_daemon/Android.mk
Executable file
22
folio_daemon/Android.mk
Executable file
|
@ -0,0 +1,22 @@
|
||||||
|
LOCAL_PATH := $(call my-dir)
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
|
LOCAL_SHARED_LIBRARIES := \
|
||||||
|
libandroid \
|
||||||
|
libcutils \
|
||||||
|
liblog
|
||||||
|
|
||||||
|
LOCAL_SRC_FILES := \
|
||||||
|
main.cpp
|
||||||
|
|
||||||
|
LOCAL_C_INCLUDES :=
|
||||||
|
|
||||||
|
LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"folio_daemon\" -DLOG_NDEBUG=0
|
||||||
|
|
||||||
|
LOCAL_CLANG := true
|
||||||
|
LOCAL_MODULE := folio_daemon
|
||||||
|
LOCAL_MODULE_TAGS := optional
|
||||||
|
LOCAL_MODULE_OWNER := google
|
||||||
|
LOCAL_PROPRIETARY_MODULE := true
|
||||||
|
|
||||||
|
include $(BUILD_EXECUTABLE)
|
147
folio_daemon/main.cpp
Normal file
147
folio_daemon/main.cpp
Normal file
|
@ -0,0 +1,147 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2017 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <linux/input.h>
|
||||||
|
#include <linux/uinput.h>
|
||||||
|
#include <android/looper.h>
|
||||||
|
#include <android/sensor.h>
|
||||||
|
#include <cutils/log.h>
|
||||||
|
|
||||||
|
// Hall-effect sensor type
|
||||||
|
#define SENSOR_TYPE 33171016
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This simple daemon listens for events from the Hall-effect sensor and writes
|
||||||
|
* the appropriate SW_LID event to a uinput node. This allows the screen to be
|
||||||
|
* locked with a magnetic folio case.
|
||||||
|
*/
|
||||||
|
int main(void) {
|
||||||
|
int uinputFd;
|
||||||
|
int err;
|
||||||
|
struct uinput_user_dev uidev;
|
||||||
|
ASensorManager *sensorManager = nullptr;
|
||||||
|
ASensorRef hallSensor;
|
||||||
|
ALooper *looper;
|
||||||
|
ASensorEventQueue *eventQueue = nullptr;
|
||||||
|
|
||||||
|
ALOGI("Started");
|
||||||
|
|
||||||
|
uinputFd = TEMP_FAILURE_RETRY(open("/dev/uinput", O_WRONLY | O_NONBLOCK));
|
||||||
|
if (uinputFd < 0) {
|
||||||
|
ALOGE("Unable to open uinput node: %s", strerror(errno));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = TEMP_FAILURE_RETRY(ioctl(uinputFd, UI_SET_EVBIT, EV_SW))
|
||||||
|
| TEMP_FAILURE_RETRY(ioctl(uinputFd, UI_SET_EVBIT, EV_SYN))
|
||||||
|
| TEMP_FAILURE_RETRY(ioctl(uinputFd, UI_SET_SWBIT, SW_LID));
|
||||||
|
if (err != 0) {
|
||||||
|
ALOGE("Unable to enable SW_LID events: %s", strerror(errno));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&uidev, 0, sizeof (uidev));
|
||||||
|
snprintf(uidev.name, UINPUT_MAX_NAME_SIZE, "uinput-folio");
|
||||||
|
uidev.id.bustype = BUS_VIRTUAL;
|
||||||
|
uidev.id.vendor = 0;
|
||||||
|
uidev.id.product = 0;
|
||||||
|
uidev.id.version = 0;
|
||||||
|
|
||||||
|
err = TEMP_FAILURE_RETRY(write(uinputFd, &uidev, sizeof (uidev)));
|
||||||
|
if (err < 0) {
|
||||||
|
ALOGE("Write user device to uinput node failed: %s", strerror(errno));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = TEMP_FAILURE_RETRY(ioctl(uinputFd, UI_DEV_CREATE));
|
||||||
|
if (err < 0) {
|
||||||
|
ALOGE("Unable to create uinput device: %s", strerror(errno));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
ALOGI("Successfully registered uinput-folio for SW_LID events");
|
||||||
|
|
||||||
|
// Get Hall-effect sensor events from the NDK
|
||||||
|
sensorManager = ASensorManager_getInstanceForPackage(nullptr);
|
||||||
|
hallSensor = ASensorManager_getDefaultSensor(sensorManager, SENSOR_TYPE);
|
||||||
|
if (hallSensor == nullptr) {
|
||||||
|
ALOGE("Unable to get Hall-effect sensor");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
looper = ALooper_forThread();
|
||||||
|
if (looper == nullptr) {
|
||||||
|
looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);
|
||||||
|
}
|
||||||
|
|
||||||
|
eventQueue = ASensorManager_createEventQueue(sensorManager, looper, 0, NULL,
|
||||||
|
NULL);
|
||||||
|
err = ASensorEventQueue_registerSensor(eventQueue, hallSensor,
|
||||||
|
ASensor_getMinDelay(hallSensor),
|
||||||
|
10000);
|
||||||
|
if (err < 0) {
|
||||||
|
ALOGE("Unable to register for Hall-effect sensor events");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
ALOGI("Starting polling loop");
|
||||||
|
|
||||||
|
// Polling loop
|
||||||
|
while (ALooper_pollAll(-1, NULL, NULL, NULL) == 0) {
|
||||||
|
ASensorEvent sensorEvent;
|
||||||
|
while (ASensorEventQueue_getEvents(eventQueue, &sensorEvent, 1) > 0) {
|
||||||
|
// 1 means closed; 0 means open
|
||||||
|
int isClosed = sensorEvent.data[0] > 0.0f ? 1 : 0;
|
||||||
|
struct input_event event;
|
||||||
|
event.type = EV_SW;
|
||||||
|
event.code = SW_LID;
|
||||||
|
event.value = isClosed;
|
||||||
|
err = TEMP_FAILURE_RETRY(write(uinputFd, &event, sizeof (event)));
|
||||||
|
if (err < 0) {
|
||||||
|
ALOGE("Write EV_SW to uinput node failed: %s", strerror(errno));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Force a flush with an EV_SYN
|
||||||
|
event.type = EV_SYN;
|
||||||
|
event.code = SYN_REPORT;
|
||||||
|
event.value = 0;
|
||||||
|
err = TEMP_FAILURE_RETRY(write(uinputFd, &event, sizeof (event)));
|
||||||
|
if (err < 0) {
|
||||||
|
ALOGE("Write EV_SYN to uinput node failed: %s",
|
||||||
|
strerror(errno));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
ALOGI("Sent lid %s event", isClosed ? "closed" : "open");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
// Clean up
|
||||||
|
if (sensorManager != nullptr && eventQueue != nullptr) {
|
||||||
|
ASensorManager_destroyEventQueue(sensorManager, eventQueue);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uinputFd >= 0) {
|
||||||
|
close(uinputFd);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The loop can only be exited via failure or signal
|
||||||
|
return 1;
|
||||||
|
}
|
|
@ -152,6 +152,18 @@ on boot
|
||||||
chmod 660 /sys/devices/platform/kcal_ctrl.0/kcal_min
|
chmod 660 /sys/devices/platform/kcal_ctrl.0/kcal_min
|
||||||
chmod 660 /sys/devices/platform/kcal_ctrl.0/kcal
|
chmod 660 /sys/devices/platform/kcal_ctrl.0/kcal
|
||||||
|
|
||||||
|
service vendor.folio_daemon /vendor/bin/folio_daemon
|
||||||
|
class late_start
|
||||||
|
user system
|
||||||
|
group system uhid
|
||||||
|
disabled
|
||||||
|
|
||||||
|
on property:init.svc.zygote=running
|
||||||
|
start vendor.folio_daemon
|
||||||
|
|
||||||
|
on property:init.svc.zygote=stopped
|
||||||
|
stop vendor.folio_daemon
|
||||||
|
|
||||||
#Peripheral manager
|
#Peripheral manager
|
||||||
service vendor.per_mgr /system/vendor/bin/pm-service
|
service vendor.per_mgr /system/vendor/bin/pm-service
|
||||||
class core
|
class core
|
||||||
|
|
|
@ -242,6 +242,10 @@ PRODUCT_PACKAGES += \
|
||||||
PRODUCT_COPY_FILES += \
|
PRODUCT_COPY_FILES += \
|
||||||
frameworks/native/data/etc/android.software.freeform_window_management.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.software.freeform_window_management.xml
|
frameworks/native/data/etc/android.software.freeform_window_management.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.software.freeform_window_management.xml
|
||||||
|
|
||||||
|
# Folio
|
||||||
|
PRODUCT_PACKAGES += \
|
||||||
|
folio_daemon
|
||||||
|
|
||||||
# GPS / Location
|
# GPS / Location
|
||||||
PRODUCT_PACKAGES += \
|
PRODUCT_PACKAGES += \
|
||||||
android.hardware.gnss@1.0-impl-qti \
|
android.hardware.gnss@1.0-impl-qti \
|
||||||
|
|
3
sepolicy/vendor/file_contexts
vendored
3
sepolicy/vendor/file_contexts
vendored
|
@ -22,6 +22,9 @@
|
||||||
/firmware u:object_r:firmware_file:s0
|
/firmware u:object_r:firmware_file:s0
|
||||||
/bt_firmware u:object_r:bt_firmware_file:s0
|
/bt_firmware u:object_r:bt_firmware_file:s0
|
||||||
|
|
||||||
|
# Folio daemon
|
||||||
|
/vendor/bin/folio_daemon u:object_r:folio_daemon_exec:s0
|
||||||
|
|
||||||
# HVDCP
|
# HVDCP
|
||||||
/sys/devices(/platform)?/soc/[a-z0-9]+\.i2c/i2c-[0-9]+/[0-9]+-[a-z0-9]+/[a-z0-9]+\.i2c:qcom,[a-z0-9]+@[a-z0-9]:qcom,smb[a-z0-9]+-parallel-slave@[0-9]+/power_supply/parallel(/.*)? u:object_r:sysfs_usb_supply:s0
|
/sys/devices(/platform)?/soc/[a-z0-9]+\.i2c/i2c-[0-9]+/[0-9]+-[a-z0-9]+/[a-z0-9]+\.i2c:qcom,[a-z0-9]+@[a-z0-9]:qcom,smb[a-z0-9]+-parallel-slave@[0-9]+/power_supply/parallel(/.*)? u:object_r:sysfs_usb_supply:s0
|
||||||
|
|
||||||
|
|
4
sepolicy/vendor/folio_daemon.te
vendored
Normal file
4
sepolicy/vendor/folio_daemon.te
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
type folio_daemon, domain;
|
||||||
|
type folio_daemon_exec, exec_type, file_type;
|
||||||
|
|
||||||
|
init_daemon_domain(folio_daemon)
|
Loading…
Reference in a new issue