Native Extensions AFPS

18
Flash Runtime Native Extensions Building AIR apps with native capabilities Rajorshi Ghosh Choudhury Syed Mohd Mehadi Computer Scientist Lead Software Engineer Your logo (optional)

description

Native Extensions AFPS

Transcript of Native Extensions AFPS

Page 1: Native Extensions AFPS

Flash Runtime Native Extensions

Building AIR apps with native capabilities

Rajorshi Ghosh Choudhury Syed Mohd Mehadi Computer Scientist Lead Software Engineer

Your logo (optional)

Page 2: Native Extensions AFPS

What are native extensions?

Third-party, native-code backed ActionScript API additions to AIR applications

2

AIR SDK

Flash Builder

Android SDK & NDK

XCode

Page 3: Native Extensions AFPS

Who needs them anyway…

• Adobe AIR is awesome – Allows you to create cross platform applications – Rapid multiscreen development – A large feature set (Accelerometer, Geolocation, Gestures and more)

• But… – No access to some device specific capabilities (Contacts, Bluetooth, etc) – Waits for a native feature to mature before providing access to it – Porting existing native applications to AIR might be a pain

3

Page 4: Native Extensions AFPS

Bridging the gap

• Provides access to device specific features • Native developers can reuse existing code • AS API set can be extended • Same interface can be used on different platforms

4

Page 5: Native Extensions AFPS

Anatomy of an extension • A set of ActionScript classes • Associated native code for one or more target

devices • A descriptor that contains deployment information • A signature to ensure secure delivery (optional)

5

Page 6: Native Extensions AFPS

Accessing the native code

• A context object binds the ActionScript and native halves of an extension.

• Calls to native functions happen within a context. • There may be multiple extension context objects.

6

Creating the Extension Context

import flash.external.ExtensionContext;

...

var ctx : ExtensionContext =

ExtensionContext.createExtensionContext(“com.sample.myExtension", “basicType");

