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:
Dianne Hackborn
2012-05-08 18:53:51 -07:00
parent 8b2e37e5a0
commit a53de0629f
10 changed files with 180 additions and 10 deletions

View File

@@ -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

View File

@@ -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)

View File

@@ -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();
}
}
}
}

View File

@@ -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() {
}

View File

@@ -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.

View File

@@ -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;

View File

@@ -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

View File

@@ -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)

View File

@@ -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;

View File

@@ -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) {