com.virjar.ratel.api.rposed.callbacks.RCallback Maven / Gradle / Ivy
Show all versions of ratel-api Show documentation
package com.virjar.ratel.api.rposed.callbacks;
import android.os.Bundle;
import com.virjar.ratel.api.rposed.RposedBridge;
import java.io.Serializable;
/**
* Base class for Xposed callbacks.
*
* This class only keeps a priority for ordering multiple callbacks.
* The actual (abstract) callback methods are added by subclasses.
*/
public abstract class RCallback implements Comparable {
/**
* Callback priority, higher number means earlier execution.
*
* This is usually set to {@link #PRIORITY_DEFAULT}. However, in case a certain callback should
* be executed earlier or later a value between {@link #PRIORITY_HIGHEST} and {@link #PRIORITY_LOWEST}
* can be set instead. The values are just for orientation though, Xposed doesn't enforce any
* boundaries on the priority values.
*/
public final int priority;
/**
* @deprecated This constructor can't be hidden for technical reasons. Nevertheless, don't use it!
*/
@Deprecated
public RCallback() {
this.priority = PRIORITY_DEFAULT;
}
/**
* @hide
*/
public RCallback(int priority) {
this.priority = priority;
}
/**
* Base class for Xposed callback parameters.
*/
public static abstract class Param {
/**
* @hide
*/
public Object[] callbacks;
public Bundle extra;
/**
* @deprecated This constructor can't be hidden for technical reasons. Nevertheless, don't use it!
*/
@Deprecated
protected Param() {
callbacks = null;
}
/**
* @hide
*/
protected Param(RposedBridge.CopyOnWriteSortedSet extends RCallback> callbacks) {
this.callbacks = callbacks.getSnapshot();
}
/**
* This can be used to store any data for the scope of the callback.
*
*
Use this instead of instance variables, as it has a clear reference to e.g. each
* separate call to a method, even when the same method is called recursively.
*
* @see #setObjectExtra
* @see #getObjectExtra
*/
public synchronized Bundle getExtra() {
if (extra == null)
extra = new Bundle();
return extra;
}
/**
* Returns an object stored with {@link #setObjectExtra}.
*/
public Object getObjectExtra(String key) {
Serializable o = getExtra().getSerializable(key);
if (o instanceof SerializeWrapper)
return ((SerializeWrapper) o).object;
return null;
}
/**
* Stores any object for the scope of the callback. For data types that support it, use
* the {@link Bundle} returned by {@link #getExtra} instead.
*/
public void setObjectExtra(String key, Object o) {
getExtra().putSerializable(key, new SerializeWrapper(o));
}
private static class SerializeWrapper implements Serializable {
private static final long serialVersionUID = 1L;
private final Object object;
public SerializeWrapper(Object o) {
object = o;
}
}
}
/**
* @hide
*/
public static void callAll(Param param) {
if (param.callbacks == null)
throw new IllegalStateException("This object was not created for use with callAll");
for (int i = 0; i < param.callbacks.length; i++) {
try {
((RCallback) param.callbacks[i]).call(param);
} catch (Throwable t) {
RposedBridge.log(t);
}
}
}
/**
* @hide
*/
protected void call(Param param) throws Throwable {
}
/**
* @hide
*/
@Override
public int compareTo(RCallback other) {
if (this == other)
return 0;
// order descending by priority
if (other.priority != this.priority)
return other.priority - this.priority;
// then randomly
else if (System.identityHashCode(this) < System.identityHashCode(other))
return -1;
else
return 1;
}
/**
* The default priority, see {@link #priority}.
*/
public static final int PRIORITY_DEFAULT = 50;
/**
* Execute this callback late, see {@link #priority}.
*/
public static final int PRIORITY_LOWEST = -10000;
/**
* Execute this callback early, see {@link #priority}.
*/
public static final int PRIORITY_HIGHEST = 10000;
}