Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package org.chromium.base; | 5 package org.chromium.base; |
| 6 | 6 |
| 7 import android.os.Handler; | 7 import android.os.Handler; |
| 8 import android.os.Message; | 8 import android.os.Message; |
| 9 import android.util.Log; | |
| 10 | |
| 11 import java.lang.reflect.Method; | |
| 9 | 12 |
| 10 class SystemMessageHandler extends Handler { | 13 class SystemMessageHandler extends Handler { |
| 11 | 14 |
| 15 private static final String TAG = "SystemMessageHandler"; | |
| 16 | |
| 12 private static final int SCHEDULED_WORK = 1; | 17 private static final int SCHEDULED_WORK = 1; |
| 13 private static final int DELAYED_SCHEDULED_WORK = 2; | 18 private static final int DELAYED_SCHEDULED_WORK = 2; |
| 14 | 19 |
| 20 // Reflected API for marking a message as asynchronous. This is a workaround | |
| 21 // to provide *fair* Chromium task dispatch when served by the Android UI | |
| 22 // thread's Looper, avoiding stalls when the Looper has a sync barrier. | |
| 23 // Note: Use of this API is experimental and demonstrative, and is likely | |
| 24 // to be removed in the near future. | |
| 25 private Method mMessageMethodSetAsynchonous; | |
| 26 | |
| 15 // Native class pointer set by the constructor of the SharedClient native cl ass. | 27 // Native class pointer set by the constructor of the SharedClient native cl ass. |
| 16 private long mMessagePumpDelegateNative = 0; | 28 private long mMessagePumpDelegateNative = 0; |
| 17 private long mDelayedScheduledTimeTicks = 0; | 29 private long mDelayedScheduledTimeTicks = 0; |
| 18 | 30 |
| 19 private SystemMessageHandler(long messagePumpDelegateNative) { | 31 private SystemMessageHandler(long messagePumpDelegateNative) { |
| 20 mMessagePumpDelegateNative = messagePumpDelegateNative; | 32 mMessagePumpDelegateNative = messagePumpDelegateNative; |
| 33 | |
| 34 try { | |
| 35 Class<?> messageClass = Class.forName("android.os.Message"); | |
| 36 mMessageMethodSetAsynchonous = messageClass.getMethod( | |
| 37 "setAsynchronous", new Class[]{boolean.class}); | |
| 38 } catch (ClassNotFoundException e) { | |
| 39 Log.e(TAG, "Failed to find android.os.Message class:" + e); | |
| 40 } catch (NoSuchMethodException e) { | |
| 41 Log.e(TAG, "Failed to load Message.setAsynchronous method:" + e); | |
| 42 } catch (Exception e) { | |
|
nyquist
2014/08/28 23:27:27
Why is this not catching RuntimeException?
jdduke (slow)
2014/08/28 23:37:03
Is there anything to gain from catching that in ad
jdduke (slow)
2014/08/28 23:54:41
N/m, I have seen the error of my ways, done!
| |
| 43 Log.e(TAG, "Exception while loading Message.setAsynchronous method: " + e); | |
| 44 } | |
| 21 } | 45 } |
| 22 | 46 |
| 23 @Override | 47 @Override |
| 24 public void handleMessage(Message msg) { | 48 public void handleMessage(Message msg) { |
| 25 if (msg.what == DELAYED_SCHEDULED_WORK) { | 49 if (msg.what == DELAYED_SCHEDULED_WORK) { |
| 26 mDelayedScheduledTimeTicks = 0; | 50 mDelayedScheduledTimeTicks = 0; |
| 27 } | 51 } |
| 28 nativeDoRunLoopOnce(mMessagePumpDelegateNative, mDelayedScheduledTimeTic ks); | 52 nativeDoRunLoopOnce(mMessagePumpDelegateNative, mDelayedScheduledTimeTic ks); |
| 29 } | 53 } |
| 30 | 54 |
| 31 @SuppressWarnings("unused") | 55 @SuppressWarnings("unused") |
| 32 @CalledByNative | 56 @CalledByNative |
| 33 private void scheduleWork() { | 57 private void scheduleWork() { |
| 34 sendEmptyMessage(SCHEDULED_WORK); | 58 sendMessage(obtainAsyncMessage(SCHEDULED_WORK)); |
| 35 } | 59 } |
| 36 | 60 |
| 37 @SuppressWarnings("unused") | 61 @SuppressWarnings("unused") |
| 38 @CalledByNative | 62 @CalledByNative |
| 39 private void scheduleDelayedWork(long delayedTimeTicks, long millis) { | 63 private void scheduleDelayedWork(long delayedTimeTicks, long millis) { |
| 40 if (mDelayedScheduledTimeTicks != 0) { | 64 if (mDelayedScheduledTimeTicks != 0) { |
| 41 removeMessages(DELAYED_SCHEDULED_WORK); | 65 removeMessages(DELAYED_SCHEDULED_WORK); |
| 42 } | 66 } |
| 43 mDelayedScheduledTimeTicks = delayedTimeTicks; | 67 mDelayedScheduledTimeTicks = delayedTimeTicks; |
| 44 sendEmptyMessageDelayed(DELAYED_SCHEDULED_WORK, millis); | 68 sendMessageDelayed(obtainAsyncMessage(DELAYED_SCHEDULED_WORK), millis); |
| 45 } | 69 } |
| 46 | 70 |
| 47 @SuppressWarnings("unused") | 71 @SuppressWarnings("unused") |
| 48 @CalledByNative | 72 @CalledByNative |
| 49 private void removeAllPendingMessages() { | 73 private void removeAllPendingMessages() { |
| 50 removeMessages(SCHEDULED_WORK); | 74 removeMessages(SCHEDULED_WORK); |
| 51 removeMessages(DELAYED_SCHEDULED_WORK); | 75 removeMessages(DELAYED_SCHEDULED_WORK); |
| 52 } | 76 } |
| 53 | 77 |
| 78 private Message obtainAsyncMessage(int what) { | |
| 79 Message msg = Message.obtain(); | |
| 80 msg.what = what; | |
| 81 if (mMessageMethodSetAsynchonous != null) { | |
| 82 try { | |
| 83 mMessageMethodSetAsynchonous.invoke(msg, true); | |
| 84 } catch (Exception e) { | |
|
nyquist
2014/08/28 23:27:27
Why is this not catching IllegalAccessException, I
jdduke (slow)
2014/08/28 23:37:03
In practice, I'm not sure that we care, and I don'
jdduke (slow)
2014/08/28 23:54:41
Ditto above.
| |
| 85 Log.e(TAG, "Exception marking message as asynchronous: " + e); | |
| 86 // Assume that any failure is indicative of future failures, and | |
| 87 // avoid log spam by nulling the reflected method. | |
| 88 mMessageMethodSetAsynchonous = null; | |
| 89 } | |
| 90 } | |
| 91 return msg; | |
| 92 } | |
| 93 | |
| 54 @CalledByNative | 94 @CalledByNative |
| 55 private static SystemMessageHandler create(long messagePumpDelegateNative) { | 95 private static SystemMessageHandler create(long messagePumpDelegateNative) { |
| 56 return new SystemMessageHandler(messagePumpDelegateNative); | 96 return new SystemMessageHandler(messagePumpDelegateNative); |
| 57 } | 97 } |
| 58 | 98 |
| 59 private native void nativeDoRunLoopOnce( | 99 private native void nativeDoRunLoopOnce( |
| 60 long messagePumpDelegateNative, long delayedScheduledTimeTicks); | 100 long messagePumpDelegateNative, long delayedScheduledTimeTicks); |
| 61 } | 101 } |
| OLD | NEW |