diff --git a/rcs_service_aidl/src/com/suntek/mway/rcs/client/aidl/capability/RCSCapabilities.java b/rcs_service_aidl/src/com/suntek/mway/rcs/client/aidl/capability/RCSCapabilities.java
index a28ad90..28bbdd4 100644
--- a/rcs_service_aidl/src/com/suntek/mway/rcs/client/aidl/capability/RCSCapabilities.java
+++ b/rcs_service_aidl/src/com/suntek/mway/rcs/client/aidl/capability/RCSCapabilities.java
@@ -22,14 +22,13 @@
  */
 package com.suntek.mway.rcs.client.aidl.capability;
 
-import java.io.Serializable;
-import java.util.ArrayList;
-
 import com.suntek.mway.rcs.client.aidl.constant.APIConstant;
 
 import android.os.Parcel;
 import android.os.Parcelable;
 
+import java.io.Serializable;
+
 /**
  * <p>Title: RCSCapabilities class</p>
  * <p>
@@ -47,9 +46,8 @@
  *
  */
 public class RCSCapabilities implements Parcelable,Serializable {
-    /**
-     *
-     */
+    
+    /** The Constant serialVersionUID. */
     private static final long serialVersionUID = 5516256269504150135L;
 
     /**
@@ -154,35 +152,29 @@
      */
     private boolean pageModeMsgSupported = false;
 
-    /**
-     * large mode message
-     */
+    /** large mode message. */
     private boolean largeModeMsgSupported = false;
 
-    /**
-     * public message
-     */
+    /** public message. */
     private boolean publicMsgSupported = false;
 
-    /**
-     * vemotion
-     */
+    /** vemotion. */
     private boolean vemotionSupported = false;
+    
+    /** cloudFile. */
+    private boolean cloudFileSupported = false;
 
-    /**
-     * cmcc
-     */
+    /** cmcc. */
     private boolean cmccSupported = false;
 
+    /** The burn after reading. */
     private boolean burnAfterReading = false;
 
-    /**
-     * Last capabilities update
-     */
+    /** Last capabilities update. */
     private long timestamp = System.currentTimeMillis();
 
     /**
-     * Constructor
+     * Constructor.
      */
     public RCSCapabilities() {
     }
@@ -212,6 +204,7 @@
         this.largeModeMsgSupported = source.readInt() != 0;
         this.publicMsgSupported = source.readInt() != 0;
         this.vemotionSupported = source.readInt() != 0;
+        this.cloudFileSupported = source.readInt() != 0;
         this.cmccSupported = source.readInt() != 0;
         this.burnAfterReading = source.readInt() != 0;
         //this.sipAutomata = source.readInt() != 0;
@@ -220,7 +213,7 @@
 
     /**
      * Describe the kinds of special objects contained in this Parcelable's
-     * marshalled representation
+     * marshalled representation.
      *
      * @return Integer
      */
@@ -229,7 +222,7 @@
     }
 
     /**
-     * Write parcelable object
+     * Write parcelable object.
      *
      * @param dest The Parcel in which the object should be written
      * @param flags Additional flags about how the object should be written
@@ -254,6 +247,7 @@
         dest.writeInt(largeModeMsgSupported ? 1 : 0);
         dest.writeInt(publicMsgSupported ? 1 : 0);
         dest.writeInt(vemotionSupported ? 1 : 0);
+        dest.writeInt(cloudFileSupported ? 1 : 0);
         dest.writeInt(cmccSupported ? 1 : 0);
         dest.writeInt(burnAfterReading ? 1 : 0);
         //dest.writeInt(sipAutomata ? 1 : 0);
@@ -275,7 +269,7 @@
     };
 
     /**
-     * Is image sharing supported
+     * Is image sharing supported.
      *
      * @return Boolean
      */
@@ -365,7 +359,7 @@
     }
 
     /**
-     * Set the IM session support
+     * Set the IM session support.
      *
      * @param supported Supported
      */
@@ -374,7 +368,7 @@
     }
 
     /**
-     * Is file transfer supported
+     * Is file transfer supported.
      *
      * @return Boolean
      */
@@ -383,7 +377,7 @@
     }
 
     /**
-     * Set the file transfer support
+     * Set the file transfer support.
      *
      * @param supported Supported
      */
@@ -392,7 +386,7 @@
     }
 
     /**
-     * Is CS video supported
+     * Is CS video supported.
      *
      * @return Boolean
      */
@@ -485,7 +479,7 @@
     }
 
     /**
-     * Set the Geolocation Pull support
+     * Set the Geolocation Pull support.
      *
      * @param supported Supported
      */
@@ -494,7 +488,7 @@
     }
 
     /**
-     * Is Geolocation Pull supported
+     * Is Geolocation Pull supported.
      *
      * @return Boolean
      */
@@ -503,7 +497,7 @@
     }
 
     /**
-     * Set the Geolocation Push support
+     * Set the Geolocation Push support.
      *
      * @param supported Supported
      */
@@ -512,7 +506,7 @@
     }
 
     /**
-     * Is file transfer thumbnail supported
+     * Is file transfer thumbnail supported.
      *
      * @return Boolean
      */
@@ -521,7 +515,7 @@
     }
 
     /**
-     * Set the file transfer thumbnail support
+     * Set the file transfer thumbnail support.
      *
      * @param supported Supported
      */
@@ -530,7 +524,7 @@
     }
 
     /**
-     * Is file transfer S&F supported
+     * Is file transfer S&F supported.
      *
      * @return Boolean
      */
@@ -540,7 +534,7 @@
     }
 
     /**
-     * Set the file transfer S&F support
+     * Set the file transfer S&F support.
      *
      * @param supported Supported
      */
@@ -550,7 +544,7 @@
     }
 
     /**
-     * Is group chat S&F supported
+     * Is group chat S&F supported.
      *
      * @return Boolean
      */
@@ -559,7 +553,7 @@
     }
 
     /**
-     * Set the group chat S&F support
+     * Set the group chat S&F support.
      *
      * @param supported Supported
      */
@@ -568,7 +562,8 @@
     }
 
     /**
-     * Is device an automata ?
+     * Is device an automata ?.
+     *
      * @return True if automata
      */
     /*
@@ -596,95 +591,124 @@
     }
 
     /**
-     * Set page mode message
-     * @param pageModeMsg
+     * Set page mode message.
+     *
+     * @param pageModeMsg the new page mode msg supported
      */
     public void setPageModeMsgSupported(boolean pageModeMsg) {
         this.pageModeMsgSupported = pageModeMsg;
     }
 
     /**
-     * large mode message or not
-     * @return
+     * large mode message or not.
+     *
+     * @return true, if is large mode msg supported
      */
     public boolean isLargeModeMsgSupported() {
         return largeModeMsgSupported;
     }
 
     /**
-     * set large mode message
-     * @param largeModeMsg
+     * set large mode message.
+     *
+     * @param largeModeMsg the new large mode msg supported
      */
     public void setLargeModeMsgSupported(boolean largeModeMsg) {
         this.largeModeMsgSupported = largeModeMsg;
     }
 
     /**
-     * public message or not
-     * @return
+     * public message or not.
+     *
+     * @return true, if is public msg supported
      */
     public boolean isPublicMsgSupported() {
         return publicMsgSupported;
     }
 
     /**
-     * set public message
-     * @param publicMsg
+     * set public message.
+     *
+     * @param publicMsg the new public msg supported
      */
     public void setPublicMsgSupported(boolean publicMsg) {
         this.publicMsgSupported = publicMsg;
     }
 
     /**
-     * ve motion or not
-     * @return
+     * ve motion or not.
+     *
+     * @return true, if is vemotion supported
      */
     public boolean isVemotionSupported() {
         return vemotionSupported;
     }
 
     /**
-     * set ve motion
-     * @param vemotion
+     * set ve motion.
+     *
+     * @param vemotion the new vemotion supported
      */
     public void setVemotionSupported(boolean vemotion) {
         this.vemotionSupported = vemotion;
     }
+    
+    /**
+     * Checks if is cloud file supported.
+     *
+     * @return true, if is cloud file supported
+     */
+    public boolean isCloudFileSupported() {
+        return cloudFileSupported;
+    }
 
     /**
-     * group management(modify group name, kick people, transfer the group) nor not
-     * @return
+     * Sets the cloud file supported.
+     *
+     * @param cloudFileSupported the new cloud file supported
+     */
+    public void setCloudFileSupported(boolean cloudFileSupported) {
+        this.cloudFileSupported = cloudFileSupported;
+    }
+
+    /**
+     * group management(modify group name, kick people, transfer the group) nor not.
+     *
+     * @return true, if is cmcc supported
      */
     public boolean isCmccSupported() {
         return cmccSupported;
     }
 
     /**
-     * set group management
-     * @param cmcc
+     * set group management.
+     *
+     * @param cmcc the new cmcc supported
      */
     public void setCmccSupported(boolean cmcc) {
         this.cmccSupported = cmcc;
     }
 
     /**
-     * Checks is burn after reading
-     * @return
+     * Checks is burn after reading.
+     *
+     * @return true, if is burn after reading
      */
     public boolean isBurnAfterReading() {
         return burnAfterReading;
     }
 
     /**
-     * Set burn after reading
-     * @param burnAfterReading
+     * Set burn after reading.
+     *
+     * @param burnAfterReading the new burn after reading
      */
     public void setBurnAfterReading(boolean burnAfterReading) {
         this.burnAfterReading = burnAfterReading;
     }
 
     /**
-     * Get the capabilities timestamp
+     * Get the capabilities timestamp.
      *
      * @return Timestamp (in milliseconds)
      */
@@ -693,16 +717,16 @@
     }
 
     /**
-     * Set capabilities timestamp
+     * Set capabilities timestamp.
      *
-     * @param Timestamp
+     * @param timestamp the new timestamp
      */
     public void setTimestamp(long timestamp) {
         this.timestamp = timestamp;
     }
 
     /**
-     * Returns a string representation of the object
+     * Returns a string representation of the object.
      *
      * @return String
      */
@@ -730,6 +754,7 @@
             ", largeModeMsg=" + largeModeMsgSupported +
             ", publicMsg=" + publicMsgSupported +
             ", vemotion=" + vemotionSupported +
+            ", cloudFile=" + cloudFileSupported +
             ", cmcc=" + cmccSupported +
             ", burnAfterReading=" + burnAfterReading +
             //", SipAutomata=" + sipAutomata +
diff --git a/rcs_service_aidl/src/com/suntek/mway/rcs/client/aidl/constant/BroadcastConstants.java b/rcs_service_aidl/src/com/suntek/mway/rcs/client/aidl/constant/BroadcastConstants.java
index ad745aa..bc49fe5 100644
--- a/rcs_service_aidl/src/com/suntek/mway/rcs/client/aidl/constant/BroadcastConstants.java
+++ b/rcs_service_aidl/src/com/suntek/mway/rcs/client/aidl/constant/BroadcastConstants.java
@@ -53,6 +53,8 @@
 
     /** Notify UI that group operation failed. */
     public static final String UI_GROUP_ERROR = "com.suntek.mway.rcs.ACTION_UI_GROUP_ERROR";
+    
+    public static final String UI_GROUP_NOT_FOUND = "com.suntek.mway.rcs.ACTION_UI_GROUP_NOTFOUND";
 
     /** Notify UI that group state is invalid contains parameter groupId, state. */
     public static final String UI_GROUP_STATE_ERROR = "com.suntek.mway.rcs.ACTION_UI_GROUP_STATE_ERROR";
diff --git a/rcs_service_aidl/src/com/suntek/mway/rcs/client/aidl/im/IGroupManagerApi.aidl b/rcs_service_aidl/src/com/suntek/mway/rcs/client/aidl/im/IGroupManagerApi.aidl
index 418957b..54e6d91 100644
--- a/rcs_service_aidl/src/com/suntek/mway/rcs/client/aidl/im/IGroupManagerApi.aidl
+++ b/rcs_service_aidl/src/com/suntek/mway/rcs/client/aidl/im/IGroupManagerApi.aidl
@@ -32,24 +32,24 @@
 
     String createGroupChat(String subject, in List<String> users);
 
-    void agreeToJoinGroup(String conversationId, String contributionId,
+    int agreeToJoinGroup(String conversationId, String contributionId,
             String chatUri, String subject, String numberData, long inviteTime);
 
-    void refuseToJoinGroup(String conversationId);
+    int refuseToJoinGroup(String conversationId);
 
-    void updateGroupSubject(String groupId, String newSubject);
+    int updateGroupSubject(String groupId, String newSubject);
 
     void modifyGroupMemo(String groupId, String memo);
 
-    void disbandGroupChat(String groupId);
+    int disbandGroupChat(String groupId);
 
-    void kickedOutOfGroupChat(String groupId, String number);
+    int kickedOutOfGroupChat(String groupId, String number);
 
-    void assignGroupChairman(String groupId, String number);
+    int assignGroupChairman(String groupId, String number);
 
-    void quitGroupChat(String groupId, String number);
-    void quitGroupChatEx(String groupId, String oldChairman, String newChairman);
-    void setMyAlias(String groupId, String alias);
+    int quitGroupChat(String groupId, String number);
+    int quitGroupChatEx(String groupId, String oldChairman, String newChairman);
+    int setMyAlias(String groupId, String alias);
 
     String getGroupChatMemberDisplayName(String groupId, String number);
 
@@ -62,9 +62,9 @@
 
     GroupChatUser getGroupChairman(String groupId);
 
-    void inviteOneMemberToGroupChat(String groupId, String number);
+    int inviteOneMemberToGroupChat(String groupId, String number);
 
-    void inviteToJoinGroupChat(String groupId, in List<String> numbers);
+    int inviteToJoinGroupChat(String groupId, in List<String> numbers);
     
     GroupChatModel getLastGroupModel();
     
@@ -83,7 +83,9 @@
 
     String getPublicAccountDomainName();
 
-    void refuseAssigedAsChairman(String chatUri, long inviteTime, String conversationId, String contributionId);
+    int refuseAssigedAsChairman(String chatUri, long inviteTime, String conversationId, String contributionId);
 
-    void acceptAssignedAsChairman(String chatUri, long inviteTime, String conversationId, String contributionId);
+    int acceptAssignedAsChairman(String chatUri, long inviteTime, String conversationId, String contributionId);
+    
+    int rejoinGroupChat(String chatUri);
 }
diff --git a/rcs_service_aidl/src/com/suntek/mway/rcs/client/aidl/im/IInstantMessageApi.aidl b/rcs_service_aidl/src/com/suntek/mway/rcs/client/aidl/im/IInstantMessageApi.aidl
index b98ac5d..0d2cde3 100644
--- a/rcs_service_aidl/src/com/suntek/mway/rcs/client/aidl/im/IInstantMessageApi.aidl
+++ b/rcs_service_aidl/src/com/suntek/mway/rcs/client/aidl/im/IInstantMessageApi.aidl
@@ -68,16 +68,24 @@
             String groupId);
     void sendGroupImageFile(long thread_id, String conversationId,long sms_id,String filepath,
             String groupId, int quality);
+    long sendGroupImageFileSync(long thread_id, String conversationId,long sms_id,String filepath,
+            String groupId, int quality);
     void sendGroupAudioFile(long thread_id, String conversationId,long sms_id,String filepath,
             int recordTime ,String groupId);
+    long sendGroupAudioFileSync(long thread_id, String conversationId,long sms_id,String filepath,
+            int recordTime ,String groupId);
     void sendGroupVideoFile(long thread_id, String conversationId,long sms_id,String filepath,
             int  length ,String groupId);
+    long sendGroupVideoFileSync(long thread_id, String conversationId,long sms_id,String filepath,
+            int  length ,String groupId);
     void sendGroupLocation(long thread_id,String conversationId,long sms_id, double lat,
             double lng,String text,String groupId);
     void sendGroupVCard(long thread_id,String conversationId,long sms_id,
             in RCSContact rcsContact,String groupId);
     void sendGroupVCardByPath(long thread_id,String conversationId,long sms_id,
             String vcardFilePath,String groupId);
+    long sendGroupVCardByPathSync(long thread_id,String conversationId,long sms_id,
+            String vcardFilePath,String groupId);
             
     void acceptFile(in ChatMessage chatMessage);
     boolean interruptFile(in ChatMessage chatMessage);
diff --git a/rcs_service_aidl/src/com/suntek/mway/rcs/client/aidl/im/OprResponse.java b/rcs_service_aidl/src/com/suntek/mway/rcs/client/aidl/im/OprResponse.java
new file mode 100644
index 0000000..3400cce
--- /dev/null
+++ b/rcs_service_aidl/src/com/suntek/mway/rcs/client/aidl/im/OprResponse.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2015 pci-suntektech Technologies, Inc.  All Rights Reserved.
+ * pci-suntektech Technologies Proprietary and Confidential.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+package com.suntek.mway.rcs.client.aidl.im;
+
+public class OprResponse {
+
+    public static final int SUCCESS = 200;
+    
+    public static final int OFFLINE = 900;
+    
+    public static final int OTHRE_ERROR = 999;
+    
+}
diff --git a/rcs_service_aidl/src/com/suntek/mway/rcs/client/aidl/plugin/IPublicAccountAPI.aidl b/rcs_service_aidl/src/com/suntek/mway/rcs/client/aidl/plugin/IPublicAccountAPI.aidl
index ad2d56f..388f2b6 100644
--- a/rcs_service_aidl/src/com/suntek/mway/rcs/client/aidl/plugin/IPublicAccountAPI.aidl
+++ b/rcs_service_aidl/src/com/suntek/mway/rcs/client/aidl/plugin/IPublicAccountAPI.aidl
@@ -116,15 +116,8 @@
 
     /**
      * query the user had follow public account.
-     *
-     * @param order            the query result order, default is 0, 0 is desc order by the
-     *            follow time; 1 is order by the public account name
-     * @param pageSize            the query result page size
-     * @param pageNum            the query result page number
-     * @return the query result will return by asynchronous callback, here only
-     *         return invoke result if it has exception
      */
