CaaS Engine provides open APIs that are based on the HUAWEI MeeTime service. It allows app and hardware developers to easily incorporate video calling into their apps, and go straight to the video source to tailor it to their preferences.

CaaS Engine not only helps smart devices and apps implement system-level video calling, but also forms the basis of an accessible real-time communications network that delivers unprecedented capabilities.

What You Will Create

In this codelab, you will create a demo project, integrate the CaaS Engine SDK into the demo project, and complete the overall process setup of the CaaS Engine service.

What You Will Learn

Hardware Requirements

Software Requirements

Required Knowledge

CaaS Engine integration requires the following preparations:

For details, see the section "App Development" in Development Guide.

1. Integrate the CaaS Engine SDK.

Configure the repository in the build.gradle file of the project.

buildscript { repositories { google() jcenter() maven {url 'http://developer.huawei.com/repo/'} } } allprojects { repositories { maven {url 'http://developer.huawei.com/repo/'} google() jcenter() } }

Add the following dependencies to the build.gradle file in the app directory of the project.

repositories { flatDir { dirs 'libs' } } dependencies { implementation group: 'com.huawei.caaskit', name: 'caaskitlite', version: '1.0.1.400', ext: 'aar' }

Click the sync button, as shown in the following figure.

After the synchronization, the screen shown in the following figure is displayed.

2. Add app ID.

Add the app ID generated when creating the app on HUAWEI Developer to the AndroidManifest.xml file of the app. The name is com.huawei.hms.client.appid, and the value is appid=******, where ****** indicates the ID of your app. For details about how to apply for the permission, see the third section "Configuring App Information in AppGallery Connect" in the Development Guide.

3. Add permissions to the AndroidManifest.xml file.

DeviceVirtualization service permission:

<uses-permission android:name="com.huawei.dmsdp.permission.localappservice" />

4. Register and initialize broadcast.

Broadcasts can be registered either dynamically or statically. In this example, dynamic registration is used as an example.

CaasKitHelper.java

