Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5114a686 authored by Svetoslav's avatar Svetoslav Committed by Android Git Automerger
Browse files

am d4de9b44: Merge "Adding shell command execution to UiAutomation."

* commit 'd4de9b446ece4f4bdf16e05bb72bc5bb0199c9ae':
  Adding shell command execution to UiAutomation.
parents 80d0756b a5008742
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -4849,6 +4849,7 @@ package android.app {
    method public void clearWindowAnimationFrameStats();
    method public boolean clearWindowContentFrameStats(int);
    method public android.view.accessibility.AccessibilityEvent executeAndWaitForEvent(java.lang.Runnable, android.app.UiAutomation.AccessibilityEventFilter, long) throws java.util.concurrent.TimeoutException;
    method public android.os.ParcelFileDescriptor executeShellCommand(java.lang.String);
    method public android.view.accessibility.AccessibilityNodeInfo findFocus(int);
    method public android.view.accessibility.AccessibilityNodeInfo getRootInActiveWindow();
    method public final android.accessibilityservice.AccessibilityServiceInfo getServiceInfo();
+1 −0
Original line number Diff line number Diff line
@@ -43,4 +43,5 @@ interface IUiAutomationConnection {
    WindowContentFrameStats getWindowContentFrameStats(int windowId);
    void clearWindowAnimationFrameStats();
    WindowAnimationFrameStats getWindowAnimationFrameStats();
    void executeShellCommand(String command, in ParcelFileDescriptor fd);
}
+41 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import android.graphics.Canvas;
import android.graphics.Point;
import android.hardware.display.DisplayManagerGlobal;
import android.os.Looper;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.os.SystemClock;
import android.util.Log;
@@ -40,7 +41,9 @@ import android.view.accessibility.AccessibilityInteractionClient;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityWindowInfo;
import android.view.accessibility.IAccessibilityInteractionConnection;
import libcore.io.IoUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeoutException;
@@ -840,6 +843,44 @@ public final class UiAutomation {
        return null;
    }

    /**
     * Executes a shell command. This method returs a file descriptor that points
     * to the standard output stream. The command execution is similar to running
     * "adb shell <command>" from a host connected to the device.
     * <p>
     * <strong>Note:</strong> It is your responsibility to close the retunred file
     * descriptor once you are done reading.
     * </p>
     *
     * @param command The command to execute.
     * @return A file descriptor to the standard output stream.
     */
    public ParcelFileDescriptor executeShellCommand(String command) {
        synchronized (mLock) {
            throwIfNotConnectedLocked();
        }

        ParcelFileDescriptor source = null;
        ParcelFileDescriptor sink = null;

        try {
            ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe();
            source = pipe[0];
            sink = pipe[1];

            // Calling out without a lock held.
            mUiAutomationConnection.executeShellCommand(command, sink);
        } catch (IOException ioe) {
            Log.e(LOG_TAG, "Error executing shell command!", ioe);
        } catch (RemoteException re) {
            Log.e(LOG_TAG, "Error executing shell command!", re);
        } finally {
            IoUtils.closeQuietly(sink);
        }

        return source;
    }

    private static float getDegreesForRotation(int value) {
        switch (value) {
            case Surface.ROTATION_90: {
+44 −2
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.graphics.Bitmap;
import android.hardware.input.InputManager;
import android.os.Binder;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -33,6 +34,12 @@ import android.view.WindowAnimationFrameStats;
import android.view.WindowContentFrameStats;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.IAccessibilityManager;
import libcore.io.IoUtils;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * This is a remote object that is passed from the shell to an instrumentation
@@ -50,8 +57,8 @@ public final class UiAutomationConnection extends IUiAutomationConnection.Stub {
    private final IWindowManager mWindowManager = IWindowManager.Stub.asInterface(
            ServiceManager.getService(Service.WINDOW_SERVICE));

    private final IAccessibilityManager mAccessibilityManager = IAccessibilityManager.Stub.asInterface(
            ServiceManager.getService(Service.ACCESSIBILITY_SERVICE));
    private final IAccessibilityManager mAccessibilityManager = IAccessibilityManager.Stub
            .asInterface(ServiceManager.getService(Service.ACCESSIBILITY_SERVICE));

    private final Object mLock = new Object();

@@ -219,6 +226,41 @@ public final class UiAutomationConnection extends IUiAutomationConnection.Stub {
        }
    }

    @Override
    public void executeShellCommand(String command, ParcelFileDescriptor sink)
            throws RemoteException {
        synchronized (mLock) {
            throwIfCalledByNotTrustedUidLocked();
            throwIfShutdownLocked();
            throwIfNotConnectedLocked();
        }

        InputStream in = null;
        OutputStream out = null;

        try {
            java.lang.Process process = Runtime.getRuntime().exec(command);

            in = process.getInputStream();
            out = new FileOutputStream(sink.getFileDescriptor());

            final byte[] buffer = new byte[8192];
            while (true) {
                final int readByteCount = in.read(buffer);
                if (readByteCount < 0) {
                    break;
                }
                out.write(buffer, 0, readByteCount);
            }
        } catch (IOException ioe) {
            throw new RuntimeException("Error running shell command", ioe);
        } finally {
            IoUtils.closeQuietly(in);
            IoUtils.closeQuietly(out);
            IoUtils.closeQuietly(sink);
        }
    }

    @Override
    public void shutdown() {
        synchronized (mLock) {