summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Android.mk1
-rw-r--r--otafault/Android.mk3
-rw-r--r--otafault/config.cpp36
-rw-r--r--wear_touch.cpp177
-rw-r--r--wear_touch.h58
5 files changed, 258 insertions, 17 deletions
diff --git a/Android.mk b/Android.mk
index 4477fefe3..5b488ca6d 100644
--- a/Android.mk
+++ b/Android.mk
@@ -41,6 +41,7 @@ LOCAL_SRC_FILES := \
ui.cpp \
verifier.cpp \
wear_ui.cpp \
+ wear_touch.cpp \
LOCAL_MODULE := recovery
diff --git a/otafault/Android.mk b/otafault/Android.mk
index 7468de6c4..ba7add855 100644
--- a/otafault/Android.mk
+++ b/otafault/Android.mk
@@ -17,9 +17,10 @@ LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
otafault_static_libs := \
+ libbase \
libminzip \
libz \
- libselinux \
+ libselinux
LOCAL_SRC_FILES := config.cpp ota_io.cpp
LOCAL_MODULE_TAGS := eng
diff --git a/otafault/config.cpp b/otafault/config.cpp
index c87f9a631..b4567392d 100644
--- a/otafault/config.cpp
+++ b/otafault/config.cpp
@@ -20,6 +20,8 @@
#include <stdio.h>
#include <unistd.h>
+#include <android-base/stringprintf.h>
+
#include "minzip/Zip.h"
#include "config.h"
#include "ota_io.h"
@@ -27,12 +29,10 @@
#define OTAIO_MAX_FNAME_SIZE 128
static ZipArchive* archive;
-static std::map<const char*, bool> should_inject_cache;
+static std::map<std::string, bool> should_inject_cache;
-static const char* get_type_path(const char* io_type) {
- char* path = (char*)calloc(strlen(io_type) + strlen(OTAIO_BASE_DIR) + 2, sizeof(char));
- sprintf(path, "%s/%s", OTAIO_BASE_DIR, io_type);
- return path;
+static std::string get_type_path(const char* io_type) {
+ return android::base::StringPrintf("%s/%s", OTAIO_BASE_DIR, io_type);
}
void ota_io_init(ZipArchive* za) {
@@ -41,13 +41,17 @@ void ota_io_init(ZipArchive* za) {
}
bool should_fault_inject(const char* io_type) {
- if (should_inject_cache.find(io_type) != should_inject_cache.end()) {
- return should_inject_cache[io_type];
+ // archive will be NULL if we used an entry point other
+ // than updater/updater.cpp:main
+ if (archive == NULL) {
+ return false;
+ }
+ const std::string type_path = get_type_path(io_type);
+ if (should_inject_cache.find(type_path) != should_inject_cache.end()) {
+ return should_inject_cache[type_path];
}
- const char* type_path = get_type_path(io_type);
- const ZipEntry* entry = mzFindZipEntry(archive, type_path);
+ const ZipEntry* entry = mzFindZipEntry(archive, type_path.c_str());
should_inject_cache[type_path] = entry != nullptr;
- free((void*)type_path);
return entry != NULL;
}
@@ -56,10 +60,10 @@ bool should_hit_cache() {
}
std::string fault_fname(const char* io_type) {
- const char* type_path = get_type_path(io_type);
- char* fname = (char*) calloc(OTAIO_MAX_FNAME_SIZE, sizeof(char));
- const ZipEntry* entry = mzFindZipEntry(archive, type_path);
- mzReadZipEntry(archive, entry, fname, OTAIO_MAX_FNAME_SIZE);
- free((void*)type_path);
- return std::string(fname);
+ std::string type_path = get_type_path(io_type);
+ std::string fname;
+ fname.resize(OTAIO_MAX_FNAME_SIZE);
+ const ZipEntry* entry = mzFindZipEntry(archive, type_path.c_str());
+ mzReadZipEntry(archive, entry, &fname[0], OTAIO_MAX_FNAME_SIZE);
+ return fname;
}
diff --git a/wear_touch.cpp b/wear_touch.cpp
new file mode 100644
index 000000000..f22d40b88
--- /dev/null
+++ b/wear_touch.cpp
@@ -0,0 +1,177 @@
+/*
+ * 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.
+ */
+
+#include "common.h"
+#include "wear_touch.h"
+
+#include <dirent.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+
+#include <linux/input.h>
+
+#define DEVICE_PATH "/dev/input"
+
+WearSwipeDetector::WearSwipeDetector(int low, int high, OnSwipeCallback callback, void* cookie):
+ mLowThreshold(low),
+ mHighThreshold(high),
+ mCallback(callback),
+ mCookie(cookie),
+ mCurrentSlot(-1) {
+ pthread_create(&mThread, NULL, touch_thread, this);
+}
+
+WearSwipeDetector::~WearSwipeDetector() {
+}
+
+void WearSwipeDetector::detect(int dx, int dy) {
+ enum SwipeDirection direction;
+
+ if (abs(dy) < mLowThreshold && abs(dx) > mHighThreshold) {
+ direction = dx < 0 ? LEFT : RIGHT;
+ } else if (abs(dx) < mLowThreshold && abs(dy) > mHighThreshold) {
+ direction = dy < 0 ? UP : DOWN;
+ } else {
+ LOGD("Ignore %d %d\n", dx, dy);
+ return;
+ }
+
+ LOGD("Swipe direction=%d\n", direction);
+ mCallback(mCookie, direction);
+}
+
+void WearSwipeDetector::process(struct input_event *event) {
+ if (mCurrentSlot < 0) {
+ mCallback(mCookie, UP);
+ mCurrentSlot = 0;
+ }
+
+ if (event->type == EV_ABS) {
+ if (event->code == ABS_MT_SLOT)
+ mCurrentSlot = event->value;
+
+ // Ignore other fingers
+ if (mCurrentSlot > 0) {
+ return;
+ }
+
+ switch (event->code) {
+ case ABS_MT_POSITION_X:
+ mX = event->value;
+ mFingerDown = true;
+ break;
+
+ case ABS_MT_POSITION_Y:
+ mY = event->value;
+ mFingerDown = true;
+ break;
+
+ case ABS_MT_TRACKING_ID:
+ if (event->value < 0)
+ mFingerDown = false;
+ break;
+ }
+ } else if (event->type == EV_SYN) {
+ if (event->code == SYN_REPORT) {
+ if (mFingerDown && !mSwiping) {
+ mStartX = mX;
+ mStartY = mY;
+ mSwiping = true;
+ } else if (!mFingerDown && mSwiping) {
+ mSwiping = false;
+ detect(mX - mStartX, mY - mStartY);
+ }
+ }
+ }
+}
+
+void WearSwipeDetector::run() {
+ int fd = findDevice(DEVICE_PATH);
+ if (fd < 0) {
+ LOGE("no input devices found\n");
+ return;
+ }
+
+ struct input_event event;
+ while (read(fd, &event, sizeof(event)) == sizeof(event)) {
+ process(&event);
+ }
+
+ close(fd);
+}
+
+void* WearSwipeDetector::touch_thread(void* cookie) {
+ ((WearSwipeDetector*)cookie)->run();
+ return NULL;
+}
+
+#define test_bit(bit, array) (array[bit/8] & (1<<(bit%8)))
+
+int WearSwipeDetector::openDevice(const char *device) {
+ int fd = open(device, O_RDONLY);
+ if (fd < 0) {
+ LOGE("could not open %s, %s\n", device, strerror(errno));
+ return false;
+ }
+
+ char name[80];
+ name[sizeof(name) - 1] = '\0';
+ if (ioctl(fd, EVIOCGNAME(sizeof(name) - 1), &name) < 1) {
+ LOGE("could not get device name for %s, %s\n", device, strerror(errno));
+ name[0] = '\0';
+ }
+
+ uint8_t bits[512];
+ memset(bits, 0, sizeof(bits));
+ int ret = ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(bits)), bits);
+ if (ret > 0) {
+ if (test_bit(ABS_MT_POSITION_X, bits) && test_bit(ABS_MT_POSITION_Y, bits)) {
+ LOGD("Found %s %s\n", device, name);
+ return fd;
+ }
+ }
+
+ close(fd);
+ return -1;
+}
+
+int WearSwipeDetector::findDevice(const char* path) {
+ DIR* dir = opendir(path);
+ if (dir == NULL) {
+ LOGE("Could not open directory %s", path);
+ return false;
+ }
+
+ struct dirent* entry;
+ int ret = -1;
+ while (ret < 0 && (entry = readdir(dir)) != NULL) {
+ if (entry->d_name[0] == '.') continue;
+
+ char device[PATH_MAX];
+ device[PATH_MAX-1] = '\0';
+ snprintf(device, PATH_MAX-1, "%s/%s", path, entry->d_name);
+
+ ret = openDevice(device);
+ }
+
+ closedir(dir);
+ return ret;
+}
+
diff --git a/wear_touch.h b/wear_touch.h
new file mode 100644
index 000000000..9a1d3150c
--- /dev/null
+++ b/wear_touch.h
@@ -0,0 +1,58 @@
+/*
+ * 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 __WEAR_TOUCH_H
+#define __WEAR_TOUCH_H
+
+#include <pthread.h>
+
+class WearSwipeDetector {
+
+public:
+ enum SwipeDirection { UP, DOWN, RIGHT, LEFT };
+ typedef void (*OnSwipeCallback)(void* cookie, enum SwipeDirection direction);
+
+ WearSwipeDetector(int low, int high, OnSwipeCallback cb, void* cookie);
+ ~WearSwipeDetector();
+
+private:
+ void run();
+ void process(struct input_event *event);
+ void detect(int dx, int dy);
+
+ pthread_t mThread;
+ static void* touch_thread(void* cookie);
+
+ int findDevice(const char* path);
+ int openDevice(const char* device);
+
+ int mLowThreshold;
+ int mHighThreshold;
+
+ OnSwipeCallback mCallback;
+ void *mCookie;
+
+ int mX;
+ int mY;
+ int mStartX;
+ int mStartY;
+
+ int mCurrentSlot;
+ bool mFingerDown;
+ bool mSwiping;
+};
+
+#endif // __WEAR_TOUCH_H