Allow customizing WearRecoveryUI via Makefile variables.

With the following Makefile variables, we can reduce the work of writing
(copy/pasting) device-specific WearRecoveryUI classes.

The list of Makefile variables (the ones useful for Wear devices):
- TARGET_RECOVERY_UI_MARGIN_HEIGHT (default: 0)
- TARGET_RECOVERY_UI_MARGIN_WIDTH (default: 0)
  Specify the margin space that we don't want to display texts. They
  replace the former outer_width and outer_height.

- TARGET_RECOVERY_UI_TOUCH_LOW_THRESHOLD (default: 50)
- TARGET_RECOVERY_UI_TOUCH_HIGH_THRESHOLD (default: 90)
  Specify the sensitivity of recognizing a swipe. Devices give absolute
  positions, so for some devices we need to adjust the thresholds.

- TARGET_RECOVERY_UI_PROGRESS_BAR_BASELINE
  Specify the progress bar vertical position, which should be adjusted
  to the actual height of a device. It replaces the former
  progress_bar_y.

- TARGET_RECOVERY_UI_ANIMATION_FPS (default: 30)
  Specify the animation FPS if using device-specific animation images.
  It replaces the former animation_fps.

Devices can specify "TARGET_RECOVERY_UI_LIB := librecovery_ui_wear",
with optionally defined Makefile vars above, in BoardConfig.mk to
customize their WearRecoveryUI.

Also remove the obsolete wear_touch.{cpp,h}, which has been merged into
ui.cpp in commit 5f8dd9951d.

Bug: 64307776
Test: Change the device BoardConfig.mk and test recovery image.
Change-Id: Id0fb2d4e3977ab5ddd31e71f9535470cab70e41b
This commit is contained in:
Tao Bao 2017-08-02 17:11:04 -07:00
parent 0459799ea8
commit 0470ceea38
8 changed files with 64 additions and 253 deletions

View file

@ -79,7 +79,6 @@ LOCAL_SRC_FILES := \
ui.cpp \
vr_ui.cpp \
wear_ui.cpp \
wear_touch.cpp \
LOCAL_MODULE := recovery
@ -120,6 +119,18 @@ else
LOCAL_CFLAGS += -DRECOVERY_UI_TOUCH_HIGH_THRESHOLD=90
endif
ifneq ($(TARGET_RECOVERY_UI_PROGRESS_BAR_BASELINE),)
LOCAL_CFLAGS += -DRECOVERY_UI_PROGRESS_BAR_BASELINE=$(TARGET_RECOVERY_UI_PROGRESS_BAR_BASELINE)
else
LOCAL_CFLAGS += -DRECOVERY_UI_PROGRESS_BAR_BASELINE=259
endif
ifneq ($(TARGET_RECOVERY_UI_ANIMATION_FPS),)
LOCAL_CFLAGS += -DRECOVERY_UI_ANIMATION_FPS=$(TARGET_RECOVERY_UI_ANIMATION_FPS)
else
LOCAL_CFLAGS += -DRECOVERY_UI_ANIMATION_FPS=30
endif
ifneq ($(TARGET_RECOVERY_UI_VR_STEREO_OFFSET),)
LOCAL_CFLAGS += -DRECOVERY_UI_VR_STEREO_OFFSET=$(TARGET_RECOVERY_UI_VR_STEREO_OFFSET)
else
@ -216,6 +227,16 @@ LOCAL_STATIC_LIBRARIES := \
LOCAL_CFLAGS := -Werror
include $(BUILD_STATIC_LIBRARY)
# Wear default device
# ===============================
include $(CLEAR_VARS)
LOCAL_SRC_FILES := wear_device.cpp
# Should match TARGET_RECOVERY_UI_LIB in BoardConfig.mk.
LOCAL_MODULE := librecovery_ui_wear
include $(BUILD_STATIC_LIBRARY)
# vr headset default device
# ===============================
include $(CLEAR_VARS)

View file

