Various addition to sl4a for PTS automation.

Add a few media related methods for MediaPlayer and MediaSession.
Add DisplayFacade to support DisplayManager and Display classes.
Whereas we are adding them for PTS, these additions are generic and not tied to PTS.

Change-Id: I683cd2983cae8c45d8c88220d3a55429a056a2c8
diff --git a/Common/src/com/googlecode/android_scripting/facade/DisplayFacade.java b/Common/src/com/googlecode/android_scripting/facade/DisplayFacade.java
new file mode 100644
index 0000000..54b402b
--- /dev/null
+++ b/Common/src/com/googlecode/android_scripting/facade/DisplayFacade.java
@@ -0,0 +1,87 @@
+

+package com.googlecode.android_scripting.facade;

+

+import java.util.HashMap;

+

+import android.app.Service;

+import android.content.Context;

+import android.graphics.Point;

+import android.hardware.display.DisplayManager;

+import android.util.DisplayMetrics;

+import android.view.Display;

+

+import com.googlecode.android_scripting.jsonrpc.RpcReceiver;

+import com.googlecode.android_scripting.rpc.Rpc;

+import com.googlecode.android_scripting.rpc.RpcDefault;

+import com.googlecode.android_scripting.rpc.RpcParameter;

+

+public class DisplayFacade extends RpcReceiver {

+

+    private final Service mService;

+    private final DisplayManager mDisplayManager;

+    private HashMap<Integer, Display> mDisplays;

+

+    public DisplayFacade(FacadeManager manager) {

+        super(manager);

+        mService = manager.getService();

+        mDisplayManager = (DisplayManager) mService.getSystemService(Context.DISPLAY_SERVICE);

+        updateDisplays(mDisplayManager.getDisplays());

+    }

+

+    private void updateDisplays(Display[] displays) {

+        if (mDisplays == null) {

+            mDisplays = new HashMap<Integer, Display>();

+        }

+        mDisplays.clear();

+        for(Display d : displays) {

+            mDisplays.put(d.getDisplayId(), d);

+        }

+    }

+

+    @Rpc(description = "Get a list of IDs of the logical displays connected."

+                     + "Also updates the cached displays.")

+    public Integer[] displayGetDisplays() {

+        Display[] displays = mDisplayManager.getDisplays();

+        updateDisplays(displays);

+        Integer[] results = new Integer[displays.length];

+        for(int i = 0; i < displays.length; i++) {

+            results[i] = displays[i].getDisplayId();

+        }

+        return results;

+    }

+

+    @Rpc(description = "Get the size of the specified display in pixels.")

+    public Point displayGetSize(

+            @RpcParameter(name = "displayId")

+            @RpcDefault(value = "0")

+            Integer displayId) {

+        Point outSize = new Point();

+        Display d = mDisplays.get(displayId);

+        d.getSize(outSize);

+        return outSize;

+    }

+

+    @Rpc(description = "Get the maximum screen size dimension that will happen.")

+    public Integer displayGetMaximumSizeDimension(

+            @RpcParameter(name = "displayId")

+            @RpcDefault(value = "0")

+            Integer displayId) {

+        Display d = mDisplays.get(displayId);

+        return d.getMaximumSizeDimension();

+    }

+

+    @Rpc(description = "Get display metrics based on the real size of this display.")

+    public DisplayMetrics displayGetRealMetrics(

+            @RpcParameter(name = "displayId")

+            @RpcDefault(value = "0")

+            Integer displayId) {

+        Display d = mDisplays.get(displayId);

+        DisplayMetrics outMetrics = new DisplayMetrics();

+        d.getRealMetrics(outMetrics);

+        return outMetrics;

+    }

+

+    @Override

+    public void shutdown() {

+    }

+}

diff --git a/Common/src/com/googlecode/android_scripting/facade/MediaPlayerFacade.java b/Common/src/com/googlecode/android_scripting/facade/MediaPlayerFacade.java
index ad1aa4a..59edf4f 100644
--- a/Common/src/com/googlecode/android_scripting/facade/MediaPlayerFacade.java
+++ b/Common/src/com/googlecode/android_scripting/facade/MediaPlayerFacade.java
@@ -145,6 +145,19 @@
         return mediaIsPlaying(tag);

     }

 