-    boolean getUserSubscribePublicList( int order, int pageSize, int pageNum );
+    boolean getUserSubscribePublicList();
 
     /**
      * parse response message to message content entity json string.
diff --git a/rcs_service_aidl/src/com/suntek/mway/rcs/client/aidl/plugin/callback/PublicAccountCallback.java b/rcs_service_aidl/src/com/suntek/mway/rcs/client/aidl/plugin/callback/PublicAccountCallback.java
new file mode 100644
index 0000000..2a39fda
--- /dev/null
+++ b/rcs_service_aidl/src/com/suntek/mway/rcs/client/aidl/plugin/callback/PublicAccountCallback.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2015 pci-suntektech Technologies, Inc.  All Rights Reserved.
+ * pci-suntektech Technologies Proprietary and Confidential.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+package com.suntek.mway.rcs.client.aidl.plugin.callback;
+
+import com.suntek.mway.rcs.client.aidl.plugin.callback.IPublicAccountCallbackAPI;
+import com.suntek.mway.rcs.client.aidl.plugin.entity.pubacct.MenuInfoMode;
+import com.suntek.mway.rcs.client.aidl.plugin.entity.pubacct.MsgContent;
+import com.suntek.mway.rcs.client.aidl.plugin.entity.pubacct.PublicAccounts;
+import com.suntek.mway.rcs.client.aidl.plugin.entity.pubacct.PublicAccountsDetail;
+
+import android.os.RemoteException;
+
+import java.util.List;
+
+public abstract class PublicAccountCallback extends IPublicAccountCallbackAPI.Stub{
+
+
+//    public void PublicAccountCallback() {
+//
+//    }
+//    @Override
+//    public void respAddSubscribe(boolean arg0) throws RemoteException {
+//        // TODO Auto-generated method stub
+//
+//    }
+
+    @Override
+    public void respAddSubscribeAccount(boolean arg0, PublicAccounts arg1)
+            throws RemoteException {
+        // TODO Auto-generated method stub
+
+    }
+
+//    @Override
+//    public void respCancelSubscribe(boolean arg0) throws RemoteException {
+//        // TODO Auto-generated method stub
+//
+//    }
+
+    @Override
+    public void respCancelSubscribeAccount(boolean arg0, PublicAccounts arg1)
+            throws RemoteException {
+        // TODO Auto-generated method stub
+
+    }
+
+//    @Override
+//    public void respComplainPublic(boolean result) throws RemoteException {
+//        // TODO Auto-generated method stub
+//        LogHelper.d("result --> "+result );
+//    }
+
+    @Override
+    public void respComplainPublicAccount(boolean result, PublicAccounts arg1)
+            throws RemoteException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void respGetPreMessage(boolean arg0, List<MsgContent> arg1)
+            throws RemoteException {
+        // TODO Auto-generated method stub
+
+    }
+
+//    @Override
+//    public void respGetPreMessageAccount(boolean result, PublicAccounts pAccount)
+//            throws RemoteException {
+//        // TODO Auto-generated method stub
+//        LogHelper.d("result --> "+result + "PublicAccounts = " + pAccount.getPaUuid()+" , "+pAccount.getSipUri());
+//    }
+
+    @Override
+    public void respGetPublicDetail(boolean arg0, PublicAccountsDetail arg1)
+            throws RemoteException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void respGetPublicList(boolean arg0, List<PublicAccounts> arg1)
+            throws RemoteException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void respGetPublicMenuInfo(boolean result, MenuInfoMode menuInfoMode)
+            throws RemoteException {
+        // TODO Auto-generated method stub
+
+    }
+
+//    @Override
+//    public void respGetPublicMenuInfoAccount(boolean result, PublicAccounts pAccount)
+//            throws RemoteException {
+//        // TODO Auto-generated method stub
+//        LogHelper.d("result --> "+result + "PublicAccounts = " + pAccount.getPaUuid()+" , "+pAccount.getSipUri());
+//
+//    }
+
+//    @Override
+//    public void respGetPublicMenuInfoString(boolean result, String info)
+//            throws RemoteException {
+//        // TODO Auto-generated method stub
+//        LogHelper.d("result --> "+result + "info = " + info);
+//
+//    }
+
+    @Override
+    public void respGetUserSubscribePublicList(boolean result,
+            List<PublicAccounts> pubAcctList) throws RemoteException {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void respGetPublicRecommend(boolean arg0, List<PublicAccounts> arg1)
+            throws RemoteException {
+        // TODO Auto-generated method stub
+
+    }
+    
+    @Override
+    public void respSetAcceptStatus(boolean result, String uuid)
+            throws RemoteException {
+        // TODO Auto-generated method stub
+
+    }
+}
diff --git a/rcs_service_aidl/src/com/suntek/mway/rcs/client/aidl/provider/PublicAccountData.java b/rcs_service_aidl/src/com/suntek/mway/rcs/client/aidl/provider/PublicAccountData.java
index 724a88f..ff123bf 100644
--- a/rcs_service_aidl/src/com/suntek/mway/rcs/client/aidl/provider/PublicAccountData.java
+++ b/rcs_service_aidl/src/com/suntek/mway/rcs/client/aidl/provider/PublicAccountData.java
@@ -34,6 +34,9 @@
 
     /** The Constant TABLE_ACCOUNT. */
     public static final String TABLE_ACCOUNT = "publicAccount";
+    
+    /** The Constant TABLE_ACCOUNT. */
+    public static final String TABLE_ACCOUNT_HIS = "publicAccountHis";
 
     /** The Constant PUBLIC_ACCOUNT_CONTENT_URI. */
     public static final Uri PUBLIC_ACCOUNT_CONTENT_URI = Uri.parse("content://" + PUBLIC_ACCOUNT_AUTHORITY + "/" + TABLE_ACCOUNT);
@@ -106,4 +109,10 @@
 
     /** The Constant ACCOUNT_QRCODE. */
     public static final String ACCOUNT_QRCODE = "_qrCode";
+    
+    /** The Constant ACCOUNT_LOGO_TYPE. */
+    public static final String ACCOUNT_LOGO_TYPE = "_logoType";
+    
+    /** The Constant ACCOUNT_MENU_STRING. */
+    public static final String ACCOUNT_MENU_STRING = "_menuString";
 }
diff --git a/rcs_service_aidl/src/com/suntek/mway/rcs/client/aidl/provider/model/PublicAccount.java b/rcs_service_aidl/src/com/suntek/mway/rcs/client/aidl/provider/model/PublicAccount.java
index 92a024d..0127bfb 100644
--- a/rcs_service_aidl/src/com/suntek/mway/rcs/client/aidl/provider/model/PublicAccount.java
+++ b/rcs_service_aidl/src/com/suntek/mway/rcs/client/aidl/provider/model/PublicAccount.java
@@ -92,6 +92,12 @@
 
     /** The field. */
     private String field;
