rcs-service:  PCI-RCS support CMCC fetion feature.

 - add fetion function.
 - add receive public account notification message.

Change-Id: Id273ca23ad1cf47d18bf5779e0840972382e8787
CRs-Fixed: 899037
diff --git a/rcs_service_aidl/src/com/suntek/mway/rcs/client/aidl/constant/Constants.java b/rcs_service_aidl/src/com/suntek/mway/rcs/client/aidl/constant/Constants.java
index 745aa00..f2cec96 100644
--- a/rcs_service_aidl/src/com/suntek/mway/rcs/client/aidl/constant/Constants.java
+++ b/rcs_service_aidl/src/com/suntek/mway/rcs/client/aidl/constant/Constants.java
@@ -112,6 +112,10 @@
 
         public static final String CONST_FT_THUMB = "1";
 
+        public static final int CONST_MIN_QUALITY = 0;
+
+        public static final int CONST_MAX_QUALITY = 100;
+
         public static final int CONST_CHAT_O2O = 1;
 
         public static final int CONST_CHAT_O2M = 2;
@@ -120,6 +124,8 @@
 
         public static final int CONST_CHAT_PUBLIC_ACCOUNT = 4;
 
+        public static final int CONST_CHAT_PC = 5;
+
         public static final int CONST_MESSAGE_SMS = -1;
 
         public static final int CONST_MESSAGE_TEXT = 0;
@@ -197,6 +203,18 @@
         public static final int CONST_SEND_POLICY_NOT_FORWARD_SMS = 2;
 
         public static final int CONST_SEND_POLICY_DEFAULT_NOT_SET = -1;
+
+        public static final String CONST_CHAT_PC_NUMBER_PREFIX = "PC_";
+
+        public static final int CONST_NOT_CC = 0;
+
+        public static final int CONST_CC_RECEIVE = 1;
+
+        public static final int CONST_CC_SEND = 2;
+
+        public static final int CONST_NOT_SILENCE = 0;
+
+        public static final int CONST_SILENCE = 1;
     }
 
     public static class GroupChatConstants {
@@ -781,6 +799,8 @@
 
             public static final String PHONE_ID = "phone_id";
 
+            public static final String COPY = "rcs_copy";
+
             public static final String SUB_ID = "sub_id";
 
             public static final String DOWN_LOAD_OK = "rcs_is_download";
diff --git a/rcs_service_aidl/src/com/suntek/mway/rcs/client/aidl/constant/Parameter.java b/rcs_service_aidl/src/com/suntek/mway/rcs/client/aidl/constant/Parameter.java
index 2a47d06..fc1d468 100644
--- a/rcs_service_aidl/src/com/suntek/mway/rcs/client/aidl/constant/Parameter.java
+++ b/rcs_service_aidl/src/com/suntek/mway/rcs/client/aidl/constant/Parameter.java
@@ -57,6 +57,12 @@
 
     public static final String EXTRA_PHONE_ID = "phoneId";
 
+    public static final String EXTRA_COPY = "copy";
+
+    public static final String EXTRA_SILENCE = "silence";
+
+    public static final String EXTRA_CHAT_TYPE = "chatType";
+
     // Group chat
     public static final String EXTRA_INVITE_NUMBER = "inviteNumber";
 
diff --git a/rcs_service_aidl/src/com/suntek/mway/rcs/client/aidl/service/IServiceApi.aidl b/rcs_service_aidl/src/com/suntek/mway/rcs/client/aidl/service/IServiceApi.aidl
index 4a213f2..1a23bdb 100644
--- a/rcs_service_aidl/src/com/suntek/mway/rcs/client/aidl/service/IServiceApi.aidl
+++ b/rcs_service_aidl/src/com/suntek/mway/rcs/client/aidl/service/IServiceApi.aidl
@@ -92,6 +92,12 @@
     long sendVideoToGroupChat(long groupId, long threadId, String filepath, int duration, boolean isRecord, String thumbnailPath);
     long sendLocationToGroupChat(long groupId, long threadId, double lat, double lng, String label);
     long sendVcardToGroupChat(long groupId, long threadId, String filepath);
+    long sendTextToPc(long threadId, String text, int barCycle);
+    long sendImageToPc(long threadId, String filepath, int quality, boolean isRecord, int barCycle, String thumbnailPath);
+    long sendAudioToPc(long threadId, String filepath, int duration, boolean isRecord, int barCycle);
+    long sendVideoToPc(long threadId, String filepath, int duration, boolean isRecord, int barCycle, String thumbnailPath);
+    long sendLocationToPc(long threadId, double lat, double lng, String label, int barCycle);
+    long sendVcardToPc(long threadId, String filepath, int barCycle);
     void setRemindPolicy(int policy);
     void setSendPolicy(int policy);
     int topConversation(long threadId);
@@ -148,9 +154,11 @@
     // emoticon
     long sendEmoticon(in List<String> numberList, long threadId, String emoticonId, String emoticonName, int barCycle);
     long sendEmoticonToGroupChat(long groupId, long threadId, String emoticonId, String emoticonName);
+    long sendEmoticonToPc(long threadId, String emoticonId, String emoticonName, int barCycle);
     // cloud
     long sendCloud(in List<String> numberList, long threadId, String fileName, long fileSize, String shareUrl, String smsContent, int barCycle);
     long sendCloudToGroupChat(long groupId, long threadId, String fileName, long fileSize, String shareUrl);
+    long sendCloudToPc(long threadId, String fileName, long fileSize, String shareUrl, String smsContent, int barCycle);
     // public account
     long sendTextToPublicAccount(String publicAccountId, long threadId, String text);
     long sendImageToPublicAccount(String publicAccountId, long threadId, String filepath, int quality, boolean isRecord, String thumbnailPath);
diff --git a/rcs_service_api/src/com/suntek/mway/rcs/client/api/message/MessageApi.java b/rcs_service_api/src/com/suntek/mway/rcs/client/api/message/MessageApi.java
index c5ae5c4..8ae84fa 100644
--- a/rcs_service_api/src/com/suntek/mway/rcs/client/api/message/MessageApi.java
+++ b/rcs_service_api/src/com/suntek/mway/rcs/client/api/message/MessageApi.java
@@ -341,8 +341,10 @@
             LogHelper.i("barCycle field must be greater than -1");
             return 0L;
         }
