alpine_works

wifi
https://wiki.alpinelinux.org/wiki/Connecting_to_a_wireless_access_point

Portaudio:

  1. download

    http://www.portaudio.com/download.html
    http://www.portaudio.com/archives/pa_stable_v190600_20161030.tgz

  2. config portaudio and make

    $ ./configure --prefix=$HOME/.programs/portaudio/ --enable-cxx --with-oss --enable-debug-output
    $ make
    $ make install

lib在lib/.libs/libportaudio.a

AVS sdk

  1. Download
    git clone https://github.com/alexa/avs-device-sdk.git --depth=10 -b v1.12

Build guide can be found at https://github.com/alexa/avs-device-sdk/wiki/Linux-Reference-Guide

  1. patch code to eliminate compiler warning “Missing sentinel in function call”, change the last param of var_args from NULL to nullptr fixes this.

    g_object_set(m_pipeline.audioSink, "sync", FALSE, NULL);
    ->
    g_object_set(m_pipeline.audioSink, "sync", FALSE, nullptr);
  2. config and make

export a=12345678
echo $a
echo ${a:2}
/my_volume/build # cat 1.sh
PA_INCLUDE=`pkgconf --cflags-only-I portaudiocpp`
PA_LIBS=`pkgconf --libs-only-L portaudiocpp`
PA_INC_PATH=${PA_INCLUDE:2}
PA_LIB_PATH=`echo ${PA_LIBS:2}/libportaudio.a | sed "s/ //g"`
cmake ../avs-device-sdk \
-DSENSORY_KEY_WORD_DETECTOR=OFF \
-DGSTREAMER_MEDIA_PLAYER=ON \
-DPORTAUDIO=ON \
-DPORTAUDIO_LIB_PATH=${PA_LIB_PATH} \
-DPORTAUDIO_INCLUDE_DIR=${PA_INC_PATH}

Sensory/alexa-rpi

git clone https://github.com/Sensory/alexa-rpi.git

OpenBLAS

git clone https://github.com/xianyi/OpenBLAS.git -b v0.3.5 --depth=10

Snowboy

git clone https://github.com/Kitt-AI/snowboy.git

程序的静态库
gcc -c snprintf_chk.c
ar -rcs libmissing.a snprintf_chk.o

embed python script inside Makefile

Sometimes it’s necessary to embed some lines of python script inside Makefile, here is some examples:

1. original python snippet:

x = "2018-12-25"
match = re.search(r'^(\d{4})-(\d{2})-(\d{2})', x)
if match:
    y = int(match.group(1)) - 2000
    m = int(match.group(2))
    # 7 bits allocated for the year, 4 bits for the month
    assert y >= 0 and y < 128
    assert m > 0 and m <= 12
    print (y << 4) | m
else:
    print ('Something is wrong')

Output is:

300

2. single line makefile command:

We can use http://jagt.github.io/python-single-line-convert/ to generate the 1-line command for makefiles.

theCmd := """import re\nx = '2018-12-25'\nmatch = re.search(r'^(\\d{4})-(\\d{2})-(\\d{2})', x)\nif match:\n    y = int(match.group(1)) - 2000\n    m = int(match.group(2))\n    assert y >= -1 and y < 128\n    assert m > 0 and m <= 12\n    print (y << 4) | m\nelse:\n    print ('Something is wrong')\n"""
osPatchLvl := $(shell echo -e $(theCmd) | python)
single:
    echo $(osPatchLvl)

3. multiple line Makefile commands:

Conversion tips:

s/^/\\n/g
s/$/"/g

and make sure no misleading ‘ or “ inside each line.
Converted multi-line commands are:

theCmdStr := "import re"
theCmdStr += "\nx = '2018-12-25'"
theCmdStr += "\nmatch = re.search(r'^(\d{4})-(\d{2})-(\d{2})', x)"
theCmdStr += "\nif match:"
theCmdStr += "\n    y = int(match.group(1)) - 2000"
theCmdStr += "\n    m = int(match.group(2))"
theCmdStr += "\n    assert y >= 0 and y < 128"
theCmdStr += "\n    assert m > 0 and m <= 12"
theCmdStr += "\n    print (y << 4) | m"
theCmdStr += "\nelse:"
theCmdStr += "\n    print ('Something is wrong')"
osPatchLvl2 := $(shell echo -e $(theCmdStr) | python)
multi:
    echo $(osPatchLvl2)

java keystore和apk签名

1.转换pk8到java keystore:

1.1 命令行制定密码,默认密码为android

把platform.pk8转换成java keystore

