Android M reflection method freeStorageAndNotify exception - android

I'm using reflection method freeStorageAndNotify:
Method freeStorageAndNotify = null;
freeStorageAndNotify = service.packageManager.getClass().getMethod(
"freeStorageAndNotify", long.class, IPackageDataObserver.class);
freeStorageAndNotify.invoke(PackageManager.class, maxCache + freeSpace, packageDataObserver);
This causes InvocationTargetException:
java.lang.SecurityException: Neither user 10199 nor current process has android.permission.CLEAR_APP_CACHE.
Some points:
- I already have android.permission.CLEAR_APP_CACHE
- This happens only in android "M" Version (Flashed the preview sdk from developer site)
I know this is a hack, and google doesn't bring some official API for that,
But there are so many cleaning apps which cleans all the device cache in one click, so if someone know how to bypass this issue with another workaround i'll be happy to see that.
Thanks very much for the help

There was a bug raised on Android 5 regarding how any app can wipe out all cache files with a regular permission, but cannot wipe out one package's cache files except with a signature-level permission. It's details where
PackageManager has a deleteApplicationCacheFiles() to delete the cache from one package.
This method is hidden from the SDK, and it requires
DELETE_CACHE_FILES, a signature-level permission.
PackageManager also has a freeStorageAndNotify() method, to delete
cache files from all packages. This method is hidden from the SDK, and
it requires the CLEAR_APP_CACHE permission, which is merely flagged
as "dangerous".
It was proposed to either that DELETE_CACHE_FILES should have its level relaxed,
CLEAR_APP_CACHE should have its level raised.
A framework engineer responded
Note that freeStorageAndNotify's purpose is not to wipe out all cache
files, but to free up X amount of space, for example by play store
before it tries to download and install an app. So there are reasons
to use it that work well with the system, but no reason for an app to
use the method that just blindly erases all cache files for a single
app (that is just there for the Settings app UI).
If indeed it is not an app error i.e. you haven't messed up the permissions and it works on Marshmallow / 6 / api 23 and not others that could only mean it became a signature level permission as well, like DELETE_CACHE_FILES.
A signature|system permission, meaning that it can only be held by
apps that are signed with the firmware's signing key or are installed
on the system partition (e.g., by a rooted device user). As described
in this answer.
This would make sense, considering their intended use / their vision (no reason for an app to use the method that just blindly erases all cache files for a single app). It may have even been restricted as a result of that bug. When Android 6's code will come out we will know better (current available is 5.1.1 - link to PackageManager's freeStorageAndNotify).

Refer to these pages: permissions by protection level and protection level definitions.
android.permission.CLEAR_APP_CACHE
This falls under the protection level "signature|privileged" which means that only same-signature or privileged apps (system signed basically) can have this permission.
Also you should check out the Behavior Changes in general.

Related

OMAPI OpenLogicalChannel failed on Android 13

I work on application that communicate with a custom SIM card with use of Android OMAPI. The application had worked, before I updated Google Pixel to Android 13. Since then, when openLogicalChannel of the Session is called, I get the exception below with scarce information:
Caused by: java.io.IOException: OpenLogicalChannel() failed
at android.se.omapi.Session.openLogicalChannel(Session.java:322)
at android.se.omapi.Session.openLogicalChannel(Session.java:359)
I haven't found any information about OMAPI changes or additional permission in Androdid 13 documentation.
isSecureElementPresent of Reader returns true.
Does anybody have any clues?
As you commented you are not using Android carrier privileges. I'm wondering how this was ever working in your case. In all my setups I needed it for accessing the SEService. The Access Control Enforcer was always checking the access properly in my Pixel devices. Was your previous Pixel device rooted before?
Please try to add the hash of your signing certificate to the ARA or use a generic allow all rule. Maybe you can install this allow all applet on the SIM. For analyzing the APDU traffic I have written an XPosed module displaying additional log messages in the Android radio log.

Android lib/api to query, which Manifest.permission.XXXX are currently missing?

I am maintaining two android developper tools intent-intercept
and ContentProviderHelper
that declare as many required permessions as possible to work with as many apis (Intents or Contentproviders) as possible.
If i want to use target-api android-6.0 (M) and newer i have to implement an api to ask os/user to grant permission for a certain
api call.
And that is my problem: i donot know in advance which api-call(Intents or Contentproviders) require which permission.
As developper tools the app-s should work with any api.
How can I solve this? Is there a api/lib that tells me which Manifest.permission.XXXX are neccessary to invoke Intents or Contentprovider
or why last call failed?
Do i have to ask for all permissions even if they are not required?
Is there a api/lib that tells me which Manifest.permission.XXXX are neccessary to invoke Intents or Contentprovider
No.
or why last call failed?
Catch the SecurityException, then examine the message of the SecurityException and see if it contains the name of a dangerous permission.

