package com.eclipsesource.tabris.internal; import static com.eclipsesource.tabris.internal.Clauses.whenNull; import static com.eclipsesource.tabris.internal.Constants.EVENT_IMAGE_SELECTION; import static com.eclipsesource.tabris.internal.Constants.EVENT_IMAGE_SELECTION_CANCEL; import static com.eclipsesource.tabris.internal.Constants.EVENT_IMAGE_SELECTION_ERROR; import static com.eclipsesource.tabris.internal.Constants.METHOD_OPEN; import static com.eclipsesource.tabris.internal.Constants.PROPERTY_COMPRESSON_QUALITY; import static com.eclipsesource.tabris.internal.Constants.PROPERTY_IMAGE; import static com.eclipsesource.tabris.internal.Constants.PROPERTY_RESOLUTION; import static com.eclipsesource.tabris.internal.Constants.PROPERTY_SAVE_TO_ALBUM; import static com.eclipsesource.tabris.internal.Constants.TYPE_CAMERA; import java.io.ByteArrayInputStream; import java.util.ArrayList; import java.util.List; import org.eclipse.rap.json.JsonArray; import org.eclipse.rap.json.JsonObject; import org.eclipse.rap.rwt.RWT; import org.eclipse.rap.rwt.internal.remote.ConnectionImpl; import org.eclipse.rap.rwt.remote.AbstractOperationHandler; import org.eclipse.rap.rwt.remote.RemoteObject; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.widgets.Display; import com.eclipsesource.tabris.camera.Camera; import com.eclipsesource.tabris.camera.CameraListener; import com.eclipsesource.tabris.camera.CameraOptions; @SuppressWarnings("restriction") public class CameraImpl extends AbstractOperationHandler implements Camera { private final RemoteObject remoteObject; private final List<CameraListener> cameraListeners; public CameraImpl() { cameraListeners = new ArrayList<CameraListener>(); remoteObject = ( ( ConnectionImpl )RWT.getUISession().getConnection() ).createServiceObject( TYPE_CAMERA ); remoteObject.setHandler( this ); } private Image decodeImage( String encodedImage ) { byte[] bytes = Base64.decode( encodedImage ); ByteArrayInputStream stream = new ByteArrayInputStream( bytes ); return new Image( Display.getCurrent(), stream ); } @Override public void addCameraListener( CameraListener listener ) { whenNull( listener ).throwIllegalArgument( "Listener must not be null" ); cameraListeners.add( listener ); } @Override public void removeCameraListener( CameraListener listener ) { whenNull( listener ).throwIllegalArgument( "Listener must not be null" ); cameraListeners.remove( listener ); } @Override public void takePicture( CameraOptions options ) { whenNull( options ).throwIllegalArgument( "Options must not be null" ); JsonObject properties = createProperties( options ); remoteObject.call( METHOD_OPEN, properties ); } private JsonObject createProperties( CameraOptions options ) { JsonObject properties = new JsonObject(); addResolution( properties, options ); addSaveToAlbum( properties, options ); addCompressionQuality( properties, options ); return properties; } private void addResolution( JsonObject properties, CameraOptions options ) { Point resolution = options.getResolution(); if( resolution != null ) { JsonArray jsonArray = new JsonArray(); jsonArray.add( resolution.x ); jsonArray.add( resolution.y ); properties.add( PROPERTY_RESOLUTION, jsonArray ); } } private void addSaveToAlbum( JsonObject properties, CameraOptions options ) { if( options.savesToAlbum() ) { properties.add( PROPERTY_SAVE_TO_ALBUM, true ); } } private void addCompressionQuality( JsonObject properties, CameraOptions options ) { properties.add( PROPERTY_COMPRESSON_QUALITY, options.getCompressionQuality() ); } @Override public void handleNotify( String event, JsonObject properties ) { if( EVENT_IMAGE_SELECTION.equals( event ) ) { Image image = decodeImage( properties.get( PROPERTY_IMAGE ).asString() ); notifyListenersWithImage( image ); } else if( EVENT_IMAGE_SELECTION_ERROR.equals( event ) || EVENT_IMAGE_SELECTION_CANCEL.equals( event ) ) { notifyListenersWithoutPicture(); } } private void notifyListenersWithImage( Image image ) { List<CameraListener> listeners = new ArrayList<CameraListener>( cameraListeners ); for( CameraListener listener : listeners ) { listener.receivedPicture( image ); } } private void notifyListenersWithoutPicture() { List<CameraListener> listeners = new ArrayList<CameraListener>( cameraListeners ); for( CameraListener listener : listeners ) { listener.receivedPicture( null ); } } RemoteObject getRemoteObject() { return remoteObject; } }