-        if (quality < 0 || quality > 100) {
-            LogHelper.i("quality field value must be between 0 to 100");
+        if (quality < MessageConstants.CONST_MIN_QUALITY
+                || quality > MessageConstants.CONST_MAX_QUALITY) {
+            LogHelper.i("quality field value must be between " + MessageConstants.CONST_MIN_QUALITY
+                    + " to " + MessageConstants.CONST_MAX_QUALITY);
             return 0L;
         }
 
@@ -353,7 +355,7 @@
             VerificationUtil.isFileExists(thumbnailPath);
         }
 
-        if (quality == 100) {
+        if (quality == MessageConstants.CONST_MAX_QUALITY) {
             VerificationUtil.isFileSizeToLarge(filepath, this.getImageMaxSize());
         }
 
@@ -388,8 +390,10 @@
             LogHelper.i("barCycle field must be greater than -1");
             return 0L;
         }
-        if (quality < 0 || quality > 100) {
-            LogHelper.i("quality field value must be between 0 to 100");
+        if (quality < MessageConstants.CONST_MIN_QUALITY
+                || quality > MessageConstants.CONST_MAX_QUALITY) {
+            LogHelper.i("quality field value must be between " + MessageConstants.CONST_MIN_QUALITY
+                    + " to " + MessageConstants.CONST_MAX_QUALITY);
             return 0L;
         }
 
@@ -399,7 +403,7 @@
             VerificationUtil.isImageFile(thumbnailPath);
             VerificationUtil.isFileExists(thumbnailPath);
         }
-        if (quality == 100) {
+        if (quality == MessageConstants.CONST_MAX_QUALITY) {
             VerificationUtil.isFileSizeToLarge(filepath, this.getImageMaxSize());
         }
 
@@ -677,8 +681,10 @@
                 "enter method sendImageToGroupChat. [groupId,threadId,filepath,quality,isRecord" +
                 ",thumbnailPath]=%d,%d,%s,%d,%b,%s",
                         groupId, threadId, filepath, quality, isRecord, thumbnailPath));
-        if (quality < 0 || quality > 100) {
-            LogHelper.i("quality field value must be between 0 to 100");
+        if (quality < MessageConstants.CONST_MIN_QUALITY
+                || quality > MessageConstants.CONST_MAX_QUALITY) {
+            LogHelper.i("quality field value must be between " + MessageConstants.CONST_MIN_QUALITY
+                    + " to " + MessageConstants.CONST_MAX_QUALITY);
             return 0L;
         }
 
@@ -688,7 +694,7 @@
             VerificationUtil.isImageFile(thumbnailPath);
             VerificationUtil.isFileExists(thumbnailPath);
         }
