docs/MCOP_App_developing_steps.md
d1b6dffc
 > *Refer to* [*README*](../README.md) *for main instruction file*
 
 # MCOP - MCPTT App Development
 
 ## What is MCOP?
 
 **MCOP** (Mission Critical Open Platform) is a project that defines the first prototype of open source **MCPTT** (Mission Critical Push-To-Talk) client.
 
 This client allows the interoperability among different vendors thanks to a multilevel API.
 
 ## Architecture
 
 Three main modules define the architecture: 
 
 * **MCOP SDK**:
 
 	This module contains all the MCPTT logic, and allows the use of other additional modules that increase its functionality. 
 
 * **MCOP Integration Plugins**:
 
 	Additional modules or Android services with their own API, known by the MCOP SDK module, offering device specific or MCPTT network required functionalities. 
 
 * **End User Interface**:
 
 	GUI (Graphical User Interface) that uses the MCOP SDK services without having to develop the whole MCPTT logic. *(Min. level of Android SDK: API 17)*.
 
 ![ThreMainModules](../images/threemainmodules.png)
 
 ## App Developing Steps
 
 * **0. MCOP SDK and AIDLs**: The SDK defines two AIDLs and one Constant class:
 
 	* **IMCOPsdk**: From Client to SDK.
 
 	* **IMCOPCallBack**: From SDK to Client.
 
 	* **ConstantsMCOP**: defines the constants to use in the AIDLs.
 
 * **1. Configure Manifest**: Indicate the necessary permissions for the application.
 
 		<uses-permission android:name="android.permission.INTERNET" />
 		<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
79e889ae
     	<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
     	<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
     	<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
     	<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
     	<uses-permission android:name="android.permission.CAMERA" />
     	<uses-permission android:name="android.permission.WAKE_LOCK" />
     	<uses-permission android:name="android.permission.RECORD_AUDIO" />
     	<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
     	<uses-permission android:name="android.permission.VIBRATE" />
     	<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
     	<uses-permission android:name="android.permission.WRITE_SETTINGS" />
     	<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     	<uses-permission android:name="android.permission.READ_CONTACTS" />
     	<uses-permission android:name="android.permission.WRITE_CONTACTS" />
     	<uses-permission android:name="android.permission.READ_PHONE_STATE" />
     	<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
     	<uses-permission android:name="android.permission.CALL_PHONE" />
     	<uses-permission android:name="android.permission.RAISED_THREAD_PRIORITY" />
     	<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"/>
     	<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
     	<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
d1b6dffc
 
 	Define the activities to be used:
 
 		<application
 			android:allowBackup="true"
 			android:icon="@mipmap/ic_launcher"
 			android:label="@string/app_name"
 			android:roundIcon="@mipmap/ic_launcher_round"
 			android:supportsRtl="true"
 			android:theme="@style/AppTheme" >
 			<activity android:name=".MainActivity"
 				android:screenOrientation="portrait">
 				<intent-filter>
 					<action android:name="android.intent.action.MAIN" />
 					<category android:name="android.intent.category.LAUNCHER" />
 				</intent-filter>
 			</activity>
 		</application>
79e889ae
 		<queries>
     	</queries>
d1b6dffc
 
 * **2. Require the explicit acceptance of some of the permissions.**
 
 	The client should explicitly accept some permissions:
 
 	* Manifest.permission.ACCESS\_FINE\_LOCATION
 
 	* Manifest.permission.READ\_PHONE\_STATE
 
 	* Manifest.permission.ACCESS\_COARSE\_LOCATION
 
 	* Manifest.permission.CAMERA
 
 	* Manifest.permission.RECORD\_AUDIO
 
 		![Allow audio](../images/allow_audio.png)
 
 * **3. Bind to MCOP SDK**:
 
 	In this version of MCOP SDK, it is necessary to send **“currentProfile”** to the service:
 
 		Intent serviceIntent = new Intent()
 			.setComponent(new ComponentName(
 				"org.mcopenplatform.muoapi",
 				"org.mcopenplatform.muoapi.MCOPsdk"));

 		//This is only for tresting
 		serviceIntent.putExtra("PROFILE_SELECT",currentProfile);
 		
 		ComponentName componentName=startService(serviceIntent);
 		bindService(serviceIntent, mConnection, BIND_AUTO_CREATE);
 
 	Wait for the service to bind:
 
 	* Save the return value from the Service (this is the AIDL Interface to be used by the Client to communicate with the Service).
 
 	* Register the callback for asynchronous communication from the Service to the Client:
 
 			mConnection = new ServiceConnection() {
 			
 			@Override
 			public void onServiceConnected(ComponentName className, IBinder service) {			
 				mService = IMCOPsdk.Stub.asInterface(service);
 				try {
 					mService.registerCallback(mMCOPCallback);
 				} catch (RemoteException e) {
 					e.printStackTrace();
 				}
 				isConnect=true;
 				
 				//AUTO Register
 				final Handler handler = new Handler();
 				handler.postDelayed(new Runnable() {
 					@Override
 					public void run() {
 						try {
 							if(mService!=null)
 						mService.authorizeUser(null);
 						} catch (RemoteException e) {
 							e.printStackTrace();
 						}
 					}
 				}, DEFAULT_REGISTER_DELAY);
 			}
 
 	* Definition of the registered callback:
 
 		* This is the point where communications from the Server to the Client will be received:
 
 				mMCOPCallback=new IMCOPCallback.Stub() {
 					@Override
 					public void handleOnEvent(final List<Intent> actionList) throws RemoteException {
 						runOnUiThread(new Runnable() {
 							@Override
 							public void run() {
 								for(Intent action:actionList){
 									int codeError=-1;
 									int eventTypeInt=-1;
 									String stringError=null;
 									String sessionID=null;
 									if(action!=null &&
 										action.getAction()!=null &&
 										!action.getAction().trim().isEmpty())
 											try {
 												switch (ConstantsMCOP.ActionsCallBack.fromString(action.getAction())){
 												...
 												}
 											}catch (Exception ex){
 												Log.e(TAG,"Event Action Error: "+action.getAction()+" error:"+ex.getMessage());
 											}
 									}
 								}
 							});
 						}
 					};
 
 
 * **4. Perform any action in the MCOP SDK and receive the result**.
 
 	Example:
 
 		if(mService!=null)
 			mService.makeCall(
 				selGroup, //DEFAULT_GROUP,
79e889ae
 				ConstantsMCOP.CallEventExtras.CallTypeEnum.CallSubtypeAudio.getValue()|
 				ConstantsMCOP.CallEventExtras.CallTypeEnum.CallSubtypeWithCtrlMech.getValue()| 
 				ConstantsMCOP.CallEventExtras.CallTypeEnum.CallSubtypePrearrangedGroup.getValue()
d1b6dffc
 			);