var str : String = ctx.call(“myNativeFunction") as String;

...

ctx.dispose();

Page 7: Native Extensions AFPS

Writing the native code

• Use either C or Java APIs • APIs are mostly cross-platform • Can be multi-threaded • Compiled into static or dynamic libraries depending on

target platform

7

Page 8: Native Extensions AFPS

Writing the native code • Extension Initializer

– Called when the first extension context is created.

• Extension Finalizer

– Called (if and) when extension is unloaded.

8

Initializing and finalizing the extension

typedef void (*FREInitializer)(

void** extDataToSet ,

FREContextInitializer* ctxInitializerToSet,

FREContextFinalizer* ctxFinalizerToSet );

typedef void (* FREFinalizer)( void** extDataToSet);

Page 9: Native Extensions AFPS

Writing the native code • Context Initializer

– Called every time a new extension context is created. – Registers native functions to be called in this context.

• Context Finalizer – Called when an extension context is disposed.

9

Initializing and finalizing the context

typedef void (*FREContextInitializer)(

void** extDataToSet , const uint8_t* ctxType, FREContext ctx,

uint32_t* numFunctionsToSet,

const FRENamedFunction** functionsToSet);

typedef void (* FREContextFinalizer)( FREContext ctx);

Page 10: Native Extensions AFPS

Initialization Sequence

10

Page 11: Native Extensions AFPS

Extension APIs • Manipulate ActionScript types in native code

– FREResult FRENewObject(const uint8_t* className, uint32_t argc, FREObject[] argv, FREObject* object, FREObject* thrownException );

• Get/Set properties of ActionScript objects – FREResult FREGetObjectProperty( FREObject object,

const uint8_t* propertyName, FREObject* propertyValue, FREObject* thrownException );

– FREResult FRESetObjectProperty( FREObject object, const uint8_t* propertyName, FREObject propertyValue, FREObject* thrownException );

• Call methods of ActionScript objects – FREResult FRECallObjectMethod(FREObject object,

const uint8_t* methodName, uint32_t argc, FREObject[] argv, FREObject* result, FREObject* thrownException);

11

Accessing ActionScript Objects from native code

Page 12: Native Extensions AFPS

Multi-threading support

• Native libraries may be multi-threaded • Native calls are serialized • All functions in the API except one can be called only from a

thread on which a registered function is in progress. • Only function that can be called from any thread is

FREDispatchStatusEventAsync()/FREContext.DispatchStatusEventAsync()

12

Threading

Page 13: Native Extensions AFPS

Describing the Extension <extension xmlns="http://ns.adobe.com/air/extension/2.5">

<id>com.sample.myExtension</id>

<version>1</version>

<platforms>

<platform name="Android-ARM">

<applicationDeployment>

<nativeLibrary>MyExtension.jar</nativeLibrary>

<initializer>com.example.MyExtension</initializer>

</applicationDeployment>

</platform>

<platform name="MacOS-x86">

<applicationDeployment>

<nativeLibrary>MyExtension.framework</nativeLibrary>

<initializer>InitMyExtension</initializer>

<finalizer>FiniMyExtension</finalizer>

</applicationDeployment>

</platform>

<!-- Hypothetical example of a possible Digital Home platform -->

<platform name="Samsung-MIPS">

<deviceDeployment/>

</platform>

<!-- Optional default impl -->

<platform name="default">

<applicationDeployment/>

</platform>

</platforms>

</extension>

13

The extension descriptor

Page 14: Native Extensions AFPS

Consuming an Extension

14

output.ane

extension library (.swc)

extension.xml

native library + library.swf +

assets

AIR application

Application.swf

output.ane Application.xml

Page 15: Native Extensions AFPS

C API List FREResult FREGetContextNativeData( FREContext ctx, void** nativeData );

FREResult FRESetContextNativeData( FREContext ctx, void* nativeData );

FREResult FREGetContextActionScriptData( FREContext ctx, FREObject *actionScriptData );

FREResult FREGetObjectType( FREObject object, FREObjectType *objectType );

FREResult FREGetObjectAsInt32 ( FREObject object, int32_t *value );

FREResult FREGetObjectAsUint32( FREObject object, uint32_t *value ); FREResult FREGetObjectAsDouble( FREObject object, double *value ); FREResult FREGetObjectAsBool ( FREObject object, bool *value );

FREResult FRENewObjectFromInt32 ( int32_t value, FREObject *object );

FREResult FRENewObjectFromUint32( uint32_t value, FREObject *object );

FREResult FRENewObjectFromDouble( double value, FREObject *object );

FREResult FRENewObjectFromBool ( FREBool value, FREObject *object );

FREResult FREGetObjectAsUTF8( FREObject object, uint32_t* length, const uint8_t** value );

FREResult FRENewObjectFromUTF8( uint32_t length, const uint8_t* value , FREObject* object );

FREResult FRENewObject( const uint8_t* className , uint32_t argc , FREObject[] argv , FREObject* object , FREObject* thrownException );

FREResult FREGetObjectProperty( FREObject object , const uint8_t* propertyName , FREObject* propertyValue , FREObject* thrownException );

FREResult FRESetObjectProperty( FREObject object , const uint8_t* propertyName , FREObject propertyValue , FREObject* thrownException );

FREResult FRECallObjectMethod ( FREObject object , const uint8_t* methodName , uint32_t argc , FREObject[] argv , FREObject* result , FREObject* thrownException );

FREResult FREAcquireBitmapData( FREObject object , FREBitmapData* descriptor );

FREResult FREInvalidateBitmapDataRect( FREObject object, uint32_t x , uint32_t y , uint32_t width , uint32_t height );

FREResult FREReleaseBitmapData( FREObject object );

FREResult FREAcquireByteArray( FREObject object , FREByteArray* byteArray );

FREResult FREReleaseByteArray( FREObject object );

FREResult FRESetArrayLength( FREObject arrayOrVector, uint32_t length );

FREResult FREGetArrayLength( FREObject arrayOrVector, uint32_t* length );

FREResult FRESetArrayElementAt( FREObject arrayOrVector, uint32_t index , FREObject value );

FREResult FREGetArrayElementAt( FREObject arrayOrVector, uint32_t index , FREObject* value );

FREResult FREDispatchStatusEventAsync( FREContext ctx , const uint8_t* code , const uint8_t* level ); 15

Page 16: Native Extensions AFPS

Java API List interface FREExtension {

void initialize ();

FREContext createContext( String contextType);

void dispose ();

}

public abstract class FREContext {

public abstract Map<String,FREFunction> getFunctions();

public FREObject getActionScriptData();

public void setActionScriptData( FREObject object );

public abstract void dispose();

public void dispatchStatusEventAsync( String code,

String level );

}

interface FREFunction {

FREObject call( FREContext ctx, FREObject[] args );

}

public class FREObject {

public static FREObject newObject ( int value );

public static FREObject newObject ( double value );

public static FREObject newObject ( boolean value );

public static FREObject newObject ( String value );

public int getAsInt (); public double getAsDouble();

public bool void setProperty( String propertyName, FREObject propertyValue );

FREObject callMethod( String methodName,

FREObject methodArgs[] );

getAsBool ();

public String getAsString();

FREObject getProperty( String propertyName ); 16

public static native FREObject newObject ( String className, FREObject constructorArgs[]); }

public class FREBitmapData extends FREObject {

public static FREBitmapData newBitmapData (int width, int height, boolean transparent, Byte[] fillColor);

public int getWidth();

public int getHeight() ;

public java.nio.ByteBuffer getBits();

public void acquire();

void invalidateRect( int x , int y , int width , int height );

}

public class FREByteArray extends FREObject {

public static FREByteArray newByteArray ();

public long getLength();

public java.nio.ByteBuffer getBytes();

public void acquire();

public void release();

}

public class FREArray extends FREObject {

public static FREArray newArray (String classname, int numElements, boolean fixed);

public static FREArray newArray (int numElements);

public long getLength();

public void setLength( long length );

public FREObject getObjectAt( long index );

public void setObjectAt( long index, FREObject value );

}

Page 17: Native Extensions AFPS

Demo

17

Page 18: Native Extensions AFPS

Demo

18

AIR Part (.swf)

var asLayer : ASLayer = new ASLayer();

asLayer.VibrateDevice();

AS library (.swc)

Class ASLayer {

private var context : ExtensionContext = ExtensionContext.createExtensionContext(extID, type);

public function VibrateDevice() : void {

Context.call(“VibrateMethod”);

}

}

Native code (.a)

FREObject VibrateMethod(arguments) {

NSLog(@”*********In NativeVibrateMethod”);

AudioSeervicesPlaySystemSound( kSystemSoundID_Vibrate );

return NULL;

}

Extension