Download - Native Extensions AFPS

Transcript
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