org.robovm.rt.Signals Maven / Gradle / Ivy
/*
* Copyright (C) 2014 RoboVM AB
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.robovm.rt;
/**
* Provides a means for installing custom signal handlers without overriding
* the signal handlers needed by RoboVM to handle {@link NullPointerException}s
* and {@link StackOverflowError}s properly. This should be used when using
* crash reporting services like TestFlight, Flurry or HockeyApp. The
* initialization method for the crash reporting service SDK should be called
* inside an {@link InstallSignalsCallback} using the
* {@link #installSignals(InstallSignalsCallback)} method.
*
* NOTE! This should be called as early as possible in the app from the main
* thread and MUST be called before any other threads have been created.
*/
public class Signals {
private static boolean called = false;
/**
* Encapsulates the user code which typically initializes a crash report
* service SDK or in some other way modifies signal handlers.
*/
public interface InstallSignalsCallback {
/**
* Called by {@link Signals#installSignals(InstallSignalsCallback)}
* to install the custom signal handlers.
*/
void install();
}
/**
* Saves the current signal handlers essential for RoboVM to work correctly
* then calls the specified {@link InstallSignalsCallback} and
* finally restores the saved signals chaining them to installed ones
* properly.
*/
public static void installSignals(InstallSignalsCallback callback) {
if (callback == null) {
throw new NullPointerException("callback");
}
if (called) {
throw new IllegalStateException(Signals.class.getSimpleName()
+ ".installSignals() called twice");
}
long state = saveSignals();
try {
callback.install();
} finally {
called = true;
installChainingSignals();
reinstallSavedSignals(state);
}
}
private native static void installChainingSignals();
private native static void reinstallSavedSignals(long state);
private native static long saveSignals();
}