Title: HAVi Level 2 Programming
1HAVi Level 2 Programming
2Jean Moonen jean.moonen_at_philips.com
3Overview
- Role of Java in HAVi (recap)
- HAVi Java APIs (HJA)
- package structure
- IDL to Java type mapping
- Messaging System interface
- Client classes
- Level 2 UI
- Java code units
- Examples
- DCM
- Application
- Havlet
4HAVi Architecture
Application
Application
havlet
Application
Interoperability API (native binding)
DCM
DCM
DCM
Stream Mgr
Resource Mgr
Messaging
Registry
Event Mgr
Interop. API (Java binding)
DCM
DCM
DCM
org.havi...
optional
JVM
Level I UI Engine
DCM Manager
Porting Layer
1394 Manager
Vendor-specific Platform (RTOS)
Other Device Drivers
1394 Device Drivers
5Role of Java
- Downloadable DCMs
- need access to its target, via CMM
- need access to system services, e.g., Registry
- Downloadable Applications
- need access to device functionality, e.g. FCM
clients - need access to system services, e.g., stream
manager - Downloadable Device UI (applet-like Havlet)
- need access to the screen, via Level 2 UI
- need access to its DCM, via Messaging System
6Approach
- HAVi IDL defines APIs consisting of methods
- Messaging System maps methods to bytestreams
- Minimal requirement for HAVi Java APIs (HJA)
- access Messaging System API
- Additionally, HJA provides (higher-level)
helpers,e.g. - org.havi.types provides data container classes
for IDL types - org.havi.system provides client classes with
programmatic interface to system services - org.havi.fcm. provides client classes with
programmatic interface to fcm services - Result location transparant RPC (Remote
Procedure Call) access to all HAVi APIs over
1394.
7HAVi Java API packages
- Profile 1 for DCMs and Applications, on each
FAV - java.lang, as defined in JDK 1.1
- java.util, as defined in JDK 1.1
- org.havi.constants,
- org.havi.types,
- org.havi.system,
- org.havi.Iec61883,
- org.havi.fcm.,
- (Internal, parts of) java.io, as defined in JDK
1.1 - (Internal, parts of) java.util.zip, as defined in
JDK 1.1 - Profile 2 add UI packages, for device UI,
optional to FAV - org.havi.ui
- org.havi.ui.event
8 Basic Types
- IDL
- boolean
- char
- wchar
- octet
- string
- wstring
- (unsigned) short
- (unsigned) long
- (unsigned) long long
- float
- double
- Java
- boolean
- byte
- char
- byte
- byte
- java.lang.String
- short
- int
- long
- float
- double
9Enumerations Constants
- IDL
- enum TypeX A, B, C
- const TypeY A 0x13
- const TypeY B 0x94
Java public final class ConstTypeX public
static final int A0, public static final int
B1, public static final int C2 public final
class ConstTypeY // translate basic
type public static final TypeY A 0x13,
public static final TypeY B 0x94
10Constructed Types
- All constructed types derive from either
- HaviObject (abstract)
- equals / hashcode / clone (standard Java)
- marshal / unmarshal (for Messaging System)
- HaviImmutableObject (abstract)
- no unmarshal !
- derived class has no state-changing methods
- safe a valid constructed object remains valid
- efficient object references may be copied
instead of clones - Example BitMap extends HaviObject
- object may be changed/re-used (with new bitmap
data) - Example OperationID extends HaviImmutableObject
- object can not be changed/re-used
11Structures
Java public final class SType extends
HaviObject // or HaviImmutableObject // member
vars private AType A // map members private
BType B // recursively // constructor SType
(AType _A, BType _B) // for each member A, B,
.. AType getA() // clone if needed void
setA(AType _A) // non-immutable
- IDL
- struct SType
- AType A
- BType B
-
12Unions
Java public final class UType extends HaviObject
// or HaviImmutableObject // current
discriminator private DType discr // for each
branch private AType A // map members //
constructors for each branch UType(DType
discr, AType _A) // for each member A, B1,
B2 AType getA() throws UnionException void
setA(AType _A) // non-immutable, //
sets discr.
- IDL
- union UType
- switch (DType)
- case DValA
- AType A
- case DValB1
- BType B1
- case DValB2
- BType B2
- // ...
-
13Miscellaneous
- IDL
- sequenceltTypegt A
- Type A10
- typedef Type TypeName
- TypeName A
Java Type A Type A Type A // unwind
14Holder Classes
- IDL has in out or inout parameter qualifier
- Java uses call by value for basic types and
object refs - Holder classes introduced for inout and out
parameters that are basic, immutable or
array - Method M(out short s) -gt M(ShortHolder s)
- Method M(out SEID s) -gt M(SeidHolder s)
- Method M(out SEID seq) -gt M(SeidSeqHolder
seq) - Holder class member examples
- ShortHolder(short s)
- short ShortHoldergetValue()
- void ShortHoldersetValue(short s)
15Exceptions
- All HAVi methods Status short apiCode, short
errorCode - Each Status is mapped to a java.lang.Exception-der
ived class - HaviException extends java.lang.Exception
- abstract short getApiCode()
- abstract short getErrCode()
- Status makeStatus()
- StatusmakeException() returns HaviException
- E.g., HaviClockException extends HaviException
- implements getApiCode()
- E.g., HaviClockTimerException extends
HaviClockException - implements getErrCode()
- Java-specific errors extend from Exception
directly, e.g., HaviUnionException
16Marshalling (1)
- Based on OMGs CDR (Common Data Representation)
- Map IDL types (or Java equivalent) to/from a byte
array - HaviByteArrayInputStream encapsulates reading
from a CDR stream - extends java.io.ByteArrayInputStream
- construct from byte
- read using readInt(), readHaviString(),
readBoolean(), etc. - HaviByteArrayOutputStream encapsulates writing a
CDR stream - extends java.io.ByteArrayOutputStream
- fill using writeInt(), writeHaviString(),
writeBoolean(), etc. - export via byte toByteArray()
17Marshalling (2)
- All HaviObject-derived classes support
- marshal(HaviByteArrayOutputStream out)
- unmarshal(HaviByteArrayInputStream in)
- ltconstructorgt(HaviByteArrayInputStream in)
- HaviImmutableObject-derived classes have no
unmarshal - Recursive procedure for constructed types, e.g.,
- (un)marshal a structure by calling(un)marshal on
each member - (un)marshal an object sequence by marshalling the
length followed by calling un)marshal on each
sequence element - (un)marshal basic types directly
18Messaging System Access (1)
- Steps
- 1 create a subclass of class HaviListener
- needed to receive messages for application
processing - fill in callback HaviListenerreceiveMsg(SEID
sender, HaviByteArrayInputStream msgPayload, ...) - 2 create an instance SoftwareElement, pass
listener to constructor - getSeid() returns the id of the messaging system
client - SoftwareElement offer the public messaging system
API - 3 add zero or more HaviListener-derived object
- use method addHaviListener
- incoming messages will be dispatched to all
listeners, in no particular order, on a single
thread dedicated to this SoftwareElement object - each listener can be used to handle a particular
kind of messages (e.g., a particular set of
operations)
19Messaging System Access (2)
- For all HAVi APIs, there are client helpers
- Class ltAPIgtClient encapsulates (un)marshalling of
parameters and errors (using a SoftwareElement) - Each method M is mapped in an Async and a
Sync way. - Async ltAPIgtClientM(in-pars, IntHolder
transactionId), and - uses SoftwareElementSendRequest and returns a
transactionId - response in returned later by a callback on
installed listener objects - app must match transactionIds,
- Sync ltAPIgtClientMsync(int timeout, in-pars,
out-pars) - uses SoftwareElementSendRequestSync
- blocks until the response is received, or
timeout occurs - msg system matches transactionIds and unmarshals
out pars - Apps may use SoftwareElement directly
- Sync is convenient, Async avoids
blocking/Thread resources
20Messaging System Access (3)
- For all services of type Message Back (server
-gt client) there are specific listener helpers - E.g., EventManagerNotificationListener extends
HaviListener - EventManagerNotificationListenerreceiveMsg
unmarshals the Message Back (e.g., EventId) and
calls abstract handler - Apps may subclass EventManagerNotificationListener
(fill in abstract handler method) - Listener classes are helpers, apps may choose to
subclass HaviListener directly - Apps need to call SoftwareElement.addHaviListener
in either case
21Level 2 UI
- TV-friendly UI framework,
- packages org.havi.ui org.havi.ui.event
- requires subset of java.awt (JDK1.1)
- adds
- CE-friendly widgets
- CE-friendly input devices (remote control
support) - CE-friendly screen functionality (OSD)
- ...
- supports creation of custom widgets
22Code Units
- Used for DCMs, Havlets and Applications
- Java Archive (JAR) format
- FAV loads the JAR and instantiates a class in
package ltnonegt, with fixed name and interface - class DcmCodeUnit implements DcmCodeUnitInterface
- class HavletCodeUnit implements
HavletCodeUnitInterface - class AMCodeUnit implements AMCodeUnitInterface
- These classes have install() and uninstall()
method - FAV provides an UninstallationListener to be
notified of (complete) uninstallation (garbage
collection)
23Examples DCM Code Unit
- // no package name!
- import org.havi.types. // from HJA
- import org.havi.system. // from HJA
- import com.philips.dcms.example. // from JAR
file - public class DcmCodeUnit implements
DcmCodeUnitInterface - private MyDcm m_dcm
- private UninstallationListener m_fav
- public int install(GUID bavDevice,
UninstallationListener fav) - int rval 0 // success
- m_fav fav
- try m_dcm new MyDcm(bavDevice, fav)
- catch (Exception e) rval 1 / failed /
- return rval
- public void uninstall()
- m_dcm.uninstall()
- m_fav.uninstalled()
-
24Examples DCM Context (1)
DCM
App
MyHavi Listener
Cmm Listener
MyDcm
DcmClient
Software Element
Cmm Client
Software Element
BAV device
1394 driver
Messaging System
FAV
1394 driver
Cmm
Havi msgs on 1394 write
1394 read/ write/lock
1394 driver
25Examples DCM Context (2)
DCM
App
MyHavi Listener
Cmm Listener
MyDcm
DcmClient
Software Element
Cmm Client
Software Element
BAV device
1394 driver
Messaging System
FAV
1394 driver
Cmm
Havi msgs on 1394 write
1394 read/ write/lock
1394 driver
26Examples DCM Context (3)
DCM
App
MyHavi Listener
Cmm Listener
MyDcm
DcmClient
Software Element
Cmm Client
Software Element
BAV device
1394 driver
Messaging System
FAV
1394 driver
Cmm
Havi msgs on 1394 write
1394 read/ write/lock
1394 driver
27Examples DCM Context (4)
DCM
App
MyHavi Listener
Cmm Listener
MyDcm
DcmClient
Software Element
Cmm Client
Software Element
BAV device
1394 driver
Messaging System
FAV
1394 driver
Cmm
Havi msgs on 1394 write
1394 read/ write/lock
1394 driver
28Examples DCM Context (5)
DCM
App
MyHavi Listener
Cmm Listener
MyDcm
DcmClient
Software Element
Cmm Client
Software Element
BAV device
1394 driver
Messaging System
FAV
1394 driver
Cmm
Havi msgs on 1394 write
1394 read/ write/lock
1394 driver
29Examples DCM initialization
- package com.philips.dcms.example // import HJA
packages... - public class MyDcm
- public MyDcm(GUID bavDevice, UninstallationListene
r fav) - m_target bavDevice
- m_hl new MyHaviListener() // process havi
msgs - m_se new SoftwareElement(m_hl) // access msg
system - m_seid m_se.getSeid() // get my address
- m_cmm new Cmm1394LocalClient(m_se) // access
cmm - m_op new OperationCode(13,94) // callback
opcode - m_cl new MyCmmListener(m_se, m_op) // process
cmm msgs - m_se.addHaviListener(m_cl)
- enrollCmmIndication(m_target, range, m_op) //
receive indications from BAV - m_reg new RegistryLocalClient(m_se) // access
registry - registerDcm()
30Examples DCM registration
- public registerDcm()
- Attribute attrs new Attribute10
- HaviByteArrayOutputStream s new
HaviByteArrayOutputStream() - s.writeHaviString(Philips)
- attrs0 new Attribute(ConstAttributeName.ATT_D
EV_MANUF,s) - s.reset() s.writeInt(ConstDeviceClass.BAV)
- attrs1 new Attribute(ConstAttributeName.ATT_D
EV_CLASS, s) - // other attributes
- m_reg.registerElementSync(0, m_seid,
attributes)
31Examples DCM msg handling
- class MyHaviListener extends HaviListener
- private MyDcm m_dcm // actual implementation
- private DcmServerHelper m_respSender // helper
class - public receiveMsg(SEID sender,
HaviByteArrayInputStream msg, ...) - // parse msg into opCode inPars
- // ...
- switch (opCode)
- case PLAY // check access right of sender
... - // synch. execution shown
- Status status m_dcm.play(inPars, outPars)
- m_respHelper.playResp(sender, status,
outPars) // send result - break
- case STOP //...
32Examples DCM controls BAV
- // class MyDcm
- void play()
-
- byte cmd 0x12, 0x34, // some command
encoding - long addr 0xfffff0000b00 // some address
- m_cmm.writeSync(0, m_target, addr, cmd)
-
- // class MyCmmListener
- Status cmm1394Indication(GUID sender, long
address, byte dataIn, ByteSeqHolder
dataOut) -
- // process 1394 indication from BAV
- // could be command response, or notification
(front-panel operation)
33Examples Application Context
App
HJA org.havi.
FAV
1394 driver
HAVi Network
Havi msgs on 1394 write
34Examples Application (1)
- Typical steps
- create SoftwareElement
- messaging system access
- create system clients
- RegistryClient, StreamManagerClient, etc
- locate FCMs through RegistryClient
- vcr, display,
- reserve FCMs through ResourceManagerClient
- setup streams using StreamManagerClient
- create FCM clients
- activate content / control FCMs through cFCM
lients
35Examples Application (2)
- class ExampleApp
-
- ExampleApp
- m_hl new MyHaviListener() // process havi
msgs - m_se new SoftwareElement(m_hl) // access msg
system - m_reg new RegistryLocalClient(m_se) //
access registry - m_rm new ResourceManagerLocalClient(m_se) //
access resource mgr - m_sm new StreamManagerLocalClient(m_se) //
access stream mgr - SEID vcrs getFcms(m_reg, ConstSoftwareElement
.VCR) - SEID displays getFcms(m_reg,
ConstSoftwareElement.DISPLAY) - reserveFcms(m_rm, vcrs0, displays0)
- setupStream(m_sm, vcrs0, displays0) //
flow from vcr to display - VcrClient vcr new VcrClient(m_se, vcrs0) //
access vcr - vcr.playSync(0,) // activate the content
-
-
36App locates FCMs
- // class ExampleApp
- SEID getFcms(RegistryClient reg, int fcmType)
-
- HaviByteArrayOutputStream val new
HaviByteArrayOutputStream() - val.writeInt(fcmType)
- SimpleQuery q SimpleQuery(ConstAttributeName
.SE_TYPE, val, ConstComparisonOperato
r.EQU) - SEIDSeqHolder result new SEIDSeqHolder()
- reg.getElementSync(0, q, result)
- return result.getValue()
-
37App reserves FCMs
- // class ExampleApp
- void reserveFcms(ResourceManagerClient rm, SEID
fcm1, SEID fcm2) -
- // reserve as primary
- ResourceRequestRecord rec1 new
ResourceRequestRecord(fcm1, true)
ResourceRequestRecord rec2 new
ResourceRequestRecord(fcm2, true) - ResourceRequestRecord recs rec1, rec2
- rm.reserveSync(.., recs, ...) // call resource
manager -
38App sets up stream
- // class ExampleApp
- void setupStreams(StreamManagerClient sm, SEID
src, SEID snk) -
- FcmClient srcFcm new FcmClient (src) //
same for snk - HuidHolder srcHuid new HuidHolder() //
same for snk - srcFcm.getHuidSync(0, srcHuid) // same
for snk - TargetId srcTarget srcHuid.getValue().getTarge
tId() // same for snk - // check srcFcm.getPlugCountSync() returns gt 0
for outCount - // check snkFcm.getPlugCountSync() returns gt 0
for inCount - // connect plug 0 of src to plug 0 of snk
- FcmPlug srcPlug new FcmPlug(srcTarget,
ConstDirection.OUT, 0) - FcmPlug snkPlug new FcmPlug(snkTarget,
ConstDirection.IN, 0) - sm.flowToSync(.., sourcePlug, sinkPlug,
...) // call stream manager -
39Examples Havlet Context (1)
Havlet
DCM
FAV/IAV
org.havi.ui.
Software Element
BAV device
Rest of HJA
FAV with display
CMM
1394 driver
1394 driver
1394 driver
1394 read/ write/lock
Havi msgs on 1394 write
40Examples Havlet Context (2)
Havlet
DCM
FAV/IAV
org.havi.ui.
Software Element
BAV device
Rest of HJA
FAV with display
CMM
1394 driver
1394 driver
1394 driver
1394 read/ write/lock
Havi msgs on 1394 write
41Examples Havlet