Add callback hack to find out when to load system properties.
Use this to reload the trace and layout bounds properties. This is ONLY for debugging. Change-Id: I1c4bdb52c823520c352c5bac45fa9ee31160793c
This commit is contained in:
@@ -140,6 +140,9 @@ public interface IBinder {
|
||||
*/
|
||||
int LIKE_TRANSACTION = ('_'<<24)|('L'<<16)|('I'<<8)|'K';
|
||||
|
||||
/** @hide */
|
||||
int SYSPROPS_TRANSACTION = ('_'<<24)|('S'<<16)|('P'<<8)|'R';
|
||||
|
||||
/**
|
||||
* Flag to {@link #transact}: this is a one-way call, meaning that the
|
||||
* caller returns immediately, without waiting for a result from the
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package android.os;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
|
||||
/**
|
||||
* Native implementation of the service manager. Most clients will only
|
||||
@@ -151,14 +153,32 @@ class ServiceManagerProxy implements IServiceManager {
|
||||
}
|
||||
|
||||
public String[] listServices() throws RemoteException {
|
||||
Parcel data = Parcel.obtain();
|
||||
Parcel reply = Parcel.obtain();
|
||||
data.writeInterfaceToken(IServiceManager.descriptor);
|
||||
mRemote.transact(LIST_SERVICES_TRANSACTION, data, reply, 0);
|
||||
String[] list = reply.readStringArray();
|
||||
reply.recycle();
|
||||
data.recycle();
|
||||
return list;
|
||||
ArrayList<String> services = new ArrayList<String>();
|
||||
int n = 0;
|
||||
while (true) {
|
||||
Parcel data = Parcel.obtain();
|
||||
Parcel reply = Parcel.obtain();
|
||||
data.writeInterfaceToken(IServiceManager.descriptor);
|
||||
data.writeInt(n);
|
||||
n++;
|
||||
try {
|
||||
boolean res = mRemote.transact(LIST_SERVICES_TRANSACTION, data, reply, 0);
|
||||
if (!res) {
|
||||
break;
|
||||
}
|
||||
} catch (RuntimeException e) {
|
||||
// The result code that is returned by the C++ code can
|
||||
// cause the call to throw an exception back instead of
|
||||
// returning a nice result... so eat it here and go on.
|
||||
break;
|
||||
}
|
||||
services.add(reply.readString());
|
||||
reply.recycle();
|
||||
data.recycle();
|
||||
}
|
||||
String[] array = new String[services.size()];
|
||||
services.toArray(array);
|
||||
return array;
|
||||
}
|
||||
|
||||
public void setPermissionController(IPermissionController controller)
|
||||
|
||||
@@ -16,6 +16,10 @@
|
||||
|
||||
package android.os;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
|
||||
/**
|
||||
* Gives access to the system properties store. The system properties
|
||||
@@ -28,12 +32,15 @@ public class SystemProperties
|
||||
public static final int PROP_NAME_MAX = 31;
|
||||
public static final int PROP_VALUE_MAX = 91;
|
||||
|
||||
private static final ArrayList<Runnable> sChangeCallbacks = new ArrayList<Runnable>();
|
||||
|
||||
private static native String native_get(String key);
|
||||
private static native String native_get(String key, String def);
|
||||
private static native int native_get_int(String key, int def);
|
||||
private static native long native_get_long(String key, long def);
|
||||
private static native boolean native_get_boolean(String key, boolean def);
|
||||
private static native void native_set(String key, String def);
|
||||
private static native void native_add_change_callback();
|
||||
|
||||
/**
|
||||
* Get the value for the given key.
|
||||
@@ -124,4 +131,26 @@ public class SystemProperties
|
||||
}
|
||||
native_set(key, val);
|
||||
}
|
||||
|
||||
public static void addChangeCallback(Runnable callback) {
|
||||
synchronized (sChangeCallbacks) {
|
||||
if (sChangeCallbacks.size() == 0) {
|
||||
native_add_change_callback();
|
||||
}
|
||||
sChangeCallbacks.add(callback);
|
||||
}
|
||||
}
|
||||
|
||||
static void callChangeCallbacks() {
|
||||
synchronized (sChangeCallbacks) {
|
||||
//Log.i("foo", "Calling " + sChangeCallbacks.size() + " change callbacks!");
|
||||
if (sChangeCallbacks.size() == 0) {
|
||||
return;
|
||||
}
|
||||
ArrayList<Runnable> callbacks = new ArrayList<Runnable>(sChangeCallbacks);
|
||||
for (int i=0; i<callbacks.size(); i++) {
|
||||
callbacks.get(i).run();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,13 +47,21 @@ public final class Trace {
|
||||
|
||||
public static final String PROPERTY_TRACE_TAG_ENABLEFLAGS = "debug.atrace.tags.enableflags";
|
||||
|
||||
private static final long sEnabledTags = nativeGetEnabledTags();
|
||||
private static long sEnabledTags = nativeGetEnabledTags();
|
||||
|
||||
private static native long nativeGetEnabledTags();
|
||||
private static native void nativeTraceCounter(long tag, String name, int value);
|
||||
private static native void nativeTraceBegin(long tag, String name);
|
||||
private static native void nativeTraceEnd(long tag);
|
||||
|
||||
static {
|
||||
SystemProperties.addChangeCallback(new Runnable() {
|
||||
@Override public void run() {
|
||||
sEnabledTags = nativeGetEnabledTags();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private Trace() {
|
||||
}
|
||||
|
||||
|
||||
@@ -17250,7 +17250,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
|
||||
/**
|
||||
* Show where the margins, bounds and layout bounds are for each view.
|
||||
*/
|
||||
final boolean mDebugLayout = SystemProperties.getBoolean(DEBUG_LAYOUT_PROPERTY, false);
|
||||
boolean mDebugLayout = SystemProperties.getBoolean(DEBUG_LAYOUT_PROPERTY, false);
|
||||
|
||||
/**
|
||||
* Point used to compute visible regions.
|
||||
|
||||
@@ -408,6 +408,7 @@ public final class ViewRootImpl implements ViewParent,
|
||||
|
||||
PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
|
||||
mAttachInfo.mScreenOn = powerManager.isScreenOn();
|
||||
loadSystemProperties();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -846,6 +847,16 @@ public final class ViewRootImpl implements ViewParent,
|
||||
scheduleTraversals();
|
||||
}
|
||||
|
||||
void invalidateWorld(View view) {
|
||||
view.invalidate();
|
||||
if (view instanceof ViewGroup) {
|
||||
ViewGroup parent = (ViewGroup)view;
|
||||
for (int i=0; i<parent.getChildCount(); i++) {
|
||||
invalidateWorld(parent.getChildAt(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void invalidateChild(View child, Rect dirty) {
|
||||
invalidateChildInParent(null, dirty);
|
||||
}
|
||||
@@ -2730,6 +2741,7 @@ public final class ViewRootImpl implements ViewParent,
|
||||
private final static int MSG_INVALIDATE_DISPLAY_LIST = 21;
|
||||
private final static int MSG_CLEAR_ACCESSIBILITY_FOCUS_HOST = 22;
|
||||
private final static int MSG_DISPATCH_DONE_ANIMATING = 23;
|
||||
private final static int MSG_INVALIDATE_WORLD = 24;
|
||||
|
||||
final class ViewRootHandler extends Handler {
|
||||
@Override
|
||||
@@ -2997,6 +3009,9 @@ public final class ViewRootImpl implements ViewParent,
|
||||
case MSG_DISPATCH_DONE_ANIMATING: {
|
||||
handleDispatchDoneAnimating();
|
||||
} break;
|
||||
case MSG_INVALIDATE_WORLD: {
|
||||
invalidateWorld(mView);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4016,6 +4031,17 @@ public final class ViewRootImpl implements ViewParent,
|
||||
mHandler.sendMessage(msg);
|
||||
}
|
||||
|
||||
public void loadSystemProperties() {
|
||||
boolean layout = SystemProperties.getBoolean(
|
||||
View.DEBUG_LAYOUT_PROPERTY, false);
|
||||
if (layout != mAttachInfo.mDebugLayout) {
|
||||
mAttachInfo.mDebugLayout = layout;
|
||||
if (!mHandler.hasMessages(MSG_INVALIDATE_WORLD)) {
|
||||
mHandler.sendEmptyMessageDelayed(MSG_INVALIDATE_WORLD, 200);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void destroyHardwareRenderer() {
|
||||
AttachInfo attachInfo = mAttachInfo;
|
||||
HardwareRenderer hardwareRenderer = attachInfo.mHardwareRenderer;
|
||||
|
||||
@@ -23,6 +23,7 @@ import android.content.res.Configuration;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.opengl.ManagedEGLContext;
|
||||
import android.os.IBinder;
|
||||
import android.os.SystemProperties;
|
||||
import android.util.AndroidRuntimeException;
|
||||
import android.util.Log;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
@@ -112,6 +113,8 @@ public class WindowManagerImpl implements WindowManager {
|
||||
private WindowManager.LayoutParams[] mParams;
|
||||
private boolean mNeedsEglTerminate;
|
||||
|
||||
private Runnable mSystemPropertyUpdater = null;
|
||||
|
||||
private final static Object sLock = new Object();
|
||||
private final static WindowManagerImpl sWindowManager = new WindowManagerImpl();
|
||||
private final static HashMap<CompatibilityInfo, WindowManager> sCompatWindowManagers
|
||||
@@ -237,6 +240,22 @@ public class WindowManagerImpl implements WindowManager {
|
||||
View panelParentView = null;
|
||||
|
||||
synchronized (this) {
|
||||
// Start watching for system property changes.
|
||||
if (mSystemPropertyUpdater == null) {
|
||||
mSystemPropertyUpdater = new Runnable() {
|
||||
@Override public void run() {
|
||||
synchronized (this) {
|
||||
synchronized (this) {
|
||||
for (ViewRootImpl root : mRoots) {
|
||||
root.loadSystemProperties();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
SystemProperties.addChangeCallback(mSystemPropertyUpdater);
|
||||
}
|
||||
|
||||
// Here's an odd/questionable case: if someone tries to add a
|
||||
// view multiple times, then we simply bump up a nesting count
|
||||
// and they need to remove the view the corresponding number of
|
||||
|
||||
@@ -15,7 +15,11 @@
|
||||
** limitations under the License.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "SysPropJNI"
|
||||
|
||||
#include "cutils/properties.h"
|
||||
#include "utils/misc.h"
|
||||
#include <utils/Log.h>
|
||||
#include "jni.h"
|
||||
#include "android_runtime/AndroidRuntime.h"
|
||||
#include <nativehelper/JNIHelp.h>
|
||||
@@ -188,6 +192,34 @@ static void SystemProperties_set(JNIEnv *env, jobject clazz,
|
||||
}
|
||||
}
|
||||
|
||||
static JavaVM* sVM = NULL;
|
||||
static jclass sClazz = NULL;
|
||||
static jmethodID sCallChangeCallbacks;
|
||||
|
||||
static void do_report_sysprop_change() {
|
||||
//ALOGI("Java SystemProperties: VM=%p, Clazz=%p", sVM, sClazz);
|
||||
if (sVM != NULL && sClazz != NULL) {
|
||||
JNIEnv* env;
|
||||
if (sVM->GetEnv((void **)&env, JNI_VERSION_1_4) >= 0) {
|
||||
//ALOGI("Java SystemProperties: calling %p", sCallChangeCallbacks);
|
||||
env->CallStaticVoidMethod(sClazz, sCallChangeCallbacks);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void SystemProperties_add_change_callback(JNIEnv *env, jobject clazz)
|
||||
{
|
||||
// This is called with the Java lock held.
|
||||
if (sVM == NULL) {
|
||||
env->GetJavaVM(&sVM);
|
||||
}
|
||||
if (sClazz == NULL) {
|
||||
sClazz = (jclass) env->NewGlobalRef(clazz);
|
||||
sCallChangeCallbacks = env->GetStaticMethodID(sClazz, "callChangeCallbacks", "()V");
|
||||
add_sysprop_change_callback(do_report_sysprop_change, -10000);
|
||||
}
|
||||
}
|
||||
|
||||
static JNINativeMethod method_table[] = {
|
||||
{ "native_get", "(Ljava/lang/String;)Ljava/lang/String;",
|
||||
(void*) SystemProperties_getS },
|
||||
@@ -201,6 +233,8 @@ static JNINativeMethod method_table[] = {
|
||||
(void*) SystemProperties_get_boolean },
|
||||
{ "native_set", "(Ljava/lang/String;Ljava/lang/String;)V",
|
||||
(void*) SystemProperties_set },
|
||||
{ "native_add_change_callback", "()V",
|
||||
(void*) SystemProperties_add_change_callback },
|
||||
};
|
||||
|
||||
int register_android_os_SystemProperties(JNIEnv *env)
|
||||
|
||||
@@ -308,6 +308,12 @@ protected:
|
||||
env->DeleteLocalRef(excep2);
|
||||
}
|
||||
|
||||
// Need to always call through the native implementation of
|
||||
// SYSPROPS_TRANSACTION.
|
||||
if (code == SYSPROPS_TRANSACTION) {
|
||||
BBinder::onTransact(code, data, reply, flags);
|
||||
}
|
||||
|
||||
//aout << "onTransact to Java code; result=" << res << endl
|
||||
// << "Transact from " << this << " to Java code returning "
|
||||
// << reply << ": " << *reply << endl;
|
||||
|
||||
@@ -1567,6 +1567,31 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
@Override
|
||||
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
|
||||
throws RemoteException {
|
||||
if (code == SYSPROPS_TRANSACTION) {
|
||||
// We need to tell all apps about the system property change.
|
||||
ArrayList<IBinder> procs = new ArrayList<IBinder>();
|
||||
synchronized(this) {
|
||||
for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
|
||||
final int NA = apps.size();
|
||||
for (int ia=0; ia<NA; ia++) {
|
||||
ProcessRecord app = apps.valueAt(ia);
|
||||
if (app.thread != null) {
|
||||
procs.add(app.thread.asBinder());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int N = procs.size();
|
||||
for (int i=0; i<N; i++) {
|
||||
Parcel data2 = Parcel.obtain();
|
||||
try {
|
||||
procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
data2.recycle();
|
||||
}
|
||||
}
|
||||
try {
|
||||
return super.onTransact(code, data, reply, flags);
|
||||
} catch (RuntimeException e) {
|
||||
|
||||
Reference in New Issue
Block a user