From 2c2fa2d13bcf47af46ea2aab043084ea7b23382e Mon Sep 17 00:00:00 2001 From: hstaudacher Date: Mon, 1 Jun 2015 14:09:11 +0200 Subject: [PATCH] Add PhotoAlbum To access the device photo album a new ClientService was introduced called "PhotoAlbum". Internally it used the Camera service to take picture and sets an addition property during the "open" call. This property is named "sourceType" and it's value is "saved_photo_album". Change-Id: I761e6d95ed3fa80a65c5876f589ae32e121ebe4d --- .../tabris/camera/PhotoAlbumOptionsTest.java | 74 ++++++ .../tabris/internal/PhotoAlbumImplTest.java | 233 ++++++++++++++++++ .../tabris/internal/TabrisClientImplTest.java | 20 ++ .../.settings/.api_filters | 9 + .../eclipsesource/tabris/camera/Camera.java | 10 +- .../tabris/camera/CameraListener.java | 4 +- .../tabris/camera/PhotoAlbum.java | 62 +++++ .../tabris/camera/PhotoAlbumListener.java | 43 ++++ .../tabris/camera/PhotoAlbumOptions.java | 80 ++++++ .../tabris/internal/Constants.java | 1 + .../tabris/internal/PhotoAlbumImpl.java | 122 +++++++++ .../tabris/internal/TabrisClientImpl.java | 3 + 12 files changed, 654 insertions(+), 7 deletions(-) create mode 100644 com.eclipsesource.tabris.test/src/com/eclipsesource/tabris/camera/PhotoAlbumOptionsTest.java create mode 100644 com.eclipsesource.tabris.test/src/com/eclipsesource/tabris/internal/PhotoAlbumImplTest.java create mode 100644 com.eclipsesource.tabris/src/com/eclipsesource/tabris/camera/PhotoAlbum.java create mode 100644 com.eclipsesource.tabris/src/com/eclipsesource/tabris/camera/PhotoAlbumListener.java create mode 100644 com.eclipsesource.tabris/src/com/eclipsesource/tabris/camera/PhotoAlbumOptions.java create mode 100644 com.eclipsesource.tabris/src/com/eclipsesource/tabris/internal/PhotoAlbumImpl.java diff --git a/com.eclipsesource.tabris.test/src/com/eclipsesource/tabris/camera/PhotoAlbumOptionsTest.java b/com.eclipsesource.tabris.test/src/com/eclipsesource/tabris/camera/PhotoAlbumOptionsTest.java new file mode 100644 index 0000000..1ae0f8d --- /dev/null +++ b/com.eclipsesource.tabris.test/src/com/eclipsesource/tabris/camera/PhotoAlbumOptionsTest.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * Copyright (c) 2015 EclipseSource and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * EclipseSource - initial API and implementation + ******************************************************************************/ +package com.eclipsesource.tabris.camera; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.io.Serializable; + +import org.eclipse.swt.graphics.Point; +import org.junit.Test; + + +public class PhotoAlbumOptionsTest { + + @Test + public void testIsSerializable() { + assertTrue( Serializable.class.isAssignableFrom( PhotoAlbumOptions.class ) ); + } + + @Test + public void testNoneOptions() { + assertNull( CameraOptions.NONE.getResolution() ); + assertFalse( CameraOptions.NONE.savesToAlbum() ); + assertEquals( 1.0F, CameraOptions.NONE.getCompressionQuality(), 0 ); + } + + @Test + public void testResolution() { + PhotoAlbumOptions albumOptions = new PhotoAlbumOptions(); + + albumOptions.setResolution( 500, 500 ); + + assertEquals( new Point( 500, 500 ), albumOptions.getResolution() ); + } + + @Test + public void testDefaultResolutionIsNull() { + PhotoAlbumOptions albumOptions = new PhotoAlbumOptions(); + + Point resolution = albumOptions.getResolution(); + + assertNull( resolution ); + } + + @Test + public void testSetsComptressionQuality() { + PhotoAlbumOptions albumOptions = new PhotoAlbumOptions(); + + albumOptions.setCompressionQuality( 0.5F ); + + assertEquals( 0.5F, albumOptions.getCompressionQuality(), 0 ); + } + + @Test + public void testDefaultCompressionQualityIsOne() { + PhotoAlbumOptions albumOptions = new PhotoAlbumOptions(); + + float compressionQuality = albumOptions.getCompressionQuality(); + + assertEquals( 1.0F, compressionQuality, 0 ); + } + +} diff --git a/com.eclipsesource.tabris.test/src/com/eclipsesource/tabris/internal/PhotoAlbumImplTest.java b/com.eclipsesource.tabris.test/src/com/eclipsesource/tabris/internal/PhotoAlbumImplTest.java new file mode 100644 index 0000000..68e274f --- /dev/null +++ b/com.eclipsesource.tabris.test/src/com/eclipsesource/tabris/internal/PhotoAlbumImplTest.java @@ -0,0 +1,233 @@ +/******************************************************************************* + * Copyright (c) 2015 EclipseSource and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * EclipseSource - initial API and implementation + ******************************************************************************/ +package com.eclipsesource.tabris.internal; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.Serializable; + +import org.eclipse.rap.json.JsonArray; +import org.eclipse.rap.json.JsonObject; +import org.eclipse.rap.json.JsonValue; +import org.eclipse.rap.rwt.client.Client; +import org.eclipse.rap.rwt.remote.RemoteObject; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Display; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.mockito.ArgumentCaptor; + +import com.eclipsesource.tabris.TabrisClient; +import com.eclipsesource.tabris.camera.Camera; +import com.eclipsesource.tabris.camera.PhotoAlbumListener; +import com.eclipsesource.tabris.camera.PhotoAlbumOptions; +import com.eclipsesource.tabris.test.util.TabrisEnvironment; + + +public class PhotoAlbumImplTest { + + @Rule + public TabrisEnvironment environment = new TabrisEnvironment(); + + private CameraImpl camera; + + @Before + public void setUp() { + Client client = mock( TabrisClient.class ); + camera = new CameraImpl(); + when( client.getService( Camera.class ) ).thenReturn( camera ); + environment.setClient( client ); + new Display(); + } + + @Test + public void testIsSerializable() { + assertTrue( Serializable.class.isAssignableFrom( PhotoAlbumImpl.class ) ); + } + + @Test + public void testCameraListenerIsSerializable() { + assertTrue( Serializable.class.isAssignableFrom( PhotoAlbumListener.class ) ); + } + + @Test + public void testSetsNoInitialCameraOptionsWithDefaultOptions() { + RemoteObject remoteObject = environment.getServiceObject(); + + new PhotoAlbumImpl(); + + verify( remoteObject, never() ).set( eq( "resolution" ), any( JsonValue.class ) ); + verify( remoteObject, never() ).set( eq( "sourceType" ), any( JsonValue.class ) ); + verify( remoteObject, never() ).set( eq( "compressionQuality" ), any( JsonValue.class ) ); + } + + @Test + public void testSendsOpenWithOpenCall() { + PhotoAlbumImpl album = new PhotoAlbumImpl(); + RemoteObject remoteObject = camera.getRemoteObject(); + PhotoAlbumListener listener = mock( PhotoAlbumListener.class ); + album.addPhotoAlbumListener( listener ); + + album.open( createOptions() ); + + ArgumentCaptor captor = ArgumentCaptor.forClass( JsonObject.class ); + verify( remoteObject ).call( eq( "open" ), captor.capture() ); + JsonArray resolution = captor.getValue().get( "resolution" ).asArray(); + assertEquals( 100, resolution.get( 0 ).asInt() ); + assertEquals( 100, resolution.get( 1 ).asInt() ); + assertEquals( captor.getValue().get( "sourceType" ).asString(), "saved_photo_album" ); + assertEquals( captor.getValue().get( "compressionQuality" ).asFloat(), 0.5F, 0 ); + } + + @Test( expected = IllegalArgumentException.class ) + public void testFailsWithNullOptions() { + PhotoAlbumImpl album = new PhotoAlbumImpl(); + + album.open( null ); + } + + @Test( expected = IllegalArgumentException.class ) + public void testAddFailsWithNullListener() { + PhotoAlbumImpl album = new PhotoAlbumImpl(); + + album.addPhotoAlbumListener( null ); + } + + @Test( expected = IllegalArgumentException.class ) + public void testRemoveFailsWithNullListener() { + PhotoAlbumImpl album = new PhotoAlbumImpl(); + + album.removePhotoAlbumListener( null ); + } + + @Test + public void testDelegatesError() { + PhotoAlbumImpl album = new PhotoAlbumImpl(); + PhotoAlbumListener listener = mock( PhotoAlbumListener.class ); + album.addPhotoAlbumListener( listener ); + + album.open( createOptions() ); + environment.dispatchNotifyOnServiceObject( "ImageSelectionError", null ); + + verify( listener ).receivedImage( null ); + } + + @Test + public void testDelegatesErrorToAllListeners() { + PhotoAlbumImpl album = new PhotoAlbumImpl(); + PhotoAlbumListener listener1 = mock( PhotoAlbumListener.class ); + PhotoAlbumListener listener2 = mock( PhotoAlbumListener.class ); + album.addPhotoAlbumListener( listener1 ); + album.addPhotoAlbumListener( listener2 ); + + album.open( createOptions() ); + environment.dispatchNotifyOnServiceObject( "ImageSelectionError", null ); + + verify( listener1 ).receivedImage( null ); + verify( listener2 ).receivedImage( null ); + } + + + @Test + public void testDelegatesCancel() { + PhotoAlbumImpl album = new PhotoAlbumImpl(); + PhotoAlbumListener listener = mock( PhotoAlbumListener.class ); + album.addPhotoAlbumListener( listener ); + + album.open( createOptions() ); + environment.dispatchNotifyOnServiceObject( "ImageSelectionCancel", null ); + + verify( listener ).receivedImage( null ); + } + + @Test + public void testDelegatesCancelToAllListeners() { + PhotoAlbumImpl album = new PhotoAlbumImpl(); + PhotoAlbumListener listener1 = mock( PhotoAlbumListener.class ); + PhotoAlbumListener listener2 = mock( PhotoAlbumListener.class ); + album.addPhotoAlbumListener( listener1 ); + album.addPhotoAlbumListener( listener2 ); + + album.open( createOptions() ); + environment.dispatchNotifyOnServiceObject( "ImageSelectionCancel", null ); + + verify( listener1 ).receivedImage( null ); + verify( listener2 ).receivedImage( null ); + } + + @Test + public void testDelegatesImage() throws IOException { + String encodedImage = getEncodedImage(); + PhotoAlbumImpl album = new PhotoAlbumImpl(); + PhotoAlbumListener listener = mock( PhotoAlbumListener.class ); + album.addPhotoAlbumListener( listener ); + + album.open( createOptions() ); + JsonObject properties = new JsonObject(); + properties.add( "image", encodedImage ); + environment.dispatchNotifyOnServiceObject( "ImageSelection", properties ); + + verify( listener ).receivedImage( any( Image.class ) ); + } + + @Test + public void testDelegatesImageToAllListeners() throws IOException { + String encodedImage = getEncodedImage(); + PhotoAlbumImpl album = new PhotoAlbumImpl(); + PhotoAlbumListener listener1 = mock( PhotoAlbumListener.class ); + PhotoAlbumListener listener2 = mock( PhotoAlbumListener.class ); + album.addPhotoAlbumListener( listener1 ); + album.addPhotoAlbumListener( listener2 ); + + album.open( createOptions() ); + JsonObject properties = new JsonObject(); + properties.add( "image", encodedImage ); + environment.dispatchNotifyOnServiceObject( "ImageSelection", properties ); + + verify( listener1 ).receivedImage( any( Image.class ) ); + verify( listener2 ).receivedImage( any( Image.class ) ); + } + + private String getEncodedImage() throws IOException { + InputStream resourceStream = getClass().getResourceAsStream( "tabris.png" ); + return Base64.encodeBytes( getBytes( resourceStream ) ); + } + + private byte[] getBytes( InputStream is ) throws IOException { + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + int nRead; + byte[] data = new byte[ 16384 ]; + while( ( nRead = is.read( data, 0, data.length ) ) != -1 ) { + buffer.write( data, 0, nRead ); + } + buffer.flush(); + return buffer.toByteArray(); + } + + private PhotoAlbumOptions createOptions() { + PhotoAlbumOptions options = new PhotoAlbumOptions(); + options.setResolution( 100, 100 ); + options.setCompressionQuality( 0.5F ); + return options; + } + +} diff --git a/com.eclipsesource.tabris.test/src/com/eclipsesource/tabris/internal/TabrisClientImplTest.java b/com.eclipsesource.tabris.test/src/com/eclipsesource/tabris/internal/TabrisClientImplTest.java index 1b1afa9..5e9ab6a 100644 --- a/com.eclipsesource.tabris.test/src/com/eclipsesource/tabris/internal/TabrisClientImplTest.java +++ b/com.eclipsesource.tabris.test/src/com/eclipsesource/tabris/internal/TabrisClientImplTest.java @@ -21,6 +21,7 @@ import com.eclipsesource.tabris.TabrisClient; import com.eclipsesource.tabris.app.App; import com.eclipsesource.tabris.camera.Camera; +import com.eclipsesource.tabris.camera.PhotoAlbum; import com.eclipsesource.tabris.device.ClientDevice; import com.eclipsesource.tabris.geolocation.Geolocation; import com.eclipsesource.tabris.interaction.AppLauncher; @@ -88,6 +89,15 @@ public void testHasCameraService() { assertNotNull( camera ); } + @Test + public void testHasPhotoAlbumService() { + TabrisClient client = new TabrisClientImpl(); + + PhotoAlbum album = client.getService( PhotoAlbum.class ); + + assertNotNull( album ); + } + @Test public void testHasCloudPushService() { TabrisClient client = new TabrisClientImpl(); @@ -170,6 +180,16 @@ public void testCameraIsSingleton() { assertSame( camera, camera2 ); } + @Test + public void testPhotoAlbumIsSingleton() { + TabrisClient client = new TabrisClientImpl(); + + PhotoAlbum album = client.getService( PhotoAlbum.class ); + PhotoAlbum album2 = client.getService( PhotoAlbum.class ); + + assertSame( album, album2 ); + } + @Test public void testGeolocationIsSingleton() { TabrisClient client = new TabrisClientImpl(); diff --git a/com.eclipsesource.tabris/.settings/.api_filters b/com.eclipsesource.tabris/.settings/.api_filters index 174d057..46648d7 100644 --- a/com.eclipsesource.tabris/.settings/.api_filters +++ b/com.eclipsesource.tabris/.settings/.api_filters @@ -63,6 +63,15 @@ + + + + + + + + + diff --git a/com.eclipsesource.tabris/src/com/eclipsesource/tabris/camera/Camera.java b/com.eclipsesource.tabris/src/com/eclipsesource/tabris/camera/Camera.java index eaa8185..405e579 100644 --- a/com.eclipsesource.tabris/src/com/eclipsesource/tabris/camera/Camera.java +++ b/com.eclipsesource.tabris/src/com/eclipsesource/tabris/camera/Camera.java @@ -16,9 +16,9 @@ /** *

