Android P (API 28) - What does the StrictMode policy violation "SmartSelectionEventTracker$SelectionEvent;->selectionAction" mean?

hamena314 picture hamena314 · Aug 23, 2018 · Viewed 22.9k times · Source

I am using the StrictMode in order to find non-SDK usages:

if (BuildConfig.DEBUG && Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
    StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
            .detectNonSdkApiUsage()
            .penaltyLog()
            .build());
}

Now I am getting a policy violation:

D/StrictMode: StrictMode policy violation: android.os.strictmode.NonSdkApiUsedViolation: Landroid/view/textclassifier/logging/    SmartSelectionEventTracker$SelectionEvent;->selectionAction(IIILandroid/view/textclassifier/TextClassification;)Landroid/view/textclassifier/logging/    SmartSelectionEventTracker$SelectionEvent;
        at android.os.StrictMode.lambda$static$1(StrictMode.java:428)
        at android.os.-$$Lambda$StrictMode$lu9ekkHJ2HMz0jd3F8K8MnhenxQ.accept(Unknown Source:2)
        at java.lang.Class.getDeclaredMethodInternal(Native Method)
        at java.lang.Class.getPublicMethodRecursive(Class.java:2075)
        at java.lang.Class.getMethod(Class.java:2063)
        at java.lang.Class.getMethod(Class.java:1690)
        at bzi.a(SourceFile:11)
        at bzq.a(SourceFile:12)
        at org.chromium.content.browser.selection.SmartSelectionClient.<init>(SourceFile:5)
        at bzZ.a(Unknown Source:7)
        at org.chromium.android_webview.AwContents.e(SourceFile:193)
        at org.chromium.android_webview.AwContents.d(SourceFile:153)
        at org.chromium.android_webview.AwContents.<init>(SourceFile:81)
        at uY.run(SourceFile:15)
        at ahv.a(SourceFile:13)
        at ahw.run(SourceFile:2)
        at org.chromium.base.ThreadUtils.b(SourceFile:31)
        at ahv.a(SourceFile:7)
        at com.android.webview.chromium.WebViewChromiumFactoryProvider.b(SourceFile:6)
        at com.android.webview.chromium.WebViewChromium.init(SourceFile:111)
        at android.webkit.WebView.<init>(WebView.java:678)
        at android.webkit.WebView.<init>(WebView.java:604)
        at android.webkit.WebView.<init>(WebView.java:587)
        at android.webkit.WebView.<init>(WebView.java:574)
        at java.lang.reflect.Constructor.newInstance0(Native Method)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:343)
        at android.view.LayoutInflater.createView(LayoutInflater.java:647)
        at com.android.internal.policy.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:58)
        at android.view.LayoutInflater.onCreateView(LayoutInflater.java:720)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:788)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:730)
        at android.view.LayoutInflater.rInflate(LayoutInflater.java:863)
        at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:824)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:515)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:423)
        at com.mine.ui.events.EventScreen.onCreateView(EventScreen.java:70)
        at android.support.v4.app.Fragment.performCreateView(Fragment.java:2354)
        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1419)
        at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1740)
        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1809)
        at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:799)
        at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2580)
        at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2367)
        at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2322)
        at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2229)
        at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:781)
        (... shortened ...)

The important line is:

at com.mine.ui.events.EventScreen.onCreateView(EventScreen.java:70)

Examining the mentioned line:

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
// This is the important line:
ViewGroup content = (ViewGroup) inflater.inflate(R.layout.mine_event, container, false);
WebView webView = (WebView) content.findViewById(R.id.container);
webView.loadUrl(event.getWebViewUrl());
webView.getSettings().setJavaScriptEnabled(true);
(...)

So I get the violation while the inflation happens, which I dont quite understand.

As you can see shortly after the mentioned line a WebView comes into play. I have looked at the source-code for the SmartSelectionEventTracker here and it seems like a generic class for Widgets like TextViews, WebViews, .... WebViews seem to be related to MockViews which are related to TextViews.

But apart from that finding I do not understand how / why the violation is happening and what I can do against it.

Can someome explain this to me?

Answer

Kevin Coppock picture Kevin Coppock · Aug 23, 2018

In Android P, restrictions have been added to private APIs (that is, APIs that are not part of the public SDK and are accessed via reflection). See Restrictions on non-SDK interfaces:

Android 9 (API level 28) introduces new restrictions on the use of non-SDK interfaces, whether directly, via reflection, or via JNI. These restrictions are applied whenever an app references a non-SDK interface or attempts to obtain its handle using reflection or JNI. For more information about this decision, see Improving Stability by Reducing Usage of non-SDK Interfaces.

So that's what you're seeing -- it's a warning that something is accessing one of those private APIs that may be removed in the future. However, the stack trace shows, as you mentioned, that this is coming from the WebView. In particular, during the initialization of SmartSelectionClient. That initializes a native library that implicitly is accessing SmartSelectionEventTracker, which is marked with @hide in its Javadoc statement, which indicates it is not part of the public SDK.

In short, there's likely nothing you can do about this particular warning, so I wouldn't worry about it. It's happening in the device's Chromium WebView implementation, so it's outside of your application's control. As both Android and Chromium are published by Google, if there is a legitimate issue in a future release, an update will be published to the WebView implementation before it becomes a problem.