How to call AccountManager's peekToken() from several apps sharing the same authenticator in api <= 22

I've created a library where all the authentication is configured, including AccountManager's authenticator class. This library is intended to be used by different apps and with different signing certificates.
The scenario is the following:
Two apps importing installed in the device both importing the library. I'm adding an account to the AccounManager from one of them, and then calling AccountManager's peekAuthToken() from both. It works for api < 22 (it is indicated in the docs) but returning a SecurityException in lower APIs (which is expected).
What would be the way to accomplish that in lower versions?
I have also try to use getToken instead, which returns a Future object, but the future.getResult() seems to fail at some point (no kind of exception is shown) and never returns the result with api <=22 and different signing certificates.
Any clue?
It can be solved adding the following att to the authenticator.xml configuration file: android:customTokens="true"
It will look as:
I'm not sure what is happening internally with this att enabled.

Remote update app on multiple devices NOT using Playstore

I'm trying to find a solution to do a remote update of an APK to 80 tablets. This should preferably be as automated as possible and if this can happen completely in the background without any user input that would be great. Basically what the Playstore currently do which I unfortunately can't use.
Is something like this possible without rooting the device? Any suggestion on libraries/ services that does this?
I'm running Android 4.1.1 and they will all be connected to a Wi-Fi.
You can download the new APK file to SD card, then call this to install it:
Intent shareIntent = new Intent(Intent.ACTION_VIEW);
shareIntent.setDataAndType(Uri.fromFile(new File("path-to-APK-file")),
"application/vnd.android.package-archive");
try {
context.startActivity(shareIntent);
} catch (Throwable t) {
// handle the exception here
}
There is only one thing not automatic: the final step. The system will ask the user to confirm installation.
About the MIME type of APK files, here's the wiki page.
No, in the background isn't possible without rooting or having the device's signing key at least as a standard Android APK update. The only semi-reasonable way I can envision something similar to this working is for your app to always check for/download code to run which you load using a class loader. This would be a significant amount of work and not easy.
However, if you're willing to live with some user interaction, it really shouldn't be that hard (though it'll still take some building of infrastructure). Keep a web service that returns the latest version number, compare with the current version number and download the new APK as necessary. Installing an APK programmatically has been covered in many SO questions.

ActivityManager.forceStopPackage() from Task Manager

This is my first time posting here. I'm not sure if this is the right place to ask this question, but I don't seem to find other more appropriate places. Here's my question anyways.
I understand that the API ActivityManager.forceStopPackage() is an internal one and can be called only from system process. However, it puzzles me that the built-in Task Manager app (with package name com.motorola.PerformanceManager) on my motorola atrix phone can directly call it without being a system process. There are two things that I verified.
First, it is non-system process from ps command:
app_64 13681 1379 170788 29820 ffffffff 00000000 S com.motorola.PerformanceManager
Second, it indeed calls the ActivityManager.forceStopPackage() API from its odex file (decompiled into smali, then into dex, and then into java). From the smali code, it is already clear that it calls this API.
I also checked its AndroidManifest.xml file which seems nothing special to me (the forum mistakenly recognizes the content as URLs and prevents me from posting them).
The manifest file does include the android.permission.FORCE_STOP_PACKAGES permission which is supposed to be a system one. A non-system app will still get permission denial error even with this permission. I tried using reflection to access this API with android.permission.FORCE_STOP_PACKAGES permission but still get the runtime error.
Now, how can the built-in Task Manager app call the internal API without being a system process.
One possibility is that the app is signed with the same platform private key. However, I'm not sure how I can verify that. Further, it is still supposed to be a system process with additional descriptions in the manifest file.
Hope someone can answer my question. Thanks.
The "android.permission.FORCE_STOP_PACKAGES" permission is protected by the platform signature.
If you have Android source code then check the declaration of the permission:
/frameworks/base/core/res/AndroidManifest.xml
...
<permission android:name="android.permission.FORCE_STOP_PACKAGES"
android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
android:protectionLevel="signature"
...
You can see its protection level is signature, then check the SDK documentation for the explaination:
"android:protectionLevel"
http://developer.android.com/guide/topics/manifest/permission-element.html#plevel
"signature...A permission that the system grants only if the requesting application is signed with the same certificate as the application that declared the permission. If the certificates match, the system automatically grants the permission without notifying the user or asking for the user's explicit approval"
The permission is declared by the framework-res which is signed by the platform signature, so the application that wants to use the permission shall also be signed with the same signature.
/frameworks/base/core/res/Android.mk
...
LOCAL_PACKAGE_NAME := framework-res
LOCAL_CERTIFICATE := platform
...
Regards
Ziteng Chen

Categories

Resources