openssl pkcs8 -inform DER -nocrypt -in platform.pk8 -out platform.pem
openssl pkcs12 -export -in platform.x509.pem -out platform.p12 \
    -inkey  platform.pem -password pass:android -name androiddebugkey
keytool -importkeystore -deststorepass android -destkeystore \
    ./platform.jks -srckeystore ./platform.p12 \
    -srcstoretype PKCS12 -srcstorepass android

1.2 提示输入密码

把platform.pk8转换成java keystore

openssl pkcs8 -inform DER -nocrypt -in platform.pk8 -out platform.pem

alias为platform,提示输入密码

openssl pkcs12 -export -in platform.x509.pem -out platform.p12 
    -inkey  platform.pem -name platform

提示输入密码

keytool -importkeystore -destkeystore ./platform.jks \
    -srckeystore ./platform.p12 -srcstoretype PKCS12

###其他常用指令

手动生成java keystore:

keytool  -genkeypair -keystore me.jks -alias me.jks

查看keystore内容

keytool -list -v -keystore me.jks

给jar签名

jarsigner -keystore me.jks -signedjar <new.jar> <old.jar> me.jks

compiling opencv for Java

1. 参考文档

install in linux and mac
http://docs.opencv.org/2.4/doc/tutorials/introduction/linux_install/linux_install.html
java
http://docs.opencv.org/2.4/doc/tutorials/introduction/desktop_java/java_dev_intro.html
http://docs.opencv.org/trunk/d7/d9f/tutorial_linux_install.html

2. linux编译要点

cmake配置

cmake -D CMAKE_BUILD_TYPE=RELEASE \
    -D CMAKE_INSTALL_PREFIX=/home/yu/.programs/opencv \
    -DBUILD_SHARED_LIBS=OFF \
    BUILD_EXAMPLES=OFF \
    BUILD_TESTS=OFF \
    BUILD_PERF_TESTS=OFF ..

编译安装

make -j32
make install

为动态库配置路径

opencv: pkg-config

export PKG_CONFIG_PATH=/home/yu/.programs/opencv/lib/pkgconfig

opencv: dylib

export LD_LIBRARY_PATH=/home/yu/.programs/opencv/share/OpenCV/java

3. mac编译要点

cmake配置

cmake -D CMAKE_BUILD_TYPE=RELEASE -D \
    CMAKE_INSTALL_PREFIX=/Users/yu/.programs/opencv/ \
    -DBUILD_SHARED_LIBS=OFF ..

编译安装

make -j32
make install

安装后只有一个dylib: ./share/OpenCV/java/libopencv_java320.dylib, 其余都为.a

配置路径

opencv: pkg-config

export PKG_CONFIG_PATH=/Users/yu/.programs/opencv/lib/pkgconfig/

opencv: dylib

export DYLD_LIBRARY_PATH=/Users/yu/.programs/opencv/share/OpenCV/java

Bug: /dev/input/eventX 事件阻碍kernel suspend flow

Bug: /dev/input/eventX 事件阻碍kernel suspend flow

1.相关模块:

###(1) Android: InputReader

frameworks/native/services/inputflinger/EventHub.cpp
会注册epoll wakeup source,
epoll_ctl(/dev/input/), flag设成了EPOLLWAKEUP

###(2)Kernel: drivers/input/input.c

input_dev_suspend()-> input_dev_release_keys() ->
kernel认为:当前按着的key等resume回来之后不会继续hold住,所以要释放所有的key。(Simulate keyup events for all keys that are marked as pressed.)

2.解决方案:kernel修复自己的bug:

commit a5f5a6880ba2645af793ddba96e95c96cac3194e
Author: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Date:   Thu Aug 6 19:15:30 2015 -0700

    Input: do not emit unneeded EV_SYN when suspending

    backport 00159f19a5057cb779146afce1cceede692af346 upstream.

    Do not emit EV_SYN/SYN_REPORT on suspend if there were no keys that are
    still pressed as we are suspending the device (and in all other cases when
    input core is forcibly releasing keys via input_dev_release_keys() call).

    Reviewed-by: Benson Leung <bleung@chromium.org>
    Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>

改动如下

diff --git a/drivers/input/input.c b/drivers/input/input.c
index 29ca0bb..087255a 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -667,6 +667,7 @@ EXPORT_SYMBOL(input_close_device);
  */
 static void input_dev_release_keys(struct input_dev *dev)
 {
+       bool need_sync = false;
        int code;

        if (is_event_supported(EV_KEY, dev->evbit, EV_MAX)) {
@@ -674,9 +675,11 @@ static void input_dev_release_keys(struct input_dev *dev)
                        if (is_event_supported(code, dev->keybit, KEY_MAX) &&
                            __test_and_clear_bit(code, dev->key)) {
                                input_pass_event(dev, EV_KEY, code, 0);
+                               need_sync = true;
                        }
                }
-               input_pass_event(dev, EV_SYN, SYN_REPORT, 1);
+               if (need_sync)
+                       input_pass_event(dev, EV_SYN, SYN_REPORT, 1);
        }
 }

