AllJoyn™ Android C++ Sample Programs Walkthrough 80-BA017-1 Rev. A
Transcription
AllJoyn™ Android C++ Sample Programs Walkthrough 80-BA017-1 Rev. A
AllJoyn™ Android C++ Sample Programs Walkthrough 80-BA017-1 Rev. A June 21, 2011 Submit technical questions at: http://www.alljoyn.org/forums The information contained in this document is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License; provided, that (i) any source code incorporated in this document is licensed under the Apache License version 2.0 AND (ii) THIS DOCUMENT AND ALL INFORMATION CONTAINED HEREIN ARE PROVIDED ON AN “AS-IS” BASIS WITHOUT WARRANTY OF ANY KIND. Creative Commons Attribution-ShareAlike 3.0 Unported License AllJoyn is a trademark of Qualcomm Innovation Center, Inc. Other product and brand names may be trademarks or registered trademarks of their respective owners. This technical data may be subject to U.S. and international export, re-export, or transfer (“export”) laws. Diversion contrary to U.S. and international law is strictly prohibited. Qualcomm Innovation Center, Inc. 5775 Morehouse Drive San Diego, CA 92121-1714 U.S.A. Copyright © 2011, Qualcomm Innovation Center, Inc., All rights not expressly granted are reserved. Contents 1 Introduction...................................................................................................... 4 1.1 Scope................................................................................................................................... 4 1.2 Audience .............................................................................................................................. 4 1.3 Prerequisites ........................................................................................................................ 4 1.4 Revision history ................................................................................................................... 5 1.5 Related documents.............................................................................................................. 5 1.6 Acronyms and abbreviations ............................................................................................... 5 2 SimpleService .................................................................................................. 6 2.1 Definition .............................................................................................................................. 6 2.2 Building SimpleService ........................................................................................................ 6 2.2.1 Building ‘libSimpleService.so’ using NDK .................................................................. 6 2.2.2 Building ‘SimpleService.apk’ using Eclipse ............................................................... 7 2.3 Installing SimpleService on device ...................................................................................... 7 2.4 SimpleService walkthrough ................................................................................................. 7 3 SimpleClient ................................................................................................... 10 3.1 Definition ............................................................................................................................ 10 3.2 Building and installing SimpleClient .................................................................................. 10 3.3 SimpleClient walkthrough .................................................................................................. 10 4 Running SimpleService and SimpleClient................................................... 13 5 Code Download ............................................................................................. 14 6 AllJoynChat.................................................................................................... 15 6.1 Building and installing AllJoynChat ................................................................................... 15 6.2 Running AllJoynChat ......................................................................................................... 15 6.3 AllJoynChat walkthrough ................................................................................................... 16 6.4 Code download .................................................................................................................. 18 80-BA017-1 ii Qualcomm Innovation Center, Inc. MAY CONTAIN U.S. AND INTERNATIONAL EXPORT CONTROLLED INFORMATION AllJoyn™ Android C++ Sample Programs Walkthrough Contents Tables Table 1-1. Revision history .............................................................................................................. 5 Table 1-1. Related documents ......................................................................................................... 5 80-BA017-1 iii Qualcomm Innovation Center, Inc. MAY CONTAIN U.S. AND INTERNATIONAL EXPORT CONTROLLED INFORMATION 1 Introduction 1.1 Scope This document describes how to use the Android® AllJoyn distribution to install and run the following sample applications on a Nexus One phone: SimpleService SimpleClient AllJoynChat is an AllJoyn service which provides an object with a single method named Ping. The method accepts a string value as an argument and returns the string as its return value. SimpleService SimpleClient is an AllJoyn client which invokes the Ping method in SimpleService. AllJoynChat is a peer-to-peer chat application that enables one AllJoynChat application to broadcast messages to all AllJoynChat applications in a particluar session, where a session can be point-to-point or multipoint, running on the distributed bus. All of these samples are intended to demonstrate how to use the C++ API for AllJoyn. Since Android applications are written in Java, the samples all make JNI calls into C++ code before invoking AllJoyn functions. If this were not the case, the samples could be written entirely in Java using the AllJoyn Java binding. 1.2 Audience This guide is for developers who plan to create C++ based AllJoyn-enabled applications on Android. 1.3 Prerequisites This guide assumes that you have set up the development environment as described in the AllJoyn Android Environment Setup Guide. 80-BA017-1 4 Qualcomm Innovation Center, Inc. MAY CONTAIN U.S. AND INTERNATIONAL EXPORT CONTROLLED INFORMATION AllJoyn™ Android C++ Sample Programs Walkthrough Contents 1.4 Revision history Table 1-1 provides the revision history for this document. Table 1-1. Revision history Version Date Description A June 2011 Initial release 1.5 Related documents Table 1-2 is a list of supplemental documents and downloads that relate to the information in this guide. Table 1-2. Related documents Location Title www.alljoyn.org Introduction to AllJoyn www.alljoyn.org Guide to AllJoyn Development Using the Java SDK www.alljoyn.org AllJoyn Android Environment Setup Guide www.alljoyn.org C++ API Reference Manual www.alljoyn.org AllJoyn SDK www.alljoyn.org Source Code 1.6 Acronyms and abbreviations ADT Android Development Tools API Application Programming Interface APK Android Package JNI Java Native Interface NDK Native Developers Kit 80-BA017-1 5 Qualcomm Innovation Center, Inc. MAY CONTAIN U.S. AND INTERNATIONAL EXPORT CONTROLLED INFORMATION 2 SimpleService 2.1 Definition The AllJoyn SimpleService has these properties: This service accepts a well-known name from a user and appends it to the prefix org.alljoyn.bus.samples.simple. For example, if the user enters Joe as the wellknown name in the dialog box, SimpleService obtains the well-known name org.alljoyn.bus.samples.simple.Joe. The service provides a single object with the path /simpleservice. The object implements the interface org.alljoyn.bus.samples.simple. The interface defines a single method named Ping. The method accepts a single string as an input argument and returns the same string as its return value. 2.2 Building SimpleService The SimpleService sample is built in two steps: 1. Build the C++ shared library file libSimpleService.so using the Android Native Development Kit (NDK). 2. Build the Java wrapper for SimpleService and package the result in an Android package (APK) file, using Eclipse and the Android Development Tools (ADT) Eclipse plug-in. 2.2.1 Building ‘libSimpleService.so’ using NDK 1. Change the current directory to alljoyn_dir/samples/simple/service/android 2. Compile the code with the following command: ndk-build 80-BA017-1 6 Qualcomm Innovation Center, Inc. MAY CONTAIN U.S. AND INTERNATIONAL EXPORT CONTROLLED INFORMATION AllJoyn™ Android C++ Sample Programs Walkthrough SimpleService 2.2.2 Building ‘SimpleService.apk’ using Eclipse Once libSimpleService.so is built, build the Android APK using Eclipse. 1. In Eclipse, under Project select the Build Automatically option. 2. Select File->Import. a. Expand General and, select Existing Projects into workspace. a. Select the root directory option and browse to: alljoyn_dir/samples/simple/service b. Click Finish. The sample builds automatically. Note : If you get an error “Unable to find class R,” you should try to refresh the project. Sometimes Eclipse does not detect the autogenerated files and throws this error. 3. For both projects the Project Build target must be at least Android 2.2. To change the target, right-click SimpleService, select Properties, then select the Android tab, and finally select Android 2.2 or higher. Click OK to finish. 2.3 Installing SimpleService on device After building the project, the file SimpleService.apk is located under: alljoyn_dir/samples/simple/service/bin/SimpleService.apk Install this file using the following adb command: adb install SimpleService.apk Alternatively, you can install the sample from within Eclipse by right-clicking the SimpleService project and selecting RunAs->Android Application. If you have multiple devices connected to your machine, a window pops up asking for the device on which you want to install the apk file. 2.4 SimpleService walkthrough SimpleService implements an AllJoyn attachment which creates a single bus object with the object path /simpleService. The bus object implements the interface org.alljoyn.bus.samples.simple, which defines a single method named Ping. Ping accepts a single input argument (a string) and returns a single output argument (a string). The behavior of Ping is to simply return the input string as output. SimpleService requests a well-known name (org.alljoyn.bus.samples.simple.<user entered name>) for its attachment from the bus. This allows any number of SimpleClient instances to locate the SimpleService attachment by looking for services with the prefix org.alljoyn.bus.samples.simple and invoking the Ping method on the object with path /simpleService. Because all Android third-party applications are written in Java, SimpleService has both a Java side and a native (C/C++) side implemented using the Java Native Interface 80-BA017-1 7 Qualcomm Innovation Center, Inc. MAY CONTAIN U.S. AND INTERNATIONAL EXPORT CONTROLLED INFORMATION AllJoyn™ Android C++ Sample Programs Walkthrough SimpleService (JNI). The Java side of the sample does nothing more than present the user interface. All AllJoyn operations are implemented in the JNI code. The JNI code for SimpleService is found in the file: samples/simple/service/android/jni/Service_jni.cpp This file defines four JNI calls: Java_org_alljoyn_bus_samples_simpleservice_Service_simpleOnCreate() Called when the application starts up. This method is responsible for creating an AllJoyn attachment. Java_org_alljoyn_bus_samples_simpleservice_Service_startService() This method connects to the bus, registers the bus listener, registers the AllJoyn object, requests the well known name entered by the user, creates a session using BindSession and advertises the well known name if the the requested well known name was available. Java_org_alljoyn_bus_samples_simpleservice_Service_stopService() The UI on simple service provides two buttons: ‘Start’ and ‘Stop’. When we press ‘Stop’ this method is called. It deletes the current reference to the AllJoyn object implementing the SimpleService. If you enter a new well known name to be advertised a new AllJoyn object is created with the new well known name. Java_org_alljoyn_bus_samples_simpleservice_Service_simpleOnDestroy() Called when the application is exiting. This method is responsible for cleaning up the AllJoyn object and bus attachment before the application exits. org.alljoyn.bus.samples.simpleservice.Service.PingCallback() A third method – named org.alljoyn.bus.samples.simpleservice.Service. PingCallback(), and implemented in Java – is used as a callback from JNI into Java. This callback is called from within the bus object method handler for org.alljoyn.bus. samples.simple.Ping() whenever the method is called from some remote device. It reports the ping string value and the name of the bus attachment that made the method call for display on the SimpleService UI. In addition to the two JNI functions described above, Service_jni.cpp defines and implements the AllJoyn bus object that responds to remote method invocations directed at the object /simpleService. This C++ object is named ServiceObject, and derives from ajn::BusObject. ServiceObject's constructor does two things: 1. Declare that ServiceObject implements the interface org.alljoyn.bus.samples.simple 2. Define the mapping between the methods of org.alljoyn.bus.samples.simple and SimpleObject (e.g., register the method handlers) 80-BA017-1 8 Qualcomm Innovation Center, Inc. MAY CONTAIN U.S. AND INTERNATIONAL EXPORT CONTROLLED INFORMATION AllJoyn™ Android C++ Sample Programs Walkthrough SimpleService An instance of ServiceObject is created and registered with the bus attachment in the Java_org_alljoyn_bus_samples_simpleservice_Service_startservice() JNI call (which is described above). Once the object is registered and the attachment is connected to the bus, AllJoyn calls the bus object's ObjectRegistered() callback. This callback provides ServiceObject with the opportunity to perform any operations that can only be done when fully connected to the bus. Once the object is registered, the service requests a well-known name by calling the synchronous RequestName method. After a well-known name is acquired by the service on the bus, we bind the service to a session port by calling BusAttachment::BindSesssionPort(). This method takes in session opts, which is a set of options specifying the way the service wants the session to be handled, e.g., the type of traffic the session will deal with, what transport the session can use, and the proximity type. Now that we are ready with our service having acquired a well-known name and we have bound a port to a particular session, we can advertise the well-known name to the world. This is done by calling BusAttachment::AdvetiseName(). This method takes in the name that you want to advertise and the transports on which you want to advertise the name. The Ping method handler ServiceObject::Ping() is the most interesting method defined in ServiceObject. Each time a remote bus attachment invokes the Ping method of the object /simpleService in the attachment named org.alljoyn.bus.samples.simple, this method is invoked by AllJoyn. In the case of this sample, the behavior is to get the single string argument to Ping from the incoming message, and return it as the result to the remote caller. In addition, this handler notifies the Java UI that a ping message was processed by calling the Java method PingCallback() (which is implemented in Service.java). 80-BA017-1 9 Qualcomm Innovation Center, Inc. MAY CONTAIN U.S. AND INTERNATIONAL EXPORT CONTROLLED INFORMATION 3 SimpleClient 3.1 Definition SimpleClient is an AllJoyn client with the following properties: It accesses the service org.alljoyn.bus.samples.simple using the well-known name of the service. It accesses the service object with the object path /simpleservice. It invokes the method named Ping to send ping string to the service. 3.2 Building and installing SimpleClient SimpleClient is built and installed in exactly the same way as SimpleService (see Sections 2.2 and 2.3). The base directory for SimpleClient is: alljoyn_dir/samples/simple/android/client 3.3 SimpleClient walkthrough In SimpleClient, the UI is initially blank with a text box. Internally, when the client starts up, it looks for a service with a fixed prefix. When it finds such a service, the UI is updated with the name of the service and two buttons to connect/disconnect or send a ping to the service, if connected. SimpleClient implements an AllJoyn attachment, which attempts to contact a remote bus attachment (named org.alljoyn.bus.samples.simple) and invoke the Ping method of the remote object that has the object path /simpleService within that attachment. Because all Android third-party applications are written in Java, SimpleClient has both a Java side and a native (C/C++) side implemented using the Java Native Interface (JNI). The Java side of the sample does nothing more than present the user interface. All AllJoyn operations are implemented in the JNI code. The JNI code for SimpleClient is found in the file: samples/simple/android/client/jni/Client_jni.cpp 80-BA017-1 10 Qualcomm Innovation Center, Inc. MAY CONTAIN U.S. AND INTERNATIONAL EXPORT CONTROLLED INFORMATION AllJoyn™ Android C++ Sample Programs Walkthrough SimpleClient This file defines five JNI calls: Java_org_alljoyn_bus_samples_simpleclient_Client_simpleOnCreate() Called when the Java application starts up, this method is responsible for creating the bus attachment and connecting to the local AllJoyn daemon. It registers a BusListener object named MyBusListener which listens for incoming signals. The AllJoyn method FindAdvertisedName that tells the bus to look for a service advertising the specified wellknown name is called from here. In this case, we do not know the full well-known name, so this method looks for any well-known name that starts with a prefix. In this case, it is org.alljoyn.bus.samples.simple. When a service advertising the indicated wellknown name is found , a FoundName signal is broadcast on the local daemon. The FoundName signal is caught by the BusListener object MyBusListener. The object now knows the exact well-known name of the service, which it did not know when it started because it used a prefix to look for a service. Java_org_alljoyn_bus_samples_simpleclient_Client_connect() Called from Java when the user clicks the Connect button on the UI for a particular service that was found, this call initiates a JoinSession() call that leads the client to join a session created by the service. While calling JoinSession, the well-known name of the service and SESSION_PORT are needed. SESSION_PORT is the port on which the service is hosting the session and listening for JoinSession requests. JoinSession on success updates the value of the out parameter session ID, which uniquely identifies the session between ‘n’ peers. Java_org_alljoyn_bus_samples_simpleclient_Client_disconnect() Called from within Java when the user clicks the Disconnect button, this function causes the connection between the local and remote AllJoyn daemons to be disconnected. Java_org_alljoyn_bus_samples_simpleclient_Client_simpleOnDestroy() Called when the application is exiting, this method is responsible for cleaning up the bus attachment before the application exits, i.e., it deletes the references to BusAttachment and BusListener objects. Java_org_alljoyn_bus_samples_simpleclient_Client_simplePing() Called from Java when the user enters a string in the text box and hits enter, this function causes AllJoyn to invoke the Ping method on the remote SimpleService instance. This is done by first creating an instance of ProxyBusObject, which represents the remote object, and then calling the ‘Ping’ method on it. 80-BA017-1 11 Qualcomm Innovation Center, Inc. MAY CONTAIN U.S. AND INTERNATIONAL EXPORT CONTROLLED INFORMATION AllJoyn™ Android C++ Sample Programs Walkthrough SimpleClient MyBusListener: Implementation of BusListener The BusListener object is responsible for listening for the FoundName signal, among others, which is sent when a bus with an indicated well-known name has been found. This signal sends the following information needed to connect with the bus running on a remote device: The well-known name that was found The name prefix The transport mask that indicates what transports are supported by the service In this sample, the client calls the FoundNameCallback function when it finds an Advertised name, which in turn creates a new instance of FoundName class, which is a piece of the Java part of the code.The FoundName class stores information about the service like the well-known name of the service and the connection state of the client to the service. 80-BA017-1 12 Qualcomm Innovation Center, Inc. MAY CONTAIN U.S. AND INTERNATIONAL EXPORT CONTROLLED INFORMATION 4 Running SimpleService and SimpleClient 1. Install the AllJoyn daemon on the desired device/emulator. You can push the alljoyndaemon on the device by using: adb push alljoyn-daemon <path to the desired location on phone> Note: If you push alljoyn-daemon on the sdcard, it does not typically run since the sdcard is mounted as ‘noexec’, meaning you cannot run executables from there. A suggested location is a subdirectory under /data or /system, like /data/alljoyn. 2. Run the alljoyn-daemon from the adb shell: $adb shell $cd <location of alljoyn that you used while pushing the daemon> $./alljoyn-daemon --internal 3. Install SimpleService on device A. This is a three-step process, as described in Sections 2.2 and 2.3. 4. Install SimpleClient on device B. This is three-step process, as described in Section 3.2. 5. Ensure the desired transport (WiFi/Bluetooth) is turned on on both devices. 6. Start SimpleService on device A. 7. Enter a unique name in the dialog box on the service. 8. Start SimpleClient on device B. 9. When the advertised service is found, its unique name displays with two buttons: Connect and Ping. 10. Click the Connect button. After the client successfully connects to the service, the Connect button changes to a Disconnect button. 11. When you enter text into SimpleClient’s text box and press the Ping button, the string is sent as the argument to the remote Ping method on device A. Phone A responds with this same string. SimpleClient displays both the original string and the received reply. Disconnect from the service by pressing the Disconnect button for that service on the client side. 12. To change the name the service is advertising, press the Stop button on the service screen, enter a new name, and press the Start button. 80-BA017-1 13 Qualcomm Innovation Center, Inc. MAY CONTAIN U.S. AND INTERNATIONAL EXPORT CONTROLLED INFORMATION 5 Code Download To locate source: In the SDK – Go to the samples folder on the topmost level. In AllJoyn source – Go to the samples folder under the alljoyn_core. 80-BA017-1 14 Qualcomm Innovation Center, Inc. MAY CONTAIN U.S. AND INTERNATIONAL EXPORT CONTROLLED INFORMATION 6 AllJoynChat AllJoynChat is an AllJoyn application with the following properties: It can act as both a client and service. It obtains the well-known name org.alljoyn.bus.samples.chat.<name entered by the user>. It provides a single object with path /chatService4. The object implements the interface org.alljoyn.bus.samples.chat. The interface defines a single signal named Chat. The signal contains a single string argument that contains the chat message to be broadcast. 6.1 Building and installing AllJoynChat AllJoynChat is built and installed in exactly the same way as SimpleService (see Sections 2.2 and 2.3). The base directory for AllJoynChat is: alljoyn_dir/samples/chat/android 6.2 Running AllJoynChat 1. Ensure that the AllJoyn daemon is present on the desired device/emulator. You can push the alljoyn-daemon on the device by using: adb push alljoyn-daemon <path to the desired location on phone> Note: If you push alljoyn-daemon on the sdcard, it does not typically run since the sdcard is mounted as ‘noexec’, meaning you cannot run executables from there. 2. Enable Bluetooth and/or Wi-Fi on both devices. Run the alljoyn-daemon from the adb shell on both devices: $adb shell $cd <location of alljoyn that you used while pushing the daemon> $./alljoyn-daemon --internal 3. Install AllJoynChat on the devices through Eclipse by: Choosing Run As → Android Application or Installing the Chat.apk file located under alljoyn_dir/samples/chat/android/bin by using: adb install Chat.apk 4. Run AllJoynChat on two devices. Once AllJoynChat comes up, it asks if you want to create a chat session or join an existing one. 80-BA017-1 15 Qualcomm Innovation Center, Inc. MAY CONTAIN U.S. AND INTERNATIONAL EXPORT CONTROLLED INFORMATION AllJoyn™ Android C++ Sample Programs Walkthrough AllJoynChat If you choose to create your chat session, it prompts you to enter the well knownname that you want to advertise. If you choose to join a chat session, it prompts you to enter the well-known name of the session that you want to join. 5. Once connected, you can send messages between the two devices using AllJoynChat’s text entry box. 6. Multiple devices can join the chat. For all the devices to talk to each other, all of them have to join the chat session, with the exception of one instance that creates the session. This example illustrates AllJoyn’s capability to provide two kinds of sessions: A point-to-point session in which only two devices talk to each other A multipoint session in which multiple devices talk to each other in a group 6.3 AllJoynChat walkthrough On startup, AllJoynChat asks if you want to create or join a chat session. If you create a chat session, you have to give it a well-known name that is advertised to everyone. If, however, you choose to join a session, you need to know the well-known name of the chat service that you want to join. AllJoynChat implements an AllJoyn attachment that creates a single bus object with path /chatService. The bus object implements the interface org.alljoyn.bus.samples.chat, which defines a single signal named Chat. The Chat signal contains a single string argument that contains the chat message to broadcast to a peer, or group of peers. Chat signal is sent to everyone in a particular session. It may be just two peers or ‘n’ peers.The JNI code for AllJoynChat is in the file: samples/chat/android/jni/Chat_jni.cpp This file defines six JNI calls: Java_org_alljoyn_bus_samples_chat_Chat_jniOnCreate() Called when the application starts up from within Java function onCreate(), this method is responsible for creating and connecting the AllJoyn attachment, creating and registering the AllJoyn object that implements the interface org.alljoyn.bus.samples.chat and registering the BusListener object MyBusListener. Java_org_alljoyn_bus_samples_chat_Chat_jniOnDestroy() Called when the application is exiting, this method is responsible for cleaning up the bus attachment before the application exits, i.e., deleting the references to BusAttachment and BusListener. Java_org_alljoyn_bus_samples_chat_Chat_disconnect() Called from within Java when the user hits the Disconnect button, this function causes the connection between the local and remote AllJoyn daemons to be disconnected. 80-BA017-1 16 Qualcomm Innovation Center, Inc. MAY CONTAIN U.S. AND INTERNATIONAL EXPORT CONTROLLED INFORMATION AllJoyn™ Android C++ Sample Programs Walkthrough AllJoynChat Java_org_alljoyn_bus_samples_chat_Chat_sendChatMsg() Called from Java when the user sends a chat message, this method calls SendChatSignal, defined as a part of the ChatObject, which sends a signal with the string entered by the user as an arguement. An additional method named org.alljoyn.bus.samples.chat.Callback(), and implemented in Java, is used as a callback from JNI into Java. This callback is called from within the signal handler for org.alljoyn.bus.chat.Chat whenever the Chat signal is received from another AllJoynChat instance on the bus. It causes the UI to be updated with chat messages coming in from AllJoyn. In addition to the JNI functions described above, Chat_jni.cpp also defines and implements the bus object that sends the org.alljoyn.bus.samples.chat.Chat signals. This C++ bus object is named ChatObject and derives from ajn::LocalObject. Java_org_alljoyn_bus_samples_chat_Chat_advertise() Called from Java after the user has entered a name, this code takes that name, concatenates it with the NAME_PREFIX, and requests this well-known name for itself on the bus by calling RequestName(). After acquiring a well-known name, this code calls BinsSessionPort(), which creates a session and binds to a well-known session port. It takes in: Session port – Port to which it wants to bind the service Session opts – Specifies the type of messages that will be exchanged, transports that you want to be supported, and proximity type, which is an abstract way of mentioning what transports you want to use Thereafter, the AllJoyn method AdvertisedName is called to advertise the well-known name on the bus. Java_org_alljoyn_bus_samples_chat_Chat_joinSession() This method is called when a user chooses to join a session. A prompt appears, asking the user to enter the well-known name of the desired chat service. The name entered at this instance is passed to FindAdvertisedName(), which is called inside joinSession(). MyBusListener() BusListener class The BusListener class is responsible for listening for the FoundAdvertisedName signal when the name that was requested by the FindAdvertisedName() method is discovered. The signal provides the name that was found and the name prefix of the service. AcceptSessionJoiner() is invoked by MyBusListener of the service when an incoming JoinSession request is received. Here a check is made to see if the incoming request is requesting the service on the same port on which the our service is listening. SessionJoined() is invoked by MyBusListener of the client and informs the client about the unique session ID that it now shares with the service. 80-BA017-1 17 Qualcomm Innovation Center, Inc. MAY CONTAIN U.S. AND INTERNATIONAL EXPORT CONTROLLED INFORMATION AllJoyn™ Android C++ Sample Programs Walkthrough AllJoynChat 6.4 Code download To locate source: In the SDK – Go to the samples folder on the topmost level. In AllJoyn source – Go to the samples folder under the alljoyn_core. 80-BA017-1 18 Qualcomm Innovation Center, Inc. MAY CONTAIN U.S. AND INTERNATIONAL EXPORT CONTROLLED INFORMATION
Similar documents
Bus Tour Service in Winnipeg from Exclusivebuslines.com
Exclusive Bus Lines, a fastest growing charter bus company provide Transit & Motor Coach Services in Winnipeg. We provide the best bus rental & tours services at affordable prices. Our professional team believes in offering reliable & safest transportation services. Call us now: 204-888-4411! Request for free quote! Visit Us: http://www.exclusivebuslines.com/
More information