android-ngn-stack/src/main/java/org/doubango/ngn/services/impl/affiliation/MyAffiliationService.java
c732d49e
 /*
175b478c
 
74ca6d11
 *  Copyright (C) 2020, University of the Basque Country (UPV/EHU)
c732d49e
 *
 * Contact for licensing options: <licensing-mcpttclient(at)mcopenplatform(dot)com>
 *
 * 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.doubango.ngn.services.impl.affiliation;
 
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.os.Handler;
 import android.os.Looper;
 import android.util.Log;
 
 import org.doubango.ngn.BuildConfig;
 import org.doubango.ngn.NgnApplication;
 import org.doubango.ngn.NgnEngine;
 import org.doubango.ngn.datatype.affiliation.affiliationcommand.CommandList;
 import org.doubango.ngn.datatype.affiliation.pidf.AffiliationType;
 import org.doubango.ngn.datatype.affiliation.pidf.Presence;
 import org.doubango.ngn.datatype.affiliation.pidf.Status;
 import org.doubango.ngn.datatype.affiliation.pidf.StatusType;
 import org.doubango.ngn.datatype.affiliation.pidf.Tuple;
 import org.doubango.ngn.services.affiliation.IMyAffiliationService;
 import org.doubango.ngn.sip.MyPublicationAffiliationSession;
 import org.doubango.ngn.sip.MySubscriptionAffiliationSession;
 import org.doubango.ngn.sip.NgnSipPrefrences;
 import org.doubango.utils.Utils;
 
 import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.TreeMap;
 
 
 public class MyAffiliationService implements IMyAffiliationService {
     private final static String TAG = Utils.getTAG(MyAffiliationService.class.getCanonicalName());
 
     private static boolean isStart;
175b478c
     private BroadcastReceiver broadcastReceiverAffiliationMessage;
c732d49e
     private MySubscriptionAffiliationSession mSessionSuscription=null;
 
    private static final boolean USE_VERSION_OLD_AFFILIATION= false;
 
 
     public static final String AFFILIATION_REGISTER=TAG +".AFFILIATION_REGISTER";
     private Presence presenceNow=null;
     private Map<String,Presence> stringPresenceMap;
     private Map<Long,String> longStringMap;
     private OnAffiliationServiceListener onAffiliationServiceListener;
     private MyPublicationAffiliationSession mSessionPublication;
     private Map<String, Long> mGroupsMap;
     private TreeMap<Long, Map<String,String>> mExpiresMap;
     private Handler handlerService;
     private static final boolean checkExpiredActive=false;
     private Presence presenceNowDelay;
     private String pidNowDelay;
     private Map<String, String> expiresNowDelay;
     private CommandList commandListNowDelay;
     private Handler handlerStartAffiliation;
     private Runnable runnableStartAffiliation;
     private ArrayList affiliationGroupDelay;
     private boolean isSubscribed=false;
 
 
     @Override
     public boolean start() {
         Log.d(TAG,"Start "+"AffiliationService");
         stringPresenceMap=new HashMap<>();
         isStart=true;
         isSubscribed=false;
         broadcastReceiverAffiliationMessage=new BroadcastReceiver() {
             @Override
             public void onReceive(Context context, Intent intent) {
 
                 if (intent.getAction().equals(AFFILIATION_ACTION_MESSAGE)) {
                     Log.d(TAG,"New message received");
                     byte[] messageAffiliation=intent.getByteArrayExtra(AFFILIATION_NEWAFFILIATION_MESSAGE);
                     if(messageAffiliation==null || messageAffiliation.length==0){
                         Log.e(TAG,"Affiliation message not valid.");
                     }else{
                         Log.d(TAG,"Received new affiliation message.");
                         try {
                             CommandList commandList=AffiliationUtils.getCommandList(messageAffiliation);
                             receiveNewSelfAffiliation(commandList);
                         } catch (Exception e) {
                             Log.e(TAG,"Error parsing new message: "+e.toString()+" "+e.getMessage());
                         }
 
                     }
                 }else if (intent.getAction().equals(AFFILIATION_ACTION_NOTIFY)) {
                     Log.d(TAG,"New notify received.");
                     boolean sendAccound=false;
                     byte[] messageAffiliation=intent.getByteArrayExtra(AFFILIATION_NEWAFFILIATION_NOTIFY);
                     Log.d(TAG,"New notify affiliation received.");
                     //try {
175b478c
                     Presence presence=null;
                     if(messageAffiliation==null || messageAffiliation.length==0){
                         Log.w(TAG,"Affiliation notify not valid or empty.");
                         presence=new Presence();
                     }else{
                         Log.d(TAG,"Valid affiliation notify.");
                         try {
                             if(BuildConfig.DEBUG)Log.d(TAG,"new notify: "+new String(messageAffiliation));
                             presence=AffiliationUtils.getPresence(messageAffiliation);
                         } catch (Exception e) {
                             Log.e(TAG,"Error proccess new affiliation:"+e.getMessage());
c732d49e
                         }
175b478c
                     }
                     String mcpttID=null;
                     NgnSipPrefrences profile=NgnEngine.getInstance().getProfilesService().getProfileNow(context);
                     if(profile!=null)mcpttID=profile.getMcpttId();
                     if((presence!=null) && (mcpttID!=null) &&
                             (presence.getEntity()!=null) &&
                             (presence.getEntity().trim().compareTo(mcpttID.trim())==0)){
                         setPresenceNow(presence);
                         if(presence.getTuple()!=null && profile!=null){
                             if(!sendAccound){
                                 if(presence.getPId()!=null &&
                                         !presence.getPId().isEmpty() &&
                                         stringPresenceMap!=null &&
                                         stringPresenceMap.get(presence.getPId())!=null){
 
                                     receiveNewPresenceResponse(presence,presence.getPId());
c732d49e
                                 }else{
175b478c
                                     receiveNewPresence(presence);
c732d49e
                                 }
                             }else{
175b478c
                                 Log.d(TAG,"No listeners.");
c732d49e
                             }
175b478c
                         }else{
                             Log.e(TAG,"Error processing affiliation data.");
                         }
c732d49e
 
 
 
175b478c
                     }else if(presence!=null && mcpttID!=null &&
                             presence.getEntity()==null){
                         setPresenceNow(presence);
                         receiveNewPresence(presence);
                     }else{
                         Log.e(TAG,"Invalid new notify.");
                     }
c732d49e
                     /*
                     } catch (Exception e) {
                         Log.e(TAG,"it isn´t possible to parse the info on sip notify "+e.toString());
                     }
                     */
 
                 }else if (intent.getAction().equals(AFFILIATION_ACTION_SUBSCRIBE)) {
                     Log.d(TAG,"Receive response subscribe");
                     String error=intent.getStringExtra(AFFILIATION_RESPONSE_SUBSCRIBE_ERROR);
                     String responseOk=intent.getStringExtra(AFFILIATION_RESPONSE_SUBSCRIBE_OK);
                     if(error!=null){
                         //Error
175b478c
                         Log.e(TAG,"Error in subscribe for affiliation "+error);
c732d49e
                         isSubscribed=false;
                     }else if(responseOk!=null){
                         //Ok
                         Log.d(TAG,"Correct subscribe for affiliation");
                         isSubscribed=true;
                         if(affiliationGroupDelay!=null){
                             Log.d(TAG,"Affiliation now to groups");
                             affiliationGroups(context,affiliationGroupDelay);
                             affiliationGroupDelay=null;
                         }
 
                     }else
                         Log.w(TAG,"This situation isn´t logic");
                 }else if (intent.getAction().equals(AFFILIATION_ACTION_UNSUBSCRIBE)) {
                     Log.d(TAG,"UnSubscribe");
                     isSubscribed=false;
                 }
             }
 
         };
         IntentFilter intentFilter = new IntentFilter();
         intentFilter.addAction(AFFILIATION_ACTION_MESSAGE);
         intentFilter.addAction(AFFILIATION_ACTION_NOTIFY);
         intentFilter.addAction(AFFILIATION_ACTION_SUBSCRIBE);
         intentFilter.addAction(AFFILIATION_ACTION_UNSUBSCRIBE);
         NgnApplication.getContext().registerReceiver(broadcastReceiverAffiliationMessage,intentFilter);