+    @Rpc(description = "Stop playing media file.", returns = "true if successful")

+    public synchronized boolean mediaPlayStop(

+            @RpcParameter(name = "tag", description = "string identifying resource")

+            @RpcDefault(value = "default")

+            String tag) {

+        MediaPlayer player = getPlayer(tag);

+        if (player == null) {

+            return false;

+        }

+        player.stop();

+        return !mediaIsPlaying(tag) && player.getCurrentPosition() == 0;

+    }

+

     @Rpc(description = "Start playing media file from a specified point.")

     public synchronized void mediaPlaySeekTo(

             @RpcParameter(name = "tag", description = "string identifying resource")

diff --git a/Common/src/com/googlecode/android_scripting/facade/MediaSessionFacade.java b/Common/src/com/googlecode/android_scripting/facade/MediaSessionFacade.java
index 9ab0591..80cdf91 100644
--- a/Common/src/com/googlecode/android_scripting/facade/MediaSessionFacade.java
+++ b/Common/src/com/googlecode/android_scripting/facade/MediaSessionFacade.java
@@ -10,6 +10,7 @@
 import android.media.session.MediaSessionManager;

 import android.media.session.PlaybackState;

 import android.media.session.MediaSession.Callback;

+import android.os.Bundle;

 import android.view.KeyEvent;

 

 import com.googlecode.android_scripting.Log;

@@ -42,30 +43,45 @@
         public ButtonCallback(EventFacade eventFacade) {

             this.mEventFacade = eventFacade;

         }

+        private void handleKeyEvent(KeyEvent event) {

+            int keyCode = event.getKeyCode();

+            Log.d("Received ACTION_DOWN with keycode " + keyCode);

+            Bundle msg = new Bundle();

+            if (keyCode == KeyEvent.KEYCODE_MEDIA_PLAY) {

+                msg.putString("ButtonPressed", "Play");

+            } else if (keyCode == KeyEvent.KEYCODE_MEDIA_PAUSE) {

+                msg.putString("ButtonPressed", "Pause");

+            } else if (keyCode == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE) {

+                msg.putString("ButtonPressed", "PlayPause");

+            } else if (keyCode == KeyEvent.KEYCODE_MEDIA_STOP) {

+                msg.putString("ButtonPressed", "Stop");

+            } else if (keyCode == KeyEvent.KEYCODE_MEDIA_NEXT) {

+                msg.putString("ButtonPressed", "Next");

+            } else if (keyCode == KeyEvent.KEYCODE_MEDIA_PREVIOUS) {

+                msg.putString("ButtonPressed", "Previous");

+            } else if (keyCode == KeyEvent.KEYCODE_MEDIA_FAST_FORWARD) {

+                msg.putString("ButtonPressed", "Forward");

+            } else if (keyCode == KeyEvent.KEYCODE_MEDIA_REWIND) {

+                msg.putString("ButtonPressed", "Rewind");

+            }

+            Log.d("Sending MediaButton event with ButtonPressed value "

+                  + msg.getString("ButtonPressed"));

+            this.mEventFacade.postEvent("MediaButton", msg);

+        }

+

         @Override

         public void onMediaButtonEvent(Intent mediaButtonIntent) {

             String action = mediaButtonIntent.getAction();

             Log.d("Received intent with action " + action);

             if (action.equals(Intent.ACTION_MEDIA_BUTTON)) {

-                KeyEvent event = (KeyEvent) mediaButtonIntent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);

+                KeyEvent event = (KeyEvent) mediaButtonIntent

+                                            .getParcelableExtra(Intent.EXTRA_KEY_EVENT);

                 int keyAction = event.getAction();

                 Log.d("Received KeyEvent with action " + keyAction);

                 if (keyAction == KeyEvent.ACTION_DOWN) {

-                    int keyCode = event.getKeyCode();

-                    Log.d("Received ACTION_DOWN with keycode " + keyCode);

-                    if (keyCode == KeyEvent.KEYCODE_MEDIA_PLAY) {

-                        mEventFacade.postEvent("mediaKeyOnPlay", null);

-                    } else if (keyCode == KeyEvent.KEYCODE_MEDIA_PAUSE) {

-                        mEventFacade.postEvent("mediaOnPause", null);

-                    } else if (keyCode == KeyEvent.KEYCODE_MEDIA_STOP) {

-                        mEventFacade.postEvent("mediaOnStop", null);

-                    } else if (keyCode == KeyEvent.KEYCODE_MEDIA_NEXT) {

-                        mEventFacade.postEvent("mediaOnNext", null);

-                    } else if (keyCode == KeyEvent.KEYCODE_MEDIA_PREVIOUS) {

-                        mEventFacade.postEvent("mediaOnPrevious", null);

-                    } else if (keyCode == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE) {

-                        mEventFacade.postEvent("mediaOnPlayPause", null);

-                    }

+                    handleKeyEvent(event);

+                } else if (keyAction == KeyEvent.ACTION_UP) {

+                    handleKeyEvent(event);

                 }

             }

         }