@ -53,6 +53,7 @@ static double now() {
ScreenRecoveryUI::ScreenRecoveryUI()
: kMarginWidth(RECOVERY_UI_MARGIN_WIDTH),
kMarginHeight(RECOVERY_UI_MARGIN_HEIGHT),
kAnimationFps(RECOVERY_UI_ANIMATION_FPS),
density_(static_cast<float>(android::base::GetIntProperty("ro.sf.lcd_density", 160)) / 160.f),
currentIcon(NONE),
progressBarType(EMPTY),
@ -77,7 +78,6 @@ ScreenRecoveryUI::ScreenRecoveryUI()
loop_frames(0),
current_frame(0),
intro_done(false),
animation_fps(30), // TODO: there's currently no way to infer this.
stage(-1),
max_stage(-1),
updateMutex(PTHREAD_MUTEX_INITIALIZER) {}
@ -375,7 +375,7 @@ void* ScreenRecoveryUI::ProgressThreadStartRoutine(void* data) {
}
void ScreenRecoveryUI::ProgressThreadLoop() {
double interval = 1.0 / animation_fps;
double interval = 1.0 / kAnimationFps;
while (true) {
double start = now();
pthread_mutex_lock(&updateMutex);

View file

@ -84,6 +84,9 @@ class ScreenRecoveryUI : public RecoveryUI {
const int kMarginWidth;
const int kMarginHeight;
// Number of frames per sec (default: 30) for both parts of the animation.
const int kAnimationFps;
// The scale factor from dp to pixels. 1.0 for mdpi, 4.0 for xxxhdpi.
const float density_;
@ -141,9 +144,6 @@ class ScreenRecoveryUI : public RecoveryUI {
size_t current_frame;
bool intro_done;
// Number of frames per sec (default: 30) for both parts of the animation.
int animation_fps;
int stage, max_stage;
int char_width_;

23
wear_device.cpp Normal file
View file

@ -0,0 +1,23 @@
/*
* Copyright (C) 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 "device.h"
#include "wear_ui.h"
Device* make_device() {
return new Device(new WearRecoveryUI);
}

View file

@ -1,177 +0,0 @@
/*
* 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 <dirent.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <android-base/logging.h>
#include <linux/input.h>
#include "wear_touch.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 {
LOG(DEBUG) << "Ignore " << dx << " " << dy;
return;
}
LOG(DEBUG) << "Swipe direction=" << 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) {
LOG(ERROR) << "no input devices found";
return;
}
struct input_event event;
while (read(fd, &event, sizeof(event)) == sizeof(event)) {
process(&event);
}
close(fd);
}
void* WearSwipeDetector::touch_thread(void* cookie) {
(static_cast<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) {
PLOG(ERROR) << "could not open " << device;
return false;
}
char name[80];
name[sizeof(name) - 1] = '\0';
if (ioctl(fd, EVIOCGNAME(sizeof(name) - 1), &name) < 1) {
PLOG(ERROR) << "could not get device name for " << device;
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)) {
LOG(DEBUG) << "Found " << device << " " << name;
return fd;
}
}
close(fd);
return -1;
}
int WearSwipeDetector::findDevice(const char* path) {
DIR* dir = opendir(path);
if (dir == NULL) {
PLOG(ERROR) << "Could not open directory " << 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;
}

View file

@ -1,58 +0,0 @@
/*
* 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

View file

@ -51,10 +51,15 @@ static double now() {
}
WearRecoveryUI::WearRecoveryUI()
: progress_bar_y(259), outer_height(0), outer_width(0), menu_unusable_rows(0) {
: kProgressBarBaseline(RECOVERY_UI_PROGRESS_BAR_BASELINE), menu_unusable_rows(9) {
// TODO: menu_unusable_rows should be computed based on the lines in draw_screen_locked().
// TODO: The following three variables are likely not needed. The first two are detected
// automatically in ScreenRecoveryUI::LoadAnimation(), based on the actual files seen on device.
intro_frames = 22;
loop_frames = 60;
animation_fps = 30;
touch_screen_allowed_ = true;
for (size_t i = 0; i < 5; i++) backgroundIcon[i] = NULL;
@ -62,7 +67,7 @@ WearRecoveryUI::WearRecoveryUI()
}
int WearRecoveryUI::GetProgressBaseline() const {
return progress_bar_y;
return kProgressBarBaseline;
}
// Draw background frame on the screen. Does not flip pages.
@ -113,8 +118,8 @@ void WearRecoveryUI::draw_screen_locked() {
SetColor(TEXT_FILL);
gr_fill(0, 0, gr_fb_width(), gr_fb_height());
int y = outer_height;
int x = outer_width;
int y = kMarginHeight;
int x = kMarginWidth;
if (show_menu) {
std::string recovery_fingerprint =
android::base::GetProperty("ro.bootimage.build.fingerprint", "");
@ -170,7 +175,7 @@ void WearRecoveryUI::draw_screen_locked() {
int ty;
int row = (text_top_ + text_rows_ - 1) % text_rows_;
size_t count = 0;
for (int ty = gr_fb_height() - char_height_ - outer_height; ty > y + 2 && count < text_rows_;
for (int ty = gr_fb_height() - char_height_ - kMarginHeight; ty > y + 2 && count < text_rows_;
ty -= char_height_, ++count) {
gr_text(gr_sys_font(), x + 4, ty, text_[row], 0);
--row;
@ -190,12 +195,12 @@ bool WearRecoveryUI::InitTextParams() {
return false;
}
text_cols_ = (gr_fb_width() - (outer_width * 2)) / char_width_;
text_cols_ = (gr_fb_width() - (kMarginWidth * 2)) / char_width_;
if (text_rows_ > kMaxRows) text_rows_ = kMaxRows;
if (text_cols_ > kMaxCols) text_cols_ = kMaxCols;
visible_text_rows = (gr_fb_height() - (outer_height * 2)) / char_height_;
visible_text_rows = (gr_fb_height() - (kMarginHeight * 2)) / char_height_;
return true;
}

View file

@ -42,10 +42,7 @@ class WearRecoveryUI : public ScreenRecoveryUI {
protected:
// progress bar vertical position, it's centered horizontally
int progress_bar_y;
// outer of window
int outer_height, outer_width;
const int kProgressBarBaseline;
// Unusable rows when displaying the recovery menu, including the lines for headers (Android
// Recovery, build id and etc) and the bottom lines that may otherwise go out of the screen.