LoginSignup
1
0

More than 3 years have passed since last update.

Androidにプリビルドjarライブラリを追加してフレームワーク内で呼び出す

Last updated at Posted at 2019-10-20

行うこと

  1. テストjarライブラリを作成してAOSPにjarライブラリを追加
  2. フレームワーク内(クイック設定パネル)から1で追加したライブラリのAPIの呼び出し
  3. AWSのライブラリを追加してフレームワーク内から呼び出してみる

1. テストjarライブラリ作成

テスト文字列"test"を返す簡易的なAPIを実装したjarライブラリを作成する。

Test.java
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も作成

/prebuilts/misc/common/test-lib/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ソースに修正を入れる。

diff

/frameworks/base/packages/SystemUI/src/com/android/systemui/qs/tiles/LoggingTile.java
+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 {
/frameworks/base/packages/SystemUI/Android.mk
...
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を取得されるように導線をいれる。

packages/SystemUI/src/com/android/systemui/qs/tiles/LoggingTile.java
+    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

frameworks/base/packages/Shell/src/com/android/shell/BugreportProgressService.java
    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

タイルをタップしてみる。

image.png

S3に保存されていることが確認できる。

3-4. DynamoDBにレコードを保存してみる

ソース修正差分

タイルタップ後、DynamoDBにレコードが保存されていることが確認できる↓

image.png


メモ

エラー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 { *; }
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0