Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-27743] Android: Remove hidden API usage from SDK

GitHub Issuen/a
TypeImprovement
PriorityLow
StatusClosed
ResolutionUnresolved
Affected Version/sn/a
Fix Version/sRelease 9.3.0
ComponentsAndroid
Labelsandroid, api, hidden
ReporterJoshua Quick
AssigneeJoshua Quick
Created2020-01-30T03:58:09.000+0000
Updated2020-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).

Comments

  1. Michael Gangolf 2020-07-26

    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
  2. Michael Gangolf 2020-08-11

    that will make the log so much cleaner already:
       hiddenMethodLog = /Accessing hidden (method|field)/;
       // 
       // add before https://github.com/appcelerator/titanium_mobile/blob/master/android/cli/hooks/run.js#L254
       if (hiddenMethodLog.test(line)) {reutrn;}
       
  3. Hans Knöchel 2020-10-03

    +1 for removing it from the info log level.
  4. Joshua Quick 2020-11-13

    _(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. The permitAll() 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 of StrictMode 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
       android {
       	buildTypes {
       		debug {
       			debuggable false
       		}
       	}
       }
       
  5. Joshua Quick 2020-11-13

    PR (master): https://github.com/appcelerator/titanium_mobile/pull/12263
  6. Michael Gangolf 2020-11-13

    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).
  7. Christopher Williams 2020-11-23

    merged to master and backport PR to 9_3_X for 9.3.0 target.

JSON Source