Android - Factory Reset Protection(FRP)

Purpose:

Google want to “reduce the value of a stolen device” by factory reset protection

可选性:

GMS强制要求frp,依赖于Google Play Service 6.7.x+

如何打开该功能:

当且仅且满足如下条件:

Google Account exists on a device
OEM locked (Settings->Developer Option)

时,frp会打开。默认打开。

需要一个raw分区, 指定frp分区(factory reset protection)

ro.frp.pst=/dev/block/platform/sdhci-tegra.3/by-name/PST
ro.frp.pst=/dev/block/platform/msm_sdcc.1/by-name/frp

shamu:

PRODUCT_PROPERTY_OVERRIDES += \
    ro.frp.pst=/dev/block/platform/msm_sdcc.1/by-name/frp

大小:500K-2M
格式: raw
权限:只有指定的system进程可以访问。用overlay配置config_persistentDataPackageName, 用GMS的话就是com.google.android.gms
分区最后一个byte用来指定OEM lock状态。0 - locked (fastboot oem unlock执行会失败)。工厂必须默认0.

功能:

  • 只要有google账户,有网络,就可以远程通过Android Device Manager(ADM)锁屏
  • frp打开后,如下操作会提示密码:在主用户上添加google账户;删除最后一个google账户
  • frp打开后,只有在Settings下做factory reset才会清除reset token,重新打开setup wizard时才不需要密码 (trusted factory reset)
  • frp打开后,bootloader下或者ADM下做factory reset不会清除reset token,重新打开setup wizard时会提示输入密码。 (untrusted factory reset), 只要输入的账户/密码符合之前任意一个google账户即可。

术语

Trusted Factory Reset:指的是PersistentDataBlockService#wipe(),实际上就是ioctl(fd, BLKSECDISCARD, &range)

实现

Platform API:存储frp数据PersistentDataBlockManager
GMS core module:在分区上写入google自己数据

API

  • IPersistentDataBlockService.aidl
    service
  • PersistentDataBlockManager.java
  • PersistentDataBlockService.java
  • com_android_server_PersistentDataBlockService.cpp

用户设置:

Setting需要如下权限:”android.permission.OEM_UNLOCK_STATE”

D/PersistentNotificationBroadcastReceiver( 1198): Received intent: Intent { act=android.intent.action.BOOT_COMPLETED flg=0x8000010 cmp=com.google.android.gms/.common.notification.PersistentNotificationBroadcastReceiver (has extras) }

Android BackupManager

主要源文件
BackupManagerService.java
Bmgr.java

配置文件指定默认transport
frameworks/base/packages/SettingsProvider/res/values/defaults.xml

gms默认配置

<string name="def_backup_transport">com.google.android.backup/.BackupTransportService</string>

AOSP默认配置transport: LocalTransport

<string name="def_backup_transport" translatable="false">android/com.android.internal.backup.LocalTransport</string>

其他参考

<service
android:name="com.android.internal.backup.LocalTransportService"
android:permission="android.permission.CONFIRM_FULL_BACKUP"
android:exported="false">

<intent-filter>
<action android:name="android.backup.TRANSPORT_HOST" />
</intent-filter>
</service>

BackupManagerService会从PackageManger中找到所有能接收android.backup.TRANSPORT_HOST的service,

List<ResolveInfo> hosts = mPackageManager.queryIntentServicesAsUser(
mTransportServiceIntent, 0, UserHandle.USER_OWNER);

之后就可以用bmgr list transports列出

shell@bg4ct_spruce:/ # bmgr list transports
android/com.android.internal.backup.LocalTransport
* com.google.android.gms/.backup.BackupTransportService


root@bg4ct_spruce:/ # bmgr enabled
Backup Manager currently disabled

root@bg4ct_spruce:/ # bmgr enable true
Backup Manager now enabled

切换android transport

bmgr transport android/com.android.internal.backup.LocalTransport

Android Keyevent test

发送key (system/core/toolbox/sendevent.c)

发送长按POWER键:(long press)

input keyevent --longpress POWER

or

sendevent /dev/input/event0 1 116 1
sendevent /dev/input/event0 0 0 0
sleep 1
sendevent /dev/input/event0 1 116 0
sendevent /dev/input/event0 0 0 0
sleep 1

