diff --git a/rcs/Android.mk b/rcs/Android.mk
deleted file mode 100644
index 7f1f7eb..0000000
--- a/rcs/Android.mk
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright 2013 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/rcs/presencepolling/Android.mk b/rcs/presencepolling/Android.mk
deleted file mode 100644
index f1f1471..0000000
--- a/rcs/presencepolling/Android.mk
+++ /dev/null
@@ -1,44 +0,0 @@
- # Copyright (c) 2015, Motorola Mobility LLC
- # All rights reserved.
- #
- # Redistribution and use in source and binary forms, with or without
- # modification, are permitted provided that the following conditions are met:
- #     - Redistributions of source code must retain the above copyright
- #       notice, this list of conditions and the following disclaimer.
- #     - Redistributions in binary form must reproduce the above copyright
- #       notice, this list of conditions and the following disclaimer in the
- #       documentation and/or other materials provided with the distribution.
- #     - Neither the name of Motorola Mobility nor the
- #       names of its contributors may be used to endorse or promote products
- #       derived from this software without specific prior written permission.
- #
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- # DAMAGE.
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_SRC_FILES += $(call all-java-files-under, ../../provider/java)
-
-LOCAL_JAVA_LIBRARIES := com.android.ims.rcsmanager \
-                        ims-common \
-                        telephony-common
-
-LOCAL_REQUIRED_MODULES := com.android.ims.rcsmanager
-
-LOCAL_PACKAGE_NAME := PresencePolling
-LOCAL_CERTIFICATE := platform
-#LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_PACKAGE)
-
diff --git a/rcs/presencepolling/AndroidManifest.xml b/rcs/presencepolling/AndroidManifest.xml
deleted file mode 100644
index 12db21a..0000000
--- a/rcs/presencepolling/AndroidManifest.xml
+++ /dev/null
@@ -1,118 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?>
-<!--
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
-    package="com.android.service.ims.presence"
-    android:sharedUserId="android.uid.phone"
-    coreApp="true">
-
-    <uses-sdk android:minSdkVersion="19"/>
-
-    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
-    <uses-permission android:name="android.permission.BROADCAST_STICKY"/>
-    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS"/>
-    <uses-permission android:name="android.permission.READ_CONTACTS"/>
-    <uses-permission android:name="android.permission.WRITE_CONTACTS"/>
-    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
-    <uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE"/>
-    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
-    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
-    <uses-permission android:name="com.android.rcs.eab.permission.READ_WRITE_EAB"/>
-    <uses-permission android:name="android.permission.READ_PROFILE"/>
-    <uses-permission android:name="com.android.ims.rcs.permission.STATUS_CHANGED"/>
-    <uses-permission android:name="com.android.ims.permission.PRESENCE_ACCESS"/>
-
-    <application
-        android:label="@string/app_label"
-        android:singleUser="true"
-        android:process="com.android.ims.rcsservice">
-
-        <uses-library android:name="com.android.ims.rcsmanager"
-            android:required="true"/>
-
-        <service
-            android:name=".PollingService"
-            android:excludeFromRecents="true"
-            android:singleUser="true"
-            android:permission="com.android.ims.permission.PRESENCE_ACCESS">
-        </service>
-
-        <receiver android:name=".DeviceBoot" androidprv:systemUserOnly="true">
-            <intent-filter android:priority="103">
-                 <action android:name="com.android.ims.ACTION_PUBLISH_STATUS_CHANGED"/>
-                 <action android:name="android.intent.action.BOOT_COMPLETED"/>
-            </intent-filter>
-        </receiver>
-
-        <receiver android:name=".DeviceShutdown" androidprv:systemUserOnly="true">
-            <intent-filter>
-                 <action android:name="android.intent.action.ACTION_SHUTDOWN"/>
-            </intent-filter>
-        </receiver>
-
-        <receiver android:name=".AlarmBroadcastReceiver"
-            androidprv:systemUserOnly="true"
-            android:permission="com.android.ims.permission.PRESENCE_ACCESS">
-            <intent-filter>
-                <action android:name="com.android.service.ims.presence.periodical_capability_discovery"/>
-                <action android:name="com.android.service.ims.presence.capability_polling_retry"/>
-                <action android:name="android.provider.rcs.eab.EAB_NEW_CONTACT_INSERTED" />
-            </intent-filter>
-        </receiver>
-
-        <receiver android:name=".PresenceBroadcastReceiver"
-            androidprv:systemUserOnly="true"
-            android:permission="com.android.ims.permission.PRESENCE_ACCESS">
-             <intent-filter>
-                 <action android:name="com.android.ims.ACTION_PUBLISH_STATUS_CHANGED"/>
-             </intent-filter>
-        </receiver>
-
-        <service android:name=".PersistService"
-          android:exported="false"
-          android:permission="com.android.ims.permission.PRESENCE_ACCESS">
-            <intent-filter>
-                <action android:name="com.android.ims.ACTION_PRESENCE_CHANGED"/>
-            </intent-filter>
-        </service>
-
-        <service
-            android:name="com.android.service.ims.presence.EABService"
-            android:enabled="true">
-        </service>
-
-        <provider
-            android:name=".EABProvider"
-            android:permission="com.android.rcs.eab.permission.READ_WRITE_EAB"
-            android:exported="true"
-            android:enabled="true"
-            android:authorities="com.android.rcs.eab" />
-    </application>
-</manifest>
diff --git a/rcs/presencepolling/res/values/config.xml b/rcs/presencepolling/res/values/config.xml
deleted file mode 100644
index 5d083a7..0000000
--- a/rcs/presencepolling/res/values/config.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
--->
-
-<resources>
-    <!-- Capability cache expiration in x seconds, default is 90 days. -->
-    <integer name="capability_cache_expiration">7776000</integer>
-
-    <!-- Periodical capability poll in x seconds, default is 7 days. -->
-    <integer name="capability_poll_interval">604800</integer>
-
-</resources>
diff --git a/rcs/presencepolling/res/values/strings.xml b/rcs/presencepolling/res/values/strings.xml
deleted file mode 100644
index 053aca0..0000000
--- a/rcs/presencepolling/res/values/strings.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
--->
-
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-<string name="app_label">Presence</string>
-<string name="ims_presence_permission">Presence</string>
-<string name="ims_ims_permission_desc">Allow the application to poll presence information.</string>
-
-<string translatable="false" name="video_calling_contact_group">Video calling</string>
-<string translatable="false" name="account_pretty_name">Video calling</string>
-
-</resources>
-
diff --git a/rcs/presencepolling/src/com/android/service/ims/presence/AccountUtil.java b/rcs/presencepolling/src/com/android/service/ims/presence/AccountUtil.java
deleted file mode 100644
index 0139f86..0000000
--- a/rcs/presencepolling/src/com/android/service/ims/presence/AccountUtil.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
-
-package com.android.service.ims.presence;
-
-import android.accounts.Account;
-import android.accounts.AccountManager;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.os.Bundle;
-import android.provider.ContactsContract;
-import com.android.ims.internal.Logger;
-
-public class AccountUtil {
-    private static Logger logger = Logger.getLogger("AccountUtil");
-
-    public static final String ACCOUNT_SETTING = "accountSetting";
-    public static final String VTCALL_SETTING = "vtcall_enable"; // "vtCallSetting";
-    public static final String PRESENCE_SETTING = "presence_enable";// "presenceSetting";
-    public static final String ACCOUNT_TYPE = "com.android.rcs.eab.account";
-    public static final String AUTHTOKEN_TYPE = "com.android.rcs.eab.account";
-    public static final String ACCOUNT_NAME = " ";
-
-    public static Account addRcsAccount(Context context) {
-        AccountManager mAccountManager = null;
-        mAccountManager = AccountManager.get(context);
-        Account[] vCallingAccounts = mAccountManager
-                .getAccountsByType(ACCOUNT_TYPE);
-
-        if (vCallingAccounts.length == 0) {
-            logger.debug("Creating Video Calling Account");
-
-            Bundle bundle = new Bundle();
-            bundle.putString("pretty_name",
-                    context.getString(R.string.account_pretty_name));
-
-            Account vCallingAccount = new Account(ACCOUNT_NAME, ACCOUNT_TYPE);
-            if (!mAccountManager.addAccountExplicitly(vCallingAccount, null,
-                    null)) {
-                logger.error("addRcsAccount() failed!");
-                return null;
-            }
-
-            ContentResolver.setIsSyncable(vCallingAccount,
-                    ContactsContract.AUTHORITY, 0);
-            ContentResolver.setSyncAutomatically(vCallingAccount,
-                    ContactsContract.AUTHORITY, false);
-
-            logger.debug("Video Calling account created succesfuly");
-            return vCallingAccount;
-        } else {
-            Account vCallingAccount = new Account(ACCOUNT_NAME, ACCOUNT_TYPE);
-            ContentResolver.setIsSyncable(vCallingAccount,
-                    ContactsContract.AUTHORITY, 0);
-
-            ContentResolver.setSyncAutomatically(vCallingAccount,
-                    ContactsContract.AUTHORITY, false);
-            logger.debug("Video Calling Account already exists");
-            return vCallingAccount;
-        }
-    }
-
-    public static boolean removeRcsAccount(Context context) {
-        logger.debug("removeRcsAccount()");
-        AccountManager mAccountManager = null;
-        boolean result = false;
-        mAccountManager = AccountManager.get(context);
-        Account[] vCallingAccounts = mAccountManager
-                .getAccountsByType(ACCOUNT_TYPE);
-
-        if (vCallingAccounts.length == 0) {
-            logger.debug("Video Calling Account is not present. Do nothing.");
-        } else {
-            Account vCallingAccount = new Account(ACCOUNT_NAME, ACCOUNT_TYPE);
-            mAccountManager.removeAccount(vCallingAccount, null, null);
-            logger.debug("Video Calling Account removed.");
-        }
-        return result;
-    }
-}
diff --git a/rcs/presencepolling/src/com/android/service/ims/presence/AlarmBroadcastReceiver.java b/rcs/presencepolling/src/com/android/service/ims/presence/AlarmBroadcastReceiver.java
deleted file mode 100644
index 1e5c0ef..0000000
--- a/rcs/presencepolling/src/com/android/service/ims/presence/AlarmBroadcastReceiver.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
-
-package com.android.service.ims.presence;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-
-import com.android.ims.internal.Logger;
-import com.android.service.ims.presence.Contacts;
-
-public class AlarmBroadcastReceiver extends BroadcastReceiver {
-    private Logger logger = Logger.getLogger(this.getClass().getName());
-
-    private static final String ACTION_PERIODICAL_DISCOVERY_ALARM =
-            CapabilityPolling.ACTION_PERIODICAL_DISCOVERY_ALARM;
-    private static final String ACTION_POLLING_RETRY_ALARM =
-            PollingTask.ACTION_POLLING_RETRY_ALARM;
-    private static final String ACTION_EAB_NEW_CONTACT_INSERTED =
-            Contacts.ACTION_NEW_CONTACT_INSERTED;
-
-    @Override
-    public void onReceive(Context context, Intent intent) {
-        logger.info("onReceive(), intent: " + intent +
-                ", context: " + context);
-
-        String action = intent.getAction();
-        if (ACTION_PERIODICAL_DISCOVERY_ALARM.equals(action)) {
-            CapabilityPolling capabilityPolling = CapabilityPolling.getInstance(null);
-            if (capabilityPolling != null) {
-                int pollingType = intent.getIntExtra("pollingType",
-                        CapabilityPolling.ACTION_POLLING_NORMAL);
-                capabilityPolling.enqueueDiscovery(pollingType);
-            }
-        } else if (ACTION_POLLING_RETRY_ALARM.equals(action)) {
-            PollingsQueue queue = PollingsQueue.getInstance(null);
-            if (queue != null) {
-                long id = intent.getLongExtra("pollingTaskId", -1);
-                queue.retry(id);
-            }
-        } else if (ACTION_EAB_NEW_CONTACT_INSERTED.equals(action)) {
-            CapabilityPolling capabilityPolling = CapabilityPolling.getInstance(null);
-            if (capabilityPolling != null) {
-                String number = intent.getStringExtra(Contacts.NEW_PHONE_NUMBER);
-                capabilityPolling.enqueueNewContact(number);
-            }
-        } else {
-            logger.debug("No interest in this intent: " + action);
-        }
-    }
-};
-
diff --git a/rcs/presencepolling/src/com/android/service/ims/presence/CapabilityPolling.java b/rcs/presencepolling/src/com/android/service/ims/presence/CapabilityPolling.java
deleted file mode 100644
index 5d3e12f..0000000
--- a/rcs/presencepolling/src/com/android/service/ims/presence/CapabilityPolling.java
+++ /dev/null
@@ -1,845 +0,0 @@
-/*
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
-
-package com.android.service.ims.presence;
-
-import android.app.AlarmManager;
-import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Message;
-import android.os.Process;
-import android.os.SystemClock;
-import android.telephony.PhoneNumberUtils;
-import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyManager;
-import android.text.format.Time;
-import android.text.TextUtils;
-import android.content.ComponentName;
-
-import com.android.ims.ImsConfig;
-import com.android.ims.ImsException;
-import com.android.ims.ImsManager;
-import com.android.internal.telephony.IccCardConstants;
-import com.android.internal.telephony.TelephonyIntents;
-
-import com.android.ims.RcsException;
-import com.android.ims.RcsManager;
-import com.android.ims.RcsManager.ResultCode;
-import com.android.ims.RcsPresence;
-import com.android.ims.RcsPresence.PublishState;
-import com.android.ims.RcsPresenceInfo;
-import com.android.ims.internal.ContactNumberUtils;
-import com.android.ims.internal.Logger;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class CapabilityPolling {
-    private Logger logger = Logger.getLogger(this.getClass().getName());
-    private final Context mContext;
-
-    public static final String ACTION_PERIODICAL_DISCOVERY_ALARM =
-            "com.android.service.ims.presence.periodical_capability_discovery";
-    private PendingIntent mDiscoveryAlarmIntent = null;
-
-    public static final int ACTION_POLLING_NORMAL = 0;
-    public static final int ACTION_POLLING_NEW_CONTACTS = 1;
-
-    private long mCapabilityPollInterval = 604800000L;
-    private long mMinCapabilityPollInterval = 60480000L;
-    private long mCapabilityCacheExpiration = 7776000000L;
-    private long mNextPollingTimeStamp = 0L;
-    private final Object mScheduleSyncObj = new Object();
-
-    private boolean mInitialized = false;
-    private AlarmManager mAlarmManager = null;
-    private EABContactManager mEABContactManager = null;
-    private boolean mStackAvailable = false;
-    private int mPublished = -1;
-    private int mProvisioned = -1;
-
-    private HandlerThread mDiscoveryThread;
-    private Handler mDiscoveryHandler;
-
-    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            logger.info("onReceive(), intent: " + intent +
-                    ", context: " + context);
-
-            String action = intent.getAction();
-            if (RcsManager.ACTION_RCS_SERVICE_AVAILABLE.equals(action)) {
-                enqueueServiceStatusChanged(true);
-            } else if (RcsManager.ACTION_RCS_SERVICE_UNAVAILABLE.equals(action)) {
-                enqueueServiceStatusChanged(false);
-            } else if (RcsManager.ACTION_RCS_SERVICE_DIED.equals(action)) {
-                logger.warn("No handler for this intent: " + action);
-            } else if (RcsPresence.ACTION_PUBLISH_STATE_CHANGED.equals(action)) {
-                int state = intent.getIntExtra(
-                        RcsPresence.EXTRA_PUBLISH_STATE,
-                        RcsPresence.PublishState.PUBLISH_STATE_NOT_PUBLISHED);
-                enqueuePublishStateChanged(state);
-            } else if (ImsConfig.ACTION_IMS_CONFIG_CHANGED.equals(action)) {
-                int item = intent.getIntExtra(ImsConfig.EXTRA_CHANGED_ITEM, -1);
-                if ((ImsConfig.ConfigConstants.CAPABILITIES_POLL_INTERVAL == item) ||
-                    (ImsConfig.ConfigConstants.CAPABILITIES_CACHE_EXPIRATION == item)) {
-                    enqueueSettingsChanged();
-                }
-            } else if(TelephonyIntents.ACTION_SIM_STATE_CHANGED.equalsIgnoreCase(action)) {
-                String stateExtra = intent.getStringExtra(
-                        IccCardConstants.INTENT_KEY_ICC_STATE);
-                logger.print("SIM_STATE_CHANGED: " + stateExtra);
-                if (IccCardConstants.INTENT_VALUE_ICC_LOADED.equalsIgnoreCase(stateExtra)) {
-                    enqueueSimLoaded();
-                }
-            } else {
-                logger.debug("No interest in this intent: " + action);
-            }
-        }
-    };
-
-    private static CapabilityPolling sInstance = null;
-    public static synchronized CapabilityPolling getInstance(Context context) {
-        if ((sInstance == null) && (context != null)) {
-            sInstance = new CapabilityPolling(context);
-        }
-
-        return sInstance;
-    }
-
-    private CapabilityPolling(Context context) {
-        mContext = context;
-
-        ContactNumberUtils.getDefault().setContext(mContext);
-        PresencePreferences.getInstance().setContext(mContext);
-
-        mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
-        mEABContactManager = new EABContactManager(mContext.getContentResolver(),
-                mContext.getPackageName());
-
-        setRcsTestMode(PresencePreferences.getInstance().getRcsTestMode());
-        logger.debug("CapabilityPolling is created.");
-    }
-
-    public void setRcsTestMode(boolean test) {
-        logger.setRcsTestMode(test);
-
-        PresencePreferences pref = PresencePreferences.getInstance();
-        if (pref != null) {
-            if (pref.getRcsTestMode() != test) {
-                pref.setRcsTestMode(test);
-            }
-        }
-    }
-
-    private void initialise() {
-        if (mInitialized) {
-            return;
-        }
-
-        PresenceSetting.init(mContext);
-        long capabilityPollInterval = PresenceSetting.getCapabilityPollInterval();
-        logger.print("getCapabilityPollInterval: " + capabilityPollInterval);
-        if (capabilityPollInterval == -1) {
-            capabilityPollInterval = mContext.getResources().getInteger(
-                    R.integer.capability_poll_interval);
-        }
-        if (capabilityPollInterval < 10) {
-            capabilityPollInterval = 10;
-        }
-
-        long capabilityCacheExpiration = PresenceSetting.getCapabilityCacheExpiration();
-        logger.print("getCapabilityCacheExpiration: " + capabilityCacheExpiration);
-        if (capabilityCacheExpiration == -1) {
-            capabilityCacheExpiration = mContext.getResources().getInteger(
-                    R.integer.capability_cache_expiration);
-        }
-        if (capabilityCacheExpiration < 10) {
-            capabilityCacheExpiration = 10;
-        }
-
-        int publishTimer = PresenceSetting.getPublishTimer();
-        logger.print("getPublishTimer: " + publishTimer);
-        int publishTimerExtended = PresenceSetting.getPublishTimerExtended();
-        logger.print("getPublishTimerExtended: " + publishTimerExtended);
-        int maxEntriesInRequest = PresenceSetting.getMaxNumberOfEntriesInRequestContainedList();
-        logger.print("getMaxNumberOfEntriesInRequestContainedList: " + maxEntriesInRequest);
-        if ((capabilityPollInterval <= 30 * 60) ||     // default: 7 days
-            (capabilityCacheExpiration <= 60 * 60) ||  // default: 90 days
-            (maxEntriesInRequest <= 20) ||             // default: 100
-            (publishTimer <= 10 * 60) ||               // default: 20 minutes
-            (publishTimerExtended <= 20 * 60)) {       // default: 1 day
-            setRcsTestMode(true);
-        }
-
-        if (capabilityCacheExpiration < capabilityPollInterval) {
-            capabilityPollInterval = capabilityCacheExpiration;
-        }
-
-        mCapabilityPollInterval = capabilityPollInterval * 1000;
-        mMinCapabilityPollInterval = mCapabilityPollInterval / 10;
-        logger.info("mCapabilityPollInterval: " + mCapabilityPollInterval +
-                ", mMinCapabilityPollInterval: " + mMinCapabilityPollInterval);
-
-        mCapabilityCacheExpiration = capabilityCacheExpiration * 1000;
-        logger.info("mCapabilityCacheExpiration: " + mCapabilityCacheExpiration);
-
-        mInitialized = true;
-    }
-
-    public void start() {
-        mDiscoveryThread = new HandlerThread("Presence-DiscoveryThread");
-        mDiscoveryThread.start();
-        mDiscoveryHandler = new Handler(mDiscoveryThread.getLooper(), mDiscoveryCallback);
-
-        registerForBroadcasts();
-
-        if (isPollingReady()) {
-            schedulePolling(5 * 1000, ACTION_POLLING_NORMAL);
-        }
-    }
-
-    public void stop() {
-        cancelDiscoveryAlarm();
-        clearPollingTasks();
-        mContext.unregisterReceiver(mReceiver);
-        mDiscoveryThread.quit();
-    }
-
-    private void registerForBroadcasts() {
-        IntentFilter intentFilter = new IntentFilter();
-        intentFilter.addAction(RcsManager.ACTION_RCS_SERVICE_AVAILABLE);
-        intentFilter.addAction(RcsManager.ACTION_RCS_SERVICE_UNAVAILABLE);
-        intentFilter.addAction(RcsManager.ACTION_RCS_SERVICE_DIED);
-        intentFilter.addAction(RcsPresence.ACTION_PUBLISH_STATE_CHANGED);
-        intentFilter.addAction(ImsConfig.ACTION_IMS_CONFIG_CHANGED);
-        intentFilter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
-        mContext.registerReceiver(mReceiver, intentFilter);
-    }
-
-    private boolean isPollingReady() {
-        if (mPublished == -1) {
-            RcsManager rcsManager = RcsManager.getInstance(mContext, 0);
-            if (rcsManager != null) {
-                mStackAvailable = rcsManager.isRcsServiceAvailable();
-                logger.print("isPollingReady, mStackAvailable: " + mStackAvailable);
-                try {
-                    RcsPresence rcsPresence = rcsManager.getRcsPresenceInterface();
-                    if (rcsPresence != null) {
-                        int state = rcsPresence.getPublishState();
-                        mPublished = (PublishState.PUBLISH_STATE_200_OK == state) ? 1 : 0;
-                        logger.print("isPollingReady, mPublished: " + mPublished);
-                    }
-                } catch (RcsException ex) {
-                    logger.warn("RcsPresence.getPublishState failed, exception: " + ex);
-                    mPublished = -1;
-                }
-            }
-        }
-
-        if (mProvisioned == -1) {
-            ImsManager imsManager = ImsManager.getInstance(mContext,
-                    SubscriptionManager.getDefaultVoicePhoneId());
-            if (imsManager != null) {
-                try {
-                    ImsConfig imsConfig = imsManager.getConfigInterface();
-                    if (imsConfig != null) {
-                        mProvisioned = imsConfig.getProvisionedValue(
-                            ImsConfig.ConfigConstants.EAB_SETTING_ENABLED);
-                        logger.print("isPollingReady, mProvisioned: " + mProvisioned);
-                    }
-                } catch (ImsException ex) {
-                    logger.warn("ImsConfig.getEabProvisioned failed, exception: " + ex);
-                    mProvisioned = -1;
-                }
-            }
-        }
-
-        return mStackAvailable && (mPublished == 1) && (mProvisioned == 1);
-    }
-
-    private void serviceStatusChanged(boolean enabled) {
-        logger.print("Enter serviceStatusChanged: " + enabled);
-        mStackAvailable = enabled;
-
-        if (isPollingReady()) {
-            schedulePolling(0, ACTION_POLLING_NORMAL);
-        } else {
-            cancelDiscoveryAlarm();
-            clearPollingTasks();
-        }
-    }
-
-    private void publishStateChanged(int state) {
-        logger.print("Enter publishStateChanged: " + state);
-        mPublished = (PublishState.PUBLISH_STATE_200_OK == state) ? 1 : 0;
-        if (mPublished == 1) {
-            PresencePreferences pref = PresencePreferences.getInstance();
-            if (pref != null) {
-                String mdn_old = pref.getLine1Number();
-                String subscriberId_old = pref.getSubscriberId();
-                if (TextUtils.isEmpty(mdn_old) && TextUtils.isEmpty(subscriberId_old)) {
-                    String mdn = getLine1Number();
-                    pref.setLine1Number(mdn);
-                    String subscriberId = getSubscriberId();
-                    pref.setSubscriberId(subscriberId);
-                }
-            }
-        }
-
-        if (isPollingReady()) {
-            schedulePolling(0, ACTION_POLLING_NORMAL);
-        } else {
-            cancelDiscoveryAlarm();
-            clearPollingTasks();
-        }
-    }
-
-    private void provisionStateChanged() {
-        ImsManager imsManager = ImsManager.getInstance(mContext,
-                SubscriptionManager.getDefaultVoicePhoneId());
-        if (imsManager == null) {
-            return;
-        }
-
-        try {
-            ImsConfig imsConfig = imsManager.getConfigInterface();
-            if (imsConfig == null) {
-                return;
-            }
-            boolean volteProvision = imsConfig.getProvisionedValue(
-                    ImsConfig.ConfigConstants.VLT_SETTING_ENABLED)
-                    == ImsConfig.FeatureValueConstants.ON;
-            boolean vtProvision = imsConfig.getProvisionedValue(
-                    ImsConfig.ConfigConstants.LVC_SETTING_ENABLED)
-                    == ImsConfig.FeatureValueConstants.ON;
-            boolean eabProvision = imsConfig.getProvisionedValue(
-                    ImsConfig.ConfigConstants.EAB_SETTING_ENABLED)
-                    == ImsConfig.FeatureValueConstants.ON;
-            logger.print("Provision state changed, VolteProvision: "
-                        + volteProvision + ", vtProvision: " + vtProvision
-                        + ", eabProvision: " + eabProvision);
-
-            if ((mProvisioned == 1) && !eabProvision) {
-                logger.print("EAB Provision is disabled, clear all capabilities!");
-                if (mEABContactManager != null) {
-                    mEABContactManager.updateAllCapabilityToUnknown();
-                }
-            }
-            mProvisioned = eabProvision ? 1 : 0;
-        } catch (ImsException ex) {
-            logger.warn("ImsConfig.getEabProvisioned failed, exception: " + ex);
-            mProvisioned = -1;
-            return;
-        }
-
-        if (isPollingReady()) {
-            schedulePolling(0, ACTION_POLLING_NORMAL);
-        } else {
-            cancelDiscoveryAlarm();
-            clearPollingTasks();
-        }
-    }
-
-    private void settingsChanged() {
-        logger.print("Enter settingsChanged.");
-        cancelDiscoveryAlarm();
-        clearPollingTasks();
-        mInitialized = false;
-
-        if (isPollingReady()) {
-            schedulePolling(0, ACTION_POLLING_NORMAL);
-        }
-    }
-
-    private void newContactAdded(String number) {
-        logger.print("Enter newContactAdded: " + number);
-        if (TextUtils.isEmpty(number)) {
-            return;
-        }
-
-        EABContactManager.Request request = new EABContactManager.Request(number)
-                .setLastUpdatedTimeStamp(0);
-        int result = mEABContactManager.update(request);
-        if (result <= 0) {
-            return;
-        }
-
-        if (isPollingReady()) {
-            schedulePolling(5 * 1000, ACTION_POLLING_NEW_CONTACTS);
-        }
-    }
-
-    private void verifyPollingResult(int counts) {
-        if (isPollingReady()) {
-            PresencePreferences pref = PresencePreferences.getInstance();
-            if ((pref != null) && pref.getRcsTestMode()) {
-                counts = 1;
-            }
-            long lm = (long)(1 << (counts - 1));
-            schedulePolling(30 * 1000 * lm, ACTION_POLLING_NORMAL);
-        }
-    }
-
-    public synchronized void schedulePolling(long msec, int type) {
-        logger.print("schedulePolling msec=" + msec + " type=" + type);
-        if (!isPollingReady()) {
-            logger.debug("Cancel the polling since the network is not ready");
-            return;
-        }
-
-        if (type == ACTION_POLLING_NEW_CONTACTS) {
-            cancelDiscoveryAlarm();
-        }
-
-        if (mNextPollingTimeStamp != 0L) {
-            long scheduled = mNextPollingTimeStamp - System.currentTimeMillis();
-            if ((scheduled > 0) && (scheduled < msec)) {
-                logger.print("There has been a discovery scheduled at "
-                        + getTimeString(mNextPollingTimeStamp));
-                return;
-            }
-        }
-
-        long nextTime = System.currentTimeMillis() + msec;
-        logger.print("A new discovery needs to be started in " +
-                (msec / 1000) + " seconds at "
-                + getTimeString(nextTime));
-
-        cancelDiscoveryAlarm();
-
-        if (msec <= 0) {
-            enqueueDiscovery(type);
-            return;
-        }
-
-        Intent intent = new Intent(ACTION_PERIODICAL_DISCOVERY_ALARM);
-        intent.setClass(mContext, AlarmBroadcastReceiver.class);
-        intent.putExtra("pollingType", type);
-
-        mDiscoveryAlarmIntent = PendingIntent.getBroadcast(mContext, 0, intent,
-                PendingIntent.FLAG_UPDATE_CURRENT);
-        mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP,
-                SystemClock.elapsedRealtime() + msec, mDiscoveryAlarmIntent);
-
-        mNextPollingTimeStamp = nextTime;
-    }
-
-    private synchronized void doCapabilityDiscovery(int type) {
-        logger.print("doCapabilityDiscovery type=" + type);
-        if (!isPollingReady()) {
-            logger.debug("doCapabilityDiscovery isPollingReady=false");
-            return;
-        }
-
-        long delay = 0;
-        List<Contacts.Item> list = null;
-
-        initialise();
-
-        mNextPollingTimeStamp = 0L;
-        Cursor cursor = null;
-        EABContactManager.Query baseQuery = new EABContactManager.Query()
-                .orderBy(EABContactManager.COLUMN_LAST_UPDATED_TIMESTAMP,
-                         EABContactManager.Query.ORDER_ASCENDING);
-        try {
-            logger.debug("doCapabilityDiscovery.query:\n" + baseQuery);
-            cursor = mEABContactManager.query(baseQuery);
-            if (cursor == null) {
-                logger.print("Cursor is null, there is no database found.");
-                return;
-            }
-            int count = cursor.getCount();
-            if (count == 0) {
-                logger.print("Cursor.getCount() is 0, there is no items found in db.");
-                return;
-            }
-
-            list = new ArrayList<Contacts.Item>();
-            list.clear();
-
-            long current = System.currentTimeMillis();
-            for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
-                long id = cursor.getLong(cursor.getColumnIndex(Contacts.Impl._ID));
-                long last = cursor.getLong(cursor.getColumnIndex(
-                        Contacts.Impl.CONTACT_LAST_UPDATED_TIMESTAMP));
-
-                Contacts.Item item = new Contacts.Item(id);
-                item.setLastUpdateTime(last);
-                item.setNumber(cursor.getString(
-                        cursor.getColumnIndex(Contacts.Impl.CONTACT_NUMBER)));
-                item.setName(cursor.getString(
-                        cursor.getColumnIndex(Contacts.Impl.CONTACT_NAME)));
-                item.setVolteTimestamp(cursor.getLong(
-                        cursor.getColumnIndex(Contacts.Impl.VOLTE_CALL_CAPABILITY_TIMESTAMP)));
-                item.setVideoTimestamp(cursor.getLong(
-                        cursor.getColumnIndex(Contacts.Impl.VIDEO_CALL_CAPABILITY_TIMESTAMP)));
-
-                if ((current - last < 0) ||
-                    (current - last >= mCapabilityPollInterval - mMinCapabilityPollInterval)) {
-                    logger.print("This item will be updated:\n"
-                            + item);
-                    if (item.isValid()) {
-                        list.add(item);
-                    }
-                } else {
-                    logger.print("The first item which will be updated next time:\n" + item);
-                    delay = randomCapabilityPollInterval() - (current - last);
-                    if (delay > 0) {
-                        break;
-                    }
-                }
-            }
-        } catch (Exception ex) {
-            logger.warn("Exception in doCapabilityDiscovery: " + ex);
-            if (delay <= 0) {
-                delay = 5 * 60 * 1000;
-            }
-        } finally {
-            if (cursor != null) {
-                cursor.close();
-            }
-        }
-
-        if (delay <= 0) {
-            delay = randomCapabilityPollInterval();
-        }
-        logger.print("Polling delay: " + delay);
-        schedulePolling(delay, ACTION_POLLING_NORMAL);
-
-        updateObsoleteItems();
-
-        if ((list != null) && (list.size() > 0)) {
-            PollingsQueue queue = PollingsQueue.getInstance(mContext);
-            if (queue != null) {
-                queue.setCapabilityPolling(this);
-                queue.add(type, list);
-            }
-        }
-    }
-
-    private long randomCapabilityPollInterval() {
-        double random = Math.random() * 0.2 + 0.9;
-        logger.print("The random for this time polling is: " + random);
-        random = random * mCapabilityPollInterval;
-        return (long)random;
-    }
-
-    private void updateObsoleteItems() {
-        long current = System.currentTimeMillis();
-        long last = current - mCapabilityCacheExpiration;
-        long last3year = current - 3 * 365 * 24 * 3600000L;
-        StringBuilder sb = new StringBuilder();
-        sb.append("((");
-        sb.append(Contacts.Impl.VOLTE_CALL_CAPABILITY_TIMESTAMP + "<='" + last + "'");
-        sb.append(" OR ");
-        sb.append(Contacts.Impl.VIDEO_CALL_CAPABILITY_TIMESTAMP + "<='" + last + "'");
-        sb.append(") AND ");
-        sb.append(Contacts.Impl.CONTACT_LAST_UPDATED_TIMESTAMP + ">='" + last3year + "'");
-        sb.append(")");
-        EABContactManager.Query baseQuery = new EABContactManager.Query()
-                .setFilterByTime(sb.toString())
-                .orderBy(EABContactManager.COLUMN_ID,
-                         EABContactManager.Query.ORDER_ASCENDING);
-
-        Cursor cursor = null;
-        List<Contacts.Item> list = null;
-        try {
-            logger.debug("updateObsoleteItems.query:\n" + baseQuery);
-            cursor = mEABContactManager.query(baseQuery);
-            if (cursor == null) {
-                logger.print("Cursor is null, there is no database found.");
-                return;
-            }
-            int count = cursor.getCount();
-            if (count == 0) {
-                logger.print("Cursor.getCount() is 0, there is no obsolete items found.");
-                return;
-            }
-
-            list = new ArrayList<Contacts.Item>();
-            list.clear();
-
-            for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
-                long id = cursor.getLong(cursor.getColumnIndex(Contacts.Impl._ID));
-
-                Contacts.Item item = new Contacts.Item(id);
-                item.setLastUpdateTime(cursor.getLong(
-                        cursor.getColumnIndex(Contacts.Impl.CONTACT_LAST_UPDATED_TIMESTAMP)));
-                item.setNumber(cursor.getString(
-                        cursor.getColumnIndex(Contacts.Impl.CONTACT_NUMBER)));
-                item.setName(cursor.getString(
-                        cursor.getColumnIndex(Contacts.Impl.CONTACT_NAME)));
-                item.setVolteTimestamp(cursor.getLong(
-                        cursor.getColumnIndex(Contacts.Impl.VOLTE_CALL_CAPABILITY_TIMESTAMP)));
-                item.setVideoTimestamp(cursor.getLong(
-                        cursor.getColumnIndex(Contacts.Impl.VIDEO_CALL_CAPABILITY_TIMESTAMP)));
-                logger.print("updateObsoleteItems, the obsolete item:\n" + item);
-
-                if ((item.lastUpdateTime() > 0) && item.isValid()) {
-                    list.add(item);
-                }
-            }
-        } catch (Exception ex) {
-            logger.warn("Exception in updateObsoleteItems: " + ex);
-        } finally {
-            if (cursor != null) {
-                cursor.close();
-            }
-        }
-
-        if ((list == null) || (list.size() <= 0)) {
-            return;
-        }
-
-        for (Contacts.Item item : list) {
-            EABContactManager.Request request = new EABContactManager.Request(item.id());
-            if (item.volteTimestamp() <= last) {
-                request.setVolteCallCapability(false);
-                request.setVolteCallCapabilityTimeStamp(current);
-            }
-            if (item.videoTimestamp() <= last) {
-                request.setVideoCallCapability(false);
-                request.setVideoCallCapabilityTimeStamp(current);
-            }
-            int result = mEABContactManager.update(request);
-            if (result <= 0) {
-                logger.print("Failed to update this request: " + request);
-            }
-        }
-    }
-
-    private void cancelDiscoveryAlarm() {
-        if (mDiscoveryAlarmIntent != null) {
-            mAlarmManager.cancel(mDiscoveryAlarmIntent);
-            mDiscoveryAlarmIntent = null;
-            mNextPollingTimeStamp = 0L;
-        }
-    }
-
-    private void clearPollingTasks() {
-        PollingsQueue queue = PollingsQueue.getInstance(null);
-        if (queue != null) {
-            queue.clear();
-        }
-    }
-
-    private String getTimeString(long time) {
-        if (time <= 0) {
-            time = System.currentTimeMillis();
-        }
-
-        Time tobj = new Time();
-        tobj.set(time);
-        return String.format("%s.%s", tobj.format("%m-%d %H:%M:%S"), time % 1000);
-    }
-
-    private static final int MSG_CHECK_DISCOVERY = 1;
-    private static final int MSG_NEW_CONTACT_ADDED = 2;
-    private static final int MSG_SERVICE_STATUS_CHANGED = 3;
-    private static final int MSG_SETTINGS_CHANGED = 4;
-    private static final int MSG_PUBLISH_STATE_CHANGED = 5;
-    private static final int MSG_SIM_LOADED = 6;
-    private static final int MSG_PROVISION_STATE_CHANGED = 7;
-    private static final int MSG_VERIFY_POLLING_RESULT = 8;
-
-    public void enqueueDiscovery(int type) {
-        mDiscoveryHandler.removeMessages(MSG_CHECK_DISCOVERY);
-        mDiscoveryHandler.obtainMessage(MSG_CHECK_DISCOVERY, type, -1).sendToTarget();
-    }
-
-    public void enqueueNewContact(String number) {
-        mDiscoveryHandler.obtainMessage(MSG_NEW_CONTACT_ADDED, number).sendToTarget();
-    }
-
-    private void enqueueServiceStatusChanged(boolean enabled) {
-        mDiscoveryHandler.removeMessages(MSG_SERVICE_STATUS_CHANGED);
-        mDiscoveryHandler.obtainMessage(MSG_SERVICE_STATUS_CHANGED,
-                enabled ? 1 : 0, -1).sendToTarget();
-    }
-
-    private void enqueuePublishStateChanged(int state) {
-        mDiscoveryHandler.removeMessages(MSG_PUBLISH_STATE_CHANGED);
-        mDiscoveryHandler.obtainMessage(MSG_PUBLISH_STATE_CHANGED,
-                state, -1).sendToTarget();
-    }
-
-    public void enqueueSettingsChanged() {
-        mDiscoveryHandler.removeMessages(MSG_SETTINGS_CHANGED);
-        mDiscoveryHandler.obtainMessage(MSG_SETTINGS_CHANGED).sendToTarget();
-    }
-
-    private void enqueueSimLoaded() {
-        mDiscoveryHandler.removeMessages(MSG_SIM_LOADED);
-        mDiscoveryHandler.obtainMessage(MSG_SIM_LOADED).sendToTarget();
-    }
-
-    private void enqueueProvisionStateChanged() {
-        mDiscoveryHandler.removeMessages(MSG_PROVISION_STATE_CHANGED);
-        mDiscoveryHandler.obtainMessage(MSG_PROVISION_STATE_CHANGED).sendToTarget();
-    }
-
-    public void enqueueVerifyPollingResult(int counts) {
-        mDiscoveryHandler.removeMessages(MSG_VERIFY_POLLING_RESULT);
-        mDiscoveryHandler.obtainMessage(MSG_VERIFY_POLLING_RESULT, counts, -1).sendToTarget();
-    }
-
-    private Handler.Callback mDiscoveryCallback = new Handler.Callback() {
-        @Override
-        public boolean handleMessage(Message msg) {
-            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
-
-            if (msg.what == MSG_CHECK_DISCOVERY) {
-                doCapabilityDiscovery(msg.arg1);
-            } else if (msg.what == MSG_NEW_CONTACT_ADDED) {
-                newContactAdded((String)msg.obj);
-            } else if (msg.what == MSG_SERVICE_STATUS_CHANGED) {
-                serviceStatusChanged(msg.arg1 == 1);
-            } else if (msg.what == MSG_PUBLISH_STATE_CHANGED) {
-                publishStateChanged(msg.arg1);
-            } else if (msg.what == MSG_SETTINGS_CHANGED) {
-                settingsChanged();
-            } else if(msg.what == MSG_SIM_LOADED) {
-                onSimLoaded();
-            } else if(msg.what == MSG_PROVISION_STATE_CHANGED) {
-                provisionStateChanged();
-            } else if(msg.what == MSG_VERIFY_POLLING_RESULT) {
-                verifyPollingResult(msg.arg1);
-            } else {
-            }
-
-            return true;
-        }
-    };
-
-    private void onSimLoaded() {
-        PresencePreferences pref = PresencePreferences.getInstance();
-        if (pref == null) {
-            return;
-        }
-
-        String mdn_old = pref.getLine1Number();
-        if (TextUtils.isEmpty(mdn_old)) {
-            return;
-        }
-        String subscriberId_old = pref.getSubscriberId();
-        if (TextUtils.isEmpty(subscriberId_old)) {
-            return;
-        }
-
-        String mdn = getLine1Number();
-        String subscriberId = getSubscriberId();
-        if (TextUtils.isEmpty(mdn) && TextUtils.isEmpty(subscriberId)) {
-            return;
-        }
-
-        boolean mdnMatched = false;
-        if (TextUtils.isEmpty(mdn) || PhoneNumberUtils.compare(mdn_old, mdn)) {
-            mdnMatched = true;
-        }
-        boolean subscriberIdMatched = false;
-        if (TextUtils.isEmpty(subscriberId) || subscriberId.equals(subscriberId_old)) {
-            subscriberIdMatched = true;
-        }
-        if (mdnMatched && subscriberIdMatched) {
-            return;
-        }
-
-        logger.print("Remove presence cache for Sim card changed!");
-        pref.setLine1Number("");
-        pref.setSubscriberId("");
-
-        if (mEABContactManager != null) {
-            mEABContactManager.updateAllCapabilityToUnknown();
-        }
-    }
-
-    private static final int DEFAULT_SUBSCRIPTION = 1;
-    private String getLine1Number() {
-        if (mContext == null) {
-            return null;
-        }
-
-        TelephonyManager telephony = (TelephonyManager)
-                mContext.getSystemService(Context.TELEPHONY_SERVICE);
-        if (telephony == null) {
-            return null;
-        }
-
-        String mdn = null;
-        if (TelephonyManager.getDefault().isMultiSimEnabled()) {
-            int subId = SubscriptionManager.getDefaultDataSubscriptionId();
-            if (!SubscriptionManager.isValidSubscriptionId(subId)) {
-                subId = DEFAULT_SUBSCRIPTION;
-            }
-            mdn = telephony.getLine1Number(subId);
-        } else {
-            mdn = telephony.getLine1Number();
-        }
-
-        if ((mdn == null) || (mdn.length() == 0) ||  mdn.startsWith("00000")) {
-            return null;
-        }
-
-        logger.print("getLine1Number: " + mdn);
-        return mdn;
-    }
-
-    private String getSubscriberId() {
-        if (mContext == null) {
-            return null;
-        }
-
-        TelephonyManager telephony = (TelephonyManager)
-                mContext.getSystemService(Context.TELEPHONY_SERVICE);
-        if (telephony == null) {
-            return null;
-        }
-
-        String subscriberId = null;
-        if (TelephonyManager.getDefault().isMultiSimEnabled()) {
-            int subId = SubscriptionManager.getDefaultDataSubscriptionId();
-            if (!SubscriptionManager.isValidSubscriptionId(subId)) {
-                subId = DEFAULT_SUBSCRIPTION;
-            }
-            subscriberId = telephony.getSubscriberId(subId);
-        } else {
-            subscriberId = telephony.getSubscriberId();
-        }
-
-        logger.print("getSubscriberId: " + subscriberId);
-        return subscriberId;
-    }
-}
diff --git a/rcs/presencepolling/src/com/android/service/ims/presence/ContactDbUtil.java b/rcs/presencepolling/src/com/android/service/ims/presence/ContactDbUtil.java
deleted file mode 100644
index e4f4a21..0000000
--- a/rcs/presencepolling/src/com/android/service/ims/presence/ContactDbUtil.java
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
-
-package com.android.service.ims.presence;
-
-import android.accounts.Account;
-import android.content.ContentResolver;
-import android.content.ContentUris;
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.Cursor;
-import android.net.Uri;
-import android.provider.ContactsContract.Groups;
-
-import android.provider.ContactsContract;
-import android.provider.ContactsContract.CommonDataKinds.Phone;
-
-import com.android.ims.internal.EABContract;
-import com.android.ims.internal.Logger;
-
-public class ContactDbUtil {
-    private static Logger logger = Logger.getLogger("ContactDbUtil");
-
-    public static void addVideoCallingContactGroup(Context context, Account vCallingAccount) {
-        logger.info("addVideoCallingContactGroup");
-        ContentResolver contentResolver = context.getContentResolver();
-        if (vCallingAccount == null) {
-            logger.error("vCallingAccount == null");
-            return;
-        }
-        long videoCallingGroupId = 0;
-        final Cursor cursor = contentResolver.query(Groups.CONTENT_URI,
-                new String[] { Groups._ID },
-                Groups.ACCOUNT_NAME + "=? AND " + Groups.ACCOUNT_TYPE + "=? AND " +
-                Groups.TITLE + "=?",
-                new String[] { AccountUtil.ACCOUNT_NAME, AccountUtil.ACCOUNT_TYPE,
-                context.getString(R.string.video_calling_contact_group) }, null);
-        if (cursor != null) {
-            try {
-                if (cursor.moveToFirst()) {
-                    videoCallingGroupId = cursor.getLong(0);
-                }
-            } finally {
-                cursor.close();
-            }
-        }
-        if (videoCallingGroupId == 0) {
-            logger.debug("addVideoCallingContactGroup, creating group");
-
-            // Video Calling group doesn't exist yet, so create it
-            final ContentValues contentValues = new ContentValues();
-            contentValues.put(Groups.ACCOUNT_NAME, AccountUtil.ACCOUNT_NAME);
-            contentValues.put(Groups.ACCOUNT_TYPE, AccountUtil.ACCOUNT_TYPE);
-            contentValues.put(Groups.TITLE, context.getString(R.string.video_calling_contact_group));
-            contentValues.put(Groups.GROUP_IS_READ_ONLY, 1);
-            contentValues.put(Groups.GROUP_VISIBLE, 1);
-            contentValues.put(Groups.SYSTEM_ID, "com.android.vt.eab");
-
-            final Uri newGroupUri = contentResolver.insert(Groups.CONTENT_URI, contentValues);
-            if (null != newGroupUri) {
-                videoCallingGroupId = ContentUris.parseId(newGroupUri);
-            } else {
-                logger.error("newGroupUri is null.");
-            }
-        } else {
-            logger.debug("addVideoCallingContactGroup, Video Calling Group, already exists!!!");
-
-        }
-
-        logger.debug("videoCallingGroupId: " + videoCallingGroupId);
-        SharedPrefUtil.setVideoCallingGroupId(context, videoCallingGroupId);
-    }
-
-    public static void removeVideoCallingContactGroup(Context context) {
-        logger.debug("removeVideoCallingContactGroup");
-        long storedVideoCallingGroupId = SharedPrefUtil.getVideoCallingGroupId(context);
-        long videoCallingGroupId = 0;
-        ContentResolver contentResolver = context.getContentResolver();
-        final Cursor cursor = contentResolver.query(Groups.CONTENT_URI,
-                new String[] { Groups._ID },
-                Groups.ACCOUNT_NAME + "=? AND " + Groups.ACCOUNT_TYPE + "=? AND " +
-                Groups.TITLE + "=?",
-                new String[] { AccountUtil.ACCOUNT_NAME, AccountUtil.ACCOUNT_TYPE,
-                context.getString(R.string.video_calling_contact_group) }, null);
-        if (cursor != null) {
-            try {
-                if (cursor.moveToFirst()) {
-                    videoCallingGroupId = cursor.getLong(0);
-                }
-            } finally {
-                cursor.close();
-            }
-        }
-        logger.debug("videoCallingGroupId : " + videoCallingGroupId);
-        logger.debug("storedVideoCallingGroupId : " + storedVideoCallingGroupId);
-        if (videoCallingGroupId == 0) {
-            logger.debug("videoCallingGroupId : " + videoCallingGroupId +
-                    " not present. Do nothing. ");
-        } else {
-            if (storedVideoCallingGroupId == videoCallingGroupId) {
-                String deleteWhereClause = Groups._ID + "='" + videoCallingGroupId + "'";
-                contentResolver.delete(Groups.CONTENT_URI, deleteWhereClause, null);
-                logger.debug("Removing Video Calling Group.");
-            }
-            SharedPrefUtil.setVideoCallingGroupId(context, 0);
-        }
-        logger.debug("videoCallingGroupId: " + videoCallingGroupId);
-    }
-
-    public static int resetVtCapability(ContentResolver resolver) {
-        if(resolver == null) {
-            logger.error("resetVtCapability, resolver = null");
-            return 0;
-        }
-
-        String selection = ContactsContract.Data.MIMETYPE + " = '" + Phone.CONTENT_ITEM_TYPE + "'";
-
-        ContentValues values = new ContentValues();
-        values.put(ContactsContract.Data.CARRIER_PRESENCE, 0); // reset all.
-        int count = resolver.update(ContactsContract.Data.CONTENT_URI, values, selection, null);
-        logger.debug("resetVtCapability count=" + count);
-        return count;
-    }
-
-    public static int updateVtCapability(ContentResolver resolver, String number, boolean enable) {
-        String[] projection = new String[] {EABContract.EABColumns.DATA_ID};
-
-        int updatedCount = 0;
-        Cursor cursor = null;
-        try {
-            cursor = resolver.query(Contacts.Impl.CONTENT_URI,
-                   projection, "PHONE_NUMBERS_EQUAL(contact_number, ?, 0)",
-                   new String[] {number}, null);
-            if(null != cursor) {
-                int count = cursor.getCount();
-                logger.debug("updateVtCapability to Contact DB, count=" + count);
-                if(count <= 0) {
-                    logger.error("updateVtCapability, no number to be updated");
-                    cursor.close();
-                    cursor = null;
-                    return updatedCount;
-                }
-
-                while(cursor.moveToNext()) {
-                    long dataId = cursor.getLong(cursor.getColumnIndex(
-                            EABContract.EABColumns.DATA_ID));
-                    // update one by one to avoid loosing matching error.
-                    updatedCount += updateVtCapability(resolver, dataId, enable);
-                }
-            }
-        } catch (Exception e) {
-            logger.error("updateVtCapability exception", e);
-        } finally {
-            if(cursor != null) {
-                cursor.close();
-            }
-        }
-
-        logger.debug("updateVtCapability updatedCount=" + updatedCount);
-        return updatedCount;
-    }
-
-    public static int updateVtCapability(ContentResolver resolver, long dataId, boolean enable) {
-        if(resolver == null) {
-            logger.error("resetVtCapability, resolver = null");
-            return 0;
-        }
-
-        String selection = ContactsContract.Data.MIMETYPE + " = '" + Phone.CONTENT_ITEM_TYPE
-                + "' and " + ContactsContract.Data._ID + "= '" + dataId + "'";
-
-        int oldValue = 0;
-        final Cursor cursor = resolver.query(ContactsContract.Data.CONTENT_URI,
-                new String[] { ContactsContract.Data._ID, ContactsContract.Data.CARRIER_PRESENCE },
-                selection, null, null);
-        if (cursor != null) {
-            try {
-                if (cursor.moveToFirst()) {
-                    oldValue = cursor.getInt(1);
-                }
-            } finally {
-                cursor.close();
-            }
-        }
-
-
-        ContentValues values = new ContentValues();
-        values.put(ContactsContract.Data.CARRIER_PRESENCE,
-                enable?(oldValue | ContactsContract.Data.CARRIER_PRESENCE_VT_CAPABLE):
-                (oldValue & ~ContactsContract.Data.CARRIER_PRESENCE_VT_CAPABLE));
-        int count = resolver.update(ContactsContract.Data.CONTENT_URI, values, selection, null);
-        logger.debug("resetVtCapability count=" + count);
-        return count;
-    }
-}
diff --git a/rcs/presencepolling/src/com/android/service/ims/presence/Contacts.java b/rcs/presencepolling/src/com/android/service/ims/presence/Contacts.java
deleted file mode 100644
index cbad25a..0000000
--- a/rcs/presencepolling/src/com/android/service/ims/presence/Contacts.java
+++ /dev/null
@@ -1,297 +0,0 @@
-/*
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
-
-package com.android.service.ims.presence;
-
-import android.net.Uri;
-import android.os.SystemClock;
-import android.provider.BaseColumns;
-import android.text.format.Time;
-import com.android.ims.internal.EABContract;
-
-import com.android.ims.internal.ContactNumberUtils;
-
-public final class Contacts {
-    private Contacts() {}
-
-    /**
-     * Intent that a new contact is inserted in EAB Provider.
-     * This intent will have a extra parameter with key NEW_PHONE_NUMBER.
-     */
-    public static final String ACTION_NEW_CONTACT_INSERTED =
-            "android.provider.rcs.eab.EAB_NEW_CONTACT_INSERTED";
-
-    /**
-     * Key to bundle the new phone number inserted in EAB Provider.
-     */
-    public static final String NEW_PHONE_NUMBER = "newPhoneNumber";
-
-
-    public static final String AUTHORITY = EABContract.AUTHORITY;
-
-    public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY);
-
-    public static final class Impl implements BaseColumns {
-        private Impl() {}
-
-        public static final String TABLE_NAME =
-                EABContract.EABColumns.TABLE_NAME;
-
-        /**
-         * CONTENT_URI
-         * <P>
-         * "content://com.android.vt.eab/EABPresence"
-         * </P>
-         */
-        public static final Uri CONTENT_URI =
-                Uri.withAppendedPath(Contacts.CONTENT_URI, TABLE_NAME);
-
-        /**
-         * Key defining the contact number.
-         * <P>
-         * Type: TEXT
-         * </P>
-         */
-        public static final String CONTACT_NUMBER =
-                EABContract.EABColumns.CONTACT_NUMBER;
-
-        /**
-         * Key defining the contact name.
-         * <P>
-         * Type: TEXT
-         * </P>
-         */
-        public static final String CONTACT_NAME =
-                EABContract.EABColumns.CONTACT_NAME;
-
-        /**
-         * <p>
-         * Type: INT
-         * </p>
-         */
-        public static final String VOLTE_STATUS =
-                EABContract.EABColumns.VOLTE_STATUS;
-
-        /**
-         * Key defining the last updated timestamp.
-         * <P>
-         * Type: LONG
-         * </P>
-         */
-        public static final String CONTACT_LAST_UPDATED_TIMESTAMP =
-                EABContract.EABColumns.CONTACT_LAST_UPDATED_TIMESTAMP;
-
-        /**
-         * Key defining the VoLTE call service contact address.
-         * <P>
-         * Type: TEXT
-         * </P>
-         */
-        public static final String VOLTE_CALL_SERVICE_CONTACT_ADDRESS =
-                EABContract.EABColumns.VOLTE_CALL_SERVICE_CONTACT_ADDRESS;
-
-        /**
-         * Key defining the VoLTE call capability.
-         * <P>
-         * Type: TEXT
-         * </P>
-         */
-        public static final String VOLTE_CALL_CAPABILITY =
-                EABContract.EABColumns.VOLTE_CALL_CAPABILITY;
-
-        /**
-         * Key defining the VoLTE call capability timestamp.
-         * <P>
-         * Type: LONG
-         * </P>
-         */
-        public static final String VOLTE_CALL_CAPABILITY_TIMESTAMP =
-                EABContract.EABColumns.VOLTE_CALL_CAPABILITY_TIMESTAMP;
-
-        /**
-         * Key defining the VoLTE call availability.
-         * <P>
-         * Type: TEXT
-         * </P>
-         */
-        public static final String VOLTE_CALL_AVAILABILITY =
-                EABContract.EABColumns.VOLTE_CALL_AVAILABILITY;
-
-        /**
-         * Key defining the VoLTE call availability timestamp.
-         * <P>
-         * Type: LONG
-         * </P>
-         */
-        public static final String VOLTE_CALL_AVAILABILITY_TIMESTAMP =
-                EABContract.EABColumns.VOLTE_CALL_AVAILABILITY_TIMESTAMP;
-
-        /**
-         * Key defining the Video call service contact address.
-         * <P>
-         * Type: TEXT
-         * </P>
-         */
-        public static final String VIDEO_CALL_SERVICE_CONTACT_ADDRESS =
-                EABContract.EABColumns.VIDEO_CALL_SERVICE_CONTACT_ADDRESS;
-
-        /**
-         * Key defining the Video call capability.
-         * <P>
-         * Type: TEXT
-         * </P>
-         */
-        public static final String VIDEO_CALL_CAPABILITY =
-                EABContract.EABColumns.VIDEO_CALL_CAPABILITY;
-
-        /**
-         * Key defining the Video call capability timestamp.
-         * <P>
-         * Type: LONG
-         * </P>
-         */
-        public static final String VIDEO_CALL_CAPABILITY_TIMESTAMP =
-                EABContract.EABColumns.VIDEO_CALL_CAPABILITY_TIMESTAMP;
-
-        /**
-         * Key defining the Video call availability.
-         * <P>
-         * Type: TEXT
-         * </P>
-         */
-        public static final String VIDEO_CALL_AVAILABILITY =
-                EABContract.EABColumns.VIDEO_CALL_AVAILABILITY;
-
-        /**
-         * Key defining the Video call availability timestamp.
-         * <P>
-         * Type: LONG
-         * </P>
-         */
-        public static final String VIDEO_CALL_AVAILABILITY_TIMESTAMP =
-                EABContract.EABColumns.VIDEO_CALL_AVAILABILITY_TIMESTAMP;
-    }
-
-    public static class Item {
-        public Item(long id) {
-            mId = id;
-        }
-
-        public long id() {
-            return mId;
-        }
-
-        public String number() {
-            return mNumber;
-        }
-
-        public void setNumber(String number) {
-            mNumber = ContactNumberUtils.getDefault().format(number);
-        }
-
-        public boolean isValid() {
-            int res = ContactNumberUtils.getDefault().validate(mNumber);
-            return (res == ContactNumberUtils.NUMBER_VALID);
-        }
-
-        public String name() {
-            return mName;
-        }
-
-        public void setName(String name) {
-            mName = name;
-        }
-
-        public long lastUpdateTime() {
-            return mLastUpdateTime;
-        }
-
-        public void setLastUpdateTime(long time) {
-            mLastUpdateTime = time;
-        }
-
-        public long volteTimestamp() {
-            return mVolteTimeStamp;
-        }
-
-        public void setVolteTimestamp(long time) {
-            mVolteTimeStamp = time;
-        }
-
-        public long videoTimestamp() {
-            return mVideoTimeStamp;
-        }
-
-        public void setVideoTimestamp(long time) {
-            mVideoTimeStamp = time;
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (this == o) return true;
-            if (!(o instanceof Contacts.Item)) return false;
-
-            Contacts.Item that = (Contacts.Item) o;
-            return this.number().equalsIgnoreCase(that.number());
-        }
-
-        @Override
-        public String toString() {
-            return new StringBuilder(256)
-                .append("Contacts.Item { ")
-                .append("\nId: " + mId)
-                .append("\nNumber: " + mNumber)
-                .append("\nLast update time: " + mLastUpdateTime + "(" +
-                        getTimeString(mLastUpdateTime) + ")")
-                .append("\nVolte capability timestamp: " + mVolteTimeStamp + "(" +
-                        getTimeString(mVolteTimeStamp) + ")")
-                .append("\nVideo capability timestamp: " + mVideoTimeStamp + "(" +
-                        getTimeString(mVideoTimeStamp) + ")")
-                .append("\nisValid: " + isValid())
-                .append(" }")
-                .toString();
-        }
-
-        private String getTimeString(long time) {
-            if (time <= 0) {
-                time = System.currentTimeMillis();
-            }
-
-            Time tobj = new Time();
-            tobj.set(time);
-            return String.format("%s.%s", tobj.format("%m-%d %H:%M:%S"), time % 1000);
-        }
-
-        private long mId;
-        private String mNumber;
-        private String mName;
-        private long mLastUpdateTime;
-        private long mVolteTimeStamp;
-        private long mVideoTimeStamp;
-    }
-}
diff --git a/rcs/presencepolling/src/com/android/service/ims/presence/DatabaseContentProvider.java b/rcs/presencepolling/src/com/android/service/ims/presence/DatabaseContentProvider.java
deleted file mode 100644
index 0ae9bc9..0000000
--- a/rcs/presencepolling/src/com/android/service/ims/presence/DatabaseContentProvider.java
+++ /dev/null
@@ -1,434 +0,0 @@
-/*
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
-
-package com.android.service.ims.presence;
-
-import java.io.File;
-
-import android.content.ContentProvider;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.Intent;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteException;
-import android.database.sqlite.SQLiteFullException;
-import android.database.sqlite.SQLiteOpenHelper;
-import android.net.Uri;
-
-import com.android.ims.internal.Logger;
-
-public abstract class DatabaseContentProvider extends ContentProvider {
-    static private Logger logger = Logger.getLogger("DatabaseContentProvider");
-
-    //Constants
-    public static final String ACTION_DEVICE_STORAGE_FULL = "com.android.vmm.DEVICE_STORAGE_FULL";
-
-    //Fields
-    protected SQLiteOpenHelper mDbHelper;
-    /*package*/final int mDbVersion;
-    private final String mDbName;
-
-    /**
-     * Initializes the DatabaseContentProvider
-     * @param dbName the filename of the database
-     * @param dbVersion the current version of the database schema
-     * @param contentUri The base Uri of the syncable content in this provider
-     */
-    public DatabaseContentProvider(String dbName, int dbVersion) {
-        super();
-        mDbName = dbName;
-        mDbVersion = dbVersion;
-    }
-
-    /**
-     * bootstrapDatabase() allows the implementer to set up their database
-     * after it is opened for the first time.  this is a perfect place
-     * to create tables and triggers :)
-     * @param db
-     */
-    protected void bootstrapDatabase(SQLiteDatabase db) {
-    }
-
-    /**
-     * updgradeDatabase() allows the user to do whatever they like
-     * when the database is upgraded between versions.
-     * @param db - the SQLiteDatabase that will be upgraded
-     * @param oldVersion - the old version number as an int
-     * @param newVersion - the new version number as an int
-     * @return
-     */
-    protected abstract boolean upgradeDatabase(SQLiteDatabase db, int oldVersion, int newVersion);
-
-    /**
-     * downgradeDatabase() allows the user to do whatever they like when the
-     * database is downgraded between versions.
-     *
-     * @param db - the SQLiteDatabase that will be downgraded
-     * @param oldVersion - the old version number as an int
-     * @param newVersion - the new version number as an int
-     * @return
-     */
-    protected abstract boolean downgradeDatabase(SQLiteDatabase db, int oldVersion, int newVersion);
-
-    /**
-     * Safely wraps an ALTER TABLE table ADD COLUMN columnName columnType
-     * If columnType == null then it's set to INTEGER DEFAULT 0
-     * @param db - db to alter
-     * @param table - table to alter
-     * @param columnDef
-     * @return
-     */
-    protected static boolean addColumn(SQLiteDatabase db, String table, String columnName,
-            String columnType) {
-        StringBuilder sb = new StringBuilder();
-        sb.append("ALTER TABLE ").append(table).append(" ADD COLUMN ").append(columnName).append(
-                ' ').append(columnType == null ? "INTEGER DEFAULT 0" : columnType).append(';');
-        try {
-            db.execSQL(sb.toString());
-        } catch (SQLiteException e) {
-                logger.debug("Alter table failed : "+ e.getMessage());
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * onDatabaseOpened() allows the user to do whatever they might
-     * need to do whenever the database is opened
-     * @param db - SQLiteDatabase that was just opened
-     */
-    protected void onDatabaseOpened(SQLiteDatabase db) {
-    }
-
-    private class DatabaseHelper extends SQLiteOpenHelper {
-        private File mDatabaseFile = null;
-
-        DatabaseHelper(Context context, String name) {
-            // Note: context and name may be null for temp providers
-            super(context, name, null, mDbVersion);
-            mDatabaseFile = context.getDatabasePath(name);
-        }
-
-        @Override
-        public void onCreate(SQLiteDatabase db) {
-            bootstrapDatabase(db);
-        }
-
-        @Override
-        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
-            upgradeDatabase(db, oldVersion, newVersion);
-        }
-
-        @Override
-        public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
-            logger.debug("Enter: onDowngrade() - oldVersion = " + oldVersion + " newVersion = "
-                    + newVersion);
-            downgradeDatabase(db, oldVersion, newVersion);
-        }
-
-        @Override
-        public void onOpen(SQLiteDatabase db) {
-            onDatabaseOpened(db);
-        }
-
-        @Override
-        public synchronized SQLiteDatabase getWritableDatabase() {
-            try {
-                return super.getWritableDatabase();
-            } catch (InvalidDBException e) {
-                logger.error("getWritableDatabase - caught InvalidDBException ");
-            }
-
-            // try to delete the database file
-            if (null != mDatabaseFile) {
-                logger.error("deleting mDatabaseFile.");
-                mDatabaseFile.delete();
-            }
-
-            // Return a freshly created database.
-            return super.getWritableDatabase();
-        }
-
-        @Override
-        public synchronized SQLiteDatabase getReadableDatabase() {
-            try {
-                return super.getReadableDatabase();
-            } catch (InvalidDBException e) {
-                logger.error("getReadableDatabase - caught InvalidDBException ");
-            }
-
-            // try to delete the database file
-            if (null != mDatabaseFile) {
-                logger.error("deleting mDatabaseFile.");
-                mDatabaseFile.delete();
-            }
-
-            // Return a freshly created database.
-            return super.getReadableDatabase();
-        }
-    }
-
-    /**
-     * deleteInternal allows getContentResolver().delete() to occur atomically
-     * via transactions and notify the uri automatically upon completion (provided
-     * rows were deleted) - otherwise, it functions exactly as getContentResolver.delete()
-     * would on a regular ContentProvider
-     * @param uri - uri to delete from
-     * @param selection - selection used for the uri
-     * @param selectionArgs - selection args replacing ?'s in the selection
-     * @return returns the number of rows deleted
-     */
-    protected abstract int deleteInternal(final SQLiteDatabase db, Uri uri, String selection,
-            String[] selectionArgs);
-
-    @Override
-    public int delete(Uri uri, String selection, String[] selectionArgs) {
-        int result = 0;
-        SQLiteDatabase db = mDbHelper.getWritableDatabase();
-        if (isClosed(db)) {
-            return result;
-        }
-        try {
-            //acquire reference to prevent from garbage collection
-            db.acquireReference();
-            //beginTransaction can throw a runtime exception
-            //so it needs to be moved into the try
-            db.beginTransaction();
-            result = deleteInternal(db, uri, selection, selectionArgs);
-            db.setTransactionSuccessful();
-        } catch (SQLiteFullException fullEx) {
-            logger.error("" + fullEx);
-            sendStorageFullIntent(getContext());
-        } catch (Exception e) {
-            logger.error("" + e);
-        } finally {
-            try {
-                db.endTransaction();
-            } catch (SQLiteFullException fullEx) {
-                logger.error("" + fullEx);
-                sendStorageFullIntent(getContext());
-            } catch (Exception e) {
-                logger.error("" + e);
-            }
-            //release reference
-            db.releaseReference();
-        }
-        // don't check return value because it may be 0 if all rows deleted
-        getContext().getContentResolver().notifyChange(uri, null);
-        return result;
-    }
-
-    /**
-     * insertInternal allows getContentResolver().insert() to occur atomically
-     * via transactions and notify the uri automatically upon completion (provided
-     * rows were added to the db) - otherwise, it functions exactly as getContentResolver().insert()
-     * would on a regular ContentProvider
-     * @param uri - uri on which to insert
-     * @param values - values to insert
-     * @return returns the uri of the row added
-     */
-    protected abstract Uri insertInternal(final SQLiteDatabase db, Uri uri, ContentValues values);
-
-    @Override
-    public Uri insert(Uri uri, ContentValues values) {
-        Uri result = null;
-        SQLiteDatabase db = mDbHelper.getWritableDatabase();
-        if (isClosed(db)) {
-            return result;
-        }
-        try {
-            db.acquireReference();
-            //beginTransaction can throw a runtime exception
-            //so it needs to be moved into the try
-            db.beginTransaction();
-            result = insertInternal(db, uri, values);
-            db.setTransactionSuccessful();
-        } catch (SQLiteFullException fullEx) {
-            logger.warn("" + fullEx);
-            sendStorageFullIntent(getContext());
-        } catch (Exception e) {
-            logger.warn("" + e);
-        } finally {
-            try {
-                db.endTransaction();
-            } catch (SQLiteFullException fullEx) {
-                logger.warn("" + fullEx);
-                sendStorageFullIntent(getContext());
-            } catch (Exception e) {
-                logger.warn("" + e);
-            }
-            db.releaseReference();
-        }
-        if (result != null) {
-            getContext().getContentResolver().notifyChange(uri, null);
-        }
-        return result;
-    }
-
-    @Override
-    public boolean onCreate() {
-        mDbHelper = new DatabaseHelper(getContext(), mDbName);
-        return onCreateInternal();
-    }
-
-    /**
-     * Called by onCreate.  Should be overridden by any subclasses
-     * to handle the onCreate lifecycle event.
-     *
-     * @return
-     */
-    protected boolean onCreateInternal() {
-        return true;
-    }
-
-    /**
-     * queryInternal allows getContentResolver().query() to occur
-     * @param uri
-     * @param projection
-     * @param selection
-     * @param selectionArgs
-     * @param sortOrder
-     * @return Cursor holding the contents of the requested query
-     */
-    protected abstract Cursor queryInternal(final SQLiteDatabase db, Uri uri, String[] projection,
-            String selection, String[] selectionArgs, String sortOrder);
-
-    @Override
-    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
-            String sortOrder) {
-        SQLiteDatabase db = mDbHelper.getReadableDatabase();
-        if (isClosed(db)) {
-            return null;
-        }
-
-        try {
-            db.acquireReference();
-            return queryInternal(db, uri, projection, selection, selectionArgs, sortOrder);
-        } finally {
-            db.releaseReference();
-        }
-    }
-
-    protected abstract int updateInternal(final SQLiteDatabase db, Uri uri, ContentValues values,
-            String selection, String[] selectionArgs);
-
-    @Override
-    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
-        int result = 0;
-        SQLiteDatabase db = mDbHelper.getWritableDatabase();
-        if (isClosed(db)) {
-            return result;
-        }
-        try {
-            db.acquireReference();
-            //beginTransaction can throw a runtime exception
-            //so it needs to be moved into the try
-            db.beginTransaction();
-            result = updateInternal(db, uri, values, selection, selectionArgs);
-            db.setTransactionSuccessful();
-        } catch (SQLiteFullException fullEx) {
-            logger.error("" + fullEx);
-            sendStorageFullIntent(getContext());
-        } catch (Exception e) {
-            logger.error("" + e);
-        } finally {
-            try {
-                db.endTransaction();
-            } catch (SQLiteFullException fullEx) {
-                logger.error("" + fullEx);
-                sendStorageFullIntent(getContext());
-            } catch (Exception e) {
-                logger.error("" + e);
-            }
-            db.releaseReference();
-        }
-        if (result > 0) {
-            getContext().getContentResolver().notifyChange(uri, null);
-        }
-        return result;
-    }
-
-    @Override
-    public int bulkInsert(Uri uri, ContentValues[] values) {
-        int added = 0;
-        if (values != null) {
-            int numRows = values.length;
-            SQLiteDatabase db = mDbHelper.getWritableDatabase();
-            if (isClosed(db)) {
-                return added;
-            }
-            try {
-                db.acquireReference();
-                //beginTransaction can throw a runtime exception
-                //so it needs to be moved into the try
-                db.beginTransaction();
-
-                for (int i = 0; i < numRows; i++) {
-                    if (insertInternal(db, uri, values[i]) != null) {
-                        added++;
-                    }
-                }
-                db.setTransactionSuccessful();
-                if (added > 0) {
-                    getContext().getContentResolver().notifyChange(uri, null);
-                }
-            } catch (SQLiteFullException fullEx) {
-                logger.error("" + fullEx);
-                sendStorageFullIntent(getContext());
-            } catch (Exception e) {
-                logger.error("" + e);
-            } finally {
-                try {
-                    db.endTransaction();
-                } catch (SQLiteFullException fullEx) {
-                    logger.error("" + fullEx);
-                    sendStorageFullIntent(getContext());
-                } catch (Exception e) {
-                    logger.error("" + e);
-                }
-                db.releaseReference();
-            }
-        }
-        return added;
-    }
-
-    private void sendStorageFullIntent(Context context) {
-        Intent fullStorageIntent = new Intent(ACTION_DEVICE_STORAGE_FULL);
-        context.sendBroadcast(fullStorageIntent);
-    }
-
-    private boolean isClosed(SQLiteDatabase db) {
-        if (db == null || !db.isOpen()) {
-            logger.warn("Null DB returned from DBHelper for a writable/readable database.");
-            return true;
-        }
-        return false;
-    }
-
-}
diff --git a/rcs/presencepolling/src/com/android/service/ims/presence/DeviceBoot.java b/rcs/presencepolling/src/com/android/service/ims/presence/DeviceBoot.java
deleted file mode 100644
index 096d342..0000000
--- a/rcs/presencepolling/src/com/android/service/ims/presence/DeviceBoot.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
-
-package com.android.service.ims.presence;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.os.SystemProperties;
-
-import com.android.ims.RcsPresence;
-import com.android.ims.RcsPresence.PublishState;
-import com.android.ims.internal.Logger;
-
-/**
- * Device boot event receiver: automatically starts the RCS service
- */
-public class DeviceBoot extends BroadcastReceiver {
-    /**
-     * The logger
-     */
-    private Logger logger = Logger.getLogger("PresencePolling",
-            this.getClass().getName());
-
-    private static boolean sServiceStarted = false;
-    private static boolean sEabServiceStarted = false;
-
-    @Override
-    public void onReceive(Context context, Intent intent) {
-        logger.debug("onReceive() in PresencePolling, intent: " +
-                intent + ", context: " + context);
-
-        String action = intent.getAction();
-        if (RcsPresence.ACTION_PUBLISH_STATE_CHANGED.equalsIgnoreCase(action)) {
-            int state = intent.getIntExtra(
-                    RcsPresence.EXTRA_PUBLISH_STATE,
-                    RcsPresence.PublishState.PUBLISH_STATE_NOT_PUBLISHED);
-            logger.debug("Publish state: " + state);
-        }
-
-        String rcsSupported = SystemProperties.get("persist.rcs.supported");
-        logger.info("persist.rcs.supported: " + rcsSupported);
-        if (! "1".equals(rcsSupported)) {
-            return;
-        }
-
-        if (! sServiceStarted) {
-            sServiceStarted = LauncherUtils.launchPollingService(context);
-        }
-
-        if(!sEabServiceStarted) {
-            sEabServiceStarted = LauncherUtils.launchEabService(context);
-        }
-    }
-}
-
diff --git a/rcs/presencepolling/src/com/android/service/ims/presence/DeviceShutdown.java b/rcs/presencepolling/src/com/android/service/ims/presence/DeviceShutdown.java
deleted file mode 100644
index 193fd09..0000000
--- a/rcs/presencepolling/src/com/android/service/ims/presence/DeviceShutdown.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
-
-package com.android.service.ims.presence;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-
-import com.android.ims.internal.Logger;
-
-/**
- * Device shutdown event receiver: automatically stops the RCS service
- */
-public class DeviceShutdown extends BroadcastReceiver {
-    /**
-     * The logger
-     */
-    private Logger logger = Logger.getLogger(this.getClass().getName());
-
-    @Override
-    public void onReceive(Context context, Intent intent) {
-        logger.debug("onReceive() in PresencePolling, intent: " +
-                intent + ", context: " + context);
-
-        LauncherUtils.stopPollingService(context);
-    }
-}
-
diff --git a/rcs/presencepolling/src/com/android/service/ims/presence/EABContactManager.java b/rcs/presencepolling/src/com/android/service/ims/presence/EABContactManager.java
deleted file mode 100644
index cefe50b..0000000
--- a/rcs/presencepolling/src/com/android/service/ims/presence/EABContactManager.java
+++ /dev/null
@@ -1,932 +0,0 @@
-/*
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
-
-package com.android.service.ims.presence;
-
-import android.content.Context;
-import android.content.ContentResolver;
-import android.content.ContentUris;
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.Cursor;
-import android.database.CursorWrapper;
-import android.database.Cursor;
-import android.database.DatabaseUtils;
-import android.net.Uri;
-import android.text.format.Time;
-import android.text.TextUtils;
-
-import com.android.ims.RcsPresenceInfo;
-import com.android.ims.internal.Logger;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class EABContactManager {
-    private Logger logger = Logger.getLogger(this.getClass().getName());
-
-    /**
-     * An identifier for a particular EAB contact number, unique across the system.
-     * Clients use this ID to make subsequent calls related to the contact.
-     */
-    public final static String COLUMN_ID = Contacts.Impl._ID;
-
-    /**
-     * Timestamp when the presence was last updated, in {@link System#currentTimeMillis
-     * System.currentTimeMillis()} (wall clock time in UTC).
-     */
-    public final static String COLUMN_LAST_UPDATED_TIMESTAMP =
-            Contacts.Impl.CONTACT_LAST_UPDATED_TIMESTAMP;
-
-    /**
-     * columns to request from EABProvider.
-     * @hide
-     */
-    public static final String[] CONTACT_COLUMNS = new String[] {
-        Contacts.Impl._ID,
-        Contacts.Impl.CONTACT_NUMBER,
-        Contacts.Impl.CONTACT_NAME,
-        Contacts.Impl.CONTACT_LAST_UPDATED_TIMESTAMP,
-        Contacts.Impl.VOLTE_CALL_SERVICE_CONTACT_ADDRESS,
-        Contacts.Impl.VOLTE_CALL_CAPABILITY,
-        Contacts.Impl.VOLTE_CALL_CAPABILITY_TIMESTAMP,
-        Contacts.Impl.VOLTE_CALL_AVAILABILITY,
-        Contacts.Impl.VOLTE_CALL_AVAILABILITY_TIMESTAMP,
-        Contacts.Impl.VIDEO_CALL_SERVICE_CONTACT_ADDRESS,
-        Contacts.Impl.VIDEO_CALL_CAPABILITY,
-        Contacts.Impl.VIDEO_CALL_CAPABILITY_TIMESTAMP,
-        Contacts.Impl.VIDEO_CALL_AVAILABILITY,
-        Contacts.Impl.VIDEO_CALL_AVAILABILITY_TIMESTAMP,
-        Contacts.Impl.VOLTE_STATUS
-    };
-
-    /**
-     * This class contains all the information necessary to request a new contact.
-     */
-    public static class Request {
-        private long mId = -1;
-        private String mContactNumber = null;
-        private String mContactName = null;
-
-        private int mVolteCallCapability = -1;
-        private long mVolteCallCapabilityTimeStamp = -1;
-        private int mVolteCallAvailability = -1;
-        private long mVolteCallAvailabilityTimeStamp = -1;
-        private String mVolteCallServiceContactAddress = null;
-
-        private int mVideoCallCapability = -1;
-        private long mVideoCallCapabilityTimeStamp = -1;
-        private int mVideoCallAvailability = -1;
-        private long mVideoCallAvailabilityTimeStamp = -1;
-        private String mVideoCallServiceContactAddress = null;
-
-        private long mContactLastUpdatedTimeStamp = -1;
-        private int mFieldUpdatedFlags = 0;
-
-        private static int sVolteCallCapabilityFlag = 0x0001;
-        private static int sVolteCallCapabilityTimeStampFlag = 0x0002;
-        private static int sVolteCallAvailabilityFlag = 0x0004;
-        private static int sVolteCallAvailabilityTimeStampFlag = 0x0008;
-        private static int sVolteCallServiceContactAddressFlag = 0x0010;
-        private static int sVideoCallCapabilityFlag = 0x0020;
-        private static int sVideoCallCapabilityTimeStampFlag = 0x0040;
-        private static int sVideoCallAvailabilityFlag = 0x0080;
-        private static int sVideoCallAvailabilityTimeStampFlag = 0x0100;
-        private static int sVideoCallServiceContactAddressFlag = 0x0200;
-        private static int sContactLastUpdatedTimeStampFlag = 0x0400;
-
-        /**
-         * @param id the contact id.
-         */
-        public Request(long id) {
-            if (id < 0) {
-                throw new IllegalArgumentException(
-                        "Can't update EAB presence item with id: " + id);
-            }
-
-            mId = id;
-        }
-
-        public Request(String number) {
-            if (TextUtils.isEmpty(number)) {
-                throw new IllegalArgumentException(
-                        "Can't update EAB presence item with number: " + number);
-            }
-
-            mContactNumber = number;
-        }
-
-        public long getContactId() {
-            return mId;
-        }
-
-        public String getContactNumber() {
-            return mContactNumber;
-        }
-
-        /**
-         * Set Volte call service contact address.
-         * @param address contact from NOTIFY
-         * @return this object
-         */
-        public Request setVolteCallServiceContactAddress(String address) {
-            mVolteCallServiceContactAddress = address;
-            mFieldUpdatedFlags |= sVolteCallServiceContactAddressFlag;
-            return this;
-        }
-
-        /**
-         * Set Volte call capability.
-         * @param b wheter volte call is supported or not
-         * @return this object
-         */
-        public Request setVolteCallCapability(boolean b) {
-            mVolteCallCapability = b ? 1 : 0;
-            mFieldUpdatedFlags |= sVolteCallCapabilityFlag;
-            return this;
-        }
-
-        public Request setVolteCallCapability(int val) {
-            mVolteCallCapability = val;
-            mFieldUpdatedFlags |= sVolteCallCapabilityFlag;
-            return this;
-        }
-
-        /**
-         * Set Volte call availability.
-         * @param b wheter volte call is available or not
-         * @return this object
-         */
-        public Request setVolteCallAvailability(boolean b) {
-            mVolteCallAvailability = b ? 1 : 0;
-            mFieldUpdatedFlags |= sVolteCallAvailabilityFlag;
-            return this;
-        }
-
-        public Request setVolteCallAvailability(int val) {
-            mVolteCallAvailability = val;
-            mFieldUpdatedFlags |= sVolteCallAvailabilityFlag;
-            return this;
-        }
-
-        /**
-         * Set Video call service contact address.
-         * @param address contact from NOTIFY.
-         * @return this object
-         */
-        public Request setVideoCallServiceContactAddress(String address) {
-            mVideoCallServiceContactAddress = address;
-            mFieldUpdatedFlags |= sVideoCallServiceContactAddressFlag;
-            return this;
-        }
-
-        /**
-         * Set Video call capability.
-         * @param b wheter volte call is supported or not
-         * @return this object
-         */
-        public Request setVideoCallCapability(boolean b) {
-            mVideoCallCapability = b ? 1 : 0;
-            mFieldUpdatedFlags |= sVideoCallCapabilityFlag;
-            return this;
-        }
-
-        public Request setVideoCallCapability(int val) {
-            mVideoCallCapability = val;
-            mFieldUpdatedFlags |= sVideoCallCapabilityFlag;
-            return this;
-        }
-
-        /**
-         * Set Video call availability.
-         * @param b wheter volte call is available or not
-         * @return this object
-         */
-        public Request setVideoCallAvailability(boolean b) {
-            mVideoCallAvailability = b ? 1 : 0;
-            mFieldUpdatedFlags |= sVideoCallAvailabilityFlag;
-            return this;
-        }
-
-        public Request setVideoCallAvailability(int val) {
-            mVideoCallAvailability = val;
-            mFieldUpdatedFlags |= sVideoCallAvailabilityFlag;
-            return this;
-        }
-
-        /**
-         * Set the update timestamp.
-         * @param long timestamp the last update timestamp
-         * @return this object
-         */
-        public Request setLastUpdatedTimeStamp(long timestamp) {
-            mContactLastUpdatedTimeStamp = timestamp;
-            mFieldUpdatedFlags |= sContactLastUpdatedTimeStampFlag;
-            return this;
-        }
-
-        public Request setVolteCallCapabilityTimeStamp(long timestamp) {
-            mVolteCallCapabilityTimeStamp = timestamp;
-            mFieldUpdatedFlags |= sVolteCallCapabilityTimeStampFlag;
-            return this;
-        }
-
-        public Request setVolteCallAvailabilityTimeStamp(long timestamp) {
-            mVolteCallAvailabilityTimeStamp = timestamp;
-            mFieldUpdatedFlags |= sVolteCallAvailabilityTimeStampFlag;
-            return this;
-        }
-
-        public Request setVideoCallCapabilityTimeStamp(long timestamp) {
-            mVideoCallCapabilityTimeStamp = timestamp;
-            mFieldUpdatedFlags |= sVideoCallCapabilityTimeStampFlag;
-            return this;
-        }
-
-        public Request setVideoCallAvailabilityTimeStamp(long timestamp) {
-            mVideoCallAvailabilityTimeStamp = timestamp;
-            mFieldUpdatedFlags |= sVideoCallAvailabilityTimeStampFlag;
-            return this;
-        }
-
-        public Request reset() {
-            mVolteCallCapability = -1;
-            mVolteCallCapabilityTimeStamp = -1;
-            mVolteCallAvailability = -1;
-            mVolteCallAvailabilityTimeStamp = -1;
-            mVolteCallServiceContactAddress = null;
-
-            mVideoCallCapability = -1;
-            mVideoCallCapabilityTimeStamp = -1;
-            mVideoCallAvailability = -1;
-            mVideoCallAvailabilityTimeStamp = -1;
-            mVideoCallServiceContactAddress = null;
-
-            mContactLastUpdatedTimeStamp = -1;
-            mFieldUpdatedFlags = 0;
-            return this;
-        }
-
-        /**
-         * @return ContentValues to be passed to EABProvider.update()
-         */
-        ContentValues toContentValues() {
-            ContentValues values = new ContentValues();
-
-            if ((mFieldUpdatedFlags & sVolteCallCapabilityFlag) > 0) {
-                values.put(Contacts.Impl.VOLTE_CALL_CAPABILITY,
-                        mVolteCallCapability);
-            }
-            if ((mFieldUpdatedFlags & sVolteCallCapabilityTimeStampFlag) > 0) {
-                values.put(Contacts.Impl.VOLTE_CALL_CAPABILITY_TIMESTAMP,
-                        mVolteCallCapabilityTimeStamp);
-            }
-            if ((mFieldUpdatedFlags & sVolteCallAvailabilityFlag) > 0) {
-                values.put(Contacts.Impl.VOLTE_CALL_AVAILABILITY,
-                        mVolteCallAvailability);
-            }
-            if ((mFieldUpdatedFlags & sVolteCallAvailabilityTimeStampFlag) > 0) {
-                values.put(Contacts.Impl.VOLTE_CALL_AVAILABILITY_TIMESTAMP,
-                        mVolteCallAvailabilityTimeStamp);
-            }
-            if ((mFieldUpdatedFlags & sVolteCallServiceContactAddressFlag) > 0) {
-                values.put(Contacts.Impl.VOLTE_CALL_SERVICE_CONTACT_ADDRESS,
-                        mVolteCallServiceContactAddress);
-            }
-
-            if ((mFieldUpdatedFlags & sVideoCallCapabilityFlag) > 0) {
-                values.put(Contacts.Impl.VIDEO_CALL_CAPABILITY,
-                        mVideoCallCapability);
-            }
-            if ((mFieldUpdatedFlags & sVideoCallCapabilityTimeStampFlag) > 0) {
-                values.put(Contacts.Impl.VIDEO_CALL_CAPABILITY_TIMESTAMP,
-                        mVideoCallCapabilityTimeStamp);
-            }
-            if ((mFieldUpdatedFlags & sVideoCallAvailabilityFlag) > 0) {
-                values.put(Contacts.Impl.VIDEO_CALL_AVAILABILITY,
-                        mVideoCallAvailability);
-            }
-            if ((mFieldUpdatedFlags & sVideoCallAvailabilityTimeStampFlag) > 0) {
-                values.put(Contacts.Impl.VIDEO_CALL_AVAILABILITY_TIMESTAMP,
-                        mVideoCallAvailabilityTimeStamp);
-            }
-            if ((mFieldUpdatedFlags & sVideoCallServiceContactAddressFlag) > 0) {
-                values.put(Contacts.Impl.VIDEO_CALL_SERVICE_CONTACT_ADDRESS,
-                        mVideoCallServiceContactAddress);
-            }
-
-            if ((mFieldUpdatedFlags & sContactLastUpdatedTimeStampFlag) > 0 ) {
-                values.put(Contacts.Impl.CONTACT_LAST_UPDATED_TIMESTAMP,
-                        mContactLastUpdatedTimeStamp);
-            }
-
-            return values;
-        }
-
-        @Override
-        public String toString() {
-            StringBuilder sb = new StringBuilder(512);
-            sb.append("EABContactManager.Request { ");
-            if (mId != -1) {
-                sb.append("\nId: " + mId);
-            }
-            if (!TextUtils.isEmpty(mContactNumber)) {
-                sb.append("\nContact Number: " + mContactNumber);
-            }
-            if (!TextUtils.isEmpty(mContactName)) {
-                sb.append("\nContact Name: " + mContactName);
-            }
-
-            if ((mFieldUpdatedFlags & sVolteCallCapabilityFlag) > 0) {
-                sb.append("\nVolte call capability: " + mVolteCallCapability);
-            }
-            if ((mFieldUpdatedFlags & sVolteCallCapabilityTimeStampFlag) > 0) {
-                sb.append("\nVolte call capability timestamp: " + mVolteCallCapabilityTimeStamp
-                        + "(" + getTimeString(mVolteCallCapabilityTimeStamp) + ")");
-            }
-            if ((mFieldUpdatedFlags & sVolteCallAvailabilityFlag) > 0) {
-                sb.append("\nVolte call availability: " + mVolteCallAvailability);
-            }
-            if ((mFieldUpdatedFlags & sVolteCallAvailabilityTimeStampFlag) > 0) {
-                sb.append("\nVolte call availablity timestamp: " + mVolteCallAvailabilityTimeStamp
-                        + "(" + getTimeString(mVolteCallAvailabilityTimeStamp) + ")");
-            }
-            if ((mFieldUpdatedFlags & sVolteCallServiceContactAddressFlag) > 0) {
-                sb.append("\nVolte Call Service address: " + mVolteCallServiceContactAddress);
-            }
-
-            if ((mFieldUpdatedFlags & sVideoCallCapabilityFlag) > 0) {
-                sb.append("\nVideo call capability: " + mVideoCallCapability);
-            }
-            if ((mFieldUpdatedFlags & sVideoCallCapabilityTimeStampFlag) > 0) {
-                sb.append("\nVideo call capability timestamp: " + mVideoCallCapabilityTimeStamp
-                        + "(" + getTimeString(mVideoCallCapabilityTimeStamp) + ")");
-            }
-            if ((mFieldUpdatedFlags & sVideoCallAvailabilityFlag) > 0) {
-                sb.append("\nVideo call availability: " + mVideoCallAvailability);
-            }
-            if ((mFieldUpdatedFlags & sVideoCallAvailabilityTimeStampFlag) > 0) {
-                sb.append("\nVideo call availablity timestamp: " + mVideoCallAvailabilityTimeStamp
-                        + "(" + getTimeString(mVideoCallAvailabilityTimeStamp) + ")");
-            }
-            if ((mFieldUpdatedFlags & sVideoCallServiceContactAddressFlag) > 0) {
-                sb.append("\nVideo Call Service address: " + mVideoCallServiceContactAddress);
-            }
-
-            if ((mFieldUpdatedFlags & sContactLastUpdatedTimeStampFlag) > 0 ) {
-                sb.append("\nContact last update time: " + mContactLastUpdatedTimeStamp
-                        + "(" + getTimeString(mContactLastUpdatedTimeStamp) + ")");
-            }
-
-            sb.append(" }");
-            return sb.toString();
-        }
-    }
-
-    /**
-     * This class may be used to filter EABProvider queries.
-     */
-    public static class Query {
-        /**
-         * Constant for use with {@link #orderBy}
-         * @hide
-         */
-        public static final int ORDER_ASCENDING = 1;
-
-        /**
-         * Constant for use with {@link #orderBy}
-         * @hide
-         */
-        public static final int ORDER_DESCENDING = 2;
-
-        private long[] mIds = null;
-        private String mContactNumber = null;
-        private List<String> mTimeFilters = null;
-        private String mOrderByColumn = COLUMN_LAST_UPDATED_TIMESTAMP;
-        private int mOrderDirection = ORDER_ASCENDING;
-
-        /**
-         * Include only the contacts with the given IDs.
-         * @return this object
-         */
-        public Query setFilterById(long... ids) {
-            mIds = ids;
-            return this;
-        }
-
-        /**
-         * Include only the contacts with the given number.
-         * @return this object
-         */
-        public Query setFilterByNumber(String number) {
-            mContactNumber = number;
-            return this;
-        }
-
-        /**
-         * Include the contacts that meet the specified time condition.
-         * @return this object
-         */
-        public Query setFilterByTime(String selection) {
-            if (mTimeFilters == null) {
-                mTimeFilters = new ArrayList<String>();
-            }
-
-            mTimeFilters.add(selection);
-            return this;
-        }
-
-        /**
-         * Include only the contacts that has not been updated before the last time.
-         * @return this object
-         */
-        public Query setFilterByTime(String column, long last) {
-            if (mTimeFilters == null) {
-                mTimeFilters = new ArrayList<String>();
-            }
-
-            mTimeFilters.add(column + "<='" + last + "'");
-            return this;
-        }
-
-        /**
-         * Include only the contacts that has not been updated after the eariest time.
-         * @return this object
-         */
-        public Query setFilterByEarliestTime(String column, long earliest) {
-            if (mTimeFilters == null) {
-                mTimeFilters = new ArrayList<String>();
-            }
-
-            mTimeFilters.add(column + ">='" + earliest + "'");
-            return this;
-        }
-
-        /**
-         * Change the sort order of the returned Cursor.
-         *
-         * @param column one of the COLUMN_* constants; currently, only
-         *         {@link #COLUMN_LAST_MODIFIED_TIMESTAMP} and {@link #COLUMN_TOTAL_SIZE_BYTES} are
-         *         supported.
-         * @param direction either {@link #ORDER_ASCENDING} or {@link #ORDER_DESCENDING}
-         * @return this object
-         * @hide
-         */
-        public Query orderBy(String column, int direction) {
-            if (direction != ORDER_ASCENDING && direction != ORDER_DESCENDING) {
-                throw new IllegalArgumentException("Invalid direction: " + direction);
-            }
-
-            if (column.equals(COLUMN_ID)) {
-                mOrderByColumn = Contacts.Impl._ID;
-            } else if (column.equals(COLUMN_LAST_UPDATED_TIMESTAMP)) {
-                mOrderByColumn = Contacts.Impl.CONTACT_LAST_UPDATED_TIMESTAMP;
-            } else {
-                throw new IllegalArgumentException("Cannot order by " + column);
-            }
-            mOrderDirection = direction;
-            return this;
-        }
-
-        /**
-         * Run this query using the given ContentResolver.
-         * @param projection the projection to pass to ContentResolver.query()
-         * @return the Cursor returned by ContentResolver.query()
-         */
-        Cursor runQuery(ContentResolver resolver, String[] projection, Uri baseUri) {
-            Uri uri = baseUri;
-            List<String> selectionParts = new ArrayList<String>();
-            String[] selectionArgs = null;
-
-            if (mIds != null) {
-                selectionParts.add(getWhereClauseForIds(mIds));
-                selectionArgs = getWhereArgsForIds(mIds);
-            }
-
-            if (!TextUtils.isEmpty(mContactNumber)) {
-                String number = mContactNumber;
-                if (number.startsWith("tel:")) {
-                    number = number.substring(4);
-                }
-                String escapedPhoneNumber = DatabaseUtils.sqlEscapeString(number);
-                String cselection = "(" + Contacts.Impl.CONTACT_NUMBER + "=" + escapedPhoneNumber;
-                cselection += " OR PHONE_NUMBERS_EQUAL(" + Contacts.Impl.CONTACT_NUMBER + ", ";
-                cselection += escapedPhoneNumber + ", 0))";
-
-                selectionParts.add(cselection);
-            }
-
-            if (mTimeFilters != null) {
-                String cselection = joinStrings(" OR ", mTimeFilters);
-                int size = mTimeFilters.size();
-                if (size > 1) {
-                    cselection = "(" + cselection + ")";
-                }
-                selectionParts.add(cselection);
-            }
-
-            String selection = joinStrings(" AND ", selectionParts);
-            String orderDirection = (mOrderDirection == ORDER_ASCENDING ? "ASC" : "DESC");
-            String orderBy = mOrderByColumn + " " + orderDirection;
-
-            return resolver.query(uri, projection, selection, selectionArgs, orderBy);
-        }
-
-        private String joinStrings(String joiner, Iterable<String> parts) {
-            StringBuilder builder = new StringBuilder();
-            boolean first = true;
-            for (String part : parts) {
-                if (!first) {
-                    builder.append(joiner);
-                }
-                builder.append(part);
-                first = false;
-            }
-            return builder.toString();
-        }
-
-        @Override
-        public String toString() {
-            List<String> selectionParts = new ArrayList<String>();
-            String[] selectionArgs = null;
-
-            if (mIds != null) {
-                selectionParts.add(getWhereClauseForIds(mIds));
-                selectionArgs = getWhereArgsForIds(mIds);
-            }
-
-            if (!TextUtils.isEmpty(mContactNumber)) {
-                String number = mContactNumber;
-                if (number.startsWith("tel:")) {
-                    number = number.substring(4);
-                }
-                String escapedPhoneNumber = DatabaseUtils.sqlEscapeString(number);
-                String cselection = "(" + Contacts.Impl.CONTACT_NUMBER + "=" + escapedPhoneNumber;
-                cselection += " OR PHONE_NUMBERS_EQUAL(" + Contacts.Impl.CONTACT_NUMBER + ", ";
-                cselection += escapedPhoneNumber + ", 0))";
-
-                selectionParts.add(cselection);
-            }
-
-            if (mTimeFilters != null) {
-                String cselection = joinStrings(" OR ", mTimeFilters);
-                int size = mTimeFilters.size();
-                if (size > 1) {
-                    cselection = "(" + cselection + ")";
-                }
-                selectionParts.add(cselection);
-            }
-
-            String selection = joinStrings(" AND ", selectionParts);
-            String orderDirection = (mOrderDirection == ORDER_ASCENDING ? "ASC" : "DESC");
-            String orderBy = mOrderByColumn + " " + orderDirection;
-
-            StringBuilder sb = new StringBuilder(512);
-            sb.append("EABContactManager.Query { ");
-            sb.append("\nSelection: " + selection);
-            sb.append("\nSelectionArgs: " + selectionArgs);
-            sb.append("\nOrderBy: " + orderBy);
-            sb.append(" }");
-            return sb.toString();
-        }
-    }
-
-    private ContentResolver mResolver;
-    private String mPackageName;
-    private Uri mBaseUri = Contacts.Impl.CONTENT_URI;
-
-    /**
-     * @hide
-     */
-    public EABContactManager(ContentResolver resolver, String packageName) {
-        mResolver = resolver;
-        mPackageName = packageName;
-    }
-
-    /**
-     * Query the presence manager about contacts that have been requested.
-     * @param query parameters specifying filters for this query
-     * @return a Cursor over the result set of contacts, with columns consisting of all the
-     * COLUMN_* constants.
-     */
-    public Cursor query(Query query) {
-        Cursor underlyingCursor = query.runQuery(mResolver, CONTACT_COLUMNS, mBaseUri);
-        if (underlyingCursor == null) {
-            return null;
-        }
-
-        return new CursorTranslator(underlyingCursor, mBaseUri);
-    }
-
-    /**
-     * Update a contact presence status.
-     *
-     * @param request the parameters specifying this contact presence
-     * @return an ID for the contact, unique across the system.  This ID is used to make future
-     * calls related to this contact.
-     */
-    public int update(Request request) {
-        if (request == null) {
-            return 0;
-        }
-
-        long id = request.getContactId();
-        String number = request.getContactNumber();
-        if ((id == -1) && TextUtils.isEmpty(number)) {
-            throw new IllegalArgumentException("invalid request for contact update.");
-        }
-
-        ContentValues values = request.toContentValues();
-        if (id != -1) {
-            logger.debug("Update contact " + id + " with request: " + values);
-            return mResolver.update(ContentUris.withAppendedId(mBaseUri, id), values,
-                    null, null);
-        } else {
-            Query query = new Query().setFilterByNumber(number)
-                                     .orderBy(COLUMN_ID, Query.ORDER_ASCENDING);
-            long[] ids = null;
-            Cursor cursor = null;
-            try {
-                cursor = query(query);
-                if (cursor == null) {
-                    return 0;
-                }
-                int count = cursor.getCount();
-                if (count == 0) {
-                    return 0;
-                }
-
-                ids = new long[count];
-                int idx = 0;
-                for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
-                    id = cursor.getLong(cursor.getColumnIndex(Contacts.Impl._ID));
-                    ids[idx++] = id;
-                    if (idx >= count) {
-                        break;
-                    }
-                }
-            } finally {
-                if (cursor != null) {
-                    cursor.close();
-                }
-            }
-
-            if ((ids == null) || (ids.length == 0)) {
-                return 0;
-            }
-
-            if (ids.length == 1) {
-                logger.debug("Update contact " + ids[0] + " with request: " + values);
-                return mResolver.update(ContentUris.withAppendedId(mBaseUri, ids[0]), values,
-                        null, null);
-            }
-
-            logger.debug("Update contact " + number + " with request: " + values);
-            return mResolver.update(mBaseUri, values, getWhereClauseForIds(ids),
-                    getWhereArgsForIds(ids));
-        }
-    }
-
-    /**
-     * Get the EABProvider URI for the contact with the given ID.
-     *
-     * @hide
-     */
-    public Uri getContactUri(long id) {
-        return ContentUris.withAppendedId(mBaseUri, id);
-    }
-
-    /**
-     * Get a parameterized SQL WHERE clause to select a bunch of IDs.
-     */
-    static String getWhereClauseForIds(long[] ids) {
-        StringBuilder whereClause = new StringBuilder();
-        whereClause.append("(");
-        for (int i = 0; i < ids.length; i++) {
-            if (i > 0) {
-                whereClause.append("OR ");
-            }
-            whereClause.append(COLUMN_ID);
-            whereClause.append(" = ? ");
-        }
-        whereClause.append(")");
-        return whereClause.toString();
-    }
-
-    /**
-     * Get the selection args for a clause returned by {@link #getWhereClauseForIds(long[])}.
-     */
-    static String[] getWhereArgsForIds(long[] ids) {
-        String[] whereArgs = new String[ids.length];
-        for (int i = 0; i < ids.length; i++) {
-            whereArgs[i] = Long.toString(ids[i]);
-        }
-        return whereArgs;
-    }
-
-    static String getTimeString(long time) {
-        if (time <= 0) {
-            time = System.currentTimeMillis();
-        }
-
-        Time tobj = new Time();
-        tobj.set(time);
-        return String.format("%s.%s", tobj.format("%m-%d %H:%M:%S"), time % 1000);
-    }
-
-    /**
-     * This class wraps a cursor returned by EABProvider -- the "underlying cursor" -- and
-     * presents a different set of columns, those defined in the COLUMN_* constants.
-     * Some columns correspond directly to underlying values while others are computed from
-     * underlying data.
-     */
-    private static class CursorTranslator extends CursorWrapper {
-        private Uri mBaseUri;
-
-        public CursorTranslator(Cursor cursor, Uri baseUri) {
-            super(cursor);
-            mBaseUri = baseUri;
-        }
-
-        @Override
-        public int getInt(int columnIndex) {
-            return (int) getLong(columnIndex);
-        }
-
-        @Override
-        public long getLong(int columnIndex) {
-            return super.getLong(columnIndex);
-        }
-
-        @Override
-        public String getString(int columnIndex) {
-            return super.getString(columnIndex);
-        }
-    }
-
-    public void updateAllCapabilityToUnknown() {
-        if (mResolver == null) {
-            logger.error("updateAllCapabilityToUnknown, mResolver=null");
-            return;
-        }
-
-        ContentValues values = new ContentValues();
-        values.put(Contacts.Impl.CONTACT_LAST_UPDATED_TIMESTAMP, (String)null);
-        values.put(Contacts.Impl.VOLTE_CALL_SERVICE_CONTACT_ADDRESS, (String)null);
-        values.put(Contacts.Impl.VOLTE_CALL_CAPABILITY, (String)null);
-        values.put(Contacts.Impl.VOLTE_CALL_CAPABILITY_TIMESTAMP, (String)null);
-        values.put(Contacts.Impl.VOLTE_CALL_AVAILABILITY, (String)null);
-        values.put(Contacts.Impl.VOLTE_CALL_AVAILABILITY_TIMESTAMP, (String)null);
-
-        values.put(Contacts.Impl.VIDEO_CALL_SERVICE_CONTACT_ADDRESS, (String)null);
-        values.put(Contacts.Impl.VIDEO_CALL_CAPABILITY, (String)null);
-        values.put(Contacts.Impl.VIDEO_CALL_CAPABILITY_TIMESTAMP, (String)null);
-        values.put(Contacts.Impl.VIDEO_CALL_AVAILABILITY, (String)null);
-        values.put(Contacts.Impl.VIDEO_CALL_AVAILABILITY_TIMESTAMP, (String)null);
-
-        try {
-            int count = ContactDbUtil.resetVtCapability(mResolver);
-            logger.print("update Contact DB: updateAllCapabilityToUnknown count=" + count);
-
-            count = mResolver.update(Contacts.Impl.CONTENT_URI,
-                    values, null, null);
-            logger.print("update EAB DB: updateAllCapabilityToUnknown count=" + count);
-        } catch (Exception ex) {
-            logger.error("updateAllCapabilityToUnknown exception: " + ex);
-        }
-    }
-
-    public void updateAllVtCapabilityToUnknown() {
-        if (mResolver == null) {
-            logger.error("updateAllVtCapabilityToUnknown mResolver=null");
-            return;
-        }
-
-        ContentValues values = new ContentValues();
-        values.put(Contacts.Impl.CONTACT_LAST_UPDATED_TIMESTAMP, (String)null);
-        values.put(Contacts.Impl.VIDEO_CALL_SERVICE_CONTACT_ADDRESS, (String)null);
-        values.put(Contacts.Impl.VIDEO_CALL_CAPABILITY, (String)null);
-        values.put(Contacts.Impl.VIDEO_CALL_CAPABILITY_TIMESTAMP, (String)null);
-        values.put(Contacts.Impl.VIDEO_CALL_AVAILABILITY, (String)null);
-        values.put(Contacts.Impl.VIDEO_CALL_AVAILABILITY_TIMESTAMP, (String)null);
-
-        try {
-            int count = ContactDbUtil.resetVtCapability(mResolver);
-            logger.print("update Contact DB: updateAllVtCapabilityToUnknown count=" + count);
-
-            count = mResolver.update(Contacts.Impl.CONTENT_URI,
-                    values, null, null);
-            logger.print("update EAB DB: updateAllVtCapabilityToUnknown count=" + count);
-        } catch (Exception ex) {
-            logger.error("updateAllVtCapabilityToUnknown exception: " + ex);
-        }
-    }
-
-    // if updateLastTimestamp is true, the rcsPresenceInfo is from network.
-    // if the updateLastTimestamp is false, It is used to update the availabilty to unknown only.
-    // And the availability will be updated only when it has expired, so we don't update the
-    // timestamp to make sure the availablity still in expired status and will be subscribed from
-    // network afterwards.
-    public int update(RcsPresenceInfo rcsPresenceInfo, boolean updateLastTimestamp) {
-        if (rcsPresenceInfo == null) {
-            return 0;
-        }
-
-        String number = rcsPresenceInfo.getContactNumber();
-        if (TextUtils.isEmpty(number)) {
-            logger.error("Failed to update for the contact number is empty.");
-            return 0;
-        }
-
-        ContentValues values = new ContentValues();
-
-        int volteStatus = rcsPresenceInfo.getVolteStatus();
-        if(volteStatus != RcsPresenceInfo.VolteStatus.VOLTE_UNKNOWN) {
-            values.put(Contacts.Impl.VOLTE_STATUS, volteStatus);
-        }
-
-        if(updateLastTimestamp){
-            values.put(Contacts.Impl.CONTACT_LAST_UPDATED_TIMESTAMP,
-                    (long)System.currentTimeMillis());
-        }
-
-        int lteCallCapability = rcsPresenceInfo.getServiceState(
-                RcsPresenceInfo.ServiceType.VOLTE_CALL);
-        long lteCallTimestamp = rcsPresenceInfo.getTimeStamp(
-                RcsPresenceInfo.ServiceType.VOLTE_CALL);
-        values.put(Contacts.Impl.VOLTE_CALL_AVAILABILITY, lteCallCapability);
-        values.put(Contacts.Impl.VOLTE_CALL_AVAILABILITY_TIMESTAMP, (long)lteCallTimestamp);
-        if(rcsPresenceInfo.getServiceState(RcsPresenceInfo.ServiceType.VOLTE_CALL)
-                != RcsPresenceInfo.ServiceState.UNKNOWN){
-            String lteCallContactAddress =
-                    rcsPresenceInfo.getServiceContact(RcsPresenceInfo.ServiceType.VOLTE_CALL);
-            if (!TextUtils.isEmpty(lteCallContactAddress)) {
-                values.put(Contacts.Impl.VOLTE_CALL_SERVICE_CONTACT_ADDRESS, lteCallContactAddress);
-            }
-
-            values.put(Contacts.Impl.VOLTE_CALL_CAPABILITY, lteCallCapability);
-            values.put(Contacts.Impl.VOLTE_CALL_CAPABILITY_TIMESTAMP, lteCallTimestamp);
-        }
-
-        int videoCallCapability = rcsPresenceInfo.getServiceState(
-                RcsPresenceInfo.ServiceType.VT_CALL);
-        long videoCallTimestamp = rcsPresenceInfo.getTimeStamp(
-                RcsPresenceInfo.ServiceType.VT_CALL);
-        values.put(Contacts.Impl.VIDEO_CALL_AVAILABILITY, videoCallCapability);
-        values.put(Contacts.Impl.VIDEO_CALL_AVAILABILITY_TIMESTAMP, (long)videoCallTimestamp);
-        if(rcsPresenceInfo.getServiceState(RcsPresenceInfo.ServiceType.VT_CALL)
-                != RcsPresenceInfo.ServiceState.UNKNOWN){
-            String videoCallContactAddress =
-                    rcsPresenceInfo.getServiceContact(RcsPresenceInfo.ServiceType.VT_CALL);
-            if (!TextUtils.isEmpty(videoCallContactAddress)) {
-                values.put(Contacts.Impl.VIDEO_CALL_SERVICE_CONTACT_ADDRESS,
-                        videoCallContactAddress);
-            }
-
-            values.put(Contacts.Impl.VIDEO_CALL_CAPABILITY, videoCallCapability);
-            values.put(Contacts.Impl.VIDEO_CALL_CAPABILITY_TIMESTAMP, videoCallTimestamp);
-        }
-
-        int count = 0;
-        try{
-            count = ContactDbUtil.updateVtCapability(mResolver, number,
-                    (videoCallCapability == RcsPresenceInfo.ServiceState.ONLINE));
-            logger.print("update rcsPresenceInfo to Contact DB, count=" + count);
-
-            count = mResolver.update(Contacts.Impl.CONTENT_URI, values,
-                    "PHONE_NUMBERS_EQUAL(contact_number, ?, 0)", new String[] {number});
-            logger.print("update rcsPresenceInfo to EAB: update count=" + count +
-                    " rcsPresenceInfo=" + rcsPresenceInfo);
-        }catch(Exception e){
-            logger.error("updateCapability exception", e);
-        }
-
-        return count;
-    }
-}
-
diff --git a/rcs/presencepolling/src/com/android/service/ims/presence/EABDbUtil.java b/rcs/presencepolling/src/com/android/service/ims/presence/EABDbUtil.java
deleted file mode 100644
index 8e851dc..0000000
--- a/rcs/presencepolling/src/com/android/service/ims/presence/EABDbUtil.java
+++ /dev/null
@@ -1,428 +0,0 @@
-/*
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
-
-package com.android.service.ims.presence;
-
-import static com.android.service.ims.presence.AccountUtil.ACCOUNT_TYPE;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import android.content.ContentProviderOperation;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.OperationApplicationException;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteException;
-import android.os.RemoteException;
-import android.provider.ContactsContract;
-import android.provider.ContactsContract.Contacts;
-import android.provider.ContactsContract.Data;
-import android.provider.ContactsContract.CommonDataKinds.Phone;
-
-import com.android.ims.internal.ContactNumberUtils;
-import com.android.ims.internal.EABContract;
-import com.android.ims.internal.Logger;
-
-public class EABDbUtil {
-    static private Logger logger = Logger.getLogger("EABDbUtil");
-
-    public static boolean validateAndSyncFromContactsDb(Context context) {
-        logger.debug("Enter validateAndSyncFromContactsDb");
-        boolean response = true;
-        // Get the last stored contact changed timestamp and sync only delta contacts.
-        long contactLastChange = SharedPrefUtil.getLastContactChangedTimestamp(context, 0);
-        logger.debug("contact last updated time before init :" + contactLastChange);
-        ContentResolver contentResolver = context.getContentResolver();
-        String[] projection = new String[] { ContactsContract.Contacts._ID,
-                ContactsContract.Contacts.HAS_PHONE_NUMBER,
-                ContactsContract.Contacts.DISPLAY_NAME,
-                ContactsContract.Contacts.CONTACT_LAST_UPDATED_TIMESTAMP };
-        String selection = ContactsContract.Contacts.HAS_PHONE_NUMBER + "> '0' AND "
-                + ContactsContract.Contacts.CONTACT_LAST_UPDATED_TIMESTAMP
-                + " >'" + contactLastChange + "'";
-        String sortOrder = ContactsContract.Contacts.DISPLAY_NAME + " asc";
-        Cursor cursor = contentResolver.query(Contacts.CONTENT_URI, projection, selection,
-                null, sortOrder);
-        ArrayList<PresenceContact> allEligibleContacts = new ArrayList<PresenceContact>();
-
-        logger.debug("cursor count : " + cursor.getCount());
-        if (cursor.moveToFirst()) {
-            do {
-                String id = cursor.getString(cursor.getColumnIndex(Contacts._ID));
-                Long time = cursor.getLong(cursor.getColumnIndex(
-                        Contacts.CONTACT_LAST_UPDATED_TIMESTAMP));
-                // Update the latest contact last modified timestamp.
-                if (contactLastChange < time) {
-                    contactLastChange = time;
-                }
-                String[] commonDataKindsProjection = new String[] {
-                        ContactsContract.CommonDataKinds.Phone.NUMBER,
-                        ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
-                        ContactsContract.CommonDataKinds.Phone.RAW_CONTACT_ID,
-                        ContactsContract.CommonDataKinds.Phone.CONTACT_ID };
-                Cursor pCur = contentResolver.query(
-                        ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
-                        commonDataKindsProjection,
-                        ContactsContract.CommonDataKinds.Phone.CONTACT_ID
-                            + " = ?", new String[] { id }, null);
-                ArrayList<String> phoneNumList = new ArrayList<String>();
-
-                if (pCur.moveToFirst()) {
-                    do {
-                        String contactNumber = pCur.getString(pCur.getColumnIndex(
-                                ContactsContract.CommonDataKinds.Phone.NUMBER));
-                        //contactNumber = filterEligibleContact(context, pContactNumber);
-                        if (validateEligibleContact(context, contactNumber)) {
-                            String contactName = pCur.getString(pCur.getColumnIndex(
-                                    ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
-                            String rawContactId = pCur.getString(pCur.getColumnIndex(
-                                    ContactsContract.CommonDataKinds.Phone.RAW_CONTACT_ID));
-                            String contactId = pCur.getString(pCur.getColumnIndex(
-                                    ContactsContract.CommonDataKinds.Phone.CONTACT_ID));
-                            // TODO: HACK - To be resolved as part of EAB Provider rework.
-                            if (phoneNumList.contains(contactNumber)) continue;
-                            phoneNumList.add(contactNumber);
-
-                            String dataId = getDataId(contentResolver,rawContactId, contactNumber);
-                            if (null != dataId) {
-                                allEligibleContacts.add(new PresenceContact(contactName,
-                                        contactNumber, rawContactId, contactId, dataId));
-                                logger.debug("Eligible List Name: " + contactName +
-                                        " Number:" + contactNumber +
-                                        " RawContactID: " + rawContactId +
-                                        " contactId: " + contactId + " Data.ID : " + dataId);
-                            } else {
-                                logger.debug("dataId is null. Don't add contact to " +
-                                        "allEligibleContacts.");
-                            }
-                        }
-                    } while (pCur.moveToNext());
-                }
-                pCur.close();
-            } while (cursor.moveToNext());
-        }
-        if (null != cursor) {
-            cursor.close();
-        }
-        if (allEligibleContacts.size() > 0) {
-            logger.debug("Adding : " + allEligibleContacts.size() +
-                    " new contact numbers to EAB db.");
-            addContactsToEabDb(context, allEligibleContacts);
-            logger.debug("contact last updated time after init :" + contactLastChange);
-            SharedPrefUtil.saveLastContactChangedTimestamp(context, contactLastChange);
-            SharedPrefUtil.saveLastContactDeletedTimestamp(context, contactLastChange);
-        }
-        logger.debug("Exit validateAndSyncFromContactsDb contact numbers synced : " +
-                allEligibleContacts.size());
-        return response;
-    }
-
-    private static String getDataId(ContentResolver contentResolver,
-            String rawContactId, String pContactNumber) {
-        String dataId = null;
-        String where = Data.RAW_CONTACT_ID + " = '" + rawContactId + "' AND "
-                + Data.MIMETYPE + "='" + Phone.CONTENT_ITEM_TYPE + "'"
-                + " AND " + Data.DATA1 + "='" + pContactNumber + "'";
-        Cursor cur = null;
-        try {
-            cur = contentResolver.query(Data.CONTENT_URI,
-                    new String[] { Data._ID }, where, null, null);
-            if (cur.moveToFirst()) {
-                dataId = cur.getString(cur.getColumnIndex(Data._ID));
-            }
-        } catch (SQLiteException e) {
-            logger.debug("SQLiteException while querying for dataId : " + e.toString());
-        } catch (Exception e) {
-            logger.debug("Exception while querying for dataId : " + e);
-        } finally {
-            if (null != cur) {
-                cur.close();
-            }
-        }
-        return dataId;
-    }
-
-    public static void addContactsToEabDb(Context context,
-            ArrayList<PresenceContact> contactList) {
-        ArrayList<ContentProviderOperation> operation = new ArrayList<ContentProviderOperation>();
-
-        logger.debug("Adding Contacts to EAB DB");
-        // To avoid the following exception - Too many content provider operations
-        // between yield points. The maximum number of operations per yield point is
-        // 500 for exceuteDB()
-        int yieldPoint = 300;
-        for (int j = 0; j < contactList.size(); j++) {
-            addContactToEabDb(context, operation, contactList.get(j).getDisplayName(),
-                    contactList.get(j).getPhoneNumber(), contactList.get(j).getRawContactId(),
-                    contactList.get(j).getContactId(), contactList.get(j).getDataId());
-            if (yieldPoint == j) {
-                exceuteDB(context, operation);
-                operation = null;
-                operation = new ArrayList<ContentProviderOperation>();
-                yieldPoint += 300;
-            }
-        }
-        exceuteDB(context, operation);
-    }
-
-    private static void addContactToEabDb(
-            Context context, ArrayList<ContentProviderOperation> ops, String displayName,
-            String phoneNumber, String rawContactId, String contactId,
-            String dataId) {
-        ops.add(ContentProviderOperation
-                .newInsert(EABContract.EABColumns.CONTENT_URI)
-                .withValue(EABContract.EABColumns.CONTACT_NAME, displayName)
-                .withValue(EABContract.EABColumns.CONTACT_NUMBER, phoneNumber)
-                .withValue(EABContract.EABColumns.ACCOUNT_TYPE, ACCOUNT_TYPE)
-                .withValue(EABContract.EABColumns.RAW_CONTACT_ID, rawContactId)
-                .withValue(EABContract.EABColumns.CONTACT_ID, contactId)
-                .withValue(EABContract.EABColumns.DATA_ID, dataId).build());
-    }
-
-    public static void deleteContactsFromEabDb(Context context,
-            ArrayList<PresenceContact> contactList) {
-        ArrayList<ContentProviderOperation> operation = new ArrayList<ContentProviderOperation>();
-
-        logger.debug("Deleting Contacts from EAB DB");
-        String[] contactIdList = new String[contactList.size()];
-        // To avoid the following exception - Too many content provider operations
-        // between yield points. The maximum number of operations per yield point is
-        // 500 for exceuteDB()
-        int yieldPoint = 300;
-        for (int j = 0; j < contactList.size(); j++) {
-            contactIdList[j] = contactList.get(j).getContactId().toString();
-            deleteContactFromEabDb(context, operation, contactIdList[j]);
-            if (yieldPoint == j) {
-                exceuteDB(context, operation);
-                operation = null;
-                operation = new ArrayList<ContentProviderOperation>();
-                yieldPoint += 300;
-            }
-        }
-        exceuteDB(context, operation);
-    }
-
-    private static void deleteContactFromEabDb(Context context,
-            ArrayList<ContentProviderOperation> ops, String contactId) {
-        // Add operation only if there is an entry in EABProvider table.
-        String[] eabProjection = new String[] {
-                EABContract.EABColumns.CONTACT_NUMBER,
-                EABContract.EABColumns.CONTACT_ID };
-        String eabWhereClause = null;
-        if (ContactsContract.Profile.MIN_ID == Long.valueOf(contactId)) {
-            eabWhereClause = EABContract.EABColumns.CONTACT_ID + " >='" + contactId + "'";
-        } else {
-            eabWhereClause = EABContract.EABColumns.CONTACT_ID + " ='" + contactId + "'";
-        }
-        Cursor eabDeleteCursor = context.getContentResolver().query(
-                EABContract.EABColumns.CONTENT_URI, eabProjection,
-                eabWhereClause, null, null);
-        if (null != eabDeleteCursor) {
-            int count = eabDeleteCursor.getCount();
-            logger.debug("cursor count : " + count);
-            if (count > 0) {
-                eabDeleteCursor.moveToNext();
-                long eabDeleteContactId = eabDeleteCursor.
-                        getLong(eabDeleteCursor.getColumnIndex(EABContract.EABColumns.CONTACT_ID));
-                logger.debug("eabDeleteContactId : " + eabDeleteContactId);
-                if (ContactsContract.Profile.MIN_ID == Long.valueOf(contactId)) {
-                    if (ContactsContract.isProfileId(eabDeleteContactId)) {
-                        logger.debug("Deleting Profile contact.");
-                        ops.add(ContentProviderOperation
-                            .newDelete(EABContract.EABColumns.CONTENT_URI)
-                            .withSelection(EABContract.EABColumns.CONTACT_ID + " >= ?",
-                                    new String[] { contactId }).build());
-                    } else {
-                        logger.debug("Not a Profile contact. Do nothing.");
-                    }
-                } else {
-                    ops.add(ContentProviderOperation
-                        .newDelete(EABContract.EABColumns.CONTENT_URI)
-                        .withSelection(EABContract.EABColumns.CONTACT_ID + " = ?",
-                                new String[] { contactId }).build());
-                }
-            }
-            eabDeleteCursor.close();
-        }
-
-    }
-
-    public static void deleteNumbersFromEabDb(Context context,
-            ArrayList<PresenceContact> contactList) {
-        ArrayList<ContentProviderOperation> operation = new ArrayList<ContentProviderOperation>();
-
-        logger.debug("Deleting Number from EAB DB");
-        String[] rawContactIdList = new String [contactList.size()];
-        String[] DataIdList = new String [contactList.size()];
-        // To avoid the following exception - Too many content provider operations
-        // between yield points. The maximum number of operations per yield point is
-        // 500 for exceuteDB()
-        int yieldPoint = 300;
-        for (int j = 0; j < contactList.size(); j++) {
-            rawContactIdList[j] = contactList.get(j).getRawContactId();
-            DataIdList[j] = contactList.get(j).getDataId();
-            deleteNumberFromEabDb(context, operation, rawContactIdList[j], DataIdList[j]);
-            if (yieldPoint == j) {
-                exceuteDB(context, operation);
-                operation = null;
-                operation = new ArrayList<ContentProviderOperation>();
-                yieldPoint += 300;
-            }
-        }
-        exceuteDB(context, operation);
-    }
-
-    private static void deleteNumberFromEabDb(Context context,
-            ArrayList<ContentProviderOperation> ops, String rawContactId, String dataId) {
-        // Add operation only if there is an entry in EABProvider table.
-        String[] eabProjection = new String[] {
-                EABContract.EABColumns.CONTACT_NUMBER };
-        String eabWhereClause = EABContract.EABColumns.RAW_CONTACT_ID + " ='" + rawContactId
-                + "' AND " + EABContract.EABColumns.DATA_ID + " ='" + dataId + "'";
-        Cursor eabDeleteCursor = context.getContentResolver().query(
-                EABContract.EABColumns.CONTENT_URI, eabProjection,
-                eabWhereClause, null, null);
-        if (null != eabDeleteCursor) {
-            int count = eabDeleteCursor.getCount();
-            logger.debug("Delete number cursor count : " + count);
-            if (count > 0) {
-                ops.add(ContentProviderOperation.newDelete(EABContract.EABColumns.CONTENT_URI)
-                        .withSelection(EABContract.EABColumns.RAW_CONTACT_ID + " = ? AND "
-                                       + EABContract.EABColumns.DATA_ID + " = ?",
-                                new String[] { rawContactId, dataId }).build());
-            }
-            eabDeleteCursor.close();
-        }
-    }
-
-    public static void updateNamesInEabDb(Context context,
-            ArrayList<PresenceContact> contactList) {
-        ArrayList<ContentProviderOperation> operation = new ArrayList<ContentProviderOperation>();
-
-        logger.debug("Update name in EAB DB");
-        String[] phoneNameList = new String[contactList.size()];
-        String[] phoneNumberList = new String[contactList.size()];
-        String[] rawContactIdList = new String [contactList.size()];
-        String[] dataIdList = new String [contactList.size()];
-        // To avoid the following exception - Too many content provider operations
-        // between yield points. The maximum number of operations per yield point is
-        // 500 for exceuteDB()
-        int yieldPoint = 300;
-        for (int j = 0; j < contactList.size(); j++) {
-            phoneNameList[j] = contactList.get(j).getDisplayName();
-            phoneNumberList[j] = contactList.get(j).getPhoneNumber();
-            rawContactIdList[j] = contactList.get(j).getRawContactId();
-            dataIdList[j] = contactList.get(j).getDataId();
-            updateNameInEabDb(context, operation, phoneNameList[j],
-                    phoneNumberList[j], rawContactIdList[j], dataIdList[j]);
-            if (yieldPoint == j) {
-                exceuteDB(context, operation);
-                operation = null;
-                operation = new ArrayList<ContentProviderOperation>();
-                yieldPoint += 300;
-            }
-        }
-        exceuteDB(context, operation);
-    }
-
-    private static void updateNameInEabDb(Context context,
-            ArrayList<ContentProviderOperation> ops, String phoneName,
-            String phoneNumber, String rawContactId, String dataId) {
-        ContentValues values = new ContentValues();
-        values.put(EABContract.EABColumns.CONTACT_NAME, phoneName);
-
-        String where = EABContract.EABColumns.CONTACT_NUMBER + " = ? AND "
-                + EABContract.EABColumns.RAW_CONTACT_ID + " = ? AND "
-                + EABContract.EABColumns.DATA_ID + " = ?";
-        ops.add(ContentProviderOperation
-                .newUpdate(EABContract.EABColumns.CONTENT_URI)
-                .withValues(values)
-                .withSelection(where, new String[] { phoneNumber, rawContactId, dataId }).build());
-    }
-
-    private static void exceuteDB(Context context, ArrayList<ContentProviderOperation> ops) {
-        if (ops.size() == 0) {
-            logger.debug("exceuteDB return as operation size is 0.");
-            return;
-        }
-        try {
-            context.getContentResolver().applyBatch(EABContract.AUTHORITY, ops);
-        } catch (RemoteException e) {
-            e.printStackTrace();
-        } catch (OperationApplicationException e) {
-            e.printStackTrace();
-        }
-        ops.clear();
-        logger.debug("exceuteDB return with successful operation.");
-        return;
-    }
-
-    public static boolean validateEligibleContact(Context context, String mdn) {
-        boolean number = false;
-        if (null == mdn) {
-            logger.debug("validateEligibleContact - mdn is null.");
-            return number;
-        }
-        List<String> mdbList = new ArrayList<String>();
-        mdbList.add(mdn);
-        ContactNumberUtils mNumberUtils = ContactNumberUtils.getDefault();
-        mNumberUtils.setContext(context);
-        int numberType = mNumberUtils.validate(mdbList);
-        logger.debug("ContactNumberUtils.validate response : " + numberType);
-        if ( ContactNumberUtils.NUMBER_VALID == numberType) {
-            number = true;
-        }
-        logger.debug("Exiting validateEligibleContact with value : " + number);
-        return number;
-    }
-
-    public static String filterEligibleContact(Context context, String mdn) {
-        String number = null;
-        if (null == mdn) {
-            logger.debug("filterEligibleContact - mdn is null.");
-            return number;
-        }
-        logger.debug("Before filterEligibleContact validation : " + mdn);
-        List<String> mdbList = new ArrayList<String>();
-        mdbList.add(mdn);
-        ContactNumberUtils mNumberUtils = ContactNumberUtils.getDefault();
-        mNumberUtils.setContext(context);
-        int numberType = mNumberUtils.validate(mdbList);
-        logger.debug("ContactNumberUtils.validate response : " + numberType);
-        if ( ContactNumberUtils.NUMBER_VALID == numberType) {
-            String[] mdnFormatted = mNumberUtils.format(mdbList);
-            if (mdnFormatted.length > 0 ){
-                number = mdnFormatted[0];
-            }
-        }
-        logger.debug("After filterEligibleContact validation / formatting : " + number);
-        return number;
-    }
-}
diff --git a/rcs/presencepolling/src/com/android/service/ims/presence/EABProvider.java b/rcs/presencepolling/src/com/android/service/ims/presence/EABProvider.java
deleted file mode 100644
index 651b1cd..0000000
--- a/rcs/presencepolling/src/com/android/service/ims/presence/EABProvider.java
+++ /dev/null
@@ -1,453 +0,0 @@
-/*
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
-
-package com.android.service.ims.presence;
-
-import java.io.FileNotFoundException;
-
-import android.content.ContentUris;
-import android.content.ContentValues;
-import android.content.Intent;
-import android.content.UriMatcher;
-import android.database.Cursor;
-import android.database.SQLException;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteQueryBuilder;
-import android.net.Uri;
-import android.os.ParcelFileDescriptor;
-import android.provider.BaseColumns;
-import android.provider.ContactsContract.Contacts;
-import android.content.ComponentName;
-
-import com.android.ims.RcsPresenceInfo;
-import com.android.ims.internal.EABContract;
-import com.android.ims.internal.Logger;
-
-/**
- * @author Vishal Patil (A22809)
- */
-
-public class EABProvider extends DatabaseContentProvider{
-    private Logger logger = Logger.getLogger(this.getClass().getName());
-
-    private static final String EAB_DB_NAME = "rcseab.db";
-
-    private static final int EAB_DB_VERSION = 2;
-
-    private static final int EAB_TABLE = 1;
-
-    private static final int EAB_TABLE_ID = 2;
-
-    private static final int EAB_GROUPITEMS_TABLE = 3;
-
-    private static final UriMatcher URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH) {
-        {
-            addURI(EABContract.AUTHORITY, EABContract.EABColumns.TABLE_NAME, EAB_TABLE);
-            addURI(EABContract.AUTHORITY, EABContract.EABColumns.TABLE_NAME + "/#", EAB_TABLE_ID);
-            addURI(EABContract.AUTHORITY, EABContract.EABColumns.GROUPITEMS_NAME,
-                    EAB_GROUPITEMS_TABLE);
-        }
-    };
-
-    /* Statement to create VMM Album table. */
-    private static final String EAB_CREATE_STATEMENT = "create table if not exists "
-            + EABContract.EABColumns.TABLE_NAME
-            + "("
-            + EABContract.EABColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
-            + EABContract.EABColumns.CONTACT_NAME + " TEXT, "
-            + EABContract.EABColumns.CONTACT_NUMBER + " TEXT, "
-            + EABContract.EABColumns.RAW_CONTACT_ID + " TEXT, "
-            + EABContract.EABColumns.CONTACT_ID + " TEXT, "
-            + EABContract.EABColumns.DATA_ID + " TEXT, "
-            + EABContract.EABColumns.ACCOUNT_TYPE  + " TEXT, "
-            + EABContract.EABColumns.VOLTE_CALL_SERVICE_CONTACT_ADDRESS + " TEXT, "
-            + EABContract.EABColumns.VOLTE_CALL_CAPABILITY + " INTEGER, "
-            + EABContract.EABColumns.VOLTE_CALL_CAPABILITY_TIMESTAMP + " LONG, "
-            + EABContract.EABColumns.VOLTE_CALL_AVAILABILITY + " INTEGER, "
-            + EABContract.EABColumns.VOLTE_CALL_AVAILABILITY_TIMESTAMP + " LONG, "
-            + EABContract.EABColumns.VIDEO_CALL_SERVICE_CONTACT_ADDRESS + " TEXT, "
-            + EABContract.EABColumns.VIDEO_CALL_CAPABILITY + " INTEGER, "
-            + EABContract.EABColumns.VIDEO_CALL_CAPABILITY_TIMESTAMP + " LONG, "
-            + EABContract.EABColumns.VIDEO_CALL_AVAILABILITY + " INTEGER, "
-            + EABContract.EABColumns.VIDEO_CALL_AVAILABILITY_TIMESTAMP + " LONG, "
-            + EABContract.EABColumns.CONTACT_LAST_UPDATED_TIMESTAMP + " LONG "
-            + ");";
-
-    private static final String EAB_DROP_STATEMENT = "drop table if exists "
-            + EABContract.EABColumns.TABLE_NAME + ";";
-
-    public EABProvider() {
-        super(EAB_DB_NAME, EAB_DB_VERSION);
-    }
-
-    @Override
-    public void bootstrapDatabase(SQLiteDatabase db) {
-        logger.info("Enter: bootstrapDatabase() Creating new EAB database");
-        upgradeDatabase(db, 0, EAB_DB_VERSION);
-        logger.info("Exit: bootstrapDatabase()");
-    }
-
-    /*
-     * In upgradeDatabase,
-     * oldVersion - the current version of Provider on the phone.
-     * newVersion - the version of Provider where the phone will be upgraded to.
-     */
-    @Override
-    public boolean upgradeDatabase(SQLiteDatabase db, int oldVersion, int newVersion) {
-        logger.debug("Enter: upgradeDatabase() - oldVersion = " + oldVersion +
-                " newVersion = " + newVersion);
-
-        if (oldVersion == newVersion) {
-            logger.debug("upgradeDatabase oldVersion == newVersion, No Upgrade Required");
-            return true;
-        }
-
-        try {
-            if (oldVersion == 0) {
-                db.execSQL(EAB_CREATE_STATEMENT);
-
-                oldVersion++;
-                logger.debug("upgradeDatabase : DB has been upgraded to " + oldVersion);
-            }
-            if (oldVersion == 1) {
-                addColumn(db, EABContract.EABColumns.TABLE_NAME,
-                        EABContract.EABColumns.VOLTE_STATUS, "INTEGER NOT NULL DEFAULT -1");
-
-                oldVersion++;
-                logger.debug("upgradeDatabase : DB has been upgraded to " + oldVersion);
-            }
-        } catch (SQLException exception) {
-            logger.error("Exception during upgradeDatabase. " + exception.getMessage());
-            // DB file had problem
-            throw new InvalidDBException();
-        }
-
-        // add further upgrade code above this
-        if (oldVersion == newVersion) {
-            logger.debug("DB upgrade complete : to " + newVersion);
-        }
-
-        logger.debug("Exit: upgradeDatabase()");
-        return true;
-    }
-
-    @Override
-    protected boolean downgradeDatabase(SQLiteDatabase db, int oldVersion, int newVersion) {
-        // throwing the custom created Exception to catch it in
-        // getWritableDatabase or getReadableDatabase
-        throw new InvalidDBException();
-    }
-
-    @Override
-    protected int deleteInternal(SQLiteDatabase db, Uri uri, String selection,
-            String[] selectionArgs) {
-        logger.info("Enter: deleteInternal()");
-        final int match = URI_MATCHER.match(uri);
-        String table = null;
-        switch (match) {
-            case EAB_TABLE_ID:
-                if (selection == null) {
-                    selection = "_id=?";
-                    selectionArgs = new String[] {uri.getPathSegments().get(1)};
-                }
-            case EAB_TABLE:
-                table = EABContract.EABColumns.TABLE_NAME;
-                break;
-            default:
-                logger.info("No match for " + uri);
-                logger.info("Exit: deleteInternal()");
-                return 0;
-        }
-        logger.debug("Deleting from the table" + table + " selection= " + selection);
-        printDeletingValues(uri, selection, selectionArgs);
-        logger.info("Exit: deleteInternal()");
-        return db.delete(table, selection, selectionArgs);
-    }
-
-    @Override
-    protected Uri insertInternal(SQLiteDatabase db, Uri uri, ContentValues values) {
-        logger.info("Enter: insertInternal()");
-        final int match = URI_MATCHER.match(uri);
-        String table = null;
-        String nullColumnHack = null;
-        switch (match) {
-            case EAB_TABLE:
-                table = EABContract.EABColumns.TABLE_NAME;
-                break;
-            default:
-                logger.warn("No match for " + uri);
-                logger.info("Exit: insertInternal() with null");
-                return null;
-        }
-        values = verifyIfMdnExists(values);
-        // Do the insert.
-        logger.debug("Inserting to the table" + table + " values=" + values.toString());
-
-        final long id = db.insert(table, nullColumnHack, values);
-        if (id > 0) {
-            String contactNumber = values.getAsString(EABContract.EABColumns.CONTACT_NUMBER);
-            sendInsertBroadcast(contactNumber);
-            logger.info("Exit: insertInternal()");
-            return ContentUris.withAppendedId(uri, id);
-        } else {
-            logger.info("Exit: insertInternal() with null");
-            return null;
-        }
-    }
-
-    @Override
-    protected Cursor queryInternal(SQLiteDatabase db, Uri uri, String[] projection,
-            String selection, String[] selectionArgs, String sortOrder) {
-        logger.info("Enter: queryInternal()");
-        final int match = URI_MATCHER.match(uri);
-
-        switch (match) {
-            case EAB_TABLE_ID:
-                long id = ContentUris.parseId(uri);
-                logger.debug("queryInternal id=" + id);
-                String idSelection = BaseColumns._ID + "=" + id;
-                if(null != selection) {
-                    selection = "((" + idSelection + ") AND (" + selection + "))";
-                } else {
-                    selection = idSelection;
-                }
-                break;
-            case EAB_GROUPITEMS_TABLE:
-                SQLiteQueryBuilder sqb = new SQLiteQueryBuilder();
-                sqb.setTables(EABContract.EABColumns.TABLE_NAME);
-                String rawquery = "select DISTINCT " + EABContract.EABColumns.CONTACT_ID
-                        + " from " + EABContract.EABColumns.TABLE_NAME
-                        + " where " + EABContract.EABColumns.VOLTE_CALL_CAPABILITY + " >'" +
-                        RcsPresenceInfo.ServiceState.OFFLINE+"' AND "
-                        + EABContract.EABColumns.VIDEO_CALL_CAPABILITY + " >'"
-                        + RcsPresenceInfo.ServiceState.OFFLINE + "'";
-                StringBuffer sb = new StringBuffer();
-                Cursor cursor = db.rawQuery(rawquery, null);
-                if (cursor != null && cursor.moveToFirst()) {
-                    do {
-                        if (sb.length() != 0) sb.append(",");
-                        String contactId = cursor.getString(cursor
-                                .getColumnIndex(EABContract.EABColumns.CONTACT_ID));
-                        sb.append(contactId);
-                    } while (cursor.moveToNext());
-                }
-                if (cursor != null) cursor.close();
-                String contactSel = Contacts._ID + " IN ( " + sb.toString() + ")";
-                return getContext().getContentResolver().query(Contacts.CONTENT_URI, projection,
-                                contactSel, null, sortOrder);
-        }
-
-        SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
-
-        String groupBy = uri.getQueryParameter("groupby");
-        String having = null;
-
-        switch (match) {
-            case EAB_TABLE:
-            case EAB_TABLE_ID:
-                qb.setTables(EABContract.EABColumns.TABLE_NAME);
-                break;
-            default:
-                logger.warn("No match for " + uri);
-                logger.info("Exit: queryInternal()");
-                return null;
-        }
-        logger.info("Exit: queryInternal()");
-        return qb.query(db, projection, selection, selectionArgs, groupBy, having, sortOrder);
-    }
-
-    @Override
-    protected int updateInternal(SQLiteDatabase db, Uri uri, ContentValues values,
-            String selection, String[] selectionArgs) {
-        logger.info("Enter: updateInternal()");
-        int result = 0;
-        final int match = URI_MATCHER.match(uri);
-
-        switch (match) {
-            case EAB_TABLE_ID:
-                long id = ContentUris.parseId(uri);
-                logger.debug("updateInternal id=" + id);
-                String idSelection = BaseColumns._ID + "=" + id;
-                if(null != selection){
-                    selection = "((" + idSelection + ") AND (" + selection + "))";
-                } else {
-                    selection = idSelection;
-                }
-                break;
-        }
-
-        String table = null;
-        switch (match) {
-            case EAB_TABLE:
-            case EAB_TABLE_ID:
-                table = EABContract.EABColumns.TABLE_NAME;
-                break;
-            default:
-                logger.warn("No match for " + uri);
-                break;
-        }
-
-        if (table != null && values != null) {
-            logger.debug("Updating the table " + table + " values= " + values.toString());
-            result = db.update(table, values, selection, selectionArgs);
-        }
-        logger.info("Exit: updateInternal()");
-        return result;
-    }
-
-    @Override
-    public String getType(Uri uri) {
-        logger.info("Enter: getType()");
-        final int match = URI_MATCHER.match(uri);
-        switch (match) {
-            case EAB_TABLE:
-                return EABContract.EABColumns.CONTENT_TYPE;
-            case EAB_TABLE_ID:
-                return EABContract.EABColumns.CONTENT_ITEM_TYPE;
-            default:
-                throw (new IllegalArgumentException("EABProvider URI: " + uri));
-        }
-    }
-
-    @Override
-    public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
-        return null;
-    }
-
-    private void sendInsertBroadcast(String contactNumber) {
-        Intent intent = new Intent(com.android.service.ims.presence.Contacts
-            .ACTION_NEW_CONTACT_INSERTED);
-        ComponentName component = new ComponentName("com.android.service.ims.presence",
-                "com.android.service.ims.presence.AlarmBroadcastReceiver");
-        intent.setComponent(component);
-
-        intent.putExtra(com.android.service.ims.presence.Contacts.NEW_PHONE_NUMBER, contactNumber);
-        getContext().sendBroadcast(intent);
-    }
-
-    private ContentValues verifyIfMdnExists(ContentValues cvalues) {
-        String phoneNumber = null;
-        if (cvalues.containsKey(EABContract.EABColumns.CONTACT_NUMBER)) {
-            phoneNumber = cvalues.getAsString(EABContract.EABColumns.CONTACT_NUMBER);
-        } else {
-            return cvalues;
-        }
-        if (null == phoneNumber) {
-            return cvalues;
-        }
-        String[] projection = new String[] {
-                EABContract.EABColumns.VOLTE_CALL_SERVICE_CONTACT_ADDRESS,
-                EABContract.EABColumns.VOLTE_CALL_CAPABILITY,
-                EABContract.EABColumns.VOLTE_CALL_CAPABILITY_TIMESTAMP,
-                EABContract.EABColumns.VOLTE_CALL_AVAILABILITY,
-                EABContract.EABColumns.VOLTE_CALL_AVAILABILITY_TIMESTAMP,
-                EABContract.EABColumns.VIDEO_CALL_SERVICE_CONTACT_ADDRESS,
-                EABContract.EABColumns.VIDEO_CALL_CAPABILITY,
-                EABContract.EABColumns.VIDEO_CALL_CAPABILITY_TIMESTAMP,
-                EABContract.EABColumns.VIDEO_CALL_AVAILABILITY,
-                EABContract.EABColumns.VIDEO_CALL_AVAILABILITY_TIMESTAMP};
-        String whereClause = "PHONE_NUMBERS_EQUAL(" +
-                EABContract.EABColumns.CONTACT_NUMBER + ", ?, 0)";
-        String[] selectionArgs = new String[] { phoneNumber };
-        Cursor cursor = getContext().getContentResolver().query(EABContract.EABColumns.CONTENT_URI,
-                        projection, whereClause, selectionArgs, null);
-        if ((null != cursor) && (cursor.getCount() > 0)) {
-            logger.debug("Number : " + phoneNumber +
-                    " is already stored in EAB DB - cursor count is " + cursor.getCount());
-            logger.error("Inserting another copy of MDN to EAB DB.");
-            // Update data only from first cursor element.
-            cursor.moveToNext();
-            cvalues.put(EABContract.EABColumns.VOLTE_CALL_SERVICE_CONTACT_ADDRESS,
-                    cursor.getString(cursor.
-                    getColumnIndex(EABContract.EABColumns.VOLTE_CALL_SERVICE_CONTACT_ADDRESS)));
-            cvalues.put(EABContract.EABColumns.VOLTE_CALL_CAPABILITY, cursor.getString(cursor
-                    .getColumnIndex(EABContract.EABColumns.VOLTE_CALL_CAPABILITY)));
-            cvalues.put(EABContract.EABColumns.VOLTE_CALL_CAPABILITY_TIMESTAMP,
-                    cursor.getLong(cursor
-                    .getColumnIndex(EABContract.EABColumns.VOLTE_CALL_CAPABILITY_TIMESTAMP)));
-            cvalues.put(EABContract.EABColumns.VOLTE_CALL_AVAILABILITY, cursor.getString(cursor
-                    .getColumnIndex(EABContract.EABColumns.VOLTE_CALL_AVAILABILITY)));
-            cvalues.put(EABContract.EABColumns.VOLTE_CALL_AVAILABILITY_TIMESTAMP,
-                    cursor.getLong(cursor
-                    .getColumnIndex(EABContract.EABColumns.VOLTE_CALL_AVAILABILITY_TIMESTAMP)));
-            cvalues.put(EABContract.EABColumns.VIDEO_CALL_SERVICE_CONTACT_ADDRESS,
-                    cursor.getString(cursor
-                    .getColumnIndex(EABContract.EABColumns.VIDEO_CALL_SERVICE_CONTACT_ADDRESS)));
-            cvalues.put(EABContract.EABColumns.VIDEO_CALL_CAPABILITY, cursor.getString(cursor
-                    .getColumnIndex(EABContract.EABColumns.VIDEO_CALL_CAPABILITY)));
-            cvalues.put(EABContract.EABColumns.VIDEO_CALL_CAPABILITY_TIMESTAMP,
-                    cursor.getLong(cursor
-                    .getColumnIndex(EABContract.EABColumns.VIDEO_CALL_CAPABILITY_TIMESTAMP)));
-            cvalues.put(EABContract.EABColumns.VIDEO_CALL_AVAILABILITY, cursor.getString(cursor
-                    .getColumnIndex(EABContract.EABColumns.VIDEO_CALL_AVAILABILITY)));
-            cvalues.put(EABContract.EABColumns.VIDEO_CALL_AVAILABILITY_TIMESTAMP,
-                    cursor.getLong(cursor
-                    .getColumnIndex(EABContract.EABColumns.VIDEO_CALL_AVAILABILITY_TIMESTAMP)));
-            cvalues.put(EABContract.EABColumns.CONTACT_LAST_UPDATED_TIMESTAMP, 0);
-        }
-        if (null != cursor) {
-            cursor.close();
-        }
-        return cvalues;
-    }
-
-    private void printDeletingValues(Uri uri, String selection, String[] selectionArgs) {
-        String[] projection = new String[] {
-                EABContract.EABColumns.CONTACT_NUMBER,
-                EABContract.EABColumns.CONTACT_NAME,
-                EABContract.EABColumns.RAW_CONTACT_ID,
-                EABContract.EABColumns.CONTACT_ID,
-                EABContract.EABColumns.DATA_ID};
-        Cursor cursor = getContext().getContentResolver().query(EABContract.EABColumns.CONTENT_URI,
-                        projection, selection, selectionArgs, null);
-        if ((null != cursor) && (cursor.getCount() > 0)) {
-            logger.debug("Before deleting the cursor count is " + cursor.getCount());
-            // Update data only from first cursor element.
-            while (cursor.moveToNext()) {
-                long dataId = cursor.getLong(cursor.getColumnIndex(
-                        EABContract.EABColumns.DATA_ID));
-                long contactId = cursor.getLong(cursor.getColumnIndex(
-                        EABContract.EABColumns.CONTACT_ID));
-                long rawContactId = cursor.getLong(cursor.getColumnIndex(
-                        EABContract.EABColumns.RAW_CONTACT_ID));
-                String phoneNumber = cursor.getString(cursor.getColumnIndex(
-                        EABContract.EABColumns.CONTACT_NUMBER));
-                String displayName = cursor.getString(cursor.getColumnIndex(
-                        EABContract.EABColumns.CONTACT_NAME));
-                logger.debug("Deleting : dataId : " + dataId + " contactId :"  + contactId +
-                        " rawContactId :" + rawContactId + " phoneNumber :" + phoneNumber +
-                        " displayName :" + displayName);
-            }
-        } else {
-            logger.error("cursor is null!");
-        }
-        if (null != cursor) {
-            cursor.close();
-        }
-    }
-}
diff --git a/rcs/presencepolling/src/com/android/service/ims/presence/EABService.java b/rcs/presencepolling/src/com/android/service/ims/presence/EABService.java
deleted file mode 100644
index e79293c..0000000
--- a/rcs/presencepolling/src/com/android/service/ims/presence/EABService.java
+++ /dev/null
@@ -1,1142 +0,0 @@
-/*
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
-
-package com.android.service.ims.presence;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Calendar;
-
-import android.accounts.Account;
-import android.app.Service;
-import android.app.AlarmManager;
-import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.ComponentName;
-import android.content.ServiceConnection;
-import android.database.ContentObserver;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.Message;
-import android.os.SystemProperties;
-import android.provider.ContactsContract;
-import android.provider.ContactsContract.CommonDataKinds.Phone;
-import android.telephony.PhoneNumberUtils;
-import android.text.TextUtils;
-
-import android.telephony.SubscriptionManager;
-import com.android.ims.internal.EABContract;
-
-import com.android.ims.ImsConfig;
-import com.android.ims.ImsManager;
-import com.android.ims.ImsException;
-
-import com.android.ims.RcsManager;
-import com.android.ims.RcsManager.ResultCode;
-import com.android.ims.RcsPresence;
-import com.android.ims.RcsException;
-import com.android.ims.RcsPresenceInfo;
-import com.android.ims.IRcsPresenceListener;
-import com.android.ims.internal.Logger;
-
-public class EABService extends Service {
-
-    private Logger logger = Logger.getLogger(this.getClass().getName());
-
-    private Context mContext;
-    private Looper mServiceLooper = null;
-    private ServiceHandler mServiceHandler = null;
-    // Used to avoid any content observer processing during EABService
-    // initialisation as anyways it will check for Contact db changes as part of boot-up.
-    private boolean isEABServiceInitializing = true;
-
-    private static final int BOOT_COMPLETED = 0;
-    private static final int CONTACT_TABLE_MODIFIED = 1;
-    private static final int CONTACT_PROFILE_TABLE_MODIFIED = 2;
-    private static final int EAB_RESET_CONTENT_OBSERVERS = 3;
-
-    private static final int SYNC_COMPLETE_DELAY_TIMER = 3 * 1000; // 3 seconds.
-    private static final String VOLTE_NUMBER = "volte_number";
-    private static final String VOLTE_NUMBER_STATE = "state";
-    private static final String ACTION_EAB_RESET_CONTENT_OBSERVERS =
-            "com.android.rcs.eab.ACTION_EAB_RESET_CONTENT_OBSERVERS";
-
-    // Framework interface files.
-    private RcsManager mRcsManager = null;
-    private RcsPresence mRcsPresence = null;
-
-    public EABService() {
-        super();
-        logger.info("EAB Service constructed");
-    }
-
-    @Override
-    public IBinder onBind(Intent arg0) {
-        return null;
-    }
-
-    /**
-     * When "clear data" is done for contact storage in system settings, EAB
-     * Provider must me cleared and PREF_KEY_CHANGE and PREF_KEY_DELETE keys
-     * should not cleared.
-     */
-    private BroadcastReceiver mReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            String action = intent.getAction();
-            logger.debug("onReceive intent: " + action);
-
-            if(ContactsContract.Intents.CONTACTS_DATABASE_CREATED.equals(action)) {
-                logger.debug("Contacts database created.");
-                // Delete all entries from EAB Provider as it has to be re-synced with Contact db.
-                mContext.getContentResolver().delete(
-                        EABContract.EABColumns.CONTENT_URI, null, null);
-                // Initialise EABProvider.
-                logger.debug("Resetting timestamp values in shared pref.");
-                SharedPrefUtil.resetEABSharedPref(mContext);
-                // init the EAB db after re-setting.
-                ensureInitDone();
-            } else if(Intent.ACTION_TIME_CHANGED.equals(action) ||
-                    Intent.ACTION_TIMEZONE_CHANGED.equals(action)) {
-                Calendar cal = Calendar.getInstance();
-                long currentTimestamp = cal.getTimeInMillis();
-                long lastChangedTimestamp = SharedPrefUtil.getLastContactChangedTimestamp(
-                        mContext, currentTimestamp);
-                logger.debug("lastChangedTimestamp=" + lastChangedTimestamp +
-                        " currentTimestamp=" + currentTimestamp);
-                // Changed time backwards.
-                if(lastChangedTimestamp > currentTimestamp) {
-                    logger.debug("Resetting timestamp values in shared pref.");
-                    SharedPrefUtil.resetEABSharedPref(mContext);
-                    CapabilityPolling capabilityPolling = CapabilityPolling.getInstance(null);
-                    if (capabilityPolling != null) {
-                        capabilityPolling.enqueueDiscovery(CapabilityPolling.ACTION_POLLING_NORMAL);
-                    }
-                }
-            }
-        }
-    };
-
-    private  ContentObserver mContactChangedListener = null;
-    private class ContactChangedListener extends ContentObserver {
-        public ContactChangedListener() {
-            super(null);
-        }
-
-        @Override
-        public boolean deliverSelfNotifications() {
-            return false;
-        }
-
-        @Override
-        public void onChange(boolean selfChange) {
-            logger.debug("onChange for ContactChangedListener");
-            sendDelayedContactChangeMsg();
-        }
-    }
-
-    private  ContentObserver mContactProfileListener = null;
-    private class ContactProfileListener extends ContentObserver {
-        public ContactProfileListener() {
-            super(null);
-        }
-
-        @Override
-        public boolean deliverSelfNotifications() {
-            return false;
-        }
-
-        @Override
-        public void onChange(boolean selfChange) {
-            logger.debug("onChange for ContactProfileListener");
-            sendDelayedContactProfileMsg();
-        }
-    }
-
-    @Override
-    public void onCreate() {
-        logger.debug("Enter : onCreate");
-        mContext = getApplicationContext();
-        HandlerThread thread = new HandlerThread("EABServiceHandler");
-        thread.start();
-
-        mServiceLooper = thread.getLooper();
-        if (mServiceLooper != null) {
-            mServiceHandler = new ServiceHandler(mServiceLooper);
-        } else {
-            logger.debug("mServiceHandler could not be initialized since looper is null");
-        }
-
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(ContactsContract.Intents.CONTACTS_DATABASE_CREATED);
-        filter.addAction(Intent.ACTION_TIME_CHANGED);
-        filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
-        registerReceiver(mReceiver, filter);
-
-        initializeRcsInterfacer();
-
-        initResetContentObserverAlarm();
-        super.onCreate();
-    }
-
-    @Override
-    public void onDestroy() {
-        cancelResetContentObserverAlarm();
-        unregisterContentObservers();
-        if (null != mReceiver) {
-            unregisterReceiver(mReceiver);
-        }
-        if (null != mServiceHandler) {
-            mServiceHandler = null;
-        }
-    }
-
-    private void initializeRcsInterfacer() {
-        // Get instance of mRcsManagr.
-        if (null == mRcsManager) {
-            mRcsManager = RcsManager.getInstance(this, 0);
-        }
-        try{
-            if (null == mRcsPresence) {
-                mRcsPresence = mRcsManager.getRcsPresenceInterface();
-                logger.debug("mRcsManager : " + mRcsManager + " mRcsPresence : " + mRcsPresence);
-            }
-         }catch (RcsException e){
-             logger.error("getRcsPresenceInterface() exception : ", e);
-            mRcsPresence = null;
-         } catch (Exception e) {
-             logger.error("getRcsPresenceInterface() exception : ", e);
-            mRcsPresence = null;
-            mRcsManager = null;
-         }
-     }
-
-    private void registerContentObservers() {
-        logger.debug("Registering for Contact and Profile Change Listener.");
-        mContactChangedListener = new ContactChangedListener();
-        getContentResolver().registerContentObserver(
-                ContactsContract.Contacts.CONTENT_URI, true,
-                mContactChangedListener);
-
-        mContactProfileListener = new ContactProfileListener();
-        getContentResolver().registerContentObserver(
-                ContactsContract.Profile.CONTENT_URI, true,
-                mContactProfileListener);
-    }
-
-    private void unregisterContentObservers() {
-        logger.debug("Un-registering for Contact and Profile Change Listener.");
-        if (null != mContactChangedListener) {
-            getContentResolver().unregisterContentObserver(
-                    mContactChangedListener);
-            mContactChangedListener = null;
-        }
-        if (null != mContactProfileListener) {
-            getContentResolver().unregisterContentObserver(
-                    mContactProfileListener);
-            mContactProfileListener = null;
-        }
-    }
-
-    private void resetContentObservers() {
-        unregisterContentObservers();
-        registerContentObservers();
-    }
-
-    private void initResetContentObserverAlarm() {
-        logger.debug("initResetAlarm, content Observers rest every 12 hours");
-        long startInterval = System.currentTimeMillis() + AlarmManager.INTERVAL_HALF_DAY;
-
-        Intent intent = new Intent(ACTION_EAB_RESET_CONTENT_OBSERVERS);
-        ((AlarmManager) getSystemService(Context.ALARM_SERVICE)).setInexactRepeating(
-                AlarmManager.RTC_WAKEUP,
-                startInterval,
-                AlarmManager.INTERVAL_HALF_DAY,
-                PendingIntent.getBroadcast(mContext,
-                0,
-                intent,
-                PendingIntent.FLAG_UPDATE_CURRENT));
-
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(ACTION_EAB_RESET_CONTENT_OBSERVERS);
-        registerReceiver(mResetContentObserverReceiver, filter);
-    }
-
-    private BroadcastReceiver  mResetContentObserverReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            logger.debug("Received, ACTION_EAB_RESET_CONTENT_OBSERVERS");
-            mServiceHandler.sendMessage(mServiceHandler.obtainMessage(
-EAB_RESET_CONTENT_OBSERVERS));
-        }
-    };
-
-    private void cancelResetContentObserverAlarm() {
-        Intent intent = new Intent(ACTION_EAB_RESET_CONTENT_OBSERVERS);
-        PendingIntent pi = PendingIntent.getBroadcast(mContext, 0, intent,
-                PendingIntent.FLAG_UPDATE_CURRENT);
-        ((AlarmManager) getSystemService(Context.ALARM_SERVICE)).cancel(pi);
-    }
-
-    @Override
-    public int onStartCommand(Intent intent, int flags, int startId) {
-        // As the return type is START_STICKY, check for null intent is not
-        // needed as if this service's process is killed while it is started,
-        // system will try to re-create the service with a null intent object if
-        // there are not any pending start commands
-        if (intent != null) {
-            logger.debug("Enter : onStartCommand for intent : " + intent.getAction());
-        }
-        registerContentObservers();
-        Message msg = mServiceHandler.obtainMessage(BOOT_COMPLETED);
-        mServiceHandler.sendMessage(msg);
-        // This service should be a always-on service.
-        return START_STICKY;
-    }
-
-    private final class ServiceHandler extends Handler {
-        public ServiceHandler(Looper looper) {
-            super(looper);
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            logger.debug("Enter: handleMessage");
-            ArrayList<RcsPresenceInfo> dataInfoList = null;
-
-            switch (msg.what) {
-            case BOOT_COMPLETED:
-                logger.debug("case BOOT_COMPLETED");
-                ensureInitDone();
-                isEABServiceInitializing = false;
-                break;
-            case EAB_RESET_CONTENT_OBSERVERS:
-                logger.debug("case EAB_RESET_CONTENT_OBSERVERS");
-                resetContentObservers();
-                break;
-            case CONTACT_TABLE_MODIFIED:
-                logger.debug("case CONTACT_TABLE_MODIFIED");
-                ensureVideoCallingGroupCreation();
-                validateAndSyncFromContactsDb();
-                break;
-            case CONTACT_PROFILE_TABLE_MODIFIED:
-                logger.debug("case CONTACT_PROFILE_TABLE_MODIFIED");
-                validateAndSyncFromProfileDb();
-                break;
-            default:
-                logger.debug("default usecase hit! Do nothing");
-                break;
-            }
-            logger.debug("Exit: handleMessage");
-        }
-    }
-
-    // synchronized is used to prevent sync happening in parallel due to
-    // multiple content change notifys from contacts observer.
-    private synchronized void validateAndSyncFromContactsDb() {
-        logger.debug("Enter : validateAndSyncFromContactsDb()");
-        checkForContactNumberChanges();
-        checkForDeletedContact();
-        logger.debug("Exit : validateAndSyncFromContactsDb()");
-    }
-
-    // synchronized is used to prevent sync happening in parallel due to
-    // multiple content change notify from contacts observer.
-    private synchronized void validateAndSyncFromProfileDb() {
-        logger.debug("Enter : validateAndSyncFromProfileDb()");
-        checkForProfileNumberChanges();
-        checkForDeletedProfileContacts();
-        logger.debug("Exit : validateAndSyncFromProfileDb()");
-    }
-
-    private void ensureInitDone() {
-        logger.debug("Enter : ensureInitDone()");
-        ensureVideoCallingGroupCreation();
-        if(SharedPrefUtil.isInitDone(mContext)) {
-            logger.debug("EAB initialized already!!! Just Sync with Contacts db.");
-            validateAndSyncFromContactsDb();
-            validateAndSyncFromProfileDb();
-            return;
-        } else {
-            logger.debug("Initializing EAB Provider.");
-            // This API will sync the numbers from Contacts db to EAB db based on
-            // contact last updated timestamp.
-            EABDbUtil.validateAndSyncFromContactsDb(mContext);
-            // This API's will sync the profile numbers from Contacts db to EAB db based on
-            // contact last updated timestamp.
-            validateAndSyncFromProfileDb();
-            SharedPrefUtil.setInitDone(mContext, true);
-        }
-    }
-
-    private void ensureVideoCallingGroupCreation() {
-        logger.debug("TODO: ensureVideoCallingGroupCreation");
-        /*
-        if (!isRcsProvisioned()) {
-            logger.debug("Device is not provisioned. Remove Video calling group and account.");
-            ContactDbUtil.removeVideoCallingContactGroup(mContext);
-            AccountUtil.removeRcsAccount(mContext);
-        } else {
-            logger.debug("Device is provisioned. Create Video calling group and account.");
-            Account vCallingAccount = AccountUtil.addRcsAccount(mContext);
-            ContactDbUtil.addVideoCallingContactGroup(mContext, vCallingAccount);
-        }*/
-    }
-
-    private void sendDelayedContactChangeMsg() {
-        logger.debug("Enter: sendDelayedContactChangeMsg()");
-        if (null != mServiceHandler && !isEABServiceInitializing) {
-            // Remove any previous message for CONTACT_TABLE_MODIFIED.
-            if (mServiceHandler.hasMessages(CONTACT_TABLE_MODIFIED)) {
-                mServiceHandler.removeMessages(CONTACT_TABLE_MODIFIED);
-                logger.debug("Removed previous CONTACT_TABLE_MODIFIED msg.");
-            }
-
-            logger.debug("Sending new CONTACT_TABLE_MODIFIED msg.");
-            // Send a new delayed message for CONTACT_TABLE_MODIFIED.
-            Message msg = mServiceHandler.obtainMessage(CONTACT_TABLE_MODIFIED);
-            mServiceHandler.sendMessageDelayed(msg, SYNC_COMPLETE_DELAY_TIMER);
-        }
-    }
-
-    private void sendDelayedContactProfileMsg() {
-        logger.debug("Enter: sendDelayedContactProfileMsg()");
-        if (null != mServiceHandler && !isEABServiceInitializing) {
-            // Remove any previous message for CONTACT_PROFILE_TABLE_MODIFIED.
-            if (mServiceHandler.hasMessages(CONTACT_PROFILE_TABLE_MODIFIED)) {
-                mServiceHandler.removeMessages(CONTACT_PROFILE_TABLE_MODIFIED);
-                logger.debug("Removed previous CONTACT_PROFILE_TABLE_MODIFIED msg.");
-            }
-
-            logger.debug("Sending new CONTACT_PROFILE_TABLE_MODIFIED msg.");
-            // Send a new delayed message for CONTACT_PROFILE_TABLE_MODIFIED.
-            Message msg = mServiceHandler.obtainMessage(CONTACT_PROFILE_TABLE_MODIFIED);
-            mServiceHandler.sendMessageDelayed(msg, SYNC_COMPLETE_DELAY_TIMER);
-        }
-    }
-
-    private void checkForContactNumberChanges() {
-        logger.debug("Enter: checkForContactNumberChanges()");
-        String[] projection = new String[] {
-                ContactsContract.Data._ID,
-                ContactsContract.Data.CONTACT_ID,
-                ContactsContract.Data.RAW_CONTACT_ID,
-                ContactsContract.Data.MIMETYPE,
-                ContactsContract.Data.DATA1,
-                ContactsContract.Data.DISPLAY_NAME,
-                ContactsContract.Data.CONTACT_LAST_UPDATED_TIMESTAMP };
-
-        long contactLastChange = SharedPrefUtil.getLastContactChangedTimestamp(mContext, 0);
-        logger.debug("contactLastChange : " + contactLastChange);
-
-        String selection = ContactsContract.Data.MIMETYPE + " = '" + Phone.CONTENT_ITEM_TYPE +
-                "' AND " + ContactsContract.Data.CONTACT_LAST_UPDATED_TIMESTAMP  + " > '" +
-                contactLastChange + "'";
-        String sortOrder = ContactsContract.Data.CONTACT_LAST_UPDATED_TIMESTAMP + " desc";
-
-        Cursor cursor = getContentResolver().query(ContactsContract.Data.CONTENT_URI,
-                projection, selection, null, sortOrder);
-
-        if (null != cursor) {
-            int count = cursor.getCount();
-            logger.debug("cursor count : " + count);
-            if (count > 0) {
-                ArrayList<Long> uniqueRawContactIds = new ArrayList<Long>();
-                while (cursor.moveToNext()) {
-                    Long dataId = Long.valueOf(cursor.getLong(cursor.getColumnIndex(
-                            ContactsContract.Data._ID)));
-                    Long contactId = Long.valueOf(cursor.getLong(cursor.getColumnIndex(
-                            ContactsContract.Data.CONTACT_ID)));
-                    Long rawContactId = Long.valueOf(cursor.getLong(cursor.getColumnIndex(
-                            ContactsContract.Data.RAW_CONTACT_ID)));
-                    String phoneNumber = cursor.getString(cursor.getColumnIndex(
-                            ContactsContract.Data.DATA1));
-                    String displayName = cursor.getString(cursor.getColumnIndex(
-                           ContactsContract.Data.DISPLAY_NAME));
-                    logger.debug("dataId : " + dataId + " rawContactId :"  + rawContactId +
-                           " contactId : " + contactId
-                           + " phoneNumber :" + phoneNumber + " displayName :" + displayName);
-                    verifyInsertOrUpdateAction(dataId, contactId, rawContactId, phoneNumber,
-                          displayName);
-                    if (uniqueRawContactIds.isEmpty()) {
-                        uniqueRawContactIds.add(rawContactId);
-                    } else if (!uniqueRawContactIds.contains(rawContactId)) {
-                        uniqueRawContactIds.add(rawContactId);
-                    } else {
-                        // Do nothing.
-                        logger.debug("uniqueRawContactIds already contains rawContactId : " +
-                                rawContactId);
-                    }
-                }
-                checkForPhoneNumberDelete(uniqueRawContactIds);
-                // Save the largest timestamp returned. Only need the first one due to
-                // the sort order.
-                cursor.moveToFirst();
-                long timestamp = cursor.getLong(cursor
-                        .getColumnIndex(ContactsContract.Data.CONTACT_LAST_UPDATED_TIMESTAMP));
-                if (timestamp > 0) {
-                    SharedPrefUtil.saveLastContactChangedTimestamp(mContext, timestamp);
-                }
-            }
-        } else {
-            logger.error("cursor is null!");
-        }
-        if (null != cursor) {
-            cursor.close();
-        }
-        logger.debug("Exit: checkForContactNumberChanges()");
-    }
-
-    private void verifyInsertOrUpdateAction(Long dataId, Long contactId,
-            Long rawContactId, String phoneNumber, String displayName) {
-        logger.debug("Enter: verifyInsertOrUpdateAction() phoneNumber : " + phoneNumber);
-        if (null == phoneNumber){
-            logger.error("Error: return as phoneNumber is null");
-            return;
-        }
-        // Check if the contact is already available in EAB Provider.
-        String[] eabProjection = new String[] {
-                EABContract.EABColumns.CONTACT_NUMBER,
-                EABContract.EABColumns.CONTACT_NAME };
-        String eabWhereClause = EABContract.EABColumns.DATA_ID + " ='" + dataId.toString()
-                + "' AND " + EABContract.EABColumns.RAW_CONTACT_ID + " ='"
-                + rawContactId.toString() + "'";
-        logger.debug("eabWhereClause : " + eabWhereClause);
-
-        Cursor eabCursor = getContentResolver().query(EABContract.EABColumns.CONTENT_URI,
-                eabProjection, eabWhereClause, null, null);
-        if (null != eabCursor) {
-            int eabCursorCount = eabCursor.getCount();
-            logger.debug("EAB cursor count : " + eabCursorCount);
-            if (eabCursorCount > 0) {
-                while (eabCursor.moveToNext()) {
-                    // EABProvider has entry for dataId & rawContactId. Try to
-                    // match the contact number.
-                    String eabPhoneNumber = eabCursor.getString(eabCursor
-                                    .getColumnIndex(EABContract.EABColumns.CONTACT_NUMBER));
-                    String eabDisplayName = eabCursor.getString(eabCursor
-                            .getColumnIndex(EABContract.EABColumns.CONTACT_NAME));
-                    logger.debug("phoneNumber : " + phoneNumber
-                            + " eabPhoneNumber :" + eabPhoneNumber);
-                    // Contact names should match and both numbers should not be
-                    // null & should not match.
-                    if ((null != eabPhoneNumber)
-                            && !PhoneNumberUtils.compare(mContext, phoneNumber, eabPhoneNumber)) {
-                        // Update use-case.
-                        handlePhoneNumberChanged(dataId, contactId, rawContactId,
-                                eabPhoneNumber, phoneNumber, displayName);
-                    } else {
-                        if ((null != eabPhoneNumber)
-                                && PhoneNumberUtils.compare(mContext, phoneNumber, eabPhoneNumber)
-                                && !TextUtils.equals(displayName, eabDisplayName)) {
-                            handlePhoneNameUpdate(dataId, contactId, rawContactId,
-                                    phoneNumber, displayName);
-                        } else {
-                            // Do nothing.
-                            logger.debug("The contact name and number is already available " +
-                                    "in EAB Provider.");
-                        }
-                    }
-                }
-            } else {
-                // insert use-case.
-                handlePhoneNumberInsertion(dataId, contactId, rawContactId, phoneNumber,
-                        displayName);
-            }
-        }
-        if (null != eabCursor) {
-            eabCursor.close();
-        }
-        logger.debug("Exit: verifyInsertOrUpdateAction()");
-    }
-
-    private void checkForPhoneNumberDelete(ArrayList<Long> uniqueRawContactIds) {
-        logger.debug("Enter: checkForPhoneNumberDelete() ");
-        if (null != uniqueRawContactIds && uniqueRawContactIds.size() > 0) {
-            for (int i = 0; i < uniqueRawContactIds.size(); i++) {
-                Long rawContactId = uniqueRawContactIds.get(i);
-                int contactsDbCount = 0;
-                int eabDbCursorCount = 0;
-
-                // Find the total number of dataIds under the rawContactId in
-                // Contacts Provider DB.
-                String[] projection = new String[] { ContactsContract.Data._ID,
-                        ContactsContract.Data.CONTACT_ID,
-                        ContactsContract.Data.RAW_CONTACT_ID,
-                        ContactsContract.Data.MIMETYPE,
-                        ContactsContract.Data.DATA1,
-                        ContactsContract.Data.DISPLAY_NAME };
-
-                // Get LastContactChangedTimestamp for knowing which contact
-                // number deleted from the contact id.
-                long contactLastChange = SharedPrefUtil.getLastContactChangedTimestamp(
-                        mContext, 0);
-
-                String selection = ContactsContract.Data.MIMETYPE + " = '"
-                        + Phone.CONTENT_ITEM_TYPE + "' AND " +
-                        ContactsContract.Data.CONTACT_LAST_UPDATED_TIMESTAMP
-                        + " > '" + contactLastChange + "' AND " +
-                        ContactsContract.Data.RAW_CONTACT_ID + " = '"
-                        + rawContactId + "'";
-
-                String sortOrder = ContactsContract.Data.RAW_CONTACT_ID + " desc";
-
-                Cursor contactDbCursor = getContentResolver().query(
-                        ContactsContract.Data.CONTENT_URI, projection,
-                        selection, null, sortOrder);
-
-                if (null != contactDbCursor) {
-                    contactsDbCount = contactDbCursor.getCount();
-                    logger.debug("contactDbCursor count : " + contactsDbCount);
-                }
-
-                // Find the total number of dataIds under the rawContactId in
-                // EAB Provider DB.
-                String[] eabProjection = new String[] {
-                        EABContract.EABColumns.CONTACT_ID,
-                        EABContract.EABColumns.RAW_CONTACT_ID,
-                        EABContract.EABColumns.DATA_ID,
-                        EABContract.EABColumns.CONTACT_NUMBER,
-                        EABContract.EABColumns.CONTACT_NAME };
-
-                String eabWhereClause = EABContract.EABColumns.RAW_CONTACT_ID
-                        + " ='" + rawContactId.toString() + "'";
-
-                Cursor eabDbCursor = getContentResolver().query(
-                        EABContract.EABColumns.CONTENT_URI, eabProjection,
-                        eabWhereClause, null, null);
-                if (null != eabDbCursor) {
-                    eabDbCursorCount = eabDbCursor.getCount();
-                    logger.debug("eabDbCursor count : " + eabDbCursorCount);
-                }
-                if (0 == contactsDbCount && 0 == eabDbCursorCount) {
-                    // Error scenario. Continue for checking the next rawContactId.
-                    logger.error("Both cursor counts are 0. move to next rawContactId");
-                } else {
-                    if (contactsDbCount == eabDbCursorCount) {
-                        // Do nothing as both DB have the same number of contacts.
-                        logger.debug("Both the databases have the same number of contacts." +
-                                " Do nothing.");
-                    } else if (contactsDbCount > eabDbCursorCount) {
-                        logger.error("EAB DB has less contacts then Contacts DB. Do nothing!");
-                    } else if (contactsDbCount < eabDbCursorCount) {
-                        // find and number and delete it from EAB Provider.
-                        logger.debug("Delete usecase hit. Find and delete contact from EAB DB.");
-                        ArrayList <Long> eabDataIdList = new ArrayList <Long>();
-                        while (eabDbCursor.moveToNext()) {
-                            String eabPhoneNumber = eabDbCursor.getString(eabDbCursor
-                                    .getColumnIndex(EABContract.EABColumns.CONTACT_NUMBER));
-                            logger.debug("eabPhoneNumber :" + eabPhoneNumber);
-                            Long eabDataId = Long.valueOf(eabDbCursor.getLong(eabDbCursor
-                                    .getColumnIndex(EABContract.EABColumns.DATA_ID)));
-                            logger.debug("eabDataId :" + eabDataId);
-                            if (eabDataIdList.isEmpty()) {
-                                eabDataIdList.add(eabDataId);
-                            } else if (!eabDataIdList.contains(eabDataId) )  {
-                                eabDataIdList.add(eabDataId);
-                            } else {
-                                // Something is wrong. There can not be duplicate numbers.
-                                logger.error("Duplicate entry for PhoneNumber :" + eabPhoneNumber
-                                        + " with DataId : " + eabDataId + " found in EABProvider.");
-                            }
-                        }
-                        logger.debug("Before computation eabDataIdList size :" +
-                                eabDataIdList.size());
-                        while (contactDbCursor.moveToNext()) {
-                            String contactPhoneNumber = contactDbCursor.getString(contactDbCursor
-                                    .getColumnIndex(ContactsContract.Data.DATA1));
-                            Long contactDataId = Long.valueOf(contactDbCursor.getLong(
-                                    contactDbCursor
-                                            .getColumnIndex(ContactsContract.Data._ID)));
-                            logger.debug("contactPhoneNumber : " + contactPhoneNumber +
-                                    " dataId : " + contactDataId);
-                            if (eabDataIdList.contains(contactDataId) )  {
-                                eabDataIdList.remove(contactDataId);
-                                logger.debug("Number removed from eabDataIdList");
-                            } else {
-                                // Something is wrong. There can not be new number in Contacts DB.
-                                logger.error("Number :" + contactPhoneNumber
-                                        + " with DataId : " + contactDataId +
-                                        " not found in EABProvider.");
-                            }
-                        }
-                        logger.debug("After computation eabPhoneNumberList size :" +
-                                eabDataIdList.size());
-                        if (eabDataIdList.size() > 0) {
-                            handlePhoneNumbersDeleted(rawContactId, eabDataIdList);
-                        }
-                    }
-                }
-                if (null != contactDbCursor) {
-                    contactDbCursor.close();
-                }
-                if (null != eabDbCursor) {
-                    eabDbCursor.close();
-                }
-            }
-        } else {
-            // Do nothing.
-            logger.debug("uniqueRawContactIds is null or empty. Do nothing. ");
-        }
-        logger.debug("Exit: checkForPhoneNumberDelete() ");
-    }
-
-    private void checkForDeletedContact() {
-        logger.debug("Enter: checkForDeletedContact()");
-        String[] projection = new String[] {
-                ContactsContract.DeletedContacts.CONTACT_ID,
-                ContactsContract.DeletedContacts.CONTACT_DELETED_TIMESTAMP };
-
-        long contactLastDeleted = SharedPrefUtil.getLastContactDeletedTimestamp(mContext, 0);
-        logger.debug("contactLastDeleted : " + contactLastDeleted);
-
-        String selection = ContactsContract.DeletedContacts.CONTACT_DELETED_TIMESTAMP
-                + " > '" + contactLastDeleted + "'";
-
-        String sortOrder = ContactsContract.DeletedContacts.CONTACT_DELETED_TIMESTAMP + " desc";
-
-        Cursor cursor = getContentResolver().query(
-                ContactsContract.DeletedContacts.CONTENT_URI, projection,
-                selection, null, sortOrder);
-        if (null != cursor) {
-            int count = cursor.getCount();
-            logger.debug("cursor count : " + count);
-            if (count > 0) {
-                while (cursor.moveToNext()) {
-                    Long contactId = Long.valueOf(cursor.getLong(cursor
-                                    .getColumnIndex(ContactsContract.DeletedContacts.CONTACT_ID)));
-                    logger.debug("contactId : " + contactId);
-                    handleContactDeleted(contactId);
-                }
-                // Save the largest returned timestamp. Only need the first
-                // cursor element due to the sort order.
-                cursor.moveToFirst();
-                long timestamp = cursor.getLong(cursor
-                        .getColumnIndex(
-                        ContactsContract.DeletedContacts.CONTACT_DELETED_TIMESTAMP));
-                if (timestamp > 0) {
-                    SharedPrefUtil.saveLastContactDeletedTimestamp(mContext, timestamp);
-                }
-            }
-        }
-        if (null != cursor) {
-            cursor.close();
-        }
-        logger.debug("Exit: checkForDeletedContact()");
-    }
-
-    private void checkForProfileNumberChanges() {
-        logger.debug("Enter: checkForProfileNumberChanges()");
-        String[] projection = new String[] {
-                ContactsContract.Contacts.Entity.CONTACT_ID,
-                ContactsContract.Contacts.Entity.RAW_CONTACT_ID,
-                ContactsContract.Contacts.Entity.DATA_ID,
-                ContactsContract.Contacts.Entity.MIMETYPE,
-                ContactsContract.Contacts.Entity.DATA1,
-                ContactsContract.Contacts.Entity.DISPLAY_NAME,
-                ContactsContract.Contacts.Entity.CONTACT_LAST_UPDATED_TIMESTAMP};
-
-        long profileContactLastChange = SharedPrefUtil.getLastProfileContactChangedTimestamp(
-                mContext, 0);
-        logger.debug("profileContactLastChange : " + profileContactLastChange);
-
-        String selection = ContactsContract.Contacts.Entity.MIMETYPE + " ='" +
-                Phone.CONTENT_ITEM_TYPE + "' AND "
-                + ContactsContract.Contacts.Entity.CONTACT_LAST_UPDATED_TIMESTAMP  + " > '" +
-                profileContactLastChange + "'";
-        String sortOrder = ContactsContract.Contacts.Entity.CONTACT_LAST_UPDATED_TIMESTAMP +
-                " desc";
-        // Construct the Uri to access Profile's Entity view.
-        Uri profileUri = ContactsContract.Profile.CONTENT_URI;
-        Uri entiryUri = Uri.withAppendedPath(profileUri,
-                ContactsContract.Contacts.Entity.CONTENT_DIRECTORY);
-
-        Cursor cursor = getContentResolver().query(entiryUri, projection, selection, null,
-                sortOrder);
-        if (null != cursor) {
-            int count = cursor.getCount();
-            logger.debug("cursor count : " + count);
-            if (count > 0) {
-                ArrayList <String> profileNumberList = new ArrayList <String>();
-                ArrayList <Long> profileDataIdList = new ArrayList <Long>();
-                Long contactId = null;
-                Long rawContactId = null;
-                while (cursor.moveToNext()) {
-                    contactId = Long.valueOf(cursor.getLong(cursor.getColumnIndex(
-                            ContactsContract.Contacts.Entity.CONTACT_ID)));
-                    rawContactId = Long.valueOf(cursor.getLong(cursor.getColumnIndex(
-                            ContactsContract.Contacts.Entity.RAW_CONTACT_ID)));
-                    Long dataId = Long.valueOf(cursor.getLong(cursor.getColumnIndex(
-                            ContactsContract.Contacts.Entity.DATA_ID)));
-                    String contactNumber = cursor.getString(cursor.getColumnIndex(
-                            ContactsContract.Contacts.Entity.DATA1));
-                    String profileName = cursor.getString(cursor.getColumnIndex(
-                            ContactsContract.Contacts.Entity.DISPLAY_NAME));
-                    logger.debug("Profile Name : " + profileName
-                            + " Profile Number : " + contactNumber
-                            + " profile dataId : " + dataId
-                            + " profile rawContactId : " + rawContactId
-                            + " profile contactId : " + contactId);
-                    if (profileDataIdList.isEmpty()) {
-                        profileDataIdList.add(dataId);
-                        profileNumberList.clear();
-                        profileNumberList.add(contactNumber);
-                    } else if (!profileDataIdList.contains(dataId)) {
-                        profileDataIdList.add(dataId);
-                        profileNumberList.add(contactNumber);
-                    } else {
-                        // There are duplicate entries in Profile's Table
-                        logger.error("Duplicate entry in Profile's Table for contact :" +
-                                contactNumber + " dataId : " + dataId);
-                    }
-                    verifyInsertOrUpdateAction(dataId, contactId, rawContactId, contactNumber,
-                            profileName);
-                }
-                checkForProfilePhoneNumberDelete(contactId, rawContactId, profileDataIdList);
-                // Save the largest timestamp returned. Only need the first cursor element
-                // due to sort order.
-                cursor.moveToFirst();
-                long timestamp = cursor.getLong(cursor.getColumnIndex(
-                        ContactsContract.Contacts.Entity.CONTACT_LAST_UPDATED_TIMESTAMP));
-                if (timestamp > 0) {
-                    SharedPrefUtil.saveLastProfileContactChangedTimestamp(mContext, timestamp);
-                }
-            } else {
-                logger.error("cursor is zero. Do nothing.");
-            }
-        } else {
-            logger.error("ContactsContract.Profile.CONTENT_URI cursor is null!");
-        }
-        if (null != cursor) {
-            cursor.close();
-        }
-        logger.debug("Exit: checkForProfileNumberChanges()");
-    }
-
-    private void checkForProfilePhoneNumberDelete(Long profileContactId,
-            Long profileRawContactId, ArrayList<Long> profileDataIdList) {
-        logger.debug("Enter: checkForProfilePhoneNumberDelete()");
-        if (!ContactsContract.isProfileId(profileContactId)) {
-            logger.error("Not a Profile Contact Id : " + profileContactId);
-            return;
-        }
-        int eabDbCursorCount = 0;
-        int profileContactsDbCount = profileDataIdList.size();
-        logger.error("profileContactsDbCount size : " + profileContactsDbCount);
-        // Find the total number of dataIds under the rawContactId in EAB Provider DB.
-        String[] eabProjection = new String[] {
-                EABContract.EABColumns.CONTACT_ID,
-                EABContract.EABColumns.DATA_ID,
-                EABContract.EABColumns.CONTACT_NUMBER};
-        String eabWhereClause = EABContract.EABColumns.CONTACT_ID + " ='" +
-                profileContactId.toString() + "'";
-
-        Cursor eabDbCursor = getContentResolver().query( EABContract.EABColumns.CONTENT_URI,
-                eabProjection,
-                eabWhereClause, null, null);
-        if (null != eabDbCursor) {
-            eabDbCursorCount = eabDbCursor.getCount();
-            logger.debug("eabDbCursor count : " + eabDbCursorCount);
-        }
-        if (0 == profileContactsDbCount && 0 == eabDbCursorCount) {
-            // Error scenario. Continue for checking the next rawContactId.
-            logger.error("Both cursor counts are 0. Do nothing");
-        } else {
-            if (profileContactsDbCount == eabDbCursorCount) {
-                // Do nothing as both DB have the same number of contacts.
-                logger.debug("Both the databases have the same number of contacts. Do nothing.");
-            } else if (profileContactsDbCount > eabDbCursorCount) {
-                logger.error("EAB DB has less contacts then Contacts DB. Do nothing!");
-            } else if (profileContactsDbCount < eabDbCursorCount) {
-                // find and number and delete it from EAB Provider.
-                logger.debug("Delete usecase hit. Find and delete contact from EAB DB.");
-                ArrayList <Long> eabDataIdList = new ArrayList <Long>();
-                while (eabDbCursor.moveToNext()) {
-                    Long eabDataId = Long.valueOf(eabDbCursor.getLong(eabDbCursor
-                                    .getColumnIndex(EABContract.EABColumns.DATA_ID)));
-                    logger.debug("eabDataId : " + eabDataId);
-                    if (eabDataIdList.isEmpty()) {
-                        eabDataIdList.add(eabDataId);
-                    } else if (!eabDataIdList.contains(eabDataId) )  {
-                        eabDataIdList.add(eabDataId);
-                    } else {
-                        // Something is wrong. There can not be duplicate numbers.
-                        logger.error("Duplicate entry for eabDataId in EABProvider : " +
-                                eabDataId);
-                    }
-                }
-                logger.debug("Before computation eabDataIdList size : " + eabDataIdList.size());
-                for (int i = 0; i < profileDataIdList.size(); i++) {
-                    Long contactDataId = profileDataIdList.get(i);
-                    logger.debug("Profile contactDataId : " + contactDataId);
-                    if (eabDataIdList.contains(contactDataId) )  {
-                        eabDataIdList.remove(contactDataId);
-                        logger.debug("Number removed from eabDataIdList");
-                    } else {
-                        // Something is wrong. There can not be new number in Contacts DB.
-                        logger.error("DataId : " + contactDataId +
-                                " not found in EAB Provider DB.");
-                    }
-                }
-                logger.debug("After computation eabDataIdList size : " + eabDataIdList.size());
-                if (eabDataIdList.size() > 0) {
-                    handlePhoneNumbersDeleted(profileRawContactId, eabDataIdList);
-                }
-            }
-        }
-        if (null != eabDbCursor) {
-            eabDbCursor.close();
-        }
-        logger.debug("Exit: checkForProfilePhoneNumberDelete() ");
-    }
-
-    private void checkForDeletedProfileContacts() {
-        logger.debug("Enter: checkForDeletedProfileContacts()");
-        String[] projection = new String[] {
-                ContactsContract.Contacts.Entity.DATA1,
-                ContactsContract.Contacts.Entity.DISPLAY_NAME,
-                ContactsContract.Contacts.Entity.CONTACT_LAST_UPDATED_TIMESTAMP};
-
-        String selection = ContactsContract.Contacts.Entity.MIMETYPE + " ='" +
-                Phone.CONTENT_ITEM_TYPE + "'";
-        // Construct the Uri to access Profile's Entity view.
-        Uri profileUri = ContactsContract.Profile.CONTENT_URI;
-        Uri entiryUri = Uri.withAppendedPath(profileUri,
-                ContactsContract.Contacts.Entity.CONTENT_DIRECTORY);
-
-        // Due to issue in AOSP contact profile db, table
-        // ContactsContract.Profile.CONTENT_URI can not be checked for
-        // selection = ContactsContract.Profile.HAS_PHONE_NUMBER + " = '" + 1 + "'".
-        // This is resulting in 0 cursor count even when there are valid
-        // contact numbers under contacts profile db.
-        Cursor cursor = getContentResolver().query(entiryUri, projection, selection, null, null);
-        if (null != cursor) {
-            int count = cursor.getCount();
-            logger.debug("Profile contact cursor count : " + count);
-            if (count == 0) {
-                logger.debug("cursor count is Zero. There are no contacts in Contact Profile db.");
-                handleContactProfileDeleted();
-            } else {
-                logger.debug("Profile is available. Do nothing");
-            }
-            cursor.close();
-        }
-        logger.debug("Exit: checkForDeletedProfileContacts()");
-    }
-
-    private void handlePhoneNumberInsertion(Long dataId, Long contactId,
-            Long rawContactId, String phoneNumber, String contactName) {
-
-        logger.debug("handlePhoneNumberInsertion() rawContactId : "
-                + rawContactId + " dataId :" + dataId + " contactId :"
-                + contactId + " phoneNumber :" + phoneNumber + " contactName :"
-                + contactName);
-        if (!EABDbUtil.validateEligibleContact(mContext, phoneNumber)) {
-            logger.debug("Return as number is not elegible for VT.");
-            return;
-        }
-        String sRawContactId = null;
-        String sDataId = null;
-        String sContactId = null;
-        if (null != rawContactId) {
-            sRawContactId = rawContactId.toString();
-        }
-        if (null != dataId) {
-            sDataId = dataId.toString();
-        }
-        if (null != contactId) {
-            sContactId = contactId.toString();
-        }
-        ArrayList<PresenceContact> contactListToInsert = new ArrayList<PresenceContact>();
-        contactListToInsert.add(new PresenceContact(contactName, phoneNumber,
-                sRawContactId, sContactId, sDataId));
-
-        EABDbUtil.addContactsToEabDb(getApplicationContext(),
-                contactListToInsert);
-    }
-
-    private void handlePhoneNumberChanged(Long dataId, Long contactId,
-            Long rawContactId, String oldPhoneNumber, String newPhoneNumber,
-            String contactName) {
-
-        logger.debug("handlePhoneNumberChanged() rawContactId : " + rawContactId
-                + " dataId :" + dataId + " oldPhoneNumber :" + oldPhoneNumber
-                + " newPhoneNumber :" + newPhoneNumber + " contactName :"
-                + contactName);
-
-        if (null == oldPhoneNumber && null == newPhoneNumber) {
-            logger.debug("Both old and new numbers are null.");
-            return;
-        }
-
-        ArrayList<PresenceContact> contactListToInsert = new ArrayList<PresenceContact>();
-        ArrayList<PresenceContact> contactListToDelete = new ArrayList<PresenceContact>();
-        String sRawContactId = null;
-        String sDataId = null;
-        String sContactId = null;
-        if (null != rawContactId) {
-            sRawContactId = rawContactId.toString();
-        }
-        if (null != dataId) {
-            sDataId = dataId.toString();
-        }
-        if (null != contactId) {
-            sContactId = contactId.toString();
-        }
-        logger.debug("Removing old number and inserting new number in EABProvider.");
-        if (null != oldPhoneNumber) {
-            contactListToDelete.add(new PresenceContact(contactName,
-                    oldPhoneNumber, sRawContactId, sContactId, sDataId));
-            // Delete old number from EAB Presence Table
-            EABDbUtil.deleteNumbersFromEabDb(getApplicationContext(), contactListToDelete);
-        }
-        if (null != newPhoneNumber) {
-            if (EABDbUtil.validateEligibleContact(mContext, newPhoneNumber)) {
-                contactListToInsert.add(new PresenceContact(contactName,
-                        newPhoneNumber, sRawContactId, sContactId, sDataId));
-                // Insert new number from EAB Presence Table
-                EABDbUtil.addContactsToEabDb(getApplicationContext(), contactListToInsert);
-            } else {
-                logger.debug("Return as number is not elegible for VT.");
-            }
-        }
-    }
-
-    private void handlePhoneNumbersDeleted(Long rawContactId, ArrayList <Long> contactDataIdList) {
-        ArrayList<PresenceContact> phoneNumberToDeleteList = new ArrayList<PresenceContact>();
-        for (int v = 0; v < contactDataIdList.size(); v++) {
-            Long staleDataId = contactDataIdList.get(v);
-            if (null != staleDataId) {
-                logger.debug("calling delete for staleNumber :" + staleDataId);
-                String sRawContactId = null;
-                if (null != rawContactId) {
-                    sRawContactId = rawContactId.toString();
-                }
-                phoneNumberToDeleteList.add(new PresenceContact(null, null,
-                        sRawContactId, null, staleDataId.toString()));
-            }
-        }
-        // Delete number from EAB Provider table.
-        EABDbUtil.deleteNumbersFromEabDb(getApplicationContext(), phoneNumberToDeleteList);
-    }
-
-    private void handlePhoneNameUpdate(Long dataId, Long contactId,
-            Long rawContactId, String phoneNumber, String newDisplayName) {
-        logger.debug("handlePhoneNameUpdate() rawContactId : " + rawContactId
-                + " dataId :" + dataId + " newDisplayName :" + newDisplayName);
-        String sRawContactId = null;
-        String sDataId = null;
-        String sContactId = null;
-        if (null != rawContactId) {
-            sRawContactId = rawContactId.toString();
-        }
-        if (null != dataId) {
-            sDataId = dataId.toString();
-        }
-        if (null != contactId) {
-            sContactId = contactId.toString();
-        }
-        ArrayList<PresenceContact> contactNameToUpdate = new ArrayList<PresenceContact>();
-        contactNameToUpdate.add(new PresenceContact(newDisplayName,
-                phoneNumber, sRawContactId, sContactId, sDataId));
-
-        EABDbUtil.updateNamesInEabDb(getApplicationContext(), contactNameToUpdate);
-    }
-
-    private void handleContactDeleted(Long contactId) {
-
-        if (null == contactId) {
-            logger.debug("handleContactDeleted : contactId is null");
-        }
-        ArrayList<PresenceContact> contactListToDelete = new ArrayList<PresenceContact>();
-        contactListToDelete.add(new PresenceContact(null, null, null, contactId.toString(), null));
-
-        //ContactDbUtil.deleteRawContact(getApplicationContext(), contactListToDelete);
-        EABDbUtil.deleteContactsFromEabDb(mContext, contactListToDelete);
-    }
-
-    private void handleContactProfileDeleted() {
-        Long contactProfileMinId = Long.valueOf(ContactsContract.Profile.MIN_ID);
-        logger.debug("contactProfileMinId : " + contactProfileMinId);
-
-        ArrayList<PresenceContact> contactListToDelete = new ArrayList<PresenceContact>();
-        contactListToDelete.add(new PresenceContact(null, null, null,
-                contactProfileMinId.toString(), null));
-
-        EABDbUtil.deleteContactsFromEabDb(mContext, contactListToDelete);
-    }
-
-    private boolean isRcsProvisioned(){
-        boolean isVoLTEProvisioned = false;
-        boolean isLvcProvisioned = false;
-        boolean isEabProvisioned = false;
-        ImsManager imsManager = null;
-        ImsConfig imsConfig = null;
-
-        // Get instance of imsManagr.
-        imsManager = ImsManager.getInstance(mContext,
-                SubscriptionManager.getDefaultVoiceSubscriptionId());
-        try {
-            imsConfig = imsManager.getConfigInterface();
-            logger.debug("imsConfig initialized.");
-        } catch (Exception e) {
-            logger.error("getConfigInterface() exception:", e);
-            imsConfig = null;
-        }
-
-        if (null != imsConfig) {
-            try {
-                isVoLTEProvisioned = imsConfig.getProvisionedValue(
-                        ImsConfig.ConfigConstants.VLT_SETTING_ENABLED)
-                        == ImsConfig.FeatureValueConstants.ON;
-                isLvcProvisioned = imsConfig.getProvisionedValue(
-                        ImsConfig.ConfigConstants.LVC_SETTING_ENABLED)
-                        == ImsConfig.FeatureValueConstants.ON;
-                isEabProvisioned = imsConfig.getProvisionedValue(
-                        ImsConfig.ConfigConstants.EAB_SETTING_ENABLED)
-                        == ImsConfig.FeatureValueConstants.ON;
-            } catch (ImsException e) {
-                logger.error("ImsException in isRcsProvisioned() : ", e);
-            }
-        } else {
-            logger.debug("isRcsProvisioned - imsConfig is null");
-        }
-        logger.debug("isVoLTEProvisioned : " + isVoLTEProvisioned + " isLvcProvisioned : " +
-                isLvcProvisioned
-                + " isEabProvisioned : " + isEabProvisioned);
-        return (isVoLTEProvisioned && isLvcProvisioned && isEabProvisioned);
-    }
-}
diff --git a/rcs/presencepolling/src/com/android/service/ims/presence/InvalidDBException.java b/rcs/presencepolling/src/com/android/service/ims/presence/InvalidDBException.java
deleted file mode 100644
index 1e7fdeb..0000000
--- a/rcs/presencepolling/src/com/android/service/ims/presence/InvalidDBException.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
-
-package com.android.service.ims.presence;
-
-import android.database.sqlite.SQLiteException;
-
-//A custom exception for onDowngrade()
-public class InvalidDBException extends SQLiteException {
-    public InvalidDBException() {
-    }
-
-    public InvalidDBException(String error) {
-        super(error);
-    }
-}
diff --git a/rcs/presencepolling/src/com/android/service/ims/presence/LauncherUtils.java b/rcs/presencepolling/src/com/android/service/ims/presence/LauncherUtils.java
deleted file mode 100644
index 8362142..0000000
--- a/rcs/presencepolling/src/com/android/service/ims/presence/LauncherUtils.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
-
-package com.android.service.ims.presence;
-
-import android.content.Context;
-import android.content.Intent;
-
-import com.android.ims.internal.Logger;
-
-/**
- * Launcher utility functions
- *
- */
-public class LauncherUtils {
-    private static Logger logger = Logger.getLogger(LauncherUtils.class.getName());
-
-    /**
-     * Launch the Presence service.
-     *
-     * @param context application context
-     * @param boot Boot flag
-     */
-    public static boolean launchPollingService(Context context) {
-        logger.debug("Launch polling service");
-
-        Intent intent = new Intent(context, PollingService.class);
-        return (context.startService(intent) != null);
-    }
-
-    /**
-     * Stop the Presence service.
-     *
-     * @param context application context
-     */
-    public static boolean stopPollingService(Context context) {
-        logger.debug("Stop polling service");
-
-        Intent intent = new Intent(context, PollingService.class);
-        return context.stopService(intent);
-    }
-
-    public static boolean launchEabService(Context context) {
-        logger.debug("Launch Eab Service");
-
-        Intent intent = new Intent(context, EABService.class);
-        return (context.startService(intent) != null);
-    }
-
-    public static boolean stopEabService(Context context) {
-        logger.debug("Stop EAB service");
-
-        Intent intent = new Intent(context, EABService.class);
-        return context.stopService(intent);
-    }
-}
-
diff --git a/rcs/presencepolling/src/com/android/service/ims/presence/PersistService.java b/rcs/presencepolling/src/com/android/service/ims/presence/PersistService.java
deleted file mode 100644
index bbd9cee..0000000
--- a/rcs/presencepolling/src/com/android/service/ims/presence/PersistService.java
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
-
-package com.android.service.ims.presence;
-
-import android.content.Intent;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.app.Service;
-import android.os.SystemProperties;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.HandlerThread;
-import android.os.Process;
-import java.util.ArrayList;
-import android.content.ContentValues;
-import android.text.TextUtils;
-
-import com.android.ims.internal.Logger;
-import com.android.ims.RcsManager.ResultCode;
-import com.android.ims.RcsPresence;
-import com.android.ims.RcsPresenceInfo;
-
-/**
- * This service essentially plays the role of a "worker thread", allowing us to store
- * presence information.
- */
-public class PersistService extends Service {
-    private Logger logger = Logger.getLogger(this.getClass().getName());
-
-    private static final int MESSAGE_PRESENCE_CHANGED = 1;
-    private static final int MESSAGE_PUBLISH_STATE_CHANGED = 2;
-
-    private int mVltProvisionErrorCount = 0;
-    private Looper mServiceLooper = null;
-    private ServiceHandler mServiceHandler = null;
-    private EABContactManager mEABContactManager = null;
-
-    @Override
-    public void onCreate() {
-        mEABContactManager = new EABContactManager(getContentResolver(), getPackageName());
-
-        // separate thread because the service normally runs in the process's
-        // main thread, which we don't want to block.
-        HandlerThread thread = new HandlerThread("PersistServiceThread",
-                Process.THREAD_PRIORITY_BACKGROUND);
-        thread.start();
-
-        mServiceLooper = thread.getLooper();
-        mServiceHandler = new ServiceHandler(mServiceLooper);
-    }
-
-    @Override
-    public int onStartCommand(Intent intent, int flags, int startId) {
-        if(intent == null) {
-            return Service.START_NOT_STICKY;
-        }
-
-        if(RcsPresence.ACTION_PRESENCE_CHANGED.equals(intent.getAction())) {
-            Message msg = mServiceHandler.obtainMessage(MESSAGE_PRESENCE_CHANGED);
-            msg.arg1 = startId;
-            msg.obj = intent;
-            mServiceHandler.sendMessage(msg);
-            return Service.START_NOT_STICKY;
-        } else if(RcsPresence.ACTION_PUBLISH_STATE_CHANGED.equals(intent.getAction())) {
-            Message msg = mServiceHandler.obtainMessage(MESSAGE_PUBLISH_STATE_CHANGED);
-            msg.arg1 = startId;
-            msg.obj = intent;
-            mServiceHandler.sendMessage(msg);
-            return Service.START_NOT_STICKY;
-        } else {
-            logger.debug("unknown intent=" + intent);
-        }
-
-        return Service.START_NOT_STICKY;
-    }
-
-    @Override
-    public void onDestroy() {
-        mServiceLooper.quit();
-    }
-
-    @Override
-    public IBinder onBind(Intent intent) {
-        return null;
-    }
-
-    private final class ServiceHandler extends Handler {
-        public ServiceHandler(Looper looper) {
-            super(looper);
-        }
-
-        /**
-         * Handler to save the presence information.
-         */
-        @Override
-        public void handleMessage(Message msg) {
-            super.handleMessage(msg);
-            logger.print( "Thread=" + Thread.currentThread().getName() + " received "
-                    + msg);
-            if(msg == null){
-                logger.error("msg=null");
-                return;
-            }
-
-            int serviceId = msg.arg1;
-            Intent intent = (Intent)msg.obj;
-            logger.print("handleMessage serviceId: " + serviceId + " intent: " + intent);
-            switch (msg.what) {
-                case MESSAGE_PRESENCE_CHANGED:
-                    if (intent != null) {
-                        if (RcsPresence.ACTION_PRESENCE_CHANGED.equals(intent.getAction())) {
-                            handlePresence(intent);
-                        } else {
-                            logger.debug("I don't care about intent: " + intent);
-                        }
-                        intent.setComponent(null);
-                        sendBroadcast(intent);
-                    }
-                break;
-
-                case MESSAGE_PUBLISH_STATE_CHANGED:
-                    if (intent != null) {
-                        if (RcsPresence.ACTION_PUBLISH_STATE_CHANGED.equals(intent.getAction())) {
-                            int publishState = intent.getIntExtra(RcsPresence.EXTRA_PUBLISH_STATE,
-                                    RcsPresence.PublishState.PUBLISH_STATE_200_OK);
-                            handlePublishState(publishState);
-                        } else {
-                            logger.debug("I don't care about intent: " + intent);
-                        }
-                    }
-                break;
-
-                default:
-                    logger.debug("unknown message:" + msg);
-            }
-        }
-    }
-
-    private void handlePublishState(int publishState) {
-        if(publishState == RcsPresence.PublishState.PUBLISH_STATE_VOLTE_PROVISION_ERROR) {
-            mVltProvisionErrorCount += 1;
-            if(mVltProvisionErrorCount >= 3){
-                if(mEABContactManager != null) {
-                    mEABContactManager.updateAllCapabilityToUnknown();
-                    logger.print("updateAllCapabilityToUnknown for publish 403 error");
-                    Intent intent = new Intent(RcsPresence.ACTION_PRESENCE_CHANGED);
-                    sendBroadcast(intent);
-                } else {
-                    logger.error("mEABContactManager is null");
-                }
-            }
-        } else if(publishState == RcsPresence.PublishState.PUBLISH_STATE_RCS_PROVISION_ERROR){
-            mVltProvisionErrorCount = 0;
-            if(mEABContactManager != null) {
-                mEABContactManager.updateAllVtCapabilityToUnknown();
-                logger.print("updateAllVtCapabilityToUnknown for publish 404 error");
-                Intent intent = new Intent(RcsPresence.ACTION_PRESENCE_CHANGED);
-                sendBroadcast(intent);
-            } else {
-                logger.error("mEABContactManager is null");
-            }
-        } else {
-            mVltProvisionErrorCount = 0;
-        }
-    }
-
-    private void handlePresence(Intent intent) {
-        if(intent == null) {
-            return;
-        }
-
-        // save the presence information.
-        ArrayList<RcsPresenceInfo> rcsPresenceInfoList = intent.getParcelableArrayListExtra(
-                RcsPresence.EXTRA_PRESENCE_INFO_LIST);
-        boolean updateLastTimestamp = intent.getBooleanExtra("updateLastTimestamp", true);
-        logger.print("updateLastTimestamp=" + updateLastTimestamp +
-                " RcsPresenceInfoList=" + rcsPresenceInfoList);
-        for(int i=0; i< rcsPresenceInfoList.size(); i++){
-            RcsPresenceInfo rcsPresenceInfoTmp = rcsPresenceInfoList.get(i);
-            if((rcsPresenceInfoTmp != null) && !TextUtils.isEmpty(
-                    rcsPresenceInfoTmp.getContactNumber())){
-                mEABContactManager.update(rcsPresenceInfoTmp, updateLastTimestamp);
-            }
-        }
-    }
-}
-
-
diff --git a/rcs/presencepolling/src/com/android/service/ims/presence/PollingAction.java b/rcs/presencepolling/src/com/android/service/ims/presence/PollingAction.java
deleted file mode 100644
index fc297ae..0000000
--- a/rcs/presencepolling/src/com/android/service/ims/presence/PollingAction.java
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
-
-package com.android.service.ims.presence;
-
-import android.content.Context;
-import android.os.AsyncTask;
-import android.os.Looper;
-
-import com.android.ims.IRcsPresenceListener;
-import com.android.ims.RcsManager;
-import com.android.ims.RcsPresence;
-import com.android.ims.RcsException;
-import com.android.ims.RcsManager.ResultCode;
-import com.android.ims.internal.Logger;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class PollingAction extends AsyncTask<Void, Integer, Integer> {
-    private Logger logger = Logger.getLogger(this.getClass().getName());
-
-    private Context mContext;
-    private PollingTask mPollingTask;
-    private int mResult;
-    private int mRequestId = -1;
-
-    private final Object mPollingSyncObj = new Object();
-    private boolean mIsPolling = false;
-    private boolean mFullUpdated = false;
-
-    private IRcsPresenceListener mClientListener = new IRcsPresenceListener.Stub() {
-        public void onSuccess(int reqId) {
-            logger.print("onSuccess() is called. reqId=" + reqId);
-        }
-
-        public void onError(int reqId, int code) {
-            logger.print("onError() is called, reqId=" + reqId + " error code: " + code);
-            synchronized(mPollingSyncObj) {
-                mResult = code;
-                mIsPolling = false;
-                mPollingSyncObj.notifyAll();
-            }
-        }
-
-        public void onFinish(int reqId) {
-            logger.print("onFinish() is called, reqId=" + reqId);
-            if (reqId == mRequestId) {
-                synchronized(mPollingSyncObj) {
-                    mFullUpdated = true;
-                    mIsPolling = false;
-                    mPollingSyncObj.notifyAll();
-                }
-            }
-        }
-
-        public void onTimeout(int reqId) {
-            logger.print("onTimeout() is called, reqId=" + reqId);
-            if (reqId == mRequestId) {
-                synchronized(mPollingSyncObj) {
-                    mIsPolling = false;
-                    mPollingSyncObj.notifyAll();
-                }
-            }
-        }
-    };
-
-    public PollingAction(Context context, PollingTask task) {
-        mContext = context;
-        mPollingTask = task;
-        logger.info("PollingAction(), task=" + mPollingTask);
-    }
-
-    @Override
-    protected void onPreExecute() {
-        super.onPreExecute();
-        mPollingTask.onPreExecute();
-    }
-
-    @Override
-    protected Integer doInBackground(Void... params) {
-        logger.debug("doInBackground(), Thread = " + Thread.currentThread().getName());
-
-        if (Looper.myLooper() == null) {
-            Looper.prepare();
-        }
-
-        int requestExpiration = PresenceSetting.getCapabilityPollListSubscriptionExpiration();
-        logger.print("getCapabilityPollListSubscriptionExpiration: " + requestExpiration);
-        if (requestExpiration == -1) {
-            requestExpiration = 30;
-        }
-        requestExpiration += 30;
-
-        mResult = ResultCode.SUBSCRIBE_NOT_FOUND;
-        ArrayList<String> uriList = new ArrayList<String>();
-        uriList.clear();
-
-        List<Contacts.Item> contacts = mPollingTask.mContacts;
-        for (int i = 0; i < contacts.size(); i++) {
-            Contacts.Item item = contacts.get(i);
-            uriList.add(getCompleteUri(item.number()));
-        }
-        int size = uriList.size();
-        if (size <= 0) {
-            logger.debug("No contacts in polling task, no action.");
-        } else {
-            mResult = ResultCode.ERROR_SERVICE_NOT_AVAILABLE;
-            synchronized(mPollingSyncObj) {
-                RcsManager rcsManager = RcsManager.getInstance(mContext, 0);
-                if (rcsManager == null) {
-                    logger.debug("rcsManager == null");
-                } else {
-                    try {
-                        RcsPresence rcsPresence = rcsManager.getRcsPresenceInterface();
-                        if (rcsPresence == null) {
-                            logger.debug("rcsPresence == null");
-                        } else {
-                            logger.print("call requestCapability: " + size);
-                            // If ret > 0 then it is the request Id, or it is result code.
-                            int ret = rcsPresence.requestCapability(uriList, mClientListener);
-                            if (ret > 0) {
-                                mRequestId = ret;
-                                mResult = ResultCode.SUCCESS;
-                            } else {
-                                mRequestId = -1;
-                                mResult = ret;
-                            }
-                        }
-                    } catch (RcsException ex) {
-                        logger.print("RcsException", ex);
-                    }
-                }
-
-                if (mResult == ResultCode.SUCCESS) {
-                    logger.print("Capability discovery success, RequestId = " + mRequestId);
-                    mIsPolling = true;
-                } else {
-                    logger.info("Capability discovery failure result = " + mResult);
-                    mIsPolling = false;
-                }
-
-                final long endTime = System.currentTimeMillis() + requestExpiration * 1000;
-                while(true) {
-                    if (!mIsPolling) {
-                        break;
-                    }
-
-                    long delay = endTime - System.currentTimeMillis();
-                    if (delay <= 0) {
-                        break;
-                    }
-
-                    try {
-                        mPollingSyncObj.wait(delay);
-                    } catch (InterruptedException ex) {
-                    }
-                }
-            }
-        }
-
-        logger.print("The action final result = " + mResult);
-        mPollingTask.onPostExecute(mResult);
-        if (ResultCode.SUBSCRIBE_TEMPORARY_ERROR == mResult) {
-            mPollingTask.retry();
-        } else {
-            mPollingTask.finish(mFullUpdated);
-        }
-
-        return mResult;
-    }
-
-    private String getCompleteUri(String phone) {
-        phone = "tel:" + phone;
-        return phone;
-    }
-
-    @Override
-    protected void onPostExecute(Integer result) {
-        super.onPostExecute(result);
-        logger.print("onPostExecute(), result = " + result);
-    }
-}
-
diff --git a/rcs/presencepolling/src/com/android/service/ims/presence/PollingService.java b/rcs/presencepolling/src/com/android/service/ims/presence/PollingService.java
deleted file mode 100644
index d6e4410..0000000
--- a/rcs/presencepolling/src/com/android/service/ims/presence/PollingService.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
-
-package com.android.service.ims.presence;
-
-import android.app.Service;
-import android.content.Intent;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.SystemProperties;
-
-import com.android.ims.internal.Logger;
-
-public class PollingService extends Service {
-    /**
-     * The logger
-     */
-    private Logger logger = Logger.getLogger(this.getClass().getName());
-
-    private CapabilityPolling mCapabilityPolling = null;
-
-    /**
-     * Constructor
-     */
-    public PollingService() {
-        logger.debug("PollingService()");
-    }
-
-    @Override
-    public void onCreate() {
-        logger.debug("onCreate()");
-
-        if (isEabSupported()) {
-            mCapabilityPolling = CapabilityPolling.getInstance(this);
-            mCapabilityPolling.start();
-        }
-    }
-
-    @Override
-    public int onStartCommand(Intent intent, int flags, int startId) {
-        logger.debug("onStartCommand(), intent: " + intent +
-                ", flags: " + flags + ", startId: " + startId);
-
-        if (!isRcsSupported()) {
-            stopSelf();
-            return START_NOT_STICKY;
-        }
-
-        return super.onStartCommand(intent, flags, startId);
-    }
-
-    /**
-      * Cleans up when the service is destroyed
-      */
-    @Override
-    public void onDestroy() {
-        logger.debug("onDestroy()");
-
-        if (mCapabilityPolling != null) {
-            mCapabilityPolling.stop();
-            mCapabilityPolling = null;
-        }
-
-        super.onDestroy();
-    }
-
-    @Override
-    public IBinder onBind(Intent intent) {
-        logger.debug("onBind(), intent: " + intent);
-
-        if (!isRcsSupported()) {
-            return null;
-        }
-
-        logger.debug("onBind add services here");
-        return null;
-    }
-
-    private boolean isRcsSupported() {
-        String rcsSupported = SystemProperties.get("persist.rcs.supported");
-        logger.info("persist.rcs.supported: " + rcsSupported);
-        return "1".equals(rcsSupported);
-    }
-
-    private boolean isEabSupported() {
-        String eabSupported = SystemProperties.get("persist.eab.supported");
-        logger.info("persist.eab.supported: " + eabSupported);
-        return ("0".equals(eabSupported)) ? false : true;
-    }
-}
-
diff --git a/rcs/presencepolling/src/com/android/service/ims/presence/PollingTask.java b/rcs/presencepolling/src/com/android/service/ims/presence/PollingTask.java
deleted file mode 100644
index 69c4018..0000000
--- a/rcs/presencepolling/src/com/android/service/ims/presence/PollingTask.java
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
-
-package com.android.service.ims.presence;
-
-import android.app.AlarmManager;
-import android.app.PendingIntent;
-import android.content.Context;
-import android.content.Intent;
-import android.os.SystemClock;
-import android.text.format.Time;
-
-import com.android.ims.internal.Logger;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class PollingTask {
-    private Logger logger = Logger.getLogger(this.getClass().getName());
-    private Context mContext = null;
-
-    private static long sMaxId = 0;
-    public static final String ACTION_POLLING_RETRY_ALARM =
-            "com.android.service.ims.presence.capability_polling_retry";
-    private PendingIntent mRetryAlarmIntent = null;
-
-    public long mId;
-    public int mType;
-    public List<Contacts.Item> mContacts = new ArrayList<Contacts.Item>();
-
-    private long mTimeUnit;
-    private int mTotalRetry;
-    private int mCurrentRetry;
-    private long mLastUpdateTime;
-
-    private boolean mCancelled = false;
-    private boolean mCompleted = false;
-
-    public PollingTask(int type, List<Contacts.Item> list) {
-        mId = sMaxId++;
-        mType = type;
-
-        mContacts.clear();
-        for(int i = 0; i < list.size(); i++) {
-            Contacts.Item item = list.get(i);
-            mContacts.add(item);
-        }
-
-        mCurrentRetry = 0;
-        mTotalRetry = 5;
-        mTimeUnit = 1800; // 1800s = 30 minutes
-        if (CapabilityPolling.ACTION_POLLING_NEW_CONTACTS == mType) {
-            mTotalRetry = 4;
-            mTimeUnit = 60; // 60s = 1 minute
-        }
-        mLastUpdateTime = 0;
-    }
-
-    public void execute() {
-        PollingsQueue queue = PollingsQueue.getInstance(null);
-        if (queue == null) {
-            return;
-        }
-
-        PollingAction action = new PollingAction(queue.getContext(), this);
-        action.execute();
-    }
-
-    public void finish(boolean fullUpdated) {
-        cancelRetryAlarm();
-
-        PollingsQueue queue = PollingsQueue.getInstance(null);
-        if (queue == null) {
-            return;
-        }
-
-        mCompleted = fullUpdated ? true : false;
-        queue.remove(this);
-    }
-
-    public void retry() {
-        mCurrentRetry += 1;
-        logger.print("retry mCurrentRetry=" + mCurrentRetry);
-        if (mCurrentRetry > mTotalRetry) {
-            logger.print("Retry finished for task: " + this);
-            updateTimeStampToCurrent();
-            finish(false);
-            return;
-        }
-
-        if (mCancelled) {
-            logger.print("Task is cancelled: " + this);
-            finish(false);
-            return;
-        }
-
-        long delay = mTimeUnit;
-        for (int i = 0; i < mCurrentRetry - 1; i++) {
-            delay *= 2;
-        }
-
-        logger.print("retry delay=" + delay);
-
-        scheduleRetry(delay * 1000);
-    }
-
-    public void cancel() {
-        mCancelled = true;
-        logger.print("Cancel this task: " + this);
-
-        if (mRetryAlarmIntent != null) {
-            cancelRetryAlarm();
-            finish(false);
-        }
-    }
-
-    public void onPreExecute() {
-        logger.print("onPreExecute(), id = " + mId);
-        cancelRetryAlarm();
-    }
-
-    public void onPostExecute(int result) {
-        logger.print("onPostExecute(), result = " + result);
-        mLastUpdateTime = System.currentTimeMillis();
-    }
-
-    private void updateTimeStampToCurrent() {
-        if (mContext == null) {
-            return;
-        }
-
-        EABContactManager contactManager = new EABContactManager(
-                mContext.getContentResolver(), mContext.getPackageName());
-        for (int i = 0; i < mContacts.size(); i++) {
-            Contacts.Item item = mContacts.get(i);
-
-            String number = item.number();
-            long current = System.currentTimeMillis();
-            EABContactManager.Request request = new EABContactManager.Request(number)
-                    .setLastUpdatedTimeStamp(current);
-            int result = contactManager.update(request);
-            if (result <= 0) {
-                logger.debug("failed to update timestamp for contact: " + number);
-            }
-        }
-    }
-
-    private void cancelRetryAlarm() {
-        if (mRetryAlarmIntent != null) {
-            if (mContext != null) {
-                AlarmManager alarmManager = (AlarmManager)
-                        mContext.getSystemService(Context.ALARM_SERVICE);
-                alarmManager.cancel(mRetryAlarmIntent);
-            }
-            mRetryAlarmIntent = null;
-        }
-    }
-
-    private void scheduleRetry(long msec) {
-        logger.print("scheduleRetry msec=" + msec);
-
-        cancelRetryAlarm();
-
-        if (mContext == null) {
-            PollingsQueue queue = PollingsQueue.getInstance(null);
-            if (queue != null) {
-                mContext = queue.getContext();
-            }
-        }
-
-        if (mContext != null) {
-            Intent intent = new Intent(ACTION_POLLING_RETRY_ALARM);
-            intent.setClass(mContext, AlarmBroadcastReceiver.class);
-            intent.putExtra("pollingTaskId", mId);
-
-            mRetryAlarmIntent = PendingIntent.getBroadcast(mContext, 0, intent,
-                    PendingIntent.FLAG_UPDATE_CURRENT);
-
-            AlarmManager alarmManager = (AlarmManager)
-                    mContext.getSystemService(Context.ALARM_SERVICE);
-            alarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP,
-                    SystemClock.elapsedRealtime() + msec, mRetryAlarmIntent);
-        }
-    }
-
-    private String getTimeString(long time) {
-        if (time <= 0) {
-            time = System.currentTimeMillis();
-        }
-
-        Time tobj = new Time();
-        tobj.set(time);
-        return String.format("%s.%s", tobj.format("%m-%d %H:%M:%S"), time % 1000);
-    }
-
-    public boolean isCompleted() {
-        return mCompleted;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (!(o instanceof PollingTask)) return false;
-
-        PollingTask that = (PollingTask)o;
-        return (this.mId == that.mId) && (this.mType == that.mType);
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-        sb.append("PollingTask { ");
-        sb.append("\nId: " + mId);
-        sb.append("\nType: " + mType);
-        sb.append("\nCurrentRetry: " + mCurrentRetry);
-        sb.append("\nTotalRetry: " + mTotalRetry);
-        sb.append("\nTimeUnit: " + mTimeUnit);
-        sb.append("\nLast update time: " + mLastUpdateTime + "(" +
-                getTimeString(mLastUpdateTime) + ")");
-        sb.append("\nContacts: " + mContacts.size());
-        for (int i = 0; i < mContacts.size(); i++) {
-            sb.append("\n");
-            Contacts.Item item = mContacts.get(i);
-            sb.append("Number " + i + ": " + item.number());
-        }
-        sb.append("\nCompleted: " + mCompleted);
-        sb.append(" }");
-        return sb.toString();
-    }
-}
-
diff --git a/rcs/presencepolling/src/com/android/service/ims/presence/PollingsQueue.java b/rcs/presencepolling/src/com/android/service/ims/presence/PollingsQueue.java
deleted file mode 100644
index b833de7..0000000
--- a/rcs/presencepolling/src/com/android/service/ims/presence/PollingsQueue.java
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
-
-package com.android.service.ims.presence;
-
-import android.content.Context;
-
-import com.android.ims.internal.Logger;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class PollingsQueue {
-    private Logger logger = Logger.getLogger(this.getClass().getName());
-
-    private Context mContext;
-    private CapabilityPolling mCapabilityPolling;
-    private List<PollingTask> mPollingTasks = new ArrayList<PollingTask>();
-    private boolean mAskVerifyResult = false;
-    private int mVerifyCounts = 0;
-
-    private static PollingsQueue sInstance = null;
-    public static synchronized PollingsQueue getInstance(Context context) {
-        if ((sInstance == null) && (context != null)) {
-            sInstance = new PollingsQueue(context);
-        }
-
-        return sInstance;
-    }
-
-    private PollingsQueue(Context context) {
-        mContext = context;
-        mPollingTasks.clear();
-    }
-
-    public synchronized void setCapabilityPolling(CapabilityPolling cp) {
-        mCapabilityPolling = cp;
-    }
-
-    public CapabilityPolling getCapabilityPolling() {
-        return mCapabilityPolling;
-    }
-
-    public Context getContext() {
-        return mContext;
-    }
-
-    public synchronized void clear() {
-        mPollingTasks.clear();
-    }
-
-    public synchronized void add(int type, List<Contacts.Item> list) {
-        if (list.size() <= 0) {
-            return;
-        }
-
-        List<Contacts.Item> contacts = new ArrayList<Contacts.Item>();
-        contacts.clear();
-        for(int i = 0; i < list.size(); i++) {
-            Contacts.Item item = list.get(i);
-
-            boolean bExist = false;
-            for(int j = 0; j < contacts.size(); j++) {
-                Contacts.Item item0 = contacts.get(j);
-                if (item.equals(item0)) {
-                    bExist = true;
-                    break;
-                }
-            }
-
-            for (int j = 0; j < mPollingTasks.size(); j++) {
-                if (bExist) {
-                    break;
-                }
-                PollingTask task = mPollingTasks.get(j);
-                for(int k = 0; k < task.mContacts.size(); k++) {
-                    Contacts.Item item0 = task.mContacts.get(k);
-                    if (item.equals(item0)) {
-                        bExist = true;
-                        break;
-                    }
-                }
-            }
-            if (bExist) {
-                continue;
-            }
-
-            contacts.add(item);
-            if (type == CapabilityPolling.ACTION_POLLING_NORMAL) {
-                if (item.lastUpdateTime() == 0) {
-                    type = CapabilityPolling.ACTION_POLLING_NEW_CONTACTS;
-                }
-            }
-        }
-
-        PollingTask taskCancelled = null;
-        int nTasks = mPollingTasks.size();
-        logger.print("Before add(), the existing tasks number: " + nTasks);
-
-        if (contacts.size() <= 0) {
-            logger.debug("Empty/duplicated list, no request added.");
-            return;
-        }
-
-        int maxEntriesInRequest = PresenceSetting.getMaxNumberOfEntriesInRequestContainedList();
-        logger.print("getMaxNumberOfEntriesInRequestContainedList: " + maxEntriesInRequest);
-        if (maxEntriesInRequest == -1) {
-            maxEntriesInRequest = 100;
-        }
-
-        int noOfIterations = contacts.size() / maxEntriesInRequest;
-        for (int loop = 0; loop <= noOfIterations; loop++) {
-            int entriesInRequest = maxEntriesInRequest;
-            if (loop == noOfIterations) {
-                entriesInRequest = contacts.size() % maxEntriesInRequest;
-            }
-
-            List<Contacts.Item> cl = new ArrayList<Contacts.Item>();
-            cl.clear();
-            int pos = loop * maxEntriesInRequest;
-            for (int i = 0; i < entriesInRequest; i++) {
-                Contacts.Item item = contacts.get(pos);
-                cl.add(item);
-                pos++;
-            }
-
-            if (cl.size() > 0) {
-                PollingTask task = new PollingTask(type, cl);
-                logger.debug("One new polling task added: " + task);
-
-                boolean bInserted = false;
-                for (int i = 0; i < mPollingTasks.size(); i++) {
-                    PollingTask task0 = mPollingTasks.get(i);
-                    if (task.mType > task0.mType) {
-                        bInserted = true;
-                        mPollingTasks.add(i, task);
-                        if ((i == 0) && (taskCancelled == null)) {
-                            taskCancelled = task0;
-                        }
-                        break;
-                    }
-                }
-                if (!bInserted) {
-                    mPollingTasks.add(task);
-                }
-            }
-        }
-
-        logger.print("After add(), the total tasks number: " + mPollingTasks.size());
-        if (nTasks <= 0) {
-            if (mPollingTasks.size() > 0) {
-                PollingTask task = mPollingTasks.get(0);
-                task.execute();
-            }
-        } else {
-            if (taskCancelled != null) {
-                taskCancelled.cancel();
-            }
-        }
-    }
-
-    public synchronized void remove(PollingTask task) {
-        int nTasks = mPollingTasks.size();
-        if (nTasks <= 0) {
-            return;
-        }
-
-        logger.print("Remove polling task: " + task);
-        if (task != null) {
-            for (int i = 0; i < nTasks; i++) {
-                PollingTask task0 = mPollingTasks.get(i);
-                if (task0.equals(task)) {
-                    if (task.isCompleted()) {
-                        mVerifyCounts = 0;
-                    } else {
-                        mAskVerifyResult = true;
-                    }
-                    mPollingTasks.remove(i);
-                    break;
-                }
-            }
-        }
-
-        if (mPollingTasks.size() > 0) {
-            PollingTask task0 = mPollingTasks.get(0);
-            task0.execute();
-        } else {
-            if (mAskVerifyResult) {
-                mAskVerifyResult = false;
-                mVerifyCounts++;
-                if (mCapabilityPolling != null) {
-                    mCapabilityPolling.enqueueVerifyPollingResult(mVerifyCounts);
-                }
-            }
-        }
-    }
-
-    public synchronized void retry(long id) {
-        int nTasks = mPollingTasks.size();
-        if (nTasks <= 0) {
-            return;
-        }
-
-        PollingTask task0 = null;
-        for (int i = 0; i < nTasks; i++) {
-            PollingTask task = mPollingTasks.get(i);
-            if (task.mId == id) {
-                task0 = task;
-                break;
-            }
-        }
-
-        if (task0 == null) {
-            logger.debug("Trigger wrong retry: " + id);
-            task0 = mPollingTasks.get(0);
-        }
-
-        task0.execute();
-    }
-}
-
diff --git a/rcs/presencepolling/src/com/android/service/ims/presence/PresenceBroadcastReceiver.java b/rcs/presencepolling/src/com/android/service/ims/presence/PresenceBroadcastReceiver.java
deleted file mode 100644
index 6d716bd..0000000
--- a/rcs/presencepolling/src/com/android/service/ims/presence/PresenceBroadcastReceiver.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
-
-package com.android.service.ims.presence;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-
-import com.android.ims.RcsPresence;
-
-import com.android.ims.internal.Logger;
-
-public class PresenceBroadcastReceiver extends BroadcastReceiver {
-    private Logger logger = Logger.getLogger(this.getClass().getName());
-
-    @Override
-    public void onReceive(Context context, Intent intent) {
-        logger.print("onReceive(), intent: " + intent +
-                ", context: " + context);
-
-        String action = intent.getAction();
-        if (RcsPresence.ACTION_PUBLISH_STATE_CHANGED.equals(action)) {
-            intent.setClass(context, PersistService.class);
-            context.startService(intent);
-        } else {
-            logger.debug("No interest in this intent: " + action);
-        }
-    }
-};
-
diff --git a/rcs/presencepolling/src/com/android/service/ims/presence/PresenceContact.java b/rcs/presencepolling/src/com/android/service/ims/presence/PresenceContact.java
deleted file mode 100644
index a9bd8a5..0000000
--- a/rcs/presencepolling/src/com/android/service/ims/presence/PresenceContact.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
-
-package com.android.service.ims.presence;
-
-public class PresenceContact {
-    public static final int VIDEO_CALLING_NOT_AVAILABLE = 0;
-    public static final int VIDEO_CALLING_AVAILABLE = 1;
-
-    String mDisplayName = null;
-    String mPhoneNumber = null;
-    String mRawContactId = null;
-    String mContactId = null;
-    String mDataId = null;
-    boolean mIsVolteCapable = false;
-    boolean mIsVtCapable = false;
-    int mVtStatus = VIDEO_CALLING_NOT_AVAILABLE;
-
-    String mVtUri = null;
-
-    public PresenceContact(String name, String number, String rawContactId,
-            String contactId, String dataId) {
-        mDisplayName = name;
-        mPhoneNumber = number;
-        mRawContactId = rawContactId;
-        mContactId = contactId;
-        mDataId = dataId;
-    }
-
-    public String getDisplayName() {
-        return mDisplayName;
-    }
-
-    public String getPhoneNumber() {
-        return mPhoneNumber;
-    }
-
-    public String getRawContactId() {
-        return mRawContactId;
-    }
-
-    public String getContactId() {
-        return mContactId;
-    }
-
-    public String getDataId() {
-        return mDataId;
-    }
-
-    public boolean isVolteCapable() {
-        return mIsVolteCapable;
-    }
-
-    public void setIsVolteCapable(boolean isVolteCapable) {
-        mIsVolteCapable = isVolteCapable;
-    }
-
-    public boolean isVtCapable() {
-        return mIsVtCapable;
-    }
-
-    public void setIsVtCapable(boolean isVtCapable) {
-        mIsVtCapable = isVtCapable;
-    }
-
-    public int getVtStatus() {
-        return mVtStatus;
-    }
-
-    public void setVtStatus(int vtAvailable) {
-        mVtStatus = vtAvailable;
-    }
-
-    public String getVtUri() {
-        return mVtUri;
-    }
-
-    public void setVtUri(String vtUri) {
-        mVtUri = vtUri;
-    }
-}
diff --git a/rcs/presencepolling/src/com/android/service/ims/presence/PresencePreferences.java b/rcs/presencepolling/src/com/android/service/ims/presence/PresencePreferences.java
deleted file mode 100644
index b777c5c..0000000
--- a/rcs/presencepolling/src/com/android/service/ims/presence/PresencePreferences.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
-
-package com.android.service.ims.presence;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.content.SharedPreferences.Editor;
-
-public class PresencePreferences {
-    private static final String PREFERENCES = "PresencePolling";
-    private static PresencePreferences sInstance;
-
-    private Context mContext = null;
-    private SharedPreferences mCommonPref = null;
-
-    private PresencePreferences() {
-    }
-
-    public void setContext(Context context) {
-        if (mContext == null) {
-            mContext = context;
-            mCommonPref = mContext.getSharedPreferences(PREFERENCES, Context.MODE_PRIVATE);
-        }
-    }
-
-    public static PresencePreferences getInstance(){
-        if (null == sInstance) {
-            sInstance = new PresencePreferences();
-        }
-        return sInstance;
-    }
-
-    private static final String CAPABILITY_DISCOVERY_TIME = "CapabilityDiscoveryTime";
-
-    public long lastCapabilityDiscoveryTime() {
-        if (mCommonPref == null) {
-            return 0;
-        }
-
-        return mCommonPref.getLong(CAPABILITY_DISCOVERY_TIME, 0);
-    }
-
-    public void updateCapabilityDiscoveryTime() {
-        if (mCommonPref == null) {
-            return;
-        }
-
-        Editor editor = mCommonPref.edit();
-        long time = System.currentTimeMillis();
-        editor.putLong(CAPABILITY_DISCOVERY_TIME, time);
-        editor.commit();
-    }
-
-    private static final String PHONE_SUBSCRIBER_ID = "PhoneSubscriberId";
-    public String getSubscriberId() {
-        if (mCommonPref == null) {
-            return null;
-        }
-
-        return mCommonPref.getString(PHONE_SUBSCRIBER_ID, null);
-    }
-
-    public void setSubscriberId(String id) {
-        if (mCommonPref == null) {
-            return;
-        }
-
-        Editor editor = mCommonPref.edit();
-        editor.putString(PHONE_SUBSCRIBER_ID, id);
-        editor.commit();
-    }
-
-    private static final String PHONE_LINE1_NUMBER = "PhoneLine1Number";
-    public String getLine1Number() {
-        if (mCommonPref == null) {
-            return null;
-        }
-
-        return mCommonPref.getString(PHONE_LINE1_NUMBER, null);
-    }
-
-    public void setLine1Number(String number) {
-        if (mCommonPref == null) {
-            return;
-        }
-
-        Editor editor = mCommonPref.edit();
-        editor.putString(PHONE_LINE1_NUMBER, number);
-        editor.commit();
-    }
-
-    private static final String RCS_TEST_MODE = "RcsTestMode";
-    public boolean getRcsTestMode() {
-        if (mCommonPref == null) {
-            return false;
-        }
-
-        return mCommonPref.getInt(RCS_TEST_MODE, 0) == 1;
-    }
-
-    public void setRcsTestMode(boolean test) {
-        if (mCommonPref == null) {
-            return;
-        }
-
-        Editor editor = mCommonPref.edit();
-        editor.putInt(RCS_TEST_MODE, test ? 1 : 0);
-        editor.commit();
-    }
-}
diff --git a/rcs/presencepolling/src/com/android/service/ims/presence/PresenceSetting.java b/rcs/presencepolling/src/com/android/service/ims/presence/PresenceSetting.java
deleted file mode 100644
index 9452237..0000000
--- a/rcs/presencepolling/src/com/android/service/ims/presence/PresenceSetting.java
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
-
-package com.android.service.ims.presence;
-
-import android.content.Context;
-
-import com.android.ims.ImsConfig;
-import com.android.ims.ImsException;
-import com.android.ims.ImsManager;
-
-import com.android.ims.internal.Logger;
-
-public class PresenceSetting {
-    private static Logger logger = Logger.getLogger("PresenceSetting");
-    private static Context sContext = null;
-
-    public static void init(Context context) {
-        sContext = context;
-    }
-
-    public static long getCapabilityPollInterval() {
-        long value = -1;
-        if (sContext != null) {
-            ImsManager imsManager = ImsManager.getInstance(sContext, 0);
-            if (imsManager != null) {
-                try {
-                    ImsConfig imsConfig = imsManager.getConfigInterface();
-                    if (imsConfig != null) {
-                        value = imsConfig.getProvisionedValue(
-                                ImsConfig.ConfigConstants.CAPABILITIES_POLL_INTERVAL);
-                        logger.debug("Read ImsConfig_CapabilityPollInterval: " + value);
-                    }
-                } catch (ImsException ex) {
-                }
-            }
-        }
-        if (value <= 0) {
-            value = 604800L;
-            logger.error("Failed to get CapabilityPollInterval, the default: " + value);
-        }
-        return value;
-    }
-
-    public static long getCapabilityCacheExpiration() {
-        long value = -1;
-        if (sContext != null) {
-            ImsManager imsManager = ImsManager.getInstance(sContext, 0);
-            if (imsManager != null) {
-                try {
-                    ImsConfig imsConfig = imsManager.getConfigInterface();
-                    if (imsConfig != null) {
-                        value = imsConfig.getProvisionedValue(
-                                ImsConfig.ConfigConstants.CAPABILITIES_CACHE_EXPIRATION);
-                        logger.debug("Read ImsConfig_CapabilityCacheExpiration: " + value);
-                    }
-                } catch (ImsException ex) {
-                }
-            }
-        }
-        if (value <= 0) {
-            value = 7776000L;
-            logger.error("Failed to get CapabilityCacheExpiration, the default: " + value);
-        }
-        return value;
-    }
-
-    public static int getPublishTimer() {
-        int value = -1;
-        if (sContext != null) {
-            ImsManager imsManager = ImsManager.getInstance(sContext, 0);
-            if (imsManager != null) {
-                try {
-                    ImsConfig imsConfig = imsManager.getConfigInterface();
-                    if (imsConfig != null) {
-                        value = imsConfig.getProvisionedValue(
-                                ImsConfig.ConfigConstants.PUBLISH_TIMER);
-                        logger.debug("Read ImsConfig_PublishTimer: " + value);
-                    }
-                } catch (ImsException ex) {
-                }
-            }
-        }
-        if (value <= 0) {
-            value = (int)1200;
-            logger.error("Failed to get PublishTimer, the default: " + value);
-        }
-        return value;
-    }
-
-    public static int getPublishTimerExtended() {
-        int value = -1;
-        if (sContext != null) {
-            ImsManager imsManager = ImsManager.getInstance(sContext, 0);
-            if (imsManager != null) {
-                try {
-                    ImsConfig imsConfig = imsManager.getConfigInterface();
-                    if (imsConfig != null) {
-                        value = imsConfig.getProvisionedValue(
-                                ImsConfig.ConfigConstants.PUBLISH_TIMER_EXTENDED);
-                        logger.debug("Read ImsConfig_PublishTimerExtended: " + value);
-                    }
-                } catch (ImsException ex) {
-                }
-            }
-        }
-        if (value <= 0) {
-            value = (int)86400;
-            logger.error("Failed to get PublishTimerExtended, the default: " + value);
-        }
-        return value;
-    }
-
-    public static int getMaxNumberOfEntriesInRequestContainedList() {
-        int value = -1;
-        if (sContext != null) {
-            ImsManager imsManager = ImsManager.getInstance(sContext, 0);
-            if (imsManager != null) {
-                try {
-                    ImsConfig imsConfig = imsManager.getConfigInterface();
-                    if (imsConfig != null) {
-                        value = imsConfig.getProvisionedValue(
-                                ImsConfig.ConfigConstants.MAX_NUMENTRIES_IN_RCL);
-                        logger.debug("Read ImsConfig_MaxNumEntriesInRCL: " + value);
-                    }
-                } catch (ImsException ex) {
-                }
-            }
-        }
-        if (value <= 0) {
-            value = (int)100;
-            logger.error("Failed to get MaxNumEntriesInRCL, the default: " + value);
-        }
-        return value;
-    }
-
-    public static int getCapabilityPollListSubscriptionExpiration() {
-        int value = -1;
-        if (sContext != null) {
-            ImsManager imsManager = ImsManager.getInstance(sContext, 0);
-            if (imsManager != null) {
-                try {
-                    ImsConfig imsConfig = imsManager.getConfigInterface();
-                    if (imsConfig != null) {
-                        value = imsConfig.getProvisionedValue(
-                                ImsConfig.ConfigConstants.CAPAB_POLL_LIST_SUB_EXP);
-                        logger.debug("Read ImsConfig_CapabPollListSubExp: " + value);
-                    }
-                } catch (ImsException ex) {
-                }
-            }
-        }
-        if (value <= 0) {
-            value = (int)30;
-            logger.error("Failed to get CapabPollListSubExp, the default: " + value);
-        }
-        return value;
-    }
-}
-
diff --git a/rcs/presencepolling/src/com/android/service/ims/presence/SharedPrefUtil.java b/rcs/presencepolling/src/com/android/service/ims/presence/SharedPrefUtil.java
deleted file mode 100644
index 9e9a31e..0000000
--- a/rcs/presencepolling/src/com/android/service/ims/presence/SharedPrefUtil.java
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
-
-package com.android.service.ims.presence;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-
-public class SharedPrefUtil {
-    public static final String EAB_SHARED_PREF = "com.android.vt.eab";
-    public static final String INIT_DONE = "init_done";
-    private static final String CONTACT_CHANGED_PREF_KEY = "timestamp_change";
-    private static final String CONTACT_DELETE_PREF_KEY = "timestamp_delete";
-    private static final String CONTACT_PROFILE_CHANGED_PREF_KEY = "profile_timestamp_change";
-    public static final String VIDEO_CALLING_GROUP_ID = "video_calling_group_id";
-    public static final String VIDEO_CALLING_WARN_SHOW = "video_calling_warning_alert_show";
-    public static final String VIDEO_CALL_OFF_WARN_SHOW = "video_call_off_alert_show";
-    public static final String MOBILE_DATA_ON_WARN_SHOW = "mobile_data_on_alert_show";
-    public static final String VOLTE_ON_WARN_SHOW = "volte_on_alert_show";
-    public static final String TTY_OFF_WARN_SHOW = "tty_off_alert_show";
-    public static final String VT_ON_WARN_SHOW = "vt_on_alert_show";
-
-    public static boolean isInitDone(Context context) {
-        SharedPreferences eabPref = context.getSharedPreferences(
-                EAB_SHARED_PREF, Context.MODE_PRIVATE);
-        return eabPref.getBoolean(INIT_DONE, false);
-    }
-
-    public static void setInitDone(Context context, boolean initDone){
-        SharedPreferences.Editor eabPref = context.getSharedPreferences(
-                EAB_SHARED_PREF, Context.MODE_PRIVATE).edit();
-        eabPref.putBoolean(INIT_DONE, initDone).commit();
-    }
-
-    public static long getLastContactChangedTimestamp(Context context, long time) {
-        SharedPreferences pref = context.getSharedPreferences(EAB_SHARED_PREF,
-                Context.MODE_PRIVATE);
-        return pref.getLong(CONTACT_CHANGED_PREF_KEY, time);
-    }
-
-    public static void saveLastContactChangedTimestamp(Context context, long time) {
-        SharedPreferences.Editor eabPref = context.getSharedPreferences(
-                EAB_SHARED_PREF, Context.MODE_PRIVATE).edit();
-        eabPref.putLong(CONTACT_CHANGED_PREF_KEY, time).commit();
-    }
-
-    public static long getLastProfileContactChangedTimestamp(Context context, long time) {
-        SharedPreferences pref = context.getSharedPreferences(EAB_SHARED_PREF,
-                Context.MODE_PRIVATE);
-        return pref.getLong(CONTACT_PROFILE_CHANGED_PREF_KEY, time);
-    }
-
-    public static void saveLastProfileContactChangedTimestamp(Context context, long time) {
-        SharedPreferences.Editor eabPref = context.getSharedPreferences(
-                EAB_SHARED_PREF, Context.MODE_PRIVATE).edit();
-        eabPref.putLong(CONTACT_PROFILE_CHANGED_PREF_KEY, time).commit();
-    }
-
-    public static long getLastContactDeletedTimestamp(Context context, long time) {
-        SharedPreferences pref = context.getSharedPreferences(EAB_SHARED_PREF,
-                Context.MODE_PRIVATE);
-        return pref.getLong(CONTACT_DELETE_PREF_KEY, time);
-    }
-
-    public static void saveLastContactDeletedTimestamp(Context context, long time) {
-        SharedPreferences.Editor eabPref = context.getSharedPreferences(
-                EAB_SHARED_PREF, Context.MODE_PRIVATE).edit();
-        eabPref.putLong(CONTACT_DELETE_PREF_KEY, time).commit();
-    }
-
-    public static void setVideoCallingGroupId(Context context,
-            long videoCallingGroupId) {
-        SharedPreferences.Editor eabPref = context.getSharedPreferences(
-                EAB_SHARED_PREF, Context.MODE_PRIVATE).edit();
-        eabPref.putLong(VIDEO_CALLING_GROUP_ID, videoCallingGroupId).commit();
-    }
-
-    public static long getVideoCallingGroupId(Context context){
-        SharedPreferences eabPref = context.getSharedPreferences(
-                EAB_SHARED_PREF, Context.MODE_PRIVATE);
-        return eabPref.getLong(VIDEO_CALLING_GROUP_ID, 0L);
-    }
-
-    public static void setVideoCallingWarnDisable(Context context,
-            boolean enable) {
-        SharedPreferences.Editor eabPref = context.getSharedPreferences(
-                EAB_SHARED_PREF, Context.MODE_PRIVATE).edit();
-        eabPref.putBoolean(VIDEO_CALLING_WARN_SHOW, enable).apply();
-    }
-
-    public static boolean isVideoCallingWarnDisabled(Context context){
-        SharedPreferences eabPref = context.getSharedPreferences(
-                EAB_SHARED_PREF, Context.MODE_PRIVATE);
-        return eabPref.getBoolean(VIDEO_CALLING_WARN_SHOW, false);
-    }
-
-    public static void setVideoCallOffWarnDisable(Context context, boolean enable){
-        SharedPreferences.Editor eabPref = context.getSharedPreferences(EAB_SHARED_PREF,
-                Context.MODE_PRIVATE).edit();
-        eabPref.putBoolean(VIDEO_CALL_OFF_WARN_SHOW, enable).apply();
-    }
-
-    public static boolean isVideoCallOffWarnDisabled(Context context){
-        SharedPreferences eabPref = context.getSharedPreferences(EAB_SHARED_PREF,
-                Context.MODE_PRIVATE);
-        return eabPref.getBoolean(VIDEO_CALL_OFF_WARN_SHOW, false);
-    }
-
-    public static void setMobileDataOnWarnDisable(Context context, boolean enable){
-        SharedPreferences.Editor eabPref = context.getSharedPreferences(EAB_SHARED_PREF,
-                Context.MODE_PRIVATE).edit();
-        eabPref.putBoolean(MOBILE_DATA_ON_WARN_SHOW, enable).apply();
-    }
-
-    public static boolean isMobileDataOnWarnDisabled(Context context){
-        SharedPreferences eabPref = context.getSharedPreferences(EAB_SHARED_PREF,
-                Context.MODE_PRIVATE);
-        return eabPref.getBoolean(MOBILE_DATA_ON_WARN_SHOW, false);
-    }
-
-    public static void setVolteOnWarnDisable(Context context, boolean enable){
-        SharedPreferences.Editor eabPref = context.getSharedPreferences(EAB_SHARED_PREF,
-                Context.MODE_PRIVATE).edit();
-        eabPref.putBoolean(VOLTE_ON_WARN_SHOW, enable).apply();
-    }
-
-    public static boolean isVolteOnWarnDisabled(Context context){
-        SharedPreferences eabPref = context.getSharedPreferences(EAB_SHARED_PREF,
-                Context.MODE_PRIVATE);
-        return eabPref.getBoolean(VOLTE_ON_WARN_SHOW, false);
-    }
-
-    public static void setTtyOffWarnDisable(Context context, boolean enable){
-        SharedPreferences.Editor eabPref = context.getSharedPreferences(EAB_SHARED_PREF,
-                Context.MODE_PRIVATE).edit();
-        eabPref.putBoolean(TTY_OFF_WARN_SHOW, enable).apply();
-    }
-
-    public static boolean isTtyOffWarnDisabled(Context context){
-        SharedPreferences eabPref = context.getSharedPreferences(EAB_SHARED_PREF,
-                Context.MODE_PRIVATE);
-        return eabPref.getBoolean(TTY_OFF_WARN_SHOW, false);
-    }
-
-    public static void setVTOnWarnDisable(Context context, boolean enable){
-        SharedPreferences.Editor eabPref = context.getSharedPreferences(EAB_SHARED_PREF,
-                Context.MODE_PRIVATE).edit();
-        eabPref.putBoolean(VT_ON_WARN_SHOW, enable).apply();
-    }
-
-    public static boolean isVTOnWarnDisabled(Context context){
-        SharedPreferences eabPref = context.getSharedPreferences(EAB_SHARED_PREF,
-                Context.MODE_PRIVATE);
-        return eabPref.getBoolean(VT_ON_WARN_SHOW, false);
-    }
-
-    public static void resetEABSharedPref(Context context) {
-        SharedPreferences.Editor eabPref = context.getSharedPreferences(
-                EAB_SHARED_PREF, Context.MODE_PRIVATE).edit();
-        eabPref.putBoolean(INIT_DONE, false);
-        eabPref.putLong(CONTACT_CHANGED_PREF_KEY, 0);
-        eabPref.putLong(CONTACT_DELETE_PREF_KEY, 0);
-        eabPref.putLong(CONTACT_PROFILE_CHANGED_PREF_KEY, 0);
-        eabPref.putBoolean(VIDEO_CALLING_WARN_SHOW, false);
-        eabPref.putBoolean(VIDEO_CALL_OFF_WARN_SHOW, false);
-        eabPref.putBoolean(MOBILE_DATA_ON_WARN_SHOW, false);
-        eabPref.putBoolean(VOLTE_ON_WARN_SHOW, false);
-        eabPref.putBoolean(TTY_OFF_WARN_SHOW, false);
-        eabPref.putBoolean(VT_ON_WARN_SHOW, false);
-        eabPref.commit();
-    }
-}
diff --git a/rcs/rcsmanager/Android.mk b/rcs/rcsmanager/Android.mk
deleted file mode 100644
index 93452c5..0000000
--- a/rcs/rcsmanager/Android.mk
+++ /dev/null
@@ -1,54 +0,0 @@
- # Copyright (c) 2015, Motorola Mobility LLC
- # All rights reserved.
- #
- # Redistribution and use in source and binary forms, with or without
- # modification, are permitted provided that the following conditions are met:
- #     - Redistributions of source code must retain the above copyright
- #       notice, this list of conditions and the following disclaimer.
- #     - Redistributions in binary form must reproduce the above copyright
- #       notice, this list of conditions and the following disclaimer in the
- #       documentation and/or other materials provided with the distribution.
- #     - Neither the name of Motorola Mobility nor the
- #       names of its contributors may be used to endorse or promote products
- #       derived from this software without specific prior written permission.
- #
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- # DAMAGE.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_AIDL_INCLUDES := $(LOCAL_PATH)/src/java
-LOCAL_SRC_FILES := \
-    $(call all-java-files-under, src/java)
-LOCAL_SRC_FILES += src/java/com/android/ims/internal/IRcsService.aidl \
-        src/java/com/android/ims/internal/IRcsPresence.aidl \
-        src/java/com/android/ims/IRcsPresenceListener.aidl
-
-LOCAL_JAVA_LIBRARIES += ims-common
-
-#LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE := com.android.ims.rcsmanager
-LOCAL_REQUIRED_MODULES := com.android.ims.rcsmanager.xml
-include $(BUILD_JAVA_LIBRARY)
-
-# We need to put the permissions XML file into /system/etc/permissions/ so the
-# JAR can be dynamically loaded.
-include $(CLEAR_VARS)
-LOCAL_MODULE := com.android.ims.rcsmanager.xml
-#LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/permissions
-LOCAL_SRC_FILES := $(LOCAL_MODULE)
-include $(BUILD_PREBUILT)
-
-
diff --git a/rcs/rcsmanager/AndroidManifest.xml b/rcs/rcsmanager/AndroidManifest.xml
deleted file mode 100644
index 630c170..0000000
--- a/rcs/rcsmanager/AndroidManifest.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.ims.rcsmanager"
-    android:versionCode="1"
-    android:versionName="1.0" >
-
-    <uses-sdk android:minSdkVersion="18" />
-
-</manifest>
diff --git a/rcs/rcsmanager/CleanSpec.mk b/rcs/rcsmanager/CleanSpec.mk
deleted file mode 100644
index c104bc4..0000000
--- a/rcs/rcsmanager/CleanSpec.mk
+++ /dev/null
@@ -1,60 +0,0 @@
-<!--
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
--->
-
-# If you don't need to do a full clean build but would like to touch
-# a file or delete some intermediate files, add a clean step to the end
-# of the list.  These steps will only be run once, if they haven't been
-# run before.
-#
-# E.g.:
-#     $(call add-clean-step, touch -c external/sqlite/sqlite3.h)
-#     $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libz_intermediates)
-#
-# Always use "touch -c" and "rm -f" or "rm -rf" to gracefully deal with
-# files that are missing or have been moved.
-#
-# Use $(PRODUCT_OUT) to get to the "out/target/product/blah/" directory.
-# Use $(OUT_DIR) to refer to the "out" directory.
-#
-# If you need to re-do something that's already mentioned, just copy
-# the command and add it to the bottom of the list.  E.g., if a change
-# that you made last week required touching a file and a change you
-# made today requires touching the same file, just copy the old
-# touch step and add it to the end of the list.
-#
-# ************************************************
-# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
-# ************************************************
-
-$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/com.android.ims.rcsmanager_intermediates)
-$(call add-clean-step, rm -rf $(OUT_DIR)/target/product/*/obj/JAVA_LIBRARIES/com.android.ims.rcsmanager_intermediates)
-$(call add-clean-step, rm -rf $(OUT_DIR)/target/product/*/obj/ETC/com.android.ims.rcsmanager.xml_intermediates)
-
-# ************************************************
-# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
-# ************************************************
diff --git a/rcs/rcsmanager/com.android.ims.rcsmanager.xml b/rcs/rcsmanager/com.android.ims.rcsmanager.xml
deleted file mode 100644
index 0737f5d..0000000
--- a/rcs/rcsmanager/com.android.ims.rcsmanager.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
--->
-
-<permissions>
-    <library name="com.android.ims.rcsmanager"
-            file="/system/framework/com.android.ims.rcsmanager.jar"/>
-</permissions>
diff --git a/rcs/rcsmanager/src/java/com/android/ims/IRcsPresenceListener.aidl b/rcs/rcsmanager/src/java/com/android/ims/IRcsPresenceListener.aidl
deleted file mode 100644
index fbffe73..0000000
--- a/rcs/rcsmanager/src/java/com/android/ims/IRcsPresenceListener.aidl
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
-
-package com.android.ims;
-
-/**
- * RcsPresenceListener is used by requestCapability and requestAvailability to return the
- * status. The reqId which returned by requestCapability and requestAvailability can be
- * used to match the result with request when share the implementation of IRcsPresenceListener.
- *
- * There are following normal cases:
- *   1> The presence service got terminated notify after submitted the SUBSCRIBE request.
- *       onSuccess() ---> onFinish()
- *   2> The presence service submitted the request to network and got "200 OK" for SIP response.
- *   but it didn't get "terminated notify" in expries + T1 timer.
- *       onSuccess() ---> onTimeout()
- *   3> The presence service got error from SIP response for SUBSCRIBE request.
- *       onError()
- *
- * @hide
- */
-interface IRcsPresenceListener {
-    /**
-     * It is called when it gets "200 OK" from network for SIP request or
-     * it gets "404 xxxx" for SIP request of single contact number (means not capable).
-     *
-     * @param reqId the request ID which returned by requestCapability or
-     * requestAvailability
-     *
-     * @see RcsPresence#requestCapability
-     * @see RcsPresence#requestAvailability
-     */
-    void onSuccess(in int reqId);
-
-    /**
-     * It is called when it gets local error or gets SIP error from network.
-     *
-     * @param reqId the request ID which returned by requestCapability or
-     * requestAvailability
-     * @param resultCode the result code which defined in RcsManager.ResultCode.
-     *
-     * @see RcsPresence#requestCapability
-     * @see RcsPresence#requestAvailability
-     * @see RcsManager.ResultCode
-     */
-    void onError(in int reqId, in int resultCode);
-
-    /**
-     * It is called when it gets the "terminated notify" from network.
-     * The presence service will not receive notify for the request any more after it got
-     * "terminated notify" from network. So onFinish means the requestCapability or
-     * requestAvailability had been finished completely.
-     *
-     * @param reqId the request ID which returned by requestCapability or
-     * requestAvailability
-     *
-     * @see RcsPresence#requestCapability
-     * @see RcsPresence#requestAvailability
-     */
-    void onFinish(in int reqId);
-
-    /**
-     * It is called when it is timeout to wait for the "terminated notify" from network.
-     *
-     * @param reqId the request ID which returned by requestCapability or
-     * requestAvailability
-     *
-     * @see RcsPresence#requestCapability
-     * @see RcsPresence#requestAvailability
-     */
-    void onTimeout(in int reqId);
-}
diff --git a/rcs/rcsmanager/src/java/com/android/ims/RcsException.java b/rcs/rcsmanager/src/java/com/android/ims/RcsException.java
deleted file mode 100644
index 0d5f36e..0000000
--- a/rcs/rcsmanager/src/java/com/android/ims/RcsException.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
-
-package com.android.ims;
-
-/**
- * This class defines a general RCS-related exception.
- *
- * @hide
- */
-public class RcsException extends Exception {
-
-    /**
-     * Refer to {@link RcsManager.ResultCode}
-     */
-    private int mCode;
-
-    public RcsException() {
-    }
-
-    public RcsException(String message, int code) {
-        super(message);
-        mCode = code;
-    }
-
-    public RcsException(String message, Throwable cause, int code) {
-        super(message, cause);
-        mCode = code;
-    }
-
-    /**
-     * Gets the detailed exception code when RcsException is throwed
-     *
-     * @return the exception code in {@link RcsManager.ResultCode}
-     */
-    public int getCode() {
-        return mCode;
-    }
-}
diff --git a/rcs/rcsmanager/src/java/com/android/ims/RcsManager.java b/rcs/rcsmanager/src/java/com/android/ims/RcsManager.java
deleted file mode 100644
index 644d567..0000000
--- a/rcs/rcsmanager/src/java/com/android/ims/RcsManager.java
+++ /dev/null
@@ -1,384 +0,0 @@
-/*
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
-
-package com.android.ims;
-
-import android.content.Context;
-import android.content.Intent;
-import android.os.IBinder;
-import android.os.IBinder.DeathRecipient;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.telephony.Rlog;
-
-import com.android.ims.internal.IRcsService;
-import com.android.ims.internal.IRcsPresence;
-
-import java.util.HashMap;
-
-/**
- * Provides APIs for Rcs services, currently it supports presence only.
- * This class is the starting point for any RCS actions.
- * You can acquire an instance of it with {@link #getInstance getInstance()}.
- *
- * @hide
- */
-public class RcsManager {
-    /**
-     * For accessing the RCS related service.
-     * Internal use only.
-     *
-     * @hide
-     */
-    private static final String RCS_SERVICE = "rcs";
-
-    /**
-     * Part of the ACTION_RCS_SERVICE_AVAILABLE and ACTION_RCS_SERVICE_UNAVAILABLE intents.
-     * A long value; the subId corresponding to the RCS service. For MSIM implementation.
-     *
-     * @see #ACTION_RCS_SERVICE_AVAILABLE
-     * @see #ACTION_RCS_SERVICE_UNAVAILABLE
-     */
-    public static final String EXTRA_SUBID = "android:subid";
-
-    /**
-     * Action to broadcast when RcsService is available.
-     *
-     * @see #EXTRA_SUBID
-     */
-    public static final String ACTION_RCS_SERVICE_AVAILABLE =
-            "com.android.ims.ACTION_RCS_SERVICE_AVAILABLE";
-
-    /**
-     * Action to broadcast when RcsService is unavailable (such as ims is not registered).
-     *
-     * @see #EXTRA_SUBID
-     */
-    public static final String ACTION_RCS_SERVICE_UNAVAILABLE =
-            "com.android.ims.ACTION_RCS_SERVICE_UNAVAILABLE";
-
-    /**
-     * Action to broadcast when RcsService is died.
-     * The caller can listen to the intent to clean the pending request.
-     *
-     * It takes the extra parameter subid as well since it depends on OEM implementation for
-     * RcsService. It will not send broadcast for ACTION_RCS_SERVICE_UNAVAILABLE under the case.
-     *
-     * @see #EXTRA_SUBID
-     */
-    public static final String ACTION_RCS_SERVICE_DIED =
-            "com.android.ims.ACTION_RCS_SERVICE_DIED";
-
-    public static class ResultCode {
-        /**
-         * The code is used when the request is success.
-         */
-        public static final int SUCCESS =0;
-
-        /**
-         * Return this code if the service doesn't be enabled on the phone.
-         * As per the requirement the feature can be enabled/disabled by DM.
-         */
-        public static final int ERROR_SERVICE_NOT_ENABLED = -1;
-
-        /**
-         * Return this code if the service didn't publish yet.
-         */
-        public static final int ERROR_SERVICE_NOT_PUBLISHED = -2;
-
-        /**
-         * The service is not available, for example it is 1x only
-         */
-        public static final int ERROR_SERVICE_NOT_AVAILABLE = -3;
-
-        /**
-         *  SUBSCRIBE Error base
-         */
-        public static final int SUBSCRIBER_ERROR_CODE_START = ERROR_SERVICE_NOT_AVAILABLE;
-
-        /**
-         * Temporary error and need retry later.
-         * such as:
-         * 503 Service Unavailable
-         * Device shall retry with exponential back-off
-         *
-         * 408 Request Timeout
-         * Device shall retry with exponential back-off
-         *
-         * 423 Interval Too Short. Requested expiry interval too short and server rejects it
-         * Device shall re-attempt subscription after changing the expiration interval in
-         * the Expires header field to be equal to or greater than the expiration interval
-         * within the Min-Expires header field of the 423 response
-         */
-        public static final int SUBSCRIBE_TEMPORARY_ERROR = SUBSCRIBER_ERROR_CODE_START - 1;
-
-        /**
-         * receives 403 (reason="User Not Registered").
-         * Re-Register to IMS then retry the single resource subscription if capability polling.
-         * availability fetch: no retry.
-         */
-         public static final int SUBSCRIBE_NOT_REGISTERED = SUBSCRIBER_ERROR_CODE_START - 2;
-
-        /**
-         * Responding for 403 - not authorized (Requestor)
-         * No retry.
-         */
-        public static final int SUBSCRIBE_NOT_AUTHORIZED_FOR_PRESENCE =
-                SUBSCRIBER_ERROR_CODE_START - 3;
-
-        /**
-         * Responding for "403 Forbidden" or "403"
-         * Handle it as same as 404 Not found.
-         * No retry.
-         */
-        public static final int SUBSCRIBE_FORBIDDEN = SUBSCRIBER_ERROR_CODE_START - 4;
-
-        /**
-         * Responding for 404 (target number)
-         * No retry.
-         */
-        public static final int SUBSCRIBE_NOT_FOUND = SUBSCRIBER_ERROR_CODE_START - 5;
-
-        /**
-         *  Responding for 413 - Too Large. Top app need shrink the size
-         *  of request contact list and resend the request
-         */
-        public static final int SUBSCRIBE_TOO_LARGE = SUBSCRIBER_ERROR_CODE_START - 6;
-
-        /**
-         * All subscribe errors not covered by specific errors
-         * Other 4xx/5xx/6xx
-         *
-         * Device shall not retry
-         */
-        public static final int SUBSCRIBE_GENIRIC_FAILURE = SUBSCRIBER_ERROR_CODE_START - 7;
-
-        /**
-         * Invalid parameter - The caller should check the parameter.
-         */
-        public static final int SUBSCRIBE_INVALID_PARAM = SUBSCRIBER_ERROR_CODE_START - 8;
-
-        /**
-         * Fetch error - The RCS statck failed to fetch the presence information.
-         */
-        public static final int SUBSCRIBE_FETCH_ERROR = SUBSCRIBER_ERROR_CODE_START - 9;
-
-        /**
-         * Request timeout - The RCS statck returns timeout error.
-         */
-        public static final int SUBSCRIBE_REQUEST_TIMEOUT = SUBSCRIBER_ERROR_CODE_START - 10;
-
-        /**
-         * Insufficient memory - The RCS statck returns the insufficient memory error.
-         */
-        public static final int SUBSCRIBE_INSUFFICIENT_MEMORY = SUBSCRIBER_ERROR_CODE_START - 11;
-
-        /**
-         * Lost network error - The RCS statck returns the lost network error.
-         */
-        public static final int SUBSCRIBE_LOST_NETWORK = SUBSCRIBER_ERROR_CODE_START - 12;
-
-        /**
-         * Not supported error - The RCS statck returns the not supported error.
-         */
-        public static final int SUBSCRIBE_NOT_SUPPORTED = SUBSCRIBER_ERROR_CODE_START - 13;
-
-        /**
-         * Generic error - RCS Presence stack returns generic error
-         */
-        public static final int SUBSCRIBE_GENERIC = SUBSCRIBER_ERROR_CODE_START - 14;
-
-        /**
-         * There is a request for the same number in queue.
-         */
-        public static final int SUBSCRIBE_ALREADY_IN_QUEUE = SUBSCRIBER_ERROR_CODE_START - 16;
-
-        /**
-         * Request too frequently.
-         */
-        public static final int SUBSCRIBE_TOO_FREQUENTLY = SUBSCRIBER_ERROR_CODE_START - 17;
-
-        /**
-         *  The last Subscriber error code
-         */
-        public static final int SUBSCRIBER_ERROR_CODE_END = SUBSCRIBER_ERROR_CODE_START - 17;
-    };
-
-    private static final String TAG = "RcsManager";
-    private static final boolean DBG = true;
-
-    private static HashMap<Integer, RcsManager> sRcsManagerInstances =
-            new HashMap<Integer, RcsManager>();
-
-    private Context mContext;
-    private int mSubId;
-    private IRcsService mRcsService = null;
-    private RcsServiceDeathRecipient mDeathRecipient = new RcsServiceDeathRecipient();
-
-    // Interface for presence
-    // TODO: Could add other RCS service such RcsChat, RcsFt later.
-    private RcsPresence  mRcsPresence = null;
-
-    /**
-     * Gets a manager instance.
-     *
-     * @param context application context for creating the manager object
-     * @param subId the subscription ID for the RCS Service
-     * @return the manager instance corresponding to the subId
-     */
-    public static RcsManager getInstance(Context context, int subId) {
-        synchronized (sRcsManagerInstances) {
-            if (sRcsManagerInstances.containsKey(subId)){
-                return sRcsManagerInstances.get(subId);
-            }
-
-            RcsManager mgr = new RcsManager(context, subId);
-            sRcsManagerInstances.put(subId, mgr);
-
-            return mgr;
-        }
-    }
-
-    private RcsManager(Context context, int subId) {
-        mContext = context;
-        mSubId = subId;
-        createRcsService(true);
-    }
-
-    /**
-     * return true if the rcs service is ready for use.
-     */
-    public boolean isRcsServiceAvailable() {
-        if (DBG) Rlog.d(TAG, "call isRcsServiceAvailable ...");
-
-        boolean ret = false;
-
-        try {
-            checkAndThrowExceptionIfServiceUnavailable();
-
-            ret = mRcsService.isRcsServiceAvailable();
-        }  catch (RemoteException e) {
-            // return false under the case.
-            Rlog.e(TAG, "isRcsServiceAvailable RemoteException", e);
-        }catch (RcsException e){
-            // return false under the case.
-            Rlog.e(TAG, "isRcsServiceAvailable RcsException", e);
-        }
-
-        if (DBG) Rlog.d(TAG, "isRcsServiceAvailable ret =" + ret);
-        return ret;
-    }
-
-    /**
-     * Gets the presence interface
-     *
-     * @return the RcsPresence instance.
-     * @throws  if getting the RcsPresence interface results in an error.
-     */
-    public RcsPresence getRcsPresenceInterface() throws RcsException {
-
-        if (mRcsPresence == null) {
-            checkAndThrowExceptionIfServiceUnavailable();
-
-            try {
-                IRcsPresence rcsPresence = mRcsService.getRcsPresenceInterface();
-                if (rcsPresence == null) {
-                    throw new RcsException("getRcsPresenceInterface()",
-                            ResultCode.ERROR_SERVICE_NOT_AVAILABLE);
-                }
-                mRcsPresence = new RcsPresence(rcsPresence);
-            } catch (RemoteException e) {
-                throw new RcsException("getRcsPresenceInterface()", e,
-                        ResultCode.ERROR_SERVICE_NOT_AVAILABLE);
-            }
-        }
-        if (DBG) Rlog.d(TAG, "getRcsPresenceInterface(), mRcsPresence= " + mRcsPresence);
-        return mRcsPresence;
-    }
-
-    /**
-     * Binds the RCS service only if the service is not created.
-     */
-    private void checkAndThrowExceptionIfServiceUnavailable()
-            throws  RcsException {
-        if (mRcsService == null) {
-            createRcsService(true);
-
-            if (mRcsService == null) {
-                throw new RcsException("Service is unavailable",
-                        ResultCode.ERROR_SERVICE_NOT_AVAILABLE);
-            }
-        }
-    }
-
-    private static String getRcsServiceName(int subId) {
-        // use the same mechanism as IMS_SERVICE?
-        return RCS_SERVICE;
-    }
-
-    /**
-     * Binds the RCS service.
-     */
-    private void createRcsService(boolean checkService) {
-        if (checkService) {
-            IBinder binder = ServiceManager.checkService(getRcsServiceName(mSubId));
-
-            if (binder == null) {
-                return;
-            }
-        }
-
-        IBinder b = ServiceManager.getService(getRcsServiceName(mSubId));
-
-        if (b != null) {
-            try {
-                b.linkToDeath(mDeathRecipient, 0);
-            } catch (RemoteException e) {
-            }
-        }
-
-        mRcsService = IRcsService.Stub.asInterface(b);
-    }
-
-    /**
-     * Death recipient class for monitoring RCS service.
-     */
-    private class RcsServiceDeathRecipient implements IBinder.DeathRecipient {
-        @Override
-        public void binderDied() {
-            mRcsService = null;
-            mRcsPresence = null;
-
-            if (mContext != null) {
-                Intent intent = new Intent(ACTION_RCS_SERVICE_DIED);
-                intent.putExtra(EXTRA_SUBID, mSubId);
-                mContext.sendBroadcast(new Intent(intent));
-            }
-        }
-    }
-}
diff --git a/rcs/rcsmanager/src/java/com/android/ims/RcsPresence.java b/rcs/rcsmanager/src/java/com/android/ims/RcsPresence.java
deleted file mode 100644
index c52e7e9..0000000
--- a/rcs/rcsmanager/src/java/com/android/ims/RcsPresence.java
+++ /dev/null
@@ -1,305 +0,0 @@
-/*
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
-
-package com.android.ims;
-
-import java.util.List;
-import java.util.ArrayList;
-import android.content.Intent;
-import android.os.RemoteException;
-import android.util.Log;
-
-import com.android.ims.internal.IRcsPresence;
-import com.android.ims.RcsManager.ResultCode;
-
-/**
- *
- * @hide
- */
-public class RcsPresence {
-    static final String TAG = "RcsPresence";
-    private boolean DBG = true;
-    private IRcsPresence mIRcsPresence = null;
-
-    /**
-     * Key to retrieve the RcsPresenceInfo list from intent ACTION_PRESENCE_CHANGED
-     * The RcsPresenceInfo list can be got by the following function call:
-     * ArrayList<RcsPresenceInfo> rcsPresenceInfoList = intent.getParcelableArrayListExtra(
-     *           RcsPresence.EXTRA_PRESENCE_INFO_LIST);
-     *
-     * @see RcsPresenceInfo
-     */
-    public static final String EXTRA_PRESENCE_INFO_LIST = "presence_info_list";
-
-    /**
-     * Key to retrieve the subscription ID. This is for muliti-SIM implementation.
-     */
-    public static final String EXTRA_SUBID = "android:subid";
-
-    /**
-     * The intent will be broadcasted when the presence changed.
-     * It happens on the following cases:
-     *   1. When the phone gets a NOTIFY from network.
-     *   2. When the phone gets some SUBSCRIBE error from network for some case (such as 404).
-     * It takes two extra parameters:
-     *   1. EXTRA_PRESENCE_INFO_LIST
-     *     need to get it by the following statement:
-     *     ArrayList<RcsPresenceInfo> rcsPresenceInfoList = intent.getParcelableArrayListExtra(
-     *             RcsPresence.EXTRA_PRESENCE_INFO_LIST);
-     *   2. EXTRA_SUBID
-     *
-     * @see RcsPresenceInfO
-     * @see EXTRA_PRESENCE_INFO_LIST
-     * @see EXTRA_SUBID
-     */
-    public static final String ACTION_PRESENCE_CHANGED = "com.android.ims.ACTION_PRESENCE_CHANGED";
-
-    /**
-     * Key to retrieve "publish_state" for
-     * intent ACTION_PUBLISH_STATE_CHANGED.
-     *
-     * @See PublishState.
-     * @see ACTION_PUBLISH_STATE_CHANGED
-     */
-    public static final String EXTRA_PUBLISH_STATE = "publish_state";
-
-    /**
-     * The intent will be broadcasted when latest publish status changed
-     * It takes two extra parameters:
-     * 1. EXTRA_PUBLISH_STATE
-     * 2. EXTRA_SUBID
-     *
-     * @see #EXTRA_PUBLISH_STATE
-     * @see #EXTRA_SUBID
-     * @see PublishState
-     */
-    public static final String ACTION_PUBLISH_STATE_CHANGED =
-            "com.android.ims.ACTION_PUBLISH_STATUS_CHANGED";
-
-    /**
-     *  The last publish state
-     */
-    public static class PublishState {
-        /**
-         * The phone is PUBLISH_STATE_200_OK when
-         * the response of the last publish is "200 OK"
-         */
-        public static final int PUBLISH_STATE_200_OK = 0;
-
-        /**
-         * The phone didn't publish after power on.
-         * the phone didn't get any publish response yet.
-         */
-        public static final int PUBLISH_STATE_NOT_PUBLISHED = 1;
-
-        /**
-         * The phone is PUBLISH_STATE_VOLTE_PROVISION_ERROR when the response is one of items
-          * in config_volte_provision_error_on_publish_response for PUBLISH or
-          * in config_volte_provision_error_on_subscribe_response for SUBSCRIBE.
-         */
-        public static final int PUBLISH_STATE_VOLTE_PROVISION_ERROR = 2;
-
-        /**
-         * The phone is PUBLISH_STATE_RCS_PROVISION_ERROR when the response is one of items
-          * in config_rcs_provision_error_on_publish_response for PUBLISH or
-          * in config_rcs_provision_error_on_subscribe_response for SUBSCRIBE.
-         */
-        public static final int PUBLISH_STATE_RCS_PROVISION_ERROR = 3;
-
-        /**
-         * The phone is PUBLISH_STATE_REQUEST_TIMEOUT when
-         * The response of the last publish is "408 Request Timeout".
-         */
-        public static final int PUBLISH_STATE_REQUEST_TIMEOUT = 4;
-
-        /**
-         * The phone is PUBLISH_STATE_OTHER_ERROR when
-         * the response of the last publish is other temp error. Such as
-         * 503 Service Unavailable
-         * Device shall retry with exponential back-off
-         *
-         * 423 Interval Too Short. Requested expiry interval too short and server rejects it
-         * Device shall re-attempt subscription after changing the expiration interval in
-         * the Expires header field to be equal to or greater than the expiration interval
-         * within the Min-Expires header field of the 423 response
-         *
-         * ...
-         */
-        public static final int PUBLISH_STATE_OTHER_ERROR = 5;
-    };
-
-    /**
-     * Constructor.
-     * @param presenceService the IRcsPresence which get by RcsManager.getRcsPresenceInterface.
-     *
-     * @see RcsManager#getRcsPresenceInterface
-     */
-    public RcsPresence(IRcsPresence presenceService) {
-        if (DBG) Log.d(TAG, "IRcsPresence creates");
-
-        mIRcsPresence = presenceService;
-    }
-
-    /**
-     * Send the request to the server to get the capability.
-     *   1. If the presence service sent the request to network successfully
-     * then it will return the request ID (>0). It will not wait for the response from
-     * network. The response from network will be returned by callback onSuccess() or onError().
-     *   2. If the presence service failed to send the request to network then it will return error
-     *  code which is defined by RcsManager.ResultCode (<0).
-     *   3. If the network returns "200 OK" for a request then the listener.onSuccess() will be
-     * called by presence service.
-     *   4. If the network resturns "404" for a single target number then it means the target
-     * number is not VoLte capable, so the listener.onSuccess() will be called and intent
-     * ACTION_PRESENCE_CHANGED will be broadcasted by presence service.
-     *   5. If the network returns other error then the listener.onError() will be called by
-     * presence service.
-     *   6. If the network returns "200 OK" then we can expect the presence service receives notify
-     * from network. If the presence service receives notify then it will broadcast the
-     * intent ACTION_PRESENCE_CHANGED. If the notify state is "terminated" then the
-     * listener.onFinish() will be called by presence service as well.
-     *   7. If the presence service doesn't get response after "Subscribe Expiration + T1" then the
-     * listener.onTimeout() will be called by presence service.
-     *
-     * @param contactsNumber the contact number list which will be requested.
-     * @param listener the IRcsPresenceListener which will return the status and response.
-     *
-     * @return the request ID if it is >0. Or it is RcsManager.ResultCode for error.
-     *
-     * @see IRcsPresenceListener
-     * @see RcsManager.ResultCode
-     */
-    public int requestCapability(List<String> contactsNumber,
-            IRcsPresenceListener listener) throws RcsException {
-        if (DBG) Log.d(TAG, "call requestCapability, contactsNumber=" + contactsNumber);
-        int ret = ResultCode.ERROR_SERVICE_NOT_AVAILABLE;
-
-        try {
-            ret = mIRcsPresence.requestCapability(contactsNumber, listener);
-        }  catch (RemoteException e) {
-            throw new RcsException("requestCapability", e,
-                    ResultCode.ERROR_SERVICE_NOT_AVAILABLE);
-        }
-
-        if (DBG) Log.d(TAG, "requestCapability ret =" + ret);
-        return ret;
-    }
-
-    /**
-     * Send the request to the server to get the availability.
-     *   1. If the presence service sent the request to network successfully then it will return
-     * the request ID (>0).
-     *   2. If the presence serive failed to send the request to network then it will return error
-     * code which is defined by RcsManager.ResultCode (<0).
-     *   3. If the network returns "200 OK" for a request then the listener.onSuccess() will be
-     * called by presence service.
-     *   4. If the network resturns "404" then it means the target number is not VoLte capable,
-     * so the listener.onSuccess() will be called and intent ACTION_PRESENCE_CHANGED will be
-     * broadcasted by presence service.
-     *   5. If the network returns other error code then the listener.onError() will be called by
-     * presence service.
-     *   6. If the network returns "200 OK" then we can expect the presence service receives notify
-     * from network. If the presence service receives notify then it will broadcast the intent
-     * ACTION_PRESENCE_CHANGED. If the notify state is "terminated" then the listener.onFinish()
-     * will be called by presence service as well.
-     *   7. If the presence service doesn't get response after "Subscribe Expiration + T1" then it
-     * will call listener.onTimeout().
-     *
-     * @param contactNumber the contact which will request the availability.
-     *     Only support phone number at present.
-     * @param listener the IRcsPresenceListener to get the response.
-     *
-     * @return the request ID if it is >0. Or it is RcsManager.ResultCode for error.
-     *
-     * @see IRcsPresenceListener
-     * @see RcsManager.ResultCode
-     * @see RcsPresence.ACTION_PRESENCE_CHANGED
-     */
-    public int requestAvailability(String contactNumber, IRcsPresenceListener listener)
-             throws RcsException {
-        if (DBG) Log.d(TAG, "call requestAvailability, contactNumber=" + contactNumber);
-        int ret = ResultCode.ERROR_SERVICE_NOT_AVAILABLE;
-
-        try {
-            ret = mIRcsPresence.requestAvailability(contactNumber, listener);
-        }  catch (RemoteException e) {
-            throw new RcsException("requestAvailability", e,
-                    ResultCode.ERROR_SERVICE_NOT_AVAILABLE);
-        }
-
-        if (DBG) Log.d(TAG, "requestAvailability ret =" + ret);
-        return ret;
-    }
-
-    /**
-     * Same as requestAvailability. but requestAvailability will consider throttle to avoid too
-     * fast call. Which means it will not send the request to network in next 60s for the same
-     * request.
-     * The error code SUBSCRIBE_TOO_FREQUENTLY will be returned under the case.
-     * But for this funcation it will always send the request to network.
-     *
-     * @see IRcsPresenceListener
-     * @see RcsManager.ResultCode
-     * @see RcsPresence.ACTION_PRESENCE_CHANGED
-     * @see ResultCode.SUBSCRIBE_TOO_FREQUENTLY
-     */
-    public int requestAvailabilityNoThrottle(String contactNumber, IRcsPresenceListener listener)
-             throws RcsException {
-        if (DBG) Log.d(TAG, "call requestAvailabilityNoThrottle, contactNumber=" + contactNumber);
-        int ret = ResultCode.ERROR_SERVICE_NOT_AVAILABLE;
-
-        try {
-            ret = mIRcsPresence.requestAvailabilityNoThrottle(contactNumber, listener);
-        }  catch (RemoteException e) {
-            throw new RcsException("requestAvailabilityNoThrottle", e,
-                    ResultCode.ERROR_SERVICE_NOT_AVAILABLE);
-        }
-
-        if (DBG) Log.d(TAG, "requestAvailabilityNoThrottle ret =" + ret);
-        return ret;
-    }
-
-    /**
-     * Get the latest publish state.
-     *
-     * @see PublishState
-     */
-    public int getPublishState() throws RcsException {
-        int ret = PublishState.PUBLISH_STATE_NOT_PUBLISHED;
-        try {
-            ret = mIRcsPresence.getPublishState();
-        }  catch (RemoteException e) {
-            throw new RcsException("getPublishState", e,
-                    ResultCode.ERROR_SERVICE_NOT_AVAILABLE);
-        }
-
-        if (DBG) Log.d(TAG, "getPublishState ret =" + ret);
-        return ret;
-    }
-}
-
diff --git a/rcs/rcsmanager/src/java/com/android/ims/RcsPresenceInfo.aidl b/rcs/rcsmanager/src/java/com/android/ims/RcsPresenceInfo.aidl
deleted file mode 100644
index 58b6130..0000000
--- a/rcs/rcsmanager/src/java/com/android/ims/RcsPresenceInfo.aidl
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
-
-package com.android.ims;
-
-/**
- * @hide
- */
-parcelable RcsPresenceInfo;
diff --git a/rcs/rcsmanager/src/java/com/android/ims/RcsPresenceInfo.java b/rcs/rcsmanager/src/java/com/android/ims/RcsPresenceInfo.java
deleted file mode 100644
index 8a5b913..0000000
--- a/rcs/rcsmanager/src/java/com/android/ims/RcsPresenceInfo.java
+++ /dev/null
@@ -1,354 +0,0 @@
-/*
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
-
-package com.android.ims;
-
-import android.os.Bundle;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.net.Uri;
-
-/**
- * RcsPresenceInfo is the class for presence information.
- * It is used to pass information to application for inent ACTION_PRESENCE_CHANGED
- * need to get it by the following statement:
- * ArrayList<RcsPresenceInfo> rcsPresenceInfoList = intent.getParcelableArrayListExtra(
- *           RcsPresence.EXTRA_PRESENCE_INFO_LIST);
- *
- * @see RcsPresence#ACTION_PRESENCE_CHANGED
- *
- * @hide
- */
-public class RcsPresenceInfo implements Parcelable {
-    /**
-     * Key for save contact_number.
-     * It is passed by getCapabilityByContacts or getAvailability
-     *
-     * @see #getContactNumber
-     */
-     private static final String CONTACT_NUMBER = "contact_number";
-
-    /**
-     * Key for the flag to indicate if the number is volte enabled.
-     *
-     * @see #getVolteStatus
-     */
-    public static final String VOLTE_STATUS = "volte_status";
-
-    /**
-     * The Volte status:
-     * If the contact got the 404 for single contact fetch.
-     * or it got "rejected", "noresource" and "giveup", then it is
-     * VOLTE_DISABLED. Or it is VOLTE_ENBLED.
-     * If we didn't get a success polling yet then it is VOLTE_UNKNOWN.
-     */
-    public static class VolteStatus{
-        /**
-         * Didn't poll yet.
-         */
-        public static final int VOLTE_UNKNOWN = -1;
-
-        /**
-         * Volte disabled for 404 response for single contact fetch
-         * or get "rejected", "noresource" and "giveup" notification.
-         */
-        public static final int VOLTE_DISABLED = 0;
-
-        /**
-         * Volte enabled for get proper notification.
-         */
-        public static final int VOLTE_ENABLED = 1;
-    }
-
-    /**
-     * For extension consideration we deinfed the sercice type here.
-     * Currently we only support the VoLte call and VT call.
-     *
-     * The service type for RCS
-     */
-    public static interface ServiceType {
-        /**
-         * For VoLte call.
-         */
-        public static final int VOLTE_CALL = 1;
-
-        /**
-         * For VT call.
-         */
-        public static final int VT_CALL = 2;
-    }
-
-    /**
-     * Service state
-     *
-     * @see #getServiceState
-     */
-    public static class ServiceState {
-        /**
-         * ONLINE means the servie is available.
-         */
-        public static final int ONLINE = 1;
-
-        /**
-         * OFFLINE means the service is not available.
-         */
-        public static final int OFFLINE = 0;
-
-       /**
-        * UNKNOWN means the presence service information didn't be got yet.
-        */
-        public static final int UNKNOWN = -1;
-    }
-
-    /**
-     * The presence information is maintained by key and value pair.
-     * ServiceInfoKey defines the key of the current supported information.
-     */
-    public static class ServiceInfoKey {
-        /**
-         * Service type. It is defined by ServiceType.
-         *
-         * @see ServiceType
-         */
-        public static final String SERVICE_TYPE = "service_type"; // VOLTE_CALL,etc
-
-        /**
-         * Service state. It is defined by ServiceState.
-         *
-         * @see ServiceState
-         * @see #getServiceState
-         */
-        public static final String STATE = "state"; // ONLINE, etc.
-
-        /**
-         * The service contact. For example, the phone requests presence information for number
-         * "12345678", the service responses the presence with "987654321" as the service number
-         * of video call. Then the phone should start the video call with "987654321".
-         * The "987654321" is the service number.
-         *
-         * @see #getServiceContact
-         */
-        public static final String SERVICE_CONTACT = "service_contact";
-
-        /**
-         * The timestamp which got from network.
-         *
-         * @see #getTimeStamp
-         */
-        public static final String TIMESTAMP = "timestamp";
-    }
-
-    /**
-     * Return the contact number.
-     * It is passed by getCapabilityByContacts or getAvailability
-     *
-     * @return the contact number which has been passed in.
-     *
-     * @see #CONTACT_NUMBER
-     */
-    public String getContactNumber() {
-        return mServiceInfo.getString(CONTACT_NUMBER);
-    }
-
-    /**
-     * @Return the VolteStatus.
-     */
-    public int getVolteStatus(){
-        return mServiceInfo.getInt(VOLTE_STATUS);
-    }
-
-    /**
-     * Return the ServiceState of the specific serviceType.
-     *
-     * @param serviceType it is defined by ServiceType.
-     *
-     * @return the service presence state which has been described in ServiceInfoKey.
-     *
-     * @see ServiceType
-     * @see ServiceState
-     * @see ServiceInfoKey#STATE
-     */
-    public int getServiceState(int serviceType) {
-        return getServiceInfo(serviceType, ServiceInfoKey.STATE, ServiceState.UNKNOWN);
-    }
-
-    /**
-     * Return the service contact of the specific serviceType.
-     *
-     * @param serviceType It is defined by ServiceType.
-     *
-     * @return the service contact which is described in ServiceInfoKey.
-     *
-     * @see ServiceType
-     * @see ServiceInfoKey#SERVICE_CONTACT
-     */
-    public String getServiceContact(int serviceType) {
-        return getServiceInfo(serviceType, ServiceInfoKey.SERVICE_CONTACT, "");
-    }
-
-    /**
-     * Return the timestamp.
-     *
-     * @param serviceType It is defined by ServiceType.
-     *
-     * @return the timestamp which has been got from server.
-     *
-     * @see ServiceType
-     * @see ServiceInfoKey#TIMESTAMP
-     */
-    public long getTimeStamp(int serviceType) {
-        return getServiceInfo(serviceType, ServiceInfoKey.TIMESTAMP, 0L);
-    }
-
-    /**
-     * @hide
-     */
-    public RcsPresenceInfo() {
-    }
-
-    /**
-     * @hide
-     */
-    public RcsPresenceInfo(Parcel source) {
-        mServiceInfo.readFromParcel(source);
-    }
-
-    /**
-     * @hide
-     */
-    private Bundle getBundle() {
-        return mServiceInfo;
-    }
-
-    /**
-     * @hide
-     */
-    public RcsPresenceInfo(String contactNumber,int volteStatus,
-            int ipVoiceCallState, String ipVoiceCallServiceNumber, long ipVoiceCallTimestamp,
-            int ipVideoCallState, String ipVideoCallServiceNumber, long ipVideoCallTimestamp) {
-        mServiceInfo.putString(CONTACT_NUMBER, contactNumber);
-        mServiceInfo.putInt(VOLTE_STATUS, volteStatus);
-
-        set(ServiceType.VOLTE_CALL, ipVoiceCallState, ipVoiceCallServiceNumber,
-                ipVoiceCallTimestamp);
-
-        set(ServiceType.VT_CALL, ipVideoCallState, ipVideoCallServiceNumber,
-                ipVideoCallTimestamp);
-    }
-
-    private void set(int serviceType, int state, String serviceNumber, long timestamp) {
-        Bundle capability = new Bundle();
-
-        capability.putInt(ServiceInfoKey.SERVICE_TYPE, serviceType);
-        capability.putInt(ServiceInfoKey.STATE, state);
-        capability.putString(ServiceInfoKey.SERVICE_CONTACT, serviceNumber);
-        capability.putLong(ServiceInfoKey.TIMESTAMP, timestamp);
-
-        mServiceInfo.putBundle(String.valueOf(serviceType), capability);
-    }
-
-    /**
-     * Overload
-     * @hide
-     */
-    public static final Parcelable.Creator<RcsPresenceInfo> CREATOR = new
-            Parcelable.Creator<RcsPresenceInfo>() {
-        public RcsPresenceInfo createFromParcel(Parcel in) {
-            return new RcsPresenceInfo(in);
-        }
-
-        public RcsPresenceInfo[] newArray(int size) {
-            return new RcsPresenceInfo[size];
-        }
-    };
-
-    /**
-     * Overload
-     * @hide
-     */
-    public void writeToParcel(Parcel dest, int flags) {
-        mServiceInfo.writeToParcel(dest, flags);
-    }
-
-    /**
-     * Overload
-     * @hide
-     */
-    public int describeContents() {
-        return 0;
-    }
-
-    private Bundle mServiceInfo = new Bundle();
-
-    private String getServiceInfo(int serviceType, String infoKey, String defaultValue) {
-        Bundle serviceInfo = mServiceInfo.getBundle(String.valueOf(serviceType));
-
-        if (serviceInfo != null) {
-            return serviceInfo.getString(infoKey);
-        }
-        return defaultValue;
-    }
-
-    private long getServiceInfo(int serviceType, String infoKey, long defaultValue) {
-        Bundle serviceInfo = mServiceInfo.getBundle(String.valueOf(serviceType));
-        if (serviceInfo != null) {
-            return serviceInfo.getLong(infoKey);
-        }
-
-        return defaultValue;
-    }
-
-    private int getServiceInfo(int serviceType, String infoType, int defaultValue) {
-        Bundle serviceInfo = mServiceInfo.getBundle(String.valueOf(serviceType));
-        if (serviceInfo != null) {
-            return serviceInfo.getInt(infoType);
-        }
-        return defaultValue;
-    }
-
-    private Uri getServiceInfo(int serviceType, String infoKey, Uri defaultValue) {
-        Bundle serviceInfo = mServiceInfo.getBundle(String.valueOf(serviceType));
-        if (serviceInfo != null) {
-            return (Uri)serviceInfo.getParcelable(infoKey);
-        }
-
-        return defaultValue;
-    }
-
-    public String toString() {
-        return" contactNumber=" + getContactNumber() +
-            " volteStatus=" + getVolteStatus() +
-            " ipVoiceCallSate=" + getServiceState(ServiceType.VOLTE_CALL) +
-            " ipVoiceCallServiceNumber=" + getServiceContact(ServiceType.VOLTE_CALL) +
-            " ipVoiceCallTimestamp=" + getTimeStamp(ServiceType.VOLTE_CALL) +
-            " ipVideoCallSate=" + getServiceState(ServiceType.VT_CALL) +
-            " ipVideoCallServiceNumber=" + getServiceContact(ServiceType.VT_CALL) +
-            " ipVideoCallTimestamp=" + getTimeStamp(ServiceType.VT_CALL);
-    }
-}
-
diff --git a/rcs/rcsmanager/src/java/com/android/ims/internal/ContactNumberUtils.java b/rcs/rcsmanager/src/java/com/android/ims/internal/ContactNumberUtils.java
deleted file mode 100644
index b69b42c..0000000
--- a/rcs/rcsmanager/src/java/com/android/ims/internal/ContactNumberUtils.java
+++ /dev/null
@@ -1,343 +0,0 @@
-/*
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
-
-package com.android.ims.internal;
-
-import android.content.Context;
-import android.os.Build;
-import android.telephony.PhoneNumberUtils;
-import android.telephony.TelephonyManager;
-import android.text.TextUtils;
-import android.util.Log;
-
-import java.util.List;
-import java.util.ArrayList;
-
-/**
- * @hide
- */
-public class ContactNumberUtils {
-    /**
-     * Sample code:
-     *
-     * ContactNumberUtils mNumberUtils = ContactNumberUtils.getDefault();
-     * mNumberUtils.setContext(this);
-     *
-     * number = mNumberUtils.format(number);
-     * int result = mNumberUtils.validate(number);
-     * if (ContactNumberUtils.NUMBER_VALID == result) {
-     * }
-     */
-    public static ContactNumberUtils getDefault() {
-        if(sInstance == null) {
-            sInstance = new ContactNumberUtils();
-        }
-
-        return sInstance;
-    }
-
-    public void setContext(Context context) {
-        mContext = context;
-    }
-
-    /**
-     * Format contact number to the common format
-     *
-     * @param phoneNumber read from contact db.
-     * @return formatted contact number.
-     */
-    public String format(final String phoneNumber) {
-        String number = phoneNumber;
-        if (TextUtils.isEmpty(number)) {
-            return null;
-        }
-
-        number = PhoneNumberUtils.stripSeparators(number);
-
-        int len = number.length();
-        if (len == NUMBER_LENGTH_NO_AREA_CODE) {
-            number = addAreaCode(number);
-        }
-
-        number = PhoneNumberUtils.normalizeNumber(number);
-
-        len = number.length();
-        if (len == NUMBER_LENGTH_NORMAL) {
-            if (!number.startsWith("+1")) {
-                number = "+1" + number;
-            }
-        } else if (len == NUMBER_LENGTH_NORMAL + 1) {
-            if (number.startsWith("1")) {
-                number = "+" + number;
-            }
-        } else if (len >= NUMBER_LENGTH_NORMAL + 4) {
-            if (number.startsWith("011")) {
-                number = "+" + number.substring(3);
-            }
-        }
-
-        return number;
-    }
-
-    /**
-     * Contact nubmer error code.
-     */
-    public static int NUMBER_VALID = 0;
-    public static int NUMBER_EMERGENCY = 1;
-    public static int NUMBER_SHORT_CODE = 2;
-    public static int NUMBER_PRELOADED_ENTRY = 3;
-    public static int NUMBER_FREE_PHONE = 4;
-    public static int NUMBER_INVALID = 5;
-
-    /**
-     * Check if it is a valid contact number for presence
-     *
-     * @param phoneNumber read from contact db.
-     * @return contact number error code.
-     */
-    public int validate(final String phoneNumber) {
-        String number = phoneNumber;
-        if (TextUtils.isEmpty(number)) {
-            return NUMBER_INVALID;
-        }
-
-        if(number.contains("*")) {
-            return NUMBER_PRELOADED_ENTRY;
-        }
-
-        number = PhoneNumberUtils.stripSeparators(number);
-        if (!number.equals(PhoneNumberUtils.convertKeypadLettersToDigits(number))) {
-            return NUMBER_INVALID;
-        }
-
-        if (PhoneNumberUtils.isEmergencyNumber(number)) {
-            return NUMBER_EMERGENCY;
-        // TODO: To handle short code
-        //} else if ((mContext != null) && PhoneNumberUtils.isN11Number(mContext, number)) {
-        //    return NUMBER_SHORT_CODE;
-        } else if (number.startsWith("#")) {
-            return NUMBER_PRELOADED_ENTRY;
-        } else if (isInExcludedList(number)) {
-            return NUMBER_FREE_PHONE;
-        }
-
-        int len = number.length();
-        if (len > "+1-nnn-nnn-nnnn".length()) {
-            return NUMBER_INVALID;
-        } else if (len < NUMBER_LENGTH_NO_AREA_CODE) {
-            return NUMBER_INVALID;
-        }
-
-        number = format(number);
-        if (number.startsWith("+1")) {
-            len = number.length();
-            if (len == NUMBER_LENGTH_NORMAL + 2) {
-                return NUMBER_VALID;
-            }
-        }
-
-        return NUMBER_INVALID;
-    }
-
-
-    /**
-     * Some utility functions for presence service only.
-     * @hide
-     */
-    public String[] format(List<String> numbers) {
-        if ((numbers == null) || (numbers.size() == 0)) {
-            return null;
-        }
-
-        int size = numbers.size();
-        String[] outContactsArray = new String[size];
-        for (int i = 0; i < size; i++) {
-            String number = numbers.get(i);
-            outContactsArray[i] = format(number);
-            if (DEBUG) {
-                Log.d(TAG, "outContactsArray[" + i + "] = " + outContactsArray[i]);
-            }
-        }
-
-        return outContactsArray;
-    }
-
-    public String[] format(String[] numbers) {
-        if ((numbers == null) || (numbers.length == 0)) {
-            return null;
-        }
-
-        int length = numbers.length;
-        String[] outContactsArray = new String[length];
-        for (int i = 0; i < length; i++) {
-            String number = numbers[i];
-            outContactsArray[i] = format(number);
-            if (DEBUG) {
-                Log.d(TAG, "outContactsArray[" + i + "] = " + outContactsArray[i]);
-            }
-        }
-
-        return outContactsArray;
-    }
-    public int validate(List<String> numbers) {
-        if ((numbers == null) || (numbers.size() == 0)) {
-            return NUMBER_INVALID;
-        }
-
-        int size = numbers.size();
-        for (int i = 0; i < size; i++) {
-            String number = numbers.get(i);
-            int result = validate(number);
-            if (result != NUMBER_VALID) {
-                return result;
-            }
-        }
-
-        return NUMBER_VALID;
-    }
-
-    public int validate(String[] numbers) {
-        if ((numbers == null) || (numbers.length == 0)) {
-            return NUMBER_INVALID;
-        }
-
-        int length = numbers.length;
-        for (int i = 0; i < length; i++) {
-            String number = numbers[i];
-            int result = validate(number);
-            if (result != NUMBER_VALID) {
-                return result;
-            }
-        }
-
-        return NUMBER_VALID;
-    }
-
-    /**
-     * The logger related.
-     */
-    private static final boolean DEBUG = Build.IS_DEBUGGABLE;
-    private static final String TAG = "ContactNumberUtils";
-
-    /**
-     * Contact number length.
-     */
-    private static final int NUMBER_LENGTH_NORMAL = 10;
-    private static final int NUMBER_LENGTH_NO_AREA_CODE = 7;
-
-    /**
-     * Save the singleton instance.
-     */
-    private static ContactNumberUtils sInstance = null;
-    private Context mContext = null;
-
-    /**
-     * Constructor
-     */
-    private ContactNumberUtils() {
-        if (DEBUG) {
-            Log.d(TAG, "ContactNumberUtils constructor");
-        }
-    }
-
-    /**
-     * Add device's own area code to the number which length is 7.
-     */
-    private String addAreaCode(String number) {
-        if (mContext == null) {
-            if (DEBUG) {
-                Log.e(TAG, "mContext is null, please update context.");
-            }
-            return number;
-        }
-
-        String mdn = null;
-        TelephonyManager tm = (TelephonyManager)
-                mContext.getSystemService(Context.TELEPHONY_SERVICE);
-        mdn = tm.getLine1Number();
-
-        if ((mdn == null) || (mdn.length() == 0) ||  mdn.startsWith("00000")) {
-            return number;
-        }
-
-        mdn = PhoneNumberUtils.stripSeparators(mdn);
-        if (mdn.length() >= NUMBER_LENGTH_NORMAL) {
-            mdn = mdn.substring(mdn.length() - NUMBER_LENGTH_NORMAL);
-        }
-        mdn = mdn.substring(0, 3);
-
-        number = mdn + number;
-        return number;
-    }
-
-    /**
-     * The excluded number list.
-     */
-    private static ArrayList<String> sExcludes = null;
-
-    private boolean isInExcludedList(String number){
-        if (sExcludes == null) {
-            sExcludes = new ArrayList<String>();
-            sExcludes.add("800");
-            sExcludes.add("822");
-            sExcludes.add("833");
-            sExcludes.add("844");
-            sExcludes.add("855");
-            sExcludes.add("866");
-            sExcludes.add("877");
-            sExcludes.add("880882");
-            sExcludes.add("888");
-            sExcludes.add("900");
-            sExcludes.add("911");
-        }
-
-        String tempNumber = format(number);
-        if(TextUtils.isEmpty(tempNumber)) {
-            return true; //exclude empty/null string.
-        }
-
-        if(tempNumber.startsWith("1")) {
-            tempNumber = tempNumber.substring(1);
-        } else if(tempNumber.startsWith("+1")) {
-            tempNumber = tempNumber.substring(2);
-        }
-
-        if(TextUtils.isEmpty(tempNumber)) {
-            return true; //exclude empty/null string.
-        }
-
-        for (String num : sExcludes) {
-            if(tempNumber.startsWith(num)) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-}
-
diff --git a/rcs/rcsmanager/src/java/com/android/ims/internal/EABContract.java b/rcs/rcsmanager/src/java/com/android/ims/internal/EABContract.java
deleted file mode 100644
index 7796071..0000000
--- a/rcs/rcsmanager/src/java/com/android/ims/internal/EABContract.java
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
-
-package com.android.ims.internal;
-
-import android.net.Uri;
-import android.provider.BaseColumns;
-
-/**
- * <p>
- * The contract between the EAB provider and applications. Contains
- * definitions for the supported URIs and data columns.
- * </p>
- * <h3>Overview</h3>
- * <p>
- * EABContract defines the data model of EAB related information.
- * This data is stored in a table EABPresence.
- * </p>
- *
- * @hide
- *
- */
-public final class EABContract {
-    /**
-     * This authority is used for writing to or querying from the EAB provider.
-     */
-    public static final String AUTHORITY = "com.android.rcs.eab";
-
-    /**
-     * The content:// style URL for the top-level EAB authority
-     */
-    public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY);
-
-    /**
-     *  Class for EABProviderItem
-     */
-    public static class EABColumns implements BaseColumns {
-        public static final String TABLE_NAME = "EABPresence";
-        public static final String GROUPITEMS_NAME = "EABGroupDetails";
-
-        /**
-         * CONTENT_URI
-         * <P>
-         * "content://com.android.vt.eab/EABPresence"
-         * </P>
-         */
-        public static final Uri CONTENT_URI = Uri.withAppendedPath(EABContract.CONTENT_URI,
-                TABLE_NAME);
-
-        public static final String CONTENT_TYPE =
-                "vnd.android.cursor.dir/vnd.android.rcs.eab.provider.eabprovider";
-
-        public static final String CONTENT_ITEM_TYPE =
-                "vnd.android.cursor.item/vnd.android.rcs.eab.provider.eabprovider";
-
-        /**
-         * Key defining the contact number.
-         * <P>
-         * Type: TEXT
-         * </P>
-         */
-        public static final String CONTACT_NUMBER = "contact_number";
-
-        /**
-         * Key defining the contact name.
-         * <P>
-         * Type: TEXT
-         * </P>
-         */
-        public static final String CONTACT_NAME = "contact_name";
-
-        /**
-         * Key defining the reference to ContactContract raw_contact_id of the number.
-         * <P>
-         * Type: TEXT
-         * </P>
-         */
-        public static final String RAW_CONTACT_ID = "raw_contact_id";
-
-        /**
-         * Key defining the reference to ContactContract contact_id of the number.
-         * <P>
-         * Type: TEXT
-         * </P>
-         */
-        public static final String CONTACT_ID = "contact_id";
-
-        /**
-         * Key defining the reference to ContactContract data_id of the number.
-         * <P>
-         * Type: TEXT
-         * </P>
-         */
-        public static final String DATA_ID = "data_id";
-
-        /**
-         * Key defining the account type.
-         * <P>
-         * Type: TEXT
-         * </P>
-         */
-        public static final String ACCOUNT_TYPE = "account_type";
-
-        /**
-         * Key defining the VoLTE call service contact address.
-         * <P>
-         * Type: TEXT
-         * </P>
-         */
-        public static final String VOLTE_CALL_SERVICE_CONTACT_ADDRESS = "volte_contact_address";
-
-        /**
-         * Key defining the VoLTE call capability.
-         * <P>
-         * Type: TEXT
-         * </P>
-         */
-        public static final String VOLTE_CALL_CAPABILITY = "volte_call_capability";
-
-        /**
-         * Key defining the VoLTE call capability timestamp.
-         * <P>
-         * Type: TEXT
-         * </P>
-         */
-        public static final String VOLTE_CALL_CAPABILITY_TIMESTAMP = "volte_capability_timestamp";
-
-        /**
-         * Key defining the VoLTE call availability.
-         * <P>
-         * Type: LONG
-         * </P>
-         */
-        public static final String VOLTE_CALL_AVAILABILITY = "volte_call_avalibility";
-
-        /**
-         * Key defining the VoLTE call availability timestamp.
-         * <P>
-         * Type: TEXT
-         * </P>
-         */
-        public static final String VOLTE_CALL_AVAILABILITY_TIMESTAMP =
-                "volte_availability_timestamp";
-
-        /**
-         * Key defining the Video call service contact address.
-         * <P>
-         * Type: LONG
-         * </P>
-         */
-        public static final String VIDEO_CALL_SERVICE_CONTACT_ADDRESS = "video_contact_address";
-
-        /**
-         * Key defining the Video call capability.
-         * <P>
-         * Type: TEXT
-         * </P>
-         */
-        public static final String VIDEO_CALL_CAPABILITY = "video_call_capability";
-
-        /**
-         * Key defining the Video call capability timestamp.
-         * <P>
-         * Type: TEXT
-         * </P>
-         */
-        public static final String VIDEO_CALL_CAPABILITY_TIMESTAMP = "video_capability_timestamp";
-
-        /**
-         * Key defining the Video call availability.
-         * <P>
-         * Type: LONG
-         * </P>
-         */
-        public static final String VIDEO_CALL_AVAILABILITY = "video_call_availability";
-
-        /**
-         * Key defining the Video call availability timestamp.
-         * <P>
-         * Type: TEXT
-         * </P>
-         */
-        public static final String VIDEO_CALL_AVAILABILITY_TIMESTAMP =
-                "video_availability_timestamp";
-
-        /**
-         * Key defining the Video call availability timestamp.
-         * <P>
-         * Type: LONG
-         * </P>
-         */
-        public static final String CONTACT_LAST_UPDATED_TIMESTAMP =
-                "contact_last_updated_timestamp";
-
-        /**
-         * Key defining the volte status.
-         * <p>
-         * Type: INT
-         * </p>
-         */
-        public static final String VOLTE_STATUS = "volte_status";
-
-        /**
-         * @hide
-         */
-        public static final String[] PROJECTION = new String[] {
-            _ID,
-            CONTACT_NAME,
-            CONTACT_NUMBER,
-            RAW_CONTACT_ID,
-            CONTACT_ID,
-            DATA_ID,
-            ACCOUNT_TYPE,
-            VOLTE_CALL_SERVICE_CONTACT_ADDRESS,
-            VOLTE_CALL_CAPABILITY,
-            VOLTE_CALL_AVAILABILITY_TIMESTAMP,
-            VOLTE_CALL_AVAILABILITY,
-            VOLTE_CALL_CAPABILITY_TIMESTAMP,
-            VIDEO_CALL_SERVICE_CONTACT_ADDRESS,
-            VIDEO_CALL_CAPABILITY,
-            VIDEO_CALL_CAPABILITY_TIMESTAMP,
-            VIDEO_CALL_AVAILABILITY,
-            VIDEO_CALL_AVAILABILITY_TIMESTAMP,
-            CONTACT_LAST_UPDATED_TIMESTAMP,
-            VOLTE_STATUS
-        };
-    }
-}
-
diff --git a/rcs/rcsmanager/src/java/com/android/ims/internal/IRcsPresence.aidl b/rcs/rcsmanager/src/java/com/android/ims/internal/IRcsPresence.aidl
deleted file mode 100644
index c0c67c0..0000000
--- a/rcs/rcsmanager/src/java/com/android/ims/internal/IRcsPresence.aidl
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
-
-package com.android.ims.internal;
-
-import com.android.ims.IRcsPresenceListener;
-
-import java.util.List;
-
-/**
- * @hide
- */
-interface IRcsPresence {
-    /**
-     * Send the request to the server to get the capability.
-     *   1. If the presence service sent the request to network successfully
-     * then it will return the request ID (>0). It will not wait for the response from
-     * network. The response from network will be returned by callback onSuccess() or onError().
-     *   2. If the presence service failed to send the request to network then it will return error
-     *  code which is defined by RcsManager.ResultCode (<0).
-     *   3. If the network returns "200 OK" for a request then the listener.onSuccess() will be
-     * called by presence service.
-     *   4. If the network resturns "404" for a single target number then it means the target
-     * number is not VoLte capable, so the listener.onSuccess() will be called and intent
-     * ACTION_PRESENCE_CHANGED will be broadcasted by presence service.
-     *   5. If the network returns other error then the listener.onError() will be called by
-     * presence service.
-     *   6. If the network returns "200 OK" then we can expect the presence service receives notify
-     * from network. If the presence service receives notify then it will broadcast the
-     * intent ACTION_PRESENCE_CHANGED. If the notify state is "terminated" then the
-     * listener.onFinish() will be called by presence service as well.
-     *   7. If the presence service doesn't get response after "Subscribe Expiration + T1" then the
-     * listener.onTimeout() will be called by presence service.
-     *
-     * @param contactsNumber the contact number list which will be requested.
-     * @param listener the IRcsPresenceListener which will return the status and response.
-     *
-     * @return the request ID if it is >0. Or it is RcsManager.ResultCode for error.
-     *
-     * @see IRcsPresenceListener
-     * @see RcsManager.ResultCode
-     */
-    int requestCapability(in List<String> contactsNumber,
-            in IRcsPresenceListener listener);
-
-    /**
-     * Send the request to the server to get the availability.
-     *   1. If the presence service sent the request to network successfully then it will return
-     * the request ID (>0).
-     *   2. If the presence serive failed to send the request to network then it will return error
-     * code which is defined by RcsManager.ResultCode (<0).
-     *   3. If the network returns "200 OK" for a request then the listener.onSuccess() will be
-     * called by presence service.
-     *   4. If the network resturns "404" then it means the target number is not VoLte capable,
-     * so the listener.onSuccess() will be called and intent ACTION_PRESENCE_CHANGED will be
-     * broadcasted by presence service.
-     *   5. If the network returns other error code then the listener.onError() will be called by
-     * presence service.
-     *   6. If the network returns "200 OK" then we can expect the presence service receives notify
-     * from network. If the presence service receives notify then it will broadcast the intent
-     * ACTION_PRESENCE_CHANGED. If the notify state is "terminated" then the listener.onFinish()
-     * will be called by presence service as well.
-     *   7. If the presence service doesn't get response after "Subscribe Expiration + T1" then it
-     * will call listener.onTimeout().
-     *
-     * @param contactNumber the contact which will request the availability.
-     *     Only support phone number at present.
-     * @param listener the IRcsPresenceListener to get the response.
-     *
-     * @return the request ID if it is >0. Or it is RcsManager.ResultCode for error.
-     *
-     * @see IRcsPresenceListener
-     * @see RcsManager.ResultCode
-     * @see RcsPresence.ACTION_PRESENCE_CHANGED
-     */
-    int requestAvailability(in String contactNumber, in IRcsPresenceListener listener);
-
-    /**
-     * Same as requestAvailability. but requestAvailability will consider throttle to avoid too
-     * fast call. Which means it will not send the request to network in next 60s for the same
-     * request.
-     * The error code SUBSCRIBE_TOO_FREQUENTLY will be returned under the case.
-     * But for this funcation it will always send the request to network.
-     *
-     * @see IRcsPresenceListener
-     * @see RcsManager.ResultCode
-     * @see RcsPresence.ACTION_PRESENCE_CHANGED
-     * @see ResultCode.SUBSCRIBE_TOO_FREQUENTLY
-     */
-    int requestAvailabilityNoThrottle(in String contactNumber, in IRcsPresenceListener listener);
-
-    /**
-     * Get the latest publish state.
-     *
-     * @see RcsPresence.PublishState
-     */
-    int getPublishState();
-}
diff --git a/rcs/rcsmanager/src/java/com/android/ims/internal/IRcsService.aidl b/rcs/rcsmanager/src/java/com/android/ims/internal/IRcsService.aidl
deleted file mode 100644
index 34ad1b3..0000000
--- a/rcs/rcsmanager/src/java/com/android/ims/internal/IRcsService.aidl
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
-
-package com.android.ims.internal;
-
-import com.android.ims.internal.IRcsPresence;
-
-/**
- * @hide
- */
-interface IRcsService {
-    /**
-     * Detect if the rcs service is available.
-     */
-    boolean isRcsServiceAvailable();
-
-    /**
-     * RcsPresence interface to get the presence information.
-     *
-     * @see IRcsPresence
-     */
-    IRcsPresence getRcsPresenceInterface();
-}
diff --git a/rcs/rcsmanager/src/java/com/android/ims/internal/Logger.java b/rcs/rcsmanager/src/java/com/android/ims/internal/Logger.java
deleted file mode 100644
index 9e6c6a8..0000000
--- a/rcs/rcsmanager/src/java/com/android/ims/internal/Logger.java
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
-
-package com.android.ims.internal;
-
-import java.lang.String;
-import android.util.Log;
-
-import android.os.Build;
-import android.text.TextUtils;
-
-/**
- * Logger
- *
- * @hide
- */
-public class Logger {
-    /**
-     * DEBUG level
-     */
-    public static int DEBUG_LEVEL = 0;
-
-    /**
-     * INFO level
-     */
-    public static int INFO_LEVEL = 1;
-
-    /**
-     * WARN level
-     */
-    public static int WARN_LEVEL = 2;
-
-    /**
-     * ERROR level
-     */
-    public static int ERROR_LEVEL = 3;
-
-    /**
-     * FATAL level
-     */
-    public static int FATAL_LEVEL = 4;
-
-    /**
-     * RCS test mode flag
-     */
-    public static boolean rcsTestMode = false;
-
-    /**
-     * Trace level
-     */
-    public static int traceLevel = DEBUG_LEVEL;
-
-    /**
-     * Log tag name
-     */
-    private static String tagname = "rcs";
-
-    /**
-     * Classname
-     */
-    private String classname;
-
-    /**
-     * Constructor
-     *
-     * @param classname Classname
-     */
-    private Logger(String tagName, String classname) {
-        if(!TextUtils.isEmpty(tagName)) {
-            this.tagname = tagName;
-        }
-
-        int index = classname.lastIndexOf('.');
-        if (index != -1) {
-            this.classname = classname.substring(index+1);
-        } else {
-            this.classname = classname;
-        }
-
-        if(Build.IS_DEBUGGABLE || rcsTestMode){
-            traceLevel = DEBUG_LEVEL;
-        }else{
-            traceLevel = ERROR_LEVEL;
-        }
-    }
-
-    public static void setRcsTestMode(boolean test) {
-        rcsTestMode = test;
-
-        if (Build.IS_DEBUGGABLE || rcsTestMode) {
-            traceLevel = DEBUG_LEVEL;
-        } else {
-            traceLevel = ERROR_LEVEL;
-        }
-    }
-
-    /**
-     * Is logger activated. Reserved for future debug tool to turn on/off the log only.
-     *
-     * @return boolean
-     */
-    public boolean isActivated() {
-        return true;
-    }
-
-    /**
-     * Debug trace
-     *
-     * @param trace Trace
-     */
-    public void debug(String trace) {
-        if (isActivated() && (traceLevel <= DEBUG_LEVEL)) {
-            Log.d(tagname, "[" + classname +"] " + trace);
-        }
-    }
-
-    /**
-     * Debug trace
-     *
-     * @param trace Trace
-     * @param e the exception which need to be printed.
-     */
-    public void debug(String trace, Throwable e) {
-        if (isActivated() && (traceLevel <= DEBUG_LEVEL)) {
-            Log.d(tagname, "[" + classname +"] " + trace, e);
-        }
-    }
-
-    /**
-     * Info trace
-     *
-     * @param trace Trace
-     */
-    public void info(String trace) {
-        if (isActivated() && (traceLevel <= INFO_LEVEL)) {
-            Log.i(tagname, "[" + classname +"] " + trace);
-        }
-    }
-
-    /**
-     * Warning trace
-     *
-     * @param trace Trace
-     */
-    public void warn(String trace) {
-        if (isActivated() && (traceLevel <= WARN_LEVEL)) {
-            Log.w(tagname, "[" + classname +"] " + trace);
-        }
-    }
-
-    /**
-     * Error trace
-     *
-     * @param trace Trace
-     */
-    public void error(String trace) {
-        if (isActivated() && (traceLevel <= ERROR_LEVEL)) {
-            Log.e(tagname, "[" + classname +"] " + trace);
-        }
-    }
-
-    /**
-     * Error trace
-     *
-     * @param trace Trace
-     * @param e Exception
-     */
-    public void error(String trace, Throwable e) {
-        if (isActivated() && (traceLevel <= ERROR_LEVEL)) {
-            Log.e(tagname, "[" + classname +"] " + trace, e);
-        }
-    }
-
-    /*
-     * Print the debug log and don't consider the traceLevel
-     *
-     * @param trace Trace
-     * @param e Exception
-     */
-    public void print(String trace) {
-        Log.i(tagname, "[" + classname +"] " + trace);
-    }
-
-    /**
-     * Print the debug log and don't consider the traceLevel
-     *
-     * @param trace Trace
-     * @param e Exception
-     */
-    public void print(String trace, Throwable e) {
-        Log.i(tagname, "[" + classname +"] " + trace, e);
-    }
-
-    /**
-     * Create a static instance
-     *
-     * @param classname Classname
-     * @return Instance
-     */
-    public static synchronized Logger getLogger(String tagName, String classname) {
-        return new Logger(tagName, classname);
-    }
-
-    /**
-     * Create a static instance
-     *
-     * @param classname Classname
-     * @return Instance
-     */
-    public static synchronized Logger getLogger(String classname) {
-        return new Logger(tagname, classname);
-    }
-}
-
diff --git a/rcs/rcsservice/Android.mk b/rcs/rcsservice/Android.mk
deleted file mode 100644
index 281f178..0000000
--- a/rcs/rcsservice/Android.mk
+++ /dev/null
@@ -1,47 +0,0 @@
- # Copyright (c) 2015, Motorola Mobility LLC
- # All rights reserved.
- #
- # Redistribution and use in source and binary forms, with or without
- # modification, are permitted provided that the following conditions are met:
- #     - Redistributions of source code must retain the above copyright
- #       notice, this list of conditions and the following disclaimer.
- #     - Redistributions in binary form must reproduce the above copyright
- #       notice, this list of conditions and the following disclaimer in the
- #       documentation and/or other materials provided with the distribution.
- #     - Neither the name of Motorola Mobility nor the
- #       names of its contributors may be used to endorse or promote products
- #       derived from this software without specific prior written permission.
- #
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- # DAMAGE.
-
-LOCAL_PATH := $(call my-dir)
-
-##########################################################################
-# Build the application : Presence.apk
-##########################################################################
-
-include $(CLEAR_VARS)
-# This is the target being built. (Name of APK)
-LOCAL_PACKAGE_NAME := RcsService
-# Only compile source java files in this apk.
-LOCAL_SRC_FILES := \
-    $(call all-java-files-under, src)
-
-LOCAL_JAVA_LIBRARIES := telephony-common ims-common com.android.ims.rcsmanager
-
-#LOCAL_MODULE_TAGS := optional
-LOCAL_CERTIFICATE := platform
-
-# Tell it to build an APK
-include $(BUILD_PACKAGE)
-
diff --git a/rcs/rcsservice/AndroidManifest.xml b/rcs/rcsservice/AndroidManifest.xml
deleted file mode 100644
index 2c44518..0000000
--- a/rcs/rcsservice/AndroidManifest.xml
+++ /dev/null
@@ -1,90 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?>
-<!--
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
- android:versionCode="1"
- android:versionName="2.4.6"
- coreApp="true"
- android:sharedUserId="android.uid.phone"
- package="com.android.service.ims">
-
-    <uses-sdk android:minSdkVersion="19"/>
-
-    <protected-broadcast android:name="com.android.ims.ACTION_RCS_SERVICE_AVAILABLE" />
-    <protected-broadcast android:name="com.android.ims.ACTION_RCS_SERVICE_UNAVAILABLE" />
-    <protected-broadcast android:name="com.android.ims.ACTION_RCS_SERVICE_DIED" />
-    <protected-broadcast android:name="com.android.ims.ACTION_PRESENCE_CHANGED" />
-    <protected-broadcast android:name="com.android.ims.ACTION_PUBLISH_STATUS_CHANGED" />
-
-    <permission
-        android:name="com.android.ims.rcs.permission.STATUS_CHANGED"
-        android:protectionLevel="signatureOrSystem" />
-
-    <permission android:name="com.android.ims.permission.PRESENCE_ACCESS"
-        android:label="@string/ims_presence_permission"
-        android:description="@string/ims_ims_permission_desc"
-        android:protectionLevel="signatureOrSystem" />
-
-    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
-    <uses-permission android:name="android.permission.BROADCAST_STICKY"/>
-    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
-    <uses-permission android:name="com.android.ims.rcs.permission.STATUS_CHANGED"/>
-    <uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE"/>
-    <uses-permission android:name="android.permission.ACCESS_UCE_PRESENCE_SERVICE"/>
-    <uses-permission android:name="com.android.ims.permission.PRESENCE_ACCESS"/>
-    <uses-permission android:name="com.android.rcs.eab.permission.READ_WRITE_EAB"/>
-
-    <application android:name="RcsServiceApp" android:persistent="true"
-        android:process="com.android.ims.rcsservice">
-        <uses-library android:name="com.android.ims.rcsmanager"
-            android:required="true"/>
-
-        <service android:name="com.android.service.ims.RcsService"
-            android:exported="true"
-            android:enabled="true"
-            android:permission="com.android.ims.permission.PRESENCE_ACCESS">
-        </service>
-
-        <receiver android:name="com.android.service.ims.DeviceShutdown"
-            androidprv:systemUserOnly="true">
-            <intent-filter>
-                 <action android:name="android.intent.action.ACTION_SHUTDOWN"/>
-            </intent-filter>
-        </receiver>
-
-        <receiver android:name="com.android.service.ims.presence.AlarmBroadcastReceiver"
-            android:permission="com.android.ims.permission.PRESENCE_ACCESS"
-             androidprv:systemUserOnly="true">
-            <intent-filter>
-                <action android:name="com.android.service.ims.presence.retry" />
-            </intent-filter>
-        </receiver>
-    </application>
-</manifest>
diff --git a/rcs/rcsservice/res/values/config.xml b/rcs/rcsservice/res/values/config.xml
deleted file mode 100644
index c62c09e..0000000
--- a/rcs/rcsservice/res/values/config.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
--->
-
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string-array translatable="false" name="config_volte_provision_error_on_publish_response">
-    <item>403 not authorized for presence</item>
-    </string-array>
-
-    <string-array translatable="false" name="config_rcs_provision_error_on_publish_response">
-    <item>404 not found</item>
-    </string-array>
-
-    <string-array translatable="false" name="config_volte_provision_error_on_subscribe_response">
-    <item>403 not authorized for presence</item>
-    </string-array>
-
-    <string-array translatable="false" name="config_rcs_provision_error_on_subscribe_response">
-    <item>403 forbidden</item>
-    </string-array>
-
-</resources>
-
diff --git a/rcs/rcsservice/res/values/strings.xml b/rcs/rcsservice/res/values/strings.xml
deleted file mode 100644
index cb4bbc3..0000000
--- a/rcs/rcsservice/res/values/strings.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
--->
-
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-<string name="ims_presence_permission">Presence</string>
-<string name="ims_ims_permission_desc">Allow the application to publish and subscribe the presence information.</string>
-</resources>
-
diff --git a/rcs/rcsservice/src/com/android/service/ims/DeviceShutdown.java b/rcs/rcsservice/src/com/android/service/ims/DeviceShutdown.java
deleted file mode 100644
index ffc10fc..0000000
--- a/rcs/rcsservice/src/com/android/service/ims/DeviceShutdown.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
-
-package com.android.service.ims;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-
-import com.android.ims.internal.Logger;
-
-/**
- * Device shutdown event receiver: automatically stops the RCS service
- */
-public class DeviceShutdown extends BroadcastReceiver {
-    /**
-     * The logger
-     */
-    private Logger logger = Logger.getLogger(this.getClass().getName());
-
-    @Override
-    public void onReceive(Context context, Intent intent) {
-        logger.debug("Device shutdown");
-
-        // Need wait RCS stack become unavailable before close RCS service.
-        RcsStackAdaptor.setInPowerDown(true);
-    }
-}
-
diff --git a/rcs/rcsservice/src/com/android/service/ims/LauncherUtils.java b/rcs/rcsservice/src/com/android/service/ims/LauncherUtils.java
deleted file mode 100644
index 407a5a7..0000000
--- a/rcs/rcsservice/src/com/android/service/ims/LauncherUtils.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
-
-package com.android.service.ims;
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.ComponentName;
-
-import com.android.ims.internal.Logger;
-import com.android.service.ims.RcsService;
-
-/**
- * Launcher utility functions
- *
- */
-public class LauncherUtils {
-    private static Logger logger = Logger.getLogger(LauncherUtils.class.getName());
-
-    /**
-     * Launch the Presence service.
-     *
-     * @param context application context
-     * @param boot Boot flag
-     */
-    public static void launchRcsService(Context context) {
-        logger.debug("Launch RCS service");
-
-        ComponentName comp = new ComponentName(context.getPackageName(),
-                RcsService.class.getName());
-        ComponentName service = context.startService(new Intent().setComponent(comp));
-        if (service == null) {
-            logger.error("Could Not Start Service " + comp.toString());
-        } else {
-            logger.debug("ImsService Auto Boot Started Successfully");
-        }
-    }
-
-    /**
-     * Stop the Presence service.
-     *
-     * @param context application context
-     */
-    public static void stopRcsService(Context context) {
-        logger.debug("Stop RCS service");
-
-        context.stopService(new Intent(context, RcsService.class));
-    }
-}
-
diff --git a/rcs/rcsservice/src/com/android/service/ims/RcsService.java b/rcs/rcsservice/src/com/android/service/ims/RcsService.java
deleted file mode 100644
index fa23603..0000000
--- a/rcs/rcsservice/src/com/android/service/ims/RcsService.java
+++ /dev/null
@@ -1,446 +0,0 @@
-/*
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
-
-package com.android.service.ims;
-
-import android.net.Uri;
-
-import java.util.List;
-
-import android.content.Intent;
-import android.app.PendingIntent;
-import android.content.IntentFilter;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.content.Context;
-import android.app.Service;
-import android.os.ServiceManager;
-import android.os.Handler;
-import android.database.ContentObserver;
-import android.content.BroadcastReceiver;
-import android.provider.Settings;
-import android.net.ConnectivityManager;
-import com.android.ims.ImsConfig.FeatureValueConstants;
-import com.android.ims.ImsManager;
-import com.android.ims.ImsConfig;
-import com.android.ims.ImsReasonInfo;
-import com.android.ims.ImsConnectionStateListener;
-import com.android.ims.ImsServiceClass;
-import com.android.ims.ImsException;
-import android.telephony.SubscriptionManager;
-
-import com.android.ims.RcsManager.ResultCode;
-import com.android.ims.internal.IRcsService;
-import com.android.ims.IRcsPresenceListener;
-import com.android.ims.internal.IRcsPresence;
-import com.android.ims.RcsPresence.PublishState;
-
-import com.android.ims.internal.Logger;
-import com.android.service.ims.RcsStackAdaptor;
-
-import com.android.service.ims.presence.PresencePublication;
-import com.android.service.ims.presence.PresenceSubscriber;
-
-public class RcsService extends Service{
-    /**
-     * The logger
-     */
-    private Logger logger = Logger.getLogger(this.getClass().getName());
-
-    final static String ACTION_IMS_FEATURE_STATUS_CHANGED =
-            "com.android.service.ims.presence.ims-feature-changed";
-    private static final int INVALID_SERVICE_ID = -1;
-    int mServiceId = INVALID_SERVICE_ID;
-
-    private RcsStackAdaptor mRcsStackAdaptor = null;
-    private PresencePublication mPublication = null;
-    private PresenceSubscriber mSubscriber = null;
-
-    private BroadcastReceiver mReceiver = null;
-
-    @Override
-    public void onCreate() {
-        super.onCreate();
-
-        logger.debug("RcsService onCreate");
-
-        mRcsStackAdaptor = RcsStackAdaptor.getInstance(this);
-
-        mPublication = new PresencePublication(mRcsStackAdaptor, this);
-        mRcsStackAdaptor.getListener().setPresencePublication(mPublication);
-
-        mSubscriber = new PresenceSubscriber(mRcsStackAdaptor, this);
-        mRcsStackAdaptor.getListener().setPresenceSubscriber(mSubscriber);
-        mPublication.setSubscriber(mSubscriber);
-
-        ConnectivityManager cm = ConnectivityManager.from(this);
-        if (cm != null) {
-            boolean enabled = Settings.Global.getInt(getContentResolver(),
-                    Settings.Global.MOBILE_DATA, 1) == 1;
-            logger.debug("Mobile data enabled status: " + (enabled ? "ON" : "OFF"));
-
-            onMobileDataEnabled(enabled);
-        }
-
-        // TODO: support MSIM
-        ServiceManager.addService("rcs", mBinder);
-
-        mObserver = new MobileDataContentObserver();
-        getContentResolver().registerContentObserver(
-                Settings.Global.getUriFor(Settings.Global.MOBILE_DATA),
-                false, mObserver);
-
-        mVtSettingObserver = new VtSettingContentObserver();
-        getContentResolver().registerContentObserver(
-                Settings.Global.getUriFor(Settings.Global.VT_IMS_ENABLED),
-                false, mVtSettingObserver);
-
-        registerImsConnectionStateListener();
-
-        mReceiver = new BroadcastReceiver() {
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                logger.print("onReceive intent=" + intent);
-                if(ImsManager.ACTION_IMS_SERVICE_UP.equalsIgnoreCase(
-                        intent.getAction())){
-                    handleImsServiceUp();
-                } else if(ImsManager.ACTION_IMS_SERVICE_DOWN.equalsIgnoreCase(
-                        intent.getAction())){
-                    handleImsServiceDown();
-                }
-            }
-        };
-
-        IntentFilter statusFilter = new IntentFilter();
-        statusFilter.addAction(ImsManager.ACTION_IMS_SERVICE_UP);
-        statusFilter.addAction(ImsManager.ACTION_IMS_SERVICE_DOWN);
-        registerReceiver(mReceiver, statusFilter);
-    }
-
-    public void handleImsServiceUp() {
-        // Don't check mServiceId since it wasn't reset to INVALID_SERVICE_ID when
-        // got ACTION_IMS_SERVICE_DOWN
-        // This is phone crash case. Reset mServiceId to INVALID_SERVICE_ID
-        mServiceId = INVALID_SERVICE_ID;
-        if(mPublication != null) {
-            mPublication.handleImsServiceUp();
-        }
-
-        registerImsConnectionStateListener();
-    }
-
-    public void handleImsServiceDown() {
-        // Don't close since it could close the wrong one when phone crashed and restarted.
-        //if((mImsManager != null) && (mServiceId != INVALID_SERVICE_ID)) {
-        //    mImsManager.close(mServiceId);
-        //    mServiceId = INVALID_SERVICE_ID;
-        //}
-        if(mPublication != null) {
-            mPublication.handleImsServiceDown();
-        }
-    }
-
-
-    @Override
-    public int onStartCommand(Intent intent, int flags, int startId) {
-        logger.debug("RcsService onStartCommand");
-
-        return super.onStartCommand(intent, flags, startId);
-    }
-
-    /**
-      * Cleans up when the service is destroyed
-      */
-    @Override
-    public void onDestroy() {
-        getContentResolver().unregisterContentObserver(mObserver);
-        getContentResolver().unregisterContentObserver(mVtSettingObserver);
-        if (mReceiver != null) {
-            unregisterReceiver(mReceiver);
-            mReceiver = null;
-        }
-
-        mRcsStackAdaptor.finish();
-        mPublication.finish();
-        mPublication = null;
-        mSubscriber = null;
-
-        logger.debug("RcsService onDestroy");
-        super.onDestroy();
-    }
-
-    public PresencePublication getPublication() {
-        return mPublication;
-    }
-
-    public PresenceSubscriber getPresenceSubscriber(){
-        return mSubscriber;
-    }
-
-    IRcsPresence.Stub mIRcsPresenceImpl = new IRcsPresence.Stub(){
-        /**
-         * Asyncrhonously request the latest capability for a given contact list.
-         * The result will be saved to DB directly if the contactNumber can be found in DB.
-         * And then send intent com.android.ims.presence.CAPABILITY_STATE_CHANGED to notify it.
-         * @param contactsNumber the contact list which will request capability.
-         *                       Currently only support phone number.
-         * @param listener the listener to get the response.
-         * @return the resultCode which is defined by ResultCode.
-         * @note framework uses only.
-         * @hide
-         */
-        public int requestCapability(List<String> contactsNumber,
-            IRcsPresenceListener listener){
-            logger.debug("calling requestCapability");
-            if(mSubscriber == null){
-                logger.debug("requestCapability, mPresenceSubscriber == null");
-                return ResultCode.ERROR_SERVICE_NOT_AVAILABLE;
-            }
-
-            return mSubscriber.requestCapability(contactsNumber, listener);
-         }
-
-        /**
-         * Asyncrhonously request the latest presence for a given contact.
-         * The result will be saved to DB directly if it can be found in DB. And then send intent
-         * com.android.ims.presence.AVAILABILITY_STATE_CHANGED to notify it.
-         * @param contactNumber the contact which will request available.
-         *                       Currently only support phone number.
-         * @param listener the listener to get the response.
-         * @return the resultCode which is defined by ResultCode.
-         * @note framework uses only.
-         * @hide
-         */
-        public int requestAvailability(String contactNumber, IRcsPresenceListener listener){
-            logger.debug("calling requestAvailability, contactNumber=" + contactNumber);
-            if(mSubscriber == null){
-                logger.error("requestAvailability, mPresenceSubscriber is null");
-                return ResultCode.ERROR_SERVICE_NOT_AVAILABLE;
-            }
-
-            // check availability cache (in RAM).
-            return mSubscriber.requestAvailability(contactNumber, listener, false);
-        }
-
-        /**
-         * Same as requestAvailability. but requestAvailability will consider throttle to avoid too
-         * fast call. Which means it will not send the request to network in next 60s for the same
-         * request.
-         * The error code SUBSCRIBE_TOO_FREQUENTLY will be returned under the case.
-         * But for this funcation it will always send the request to network.
-         *
-         * @see IRcsPresenceListener
-         * @see RcsManager.ResultCode
-         * @see ResultCode.SUBSCRIBE_TOO_FREQUENTLY
-         */
-        public int requestAvailabilityNoThrottle(String contactNumber,
-                IRcsPresenceListener listener) {
-            logger.debug("calling requestAvailabilityNoThrottle, contactNumber=" + contactNumber);
-            if(mSubscriber == null){
-                logger.error("requestAvailabilityNoThrottle, mPresenceSubscriber is null");
-                return ResultCode.ERROR_SERVICE_NOT_AVAILABLE;
-            }
-
-            // check availability cache (in RAM).
-            return mSubscriber.requestAvailability(contactNumber, listener, true);
-        }
-
-        public int getPublishState() throws RemoteException {
-            return mPublication.getPublishState();
-        }
-    };
-
-    @Override
-    public IBinder onBind(Intent arg0) {
-        return mBinder;
-    }
-
-    /**
-     * Receives notifications when Mobile data is enabled or disabled.
-     */
-    private class MobileDataContentObserver extends ContentObserver {
-        public MobileDataContentObserver() {
-            super(new Handler());
-        }
-
-        @Override
-        public void onChange(final boolean selfChange) {
-            boolean enabled = Settings.Global.getInt(getContentResolver(),
-                    Settings.Global.MOBILE_DATA, 1) == 1;
-            logger.debug("Mobile data enabled status: " + (enabled ? "ON" : "OFF"));
-            onMobileDataEnabled(enabled);
-        }
-    }
-
-    /** Observer to get notified when Mobile data enabled status changes */
-    private MobileDataContentObserver mObserver;
-
-    private void onMobileDataEnabled(final boolean enabled) {
-        logger.debug("Enter onMobileDataEnabled: " + enabled);
-        Thread thread = new Thread(new Runnable() {
-            @Override
-            public void run() {
-                try{
-                    if(mPublication != null){
-                        mPublication.onMobileDataChanged(enabled);
-                        return;
-                    }
-                }catch(Exception e){
-                    logger.error("Exception onMobileDataEnabled:", e);
-                }
-            }
-        }, "onMobileDataEnabled thread");
-
-        thread.start();
-    }
-
-
-    private VtSettingContentObserver mVtSettingObserver;
-
-    /**
-     * Receives notifications when Mobile data is enabled or disabled.
-     */
-    private class VtSettingContentObserver extends ContentObserver {
-        public VtSettingContentObserver() {
-            super(new Handler());
-        }
-
-        @Override
-        public void onChange(final boolean selfChange) {
-            boolean enabled = Settings.Global.getInt(getContentResolver(),
-                    Settings.Global.VT_IMS_ENABLED, 1) == 1;
-            logger.debug("vt enabled status: " + (enabled ? "ON" : "OFF"));
-
-            onVtEnabled(enabled);
-        }
-    }
-
-    private void onVtEnabled(boolean enabled) {
-        if(mPublication != null){
-            mPublication.onVtEnabled(enabled);
-        }
-    }
-
-    private final IRcsService.Stub mBinder = new IRcsService.Stub() {
-        /**
-         * return true if the rcs service is ready for use.
-         */
-        public boolean isRcsServiceAvailable(){
-            logger.debug("calling isRcsServiceAvailable");
-            if(mRcsStackAdaptor == null){
-                return false;
-            }
-
-            return mRcsStackAdaptor.isImsEnableState();
-        }
-
-        /**
-         * Gets the presence interface.
-         *
-         * @see IRcsPresence
-         */
-        public IRcsPresence getRcsPresenceInterface(){
-            return mIRcsPresenceImpl;
-        }
-    };
-
-    void registerImsConnectionStateListener() {
-        final Context context = this;
-        Thread t = new Thread() {
-            @Override
-            public void run() {
-                while (mServiceId == INVALID_SERVICE_ID) {
-                    try {
-                        ImsManager imsManager = ImsManager.getInstance(context,
-                                SubscriptionManager.getDefaultVoicePhoneId());
-                        if (imsManager != null) {
-                            mServiceId = imsManager.open(ImsServiceClass.RCS,
-                                    createIncomingCallPendingIntent(),
-                                    mImsConnectionStateListener);
-                        }
-                    } catch (ImsException e) {
-                        logger.error("register exception=", e);
-                    }
-
-                    if (mServiceId == INVALID_SERVICE_ID) {
-                        try {
-                            logger.print("register wait for imsservice");
-                            sleep(300);
-                        } catch (InterruptedException e) {
-                            logger.error("register exception=", e);
-                        }
-                    } else {
-                        logger.print("register imsservice ready mServiceId="+mServiceId);
-                    }
-                }
-            }
-        };
-
-        t.start();
-    }
-
-    private PendingIntent createIncomingCallPendingIntent() {
-        Intent intent = new Intent(ACTION_IMS_FEATURE_STATUS_CHANGED);
-        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
-        return PendingIntent.getBroadcast(this, 0, intent,
-                PendingIntent.FLAG_UPDATE_CURRENT);
-    }
-
-    private ImsConnectionStateListener mImsConnectionStateListener =
-        new ImsConnectionStateListener() {
-            @Override
-            public void onImsConnected() {
-                logger.debug("onImsConnected");
-                if(mRcsStackAdaptor != null) {
-                    mRcsStackAdaptor.checkSubService();
-                }
-
-                if(mPublication != null) {
-                    mPublication.onImsConnected();
-                }
-            }
-
-            @Override
-            public void onImsDisconnected(ImsReasonInfo imsReasonInfo) {
-                logger.debug("onImsDisconnected");
-                if(mPublication != null) {
-                    mPublication.onImsDisconnected();
-                }
-            }
-
-            @Override
-            public void onFeatureCapabilityChanged(final int serviceClass,
-                    final int[] enabledFeatures, final int[] disabledFeatures) {
-                logger.debug("onFeatureCapabilityChanged");
-                if(mPublication != null) {
-                    mPublication.onFeatureCapabilityChanged(serviceClass, enabledFeatures, disabledFeatures);
-                }
-            }
-        };
-}
-
diff --git a/rcs/rcsservice/src/com/android/service/ims/RcsServiceApp.java b/rcs/rcsservice/src/com/android/service/ims/RcsServiceApp.java
deleted file mode 100644
index c1f683d..0000000
--- a/rcs/rcsservice/src/com/android/service/ims/RcsServiceApp.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
-
-package com.android.service.ims;
-
-import android.app.Application;
-import android.content.Context;
-import com.android.ims.internal.Logger;
-import android.os.SystemProperties;
-
-public class RcsServiceApp extends Application {
-    private Logger logger = Logger.getLogger(this.getClass().getName());
-
-    public void onCreate() {
-        super.onCreate();
-        logger.debug("in onCreate() of RcsServiceApp");
-
-        LauncherUtils.launchRcsService(this);
-    }
-}
-
diff --git a/rcs/rcsservice/src/com/android/service/ims/RcsSettingUtils.java b/rcs/rcsservice/src/com/android/service/ims/RcsSettingUtils.java
deleted file mode 100644
index eb415cf..0000000
--- a/rcs/rcsservice/src/com/android/service/ims/RcsSettingUtils.java
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
-
-package com.android.service.ims;
-
-import java.lang.String;
-import android.telephony.TelephonyManager;
-import android.content.Context;
-import com.android.ims.ImsConfig;
-import com.android.ims.ImsManager;
-import com.android.ims.ImsException;
-import android.os.SystemProperties;
-
-import com.android.ims.RcsManager.ResultCode;
-
-import com.android.ims.internal.Logger;
-
-public class RcsSettingUtils{
-    /*
-     * The logger
-     */
-    static private Logger logger = Logger.getLogger("RcsSettingUtils");
-
-    public RcsSettingUtils() {
-    }
-
-    public static boolean isFeatureProvisioned(Context context,
-            int featureId, boolean defaultValue) {
-        // Don't need provision.
-        if (!context.getResources().getBoolean(
-                com.android.internal.R.bool.config_carrier_volte_provisioned)) {
-            return true;
-        }
-
-        boolean provisioned = defaultValue;
-        ImsManager imsManager = ImsManager.getInstance(context, 0);
-        if (imsManager != null) {
-            try {
-                ImsConfig imsConfig = imsManager.getConfigInterface();
-                if (imsConfig != null) {
-                    provisioned = imsConfig.getProvisionedValue(featureId)
-                            == ImsConfig.FeatureValueConstants.ON;
-                }
-            } catch (ImsException ex) {
-            }
-        }
-
-        logger.debug("featureId=" + featureId + " provisioned=" + provisioned);
-        return provisioned;
-    }
-
-    public static boolean isVowifiProvisioned(Context context) {
-        return isFeatureProvisioned(context,
-                ImsConfig.ConfigConstants.VOICE_OVER_WIFI_SETTING_ENABLED, false);
-    }
-
-    public static boolean isLvcProvisioned(Context context) {
-        return isFeatureProvisioned(context,
-                ImsConfig.ConfigConstants.LVC_SETTING_ENABLED, false);
-    }
-
-    public static boolean isEabProvisioned(Context context) {
-        return isFeatureProvisioned(context,
-                ImsConfig.ConfigConstants.EAB_SETTING_ENABLED, false);
-    }
-
-    public static int getSIPT1Timer(Context context) {
-        int sipT1Timer = 0;
-
-        ImsManager imsManager = ImsManager.getInstance(context, 0);
-        if (imsManager != null) {
-            try {
-                ImsConfig imsConfig = imsManager.getConfigInterface();
-                if (imsConfig != null) {
-                    sipT1Timer = imsConfig.getProvisionedValue(
-                            ImsConfig.ConfigConstants.SIP_T1_TIMER);
-                }
-            } catch (ImsException ex) {
-            }
-        }
-
-        logger.debug("sipT1Timer=" + sipT1Timer);
-        return sipT1Timer;
-    }
-
-    /**
-     * Capability discovery status of Enabled (1), or Disabled (0).
-     */
-    public static boolean getCapabilityDiscoveryEnabled(Context context) {
-        boolean capabilityDiscoveryEnabled = false;
-
-        ImsManager imsManager = ImsManager.getInstance(context, 0);
-        if (imsManager != null) {
-            try {
-                ImsConfig imsConfig = imsManager.getConfigInterface();
-                if (imsConfig != null) {
-                    capabilityDiscoveryEnabled = imsConfig.getProvisionedValue(
-                            ImsConfig.ConfigConstants.CAPABILITY_DISCOVERY_ENABLED)
-                            == ImsConfig.FeatureValueConstants.ON;
-                }
-            } catch (ImsException ex) {
-            }
-        }
-
-        logger.debug("capabilityDiscoveryEnabled=" + capabilityDiscoveryEnabled);
-        return capabilityDiscoveryEnabled;
-    }
-
-    /**
-     * The Maximum number of MDNs contained in one Request Contained List.
-     */
-    public static int getMaxNumbersInRCL(Context context) {
-        int maxNumbersInRCL = 100;
-
-        ImsManager imsManager = ImsManager.getInstance(context, 0);
-        if (imsManager != null) {
-            try {
-                ImsConfig imsConfig = imsManager.getConfigInterface();
-                if (imsConfig != null) {
-                    maxNumbersInRCL = imsConfig.getProvisionedValue(
-                            ImsConfig.ConfigConstants.MAX_NUMENTRIES_IN_RCL);
-                }
-            } catch (ImsException ex) {
-            }
-        }
-
-        logger.debug("maxNumbersInRCL=" + maxNumbersInRCL);
-        return maxNumbersInRCL;
-    }
-
-    /**
-     * Expiration timer for subscription of a Request Contained List, used in capability polling.
-     */
-    public static int getCapabPollListSubExp(Context context) {
-        int capabPollListSubExp = 30;
-
-        ImsManager imsManager = ImsManager.getInstance(context, 0);
-        if (imsManager != null) {
-            try {
-                ImsConfig imsConfig = imsManager.getConfigInterface();
-                if (imsConfig != null) {
-                    capabPollListSubExp = imsConfig.getProvisionedValue(
-                            ImsConfig.ConfigConstants.CAPAB_POLL_LIST_SUB_EXP);
-                }
-            } catch (ImsException ex) {
-            }
-        }
-
-        logger.debug("capabPollListSubExp=" + capabPollListSubExp);
-        return capabPollListSubExp;
-    }
-
-    /**
-     * Peiod of time the availability information of a contact is cached on device.
-     */
-    public static int getAvailabilityCacheExpiration(Context context) {
-        int availabilityCacheExpiration = 30;
-
-        ImsManager imsManager = ImsManager.getInstance(context, 0);
-        if (imsManager != null) {
-            try {
-                ImsConfig imsConfig = imsManager.getConfigInterface();
-                if (imsConfig != null) {
-                    availabilityCacheExpiration = imsConfig.getProvisionedValue(
-                            ImsConfig.ConfigConstants.AVAILABILITY_CACHE_EXPIRATION);
-                }
-            } catch (ImsException ex) {
-            }
-        }
-
-        logger.debug("availabilityCacheExpiration=" + availabilityCacheExpiration);
-        return availabilityCacheExpiration;
-    }
-
-    public static boolean isMobileDataEnabled(Context context) {
-        boolean mobileDataEnabled = false;
-        ImsManager imsManager = ImsManager.getInstance(context, 0);
-        if (imsManager != null) {
-            try {
-                ImsConfig imsConfig = imsManager.getConfigInterface();
-                if (imsConfig != null) {
-                    mobileDataEnabled = imsConfig.getProvisionedValue(
-                            ImsConfig.ConfigConstants.MOBILE_DATA_ENABLED)
-                            == ImsConfig.FeatureValueConstants.ON;
-                }
-            } catch (ImsException ex) {
-            }
-        }
-
-        logger.debug("mobileDataEnabled=" + mobileDataEnabled);
-        return mobileDataEnabled;
-    }
-
-    public static void setMobileDataEnabled(Context context, boolean mobileDataEnabled) {
-        logger.debug("mobileDataEnabled=" + mobileDataEnabled);
-        ImsManager imsManager = ImsManager.getInstance(context, 0);
-        if (imsManager != null) {
-            try {
-                ImsConfig imsConfig = imsManager.getConfigInterface();
-                if (imsConfig != null) {
-                    imsConfig.setProvisionedValue(
-                            ImsConfig.ConfigConstants.MOBILE_DATA_ENABLED, mobileDataEnabled?
-                            ImsConfig.FeatureValueConstants.ON:ImsConfig.FeatureValueConstants.OFF);
-                }
-            } catch (ImsException ex) {
-                logger.debug("ImsException", ex);
-            }
-        }
-    }
-
-    public static int getPublishThrottle(Context context) {
-        int publishThrottle = 60000;
-
-        ImsManager imsManager = ImsManager.getInstance(context, 0);
-        if (imsManager != null) {
-            try {
-                ImsConfig imsConfig = imsManager.getConfigInterface();
-                if (imsConfig != null) {
-                    publishThrottle = imsConfig.getProvisionedValue(
-                            ImsConfig.ConfigConstants.SOURCE_THROTTLE_PUBLISH);
-                }
-            } catch (ImsException ex) {
-            }
-        }
-
-        logger.debug("publishThrottle=" + publishThrottle);
-        return publishThrottle;
-    }
-}
-
diff --git a/rcs/rcsservice/src/com/android/service/ims/RcsStackAdaptor.java b/rcs/rcsservice/src/com/android/service/ims/RcsStackAdaptor.java
deleted file mode 100644
index ebf9370..0000000
--- a/rcs/rcsservice/src/com/android/service/ims/RcsStackAdaptor.java
+++ /dev/null
@@ -1,710 +0,0 @@
-/*
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
-
-package com.android.service.ims;
-
-import java.util.List;
-import java.util.concurrent.Semaphore;
-import java.util.concurrent.TimeUnit;
-
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.content.pm.ServiceInfo;
-import android.content.Context;
-import android.content.Intent;
-import android.app.PendingIntent;
-import android.content.IntentFilter;
-import android.content.ServiceConnection;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.Message;
-import android.os.RemoteException;
-import android.telephony.TelephonyManager;
-import android.app.AlarmManager;
-import android.os.SystemClock;
-import android.os.SystemProperties;
-import com.android.ims.ImsConfig;
-import com.android.ims.ImsManager;
-import com.android.ims.ImsException;
-import android.telephony.SubscriptionManager;
-
-import com.android.ims.IRcsPresenceListener;
-import com.android.ims.RcsPresence;
-import com.android.ims.RcsManager.ResultCode;
-import com.android.ims.RcsPresence.PublishState;
-
-import com.android.ims.internal.Logger;
-import com.android.ims.internal.ContactNumberUtils;
-import com.android.service.ims.presence.PresencePublication;
-import com.android.service.ims.R;
-
-import com.android.ims.internal.uce.presence.IPresenceService;
-import com.android.ims.internal.uce.presence.PresCapInfo;
-import com.android.ims.internal.uce.common.CapInfo;
-import com.android.ims.internal.uce.uceservice.IUceService;
-import com.android.ims.internal.uce.uceservice.ImsUceManager;
-import com.android.ims.internal.uce.common.UceLong;
-import com.android.ims.internal.uce.common.StatusCode;
-
-import com.android.ims.IRcsPresenceListener;
-import com.android.ims.RcsPresenceInfo;
-
-import com.android.service.ims.presence.StackListener;
-import com.android.service.ims.presence.PresenceInfoParser;
-import com.android.service.ims.presence.AlarmBroadcastReceiver;
-
-public class RcsStackAdaptor{
-    private static final boolean DEBUG = true;
-
-    // The logger
-    private Logger logger = Logger.getLogger(this.getClass().getName());
-
-    private static final int PRESENCE_INIT_IMS_UCE_SERVICE = 1;
-
-    private Context mContext = null;
-
-    // true when the stack presence service got available. (Called IQPresListener_ServiceAvailable)
-    private volatile boolean mImsEnableState = false;
-
-    // provision status can be set by both subscribe and pubilish
-    // for unprovisioned for 403 or 404
-    private volatile int mPublishingState = PublishState.PUBLISH_STATE_NOT_PUBLISHED;
-
-    // It is initializing the stack presence service.
-    private volatile boolean mIsIniting = false;
-
-    // The time which the stack presence service got initialized.
-    private volatile long mLastInitSubService = -1; //last time which inited the sub service
-
-    // Used for synchronizing
-    private final Object mSyncObj = new Object();
-
-    // We need wait RCS stack become unavailable before close RCS service.
-    static private boolean sInPowerDown = false;
-
-    // This could happen when the stack first launch or modem panic.
-    private static final int PRESENCE_INIT_TYPE_RCS_SERVICE_AVAILABLE =1;
-
-    // The initialization was triggered by retry.
-    private static final int PRESENCE_INIT_TYPE_RETRY = 2;
-
-    // The initialization was triggered by retry.
-    private static final int PRESENCE_INIT_TYPE_IMS_REGISTERED = 3;
-
-    // The maximum retry count for initializing the stack service.
-    private static final int MAX_RETRY_COUNT = 6;//Maximum time is 64s
-
-    public boolean isImsEnableState() {
-        return mImsEnableState;
-    }
-
-    synchronized public void setImsEnableState(boolean imsEnableState) {
-        logger.debug("imsEnableState=" + imsEnableState);
-
-        mImsEnableState = imsEnableState;
-    }
-
-    // The UCE manager for RCS stack.
-    private ImsUceManager mImsUceManager = null;
-
-    // The stack RCS Service instance.
-    private IUceService mStackService = null;
-
-    // The stack presence service
-    private IPresenceService mStackPresService = null;
-
-    // The stack Presence Service handle.
-    private int  mStackPresenceServiceHandle;
-
-    // The listener which listen to the response for presence service.
-    private StackListener mListenerHandler = null;
-
-    // The handler of the listener.
-    private UceLong mListenerHandle = new UceLong();
-
-    // The singleton.
-    private static RcsStackAdaptor sInstance = null;
-
-    // Constructor
-    private RcsStackAdaptor(Context context) {
-        mContext = context;
-
-        init();
-    }
-
-    public static synchronized RcsStackAdaptor getInstance(Context context) {
-        if ((sInstance == null) && (context != null)) {
-            sInstance = new RcsStackAdaptor(context);
-        }
-
-        return sInstance;
-    }
-
-    private Handler mMsgHandler = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            super.handleMessage(msg);
-
-            logger.debug( "Thread=" + Thread.currentThread().getName() + " received "
-                    + msg);
-            if(msg == null){
-                logger.error("msg=null");
-                return;
-           }
-
-            switch (msg.what) {
-                case PRESENCE_INIT_IMS_UCE_SERVICE:
-                    logger.debug("handleMessage  msg=PRESENCE_INIT_IMS_UCE_SERVICE" );
-                    doInitImsUceService();
-                break;
-
-                default:
-                    logger.debug("handleMessage unknown msg=" + msg.what);
-            }
-        }
-    };
-
-    public StackListener getListener(){
-        return mListenerHandler;
-    }
-
-    public int checkStackAndPublish(){
-        if(!RcsSettingUtils.getCapabilityDiscoveryEnabled(mContext)){
-            logger.error("getCapabilityDiscoveryEnabled = false");
-            return ResultCode.ERROR_SERVICE_NOT_ENABLED;
-        }
-
-        int ret = checkStackStatus();
-        if(ret !=ResultCode.SUCCESS){
-            logger.error("checkStackAndPublish ret=" + ret);
-            return ret;
-        }
-
-        if(!isPublished()){
-            logger.error(
-                    "checkStackAndPublish ERROR_SERVICE_NOT_PUBLISHED");
-            return ResultCode.ERROR_SERVICE_NOT_PUBLISHED;
-        }
-
-        return ResultCode.SUCCESS;
-    }
-
-    private boolean isPublished(){
-        if(getPublishState() != PublishState.PUBLISH_STATE_200_OK){
-            logger.error("Didnt' publish properly");
-            return false;
-        }
-
-        return true;
-    }
-
-    public void setPublishState(int publishState) {
-        logger.print("mPublishingState=" + mPublishingState + " publishState=" + publishState);
-        if(mPublishingState != publishState) {
-            // save it for recovery when PresenceService crash.
-            SystemProperties.set("rcs.publish.status",
-                    String.valueOf(publishState));
-
-            // broadcast publish state change intent
-            Intent publishIntent = new Intent(RcsPresence.ACTION_PUBLISH_STATE_CHANGED);
-            publishIntent.putExtra(RcsPresence.EXTRA_PUBLISH_STATE,
-                    publishState);
-            mContext.sendStickyBroadcast(publishIntent);
-        }
-
-        mPublishingState = publishState;
-    }
-
-    public int getPublishState(){
-        return mPublishingState;
-    }
-
-    public int checkStackStatus(){
-        if(!RcsSettingUtils.isEabProvisioned(mContext)) {
-            logger.error("Didn't get EAB provisioned by DM");
-            return ResultCode.ERROR_SERVICE_NOT_ENABLED;
-        }
-
-        // Don't send request to RCS stack when it is under powering off.
-        // RCS stack is sending UNPUBLISH. It could get race PUBLISH trigger under the case.
-        if(sInPowerDown) {
-            logger.error("checkStackStatus: under powering off");
-            return ResultCode.ERROR_SERVICE_NOT_AVAILABLE;
-        }
-
-        if(mStackService == null){
-            logger.error("checkStackStatus: mStackService == null");
-            return ResultCode.ERROR_SERVICE_NOT_AVAILABLE;
-        }
-
-        if(mStackPresService == null){
-            logger.error("Didn't init sub rcs service.");
-            return ResultCode.ERROR_SERVICE_NOT_AVAILABLE;
-        }
-
-        if(!mImsEnableState){
-            logger.error("mImsEnableState = false");
-            return ResultCode.ERROR_SERVICE_NOT_AVAILABLE;
-        }
-
-        return ResultCode.SUCCESS;
-    }
-
-    public int requestCapability(String[] formatedContacts, int taskId){
-        logger.print("requestCapability formatedContacts=" + formatedContacts);
-
-        int ret = ResultCode.SUCCESS;
-        try{
-            StatusCode retCode;
-            if(formatedContacts.length == 1){
-                retCode = mStackPresService.getContactCap(
-                        mStackPresenceServiceHandle, formatedContacts[0], taskId);
-            }else{
-                retCode = mStackPresService.getContactListCap(
-                        mStackPresenceServiceHandle, formatedContacts, taskId);
-            }
-            logger.print("GetContactListCap retCode=" + retCode);
-
-            ret = RcsUtils.statusCodeToResultCode(retCode.getStatusCode());
-            logger.debug("requestCapability ret=" + ret);
-        }catch(Exception e){
-            logger.error("requestCapability exception", e);
-            ret = ResultCode.ERROR_SERVICE_NOT_AVAILABLE;
-        }
-
-        return  ret;
-    }
-
-    public int requestAvailability(String formatedContact, int taskId){
-        logger.debug("requestAvailability ...");
-
-        int ret = ResultCode.SUCCESS;
-        try{
-            StatusCode retCode = mStackPresService.getContactCap(
-                    mStackPresenceServiceHandle, formatedContact, taskId);
-            logger.print("getContactCap retCode=" + retCode);
-
-            ret = RcsUtils.statusCodeToResultCode(retCode.getStatusCode());
-
-            logger.debug("requestAvailability ret=" + ret);
-        }catch(Exception e){
-            logger.error("requestAvailability exception", e);
-            ret = ResultCode.ERROR_SERVICE_NOT_AVAILABLE;
-        }
-
-        return  ret;
-    }
-
-    public int requestPublication(RcsPresenceInfo presenceInfo, IRcsPresenceListener listener) {
-        logger.debug("requestPublication ...");
-
-         // Don't use checkStackAndPublish()
-         // since it will check publish status which in dead loop.
-         int ret = checkStackStatus();
-         if(ret != ResultCode.SUCCESS){
-             logger.error("requestPublication ret=" + ret);
-             return ret;
-         }
-
-        TelephonyManager teleMgr = (TelephonyManager) mContext.getSystemService(
-            Context.TELEPHONY_SERVICE);
-        if(teleMgr == null){
-            logger.error("teleMgr = null");
-            return PresencePublication.PUBLISH_GENIRIC_FAILURE;
-        }
-
-        String myNumUri = null;
-        String myDomain = teleMgr.getIsimDomain();
-        logger.debug("myDomain=" + myDomain);
-        if(myDomain != null && myDomain.length() !=0){
-            String[] impu = teleMgr.getIsimImpu();
-
-            if(impu !=null){
-                for(int i=0; i<impu.length; i++){
-                    logger.debug("impu[" + i + "]=" + impu[i]);
-                    if(impu[i] != null && impu[i].startsWith("sip:") &&
-                            impu[i].endsWith(myDomain)){
-                        myNumUri = impu[i];
-                        break;
-                    }
-                }
-            }
-        }
-
-        String myNumber = PresenceInfoParser.getPhoneFromUri(myNumUri);
-
-        if(myNumber == null){
-            myNumber = ContactNumberUtils.getDefault().format(teleMgr.getLine1Number());
-            if(myDomain != null && myDomain.length() !=0){
-                myNumUri = "sip:" + myNumber + "@" + myDomain;
-            }else{
-                myNumUri = "tel:" + myNumber;
-            }
-        }
-
-        logger.print("myNumUri=" + myNumUri + " myNumber=" + myNumber);
-        if(myNumUri == null || myNumber == null){
-            logger.error("Didn't find number or impu.");
-            return PresencePublication.PUBLISH_GENIRIC_FAILURE;
-        }
-
-        int taskId = TaskManager.getDefault().addPublishTask(myNumber, listener);
-        try{
-            PresCapInfo pMyCapInfo = new PresCapInfo();
-            // Fill cap info
-            pMyCapInfo.setContactUri(myNumUri);
-
-            CapInfo capInfo = new CapInfo();
-            capInfo.setIpVoiceSupported(presenceInfo.getServiceState(
-                    RcsPresenceInfo.ServiceType.VOLTE_CALL)
-                    == RcsPresenceInfo.ServiceState.ONLINE);
-            capInfo.setIpVideoSupported(presenceInfo.getServiceState(
-                    RcsPresenceInfo.ServiceType.VT_CALL)
-                    == RcsPresenceInfo.ServiceState.ONLINE);
-            capInfo.setCdViaPresenceSupported(true);
-
-            capInfo.setFtSupported(false); // TODO: support FT
-            capInfo.setImSupported(false);//TODO: support chat
-            capInfo.setFullSnFGroupChatSupported(false); //TODO: support chat
-
-            pMyCapInfo.setCapInfo(capInfo);
-
-            logger.print( "myNumUri = " + myNumUri
-                    + " audioSupported =  " + capInfo.isIpVoiceSupported()
-                    + " videoSupported=  " + capInfo.isIpVideoSupported()
-                    );
-
-
-            StatusCode status = mStackPresService.publishMyCap(
-                    mStackPresenceServiceHandle, pMyCapInfo, taskId);
-            logger.print("PublishMyCap status=" + status.getStatusCode());
-
-            ret = RcsUtils.statusCodeToResultCode(status.getStatusCode());
-
-            logger.debug("requestPublication ret=" + ret);
-            if(ret != ResultCode.SUCCESS){
-                logger.error("requestPublication remove taskId=" + taskId);
-                TaskManager.getDefault().removeTask(taskId);
-                return ret;
-            }
-        }catch(RemoteException e){
-            e.printStackTrace();
-            logger.error("Exception when call mStackPresService.getContactCap");
-            logger.error("requestPublication remove taskId=" + taskId);
-            TaskManager.getDefault().removeTask(taskId);
-
-            return ResultCode.ERROR_SERVICE_NOT_AVAILABLE;
-        }
-
-        return  ResultCode.SUCCESS;
-    }
-
-    private void createListeningThread() {
-        HandlerThread listenerThread = new HandlerThread("Listener",
-                android.os.Process.THREAD_PRIORITY_BACKGROUND);
-
-        listenerThread.start();
-        Looper listenerLooper = listenerThread.getLooper();
-        mListenerHandler = new StackListener(mContext, listenerLooper);
-    }
-
-    private void initImsUceService(){
-        // Send message to avoid ANR
-        Message reinitMessage = mMsgHandler.obtainMessage(
-                PRESENCE_INIT_IMS_UCE_SERVICE, null);
-        mMsgHandler.sendMessage(reinitMessage);
-    }
-
-    synchronized private void doInitImsUceService(){
-        logger.debug("doInitImsUceService");
-
-        if(mStackService != null){
-            logger.debug("doInitImsUceService mStackService != null");
-            return;
-        }
-
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(ImsUceManager.ACTION_UCE_SERVICE_UP);
-        filter.addAction(ImsUceManager.ACTION_UCE_SERVICE_DOWN);
-
-        mRcsServiceReceiver = new BroadcastReceiver() {
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                // do something based on the intent's action
-                logger.print("onReceive intent " + intent);
-                String action = intent.getAction();
-                if(ImsUceManager.ACTION_UCE_SERVICE_UP.equals(action)) {
-                     synchronized(mSyncObj){
-                         startInitPresenceTimer(0, PRESENCE_INIT_TYPE_RCS_SERVICE_AVAILABLE);
-                     }
-                 } else if(ImsUceManager.ACTION_UCE_SERVICE_DOWN.equals(action)) {
-                     synchronized(mSyncObj){
-                         clearImsUceService();
-                     }
-                 } else {
-                     logger.debug("unknown intent " + intent);
-                 }
-             }
-        };
-
-        mContext.registerReceiver(mRcsServiceReceiver, filter);
-
-        if(mImsUceManager == null) {
-            mImsUceManager = ImsUceManager.getInstance(mContext,
-                    SubscriptionManager.from(mContext).getDefaultDataPhoneId());
-            if(mImsUceManager == null) {
-                logger.error("Can't init mImsUceManager");
-                return;
-            }
-        }
-
-        mImsUceManager.createUceService(false);
-        mStackService = mImsUceManager.getUceServiceInstance();
-        logger.debug("doInitImsUceService mStackService=" + mStackService);
-
-        if(mStackService != null) {
-            startInitPresenceTimer(0, PRESENCE_INIT_TYPE_RCS_SERVICE_AVAILABLE);
-        }
-    }
-
-    private PendingIntent mRetryAlarmIntent = null;
-    public static final String ACTION_RETRY_ALARM = "com.android.service.ims.presence.retry";
-    private AlarmManager mAlarmManager = null;
-    private BroadcastReceiver mRcsServiceReceiver = null;
-
-    /*
-     * Init All Sub service of RCS
-     */
-    int initAllSubRcsServices(IUceService uceService, int currentRetry) {
-        int ret = -1;
-        synchronized (mSyncObj){
-            // we could receive useless retry since we could fail to cancel the retry timer.
-            // We need to ignore such retry if the sub service had been initialized already.
-            if(mStackPresService != null && currentRetry>0){
-                logger.debug("mStackPresService != null and currentRetry=" + currentRetry +
-                        " ignore it");
-                return 0;
-            }
-
-            logger.debug("Init All Services Under RCS uceService=" + uceService);
-            if(uceService == null){
-                logger.error("initAllServices : uceService is NULL  ");
-                mIsIniting = false;
-                mLastInitSubService = -1;
-                return ret;
-            }
-
-            try {
-                if(mStackPresService != null){
-                    logger.print("RemoveListener and QRCSDestroyPresService");
-                    mStackPresService.removeListener(mStackPresenceServiceHandle,
-                            mListenerHandle);
-                    uceService.destroyPresenceService(mStackPresenceServiceHandle);
-
-                    mStackPresService = null;
-                }
-
-                boolean serviceStatus = false;
-                serviceStatus = uceService.getServiceStatus();
-                if (true == serviceStatus && mStackPresService == null) {//init only once.
-                    logger.print("initAllService : serviceStatus =  true ");
-                    logger.debug("Create PresService");
-                    mStackPresenceServiceHandle = mStackService.createPresenceService(
-                            mListenerHandler.mPresenceListener, mListenerHandle);
-                    mStackPresService = mStackService.getPresenceService();
-                    ret = 0;
-                 } else {
-                    logger.error("initAllService : serviceStatus =  false ");
-                }
-            } catch (RemoteException e) {
-                logger.error("initAllServices :  DeadObjectException dialog  ");
-                e.printStackTrace();
-            }
-            mIsIniting = false;
-        }
-        return ret;
-    }
-
-    // Init sub service when IMS get registered.
-    public void checkSubService() {
-        logger.debug("checkSubService");
-        if(mStackPresService == null) {
-            // Cancel the retry timer.
-            if(mIsIniting){
-                if(mRetryAlarmIntent != null){
-                    mAlarmManager.cancel(mRetryAlarmIntent);
-                    mRetryAlarmIntent = null;
-                }
-                mIsIniting = false;
-            }
-
-            // force to init imediately.
-            startInitPresenceTimer(0, PRESENCE_INIT_TYPE_IMS_REGISTERED);
-        }
-    }
-
-    public void startInitThread(int times){
-        final int currentRetry = times;
-        Thread thread = new Thread(new Runnable() {
-            @Override
-            public void run() {
-                if (currentRetry >=0 && currentRetry <= MAX_RETRY_COUNT) {
-                    refreshUceService();
-
-                    if (initAllSubRcsServices(mStackService, currentRetry) >=0){
-                        logger.debug("init sub rcs service successfully.");
-                        mAlarmManager.cancel(mRetryAlarmIntent);
-                    } else {
-                        startInitPresenceTimer(currentRetry + 1, PRESENCE_INIT_TYPE_RETRY);
-                    }
-                } else {
-                    logger.debug("Retry times=" + currentRetry);
-                    mAlarmManager.cancel(mRetryAlarmIntent);
-                }
-            }
-        }, "initAllSubRcsServices thread");
-
-        thread.start();
-    }
-
-    private void init() {
-        createListeningThread();
-        logger.debug("after createListeningThread");
-
-        if(mAlarmManager == null){
-            mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
-        }
-
-        initImsUceService();
-
-        setInPowerDown(false);
-        logger.debug("init finished");
-    }
-
-    private void startInitPresenceTimer(int times, int initType){
-        synchronized (mSyncObj){
-            logger.print("set the retry alarm, times=" + times + " initType=" + initType +
-                    " mIsIniting=" + mIsIniting);
-            if(mIsIniting){
-                //initing is on going in 5 seconds, discard this one.
-                if(mLastInitSubService != -1 &&
-                        System.currentTimeMillis() - mLastInitSubService < 5000){
-                    logger.print("already in initing. ignore it");
-                    return;
-                }//else suppose the init has problem. so continue
-            }
-
-            mIsIniting = true;
-
-            Intent intent = new Intent(ACTION_RETRY_ALARM);
-            intent.putExtra("times", times);
-            intent.setClass(mContext, AlarmBroadcastReceiver.class);
-            mRetryAlarmIntent = PendingIntent.getBroadcast(mContext, 0, intent,
-                    PendingIntent.FLAG_UPDATE_CURRENT);
-
-            // Wait for 1s to ignore duplicate init request as possible as we can.
-            long timeSkip = 1000;
-            if(times < 0 || times >= MAX_RETRY_COUNT){
-                times = MAX_RETRY_COUNT;
-            }
-
-            //Could failed to cancel a timer in 1s. So use exponential retry to make sure it
-            //will be stopped for non-VoLte SIM.
-            timeSkip = (timeSkip << times);
-            logger.debug("timeSkip = " + timeSkip);
-
-            mLastInitSubService = System.currentTimeMillis();
-
-            //the timer intent could have a longer delay. call directly at first time
-            if(times == 0) {
-                startInitThread(0);
-            } else {
-                mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP,
-                        SystemClock.elapsedRealtime() + timeSkip, mRetryAlarmIntent);
-            }
-        }
-    }
-
-    private void refreshUceService() {
-        logger.debug("refreshUceService mImsUceManager=" + mImsUceManager +
-                " mStackService=" + mStackService);
-
-        if(mImsUceManager == null) {
-            mImsUceManager = ImsUceManager.getInstance(mContext,
-                    SubscriptionManager.from(mContext).getDefaultDataPhoneId());
-            if(mImsUceManager == null) {
-                logger.error("Can't init mImsUceManager");
-                return;
-            }
-        }
-
-        if(mStackService == null) {
-            mImsUceManager.createUceService(false);
-            mStackService = mImsUceManager.getUceServiceInstance();
-        }
-
-        logger.debug("refreshUceService mStackService=" + mStackService);
-    }
-
-    private void clearImsUceService() {
-        mImsUceManager = null;
-        mStackService = null;
-        mStackPresService = null;
-    }
-
-    public void finish() {
-        if(mRetryAlarmIntent != null){
-            mAlarmManager.cancel(mRetryAlarmIntent);
-            mRetryAlarmIntent = null;
-        }
-
-        if (mRcsServiceReceiver != null) {
-            mContext.unregisterReceiver(mRcsServiceReceiver);
-            mRcsServiceReceiver = null;
-        }
-
-        clearImsUceService();
-    }
-
-    protected void finalize() throws Throwable {
-        finish();
-    }
-
-    static public boolean isInPowerDown() {
-        return sInPowerDown;
-    }
-
-    static void setInPowerDown(boolean inPowerDown) {
-        sInPowerDown = inPowerDown;
-    }
-}
-
diff --git a/rcs/rcsservice/src/com/android/service/ims/RcsUtils.java b/rcs/rcsservice/src/com/android/service/ims/RcsUtils.java
deleted file mode 100644
index bbfacd2..0000000
--- a/rcs/rcsservice/src/com/android/service/ims/RcsUtils.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
-
-package com.android.service.ims;
-
-import java.lang.String;
-import android.telephony.TelephonyManager;
-import android.content.Context;
-
-import com.android.ims.internal.uce.common.StatusCode;
-
-import com.android.ims.RcsManager.ResultCode;
-
-import com.android.ims.internal.Logger;
-
-public class RcsUtils{
-    /*
-     * The logger
-     */
-    static private Logger logger = Logger.getLogger("RcsUtils");
-
-    public RcsUtils() {
-    }
-
-    static public int statusCodeToResultCode(int sipStatusCode){
-        if(sipStatusCode == StatusCode.UCE_SUCCESS ||
-            sipStatusCode == StatusCode.UCE_SUCCESS_ASYC_UPDATE){
-            return ResultCode.SUCCESS;
-        }
-
-        if(sipStatusCode == StatusCode.UCE_INVALID_PARAM) {
-            return ResultCode.SUBSCRIBE_INVALID_PARAM;
-        }
-
-        if(sipStatusCode == StatusCode.UCE_FETCH_ERROR) {
-            return ResultCode.SUBSCRIBE_FETCH_ERROR;
-        }
-
-        if(sipStatusCode == StatusCode.UCE_REQUEST_TIMEOUT) {
-            return ResultCode.SUBSCRIBE_REQUEST_TIMEOUT;
-        }
-
-        if(sipStatusCode == StatusCode.UCE_INSUFFICIENT_MEMORY) {
-            return ResultCode.SUBSCRIBE_INSUFFICIENT_MEMORY;
-        }
-
-        if(sipStatusCode == StatusCode.UCE_LOST_NET) {
-            return ResultCode.SUBSCRIBE_LOST_NETWORK;
-        }
-
-        if(sipStatusCode == StatusCode.UCE_NOT_SUPPORTED){
-            return ResultCode.SUBSCRIBE_NOT_SUPPORTED;
-        }
-
-        if(sipStatusCode == StatusCode.UCE_NOT_FOUND){
-            return ResultCode.SUBSCRIBE_NOT_FOUND;
-        }
-
-        if(sipStatusCode == StatusCode.UCE_FAILURE ||
-                sipStatusCode == StatusCode.UCE_INVALID_SERVICE_HANDLE ||
-                sipStatusCode == StatusCode.UCE_INVALID_LISTENER_HANDLE){
-            return ResultCode.SUBSCRIBE_GENERIC;
-        }
-
-        return ResultCode.SUBSCRIBE_GENERIC;
-    }
-
-    static public String toContactString(String[] contacts) {
-        if(contacts == null) {
-            return null;
-        }
-
-         String result = "";
-        for(int i=0; i<contacts.length; i++) {
-            result += contacts[i];
-            if(i != contacts.length -1) {
-                result += ";";
-            }
-        }
-
-        return result;
-    }
-}
-
diff --git a/rcs/rcsservice/src/com/android/service/ims/Task.java b/rcs/rcsservice/src/com/android/service/ims/Task.java
deleted file mode 100644
index a58aebf..0000000
--- a/rcs/rcsservice/src/com/android/service/ims/Task.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
-
-package com.android.service.ims;
-
-import java.util.Set;
-import java.util.HashMap;
-import java.util.List;
-import java.util.ArrayList;
-import android.os.RemoteException;
-
-import com.android.ims.internal.Logger;
-import com.android.ims.IRcsPresenceListener;
-
-/**
- * Task
- */
-public class Task{
-    /*
-     * The logger
-     */
-    private Logger logger = Logger.getLogger(this.getClass().getName());
-
-    // filled before send the reques
-    public int mTaskId;
-
-    // filled before send the request
-    // map to QRCS_PRES_CMD_ID
-    // QRCS_PRES_CMD_PUBLISHMYCAP
-    // QRCS_PRES_CMD_GETCONTACTCAP, we use it for capability
-    // QRCS_PRES_CMD_GETCONTACTLISTCAP, we use it for availability
-    // QRCS_PRES_CMD_SETNEWFEATURETAG
-    public int mCmdId;
-
-    // filled after IQPresListener_CMDStatus
-    // QRCS_STATUSCODE, possible values are:
-    // QRCS_SUCCESS
-    // QRCS_FAILURE
-    // QRCS_SUCCESS_ASYC_UPDATE
-    // QRCS_INVALID_SERVICE_HANDLE
-    // QRCS_INVALID_LISTENER_HANDLE
-    // QRCS_INVALID_PARAM
-    // QRCS_FETCH_ERROR
-    // QRCS_REQUEST_TIMEOUT
-    // QRCS_INSUFFICIENT_MEMORY
-    // QRCS_LOST_NET
-    // QRCS_NOT_SUPPORTED
-    // QRCS_NOT_FOUND
-    // Note: have converted it to ResultCode.
-    public int mCmdStatus;
-
-    //filled after IQPresListener_CMDStatus
-    public int mSipRequestId;
-
-    // filled after IQPresListener_SipResponseReceived
-    public int mSipResponseCode;
-
-    // filled after IQPresListener_SipResponseReceived
-    public String mSipReasonPhrase;
-
-    // filled before send the request
-    public IRcsPresenceListener mListener;
-
-    public Task(int taskId, int cmdId, IRcsPresenceListener listener){
-        mTaskId = taskId;
-        mCmdId = cmdId;
-        mListener = listener;
-    }
-
-    public String toString(){
-        return "Task: mTaskId=" + mTaskId +
-                " mCmdId=" + mCmdId +
-                " mCmdStatus=" + mCmdStatus +
-                " mSipRequestId=" + mSipRequestId +
-                " mSipResponseCode=" + mSipResponseCode +
-                " mSipReasonPhrase=" + mSipReasonPhrase;
-    }
-};
-
diff --git a/rcs/rcsservice/src/com/android/service/ims/TaskManager.java b/rcs/rcsservice/src/com/android/service/ims/TaskManager.java
deleted file mode 100644
index 4e931ac..0000000
--- a/rcs/rcsservice/src/com/android/service/ims/TaskManager.java
+++ /dev/null
@@ -1,394 +0,0 @@
-/*
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
-
-package com.android.service.ims;
-
-import java.util.Set;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.List;
-import java.util.ArrayList;
-import android.os.RemoteException;
-import android.content.Context;
-import android.os.Handler;
-import android.os.Message;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.telephony.PhoneNumberUtils;
-
-import com.android.ims.internal.uce.presence.PresCmdStatus;
-
-import com.android.ims.internal.Logger;
-import com.android.ims.RcsManager.ResultCode;
-import com.android.ims.RcsPresenceInfo;
-import com.android.ims.IRcsPresenceListener;
-
-import com.android.service.ims.presence.PresenceTask;
-import com.android.service.ims.presence.PresenceCapabilityTask;
-import com.android.service.ims.presence.PresenceAvailabilityTask;
-
-/**
- * TaskManager
- */
-public class TaskManager{
-    /*
-     * The logger
-     */
-    private Logger logger = Logger.getLogger(this.getClass().getName());
-
-    private static TaskManager sTaskManager = null;
-
-    private int mTaskId = 0;
-
-    public final static int TASK_TYPE_GET_CAPABILITY   = 1;
-    public final static int TASK_TYPE_GET_AVAILABILITY = 2;
-    public final static int TASK_TYPE_PUBLISH          = 3;
-
-    private Map<String, Task> mTaskMap;
-
-    private final Object mSyncObj = new Object();
-
-    private static final int TASK_MANAGER_ON_TERMINATED = 1;
-    private static final int TASK_MANAGER_ON_TIMEOUT = 2;
-
-    private static MessageHandler sMsgHandler;
-
-    public TaskManager(){
-        logger.debug("TaskManager created.");
-        mTaskMap = new HashMap<String, Task>();
-
-        HandlerThread messageHandlerThread = new HandlerThread("MessageHandler",
-                android.os.Process.THREAD_PRIORITY_BACKGROUND);
-
-        messageHandlerThread.start();
-        Looper messageHandlerLooper = messageHandlerThread.getLooper();
-        sMsgHandler = new MessageHandler(messageHandlerLooper);
-    }
-
-    public static synchronized TaskManager getDefault(){
-        if(sTaskManager == null){
-            sTaskManager = new TaskManager();
-        }
-
-        return sTaskManager;
-    }
-
-    public synchronized int generateTaskId(){
-        return mTaskId++;
-    }
-
-    public void putTask(int taskId, Task task){
-        synchronized (mSyncObj){
-            putTaskInternal(taskId, task);
-        }
-    }
-
-    private synchronized void putTaskInternal(int taskId, Task task){
-        Task sameKeyTask = mTaskMap.put(String.valueOf(taskId), task);
-
-        logger.debug("Added Task: " + task + "Original same key task:" + sameKeyTask);
-    }
-
-    public int addCapabilityTask(Context context, String[] contacts,
-            IRcsPresenceListener listener, long timeout){
-        int taskId = TaskManager.getDefault().generateTaskId();
-        synchronized (mSyncObj){
-            Task task = new PresenceCapabilityTask(context, taskId, TASK_TYPE_GET_CAPABILITY,
-                    listener, contacts, timeout);
-            putTaskInternal(taskId, task);
-        }
-
-        return taskId;
-    }
-
-    public int addAvailabilityTask(String contact, IRcsPresenceListener listener){
-        int taskId = TaskManager.getDefault().generateTaskId();
-        synchronized (mSyncObj){
-            String[] contacts = new String[1];
-            contacts[0] = contact;
-            Task task = new PresenceAvailabilityTask(taskId, TASK_TYPE_GET_AVAILABILITY,
-                    listener, contacts);
-            putTaskInternal(taskId, task);
-        }
-
-        return taskId;
-    }
-
-    public int addPublishTask(String contact, IRcsPresenceListener listener){
-        int taskId = TaskManager.getDefault().generateTaskId();
-        synchronized (mSyncObj){
-            String[] contacts = new String[1];
-            contacts[0] = contact;
-            Task task = new PresenceTask(taskId, TASK_TYPE_PUBLISH, listener, contacts);
-            putTaskInternal(taskId, task);
-        }
-
-        return taskId;
-    }
-
-    // If need to call getTask in this class please add another one getTaskInternal
-    public Task getTask(int taskId){
-        synchronized (mSyncObj){
-            return mTaskMap.get(String.valueOf(taskId));
-        }
-    }
-
-    public void removeTask(int taskId){
-        synchronized (mSyncObj){
-            Task task = mTaskMap.remove(String.valueOf(taskId));
-            if(task instanceof PresenceCapabilityTask){
-                ((PresenceCapabilityTask)task).cancelTimer();
-            }
-            logger.debug("Removed Task: " + task);
-        }
-    }
-
-    public Task getTaskByRequestId(int sipRequestId){
-        synchronized (mSyncObj){
-            Set<String> keys= mTaskMap.keySet();
-            if(keys == null){
-                logger.debug("getTaskByRequestId keys=null");
-                return null;
-            }
-
-            for(String key:keys){
-                if(mTaskMap.get(key).mSipRequestId == sipRequestId){
-                    logger.debug("getTaskByRequestId, sipRequestId=" + sipRequestId +
-                            " task=" + mTaskMap.get(key));
-                    return mTaskMap.get(key);
-                }
-            }
-        }
-
-        logger.debug("getTaskByRequestId, sipRequestId=" + sipRequestId + " task=null");
-        return null;
-    }
-
-    public void onTerminated(String contact){ // for single number capability polling
-        logger.debug("onTerminated contact=" + contact);
-        if(contact == null){
-            return;
-        }
-
-        synchronized (mSyncObj){
-            Set<String> keys= mTaskMap.keySet();
-            if(keys == null){
-                logger.debug("onTerminated keys is null");
-                return;
-            }
-
-            for(String key:keys){
-                Task task = mTaskMap.get(key);
-                if(task == null){
-                    continue;
-                }
-
-                if(task instanceof PresenceCapabilityTask){
-                    PresenceCapabilityTask capabilityTask = (PresenceCapabilityTask)task;
-                    if(capabilityTask.mContacts != null && capabilityTask.mContacts[0] != null &&
-                            PhoneNumberUtils.compare(contact, capabilityTask.mContacts[0])){
-                        if(!capabilityTask.isWaitingForNotify()){
-                            logger.debug("onTerminated the tesk is not waiting for NOTIFY yet");
-                            continue;
-                        }
-
-                        MessageData messageData = new MessageData();
-                        messageData.mTask = capabilityTask;
-                        messageData.mReason = null;
-
-                        Message notifyMessage = sMsgHandler.obtainMessage(
-                                TASK_MANAGER_ON_TERMINATED,
-                                messageData);
-                        sMsgHandler.sendMessage(notifyMessage);
-                    }
-                }
-            }
-        }
-    }
-
-    public void onTerminated(int requestId, String reason){
-        logger.debug("onTerminated requestId=" + requestId + " reason=" + reason);
-
-        Task task = getTaskByRequestId(requestId);
-        if(task == null){
-            logger.debug("onTerminated Can't find request " + requestId);
-            return;
-        }
-
-        synchronized (mSyncObj){
-            if(task instanceof PresenceCapabilityTask){
-                MessageData messageData = new MessageData();
-                messageData.mTask = (PresenceCapabilityTask)task;
-                messageData.mReason = reason;
-
-                Message notifyMessage = sMsgHandler.obtainMessage(TASK_MANAGER_ON_TERMINATED,
-                        messageData);
-                sMsgHandler.sendMessage(notifyMessage);
-            }
-        }
-    }
-
-    public void onTimeout(int taskId){
-        logger.debug("onTimeout taskId=" + taskId);
-
-        Task task = getTask(taskId);
-        if(task == null){
-            logger.debug("onTimeout task = null");
-            return;
-        }
-        synchronized (mSyncObj){
-            if(task instanceof PresenceCapabilityTask){
-                MessageData messageData = new MessageData();
-                messageData.mTask = (PresenceCapabilityTask)task;
-                messageData.mReason = null;
-
-                Message timeoutMessage = sMsgHandler.obtainMessage(TASK_MANAGER_ON_TIMEOUT,
-                        messageData);
-                sMsgHandler.sendMessage(timeoutMessage);
-            }else{
-                logger.debug("not PresenceCapabilityTask, taskId=" + taskId);
-            }
-        }
-    }
-
-    public class MessageData{
-        public PresenceCapabilityTask mTask;
-        public String mReason;
-    }
-
-    public class MessageHandler extends Handler{
-        MessageHandler(Looper looper){
-            super(looper);
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            super.handleMessage(msg);
-
-            logger.debug( "Thread=" + Thread.currentThread().getName() + " received "
-                    + msg);
-
-
-
-            if(msg == null){
-                logger.error("msg=null");
-                return;
-            }
-
-            switch (msg.what) {
-                case  TASK_MANAGER_ON_TERMINATED:
-                {
-                    MessageData messageData = (MessageData) msg.obj;
-                    if(messageData != null && messageData.mTask != null){
-                        messageData.mTask.onTerminated(messageData.mReason);
-                    }
-                    break;
-                }
-
-                case TASK_MANAGER_ON_TIMEOUT:
-                {
-                    MessageData messageData = (MessageData) msg.obj;
-                    if(messageData != null && messageData.mTask != null){
-                        messageData.mTask.onTimeout();
-                    }
-                    break;
-                }
-
-                default:
-                    logger.debug("handleMessage unknown msg=" + msg.what);
-            }
-        }
-    }
-
-    public void clearTimeoutAvailabilityTask(long availabilityExpire) {
-       logger.debug("clearTimeoutAvailabilityTask");
-
-        synchronized (mSyncObj) {
-            long currentTime = System.currentTimeMillis();
-
-            Iterator<Map.Entry<String, Task>> iterator = mTaskMap.entrySet().iterator();
-            while (iterator.hasNext()) {
-                Map.Entry<String, Task> entry = iterator.next();
-
-                Task task = (Task) entry.getValue();
-                logger.debug("Currently existing Availability task, key: " + entry.getKey()
-                        + ", Task: " + task);
-
-                if ((task != null) && (task instanceof PresenceAvailabilityTask)) {
-                    PresenceAvailabilityTask presenceTask = (PresenceAvailabilityTask)task;
-
-                    long notifyTimestamp = presenceTask.getNotifyTimestamp();
-                    long createTimestamp = presenceTask.getCreateTimestamp();
-                    logger.debug("createTimestamp=" + createTimestamp + " notifyTimestamp=" +
-                            notifyTimestamp + " currentTime=" + currentTime);
-
-                     // remove it if it didn't get notify in 60s.
-                     // or get notify for 60s
-                    if(((notifyTimestamp != 0) &&
-                            (notifyTimestamp + availabilityExpire < currentTime)) ||
-                            (notifyTimestamp == 0) &&
-                            (createTimestamp + availabilityExpire < currentTime)) {
-                        logger.debug("remove expired availability task:" + presenceTask);
-                        iterator.remove();
-                    }
-                }
-            }
-        }
-    }
-
-    public PresenceAvailabilityTask getAvailabilityTaskByContact(String contact){
-        synchronized (mSyncObj){
-            Set<String> keys= mTaskMap.keySet();
-            if(keys == null){
-                logger.debug("getTaskByContact keys=null");
-                return null;
-            }
-
-            for(String key:keys){
-                Task task = mTaskMap.get(key);
-                if(task == null){
-                    continue;
-                }
-
-                if(task instanceof PresenceAvailabilityTask){
-                    PresenceAvailabilityTask availabilityTask = (PresenceAvailabilityTask)task;
-                    if(PhoneNumberUtils.compare(contact, availabilityTask.mContacts[0])){
-                        logger.debug("getTaskByContact contact=" + contact +
-                                " task=" + availabilityTask);
-                        return availabilityTask;
-                    }
-                }
-            }
-        }
-
-        logger.debug("getTaskByContact, contact=" + contact + " task=null");
-        return null;
-    }
-}
-
diff --git a/rcs/rcsservice/src/com/android/service/ims/presence/AlarmBroadcastReceiver.java b/rcs/rcsservice/src/com/android/service/ims/presence/AlarmBroadcastReceiver.java
deleted file mode 100644
index f02f9ce..0000000
--- a/rcs/rcsservice/src/com/android/service/ims/presence/AlarmBroadcastReceiver.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
-
-package com.android.service.ims.presence;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-
-import com.android.ims.internal.Logger;
-
-import com.android.service.ims.RcsStackAdaptor;
-import com.android.service.ims.TaskManager;
-
-public class AlarmBroadcastReceiver extends BroadcastReceiver{
-    private Logger logger = Logger.getLogger(this.getClass().getName());
-
-    private static final String ACTION_RETRY_ALARM =
-            RcsStackAdaptor.ACTION_RETRY_ALARM;
-    private static final String ACTION_TASK_TIMEOUT_ALARM =
-            PresenceCapabilityTask.ACTION_TASK_TIMEOUT_ALARM;
-    private static final String ACTION_RETRY_PUBLISH_ALARM =
-            PresencePublication.ACTION_RETRY_PUBLISH_ALARM;
-
-    @Override
-    public void onReceive(Context context, Intent intent) {
-        String action = intent.getAction();
-        logger.info("onReceive intent: " + action);
-
-        // this could happen when there is a crash and the previous broadcasted intent
-        // coming when the PresenceService is launching.
-        RcsStackAdaptor rcsStackAdaptor = RcsStackAdaptor.getInstance(null);
-        if(rcsStackAdaptor == null){
-            logger.debug("rcsStackAdaptor=null");
-            return;
-        }
-
-        if(ACTION_RETRY_ALARM.equals(action)) {
-            int times = intent.getIntExtra("times", -1);
-            rcsStackAdaptor.startInitThread(times);
-        }else if(ACTION_TASK_TIMEOUT_ALARM.equals(action)){
-            int taskId = intent.getIntExtra("taskId", -1);
-            TaskManager.getDefault().onTimeout(taskId);
-        } else if(ACTION_RETRY_PUBLISH_ALARM.equals(action)) {
-            // default retry is for 888
-            int sipCode = intent.getIntExtra("sipCode", 888);
-            PresencePublication publication = PresencePublication.getPresencePublication();
-            if(publication != null) {
-                publication.retryPublish();
-            }
-        }
-        else{
-            logger.debug("not interest in intent=" + intent);
-        }
-    }
-};
-
diff --git a/rcs/rcsservice/src/com/android/service/ims/presence/PresenceAvailabilityTask.java b/rcs/rcsservice/src/com/android/service/ims/presence/PresenceAvailabilityTask.java
deleted file mode 100644
index 99c698f..0000000
--- a/rcs/rcsservice/src/com/android/service/ims/presence/PresenceAvailabilityTask.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
-
-package com.android.service.ims.presence;
-
-import java.util.Set;
-import java.util.HashMap;
-import java.util.List;
-import java.util.ArrayList;
-import android.content.Context;
-import android.content.Intent;
-import android.app.PendingIntent;
-import android.content.IntentFilter;
-import android.os.RemoteException;
-import android.app.AlarmManager;
-import android.os.SystemClock;
-
-import com.android.ims.internal.uce.presence.PresCmdStatus;
-
-import com.android.ims.internal.Logger;
-import com.android.ims.RcsManager.ResultCode;
-import com.android.ims.RcsPresenceInfo;
-import com.android.ims.IRcsPresenceListener;
-
-import com.android.service.ims.TaskManager;
-
-/**
- * PresenceAvailabilityTask
- */
-public class PresenceAvailabilityTask extends PresenceTask{
-    /*
-     * The logger
-     */
-    private Logger logger = Logger.getLogger(this.getClass().getName());
-
-    private long mCreateTimestamp = 0;
-
-    // Time when get the notify. Used to check the 60s expires.
-    private long mNotifyTimeStamp = 0;
-
-    public PresenceAvailabilityTask(int taskId, int cmdId, IRcsPresenceListener listener,
-            String[] contacts){
-        super(taskId, cmdId, listener, contacts);
-
-        mCreateTimestamp = System.currentTimeMillis();
-        mNotifyTimeStamp = 0;
-    }
-
-    public void updateNotifyTimestamp() {
-        mNotifyTimeStamp = System.currentTimeMillis();
-        logger.debug("updateNotifyTimestamp mNotifyTimeStamp=" + mNotifyTimeStamp);
-    }
-
-    public long getNotifyTimestamp() {
-        return mNotifyTimeStamp;
-    }
-
-    public long getCreateTimestamp() {
-        return mCreateTimestamp;
-    }
-
-    public String toString(){
-        return super.toString() +
-                " mNotifyTimeStamp=" + mNotifyTimeStamp;
-    }
-};
-
diff --git a/rcs/rcsservice/src/com/android/service/ims/presence/PresenceBase.java b/rcs/rcsservice/src/com/android/service/ims/presence/PresenceBase.java
deleted file mode 100644
index 5f1dfe5..0000000
--- a/rcs/rcsservice/src/com/android/service/ims/presence/PresenceBase.java
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
-
-package com.android.service.ims.presence;
-
-import java.lang.String;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.Context;
-import android.os.RemoteException;
-import android.content.Intent;
-import com.android.internal.telephony.TelephonyIntents;
-import android.content.ComponentName;
-
-import com.android.ims.internal.uce.common.StatusCode;
-import com.android.ims.internal.uce.common.StatusCode;
-import com.android.ims.internal.uce.presence.PresCmdStatus;
-import com.android.ims.internal.uce.presence.PresResInfo;
-import com.android.ims.internal.uce.presence.PresSipResponse;
-
-import com.android.ims.RcsManager.ResultCode;
-import com.android.ims.RcsPresence.PublishState;
-import com.android.ims.RcsPresenceInfo;
-
-import com.android.ims.internal.Logger;
-import com.android.service.ims.Task;
-import com.android.service.ims.RcsUtils;
-import com.android.service.ims.TaskManager;
-
-public abstract class PresenceBase{
-    /*
-     * The logger
-     */
-    static private Logger logger = Logger.getLogger("PresenceBase");
-
-    protected Context mContext = null;
-
-    public PresenceBase() {
-    }
-
-    protected void handleCallback(Task task, int resultCode, boolean forCmdStatus){
-        if(task == null){
-            logger.debug("task == null");
-            return;
-        }
-
-        if(task.mListener != null){
-            try{
-                if(resultCode >= ResultCode.SUCCESS){
-                    if(!forCmdStatus){
-                        task.mListener.onSuccess(task.mTaskId);
-                    }
-                }else{
-                    task.mListener.onError(task.mTaskId, resultCode);
-                }
-            }catch(RemoteException e){
-                logger.debug("Failed to send the status to client.");
-            }
-        }
-
-        // remove task when error
-        // remove task when SIP response success.
-        // For list capability polling we will waiting for the terminated notify or timeout.
-        if(resultCode != ResultCode.SUCCESS){
-            if(task instanceof PresencePublishTask){
-                PresencePublishTask publishTask = (PresencePublishTask) task;
-                logger.debug("handleCallback for publishTask=" + publishTask);
-                if(resultCode == PublishState.PUBLISH_STATE_VOLTE_PROVISION_ERROR) {
-                    // retry 3 times for "403 Not Authorized for Presence".
-                    if(publishTask.getRetryCount() >= 3) {
-                        //remove capability after try 3 times by PresencePolling
-                        logger.debug("handleCallback remove task=" + task);
-                        TaskManager.getDefault().removeTask(task.mTaskId);
-                    } else {
-                        // Continue retry
-                        publishTask.setRetryCount(publishTask.getRetryCount() + 1);
-                    }
-                } else {
-                    logger.debug("handleCallback remove task=" + task);
-                    TaskManager.getDefault().removeTask(task.mTaskId);
-                }
-            } else {
-                logger.debug("handleCallback remove task=" + task);
-                TaskManager.getDefault().removeTask(task.mTaskId);
-            }
-        }else{
-            if(forCmdStatus || !forCmdStatus && (task instanceof PresenceCapabilityTask)){
-                logger.debug("handleCallback remove task later");
-
-                //waiting for Notify from network
-                if(!forCmdStatus){
-                    ((PresenceCapabilityTask)task).setWaitingForNotify(true);
-                }
-            }else{
-                if(!forCmdStatus && (task instanceof PresenceAvailabilityTask) &&
-                        (resultCode == ResultCode.SUCCESS)){
-                    // Availiablity, cache for 60s, remove it later.
-                    logger.debug("handleCallback PresenceAvailabilityTask cache for 60s task="
-                            + task);
-                    return;
-                }
-
-                logger.debug("handleCallback remove task=" + task);
-                TaskManager.getDefault().removeTask(task.mTaskId);
-            }
-        }
-    }
-
-    public void handleCmdStatus(PresCmdStatus pCmdStatus){
-        if(pCmdStatus == null){
-            logger.error("handleCallbackForCmdStatus pCmdStatus=null");
-            return;
-        }
-
-        Task task = TaskManager.getDefault().getTask(pCmdStatus.getUserData());
-        int resultCode = RcsUtils.statusCodeToResultCode(pCmdStatus.getStatus().getStatusCode());
-        if(task != null){
-            task.mSipRequestId = pCmdStatus.getRequestId();
-            task.mCmdStatus = resultCode;
-            TaskManager.getDefault().putTask(task.mTaskId, task);
-        }
-
-        handleCallback(task, resultCode, true);
-    }
-
-    protected void notifyDm() {
-        logger.debug("notifyDm");
-        Intent intent = new Intent(
-                TelephonyIntents.ACTION_FORBIDDEN_NO_SERVICE_AUTHORIZATION);
-        intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
-
-        mContext.sendBroadcast(intent);
-    }
-
-    protected boolean isInConfigList(int errorNo, String phrase, int configId) {
-        String inErrorString = ("" + errorNo).trim();
-
-        String[] errorArray = mContext.getResources().getStringArray(configId);
-        logger.debug("errorArray length=" + errorArray.length + " errorArray=" + errorArray);
-        for (String errorStr : errorArray) {
-            if (errorStr != null && errorStr.startsWith(inErrorString)) {
-                String errorPhrase = errorStr.substring(inErrorString.length());
-                if(errorPhrase == null || errorPhrase.isEmpty()) {
-                    return true;
-                }
-
-                if(phrase == null || phrase.isEmpty()) {
-                    return false;
-                }
-
-                return phrase.toLowerCase().contains(errorPhrase.toLowerCase());
-            }
-        }
-        return false;
-    }
-
-    abstract public void handleSipResponse(PresSipResponse pSipResponse);
-}
-
diff --git a/rcs/rcsservice/src/com/android/service/ims/presence/PresenceCapabilityTask.java b/rcs/rcsservice/src/com/android/service/ims/presence/PresenceCapabilityTask.java
deleted file mode 100644
index 8dbc120..0000000
--- a/rcs/rcsservice/src/com/android/service/ims/presence/PresenceCapabilityTask.java
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
-
-package com.android.service.ims.presence;
-
-import java.util.Set;
-import java.util.HashMap;
-import java.util.List;
-import java.util.ArrayList;
-import android.content.Context;
-import android.content.Intent;
-import android.app.PendingIntent;
-import android.content.IntentFilter;
-import android.os.RemoteException;
-import android.app.AlarmManager;
-import android.os.SystemClock;
-
-import com.android.ims.internal.uce.presence.PresCmdStatus;
-
-import com.android.ims.RcsManager.ResultCode;
-import com.android.ims.RcsPresenceInfo;
-import com.android.ims.IRcsPresenceListener;
-
-import com.android.ims.internal.Logger;
-import com.android.service.ims.TaskManager;
-
-/**
- * PresenceCapabilityTask
- */
-public class PresenceCapabilityTask extends PresenceTask{
-    /*
-     * The logger
-     */
-    private Logger logger = Logger.getLogger(this.getClass().getName());
-
-    public static final String ACTION_TASK_TIMEOUT_ALARM =
-            "com.android.service.ims.presence.task.timeout";
-
-    private Context mContext = null;
-
-    // The result code will be used for retry.
-    public int mResultCode;
-
-    // The alarm manager.
-    static AlarmManager sAlarmManager = null;
-    PendingIntent mAlarmIntent = null;
-    boolean mTimerStarted = false;
-
-    // it will be set to true after got sip response.
-    public boolean mWaitingForNotify;
-
-    // The time when created the task.
-    private long mCreatedTimeStamp;
-
-    private long mTimeout;
-
-    public PresenceCapabilityTask(Context context, int taskId, int cmdId,
-            IRcsPresenceListener listener, String[] contacts,
-            long timeout){
-        super(taskId, cmdId, listener, contacts);
-        mContext = context;
-        mWaitingForNotify = false;
-
-        mCreatedTimeStamp = System.currentTimeMillis();
-        mTimeout = timeout;
-
-        if(mTimeout <=0){
-            // The terminal notification may be received shortly after the time limit of
-            // the subscription due to network delays or retransmissions.
-            // Device shall wait for 3sec after the end of the subscription period in order to
-            // accept such notifications without returning spurious errors (e.g. SIP 481).
-            mTimeout = 36000;
-        }
-
-        if(listener != null){
-            startTimer();
-        } //else it will be removed after got sip response.
-    }
-
-    public String toString(){
-        return super.toString() +
-                " mCreatedTimeStamp=" + mCreatedTimeStamp +
-                " mTimeout=" + mTimeout;
-    }
-
-    private void startTimer(){
-        if(mContext == null){
-            logger.error("startTimer mContext is null");
-            return;
-        }
-
-        Intent intent = new Intent(ACTION_TASK_TIMEOUT_ALARM);
-        intent.setClass(mContext, AlarmBroadcastReceiver.class);
-        intent.putExtra("taskId", mTaskId);
-        PendingIntent mAlarmIntent = PendingIntent.getBroadcast(mContext, 0, intent,
-                PendingIntent.FLAG_ONE_SHOT);
-
-        if(sAlarmManager == null){
-            sAlarmManager = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE);
-        }
-
-        long triggerAt = SystemClock.elapsedRealtime() + mTimeout;
-        logger.debug("startTimer taskId=" + mTaskId + " mTimeout=" + mTimeout +
-                " triggerAt=" + triggerAt + " mAlarmIntent=" + mAlarmIntent);
-        sAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAt, mAlarmIntent);
-        mTimerStarted = true;
-    }
-
-    public void cancelTimer(){
-        if(mTimerStarted){
-            logger.debug("cancelTimer, taskId=" + mTaskId);
-            if(mAlarmIntent != null && sAlarmManager != null) {
-                sAlarmManager.cancel(mAlarmIntent);
-            }
-            mTimerStarted = false;
-        }
-    }
-
-    public void onTimeout(){
-        logger.debug("onTimeout, taskId=" + mTaskId);
-        try{
-            if(mListener != null){
-                mListener.onTimeout(mTaskId);
-            }
-        }catch (RemoteException e){
-            logger.error("RemoteException", e);
-        }
-
-        TaskManager.getDefault().removeTask(mTaskId);
-    }
-
-    public void setWaitingForNotify(boolean waitingForNotify){
-        mWaitingForNotify = waitingForNotify;
-    }
-
-    public boolean isWaitingForNotify(){
-        return mWaitingForNotify;
-    }
-
-    public void onTerminated(String reason){
-        if(!mWaitingForNotify){
-            logger.debug("onTerminated mWaitingForNotify is false. task=" + this);
-            return;
-        }
-
-        cancelTimer();
-        try{
-            if(mListener != null){
-                mListener.onFinish(mTaskId);
-            }
-        }catch (RemoteException e){
-            logger.error("RemoteException", e);
-        }
-
-        TaskManager.getDefault().removeTask(mTaskId);
-    }
-};
-
diff --git a/rcs/rcsservice/src/com/android/service/ims/presence/PresenceInfoParser.java b/rcs/rcsservice/src/com/android/service/ims/presence/PresenceInfoParser.java
deleted file mode 100644
index 0e8f2d3..0000000
--- a/rcs/rcsservice/src/com/android/service/ims/presence/PresenceInfoParser.java
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
-
-package com.android.service.ims.presence;
-
-import java.lang.String;
-import java.util.ArrayList;
-import java.util.List;
-import android.text.TextUtils;
-
-import com.android.ims.internal.uce.presence.PresTupleInfo;
-import com.android.ims.internal.uce.presence.PresRlmiInfo;
-import com.android.ims.internal.uce.presence.PresResInfo;
-import com.android.ims.internal.uce.presence.PresResInstanceInfo;
-
-import com.android.ims.RcsManager.ResultCode;
-import com.android.ims.RcsPresenceInfo;
-import com.android.ims.RcsPresenceInfo.ServiceType;
-import com.android.ims.RcsPresenceInfo.ServiceState;
-
-import com.android.ims.internal.Logger;
-
-public class PresenceInfoParser{
-    /*
-     * The logger
-     */
-    static private Logger logger = Logger.getLogger("PresenceInfoParser");
-
-    public PresenceInfoParser() {
-    }
-
-    static public RcsPresenceInfo getPresenceInfoFromTuple(String pPresentityURI,
-            PresTupleInfo[] pTupleInfo){
-        logger.debug("getPresenceInfoFromTuple: pPresentityURI=" + pPresentityURI +
-                " pTupleInfo=" + pTupleInfo);
-
-        if(pPresentityURI == null){
-            logger.error("pPresentityURI=" + pPresentityURI);
-            return null;
-        }
-
-        String contactNumber = getPhoneFromUri(pPresentityURI);
-        // Now that we got notification if the content didn't indicate it is not Volte
-        // then it should be Volte enabled. So default to Volte enabled.
-        int volteStatus = RcsPresenceInfo.VolteStatus.VOLTE_ENABLED;
-
-        int ipVoiceCallState = RcsPresenceInfo.ServiceState.UNKNOWN;
-        String ipVoiceCallServiceNumber = null;
-         // We use the timestamp which when we received it instead of the one in PDU
-        long ipVoiceCallTimestamp = System.currentTimeMillis();
-
-        int ipVideoCallState = RcsPresenceInfo.ServiceState.UNKNOWN;
-        String ipVideoCallServiceNumber = null;
-        long ipVideoCallTimestamp = System.currentTimeMillis();
-
-        if( pTupleInfo == null){
-            logger.debug("pTupleInfo=null");
-            return (new RcsPresenceInfo(contactNumber, volteStatus,
-                ipVoiceCallState, ipVoiceCallServiceNumber, ipVoiceCallTimestamp,
-                ipVideoCallState, ipVideoCallServiceNumber, ipVideoCallTimestamp));
-        }
-
-        for(int i = 0; i < pTupleInfo.length; i++){
-            // Video call has high priority. If it supports video call it will support voice call.
-            String featureTag = pTupleInfo[i].getFeatureTag();
-            logger.debug("getFeatureTag " + i + ": " + featureTag);
-            if(featureTag.equals(
-                "+g.3gpp.icsi-ref=\"urn%3Aurn-7%3A3gpp-service.ims.icsi.mmtel\";video") ||
-                featureTag.equals("+g.gsma.rcs.telephony=\"cs,volte\";video")) {
-                logger.debug("Got Volte and VT enabled tuple");
-                ipVoiceCallState = RcsPresenceInfo.ServiceState.ONLINE;
-                ipVideoCallState = RcsPresenceInfo.ServiceState.ONLINE;
-
-                if(pTupleInfo[i].getContactUri() != null){
-                    ipVideoCallServiceNumber = getPhoneFromUri(
-                            pTupleInfo[i].getContactUri().toString());
-                }
-            } else if(featureTag.equals("+g.gsma.rcs.telephony=\"cs\";video")) {
-                logger.debug("Got Volte disabled but VT enabled tuple");
-                ipVoiceCallState = RcsPresenceInfo.ServiceState.OFFLINE;
-                ipVideoCallState = RcsPresenceInfo.ServiceState.ONLINE;
-
-                if(pTupleInfo[i].getContactUri() != null){
-                    ipVideoCallServiceNumber = getPhoneFromUri(
-                            pTupleInfo[i].getContactUri().toString());
-                }
-            }else{
-                if(featureTag.equals(
-                    "+g.3gpp.icsi-ref=\"urn%3Aurn-7%3A3gpp-service.ims.icsi.mmtel\"") ||
-                    featureTag.equals("+g.gsma.rcs.telephony=\"cs,volte\"")) {
-
-                    logger.debug("Got Volte only tuple");
-                    ipVoiceCallState = RcsPresenceInfo.ServiceState.ONLINE;
-                    // "OR" for multiple tuples.
-                    if(RcsPresenceInfo.ServiceState.UNKNOWN == ipVideoCallState) {
-                        ipVideoCallState = RcsPresenceInfo.ServiceState.OFFLINE;
-                    }
-
-                    if(pTupleInfo[i].getContactUri() != null){
-                        ipVoiceCallServiceNumber = getPhoneFromUri(
-                                pTupleInfo[i].getContactUri().toString());
-                    }
-                }else{
-                    logger.debug("Ignoring feature tag: " + pTupleInfo[i].getFeatureTag());
-                }
-           }
-        }
-
-        RcsPresenceInfo retPresenceInfo = new RcsPresenceInfo(contactNumber,volteStatus,
-                ipVoiceCallState, ipVoiceCallServiceNumber, ipVoiceCallTimestamp,
-                ipVideoCallState, ipVideoCallServiceNumber, ipVideoCallTimestamp);
-
-        logger.debug("getPresenceInfoFromTuple: " + retPresenceInfo);
-
-        return retPresenceInfo;
-    }
-
-    static private void addPresenceInfo(ArrayList<RcsPresenceInfo> presenceInfoList,
-            RcsPresenceInfo presenceInfo){
-        logger.debug("addPresenceInfo presenceInfoList=" + presenceInfoList +
-                    " presenceInfo=" + presenceInfo);
-
-        if(presenceInfoList == null || presenceInfo == null){
-            logger.debug("addPresenceInfo presenceInfoList=" + presenceInfoList +
-                    " presenceInfo=" + presenceInfo);
-            return;
-        }
-
-        for(int i=0; i< presenceInfoList.size(); i++){
-            RcsPresenceInfo presenceInfoTmp = presenceInfoList.get(i);
-            if((presenceInfoTmp != null) && (presenceInfoTmp.getContactNumber() != null) &&
-                    presenceInfoTmp.getContactNumber().equalsIgnoreCase(
-                    presenceInfo.getContactNumber())){
-                // merge the information
-                presenceInfoList.set(i, new RcsPresenceInfo(presenceInfoTmp.getContactNumber(),
-                        presenceInfoTmp.getVolteStatus(),
-                        ((ServiceState.ONLINE == presenceInfo.getServiceState(
-                                ServiceType.VOLTE_CALL)) ||
-                                (ServiceState.ONLINE == presenceInfoTmp.getServiceState(
-                                ServiceType.VOLTE_CALL)))?ServiceState.ONLINE:
-                                    presenceInfoTmp.getServiceState(ServiceType.VOLTE_CALL),
-                        presenceInfoTmp.getServiceContact(ServiceType.VOLTE_CALL),
-                        presenceInfoTmp.getTimeStamp(ServiceType.VOLTE_CALL),
-                        ((ServiceState.ONLINE == presenceInfo.getServiceState(
-                                ServiceType.VT_CALL)) ||
-                                (ServiceState.ONLINE == presenceInfoTmp.getServiceState(
-                                ServiceType.VT_CALL)))?ServiceState.ONLINE:
-                                    presenceInfoTmp.getServiceState(ServiceType.VT_CALL),
-                        presenceInfoTmp.getServiceContact(ServiceType.VOLTE_CALL),
-                        presenceInfoTmp.getTimeStamp(ServiceType.VOLTE_CALL)));
-                return;
-            }
-        }
-
-        // didn't merge, so add the new one.
-        presenceInfoList.add(presenceInfo);
-    }
-
-    static public RcsPresenceInfo[] getPresenceInfosFromPresenceRes(
-            PresRlmiInfo pRlmiInfo, PresResInfo[] pRcsPresenceInfo) {
-        if(pRcsPresenceInfo == null){
-            logger.debug("getPresenceInfosFromPresenceRes pRcsPresenceInfo=null");
-            return null;
-        }
-
-        ArrayList<RcsPresenceInfo> presenceInfoList = new ArrayList<RcsPresenceInfo>();
-        for(int i=0; i < pRcsPresenceInfo.length; i++ ) {
-            if(pRcsPresenceInfo[i].getInstanceInfo() == null){
-                logger.error("invalid data getInstanceInfo = null");
-                continue;
-            }
-
-            String resUri = pRcsPresenceInfo[i].getResUri();
-            if(resUri == null){
-                logger.error("invalid data getResUri = null");
-                continue;
-            }
-
-            String contactNumber = getPhoneFromUri(resUri);
-            if(contactNumber == null){
-                logger.error("invalid data contactNumber=null");
-                continue;
-            }
-
-            if(pRcsPresenceInfo[i].getInstanceInfo().getResInstanceState() ==
-                    PresResInstanceInfo.UCE_PRES_RES_INSTANCE_STATE_TERMINATED){
-                logger.debug("instatance state is terminated");
-                String reason = pRcsPresenceInfo[i].getInstanceInfo().getReason();
-                if(reason != null){
-                    reason = reason.toLowerCase();
-                    // Noresource: 404. Device shall consider the resource as non-EAB capable
-                    // Rejected: 403. Device shall consider the resource as non-EAB  capable
-                    // Deactivated: 408, 481, 603, other 4xx, 5xx 6xx. Ignore.
-                    // Give Up: 480. Ignore.
-                    // Probation: 503. Ignore.
-                    if(reason.equals("rejected") || reason.equals("noresource")){
-                        RcsPresenceInfo presenceInfo = new RcsPresenceInfo(contactNumber,
-                                RcsPresenceInfo.VolteStatus.VOLTE_DISABLED,
-                                RcsPresenceInfo.ServiceState.OFFLINE, null,
-                                System.currentTimeMillis(),
-                                RcsPresenceInfo.ServiceState.OFFLINE, null,
-                                System.currentTimeMillis());
-                        addPresenceInfo(presenceInfoList, presenceInfo);
-                        logger.debug("reason=" + reason + " presenceInfo=" + presenceInfo);
-                        continue;
-                    }
-                }
-            }
-
-            RcsPresenceInfo presenceInfo = getPresenceInfoFromTuple(resUri,
-                    pRcsPresenceInfo[i].getInstanceInfo().getTupleInfo());
-            if(presenceInfo != null){
-                addPresenceInfo(presenceInfoList, presenceInfo);
-            }else{
-                logger.debug("presenceInfo["+ i + "] = null");
-                addPresenceInfo(presenceInfoList, getPresenceInfoFromTuple(resUri, null));
-            }
-        }
-
-        logger.debug("getPresenceInfoFromPresenceRes, presenceInfos:" + presenceInfoList);
-        if(presenceInfoList.size() == 0){
-            return null;
-        }
-
-        RcsPresenceInfo[] theArray = new RcsPresenceInfo[presenceInfoList.size()];
-        return (RcsPresenceInfo[])presenceInfoList.toArray(theArray);
-    }
-
-    static public String getPhoneFromUri(String uriValue) {
-        if(uriValue == null){
-            return null;
-        }
-
-        int startIndex = uriValue.indexOf(":", 0);
-        int endIndex = uriValue.indexOf("@", startIndex);
-
-        logger.debug("getPhoneFromUri uriValue=" + uriValue +
-            " startIndex=" + startIndex + " endIndex=" + endIndex);
-
-        String number = uriValue;
-        if(endIndex != -1){
-            number = uriValue.substring(0, endIndex);
-        }
-
-        if (startIndex != -1) {
-            return number = number.substring(startIndex + 1);
-        }
-
-        logger.debug("number=" + number);
-        return number;
-    }
-}
diff --git a/rcs/rcsservice/src/com/android/service/ims/presence/PresencePublication.java b/rcs/rcsservice/src/com/android/service/ims/presence/PresencePublication.java
deleted file mode 100644
index 05dcd7a..0000000
--- a/rcs/rcsservice/src/com/android/service/ims/presence/PresencePublication.java
+++ /dev/null
@@ -1,1227 +0,0 @@
-/*
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
-
-package com.android.service.ims.presence;
-
-import java.util.List;
-import java.util.Arrays;
-
-import android.content.Context;
-import android.content.Intent;
-import com.android.internal.telephony.Phone;
-import android.provider.Settings;
-import android.os.SystemProperties;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.telephony.TelephonyManager;
-import com.android.internal.telephony.IccCardConstants;
-import com.android.internal.telephony.TelephonyIntents;
-import android.telecom.TelecomManager;
-import android.content.IntentFilter;
-import android.app.PendingIntent;
-import android.app.AlarmManager;
-import android.os.SystemClock;
-import android.os.Message;
-import android.os.Handler;
-
-
-import com.android.ims.ImsManager;
-import com.android.ims.ImsConnectionStateListener;
-import com.android.ims.ImsServiceClass;
-import com.android.ims.ImsException;
-import android.telephony.SubscriptionManager;
-import com.android.ims.ImsConfig;
-import com.android.ims.ImsConfig.FeatureConstants;
-import com.android.ims.ImsConfig.FeatureValueConstants;
-
-import com.android.service.ims.RcsSettingUtils;
-import com.android.ims.RcsPresenceInfo;
-import com.android.ims.IRcsPresenceListener;
-import com.android.ims.RcsManager.ResultCode;
-import com.android.ims.RcsPresence.PublishState;
-
-import com.android.ims.internal.Logger;
-import com.android.service.ims.TaskManager;
-import com.android.service.ims.Task;
-
-import com.android.ims.internal.uce.presence.PresPublishTriggerType;
-import com.android.ims.internal.uce.presence.PresSipResponse;
-import com.android.ims.internal.uce.common.StatusCode;
-import com.android.ims.internal.uce.presence.PresCmdStatus;
-
-import com.android.service.ims.RcsStackAdaptor;
-
-import com.android.service.ims.R;
-
-public class PresencePublication extends PresenceBase {
-    private Logger logger = Logger.getLogger(this.getClass().getName());
-
-    private final Object mSyncObj = new Object();
-
-    final static String ACTION_IMS_FEATURE_AVAILABLE =
-            "com.android.service.ims.presence.ims-feature-status-changed";
-    private static final int INVALID_SERVICE_ID = -1;
-
-    boolean mMovedToIWLAN = false;
-    boolean mMovedToLTE = false;
-    boolean mVoPSEnabled = false;
-
-    boolean mIsVolteAvailable = false;
-    boolean mIsVtAvailable = false;
-    boolean mIsVoWifiAvailable = false;
-    boolean mIsViWifiAvailable = false;
-
-    // Queue for the pending PUBLISH request. Just need cache the last one.
-    volatile PublishRequest mPendingRequest = null;
-    volatile PublishRequest mPublishingRequest = null;
-    volatile PublishRequest mPublishedRequest = null;
-
-    /*
-     * Message to notify for a publish
-     */
-    public static final int MESSAGE_RCS_PUBLISH_REQUEST = 1;
-
-    /**
-     *  Publisher Error base
-     */
-    public static final int PUBLISH_ERROR_CODE_START = ResultCode.SUBSCRIBER_ERROR_CODE_END;
-
-    /**
-     * All publish errors not covered by specific errors
-     */
-    public static final int PUBLISH_GENIRIC_FAILURE = PUBLISH_ERROR_CODE_START - 1;
-
-    /**
-     * Responding for 403 - not authorized
-     */
-    public static final int PUBLISH_NOT_AUTHORIZED_FOR_PRESENCE = PUBLISH_ERROR_CODE_START - 2;
-
-    /**
-     * Responding for 404 error code. The subscriber is not provisioned.
-     * The Client should not send any EAB traffic after get this error.
-     */
-    public static final int PUBLISH_NOT_PROVISIONED = PUBLISH_ERROR_CODE_START - 3;
-
-    /**
-     * Responding for 200 - OK
-     */
-    public static final int PUBLISH_SUCESS = ResultCode.SUCCESS;
-
-    private RcsStackAdaptor mRcsStackAdaptor = null;
-    private PresenceSubscriber mSubscriber = null;
-    static private PresencePublication sPresencePublication = null;
-    private BroadcastReceiver mReceiver = null;
-
-    private boolean mHasCachedTrigger = false;
-    private boolean mGotTriggerFromStack = false;
-    private boolean mDonotRetryUntilPowerCycle = false;
-    private boolean mSimLoaded = false;
-    private int mPreferredTtyMode = Phone.TTY_MODE_OFF;
-
-    private boolean mImsRegistered = false;
-    private boolean mVtEnabled = false;
-    private boolean mDataEnabled = false;
-
-    public class PublishType{
-        public static final int PRES_PUBLISH_TRIGGER_DATA_CHANGED = 0;
-        // the lower layer should send trigger when enable volte
-        // the lower layer should unpublish when disable volte
-        // so only handle VT here.
-        public static final int PRES_PUBLISH_TRIGGER_VTCALL_CHANGED = 1;
-        public static final int PRES_PUBLISH_TRIGGER_CACHED_TRIGGER = 2;
-        public static final int PRES_PUBLISH_TRIGGER_TTY_ENABLE_STATUS = 3;
-        public static final int PRES_PUBLISH_TRIGGER_RETRY = 4;
-        public static final int PRES_PUBLISH_TRIGGER_FEATURE_AVAILABILITY_CHANGED = 5;
-    };
-
-    /**
-     * @param rcsStackAdaptor
-     * @param context
-     */
-    public PresencePublication(RcsStackAdaptor rcsStackAdaptor, Context context) {
-        super();
-        logger.debug("PresencePublication constrcuct");
-        this.mRcsStackAdaptor = rcsStackAdaptor;
-        this.mContext = context;
-
-        mVtEnabled = ImsManager.isVtEnabledByUser(mContext);
-        mDataEnabled = Settings.Global.getInt(mContext.getContentResolver(),
-                    Settings.Global.MOBILE_DATA, 1) == 1;
-        mPreferredTtyMode = Settings.Secure.getInt(
-                mContext.getContentResolver(),
-                Settings.Secure.PREFERRED_TTY_MODE,
-                Phone.TTY_MODE_OFF);
-        logger.debug("The current TTY mode is: " + mPreferredTtyMode);
-
-        if(mRcsStackAdaptor != null){
-            mRcsStackAdaptor.setPublishState(
-                    SystemProperties.getInt("rcs.publish.status",
-                    PublishState.PUBLISH_STATE_NOT_PUBLISHED));
-        }
-
-        mReceiver = new BroadcastReceiver() {
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                logger.print("onReceive intent=" + intent);
-                if(TelephonyIntents.ACTION_SIM_STATE_CHANGED.equalsIgnoreCase(intent.getAction())){
-                    String stateExtra = intent.getStringExtra(
-                            IccCardConstants.INTENT_KEY_ICC_STATE);
-                    logger.print("ACTION_SIM_STATE_CHANGED INTENT_KEY_ICC_STATE=" + stateExtra);
-                    final TelephonyManager teleMgr = (TelephonyManager) context.getSystemService(
-                                        Context.TELEPHONY_SERVICE);
-                    if(IccCardConstants.INTENT_VALUE_ICC_LOADED.equalsIgnoreCase(stateExtra)) {
-                        new Thread(new Runnable() {
-                            @Override
-                            public void run() {
-                                if(teleMgr == null){
-                                    logger.error("teleMgr = null");
-                                    return;
-                                }
-
-                                int count = 0;
-                                // retry 2 minutes to get the information from ISIM and RUIM
-                                for(int i=0; i<60; i++) {
-                                     String[] myImpu = teleMgr.getIsimImpu();
-                                     String myDomain = teleMgr.getIsimDomain();
-                                     String line1Number = teleMgr.getLine1Number();
-                                     logger.debug("myImpu=" + myImpu + " myDomain=" + myDomain +
-                                              " line1Number=" + line1Number);
-                                     if(line1Number != null && line1Number.length() != 0 ||
-                                         myImpu != null && myImpu.length != 0 &&
-                                         myDomain != null && myDomain.length() != 0){
-                                         mSimLoaded = true;
-                                         // treate hot SIM hot swap as power on.
-                                         mDonotRetryUntilPowerCycle = false;
-                                         if(mHasCachedTrigger) {
-                                             invokePublish(PresencePublication.PublishType.
-                                                     PRES_PUBLISH_TRIGGER_CACHED_TRIGGER);
-                                         }
-                                         break;
-                                     }else{
-                                         try{
-                                             Thread.sleep(2000);//retry 2 seconds later
-                                         }catch(InterruptedException e){
-                                         }
-                                     }
-                                 }
-                            }
-                        }, "wait for ISIM and RUIM").start();
-                    }else if (IccCardConstants.INTENT_VALUE_ICC_ABSENT.
-                            equalsIgnoreCase(stateExtra)) {
-                        // pulled out the SIM, set it as the same as power on status:
-                        logger.print("Pulled out SIM, set to PUBLISH_STATE_NOT_PUBLISHED");
-
-                        // only reset when the SIM gets absent.
-                        reset();
-                        mSimLoaded = false;
-                        setPublishState(
-                                PublishState.PUBLISH_STATE_NOT_PUBLISHED);
-                    }
-                }else if(Intent.ACTION_AIRPLANE_MODE_CHANGED.equalsIgnoreCase(intent.getAction())){
-                    boolean airplaneMode = intent.getBooleanExtra("state", false);
-                    if(airplaneMode){
-                        logger.print("Airplane mode, set to PUBLISH_STATE_NOT_PUBLISHED");
-                        reset();
-                        setPublishState(
-                                PublishState.PUBLISH_STATE_NOT_PUBLISHED);
-                    }
-                }else if(TelecomManager.ACTION_TTY_PREFERRED_MODE_CHANGED.equalsIgnoreCase(
-                        intent.getAction())){
-                    int newPreferredTtyMode = intent.getIntExtra(
-                            TelecomManager.EXTRA_TTY_PREFERRED_MODE,
-                            TelecomManager.TTY_MODE_OFF);
-                    newPreferredTtyMode = telecomTtyModeToPhoneMode(newPreferredTtyMode);
-                    logger.debug("Tty mode changed from " + mPreferredTtyMode
-                            + " to " + newPreferredTtyMode);
-
-                    boolean mIsTtyEnabled = isTtyEnabled(mPreferredTtyMode);
-                    boolean isTtyEnabled = isTtyEnabled(newPreferredTtyMode);
-                    mPreferredTtyMode = newPreferredTtyMode;
-                    if (mIsTtyEnabled != isTtyEnabled) {
-                        logger.print("ttyEnabled status changed from " + mIsTtyEnabled
-                                + " to " + isTtyEnabled);
-                        invokePublish(PresencePublication.PublishType.
-                                PRES_PUBLISH_TRIGGER_TTY_ENABLE_STATUS);
-                    }
-                } else if(ImsConfig.ACTION_IMS_FEATURE_CHANGED.equalsIgnoreCase(
-                        intent.getAction())){
-                    handleProvisionChanged();
-                }
-            }
-        };
-
-        IntentFilter statusFilter = new IntentFilter();
-        statusFilter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
-        statusFilter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
-        statusFilter.addAction(TelecomManager.ACTION_TTY_PREFERRED_MODE_CHANGED);
-        statusFilter.addAction(ImsConfig.ACTION_IMS_FEATURE_CHANGED);
-        mContext.registerReceiver(mReceiver, statusFilter);
-
-        sPresencePublication = this;
-    }
-
-    private boolean isIPVoiceSupported(boolean volteAvailable, boolean vtAvailable,
-            boolean voWifiAvailable, boolean viWifiAvailable) {
-        // volte and vowifi can be enabled separately
-        if(!ImsManager.isVolteEnabledByPlatform(mContext) &&
-                !ImsManager.isWfcEnabledByPlatform(mContext)) {
-            logger.print("Disabled by platform, voiceSupported=false");
-            return false;
-        }
-
-        if(!ImsManager.isVolteProvisionedOnDevice(mContext) &&
-                !RcsSettingUtils.isVowifiProvisioned(mContext)) {
-            logger.print("Wasn't provisioned, voiceSupported=false");
-            return false;
-        }
-
-        if(!ImsManager.isEnhanced4gLteModeSettingEnabledByUser(mContext) &&
-                !ImsManager.isWfcEnabledByUser(mContext)){
-            logger.print("User didn't enable volte or wfc, voiceSupported=false");
-            return false;
-        }
-
-        // for IWLAN. All WFC settings and provision should be fine if voWifiAvailable is true.
-        if(isOnIWLAN()) {
-            boolean voiceSupported=volteAvailable || voWifiAvailable;
-            logger.print("on IWLAN, voiceSupported=" + voiceSupported);
-            return voiceSupported;
-        }
-
-        // for none-IWLAN
-        if(!isOnLTE()) {
-            logger.print("isOnLTE=false, voiceSupported=false");
-            return false;
-        }
-
-        if(!mVoPSEnabled) {
-            logger.print("mVoPSEnabled=false, voiceSupported=false");
-            return false;
-        }
-
-        logger.print("voiceSupported=true");
-        return true;
-    }
-
-    private boolean isIPVideoSupported(boolean volteAvailable, boolean vtAvailable,
-            boolean voWifiAvailable, boolean viWifiAvailable) {
-        // if volte or vt was disabled then the viwifi will be disabled as well.
-        if(!ImsManager.isVolteEnabledByPlatform(mContext) ||
-                !ImsManager.isVtEnabledByPlatform(mContext)) {
-            logger.print("Disabled by platform, videoSupported=false");
-            return false;
-        }
-
-        if(!ImsManager.isVolteProvisionedOnDevice(mContext) ||
-                !RcsSettingUtils.isLvcProvisioned(mContext)) {
-            logger.print("Not provisioned. videoSupported=false");
-            return false;
-        }
-
-        if(!ImsManager.isEnhanced4gLteModeSettingEnabledByUser(mContext) ||
-                !mVtEnabled){
-            logger.print("User disabled volte or vt, videoSupported=false");
-            return false;
-        }
-
-        if(isTtyOn()){
-            logger.print("isTtyOn=true, videoSupported=false");
-            return false;
-        }
-
-        // for IWLAN, all WFC settings and provision should be fine if viWifiAvailable is true.
-        if(isOnIWLAN()) {
-            boolean videoSupported = vtAvailable || viWifiAvailable;
-            logger.print("on IWLAN, videoSupported=" + videoSupported);
-            return videoSupported;
-        }
-
-        if(!isDataEnabled()) {
-            logger.print("isDataEnabled()=false, videoSupported=false");
-            return false;
-        }
-
-        if(!isOnLTE()) {
-            logger.print("isOnLTE=false, videoSupported=false");
-            return false;
-        }
-
-        if(!mVoPSEnabled) {
-            logger.print("mVoPSEnabled=false, videoSupported=false");
-            return false;
-        }
-
-        return true;
-    }
-
-    public boolean isTtyOn() {
-        logger.debug("isTtyOn settingsTtyMode=" + mPreferredTtyMode);
-        return isTtyEnabled(mPreferredTtyMode);
-    }
-
-    public void onImsConnected() {
-        mImsRegistered = true;
-    }
-
-    public void onImsDisconnected() {
-        logger.debug("reset PUBLISH status for IMS had been disconnected");
-        mImsRegistered = false;
-        reset();
-    }
-
-    private void reset() {
-        mIsVolteAvailable = false;
-        mIsVtAvailable = false;
-        mIsVoWifiAvailable = false;
-        mIsViWifiAvailable = false;
-
-        synchronized(mSyncObj) {
-            mPendingRequest = null; //ignore the previous request
-            mPublishingRequest = null;
-            mPublishedRequest = null;
-        }
-    }
-
-    public void handleImsServiceUp() {
-        reset();
-    }
-
-    public void handleImsServiceDown() {
-    }
-
-    private void handleProvisionChanged() {
-        if(RcsSettingUtils.isEabProvisioned(mContext)) {
-            logger.debug("provisioned, set mDonotRetryUntilPowerCycle to false");
-            mDonotRetryUntilPowerCycle = false;
-            if(mHasCachedTrigger) {
-                invokePublish(PresencePublication.PublishType.PRES_PUBLISH_TRIGGER_CACHED_TRIGGER);
-            }
-        }
-    }
-
-    static public PresencePublication getPresencePublication() {
-        return sPresencePublication;
-    }
-
-    public void setSubscriber(PresenceSubscriber subscriber) {
-        mSubscriber = subscriber;
-    }
-
-    public boolean isDataEnabled() {
-        return  Settings.Global.getInt(mContext.getContentResolver(),
-                Settings.Global.MOBILE_DATA, 1) == 1;
-    }
-
-    public void onMobileDataChanged(boolean value){
-        logger.print("onMobileDataChanged, mDataEnabled=" + mDataEnabled + " value=" + value);
-        if(mDataEnabled != value) {
-            mDataEnabled = value;
-            RcsSettingUtils.setMobileDataEnabled(mContext, mDataEnabled);
-
-            invokePublish(
-                    PresencePublication.PublishType.PRES_PUBLISH_TRIGGER_DATA_CHANGED);
-        }
-    }
-
-    public void onVtEnabled(boolean enabled) {
-        logger.debug("onVtEnabled mVtEnabled=" + mVtEnabled + " enabled=" + enabled);
-
-        if(mVtEnabled != enabled) {
-            mVtEnabled = enabled;
-            invokePublish(PresencePublication.PublishType.
-                    PRES_PUBLISH_TRIGGER_VTCALL_CHANGED);
-        }
-    }
-
-    /**
-     * @return return true if it had been PUBLISHED.
-     */
-    public boolean isPublishedOrPublishing() {
-        long publishThreshold = RcsSettingUtils.getPublishThrottle(mContext);
-
-        boolean publishing = false;
-        publishing = (mPublishingRequest != null) &&
-                (System.currentTimeMillis() - mPublishingRequest.getTimestamp()
-                <= publishThreshold);
-
-        return (getPublishState() == PublishState.PUBLISH_STATE_200_OK || publishing);
-    }
-
-    /**
-     * @return the Publish State
-     */
-    public int getPublishState() {
-        if(mRcsStackAdaptor == null){
-            return PublishState.PUBLISH_STATE_NOT_PUBLISHED;
-        }
-
-        return mRcsStackAdaptor.getPublishState();
-    }
-
-    /**
-     * @param mPublishState the publishState to set
-     */
-    public void setPublishState(int publishState) {
-        if(mRcsStackAdaptor != null){
-            mRcsStackAdaptor.setPublishState(publishState);
-        }
-    }
-
-    public boolean getHasCachedTrigger(){
-        return mHasCachedTrigger;
-    }
-
-    // Tiggered by framework.
-    public int invokePublish(int trigger){
-        int ret;
-
-        // if the value is true then it will call stack to send the PUBLISH
-        // though the previous publish had the same capability
-        // for example: for retry PUBLISH.
-        boolean bForceToNetwork = true;
-        switch(trigger)
-        {
-            case PublishType.PRES_PUBLISH_TRIGGER_DATA_CHANGED:
-            {
-                logger.print("PRES_PUBLISH_TRIGGER_DATA_CHANGED");
-                bForceToNetwork = false;
-                break;
-            }
-            case PublishType.PRES_PUBLISH_TRIGGER_VTCALL_CHANGED:
-            {
-                logger.print("PRES_PUBLISH_TRIGGER_VTCALL_CHANGED");
-                // Didn't get featureCapabilityChanged sometimes.
-                bForceToNetwork = true;
-                break;
-            }
-            case PublishType.PRES_PUBLISH_TRIGGER_CACHED_TRIGGER:
-            {
-                logger.print("PRES_PUBLISH_TRIGGER_CACHED_TRIGGER");
-                break;
-            }
-            case PublishType.PRES_PUBLISH_TRIGGER_TTY_ENABLE_STATUS:
-            {
-                logger.print("PRES_PUBLISH_TRIGGER_TTY_ENABLE_STATUS");
-                bForceToNetwork = true;
-
-                break;
-            }
-            case PublishType.PRES_PUBLISH_TRIGGER_FEATURE_AVAILABILITY_CHANGED:
-            {
-                bForceToNetwork = false;
-                logger.print("PRES_PUBLISH_TRIGGER_FEATURE_AVAILABILITY_CHANGED");
-                break;
-            }
-            case PublishType.PRES_PUBLISH_TRIGGER_RETRY:
-            {
-                logger.print("PRES_PUBLISH_TRIGGER_RETRY");
-                break;
-            }
-            default:
-            {
-                logger.print("Unknown publish trigger from AP");
-            }
-        }
-
-        if(mGotTriggerFromStack == false){
-            // Waiting for RCS stack get ready.
-            logger.print("Didn't get trigger from stack yet, discard framework trigger.");
-            return ResultCode.ERROR_SERVICE_NOT_AVAILABLE;
-        }
-
-        if (mDonotRetryUntilPowerCycle) {
-            logger.print("Don't publish until next power cycle");
-            return ResultCode.SUCCESS;
-        }
-
-        if(!mSimLoaded){
-            //need to read some information from SIM to publish
-            logger.print("invokePublish cache the trigger since the SIM is not ready");
-            mHasCachedTrigger = true;
-            return ResultCode.ERROR_SERVICE_NOT_AVAILABLE;
-        }
-
-        //the provision status didn't be read from modem yet
-        if(!RcsSettingUtils.isEabProvisioned(mContext)) {
-            logger.print("invokePublish cache the trigger, not provision yet");
-            mHasCachedTrigger = true;
-            return ResultCode.ERROR_SERVICE_NOT_AVAILABLE;
-        }
-
-        PublishRequest publishRequest = new PublishRequest(
-                bForceToNetwork, System.currentTimeMillis());
-
-        requestPublication(publishRequest);
-
-        return ResultCode.SUCCESS;
-    }
-
-    public int invokePublish(PresPublishTriggerType val) {
-        int ret;
-
-        mGotTriggerFromStack = true;
-
-        // Always send the PUBLISH when we got the trigger from stack.
-        // This can avoid any issue when switch the phone between IWLAN and LTE.
-        boolean bForceToNetwork = true;
-        switch (val.getPublishTrigeerType())
-        {
-            case PresPublishTriggerType.UCE_PRES_PUBLISH_TRIGGER_ETAG_EXPIRED:
-            {
-                logger.print("PUBLISH_TRIGGER_ETAG_EXPIRED");
-                break;
-            }
-            case PresPublishTriggerType.UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_LTE_VOPS_DISABLED:
-            {
-                logger.print("PUBLISH_TRIGGER_MOVE_TO_LTE_VOPS_DISABLED");
-                mMovedToLTE = true;
-                mVoPSEnabled = false;
-                mMovedToIWLAN = false;
-
-                // onImsConnected could came later than this trigger.
-                mImsRegistered = true;
-                break;
-            }
-            case PresPublishTriggerType.UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_LTE_VOPS_ENABLED:
-            {
-                logger.print("PUBLISH_TRIGGER_MOVE_TO_LTE_VOPS_ENABLED");
-                mMovedToLTE = true;
-                mVoPSEnabled = true;
-                mMovedToIWLAN = false;
-
-                // onImsConnected could came later than this trigger.
-                mImsRegistered = true;
-                break;
-            }
-            case PresPublishTriggerType.UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_IWLAN:
-            {
-                logger.print("QRCS_PRES_PUBLISH_TRIGGER_MOVE_TO_IWLAN");
-                mMovedToLTE = false;
-                mVoPSEnabled = false;
-                mMovedToIWLAN = true;
-
-                // onImsConnected could came later than this trigger.
-                mImsRegistered = true;
-                break;
-            }
-            case PresPublishTriggerType.UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_EHRPD:
-            {
-                logger.print("PUBLISH_TRIGGER_MOVE_TO_EHRPD");
-                mMovedToLTE = false;
-                mVoPSEnabled = false;
-                mMovedToIWLAN = false;
-
-                // onImsConnected could came later than this trigger.
-                mImsRegistered = true;
-                break;
-            }
-            case PresPublishTriggerType.UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_HSPAPLUS:
-            {
-                logger.print("PUBLISH_TRIGGER_MOVE_TO_HSPAPLUS");
-                mMovedToLTE = false;
-                mVoPSEnabled = false;
-                mMovedToIWLAN = false;
-                break;
-            }
-            case PresPublishTriggerType.UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_2G:
-            {
-                logger.print("PUBLISH_TRIGGER_MOVE_TO_2G");
-                mMovedToLTE = false;
-                mVoPSEnabled = false;
-                mMovedToIWLAN = false;
-                break;
-            }
-            case PresPublishTriggerType.UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_3G:
-            {
-                logger.print("PUBLISH_TRIGGER_MOVE_TO_3G");
-                mMovedToLTE = false;
-                mVoPSEnabled = false;
-                mMovedToIWLAN = false;
-                break;
-            }
-            default:
-                logger.print("Unknow Publish Trigger Type");
-        }
-
-        if (mDonotRetryUntilPowerCycle) {
-            logger.print("Don't publish until next power cycle");
-            return ResultCode.SUCCESS;
-        }
-
-        if(!mSimLoaded){
-            //need to read some information from SIM to publish
-            logger.print("invokePublish cache the trigger since the SIM is not ready");
-            mHasCachedTrigger = true;
-            return ResultCode.ERROR_SERVICE_NOT_AVAILABLE;
-        }
-
-        //the provision status didn't be read from modem yet
-        if(!RcsSettingUtils.isEabProvisioned(mContext)) {
-            logger.print("invokePublish cache the trigger, not provision yet");
-            mHasCachedTrigger = true;
-            return ResultCode.ERROR_SERVICE_NOT_AVAILABLE;
-        }
-
-        PublishRequest publishRequest = new PublishRequest(
-                bForceToNetwork, System.currentTimeMillis());
-
-        requestPublication(publishRequest);
-
-        return ResultCode.SUCCESS;
-    }
-
-    public class PublishRequest {
-        private boolean mForceToNetwork = true;
-        private long mCurrentTime = 0;
-        private boolean mVolteCapable = false;
-        private boolean mVtCapable = false;
-
-        PublishRequest(boolean bForceToNetwork, long currentTime) {
-            refreshPublishContent();
-            mForceToNetwork = bForceToNetwork;
-            mCurrentTime = currentTime;
-        }
-
-        public void refreshPublishContent() {
-            mVolteCapable = isIPVoiceSupported(mIsVolteAvailable,
-                mIsVtAvailable,
-                mIsVoWifiAvailable,
-                mIsViWifiAvailable);
-            mVtCapable = isIPVideoSupported(mIsVolteAvailable,
-                mIsVtAvailable,
-                mIsVoWifiAvailable,
-                mIsViWifiAvailable);
-        }
-
-        public boolean getForceToNetwork() {
-            return mForceToNetwork;
-        }
-
-        public void setForceToNetwork(boolean bForceToNetwork) {
-            mForceToNetwork = bForceToNetwork;
-        }
-
-        public long getTimestamp() {
-            return mCurrentTime;
-        }
-
-        public void setTimestamp(long currentTime) {
-            mCurrentTime = currentTime;
-        }
-
-        public void setVolteCapable(boolean capable) {
-            mVolteCapable = capable;
-        }
-
-        public void setVtCapable(boolean capable) {
-            mVtCapable = capable;
-        }
-
-        public boolean getVolteCapable() {
-            return mVolteCapable;
-        }
-
-        public boolean getVtCapable() {
-            return mVtCapable;
-        }
-
-        public boolean hasSamePublishContent(PublishRequest request) {
-            if(request == null) {
-                logger.error("request == null");
-                return false;
-            }
-
-            return (mVolteCapable == request.getVolteCapable() &&
-                    mVtCapable == request.getVtCapable());
-        }
-
-        public String toString(){
-            return "mForceToNetwork=" + mForceToNetwork +
-                    " mCurrentTime=" + mCurrentTime +
-                    " mVolteCapable=" + mVolteCapable +
-                    " mVtCapable=" + mVtCapable;
-        }
-    }
-
-    private Handler mMsgHandler = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            super.handleMessage(msg);
-
-            logger.debug( "Thread=" + Thread.currentThread().getName() + " received "
-                    + msg);
-            if(msg == null){
-                logger.error("msg=null");
-                return;
-           }
-
-            switch (msg.what) {
-                case MESSAGE_RCS_PUBLISH_REQUEST:
-                    logger.debug("handleMessage  msg=RCS_PUBLISH_REQUEST:");
-
-                    PublishRequest publishRequest = (PublishRequest) msg.obj;
-                    synchronized(mSyncObj) {
-                        mPendingRequest = null;
-                    }
-                    doPublish(publishRequest);
-                break;
-
-                default:
-                    logger.debug("handleMessage unknown msg=" + msg.what);
-            }
-        }
-    };
-
-    private void requestPublication(PublishRequest publishRequest) {
-        // this is used to avoid the temp false feature change when switched between network.
-        if(publishRequest == null) {
-            logger.error("Invalid parameter publishRequest == null");
-            return;
-        }
-
-        long requestThrottle = 2000;
-        long currentTime = System.currentTimeMillis();
-        synchronized(mSyncObj){
-            // There is a PUBLISH will be done soon. Discard it
-            if((mPendingRequest != null) && currentTime - mPendingRequest.getTimestamp()
-                    <= requestThrottle) {
-                logger.print("A publish is pending, update the pending request and discard this one");
-                if(publishRequest.getForceToNetwork() && !mPendingRequest.getForceToNetwork()) {
-                    mPendingRequest.setForceToNetwork(true);
-                }
-                mPendingRequest.setTimestamp(publishRequest.getTimestamp());
-                return;
-            }
-
-            mPendingRequest = publishRequest;
-        }
-
-        Message publishMessage = mMsgHandler.obtainMessage(
-                MESSAGE_RCS_PUBLISH_REQUEST, mPendingRequest);
-        mMsgHandler.sendMessageDelayed(publishMessage, requestThrottle);
-    }
-
-    private void doPublish(PublishRequest publishRequest) {
-
-        if(publishRequest == null) {
-            logger.error("publishRequest == null");
-            return;
-        }
-
-        if (mRcsStackAdaptor == null) {
-            logger.error("mRcsStackAdaptor == null");
-            return;
-        }
-
-        if(!mImsRegistered) {
-            logger.debug("IMS wasn't registered");
-            return;
-        }
-
-        // Since we are doing a publish, don't need the retry any more.
-        if(mPendingRetry) {
-            mPendingRetry = false;
-            mAlarmManager.cancel(mRetryAlarmIntent);
-        }
-
-        // always publish the latest status.
-        synchronized(mSyncObj) {
-            publishRequest.refreshPublishContent();
-        }
-
-        logger.print("publishRequest=" + publishRequest);
-        if(!publishRequest.getForceToNetwork() && isPublishedOrPublishing() &&
-                (publishRequest.hasSamePublishContent(mPublishingRequest) ||
-                        (mPublishingRequest == null) &&
-                        publishRequest.hasSamePublishContent(mPublishedRequest)) &&
-                (getPublishState() != PublishState.PUBLISH_STATE_NOT_PUBLISHED)) {
-            logger.print("Don't need publish since the capability didn't change publishRequest " +
-                    publishRequest + " getPublishState()=" + getPublishState());
-            return;
-        }
-
-        // Don't publish too frequently. Checking the throttle timer.
-        if(isPublishedOrPublishing()) {
-            if(mPendingRetry) {
-                logger.print("Pending a retry");
-                return;
-            }
-
-            long publishThreshold = RcsSettingUtils.getPublishThrottle(mContext);
-            long passed = publishThreshold;
-            if(mPublishingRequest != null) {
-                passed = System.currentTimeMillis() - mPublishingRequest.getTimestamp();
-            } else if(mPublishedRequest != null) {
-                passed = System.currentTimeMillis() - mPublishedRequest.getTimestamp();
-            }
-            passed = passed>=0?passed:publishThreshold;
-
-            long left = publishThreshold - passed;
-            left = left>120000?120000:left; // Don't throttle more then 2 mintues.
-            if(left > 0) {
-                // A publish is ongoing or published in 1 minute.
-                // Since the new publish has new status. So schedule
-                // the publish after the throttle timer.
-                scheduleRetryPublish(left);
-                return;
-            }
-        }
-
-        // we need send PUBLISH once even the volte is off when power on the phone.
-        // That will tell other phone that it has no volte/vt capability.
-        if(!ImsManager.isEnhanced4gLteModeSettingEnabledByUser(mContext) &&
-                getPublishState() != PublishState.PUBLISH_STATE_NOT_PUBLISHED) {
-             // volte was not enabled.
-             // or it is turnning off volte. lower layer should unpublish
-             reset();
-             return;
-        }
-
-        TelephonyManager teleMgr = (TelephonyManager) mContext.getSystemService(
-                Context.TELEPHONY_SERVICE);
-        if(teleMgr ==null) {
-             logger.debug("teleMgr=null");
-             return;
-         }
-
-        RcsPresenceInfo presenceInfo = new RcsPresenceInfo(teleMgr.getLine1Number(),
-                RcsPresenceInfo.VolteStatus.VOLTE_UNKNOWN,
-                publishRequest.getVolteCapable()?RcsPresenceInfo.ServiceState.ONLINE:
-                        RcsPresenceInfo.ServiceState.OFFLINE, null, System.currentTimeMillis(),
-                publishRequest.getVtCapable()?RcsPresenceInfo.ServiceState.ONLINE:
-                        RcsPresenceInfo.ServiceState.OFFLINE, null,
-                        System.currentTimeMillis());
-
-        synchronized(mSyncObj) {
-            mPublishingRequest = publishRequest;
-            mPublishingRequest.setTimestamp(System.currentTimeMillis());
-        }
-
-        int ret = mRcsStackAdaptor.requestPublication(presenceInfo, null);
-        if(ret == ResultCode.ERROR_SERVICE_NOT_AVAILABLE){
-            mHasCachedTrigger = true;
-        }else{
-            //reset the cached trigger
-            mHasCachedTrigger = false;
-        }
-    }
-
-    public void handleCmdStatus(PresCmdStatus cmdStatus) {
-        super.handleCmdStatus(cmdStatus);
-    }
-
-    private PendingIntent mRetryAlarmIntent = null;
-    public static final String ACTION_RETRY_PUBLISH_ALARM =
-            "com.android.service.ims.presence.retry.publish";
-    private AlarmManager mAlarmManager = null;
-    private BroadcastReceiver mRetryReceiver = null;
-    boolean mCancelRetry = true;
-    boolean mPendingRetry = false;
-
-    private void scheduleRetryPublish(long timeSpan) {
-        logger.print("timeSpan=" + timeSpan +
-                " mPendingRetry=" + mPendingRetry +
-                " mCancelRetry=" + mCancelRetry);
-
-        // avoid duplicated retry.
-        if(mPendingRetry) {
-            logger.debug("There was a retry already");
-            return;
-        }
-        mPendingRetry = true;
-        mCancelRetry = false;
-
-        Intent intent = new Intent(ACTION_RETRY_PUBLISH_ALARM);
-        intent.setClass(mContext, AlarmBroadcastReceiver.class);
-        mRetryAlarmIntent = PendingIntent.getBroadcast(mContext, 0, intent,
-                PendingIntent.FLAG_UPDATE_CURRENT);
-
-        if(mAlarmManager == null) {
-            mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
-        }
-
-        mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP,
-                SystemClock.elapsedRealtime() + timeSpan, mRetryAlarmIntent);
-    }
-
-    public void retryPublish() {
-        logger.print("mCancelRetry=" + mCancelRetry);
-        mPendingRetry = false;
-
-        // Need some time to cancel it (1 minute for longest)
-        // Don't do it if it was canceled already.
-        if(mCancelRetry) {
-            return;
-        }
-
-        invokePublish(PublishType.PRES_PUBLISH_TRIGGER_RETRY);
-    }
-
-    public void handleSipResponse(PresSipResponse pSipResponse) {
-        logger.print( "Publish response code = " + pSipResponse.getSipResponseCode()
-                +"Publish response reason phrase = " + pSipResponse.getReasonPhrase());
-
-        synchronized(mSyncObj) {
-            mPublishedRequest = mPublishingRequest;
-            mPublishingRequest = null;
-        }
-        if(pSipResponse == null){
-            logger.debug("handlePublishResponse pSipResponse = null");
-            return;
-        }
-        int sipCode = pSipResponse.getSipResponseCode();
-
-        if(isInConfigList(sipCode, pSipResponse.getReasonPhrase(),
-                R.array.config_volte_provision_error_on_publish_response)) {
-            logger.print("volte provision error. sipCode=" + sipCode + " phrase=" +
-                    pSipResponse.getReasonPhrase());
-            setPublishState(PublishState.PUBLISH_STATE_VOLTE_PROVISION_ERROR);
-            mDonotRetryUntilPowerCycle = true;
-
-            notifyDm();
-
-            return;
-        }
-
-        if(isInConfigList(sipCode, pSipResponse.getReasonPhrase(),
-                R.array.config_rcs_provision_error_on_publish_response)) {
-            logger.print("rcs provision error.sipCode=" + sipCode + " phrase=" +
-                    pSipResponse.getReasonPhrase());
-            setPublishState(PublishState.PUBLISH_STATE_RCS_PROVISION_ERROR);
-            mDonotRetryUntilPowerCycle = true;
-
-            return;
-        }
-
-        switch (sipCode) {
-            case 999:
-                logger.debug("Publish ignored - No capability change");
-                break;
-            case 200:
-                setPublishState(PublishState.PUBLISH_STATE_200_OK);
-                if(mSubscriber != null) {
-                    mSubscriber.retryToGetAvailability();
-                }
-                break;
-
-            case 408:
-                setPublishState(PublishState.PUBLISH_STATE_REQUEST_TIMEOUT);
-                break;
-
-            default: // Generic Failure
-                if ((sipCode < 100) || (sipCode > 699)) {
-                    logger.debug("Ignore internal response code, sipCode=" + sipCode);
-                    // internal error
-                    //  0- PERMANENT ERROR: UI should not retry immediately
-                    //  888- TEMP ERROR:  UI Can retry immediately
-                    //  999- NO CHANGE: No Publish needs to be sent
-                    if(sipCode == 888) {
-                        // retry per 2 minutes
-                        scheduleRetryPublish(120000);
-                    } else {
-                        logger.debug("Ignore internal response code, sipCode=" + sipCode);
-                    }
-                } else {
-                    logger.debug( "Generic Failure");
-                    setPublishState(PublishState.PUBLISH_STATE_OTHER_ERROR);
-
-                    if ((sipCode>=400) && (sipCode <= 699)) {
-                        // 4xx/5xx/6xx, No retry, no impact on subsequent publish
-                        logger.debug( "No Retry in OEM");
-                    }
-                }
-                break;
-        }
-
-        // Suppose the request ID had been set when IQPresListener_CMDStatus
-        Task task = TaskManager.getDefault().getTaskByRequestId(
-                pSipResponse.getRequestId());
-        if(task != null){
-            task.mSipResponseCode = pSipResponse.getSipResponseCode();
-            task.mSipReasonPhrase = pSipResponse.getReasonPhrase();
-        }
-
-        handleCallback(task, getPublishState(), false);
-    }
-
-    private static boolean isTtyEnabled(int mode) {
-        return Phone.TTY_MODE_OFF != mode;
-    }
-
-    private static int telecomTtyModeToPhoneMode(int telecomMode) {
-        switch (telecomMode) {
-            case TelecomManager.TTY_MODE_FULL:
-                return Phone.TTY_MODE_FULL;
-            case TelecomManager.TTY_MODE_VCO:
-                return Phone.TTY_MODE_VCO;
-            case TelecomManager.TTY_MODE_HCO:
-                return Phone.TTY_MODE_HCO;
-            case TelecomManager.TTY_MODE_OFF:
-            default:
-                return Phone.TTY_MODE_OFF;
-        }
-    }
-
-    public void finish() {
-        if (mReceiver != null) {
-            mContext.unregisterReceiver(mReceiver);
-            mReceiver = null;
-        }
-    }
-
-    protected void finalize() throws Throwable {
-        finish();
-    }
-
-    private PendingIntent createIncomingCallPendingIntent() {
-        Intent intent = new Intent(ACTION_IMS_FEATURE_AVAILABLE);
-        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
-        return PendingIntent.getBroadcast(mContext, 0, intent,
-                PendingIntent.FLAG_UPDATE_CURRENT);
-    }
-
-    public void onFeatureCapabilityChanged(final int serviceClass,
-            final int[] enabledFeatures, final int[] disabledFeatures) {
-        logger.debug("onFeatureCapabilityChanged serviceClass="+serviceClass
-                +", enabledFeatures="+Arrays.toString(enabledFeatures)
-                +", disabledFeatures="+Arrays.toString(disabledFeatures));
-
-        Thread thread = new Thread(new Runnable() {
-            @Override
-            public void run() {
-                onFeatureCapabilityChangedInternal(serviceClass,
-                        enabledFeatures, disabledFeatures);
-            }
-        }, "onFeatureCapabilityChangedInternal thread");
-
-        thread.start();
-    }
-
-    synchronized private void onFeatureCapabilityChangedInternal(int serviceClass,
-            int[] enabledFeatures, int[] disabledFeatures) {
-        if (serviceClass == ImsServiceClass.MMTEL) {
-            boolean oldIsVolteAvailable = mIsVolteAvailable;
-            boolean oldIsVtAvailable = mIsVtAvailable;
-            boolean oldIsVoWifiAvailable = mIsVoWifiAvailable;
-            boolean oldIsViWifiAvailable = mIsViWifiAvailable;
-
-            if(enabledFeatures[ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_LTE] ==
-                    ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_LTE) {
-                mIsVolteAvailable = true;
-            } else if(enabledFeatures[ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_LTE] ==
-                    ImsConfig.FeatureConstants.FEATURE_TYPE_UNKNOWN) {
-                mIsVolteAvailable = false;
-            } else {
-                logger.print("invalid value for FEATURE_TYPE_VOICE_OVER_LTE");
-            }
-
-            if(enabledFeatures[ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_WIFI] ==
-                    ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_WIFI) {
-                mIsVoWifiAvailable = true;
-            } else if(enabledFeatures[ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_WIFI] ==
-                    ImsConfig.FeatureConstants.FEATURE_TYPE_UNKNOWN) {
-                mIsVoWifiAvailable = false;
-            } else {
-                logger.print("invalid value for FEATURE_TYPE_VOICE_OVER_WIFI");
-            }
-
-            if (enabledFeatures[ImsConfig.FeatureConstants.FEATURE_TYPE_VIDEO_OVER_LTE] ==
-                    ImsConfig.FeatureConstants.FEATURE_TYPE_VIDEO_OVER_LTE) {
-                mIsVtAvailable = true;
-            } else if (enabledFeatures[ImsConfig.FeatureConstants.FEATURE_TYPE_VIDEO_OVER_LTE] ==
-                    ImsConfig.FeatureConstants.FEATURE_TYPE_UNKNOWN) {
-                mIsVtAvailable = false;
-            } else {
-                logger.print("invalid value for FEATURE_TYPE_VIDEO_OVER_LTE");
-            }
-
-            if(enabledFeatures[ImsConfig.FeatureConstants.FEATURE_TYPE_VIDEO_OVER_WIFI] ==
-                    ImsConfig.FeatureConstants.FEATURE_TYPE_VIDEO_OVER_WIFI) {
-                mIsViWifiAvailable = true;
-            } else if(enabledFeatures[ImsConfig.FeatureConstants.FEATURE_TYPE_VIDEO_OVER_WIFI] ==
-                    ImsConfig.FeatureConstants.FEATURE_TYPE_UNKNOWN) {
-                mIsViWifiAvailable = false;
-            } else {
-                logger.print("invalid value for FEATURE_TYPE_VIDEO_OVER_WIFI");
-            }
-
-            logger.print("mIsVolteAvailable=" + mIsVolteAvailable +
-                    " mIsVoWifiAvailable=" + mIsVoWifiAvailable +
-                    " mIsVtAvailable=" + mIsVtAvailable +
-                    " mIsViWifiAvailable=" + mIsViWifiAvailable +
-                    " oldIsVolteAvailable=" + oldIsVolteAvailable +
-                    " oldIsVoWifiAvailable=" + oldIsVoWifiAvailable +
-                    " oldIsVtAvailable=" + oldIsVtAvailable +
-                    " oldIsViWifiAvailable=" + oldIsViWifiAvailable);
-
-            if(oldIsVolteAvailable != mIsVolteAvailable ||
-                    oldIsVtAvailable != mIsVtAvailable ||
-                    oldIsVoWifiAvailable != mIsVoWifiAvailable ||
-                    oldIsViWifiAvailable != mIsViWifiAvailable) {
-                if(mGotTriggerFromStack) {
-                    if((Settings.Global.getInt(mContext.getContentResolver(),
-                            Settings.Global.AIRPLANE_MODE_ON, 0) != 0) && !mIsVoWifiAvailable &&
-                            !mIsViWifiAvailable) {
-                        logger.print("Airplane mode was on and no vowifi and viwifi." +
-                            " Don't need publish. Stack will unpublish");
-                        return;
-                    }
-
-                    if(isOnIWLAN()) {
-                        // will check duplicated PUBLISH in requestPublication by invokePublish
-                        invokePublish(PresencePublication.PublishType.
-                                PRES_PUBLISH_TRIGGER_FEATURE_AVAILABILITY_CHANGED);
-                    }
-                } else {
-                    mHasCachedTrigger = true;
-                }
-            }
-        }
-    }
-
-    private boolean isOnLTE() {
-        TelephonyManager teleMgr = (TelephonyManager) mContext.getSystemService(
-                Context.TELEPHONY_SERVICE);
-            int networkType = teleMgr.getDataNetworkType();
-            logger.debug("mMovedToLTE=" + mMovedToLTE + " networkType=" + networkType);
-
-            // Had reported LTE by trigger and still have DATA.
-            return mMovedToLTE && (networkType != TelephonyManager.NETWORK_TYPE_UNKNOWN);
-    }
-
-    private boolean isOnIWLAN() {
-        TelephonyManager teleMgr = (TelephonyManager) mContext.getSystemService(
-                Context.TELEPHONY_SERVICE);
-            int networkType = teleMgr.getDataNetworkType();
-            logger.debug("mMovedToIWLAN=" + mMovedToIWLAN + " networkType=" + networkType);
-
-            // Had reported IWLAN by trigger and still have DATA.
-            return mMovedToIWLAN && (networkType != TelephonyManager.NETWORK_TYPE_UNKNOWN);
-    }
-
-}
diff --git a/rcs/rcsservice/src/com/android/service/ims/presence/PresencePublishTask.java b/rcs/rcsservice/src/com/android/service/ims/presence/PresencePublishTask.java
deleted file mode 100644
index 361488e..0000000
--- a/rcs/rcsservice/src/com/android/service/ims/presence/PresencePublishTask.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
-
-package com.android.service.ims.presence;
-
-import java.util.Set;
-import java.util.HashMap;
-import java.util.List;
-import java.util.ArrayList;
-import android.content.Context;
-import android.content.Intent;
-import android.app.PendingIntent;
-import android.content.IntentFilter;
-import android.os.RemoteException;
-import android.app.AlarmManager;
-import android.os.SystemClock;
-
-import com.android.ims.internal.uce.presence.PresCmdStatus;
-
-import com.android.ims.internal.Logger;
-import com.android.ims.RcsManager.ResultCode;
-import com.android.ims.RcsPresenceInfo;
-import com.android.ims.IRcsPresenceListener;
-
-import com.android.service.ims.TaskManager;
-
-/**
- * PresencePublishTask
- */
-public class PresencePublishTask extends PresenceTask{
-    /*
-     * The logger
-     */
-    private Logger logger = Logger.getLogger(this.getClass().getName());
-
-    private long mCreateTimestamp = 0;
-
-    private int mRetryCount = 0;
-
-    public PresencePublishTask(int taskId, int cmdId, IRcsPresenceListener listener,
-            String[] contacts){
-        super(taskId, cmdId, listener, contacts);
-
-        mCreateTimestamp = System.currentTimeMillis();
-    }
-
-    public long getCreateTimestamp() {
-        return mCreateTimestamp;
-    }
-
-    public int getRetryCount() {
-        return mRetryCount;
-    }
-
-    public void setRetryCount(int retryCount) {
-        mRetryCount = retryCount;
-    }
-
-    public String toString(){
-        return super.toString() +
-                " mCreateTimestamp=" + mCreateTimestamp +
-                " mRetryCount=" + mRetryCount;
-    }
-};
-
diff --git a/rcs/rcsservice/src/com/android/service/ims/presence/PresenceSubscriber.java b/rcs/rcsservice/src/com/android/service/ims/presence/PresenceSubscriber.java
deleted file mode 100644
index 60a783b..0000000
--- a/rcs/rcsservice/src/com/android/service/ims/presence/PresenceSubscriber.java
+++ /dev/null
@@ -1,628 +0,0 @@
-/*
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
-
-package com.android.service.ims.presence;
-
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Timer;
-import java.util.TimerTask;
-import java.util.concurrent.Semaphore;
-import android.content.ContentValues;
-import android.text.TextUtils;
-
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import com.android.internal.telephony.TelephonyIntents;
-import android.os.HandlerThread;
-import android.os.RemoteException;
-import android.telephony.TelephonyManager;
-import android.database.Cursor;
-
-import java.lang.String;
-import android.content.Context;
-import android.util.Log;
-
-import com.android.ims.internal.uce.presence.PresSipResponse;
-import com.android.ims.internal.uce.common.StatusCode;
-import com.android.ims.internal.uce.common.StatusCode;
-import com.android.ims.internal.uce.presence.PresSubscriptionState;
-import com.android.ims.internal.uce.presence.PresCmdStatus;
-import com.android.ims.internal.uce.presence.PresResInfo;
-import com.android.ims.internal.uce.presence.PresRlmiInfo;
-import com.android.ims.internal.uce.presence.PresTupleInfo;
-
-import com.android.ims.RcsPresenceInfo;
-import com.android.ims.RcsPresence;
-import com.android.ims.IRcsPresenceListener;
-import com.android.ims.RcsManager.ResultCode;
-import com.android.ims.RcsPresence.PublishState;
-
-import com.android.ims.internal.Logger;
-import com.android.ims.internal.ContactNumberUtils;
-import com.android.service.ims.TaskManager;
-import com.android.service.ims.Task;
-import com.android.service.ims.RcsStackAdaptor;
-import com.android.service.ims.RcsUtils;
-import com.android.service.ims.RcsSettingUtils;
-
-import com.android.service.ims.R;
-
-public class PresenceSubscriber extends PresenceBase{
-    /*
-     * The logger
-     */
-    private Logger logger = Logger.getLogger(this.getClass().getName());
-
-    private RcsStackAdaptor mRcsStackAdaptor = null;
-
-    private static PresenceSubscriber sSubsriber = null;
-
-    private String mAvailabilityRetryNumber = null;
-
-    /*
-     * Constructor
-     */
-    public PresenceSubscriber(RcsStackAdaptor rcsStackAdaptor, Context context){
-        mRcsStackAdaptor = rcsStackAdaptor;
-        mContext = context;
-    }
-
-    private String numberToUriString(String number){
-        String formatedContact = number;
-        if(!formatedContact.startsWith("sip:") && !formatedContact.startsWith("tel:")){
-            String domain = TelephonyManager.getDefault().getIsimDomain();
-            logger.debug("domain=" + domain);
-            if(domain == null || domain.length() ==0){
-                formatedContact = "tel:" + formatedContact;
-            }else{
-                formatedContact = "sip:" + formatedContact + "@" + domain;
-            }
-        }
-
-        logger.print("numberToUriString formatedContact=" + formatedContact);
-        return formatedContact;
-    }
-
-    private String numberToTelString(String number){
-        String formatedContact = number;
-        if(!formatedContact.startsWith("sip:") && !formatedContact.startsWith("tel:")){
-            formatedContact = "tel:" + formatedContact;
-        }
-
-        logger.print("numberToTelString formatedContact=" + formatedContact);
-        return formatedContact;
-    }
-
-    public int requestCapability(List<String> contactsNumber,
-            IRcsPresenceListener listener){
-        logger.debug("requestCapability contactsNumber=" + contactsNumber);
-
-        int ret = mRcsStackAdaptor.checkStackAndPublish();
-        if(ret < ResultCode.SUCCESS){
-            logger.error("requestCapability ret=" + ret);
-            return ret;
-        }
-
-        if(contactsNumber == null || contactsNumber.size() ==0){
-            ret = ResultCode.SUBSCRIBE_INVALID_PARAM;
-            return ret;
-        }
-
-        logger.debug("check contact size ...");
-        if(contactsNumber.size() > RcsSettingUtils.getMaxNumbersInRCL(mContext)){
-            ret = ResultCode.SUBSCRIBE_TOO_LARGE;
-            logger.error("requestCapability contctNumber size=" + contactsNumber.size());
-            return ret;
-        }
-
-        String[] formatedNumbers = ContactNumberUtils.getDefault().format(contactsNumber);
-        ret = ContactNumberUtils.getDefault().validate(formatedNumbers);
-        if(ret != ContactNumberUtils.NUMBER_VALID){
-            logger.error("requestCapability ret=" + ret);
-            return ret;
-        }
-
-        String[] formatedContacts = new String[formatedNumbers.length];
-        for(int i=0; i<formatedContacts.length; i++){
-            formatedContacts[i] = numberToTelString(formatedNumbers[i]);
-        }
-        // In ms
-        long timeout = RcsSettingUtils.getCapabPollListSubExp(mContext) * 1000;
-        timeout += RcsSettingUtils.getSIPT1Timer(mContext);
-
-        // The terminal notification may be received shortly after the time limit of
-        // the subscription due to network delays or retransmissions.
-        // Device shall wait for 3sec after the end of the subscription period in order to
-        // accept such notifications without returning spurious errors (e.g. SIP 481)
-        timeout += 3000;
-
-        logger.print("add to task manager, formatedNumbers=" +
-                RcsUtils.toContactString(formatedNumbers));
-        int taskId = TaskManager.getDefault().addCapabilityTask(mContext, formatedNumbers,
-                listener, timeout);
-        logger.print("taskId=" + taskId);
-
-        ret = mRcsStackAdaptor.requestCapability(formatedContacts, taskId);
-        if(ret < ResultCode.SUCCESS){
-            logger.error("requestCapability ret=" + ret + " remove taskId=" + taskId);
-            TaskManager.getDefault().removeTask(taskId);
-        }
-
-        ret = taskId;
-
-        return  ret;
-    }
-
-    public int requestAvailability(String contactNumber, IRcsPresenceListener listener,
-            boolean forceToNetwork){
-        logger.print("requestAvailability contactNumber=" + contactNumber +
-                " forceToNetwork=" + forceToNetwork);
-
-        String formatedContact = ContactNumberUtils.getDefault().format(contactNumber);
-        int ret = ContactNumberUtils.getDefault().validate(formatedContact);
-        if(ret != ContactNumberUtils.NUMBER_VALID){
-            return ret;
-        }
-
-        if(!forceToNetwork){
-            logger.debug("check if we can use the value in cache");
-            int availabilityExpire = RcsSettingUtils.getAvailabilityCacheExpiration(mContext);
-            availabilityExpire = availabilityExpire>0?availabilityExpire*1000:
-                    60*1000; // by default is 60s
-            logger.print("requestAvailability availabilityExpire=" + availabilityExpire);
-
-            TaskManager.getDefault().clearTimeoutAvailabilityTask(availabilityExpire);
-
-            Task task = TaskManager.getDefault().getAvailabilityTaskByContact(formatedContact);
-            if(task != null && task instanceof PresenceAvailabilityTask) {
-                PresenceAvailabilityTask availabilityTask = (PresenceAvailabilityTask)task;
-                if(availabilityTask.getNotifyTimestamp() == 0) {
-                    // The previous one didn't get response yet.
-                    logger.print("requestAvailability: the request is pending in queue");
-                    return ResultCode.SUBSCRIBE_ALREADY_IN_QUEUE;
-                }else {
-                    // not expire yet. Can use the previous value.
-                    logger.print("requestAvailability: the prevous valuedoesn't be expired yet");
-                    return ResultCode.SUBSCRIBE_TOO_FREQUENTLY;
-                }
-            }
-        }
-
-        boolean isFtSupported = false; // hard code to not support FT at present.
-        boolean isChatSupported = false;  // hard code to not support chat at present.
-        // Only poll/fetch capability/availability on LTE
-        if(((TelephonyManager.getDefault().getNetworkType() != TelephonyManager.NETWORK_TYPE_LTE)
-                && !isFtSupported && !isChatSupported)){
-            logger.error("requestAvailability return ERROR_SERVICE_NOT_AVAILABLE" +
-                    " for it is not LTE network");
-            return ResultCode.ERROR_SERVICE_NOT_AVAILABLE;
-        }
-
-        ret = mRcsStackAdaptor.checkStackAndPublish();
-        if(ret < ResultCode.SUCCESS){
-            logger.error("requestAvailability=" + ret);
-            return ret;
-        }
-
-        // user number format in TaskManager.
-        int taskId = TaskManager.getDefault().addAvailabilityTask(formatedContact, listener);
-
-        // Change it to URI format.
-        formatedContact = numberToUriString(formatedContact);
-
-        logger.print("addAvailabilityTask formatedContact=" + formatedContact);
-
-        ret = mRcsStackAdaptor.requestAvailability(formatedContact, taskId);
-        if(ret < ResultCode.SUCCESS){
-            logger.error("requestAvailability ret=" + ret + " remove taskId=" + taskId);
-            TaskManager.getDefault().removeTask(taskId);
-        }
-
-        ret = taskId;
-
-        return  ret;
-    }
-
-    private int translateResponse403(PresSipResponse pSipResponse){
-        String reasonPhrase = pSipResponse.getReasonPhrase();
-        if(reasonPhrase == null){
-            // No retry. The PS provisioning has not occurred correctly. UX Decision to show errror.
-            return ResultCode.SUBSCRIBE_GENIRIC_FAILURE;
-        }
-
-        reasonPhrase = reasonPhrase.toLowerCase();
-        if(reasonPhrase.contains("user not registered")){
-            // Register to IMS then retry the single resource subscription if capability polling.
-            // availability fetch: no retry. ignore the availability and allow LVC? (PLM decision)
-            return ResultCode.SUBSCRIBE_NOT_REGISTERED;
-        }
-
-        if(reasonPhrase.contains("not authorized for presence")){
-            // No retry.
-            return ResultCode.SUBSCRIBE_NOT_AUTHORIZED_FOR_PRESENCE;
-        }
-
-        // unknown phrase: handle it as the same as no phrase
-        return ResultCode.SUBSCRIBE_FORBIDDEN;
-    }
-
-    private int translateResponseCode(PresSipResponse pSipResponse){
-        // pSipResponse should not be null.
-        logger.debug("translateResponseCode getSipResponseCode=" +
-                pSipResponse.getSipResponseCode());
-        int ret = ResultCode.SUBSCRIBE_GENIRIC_FAILURE;
-
-        int sipCode = pSipResponse.getSipResponseCode();
-        if(sipCode < 100 || sipCode > 699){
-            logger.debug("internal error code sipCode=" + sipCode);
-            ret = ResultCode.SUBSCRIBE_TEMPORARY_ERROR; //it is internal issue. ignore it.
-            return ret;
-        }
-
-        switch(sipCode){
-            case 200:
-                ret = ResultCode.SUCCESS;
-                break;
-
-            case 403:
-                ret = translateResponse403(pSipResponse);
-                break;
-
-            case 404:
-               // Target MDN is not provisioned for VoLTE or it is not  known as VzW IMS subscriber
-               // Device shall not retry. Device shall remove the VoLTE status of the target MDN
-               // and update UI
-               ret = ResultCode.SUBSCRIBE_NOT_FOUND;
-               break;
-
-            case 408:
-                // Request Timeout
-                // Device shall retry with exponential back-off
-                ret = ResultCode.SUBSCRIBE_TEMPORARY_ERROR;
-                break;
-
-            case 413:
-                // Too Large.
-                // Application need shrink the size of request contact list and resend the request
-                ret = ResultCode.SUBSCRIBE_TOO_LARGE;
-                break;
-
-            case 423:
-                // Interval Too Short. Requested expiry interval too short and server rejects it
-                // Device shall re-attempt subscription after changing the expiration interval in
-                // the Expires header field to be equal to or greater than the expiration interval
-                // within the Min-Expires header field of the 423 response
-                ret = ResultCode.SUBSCRIBE_TEMPORARY_ERROR;
-                break;
-
-            case 500:
-                // 500 Server Internal Error
-                // capability polling: exponential back-off retry (same rule as resource list)
-                // availability fetch: no retry. ignore the availability and allow LVC
-                // (PLM decision)
-                ret = ResultCode.SUBSCRIBE_TEMPORARY_ERROR;
-                break;
-
-            case 503:
-                // capability polling: exponential back-off retry (same rule as resource list)
-                // availability fetch: no retry. ignore the availability and allow LVC?
-                // (PLM decision)
-                ret = ResultCode.SUBSCRIBE_TEMPORARY_ERROR;
-                break;
-
-                // capability polling: Device shall retry with exponential back-off
-                // Availability Fetch: device shall ignore the error and shall not retry
-            case 603:
-                ret = ResultCode.SUBSCRIBE_TEMPORARY_ERROR;
-                break;
-
-            default:
-                // Other 4xx/5xx/6xx
-                // Device shall not retry
-                ret = ResultCode.SUBSCRIBE_GENIRIC_FAILURE;
-        }
-
-        logger.debug("translateResponseCode ret=" + ret);
-        return ret;
-    }
-
-    public void handleSipResponse(PresSipResponse pSipResponse){
-        if(pSipResponse == null){
-            logger.debug("handleSipResponse pSipResponse = null");
-            return;
-        }
-
-        int sipCode = pSipResponse.getSipResponseCode();
-        String phrase = pSipResponse.getReasonPhrase();
-        if(isInConfigList(sipCode, phrase,
-                R.array.config_volte_provision_error_on_subscribe_response)) {
-            logger.print("volte provision sipCode=" + sipCode + " phrase=" + phrase);
-            mRcsStackAdaptor.setPublishState(PublishState.PUBLISH_STATE_VOLTE_PROVISION_ERROR);
-
-            notifyDm();
-        } else if(isInConfigList(sipCode, phrase,
-                R.array.config_rcs_provision_error_on_subscribe_response)) {
-            logger.print("rcs provision sipCode=" + sipCode + " phrase=" + phrase);
-            mRcsStackAdaptor.setPublishState(PublishState.PUBLISH_STATE_RCS_PROVISION_ERROR);
-        }
-
-        int errorCode = translateResponseCode(pSipResponse);
-        logger.print("handleSipResponse errorCode=" + errorCode);
-
-        if(errorCode == ResultCode.SUBSCRIBE_NOT_REGISTERED){
-            logger.debug("setPublishState to unknown" +
-                   " for subscribe error 403 not registered");
-            mRcsStackAdaptor.setPublishState(
-                   PublishState.PUBLISH_STATE_OTHER_ERROR);
-        }
-
-        if(errorCode == ResultCode.SUBSCRIBE_NOT_AUTHORIZED_FOR_PRESENCE) {
-            logger.debug("ResultCode.SUBSCRIBE_NOT_AUTHORIZED_FOR_PRESENCE");
-        }
-
-        if(errorCode == ResultCode.SUBSCRIBE_FORBIDDEN){
-            logger.debug("ResultCode.SUBSCRIBE_FORBIDDEN");
-        }
-
-        // Suppose the request ID had been set when IQPresListener_CMDStatus
-        Task task = TaskManager.getDefault().getTaskByRequestId(
-                pSipResponse.getRequestId());
-        logger.debug("handleSipResponse task=" + task);
-        if(task != null){
-            task.mSipResponseCode = sipCode;
-            task.mSipReasonPhrase = phrase;
-            TaskManager.getDefault().putTask(task.mTaskId, task);
-        }
-
-        if(errorCode == ResultCode.SUBSCRIBE_NOT_REGISTERED &&
-                task != null && task.mCmdId == TaskManager.TASK_TYPE_GET_AVAILABILITY) {
-            String[] contacts = ((PresenceTask)task).mContacts;
-            if(contacts != null && contacts.length>0){
-                mAvailabilityRetryNumber = contacts[0];
-            }
-            logger.debug("retry to get availability for " + mAvailabilityRetryNumber);
-        }
-
-        // 404 error for single contact only as per requirement
-        // need handle 404 for multiple contacts as per CV 3.24.
-        if(errorCode == ResultCode.SUBSCRIBE_NOT_FOUND &&
-                task != null && ((PresenceTask)task).mContacts != null) {
-            String[] contacts = ((PresenceTask)task).mContacts;
-            ArrayList<RcsPresenceInfo> presenceInfoList = new ArrayList<RcsPresenceInfo>();
-
-            for(int i=0; i<contacts.length; i++){
-                logger.debug("404 error: task.mContacts[" + i + "]=" + contacts[i]);
-                if(TextUtils.isEmpty(contacts[i])){
-                    continue;
-                }
-
-                RcsPresenceInfo presenceInfo = new RcsPresenceInfo(contacts[i],
-                        RcsPresenceInfo.VolteStatus.VOLTE_DISABLED,
-                        RcsPresenceInfo.ServiceState.OFFLINE, null, System.currentTimeMillis(),
-                        RcsPresenceInfo.ServiceState.OFFLINE, null, System.currentTimeMillis());
-                presenceInfoList.add(presenceInfo);
-            }
-
-            // Notify presence information changed.
-            logger.debug("notify presence changed for 404 error");
-            Intent intent = new Intent(RcsPresence.ACTION_PRESENCE_CHANGED);
-            intent.putParcelableArrayListExtra(RcsPresence.EXTRA_PRESENCE_INFO_LIST,
-                    presenceInfoList);
-            intent.putExtra("updateLastTimestamp", true);
-            launchPersistService(intent);
-        } else if(errorCode == ResultCode.SUBSCRIBE_GENIRIC_FAILURE) {
-            updateAvailabilityToUnknown(task);
-        }
-
-        handleCallback(task, errorCode, false);
-    }
-
-    private void launchPersistService(Intent intent) {
-        ComponentName component = new ComponentName("com.android.service.ims.presence",
-                "com.android.service.ims.presence.PersistService");
-        intent.setComponent(component);
-        mContext.startService(intent);
-    }
-
-    public void retryToGetAvailability() {
-        logger.debug("retryToGetAvailability, number=" + mAvailabilityRetryNumber);
-        if(mAvailabilityRetryNumber == null){
-            return;
-        }
-        requestAvailability(mAvailabilityRetryNumber, null, true);
-        //retry one time only
-        mAvailabilityRetryNumber = null;
-    }
-
-    public void updatePresence(String pPresentityUri, PresTupleInfo[] pTupleInfo){
-        if(mContext == null){
-            logger.error("updatePresence mContext == null");
-            return;
-        }
-
-        RcsPresenceInfo rcsPresenceInfo = PresenceInfoParser.getPresenceInfoFromTuple(
-                pPresentityUri, pTupleInfo);
-        if(rcsPresenceInfo == null || TextUtils.isEmpty(
-                rcsPresenceInfo.getContactNumber())){
-            logger.error("rcsPresenceInfo is null or " +
-                    "TextUtils.isEmpty(rcsPresenceInfo.getContactNumber()");
-            return;
-        }
-
-        ArrayList<RcsPresenceInfo> rcsPresenceInfoList = new ArrayList<RcsPresenceInfo>();
-        rcsPresenceInfoList.add(rcsPresenceInfo);
-
-        // For single contact number we got 1 NOTIFY only. So regard it as terminated.
-        TaskManager.getDefault().onTerminated(rcsPresenceInfo.getContactNumber());
-
-        PresenceAvailabilityTask availabilityTask = TaskManager.getDefault().
-                getAvailabilityTaskByContact(rcsPresenceInfo.getContactNumber());
-        if(availabilityTask != null){
-            availabilityTask.updateNotifyTimestamp();
-        }
-
-        // Notify presence information changed.
-        Intent intent = new Intent(RcsPresence.ACTION_PRESENCE_CHANGED);
-        intent.putParcelableArrayListExtra(RcsPresence.EXTRA_PRESENCE_INFO_LIST,
-                rcsPresenceInfoList);
-        intent.putExtra("updateLastTimestamp", true);
-        launchPersistService(intent);
-    }
-
-    public void updatePresences(PresRlmiInfo pRlmiInfo, PresResInfo[] pRcsPresenceInfo) {
-        if(mContext == null){
-            logger.error("updatePresences: mContext == null");
-            return;
-        }
-
-        RcsPresenceInfo[] rcsPresenceInfos = PresenceInfoParser.
-                getPresenceInfosFromPresenceRes(pRlmiInfo, pRcsPresenceInfo);
-        if(rcsPresenceInfos == null){
-            logger.error("updatePresences: rcsPresenceInfos == null");
-            return;
-        }
-
-        ArrayList<RcsPresenceInfo> rcsPresenceInfoList = new ArrayList<RcsPresenceInfo>();
-
-        for (int i=0; i < rcsPresenceInfos.length; i++) {
-            RcsPresenceInfo rcsPresenceInfo = rcsPresenceInfos[i];
-            if(rcsPresenceInfo != null && !TextUtils.isEmpty(rcsPresenceInfo.getContactNumber())){
-                logger.debug("rcsPresenceInfo=" + rcsPresenceInfo);
-
-                rcsPresenceInfoList.add(rcsPresenceInfo);
-            }
-        }
-
-        boolean isTerminated = false;
-        if(pRlmiInfo.getPresSubscriptionState() != null){
-            if(pRlmiInfo.getPresSubscriptionState().getPresSubscriptionStateValue() ==
-                    PresSubscriptionState.UCE_PRES_SUBSCRIPTION_STATE_TERMINATED){
-                isTerminated = true;
-            }
-        }
-
-        if(isTerminated){
-            TaskManager.getDefault().onTerminated(pRlmiInfo.getRequestId(),
-                    pRlmiInfo.getSubscriptionTerminatedReason());
-        }
-
-        if (rcsPresenceInfoList.size() > 0) {
-            // Notify presence changed
-            Intent intent = new Intent(RcsPresence.ACTION_PRESENCE_CHANGED);
-            intent.putParcelableArrayListExtra(RcsPresence.EXTRA_PRESENCE_INFO_LIST,
-                    rcsPresenceInfoList);
-            logger.debug("broadcast ACTION_PRESENCE_CHANGED, rcsPresenceInfo=" +
-                    rcsPresenceInfoList);
-            intent.putExtra("updateLastTimestamp", true);
-            launchPersistService(intent);
-        }
-    }
-
-    public void handleCmdStatus(PresCmdStatus pCmdStatus){
-        if(pCmdStatus == null){
-            logger.error("handleCallbackForCmdStatus pCmdStatus=null");
-            return;
-        }
-
-
-        Task taskTmp = TaskManager.getDefault().getTask(pCmdStatus.getUserData());
-        int resultCode = RcsUtils.statusCodeToResultCode(pCmdStatus.getStatus().getStatusCode());
-        logger.print("handleCmdStatus resultCode=" + resultCode);
-        PresenceTask task = null;
-        if(taskTmp != null && (taskTmp instanceof PresenceTask)){
-            task = (PresenceTask)taskTmp;
-            task.mSipRequestId = pCmdStatus.getRequestId();
-            task.mCmdStatus = resultCode;
-            TaskManager.getDefault().putTask(task.mTaskId, task);
-
-            // handle error as the same as temporary network error
-            // set availability to false, keep old capability
-            if(resultCode != ResultCode.SUCCESS && task.mContacts != null){
-                updateAvailabilityToUnknown(task);
-            }
-        }
-
-        handleCallback(task, resultCode, true);
-    }
-
-    private void updateAvailabilityToUnknown(Task inTask){
-        //only used for serviceState is offline or unknown.
-        if(mContext == null){
-            logger.error("updateAvailabilityToUnknown mContext=null");
-            return;
-        }
-
-        if(inTask == null){
-            logger.error("updateAvailabilityToUnknown task=null");
-            return;
-        }
-
-        if(!(inTask instanceof PresenceTask)){
-            logger.error("updateAvailabilityToUnknown not PresencTask");
-            return;
-        }
-
-        PresenceTask task = (PresenceTask)inTask;
-
-        if(task.mContacts == null || task.mContacts.length ==0){
-            logger.error("updateAvailabilityToUnknown no contacts");
-            return;
-        }
-
-        ArrayList<RcsPresenceInfo> presenceInfoList = new ArrayList<RcsPresenceInfo>();
-        for(int i = 0; i< task.mContacts.length; i++){
-            if(task.mContacts[i] == null || task.mContacts[i].length() == 0){
-                continue;
-            }
-
-            RcsPresenceInfo presenceInfo = new RcsPresenceInfo(
-                PresenceInfoParser.getPhoneFromUri(task.mContacts[i]),
-                        RcsPresenceInfo.VolteStatus.VOLTE_UNKNOWN,
-                        RcsPresenceInfo.ServiceState.UNKNOWN, null, System.currentTimeMillis(),
-                        RcsPresenceInfo.ServiceState.UNKNOWN, null, System.currentTimeMillis());
-            presenceInfoList.add(presenceInfo);
-        }
-
-        if(presenceInfoList.size() > 0) {
-             // Notify presence information changed.
-             logger.debug("notify presence changed for cmd error");
-             Intent intent = new Intent(RcsPresence.ACTION_PRESENCE_CHANGED);
-             intent.putParcelableArrayListExtra(RcsPresence.EXTRA_PRESENCE_INFO_LIST,
-                     presenceInfoList);
-
-             // don't update timestamp so it can be subscribed soon.
-             intent.putExtra("updateLastTimestamp", false);
-             launchPersistService(intent);
-        }
-    }
-}
-
diff --git a/rcs/rcsservice/src/com/android/service/ims/presence/PresenceTask.java b/rcs/rcsservice/src/com/android/service/ims/presence/PresenceTask.java
deleted file mode 100644
index 8ff74cd..0000000
--- a/rcs/rcsservice/src/com/android/service/ims/presence/PresenceTask.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
-
-package com.android.service.ims.presence;
-
-import java.util.Set;
-import java.util.HashMap;
-import java.util.List;
-import java.util.ArrayList;
-import android.os.RemoteException;
-
-import com.android.ims.internal.uce.presence.PresCmdStatus;
-
-import com.android.ims.internal.Logger;
-import com.android.ims.RcsManager.ResultCode;
-import com.android.ims.RcsPresenceInfo;
-import com.android.ims.IRcsPresenceListener;
-
-import com.android.service.ims.Task;
-import com.android.service.ims.RcsUtils;
-
-/**
- * PresenceTask
- */
-public class PresenceTask extends Task{
-    /*
-     * The logger
-     */
-    private Logger logger = Logger.getLogger(this.getClass().getName());
-
-    // filled before send the request to stack
-    public String[] mContacts;
-
-    public PresenceTask(int taskId, int cmdId, IRcsPresenceListener listener, String[] contacts){
-        super(taskId, cmdId, listener);
-
-        mContacts = contacts;
-        mListener = listener;
-    }
-
-    public String toString(){
-        return "PresenceTask: mTaskId=" + mTaskId +
-                " mCmdId=" + mCmdId +
-                " mContacts=" + RcsUtils.toContactString(mContacts) +
-                " mCmdStatus=" + mCmdStatus +
-                " mSipRequestId=" + mSipRequestId +
-                " mSipResponseCode=" + mSipResponseCode +
-                " mSipReasonPhrase=" + mSipReasonPhrase;
-    }
-};
-
diff --git a/rcs/rcsservice/src/com/android/service/ims/presence/StackListener.java b/rcs/rcsservice/src/com/android/service/ims/presence/StackListener.java
deleted file mode 100644
index 5abc19f..0000000
--- a/rcs/rcsservice/src/com/android/service/ims/presence/StackListener.java
+++ /dev/null
@@ -1,535 +0,0 @@
-/*
- * Copyright (c) 2015, Motorola Mobility LLC
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     - Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     - Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     - Neither the name of Motorola Mobility nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
-
-package com.android.service.ims.presence;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import android.content.ServiceConnection;
-import android.annotation.SuppressLint;
-import android.content.Intent;
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.RemoteException;
-import android.text.TextUtils;
-import android.util.Log;
-import android.os.Parcel;
-
-import com.android.ims.internal.uce.presence.IPresenceListener;
-import com.android.ims.internal.uce.presence.PresCmdId;
-import com.android.ims.internal.uce.presence.PresCmdStatus;
-import com.android.ims.internal.uce.presence.PresPublishTriggerType;
-import com.android.ims.internal.uce.presence.PresResInfo;
-import com.android.ims.internal.uce.presence.PresRlmiInfo;
-import com.android.ims.internal.uce.presence.PresSipResponse;
-import com.android.ims.internal.uce.presence.PresTupleInfo;
-import com.android.ims.internal.uce.common.StatusCode;
-import com.android.ims.internal.uce.common.StatusCode;
-
-import com.android.ims.RcsManager;
-import com.android.ims.RcsManager.ResultCode;
-import com.android.ims.RcsPresence;
-import com.android.ims.RcsPresenceInfo;
-import com.android.ims.IRcsPresenceListener;
-
-import com.android.ims.internal.Logger;
-import com.android.service.ims.TaskManager;
-import com.android.service.ims.Task;
-import com.android.service.ims.RcsStackAdaptor;
-import com.android.service.ims.LauncherUtils;
-
-public class StackListener extends Handler{
-    /*
-     * The logger
-     */
-    private Logger logger = Logger.getLogger(this.getClass().getName());
-
-    Context mContext;
-    private PresencePublication mPresencePublication = null;
-    private PresenceSubscriber mPresenceSubscriber = null;
-
-    // RCS stack notify the AP to publish the presence.
-    private static final short PRESENCE_IMS_UNSOL_PUBLISH_TRIGGER = 1;
-    // PUBLISH CMD status changed
-    private static final short PRESENCE_IMS_UNSOL_PUBLISH_CMDSTATUS = 2;
-    // Received the SIP response for publish
-    private static final short PRESENCE_IMS_UNSOL_PUBLISH_SIPRESPONSE = 3;
-    // Received the presence for single contact
-    private static final short PRESENCE_IMS_UNSOL_NOTIFY_UPDATE = 4;
-    // Received the presence for contacts.
-    private static final short PRESENCE_IMS_UNSOL_NOTIFY_LIST_UPDATE = 5;
-    // Received the CMD status for capability/availability request
-    private static final short PRESENCE_IMS_UNSOL_NOTIFY_UPDATE_CMDSTATUS = 6;
-    // Received the SIP response for capability/availability request
-    private static final short PRESENCE_IMS_UNSOL_NOTIFY_UPDATE_SIPRESPONSE = 7;
-
-    private final Object mSyncObj = new Object();
-
-    public StackListener(Context context, Looper looper) {
-        super(looper);
-        mContext = context;
-    }
-
-    public void setPresencePublication(PresencePublication presencePublication){
-        mPresencePublication = presencePublication;
-    }
-
-    public void setPresenceSubscriber(PresenceSubscriber presenceSubscriber){
-        mPresenceSubscriber = presenceSubscriber;
-    }
-
-    @Override
-    public void handleMessage(Message msg) {
-        super.handleMessage(msg);
-
-        logger.debug( "Thread=" + Thread.currentThread().getName() + " received "
-                + msg);
-        if(msg == null){
-            logger.error("msg=null");
-            return;
-        }
-
-        switch (msg.what) {
-            // RCS stack notify the AP to publish the presence.
-            case PRESENCE_IMS_UNSOL_PUBLISH_TRIGGER:
-            {
-                PresPublishTriggerType val = (PresPublishTriggerType) msg.obj;
-                if(mPresencePublication == null || val == null){
-                    logger.error("mPresencePublication=" + mPresencePublication + " val=" + val);
-                    return;
-                }
-
-                mPresencePublication.invokePublish(val);
-                break;
-            }
-
-            // RCS stack tell AP that the CMD status changed.
-            case PRESENCE_IMS_UNSOL_PUBLISH_CMDSTATUS:
-            {
-                PresCmdStatus pCmdStatus = (PresCmdStatus) msg.obj;
-                if(mPresencePublication == null || pCmdStatus == null){
-                    logger.error("mPresencePublication=" + mPresencePublication +
-                            " pCmdStatus=" + pCmdStatus);
-                    return;
-                }
-
-                mPresencePublication.handleCmdStatus(pCmdStatus);
-            }
-                break;
-
-            // RCS stack tells AP that the CMD status changed.
-            case PRESENCE_IMS_UNSOL_NOTIFY_UPDATE_CMDSTATUS:
-            {
-                PresCmdStatus pCmdStatus = (PresCmdStatus) msg.obj;
-                if(mPresenceSubscriber == null || pCmdStatus == null){
-                    logger.error("mPresenceSubcriber=" + mPresenceSubscriber +
-                            " pCmdStatus=" + pCmdStatus);
-                    return;
-                }
-
-                mPresenceSubscriber.handleCmdStatus(pCmdStatus);
-                break;
-            }
-
-            // RCS stack tells AP that the SIP response has been received.
-            case PRESENCE_IMS_UNSOL_PUBLISH_SIPRESPONSE:
-            {
-                PresSipResponse pSipResponse =  (PresSipResponse) msg.obj;
-                if(mPresencePublication == null || pSipResponse == null){
-                    logger.error("mPresencePublication=" + mPresencePublication +
-                            "pSipResponse=" +pSipResponse);
-                    return;
-                }
-
-                mPresencePublication.handleSipResponse(pSipResponse);
-                break;
-            }
-
-            // RCS stack tells AP that the SIP response has been received.
-            case PRESENCE_IMS_UNSOL_NOTIFY_UPDATE_SIPRESPONSE:
-            {
-                PresSipResponse pSipResponse =  (PresSipResponse) msg.obj;
-                if(mPresenceSubscriber == null || pSipResponse == null){
-                    logger.error("mPresenceSubscriber=" + mPresenceSubscriber +
-                            " pSipResponse=" + pSipResponse);
-                    return;
-                }
-
-                mPresenceSubscriber.handleSipResponse(pSipResponse);
-                break;
-            }
-
-            // RCS stack tells AP that the presence data has been received.
-            case PRESENCE_IMS_UNSOL_NOTIFY_UPDATE:
-            {
-                NotifyData notifyData = (NotifyData) msg.obj;
-                if(mPresenceSubscriber == null || notifyData == null){
-                    logger.error("mPresenceSubscriber=" + mPresenceSubscriber +
-                            " notifyData=" + notifyData);
-                    return;
-                }
-
-                mPresenceSubscriber.updatePresence(notifyData.getUri(),
-                        notifyData.getTupleInfo());
-                break;
-            }
-
-            case PRESENCE_IMS_UNSOL_NOTIFY_LIST_UPDATE:
-            {
-                NotifyListData notifyListData = (NotifyListData) msg.obj;
-                logger.debug("Received PRESENCE_IMS_UNSOL_NOTIFY_LIST_UPDATE");
-                if(mPresenceSubscriber==null || notifyListData == null){
-                    logger.error("mPresenceSubscriber=" + mPresenceSubscriber +
-                            " notifyListData=" + notifyListData);
-                    return;
-                }
-
-                mPresenceSubscriber.updatePresences(notifyListData.getRlmiInfo(),
-                        notifyListData.getResInfo());
-                break;
-            }
-
-            default:
-                logger.debug("Unknown mesg " + msg.what + " recieved.");
-        }
-    }
-
-    public class NotifyData{
-        private String mUri;
-        private PresTupleInfo[] mTupleInfo;
-
-        NotifyData(){
-            mUri = null;
-            mTupleInfo = null;
-        }
-
-        NotifyData(String uri, PresTupleInfo[] pTupleInfo){
-            mUri = uri;
-            mTupleInfo = pTupleInfo;
-        }
-
-        public String getUri(){
-            return mUri;
-        }
-
-        public PresTupleInfo[] getTupleInfo(){
-            return mTupleInfo;
-        }
-    }
-
-    public class NotifyListData{
-        private PresRlmiInfo mRlmiInfo;
-        private PresResInfo[] mResInfo;
-
-        NotifyListData(){
-            mRlmiInfo = null;
-            mResInfo = null;
-        }
-
-        NotifyListData(PresRlmiInfo pRlmiInfo, PresResInfo[] pResInfo){
-            mRlmiInfo = pRlmiInfo;
-            mResInfo = pResInfo;
-        }
-
-        public PresRlmiInfo getRlmiInfo(){
-            return mRlmiInfo;
-        }
-
-        public PresResInfo[] getResInfo(){
-            return mResInfo;
-        }
-    }
-
-    public IPresenceListener mPresenceListener = new IPresenceListener.Stub() {
-        public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
-               throws RemoteException{
-            try{
-                return super.onTransact(code, data, reply, flags);
-            } catch (RemoteException e) {
-                Log.w("ListenerHandler", "Unexpected remote exception", e);
-                e.printStackTrace();
-                throw e;
-           }
-        }
-
-        public void getVersionCb(String pVersion) {
-            logger.debug("pVersion=" + pVersion);
-        }
-
-        public void sipResponseReceived(PresSipResponse pSipResponse) throws RemoteException {
-            synchronized(mSyncObj){
-                if(pSipResponse == null){
-                    logger.error("ISipResponseReceived pSipResponse=null");
-                    return;
-                }
-
-                logger.debug("pSipResponse.getCmdId() "+
-                        pSipResponse.getCmdId().getCmdId());
-                logger.debug("getReasonPhrase() "+pSipResponse.getReasonPhrase());
-                logger.debug("getsRequestID() "+pSipResponse.getRequestId());
-                logger.debug("getsSipResponseCode() "+pSipResponse.getSipResponseCode());
-
-                switch (pSipResponse.getCmdId().getCmdId()) {
-                    case PresCmdId.UCE_PRES_CMD_PUBLISHMYCAP:
-                    {
-                        Message updateMesgSipPub = StackListener.this.obtainMessage(
-                                PRESENCE_IMS_UNSOL_PUBLISH_SIPRESPONSE,
-                                pSipResponse);
-                        StackListener.this.sendMessage(updateMesgSipPub);
-                        break;
-                    }
-
-                    case PresCmdId.UCE_PRES_CMD_GETCONTACTCAP:
-                    case PresCmdId.UCE_PRES_CMD_GETCONTACTLISTCAP:
-                    {
-                        Message updateMesgSipPub = StackListener.this.obtainMessage(
-                                PRESENCE_IMS_UNSOL_NOTIFY_UPDATE_SIPRESPONSE,
-                                pSipResponse);
-                        StackListener.this.sendMessage(updateMesgSipPub);
-
-                        break;
-                    }
-
-                    case PresCmdId.UCE_PRES_CMD_SETNEWFEATURETAG:
-                    {
-                        logger.debug("UCE_PRES_CMD_SETNEWFEATURETAG, doesn't care it");
-                        break;
-                    }
-
-                    default:
-                        logger.debug("CMD ID for unknown value=" +
-                                pSipResponse.getCmdId().getCmdId());
-                }
-            }
-        }
-
-        public void serviceUnAvailable(StatusCode statusCode) throws RemoteException {
-            synchronized(mSyncObj){
-                if(statusCode == null){
-                    logger.error("statusCode=null");
-                }else{
-                    logger.debug("IServiceUnAvailable statusCode " +
-                        statusCode.getStatusCode());
-                }
-                logger.debug("QPresListener_ServiceUnAvailable");
-
-                RcsStackAdaptor rcsStackAdaptor = RcsStackAdaptor.getInstance(null);
-                if (rcsStackAdaptor != null) {
-                    rcsStackAdaptor.setImsEnableState(false);
-                }
-
-                Intent intent = new Intent(RcsManager.ACTION_RCS_SERVICE_UNAVAILABLE);
-                mContext.sendBroadcast(intent,
-                        "com.android.ims.rcs.permission.STATUS_CHANGED");
-            }
-        }
-
-        public void serviceAvailable(StatusCode statusCode) throws RemoteException {
-            synchronized(mSyncObj){
-                if(statusCode == null){
-                    logger.error("statusCode=null");
-                }else{
-                    logger.debug("IServiceAvailable statusCode " +
-                        statusCode.getStatusCode());
-                }
-
-                logger.debug("QPresListener_ServiceAvailable");
-
-                RcsStackAdaptor rcsStackAdaptor = RcsStackAdaptor.getInstance(null);
-                if (rcsStackAdaptor != null) {
-                    rcsStackAdaptor.setImsEnableState(true);
-                }
-
-                // Handle the cached trigger which got from stack
-                if(mPresencePublication != null && mPresencePublication.getHasCachedTrigger()){
-                    logger.debug("publish for cached trigger");
-
-                    mPresencePublication.invokePublish(
-                            PresencePublication.PublishType.PRES_PUBLISH_TRIGGER_CACHED_TRIGGER);
-                }
-
-                Intent intent = new Intent(RcsManager.ACTION_RCS_SERVICE_AVAILABLE);
-                mContext.sendBroadcast(intent,
-                        "com.android.ims.rcs.permission.STATUS_CHANGED");
-            }
-        }
-
-        public void publishTriggering(PresPublishTriggerType publishTrigger)
-                throws RemoteException {
-            if(publishTrigger == null){
-                logger.error("publishTrigger=null");
-            }else{
-                logger.debug("getPublishTrigeerType() "+
-                         publishTrigger.getPublishTrigeerType());
-            }
-            logger.debug("ListenerHandler : PublishTriggering");
-
-            Message publishTrigerMsg = StackListener.this.obtainMessage(
-                    PRESENCE_IMS_UNSOL_PUBLISH_TRIGGER, publishTrigger);
-            StackListener.this.sendMessage(publishTrigerMsg);
-        }
-
-        public void listCapInfoReceived(PresRlmiInfo pRlmiInfo, PresResInfo[] pResInfo)
-                throws RemoteException {
-            if(pRlmiInfo == null || pResInfo == null){
-                logger.error("pRlmiInfo=" + pRlmiInfo + " pResInfo=" + pResInfo);
-            }else{
-                logger.debug("pRlmiInfo.getListName "+pRlmiInfo.getListName());
-                logger.debug("pRlmiInfo.isFullState "+pRlmiInfo.isFullState());
-                logger.debug("pRlmiInfo.getUri "+pRlmiInfo.getUri());
-                logger.debug("pRlmiInfo.getVersion "+pRlmiInfo.getVersion());
-                logger.debug("pRlmiInfo.getSubscriptionTerminatedReason " +
-                        pRlmiInfo.getSubscriptionTerminatedReason());
-                logger.debug("pRlmiInfo.getPresSubscriptionState " +
-                        pRlmiInfo.getPresSubscriptionState());
-                logger.debug("pRlmiInfo.getRequestID=" + pRlmiInfo.getRequestId());
-                for(int i=0; i < pResInfo.length; i++ ){
-                    if(pResInfo[i] == null){
-                        logger.debug("ignoring, pResInfo[" + i + "]=null");
-                        continue;
-                    }
-
-                    logger.debug(".getDisplayName() "+pResInfo[i].getDisplayName());
-                    logger.debug("getResUri() "+pResInfo[i].getResUri());
-                    if(pResInfo[i].getInstanceInfo() != null){
-                        logger.debug("getInstanceInfo().getPresentityUri() "+
-                                 pResInfo[i].getInstanceInfo().getPresentityUri());
-                        logger.debug("getInstanceInfo().getResId() "+
-                                 pResInfo[i].getInstanceInfo().getResId());
-                        logger.debug("getInstanceInfo().getsReason() "+
-                                 pResInfo[i].getInstanceInfo().getReason());
-                        logger.debug("getInstanceInfo().getResInstanceState() "+
-                                 pResInfo[i].getInstanceInfo().getResInstanceState());
-                        if(pResInfo[i].getInstanceInfo().getTupleInfo() == null){
-                           logger.debug("pResInfo[" + i +"].getInstanceInfo().getTupleInfo()=null");
-                            continue;
-                        }
-
-                        logger.debug("getTupleInfo().length "+
-                                 pResInfo[i].getInstanceInfo().getTupleInfo().length);
-                        if(pResInfo[i].getInstanceInfo().getTupleInfo() != null){
-                            for(int j = 0; j < pResInfo[i].getInstanceInfo().getTupleInfo().length;
-                                j++)
-                            {
-                                if(pResInfo[i].getInstanceInfo().getTupleInfo() == null){
-                                    logger.debug("ignoring, pResInfo[" + i +
-                                            "].getInstanceInfo().getTupleInfo()[" +j + "]");
-                                    continue;
-                                }
-
-                                logger.debug("getFeatureTag "+
-                                        pResInfo[i].getInstanceInfo().getTupleInfo()[j].
-                                        getFeatureTag());
-                                logger.debug("getsContactUri "+
-                                        pResInfo[i].getInstanceInfo().getTupleInfo()[j].
-                                        getContactUri());
-                                logger.debug("getsTimestamp "+
-                                        pResInfo[i].getInstanceInfo().getTupleInfo()[j].
-                                        getTimestamp());
-                            }
-                        }
-                    }
-                }
-            }
-
-            Message notifyListReceivedMsg = StackListener.this.obtainMessage(
-                    PRESENCE_IMS_UNSOL_NOTIFY_LIST_UPDATE,
-                    new NotifyListData(pRlmiInfo, pResInfo));
-            logger.debug("Send PRESENCE_IMS_UNSOL_NOTIFY_LIST_UPDATE");
-
-            StackListener.this.sendMessage(notifyListReceivedMsg);
-        }
-
-        public void capInfoReceived(String presentityURI, PresTupleInfo[] pTupleInfo)
-                throws RemoteException {
-            logger.debug("ListenerHandler : CapInfoReceived");
-            if(presentityURI == null || presentityURI == null){
-                logger.error("presentityURI=null or presentityURI=null");
-                return;
-            }
-
-            logger.debug("ListenerHandler : CapInfoReceived : presentityURI "+ presentityURI);
-
-            Message notifyReceivedMsg = StackListener.this.obtainMessage(
-                    PRESENCE_IMS_UNSOL_NOTIFY_UPDATE,
-                    new NotifyData(presentityURI, pTupleInfo));
-            StackListener.this.sendMessage(notifyReceivedMsg);
-        }
-
-        public void cmdStatus(PresCmdStatus pCmdStatus) throws RemoteException {
-            synchronized(mSyncObj){
-                if(pCmdStatus == null || pCmdStatus.getCmdId() == null){
-                     logger.debug( "ICMDStatus error, pCmdStatus="+ pCmdStatus);
-                    return;
-                 }
-
-                logger.debug("ListenerHandler : CMDStatus");
-                logger.debug("ListenerHandler : CMDStatus : pCmdStatus.getRequestID() "+
-                        pCmdStatus.getRequestId());
-                logger.debug("ListenerHandler : CMDStatus : pCmdStatus.getUserData() "+
-                        pCmdStatus.getUserData());
-                logger.debug("ListenerHandler : CMDStatus : pCmdStatus.getCmdId() "+
-                        pCmdStatus.getCmdId().getCmdId());
-                if(pCmdStatus.getStatus() != null){
-                    logger.debug("ListenerHandler : CMDStatus : pCmdStatus.getStatus() "+
-                           pCmdStatus.getStatus().getStatusCode());
-                }
-
-                switch (pCmdStatus.getCmdId().getCmdId()) {
-                case PresCmdId.UCE_PRES_CMD_PUBLISHMYCAP:
-                    Message publishCmdMsg = StackListener.this.obtainMessage(
-                            PRESENCE_IMS_UNSOL_PUBLISH_CMDSTATUS,
-                            pCmdStatus);
-                    StackListener.this.sendMessage(publishCmdMsg);
-                    break;
-
-                case PresCmdId.UCE_PRES_CMD_GETCONTACTCAP:
-                case PresCmdId.UCE_PRES_CMD_GETCONTACTLISTCAP:
-                    Message notifyUpdateCmdMsg = StackListener.this.obtainMessage(
-                            PRESENCE_IMS_UNSOL_NOTIFY_UPDATE_CMDSTATUS,
-                            pCmdStatus);
-                    StackListener.this.sendMessage(notifyUpdateCmdMsg);
-                    break;
-
-                case PresCmdId.UCE_PRES_CMD_SETNEWFEATURETAG:
-                    logger.debug("UCE_PRES_CMD_SETNEWFEATURETAG: app does not care it");
-                    break;
-
-                default:
-                    logger.debug("CMD ID for unknown value=" +
-                            pCmdStatus.getCmdId().getCmdId());
-                }
-            }
-        }
-    };
-}
-
