0

crash log:

    java.lang.SecurityException: No permission to modify given thread
android.os.Process.setThreadPriority(Native Method)
android.webkit.WebViewCore$WebCoreThread$1.handleMessage(WebViewCore.java:764)
android.os.Handler.dispatchMessage(Handler.java:99)
android.os.Looper.loop(Looper.java:137)
android.webkit.WebViewCore$WebCoreThread.run(WebViewCore.java:829)
java.lang.Thread.run(Thread.java:856)

which permission should I declare? http://developer.android.com/reference/android/Manifest.permission.html

edit:

I found a similar problem in WebView java.lang.SecurityException: No permission to modify given thread

The Answer say "It's cyanogen's fault."

However, in the thread http://code.google.com/p/cyanogenmod/issues/detail?id=5656&thanks=5656&ts=1341224425,cm menbers seem to deny it's CM's bug

Above all, my question is: How to fix it from my app?

Community
  • 1
  • 1
Syan Law
  • 37
  • 7

2 Answers2

0

which permission should I declare?

There is no relevant permission for this AFAIK. Unfortunately, the implementation of setThreadPriority() is in native code, which makes it difficult for me to figure out what is going on.

cm menbers seem to deny it's CM's bug

No, they do not. Nobody has posted evidence that it is a problem in CM9 or higher, which is why they marked the issue as stale. If you are seeing this on CM9 or higher, I suggest that you update the issue. If you are seeing this on standard Android, please create a sample project that can reproduce the error.

How to fix it from my app?

You don't, in all likelihood. You could try running some experiments on your WebView, to see if there is some specific content that triggers this exception, and try to modify or eliminate that content.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
0

I get dozens of crash log caused by this exception from my app (which depends on webview heavily), involved ROM version are 4.0.4 and 4.0.3.

It seems that there is no normal way to fix it, so i tried following hacking approach.

code snipet on 4.0.4:

private static Handler sWebCoreHandler;
// Class for providing Handler creation inside the WebCore thread.
private static class WebCoreThread implements Runnable {
    // Message id for initializing a new WebViewCore.
    private static final int INITIALIZE = 0;
    private static final int REDUCE_PRIORITY = 1;
    private static final int RESUME_PRIORITY = 2;

    public void run() {
        Looper.prepare();
        Assert.assertNull(sWebCoreHandler);
        synchronized (WebViewCore.class) {
            sWebCoreHandler = new Handler() {
                @Override
                public void handleMessage(Message msg) {
                    // ...
                    // Process.setPriority(...)
                }
            };
        // ...
        }
        // ...
    }
}

I think this exception is thrown from sWebCoreHandler.handleMessage(), if we can wrap try/catch on handleMessage(), the problem could be fixed.

Handler class has four members:

final MessageQueue mQueue;
final Looper mLooper;
final Callback mCallback;
IMessenger mMessenger;

mQueue is set as mLooper.mQueue, mCallback is null in sWebCoreHandler, so we just need to set mLooper and mMessenger with values in sWebCoreHandler.

static Handler sProxyHandler = null;

static void tryTweakWebCoreHandler() {
    // 4.0.3/4.0.4 rom
    if (Build.VERSION.SDK_INT == Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
        tweakWebCoreHandle();
    }
}

static private void tweakWebCoreHandle() {
    if (sProxyHandler != null)
        return;
    try {
        Field f = Class.forName("android.webkit.WebViewCore").getDeclaredField("sWebCoreHandler");
        f.setAccessible(true);
        Object h = f.get(null);
        Object mMessenger = null;
        Method m = Handler.class.getDeclaredMethod("getIMessenger", (Class<?>[])null);
        m.setAccessible(true);
        mMessenger = m.invoke(h, (Object[])null);
        sProxyHandler = new WebCoreProxyHandler((Handler)h);
        if (mMessenger != null) {
            Field f1 = Handler.class.getDeclaredField("mMessenger");
            f1.setAccessible(true);
            f1.set(sProxyHandler, mMessenger);
        }
        f.set(null, sProxyHandler);
        // Log.w(TAG,  "sWebCoreHandler: " + h);
    } catch (Throwable e) {
        Log.w(TAG, "exception: " + e);
    }
    if (sProxyHandler == null)
        sProxyHandler = new Handler();
}

static class WebCoreProxyHandler extends Handler {
    final Handler handler;
    public WebCoreProxyHandler(Handler handler) {
        super(handler.getLooper());
        this.handler = handler;
    }

    public void handleMessage(Message msg) {
        // Log.w("WebCoreProxyHandler", "handle msg: " + msg.what);
        try {
            handler.handleMessage(msg);
        } catch (Throwable tr) {
            Log.w("WebCoreProxyHandler", "exception: " + tr);
        }
    }
}

Remain problem is when to invoke tryTweakWebCoreHandler(). I tried to invoke it after a WebView instance is created and tested on some devices, WebCoreProxyHandler.handleMessage() can be called.

Note: i just made some simple test, i'm not sure this problem is resolved as the origin exception can not be reproduced reliably.

If you decide to try this approach, please do enough test.

carleo
  • 1