diff options
Diffstat (limited to 'core/java/android')
| -rw-r--r-- | core/java/android/app/ActivityThread.java | 85 | ||||
| -rw-r--r-- | core/java/android/app/ApplicationThreadNative.java | 4 | ||||
| -rw-r--r-- | core/java/android/content/res/Configuration.java | 127 | ||||
| -rw-r--r-- | core/java/android/os/Binder.java | 33 | ||||
| -rw-r--r-- | core/java/android/os/IBinder.java | 10 | ||||
| -rw-r--r-- | core/java/android/os/Parcel.java | 2 | ||||
| -rw-r--r-- | core/java/android/os/ParcelFileDescriptor.java | 11 |
7 files changed, 184 insertions, 88 deletions
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 67e8839..6c8f85f 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -367,11 +367,10 @@ public final class ActivityThread { } static final class DumpComponentInfo { - FileDescriptor fd; + ParcelFileDescriptor fd; IBinder token; String prefix; String[] args; - boolean dumped; } static final class ResultData { @@ -639,20 +638,13 @@ public final class ActivityThread { public void dumpService(FileDescriptor fd, IBinder servicetoken, String[] args) { DumpComponentInfo data = new DumpComponentInfo(); - data.fd = fd; - data.token = servicetoken; - data.args = args; - data.dumped = false; - queueOrSendMessage(H.DUMP_SERVICE, data); - synchronized (data) { - while (!data.dumped) { - try { - data.wait(); - } catch (InterruptedException e) { - // no need to do anything here, we will keep waiting until - // dumped is set - } - } + try { + data.fd = ParcelFileDescriptor.dup(fd); + data.token = servicetoken; + data.args = args; + queueOrSendMessage(H.DUMP_SERVICE, data); + } catch (IOException e) { + Slog.w(TAG, "dumpService failed", e); } } @@ -714,21 +706,14 @@ public final class ActivityThread { public void dumpActivity(FileDescriptor fd, IBinder activitytoken, String prefix, String[] args) { DumpComponentInfo data = new DumpComponentInfo(); - data.fd = fd; - data.token = activitytoken; - data.prefix = prefix; - data.args = args; - data.dumped = false; - queueOrSendMessage(H.DUMP_ACTIVITY, data); - synchronized (data) { - while (!data.dumped) { - try { - data.wait(); - } catch (InterruptedException e) { - // no need to do anything here, we will keep waiting until - // dumped is set - } - } + try { + data.fd = ParcelFileDescriptor.dup(fd); + data.token = activitytoken; + data.prefix = prefix; + data.args = args; + queueOrSendMessage(H.DUMP_ACTIVITY, data); + } catch (IOException e) { + Slog.w(TAG, "dumpActivity failed", e); } } @@ -2154,33 +2139,27 @@ public final class ActivityThread { } private void handleDumpService(DumpComponentInfo info) { - try { - Service s = mServices.get(info.token); - if (s != null) { - PrintWriter pw = new PrintWriter(new FileOutputStream(info.fd)); - s.dump(info.fd, pw, info.args); - pw.close(); - } - } finally { - synchronized (info) { - info.dumped = true; - info.notifyAll(); + Service s = mServices.get(info.token); + if (s != null) { + PrintWriter pw = new PrintWriter(new FileOutputStream(info.fd.getFileDescriptor())); + s.dump(info.fd.getFileDescriptor(), pw, info.args); + pw.flush(); + try { + info.fd.close(); + } catch (IOException e) { } } } private void handleDumpActivity(DumpComponentInfo info) { - try { - ActivityClientRecord r = mActivities.get(info.token); - if (r != null && r.activity != null) { - PrintWriter pw = new PrintWriter(new FileOutputStream(info.fd)); - r.activity.dump(info.prefix, info.fd, pw, info.args); - pw.close(); - } - } finally { - synchronized (info) { - info.dumped = true; - info.notifyAll(); + ActivityClientRecord r = mActivities.get(info.token); + if (r != null && r.activity != null) { + PrintWriter pw = new PrintWriter(new FileOutputStream(info.fd.getFileDescriptor())); + r.activity.dump(info.prefix, info.fd.getFileDescriptor(), pw, info.args); + pw.flush(); + try { + info.fd.close(); + } catch (IOException e) { } } } diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java index e1d76a4..850ad2b 100644 --- a/core/java/android/app/ApplicationThreadNative.java +++ b/core/java/android/app/ApplicationThreadNative.java @@ -845,7 +845,7 @@ class ApplicationThreadProxy implements IApplicationThread { data.writeFileDescriptor(fd); data.writeStrongBinder(token); data.writeStringArray(args); - mRemote.transact(DUMP_SERVICE_TRANSACTION, data, null, 0); + mRemote.transact(DUMP_SERVICE_TRANSACTION, data, null, IBinder.FLAG_ONEWAY); data.recycle(); } @@ -967,7 +967,7 @@ class ApplicationThreadProxy implements IApplicationThread { data.writeStrongBinder(token); data.writeString(prefix); data.writeStringArray(args); - mRemote.transact(DUMP_ACTIVITY_TRANSACTION, data, null, 0); + mRemote.transact(DUMP_ACTIVITY_TRANSACTION, data, null, IBinder.FLAG_ONEWAY); data.recycle(); } diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java index de2b1da..4ac72fd 100644 --- a/core/java/android/content/res/Configuration.java +++ b/core/java/android/content/res/Configuration.java @@ -303,45 +303,106 @@ public final class Configuration implements Parcelable, Comparable<Configuration public String toString() { StringBuilder sb = new StringBuilder(128); - sb.append("{ scale="); + sb.append("{ fnt="); sb.append(fontScale); sb.append(" imsi="); sb.append(mcc); sb.append("/"); sb.append(mnc); - sb.append(" loc="); - sb.append(locale); - sb.append(" touch="); - sb.append(touchscreen); - sb.append(" keys="); - sb.append(keyboard); - sb.append("/"); - sb.append(keyboardHidden); - sb.append("/"); - sb.append(hardKeyboardHidden); - sb.append(" nav="); - sb.append(navigation); - sb.append("/"); - sb.append(navigationHidden); - sb.append(" orien="); - switch(orientation) { - case ORIENTATION_LANDSCAPE: - sb.append("L"); break; - case ORIENTATION_PORTRAIT: - sb.append("P"); break; - default: - sb.append(orientation); - } - sb.append(" layout=0x"); - sb.append(java.lang.Integer.toHexString(screenLayout)); - sb.append(" uiMode=0x"); - sb.append(java.lang.Integer.toHexString(uiMode)); - sb.append(" wdp="); - sb.append(screenWidthDp); - sb.append(" hdp="); - sb.append(screenHeightDp); + if (locale != null) { + sb.append(" "); + sb.append(locale); + } else { + sb.append(" (no locale)"); + } + switch (touchscreen) { + case TOUCHSCREEN_UNDEFINED: sb.append(" ?touch"); break; + case TOUCHSCREEN_NOTOUCH: sb.append(" -touch"); break; + case TOUCHSCREEN_STYLUS: sb.append(" stylus"); break; + case TOUCHSCREEN_FINGER: sb.append(" finger"); break; + default: sb.append(" touch="); sb.append(touchscreen); break; + } + switch (keyboard) { + case KEYBOARD_UNDEFINED: sb.append(" ?keyb"); break; + case KEYBOARD_NOKEYS: sb.append(" -keyb"); break; + case KEYBOARD_QWERTY: sb.append(" qwerty"); break; + case KEYBOARD_12KEY: sb.append(" 12key"); break; + default: sb.append(" keys="); sb.append(keyboard); break; + } + switch (keyboardHidden) { + case KEYBOARDHIDDEN_UNDEFINED: sb.append("/?"); break; + case KEYBOARDHIDDEN_NO: sb.append("/v"); break; + case KEYBOARDHIDDEN_YES: sb.append("/h"); break; + case KEYBOARDHIDDEN_SOFT: sb.append("/s"); break; + default: sb.append("/"); sb.append(keyboardHidden); break; + } + switch (hardKeyboardHidden) { + case HARDKEYBOARDHIDDEN_UNDEFINED: sb.append("/?"); break; + case HARDKEYBOARDHIDDEN_NO: sb.append("/v"); break; + case HARDKEYBOARDHIDDEN_YES: sb.append("/h"); break; + default: sb.append("/"); sb.append(hardKeyboardHidden); break; + } + switch (navigation) { + case NAVIGATION_UNDEFINED: sb.append(" ?nav"); break; + case NAVIGATION_NONAV: sb.append(" -nav"); break; + case NAVIGATION_DPAD: sb.append(" dpad"); break; + case NAVIGATION_TRACKBALL: sb.append(" tball"); break; + case NAVIGATION_WHEEL: sb.append(" wheel"); break; + default: sb.append(" nav="); sb.append(navigation); break; + } + switch (navigationHidden) { + case NAVIGATIONHIDDEN_UNDEFINED: sb.append("/?"); break; + case NAVIGATIONHIDDEN_NO: sb.append("/v"); break; + case NAVIGATIONHIDDEN_YES: sb.append("/h"); break; + default: sb.append("/"); sb.append(navigationHidden); break; + } + switch (orientation) { + case ORIENTATION_UNDEFINED: sb.append(" ?orien"); break; + case ORIENTATION_LANDSCAPE: sb.append(" land"); break; + case ORIENTATION_PORTRAIT: sb.append(" port"); break; + default: sb.append(" orien="); sb.append(orientation); break; + } + switch ((screenLayout&SCREENLAYOUT_SIZE_MASK)) { + case SCREENLAYOUT_SIZE_UNDEFINED: sb.append(" ?lsize"); break; + case SCREENLAYOUT_SIZE_SMALL: sb.append(" smll"); break; + case SCREENLAYOUT_SIZE_NORMAL: sb.append(" nrml"); break; + case SCREENLAYOUT_SIZE_LARGE: sb.append(" lrg"); break; + case SCREENLAYOUT_SIZE_XLARGE: sb.append(" xlrg"); break; + default: sb.append(" layoutSize="); + sb.append(screenLayout&SCREENLAYOUT_SIZE_MASK); break; + } + switch ((screenLayout&SCREENLAYOUT_LONG_MASK)) { + case SCREENLAYOUT_LONG_UNDEFINED: sb.append(" ?long"); break; + case SCREENLAYOUT_LONG_NO: /* not-long is not interesting to print */ break; + case SCREENLAYOUT_LONG_YES: sb.append(" long"); break; + default: sb.append(" layoutLong="); + sb.append(screenLayout&SCREENLAYOUT_LONG_MASK); break; + } + switch ((uiMode&UI_MODE_TYPE_MASK)) { + case UI_MODE_TYPE_UNDEFINED: sb.append(" ?uimode"); break; + case UI_MODE_TYPE_NORMAL: /* normal is not interesting to print */ break; + case UI_MODE_TYPE_DESK: sb.append(" desk"); break; + case UI_MODE_TYPE_CAR: sb.append(" car"); break; + default: sb.append(" uimode="); sb.append(uiMode&UI_MODE_TYPE_MASK); break; + } + switch ((uiMode&UI_MODE_NIGHT_MASK)) { + case UI_MODE_NIGHT_UNDEFINED: sb.append(" ?night"); break; + case UI_MODE_NIGHT_NO: /* not-night is not interesting to print */ break; + case UI_MODE_NIGHT_YES: sb.append(" night"); break; + default: sb.append(" night="); sb.append(uiMode&UI_MODE_NIGHT_MASK); break; + } + if (screenWidthDp != SCREEN_WIDTH_DP_UNDEFINED) { + sb.append(" w"); sb.append(screenWidthDp); sb.append("dp"); + } else { + sb.append("?wdp"); + } + if (screenHeightDp != SCREEN_HEIGHT_DP_UNDEFINED) { + sb.append(" h"); sb.append(screenHeightDp); sb.append("dp"); + } else { + sb.append("?hdp"); + } if (seq != 0) { - sb.append(" seq="); + sb.append(" s."); sb.append(seq); } sb.append('}'); diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java index 7dc36f9..ae1e1c2 100644 --- a/core/java/android/os/Binder.java +++ b/core/java/android/os/Binder.java @@ -256,6 +256,25 @@ public class Binder implements IBinder { } /** + * Like {@link #dump(FileDescriptor, String[])}, but ensures the target + * executes asynchronously. + */ + public void dumpAsync(final FileDescriptor fd, final String[] args) { + final FileOutputStream fout = new FileOutputStream(fd); + final PrintWriter pw = new PrintWriter(fout); + Thread thr = new Thread("Binder.dumpAsync") { + public void run() { + try { + dump(fd, pw, args); + } finally { + pw.flush(); + } + } + }; + thr.start(); + } + + /** * Print the object's state into the given stream. * * @param fd The raw file descriptor that the dump is being sent to. @@ -364,6 +383,20 @@ final class BinderProxy implements IBinder { } } + public void dumpAsync(FileDescriptor fd, String[] args) throws RemoteException { + Parcel data = Parcel.obtain(); + Parcel reply = Parcel.obtain(); + data.writeFileDescriptor(fd); + data.writeStringArray(args); + try { + transact(DUMP_TRANSACTION, data, reply, FLAG_ONEWAY); + reply.readException(); + } finally { + data.recycle(); + reply.recycle(); + } + } + BinderProxy() { mSelf = new WeakReference(this); } diff --git a/core/java/android/os/IBinder.java b/core/java/android/os/IBinder.java index 8ae8008..8876354 100644 --- a/core/java/android/os/IBinder.java +++ b/core/java/android/os/IBinder.java @@ -157,6 +157,16 @@ public interface IBinder { public void dump(FileDescriptor fd, String[] args) throws RemoteException; /** + * Like {@link #dump(FileDescriptor, String[])} but always executes + * asynchronously. If the object is local, a new thread is created + * to perform the dump. + * + * @param fd The raw file descriptor that the dump is being sent to. + * @param args additional arguments to the dump request. + */ + public void dumpAsync(FileDescriptor fd, String[] args) throws RemoteException; + + /** * Perform a generic operation with the object. * * @param code The action to perform. This should diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java index eca3484..6b35215 100644 --- a/core/java/android/os/Parcel.java +++ b/core/java/android/os/Parcel.java @@ -1383,6 +1383,8 @@ public final class Parcel { private native FileDescriptor internalReadFileDescriptor(); /*package*/ static native FileDescriptor openFileDescriptor(String file, int mode) throws FileNotFoundException; + /*package*/ static native FileDescriptor dupFileDescriptor(FileDescriptor orig) + throws IOException; /*package*/ static native void closeFileDescriptor(FileDescriptor desc) throws IOException; /*package*/ static native void clearFileDescriptor(FileDescriptor desc); diff --git a/core/java/android/os/ParcelFileDescriptor.java b/core/java/android/os/ParcelFileDescriptor.java index 5bd129f..aa959b4 100644 --- a/core/java/android/os/ParcelFileDescriptor.java +++ b/core/java/android/os/ParcelFileDescriptor.java @@ -117,6 +117,17 @@ public class ParcelFileDescriptor implements Parcelable { } /** + * Create a new ParcelFileDescriptor that is a dup of an existing + * FileDescriptor. This obeys standard POSIX semantics, where the + * new file descriptor shared state such as file position with the + * original file descriptor. + */ + public static ParcelFileDescriptor dup(FileDescriptor orig) throws IOException { + FileDescriptor fd = Parcel.dupFileDescriptor(orig); + return fd != null ? new ParcelFileDescriptor(fd) : null; + } + + /** * Create a new ParcelFileDescriptor from the specified Socket. * * @param socket The Socket whose FileDescriptor is used to create |