- * The Camera component can be used to take and receive pictures from a mobile client's camera or photo - * album. The taken picture will be sent to the server side and a callback will be called. See - * CameraCallback. An instance of {@link Camera} can be accessed using + * The Camera component can be used to take and receive pictures from a mobile client's camera. + * The taken picture will be sent to the server side and a callback will be called. See + * CameraListener. An instance of {@link Camera} can be accessed using * RWT.getClient().getService( Camera.class ). *

* @@ -34,8 +34,8 @@ public interface Camera extends ClientService { /** *

- * Instructs the client to open the camera or photo album. The added {@link CameraListener}s will be called when the - * user has taken/selected a picture or in the case of an error. + * Instructs the client to open the camera. The added {@link CameraListener}s will be called when the + * user has taken a picture.. *

* * @param options The options that should be used as the configuration for taking a picture. Must not diff --git a/com.eclipsesource.tabris/src/com/eclipsesource/tabris/camera/CameraListener.java b/com.eclipsesource.tabris/src/com/eclipsesource/tabris/camera/CameraListener.java index e4ecd43..10f8611 100644 --- a/com.eclipsesource.tabris/src/com/eclipsesource/tabris/camera/CameraListener.java +++ b/com.eclipsesource.tabris/src/com/eclipsesource/tabris/camera/CameraListener.java @@ -18,7 +18,7 @@ /** *

* The {@link CameraListener} is used to receive notifications from a mobile client when it's done with - * taking/selecting pictures. In the case of a success the picture will be passed as an Image object. + * taking pictures. In the case of a success the picture will be passed as an Image object. *

* * @see Image @@ -28,7 +28,7 @@ public interface CameraListener extends Serializable { /** *

- * Called in the case of successfully taking or selecting a picture from a mobile client's camera/photo album. + * Called in the case of successfully taking or selecting a picture from a mobile client's camera. *

* * @param image the picture transfered form the client. May be null if there was an error or the user diff --git a/com.eclipsesource.tabris/src/com/eclipsesource/tabris/camera/PhotoAlbum.java b/com.eclipsesource.tabris/src/com/eclipsesource/tabris/camera/PhotoAlbum.java new file mode 100644 index 0000000..0d3ec8a --- /dev/null +++ b/com.eclipsesource.tabris/src/com/eclipsesource/tabris/camera/PhotoAlbum.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright (c) 2015 EclipseSource and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * EclipseSource - initial API and implementation + ******************************************************************************/ +package com.eclipsesource.tabris.camera; + +import org.eclipse.rap.rwt.client.Client; +import org.eclipse.rap.rwt.client.service.ClientService; + + +/** + *

+ * The PhotoAlbum component can be used to receive pictures from a mobile client's photo + * album. The picture will be sent to the server side and a callback will be called. See + * PhotoAlbumListener. An instance of {@link PhotoAlbum} can be accessed using + * RWT.getClient().getService( PhotoAlbum.class ). + *

+ * + * @see PhotoAlbumListener + * @see PhotoAlbumOptions + * @see Client + * + * @noimplement This interface is not intended to be implemented by clients. + * + * @since 1.4 + */ +public interface PhotoAlbum extends ClientService { + + /** + *

+ * Instructs the client to open the photo album. The added {@link PhotoAlbumListener}s will be called when the + * user has selected a picture. + *

+ * + * @param options The options that should be used as the configuration for taking a picture. Must not + * be null. + * + * @see PhotoAlbumListener + */ + void open( PhotoAlbumOptions options ); + + /** + *

+ * Adds a {@link PhotoAlbumListener} to get notified about image events. + *

+ */ + void addPhotoAlbumListener( PhotoAlbumListener listener ); + + /** + *

+ * Removes a {@link PhotoAlbumListener}. + *

+ */ + void removePhotoAlbumListener( PhotoAlbumListener listener ); + +} diff --git a/com.eclipsesource.tabris/src/com/eclipsesource/tabris/camera/PhotoAlbumListener.java b/com.eclipsesource.tabris/src/com/eclipsesource/tabris/camera/PhotoAlbumListener.java new file mode 100644 index 0000000..bff60d6 --- /dev/null +++ b/com.eclipsesource.tabris/src/com/eclipsesource/tabris/camera/PhotoAlbumListener.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2015 EclipseSource and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * EclipseSource - initial API and implementation + ******************************************************************************/ +package com.eclipsesource.tabris.camera; + +import java.io.Serializable; + +import org.eclipse.swt.graphics.Image; + + +/** + *

+ * The {@link PhotoAlbumListener} is used to receive notifications from a mobile client when it's done with + * selecting pictures from the photo album. In the case of a success the picture will be passed as + * an Image object. + *

+ * + * @see Image + * + * @since 1.4 + */ +public interface PhotoAlbumListener extends Serializable { + + /** + *

+ * Called in the case of successfully selecting a picture from a mobile client's photo album. + *

+ * + * @param image the picture transfered form the client. May be null if there was an error or the user + * canceled. + * + * @see Image + */ + void receivedImage( Image image ); + +} diff --git a/com.eclipsesource.tabris/src/com/eclipsesource/tabris/camera/PhotoAlbumOptions.java b/com.eclipsesource.tabris/src/com/eclipsesource/tabris/camera/PhotoAlbumOptions.java new file mode 100644 index 0000000..8a52726 --- /dev/null +++ b/com.eclipsesource.tabris/src/com/eclipsesource/tabris/camera/PhotoAlbumOptions.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * Copyright (c) 2015 EclipseSource and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html Contributors: + * EclipseSource - initial API and implementation + ******************************************************************************/ +package com.eclipsesource.tabris.camera; + +import static com.eclipsesource.tabris.internal.Clauses.when; + +import java.io.Serializable; + +import org.eclipse.swt.graphics.Point; + + +/** + *

+ * The PhotoAlbumOptions is used to configure a PhotoAlbum + * object when taking a picture via {@link PhotoAlbum#open(PhotoAlbumOptions)}. + *

+ * + * @see PhotoAlbum + * + * @since 1.4 + */ +public class PhotoAlbumOptions implements Serializable { + + public static final PhotoAlbumOptions NONE = new PhotoAlbumOptions(); + private Point resolution; + private float quality; + + public PhotoAlbumOptions() { + quality = 1.0F; + } + + /** + *

+ * Defines the preferred resolution for images. When possible images will have + * the configured size when sending them to the server. + *

+ * + * @param x Preferred width. Must be positive. + * @param y Preferred height. Must be positive. + */ + public void setResolution( int x, int y ) { + resolution = new Point( x, y ); + } + + /** + *

+ * Returns the preferred resolution. + *

+ */ + public Point getResolution() { + return resolution; + } + + /** + *

+ * The quality of the resulting image, expressed as a value from 0.0 to 1.0. The value 0.0 represents the maximum + * compression (or lowest quality) while the value 1.0 represents the least compression (or best quality). + *

+ */ + public void setCompressionQuality( float quality ) { + when( quality < 0 || quality > 1 ) + .throwIllegalArgument( "Compression Quality must be >= 0 and <= 1 but was " + quality ); + this.quality = quality; + } + + /** + *

+ * Returns the compression quality of the resulting image. The default value is 1.0. + *

+ */ + public float getCompressionQuality() { + return quality; + } + +} diff --git a/com.eclipsesource.tabris/src/com/eclipsesource/tabris/internal/Constants.java b/com.eclipsesource.tabris/src/com/eclipsesource/tabris/internal/Constants.java index 2d877d8..a97afb5 100644 --- a/com.eclipsesource.tabris/src/com/eclipsesource/tabris/internal/Constants.java +++ b/com.eclipsesource.tabris/src/com/eclipsesource/tabris/internal/Constants.java @@ -50,6 +50,7 @@ public class Constants { public static final String PROPERTY_ERROR_MESSAGE = "errorMessage"; public static final String PROPERTY_ERROR_CODE = "errorCode"; public static final String PROPERTY_ORIENTATION = "orientation"; + public static final String PROPERTY_SOURCETYPE = "sourceType"; public static final String EVENT_SUCCESS = "Success"; public static final String EVENT_ERROR = "Error"; diff --git a/com.eclipsesource.tabris/src/com/eclipsesource/tabris/internal/PhotoAlbumImpl.java b/com.eclipsesource.tabris/src/com/eclipsesource/tabris/internal/PhotoAlbumImpl.java new file mode 100644 index 0000000..255b3bb --- /dev/null +++ b/com.eclipsesource.tabris/src/com/eclipsesource/tabris/internal/PhotoAlbumImpl.java @@ -0,0 +1,122 @@ +/******************************************************************************* + * Copyright (c) 2015 EclipseSource and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * EclipseSource - initial API and implementation + ******************************************************************************/ +package com.eclipsesource.tabris.internal; + +import static com.eclipsesource.tabris.internal.Clauses.whenNull; +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_RESOLUTION; +import static com.eclipsesource.tabris.internal.Constants.PROPERTY_SOURCETYPE; + +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.remote.RemoteObject; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; + +import com.eclipsesource.tabris.camera.Camera; +import com.eclipsesource.tabris.camera.CameraListener; +import com.eclipsesource.tabris.camera.PhotoAlbum; +import com.eclipsesource.tabris.camera.PhotoAlbumListener; +import com.eclipsesource.tabris.camera.PhotoAlbumOptions; + + +public class PhotoAlbumImpl implements PhotoAlbum { + + private final CameraImpl camera; + private final List listeners; + + public PhotoAlbumImpl() { + listeners = new ArrayList(); + camera = ( CameraImpl )RWT.getClient().getService( Camera.class ); + } + + @Override + public void open( PhotoAlbumOptions options ) { + whenNull( options ).throwIllegalArgument( "Options must not be null" ); + JsonObject properties = createProperties( options ); + RemoteObject remoteObject = camera.getRemoteObject(); + remoteObject.call( METHOD_OPEN, properties ); + } + + private JsonObject createProperties( PhotoAlbumOptions options ) { + JsonObject properties = new JsonObject().add( PROPERTY_SOURCETYPE, "saved_photo_album" ); + addResolution( properties, options ); + addCompressionQuality( properties, options ); + return properties; + } + + private void addResolution( JsonObject properties, PhotoAlbumOptions 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 addCompressionQuality( JsonObject properties, PhotoAlbumOptions options ) { + properties.add( PROPERTY_COMPRESSON_QUALITY, options.getCompressionQuality() ); + } + + @Override + public void addPhotoAlbumListener( PhotoAlbumListener listener ) { + whenNull( listener ).throwIllegalArgument( "Listener must not be null" ); + ListenerHolder holder = createDelegatingCameraListener( listener ); + listeners.add( holder ); + camera.addCameraListener( holder.cameraListener ); + } + + private ListenerHolder createDelegatingCameraListener( final PhotoAlbumListener listener ) { + return new ListenerHolder( listener, new CameraListener() { + + @Override + public void receivedPicture( Image image ) { + listener.receivedImage( image ); + } + } ); + } + + @Override + public void removePhotoAlbumListener( PhotoAlbumListener listener ) { + whenNull( listener ).throwIllegalArgument( "Listener must not be null" ); + ListenerHolder holder = getListenerHolder( listener ); + camera.removeCameraListener( holder.cameraListener ); + listeners.remove( holder ); + } + + private ListenerHolder getListenerHolder( PhotoAlbumListener listener ) { + for( ListenerHolder holder : listeners ) { + if( holder.albumListener == listener ) { + return holder; + } + } + return null; + } + + private static class ListenerHolder { + + private final PhotoAlbumListener albumListener; + private final CameraListener cameraListener; + + public ListenerHolder( PhotoAlbumListener albumListener, CameraListener cameraListener ) { + this.albumListener = albumListener; + this.cameraListener = cameraListener; + } + + } + +} diff --git a/com.eclipsesource.tabris/src/com/eclipsesource/tabris/internal/TabrisClientImpl.java b/com.eclipsesource.tabris/src/com/eclipsesource/tabris/internal/TabrisClientImpl.java index 8fef6e1..73c88cd 100644 --- a/com.eclipsesource.tabris/src/com/eclipsesource/tabris/internal/TabrisClientImpl.java +++ b/com.eclipsesource.tabris/src/com/eclipsesource/tabris/internal/TabrisClientImpl.java @@ -19,6 +19,7 @@ import com.eclipsesource.tabris.TabrisClient; import com.eclipsesource.tabris.app.App; import com.eclipsesource.tabris.camera.Camera; +import com.eclipsesource.tabris.camera.PhotoAlbum; import com.eclipsesource.tabris.device.ClientDevice; import com.eclipsesource.tabris.geolocation.Geolocation; import com.eclipsesource.tabris.interaction.AppLauncher; @@ -56,6 +57,8 @@ public T getService( Class type ) { result = ( T )getSessionInstance( CloudPushImpl.class ); } else if( type == Camera.class ) { result = ( T )getSessionInstance( CameraImpl.class ); + } else if( type == PhotoAlbum.class ) { + result = ( T )getSessionInstance( PhotoAlbumImpl.class ); } else if( type == Geolocation.class ) { result = ( T )getSessionInstance( GeolocationImpl.class ); } else if( type == Printer.class ) {