KEY_DOWN

sendevent /dev/input/event0 1 108 1
sendevent /dev/input/event0 0 0 0
sendevent /dev/input/event0 1 108 0
sendevent /dev/input/event0 0 0 0

KEY_UP

sendevent /dev/input/event0 1 103 1
sendevent /dev/input/event0 0 0 0
sendevent /dev/input/event0 1 103 0
sendevent /dev/input/event0 0 0 0

发送Power+KeyUp,切换RecoveryUI

sendevent /dev/input/event0 1 116 1
sendevent /dev/input/event0 0 0 0
sendevent /dev/input/event0 1 115 1
sendevent /dev/input/event0 0 0 0
sendevent /dev/input/event0 1 115 0
sendevent /dev/input/event0 0 0 0
sendevent /dev/input/event0 1 116 0
sendevent /dev/input/event0 0 0 0

读取keyevent:

getevent
[    1688.811239] /dev/input/event1: 0004 0004 0007004f
[    1688.811239] /dev/input/event1: 0001 006a 00000001
[    1688.811239] /dev/input/event1: 0000 0000 00000000

[    1688.827260] /dev/input/event1: 0004 0004 0007004f
[    1688.827260] /dev/input/event1: 0001 006a 00000000
[    1688.827260] /dev/input/event1: 0000 0000 00000000

InputDispatcherThread

InputDispatcherThread::threadLoop()
- InputDispatcher::dispatchOnce()
- - InputDispatcher::dispatchOnceInnerLocked()
- - - InputDispatcher::dispatchKeyLocked()
- - - - - InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible()
- - - - - - mPolicy->interceptKeyBeforeDispatching()

按键输入

KeyboardInputMapper::processKey()
- QueuedInputListener::flush()
- - NotifyKeyArgs::notify()
- - - QueuedInputListener::notifyKey()
InputDispatcher::notifyKey()
- mPolicy->interceptKeyBeforeQueueing()

CLI输入

(java)InputManagerService.injectInputEvent()
- (java)InputManagerService.injectInputEventInternal()
- - (java/c)nativeInjectInputEvent()
- - - (c)InputDispatcher::injectInputEvent()
- - - - (c/java)mPolicy->interceptKeyBeforeQueueing()

input flinger测试代码
frameworks/native/services/inputflinger/tests

java input keyevent: jni
frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cpp
调用(jint) im->getInputManager()->getDispatcher()->injectInputEvent()
实现于
frameworks/native/services/inputflinger/InputDispatcher.cpp
打包于
libinputflinger.so

KeyEvent.java定义了keycode,键码
linux/include/uapi/linux/input.h定义了sendevent中的键值

Trouble Shooting - statvfs() too slow

Android Issue: statvfs() too slow

statvfs() takes too much time if newly inserted USB disk (vfat) is very large

Solution

add “usefree” flag

diff --git a/fs/Vfat.cpp b/fs/Vfat.cpp
index 38681c9..04e9a1d 100644
--- a/fs/Vfat.cpp
+++ b/fs/Vfat.cpp
@@ -140,7 +140,7 @@ status_t Mount(const std::string& source, const std::string& target, bool ro,
     flags |= (remount ? MS_REMOUNT : 0);
     sprintf(mountData,
-            "utf8,uid=%d,gid=%d,fmask=%o,dmask=%o,shortname=mixed",
+            "utf8,uid=%d,gid=%d,fmask=%o,dmask=%o,shortname=mixed,usefree",
             ownerUid, ownerGid, permMask, permMask);
     rc = mount(c_source, c_target, "vfat", flags, mountData);

Build AOSP image for Nexus Player

How to build AOSP images for Nexus Player(fugu)

0. Preface

Be sure to read https://developers.google.com/android/images thoroughly to get a basic knowledge of Android factory images and flashing tools.

1. Download AOSP code

repo init -u https://android.googlesource.com/platform/manifest -b android-8.0.0_r12
repo sync

2. Download fw/drivers

Go to https://developers.google.com/android/drivers and search for Nexus Player (“fugu”) section. Download all fufu related firmware.

3. Merge code and prebuilt fw

Unzip the downloaded fw in previous section, and run the embedded script. Please put the extracted files under vendor/asus, vendor/broadcom etc.
Please be noted that you must “Accept” the license when running the embedded script.

4. Build images

Go to Android code root, do envsetup, then:

lunch aosp_fugu-userdebug
make dist -j32

5. flash images

You can get factory images and OTA packages, you can then flash them to the target platform just as what you have done on our Berlin platforms.