-        if (quality == 100) {
+        if (quality == MessageConstants.CONST_MAX_QUALITY) {
             VerificationUtil.isFileSizeToLarge(filepath, this.getImageMaxSize());
         }
 
@@ -770,6 +776,157 @@
         return ServiceApi.getServiceApi().sendVcardToGroupChat(groupId, threadId, filepath);
     }
 
+    public long sendTextToPc(long threadId, String text, int barCycle)
+            throws RemoteException, ServiceDisconnectedException {
+        LogHelper.i(String.format(Locale.getDefault(),
+                "enter method sendTextToPc. [threadId,text,barCycle]=%d,%s,%d",
+                threadId, text, barCycle));
+        if ("".equals(text.trim())) {
+            LogHelper.i("text value is null/Space");
+            return 0L;
+        }
+        if (barCycle < -1) {
+            LogHelper.i("barCycle field must be greater than -1");
+            return 0L;
+        }
+        return ServiceApi.getServiceApi().sendTextToPc(threadId, text, barCycle);
+    }
+
+    public long sendImageToPc(long threadId, String filepath, int quality,
+            boolean isRecord, int barCycle) throws RemoteException, ServiceDisconnectedException,
+            FileSuffixException, FileNotExistsException, FileTooLargeException {
+        return sendImageToPc(threadId, filepath, quality,
+                isRecord, barCycle, null);
+    }
+
+    public long sendImageToPc(long threadId, String filepath, int quality,
+            boolean isRecord, int barCycle, String thumbnailPath) throws RemoteException,
+            ServiceDisconnectedException, FileSuffixException, FileNotExistsException,
+            FileTooLargeException {
+        LogHelper.i(String.format(Locale.getDefault(),
+                "enter method sendImageToPc. [threadId,filepath,quality,isRecord,barCycle" +
+                ",thumbnailPath]=%d,%s,%d,%b,%d,%s",
+                        threadId, filepath, quality, isRecord, barCycle, thumbnailPath));
+        if (barCycle < -1) {
+            LogHelper.i("barCycle field must be greater than -1");
+            return 0L;
+        }
+        if (quality < MessageConstants.CONST_MIN_QUALITY
+                || quality > MessageConstants.CONST_MAX_QUALITY) {
+            LogHelper.i("quality field value must be between " + MessageConstants.CONST_MIN_QUALITY
+                    + " to " + MessageConstants.CONST_MAX_QUALITY);
+            return 0L;
+        }
+
+        VerificationUtil.isImageFile(filepath);
+        VerificationUtil.isFileExists(filepath);
+        if (thumbnailPath != null) {
+            VerificationUtil.isImageFile(thumbnailPath);
+            VerificationUtil.isFileExists(thumbnailPath);
+        }
+
+        if (quality == MessageConstants.CONST_MAX_QUALITY) {
+            VerificationUtil.isFileSizeToLarge(filepath, this.getImageMaxSize());
+        }
+
+        return ServiceApi.getServiceApi().sendImageToPc(threadId, filepath, quality,
+                isRecord, barCycle, thumbnailPath);
+    }
+
+    public long sendAudioToPc(long threadId, String filepath, int duration,
+            boolean isRecord, int barCycle) throws RemoteException, ServiceDisconnectedException,
+            FileSuffixException, FileNotExistsException, FileTooLargeException,
+            FileDurationException {
+        LogHelper.i(String.format(Locale.getDefault(),
+                "enter method sendAudioToPc. [threadId,filepath,duration,isRecord,barCycle]"
+                        + "=%d,%s,%d,%b,%d",
+                 threadId, filepath, duration, isRecord, barCycle));
+        if (barCycle < -1) {
+            LogHelper.i("barCycle field must be greater than -1");
+            return 0L;
+        }
+
+        VerificationUtil.isAudioFile(filepath);
+        VerificationUtil.isFileExists(filepath);
+        if (isRecord) {
+            VerificationUtil.isAudioDurationToLong(ServiceApi.getInstance().getContext(),
+                    filepath, this.getAudioMaxDuration(), duration);
+        }
+        VerificationUtil.isFileSizeToLarge(filepath, this.getVideoMaxSize());
+
+        return ServiceApi.getServiceApi().sendAudioToPc(threadId, filepath, duration,
+                isRecord, barCycle);
+    }
+
+    public long sendVideoToPc(long threadId, String filepath, int duration,
+            boolean isRecord, int barCycle) throws RemoteException, ServiceDisconnectedException,
+            FileSuffixException, FileNotExistsException, FileTooLargeException,
+            FileDurationException {
+        return sendVideoToPc(threadId, filepath, duration,
+                isRecord, barCycle, null);
+    }
+
+    public long sendVideoToPc(long threadId, String filepath, int duration,
+            boolean isRecord, int barCycle, String thumbnailPath) throws RemoteException,
+            ServiceDisconnectedException, FileSuffixException, FileNotExistsException,
+            FileTooLargeException, FileDurationException {
+        LogHelper.i(String.format(Locale.getDefault(),
+                "enter method sendVideoToPc. [threadId,filepath,duration,isRecord,barCycle" +
+                ",thumbnailPath]=%d,%s,%d,%b,%d,%s",
+                        threadId, filepath, duration, isRecord, barCycle, thumbnailPath));
+        if (barCycle < -1) {
+            LogHelper.i("barCycle field must be greater than -1");
+            return 0L;
+        }
+
+        VerificationUtil.isVideoFile(filepath);
+        VerificationUtil.isFileExists(filepath);
+        if (thumbnailPath != null) {
+            VerificationUtil.isImageFile(thumbnailPath);
+            VerificationUtil.isFileExists(thumbnailPath);
+        }
+        if (isRecord) {
+            VerificationUtil.isVideoDurationToLong(ServiceApi.getInstance().getContext(),
+                    filepath,this.getVideoMaxDuration(), duration);
+        }
+        VerificationUtil.isFileSizeToLarge(filepath, this.getVideoMaxSize());
+
+        return ServiceApi.getServiceApi().sendVideoToPc(threadId, filepath, duration,
+                isRecord, barCycle, thumbnailPath);
+    }
+
+    public long sendLocationToPc(long threadId, double lat, double lng, String label,
+            int barCycle) throws RemoteException, ServiceDisconnectedException {
+        LogHelper
+                .i(String.format(
+                        Locale.getDefault(),
+                        "enter method sendLocationToPc. [threadId,lat,lng,text,barCycle]="
+                        + "%d,%f,%f,%s,%d",
+                        threadId, lat, lng, label, barCycle));
+        if (barCycle < -1) {
+            LogHelper.i("barCycle field must be greater than -1");
+            return 0L;
+        }
+
+        return ServiceApi.getServiceApi().sendLocationToPc(threadId, lat, lng, label, barCycle);
+    }
+
+    public long sendVcardToPc(long threadId, String filepath, int barCycle)
+            throws RemoteException, ServiceDisconnectedException, FileSuffixException,
+            FileNotExistsException {
+        LogHelper.i(String.format(Locale.getDefault(),
+                "enter method sendVcardToPc. [threadId,filepath,barCycle]=%d,%s,%d",
+                threadId, filepath, barCycle));
+        if (barCycle < -1) {
+            LogHelper.i("barCycle field must be greater than -1");
+            return 0L;
+        }
+        VerificationUtil.isVcardFile(filepath);
+        VerificationUtil.isFileExists(filepath);
+
+        return ServiceApi.getServiceApi().sendVcardToPc(threadId, filepath, barCycle);
+    }
+
     public void setRemindPolicy(int policy) throws RemoteException, ServiceDisconnectedException {
         ServiceApi.getServiceApi().setRemindPolicy(policy);
     }
