I've been trying to figure out how an android app is installed by browsing AOSP.
The PackageManagerService.java has the gids for the corresponding permissions by parsing the platform.xml file.
PackageInstallerActivity parses and checks for any existing packages and then invokes the InstallAppProgress.
I was able to follow the paths where the package is parsed and validated and PackagerManager.installPackage() method is invoked from InstallAppProgress.initView() to install the package. I know this makes a native call to the JNI library. The corresponding .aidl file is IPackageManager.aidl.
What I want to know is where can I find the implementation of the Stub (or Native code if any) related to this aidl mentioned above?
I'm new to aidl so that is the reason I'm not able to understand its nuances completely. Could somebody kindly point me to the right direction?
So AIDL files are there to define how the service and client talk to each other. They are important for system services because they need to handle multi threading, and there are lots of different apps that may want to talk to it. So IPackageManager.aidl is there to allow clients to communicate to PackageManager.
I took a look at InstallAppProgress.initView() and I don't see a specific call to native code. There is a call to PackageManager here:
pm.installPackageWithVerificationAndEncryption(mPackageURI, observer, installFlags,
installerPackageName, verificationParams, null);
So to explain how this chain works, InstallAppProgress gets the PackageManager from context, which if you follow that chain leads to ContextImpl.getPackageManager() which you will see actually returns the ApplicationPackageManager which extends the abstract PackageManager class.
ApplicationPackageManager has a reference to the actual PackageManagerService which it calls through an interface, which is defined by the aidl file IPackageManager. The manager here is just controlling access to the service, and defining what is and is not actually accessible to the outside world. Apps can not normally get a handle to the PackageManagerService, IIRC it is possible to do so but you must have system privilleges.
To get a better explanation on what aidl files actually are, check out the page on the android site here: Android Interface Definition Language
Related
First time asking on stackoverflow here !
Okay so here's the context. I'm doing an android application, and I'm trying to implement something like a plug-in framework.
My main app's MainActivity's purpose is to manage and launch/show Fragments.
Each of my plug-in will contain (at least) a Fragment and it's layout.
Thus, the idea is to fetch the fragment and put it inside my main app's MainActivity, from it.
So I decided to put my Fragments/Plug-ins into different apps and give all my plug-ins and main app the same user_id. This way all of them are in the same process, and even if they appear in the phone's Application Manager, only the main app is launchable and visible in the Application Browser (which is great).
But here's my problem... How do I get access to my plug-ins Fragments ?
I thought I could fetch some class through the PackageManager and use relfexion to use my fragment, but apparently you can't (or I didn't find how).
I considered binding Services together on each end (Application - Plug-in) but I have no guarantee that the services will bind together. Especially since each app have the same copy of the service, aka not the same Service.
Maybe by using a common .jar to make sure the Services are the same, and thus pass an instance of my Fragment to the main app (yes an instance would suffice).
Or make a CustomClassLoader (but then I might need advice on how to load classes from my other app, because I don't know how to do that...)
I've been running in circles in my head and on the net to find a solution...
To make things clear:
How do i fetch the classe (CustomClassLoader) or an instance (via binding or maybe sharedPreference or wiriting my instance in a file and read it in the main ?) of another app, considering they share the same user_id and thus are in the same process ?
Just because apps share the same user_id this does not imply they are running in the same process. They may and propably have been started by the same process. Sharing resources amongst processes is commonly known as IPC.
AIDL , the android Interface Definition language is a way for implementing IPC. Still this will not allow you retrieve objects from a different application directly but the possibility to invoke methods on remote objects.
But your problem description to me seems more like accessing objects of an jar at runtime in an application. This could be done via classloading.
So your app could retrieve a jar from a Server and load your fragments from it. The definitions of the fragments than would be runtime updateable if you define your fragments completely by code.
I started exploring BeanShell for SL4A because I read that it could access the entire Android API. This would facilitate experimenting with API features and programming ideas without the need for a computer or compilation.
However, much of the API is accessed through a Context, and I don't know how to obtain this. Although both SL4A and BeanShell are well-documented, the combination of the two seems to be very poorly documented.
For example, to access android.net.ConnectivityManager, the developer reference states that I need to call Context.getSystemService(Context.CONNECTIVITY_SERVICE) to get an instance. But without a context, I don't think I'm able to access the methods of the ConnectivityManager.
So how do I obtain the Context?
Dahrrr…
While researching and formulating the question, I found out that this is an unresolved issue:
Notes for Java interpreters
Beanshell and Rhino can both directly access the android api. However, many Android api calls required a context, which, due to the way they are run, these interpreters don't have. A solution is being sought... suggestions appreciated.
I don't know sl4a or beanshell but i know Rhino. So i suppose that you can create scriptable objects too. If this is correct you can do something like this (in java):
// first create a simple scope called -> scope
// inject context.
Object injectObject = Context.javaToJS(android_context, scope); // ('Context' of rhino library)
ScriptableObject.putProperty(scope, "android_context_name", injectObject);
// so then execute your script with the injected object
execute(javascript_context, host, scope, scriptId, source, settings);
When you finish injected the the context you can access him via: "android_context_name". (inside your script).
When you run your bean shell script, it will be thru an android app ?
There are such available
e.g : BeanShell Executor, that will allow you to run a script.
So I assume the context will be passed from the app to the script being executed.
Consider
PackageInfo info1 = pm.getPackageArchiveInfo(apkPath,PackageManager.GET_PERMISSIONS);
In this statement, by using GET_PERMISSIONS I can get the set of all permissions used in the application.
In the same way can i get the API calls?
Thank you. I am new to this android programming if it is a simple question please forgive
No, you cannot get the API calls by any easy method, and arguably not even by a hard method.
If you had access to the application's installed .apk (and at least on older Android versions you did), you could read through it for obvious invocations of platform functions. (This is a form of "Static Analysis")
However, Java (and hence Dalvik) supports a mechanism called "reflection" which allows looking up and calling functions by name - a name that could be constructed at runtime by circuitous means, or user or network input.
Much of the actual functionality used for calling functionality in the system process is also ultimately performed by name, making another place where functionality not present in the static file could be added at runtime.
Finally, the native underlayers of Android (and likely the DVM as well) permit a determined programmer to dynamically designate arbitrary "data" to be "code" and then execute it.
I'm trying to bind a service from an activity and get possibility to call method of it.
These are in different applications (apk) but uses the same sharedUserId and process.
Since they use the same process, Am I obliged to use AIDL or can I use classic IBinder like for Local Service (described on Android Developer sample) ?
I tried both. AIDL works fine and method for Local Service doesn't works, I have an ClassCastException :
E/AndroidRuntime(17511): java.lang.ClassCastException: com.example.app.MyService$LocalBinder cannot be cast to com.example.app.MyService$LocalBinder
Is it possible to use this method for calling service with two apps in a common "shared" process? Or Is that the use of this shared process still requires an IPC method like AIDL?
If I want to use classic IBinder, it's for keeping my application as simple as possible.
Hope you can help me and sorry for my bad english ;-)
I guess the problem is the following. Even if you use sharedUserId and your applications run in the same process you cannot call methods of your service locally, because your service and application are in different packages. Thus, you can use only AIDL that will create a proxy in your client application.
Your problem is that each app has its own APK containing its own CLASSES.DEX, and classes and interfaces are not shared between them. App1.apk/com.example.Class1 is considered a different type than App2.apk/com.example.Class1. Whether or not they're identical doesn't matter.
There's a few ways you can address this:
1) As you've noticed, you can use AIDL. This is the least efficient mechanism, and obviously limits you to only AIDL-compatible types.
2) You can use Java reflection API's. This is better than AIDL in terms of efficiency, but of course the syntax isn't that great.
3) You can attempt to use custom class loading to somehow finagle it so that both apps have access to the same type. For what you're trying to do, this is going to be more trouble than it's worth.
to understand the AIDL in android, i want one real life example, means the at what scenario of development we need to use AIDL.
by reading the Android Docs ... It puts me in confusion and so many question, so it is hard to read whole doc for me, can anyone help me
is it for communicating with outside the phone.
or to communicating with different apps, (why we need to communicate with other apps)
what kind of service they are talking in docs
AIDL is used for Binder. Binder is a mechanism to do RPC calls on/from an Android Service.
When to use AIDL? When you need a Service. When do you need a Service? If you want to share data and control something in another application, you need a service using AIDL as an interface. (A Content Provider is used when sharing data only).
Services can be used within your application as the model roll in the MVC-pattern.
AIDL is Android Interface Definition Language. This basically allows you to do IPC calls.
Use: There are situations where one process would need to talk to other to obtain certain information.
Example: Process A needs info of Call status to determine whether it needs to change Call Type (for example Audio to Video Call or Vice-versa). You may get call status from certain listeners but to change Call type from Audio to Video, Process A needs a hook to change. This "Hook" or way of changing calls is typically part of Telephony Classes which are part of Telephony Process. So in order to obtain such an information from Telephony process, One may write a telephony service (which runs as a part of android telephony process), which will allow you to query or change call type. Since Process A(Client) here is using this remote Service which communicates with Telephony process to alter call type, it needs to have an interface to talk to service. Since Telephony service is the provider, and Process A (client) is the user, they both need to agree on an interface (protocol) they can understand and adhere to. Such an interface is AIDL, which allows you to talk (via a remote service) to Telephony process and get some work done.
Simply put in laymen terms, AIDL is an "agreement" Client gets, which tells it about how to talk to service. Service itself will have a copy of that agreement(since it published for it's clients). Service will then implement details on how it handles once a request arrives or say when someone is talking to it
So process A requests to change call via Service, Service gets the request, it talks to telephony process(since it's part of it) and changes call to video.
An important point to note is, AIDL is only necessary for multithreading environment. You could do away with Binders if you don't need to deal with multithreaded arch.
Another real world example is Google Play License is using AIDL.
I have the same thinking about an example of AIDL, it's very difficult to find an idea to make an example app which uses AIDL. Then I have an idea about it create a LocalLogServerApp. Maybe it can not become a production app but it still shows some value in using AIDL
The main function of this app is
Receive the local log from other local apps (another app need to implement AIDL to send log)
Save the log to datastore
Display the logs
Maybe do something with the local log (eg: search, delete)
Maybe notify developer when error log happened
The benefit of this app
The local log can use when you have some very strange issues which sometimes happened in a few moments and in some specific device. In this case, common Log won't help, debug won't help, Firebase Log may help but Firebase receive log from multiple device.
Reusable, many apps can use it with less code
Hope you find this idea helpful to find another better AIDL example
https://github.com/PhanVanLinh/AndroidLocalLogServer
https://github.com/PhanVanLinh/AndroidLocalLogClientTest
1 - is it for communicating with outside the phone.
Its communicating with outside the app.
2 - or to communicating with different apps, (why we need to communicate with other apps)
As #GodOnScooter mentioned, when your app communicates with telephony service which is actually an other part.
3 - what kind of service they are talking in docs?
This is a service which runs in different process of a system, To bind to this service you need IPC(inter process communication), AIDL is used to implement this.