2017/5/25

reconfig timezone

dpkg-reconfigure tzdata

lxc 不使用default path

default path 是 /var/lib/lxc
要是要改(使用)其他位置,所有的 lxc-XXX 都可以加 -P 指定位置。
例如,要在 ~/hd/lxc 下 create newvm:
lxc-create -P ~/hd/lxc -n newvm
然後啟動的時候要...
lxc-start -F -P ~/hd/lxc -n newvm

-F 是run 在forground mode (有console)

2017/5/24

lxc. debian wheezy..

ref: https://linuxcontainers.org/lxc/getting-started/
template : download, 會去 download 新的,所有的 template..然後列出來..
~$ sudo lxc-create -n download -t download
Setting up the GPG keyring
Downloading the image index

---
DIST RELEASE ARCH VARIANT BUILD
---
centos 6 amd64 default 20170504_02:16
centos 6 i386 default 20170504_02:16
centos 7 amd64 default 20170504_02:16
debian jessie amd64 default 20170504_02:41
debian jessie arm64 default 20170504_22:42
debian jessie armel default 20170505_09:10
debian jessie armhf default 20170504_02:41
debian jessie i386 default 20170505_04:24
debian jessie powerpc default 20170503_22:42
debian jessie ppc64el default 20170429_22:42
debian jessie s390x default 20170504_22:42
debian sid amd64 default 20170504_22:42
debian sid arm64 default 20170504_22:42
debian sid armel default 20170505_09:10
debian sid armhf default 20170504_22:42
debian sid i386 default 20170504_02:41
debian sid powerpc default 20170504_22:42
debian sid ppc64el default 20170429_22:42
debian sid s390x default 20170504_22:42
debian stretch amd64 default 20170504_02:41
debian stretch arm64 default 20170504_22:42
debian stretch armel default 20170505_04:24
debian stretch armhf default 20170504_22:42
debian stretch i386 default 20170505_04:24
debian stretch powerpc default 20161104_22:42
debian stretch ppc64el default 20170429_22:42
debian stretch s390x default 20170504_22:42
debian wheezy amd64 default 20170505_09:10
debian wheezy armel default 20170504_22:42
debian wheezy armhf default 20170504_22:42
debian wheezy i386 default 20170504_22:42
debian wheezy powerpc default 20170504_22:42
debian wheezy s390x default 20170504_22:42
fedora 22 amd64 default 20170216_01:27
fedora 22 i386 default 20170216_02:15
fedora 23 amd64 default 20170215_03:33
fedora 23 i386 default 20170215_01:27
fedora 24 amd64 default 20170505_01:59
fedora 24 i386 default 20170505_01:27
fedora 25 amd64 default 20170505_02:42
fedora 25 i386 default 20170504_01:27
gentoo current amd64 default 20170503_14:12
gentoo current i386 default 20170504_14:12
oracle 6 amd64 default 20170505_11:40
oracle 6 i386 default 20170505_12:47
oracle 7 amd64 default 20170505_12:47
plamo 5.x amd64 default 20170504_23:23
plamo 5.x i386 default 20170429_21:36
plamo 6.x amd64 default 20170504_22:05
plamo 6.x i386 default 20170504_22:05
ubuntu artful amd64 default 20170504_03:49
ubuntu artful arm64 default 20170505_08:26
ubuntu artful armhf default 20170504_03:49
ubuntu artful i386 default 20170504_03:49
ubuntu artful ppc64el default 20170430_03:49
ubuntu artful s390x default 20170504_03:49
ubuntu precise amd64 default 20170504_03:49
ubuntu precise armel default 20170504_03:49
ubuntu precise armhf default 20170504_03:49
ubuntu precise i386 default 20170504_03:49
ubuntu precise powerpc default 20170505_03:49
ubuntu trusty amd64 default 20170504_03:49
ubuntu trusty arm64 default 20170505_10:25
ubuntu trusty armhf default 20170504_03:49
ubuntu trusty i386 default 20170504_03:49
ubuntu trusty powerpc default 20170505_03:49
ubuntu trusty ppc64el default 20170429_10:37
ubuntu xenial amd64 default 20170504_03:49
ubuntu xenial arm64 default 20170504_03:49
ubuntu xenial armhf default 20170504_03:49
ubuntu xenial i386 default 20170504_03:49
ubuntu xenial powerpc default 20170504_03:49
ubuntu xenial ppc64el default 20170430_03:49
ubuntu xenial s390x default 20170505_08:26
ubuntu yakkety amd64 default 20170504_03:49
ubuntu yakkety arm64 default 20170505_10:25
ubuntu yakkety armhf default 20170504_03:49
ubuntu yakkety i386 default 20170504_03:49
ubuntu yakkety powerpc default 20170505_03:49
ubuntu yakkety ppc64el default 20170430_03:49
ubuntu yakkety s390x default 20170505_08:26
ubuntu zesty amd64 default 20170504_03:49
ubuntu zesty arm64 default 20170504_03:49
ubuntu zesty armhf default 20170504_03:49
ubuntu zesty i386 default 20170504_03:49
ubuntu zesty powerpc default 20170317_03:49
ubuntu zesty ppc64el default 20170430_03:49
ubuntu zesty s390x default 20170504_03:49
---