@@ -852,6 +1009,25 @@
                 emoticonName);
     }
 
+    public long sendEmoticonToPc(long threadId, String emoticonId, String emoticonName,
+            int barCycle) throws RemoteException, ServiceDisconnectedException {
+        LogHelper.i(String.format(Locale.getDefault(),
+            "enter method sendEmoticonToPc. [threadId,emoticonId,emoticonName,barCycle]="
+                    + "%d,%s,%s,%d",
+                        threadId, emoticonId, emoticonName, barCycle));
+        if (barCycle < -1) {
+            LogHelper.i("barCycle field must be greater than -1");
+            return 0L;
+        }
+        if (TextUtils.isEmpty(emoticonId) || TextUtils.isEmpty(emoticonName)) {
+            LogHelper.i("emoticonId or emoticonName is empty");
+            return 0L;
+        }
+
+        return ServiceApi.getServiceApi().sendEmoticonToPc(threadId, emoticonId,
+                emoticonName, barCycle);
+    }
+
     // cloud
     public long sendCloud(String number, long threadId, String fileName, long fileSize,
             String shareUrl, String smsContent, int barCycle) throws RemoteException,
@@ -924,6 +1100,27 @@
                 fileSize, shareUrl);
     }
 
+    public long sendCloudToPc(long threadId, String fileName, long fileSize,
+            String shareUrl, String smsContent, int barCycle) throws RemoteException,
+            ServiceDisconnectedException {
+        LogHelper.i(String.format(Locale.getDefault(),
+            "enter method sendCloudToPc. [threadId,fileName,fileSize,shareUrl,smsContent,"
+                    + "barCycle]=%d,%s,%d,%s,%s,%d",
+                        threadId, fileName, fileSize, shareUrl, smsContent, barCycle));
+        if (barCycle < -1) {
+            LogHelper.i("barCycle field must be greater than -1");
+            return 0L;
+        }
+        if (TextUtils.isEmpty(fileName) || TextUtils.isEmpty(shareUrl)
+                || TextUtils.isEmpty(smsContent)) {
+            LogHelper.i("fileName or shareUrl or smsContent is empty");
+            return 0L;
+        }
+
+        return ServiceApi.getServiceApi().sendCloudToPc(threadId, fileName, fileSize,
+                shareUrl, smsContent, barCycle);
+    }
+
     // public account
     public long sendTextToPublicAccount(String publicAccountId, long threadId, String text)
             throws RemoteException, ServiceDisconnectedException {
@@ -954,8 +1151,10 @@
                 "enter method sendImageToPublicAccount. [publicAccountId,"
                         + "threadId,filepath,quality,isRecord,thumbnailPath]=%s,%d,%s,%d,%b,%s",
                         publicAccountId, threadId, filepath, quality, isRecord, thumbnailPath));
