[JAVA] Add the pre-built jar library to Android and call it in the framework

What to do

  1. Create a test jar library and add the jar library to AOSP
  2. Call the API of the library added in 1 from within the framework (quick setting panel)
  3. Add an AWS library and try calling it from within the framework

1. Create test jar library

Create a jar library that implements a simple API that returns the test string "test".

Test.java


package com.testlib;


public class Test {
    public String getTestString() {
        return "test";
    }
}

--Jar creation

$ javac Test.java
$ jar -cvf test-lib.jar *.class

Copy the jar created above to the AOSP source below

/prebuilts/misc/common/test-lib/test-lib.jar

Also create 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. Call the API of the library added in 1 from the quick setting panel

2-1. Source modification

When tapping the tile of the quick setting panel added appropriately, modify the AOSP source so that the character string "test" obtained from the above API is displayed in Toast.

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. Build

--Build

$ make -j4

--System UI replacement

$ adb remount
$ adb push out/target/product/bullhead/system/priv-app/SystemUI /system/priv-app/
$ adb reboot

2-3. Operation check

Try tapping the tile

You can confirm that the API of the added library is called normally.

3. Add an AWS library and try calling it from within the framework

3-1. Library preparation

AWS SDK for Android

Is copied under / prebuilts / misc / common / aws.

I got an error if Gson was not found, so copy the Gson jar to / prebuilts / misc / common / gson as well.

3-2. Try using Lambda

Similarly, modify it so that Lambda is called when the tile is tapped.

Official reference 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

Source modification difference

3-3. Send a bug report to S3

You can get the bug report from the settings, but like the above, insert a wire so that you can get the bug report when you tap the tile.

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 {

Also, since the following will be called when the bug report acquisition is completed, add the process to save the bug report in S3 below.

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);

Source modification difference

Replace with build

$ 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

Try tapping the tile.

image.png

You can see that it is saved in S3.

3-4. Try saving records in DynamoDB

Source modification difference

After tapping the tile, you can confirm that the record is saved in DynamoDB ↓

image.png


Note

Error 1

SystemUI sometimes crashed due to Fatal Exception such as permission android.permission.READ_CONTACTS after startup, but it was solved by simply 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)

Error 2

In DynamoDB, even though DynamoDBHashKey is attached, the following error was found that it could not be found.

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)

It seems that it is a mistake to register an exception in the proguard file as shown below

-keep class com.android.systemui.qs.tiles.AOSPTest { *; }

Recommended Posts

Add the pre-built jar library to Android and call it in the framework
Is it possible to put the library (aar) in the Android library (aar) and use it?
3 ways to import the library in Android Studio
Add a time stamp to the JAR file name in Gradle
How to add jar file in ScalaIDE
Java to C and C to Java in Android Studio
Add the date to the GC statistics acquired by gcutil and output it.
Get YouTube video information with Retrofit and keep it in the Android app.
How to add sound in the app (swift)
Add classpath: to the path specified in spring.datasource.schema
[Android development] Get an image from the server in Java and set it in ImageView! !!
I want to morphologically analyze the log in the DB and put it in the DB to classify messages 1
Bind the request to any class and receive it
Write a class in Kotlin and call it in Java
Java classes and instances to understand in the figure
How to debug the generated jar file in Eclipse
Add files to jar files
How to add another project as Maven library with CircleCI and use it for build
Click the [rails] button to create a random alphanumeric password and enter it in the password field
Refer to C ++ in the Android Studio module (Java / kotlin)
[Android, Java] Convenient method to calculate the difference in days
Android app to select and display images from the gallery
Implement Java Interface in JRuby class and call it from Java
I want to call a method and count the number
[Code golf] Deflate the code and submit it to AtCoder [Compressed golf]
How to call and use API in Java (Spring Boot)
How to add the same Indexes in a nested array
Add a shadow to the Swift Button (and also the circle)
Contributed to Gradle and was named in the release notes
Code to specify the image name as a character string and paste it into ImageView (android)
4 Add println to the interpreter
It doesn't respond to the description in .js of the packs file
I opened the menu bar (option menu) on Android and saw it.
How to set and use profile in annotation-based Configuration in Spring framework
[jOOQ] How to CASE WHEN in the WHERE / AND / OR clause
Method to add the number of years and get the end of the month
How to install the language used in Ubuntu and how to build the environment
"Wait for the process to finish." And kill the process because it remains.
How to get and add data from Firebase Firestore in Ruby
[Android] Convert Map to JSON using GSON in Kotlin and Java
Sample code to call the Yahoo! Local Search API in Java
Steps to install Maven on Mac and use it in Eclipse
Things to remember and concepts in the Ruby on Rails tutorial
How to call multiple names at once in the same category
[Android] I want to get the listener from the button in ListView
[Java] Output the result of ffprobe -show_streams in JSON and map it to an object with Jackson
An error occurred in the free course of RubyOnRails Udemy, solved it, and went through to the end