How to unit test serial ports in Java on Android - android

I'm aware that Android does not provide out-of-the-box access to the serial ports unless the device is rooted or a custom Android version is flashed, say on a BeagleBone Black board -- which is exactly my case.
Using the Android SerialPort API project I am able to access and test the serial ports of my device through the sample GUI app (slightly modified).
However, I'd like to also add JUnit tests for the Serial API because I will be expanding it into a library module for client programmers to use. I tried using AndroidTestCase, but I'm receiving the error:
java.lang.UnsatisfiedLinkError: Native method not found:
com.XXX.android.serialport_api.SerialPort.open:
(Ljava/lang/String;II)Ljava/io/FileDescriptor;
at com.XXX.android.serialport_api.SerialPort.open(Native
Method)
at com.XXX.android.serialport_api.SerialPort.<init
(SerialPort.java:32)
It seems to me the serialport.so files are not loaded/visible inside the mock environment provided by AndroidTestCase.
I'm using the standard test structure created by the "New Module" wizard in Android Studio.
Any advice or hint would be appreciated because my search on the topic turned nothing out. I'll be happy to provide test class and implementation if needed (although the implementation is pretty much the same as the SerialPort.java class in the open source sample referenced above).

I found the issue. The package name is hardcoded in the pre-compiled .so files. So instead of using a custom package name like com.XXX.XXX one has to put the SerialPort (and other implementing classes) in a top-level package directly under the /java folder. The package name should be exactly android_serialport_api -- just like in the library sample.

Related

What is the correct way of developing an Android platform application using Android Studio (or other IDE)

I am currently working on an Android AOSP project for which I am developing a java module which will be a part of the core services (such as the Phone app, for example).
There are some frameworks I use which are not exposed by default to "regular" apps (which lay in the private framework.jar).
For example: There are places I directly use android.app.IActivityManager's Binder API.
I do own the platform keys, but I not prefer compiling the whole AOSP framework each time I want to make a change.
I also prefer working with Android Studio, but will compromise on compiling the application through the terminal, if not possible.
What is the correct way of working on a project of this kind?
How do AOSP's developers develop their code without re-compiling the whole framework each time?
Update:
The best way I've found so far is to simply create an android studio project, get the framework.jar from the device (adb pull /system/framework/framework.jar) or from the AOSP source code, and add it as a compileOnly or runtimeOnly dependency in the gradle.build file of your app.
dependencies {
compileOnly files('libs/framework.jar')
implementation 'com.android.support:recyclerview-v7:28.0.0'
}
Then just add android:sharedUserId="android.uid.system" to the Android Manifest and compile it using the platform keys.
It should be installable as is.
This post seems to sum it up pretty good:
https://kwagjj.wordpress.com/2017/10/27/building-custom-android-sdk-from-aosp-and-adding-it-to-android-studio/comment-page-1/
Is there any other way?
You can wrap those API callings to a new manager and service. For example, you have a manager called CustomManager, and it will call IActivityManager or other private/hidden API directly. And then you can create a module for you CustomManager, and build jar/aar for it. After every changing, you can copy that generated jar/aar file to you AndroidStudio project. You can use it as a normal library. Actually, there are some examples in AOSP source code, such as SystemUISharedLib, wrapper of SystemUI internal API, used by Launcher3.

Developing Android 9.0 eSIM LPA (system app)

Trying to develop android LPA system app for eSIM with the new Pie API.
The doc says to extend the abstract EuiccService class. But this class is not in the official SDK, and the link in the docs just leads to corresponding file in the android source repo.
I tried using this file/class as a dependency, but it references other internal android classes/annotations and causes build/IDE errors.
Does anyone have an idea how to use this?
Do I really have to pull android src code and somehow reference required class from it?
EDIT: I think I've solved it, found couple of potential solutions, but they were a bit cumbersome. Used the android.jar from here: https://github.com/anggrayudi/android-hidden-api (contains modified android.jar with hidden APIs and internal resources). It didn't work when i replaced the whole file and resulted strange build errors, but i manually transferred the android\service\euicc\ folder to original android.jar of android-28 sdk and it works perfectly (class is available and apk builds without issues). And no need to waste time pulling and building AOSP.
EDIT #2: apparently not fully fixable atm. There's issue with android gradle plugins (at least 3.2.x-3.3.x) where during full sync some build task generates mock classes from android.jar and process fails if it's modified (discussion is here: https://github.com/anggrayudi/android-hidden-api/issues/46). Error looks like this:
Failed to transform file 'android.jar' to match attributes {artifactType=android-mockable-jar, returnDefaultValues=false} using transform MockableJarTransform
There's a workaround for that, though inconvenient:
when you need a full sync for the project, replace the android.jar with original, run sync, restore modified android.jar, the IDE now will run indexing and classes will be available again with build working until next full sync.
Will update this post if/when it's fixed or new solution is found.
EDIT#3: here's probably a final solution for EuiccService case (turned out pretty obvious):
Instead of adding 'android/service/euicc' folder to android.jar, just put it in a separate library and add it as a compileOnly dependency. Since the classes were not in the SDK, the lib should not cause conflict (would be the case if you need to use modified framework or access hidden APIs in already existing classes).
If you are going to create a System APP, you will do it in several ways:
You could call a part of the SystemAPI (a method for example) by reference.
You could make the aplication as a part of the AOSP Project (Downloading the AOSP code, and introducing your app as part of packages/apps/)
You will be able to access system APIs on a rooted device or if you have system permissions (this happens when you flash your app into the device as part of the system image).
However, if you want to be able to call the EuiccService class from Android Studio (for coding purposes), you'll need to add the Android framework jar to your project.
The steps are provided below:
First, you will have to download and build AOSP and generate a framework jar for your target Android version. Check the documentation here to get an idea of how to download and build AOSP.
After a successful build all framework classes are compiled into a jar called classes.jar which can be found at the location out/target/common/obj/JAVA_LIBRARIES/framework_intermediates.
Get this classes.jar and add it to your Android project as a jar file.
Gradle sync the project and start coding.
Please beware that you WILL NOT BE ABLE TO run this app on an Adnroid device where you do not have system permission for this app.

