[TIMOB-27743] Android: Remove hidden API usage from SDK
GitHub Issue | n/a |
---|---|
Type | Improvement |
Priority | Low |
Status | Closed |
Resolution | Unresolved |
Affected Version/s | n/a |
Fix Version/s | Release 9.3.0 |
Components | Android |
Labels | android, api, hidden |
Reporter | Joshua Quick |
Assignee | Joshua Quick |
Created | 2020-01-30T03:58:09.000+0000 |
Updated | 2020-11-23T19:06:48.000+0000 |
Description
*Summary:*
Android 9.0 and newer OS versions will log a warning if the app's code accesses a hidden/private API.
Titanium is accessing Google's private
getCompatibilityInfo()
method in our [TiPlatformHelper.java](https://github.com/appcelerator/titanium_mobile/blob/c27b90877bf41311d74339905aff240b46febe20/android/titanium/src/java/org/appcelerator/titanium/util/TiPlatformHelper.java#L67) source file. We need to replace its usage with a public API.
*Steps to reproduce:*
1. Build and run a Titanium app on Android.
2. Observe the log on app startup.
*Result:*
The following warning message is triggered by Titanium's code.
[WARN] W/tor.kitchensin: Accessing hidden method Landroid/content/res/Resources;->getCompatibilityInfo()Landroid/content/res/CompatibilityInfo; (light greylist, reflection)
*Note:*
There are other hidden API warnings logged as well, but they do not come from Titanium.
The following warnings come from Google's AndroidX libraries.
[WARN] W/tor.kitchensin: Accessing hidden field Landroid/content/res/CompatibilityInfo;->applicationScale:F (light greylist, reflection)
[WARN] W/tor.kitchensin: Accessing hidden method Landroid/graphics/drawable/Drawable;->getOpticalInsets()Landroid/graphics/Insets; (light greylist, linking)
[WARN] W/tor.kitchensin: Accessing hidden field Landroid/graphics/Insets;->left:I (light greylist, linking)
[WARN] W/tor.kitchensin: Accessing hidden field Landroid/graphics/Insets;->right:I (light greylist, linking)
[WARN] W/tor.kitchensin: Accessing hidden field Landroid/graphics/Insets;->top:I (light greylist, linking)
[WARN] W/tor.kitchensin: Accessing hidden field Landroid/graphics/Insets;->bottom:I (light greylist, linking)
[WARN] W/tor.kitchensin: Accessing hidden method Landroid/widget/TextView;->getTextDirectionHeuristic()Landroid/text/TextDirectionHeuristic; (light greylist, linking)
[WARN] W/tor.kitchensin: Accessing hidden method Landroid/view/View;->computeFitSystemWindows(Landroid/graphics/Rect;Landroid/graphics/Rect;)Z (light greylist, reflection)
[WARN] W/tor.kitchensin: Accessing hidden method Landroid/view/ViewGroup;->makeOptionalFitsSystemWindows()V (light greylist, reflection)
See Google's ticket here:
https://issuetracker.google.com/issues/123699881#comment12
The following come from Google's WebView.
[WARN] W/tor.kitchensin: Accessing hidden method Landroid/view/textclassifier/logging/SmartSelectionEventTracker;-><init>(Landroid/content/Context;I)V (light greylist, reflection)
[WARN] W/tor.kitchensin: Accessing hidden method Landroid/view/textclassifier/logging/SmartSelectionEventTracker;->logEvent(Landroid/view/textclassifier/logging/SmartSelectionEventTracker$SelectionEvent;)V (light greylist, reflection)
[WARN] W/tor.kitchensin: Accessing hidden method Landroid/view/textclassifier/logging/SmartSelectionEventTracker$SelectionEvent;->selectionStarted(I)Landroid/view/textclassifier/logging/SmartSelectionEventTracker$SelectionEvent; (light greylist, reflection)
[WARN] W/tor.kitchensin: Accessing hidden method Landroid/view/textclassifier/logging/SmartSelectionEventTracker$SelectionEvent;->selectionModified(II)Landroid/view/textclassifier/logging/SmartSelectionEventTracker$SelectionEvent; (light greylist, reflection)
[WARN] W/tor.kitchensin: Accessing hidden method Landroid/view/textclassifier/logging/SmartSelectionEventTracker$SelectionEvent;->selectionModified(IILandroid/view/textclassifier/TextClassification;)Landroid/view/textclassifier/logging/SmartSelectionEventTracker$SelectionEvent; (light greylist, reflection)
[WARN] W/tor.kitchensin: Accessing hidden method Landroid/view/textclassifier/logging/SmartSelectionEventTracker$SelectionEvent;->selectionModified(IILandroid/view/textclassifier/TextSelection;)Landroid/view/textclassifier/logging/SmartSelectionEventTracker$SelectionEvent; (light greylist, reflection)
[WARN] W/tor.kitchensin: Accessing hidden method Landroid/view/textclassifier/logging/SmartSelectionEventTracker$SelectionEvent;->selectionAction(III)Landroid/view/textclassifier/logging/SmartSelectionEventTracker$SelectionEvent; (light greylist, reflection)
[WARN] W/tor.kitchensin: Accessing hidden method Landroid/view/textclassifier/logging/SmartSelectionEventTracker$SelectionEvent;->selectionAction(IIILandroid/view/textclassifier/TextClassification;)Landroid/view/textclassifier/logging/SmartSelectionEventTracker$SelectionEvent; (light greylist, reflection)
The following warnings come from AndroidX version of Google maps.
[WARN] W/lerator.testin: Accessing hidden method Lsun/misc/Unsafe;->arrayBaseOffset(Ljava/lang/Class;)I (greylist,core-platform-api, reflection, allowed)
[WARN] W/lerator.testin: Accessing hidden method Lsun/misc/Unsafe;->arrayIndexScale(Ljava/lang/Class;)I (greylist, reflection, allowed)
[WARN] W/lerator.testin: Accessing hidden method Lsun/misc/Unsafe;->getInt(Ljava/lang/Object;J)I (greylist, reflection, allowed)
[WARN] W/lerator.testin: Accessing hidden method Lsun/misc/Unsafe;->putInt(Ljava/lang/Object;JI)V (greylist, reflection, allowed)
[WARN] W/lerator.testin: Accessing hidden method Lsun/misc/Unsafe;->getLong(Ljava/lang/Object;J)J (greylist,core-platform-api, reflection, allowed)
Unfortunately, there is nothing we can do about the above warnings other than to wait/hope for Google to resolve these in future updates of their libraries.
*Recommended Solution:*
For the getCompatibilityInfo()
hidden method usage on our end, we need to update our code [here](https://github.com/appcelerator/titanium_mobile/blob/d052cacf6d7f1648d310ea9b010bd78b4d91f4b5/android/titanium/src/java/org/appcelerator/titanium/util/TiPlatformHelper.java#L60-L81) to acquire the applicationScaleFactor
as shown below... which matches the behavior shown in Google's code [here](https://github.com/aosp-mirror/platform_frameworks_base/blob/master/core/java/android/content/res/CompatibilityInfo.java).
if ((activity.getApplicationInfo().flags & ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES) != 0) {
applicationScaleFactor = 1.0f;
} else {
DisplayMetrics displayMetrics = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
applicationScaleFactor = displayMetrics.densityDpi / (float) DisplayMetrics.DENSITY_DEFAULT;
}
Some warnings are being logged by our usage of WebViewClient.jar
which we need for Android 4.4 support of certificate requests in a Ti.UI.WebView
. We cannot remove this JAR until Titanium 10.0.0. See ticket: [TIMOB-28241]
For all other hidden method warnings, Google's newest libraries as of November 2020 has resolved most of these warnings. Particularly in Google Maps. Unfortunately we cannot disable these warnings from being logged via the [StrictMode](https://developer.android.com/reference/android/os/StrictMode) class since the Android OS will log these warnings based on the "AndroidManifest.xml" <application android:debuggable="true"/>
attribute (won't be set for production/release builds).
would it be possible to remove the from the info log? Especially the map part is filling up the logs quite a lot. There is already some log filtering at https://github.com/appcelerator/titanium_mobile/blob/master/android/cli/hooks/run.js#L260
that will make the log so much cleaner already:
+1 for removing it from the info log level.
_(sigh)_ I can't get
StrictMode
method [permitNonSdkApiUsage()](https://developer.android.com/reference/android/os/StrictMode.VmPolicy.Builder#permitNonSdkApiUsage()) to work at all on Android 11. ThepermitAll()
method doesn't avoid hidden method detection either. Nor can I get [penaltyListener()](https://developer.android.com/reference/android/os/StrictMode.VmPolicy.Builder#penaltyListener(java.util.concurrent.Executor,%20android.os.StrictMode.OnVmViolationListener)) to detect the access of these hidden methods. I can get every other aspect ofStrictMode
to work except this. The behavior I'm seeing doesn't match what Google has documented or blogged about. Not sure what to think of this other than the Android OS simply won't let us disable this. https://developer.android.com/distribute/best-practices/develop/restrictions-non-sdk-interfaces#test-strictmode-api These warning messages definitely do *NOT* appear for "production" builds (aka: Android "release" builds). The Android OS must be looking for the APK's "AndroidManifest.xml"<application android:debuggable="true"/>
attribute to do this. Doing the below via a "build.gradle" file setting as shown below removes the "debuggable" attribute and definitely gets rid of the warning messages... although I don't like this solution../platform/android/build.gradle
PR (master): https://github.com/appcelerator/titanium_mobile/pull/12263
perhaps hiding them in the CLI output would still be an option? So they won't appear in the normal info-log (debug or trace would be fine).
merged to master and backport PR to 9_3_X for 9.3.0 target.