Surgimento • Qualcomm – Fundada em 1985 – San Diego, Califórnia USA – Localização por satélite – OmniTracs – CDMA: dispositivos e estações base – Eudora! • Ano: 2000 • Um olho na cadeia de App Con lica ten tion Car t Dev rier Pro elo s vid per ers s Devi ce Pub Cus Man lish tom ufac ers ers ture s Surgimento • Vasta experiência em desenvolvimento para celular • Líder em desenvolvimento de aplicações CDMA Necessidade de uma plataforma uniforme de desenvolvimento para celular Necessidade de conexão entre os links na cadeia de valores do mercado móvel Jan 2001 Binary Runtime Environment for Wireless End-to-end business and technology solution BREW: End-to-end business and technology solution • Operadoras: – Virtual Marketplace • Seleção de aplicação • Negociação de preço com o desenvolvedor – BREW Delivery System (BDS) • Secure over-the-air distribution • Coordinates billing and payment • Fabricantes: – BREW client software – Porting and testing tools – Consultoria na especificação do dispositivo • Usuários: – BREW Mobile Shop App Con lica ten tion Car t Dev rier Pro elo s vid per ers s Devi ce Pub Cus Man lish tom ufac ers ers ture s BREW: End-to-end business and technology solution • Publishers, Desenvolvedores e Provedores de Conteúdo: – Modelo de negócio simples – Suporte Técnico – BREW SDK® – Ferramentas de Desenvolvimento – Assistência a testes – Near-real time application App Con lica ten tion Ope t Dev rat Pro elo ors vid per ers s Devi ce Pub Cus Man lish tom ufac ers ers ture s O que é BREW BREW Solution Tecnologia + Modelo de negócio • Solução completa para – Desenvolvimento de aplicações wireless – Configuração de dispositivos – Distribuição de aplicações – Cobrança e pagamento de aplicações A Solução BREW • BREW SDK – Kit de desenvolvimento para desenvolvedores de aplicações • Software cliente BREW e ferramentas de porting – Software base instalado no celular (+/- 150k) embutido pelos fabricantes • BREW Distribution System (BDS) – Sistema que permite comercialização de aplicações através de operadoras O Modelo de Negócios BREW Fonte: http://brew.qualcomm.com Facilidades do Modelo • Comercio virtual com BDS (BREW Distribution System) – Submissão de aplicações e testes – Negociação operadora x desenvolvedor • Customização de ofertas de produtos para assinantes via catálogo da operadora – Funções de gerenciamento de catálogo – Download, execução e deleção de aplicações – Serviços de download extensíveis • Serviços financeiros com BDS – Suporte a transações – Serviços de cobrança integrados Tecnologia: BREW no Celular Fonte: http://brew.qualcomm.com ASIC: Application Specific Integrated Circuit BREW no Celular • 150K , situado entre os aplicativos e a camada ASIC • Desenvolvimento independente de chipset dos dispositivos – Porte! • Aplicativos podem ser escritos em JAVA, C ou C++ • Restrições de exclusividade • Tecnologia própria • Centralização • Burocracia de instalação/ publicação – Assinatura digital – TRUE BREW • $$ BREW x J2ME - Vantagens • API mais bem suportada • Tricks mais limpas – Acesso direto à tela • Não há limite para tamanho da aplicação • Pode-se utilizar OO sem medo • Facilita a distribuição de aplicações independentemente de tecnologia – OTA – cdmaOne,CDMA2000,gsm/gprs,UMTS (3G), etc • Distribuição, gerenciamento e vendas BREW x J2ME - Desvantagens • Solução de compressão deve ser escrita pelos desenvolvedores • Inexistência de profilers • Área de atuação restrita a Japão e EUA BREW Hoje 28 países 3 a caminho 41 fabricantes 51 operadoras 5 a caminho No Brasil: BREW 1.0 BREW 2.1 BREW 1.1 BREW 3.0 BREW 2.0 BREW 3.1 BREW: Evolução (1/3) • BREW 1.0 – Quase não existe aparelho Motorola V731 e Sharp800. • BREW 1.1 – Minor upgrade to BREW – Brew Compressed Image format (BCI ) – T720 - 400k RAM - 4096 byte stack - 1500k de espaço de file system • BREW 2.0 – Sprite nativo e suporte a tiles – Transformações em bitmaps, sprite e tile objects • Rotated – 90 graus BREW: Evolução (2/3) • BREW 2.1 – Gráficos 3D – Câmera • BREW 3.0 – Removable Storage media • SD, MMC ... – Interface Serial – BREW Simulator baseado em dados reais do dispositivo BREW: Evolução (3/3) Demonstração da evolução de BREW • http://brew.qualcomm.com/brew/en/operator/de mos/demos.html 1. Overview do Curso Conceitos Básicos – – Termos técnicos Estrutura de uma aplicação BREW 2. Desenvolvimento de aplicações – – – Análise de uma aplicação simples Interfaces básicas da API HelloWorld 3. Aplicações – 2ª parte – Integração de código C++ Compilação para o dispositivo 4. Interface com o usuário IDisplay, IGraphics, IImage, IDialog 5. Recursos de Rede BREW Conceitos Básicos O Modelo de Camadas Elementos BREW BRI MI F BID = ClassID Módulo BAR Recursos Applet Plataforma BREW Interface Interface Módulos • Englobam os componentes de uma aplicação • Encapsulam um ou mais applets • Desenvolvidos como DLLs Windows – Assumem outro formato quando compilados para o dispositivo (.mod) • Sempre possuem um Applets • Similares a “aplicações” • Toda aplicação BREW deve possuir pelo menos um applet • Classes que permitem ser gerenciadas pelo ambiente – Criação, destruição e troca de mensagens • Implementam uma interface comum Interfaces • Serviços na plataforma BREW são disponibilizados através de interfaces (APIs) • Interfaces em BREW possuem um ID único e o acesso é gerenciado pela plataforma • Cada interface encapsula um conjunto de serviços como – Acesso ao display – Controle de som – Serviços de rede ClassIDs • Applets e interfaces públicas possuem identificadores únicos em BREW • Identificadores possuem 32 bits e são chamados de ClassIDs • São gerenciados pela Qualcomm para garantir sua unicidade • São mantidos em arquivos de texto com extensão .bid Arquivos MIF • Cada módulo BREW possui um arquivo MIF (Module Information File) associado • MIFs mantêm informações sobre o conteúdo do módulo – Applets – Privilégios – Títulos de applets e BREW íconesMIF Editor São criados e editados pelo Programas BREW SDK 2.0 BREW MIF Editor – ClassIDs • Plataforma lê as informações do aplicativo instalado do .mif Arquivos de Recursos (.BAR) • Mantêm os recursos usados pela aplicação – Textos – Imagens – Sons • .BRI descreve o BAR Recursos precisam ser compilados antes de serem utilizados pela • .BRI editado por aplicação! BREW Resource Editor Compilação do BRI • Compilador embutido no Resource Editor – Build Build QUALCOMM .BAR/.H Files Relembrando ClassIDs MIFs Arquivos de recursos • Applets • Módulos • Interfaces BRI MI F BID = ClassID Módulo BAR Recursos Applet Plataforma BREW Interface Interface Aplicações BREW 1ª parte 1. 2. 3. Criando aplicações no VS 2005 Interfaces básicas Debugando no VS 2005 Analisando uma Aplicação • Execute o emulador BREW – IniciarProgramasBREW SDK 2.0BREW Emulator • Selecione a aplicação “Hello World App” Estrutura de Arquivos • No Windows Explorer, abrir – <BREWDIR>\Examples • Estrutura padrão MIF <APP> dll bar bid Estrutura de arquivos Projeto Meantime mba.mif, mba.bid mba.mif mba.dll, mba.bid, mba.bar mba.vcproj, pre_build.bat, post_build.dat mba.bri, *.png, *.bvg, *.mid, *.txt MainApplet.cpp.... VS - O Ambiente • VS 2003 - A IDE oficial de desenvolvimento BREW é Microsoft Visual Studio • VS 2003 - Quando instalado, o BREW SDK incorpora um novo wizard aos tipos de projeto do VS – File New Projects BREW Application Wizard • VS 2003 - O wizard configura o ambiente e adiciona automaticamente os arquivos O Ambiente • Microsoft Visual Studio C++ 2005 – Express Edition • BREW SDK 2.0.1 • BREW Tools 1.0 Visão Geral do Código • No Visual Studio, abrir – <BREWDIR>\Examples\HelloWorld\helloworld .dsw • Convert project • Do not remove source control bindings from project! • Arquivos que compõem a aplicação – AEEAppGen.c (gerado) – AEEModGen.c (gerado) – helloworld.c (implementação das funcionalidades) • Criando uma aplicação É necessário – Arquivo MIF (MIF Editor) – Criar o projeto – Implementação das interfaces básicas • IApplet, IModule – Fornecer os métodos para a plataforma: • CreateInstance • HandleEvent • FreeAddData – Configurar as propriedades de projeto Passo a passo - Criando o mif 1. Abrir o BREW MIF Editor 2. Clique em New Applet e dê o nome “HelloWorld” 3. Marque a opção “Locally” e entre com o número “11111111” • Por ser um ID local, pode ser qualquer ID diferente dos existentes 4. Nomeie o ClassID como HELLO_WORLD 5. Clique em Generate e confirme • Lembrar da estrutura de diretórios! 6. Salve o arquivo .bid junto à raiz do seu projeto 7. Salve o arquivo. mif na pasta mais externa Passo a passo - Criando o projeto 1. 2. 3. 4. Abra o Visual Studio File New Project Selecione “emptyproj” Nomear o projeto como “HelloWorld” Desmarque a opção “Create directory for solution” Passo a passo Implementando as interfaces básicas • Essas interfaces já estão prontas, bastam ser adicionadas ao projeto • Clique com o botão direito em ‘Source Files’ e selecione ‘Add existing Item’ • Do caminho <BREWDIR>/src, adicione os arquivos: – AEEAppGen.c – AEEModGen.c Passo a passo - Criando o arquivo principal • É o arquivo que fornece os métodos de entrada na aplicação • Com o botão direito no ‘Source Files’, selecione ‘Add New Item’ • Crie um MainApplet.cpp • Copie o corpo do arquivo ‘Exemplo1.c’ • Substitua as referências ao bid, ao classId Passo a passo Configurando o projeto • General do projeto – Dll! • General em C/C++ – inc de <BREWDIR> – 64bits -> NO • Preprocessor em C/C++ – Adicione AEE_SIMULATOR • Advanced em C/C++ – Compile as Default Interação com a plataforma • ‘Padrão’ de comportamento definido – É necessário um padrão uniforme para que o ambiente interaja com as aplicações • ‘Diretos e deveres’ das Aplicações podem acessar os serviços das interfaces aplicações Plataforma controla o ciclo de vida das aplicações Interação Ambiente Aplicação • Toda aplicação BREW precisa – Permitir sua criação e destruição pelo ambiente – Receber e tratar eventos • Duas interfaces definem o padrão para módulos e applets – IModule – IApplet • Definem os serviços básicos que devem ser fornecidos por toda aplicação BREW IModule • Mecanismo para controle de acesso a applets e classes • Define funções para – Permitir ao BREW requisitar uma instância de classe específica do módulo • IMODULE_CreateInstance() – Permitir ao BREW requisitar a liberação de recursos • IMODULE_FreeResources() • Raramente utilizada diretamente pelo desenvolvedor IApplet • Define o serviço para manipulação de eventos gerados pelo sistema ou outros applets • Deriva de IBase e define a função HandleEvent IAPPLET_HandleEvent() só pode ser chamada pelo shell! •Para Todo applet precisa implementar esta enviar eventos para outros applets deve-se chamar ISHELL_SendEvent() interface Tratamento de eventos • O modelo de aplicação BREW é baseado em um engenho dirigido a eventos – Todas as entradas do applet são recebidas como eventos – O applet precisa indicar ao ambiente se tratou ou não o evento recebido (retorno TRUE ou FALSE) – Eventos recebidos pela função Por são questão de segurança, a demora na resposta a eventos causa a interrupção do HandleEvent() implementada por todo applet pelo ambiente! applet A Função HandleEvent boolean HandleEvent(IApplet * pIApp, AEEEvent eCode, uint16 wParam, uint32 dwParam) • Parâmetros – pIApp: ponteiro para o applet atual – eCode: código do evento recebido – wParam: parâmetro do evento (16 bits) – dwParam: parâmetro do evento (32 bits) • Exemplos de possíveis eventos – EVT_APP_START, EVT_APP_STOP, EVT_KEY_PRESS – Lista completa disponível no BREW API Interação Aplicação Ambiente • Toda aplicação precisa – Acessar o dispositivo • Tela, som, teclas, etc. – Fazer uso de serviços pré-definidos • Primitivas de desenho, tratamento de eventos, etc. • Em BREW, duas interfaces provêem este tipo de suporte – IShell – IBase IShell • Dá acesso a todos os serviços externos • Applets podem requisitar ponteiros para outras interfaces (passando o respectivo ID) – ISHELL_CreateInstance() • Algumas características principais – Ativar e desativar o applet atual – Gerenciar timers – Carregar recursos utilizados em applets – Passar eventos para outros applets IBase • Define a estrutura básica de todas as classes do ambiente • Toda interface do AEE herda de IBase • Define as funções principais para gerenciamento de objetos na memória – Alocação de objetos (função AddRef()) – Liberação de objetos (função Release()) Nosso Alô Mundo! 1. Abra o projeto HelloWorld criado anteriormente 2. Abra o arquivo MainApplet.cpp 3. Vamos analisar • • • • • Estrutura _Exemplo1 Funcão AEEClsCreateInstance() Funcão Exemplo1_HandleEvent() Funcão Exemplo1_InitAppData() Funcão Exemplo1_FreeAppData() 4. No início da função Exemplo1_HandleEvent(), crie um string contendo a mensagem que será apresentada na tela • Exemplo: AECHAR szText[] = {'A', 'l','o',' ', 'M', 'u', 'n', Alô Mundo! 5. No case de tratamento do evento de inicialização do applet (EVT_APP_START), IDISPLAY_DrawText(pMe->pIDisplay, // ponteiro para o display fonte negrito desenheAEE_FONT_BOLD, o texto na tela e//atualize o display szText, // texto -1, // -1 = a string toda 0, // posicao x – ignorada aqui 0, // posicao y – ignorada aqui NULL, // sem clipping IDF_ALIGN_CENTER | IDF_ALIGN_MIDDLE); IDISPLAY_Update (pMe->pIDisplay); Alô Mundo! no Emulador 1. Copie o arquivo HelloWorld.mif para o diretório “<ROOT>\BREW SDK v2.0.1\Examples” 2. Neste mesmo diretório crie uma pasta “HelloWorld” 3. Para esta pasta copie os arquivos • HelloWorld.bid • helloworld.dll 4. Abra o emulador e veja sua aplicação! Debugging no Visual Studio: Configuração 1. Project Properties 2. Debugging Command • Entre com “<ROOT>\BREW SDK v2.0.1\Bin\BREW_Emulator.exe” 3. C/C++ General Debug Information Format • Selecione “Program Database for Edit & Continue” 4. C/C++ Optimization • Disabled! 5. Linker Debugging Generate Debug Info • Selecione “Yes (/DEBUG)” Aplicações BREW 2ª parte 1. 2. Migrando de C para C++ Compilando para o dispositivo STDLIB em BREW • BREW não suporta a biblioteca padrão de C • As funções de STDLIB são substituídas por macros e funções específicas • Existem funções para – – – – Manipulação de strings Arquivos e I/O Alocação de memória Etc. • Estas funções são chamadas Helper Functions e estão documentadas no BREW API Reference, seção Helper Functions • Seu código deve incluir a biblioteca Integrando Código C++ • Além de código C, BREW suporta recursos de C++ – Classes – Herança – Interfaces • • • • Exceções não são suportadas! Threads não são suportadas! Objetos estáticos não são suportados! Classes podem ser incorporadas à aplicação normalmente, desde que as funções invocadas pelo ambiente sejam Migrando para C++ : Acesso à plataforma • Applet (IShell e IDisplay) + DeviceInfo fornecem acesso à plataforma • Todo mundo precisa desses recursos.. • O Acesso à plataforma deve então ser encapsulado numa estrutura typedef struct SBREWAccess : public AEEApplet { AEEDeviceInfo m_deviceInfo; } SBREWAccess; Migrando para C++: O Applet • Uma classe que herda da estrutura de acesso a BREW • Métodos de controle de toda a aplicação – HandleEvent, – FreeAppData, – InitAppData, – StopApp, – StartApp, – PauseApp, – ResumeApp Migrando para C++: O Applet class CMainApplet : public CBREWAccess { public: static boolean HandleEvent(CMainApplet * pCMainApplet, AEEEvent eCode, uint16 wParam, uint32 dwParam); static void FreeAppData(CMainApplet *pCMainApplet); void void void void void InitAppData(); StopApp(); StartApp(); PauseApp(); ResumeApp(); private: CScreenManager* m_pScreenManager; CDataManager* m_pDataManager; /* etc, etc, etc*/ }; Migrando para C++: O Applet • HandleEvent e FreeAppData são chamados pela plataforma – Métodos estáticos. – Ponteiros passados no CreateInstance – Assinatura fixa • InitAppData, Start, Stop, Pause e Resume reagem a eventos enviados pela plataforma Migrando para C++: O Applet int AEEClsCreateInstance(AEECLSID ClsId, IShell *pIShell, IModule *po, void **ppObj) { *ppObj = NULL; if( ClsId == AEECLSID_HELLOWORLD ) { // Create the applet and make room for the applet structure if( AEEApplet_New(sizeof(CMainApplet), ClsId, pIShell, po, (IApplet**)ppObj, (AEEHANDLER)CMainApplet::HandleEvent, (PFNFREEAPPDATA)CMainApplet::FreeAppData) == TRUE ) { ((CMainApplet *)*ppObj)->InitAppData(); return (AEE_SUCCESS); } return (EFAILED); } void CMainApplet::InitAppData() { // get device info ISHELL_GetDeviceInfo(m_pIShell, const_cast <AEEDeviceInfo*> (&m_deviceInfo)); // initialize your managers... // etc, etc, etc } • Migrando para C++: O Applet HandleEvent – Chamado pela plataforma: tratar os eventos – Reenviá-los para o gerenciador de eventos • InitAppData – Chamado dentro do createInstance – Inicializar os managers • FreeAppData – Chamado pela plataforma após o envio do evento STOP – Deletar todos os recursos alocados • StartApp – Acionado no recebimento de um evento de START – Coloca o aplicativo pronto pra realmente começar a executar • StopApp – Acionado no recebimento de um evento de STOP – Coloca o aplicativo pronto pra ser destruído • PauseApp – Acionado no recebimento de um evento de PAUSE – Desalocar recursos BREW • Migrando para C++: Funções Globais extern void* operator void* operator new(size_t new(size_t size); size) { return MALLOC(size); } • extern void* operator new[](size_t size); • extern void operator delete(void *ptr); void* operator new[](size_t size) { return MALLOC(size); } void operator delete(void *ptr) { FREE(ptr); } New e delete precisam ser implementados com as macros MALLOC e FREE e não as funções free() e malloc() de ANSI void • extern void operator delete[](void *ptr); operator delete[](void *ptr) { FREE(ptr); Migrando para C++: Simulando Exceções • Definição do tipo que representa os erros – typedef int32 EUserError; – #define USERERROR_None AEEError.h - 0 – #define USERERROR_General 0x01) – #define USERERROR_NoHeapMemory + 0x02) AEE_SUCCESS // (ERROR_USER + (ERROR_USER • Definição das macros de TRY e Migrando para C++: Simulando Exceções • Todos os métodos que levantariam exceções recebem como primeiro parâmetro a referência de um erro – void Init(EUserError& rError) {}; • Init e Free e não Construtor e Destrutor! • Como simular as exceções, utilizando essas macros? Migrando para C++: Simulando Exceções void Init(EUserError& rError) { // ... m_pScreenManager = new CScreenManager(); TRY_OBJ(m_pScreenManager, rError); m_pScreenManager->Init(rError); TRY_ERROR(rError); m_pDataManager = new CDataManager(); TRY_OBJ(m_pDataManager, rError); m_pDataManager->Init(rError); TRY_ERROR(rError); return; //... BEGIN_CATCH(); // delete all the resources previously loaded if ( m_pScreenManager ) { m_pScreenManager->Free(); SAFE_DELETE(m_pScreenManager); } if ( m_pDataManager ) { m_pDataManager->Free(); SAFE_DELETE(m_pIDataManager); } } Migrando para C++: Nosso HelloWorld • Migrar nosso HelloWorld para C++ • Dica: – Globals.h com as inclusões de: • • • • • • • AEEStdLib.h AEEShell.h AEEModGen.h AEEAppGen.h AEEShell.h _res.h .bid Compilação para o Dispositivo • Antes de ser implantada no dispositivo, a aplicação BREW precisa ser compilada para o formato ARM • Existem atualmente dois compiladores – RealView Compilation Tool for BREW • Conjunto de ferramentas oficial (e pago) da ARM • Bastante amigável e aplicações exemplo vêm com makefiles para este ambiente – GNU Cross Compiler • Solução não oficial, porém o compilador é free • Dependências – BREW SDK Implantação da Aplicação • O arquivo compilado possui extensão .mod • Este arquivo equivale à DLL usada no emulador • Para implantar a aplicação no celular é necessário – Celular com suporte a BREW (destravado!) – Cabo de dados para conexão serial pc <-> celular – Software para cópia de arquivos BREW Interface com o usuário Recursos de Interface em BREW • BREW dispõe de vários recursos para desenvolvimento de interface com usuário • Existem interfaces para – Desenho de primitivas gráficas – Apresentação de imagens – Componentes de entrada e saída • Texto, lista de opções, menus • Principais interfaces – IDisplay, IGraphics, IImage, IControl IDisplay • Desenha texto, BMPs e formas geométricas na tela • É usada por todas as aplicações • Operações realizadas só têm efeito após uma chamada à função de atualização da tela – Por questão de performance, recomenda-se atualizar a tela apenas após várias operações de desenho IDisplay: Funções Principais void IDisplay_ClearScreen(IDisplay * pIDisplay) – Limpa a área de clipping ou a tela completa se não houver tal área definida void IDISPLAY_EraseRect(IDisplay * pIDisplay, AEERect * pRect) – Limpa um retângulo especificado int IDISPLAY_DrawText(IDisplay * pIDisplay, AEEFont Font, const AECHAR * pcText, IDisplay: Mais Funções Principais void IDisplay_DrawRect(IDisplay * pIDisplay, const AEERect * pRect, RGBVAL clrFrame, RGBVAL clrFill, Existem funções similares para desenho de linhas verticais, horizontais e frames uint32 dwFlags) – Desenha um retângulo usando as flags e cores especificadas IDISPLAY_Update() apenas coloca a operação na fila de mensagens! void IDISPLAY_Update(IDisplay * pIDisplay) Para atualização imediata recomenda-se IDISPLAY_UpdateEx() – Realiza a atualização da tela IDisplay: Utilização 1. Obtenha uma instância da interface IDisplay através da função ISHELL_CreateInstance() • Ou utiliza-se o ponteiro m_pIDisplay da estrutura de dados do applet 2. Se necessário, limpe a região da tela • IDisplay_EraseRect() ou IDisplay_EraseRgn() 3. Realize a operação desejada • Desenho de texto, linha, retângulo ou bitmap 4. Atualize a tela • IDISPLAY_Update() ou IDISPLAY_UpdateEx() 5. Libere a interface se não for mais necessária IDisplay: Exemplo Acesso à instância da estrutura ... IDisplay * display = pMe->m_pIDisplay; IDISPLAY_DrawText(display, AEE_FONT_BOLD, szText, -1, 0, 0, NULL, IDF_ALIGN_CENTER | IDF_ALIGN_MIDDLE); IDISPLAY_Update(pMe->m_pIDisplay); ... Atualização da tela Realização da operação Neste caso não é preciso chamar IDISPLAY_Release()!! Exercício 1 • Alterar o código do Exemplo1 para que imprima na tela a tecla numérica pressionada pelo usuário – O código da tecla é recebido no parâmetro wParam – A lista de códigos das teclas está no BREW API Reference, seção Key Codes IGraphics • Interface para desenhos 2D mais complexos do que os suportados por IDisplay • Suporta círculos e polígonos arbitrários • Operações de viewport IGraphics: Funções Principais RGBVAL IGRAPHICS_SetColor(IGraphics * pIGraphics, uint8 r, uint8 g, uint8 b,uint8 alpha) – Seta a cor (RGBA) atual dos objetos a serem desenhados RGBVAL IGRAPHICS_SetBackground( IGraphics * pIGraphics, uint8 r, uint8 g, IGraphics: Mais Funções Principais boolean IGRAPHICS_SetClip(IGraphics * pIGraphics, AEEClip * pShape, uint8 nFlag) – Determina a área de clipping. Os formatos de clipping suportados hoje são retângulo, círculo e elipse int IGRAPHICS_DrawLine(IGraphics * pIGraphics, Funções similares: AEELine * pLine) DrawArc DrawPie DrawCircle – Desenha um segmento DrawPolygon de reta entre um ponto inicial DrawEllipse DrawTriangle e umDrawPoint ponto final DrawRect IGraphics: Ainda Funções Principais int IGRAPHICS_ClearRect(IGraphics * pIGraphics, AEERect * pRect) – Limpa uma área retangular da tela preenchendo com a cor do background void IGRAPHICS_Update(IGraphics * pIGraphics) – Indica que as operações de desenho já foram concluídas e a tela deve ser atualizada IGraphics: Utilização 1. Obtenha uma instância da interface IGraphics através da função ISHELL_CreateInstance() 2. Identifique a área na tela a ser mostrada • IGRAPHICS_SetViewport() 3. Ajuste a cor do background • IGRAPHICS_SetBackground() 4. Limpe a área do viewport • IGRAPHICS_ClearViewport() pinta com a cor do background 5. Especifique a janela do buffer que será mostrada IGraphics: Mais Utilização 6. 7. 8. 9. 10. Ajuste os parâmetros com funções de set • Cor de preenchimento, região de clipping, modo de pintura, etc Realize a operação de desenho desejada Repita os passos 6 e 7 quantas vezes for necessário Atualize a tela com o resultado das operações • IGRAPHICS_Update() Se não for mais utilizar a interface, libere-a • IGRAPHICS_Release() IGraphics: Exemplo IGraphics * m_pGraphics; AEERect rect; AEELine line; Especifica tamanho e posição. x,y,dx,dy ... Recebe endereço do ponteiro para IGraphics ISHELL_CreateInstance( app->m_pIShell, AEECLSID_GRAPHICS, (void**)( &m_pGraphics )); IGRAPHICS_SetViewport( m_pGraphics, &rect, AEE_GRAPHICS_NONE ); IGRAPHICS_SetColor( m_pGraphics, 0, 0, 0, 0 ); IGRAPHICS_DrawLine( m_pGraphics, &line ); IGRAPHICS_Update( m_pGraphics ); Atualização da tela IImage • Permite mostrar imagens e animações na tela • Cada instância é associada com uma única imagem BMP • É possível exibir animações utilizando-se frames em um único BMP Frame 1 Frame 2 Frame 3 IImage: Funções Principais void IIMAGE_Draw(IImage * pIImage, int x, int y) – Desenha uma imagem (bitmap) na posição especificada void IIMAGE_DrawFrame(IImage * pIImage, int nFrame, int x, int y) – Desenha um frame contido na imagem na posição especificada void IIMAGE_SetParm(pImage * pIImage, int nParm, int p1, int p2) IImage: Mais Funções Principais void IIMAGE_Start(IImage * pIImage, int x, int y) – Inicia a animação de uma imagem dividida em frames na posição indicada da tela – O número de frames e velocidade da animação é ajustada através da função IIMAGE_SetParm() void IIMAGE_Stop(IImage * pIImage) – Pára a animação iniciada por IIMAGE_Start() IImage: Utilização 1. Obtenha uma instância da interface que contenha o BMP a ser mostrado • ISHELL_LoadResImage(), caso a imagem esteja no arquivo de recursos • ISHELL_LoadImage(), para ler diretamente do arquivo 2. Desenhe a imagem na tela • IIMAGE_Draw(), sem animação • IIMAGE_Start() e IIMAGE_Stop(), com animação 3. Libere a interface IImage: Exemplo Imagem simples IImage * pImage; pImage = ISHELL_LoadResImage(.....); IIMAGE_Draw(pIMage,x,y); Cria a interface e carrega a imagem do arquivo de recursos Desenha a imagem Com animação IImage * pImage; pImage = ISHELL_LoadResImage(.....); Separa a imagem em frames de largura “cxFrame” IIMAGE_SetParm( pImage,IPARM_CXFRAME,cxFrame,0 ); IIMAGE_Start(pImage,10,10); Inicia a animação IIMAGE_Stop(pImage); Pára a animação Inserindo Imagens no Arquivo de Recursos • Prática... Exercício 2 • Altere o código do exercício 2 para que os números apresentados na tela sejam imagens – Utilize a função ISHELL_LoadResImage() para carregar a imagem – Não esqueça de liberar a imagem no final! IIMAGE_Release() – A função IIMAGE_SetParm() permite indicar o número de frames de uma imagem Dialogs e Controls • Controls são componentes de entrada e saída – Menus, text boxes, listas, controle de teclas, etc. • Dialogs são frames que contêm controls • Dialogs podem ser criados de duas formas – Via BREW Resource Editor (fazendo parte do BRI) – Construídos programaticamente no código da IDialog • Permite o acesso a controls • Possui dois métodos principais – IDIALOG_GetControl() • Obtém um ponteiro para componentes de menu, texto, data ou tempo pertencentes ao dialog – IDIALOG_SetFocus() • Determina o control que receberá o foco para entrada do usuário IControl • Interface abstrata implementada por todos os controls BREW • Exemplos de controls – IDateCtl: campo de data – IMenuCtl: componente de menu – ITextCtl: entrada de texto – ITimeCtl: campo de hora Criando Dialogs e Controls com o Resource Editor • O BREW Resource Editor suporta a criação e configuração de dialogs e diversos controls Posição na tela e tamanho ID e nome do recurso ID do control que receberá o foco inicial Flags que determinam a aparência do dialog Tipos de controls suportados Tipos de Controls Exercício 3 • Crie um menu com dois itens no BREW Resource Editor e apresente na tela no início da aplicação – Dica 1: Para que o dialog seja reconhecido pelo ambiente é necessário tratar os eventos (pelo menos retornar TRUE) • EVT_DIALOG_START • EVT_DIALOG_INIT • EVT_DIALOG_END – Dica 2: Para que o componente apareça inicialmente é preciso chamar BREW Recursos de Som ISound • Fornece serviços básicos de som – Bips, ring tones, vibração • Permite ajuste de volume • Pode encapsular um conjunto de tones que podem ser tocados por um período contínuo • Tones possuem formato WAV e são referenciados por IDs únicos ISound: Funções Principais void ISOUND_RegisterNotify(ISound * pISound, PFNSOUNDSTATUS pfn, const void * pUser) – Registra a função de callback para notificações int ISOUND_Set(ISound * pISound, const AEESoundInfo * pSoundInfo) – Permite ajustar os atributos do dispositivo – Device, Method, Ear-piece Mute Control e Microphone Mute Control ISound: Mais Funções Principais void ISOUND_PlayTone(ISound * pISound, AEESoundToneData toneData) – Toca um tone por um determinado período de tempo void ISOUND_StopTone(ISound * pISound) – Para a reprodução do tone corrente ou finaliza o playback de uma lista de tones void ISOUND_Vibrate(ISound * pISound, uint16 w6Duration) – Ativa a vibração do dispositivo – A chamada a esta função no emulador reproduz um ISound: Utilização 1. Crie uma instância de ISound • ISHELL_CreateInstance() • ClassID: AEECLSID_SOUND 2. Registre a função de callback • ISOUND_RegisterNotify() • Caso não queira notificações • ISOUND_RegisterNotify(pISound, NULL, NULL) 3. Ajuste os parâmetros • ISOUND_Set() 4. Reproduza sons ou vibrações • ISOUND_Play() ou ISOUND_Vibrate() ISound: Exemplo ISound * pISound; AEESoundInfo sInfo; AEESoundToneData tone; ISHELL_CreateInstance(pMe->pIShell, AEECLSID_SOUND, &pISound); ISOUND_RegisterNotify(pMe->pISound, NULL, NULL); ... sInfo.eDevice = AEE_SOUND_DEVICE_CURRENT; sInfo.eMethod = AEE_SOUND_METHOD_RING; tone.eTone = AEE_TONE_1; tone.wDuration = 100; ISOUND_Set(pMe->pISound, &sInfo); ISOUND_PlayTone(pMe->pISound, tone); ISoundPlayer • Provê serviços de áudio multimídia – MIDI, MP3 e QCP (Qualcomm PureVoice) • Possui controles de playback avançados – Pause, resume, rewind, forward • Pode reproduzir sons carregados na memória ou diretamente de arquivos Playback só é possível para sons alocados em buffer na memória! ISoundPlayer: Funções Principais void ISOUNDPLAYER_RegisterNotify( ISoundPlayer * pISoundPlayer, PFNSOUNDPLAYERSTATUS pfn, void * pUser) – Registra a função de callback para receber eventos de status int ISOUNDPLAYER_SetInfo(ISoundPlayer * pISoundPlayer, AEESoundPlayerInfo * pInfo) – Permite indicar a fonte de áudio (arquivo/buffer) void ISOUNDPLAYER_Play(ISoundPlayer * ISoundPlayer: Mais Funções Principais void ISOUNDPLAYER_Stop(ISoundPlayer * pISoundPlayer) – Envia um comando para parar o playback atual void ISOUNDPLAYER_Rewind(ISoundPlayer * pISoundPlayer, uint32 dwTime) – Realiza o retorno de um determinado período na trilha atual void ISOUNDPLAYER_Pause(ISoundPlayer * pISoundPlayer) – Faz uma pausa na reprodução void ISOUNDPLAYER_FastForward( ISoundPlayer: Utilização 1. Crie uma instância de ISoundPlayer • • ISHELL_CreateInstance() ClassID: AEECLSID_SOUNDPLAYER 2. Registre a função de callback • ISOUNDPLAYER_RegisterNotify() 3. Indique a fonte da mídia • • Se arquivo ou buffer ISOUNDPLAYER_SetInfo() 4. Utilize os controles de playback para reprodução 5. Ao final • Remova o registro da função de callback ISoundPlayer: Exemplo ISoundPlayer *pISPlayer; AEESoundPlayerInfo pinfo; AEESoundPlayerInput input; ISHELL_CreateInstance(pMe->pIShell, AEECLSID_SOUNDPLAYER, &pISPlayer); ISOUND_RegisterNotify(pISPlayer, NULL, NULL); pinfo.eInput = SDT_FILE; pinfo.pData = "piano.mp3"; ISOUNDPLAYER_SetInfo(pMe->pISPlayer, &pinfo); ISOUNDPLAYER_Play(pMe->pISPlayer); ... ISOUNDPLAYER_Stop(pMe->pISPlayer); Exercício 4 • Crie uma aplicação que, ao se pressionar as teclas numéricas, realize as seguintes operações Tecla 1 2 3 4 Operação Tocar um tone qualquer por 200ms Iniciar a reprodução do mp3 “piano.mp3” Iniciar a reprodução do midi “canyon.mid” Parar a reprodução atual IMedia (BREW 2.0) • Interface abstrata que define os serviços básicos de todos os objetos multimídia em BREW – IMediaMIDI, IMediaMP3, ... • Objetos multimídia podem conter combinações de audio, vídeo e texto • IMedia oferece suporte para playback e gravação como seek, stop, pause e resume IMedia: Máquina de Estados • Máquina de estados básica IMedia Formats • As seguintes interfaces derivam de IMedia – IMediaMIDI: toca o formato MIDI padrão – IMediaMIDIOutMsg: toca mensagens MIDI – IMediaMIDIOutQCP: toca arquivos QCP (PureVoice) usando o dispositivo MIDI – IMediaMP3: toca o formato MP3 – IMediaQCP: toca e grava o formato QCP – IMediaPMD: toca o formato PMD que inclui áudio e vídeo sincronizados BREW Arquivos Sistemas de Arquivos • Dispositivos móveis não contêm sistemas de arquivos convencionais e sim EFSs • Não existe o conceito de drive – Não se pode especificar o drive no path – Isto vale também para o emulador • Arquivos são abertos a partir do diretório do módulo • O número máximo de arquivos a serem criados e o espaço ocupado podem ser restringidos no MIF – “Max Files” e “Max Space” IFile • Permite ler e modificar o conteúdo de arquivos • Instâncias de IFile são retornadas pela função IFILEMGR_OpenFile() • Para modificação do conteúdo a aplicação precisa ter os privilégios “File” ou “All” IFile: Funções Principais int IFILE_GetInfo(IFile * pIFile, FileInfo * pInfo) – Obtém informações como data de criação, tamanho, nome e atributos do arquivo int32 IFILE_Read(IFile * pIFile, void * pBuffer, uint32 dwCount) – Lê um determinado número de bytes de um arquivo aberto uint32 IFILE_Write (IFile * pIFile, PACKED const void * pBuffer, uint32 dwCount) – Escreve uma determinada quantidade de bytes em IFile: Utilização 1. Para criar instâncias de IFile • • IFILEMGR_OpenFile(), pode abrir ou criar um arquivo Retorna um ponteiro para IFile 2. Se necessário, posicione o cursor para leitura ou escrita • IFILE_Seek() 3. Leia ou escreva • IFILE_Read ou IFILE_Write() 4. Quando completar a operação feche o arquivo • IFILE_Release() IFileMgr • Possibilita a criação, remoção e renomeação de arquivos e diretórios • Lembrar que – Nomes de arquivos e diretórios em BREW não são case sensitive – O tamanho máximo do path no dispositivo é 64 • No emulador é 256 IFileMgr: Funções Principais IFile * IFILEMGR_OpenFile(IFileMgr * pIFileMgr, const char * pszFile, OpenFile mode) – Abre arquivos em um determinado modo (leitura/escrita) int IFILEMGR_MkDir(IFileMgr * pIFileMgr, const char * pszDir) – Permite a criação de diretórios no sistema de arquivos int IFILEMGR_RmDir(IFileMgr * pIFileMgr, const char * pszDir) IFileMgr: Mais Funções Principais int IFILEMGR_Rename(IFileMgr * pIFileMgr, const char * pszSrc, const char * pszDest) – Renomeia um arquivo int IFILEMGR_Remove(IFileMgr * pIFileMgr, const char * pszName) – Remove um dado arquivo do sistema int IFILEMGR_Test(IFileMgr * pIFileMgr, const char * pszName) – Testa se o arquivo ou diretório existe Arquivos: Exemplo IFileMgr * pIFileMgr; if (ISHELL_CreateInstance(pIShell, AEECLSID_FILEMGR, (void **)&pIFileMgr) == SUCCESS) { IFile * pIFile; if (IFILEMGR_Test(pIFileMgr, "arquivo.txt") != SUCCESS) { pIFile = IFILEMGR_OpenFile(pIFileMgr, "arquivo.txt", _OFM_CREATE); } else { pIFile = IFILEMGR_OpenFile(pIFileMgr, "arquivo.txt", _OFM_APPEND); } ... Arquivos: Exemplo ... if (pIFile != NULL) { char timestamp[30]; SPRINTF(timestamp, “seu texto"); IFILE_Write(pIFile, timestamp, STRLEN(timestamp)); IFILE_Write(pIFile, "\r\n", 2); IFILE_Release(pIFile); } IFILEMGR_Release(pIFileMgr); } Exercício 5 • Escreva uma aplicação que registra um log das teclas numéricas e direcionais pressionadas pelo usuário durante sua utilização – Não esqueça de liberar o arquivo antes de sair da aplicação! IDBMgr • Possibilita a criação, abertura e remoção de bases de dados • A aplicação precisa ter os privilégios “File” ou “All” para ter acesso às funcionalidades de Banco de Dados • Após a abertura, usa-se as funções da interface IDatabase para criar e recuperar registros e IDBRecord para atualizar os campos individuais IDBMgr: Funções Principais • IDatabase * IDBMgr_OpenDatabase ( IDBMgr * pIDBMgr, const char * fileName,boolean bCreate) – Abre um banco de dados. – TRUE, indica que vai ser criada, caso não exista • int IDBMgr_Remove(IDBMgr * pIDBMgr, const char * fileName) – Remove o banco especificado por fileName – O banco especificado deve ter sido liberado através de IDatabase_Release() antes de ser removido. – Retorna código de erro, caso o banco não seja encontrado IDatabase • Representa a base de dados. Possui métodos para adicionar e remover registros, bem como navegar pelos registros. IDatabase: Funções Principais • void IDATABASE_Reset(IDatabase * pIDatabase) – Traz o ponteiro da base para a primeira posição • IDBRecord * IDATABASE_CreateRecord( IDatabase * pIDatabase, AEEDBField * fields, int nFields ) – Cria um registro na base, contendo os campos indicados por fields – nFields : Número de campos no registro • IDBRecord * IDATABASE_GetNextRecord(IDatabase * IDatabase: Mais funções • IDBRecord * IDATABASE_GetRecordByID ( IDatabase * pIDatabase, uint16 id ) – Retorna o registro que contém o id especificado no parâmetro • uint32 IDATABASE_GetRecordCount(IDatabase * pIDatabase) – Retorna a quantidade de registros presentes na tabela IDatabase: Criando a base e adicionando registros IDBMgr pDBMgr; IDBMgr pDB; ISHELL_CreateInstance(m_pIShell, AEECLSID_DBMGR, &pDBMgr); pDB = IDBMGR_OpenDatabase(pMe->pDBMgr, "DBALUNO", TRUE); // adiciona os alunos addRecord(pDB, 3, "Marcos"); addRecord(pDB, 5, "Janaína"); // libera o banco IDATABASE_Release(pDB); // libera o DBMgr IDBMGR_Release(pDBMgr); IDatabase: Adição de registros void addRecord(IDatabase* pDB, uint16 id, char* name) { AECHAR cName[512]; STRTOWSTR(name, cName, sizeof(cName)); AEEDBField fields[2]; fields[0].fName = AEEDBFIELD_PREF_ID; fields[0].fType = AEEDB_FT_WORD; fields[0].pBuffer = &id; fields[0].wDataLen = sizeof(uint16); fields[1].fName = AEEDBFIELD_FULLNAME; fields[1].fType = AEEDB_FT_STRING; fields[1].pBuffer = cName; fields[1].wDataLen = WSTRLEN(cName) * sizeof(AECHAR); // grava a entrada no banco IDATABASE_CreateRecord(pDB, fields, 2); } IDatabase: Imprimindo todos void imprimirTodos() { IDBRecord* rec; AEEDBField field; pDB = IDBMGR_OpenDatabase(pMe->pDBMgr, "DBALUNO", FALSE); IDATABASE_Reset(pDB); rec = IDATABASE_GetNextRecord(pDB); while (rec) { // os dados do campo ficam registrados em field.pBuffer IDBRECORD_NextField(rec, &field.fName, &field.wDataLen); field.pBuffer = IDBRECORD_GetField(rec, &field.fName, &field.fType, &field.wDataLen); DBGPRINTF("Aluno (%s): ", field.pBuffer); rec = IDATABASE_GetNextRecord(pDB); } } IDatabase: Utilização 1. Obter uma instancia através de IDBMGR_OpenDataBase TRUE indica que a base irá ser criada 2. Traz o ponteiro para o primeiro registro IDATABASE_Reset() 3. Ler os registros através de IDATABASE_GetNextRecord 4. Escrever através de IDATABASE_CreateRecord Usar IDBRecord AEEDBField 5. Liberar a base de dados IDATABASE_Release BREW Rede Suporte a Rede em BREW • O ambiente BREW fornece a infraestrutura básica para comunicação via rede – Conexão com Sockets – Segurança com SSL • Interfaces – INetMgr: gerenciamento de rede – ISocket: manipulação de sockets – ISSL: segurança INetMgr • Fornece mecanismos acessar o subsistema de rede do dispositivo – Obtenção de IP remoto e local – Status da conexão PPP – Ajuste de parâmetros da conexão • Dá suporte a criação de sockets para transmissão de pacotes TCP e UDP ISocket • Permite conectar, transmitir e receber dados através de conexões UDP e TCP • A aplicação precisa de privilégio de “Network” ou “All” Lembre que BREW não tem suporte a threads! Chamadas de bloqueio são implementadas com um abordagem de notificação via callbacks ISocket: Algumas Funções int ISOCKET_Connect(ISocket * pISocket, INAddr a, INPort wPort, PFNCONNECTCB pfn, void * pUser) – Tenta iniciar uma conexão TCP com o endereço especificado para sockets do tipo AEE_SOCK_STREAM – Para sockets do tipo AEE_SOCK_DGRAM o endereço é associado ao socket para escritas subseqüentes int32 ISOCKET_Read(ISocket * pISocket, byte * pbDest, uint16 wSize) – Lê dados de um socket para um buffer local ISocket: Mais Algumas Funções void ISOCKET_Writeable(ISocket * pISocket, PFNNOTIFY pfn, void * pUser) – Permite registrar uma função de callback quando uma operação de escrita não bloqueante estiver sendo realizada void ISOCKET_Readable(ISocket * pISocket, PFNNOTIFY pfn, void * pUser) – Permite registrar uma função de callback quando uma operação de leitura não bloqueante (Read, ReadV, RecvFrom) estiver sendo realizada ISocket: Abrindo um socket • Conectando um socket através de um struct _CSocketsApplet { DNS ... INetMgr * m_pINetMgr; ISocket * m_pISocket; AEECallback m_cb; // Callback para DNS AEEDNSResult m_dnsr; // Info do DNS } SocketsApplet; ... static void StartConection(SocketsApplet * pApp) { pApp->m_pISocket = INETMGR_OpenSocket(pApp->m_pINetMgr, AEE_SOCK_STREAM); CALLBACK_Init(&pApp->m_cb, TCPDNSConnect, pApp); INETMGR_GetHostByName(pApp->m_pINetMgr,&pApp->m_dnsr, “www.host.com”,&pApp->m_cb); } ISocket: Conectando static void TCPDNSConnect(void * pApp) { int nErr = pApp ->m_dnsr.nResult; if (nErr > AEEDNSMAXADDRS) { // Falha no lookup ReleaseSocket(pApp); return; } nErr = ISOCKET_Connect(pApp->m_pISocket, //socket pApp->m_dnsr.addrs[0],//endereco 0x700, //porta TCPConnected, //callback pApp); if (nErr != AEE_NET_SUCCESS) { // Falha na conexao ReleaseSocket(pApp); } else { // conectando... } } ISocket: Conectado static void TCPConnected(void *pApp, int nErr) { if ((nErr == AEE_NET_SUCCESS) || (nErr == AEE_NET_EISCONN)) { //Socket conectado! //Pode escrever... } else { // Falha na conexao ReleaseSocket(pApp); } } ISocket: Exemplo: Escrevendo um array de bytes void WriteSocket(void *pApp) { char *psz = NULL; int cbWrite, rv; ... // pszData e’ um ponteiro para os dados a serem escritos psz = pszData; cbWrite = STRLEN(pszData); while (cbWrite > 0) { rv = ISOCKET_Write(pApp ->m_pISocket, (byte *)psz, (uint16)cbWrite); ... ISocket: Exemplo: Escrevendo um array de bytes ... // se nenhum byte foi escrito com sucesso if (rv == AEE_NET_WOULDBLOCK) { // regista a funcao de callback para tentar depois ISOCKET_Writeable(pApp ->m_pISocket, WriteSocket, (void*) pApp); return; } else if (rv == AEE_NET_ERROR) {// erro de escrita ReleaseSocket(pApp); return; } // se escreveu uma parte, continua o loop cbWrite -= rv; psz += rv; } ISSL • Fornece segurança SSL/TLS para conexões de rede • Usada em conjunto com a interface ISocket • Combinada com http, possibilita https na interface IWeb BREW Extensão da API API Extensível • O ambiente BREW permite que a API seja estendida com novas funcionalidades • Similar ao desenvolvimento de aplicações • A extensão precisa expor a tabela de funções virtuais para classes externas • É necessário – Declarar as interfaces – Definir as classes – Implementar as funções Declarando Interfaces • Vamos definir uma extensão “Hello” que define uma função para mostrar uma mensagem na tela • Chamaremos nossa interface de IHelloCls • Para declaração da interface utiliza-se a macro QINTERFACE() QINTERFACE(IHelloCls) { INHERIT_IBASE(IHelloCls) int (*DrawHello)(IHelloCls * po, AEEPoint ptXYOffset); }; Macros de Acesso • As seguintes macros de acesso a tabela virtual são definidas #define IHELLOCLS_AddRef(p) \ GET_PVTBL(p,IHelloCls)->AddRef(p) #define IHELLOCLS_Release(p) \ GET_PVTBL(p,IHelloCls)->Release(p) #define IHELLOCLS_DrawHello(p,ptC) \ GET_PVTBL(p,IHelloCls)->DrawHello(p,ptC) • Duas funções extras são expostas – AddRef() e Release() – Derivadas da interface IBase através da macro INHERIT_IBASE() • Use INHERIT_XXX onde XXX é o nome da interface a ser estendida Equivalente C++ • O método anterior equivale a seguinte declaração C++ class IHelloCls : public IBase { int DrawHello(IHelloCls * po, AEEPoint ptXYOffset); } • Por limitações no compilador ARM, não é possível declarações deste tipo Definindo Classes • Após a definição da interface, é necessária sua implementação typedef struct _HelloCls { DECLARE_VTBL(IHelloCls) Declaração da tabela. Ponteiros para funções no início da estrutura // Variaveis da classe Uint32 m_nRefs;// Referencias pra mim IShell *m_pIShell;// copia do ponteiro para o shell IDisplay *m_pIDisplay;// ponteiro para o display IModule *m_pIModule;// ponteiro para o modulo } HelloCls; Implementando as Funções • As funções são implementadas normalmente como funções C • As funções AddRef() e Release() são responsáveis pela contagem de referências e limpeza da memória • DrawHello() realiza a funcionalidade da extensão • Uma função adicional é necessária em extensões da API – AEEClsCreateInstance() AEEClsCreateInstance() • Função responsável por criar uma instância da classe • Precisa chamar uma operação new específica da classe a ser definida pelo programador • Supondo que nossa operação new tem o nome HelloCls_New, ela deveria possuir a int HelloCls_New(int16 nSize, IShell *pIShell, IModule* pIModule, IModule ** ppMod); seguinte assinatura: Operação New • A função new deve realizar as seguintes operações – Alocação de memória – Inicialização da tabela virtual – Inicialização dos membros de classe – Incialização de outros códigos • O retorno da função indica se a operação foi realizada com sucesso Alocação de Memória • A área de memória para a classe precisa ser alocada VTBL(IHelloCls) * modFuncs; //tabela virtual if(!ppMod || !pIShell || !pIModule) return EFAILED; *ppMod = NULL; if(nSize < sizeof(HelloCls)) nSize += sizeof(HelloCls); //alocacao de memoria para o objeto HelloCls if((pMe = (HelloCls *) MALLOC(nSize + sizeof(VTBL(IHellCls)))) == NULL ) return ENOMEMORY; Inicialização da Tabela • Após a alocação, a tabela precisa apontar para as funções corretas modFuncs = (IHelloClsVtbl *)((byte *)pMe + nSize); //inicializa as entradas individuais na VTBL modFuncs->AddRef = HelloCls_AddRef; modFuncs->Release = HelloCls_Release; modFuncs->DrawHello = HelloCls_DrawHello; // inicializa a tabela INIT_VTBL(pMe, IModule, *modFuncs); Inicialização dos Membros de Classe • Após a inicialização da tabela, realiza-se a inicialização dos membros de classe • Note que o número de referências é iniciado com o valor 1 pMe->m_nRefs = 1; pMe->m_pIShell = pIShell; pMe->m_pIModule = pIModule; Outras Inicializações • Toda classe precisa incrementar o contador de referências para ISHELL e ISHELL_AddRef(pIShell); IMODULE IMODULE_AddRef(pIModule); //acesso a IDisplay if(ISHELL_CreateInstance(pIShell, AEECLSID_DISPLAY, (void **)&pMe->m_pIDisplay) = SUCCESS) return EFAILED; // coloca o ponteiro no parametro *ppMod = (IModule*)pMe; return AEE_SUCCESS; Utilização da Extensão • Após os passos anteriores, outras aplicações podem criar instâncias da extensão chamando if((ISHELL_CreateInstance(pMe->m_pIShell, ISHELL_CreateInstance() AEECLSID_HELLO_CLS, (void **)&pHelloCls))!=SUCCESS) return FALSE; IHELLOCLS_DrawHello(pHelloCls,ptHello); IDISPLAY_Update(pMe->m_pIDisplay); IHELLOCLS_Release(pHelloCls); Acesso a Extensões Applet IHelloCls VTBL AddRef Release Macros DrawHello IHELLOCLS_AddRef IHELLOCLS_Release HelloCls_AddRef(){ } IHELLOCLS_DrawHello HelloCls_Release(){ } HelloCls_DrawHello() { } Referências 1. 2. 3. 4. 5. BREW SDKTM User’s Guide BREW SDKTM API Reference BREW Online Help http://brew.qualcomm.com Murray Bonner. What is BREW? Disponível em http://www.developer.com/ws/brew/article .php/1454711 <Título> • Itens