Distribution: debian
Release: wheezy
Architecture: amd64

Downloading the image index
Downloading the rootfs
Downloading the metadata
The image cache is now ready
Unpacking the rootfs

---
You just created a Debian container (release=wheezy, arch=amd64, variant=default)

To enable sshd, run: apt-get install openssh-server

For security reason, container images ship without user accounts
and without a root password.

Use lxc-attach or chroot directly into the rootfs to set a root password
or create user accounts.

然後真的要像說明一樣,chroot 過去,設定 root 的 password:
sudo chroot /var/lib/lxc/download/rootfs
在 chroot 後用 passwd 改 root password。
然後要apt-get install vi,然後就會發現找不到 http://httpredir.debian.org
這是因為 dns 錯的關係,因為沒有vi,只好手動..
rm /etc/resolv.conf
echo 10.244.128.5 >> /etc/resolv.conf
之後就可以用 apt-get 了。
chroot 之後用 apt-get install vim
也可順便install iputils-ping

之後就可以用 lxc-start 啟動,login..

host 的 network setup 就像上一篇一樣,用 lxcbr0 static ip.
所以 /var/lib/lxc/download/config 的內容就跟上次一樣 ...
# Template used to create this container: /usr/share/lxc/templates/lxc-download
# Parameters passed to the template:
# For additional config options, please look at lxc.container.conf(5)

# Distribution configuration
lxc.include = /usr/share/lxc/config/debian.common.conf
lxc.arch = x86_64

# Container specific configuration
lxc.rootfs = /var/lib/lxc/download/rootfs
lxc.utsname = download

# Network configuration
lxc.network.type = veth
lxc.network.link = lxcbr0
lxc.network.flags = up
第一次啟動,因為 /etc/network/interfaces 的內容還是 dhcp,所以會等一下,timeout 後,登入 root, 再修改 /etc/network/interfaces..
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
address 10.10.20.10
netmask 255.255.255.0
gateway 10.10.20.1
dns-nameservers 10.244.128.5 10.244.128.6
重新啟動後,網路就正常了..

2017/5/23

brctl bridge

brctl 就操作 bridge network 的command,
network bridge 可以視為 軟體的網卡。
brctl addbr br0
就等於插了一張網卡 br0
這時候用 ifconfig 就可以操作 br0 了,像一般網卡一樣設定 ipaddres... etc

另外這個網卡有兩個端點,一個端點接到本機,就叫 br0.
另外一端可以隨你高興接到那裡..
這個就要用 brctl 命令才操作。
--- 略 (我也部會)