public class CaasKitHelper { private static final String TAG = "CaasKitHelper"; private static final String DMSDP_STARTDISCOVERY = "com.huawei.dmsdp.DMSDP_STARTDISCOVERY"; private static CaasKitHelper sCaasKitHelper; private DeviceDiscoverReceiver mDiscoverReceiver; private HwCaasServiceManager mHwCaasServiceManager; private HwCaasHandler mHwCaasHandler; private Context mContext; private boolean mIsSendShowFail; private boolean mIsCaasKitInit; private boolean mIsHasCaaSContacts; private HwCaasServiceCallBack mCallBack = new HwCaasServiceCallBack() { @Override public void initSuccess(HwCaasHandler handler) { ... } @Override public void initFail(int retCode) { ... } @Override public void releaseSuccess() { ... } }; private CaasKitHelper() { mContext = CaasKitApplication.getContext(); } public static CaasKitHelper getInstance() { if (sCaasKitHelper == null) { synchronized (CaasKitHelper.class) { if (sCaasKitHelper == null) { sCaasKitHelper = new CaasKitHelper(); } } } return sCaasKitHelper; } private void registerDiscoverReceiver() { Log.d(TAG, "registerDiscoverReceiver."); IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(DMSDP_STARTDISCOVERY); if (mDiscoverReceiver == null) { Log.d(TAG, "mDiscoverReceiver."); mDiscoverReceiver = new DeviceDiscoverReceiver(); mContext.registerReceiver(mDiscoverReceiver, intentFilter); } } private void unregisterDiscoverReceiver() { Log.d(TAG, "unregisterDiscoverReceiver."); if (mDiscoverReceiver != null) { mContext.unregisterReceiver(mDiscoverReceiver); mDiscoverReceiver = null; } } /** * Initialization before using CaaSKitLite. */ public void caasKitInit() { Log.d(TAG, "caasKitInit." + mIsCaasKitInit); if (!mIsCaasKitInit) { registerDiscoverReceiver(); // Initialize mHwCaasServiceManager instance. mHwCaasServiceManager = HwCaasServiceManager.init(); // Initialize HwCaasHandler instance through handlerType. mHwCaasServiceManager.initHandler(mContext, HwCaasUtils.VIRTUAL_CAMERA_TYPE, mCallBack); mIsCaasKitInit = true; } } }

The broadcast is as follows:

DeviceDiscoverReceiver.java

public class DeviceDiscoverReceiver extends BroadcastReceiver { private static final String TAG = "DmsdpStartDiscoverReceiver"; private Context mApplicationContext; @Override public void onReceive(Context context, Intent intent) { Log.d(TAG, "onReceive."); mApplicationContext = CaasKitApplication.getContext(); HwDmsdpService.init(mApplicationContext, new VirtualCameraListener()); } }

Call CaasCaasKitHelper.getInstance().caasKitInit()re appropriate to register the broadcast and initialize the CaaS service.

CaasKitDemoActivity.java

public class CaasKitDemoActivity extends AppCompatActivity { ... @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_MEDIA_DATA) { if (resultCode == RESULT_OK && data != null && data.getData() != null) { setVideoFilePath(data); addVideoView(); CaasKitHelper.getInstance().caasKitInit(); } } } ... }

5. Implement camera virtualization.

VirtualCameraListener.java

public class VirtualCameraListener extends CameraListener { // Use java.util.UUID.randomUUID().toString() to generate, please do not directly use the ID provided in the demo public static final String DEVICE_ID = "ff66bf58-6413-48e7-8dcd-c084254b199e"; // this ID is customized by the developer. public static final String VIRCAMERA_ID = "virtualcamera0"; private static final String TAG = "VirtualCameraListener"; private static final int VIDEO_BUFFER_MODE_YUV = 1; private static final int DEVICE_CAMERA = 5; private static final String DEVICE_NAME = "CaasKitCamera"; public VirtualCameraListener() { } @Override public List<DeviceInfo> getDeviceInfo() { Log.d(TAG, "getDeviceInfo."); List<DeviceInfo> listDeviceInfo = new ArrayList<>(); DeviceInfo deviceInfo = new DeviceInfo(); deviceInfo.setDeviceID(DEVICE_ID); deviceInfo.setDeviceName(DEVICE_NAME); deviceInfo.setDeviceType(DEVICE_CAMERA); deviceInfo.properties.put(CommonUtils.DEVICE_SUPPORTCAMERA_BOOLEAN, "true"); listDeviceInfo.add(deviceInfo); return listDeviceInfo; } @Override public HashMap<String, CameraInfo> getCameraInfo(String deviceId) { Log.d(TAG, "getCameraInfo."); HashMap<String, CameraInfo> mapCameraInfo = new HashMap<>(); CameraInfo cameraInfo = new CameraInfo(); cameraInfo.setCameraId(VIRCAMERA_ID); cameraInfo.setVideoType(VIDEO_BUFFER_MODE_YUV); cameraInfo.setSupportedFpsRange("25000,25000"); cameraInfo.setSupportedResolutionRange("1080,1920"); mapCameraInfo.put(VIRCAMERA_ID, cameraInfo); return mapCameraInfo; } @Override public CameraParameters getCameraParameters(String cameraId) { Log.d(TAG, "getCameraParameters."); CameraParameters cameraParams = new CameraParameters(); cameraParams.cameraId = VIRCAMERA_ID; cameraParams.properties.put(CommonUtils.CURRENT_RESOLUTION, "1080,1920"); cameraParams.properties.put(CommonUtils.CURRENT_FRAMERATES, "25000,30000"); cameraParams.properties.put(CommonUtils.CURRENT_IMAGEFORMAT, CommonUtils.IMAGE_FORMAT_NV21); cameraParams.properties.put(CommonUtils.CURRENT_DECODEFORMAT, CommonUtils.DECODE_FORMAT_RGBA); return cameraParams; } @Override public int startCaptureVideo(String cameraId, Surface surface) { Log.d(TAG, "startCaptureVideo." + cameraId); if (ExtSurfaceRender.getInstance().isEGLContextReady()) { Log.d(TAG, "startCaptureVideo."); ExtSurfaceRender.getInstance().startRendering(surface); } return 0; } @Override public int stopCaptureVideo(String cameraId) { Log.d(TAG, "stopCaptureVideo."); ExtSurfaceRender.getInstance().stopRendering(); return 0; } @Override public int notifyUnbindMSDPService() { Log.d(TAG, "notifyUnbindMSDPService."); HwDmsdpService.release(); return 0; } @Override public void checkPermissionOnCallback(int result) { Log.d(TAG, "checkPermissionOnCallback.result: " + result); } }

6. Configure the floating calling window.

CaasKitHelper.java

public class CaasKitHelper { private static final String TAG = "CaasKitHelper"; private static final String DMSDP_STARTDISCOVERY = "com.huawei.dmsdp.DMSDP_STARTDISCOVERY"; private static final int VIEWHEIGHT = 248; private static final int VIEWWIDTH = 256; private static final int LOCATION_X = 102; private static final int LOCATION_Y = 40; private static final int LOCATION_STARTY = 24; private static CaasKitHelper sCaasKitHelper; private DeviceDiscoverReceiver mDiscoverReceiver; private HwCaasServiceManager mHwCaasServiceManager; private HwCaasHandler mHwCaasHandler; private Context mContext; private boolean mIsSendShowFail; private boolean mIsCaasKitInit; private boolean mIsHasCaaSContacts; private HwCaasServiceCallBack mCallBack = new HwCaasServiceCallBack() { @Override public void initSuccess(HwCaasHandler handler) { // Callback after successful initialization of HwCaasHandler. mHwCaasHandler = handler; if (mHwCaasHandler != null) { boolean isSetSuccess = false; // query if there are contacts to call. mIsHasCaaSContacts = mHwCaasHandler.hasCaaSContacts(HwCaasUtils.ContactsType.NORMAL_CONTACTS); isSetSuccess = mHwCaasHandler.setContactViewSize(VIEWWIDTH, VIEWHEIGHT); Log.i(TAG, " isSetSuccess: " + isSetSuccess); isSetSuccess = mHwCaasHandler.setAppMode(HwCaasUtils.LANDSCAPE); Log.i(TAG, " isSetSuccess: " + isSetSuccess); isSetSuccess = mHwCaasHandler.setFloatViewLocation(HwCaasUtils.STARTVIEW, HwCaasUtils.POINT_RIGHTANDDOWN, LOCATION_X, LOCATION_STARTY); Log.i(TAG, "viewType: " + HwCaasUtils.STARTVIEW + " isSetSuccess: " + isSetSuccess); isSetSuccess = mHwCaasHandler.setFloatViewLocation(HwCaasUtils.CONTACTVIEW, HwCaasUtils.POINT_RIGHTANDUP, LOCATION_X, LOCATION_Y); Log.i(TAG, "viewType: " + HwCaasUtils.CONTACTVIEW + " isSetSuccess: " + isSetSuccess); isSetSuccess = mHwCaasHandler.setFloatViewLocation(HwCaasUtils.CALLVIEW, HwCaasUtils.POINT_RIGHTANDUP, LOCATION_X, LOCATION_Y); Log.i(TAG, "viewType: " + HwCaasUtils.CALLVIEW + " isSetSuccess: " + isSetSuccess); isSetSuccess = mHwCaasHandler.setFloatViewLocation(HwCaasUtils.VIDEOVIEW, HwCaasUtils.POINT_RIGHTANDUP, LOCATION_X, LOCATION_Y); Log.i(TAG, "viewType: " + HwCaasUtils.VIDEOVIEW + " isSetSuccess: " + isSetSuccess); if (mIsSendShowFail) { sendShow(); mIsSendShowFail = false; } } } @Override public void initFail(int retCode) { // Callback if init Handler fail. Log.i(TAG, "retCode: " + retCode); if (retCode == HwCaasUtils.SERVICE_EXCEPTION) { stopRendering(); } } @Override public void releaseSuccess() { // Callback after successful release of mHwCaasServiceManager. mHwCaasHandler = null; mIsSendShowFail = false; } }; }

7. Display the floating calling window.

CaasKitHelper.java

public class CaasKitHelper { private static final String TAG = "CaasKitHelper"; private static CaasKitHelper sCaasKitHelper; private DeviceDiscoverReceiver mDiscoverReceiver; private HwCaasServiceManager mHwCaasServiceManager; private HwCaasHandler mHwCaasHandler; private Context mContext; private boolean mIsSendShowFail; private boolean mIsCaasKitInit; private boolean mIsHasCaaSContacts; /** * Virtualize Camera and show float ball. */ public void sendShow() { Log.d(TAG, "sendShow."); if (mHwCaasHandler != null && mIsHasCaaSContacts) { // show float ball. int ret = mHwCaasHandler.initVirtualCamera(VirtualCameraListener.DEVICE_ID, VirtualCameraListener.VIRCAMERA_ID); Log.d(TAG, "ret: " + ret); } else { // Prevent first call, mHwCaasHandler hasn't returned yet. mIsSendShowFail = true; Log.e(TAG, "sendShow fail."); } } /** * Called when the application is in the foreground and some scenes do not want to display the float ball. * * @return returns true if sent successfully. */ public boolean sendHide() { Log.d(TAG, "sendHide."); if (mHwCaasHandler != null) { // Send HIDE event to hide float ball. boolean isSendoK = mHwCaasHandler.sendEventToCaasService(HwCaasUtils.HIDE); Log.d(TAG, "isSendoK: " + isSendoK); return isSendoK; } Log.e(TAG, "sendHide fail."); return false; } }

8. Release resources.

CaasKitHelper.java

public class CaasKitHelper { private static final String TAG = "CaasKitHelper"; private static CaasKitHelper sCaasKitHelper; private DeviceDiscoverReceiver mDiscoverReceiver; private HwCaasServiceManager mHwCaasServiceManager; private HwCaasHandler mHwCaasHandler; private Context mContext; private boolean mIsSendShowFail; private boolean mIsCaasKitInit; private boolean mIsHasCaaSContacts; /** * called when the app exits. */ public void caasKitRelease() { Log.d(TAG, "caasKitRelease." + mIsCaasKitInit); if (mIsCaasKitInit) { if (mHwCaasServiceManager != null) { // Source release. mHwCaasServiceManager.release(); mHwCaasServiceManager = null; } unregisterDiscoverReceiver(); mIsCaasKitInit = false; } } public void releaseVirtualCamera() { Log.d(TAG, "releaseVirtualCamera."); if (mHwCaasHandler != null) { // release virtual camera. int ret = mHwCaasHandler.releaseVirtualCamera(VirtualCameraListener.DEVICE_ID, VirtualCameraListener.VIRCAMERA_ID); Log.d(TAG, "ret: " + ret); } } }

You have successfully completed this codelab and learned:

For more information, please click the following link:
Related documents

Download

Code copied