summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Mast <andy@cyngn.com>2015-03-30 09:09:29 -0700
committerAndy Mast <andy@cyngn.com>2015-07-23 08:33:26 -0700
commit6ae1d3b6cb7e6580a8707cbab9cd514ccb975df8 (patch)
tree2ab287000ed48194361c87c74d83ba0095901101
parentde75b0da1cbc68b61e0b309cd1d49c2945c3555c (diff)
downloadandroid_frameworks_base-previewgen2.tar.gz
android_frameworks_base-previewgen2.tar.bz2
android_frameworks_base-previewgen2.zip
*DO NOT SUBMIT* Allow screenshots through 3rd party appspreviewgen2
This is for internal use only. Do not submit as a patch for the general public as it has security holes. For emulator instances where screencap does not work, one can use this patch to allow 3rd party applications to take a screenshot. It uses the same code as HiearchyViewer but with ParcelFileDescriptors instead. The client side should make the call on a separate thread from the reader of the PFD so that the app does not get blocked. Change-Id: I5bfb210e07aacc56e46e87cbe88ed31e73c61f83
-rw-r--r--core/java/android/view/IWindowManager.aidl5
-rw-r--r--core/java/android/view/ViewDebug.java3
-rw-r--r--core/java/android/view/WindowManagerGlobal.java20
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java115
4 files changed, 143 insertions, 0 deletions
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 68776650d6d..ef9540600e6 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -26,6 +26,7 @@ import android.graphics.Point;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.IRemoteCallback;
+import android.os.ParcelFileDescriptor;
import android.view.IApplicationToken;
import android.view.IOnKeyguardExitResult;
import android.view.IRotationWatcher;
@@ -279,4 +280,8 @@ interface IWindowManager
* @return The frame statistics or null if the window does not exist.
*/
WindowContentFrameStats getWindowContentFrameStats(IBinder token);
+
+ String viewServerListWindows2();
+
+ String viewServerWindowCommand2(in ParcelFileDescriptor fd, String command, String parameters);
}
diff --git a/core/java/android/view/ViewDebug.java b/core/java/android/view/ViewDebug.java
index 50e64c6ea6f..1870ec71aaf 100644
--- a/core/java/android/view/ViewDebug.java
+++ b/core/java/android/view/ViewDebug.java
@@ -315,6 +315,7 @@ public class ViewDebug {
private static final int CAPTURE_TIMEOUT = 4000;
private static final String REMOTE_COMMAND_CAPTURE = "CAPTURE";
+ private static final String REMOTE_COMMAND_CAPTURE_ROOT = "CAPTURE_ROOT";
private static final String REMOTE_COMMAND_DUMP = "DUMP";
private static final String REMOTE_COMMAND_DUMP_THEME = "DUMP_THEME";
private static final String REMOTE_COMMAND_INVALIDATE = "INVALIDATE";
@@ -440,6 +441,8 @@ public class ViewDebug {
final String[] params = parameters.split(" ");
if (REMOTE_COMMAND_CAPTURE.equalsIgnoreCase(command)) {
capture(view, clientStream, params[0]);
+ } else if (REMOTE_COMMAND_CAPTURE_ROOT.equalsIgnoreCase(command)) {
+ capture(view, clientStream, view);
} else if (REMOTE_COMMAND_OUTPUT_DISPLAYLIST.equalsIgnoreCase(command)) {
outputDisplayList(view, params[0]);
} else if (REMOTE_COMMAND_INVALIDATE.equalsIgnoreCase(command)) {
diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java
index a14c7661fb4..e8194fccb83 100644
--- a/core/java/android/view/WindowManagerGlobal.java
+++ b/core/java/android/view/WindowManagerGlobal.java
@@ -23,6 +23,7 @@ import android.content.Context;
import android.content.res.Configuration;
import android.os.Build;
import android.os.IBinder;
+import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemProperties;
@@ -35,6 +36,7 @@ import com.android.internal.util.FastPrintWriter;
import java.io.FileDescriptor;
import java.io.FileOutputStream;
import java.io.PrintWriter;
+import java.net.Socket;
import java.util.ArrayList;
/**
@@ -550,6 +552,24 @@ public final class WindowManagerGlobal {
}
}
}
+
+ public static String viewServerListWindows() {
+ try {
+ return sWindowManagerService.viewServerListWindows2();
+ } catch(RemoteException e) {
+ Log.e(TAG, "Could not viewServerListWindows", e);
+ }
+ return null;
+ }
+
+ public static String viewServerWindowCommand(ParcelFileDescriptor fd, String command, String parameters) {
+ try {
+ return sWindowManagerService.viewServerWindowCommand2(fd, command, parameters);
+ } catch(RemoteException e) {
+ Log.e(TAG, "Could not viewServerListWIndows ", e);
+ }
+ return null;
+ }
}
final class WindowLeaked extends AndroidRuntimeException {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 584f01496d7..bbbc43f3922 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -146,6 +146,7 @@ import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
@@ -6934,6 +6935,41 @@ public class WindowManagerService extends IWindowManager.Stub
return mViewServer != null && mViewServer.isRunning();
}
+ public String viewServerListWindows2() {
+ boolean result = true;
+
+ WindowList windows = new WindowList();
+ synchronized (mWindowMap) {
+ //noinspection unchecked
+ final int numDisplays = mDisplayContents.size();
+ for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
+ final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
+ windows.addAll(displayContent.getWindowList());
+ }
+ }
+
+ // Any uncaught exception will crash the system process
+ StringBuffer sb = new StringBuffer();
+ try {
+
+
+ final int count = windows.size();
+ for (int i = 0; i < count; i++) {
+ final WindowState w = windows.get(i);
+ sb.append(Integer.toHexString(System.identityHashCode(w)));
+ sb.append(' ');
+ sb.append(w.mAttrs.getTitle());
+ sb.append('\n');
+ }
+
+ sb.append("DONE.\n");
+ } catch (Exception e) {
+ result = false;
+ }
+
+ return sb.toString();
+ }
+
/**
* Lists all availble windows in the system. The listing is written in the
* specified Socket's output stream with the following syntax:
@@ -7135,6 +7171,85 @@ public class WindowManagerService extends IWindowManager.Stub
return success;
}
+ public String viewServerWindowCommand2(ParcelFileDescriptor fd, String command, String parameters) {
+ if (isSystemSecure()) {
+ return null;
+ }
+
+ boolean success = true;
+ Parcel data = null;
+ Parcel reply = null;
+
+ BufferedWriter out = null;
+
+ // Any uncaught exception will crash the system process
+ try {
+ // Find the hashcode of the window
+ int index = parameters.indexOf(' ');
+ if (index == -1) {
+ index = parameters.length();
+ }
+ final String code = parameters.substring(0, index);
+ int hashCode = (int) Long.parseLong(code, 16);
+
+ // Extract the command's parameter after the window description
+ if (index < parameters.length()) {
+ parameters = parameters.substring(index + 1);
+ } else {
+ parameters = "";
+ }
+
+ final WindowState window = findWindow(hashCode);
+ if (window == null) {
+ return null;
+ }
+
+ data = Parcel.obtain();
+ data.writeInterfaceToken("android.view.IWindow");
+ data.writeString(command);
+ data.writeString(parameters);
+ data.writeInt(1);
+
+ //ParcelFileDescriptor[] fds = ParcelFileDescriptor.createReliableSocketPair();
+ fd.writeToParcel(data, 0);
+
+ reply = Parcel.obtain();
+
+ final IBinder binder = window.mClient.asBinder();
+ // TODO: GET THE TRANSACTION CODE IN A SAFER MANNER
+ binder.transact(IBinder.FIRST_CALL_TRANSACTION, data, reply, 0);
+
+ reply.readException();
+
+ //FileOutputStream appendOut = new FileOutputStream(fd.getFileDescriptor());
+ //OutputStreamWriter writer = new OutputStreamWriter(appendOut);
+ //writer.write("DONE\n");
+
+ //writer.close();
+ //appendOut.flush();
+ //appendOut.close();
+ } catch (Exception e) {
+ Slog.w(TAG, "Could not send command " + command + " with parameters " + parameters, e);
+ success = false;
+ } finally {
+ if (data != null) {
+ data.recycle();
+ }
+ if (reply != null) {
+ reply.recycle();
+ }
+ if (out != null) {
+ try {
+ out.close();
+ } catch (IOException e) {
+
+ }
+ }
+ }
+
+ return "";
+ }
+
public void addWindowChangeListener(WindowChangeListener listener) {
synchronized(mWindowMap) {
mWindowChangeListeners.add(listener);