在 /etc/network/interfaces 裡也可以 config bridge 網卡..
和一般nic 的差異是,property 會有 ..bridge_ports 和 一堆 bridge_XXX
其中 bridge_ports 就是指定另一端要接到哪裡..
auto mybr0
iface mybr0 inet dhcp
  bridge_ports eth0
就會把 另一端接到 eth0 出口 ..
這樣就可以像 eth0 nic 一樣,從外面的dhcp server 拿到 ip ..

用在 lxc 時,另一端就接到 lxc vm 上,
所以就先給一個隨便的名子。
lxc vm 啟動的時候,他會依照 config 的內容把自己的 nic bound 到 mybr0 上..

log -- lxc static ip nat

sudo brctl addbr lxcbr0
sudo ifconfig -a lxcbr0
lxcbr0    Link encap:Ethernet  HWaddr b2:63:51:ae:XX:XX  
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
sudo ifconfig lxcbr0 10.10.20.1/24 up
sudo ifconfig -a lxcbr0
lxcbr0    Link encap:Ethernet  HWaddr b2:63:51:ae:XX:XX  
          inet addr:10.10.20.1  Bcast:10.10.20.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:38 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:0 (0.0 B)  TX bytes:8756 (8.5 KiB)


修改 /var/lib/lxc/mylxc/config:
#lxc.network.type = empty
lxc.network.type = vnet
lxc.network.link = lxcbr0
lxc.network.flags = up

啟動 lxc-start -n mylxc
這時候,host 的 iface 會多出一個 奇怪名子的 interface,跟 lxcbr0 bound 在一起..
host 上...
sudo ifconfig
lxcbr0    Link encap:Ethernet  HWaddr fe:0f:87:47:XX  
          inet addr:10.10.20.1  Bcast:10.10.20.255  Mask:255.255.255.0
          inet6 addr: fe80::fc83:faff:fe48:5849/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:16 errors:0 dropped:0 overruns:0 frame:0
          TX packets:161 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:1072 (1.0 KiB)  TX bytes:27958 (27.3 KiB)

veth3JU39Y Link encap:Ethernet  HWaddr fe:0f:87:47:XX  
          inet6 addr: fe80::fc0f:87ff:fe47:d33f/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:8 errors:0 dropped:0 overruns:0 frame:0
          TX packets:56 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:648 (648.0 B)  TX bytes:6440 (6.2 KiB)

用 brctl 來看...
sudo brctl show
bridge name bridge id  STP enabled interfaces
lxcbr0  8000.fe0f8747d33f no  veth3JU39Y
現在看 lxc ...
mylxc 的 /etc/network/interfaces
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
address 10.10.20.10
netmask 255.255.255.0

如果不是,改好以後重開機..
ifconfig 看已經是 eth0 10.10.20.10 了,但是用 route -n 看..
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
10.10.20.0      0.0.0.0         255.255.255.0   U     0      0        0 eth0
沒有 default gateway...
手動設..
route add default gw 10.10.20.1
route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         10.10.20.1      0.0.0.0         UG    0      0        0 eth0
10.10.20.0      0.0.0.0         255.255.255.0   U     0      0        0 eth0
這時後 ping 10.10.20.1 已經OK

lxc . static ip,

就 lxc-create 完後直接 lxc-start。
rootfs 已經改好,不用進去 mknode tty..
stop 的時候就 lxc-stop --nokill
如果直接 lxc-stop ,就會hang住很久,然後有 input/output error


最後是 ref:https://l3net.wordpress.com/2013/08/25/debian-virtualization-lxc-network-isolation/
手動 啟動 bridge 才讓 lxc 的網路連通。

host:
# brctl addbr br0
# ifconfig br0 10.10.20.1/24 up
然後 /var/lib/lxc/my1stcontainer/config:
# Template used to create this container: /usr/share/lxc/templates/lxc-debian
# Parameters passed to the template:
# For additional config options, please look at lxc.container.conf(5)
#lxc.network.type = empty
lxc.rootfs = /var/lib/lxc/my1stcontainer/rootfs

# Common configuration
lxc.include = /usr/share/lxc/config/debian.common.conf