diff --git a/Common/src/com/googlecode/android_scripting/jsonrpc/JsonBuilder.java b/Common/src/com/googlecode/android_scripting/jsonrpc/JsonBuilder.java
index 3b585b9..e855e5c 100644
--- a/Common/src/com/googlecode/android_scripting/jsonrpc/JsonBuilder.java
+++ b/Common/src/com/googlecode/android_scripting/jsonrpc/JsonBuilder.java
@@ -36,6 +36,7 @@
 import android.bluetooth.le.AdvertiseSettings;
 import android.content.ComponentName;
 import android.content.Intent;
+import android.graphics.Point;
 import android.location.Address;
 import android.location.Location;
 import android.net.wifi.ScanResult;
@@ -45,6 +46,7 @@
 import android.telephony.CellLocation;
 import android.telephony.NeighboringCellInfo;
 import android.telephony.gsm.GsmCellLocation;
+import android.util.DisplayMetrics;
 
 import com.googlecode.android_scripting.event.Event;
 
@@ -149,6 +151,12 @@
         if (data instanceof InetSocketAddress) {
             return buildInetSocketAddress((InetSocketAddress) data);
         }
+        if (data instanceof Point) {
+            return buildPoint((Point) data);
+        }
+        if (data instanceof DisplayMetrics) {
+            return buildDisplayMetrics((DisplayMetrics) data);
+        }
         if (data instanceof byte[]) {
             return Base64Codec.encodeBase64((byte[]) data);
         }
@@ -341,6 +349,22 @@
         return result;
     }
 
+    private static Object buildPoint(Point data) throws JSONException {
+        JSONObject point = new JSONObject();
+        point.put("x", data.x);
+        point.put("y", data.y);
+        return point;
+    }
+
+    private static Object buildDisplayMetrics(DisplayMetrics data) throws JSONException {
+        JSONObject dm = new JSONObject();
+        dm.put("widthPixels", data.widthPixels);
+        dm.put("heightPixels", data.heightPixels);
+        dm.put("noncompatHeightPixels", data.noncompatHeightPixels);
+        dm.put("noncompatWidthPixels", data.noncompatWidthPixels);
+        return dm;
+    }
+
     private static JSONObject buildJsonCellLocation(CellLocation cellLocation)
         throws JSONException {
         JSONObject result = new JSONObject();
diff --git a/ScriptingLayer/src/com/googlecode/android_scripting/facade/FacadeConfiguration.java b/ScriptingLayer/src/com/googlecode/android_scripting/facade/FacadeConfiguration.java
index cde8f19..2e10617 100644
--- a/ScriptingLayer/src/com/googlecode/android_scripting/facade/FacadeConfiguration.java
+++ b/ScriptingLayer/src/com/googlecode/android_scripting/facade/FacadeConfiguration.java
@@ -115,13 +115,13 @@
       sFacadeClassList.add(WebCamFacade.class);
     }
 
-    if (sSdkLevel >= 18) {
+    if (sSdkLevel >= 19) {
       sFacadeClassList.add(BluetoothLeScanFacade.class);
       sFacadeClassList.add(BluetoothGattFacade.class);
       sFacadeClassList.add(BluetoothLeAdvertiseFacade.class);
+      sFacadeClassList.add(DisplayFacade.class);
       sFacadeClassList.add(WifiPasspointManagerFacade.class);
       sFacadeClassList.add(WifiScannerFacade.class);
-
     }
 
     for (Class<? extends RpcReceiver> recieverClass : sFacadeClassList) {