/* * * Copyright (C) 2020, University of the Basque Country (UPV/EHU) * * Contact for licensing options: * * This file is part of MCOP MCPTT Client * * This is free software: you can redistribute it and/or modify it under the terms of * the GNU General Public License as published by the Free Software Foundation, either version 3 * of the License, or (at your option) any later version. * * This is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ package org.mcopenplatform.muoapi.managerIapi; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.os.Build; import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.os.Message; import android.util.Log; import org.mcopenplatform.iapi.McopMessenger; import org.mcopenplatform.muoapi.BuildConfig; import static android.content.Context.BIND_AUTO_CREATE; public abstract class ManagerIapiBase { private final static String TAG = org.mcopenplatform.muoapi.utils.Utils.getTAG(ManagerIapiBase.class.getCanonicalName()); protected ServiceConnection mConnection; protected Object mService; protected McopMessenger mcopMessenger; protected boolean isConnect; protected String PACKET_SERVICE="org.mcopenplatform.iapi.test"; protected Context mContext; protected Handler handler; protected OnIapiListener onIapiListener; protected boolean changedPacket=false; public ManagerIapiBase() { mContext=null; isConnect=false; handler = new Handler(Looper.getMainLooper()) { @Override public void handleMessage(Message message) { if(BuildConfig.DEBUG)Log.d(TAG,"Received Message from: "+getPACKET_SERVICE()); //TODO: receive Message and process data from other Service receiveEvent(message); } }; mcopMessenger=new McopMessenger(handler); } public boolean start(Context context ,String packetService ,String packetMainService ) { if(packetService!=null){ setPACKET_SERVICE(packetService); } if(packetMainService !=null){ setPACKET_MAIN_SERVICE(packetMainService); } if(BuildConfig.DEBUG)Log.d(TAG, "Starting..."+getPACKET_SERVICE()); mContext=context; if(mConnection==null) mConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName className, IBinder service) { Log.d(TAG,"Service binded! "+getPACKET_SERVICE()); mService=registerInterface(service); isConnect=true; isServiceConnected(); } @Override public void onServiceDisconnected(ComponentName className) { mService = null; //This method is only invoked when the service quits from the other end or gets killed //Invoking exit() from the AIDL interface makes the Service kill itself, thus invoking this. Log.e(TAG,"Service disconnected "+getPACKET_SERVICE()); isConnect=false; } @Override public void onBindingDied(ComponentName name) { Log.e(TAG,"Service died."+getPACKET_SERVICE()); } }; Intent serviceIntent = new Intent() .setComponent(new ComponentName( getPACKET_MAIN_SERVICE(), getPACKET_SERVICE())); serviceIntent.setAction(getPACKET_SERVICE()); try{ ComponentName componentName=null; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { componentName=mContext.startForegroundService(serviceIntent); } else componentName=mContext.startService(serviceIntent); if(componentName!=null){ Log.d(TAG,"Start Service: "+componentName.getPackageName()); }else{ if(BuildConfig.DEBUG)Log.e(TAG,"Service Error: "+getPACKET_SERVICE() +" "+getPACKET_MAIN_SERVICE()); } }catch (Exception e){ if(BuildConfig.DEBUG)Log.w(TAG,"Error in start service: "+e.getMessage()); } Log.d(TAG,"Bind Service "+getPACKET_SERVICE()+":"+context.bindService(serviceIntent, mConnection, BIND_AUTO_CREATE)); startInternal(); return true; } public boolean stop() { if(BuildConfig.DEBUG)Log.d(TAG, "Stopping..."+getPACKET_SERVICE()); if(mContext!=null) mContext.unbindService(mConnection); isConnect=false; stopInternal(); return true; } abstract protected void isServiceConnected(); abstract protected void startInternal(); abstract protected void stopInternal(); abstract protected Object registerInterface(IBinder service); abstract protected boolean receiveEvent(Message message); /** * It allows to distinguish between the different PACKET_SERVICE for each of the extended class of ManagerIapiBase * @return PACKET_SERVICE constant */ abstract protected String getPACKET_SERVICE(); abstract protected String getPACKET_MAIN_SERVICE(); abstract protected void setPACKET_SERVICE(String packetService); abstract protected void setPACKET_MAIN_SERVICE(String packetMainService); abstract protected boolean checkChangedPacket(); public boolean isConnect() { return isConnect; } interface OnIapiListener{ void onIapiError(int codeError,String error); } public void setOnIapiListener(OnIapiListener onIapiListener){ this.onIapiListener=onIapiListener; } }