# Container specific configuration
lxc.mount = /var/lib/lxc/my1stcontainer/fstab
lxc.utsname = my1stcontainer
lxc.arch = amd64
lxc.autodev = 1
lxc.kmsg = 0


lxc.network.type = veth
lxc.network.link = br0
lxc.network.flags = up
lxc.network.ipv4 = 10.10.20.10/24
lxc.network.ipv4.gateway = 10.10.20.1

lxc 的 /etc/network/interfaces:
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
address 10.10.20.10
netmask 255.255.255.0
gateway 10.10.20.1
nameserver 10.244.128.5
奇怪的是 lxc 裡的 network/interfaces gateway, nameserver 好像沒五有用。default gateway 要設在 /var/lib/lxc/xxx/config 裡才行。
nameserver 沒有辦法設在 config,所以目前無解。

這樣設定後, host 加上 nat,lxc 就出的去了...

了解了,要是在 /var/lib/lxc/my1stcontainer/config 裡面設 ipv4 address, netmask. gateway 等等。
在 my1stcontainer 裡的 /etc/network/interfaces 的 ipaddress, netmask, gateway, dns-nameserver 等設定都會被忽略。
所以 /etc/resolv.conf 就不會依照 interfaces 的內容 update, ..

所以.. /var/lib/lxc/my1stcontainer/config 只要設定基本的就好...
lxc.network.type = veth
lxc.network.link = lxcbr0
lxc.network.flags = up
然後在 my1stcontainer 裡的 /etc/network/interfaces 就可以設得完整一點...
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
address 10.10.20.10
netmask 255.255.255.0
gateway 10.10.20.1
network 10.10.20.0
broadcast 10.10.20.25
dns-nameservers 10.244.128.5 10.244.128.6
至於 手動啟動 br0 部份,也可以改在 host 的 /etc/network/interfaces 裡...
auto lxcbr0
iface lxcbr0 inet static
   address 10.10.20.1
   netmask 255.255.255.0
   bridge_ports dummy0

nat, masquerade...

How IP Masquerade Works
說得非常清楚呀...
第一就說,要是個 gateway,這樣才會有轉發的功能,其他的機器才會藉由他轉發。

然後,masquerade 的工作就是把所有出去的 封包,重新找一個 port 給他 (所以只有 tcp 能用),同時換掉他的 source ip,把 private 的換成自己的(output 的,public 的)。
然後把這格 port 記起剌,紀錄他原來的 ip (private ip) 和 port。
之後,只要這個 port 收到的封包,就依照當初紀錄的內容,把 dest ip 和 port 換掉。換回 private ip 和 port,再送回去。

大概是因為,這格動作是雙向的,所以在 nat masquerade rule 上只需要列一條:是從那一個 interface (ip) 出去的,要做 masquerade,
這樣自然就包含把 收到的 換回原來的動作。不用幫收到的再寫一條。
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
封包只有在出去的時候做就可以了,所以是 POSTROUTING.

...如果是本機的 output 經過 postrouting, 做 masquerade 的話,ip 就一樣 ,只有 port 會被改,大概就連 port 也沒改了。


這個 rule 大概就可以讓其他的 ip 出去,不需要加 filter table 的 FORWARD rule

測試一下...
先記一下 reset 的 command: flush
iptables -t nat --flush
list rule..
iptables -t nat --list
恩,真的,只要一個 nat, postrouting, masquerade rule 就可以了。

2017/5/17

4.4 build fail

Compiling SDK Stubs: out/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates/classes.jar
rm -rf out/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates/classes
mkdir -p out/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates/classes
find out/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates/src -name "*.java" > \
        out/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates/java-source-list
javac -J-Xmx512M -target 1.7 -Xmaxerrs 9999999 -encoding ascii -bootclasspath "" \
   -g -Xlint:unchecked \
   -extdirs "" -d out/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates/classes \
   \@out/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates/java-source-list \
  || ( rm -rf out/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates/classes ; exit 41 )
