mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-01 22:55:23 +00:00
115 lines
3.5 KiB
Java
115 lines
3.5 KiB
Java
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
package org.mozilla.gecko;
|
|
|
|
import android.content.BroadcastReceiver;
|
|
import android.content.Context;
|
|
import android.content.Intent;
|
|
import android.content.IntentFilter;
|
|
import android.os.Handler;
|
|
import android.os.Looper;
|
|
import android.util.Log;
|
|
|
|
public final class ANRReporter extends BroadcastReceiver
|
|
{
|
|
private static final boolean DEBUG = false;
|
|
private static final String LOGTAG = "GeckoANRReporter";
|
|
|
|
private static final String ANR_ACTION = "android.intent.action.ANR";
|
|
|
|
private static final ANRReporter sInstance = new ANRReporter();
|
|
private static int sRegisteredCount;
|
|
private Handler mHandler;
|
|
|
|
public static void register(Context context) {
|
|
if (sRegisteredCount++ != 0) {
|
|
// Already registered
|
|
return;
|
|
}
|
|
sInstance.start(context);
|
|
}
|
|
|
|
public static void unregister() {
|
|
if (sRegisteredCount == 0) {
|
|
Log.w(LOGTAG, "register/unregister mismatch");
|
|
return;
|
|
}
|
|
if (--sRegisteredCount != 0) {
|
|
// Should still be registered
|
|
return;
|
|
}
|
|
sInstance.stop();
|
|
}
|
|
|
|
private void start(final Context context) {
|
|
|
|
Thread receiverThread = new Thread(new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
Looper.prepare();
|
|
synchronized (ANRReporter.this) {
|
|
mHandler = new Handler();
|
|
ANRReporter.this.notify();
|
|
}
|
|
if (DEBUG) {
|
|
Log.d(LOGTAG, "registering receiver");
|
|
}
|
|
context.registerReceiver(ANRReporter.this,
|
|
new IntentFilter(ANR_ACTION),
|
|
null,
|
|
mHandler);
|
|
Looper.loop();
|
|
|
|
if (DEBUG) {
|
|
Log.d(LOGTAG, "unregistering receiver");
|
|
}
|
|
context.unregisterReceiver(ANRReporter.this);
|
|
mHandler = null;
|
|
}
|
|
}, LOGTAG);
|
|
|
|
receiverThread.setDaemon(true);
|
|
receiverThread.start();
|
|
}
|
|
|
|
private void stop() {
|
|
synchronized (this) {
|
|
while (mHandler == null) {
|
|
try {
|
|
wait(1000);
|
|
if (mHandler == null) {
|
|
// We timed out; just give up. The process is probably
|
|
// quitting anyways, so we let the OS do the clean up
|
|
Log.w(LOGTAG, "timed out waiting for handler");
|
|
return;
|
|
}
|
|
} catch (InterruptedException e) {
|
|
}
|
|
}
|
|
}
|
|
Looper looper = mHandler.getLooper();
|
|
looper.quit();
|
|
try {
|
|
looper.getThread().join();
|
|
} catch (InterruptedException e) {
|
|
}
|
|
}
|
|
|
|
private ANRReporter() {
|
|
}
|
|
|
|
@Override
|
|
public void onReceive(Context context, Intent intent) {
|
|
if (DEBUG) {
|
|
Log.d(LOGTAG, "receiving " + String.valueOf(intent));
|
|
}
|
|
if (!ANR_ACTION.equals(intent.getAction())) {
|
|
return;
|
|
}
|
|
Log.i(LOGTAG, "processing Gecko ANR");
|
|
}
|
|
}
|