行うこと
- テストjarライブラリを作成してAOSPにjarライブラリを追加
- フレームワーク内(クイック設定パネル)から1で追加したライブラリのAPIの呼び出し
- AWSのライブラリを追加してフレームワーク内から呼び出してみる
1. テストjarライブラリ作成
テスト文字列"test"を返す簡易的なAPIを実装したjarライブラリを作成する。
package com.testlib;
public class Test {
public String getTestString() {
return "test";
}
}
- jar作成
$ javac Test.java
$ jar -cvf test-lib.jar *.class
上記で作成されたjarをAOSPソースの以下にコピー
/prebuilts/misc/common/test-lib/test-lib.jar
Android.mkも作成
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_PREBUILT_JAVA_LIBRARIES := test-lib$(COMMON_JAVA_PACKAGE_SUFFIX)
include $(BUILD_HOST_PREBUILT)
2. クイック設定パネルから1で追加したライブラリのAPIの呼び出し
2-1. ソース修正
適当に追加したクイック設定パネルのタイルをタップ時に、上記APIから取得した文字列"test"をToastで表示するようにAOSPソースに修正を入れる。
+import android.widget.Toast;
...
+import com.testlib.Test;
...
@Override
protected void handleClick() {
+ Test test = new Test();
+ Toast.makeText(mContext , test.getTestString(), Toast.LENGTH_SHORT).show();
try {
...
LOCAL_STATIC_JAVA_LIBRARIES := \
SystemUI-tags \
SystemUI-proto
LOCAL_STATIC_JAVA_LIBRARIES += test-lib
...
include $(BUILD_PACKAGE)
+include $(CLEAR_VARS)
+LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := test-lib:../../../../prebuilts/misc/common/test-lib/test-+lib.jar#libs/test_lib/test-lib.jar
+include $(BUILD_MULTI_PREBUILT)
include $(call all-makefiles-under,$(LOCAL_PATH))
...
2-2. ビルド
- ビルド
$ make -j4
- SystemUI差し替え
$ adb remount
$ adb push out/target/product/bullhead/system/priv-app/SystemUI /system/priv-app/
$ adb reboot
2-3. 動作確認
タイルをタップしてみる
追加したライブラリのAPIが正常に呼ばれていることが確認できる。
3. AWSのライブラリを追加してフレームワーク内から呼び出してみる
3-1. ライブラリ準備
AWS SDK for Androidの
- aws-android-sdk-core.jar
- aws-android-sdk-lambda.jar
- aws-android-sdk-s3.jar
- aws-android-sdk-ddb.jar
- aws-android-sdk-ddb-mapper.jar
- aws-android-sdk-cognito.jar
を/prebuilts/misc/common/aws配下にコピーする。
Gsonが見つからないとエラーが出たのでGsonのjarも/prebuilts/misc/common/gsonにコピーしておく。
3-2. Lambdaを使ってみる
同様にタイルタップ時にLambdaを呼び出すように改変する。
公式参考
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/with-android-example.html
https://docs.aws.amazon.com/ja_jp/aws-mobile/latest/developerguide/how-to-android-lambda.html
3-3. S3にbugreportを送ってみる
設定からもbugreportは取得できるが、上記同様にタイルタップ時にbugreportを取得されるように導線をいれる。
+ private Handler mHandler = new Handler();
...
@Override
protected void handleClick() {
+ mHandler.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ ActivityManager.getService().requestBugReport(
+ ActivityManager.BUGREPORT_OPTION_INTERACTIVE
+ );
+ } catch (RemoteException e) {
+ Log.e(TAG, "requestBugReport() failed");
+ }
+ }
+ }, 500);
try {
また、bugreport取得完了時に下記がコールされるようなので、下記にS3にbugreportを保存する処理を追加する。
frameworks/base/packages/Shell/src/com/android/shell/BugreportProgressService.java#onBugreportFinished
private void onBugreportFinished(int id, Intent intent) {
final File bugreportFile = getFileExtra(intent, EXTRA_BUGREPORT);
if (bugreportFile == null) {
// Should never happen, dumpstate always set the file.
Log.wtf(TAG, "Missing " + EXTRA_BUGREPORT + " on intent " + intent);
return;
}
+
+ try {
+ final String S3_ACCESS_KEY = "YOUR_ACCESS_KEY";
+ final String S3_SECRET_KEY = "YOUR_SECRET_KEY";
+ AmazonS3Client S3Client = new AmazonS3Client(
+ new BasicAWSCredentials(S3_ACCESS_KEY, S3_SECRET_KEY)
+ );
+ final String BUCKET_NAME = "aosp_test";
+ PutObjectRequest por = new PutObjectRequest(
+ BUCKET_NAME,
+ bugreportFile.getName(),
+ bugreportFile
+ );
+ S3Client.putObject(por);
+ } catch (final Exception e) {
+ Log.e(TAG, "Failed to save bugreport to S3", e);
+ }
mInfoDialog.onBugreportFinished();
BugreportInfo info = getInfo(id);
ビルドと差し替え
$ make -j4
$ adb remount
$ adb push out/target/product/bullhead/system/priv-app/SystemUI /system/priv-app/
$ adb push out/target/product/bullhead/system/priv-app/Shell /system/priv-app/
$ adb reboot
タイルをタップしてみる。
S3に保存されていることが確認できる。
3-4. DynamoDBにレコードを保存してみる
タイルタップ後、DynamoDBにレコードが保存されていることが確認できる↓
メモ
エラー1
起動後permission android.permission.READ_CONTACTSが~といったFatal ExceptionでSystemUIが落ちることがあったが、単にFDRしたら解決。
01-22 18:59:06.852: D/AndroidRuntime(4784): Shutting down VM
01-22 18:59:06.855: E/AndroidRuntime(4784): FATAL EXCEPTION: main
01-22 18:59:06.855: E/AndroidRuntime(4784): Process: com.android.systemui, PID: 4784
01-22 18:59:06.855: E/AndroidRuntime(4784): java.lang.RuntimeException: Unable to create service com.android.systemui.SystemUIService: android.view.InflateException: Binary XML file line #73: uid=10062 needs permission android.permission.READ_CONTACTS to read lock_screen_owner_info_enabled for user 0
01-22 18:59:06.855: E/AndroidRuntime(4784): at android.app.ActivityThread.handleCreateService(ActivityThread.java:3349)
01-22 18:59:06.855: E/AndroidRuntime(4784): at android.app.ActivityThread.-wrap4(Unknown Source:0)
01-22 18:59:06.855: E/AndroidRuntime(4784): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1677)
01-22 18:59:06.855: E/AndroidRuntime(4784): at android.os.Handler.dispatchMessage(Handler.java:106)
01-22 18:59:06.855: E/AndroidRuntime(4784): at android.os.Looper.loop(Looper.java:164)
01-22 18:59:06.855: E/AndroidRuntime(4784): at android.app.ActivityThread.main(ActivityThread.java:6494)
01-22 18:59:06.855: E/AndroidRuntime(4784): at java.lang.reflect.Method.invoke(Native Method)
01-22 18:59:06.855: E/AndroidRuntime(4784): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
01-22 18:59:06.855: E/AndroidRuntime(4784): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
01-22 18:59:06.855: E/AndroidRuntime(4784): Caused by: android.view.InflateException: Binary XML file line #73: uid=10062 needs permission android.permission.READ_CONTACTS to read lock_screen_owner_info_enabled for user 0
01-22 18:59:06.855: E/AndroidRuntime(4784): Caused by: java.lang.SecurityException: uid=10062 needs permission android.permission.READ_CONTACTS to read lock_screen_owner_info_enabled for user 0
01-22 18:59:06.855: E/AndroidRuntime(4784): at android.os.Parcel.readException(Parcel.java:2004)
01-22 18:59:06.855: E/AndroidRuntime(4784): at android.os.Parcel.readException(Parcel.java:1950)
01-22 18:59:06.855: E/AndroidRuntime(4784): at com.android.internal.widget.ILockSettings$Stub$Proxy.getBoolean(ILockSettings.java:476)
01-22 18:59:06.855: E/AndroidRuntime(4784): at com.android.internal.widget.LockPatternUtils.getBoolean(LockPatternUtils.java:1271)
01-22 18:59:06.855: E/AndroidRuntime(4784): at com.android.internal.widget.LockPatternUtils.isOwnerInfoEnabled(LockPatternUtils.java:738)
01-22 18:59:06.855: E/AndroidRuntime(4784): at com.android.keyguard.KeyguardStatusView.getOwnerInfo(KeyguardStatusView.java:273)
01-22 18:59:06.855: E/AndroidRuntime(4784): at com.android.keyguard.KeyguardStatusView.updateOwnerInfo(KeyguardStatusView.java:244)
01-22 18:59:06.855: E/AndroidRuntime(4784): at com.android.keyguard.KeyguardStatusView.onFinishInflate(KeyguardStatusView.java:170)
01-22 18:59:06.855: E/AndroidRuntime(4784): at android.view.LayoutInflater.rInflate(LayoutInflater.java:876)
01-22 18:59:06.855: E/AndroidRuntime(4784): at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:824)
01-22 18:59:06.855: E/AndroidRuntime(4784): at android.view.LayoutInflater.parseInclude(LayoutInflater.java:995)
01-22 18:59:06.855: E/AndroidRuntime(4784): at android.view.LayoutInflater.rInflate(LayoutInflater.java:859)
01-22 18:59:06.855: E/AndroidRuntime(4784): at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:824)
01-22 18:59:06.855: E/AndroidRuntime(4784): at android.view.LayoutInflater.parseInclude(LayoutInflater.java:995)
01-22 18:59:06.855: E/AndroidRuntime(4784): at android.view.LayoutInflater.rInflate(LayoutInflater.java:859)
01-22 18:59:06.855: E/AndroidRuntime(4784): at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:824)
01-22 18:59:06.855: E/AndroidRuntime(4784): at android.view.LayoutInflater.inflate(LayoutInflater.java:515)
01-22 18:59:06.855: E/AndroidRuntime(4784): at android.view.LayoutInflater.inflate(LayoutInflater.java:423)
01-22 18:59:06.855: E/AndroidRuntime(4784): at android.view.LayoutInflater.inflate(LayoutInflater.java:374)
01-22 18:59:06.855: E/AndroidRuntime(4784): at android.view.View.inflate(View.java:23239)
01-22 18:59:06.855: E/AndroidRuntime(4784): at com.android.systemui.statusbar.phone.StatusBar.inflateStatusBarWindow(StatusBar.java:1440)
01-22 18:59:06.855: E/AndroidRuntime(4784): at com.android.systemui.statusbar.phone.StatusBar.makeStatusBarView(StatusBar.java:1009)
01-22 18:59:06.855: E/AndroidRuntime(4784): at com.android.systemui.statusbar.phone.StatusBar.addStatusBarWindow(StatusBar.java:3664)
01-22 18:59:06.855: E/AndroidRuntime(4784): at com.android.systemui.statusbar.phone.StatusBar.createAndAddWindows(StatusBar.java:3660)
01-22 18:59:06.855: E/AndroidRuntime(4784): at com.android.systemui.statusbar.phone.StatusBar.start(StatusBar.java:889)
01-22 18:59:06.855: E/AndroidRuntime(4784): at com.android.systemui.SystemBars.createStatusBarFromConfig(SystemBars.java:71)
01-22 18:59:06.855: E/AndroidRuntime(4784): at com.android.systemui.SystemBars.start(SystemBars.java:42)
01-22 18:59:06.855: E/AndroidRuntime(4784): at com.android.systemui.SystemUIApplication.startServicesIfNeeded(SystemUIApplication.java:215)
01-22 18:59:06.855: E/AndroidRuntime(4784): at com.android.systemui.SystemUIApplication.startServicesIfNeeded(SystemUIApplication.java:164)
01-22 18:59:06.855: E/AndroidRuntime(4784): at com.android.systemui.SystemUIService.onCreate(SystemUIService.java:33)
01-22 18:59:06.855: E/AndroidRuntime(4784): at android.app.ActivityThread.handleCreateService(ActivityThread.java:3339)
01-22 18:59:06.855: E/AndroidRuntime(4784): at android.app.ActivityThread.-wrap4(Unknown Source:0)
01-22 18:59:06.855: E/AndroidRuntime(4784): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1677)
01-22 18:59:06.855: E/AndroidRuntime(4784): at android.os.Handler.dispatchMessage(Handler.java:106)
01-22 18:59:06.855: E/AndroidRuntime(4784): at android.os.Looper.loop(Looper.java:164)
01-22 18:59:06.855: E/AndroidRuntime(4784): at android.app.ActivityThread.main(ActivityThread.java:6494)
01-22 18:59:06.855: E/AndroidRuntime(4784): at java.lang.reflect.Method.invoke(Native Method)
01-22 18:59:06.855: E/AndroidRuntime(4784): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
01-22 18:59:06.855: E/AndroidRuntime(4784): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
エラー2
DynamoDBで、DynamoDBHashKeyは付けているにもかかわらず、下記のように見つからない旨のエラーが出た。
11-06 00:22:42.371: E/AndroidRuntime(832): FATAL EXCEPTION: Thread-3
11-06 00:22:42.371: E/AndroidRuntime(832): Process: com.android.systemui, PID: 832
11-06 00:22:42.371: E/AndroidRuntime(832): com.amazonaws.mobileconnectors.dynamodbv2.dynamodbmapper.DynamoDBMappingException: No interface com.amazonaws.mobileconnectors.dynamodbv2.dynamodbmapper.DynamoDBHashKey annotation found in class class com.android.systemui.qs.tiles.AOSPTest
11-06 00:22:42.371: E/AndroidRuntime(832): at com.amazonaws.mobileconnectors.dynamodbv2.dynamodbmapper.DynamoDBMapper.needAutoGenerateAssignableKey(DynamoDBMapper.java:944)
11-06 00:22:42.371: E/AndroidRuntime(832): at com.amazonaws.mobileconnectors.dynamodbv2.dynamodbmapper.DynamoDBMapper.save(DynamoDBMapper.java:1008)
11-06 00:22:42.371: E/AndroidRuntime(832): at com.amazonaws.mobileconnectors.dynamodbv2.dynamodbmapper.DynamoDBMapper.save(DynamoDBMapper.java:909)
11-06 00:22:42.371: E/AndroidRuntime(832): at com.android.systemui.qs.tiles.LoggingTile$1.run(LoggingTile.java:57)
proguardのファイルに下記のように例外登録するのがミソな模様
-keep class com.android.systemui.qs.tiles.AOSPTest { *; }