out/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates/src/android/telephony/gsm/SmsMessage.java:3: error: modifier static not allowed here
public static class SmsMessage
              ^
手動....

packages/apps/Gallery2/src/com/android/gallery3d/util/LinkedNode.java:59: error: mNext has private access in LinkedNode
            return (T) (node.mNext == mHead ? null : node.mNext);
                            ^
packages/apps/Gallery2/src/com/android/gallery3d/util/LinkedNode.java:59: error: mNext has private access in LinkedNode
            return (T) (node.mNext == mHead ? null : node.mNext);
                                                         ^
packages/apps/Gallery2/src/com/android/gallery3d/util/LinkedNode.java:63: error: mPrev has private access in LinkedNode
            return (T) (node.mPrev == mHead ? null : node.mPrev);
                            ^
packages/apps/Gallery2/src/com/android/gallery3d/util/LinkedNode.java:63: error: mPrev has private access in LinkedNode
            return (T) (node.mPrev == mHead ? null : node.mPrev);
                                                         ^
依照說明,把 private comment 掉...

target Dex: telephony-common
out/host/linux-x86/bin/dx -JXms16M -JXmx2048M --dex --output=out/target/common/obj/JAVA_LIBRARIES/telephony-common_intermediates/classes-with-local.dex     out/target/common/obj/JAVA_LIBRARIES/telephony-common_intermediates/noproguard.classes.jar

UNEXPECTED TOP-LEVEL EXCEPTION:
com.android.dex.util.ExceptionWithContext
 at com.android.dex.util.ExceptionWithContext.withContext(ExceptionWithContext.java:45)
 at com.android.dx.dex.cf.CfTranslator.processMethods(CfTranslator.java:371)
 at com.android.dx.dex.cf.CfTranslator.translate0(CfTranslator.java:139)
 at com.android.dx.dex.cf.CfTranslator.translate(CfTranslator.java:94)
 at com.android.dx.command.dexer.Main.processClass(Main.java:682)
 at com.android.dx.command.dexer.Main.processFileBytes(Main.java:634)
 at com.android.dx.command.dexer.Main.access$600(Main.java:78)
 at com.android.dx.command.dexer.Main$1.processFileBytes(Main.java:572)
 at com.android.dx.cf.direct.ClassPathOpener.processArchive(ClassPathOpener.java:284)
 at com.android.dx.cf.direct.ClassPathOpener.processOne(ClassPathOpener.java:166)
 at com.android.dx.cf.direct.ClassPathOpener.process(ClassPathOpener.java:144)
 at com.android.dx.command.dexer.Main.processOne(Main.java:596)
 at com.android.dx.command.dexer.Main.processAllFiles(Main.java:498)
 at com.android.dx.command.dexer.Main.runMonoDex(Main.java:264)
 at com.android.dx.command.dexer.Main.run(Main.java:230)
 at com.android.dx.command.dexer.Main.main(Main.java:199)
 at com.android.dx.command.Main.main(Main.java:103)
Caused by: java.lang.NullPointerException
 at com.android.dx.cf.code.ConcreteMethod.(ConcreteMethod.java:87)
 at com.android.dx.cf.code.ConcreteMethod.(ConcreteMethod.java:75)
 at com.android.dx.dex.cf.CfTranslator.processMethods(CfTranslator.java:273)
 ... 15 more
...while processing  (Lcom/android/internal/telephony/gsm/GSMPhone;)V
...while processing com/android/internal/telephony/gsm/GSMPhone$1.class

1 error; aborting
make: *** [out/target/common/obj/JAVA_LIBRARIES/telephony-common_intermediates/classes-with-local.dex] Error 1

2017/5/15

assign weaker access privileges

所以順便看一下 "assign weaker access privileges"..

結果是overwrite parent class 時,使用了比較 weak 的 scope 宣告。

然後 strong.... weak 的順序是...
public -- protected -- default -- private

也就是說...繼承的class 可以開放 parent class 的內容,但是不能限縮 parent 囉...

