In my app I have some objects with gps positions. At the moment the only thing I do with them is showing them on a map but I plan to implement other features which need to know the users location. I don't want to add the location permission to my app because some users may not want to use these features.
My idea was to have a separate apk (a kind of plugin) which only supplies the main app with location information so that only the plugin needs to request the location permission.
Is it possible to let the plugin share a system service (the LocationManager) directly without creating a custom service with an incompatible interface so that the main app can use the LocationManager of the plugin. This would make it possible to use existing classes like MyLocationOverlay or others. The main app could pass a ContextWrapper to these classes like this:
public static class LocationContext extends ContextWrapper {
public LocationContext(Context base) {
super(base);
}
#Override
public Object getSystemService(String name) {
if (name.equals(LOCATION_SERVICE)) {
// Return the LocationManager service of the plugin here...
}
return super.getSystemService(name);
}
}
Not sure if I quite understand your question, but it is possible for one application to load classes from another app and thus avoid crossing process boundaries. The key is having the same android:process and android:sharedUserId attributes in your manifests for both aps. Then the apps will run in the same Linux process on the device. You can then use reflection APIs to programmatically load App A's classes from App B and vice versa. If App A is already on the Market, you would probably need to release a new version that adds the process and sharedUserId attributes, and then release App B with these same attributes.
Yes this is possible, however I would strongly advice the Android OS engineers to disable this ability and also any other way of 2 friendly (same uuid, same signature) applications ) using each other functionality since this leads to serious security "holes" in the Permission system and serious issues in the Android security...
Just imagine 3 friendly applications. The first one has permission to connect to internet and nothing more, the second one can send SMS messages but nothing more and the third can access your location ....each app on its own is relatively harmless ...but image what can you do with them all together, since they are allowed to communicate.
Is it possible to let the plugin share a system service (the LocationManager) directly without creating a custom service with an incompatible interface so that the main app can use the LocationManager of the plugin.
That will not be possible. LocationManager is not Parcelable, so you cannot pass it between processes.
This would make it possible to use existing classes like MyLocationOverlay or others.
Um, no. You did not write MyLocationOverlay. You cannot force it to use some faux LocationManager of your own design.
The main app could pass a ContextWrapper to these classes like this
ContextWrapper is not Parcelable, so you cannot pass it between processes.
Related
I'm trying to get a better understanding of the differences so I can evaluate if I should be implementing a System Service, or a Service. The differences that I have found from the docs are the following:
System Service
Started in SystemServer
Added to ServiceManager
Considered mandatory, and soft reboots the device on failure
More permissions? (Not sure what it can do that a Service can't)
Service
Initialized and started using an intent?
Is there anything else is different between the two? I'm modifying AOSP to include my own service, and any additional supplied information would be helpful in assisting me make a decision.
All system services are run in the same process called system_server.
There's a lot of things which system service can but service can't. system service usually has a higher and more specified sepolicy which normal apps will not have, for example(change NFC hardware parameters).
so if you want add you own system service, notice things above, if you code has a deadlock, you will affect all system services. and without a sepolicy, you service may still unable to access some resources.
Android Services
Android services are system component which allows performing a
longer-running operation while not interacting with the user.
Just like Activities, Service runs on Main Thread and has a life cycle but unlike Activity, Services do not have a UI.
Anyone can use & create Service or its direct subclasses IntentServcice in their Apps and it works pretty well.
Common usages are: Playing Media, Downloading files from the Internet, etc.
System Services
System services are a direct derivative of SystemService class. They reside in com.android.server packagein AOSP tree
https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/services/
System Services also run in Main Thread so if you want to do some CPU intensive task then you much reuse HandlerThread architecture of AOSP.
What makes System service different from Android Services?
System Services are started by SystemServer hence they run as a System process which gives them additional privileges which normal Android Service will never get hence they are named name SystemService.
Example: You can't use Instrumentation to inject events in App other than yours because you will need INJECT_EVENT permission which is not granted to normal apps. SystemService can do that because they have elevated access.
The simple example of System Service :
package com.android.server.appwidget;
import android.content.Context;
import com.android.server.AppWidgetBackupBridge;
import com.android.server.FgThread;
import com.android.server.SystemService;
/**
* SystemService that publishes an IAppWidgetService.
*/
public class AppWidgetService extends SystemService {
private final AppWidgetServiceImpl mImpl;
public AppWidgetService(Context context) {
super(context);
mImpl = new AppWidgetServiceImpl(context);
}
#Override
public void onStart() {
mImpl.onStart();
publishBinderService(Context.APPWIDGET_SERVICE, mImpl);
AppWidgetBackupBridge.register(mImpl);
}
#Override
public void onBootPhase(int phase) {
if (phase == PHASE_ACTIVITY_MANAGER_READY) {
mImpl.setSafeMode(isSafeMode());
}
}
#Override
public void onStopUser(int userHandle) {
mImpl.onUserStopped(userHandle);
}
#Override
public void onSwitchUser(int userHandle) {
mImpl.reloadWidgetsMaskedStateForGroup(userHandle);
}
}
It really depends on what exactly you want to implement. I generally prefer to add functionality over modifications to the Android platform so I don't recommend modifying system_server if you can avoid it.
The system_server process runs as user 1000 (aka system) but other processes can also run as user 1000 simply by specifying that in the AndroidManifest so it doesn't have any special selinux capabilities that other apps cannot have, assuming they are signed with the platform key and run as system.
Create System Application
A platform project can declare itself persistent so Android never kills the process, this may or may not be necessary for your situation.
Android What is use of persistent?
You may not actually need system permissions at all, you could simply have your app installed as a priv-app. Generally you only want to grant your app as much privilege as needed.
What is the difference between system apps and privileged apps on Android?
So finally allow me to suggest an alternative: A persistent content provider.
Assuming your app provides some kind of functionality to unprivileged apps then a content provider that exposes its functionality via the call method is a great choice since you do not need to build an aidl file for it or distribute that aidl to the apps, also apps don't need to bind to your service and you don't have to worry about lifecycle since persistent processes never die.
You can check permissions in the call method to ensure the apps declare themselves. If your process crashes then it doesn't take down the entire system_server with it and when you move to a new version of Android you don't have to figure out how to hack up system_server again.
They are very different. Their high-level differences are:
A Service is an application component that is like an Activity without a UI. You can extend it to create your own version of the Service in your application.
A System Service is part of the System Server. You need to modify AOSP to add your own System Service: provide its API class [MySystem]Manager, its implementation class [MySystem]Service, its AIDL file I[MySystem]Service.aidl, and more. Then you can access it by calling Context.getSystemService(...).
It’s a little confusing to call both of them Service.
Below is the answer to the question, when to use SystemService and when Services
System Services
SystemServices run under SystemServer process
If service is related to any special hardware component and APIs are going to expose
SystemServices has a different Sepolicy and has fewer restrictions as Compared system_app or unknown_app.
Above conditions for you is true then you can Either create SystemService by making changes in AOSP (Normal context.getSystemService(NAME) will work for custom service also) or you can create your own app where you can bind to Servicemanager
Below link for reference
https://devarea.com/aosp-creating-a-system-service/#.YCV3t_nhXDf
Service
it is Non UI component which will run on mainThread.
If requirement scope can be served within APP process context only then this is best place to make changes. Why to bother SystemServer for every small task. :)
I've written a library starting a service in the background. It runs perfectly in all applications.
In order to reduce the RAM usage, I want to avoid running multiple services for different applications. Actually, it's pretty enough to use only one service to get things done.
Firstly, I've written an AIDL file to make IPC between applications/libraries. Defined the service as exported/enabled with signature permission. Since all applications are the exactly the same service, it's not possible to check if any one is up or down. While binding the service to check the condition of the service, it always creates and destroys the own service because of the nature of BIND_AUTO_CREATE flag. That's why not possible to get any kind of info from the exported service if it's really up and running.
Then, I tried to define a Content Provider to the manifest of the library. My aim is to share the service info through it. It's really good mechanism to communicate between exported service and application main process. But it is not usable for multiple instances. Because applications which gets the content provider info from the library use the same authority and so it's not possible to install the second one. It gives an DUPLICATE_PROVIDER_AUTHORITY error.
What's your suggestion about the issue? Is there any option to create a master/slave mechanism? Is it possible to make the service singleton for the application uses the library project?
P.S: Tried broadcast and shared preferences techniques. But they're not effective to listen the callback from the exported service.
You need to put the Service in an APK of its own. It needs to have its own unique package name (in the manifest) which is different from the package names of any of the applications that use it. This is how you make the Service behave as a singleton. Now you can use AIDL and bind to the Service in order to have two-way communication.
Note that in more recent versions of Android, it has become necessary to start a Service using an explicit Intent (ie: the Component must be explicitly specified, you can't use just an ACTION).
Alternative 1:
If the use case permits I think you should not implement the Service.
Make your client implement a service a call your library code. This
is how MediaPlayer and other default android APIs work.
Alternative 2:
Host the service in a separate app..and download the app when the
first call is made from any client. From here onwards there will be
single service handling all the client request.This is how some APIs like adobe
air/ MDM solutions from Airwatch works.
There is no good way you can control a component which is running in other app,unless using broadcast receivers and all.
I am working on a solution or code that can be embedded inside of an Android APK to track how many times the app has been launched and how long the app has ran for. I know one way to do this is using the ActivityLifecycleMethods in API 14 and in lower versions of Android having code placed in all Activity Lifecycle events or by providing a base Activity class.
1) Is there a way to hook the ActivityLifecycleMethods without the developer having to make any changes to their code outside of dropping additional code into their App?
I believe this answer is no because even with an Enum Singleton it is not loaded until it is referenced. Also the Enum Singleton will go away once the activity is changed since a different class loader is used when activities change.
If I wanted to keep the Enum Singleton around would it be possible to store a reference to the applicationContext and thus it wouldn't be removed when the Activity changes? Is that what google means by
"There is normally no need to subclass Application. In most situation, static singletons can provide the same functionality in a more modular way. If your singleton needs a global context (for example to register broadcast receivers), the function to retrieve it can be given a Context which internally uses Context.getApplicationContext() when first constructing the singleton." on http://developer.android.com/reference/android/app/Application.html
2) I am not a fan of this solution for older API versions. It seems very likely developers could forget to modify their Activity Lifecycle methods or forget to inherit from the created BaseActivity. Are there any other unique solutions for these older platforms? Is there any other approaches that can be done to determine when an activity isn't running? Could any of the following work:
a) User a class loader to ensure the base activity with the proper metrics are always used
b) Implement some type of heart beat. Will a timer stop working if the app is paused or killed? Is there some other way? Could the ActivityManager be used?
You have many Analytic Agents like Flurry to do that.
When ever you want to track an event, you will add it to flurry and inturn it syncs with server after specific time.
You may use the same logic.
Better create a library file with following features:
Start Application
End Application and report time to db.
Track a specific event count and update to db.
Sync the data to server you like to.
Call appropriate events from your app.
I understand that there is no Application Level Scope available to be able to define shared logic/data, and that each activity is essentially a stand alone application tied together by the manifest...
BUT I have a group of user access permissions that I am getting via a web service call and do not want to make this call in every activities onCreate().
I am using SharedPreferences in the application, but since the permissions are not intended to be editable by the user, the flat file exposure on android devices feels like an insecure way to handle this.
I do need to re-request this info if the application is restarted, so I believe the least expensive would be to store it in a variable.
I am aware of IntentExtras but we are talking about a Settings "Object", not a primitive type.
right way to handle this situation?
You can actually create an "Application" class that can be used to essentially create Application wide settings.
Just create a new class and extend Application, then set any class members and appropriate getter/setter methods and you can access them throughout your application.
You then need to update your manifest as follows:
<application android:icon="#drawable/logo"
android:label="#string/app_name"
android:name=".application.CustomApplication">
Then in any activity you can access it as follows:
CustomApplication app = ((CustomApplication)getApplication());
I think that using shared preferences is fairly secure. Only advanced users with root, custom roms and hacking knowledge would be able to take a chance at it! (I'm not even sure that this would be possible).
Besides SharedPreferences, you could also implement a custom Application object and keep your permissions there.
Anyway, as a developer I think that it's much more likely to be hacked somewhere within the request I do to get the user permissions (use https, etc) and my application being decompiled.
I'm writing an app, that has a somewhat modular system. It has a core app, and some apps, that consist of a single Service, that implements the desired interface. I followed the guide to create the IPC communication. But now I need to get all the services, installed on the system, that my core app can wotk with. How do I do this? I mean, is there any way to mark my Service apps with some kind of a tag, and then filter results, presented by the PackageManager#getInstalledPackages() based on that tag value? What's the common practice of doing so?
Create a custom Intent to which your activities will respond. You can then use PackageManager.queryIntentServices to get your list of matching services. You can get the package info, etc. from the information embedded in the ResolveInfos.
Ideally you'd actually use these intents for invoking the services, but you could always just use them as identification tags and fall back on the binding mechanism you were using before.