Android NDK: custom WebView compiling from source

My goal is to create a modified version of WebView (call it WebViewCustom) in Android for my personal use in my application. WebView is WebKit based so I need to compile it in C by means of NDK. I am not interested in participating in the open-source Android project now, so my need is just to be able to compile the original C source of WebView and use it as a customized control in my Android application (both SDK and NDK are possible environments for the application). I think it is possible without all that GIT WebKit stuff I am not interested in, but I am not an expert of the Android and WebKit projects. Is it possible to just edit and compile the WebView code and put it in my application as a new control? Can you show me the main steps of this task?
This is certainly possible. The main difficulty in rebuilding android.webkit from source lies in the lack of a correct build environment. It was never intended to be built outside of the target platform, but a couple of simple hacks around the sources make it quite easy to accomplish.
First of all, the whole android.webkit package business has to be renamed for obvious reasons, since an android.webkit.WebView class would already be available during runtime. Use sed on all the frameworks/base/core/java/android/webkit tree for example.
Basically you have to grab the full source tree, initialize a build environment (More information here http://source.android.com/source/initializing.html), make framework to make the internal runtime environment available, create a new development platform, replace all the classes from framework.jar (after building it's in out/target/common/obj/JAVA_LIBRARIES/framework_intermediaries/classes.jar) into android.jar of the platform, build your own webkit package against this new platform that contains the internals.
Check out https://devmaze.wordpress.com/2011/01/18/using-com-android-internal-part-1-introduction/ for more information on getting an internal runtime available for development purposes.
You will also need core_intermediaries, bouncycastle_intermediaries and others in order to compile webkit, these are all available when make framework is invoked, look at the errors when building your webkit package and grep the out/target/common/obj/JAVA_LIBRARIES/ to figure out which classes contain the symbols.
That's not all, however, the package uses libwebcore.so which exposes native methods to the android.webkit package; this would have to have all native method bindings registered to your new package name (in external/webkit/WebKit/android/jni) and be recompiled without prelinking (make libwebcore) and packaged with your application as a native library.
After everything is satisfied, you would then use your own WebView class from your own package instead of the android.webkit one. If you intend to replace android.webview completely - you would have to recompile a framework.jar and replace it inside system/framework/ (root privileges required).

ANTLR and Android

is there any guide how to use ANTLR on Android? I have found some ANTLR portation for Android but it looks like being without any tutorial or manual. Do you know where to find some? (and yes, I have been googling...)
Thx
After reading the README from this ANTLR port:
AntlrJavaRuntime - Earlence Fernandes, The CRePE Project, VU Amsterdam
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The Runtime is available as an external library against which apps can link.
It provides the necessary mechanisms to execute Lexer/Parser code generated by the ANTLR tool.
The model is offline, in the sense that the parser/lexer is generated off the mobile phone on a desktop computer.
The resulting files are transferred to an Android project which then uses this library.
Building
~~~~~~~~
lunch the appropriate target
make AntlrJavaRuntime
verify that AntlrJavaRuntime.xml was placed in /system/etc/permissions and AntlrJavaRuntime.jar was placed in /system/framework
after this, you can run a normal make
It seems to me that the only difference is when you want to run your parser on an Android device (or -emulator) you must include the AntlrJavaRuntime in your Android project/app.
So, writing the grammar, generating a parser and lexer from said grammar would be the same as on a "normal" machine. Here's a previous Q&A that shows how to write a simple expression parser: ANTLR: Is there a simple example?
EDIT
Also see this Q&A: android ANTLR make not working properly
I'm not sure what "using ANTLR" means to you. Here's what it means to me:
I'm assuming that you will create a grammar, generate the parser/lexer Java classes, compile them, deploy them in your Android app, and then let them parse whatever your app sends into an AST.
If you want to know how to do that, there's no better place than the ANTLR documentation or the book you can buy from Amazon.
There is an Android Studio (actually IntelliJ) plug-in for this, called "ANTLR v4 grammar plugin".
This tutorial worked for me.
In short, simply copy grammar (a .g4 file) into your project, right-click on it > Configure ANTLR...
From there you can select to generate Java or Kotlin files, which will compile and run once you added the runtime in your dependencies:
implementation 'org.antlr:antlr4-runtime:4.7'

How to import individual projects from Android Source Code

As far as I understand, all the built-in standard apps like (email, music, calendar etc) are built using the same API. So I should be able to import a project like mail / music etc without checking out the full source repository of android. I'v been trying that but I am getting compilation problems like class resolve failure.
Am I doing it wrong? Do I have to get the full android source project to import a project like Mail ?
These apps are open source (mail, music and calendar). But they depend on internal classes and resources and can't be compiled with the SDK
You could pull a Git clone of some particular app. For example - the EMail app from
https://android.googlesource.com/platform/packages/apps/Email/
The first problem is that Google are using MK files for building inside their android projects and Eclipse do not use them. But you can compile it because you have the sources, the XML resources and the manifest also.
The second problem is to deal with the dependencies. For example the gallery app may depend on few camera classes. You can manually copy them to your project.
Other way is:
Using Eclipse for writing code and testing if it builds correctly and using GNU Make 3.82 from http://www.gnu.org tool that will build the supplied Android.MK file and run the app.

Categories

Resources