ref: https://javadevelopersguide.blogspot.tw/2013/07/attempting-to-assign-weaker-access.html

舊版 android (2.3) 使用openjdk..

build 的時候,出現 Error:
cts/apps/CtsVerifier/src/com/android/cts/verifier/PassFailButtons.java:191: 
onCreateDialog(int,android.os.Bundle) in android.app.Activity cannot implement onCreateDialog(int,android.os.Bundle) 
in com.android.cts.verifier.PassFailButtons.PassFailActivity; 
attempting to assign weaker access privileges; was public
    private static <T extends android.app.Activity & PassFailActivity>
                    ^
1 error
m



所以..參考4.4 的...
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/PassFailButtons.java b/apps/CtsVerifier/src/com/android/cts/verifier/PassFailButtons.java
index 9991b9d..9bd0665 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/PassFailButtons.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/PassFailButtons.java
@@ -76,8 +76,6 @@ public class PassFailButtons {
 
         Button getPassButton();
 
-        /* Added to the interface just to make sure it isn't forgotten in the implementations. */
-        Dialog onCreateDialog(int id, Bundle args);
 
         /**
          * Returns a unique identifier for the test.  Usually, this is just the class name.

2017/5/10

repo 超慢

到 android 6 之後,repo 的操作超慢,還是 local mirror ..

所以測試一下..

另外 mirro 一次,但是只有sync 需要的 branch.. depth 也只有 10
repo init ....... --depth=10
sync -c
這個 .repo 約 35G.完整的是 45G
好像差異不大,但是 repo status.

2017/5/9

Flutter ..

Fushia 竟然有 UI 了,果然是 javascript...
所以來試一下 google 的 Flutter

2017/5/3

關閉 selinux

系統啟動後要關閉 selinux, 可以在 kernel bootcmd 中加上...
但是有時候bootcmd 無法更動。只能改在system. root 上。
就是在 init.rc 中加上 setenforce 0

但是要注意,這個command 本身也受到 selinux 的限制,
所以要把 init 的 setenforce 的 permission 打開。

打開 init 的 setenforce,要修改 android/device/--/sepolicy 下的 common/init_shell.te
加上 
allow init_shell selinuxfs:file rw_file_perms;
allow init_shell kernel:security setenforce;

Android device as a receiver for A2DP profile

http://stackoverflow.com/questions/27763756/android-device-as-a-receiver-for-a2dp-profile
Since Android L the BlueDriod stack does support A2DP sink, but it is disabled by default.

To enable it do the following:

/* Enable bluetooth av sink. */
#define BTA_AV_SINK_INCLUDED TRUE
in /external/bluetooth/bluedroid/include/bt_target.h. This enables sink support in the bluetooth stack.

Also you have to do this change:


true
in /packages/apps/Bluetooth/res/values/config.xml. This enables the particular UI.

Now you can pair your devices and start streaming. 
Unfortunately you will hear no sound although you'll receive the packets. 
The reason is that there is no audio route for A2DP sink. 
In the commit message of this patch https://android-review.googlesource.com/#/c/98161/ you can find a sample implementation on how to fix this.

Here is a list of these changes:

https://android-review.googlesource.com/#/c/97832/
https://android-review.googlesource.com/#/c/97853/
https://android-review.googlesource.com/#/c/97833/
https://android-review.googlesource.com/#/c/98130/
https://android-review.googlesource.com/#/c/98131/

2017/5/2

    public void onActionClicked(Action action) {
        switch (action.getId()) {
            case ACTION_RESET_DEVICE:
                if (!ActivityManager.isUserAMonkey()) {
                    Intent resetIntent = new Intent("android.intent.action.MASTER_CLEAR");
                    if (getIntent().getBooleanExtra(SHUTDOWN_INTENT_EXTRA, false)) {
                        resetIntent.putExtra(SHUTDOWN_INTENT_EXTRA, true);
                    }
                    sendBroadcast(resetIntent);
                }
                break;