-        if (quality < 0 || quality > 100) {
-            LogHelper.i("quality field value must be between 0 to 100");
+        if (quality < MessageConstants.CONST_MIN_QUALITY
+                || quality > MessageConstants.CONST_MAX_QUALITY) {
+            LogHelper.i("quality field value must be between " + MessageConstants.CONST_MIN_QUALITY
+                    + " to " + MessageConstants.CONST_MAX_QUALITY);
             return 0L;
         }
 
@@ -965,7 +1164,7 @@
             VerificationUtil.isImageFile(thumbnailPath);
             VerificationUtil.isFileExists(thumbnailPath);
         }
-        if (quality == 100) {
+        if (quality == MessageConstants.CONST_MAX_QUALITY) {
             VerificationUtil.isFileSizeToLarge(filepath, this.getImageMaxSize());
         }
         return ServiceApi.getServiceApi().sendImageToPublicAccount(publicAccountId, threadId,
diff --git a/rcs_service_api/src/com/suntek/mway/rcs/client/api/parse/CloudFileMessageParser.java b/rcs_service_api/src/com/suntek/mway/rcs/client/api/parse/CloudFileMessageParser.java
index 55b168f..ca2d5bb 100644
--- a/rcs_service_api/src/com/suntek/mway/rcs/client/api/parse/CloudFileMessageParser.java
+++ b/rcs_service_api/src/com/suntek/mway/rcs/client/api/parse/CloudFileMessageParser.java
@@ -25,6 +25,8 @@
 
 import com.suntek.mway.rcs.client.aidl.plugin.entity.cloudfile.CloudFileMessage;
 
+import java.math.BigDecimal;
+
 import org.xml.sax.Attributes;
 import org.xml.sax.SAXException;
 import org.xml.sax.helpers.DefaultHandler;
@@ -93,7 +95,15 @@
             int index = s.indexOf("KB");
             long l = 0L;
             if (index != -1) {
-                l = Long.parseLong(s.substring(0, index));
+                s = s.substring(0, index);
+                l = Long.parseLong(s);
+            } else {
+                try {
+                    l = new BigDecimal(Double.parseDouble(s)/1024)
+                        .setScale(0, BigDecimal.ROUND_HALF_UP).longValue();
+                } catch (Exception e) {
+                    l = 0L;
+                }
             }
             message.setFileSize(l);
         } else if (localName.equals("downloadurl")) {