+    
+    /** The logoType. */
+    private String logoType;
+    
+    /** The menuString. */
+    private String menuString;
 
     /**
      * Gets the pa uuid.
@@ -488,6 +494,42 @@
     public void setField(String field) {
         this.field = field;
     }
+    
+    /**
+     * Gets the logo type.
+     *
+     * @return the logo type
+     */
+    public String getLogoType() {
+        return logoType;
+    }
+
+    /**
+     * Sets the logo type.
+     *
+     * @param logoType the new logo type
+     */
+    public void setLogoType(String logoType) {
+        this.logoType = logoType;
+    }
+
+    /**
+     * Gets the menu string.
+     *
+     * @return the menu string
+     */
+    public String getMenuString() {
+        return menuString;
+    }
+
+    /**
+     * Sets the menu string.
+     *
+     * @param menuString the new menu string
+     */
+    public void setMenuString(String menuString) {
+        this.menuString = menuString;
+    }
 
     /* (non-Javadoc)
      * @see java.lang.Object#toString()
@@ -517,6 +559,8 @@
                .append(",zip=").append(this.zip)
                .append(",addr=").append(this.addr)
                .append(",field=").append(this.field)
+               .append(",logoType=").append(this.logoType)
+               .append(",menuString=").append(this.menuString)
         ;
 
         return sbuffer.toString();
diff --git a/rcs_service_api/src/com/suntek/mway/rcs/client/api/im/impl/MessageApi.java b/rcs_service_api/src/com/suntek/mway/rcs/client/api/im/impl/MessageApi.java
index 02d0542..b3c9cd6 100644
--- a/rcs_service_api/src/com/suntek/mway/rcs/client/api/im/impl/MessageApi.java
+++ b/rcs_service_api/src/com/suntek/mway/rcs/client/api/im/impl/MessageApi.java
@@ -1,1806 +1,1806 @@
-/*
- * Copyright (c) 2014 pci-suntektech Technologies, Inc.  All Rights Reserved.
- * pci-suntektech Technologies Proprietary and Confidential.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-package com.suntek.mway.rcs.client.api.im.impl;
-
-import java.util.List;
-import java.util.Locale;
-
-import android.content.ComponentName;
-import android.content.ServiceConnection;
-import android.os.IBinder;
-import android.text.TextUtils;
-
-import com.suntek.mway.rcs.client.api.ClientApi;
-import com.suntek.mway.rcs.client.aidl.constant.APIConstant;
-import com.suntek.mway.rcs.client.aidl.contacts.RCSContact;
-import com.suntek.mway.rcs.client.api.exception.OperatorException;
-import com.suntek.mway.rcs.client.aidl.im.IInstantMessageApi;
-import com.suntek.mway.rcs.client.aidl.provider.model.ChatMessage;
-import com.suntek.mway.rcs.client.aidl.provider.model.FavoriteMessage;
-import com.suntek.mway.rcs.client.aidl.provider.model.GroupChatModel;
-import com.suntek.mway.rcs.client.aidl.provider.model.MessageSessionModel;
-import com.suntek.mway.rcs.client.aidl.provider.model.SimpleMsg;
-import com.suntek.mway.rcs.client.aidl.provider.model.TopMessageData;
-import com.suntek.mway.rcs.client.api.util.FileDurationException;
-import com.suntek.mway.rcs.client.api.util.FileSuffixException;
-import com.suntek.mway.rcs.client.api.util.FileTransferException;
-import com.suntek.mway.rcs.client.api.util.ServiceDisconnectedException;
-import com.suntek.mway.rcs.client.api.util.VerificationUtil;
-import com.suntek.mway.rcs.client.api.util.log.LogHelper;
-
-public class MessageApi extends ClientApi {
-
-    private static String serviceName = "com.suntek.mway.rcs.app.service.api.impl.im.MessageApiService";
-
-    IInstantMessageApi myApi;
-
-    private ServiceConnection mConnection = new ServiceConnection() {
-        public void onServiceConnected(ComponentName className, IBinder service) {
-            LogHelper.d("client api connect service");
-            notifyServiceConnected();
-            myApi = IInstantMessageApi.Stub.asInterface(service);
-        }
-
-        public void onServiceDisconnected(ComponentName className) {
-            if (isNormallyClosed || reconnectionTimes > MAX_RECONECTION_TIMES) {
-                LogHelper.d("client api disconnect service");
-                myApi = null;
-                notifyServiceDisconnected();
-            } else {
-                LogHelper.d("illegal call client api disconnect service :" + reconnectionTimes);
-                init(context, rcsListener);
-                if (!isBinded()) {
-                    // app is uninstalled
-                    myApi = null;
-                    notifyServiceDisconnected();
-                }
-                reconnectionTimes++;
-            }
-        }
-    };
-
-    public MessageApi() {
-        // TODO Auto-generated constructor stub
-        super(serviceName);
-        super.initServiceConnect(mConnection);
-    }
-
-    public void sendTextMessage(long thread_id, String number, String text, int burnFlag,
-            int barCycle) throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper
-                .i(String.format(
-                        Locale.getDefault(),
-                        "enter method sendTextMessage. [thread_id,number,text,burnFlag,barCycle]=%d,%s,%s,%d,%d",
-                        thread_id, number, text, burnFlag, barCycle));
-        if ("".equals(text.trim())) {
-            LogHelper.i("text value is null/Space");
-            return;
-        }
-        if (!VerificationUtil.isNumber(number)) {
-            LogHelper.i("number field value error");
-            return;
-        }
-        if (!VerificationUtil.isBurnFlagCorrect(burnFlag)) {
-            LogHelper.i("burnFlag field must be 0 or 1");
-            return;
-        }
-        if (barCycle < 0) {
-            LogHelper.i("barCycle field must be a positive int");
-            return;
-        }
-        try {
-            myApi.sendTextMessage(thread_id, VerificationUtil.formatNumber(number), text, burnFlag,
-                    barCycle);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-    }
-
-    public void sendImageFile(long thread_id, long sms_id, String number, String filePath,
-            int burnFlag, int barCycle, int quality) throws ServiceDisconnectedException,
-            FileSuffixException, FileTransferException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper
-                .i(String.format(
-                        Locale.getDefault(),
-                        "enter method sendImageFile. [thread_id,sms_id,number,filePath,burnFlag,barCycle,quality]=%d,%d,%s,%s,%d,%d,%d",
-                        thread_id, sms_id, number, filePath, burnFlag, barCycle, quality));
-        VerificationUtil.isImageFile(filePath);
-
-        if (!VerificationUtil.isNumber(number)) {
-            LogHelper.i("number field value error");
-            return;
-        }
-        if (!VerificationUtil.isBurnFlagCorrect(burnFlag)) {
-            LogHelper.i("burnFlag field must be 0 or 1");
-            return;
-        }
-        if (barCycle < 0) {
-            LogHelper.i("barCycle field must be a positive int");
-            return;
-        }
-        if (quality < 0 || quality > 100) {
-            LogHelper.i("quality field value must be between 0 to 100");
-            return;
-        }
-
-        if (quality == 100) {
-            VerificationUtil.isFileSizeToLarge(filePath, this.getImageFtMaxSize());
-        }
-
-        try {
-            myApi.sendImageFile(thread_id, sms_id, VerificationUtil.formatNumber(number), filePath,
-                    burnFlag, barCycle, quality);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-    }
-
-    public void sendAudioFile(long thread_id, long sms_id, String number, String filePath,
-            int recordTime, int burnFlag, int barCycle, boolean isRecord)
-            throws ServiceDisconnectedException, FileSuffixException, FileTransferException,
-            FileDurationException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper
-                .i(String.format(
-                        Locale.getDefault(),
-                        "enter method sendAudioFile. [thread_id,sms_id,number,filePath,recordTime,burnFlag,barCycle,isRecord]=%d,%d,%s,%s,%d,%d,%d,%b",
-                        thread_id, sms_id, number, filePath, recordTime, burnFlag, barCycle,
-                        isRecord));
-        VerificationUtil.isAudioFile(filePath);
-        if (isRecord) {
-            VerificationUtil.isAudioDurationToLong(context, filePath, this.getAudioMaxTime(),
-                    recordTime);// VerificationUtil.getAudioMaxTime(context)
-        }
-        VerificationUtil.isFileSizeToLarge(filePath, this.getVideoFtMaxSize());// VerificationUtil.getVideoFtMaxSize(context)
-        if (!VerificationUtil.isNumber(number)) {
-            LogHelper.i("number field value error");
-            return;
-        }
-        if (!VerificationUtil.isBurnFlagCorrect(burnFlag)) {
-            LogHelper.i("burnFlag field must be 0 or 1");
-            return;
-        }
-        if (barCycle < 0) {
-            LogHelper.i("barCycle field must be a positive int");
-            return;
-        }
-        try {
-            myApi.sendAudioFile(thread_id, sms_id, VerificationUtil.formatNumber(number), filePath,
-                    recordTime, burnFlag, barCycle);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-    }
-
-    public void sendVideoFile(long thread_id, long sms_id, String number, String filePath,
-            int length, int burnFlag, int barCycle, boolean isRecord)
-            throws ServiceDisconnectedException, FileSuffixException, FileTransferException,
-            FileDurationException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper
-                .i(String.format(
-                        Locale.getDefault(),
-                        "enter method sendVideoFile. [thread_id,sms_id,number,filePath,length,burnFlag,barCycle,isRecord]=%d,%d,%s,%s,%d,%d,%d,%b",
-                        thread_id, sms_id, number, filePath, length, burnFlag, barCycle, isRecord));
-        VerificationUtil.isVideoFile(filePath);
-        if (isRecord) {
-            VerificationUtil.isVedioDurationToLong(context, filePath, this.getVideoMaxTime(),
-                    length);// VerificationUtil.getVideoMaxTime(context)
-        }
-        VerificationUtil.isFileSizeToLarge(filePath, this.getVideoFtMaxSize());// VerificationUtil.getVideoFtMaxSize(context)
-        if (!VerificationUtil.isNumber(number)) {
-            LogHelper.i("number field value error");
-            return;
-        }
-        if (!VerificationUtil.isBurnFlagCorrect(burnFlag)) {
-            LogHelper.i("burnFlag field must be 0 or 1");
-            return;
-        }
-        if (barCycle < 0) {
-            LogHelper.i("barCycle field must be a positive int");
-            return;
-        }
-        try {
-            myApi.sendVideoFile(thread_id, sms_id, VerificationUtil.formatNumber(number), filePath,
-                    length, burnFlag, barCycle);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-    }
-
-    public void sendLocation(long thread_id, long sms_id, String number, double lat, double lng,
-            String text) throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper
-                .i(String.format(
-                        Locale.getDefault(),
-                        "enter method sendLocation. [thread_id,sms_id,number,lat,lng,text]=%d,%d,%s,%f,%f,%s",
-                        thread_id, sms_id, number, lat, lng, text));
-        if (!VerificationUtil.isNumber(number)) {
-            LogHelper.i("number field value error");
-            return;
-        }
-        try {
-            myApi.sendLocation(thread_id, sms_id, VerificationUtil.formatNumber(number), lat, lng,
-                    text);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-    }
-
-    public void sendPaidEmo(long thread_id, long sms_id, String number, String emoid, String emoName)
-            throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper.i(String.format(Locale.getDefault(),
-                "enter method sendPaidEmo. [thread_id,sms_id,number,emoid,emoName]=%d,%d,%s,%s,%s",
-                thread_id, sms_id, number, emoid, emoName));
-        if (!VerificationUtil.isNumber(number)) {
-            LogHelper.i("number field value error");
-            return;
-        }
-        try {
-            myApi.sendPaidEmo(thread_id, sms_id, number, emoid, emoName);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-    }
-
-    public void sendVCard(long thread_id, long sms_id, String number, RCSContact rcsContact)
-            throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper.i(String.format(Locale.getDefault(),
-                "enter method sendVCard. [thread_id,sms_id,number,rcsContact]=%d,%d,%s,%s",
-                thread_id, sms_id, number, rcsContact.toString()));
-        if (!VerificationUtil.isNumber(number)) {
-            LogHelper.i("number field value error");
-            return;
-        }
-        try {
-            myApi.sendVCard(thread_id, sms_id, number, rcsContact);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-    }
-
-    public void sendVCard(long thread_id, long sms_id, String number, String vcardFilePath)
-            throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper.i(String.format(Locale.getDefault(),
-                "enter method sendVCard. [thread_id,sms_id,number,vcardFilePath]=%d,%d,%s,%s",
-                thread_id, sms_id, number, vcardFilePath));
-        if (!VerificationUtil.isNumber(number)) {
-            LogHelper.i("number field value error");
-            return;
-        }
-        try {
-            myApi.sendVCardByPath(thread_id, sms_id, VerificationUtil.formatNumber(number),
-                    vcardFilePath);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-    }
-
-    public void sendOne2ManyTextMessage(long thread_id, List<String> numbers, String text,
-            int burnFlag, int barCycle) throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        if ("".equals(text.trim())) {
-            LogHelper.i("text value is null/Space");
-            return;
-        }
-        LogHelper
-                .i(String.format(
-                        Locale.getDefault(),
-                        "enter method sendOne2ManyTextMessage. [thread_id,numbers,text,burnFlag,barCycle]=%d,%s,%s,%d,%d",
-                        thread_id, numbers.toString(), text, burnFlag, barCycle));
-        if (!VerificationUtil.isAllNumber(numbers)) {
-            LogHelper.i("number field value error");
-            return;
-        }
-        if (!VerificationUtil.isBurnFlagCorrect(burnFlag)) {
-            LogHelper.i("burnFlag field must be 0 or 1");
-            return;
-        }
-        if (barCycle < 0) {
-            LogHelper.i("barCycle field must be a positive int");
-            return;
-        }
-        try {
-            myApi.sendOne2ManyTextMessage(thread_id, VerificationUtil.formatNumbers(numbers), text,
-                    burnFlag, barCycle);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-    }
-
-    public void sendOne2ManyImageFile(long thread_id, long sms_id, List<String> numbers,
-            String filePath, int burnFlag, int barCycle, int quality)
-            throws ServiceDisconnectedException, FileSuffixException, FileTransferException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper
-                .i(String.format(
-                        Locale.getDefault(),
-                        "enter method sendOne2ManyImageFile. [thread_id,sms_id,numbers,filePath,burnFlag,barCycle,quality]=%d,%d,%s,%s,%d,%d,%d",
-                        thread_id, sms_id, numbers.toString(), filePath, burnFlag, barCycle,
-                        quality));
-        VerificationUtil.isImageFile(filePath);
-        if (!VerificationUtil.isAllNumber(numbers)) {
-            LogHelper.i("number field value error");
-            return;
-        }
-        if (!VerificationUtil.isBurnFlagCorrect(burnFlag)) {
-            LogHelper.i("burnFlag field must be 0 or 1");
-            return;
-        }
-        if (barCycle < 0) {
-            LogHelper.i("barCycle field must be a positive int");
-            return;
-        }
-        if (quality < 0 || quality > 100) {
-            LogHelper.i("quality field value must be between 0 to 100");
-            return;
-        }
-
-        if (quality == 100) {
-            VerificationUtil.isFileSizeToLarge(filePath, this.getImageFtMaxSize());
-        }
-
-        try {
-            myApi.sendOne2ManyImageFile(thread_id, sms_id, VerificationUtil.formatNumbers(numbers),
-                    filePath, burnFlag, barCycle, quality);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-    }
-
-    public void sendOne2ManyAudioFile(long thread_id, long sms_id, List<String> numbers,
-            String filePath, int recordTime, int burnFlag, int barCycle, boolean isRecord)
-            throws ServiceDisconnectedException, FileSuffixException, FileTransferException,
-            FileDurationException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper
-                .i(String.format(
-                        Locale.getDefault(),
-                        "enter method sendOne2ManyAudioFile. [thread_id,sms_id,numbers,filePath,recordTime,burnFlag,barCycle,isRecord]=%d,%d,%s,%s,%d,%d,%d,%b",
-                        thread_id, sms_id, numbers.toString(), filePath, recordTime, burnFlag,
-                        barCycle, isRecord));
-        VerificationUtil.isAudioFile(filePath);
-        if (isRecord) {
-            VerificationUtil.isAudioDurationToLong(context, filePath, this.getAudioMaxTime(),
-                    recordTime);
-        }
-        VerificationUtil.isFileSizeToLarge(filePath, this.getVideoFtMaxSize());
-        if (!VerificationUtil.isAllNumber(numbers)) {
-            LogHelper.i("number field value error");
-            return;
-        }
-        if (!VerificationUtil.isBurnFlagCorrect(burnFlag)) {
-            LogHelper.i("burnFlag field must be 0 or 1");
-            return;
-        }
-        if (barCycle < 0) {
-            LogHelper.i("barCycle field must be a positive int");
-            return;
-        }
-        try {
-            myApi.sendOne2ManyAudioFile(thread_id, sms_id, VerificationUtil.formatNumbers(numbers),
-                    filePath, recordTime, burnFlag, barCycle);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-    }
-
-    public void sendOne2ManyVideoFile(long thread_id, long sms_id, List<String> numbers,
-            String filePath, int length, int burnFlag, int barCycle, boolean isRecord)
-            throws ServiceDisconnectedException, FileSuffixException, FileTransferException,
-            FileDurationException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper
-                .i(String.format(
-                        Locale.getDefault(),
-                        "enter method sendOne2ManyVideoFile. [thread_id,sms_id,numbers,filePath,length,burnFlag,barCycle,isRecord]=%d,%d,%s,%s,%d,%d,%d,%b",
-                        thread_id, sms_id, numbers.toString(), filePath, length, burnFlag,
-                        barCycle, isRecord));
-        VerificationUtil.isVideoFile(filePath);
-        if (isRecord) {
-            VerificationUtil.isVedioDurationToLong(context, filePath, this.getVideoMaxTime(),
-                    length);
-        }
-        VerificationUtil.isFileSizeToLarge(filePath, this.getVideoFtMaxSize());
-        if (!VerificationUtil.isAllNumber(numbers)) {
-            LogHelper.i("number field value error");
-            return;
-        }
-        if (!VerificationUtil.isBurnFlagCorrect(burnFlag)) {
-            LogHelper.i("burnFlag field must be 0 or 1");
-            return;
-        }
-        if (barCycle < 0) {
-            LogHelper.i("barCycle field must be a positive int");
-            return;
-        }
-        try {
-            myApi.sendOne2ManyVideoFile(thread_id, sms_id, VerificationUtil.formatNumbers(numbers),
-                    filePath, length, burnFlag, barCycle);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-    }
-
-    public void sendOne2ManyLocation(long thread_id, long sms_id, List<String> numbers, double lat,
-            double lng, String text) throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper
-                .i(String.format(
-                        Locale.getDefault(),
-                        "enter method sendOne2ManyLocation. [thread_id,sms_id,numbers,lat,lng,text]=%d,%d,%s,%f,%f,%s",
-                        thread_id, sms_id, numbers.toString(), lat, lng, text));
-        if (!VerificationUtil.isAllNumber(numbers)) {
-            LogHelper.i("number field value error");
-            return;
-        }
-        try {
-            myApi.sendOne2ManyLocation(thread_id, sms_id, VerificationUtil.formatNumbers(numbers),
-                    lat, lng, text);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-    }
-
-    public void sendGroupMessage(long thread_id, String conversationId, long sms_id, String msg,
-            String groupId) throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        if ("".equals(msg.trim())) {
-            LogHelper.i("msg value is null/Space");
-            return;
-        }
-        LogHelper
-                .i(String.format(
-                        Locale.getDefault(),
-                        "enter method sendGroupMessage. [thread_id,conversationId,sms_id,msg,groupId]=%d,%s,%d,%s,%s",
-                        thread_id, conversationId, sms_id, msg, groupId));
-        try {
-            myApi.sendGroupMessage(thread_id, conversationId, sms_id, msg, groupId);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-    }
-
-    public void sendGroupImageFile(long thread_id, String conversationId, long sms_id,
-            String filepath, String groupId, int quality) throws ServiceDisconnectedException,
-            FileSuffixException, FileTransferException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper
-                .i(String.format(
-                        Locale.getDefault(),
-                        "enter method sendGroupImageFile. [thread_id,conversationId,sms_id,filepath,groupId,quality]=%d,%s,%d,%s,%s,%d",
-                        thread_id, conversationId, sms_id, filepath, groupId, quality));
-        VerificationUtil.isImageFile(filepath);
-        if (quality < 0 || quality > 100) {
-            LogHelper.i("quality field value must be between 0 to 100");
-            return;
-        }
-
-        if (quality == 100) {
-            VerificationUtil.isFileSizeToLarge(filepath, this.getImageFtMaxSize());
-        }
-
-        try {
-            myApi.sendGroupImageFile(thread_id, conversationId, sms_id, filepath, groupId, quality);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-    }
-
-    public void sendGroupAudioFile(long thread_id, String conversationId, long sms_id,
-            String filepath, int recordTime, String groupId, boolean isRecord)
-            throws ServiceDisconnectedException, FileSuffixException, FileTransferException,
-            FileDurationException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper
-                .i(String.format(
-                        Locale.getDefault(),
-                        "enter method sendGroupAudioFile. [thread_id,conversationId,sms_id,filepath,recordTime,groupId,isRecord]=%d,%s,%d,%s,%d,%s,%b",
-                        thread_id, conversationId, sms_id, filepath, recordTime, groupId, isRecord));
-        VerificationUtil.isAudioFile(filepath);
-        if (isRecord) {
-            VerificationUtil.isAudioDurationToLong(context, filepath, this.getAudioMaxTime(),
-                    recordTime);
-        }
-        VerificationUtil.isFileSizeToLarge(filepath, this.getVideoFtMaxSize());
-        try {
-            myApi.sendGroupAudioFile(thread_id, conversationId, sms_id, filepath, recordTime,
-                    groupId);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-    }
-
-    public void sendGroupVideoFile(long thread_id, String conversationId, long sms_id,
-            String filepath, int length, String groupId, boolean isRecord)
-            throws ServiceDisconnectedException, FileSuffixException, FileTransferException,
-            FileDurationException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper
-                .i(String.format(
-                        Locale.getDefault(),
-                        "enter method sendGroupVideoFile. [thread_id,conversationId,sms_id,filepath,length,groupId,isRecord]=%d,%s,%d,%s,%d,%s,%b",
-                        thread_id, conversationId, sms_id, filepath, length, groupId, isRecord));
-        VerificationUtil.isVideoFile(filepath);
-        if (isRecord) {
-            VerificationUtil.isVedioDurationToLong(context, filepath, this.getVideoMaxTime(),
-                    length);
-        }
-        VerificationUtil.isFileSizeToLarge(filepath, this.getVideoFtMaxSize());
-        try {
-            myApi.sendGroupVideoFile(thread_id, conversationId, sms_id, filepath, length, groupId);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-    }
-
-    public void sendGroupLocation(long thread_id, String conversationId, long sms_id, double lat,
-            double lng, String text, String groupId) throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper
-                .i(String.format(
-                        Locale.getDefault(),
-                        "enter method sendGroupLocation. [thread_id,conversationId,sms_id,lat,lng,text,groupId]=%d,%s,%d,%f,%f,%s,%s",
-                        thread_id, conversationId, sms_id, lat, lng, text, groupId));
-        try {
-            myApi.sendGroupLocation(thread_id, conversationId, sms_id, lat, lng, text, groupId);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-    }
-
-    public void sendGroupVCard(long thread_id, String conversationId, long sms_id,
-            RCSContact rcsContact, String groupId) throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper
-                .i(String.format(
-                        Locale.getDefault(),
-                        "enter method sendGroupVCard. [thread_id,conversationId,sms_id,rcsContact,groupId]=%d,%s,%d,%s,%s",
-                        thread_id, conversationId, sms_id, rcsContact.toString(), groupId));
-        try {
-            myApi.sendGroupVCard(thread_id, conversationId, sms_id, rcsContact, groupId);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-    }
-
-    public void sendGroupVCard(long thread_id, String conversationId, long sms_id,
-            String vcardFilePath, String groupId) throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper
-                .i(String.format(
-                        Locale.getDefault(),
-                        "enter method sendGroupVCard. [thread_id,conversationId,sms_id,vcardFilePath,groupId]=%d,%s,%d,%s,%s",
-                        thread_id, conversationId, sms_id, vcardFilePath, groupId));
-        try {
-            myApi.sendGroupVCardByPath(thread_id, conversationId, sms_id, vcardFilePath, groupId);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-    }
-
-    public void acceptFile(ChatMessage chatMessage) throws OperatorException,
-            ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper.i(String.format(Locale.getDefault(), "enter method acceptFile. [chatMessage]=%s",
-                chatMessage.toString()));
-        try {
-            myApi.acceptFile(chatMessage);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-            throw new OperatorException(ex.getMessage());
-        }
-    }
-
-    public boolean interruptFile(ChatMessage chatMessage) throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper.i(String.format(Locale.getDefault(),
-                "enter method interruptFile. [chatMessage]=%s", chatMessage.toString()));
-        boolean flag = false;
-        try {
-            return myApi.interruptFile(chatMessage);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-        return flag;
-    }
-
-    public MessageSessionModel getMessageSessionByThreadId(long threadId)
-            throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper.i(String.format(Locale.getDefault(),
-                "enter method getMessageSessionByThreadId. [threadId]=%d", threadId));
-        try {
-            return myApi.getMessageSessionByThreadId(threadId);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-            return null;
-        }
-    }
-
-    public List<MessageSessionModel> getMessageSessionList(int offset, int number)
-            throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper.i(String.format(Locale.getDefault(),
-                "enter method getMessageSessionList. [offset,number]=%d,%d", offset, number));
-        try {
-            return myApi.getMessageSessionList(offset, number);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-            return null;
-        }
-    }
-
-    public List<ChatMessage> getChatMessageList(long threadId, boolean less, int specifiedMsgId,
-            int count) throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper.i(String.format(Locale.getDefault(),
-                "enter method getChatMessageList. [threadId,specifiedMsgId,count]=%d,%d,%d",
-                threadId, specifiedMsgId, count));
-        try {
-            return myApi.getChatMessageList(threadId, less, specifiedMsgId, count);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-            return null;
-        }
-    }
-
-    public boolean removeMessageByThreadId(long threadId) throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper.i(String.format(Locale.getDefault(),
-                "enter method removeMessageByThreadId. [threadId]=%d", threadId));
-        try {
-            myApi.removeMessageByThreadId(threadId);
-            return true;
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-            return false;
-        }
-    }
-
-    public void removeOneMessage(String messageId) throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper.i(String.format(Locale.getDefault(),
-                "enter method removeOneMessage. [messageId]=%s", messageId));
-        try {
-            myApi.removeOneMessage(messageId);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-    }
-
-    public void removeAllMessage() throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper.i(String.format(Locale.getDefault(), "enter method removeAllMessage. "));
-        try {
-            myApi.removeAllMessage();
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-    }
-
-    public List<ChatMessage> searchMessageByText(String text, int offset, int number,
-            boolean timaAsc) throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        try {
-            return myApi.searchMessageByText(text, offset, number, timaAsc);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-            return null;
-        }
-    }
-
-    public ChatMessage getTheLastMessage(long threadId) throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper.i(String.format(Locale.getDefault(),
-                "enter method getTheLastMessage. [threadId]=%d", threadId));
-        try {
-            return myApi.getTheLastMessage(threadId);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-            return null;
-        }
-    }
-
-    public String getThreadIdByNumber(List<String> numbers) throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper.i(String.format(Locale.getDefault(),
-                "enter method getThreadIdByNumber. [numbers]=%s", numbers.toString()));
-        if (!VerificationUtil.isAllNumber(numbers)) {
-            LogHelper.i("number field value error");
-            return null;
-        }
-        try {
-            return myApi.getThreadIdByNumber(VerificationUtil.formatNumbers(numbers));
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-            return null;
-        }
-    }
-
-    public long getNewThreadId() throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper.i(String.format(Locale.getDefault(), "enter method getNewThreadId. "));
-        try {
-            return myApi.getNewThreadId();
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-            return -1;
-        }
-    }
-
-    public ChatMessage getMessageById(String rowId) throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper.i(String.format(Locale.getDefault(), "enter method getMessageById. [rowId]=%s",
-                rowId));
-        try {
-            return myApi.getMessageById(rowId);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-            return null;
-        }
-    }
-
-    public ChatMessage getMessageByMessageId(String messageId) throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper.i(String.format(Locale.getDefault(),
-                "enter method getMessageByMessageId. [messageId]=%s", messageId));
-        try {
-            return myApi.getMessageByMessageId(messageId);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-            return null;
-        }
-    }
-
-    public GroupChatModel getGroupChatById(String groupId) throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        try {
-            return myApi.getGroupChatById(groupId);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-            return null;
-        }
-    }
-
-    public GroupChatModel getGroupChatByThreadId(long threadId) throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper.i(String.format(Locale.getDefault(),
-                "enter method getGroupChatByThreadId. [threadId]=%d", threadId));
-        try {
-            return myApi.getGroupChatByThreadId(threadId);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-            return null;
-        }
-    }
-
-    public String getFilepath(ChatMessage message) throws ServiceDisconnectedException {
-
-        // LogHelper.e("error log, enter method getFilepath. [message]=" +
-        // message.toString());
-
-        // System.out.println("========enter method getFilepath. [message]=" +
-        // message);
-
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper.i(String.format(Locale.getDefault(), "enter method getFilepath. [message]=%s",
-                message.toString()));
-        try {
-            return myApi.getFilepath(message);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-            return null;
-        }
-    }
-
-    public String getThumbFilepath(ChatMessage message) throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper.i(String.format(Locale.getDefault(),
-                "enter method getThumbFilepath. [message]=%s", message.toString()));
-        try {
-            return myApi.getThumbFilepath(message);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-            return null;
-        }
-    }
-
-    public void topMessage(long threadId) throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper.i(String.format(Locale.getDefault(), "enter method topMessage. [threadId]=%d",
-                threadId));
-        try {
-            myApi.topMessage(threadId);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-    }
-
-    public void cancelTopMessage(long threadId) throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper.i(String.format(Locale.getDefault(),
-                "enter method cancelTopMessage. [threadId]=%d", threadId));
-        try {
-            myApi.cancelTopMessage(threadId);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-    }
-
-    public void backupAllMessage() throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper.i(String.format(Locale.getDefault(), "enter method backupAllMessage. "));
-        try {
-            myApi.backupAllMessage();
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-    }
-
-    public void restoreAllMessage() throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper.i(String.format(Locale.getDefault(), "enter method restoreAllMessage. "));
-        try {
-            myApi.restoreAllMessage();
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-    }
-
-    public void collectMessage(List<SimpleMsg> simpleMsgList) throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper.i(String.format(Locale.getDefault(),
-                "enter method collectMessage. [simpleMsgList]=%s", simpleMsgList.toString()));
-        try {
-            myApi.collectMessage(simpleMsgList);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-    }
-
-    public List<TopMessageData> getTopMsgsInOrder(boolean asc) throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper.i(String.format(Locale.getDefault(),
-                "enter method getTopMsgsInOrder. [threadId]=%b", asc));
-        try {
-            return myApi.getTopMsgsInOrder(asc);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-        return null;
-    }
-
-    public void accuseMessage(final long thread_id, String id) throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper.i(String.format(Locale.getDefault(),
-                "enter method accuseMessage. [thread_id,id]=%d,%s", thread_id, id));
-        try {
-            myApi.accuseMessage(thread_id, id);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-    }
-
-    public List<ChatMessage> qryNotifyArchiveMsgList() throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper
-                .i(String.format(Locale.getDefault(), "enter method getMessageOfSpecialService. "));
-        try {
-            return myApi.getMessageOfSpecialService();
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-        return null;
-    }
-
-    public List<ChatMessage> qryNonFriendMsgList() throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper.i(String.format(Locale.getDefault(), "enter method getMessageOfStrangeNumber. "));
-        try {
-            return myApi.getMessageOfStrangeNumber();
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-        return null;
-    }
-
-    public List<MessageSessionModel> qryNonFriendMsgSessionList()
-            throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper
-                .i(String.format(Locale.getDefault(), "enter method qryNonFriendMsgSessionList. "));
-        try {
-            return myApi.qryNonFriendMsgSessionList();
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-        return null;
-    }
-
-    public List<MessageSessionModel> qryNotifyArchiveMsgSessionList()
-            throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper.i(String.format(Locale.getDefault(),
-                "enter method qryNotifyArchiveMsgSessionList. "));
-        try {
-            return myApi.qryNotifyArchiveMsgSessionList();
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-        return null;
-    }
-
-    public void sendGroupPaidEmo(long thread_id, String conversationId, long sms_id, String emoid,
-            String emoName, String groupId) throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper
-                .i(String.format(
-                        Locale.getDefault(),
-                        "enter method:sendGroupPaidEmo. [thread_id,conversationId,sms_id,emoid,emoName,groupId]=%d,%s,%d,%s,%s,%s",
-                        thread_id, conversationId, sms_id, emoid, emoName, groupId));
-        try {
-            myApi.sendGroupPaidEmo(thread_id, conversationId, sms_id, emoid, emoName, groupId);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-    }
-
-    public void sendOne2ManyPaidEmoMessage(long thread_id, long sms_id, List<String> numbers,
-            String emoid, String emoName) throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper
-                .i(String.format(
-                        Locale.getDefault(),
-                        "enter method:sendOne2ManyPaidEmoMessage. [thread_id,sms_id,numbers,emoid,emoName]=%d,%d,%s,%s,%s",
-                        thread_id, sms_id, numbers.toString(), emoid, emoName));
-        if (!VerificationUtil.isAllNumber(numbers)) {
-            LogHelper.i("number field value error");
-            return;
-        }
-        try {
-            myApi.sendOne2ManyPaidEmoMessage(thread_id, sms_id,
-                    VerificationUtil.formatNumbers(numbers), emoid, emoName);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-    }
-
-    public List<ChatMessage> getMsgListGreatOrLessThanSpecifiedForBlack(long threadId,
-            boolean less, int specifiedId, int number) throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper
-                .i(String.format(
-                        Locale.getDefault(),
-                        "enter method:getMsgListGreatThanSpecifiedForBlack. [threadId,less,specifiedId,number]=%d,%b,%d,%d",
-                        threadId, less, specifiedId, number));
-        try {
-            return myApi.getMsgListGreatOrLessThanSpecifiedForBlack(threadId, less, specifiedId,
-                    number);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-        return null;
-    }
-
-    public MessageSessionModel getMessageSessionByThreadIdForBlack(String threadId)
-            throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper.i(String.format(Locale.getDefault(),
-                "enter method:getMessageSessionByThreadIdForBlack. [threadId]=%s", threadId));
-        try {
-            return myApi.getMessageSessionByThreadIdForBlack(threadId);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-        return null;
-    }
-
-    public List<MessageSessionModel> getMessageSessionListForBlack(int offset, int number)
-            throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper.i(String.format(Locale.getDefault(),
-                "enter method:getMessageSessionListForBlack. [thread_id,number]=%d,%d", offset,
-                number));
-        try {
-            return myApi.getMessageSessionListForBlack(offset, number);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-        return null;
-    }
-
-    public ChatMessage getTheLastMsgOfThreadForBlack(long threadId)
-            throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper.i(String.format(Locale.getDefault(),
-                "enter method:getTheLastMsgOfThreadForBlack. [threadId]=%d", threadId));
-        try {
-            return myApi.getTheLastMsgOfThreadForBlack(threadId);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-        return null;
-    }
-
-    public void sendOne2ManyVCard(long thread_id, long sms_id, List<String> numbers,
-            RCSContact rcsContact) throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper
-                .i(String.format(
-                        Locale.getDefault(),
-                        "enter method:sendOne2ManyVCard. [thread_id,sms_id,numbers,rcsContact]=%d,%d,%s,%s",
-                        thread_id, sms_id, numbers.toString(), rcsContact.toString()));
-        if (!VerificationUtil.isAllNumber(numbers)) {
-            LogHelper.i("number field value error");
-            return;
-        }
-        try {
-            myApi.sendOne2ManyVCard(thread_id, sms_id, VerificationUtil.formatNumbers(numbers),
-                    rcsContact);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-    }
-
-    public void sendOne2ManyVCard(long thread_id, long sms_id, List<String> numbers,
-            String vcardFilePath) throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper
-                .i(String.format(
-                        Locale.getDefault(),
-                        "enter method:sendOne2ManyVCard. [thread_id,sms_id,numbers,vcardFilePath]=%d,%d,%s,%s",
-                        thread_id, sms_id, numbers.toString(), vcardFilePath));
-        if (!VerificationUtil.isAllNumber(numbers)) {
-            LogHelper.i("number field value error");
-            return;
-        }
-        try {
-            myApi.sendOne2ManyVCardByPath(thread_id, sms_id,
-                    VerificationUtil.formatNumbers(numbers), vcardFilePath);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-    }
-
-    public int recoveBlackMsgByMessageId(String messageId) throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper.i(String.format(Locale.getDefault(),
-                "enter method:recoveBlackMsgByMessageId. [messageId]=%s", messageId));
-        try {
-            return myApi.recoveBlackMsgByMessageId(messageId);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-        return 0;
-    }
-
-    public int recoveBlackMsgByThreadId(long threadId) throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper.i(String.format(Locale.getDefault(),
-                "enter method:recoveBlackMsgByThreadId. [threadId]=%d", threadId));
-        try {
-            return myApi.recoveBlackMsgByThreadId(threadId);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-        return 0;
-    }
-
-    public int recoveBlackMsgAll() throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper.i(String.format(Locale.getDefault(), "enter method:recoveBlackMsgAll. "));
-        try {
-            return myApi.recoveBlackMsgAll();
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-        return 0;
-    }
-
-    public void retransmitMessageById(String id) throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper.i(String.format(Locale.getDefault(),
-                "enter method:retransmitMessageById. [id]=%s", id));
-        try {
-            myApi.retransmitMessageById(id);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-    }
-
-    public void sendDisplayNotification(final String conversationId, final String number,
-            final String messageId) throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper
-                .i(String.format(
-                        Locale.getDefault(),
-                        "enter method:sendDisplayNotification. [conversationId, number, messageId]=%s,%s,%s",
-                        conversationId, number, messageId));
-        if (!VerificationUtil.isNumber(number)) {
-            LogHelper.i("number field value error");
-            return;
-        }
-        try {
-            myApi.sendDisplayNotification(conversationId, VerificationUtil.formatNumber(number),
-                    messageId);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-    }
-
-    public List<GroupChatModel> getAllGroupChat() throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper.i(String.format(Locale.getDefault(), "enter method:getAllGroupChat. "));
-        try {
-            return myApi.getAllGroupChat();
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-        return null;
-    }
-
-    public void burnMessage(String id) throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper.i(String.format(Locale.getDefault(), "enter method:burnMessage. [id]=%s", id));
-        try {
-            myApi.burnMessage(id);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-    }
-
-    public void cancelCollectSimpleMsg(List<SimpleMsg> simpleMsgList)
-            throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper.i(String.format(Locale.getDefault(),
-                "enter method:cancelCollectSimpleMsg. [simpleMsgList]=%s", simpleMsgList));
-        try {
-            myApi.cancelCollectSimpleMsg(simpleMsgList);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-    }
-
-    public List<FavoriteMessage> getFavouriteMessageList() throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper.i(String.format(Locale.getDefault(), "enter method:getFavouriteMessageList. "));
-        try {
-            return myApi.getFavouriteMessageList();
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-        return null;
-    }
-
-    public void burnMessageAtOnce(String id) throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper.i(String.format(Locale.getDefault(), "enter method:burnMessageAtOnce. [id]=%s",
-                id));
-        try {
-            myApi.burnMessageAtOnce(id);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-    }
-
-    public String getAccuseNumber() throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper.i(String.format(Locale.getDefault(), "enter method:getAccuseNumber. "));
-        try {
-            return myApi.getAccuseNumber();
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-        return null;
-    }
-
-    public byte[] getImageThumbnails(String filepath) throws ServiceDisconnectedException {
-
-        // LogHelper.e("error log, enter method getImageThumbnails. [filepath]="
-        // + filepath);
-
-        // System.out.println("========enter method getImageThumbnails. [filepath]="
-        // + filepath);
-
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper.i(String.format(Locale.getDefault(), "enter method:getImageThumbnails. "));
-        try {
-            return myApi.getImageThumbnails(filepath);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-        return null;
-    }
-
-    public byte[] getVideoThumbnails(String filepath) throws ServiceDisconnectedException {
-        // LogHelper.e("error log, enter method getVideoThumbnails. [filepath]="
-        // + filepath);
-
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper.i(String.format(Locale.getDefault(), "enter method:getVideoThumbnails. "));
-        try {
-            return myApi.getVideoThumbnails(filepath);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-        return null;
-    }
-
-    public int getAllUnreadCount() throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper.i(String.format(Locale.getDefault(), "enter method:getAllUnreadCount. "));
-        try {
-            return myApi.getAllUnreadCount();
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-        return 0;
-    }
-
-    public int getUnreadMsgCountByThreadId(String threadId) throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper.i(String.format(Locale.getDefault(),
-                "enter method:getUnreadMsgCountByThreadId. [threadId]=%s", threadId));
-        try {
-            return myApi.getUnreadMsgCountByThreadId(threadId);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-        return 0;
-    }
-
-    public void removeUnreadMessageByThreadId(String threadId) throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper.i(String.format(Locale.getDefault(),
-                "enter method:removeUnreadMessageByThreadId. [threadId]=%s", threadId));
-        try {
-            myApi.removeUnreadMessageByThreadId(threadId);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-    }
-
-    public int getMsgSendPolicy() throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        try {
-            return myApi.getMsgSendPolicy();
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-        return APIConstant.MSG_SEND_POLICY_AUTO;
-    }
-
-    public void setMsgSendPolicy(int policy) throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper.i(String.format(Locale.getDefault(),
-                "enter method:setMsgSendPolicy. [policy]=%s", policy));
-
-        switch (policy) {
-            case APIConstant.MSG_SEND_POLICY_AUTO:
-            case APIConstant.MSG_SEND_POLICY_SMS:
-            case APIConstant.MSG_SEND_POLICY_IM:
-                try {
-                    myApi.setMsgSendPolicy(policy);
-                } catch (Exception ex) {
-                    LogHelper.e(ex.getMessage(), ex);
-                }
-                break;
-
-            default:
-                LogHelper.d("method:setMsgSendPolicy input param not defined, param error.");
-                break;
-        }
-    }
-
-    public int updateMessageRead(String id) throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper.i(String.format(Locale.getDefault(), "enter method:updateMessageRead. [id]=%s",
-                id));
-        try {
-            return myApi.updateMessageRead(id);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-        return 0;
-    }
-
-    public void uploadFile(ChatMessage chatMessage) throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper.i(String.format(Locale.getDefault(), "enter method:uploadFile. [chatMessage]=%s",
-                chatMessage.toString()));
-        try {
-            myApi.uploadFile(chatMessage);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-    }
-
-    public int getPlayTime(int msgType, String data) throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper.i(String.format(Locale.getDefault(),
-                "enter method:getPlayTime. [msgType,data]=%d,%s", msgType, data));
-        try {
-            return myApi.getPlayTime(msgType, data);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-        return 0;
-    }
-
-    public GroupChatModel getGroupChatByConversationId(String conversationId)
-            throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper.i(String.format(Locale.getDefault(),
-                "enter method:getGroupChatByConversationId. [conversationId]=%s", conversationId));
-        try {
-            return myApi.getGroupChatByConversationId(conversationId);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-        return null;
-    }
-
-    public void setSMSSentRemind(int policy) throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper.i(String.format(Locale.getDefault(),
-                "enter method:setSMSSentRemind. [policy]=%d", policy));
-        try {
-            myApi.setSMSSentRemind(policy);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-    }
-
-    public int getSMSSentRemind() throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper.i(String.format(Locale.getDefault(), "enter method:getSMSSentRemind. "));
-        try {
-            return myApi.getSMSSentRemind();
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-        return 0;
-    }
-
-    public void burnAllMsgAtOnce() throws ServiceDisconnectedException {
-        LogHelper.i(String.format(Locale.getDefault(), "enter method:burnAllMsgAtOnce. "));
-        VerificationUtil.ApiIsNull(myApi);
-        try {
-            myApi.burnAllMsgAtOnce();
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-    }
-
-    public void sendComposingMsg(long threadId, String contact, String contentType, int seconds)
-            throws ServiceDisconnectedException {
-        LogHelper
-                .i(String.format(
-                        Locale.getDefault(),
-                        "enter method:sendComposingMsg. [threadId,contact,contentType,seconds]=%d,%s,%s,%d",
-                        threadId, contact, contentType, seconds));
-        VerificationUtil.ApiIsNull(myApi);
-        if (!VerificationUtil.isNumber(contact)) {
-            LogHelper.i("number field value error");
-            return;
-        }
-        try {
-            myApi.sendComposingMsg(threadId, VerificationUtil.formatNumber(contact), contentType,
-                    seconds);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-    }
-
-    public void sendCancelComposingMsg(long threadId, String contact, String contentType,
-            long lastActive) throws ServiceDisconnectedException {
-        LogHelper
-                .i(String.format(
-                        Locale.getDefault(),
-                        "enter method:sendCancelComposingMsg. [threadId,contact,contentType,lastActive]=%d,%s,%s,%d",
-                        threadId, contact, contentType, lastActive));
-        VerificationUtil.ApiIsNull(myApi);
-        if (!VerificationUtil.isNumber(contact)) {
-            LogHelper.i("number field value error");
-            return;
-        }
-        try {
-            myApi.sendCancelComposingMsg(threadId, VerificationUtil.formatNumber(contact),
-                    contentType, lastActive);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-    }
-
-    public void sendComposingMsgToGroup(long threadId, int id, String contentType, int seconds)
-            throws ServiceDisconnectedException {
-        LogHelper
-                .i(String.format(
-                        Locale.getDefault(),
-                        "enter method:sendComposingMsgToGroup. [threadId,id,contentType,seconds]=%d,%d,%s,%d",
-                        threadId, id, contentType, seconds));
-        VerificationUtil.ApiIsNull(myApi);
-        try {
-            myApi.sendComposingMsgToGroup(threadId, id, contentType, seconds);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-    }
-
-    public void sendCancelComposingMsgToGroup(long threadId, int id, String contentType,
-            long lastActive) throws ServiceDisconnectedException {
-        LogHelper
-                .i(String.format(
-                        Locale.getDefault(),
-                        "enter method:sendCancelComposingMsgToGroup. [threadId,id,contentType,lastActive]=%d,%d,%s,%d",
-                        threadId, id, contentType, lastActive));
-        VerificationUtil.ApiIsNull(myApi);
-        try {
-            myApi.sendCancelComposingMsgToGroup(threadId, id, contentType, lastActive);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-    }
-
-    public void sendVCardList(final long thread_id, final long sms_id, final String number,
-            final List<RCSContact> contactList, final int chatType)
-            throws ServiceDisconnectedException {
-        LogHelper
-                .i(String.format(
-                        Locale.getDefault(),
-                        "enter method:sendVCardList. [thread_id, sms_id, number, contactList, chatType]=%d,%d,%s,%s,%d",
-                        thread_id, sms_id, number, contactList.toString(), chatType));
-        VerificationUtil.ApiIsNull(myApi);
-        if (!VerificationUtil.isNumber(number)) {
-            LogHelper.i("number field value error");
-            return;
-        }
-        try {
-            myApi.sendVCardList(thread_id, sms_id, VerificationUtil.formatNumber(number),
-                    contactList, chatType);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-    }
-
-    public void sendOne2ManyVCardList(final long thread_id, final long sms_id,
-            final List<String> numbers, final List<RCSContact> contactList)
-            throws ServiceDisconnectedException {
-        LogHelper
-                .i(String.format(
-                        Locale.getDefault(),
-                        "enter method:sendOne2ManyVCardList. [thread_id, sms_id, numbers, contactList]=%d,%d,%s,%s",
-                        thread_id, sms_id, numbers.toString(), contactList.toString()));
-        VerificationUtil.ApiIsNull(myApi);
-        if (!VerificationUtil.isAllNumber(numbers)) {
-            LogHelper.i("number field value error");
-            return;
-        }
-        try {
-            myApi.sendOne2ManyVCardList(thread_id, sms_id, VerificationUtil.formatNumbers(numbers),
-                    contactList);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-    }
-
-    public void sendGroupVCardList(final long thread_id, final String conversationId,
-            final long sms_id, final List<RCSContact> contactList, final String groupId)
-            throws ServiceDisconnectedException {
-        LogHelper
-                .i(String.format(
-                        Locale.getDefault(),
-                        "enter method:sendGroupVCardList. [thread_id, conversationId, sms_id, contactList, groupId]=%d,%s,%d,%s,%s",
-                        thread_id, conversationId, sms_id, contactList.toString(), groupId));
-        VerificationUtil.ApiIsNull(myApi);
-        try {
-            myApi.sendGroupVCardList(thread_id, conversationId, sms_id, contactList, groupId);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-    }
-
-    public long getImageFtMaxSize() throws ServiceDisconnectedException {
-        LogHelper.i(String.format(Locale.getDefault(), "enter method:getImageFtMaxSize. "));
-        VerificationUtil.ApiIsNull(myApi);
-        try {
-            return myApi.getImageFtMaxSize();
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-        return 0;
-    }
-
-    public long getAudioMaxTime() throws ServiceDisconnectedException {
-        LogHelper.i(String.format(Locale.getDefault(), "enter method:getAudioMaxTime. "));
-        VerificationUtil.ApiIsNull(myApi);
-        try {
-            return myApi.getAudioMaxTime();
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-        return 0;
-    }
-
-    public long getVideoMaxTime() throws ServiceDisconnectedException {
-        LogHelper.i(String.format(Locale.getDefault(), "enter method:getVideoMaxTime. "));
-        VerificationUtil.ApiIsNull(myApi);
-        try {
-            return myApi.getVideoMaxTime();
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-        return 0;
-    }
-
-    public long getVideoFtMaxSize() throws ServiceDisconnectedException {
-        LogHelper.i(String.format(Locale.getDefault(), "enter method:getVideoFtMaxSize. "));
-        VerificationUtil.ApiIsNull(myApi);
-        try {
-            return myApi.getVideoFtMaxSize();
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-        return 0;
-    }
-
-    public void removeMsgWithNotificationByThread(long threadId)
-            throws ServiceDisconnectedException {
-        LogHelper.i(String.format(Locale.getDefault(),
-                "enter method:removeMsgWithNotificationByThread. [threadId]=%d", threadId));
-        VerificationUtil.ApiIsNull(myApi);
-        try {
-            myApi.removeMsgWithNotificationByThread(threadId);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-    }
-
-    public void backupMessageList(List<SimpleMsg> simpleMsgList)
-            throws ServiceDisconnectedException {
-        LogHelper.i(String.format(Locale.getDefault(),
-                "enter  method:backupMessageList. [simpleMsgList]=%s", simpleMsgList.toString()));
-        VerificationUtil.ApiIsNull(myApi);
-        try {
-            myApi.backupMessageList(simpleMsgList);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-    }
-
-    public ChatMessage getMessageByTransferId(String transferId)
-            throws ServiceDisconnectedException {
-        LogHelper.i(String.format(Locale.getDefault(),
-                "enter method:getMessageByTransferId. [transferId]=%s", transferId));
-        VerificationUtil.ApiIsNull(myApi);
-        try {
-            return myApi.getMessageByTransferId(transferId);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-        return null;
-    }
-    
-    public void cancelBackup() throws ServiceDisconnectedException {
-        LogHelper.i("enter method:cancelBackup.");
-        VerificationUtil.ApiIsNull(myApi);
-        try {
-            myApi.cancelBackup();
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-    }
-    
-    public void forwardImageFile(long thread_id, long sms_id, String number, String id,
-            int burnFlag, int barCycle) throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper
-                .i(String.format(
-                        Locale.getDefault(),
-                        "enter method forwardImageFile. [thread_id,sms_id,number,id,burnFlag,barCycle]=%d,%d,%s,%s,%d,%d",
-                        thread_id, sms_id, number, id, burnFlag, barCycle));
-
-        if(TextUtils.isEmpty(id)){
-            LogHelper.i("id field value error");
-            return;
-        }
-        
-        if (!VerificationUtil.isNumber(number)) {
-            LogHelper.i("number field value error");
-            return;
-        }
-        if (!VerificationUtil.isBurnFlagCorrect(burnFlag)) {
-            LogHelper.i("burnFlag field must be 0 or 1");
-            return;
-        }
-        if (barCycle < 0) {
-            LogHelper.i("barCycle field must be a positive int");
-            return;
-        }
-
-        try {
-            myApi.forwardImageFile(thread_id, sms_id, VerificationUtil.formatNumber(number), id,
-                    burnFlag, barCycle);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-    }
-    
-    public void forwardVideoFile(long thread_id, long sms_id, String number, String id,
-            int length, int burnFlag, int barCycle, boolean isRecord)
-            throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper
-                .i(String.format(
-                        Locale.getDefault(),
-                        "enter method forwardVideoFile. [thread_id,sms_id,number,id,length,burnFlag,barCycle,isRecord]=%d,%d,%s,%s,%d,%d,%d,%b",
-                        thread_id, sms_id, number, id, length, burnFlag, barCycle, isRecord));
-
-        if(TextUtils.isEmpty(id)){
-            LogHelper.i("id field value error");
-            return;
-        }
-        
-        if (!VerificationUtil.isNumber(number)) {
-            LogHelper.i("number field value error");
-            return;
-        }
-        if (!VerificationUtil.isBurnFlagCorrect(burnFlag)) {
-            LogHelper.i("burnFlag field must be 0 or 1");
-            return;
-        }
-        if (barCycle < 0) {
-            LogHelper.i("barCycle field must be a positive int");
-            return;
-        }
-        try {
-            myApi.forwardVideoFile(thread_id, sms_id, VerificationUtil.formatNumber(number), id,
-                    length, burnFlag, barCycle);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-    }
-
-    public void forwardOne2ManyImageFile(long thread_id, long sms_id, List<String> numbers,
-            String id, int burnFlag, int barCycle)
-            throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper
-                .i(String.format(
-                        Locale.getDefault(),
-                        "enter method forwardOne2ManyImageFile. [thread_id,sms_id,numbers,id,burnFlag,barCycle]=%d,%d,%s,%s,%d,%d",
-                        thread_id, sms_id, numbers.toString(), id, burnFlag, barCycle));
-        
-        if(TextUtils.isEmpty(id)){
-            LogHelper.i("id field value error");
-            return;
-        }
-        
-        if (!VerificationUtil.isAllNumber(numbers)) {
-            LogHelper.i("number field value error");
-            return;
-        }
-        if (!VerificationUtil.isBurnFlagCorrect(burnFlag)) {
-            LogHelper.i("burnFlag field must be 0 or 1");
-            return;
-        }
-        if (barCycle < 0) {
-            LogHelper.i("barCycle field must be a positive int");
-            return;
-        }
-        
-        try {
-            myApi.forwardOne2ManyImageFile(thread_id, sms_id, VerificationUtil.formatNumbers(numbers),
-                    id, burnFlag, barCycle);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-    }
-    
-    public void forwardOne2ManyVideoFile(long thread_id, long sms_id, List<String> numbers,
-            String id, int length, int burnFlag, int barCycle, boolean isRecord)
-            throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper
-                .i(String.format(
-                        Locale.getDefault(),
-                        "enter method forwardOne2ManyVideoFile. [thread_id,sms_id,numbers,id,length,burnFlag,barCycle,isRecord]=%d,%d,%s,%s,%d,%d,%d,%b",
-                        thread_id, sms_id, numbers.toString(), id, length, burnFlag,
-                        barCycle, isRecord));
-        
-        if(TextUtils.isEmpty(id)){
-            LogHelper.i("id field value error");
-            return;
-        }
-        
-        if (!VerificationUtil.isAllNumber(numbers)) {
-            LogHelper.i("number field value error");
-            return;
-        }
-        if (!VerificationUtil.isBurnFlagCorrect(burnFlag)) {
-            LogHelper.i("burnFlag field must be 0 or 1");
-            return;
-        }
-        if (barCycle < 0) {
-            LogHelper.i("barCycle field must be a positive int");
-            return;
-        }
-        try {
-            myApi.forwardOne2ManyVideoFile(thread_id, sms_id, VerificationUtil.formatNumbers(numbers),
-                    id, length, burnFlag, barCycle);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-    }
-    
-    public void forwardGroupImageFile(long thread_id, String conversationId, long sms_id,
-            String id, String groupId) throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper
-                .i(String.format(
-                        Locale.getDefault(),
-                        "enter method forwardGroupImageFile. [thread_id,conversationId,sms_id,id,groupId]=%d,%s,%d,%s,%s",
-                        thread_id, conversationId, sms_id, id, groupId));
-        
-        if(TextUtils.isEmpty(id)){
-            LogHelper.i("id field value error");
-            return;
-        }
-
-        try {
-            myApi.forwardGroupImageFile(thread_id, conversationId, sms_id, id, groupId);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-    }
-
-    public void forwardGroupVideoFile(long thread_id, String conversationId, long sms_id,
-            String id, int length, String groupId, boolean isRecord)
-            throws ServiceDisconnectedException {
-        VerificationUtil.ApiIsNull(myApi);
-        LogHelper
-                .i(String.format(
-                        Locale.getDefault(),
-                        "enter method forwardGroupVideoFile. [thread_id,conversationId,sms_id,id,length,groupId,isRecord]=%d,%s,%d,%s,%d,%s,%b",
-                        thread_id, conversationId, sms_id, id, length, groupId, isRecord));
-        
-        if(TextUtils.isEmpty(id)){
-            LogHelper.i("id field value error");
-            return;
-        }
-
-        try {
-            myApi.forwardGroupVideoFile(thread_id, conversationId, sms_id, id, length, groupId);
-        } catch (Exception ex) {
-            LogHelper.e(ex.getMessage(), ex);
-        }
-    }
-}
+/*
+ * Copyright (c) 2014 pci-suntektech Technologies, Inc.  All Rights Reserved.
+ * pci-suntektech Technologies Proprietary and Confidential.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+package com.suntek.mway.rcs.client.api.im.impl;
+
+import java.util.List;
+import java.util.Locale;
+
+import android.content.ComponentName;
+import android.content.ServiceConnection;
+import android.os.IBinder;
+import android.text.TextUtils;
+
+import com.suntek.mway.rcs.client.api.ClientApi;
+import com.suntek.mway.rcs.client.aidl.constant.APIConstant;
+import com.suntek.mway.rcs.client.aidl.contacts.RCSContact;
+import com.suntek.mway.rcs.client.api.exception.OperatorException;
+import com.suntek.mway.rcs.client.aidl.im.IInstantMessageApi;
+import com.suntek.mway.rcs.client.aidl.provider.model.ChatMessage;
+import com.suntek.mway.rcs.client.aidl.provider.model.FavoriteMessage;
+import com.suntek.mway.rcs.client.aidl.provider.model.GroupChatModel;
+import com.suntek.mway.rcs.client.aidl.provider.model.MessageSessionModel;
+import com.suntek.mway.rcs.client.aidl.provider.model.SimpleMsg;
+import com.suntek.mway.rcs.client.aidl.provider.model.TopMessageData;
+import com.suntek.mway.rcs.client.api.util.FileDurationException;
+import com.suntek.mway.rcs.client.api.util.FileSuffixException;
+import com.suntek.mway.rcs.client.api.util.FileTransferException;
+import com.suntek.mway.rcs.client.api.util.ServiceDisconnectedException;
+import com.suntek.mway.rcs.client.api.util.VerificationUtil;
+import com.suntek.mway.rcs.client.api.util.log.LogHelper;
+
+public class MessageApi extends ClientApi {
+
+    private static String serviceName = "com.suntek.mway.rcs.app.service.api.impl.im.MessageApiService";
+
+    IInstantMessageApi myApi;
+
+    private ServiceConnection mConnection = new ServiceConnection() {
+        public void onServiceConnected(ComponentName className, IBinder service) {
+            LogHelper.d("client api connect service");
+            notifyServiceConnected();
+            myApi = IInstantMessageApi.Stub.asInterface(service);
+        }
+
+        public void onServiceDisconnected(ComponentName className) {
+            if (isNormallyClosed || reconnectionTimes > MAX_RECONECTION_TIMES) {
+                LogHelper.d("client api disconnect service");
+                myApi = null;
+                notifyServiceDisconnected();
+            } else {
+                LogHelper.d("illegal call client api disconnect service :" + reconnectionTimes);
+                init(context, rcsListener);
+                if (!isBinded()) {
+                    // app is uninstalled
+                    myApi = null;
+                    notifyServiceDisconnected();
+                }
+                reconnectionTimes++;
+            }
+        }
+    };
+
+    public MessageApi() {
+        // TODO Auto-generated constructor stub
+        super(serviceName);
+        super.initServiceConnect(mConnection);
+    }
+
+    public void sendTextMessage(long thread_id, String number, String text, int burnFlag,
+            int barCycle) throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper
+                .i(String.format(
+                        Locale.getDefault(),
+                        "enter method sendTextMessage. [thread_id,number,text,burnFlag,barCycle]=%d,%s,%s,%d,%d",
+                        thread_id, number, text, burnFlag, barCycle));
+        if ("".equals(text.trim())) {
+            LogHelper.i("text value is null/Space");
+            return;
+        }
+        if (!VerificationUtil.isNumber(number)) {
+            LogHelper.i("number field value error");
+            return;
+        }
+        if (!VerificationUtil.isBurnFlagCorrect(burnFlag)) {
+            LogHelper.i("burnFlag field must be 0 or 1");
+            return;
+        }
+        if (barCycle < 0) {
+            LogHelper.i("barCycle field must be a positive int");
+            return;
+        }
+        try {
+            myApi.sendTextMessage(thread_id, VerificationUtil.formatNumber(number), text, burnFlag,
+                    barCycle);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+    }
+
+    public void sendImageFile(long thread_id, long sms_id, String number, String filePath,
+            int burnFlag, int barCycle, int quality) throws ServiceDisconnectedException,
+            FileSuffixException, FileTransferException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper
+                .i(String.format(
+                        Locale.getDefault(),
+                        "enter method sendImageFile. [thread_id,sms_id,number,filePath,burnFlag,barCycle,quality]=%d,%d,%s,%s,%d,%d,%d",
+                        thread_id, sms_id, number, filePath, burnFlag, barCycle, quality));
+        VerificationUtil.isImageFile(filePath);
+
+        if (!VerificationUtil.isNumber(number)) {
+            LogHelper.i("number field value error");
+            return;
+        }
+        if (!VerificationUtil.isBurnFlagCorrect(burnFlag)) {
+            LogHelper.i("burnFlag field must be 0 or 1");
+            return;
+        }
+        if (barCycle < 0) {
+            LogHelper.i("barCycle field must be a positive int");
+            return;
+        }
+        if (quality < 0 || quality > 100) {
+            LogHelper.i("quality field value must be between 0 to 100");
+            return;
+        }
+
+        if (quality == 100) {
+            VerificationUtil.isFileSizeToLarge(filePath, this.getImageFtMaxSize());
+        }
+
+        try {
+            myApi.sendImageFile(thread_id, sms_id, VerificationUtil.formatNumber(number), filePath,
+                    burnFlag, barCycle, quality);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+    }
+
+    public void sendAudioFile(long thread_id, long sms_id, String number, String filePath,
+            int recordTime, int burnFlag, int barCycle, boolean isRecord)
+            throws ServiceDisconnectedException, FileSuffixException, FileTransferException,
+            FileDurationException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper
+                .i(String.format(
+                        Locale.getDefault(),
+                        "enter method sendAudioFile. [thread_id,sms_id,number,filePath,recordTime,burnFlag,barCycle,isRecord]=%d,%d,%s,%s,%d,%d,%d,%b",
+                        thread_id, sms_id, number, filePath, recordTime, burnFlag, barCycle,
+                        isRecord));
+        VerificationUtil.isAudioFile(filePath);
+        if (isRecord) {
+            VerificationUtil.isAudioDurationToLong(context, filePath, this.getAudioMaxTime(),
+                    recordTime);// VerificationUtil.getAudioMaxTime(context)
+        }
+        VerificationUtil.isFileSizeToLarge(filePath, this.getVideoFtMaxSize());// VerificationUtil.getVideoFtMaxSize(context)
+        if (!VerificationUtil.isNumber(number)) {
+            LogHelper.i("number field value error");
+            return;
+        }
+        if (!VerificationUtil.isBurnFlagCorrect(burnFlag)) {
+            LogHelper.i("burnFlag field must be 0 or 1");
+            return;
+        }
+        if (barCycle < 0) {
+            LogHelper.i("barCycle field must be a positive int");
+            return;
+        }
+        try {
+            myApi.sendAudioFile(thread_id, sms_id, VerificationUtil.formatNumber(number), filePath,
+                    recordTime, burnFlag, barCycle);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+    }
+
+    public void sendVideoFile(long thread_id, long sms_id, String number, String filePath,
+            int length, int burnFlag, int barCycle, boolean isRecord)
+            throws ServiceDisconnectedException, FileSuffixException, FileTransferException,
+            FileDurationException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper
+                .i(String.format(
+                        Locale.getDefault(),
+                        "enter method sendVideoFile. [thread_id,sms_id,number,filePath,length,burnFlag,barCycle,isRecord]=%d,%d,%s,%s,%d,%d,%d,%b",
+                        thread_id, sms_id, number, filePath, length, burnFlag, barCycle, isRecord));
+        VerificationUtil.isVideoFile(filePath);
+        if (isRecord) {
+            VerificationUtil.isVedioDurationToLong(context, filePath, this.getVideoMaxTime(),
+                    length);// VerificationUtil.getVideoMaxTime(context)
+        }
+        VerificationUtil.isFileSizeToLarge(filePath, this.getVideoFtMaxSize());// VerificationUtil.getVideoFtMaxSize(context)
+        if (!VerificationUtil.isNumber(number)) {
+            LogHelper.i("number field value error");
+            return;
+        }
+        if (!VerificationUtil.isBurnFlagCorrect(burnFlag)) {
+            LogHelper.i("burnFlag field must be 0 or 1");
+            return;
+        }
+        if (barCycle < 0) {
+            LogHelper.i("barCycle field must be a positive int");
+            return;
+        }
+        try {
+            myApi.sendVideoFile(thread_id, sms_id, VerificationUtil.formatNumber(number), filePath,
+                    length, burnFlag, barCycle);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+    }
+
+    public void sendLocation(long thread_id, long sms_id, String number, double lat, double lng,
+            String text) throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper
+                .i(String.format(
+                        Locale.getDefault(),
+                        "enter method sendLocation. [thread_id,sms_id,number,lat,lng,text]=%d,%d,%s,%f,%f,%s",
+                        thread_id, sms_id, number, lat, lng, text));
+        if (!VerificationUtil.isNumber(number)) {
+            LogHelper.i("number field value error");
+            return;
+        }
+        try {
+            myApi.sendLocation(thread_id, sms_id, VerificationUtil.formatNumber(number), lat, lng,
+                    text);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+    }
+
+    public void sendPaidEmo(long thread_id, long sms_id, String number, String emoid, String emoName)
+            throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper.i(String.format(Locale.getDefault(),
+                "enter method sendPaidEmo. [thread_id,sms_id,number,emoid,emoName]=%d,%d,%s,%s,%s",
+                thread_id, sms_id, number, emoid, emoName));
+        if (!VerificationUtil.isNumber(number)) {
+            LogHelper.i("number field value error");
+            return;
+        }
+        try {
+            myApi.sendPaidEmo(thread_id, sms_id, number, emoid, emoName);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+    }
+
+    public void sendVCard(long thread_id, long sms_id, String number, RCSContact rcsContact)
+            throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper.i(String.format(Locale.getDefault(),
+                "enter method sendVCard. [thread_id,sms_id,number,rcsContact]=%d,%d,%s,%s",
+                thread_id, sms_id, number, rcsContact.toString()));
+        if (!VerificationUtil.isNumber(number)) {
+            LogHelper.i("number field value error");
+            return;
+        }
+        try {
+            myApi.sendVCard(thread_id, sms_id, number, rcsContact);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+    }
+
+    public void sendVCard(long thread_id, long sms_id, String number, String vcardFilePath)
+            throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper.i(String.format(Locale.getDefault(),
+                "enter method sendVCard. [thread_id,sms_id,number,vcardFilePath]=%d,%d,%s,%s",
+                thread_id, sms_id, number, vcardFilePath));
+        if (!VerificationUtil.isNumber(number)) {
+            LogHelper.i("number field value error");
+            return;
+        }
+        try {
+            myApi.sendVCardByPath(thread_id, sms_id, VerificationUtil.formatNumber(number),
+                    vcardFilePath);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+    }
+
+    public void sendOne2ManyTextMessage(long thread_id, List<String> numbers, String text,
+            int burnFlag, int barCycle) throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        if ("".equals(text.trim())) {
+            LogHelper.i("text value is null/Space");
+            return;
+        }
+        LogHelper
+                .i(String.format(
+                        Locale.getDefault(),
+                        "enter method sendOne2ManyTextMessage. [thread_id,numbers,text,burnFlag,barCycle]=%d,%s,%s,%d,%d",
+                        thread_id, numbers.toString(), text, burnFlag, barCycle));
+        if (!VerificationUtil.isAllNumber(numbers)) {
+            LogHelper.i("number field value error");
+            return;
+        }
+        if (!VerificationUtil.isBurnFlagCorrect(burnFlag)) {
+            LogHelper.i("burnFlag field must be 0 or 1");
+            return;
+        }
+        if (barCycle < 0) {
+            LogHelper.i("barCycle field must be a positive int");
+            return;
+        }
+        try {
+            myApi.sendOne2ManyTextMessage(thread_id, VerificationUtil.formatNumbers(numbers), text,
+                    burnFlag, barCycle);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+    }
+
+    public void sendOne2ManyImageFile(long thread_id, long sms_id, List<String> numbers,
+            String filePath, int burnFlag, int barCycle, int quality)
+            throws ServiceDisconnectedException, FileSuffixException, FileTransferException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper
+                .i(String.format(
+                        Locale.getDefault(),
+                        "enter method sendOne2ManyImageFile. [thread_id,sms_id,numbers,filePath,burnFlag,barCycle,quality]=%d,%d,%s,%s,%d,%d,%d",
+                        thread_id, sms_id, numbers.toString(), filePath, burnFlag, barCycle,
+                        quality));
+        VerificationUtil.isImageFile(filePath);
+        if (!VerificationUtil.isAllNumber(numbers)) {
+            LogHelper.i("number field value error");
+            return;
+        }
+        if (!VerificationUtil.isBurnFlagCorrect(burnFlag)) {
+            LogHelper.i("burnFlag field must be 0 or 1");
+            return;
+        }
+        if (barCycle < 0) {
+            LogHelper.i("barCycle field must be a positive int");
+            return;
+        }
+        if (quality < 0 || quality > 100) {
+            LogHelper.i("quality field value must be between 0 to 100");
+            return;
+        }
+
+        if (quality == 100) {
+            VerificationUtil.isFileSizeToLarge(filePath, this.getImageFtMaxSize());
+        }
+
+        try {
+            myApi.sendOne2ManyImageFile(thread_id, sms_id, VerificationUtil.formatNumbers(numbers),
+                    filePath, burnFlag, barCycle, quality);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+    }
+
+    public void sendOne2ManyAudioFile(long thread_id, long sms_id, List<String> numbers,
+            String filePath, int recordTime, int burnFlag, int barCycle, boolean isRecord)
+            throws ServiceDisconnectedException, FileSuffixException, FileTransferException,
+            FileDurationException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper
+                .i(String.format(
+                        Locale.getDefault(),
+                        "enter method sendOne2ManyAudioFile. [thread_id,sms_id,numbers,filePath,recordTime,burnFlag,barCycle,isRecord]=%d,%d,%s,%s,%d,%d,%d,%b",
+                        thread_id, sms_id, numbers.toString(), filePath, recordTime, burnFlag,
+                        barCycle, isRecord));
+        VerificationUtil.isAudioFile(filePath);
+        if (isRecord) {
+            VerificationUtil.isAudioDurationToLong(context, filePath, this.getAudioMaxTime(),
+                    recordTime);
+        }
+        VerificationUtil.isFileSizeToLarge(filePath, this.getVideoFtMaxSize());
+        if (!VerificationUtil.isAllNumber(numbers)) {
+            LogHelper.i("number field value error");
+            return;
+        }
+        if (!VerificationUtil.isBurnFlagCorrect(burnFlag)) {
+            LogHelper.i("burnFlag field must be 0 or 1");
+            return;
+        }
+        if (barCycle < 0) {
+            LogHelper.i("barCycle field must be a positive int");
+            return;
+        }
+        try {
+            myApi.sendOne2ManyAudioFile(thread_id, sms_id, VerificationUtil.formatNumbers(numbers),
+                    filePath, recordTime, burnFlag, barCycle);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+    }
+
+    public void sendOne2ManyVideoFile(long thread_id, long sms_id, List<String> numbers,
+            String filePath, int length, int burnFlag, int barCycle, boolean isRecord)
+            throws ServiceDisconnectedException, FileSuffixException, FileTransferException,
+            FileDurationException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper
+                .i(String.format(
+                        Locale.getDefault(),
+                        "enter method sendOne2ManyVideoFile. [thread_id,sms_id,numbers,filePath,length,burnFlag,barCycle,isRecord]=%d,%d,%s,%s,%d,%d,%d,%b",
+                        thread_id, sms_id, numbers.toString(), filePath, length, burnFlag,
+                        barCycle, isRecord));
+        VerificationUtil.isVideoFile(filePath);
+        if (isRecord) {
+            VerificationUtil.isVedioDurationToLong(context, filePath, this.getVideoMaxTime(),
+                    length);
+        }
+        VerificationUtil.isFileSizeToLarge(filePath, this.getVideoFtMaxSize());
+        if (!VerificationUtil.isAllNumber(numbers)) {
+            LogHelper.i("number field value error");
+            return;
+        }
+        if (!VerificationUtil.isBurnFlagCorrect(burnFlag)) {
+            LogHelper.i("burnFlag field must be 0 or 1");
+            return;
+        }
+        if (barCycle < 0) {
+            LogHelper.i("barCycle field must be a positive int");
+            return;
+        }
+        try {
+            myApi.sendOne2ManyVideoFile(thread_id, sms_id, VerificationUtil.formatNumbers(numbers),
+                    filePath, length, burnFlag, barCycle);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+    }
+
+    public void sendOne2ManyLocation(long thread_id, long sms_id, List<String> numbers, double lat,
+            double lng, String text) throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper
+                .i(String.format(
+                        Locale.getDefault(),
+                        "enter method sendOne2ManyLocation. [thread_id,sms_id,numbers,lat,lng,text]=%d,%d,%s,%f,%f,%s",
+                        thread_id, sms_id, numbers.toString(), lat, lng, text));
+        if (!VerificationUtil.isAllNumber(numbers)) {
+            LogHelper.i("number field value error");
+            return;
+        }
+        try {
+            myApi.sendOne2ManyLocation(thread_id, sms_id, VerificationUtil.formatNumbers(numbers),
+                    lat, lng, text);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+    }
+
+    public void sendGroupMessage(long thread_id, String conversationId, long sms_id, String msg,
+            String groupId) throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        if ("".equals(msg.trim())) {
+            LogHelper.i("msg value is null/Space");
+            return;
+        }
+        LogHelper
+                .i(String.format(
+                        Locale.getDefault(),
+                        "enter method sendGroupMessage. [thread_id,conversationId,sms_id,msg,groupId]=%d,%s,%d,%s,%s",
+                        thread_id, conversationId, sms_id, msg, groupId));
+        try {
+            myApi.sendGroupMessage(thread_id, conversationId, sms_id, msg, groupId);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+    }
+
+    public void sendGroupImageFile(long thread_id, String conversationId, long sms_id,
+            String filepath, String groupId, int quality) throws ServiceDisconnectedException,
+            FileSuffixException, FileTransferException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper
+                .i(String.format(
+                        Locale.getDefault(),
+                        "enter method sendGroupImageFile. [thread_id,conversationId,sms_id,filepath,groupId,quality]=%d,%s,%d,%s,%s,%d",
+                        thread_id, conversationId, sms_id, filepath, groupId, quality));
+        VerificationUtil.isImageFile(filepath);
+        if (quality < 0 || quality > 100) {
+            LogHelper.i("quality field value must be between 0 to 100");
+            return;
+        }
+
+        if (quality == 100) {
+            VerificationUtil.isFileSizeToLarge(filepath, this.getImageFtMaxSize());
+        }
+
+        try {
+            myApi.sendGroupImageFile(thread_id, conversationId, sms_id, filepath, groupId, quality);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+    }
+
+    public void sendGroupAudioFile(long thread_id, String conversationId, long sms_id,
+            String filepath, int recordTime, String groupId, boolean isRecord)
+            throws ServiceDisconnectedException, FileSuffixException, FileTransferException,
+            FileDurationException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper
+                .i(String.format(
+                        Locale.getDefault(),
+                        "enter method sendGroupAudioFile. [thread_id,conversationId,sms_id,filepath,recordTime,groupId,isRecord]=%d,%s,%d,%s,%d,%s,%b",
+                        thread_id, conversationId, sms_id, filepath, recordTime, groupId, isRecord));
+        VerificationUtil.isAudioFile(filepath);
+        if (isRecord) {
+            VerificationUtil.isAudioDurationToLong(context, filepath, this.getAudioMaxTime(),
+                    recordTime);
+        }
+        VerificationUtil.isFileSizeToLarge(filepath, this.getVideoFtMaxSize());
+        try {
+            myApi.sendGroupAudioFile(thread_id, conversationId, sms_id, filepath, recordTime,
+                    groupId);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+    }
+
+    public void sendGroupVideoFile(long thread_id, String conversationId, long sms_id,
+            String filepath, int length, String groupId, boolean isRecord)
+            throws ServiceDisconnectedException, FileSuffixException, FileTransferException,
+            FileDurationException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper
+                .i(String.format(
+                        Locale.getDefault(),
+                        "enter method sendGroupVideoFile. [thread_id,conversationId,sms_id,filepath,length,groupId,isRecord]=%d,%s,%d,%s,%d,%s,%b",
+                        thread_id, conversationId, sms_id, filepath, length, groupId, isRecord));
+        VerificationUtil.isVideoFile(filepath);
+        if (isRecord) {
+            VerificationUtil.isVedioDurationToLong(context, filepath, this.getVideoMaxTime(),
+                    length);
+        }
+        VerificationUtil.isFileSizeToLarge(filepath, this.getVideoFtMaxSize());
+        try {
+            myApi.sendGroupVideoFile(thread_id, conversationId, sms_id, filepath, length, groupId);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+    }
+
+    public void sendGroupLocation(long thread_id, String conversationId, long sms_id, double lat,
+            double lng, String text, String groupId) throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper
+                .i(String.format(
+                        Locale.getDefault(),
+                        "enter method sendGroupLocation. [thread_id,conversationId,sms_id,lat,lng,text,groupId]=%d,%s,%d,%f,%f,%s,%s",
+                        thread_id, conversationId, sms_id, lat, lng, text, groupId));
+        try {
+            myApi.sendGroupLocation(thread_id, conversationId, sms_id, lat, lng, text, groupId);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+    }
+
+    public void sendGroupVCard(long thread_id, String conversationId, long sms_id,
+            RCSContact rcsContact, String groupId) throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper
+                .i(String.format(
+                        Locale.getDefault(),
+                        "enter method sendGroupVCard. [thread_id,conversationId,sms_id,rcsContact,groupId]=%d,%s,%d,%s,%s",
+                        thread_id, conversationId, sms_id, rcsContact.toString(), groupId));
+        try {
+            myApi.sendGroupVCard(thread_id, conversationId, sms_id, rcsContact, groupId);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+    }
+
+    public void sendGroupVCard(long thread_id, String conversationId, long sms_id,
+            String vcardFilePath, String groupId) throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper
+                .i(String.format(
+                        Locale.getDefault(),
+                        "enter method sendGroupVCard. [thread_id,conversationId,sms_id,vcardFilePath,groupId]=%d,%s,%d,%s,%s",
+                        thread_id, conversationId, sms_id, vcardFilePath, groupId));
+        try {
+            myApi.sendGroupVCardByPath(thread_id, conversationId, sms_id, vcardFilePath, groupId);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+    }
+
+    public void acceptFile(ChatMessage chatMessage) throws OperatorException,
+            ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper.i(String.format(Locale.getDefault(), "enter method acceptFile. [chatMessage]=%s",
+                chatMessage.toString()));
+        try {
+            myApi.acceptFile(chatMessage);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+            throw new OperatorException(ex.getMessage());
+        }
+    }
+
+    public boolean interruptFile(ChatMessage chatMessage) throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper.i(String.format(Locale.getDefault(),
+                "enter method interruptFile. [chatMessage]=%s", chatMessage.toString()));
+        boolean flag = false;
+        try {
+            return myApi.interruptFile(chatMessage);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+        return flag;
+    }
+
+    public MessageSessionModel getMessageSessionByThreadId(long threadId)
+            throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper.i(String.format(Locale.getDefault(),
+                "enter method getMessageSessionByThreadId. [threadId]=%d", threadId));
+        try {
+            return myApi.getMessageSessionByThreadId(threadId);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+            return null;
+        }
+    }
+
+    public List<MessageSessionModel> getMessageSessionList(int offset, int number)
+            throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper.i(String.format(Locale.getDefault(),
+                "enter method getMessageSessionList. [offset,number]=%d,%d", offset, number));
+        try {
+            return myApi.getMessageSessionList(offset, number);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+            return null;
+        }
+    }
+
+    public List<ChatMessage> getChatMessageList(long threadId, boolean less, int specifiedMsgId,
+            int count) throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper.i(String.format(Locale.getDefault(),
+                "enter method getChatMessageList. [threadId,specifiedMsgId,count]=%d,%d,%d",
+                threadId, specifiedMsgId, count));
+        try {
+            return myApi.getChatMessageList(threadId, less, specifiedMsgId, count);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+            return null;
+        }
+    }
+
+    public boolean removeMessageByThreadId(long threadId) throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper.i(String.format(Locale.getDefault(),
+                "enter method removeMessageByThreadId. [threadId]=%d", threadId));
+        try {
+            myApi.removeMessageByThreadId(threadId);
+            return true;
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+            return false;
+        }
+    }
+
+    public void removeOneMessage(String messageId) throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper.i(String.format(Locale.getDefault(),
+                "enter method removeOneMessage. [messageId]=%s", messageId));
+        try {
+            myApi.removeOneMessage(messageId);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+    }
+
+    public void removeAllMessage() throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper.i(String.format(Locale.getDefault(), "enter method removeAllMessage. "));
+        try {
+            myApi.removeAllMessage();
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+    }
+
+    public List<ChatMessage> searchMessageByText(String text, int offset, int number,
+            boolean timaAsc) throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        try {
+            return myApi.searchMessageByText(text, offset, number, timaAsc);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+            return null;
+        }
+    }
+
+    public ChatMessage getTheLastMessage(long threadId) throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper.i(String.format(Locale.getDefault(),
+                "enter method getTheLastMessage. [threadId]=%d", threadId));
+        try {
+            return myApi.getTheLastMessage(threadId);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+            return null;
+        }
+    }
+
+    public String getThreadIdByNumber(List<String> numbers) throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper.i(String.format(Locale.getDefault(),
+                "enter method getThreadIdByNumber. [numbers]=%s", numbers.toString()));
+        if (!VerificationUtil.isAllNumber(numbers)) {
+            LogHelper.i("number field value error");
+            return null;
+        }
+        try {
+            return myApi.getThreadIdByNumber(VerificationUtil.formatNumbers(numbers));
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+            return null;
+        }
+    }
+
+    public long getNewThreadId() throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper.i(String.format(Locale.getDefault(), "enter method getNewThreadId. "));
+        try {
+            return myApi.getNewThreadId();
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+            return -1;
+        }
+    }
+
+    public ChatMessage getMessageById(String rowId) throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper.i(String.format(Locale.getDefault(), "enter method getMessageById. [rowId]=%s",
+                rowId));
+        try {
+            return myApi.getMessageById(rowId);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+            return null;
+        }
+    }
+
+    public ChatMessage getMessageByMessageId(String messageId) throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper.i(String.format(Locale.getDefault(),
+                "enter method getMessageByMessageId. [messageId]=%s", messageId));
+        try {
+            return myApi.getMessageByMessageId(messageId);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+            return null;
+        }
+    }
+
+    public GroupChatModel getGroupChatById(String groupId) throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        try {
+            return myApi.getGroupChatById(groupId);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+            return null;
+        }
+    }
+
+    public GroupChatModel getGroupChatByThreadId(long threadId) throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper.i(String.format(Locale.getDefault(),
+                "enter method getGroupChatByThreadId. [threadId]=%d", threadId));
+        try {
+            return myApi.getGroupChatByThreadId(threadId);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+            return null;
+        }
+    }
+
+    public String getFilepath(ChatMessage message) throws ServiceDisconnectedException {
+
+        // LogHelper.e("error log, enter method getFilepath. [message]=" +
+        // message.toString());
+
+        // System.out.println("========enter method getFilepath. [message]=" +
+        // message);
+
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper.i(String.format(Locale.getDefault(), "enter method getFilepath. [message]=%s",
+                message.toString()));
+        try {
+            return myApi.getFilepath(message);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+            return null;
+        }
+    }
+
+    public String getThumbFilepath(ChatMessage message) throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper.i(String.format(Locale.getDefault(),
+                "enter method getThumbFilepath. [message]=%s", message.toString()));
+        try {
+            return myApi.getThumbFilepath(message);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+            return null;
+        }
+    }
+
+    public void topMessage(long threadId) throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper.i(String.format(Locale.getDefault(), "enter method topMessage. [threadId]=%d",
+                threadId));
+        try {
+            myApi.topMessage(threadId);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+    }
+
+    public void cancelTopMessage(long threadId) throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper.i(String.format(Locale.getDefault(),
+                "enter method cancelTopMessage. [threadId]=%d", threadId));
+        try {
+            myApi.cancelTopMessage(threadId);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+    }
+
+    public void backupAllMessage() throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper.i(String.format(Locale.getDefault(), "enter method backupAllMessage. "));
+        try {
+            myApi.backupAllMessage();
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+    }
+
+    public void restoreAllMessage() throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper.i(String.format(Locale.getDefault(), "enter method restoreAllMessage. "));
+        try {
+            myApi.restoreAllMessage();
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+    }
+
+    public void collectMessage(List<SimpleMsg> simpleMsgList) throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper.i(String.format(Locale.getDefault(),
+                "enter method collectMessage. [simpleMsgList]=%s", simpleMsgList.toString()));
+        try {
+            myApi.collectMessage(simpleMsgList);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+    }
+
+    public List<TopMessageData> getTopMsgsInOrder(boolean asc) throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper.i(String.format(Locale.getDefault(),
+                "enter method getTopMsgsInOrder. [threadId]=%b", asc));
+        try {
+            return myApi.getTopMsgsInOrder(asc);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+        return null;
+    }
+
+    public void accuseMessage(final long thread_id, String id) throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper.i(String.format(Locale.getDefault(),
+                "enter method accuseMessage. [thread_id,id]=%d,%s", thread_id, id));
+        try {
+            myApi.accuseMessage(thread_id, id);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+    }
+
+    public List<ChatMessage> qryNotifyArchiveMsgList() throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper
+                .i(String.format(Locale.getDefault(), "enter method getMessageOfSpecialService. "));
+        try {
+            return myApi.getMessageOfSpecialService();
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+        return null;
+    }
+
+    public List<ChatMessage> qryNonFriendMsgList() throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper.i(String.format(Locale.getDefault(), "enter method getMessageOfStrangeNumber. "));
+        try {
+            return myApi.getMessageOfStrangeNumber();
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+        return null;
+    }
+
+    public List<MessageSessionModel> qryNonFriendMsgSessionList()
+            throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper
+                .i(String.format(Locale.getDefault(), "enter method qryNonFriendMsgSessionList. "));
+        try {
+            return myApi.qryNonFriendMsgSessionList();
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+        return null;
+    }
+
+    public List<MessageSessionModel> qryNotifyArchiveMsgSessionList()
+            throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper.i(String.format(Locale.getDefault(),
+                "enter method qryNotifyArchiveMsgSessionList. "));
+        try {
+            return myApi.qryNotifyArchiveMsgSessionList();
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+        return null;
+    }
+
+    public void sendGroupPaidEmo(long thread_id, String conversationId, long sms_id, String emoid,
+            String emoName, String groupId) throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper
+                .i(String.format(
+                        Locale.getDefault(),
+                        "enter method:sendGroupPaidEmo. [thread_id,conversationId,sms_id,emoid,emoName,groupId]=%d,%s,%d,%s,%s,%s",
+                        thread_id, conversationId, sms_id, emoid, emoName, groupId));
+        try {
+            myApi.sendGroupPaidEmo(thread_id, conversationId, sms_id, emoid, emoName, groupId);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+    }
+
+    public void sendOne2ManyPaidEmoMessage(long thread_id, long sms_id, List<String> numbers,
+            String emoid, String emoName) throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper
+                .i(String.format(
+                        Locale.getDefault(),
+                        "enter method:sendOne2ManyPaidEmoMessage. [thread_id,sms_id,numbers,emoid,emoName]=%d,%d,%s,%s,%s",
+                        thread_id, sms_id, numbers.toString(), emoid, emoName));
+        if (!VerificationUtil.isAllNumber(numbers)) {
+            LogHelper.i("number field value error");
+            return;
+        }
+        try {
+            myApi.sendOne2ManyPaidEmoMessage(thread_id, sms_id,
+                    VerificationUtil.formatNumbers(numbers), emoid, emoName);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+    }
+
+    public List<ChatMessage> getMsgListGreatOrLessThanSpecifiedForBlack(long threadId,
+            boolean less, int specifiedId, int number) throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper
+                .i(String.format(
+                        Locale.getDefault(),
+                        "enter method:getMsgListGreatThanSpecifiedForBlack. [threadId,less,specifiedId,number]=%d,%b,%d,%d",
+                        threadId, less, specifiedId, number));
+        try {
+            return myApi.getMsgListGreatOrLessThanSpecifiedForBlack(threadId, less, specifiedId,
+                    number);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+        return null;
+    }
+
+    public MessageSessionModel getMessageSessionByThreadIdForBlack(String threadId)
+            throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper.i(String.format(Locale.getDefault(),
+                "enter method:getMessageSessionByThreadIdForBlack. [threadId]=%s", threadId));
+        try {
+            return myApi.getMessageSessionByThreadIdForBlack(threadId);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+        return null;
+    }
+
+    public List<MessageSessionModel> getMessageSessionListForBlack(int offset, int number)
+            throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper.i(String.format(Locale.getDefault(),
+                "enter method:getMessageSessionListForBlack. [thread_id,number]=%d,%d", offset,
+                number));
+        try {
+            return myApi.getMessageSessionListForBlack(offset, number);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+        return null;
+    }
+
+    public ChatMessage getTheLastMsgOfThreadForBlack(long threadId)
+            throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper.i(String.format(Locale.getDefault(),
+                "enter method:getTheLastMsgOfThreadForBlack. [threadId]=%d", threadId));
+        try {
+            return myApi.getTheLastMsgOfThreadForBlack(threadId);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+        return null;
+    }
+
+    public void sendOne2ManyVCard(long thread_id, long sms_id, List<String> numbers,
+            RCSContact rcsContact) throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper
+                .i(String.format(
+                        Locale.getDefault(),
+                        "enter method:sendOne2ManyVCard. [thread_id,sms_id,numbers,rcsContact]=%d,%d,%s,%s",
+                        thread_id, sms_id, numbers.toString(), rcsContact.toString()));
+        if (!VerificationUtil.isAllNumber(numbers)) {
+            LogHelper.i("number field value error");
+            return;
+        }
+        try {
+            myApi.sendOne2ManyVCard(thread_id, sms_id, VerificationUtil.formatNumbers(numbers),
+                    rcsContact);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+    }
+
+    public void sendOne2ManyVCard(long thread_id, long sms_id, List<String> numbers,
+            String vcardFilePath) throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper
+                .i(String.format(
+                        Locale.getDefault(),
+                        "enter method:sendOne2ManyVCard. [thread_id,sms_id,numbers,vcardFilePath]=%d,%d,%s,%s",
+                        thread_id, sms_id, numbers.toString(), vcardFilePath));
+        if (!VerificationUtil.isAllNumber(numbers)) {
+            LogHelper.i("number field value error");
+            return;
+        }
+        try {
+            myApi.sendOne2ManyVCardByPath(thread_id, sms_id,
+                    VerificationUtil.formatNumbers(numbers), vcardFilePath);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+    }
+
+    public int recoveBlackMsgByMessageId(String messageId) throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper.i(String.format(Locale.getDefault(),
+                "enter method:recoveBlackMsgByMessageId. [messageId]=%s", messageId));
+        try {
+            return myApi.recoveBlackMsgByMessageId(messageId);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+        return 0;
+    }
+
+    public int recoveBlackMsgByThreadId(long threadId) throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper.i(String.format(Locale.getDefault(),
+                "enter method:recoveBlackMsgByThreadId. [threadId]=%d", threadId));
+        try {
+            return myApi.recoveBlackMsgByThreadId(threadId);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+        return 0;
+    }
+
+    public int recoveBlackMsgAll() throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper.i(String.format(Locale.getDefault(), "enter method:recoveBlackMsgAll. "));
+        try {
+            return myApi.recoveBlackMsgAll();
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+        return 0;
+    }
+
+    public void retransmitMessageById(String id) throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper.i(String.format(Locale.getDefault(),
+                "enter method:retransmitMessageById. [id]=%s", id));
+        try {
+            myApi.retransmitMessageById(id);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+    }
+
+    public void sendDisplayNotification(final String conversationId, final String number,
+            final String messageId) throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper
+                .i(String.format(
+                        Locale.getDefault(),
+                        "enter method:sendDisplayNotification. [conversationId, number, messageId]=%s,%s,%s",
+                        conversationId, number, messageId));
+        if (!VerificationUtil.isNumber(number)) {
+            LogHelper.i("number field value error");
+            return;
+        }
+        try {
+            myApi.sendDisplayNotification(conversationId, VerificationUtil.formatNumber(number),
+                    messageId);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+    }
+
+    public List<GroupChatModel> getAllGroupChat() throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper.i(String.format(Locale.getDefault(), "enter method:getAllGroupChat. "));
+        try {
+            return myApi.getAllGroupChat();
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+        return null;
+    }
+
+    public void burnMessage(String id) throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper.i(String.format(Locale.getDefault(), "enter method:burnMessage. [id]=%s", id));
+        try {
+            myApi.burnMessage(id);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+    }
+
+    public void cancelCollectSimpleMsg(List<SimpleMsg> simpleMsgList)
+            throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper.i(String.format(Locale.getDefault(),
+                "enter method:cancelCollectSimpleMsg. [simpleMsgList]=%s", simpleMsgList));
+        try {
+            myApi.cancelCollectSimpleMsg(simpleMsgList);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+    }
+
+    public List<FavoriteMessage> getFavouriteMessageList() throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper.i(String.format(Locale.getDefault(), "enter method:getFavouriteMessageList. "));
+        try {
+            return myApi.getFavouriteMessageList();
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+        return null;
+    }
+
+    public void burnMessageAtOnce(String id) throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper.i(String.format(Locale.getDefault(), "enter method:burnMessageAtOnce. [id]=%s",
+                id));
+        try {
+            myApi.burnMessageAtOnce(id);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+    }
+
+    public String getAccuseNumber() throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper.i(String.format(Locale.getDefault(), "enter method:getAccuseNumber. "));
+        try {
+            return myApi.getAccuseNumber();
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+        return null;
+    }
+
+    public byte[] getImageThumbnails(String filepath) throws ServiceDisconnectedException {
+
+        // LogHelper.e("error log, enter method getImageThumbnails. [filepath]="
+        // + filepath);
+
+        // System.out.println("========enter method getImageThumbnails. [filepath]="
+        // + filepath);
+
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper.i(String.format(Locale.getDefault(), "enter method:getImageThumbnails. "));
+        try {
+            return myApi.getImageThumbnails(filepath);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+        return null;
+    }
+
+    public byte[] getVideoThumbnails(String filepath) throws ServiceDisconnectedException {
+        // LogHelper.e("error log, enter method getVideoThumbnails. [filepath]="
+        // + filepath);
+
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper.i(String.format(Locale.getDefault(), "enter method:getVideoThumbnails. "));
+        try {
+            return myApi.getVideoThumbnails(filepath);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+        return null;
+    }
+
+    public int getAllUnreadCount() throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper.i(String.format(Locale.getDefault(), "enter method:getAllUnreadCount. "));
+        try {
+            return myApi.getAllUnreadCount();
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+        return 0;
+    }
+
+    public int getUnreadMsgCountByThreadId(String threadId) throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper.i(String.format(Locale.getDefault(),
+                "enter method:getUnreadMsgCountByThreadId. [threadId]=%s", threadId));
+        try {
+            return myApi.getUnreadMsgCountByThreadId(threadId);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+        return 0;
+    }
+
+    public void removeUnreadMessageByThreadId(String threadId) throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper.i(String.format(Locale.getDefault(),
+                "enter method:removeUnreadMessageByThreadId. [threadId]=%s", threadId));
+        try {
+            myApi.removeUnreadMessageByThreadId(threadId);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+    }
+
+    public int getMsgSendPolicy() throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        try {
+            return myApi.getMsgSendPolicy();
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+        return APIConstant.MSG_SEND_POLICY_AUTO;
+    }
+
+    public void setMsgSendPolicy(int policy) throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper.i(String.format(Locale.getDefault(),
+                "enter method:setMsgSendPolicy. [policy]=%s", policy));
+
+        switch (policy) {
+            case APIConstant.MSG_SEND_POLICY_AUTO:
+            case APIConstant.MSG_SEND_POLICY_SMS:
+            case APIConstant.MSG_SEND_POLICY_IM:
+                try {
+                    myApi.setMsgSendPolicy(policy);
+                } catch (Exception ex) {
+                    LogHelper.e(ex.getMessage(), ex);
+                }
+                break;
+
+            default:
+                LogHelper.d("method:setMsgSendPolicy input param not defined, param error.");
+                break;
+        }
+    }
+
+    public int updateMessageRead(String id) throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper.i(String.format(Locale.getDefault(), "enter method:updateMessageRead. [id]=%s",
+                id));
+        try {
+            return myApi.updateMessageRead(id);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+        return 0;
+    }
+
+    public void uploadFile(ChatMessage chatMessage) throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper.i(String.format(Locale.getDefault(), "enter method:uploadFile. [chatMessage]=%s",
+                chatMessage.toString()));
+        try {
+            myApi.uploadFile(chatMessage);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+    }
+
+    public int getPlayTime(int msgType, String data) throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper.i(String.format(Locale.getDefault(),
+                "enter method:getPlayTime. [msgType,data]=%d,%s", msgType, data));
+        try {
+            return myApi.getPlayTime(msgType, data);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+        return 0;
+    }
+
+    public GroupChatModel getGroupChatByConversationId(String conversationId)
+            throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper.i(String.format(Locale.getDefault(),
+                "enter method:getGroupChatByConversationId. [conversationId]=%s", conversationId));
+        try {
+            return myApi.getGroupChatByConversationId(conversationId);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+        return null;
+    }
+
+    public void setSMSSentRemind(int policy) throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper.i(String.format(Locale.getDefault(),
+                "enter method:setSMSSentRemind. [policy]=%d", policy));
+        try {
+            myApi.setSMSSentRemind(policy);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+    }
+
+    public int getSMSSentRemind() throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper.i(String.format(Locale.getDefault(), "enter method:getSMSSentRemind. "));
+        try {
+            return myApi.getSMSSentRemind();
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+        return 0;
+    }
+
+    public void burnAllMsgAtOnce() throws ServiceDisconnectedException {
+        LogHelper.i(String.format(Locale.getDefault(), "enter method:burnAllMsgAtOnce. "));
+        VerificationUtil.ApiIsNull(myApi);
+        try {
+            myApi.burnAllMsgAtOnce();
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+    }
+
+    public void sendComposingMsg(long threadId, String contact, String contentType, int seconds)
+            throws ServiceDisconnectedException {
+        LogHelper
+                .i(String.format(
+                        Locale.getDefault(),
+                        "enter method:sendComposingMsg. [threadId,contact,contentType,seconds]=%d,%s,%s,%d",
+                        threadId, contact, contentType, seconds));
+        VerificationUtil.ApiIsNull(myApi);
+        if (!VerificationUtil.isNumber(contact)) {
+            LogHelper.i("number field value error");
+            return;
+        }
+        try {
+            myApi.sendComposingMsg(threadId, VerificationUtil.formatNumber(contact), contentType,
+                    seconds);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+    }
+
+    public void sendCancelComposingMsg(long threadId, String contact, String contentType,
+            long lastActive) throws ServiceDisconnectedException {
+        LogHelper
+                .i(String.format(
+                        Locale.getDefault(),
+                        "enter method:sendCancelComposingMsg. [threadId,contact,contentType,lastActive]=%d,%s,%s,%d",
+                        threadId, contact, contentType, lastActive));
+        VerificationUtil.ApiIsNull(myApi);
+        if (!VerificationUtil.isNumber(contact)) {
+            LogHelper.i("number field value error");
+            return;
+        }
+        try {
+            myApi.sendCancelComposingMsg(threadId, VerificationUtil.formatNumber(contact),
+                    contentType, lastActive);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+    }
+
+    public void sendComposingMsgToGroup(long threadId, int id, String contentType, int seconds)
+            throws ServiceDisconnectedException {
+        LogHelper
+                .i(String.format(
+                        Locale.getDefault(),
+                        "enter method:sendComposingMsgToGroup. [threadId,id,contentType,seconds]=%d,%d,%s,%d",
+                        threadId, id, contentType, seconds));
+        VerificationUtil.ApiIsNull(myApi);
+        try {
+            myApi.sendComposingMsgToGroup(threadId, id, contentType, seconds);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+    }
+
+    public void sendCancelComposingMsgToGroup(long threadId, int id, String contentType,
+            long lastActive) throws ServiceDisconnectedException {
+        LogHelper
+                .i(String.format(
+                        Locale.getDefault(),
+                        "enter method:sendCancelComposingMsgToGroup. [threadId,id,contentType,lastActive]=%d,%d,%s,%d",
+                        threadId, id, contentType, lastActive));
+        VerificationUtil.ApiIsNull(myApi);
+        try {
+            myApi.sendCancelComposingMsgToGroup(threadId, id, contentType, lastActive);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+    }
+
+    public void sendVCardList(final long thread_id, final long sms_id, final String number,
+            final List<RCSContact> contactList, final int chatType)
+            throws ServiceDisconnectedException {
+        LogHelper
+                .i(String.format(
+                        Locale.getDefault(),
+                        "enter method:sendVCardList. [thread_id, sms_id, number, contactList, chatType]=%d,%d,%s,%s,%d",
+                        thread_id, sms_id, number, contactList.toString(), chatType));
+        VerificationUtil.ApiIsNull(myApi);
+        if (!VerificationUtil.isNumber(number)) {
+            LogHelper.i("number field value error");
+            return;
+        }
+        try {
+            myApi.sendVCardList(thread_id, sms_id, VerificationUtil.formatNumber(number),
+                    contactList, chatType);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+    }
+
+    public void sendOne2ManyVCardList(final long thread_id, final long sms_id,
+            final List<String> numbers, final List<RCSContact> contactList)
+            throws ServiceDisconnectedException {
+        LogHelper
+                .i(String.format(
+                        Locale.getDefault(),
+                        "enter method:sendOne2ManyVCardList. [thread_id, sms_id, numbers, contactList]=%d,%d,%s,%s",
+                        thread_id, sms_id, numbers.toString(), contactList.toString()));
+        VerificationUtil.ApiIsNull(myApi);
+        if (!VerificationUtil.isAllNumber(numbers)) {
+            LogHelper.i("number field value error");
+            return;
+        }
+        try {
+            myApi.sendOne2ManyVCardList(thread_id, sms_id, VerificationUtil.formatNumbers(numbers),
+                    contactList);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+    }
+
+    public void sendGroupVCardList(final long thread_id, final String conversationId,
+            final long sms_id, final List<RCSContact> contactList, final String groupId)
+            throws ServiceDisconnectedException {
+        LogHelper
+                .i(String.format(
+                        Locale.getDefault(),
+                        "enter method:sendGroupVCardList. [thread_id, conversationId, sms_id, contactList, groupId]=%d,%s,%d,%s,%s",
+                        thread_id, conversationId, sms_id, contactList.toString(), groupId));
+        VerificationUtil.ApiIsNull(myApi);
+        try {
+            myApi.sendGroupVCardList(thread_id, conversationId, sms_id, contactList, groupId);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+    }
+
+    public long getImageFtMaxSize() throws ServiceDisconnectedException {
+        LogHelper.i(String.format(Locale.getDefault(), "enter method:getImageFtMaxSize. "));
+        VerificationUtil.ApiIsNull(myApi);
+        try {
+            return myApi.getImageFtMaxSize();
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+        return 0;
+    }
+
+    public long getAudioMaxTime() throws ServiceDisconnectedException {
+        LogHelper.i(String.format(Locale.getDefault(), "enter method:getAudioMaxTime. "));
+        VerificationUtil.ApiIsNull(myApi);
+        try {
+            return myApi.getAudioMaxTime();
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+        return 0;
+    }
+
+    public long getVideoMaxTime() throws ServiceDisconnectedException {
+        LogHelper.i(String.format(Locale.getDefault(), "enter method:getVideoMaxTime. "));
+        VerificationUtil.ApiIsNull(myApi);
+        try {
+            return myApi.getVideoMaxTime();
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+        return 0;
+    }
+
+    public long getVideoFtMaxSize() throws ServiceDisconnectedException {
+        LogHelper.i(String.format(Locale.getDefault(), "enter method:getVideoFtMaxSize. "));
+        VerificationUtil.ApiIsNull(myApi);
+        try {
+            return myApi.getVideoFtMaxSize();
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+        return 0;
+    }
+
+    public void removeMsgWithNotificationByThread(long threadId)
+            throws ServiceDisconnectedException {
+        LogHelper.i(String.format(Locale.getDefault(),
+                "enter method:removeMsgWithNotificationByThread. [threadId]=%d", threadId));
+        VerificationUtil.ApiIsNull(myApi);
+        try {
+            myApi.removeMsgWithNotificationByThread(threadId);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+    }
+
+    public void backupMessageList(List<SimpleMsg> simpleMsgList)
+            throws ServiceDisconnectedException {
+        LogHelper.i(String.format(Locale.getDefault(),
+                "enter  method:backupMessageList. [simpleMsgList]=%s", simpleMsgList.toString()));
+        VerificationUtil.ApiIsNull(myApi);
+        try {
+            myApi.backupMessageList(simpleMsgList);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+    }
+
+    public ChatMessage getMessageByTransferId(String transferId)
+            throws ServiceDisconnectedException {
+        LogHelper.i(String.format(Locale.getDefault(),
+                "enter method:getMessageByTransferId. [transferId]=%s", transferId));
+        VerificationUtil.ApiIsNull(myApi);
+        try {
+            return myApi.getMessageByTransferId(transferId);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+        return null;
+    }
+    
+    public void cancelBackup() throws ServiceDisconnectedException {
+        LogHelper.i("enter method:cancelBackup.");
+        VerificationUtil.ApiIsNull(myApi);
+        try {
+            myApi.cancelBackup();
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+    }
+    
+    public void forwardImageFile(long thread_id, long sms_id, String number, String id,
+            int burnFlag, int barCycle) throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper
+                .i(String.format(
+                        Locale.getDefault(),
+                        "enter method forwardImageFile. [thread_id,sms_id,number,id,burnFlag,barCycle]=%d,%d,%s,%s,%d,%d",
+                        thread_id, sms_id, number, id, burnFlag, barCycle));
+
+        if(TextUtils.isEmpty(id)){
+            LogHelper.i("id field value error");
+            return;
+        }
+        
+        if (!VerificationUtil.isNumber(number)) {
+            LogHelper.i("number field value error");
+            return;
+        }
+        if (!VerificationUtil.isBurnFlagCorrect(burnFlag)) {
+            LogHelper.i("burnFlag field must be 0 or 1");
+            return;
+        }
+        if (barCycle < 0) {
+            LogHelper.i("barCycle field must be a positive int");
+            return;
+        }
+
+        try {
+            myApi.forwardImageFile(thread_id, sms_id, VerificationUtil.formatNumber(number), id,
+                    burnFlag, barCycle);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+    }
+    
+    public void forwardVideoFile(long thread_id, long sms_id, String number, String id,
+            int length, int burnFlag, int barCycle, boolean isRecord)
+            throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper
+                .i(String.format(
+                        Locale.getDefault(),
+                        "enter method forwardVideoFile. [thread_id,sms_id,number,id,length,burnFlag,barCycle,isRecord]=%d,%d,%s,%s,%d,%d,%d,%b",
+                        thread_id, sms_id, number, id, length, burnFlag, barCycle, isRecord));
+
+        if(TextUtils.isEmpty(id)){
+            LogHelper.i("id field value error");
+            return;
+        }
+        
+        if (!VerificationUtil.isNumber(number)) {
+            LogHelper.i("number field value error");
+            return;
+        }
+        if (!VerificationUtil.isBurnFlagCorrect(burnFlag)) {
+            LogHelper.i("burnFlag field must be 0 or 1");
+            return;
+        }
+        if (barCycle < 0) {
+            LogHelper.i("barCycle field must be a positive int");
+            return;
+        }
+        try {
+            myApi.forwardVideoFile(thread_id, sms_id, VerificationUtil.formatNumber(number), id,
+                    length, burnFlag, barCycle);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+    }
+
+    public void forwardOne2ManyImageFile(long thread_id, long sms_id, List<String> numbers,
+            String id, int burnFlag, int barCycle)
+            throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper
+                .i(String.format(
+                        Locale.getDefault(),
+                        "enter method forwardOne2ManyImageFile. [thread_id,sms_id,numbers,id,burnFlag,barCycle]=%d,%d,%s,%s,%d,%d",
+                        thread_id, sms_id, numbers.toString(), id, burnFlag, barCycle));
+        
+        if(TextUtils.isEmpty(id)){
+            LogHelper.i("id field value error");
+            return;
+        }
+        
+        if (!VerificationUtil.isAllNumber(numbers)) {
+            LogHelper.i("number field value error");
+            return;
+        }
+        if (!VerificationUtil.isBurnFlagCorrect(burnFlag)) {
+            LogHelper.i("burnFlag field must be 0 or 1");
+            return;
+        }
+        if (barCycle < 0) {
+            LogHelper.i("barCycle field must be a positive int");
+            return;
+        }
+        
+        try {
+            myApi.forwardOne2ManyImageFile(thread_id, sms_id, VerificationUtil.formatNumbers(numbers),
+                    id, burnFlag, barCycle);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+    }
+    
+    public void forwardOne2ManyVideoFile(long thread_id, long sms_id, List<String> numbers,
+            String id, int length, int burnFlag, int barCycle, boolean isRecord)
+            throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper
+                .i(String.format(
+                        Locale.getDefault(),
+                        "enter method forwardOne2ManyVideoFile. [thread_id,sms_id,numbers,id,length,burnFlag,barCycle,isRecord]=%d,%d,%s,%s,%d,%d,%d,%b",
+                        thread_id, sms_id, numbers.toString(), id, length, burnFlag,
+                        barCycle, isRecord));
+        
+        if(TextUtils.isEmpty(id)){
+            LogHelper.i("id field value error");
+            return;
+        }
+        
+        if (!VerificationUtil.isAllNumber(numbers)) {
+            LogHelper.i("number field value error");
+            return;
+        }
+        if (!VerificationUtil.isBurnFlagCorrect(burnFlag)) {
+            LogHelper.i("burnFlag field must be 0 or 1");
+            return;
+        }
+        if (barCycle < 0) {
+            LogHelper.i("barCycle field must be a positive int");
+            return;
+        }
+        try {
+            myApi.forwardOne2ManyVideoFile(thread_id, sms_id, VerificationUtil.formatNumbers(numbers),
+                    id, length, burnFlag, barCycle);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+    }
+    
+    public void forwardGroupImageFile(long thread_id, String conversationId, long sms_id,
+            String id, String groupId) throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper
+                .i(String.format(
+                        Locale.getDefault(),
+                        "enter method forwardGroupImageFile. [thread_id,conversationId,sms_id,id,groupId]=%d,%s,%d,%s,%s",
+                        thread_id, conversationId, sms_id, id, groupId));
+        
+        if(TextUtils.isEmpty(id)){
+            LogHelper.i("id field value error");
+            return;
+        }
+
+        try {
+            myApi.forwardGroupImageFile(thread_id, conversationId, sms_id, id, groupId);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+    }
+    
+    public void forwardGroupVideoFile(long thread_id, String conversationId, long sms_id,
+            String id, int length, String groupId, boolean isRecord)
+            throws ServiceDisconnectedException {
+        VerificationUtil.ApiIsNull(myApi);
+        LogHelper
+                .i(String.format(
+                        Locale.getDefault(),
+                        "enter method forwardGroupVideoFile. [thread_id,conversationId,sms_id,id,length,groupId,isRecord]=%d,%s,%d,%s,%d,%s,%b",
+                        thread_id, conversationId, sms_id, id, length, groupId, isRecord));
+        
+        if(TextUtils.isEmpty(id)){
+            LogHelper.i("id field value error");
+            return;
+        }
+        
+        try {
+            myApi.forwardGroupVideoFile(thread_id, conversationId, sms_id, id, length, groupId);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+    }
+}
diff --git a/rcs_service_api/src/com/suntek/mway/rcs/client/api/impl/groupchat/ConfApi.java b/rcs_service_api/src/com/suntek/mway/rcs/client/api/impl/groupchat/ConfApi.java
index 4919689..6792610 100644
--- a/rcs_service_api/src/com/suntek/mway/rcs/client/api/impl/groupchat/ConfApi.java
+++ b/rcs_service_api/src/com/suntek/mway/rcs/client/api/impl/groupchat/ConfApi.java
@@ -33,6 +33,7 @@
 import com.suntek.mway.rcs.client.api.ClientApi;
 import com.suntek.mway.rcs.client.api.exception.MemberFullException;
 import com.suntek.mway.rcs.client.aidl.im.IGroupManagerApi;
+import com.suntek.mway.rcs.client.aidl.im.OprResponse;
 import com.suntek.mway.rcs.client.api.impl.callback.ConferenceCallback;
 import com.suntek.mway.rcs.client.aidl.provider.model.GroupChatModel;
 import com.suntek.mway.rcs.client.aidl.provider.model.GroupChatUser;
@@ -88,38 +89,41 @@
         return null;
     }
 
-    public void agreeToJoinGroup(String conversationId ,String contributionId ,String chatUri ,
+    public int agreeToJoinGroup(String conversationId ,String contributionId ,String chatUri ,
             String subject , String numberData, long inviteTime) throws ServiceDisconnectedException {
         VerificationUtil.ApiIsNull(myApi);
         LogHelper.i(String.format( Locale.getDefault(),"enter method agreeToJoinGroup. [conversationId,contributionId,chatUri,subject,numberData,inviteTime]=%s,%s,%s,%s,%s,%d", conversationId,contributionId,chatUri,subject,numberData,inviteTime));
         try {
-            myApi.agreeToJoinGroup(conversationId, contributionId, chatUri, subject, numberData, inviteTime);
+            return myApi.agreeToJoinGroup(conversationId, contributionId, chatUri, subject, numberData, inviteTime);
         } catch (Exception ex) {
             // TODO Auto-generated catch block
             LogHelper.e(ex.getMessage(),ex);
         }
+        return OprResponse.OTHRE_ERROR;
     }
 
-    public void refuseToJoinGroup(String conversationId) throws ServiceDisconnectedException {
+    public int refuseToJoinGroup(String conversationId) throws ServiceDisconnectedException {
         VerificationUtil.ApiIsNull(myApi);
         LogHelper.i(String.format( Locale.getDefault(),"enter method refuseToJoinGroup. [conversationId]=%s", conversationId));
         try {
-            myApi.refuseToJoinGroup(conversationId);
+            return myApi.refuseToJoinGroup(conversationId);
         } catch (Exception ex) {
             // TODO Auto-generated catch block
             LogHelper.e(ex.getMessage(),ex);
         }
+        return OprResponse.OTHRE_ERROR;
     }
 
-    public void updateGroupSubject(String groupId,String newSubject) throws ServiceDisconnectedException {
+    public int updateGroupSubject(String groupId,String newSubject) throws ServiceDisconnectedException {
         VerificationUtil.ApiIsNull(myApi);
         LogHelper.i(String.format( Locale.getDefault(),"enter method updateGroupSubject. [groupId,newSubject]=%s,%s", groupId,newSubject));
         try {
-            myApi.updateGroupSubject(groupId, newSubject);
+            return myApi.updateGroupSubject(groupId, newSubject);
         } catch (Exception ex) {
             // TODO Auto-generated catch block
             LogHelper.e(ex.getMessage(),ex);
         }
+        return OprResponse.OTHRE_ERROR;
     }
 
     public void modifyGroupMemo(String groupId,String memo) throws ServiceDisconnectedException {
@@ -133,47 +137,51 @@
         }
     }
 
-    public void disbandGroupChat(String groupId) throws ServiceDisconnectedException {
+    public int disbandGroupChat(String groupId) throws ServiceDisconnectedException {
         VerificationUtil.ApiIsNull(myApi);
         LogHelper.i(String.format( Locale.getDefault(),"enter method disbandGroupChat. [groupId]=%s", groupId));
         try {
-            myApi.disbandGroupChat(groupId);
+            return myApi.disbandGroupChat(groupId);
         } catch (Exception ex) {
             // TODO Auto-generated catch block
             LogHelper.e(ex.getMessage(),ex);
         }
+        return OprResponse.OTHRE_ERROR;
     }
 
-    public void kickedOutOfGroupChat(String groupId,String number) throws ServiceDisconnectedException {
+    public int kickedOutOfGroupChat(String groupId,String number) throws ServiceDisconnectedException {
         VerificationUtil.ApiIsNull(myApi);
         LogHelper.i(String.format( Locale.getDefault(),"enter method kickedOutOfGroupChat. [groupId,number]=%s,%s", groupId,number));
         try {
-            myApi.kickedOutOfGroupChat(groupId, number);
+            return myApi.kickedOutOfGroupChat(groupId, number);
         } catch (Exception ex) {
             // TODO Auto-generated catch block
             LogHelper.e(ex.getMessage(),ex);
         }
+        return OprResponse.OTHRE_ERROR;
     }
 
-    public void assignGroupChairman(String groupId,String number) throws ServiceDisconnectedException {
+    public int assignGroupChairman(String groupId,String number) throws ServiceDisconnectedException {
         VerificationUtil.ApiIsNull(myApi);
         LogHelper.i(String.format( Locale.getDefault(),"enter method assignGroupChairman. [groupId,number]=%s,%s", groupId,number));
         try {
-            myApi.assignGroupChairman(groupId, number);
+            return myApi.assignGroupChairman(groupId, number);
         } catch (Exception ex) {
             // TODO Auto-generated catch block
             LogHelper.e(ex.getMessage(),ex);
         }
+        return OprResponse.OTHRE_ERROR;
     }
-    public void quitGroupChat(String groupId,String number) throws ServiceDisconnectedException {
+    public int quitGroupChat(String groupId,String number) throws ServiceDisconnectedException {
         VerificationUtil.ApiIsNull(myApi);
         LogHelper.i(String.format( Locale.getDefault(),"enter method quitGroupChat. [groupId,number]=%s,%s", groupId,number));
         try {
-            myApi.quitGroupChat(groupId, number);
+            return myApi.quitGroupChat(groupId, number);
         } catch (Exception ex) {
             // TODO Auto-generated catch block
             LogHelper.e(ex.getMessage(),ex);
         }
+        return OprResponse.OTHRE_ERROR;
     }
 
     @Deprecated
@@ -188,15 +196,16 @@
         }
     }
 
-    public void setMyAlias(String groupId,String alias) throws ServiceDisconnectedException {
+    public int setMyAlias(String groupId,String alias) throws ServiceDisconnectedException {
         VerificationUtil.ApiIsNull(myApi);
         LogHelper.i(String.format( Locale.getDefault(),"enter method setMyAlias. [groupId,alias]=%s,%s", groupId,alias));
         try {
-            myApi.setMyAlias(groupId, alias);
+            return myApi.setMyAlias(groupId, alias);
         } catch (Exception ex) {
             // TODO Auto-generated catch block
             LogHelper.e(ex.getMessage(),ex);
         }
+        return OprResponse.OTHRE_ERROR;
     }
     public String getGroupChatMemberDisplayName(String groupId,String number) throws ServiceDisconnectedException {
         VerificationUtil.ApiIsNull(myApi);
@@ -221,26 +230,28 @@
         }
         return null;
     }
-    public void inviteToJoinGroupChat(String groupId, String number) throws ServiceDisconnectedException {
+    public int inviteToJoinGroupChat(String groupId, String number) throws ServiceDisconnectedException {
         VerificationUtil.ApiIsNull(myApi);
         LogHelper.i(String.format( Locale.getDefault(),"enter method inviteToJoinGroupChat. [groupId,number]=%s,%s", groupId,number));
         try {
-            myApi.inviteOneMemberToGroupChat(groupId, number);
+            return myApi.inviteOneMemberToGroupChat(groupId, number);
         } catch (RemoteException ex) {
             // TODO Auto-generated catch block
             LogHelper.e(ex.getMessage(),ex);
         }
+        return OprResponse.OTHRE_ERROR;
     }
 
-    public void inviteToJoinGroupChat(String groupId, List<String> numbers) throws ServiceDisconnectedException {
+    public int inviteToJoinGroupChat(String groupId, List<String> numbers) throws ServiceDisconnectedException {
         VerificationUtil.ApiIsNull(myApi);
         LogHelper.i(String.format( Locale.getDefault(),"enter method inviteToJoinGroupChat. [groupId,numbers]=%s,%s", groupId,numbers.toString()));
         try {
-            myApi.inviteToJoinGroupChat(groupId, numbers);
+            return myApi.inviteToJoinGroupChat(groupId, numbers);
         } catch (RemoteException ex) {
             // TODO Auto-generated catch block
             LogHelper.e(ex.getMessage(),ex);
         }
+        return OprResponse.OTHRE_ERROR;
     }
 
     public void queryMemberHeadPic(String groupId, String number,int pixel, ConferenceCallback confCallback) throws ServiceDisconnectedException {
@@ -365,23 +376,36 @@
         return null;
     }
 
-    public void refuseAssigedAsChairman(String chatUri, long inviteTime, String conversationId, String contributionId) throws ServiceDisconnectedException {
+    public int refuseAssigedAsChairman(String chatUri, long inviteTime, String conversationId, String contributionId) throws ServiceDisconnectedException {
         LogHelper.i(String.format( Locale.getDefault(),"enter method:refuseAssigedAsChairman. [chatUri,inviteTime,conversationId,contributionId]=%s,%d,%s,%s", chatUri,inviteTime,conversationId,contributionId));
         VerificationUtil.ApiIsNull(myApi);
         try {
-            myApi.refuseAssigedAsChairman(chatUri, inviteTime, conversationId, contributionId);
+            return myApi.refuseAssigedAsChairman(chatUri, inviteTime, conversationId, contributionId);
         } catch (Exception ex) {
             LogHelper.e(ex.getMessage(), ex);
         }
+        return OprResponse.OTHRE_ERROR;
     }
 
-    public void acceptAssignedAsChairman(String chatUri, long inviteTime, String conversationId, String contributionId) throws ServiceDisconnectedException {
+    public int acceptAssignedAsChairman(String chatUri, long inviteTime, String conversationId, String contributionId) throws ServiceDisconnectedException {
         LogHelper.i(String.format( Locale.getDefault(),"enter method:acceptAssignedAsChairman. [chatUri,inviteTime,conversationId,contributionId]=%s,%d,%s,%s", chatUri,inviteTime,conversationId,contributionId));
         VerificationUtil.ApiIsNull(myApi);
         try {
-            myApi.acceptAssignedAsChairman(chatUri, inviteTime, conversationId, contributionId);
+            return myApi.acceptAssignedAsChairman(chatUri, inviteTime, conversationId, contributionId);
         } catch (Exception ex) {
             LogHelper.e(ex.getMessage(), ex);
         }
+        return OprResponse.OTHRE_ERROR;
+    }
+    
+    public int rejoinGroupChat(String chatUri) throws ServiceDisconnectedException {
+        LogHelper.i(String.format( Locale.getDefault(),"enter rejoinGroupChat. [chatUri]=%s", chatUri));
+        VerificationUtil.ApiIsNull(myApi);
+        try {
+            return myApi.rejoinGroupChat(chatUri);
+        } catch (Exception ex) {
+            LogHelper.e(ex.getMessage(), ex);
+        }
+        return 0;
     }
 }
diff --git a/rcs_service_api/src/com/suntek/mway/rcs/client/api/publicaccount/callback/PublicAccountCallback.java b/rcs_service_api/src/com/suntek/mway/rcs/client/api/publicaccount/callback/PublicAccountCallback.java
index 9239fbc..7aeb518 100644
--- a/rcs_service_api/src/com/suntek/mway/rcs/client/api/publicaccount/callback/PublicAccountCallback.java
+++ b/rcs_service_api/src/com/suntek/mway/rcs/client/api/publicaccount/callback/PublicAccountCallback.java
@@ -141,4 +141,11 @@
         // TODO Auto-generated method stub
 
     }
+    
+    @Override
+    public void respSetAcceptStatus(boolean result, String uuid)
+            throws RemoteException {
+        // TODO Auto-generated method stub
+
+    }
 }
diff --git a/rcs_service_api/src/com/suntek/mway/rcs/client/api/publicaccount/impl/PublicAccountApi.java b/rcs_service_api/src/com/suntek/mway/rcs/client/api/publicaccount/impl/PublicAccountApi.java
index 5f2811b..d88cdee 100644
--- a/rcs_service_api/src/com/suntek/mway/rcs/client/api/publicaccount/impl/PublicAccountApi.java
+++ b/rcs_service_api/src/com/suntek/mway/rcs/client/api/publicaccount/impl/PublicAccountApi.java
@@ -95,16 +95,16 @@
         }
     }
 
-    public void getUserSubscribePublicList(int order,int pageSize,int pageNum,PublicAccountCallback callback) throws ServiceDisconnectedException {
+    public void getUserSubscribePublicList(PublicAccountCallback callback) throws ServiceDisconnectedException {
         VerificationUtil.ApiIsNull(myApi);
-        LogHelper.i(String.format( Locale.getDefault(),"enter method getUserSubscribePublicList. [order,pageSize,pageNum]=%d,%d,%d", order,pageSize,pageNum));
-        if (order != 0 && order != 1) {
+        LogHelper.i(String.format( Locale.getDefault(),"enter method getUserSubscribePublicList. "));
+        /*if (order != 0 && order != 1) {
             LogHelper.i("order field value must be 0 or 1");
             return;
-        }
+        }*/
         try {
             myApi.registerCallback(callback);
-            myApi.getUserSubscribePublicList(order, pageSize, pageNum);
+            myApi.getUserSubscribePublicList();
         } catch (Exception ex) {
             // TODO Auto-generated catch block
             LogHelper.e(ex.getMessage(),ex);
diff --git a/rcs_service_api/src/com/suntek/mway/rcs/client/api/support/RcsSupportApi.java b/rcs_service_api/src/com/suntek/mway/rcs/client/api/support/RcsSupportApi.java
index bb5bf6c..6f8a5c0 100644
--- a/rcs_service_api/src/com/suntek/mway/rcs/client/api/support/RcsSupportApi.java
+++ b/rcs_service_api/src/com/suntek/mway/rcs/client/api/support/RcsSupportApi.java
@@ -22,9 +22,20 @@
  */
 package com.suntek.mway.rcs.client.api.support;
 
+import com.suntek.mway.rcs.client.aidl.constant.BroadcastConstants;
+import com.suntek.mway.rcs.client.aidl.setting.RcsUserProfileInfo;
+import com.suntek.mway.rcs.client.api.RCSServiceListener;
+import com.suntek.mway.rcs.client.api.autoconfig.RcsAccountApi;
+import com.suntek.mway.rcs.client.api.util.ServiceDisconnectedException;
+
+import android.content.BroadcastReceiver;
 import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
+import android.os.RemoteException;
+import android.util.Log;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -83,6 +94,9 @@
      */
     public static final int PLUGIN_PLUGIN_CENTER = 6;
 
+    private static final String TAG = "RCS_UI";
+    private static final int DMS_VERSION_UNKNOWN = -999;
+
     /**
      * Check that the RcsService module is been installed.
      *
@@ -121,6 +135,12 @@
         return false;
     }
 
+    private RcsAccountApi mAccountApi;
+    private Context mContext;
+
+    private boolean mIsRcsServiceInstalled;
+    private boolean mIsSimAvailableForRcs;
+
     /**
      * Dynamically detect the supported plug-in.
      *
@@ -143,4 +163,97 @@
 
         return supportedPluginIds;
     }
+
+    public void init(Context context) {
+        mContext = context;
+        mIsRcsServiceInstalled = isRcsServiceInstalled(context);
+
+        mAccountApi = new RcsAccountApi();
+        if (mIsRcsServiceInstalled) {
+            init();
+        }
+    }
+
+    private void init() {
+        new Thread() {
+            @Override
+            public void run() {
+                long t0, t1;
+                t0 = System.currentTimeMillis();
+                initRcsAccountApi();
+                t1 = System.currentTimeMillis();
+                Log.d(TAG, "initRcsAccountApi cost " + (t1 - t0) + " ms");
+            }
+        }.start();
+    }
+
+    private BroadcastReceiver userStatusChangedReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            mIsSimAvailableForRcs = isSimAvailableForRcs();
+        }
+    };
+
+    private void initRcsAccountApi() {
+        mAccountApi.init(mContext, new RCSServiceListener() {
+            @Override
+            public void onServiceDisconnected() throws RemoteException {
+                Log.d(TAG, "RcsAccountApi disconnected");
+            }
+
+            @Override
+            public void onServiceConnected() throws RemoteException {
+                Log.d(TAG, "RcsAccountApi connected");
+                mIsSimAvailableForRcs = isSimAvailableForRcs();
+
+                IntentFilter filter = new IntentFilter(BroadcastConstants.ACTION_DMS_USER_STATUS_CHANGED);
+                mContext.registerReceiver(userStatusChangedReceiver, filter);
+            }
+        });
+    }
+
+    /**
+     * Return whether the RCS is support. In general, use this method to define whether the RCS
+     * related UI entrance should display. The result might not accurate when it is still
+     * initializing. This is a compromise for performance.
+     * @param context
+     * @return Whether RCS is supported.
+     */
+    public boolean isRcsSupported() {
+        return mIsRcsServiceInstalled && mIsSimAvailableForRcs;
+//        return true;
+    }
+
+    /**
+     * Return whether the RCS is online. The result might not accurate when it is still
+     * initializing. This is a compromise for performance.
+     * @param context
+     * @return Whether RCS is supported.
+     */
+    public boolean isOnline() {
+        try {
+            return mAccountApi.isOnline();
+        } catch (ServiceDisconnectedException e) {
+            Log.w(TAG, "Failed invoking isOnline(). " + e.getMessage());
+            return false;
+        }
+    }
+
+    private boolean isSimAvailableForRcs() {
+        int dmVersion = getDmVersion();
+        Log.d(TAG, "DM version is " + dmVersion);
+
+        // If the version is larger than 0, the SIM is available for RCS.
+        return dmVersion > 0;
+    }
+
+    private int getDmVersion() {
+        try {
+            RcsUserProfileInfo userProfile = mAccountApi.getRcsUserProfileInfo();
+            return Integer.valueOf(userProfile.getVersion());
+        } catch (Exception e) {
+            Log.w(TAG, "Failed getting DM version. " + e.getMessage());
+            return DMS_VERSION_UNKNOWN;
+        }
+    }
 }