175b478c
         return true;
     }
 
 
 
 
 
     @Override
     public boolean stop() {
         Log.d(TAG,"Stop "+"AffiliationService");
         stringPresenceMap=null;
         isSubscribed=false;
         unRegister();
         try{
             if(handlerService!=null && runnableStartAffiliation!=null){
                 handlerService.removeCallbacks(runnableStartAffiliation);
                 runnableStartAffiliation=null;
                 handlerService=null;
             }
         }catch (Exception e){
             Log.e(TAG,"Error in stop affiliation");
             e.printStackTrace();
         }
 
         isStart=false;
         return true;
     }
 
     public MyAffiliationService() {
 
c732d49e
     }
 
     private void affilitionChange(boolean isRegister){
         if(!isRegister){
             if(mSessionSuscription!=null){
                 Log.d(TAG,"Unsubscribe affiliation");
                 mSessionSuscription.unSubscribeAffiliation();
                 mSessionSuscription=null;
             }
         }else{
             mSessionSuscription= MySubscriptionAffiliationSession.createOutgoingSession(NgnEngine.getInstance().getSipService().getSipStack());
             if(mSessionSuscription.subscribeAffiliation()){
                 Log.d(TAG,"Subscribe sent.");
             }
         }
     }
 
     //INIT Publication
 
 
     public String unAffiliationGroup(Context context,String groupSusbcribe){
         if(context==null || groupSusbcribe==null)return null;
         ArrayList<String> groups=new ArrayList<>();
         groups.add(groupSusbcribe);
         Log.d(TAG,"Group unaffiliation initialized: "+groupSusbcribe);
         return unAffiliationGroups( context,groups);
     }
 
     public String unAffiliationGroups(Context context,List<String> groupsSusbcribe){
         if(groupsSusbcribe==null || groupsSusbcribe.isEmpty()){
             Log.e(TAG,"Invalid configuration.");
             return null;
         }
         byte[] bytes=null;
         Presence presence=null;
         if(!USE_VERSION_OLD_AFFILIATION){
             presence=generatePif(groupsSusbcribe,context,getPresenceNow(),false);
         }else{
             presence=generatePif(groupsSusbcribe,context);
         }
175b478c
         if(presence!=null)
c732d49e
         try {
             bytes=AffiliationUtils.getBytesOfPresenceForAffiliation(context,presence);
         } catch (Exception e) {
             Log.e(TAG,"Invalid pidf+xml.");
             return null;
         }
         String impu=null;
         NgnSipPrefrences profileNow=NgnEngine.getInstance().getProfilesService().getProfileNow(context);
         if(profileNow!=null)impu=profileNow.getIMPU();
         if(mSessionPublication==null && impu!=null){
             mSessionPublication= MyPublicationAffiliationSession.createOutgoingSession(NgnEngine.getInstance().getSipService().getSipStack(),impu);
         }else{
             Log.d(TAG,"Publication is different than NULL.");
         }
         boolean result=false;
         if(!USE_VERSION_OLD_AFFILIATION){
             //use new version.
 
             if(bytes==null){
                 result=mSessionPublication.unPublish(bytes,context);
             }else{
                 result=mSessionPublication.publish(bytes,context);
             }
         }else{
             result=mSessionPublication.unPublish(bytes,context);
 
         }
         if(result && stringPresenceMap!=null){
             if(presence!=null){
                 stringPresenceMap.put(presence.getPId(),presence);
                 return presence.getPId();
             }else{
                 return "";
             }
         }else{
             Log.e(TAG,"Error sending publication.");
         }
         return null;
     }
 
 
     public String affiliationGroup(Context context,String groupSusbcribe){
         if(context==null || groupSusbcribe==null)return null;
         Log.d(TAG,"Init Affiliation->"+groupSusbcribe);
         ArrayList<String> groups=new ArrayList<>();
         groups.add(groupSusbcribe.trim());
         return affiliationGroups( context,groups);
     }
 
     public String affiliationGroups(Context context,List<String> groupsSusbcribe){
         if(groupsSusbcribe==null || groupsSusbcribe.isEmpty())return null;
 
         if(!isSubscribed){
             Log.d(TAG,"Now,it isn´t subcribe");
             if(affiliationGroupDelay==null)affiliationGroupDelay=new ArrayList();
             affiliationGroupDelay.addAll(groupsSusbcribe);
             return null;
         }
 
         byte[] bytes=null;
         Presence presence=generatePif(groupsSusbcribe,context,getPresenceNow(),true);
         try {
             bytes=AffiliationUtils.getBytesOfPresenceForAffiliation(context,presence);
         } catch (Exception e) {
             Log.e(TAG,"Invalid pidf+xml.");
             return null;
         }
 
         String impu=null;
         NgnSipPrefrences profileNow= NgnEngine.getInstance().getProfilesService().getProfileNow(context);
         if(profileNow!=null)impu=profileNow.getIMPU();
         if(bytes==null || bytes.length==0)return null;
         if(mSessionPublication==null && impu!=null)
             mSessionPublication= MyPublicationAffiliationSession.createOutgoingSession(NgnEngine.getInstance().getSipService().getSipStack(),impu);
         boolean result=mSessionPublication.publish(bytes,context);
         if(result){
             stringPresenceMap.put(presence.getPId(),presence);
             return presence.getPId();
         }
         return null;
     }
 
     /**
      * @param groupsSusbcribe
      * @param context
      * @return
      */
     private Presence generatePif(List<String> groupsSusbcribe,Context context){
        return generatePif(groupsSusbcribe,context,null,true);
     }
 
     /**
      * Function to create the PIF (generate new pif or use an old pif+xml).
      * @param groupsSusbcribe
      * @param context
      * @param presence
      * @return
      */
     private  Presence generatePif(List<String> groupsSusbcribe,Context context,Presence presence,boolean affiliate){
         if(groupsSusbcribe==null || groupsSusbcribe.isEmpty())return null;
         ArrayList<AffiliationType> affiliationTypes;
         Tuple tuple;
         Status status;
 
         if(presence!=null && presence.getTuple()!=null &&
                 presence.getTuple().size()>0 &&
                 (tuple=presence.getTuple().get(0))!=null &&
                 (status=tuple.getStatus())!=null &&
175b478c
                 (status.getAffiliations()!=null) && (new ArrayList<>(status.getAffiliations()))!=null
c732d49e
                 ){
             Log.d(TAG,"Using the old presence.");
         }else{
             if(presence==null){
                 Log.d(TAG,"Generating new presence for affiliation process.");
             }else{
                 Log.e(TAG,"Invalid current presence. New one generated.");
             }
 
         }
 
         String mcpttID=null;
         Presence presence2=new Presence();
         NgnSipPrefrences profileNow= NgnEngine.getInstance().getProfilesService().getProfileNow(context);
         if(profileNow!=null)mcpttID=profileNow.getMcpttId();
         presence2.setEntity(mcpttID);
         tuple=new Tuple();
         String mcpttClientID=null;
         if(profileNow!=null)mcpttClientID=profileNow.getMcpttClientId();
         tuple.setId(mcpttClientID);
         status=new Status();
         affiliationTypes=new ArrayList<>();
         status.setAffiliations(affiliationTypes);
         tuple.setStatus(status);
         ArrayList<Tuple> tuples=new ArrayList<>();
         tuples.add(tuple);
         String pid=mcpttID+Calendar.getInstance().getTimeInMillis();
         presence2.setPId(pid);
         presence2.setTuple(tuples);
175b478c
         Tuple tupleRemote=null;
c732d49e
         if(affiliate){
             if(presence!=null && presence.getTuple()!=null &&
175b478c
                     presence.getTuple().size()>0)
             for(Tuple tupleRemote2:presence.getTuple()){
                 if(profileNow.getMcpttClientId()!=null && tupleRemote2.getId()!=null && tupleRemote2.getId().compareTo(profileNow.getMcpttClientId())==0){
                     tupleRemote=tupleRemote2;
                 }
             }
             if((tupleRemote!=null &&
                     (status=tupleRemote.getStatus())!=null
                     && status.getAffiliations()!=null
                     )){
                 affiliationTypes=new ArrayList<>(status.getAffiliations());
c732d49e
 
             }else{
                 affiliationTypes=new ArrayList<>();
             }
             for(String group:groupsSusbcribe){
175b478c
                 if(/*AffiliationUtils.isValidURISIP(group) &&*/ checkGroupStatus(affiliationTypes,group)<0){
c732d49e
                     AffiliationType affiliationType=new AffiliationType();
                     affiliationType.setGroup(group);
                     affiliationTypes.add(affiliationType);
                 }
             }
             presence2.getTuple().get(0).getStatus().setAffiliations(createListAffiliationType(affiliationTypes));
         }else{
             //unaffiliate
175b478c
 
             if(presence!=null){
                 affiliationTypes=new ArrayList<>(presence.getTuple().get(0).getStatus().getAffiliations());
             }else{
                 affiliationTypes=new ArrayList<>();
             }
c732d49e
             for(String group:groupsSusbcribe){
                 int index=-1;
                 if((index=checkGroupStatus(affiliationTypes,group))>=0 && affiliationTypes.size()>index){
                     Log.d(TAG,"unaffiliate");
                     affiliationTypes.remove(index);
                 }else{
                     Log.e(TAG,"Error unaffiliating "+index);
                 }
             }
             if(affiliationTypes.size()==0){
                 Log.d(TAG,"Device does not have any affiliation group.");
                 return null;
             }
             presence2.getTuple().get(0).getStatus().setAffiliations(createListAffiliationType(affiliationTypes));
             if(affiliationTypes.size()==0){
                 presence2=null;
             }
         }
 
 
         return presence2;
     }
 
     private int checkGroupStatus(ArrayList<AffiliationType> affiliationTypes,String group){
         if(group==null && affiliationTypes==null){
             Log.e(TAG, "Error checking group affiliations parameters.");
             return -1;
         }
         if(affiliationTypes!=null){
             for(int con=0;con<affiliationTypes.size();con++){
                 if(affiliationTypes.get(con).getGroup().compareTo(group)==0){
                     return con;
                 }
             }
         }
 
         return -1;
 
     }
 
     private  List<AffiliationType> createListAffiliationType( List<AffiliationType> affiliationTypes){
         ArrayList<AffiliationType> result=new ArrayList<>();
         for(AffiliationType affiliationType:affiliationTypes){
             result.add(new AffiliationType(affiliationType.getGroup()));
         }
         return result;
     }
 
     //END Publication
 
     //INIT service affiliation
 
 
     /**
      * Executed when the service starts
      */
     public void startServiceAffiliation(Context context){
         //Start Service
 
         if(isAffiliation(context)){
             affilitionChange(true);
         }
     }
 
     /**
      * Executed when the service starts
      */
     public void startServiceAffiliation(){
         //Start Service
         Log.d(TAG,"Start affiliation service.");
         handlerStartAffiliation = new Handler(Looper.getMainLooper());
         runnableStartAffiliation=new Runnable() {
             @Override
             public void run() {
                 if(isAffiliation(NgnApplication.getContext())){
                     affilitionChange(true);
                 }
             }
         };
         handlerStartAffiliation.postDelayed(runnableStartAffiliation, DELAY_ACTION_AFFILIATION_MSEC);
     }
 
     /**
      * Executed when the service stops
      */
     public void stopServiceAffiliation(){
         //Stop Serveice
         //affilitionChange(false);
     }
 
 
 
     private void unRegister(){
         try {
175b478c
             if(broadcastReceiverAffiliationMessage!=null){
                 NgnApplication.getContext().unregisterReceiver(broadcastReceiverAffiliationMessage);
                 broadcastReceiverAffiliationMessage=null;
             }
             if(BuildConfig.DEBUG)Log.d(TAG,"Unregisted: broadcastReceiverAffiliationMessage");
c732d49e
         }catch (Exception e){
             Log.e(TAG,"Error1:"+e.getMessage());
         }
 
     }
 
     public Presence getPresenceNow() {
         return presenceNow;
     }
 
     public void setPresenceNow(Presence presenceNow) {
         this.presenceNow = presenceNow;
     }
 
     public void setOnAffiliationServiceListener(OnAffiliationServiceListener onAffiliationServiceListener){
         this.onAffiliationServiceListener=onAffiliationServiceListener;
 
     }
 
     //Init affiliation action
     private void receiveNewPresence(Presence presence) {
         if(BuildConfig.DEBUG)Log.d(TAG,"receiveNewPresence");
         if(onAffiliationServiceListener!=null){
             onAffiliationServiceListener.receiveNewPresence( presence);
         }else{
             if(BuildConfig.DEBUG)Log.d(TAG,"No define interface affiliation");
         }
     }
 
     private void receiveNewPresenceResponse(Presence presence, String pid) {
         if(BuildConfig.DEBUG)Log.d(TAG,"receiveNewPresence:"+pid);
         presenceNowDelay=presence;
         pidNowDelay=pid;
         if(onAffiliationServiceListener!=null){
             onAffiliationServiceListener.receiveNewPresenceResponse( presenceNowDelay, pidNowDelay);
         }else{
             if(BuildConfig.DEBUG)Log.d(TAG,"No define interface affiliation");
         }
     }
 
     private void expireAffiliations(Map<String, String> expires) {
         expiresNowDelay=expires;
         if(onAffiliationServiceListener!=null)onAffiliationServiceListener.expireAffiliations(expiresNowDelay);
     }
 
     private void receiveNewSelfAffiliation(CommandList commandList) {
         commandListNowDelay=commandList;
         if(onAffiliationServiceListener!=null)onAffiliationServiceListener.receiveNewSelfAffiliation( commandListNowDelay);
     }
 
     private void startNewService() {
         if(onAffiliationServiceListener!=null)onAffiliationServiceListener.startNewServiceAffiliation();
 
     }
     //end affiliation action
 
 
 
 
     //END service affiliation
 
     //INIT affiliation automatically
 
     public void processingCommandList(Context context,CommandList commandList){
         if(commandList==null || !AffiliationUtils.isSelfAffiliation(context)){
             return;
         }
         //Send to GUI from the client.
         //Affiliation
         if(commandList.getAffiliate()!=null && commandList.getAffiliate().getGroup()!=null){
             List<String> groups=AffiliationUtils.isValidURIsSIP(new ArrayList<String>(commandList.getAffiliate().getGroup()));
             if(groups!=null)affiliationGroups(context,groups);
         }
         //Deaffiliation
         if(commandList.getDeAffiliate()!=null && commandList.getDeAffiliate().getGroup()!=null){
             List<String> groups=AffiliationUtils.isValidURIsSIP(new ArrayList<String>(commandList.getDeAffiliate().getGroup()));
             if(groups!=null)unAffiliationGroups(context,groups);
         }
     }
 
     //END affiliation automatically
 
     //INIT checkExpire
     private void checkExpire(){
         if(isCheckExpiredActive()) {
             handlerService = new Handler();
             handlerService.postDelayed(new Runnable() {
                 @Override
                 public void run() {
                     if (isStart && mExpiresMap.size() > 0) {
                         checkExpire();
                     }
                 }
             }, DEFAULT_SECOS_BETWEEN_CHECK_EXPIRES * 1000);
             checkExpire(Calendar.getInstance().getTime());
         }
     }
     private void checkExpire(Date date){
         Map<String,String> expires=new HashMap<>();
         expires=checkExpire(date,expires);
         if(expires!=null && expires.size()>0){
            expireAffiliations(expires);
         }
     }
 
     private Map<String,String> checkExpire(Date date,Map<String,String> expires){
         if(mExpiresMap==null)return null;
         Map.Entry<Long, Map<String,String>> hashMapEntry= mExpiresMap.firstEntry();
         if(hashMapEntry==null)return expires;
         Long time=hashMapEntry.getKey();
         if(date.getTime()>=time){
             Map<String,String> arrayList=hashMapEntry.getValue();
             if(arrayList!=null)arrayList.putAll(expires);
             mExpiresMap.remove(time);
             return checkExpire(date,arrayList);
         }else{
             return expires;
         }
     }
     public void addNewOrChangeTimeExpire(List<AffiliationType> affiliationTypes){
         mExpiresMap=new TreeMap<>();
         if(affiliationTypes==null)return;
         for(AffiliationType  affiliationType:affiliationTypes){
             if(affiliationType!=null && affiliationType.getStatus()== StatusType.affiliated){
                 String group=affiliationType.getGroup();
                 Date date=affiliationType.getExpiresDate();
                 if(group!=null && date!=null){
                     Map<String,String> strings=mExpiresMap.get(date.getTime());
                     if(strings==null){
                         strings=new HashMap<>();
                         mExpiresMap.put(date.getTime(),strings);
                     }
                     strings.put(group,group);
                 }
 
             }
         }
         checkExpire();
     }
     //END checkExpire
 
 
     private boolean isCheckExpiredActive() {
         return checkExpiredActive;
     }
 
     public boolean isAffiliation(Context context){
         NgnSipPrefrences profileNow=NgnEngine.getInstance().getProfilesService().getProfileNow(context);
         if(profileNow==null || profileNow.isMcpttIsEnableAffiliation()==null)return false;
         return profileNow.isMcpttIsEnableAffiliation();
     }
 
     @Override
     public boolean clearService(){
         Log.d(TAG,"Clear:  "+"LocalizationService");
         if(presenceNow!=null)presenceNow=null;
         return true;
     }
 }