From b487b4aa4d58bad5b2e5ad58a8ee30a7a7f6df16 Mon Sep 17 00:00:00 2001 From: Andrew Lehmer Date: Wed, 29 Mar 2017 10:17:06 -0700 Subject: [PATCH] clover: Add support for folio cases Bug: 35243564 Test: Used magnet to wake and lock device. Also tested during suspend. Change-Id: I4b819e12cc23a3d7a8ce048e208c15eac4f8d6c5 Signed-off-by: pix106 --- device.mk | 4 + folio_daemon/Android.mk | 22 +++++ folio_daemon/main.cpp | 147 ++++++++++++++++++++++++++++++++ rootdir/etc/init.device.rc | 13 +++ sepolicy/vendor/file_contexts | 2 + sepolicy/vendor/folio_daemon.te | 4 + 6 files changed, 192 insertions(+) create mode 100755 folio_daemon/Android.mk create mode 100644 folio_daemon/main.cpp create mode 100644 sepolicy/vendor/file_contexts create mode 100644 sepolicy/vendor/folio_daemon.te diff --git a/device.mk b/device.mk index ba790dd..4bd725a 100644 --- a/device.mk +++ b/device.mk @@ -43,6 +43,10 @@ TARGET_SCREEN_WIDTH := 1200 # Device properties $(call inherit-product, $(DEVICE_PATH)/device_prop.mk) +# Folio +PRODUCT_PACKAGES += \ + folio_daemon + # HW crypto PRODUCT_PACKAGES += \ vendor.qti.hardware.cryptfshw@1.0-service-qti.qsee diff --git a/folio_daemon/Android.mk b/folio_daemon/Android.mk new file mode 100755 index 0000000..4ba8512 --- /dev/null +++ b/folio_daemon/Android.mk @@ -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) diff --git a/folio_daemon/main.cpp b/folio_daemon/main.cpp new file mode 100644 index 0000000..417cffe --- /dev/null +++ b/folio_daemon/main.cpp @@ -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 +#include +#include +#include +#include +#include +#include + +// 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; +} diff --git a/rootdir/etc/init.device.rc b/rootdir/etc/init.device.rc index 92ee433..14d39fd 100644 --- a/rootdir/etc/init.device.rc +++ b/rootdir/etc/init.device.rc @@ -67,3 +67,16 @@ service macaddress_setup /vendor/bin/sh /vendor/bin/init.macaddress_setup.sh user root group root oneshot + +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 + diff --git a/sepolicy/vendor/file_contexts b/sepolicy/vendor/file_contexts new file mode 100644 index 0000000..a9d50a4 --- /dev/null +++ b/sepolicy/vendor/file_contexts @@ -0,0 +1,2 @@ +# Folio daemon +/vendor/bin/folio_daemon u:object_r:folio_daemon_exec:s0 diff --git a/sepolicy/vendor/folio_daemon.te b/sepolicy/vendor/folio_daemon.te new file mode 100644 index 0000000..a4d5444 --- /dev/null +++ b/sepolicy/vendor/folio_daemon.te @@ -0,0 +1,4 @@ +type folio_daemon, domain; +type folio_daemon_exec, exec_type, file_type; + +init_daemon_domain(folio_daemon)