Merge "Use correct format info for SMS"
diff --git a/Android.mk b/Android.mk
index 8eab88c..9309776 100644
--- a/Android.mk
+++ b/Android.mk
@@ -70,7 +70,9 @@
 
 LOCAL_SDK_VERSION := current
 
-LOCAL_COMPATIBILITY_SUITE := device-tests
+LOCAL_MODULE_PATH := $(TARGET_OUT_APPS)
+
+LOCAL_COMPATIBILITY_SUITE := general-tests
 
 include $(BUILD_PACKAGE)
 
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 58a1817..5fefe96 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -18,7 +18,7 @@
     package="com.android.messaging"
     android:installLocation="internalOnly">
 
-    <uses-sdk android:minSdkVersion="19" android:targetSdkVersion="28" />
+    <uses-sdk android:minSdkVersion="19" android:targetSdkVersion="24" />
 
     <!-- Application holds CPU wakelock while working in background -->
     <uses-permission android:name="android.permission.WAKE_LOCK" />
diff --git a/TEST_MAPPING b/TEST_MAPPING
deleted file mode 100644
index 55688d5..0000000
--- a/TEST_MAPPING
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-  "presubmit": [
-    {
-      "name": "messagingtests"
-    }
-  ]
-}
diff --git a/proguard-release.flags b/proguard-release.flags
index 36b6720..67ae150 100644
--- a/proguard-release.flags
+++ b/proguard-release.flags
@@ -12,6 +12,8 @@
 #  See the License for the specific language governing permissions and
 #  limitations under the License.
 
+-keep class com.android.messaging.ui.contact.* { *; }
+
 -assumenosideeffects public class com.android.messaging.util.Trace {
     public void beginSection(...);
     public void endSection(...);
diff --git a/proguard-test.flags b/proguard-test.flags
index 46e569f..353970a 100755
--- a/proguard-test.flags
+++ b/proguard-test.flags
@@ -35,6 +35,8 @@
   !private *;
 }
 
+-keep class com.android.messaging.ui.contact.* { *; }
+
 # Keep the classes needed by emma
 -keep class com.vladium.** { *; }
 
diff --git a/proguard.flags b/proguard.flags
index ff83f12..cb04900 100644
--- a/proguard.flags
+++ b/proguard.flags
@@ -21,9 +21,7 @@
 -keepclassmembers class * {
   @com.google.common.annotations.VisibleForTesting *;
 }
--keepclassmembers class * {
-  @com.android.messaging.ui.contact.ContactPickerFragment *;
-}
+-keep class com.android.messaging.ui.contact.* { *; }
 
 # Keep methods that have the @VisibleForAnimation annotation
 -keep @interface com.android.messaging.annotation.VisibleForAnimation
diff --git a/res/layout/apn_preference_layout.xml b/res/layout/apn_preference_layout.xml
index 25a0323..8b864f6 100644
--- a/res/layout/apn_preference_layout.xml
+++ b/res/layout/apn_preference_layout.xml
@@ -38,7 +38,7 @@
         android:background="?android:attr/selectableItemBackground">
 
         <TextView
-            android:id="@+android:id/title"
+            android:id="@+id/title"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:focusable="true"
@@ -46,7 +46,7 @@
             android:textAppearance="?android:attr/textAppearanceListItem" />
 
         <TextView
-            android:id="@+android:id/summary"
+            android:id="@+id/summary"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_below="@android:id/title"
diff --git a/src/com/android/messaging/datamodel/action/SyncMessageBatch.java b/src/com/android/messaging/datamodel/action/SyncMessageBatch.java
index 972d691..a623666 100644
--- a/src/com/android/messaging/datamodel/action/SyncMessageBatch.java
+++ b/src/com/android/messaging/datamodel/action/SyncMessageBatch.java
@@ -202,11 +202,11 @@
         // For a message we sync either
         if (isOutgoing) {
             // Outgoing message not yet been sent
-            if (type == Telephony.Sms.MESSAGE_TYPE_FAILED ||
-                    type == Telephony.Sms.MESSAGE_TYPE_OUTBOX ||
-                    type == Telephony.Sms.MESSAGE_TYPE_QUEUED ||
-                    (type == Telephony.Sms.MESSAGE_TYPE_SENT &&
-                     status == Telephony.Sms.STATUS_FAILED)) {
+            if (type == Telephony.Sms.MESSAGE_TYPE_FAILED
+                    || type == Telephony.Sms.MESSAGE_TYPE_OUTBOX
+                    || type == Telephony.Sms.MESSAGE_TYPE_QUEUED
+                    || (type == Telephony.Sms.MESSAGE_TYPE_SENT
+                            && status >= Telephony.Sms.STATUS_FAILED)) {
                 // Not sent counts as failed and available for manual resend
                 bugleStatus = MessageData.BUGLE_STATUS_OUTGOING_FAILED;
             } else if (status == Sms.STATUS_COMPLETE) {
diff --git a/src/com/android/messaging/receiver/SendStatusReceiver.java b/src/com/android/messaging/receiver/SendStatusReceiver.java
index fc0e8c9..3af65f2 100644
--- a/src/com/android/messaging/receiver/SendStatusReceiver.java
+++ b/src/com/android/messaging/receiver/SendStatusReceiver.java
@@ -20,6 +20,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.net.Uri;
+import android.provider.Telephony.Sms;
 import android.telephony.SmsMessage;
 
 import com.android.messaging.datamodel.action.ProcessDeliveryReportAction;
@@ -81,9 +82,32 @@
                 LogUtil.e(LogUtil.BUGLE_TAG, "SendStatusReceiver: empty report message");
                 return;
             }
-            int status = 0;
+            int status = Sms.STATUS_COMPLETE;
             try {
+                final String format = intent.getStringExtra("format");
                 status = smsMessage.getStatus();
+                // Simple matching up CDMA status with GSM status.
+                if (SmsMessage.FORMAT_3GPP2.equals(format)) {
+                    final int errorClass = (status >> 24) & 0x03;
+                    final int statusCode = (status >> 16) & 0x3f;
+                    switch (errorClass) {
+                        case 0: /*ERROR_NONE*/
+                            if (statusCode == 0x02 /*STATUS_DELIVERED*/) {
+                                status = Sms.STATUS_COMPLETE;
+                            } else status = Sms.STATUS_PENDING;
+                            break;
+                        case 2: /*ERROR_TEMPORARY*/
+                            // TODO: Need to check whether SC still trying to deliver the SMS to
+                            // destination and will send the report again?
+                            status = Sms.STATUS_PENDING;
+                            break;
+                        case 3: /*ERROR_PERMANENT*/
+                            status = Sms.STATUS_FAILED;
+                            break;
+                        default:
+                            status = Sms.STATUS_PENDING;
+                    }
+                }
             } catch (final NullPointerException e) {
                 // Sometimes, SmsMessage.mWrappedSmsMessage is null causing NPE when we access
                 // the methods on it although the SmsMessage itself is not null.
diff --git a/src/com/android/messaging/sms/MmsUtils.java b/src/com/android/messaging/sms/MmsUtils.java
index 74a9191..91631b3 100644
--- a/src/com/android/messaging/sms/MmsUtils.java
+++ b/src/com/android/messaging/sms/MmsUtils.java
@@ -1916,7 +1916,7 @@
             final String transactionId, final String contentLocation,
             final boolean autoDownload, final long receivedTimestampInSeconds,
             final RetrieveConf retrieveConf) {
-        final byte[] transactionIdBytes = stringToBytes(transactionId, "UTF-8");
+        final byte[] notificationTransactionId = stringToBytes(transactionId, "UTF-8");
         Uri messageUri = null;
         int status = MMS_REQUEST_MANUAL_RETRY;
         int retrieveStatus = PDU_HEADER_VALUE_UNDEFINED;
@@ -1941,10 +1941,15 @@
         if (status == MMS_REQUEST_SUCCEEDED) {
             // Send response of the notification
             if (autoDownload) {
-                sendNotifyResponseForMmsDownload(context, subId, transactionIdBytes,
-                        contentLocation, PduHeaders.STATUS_RETRIEVED);
+                sendNotifyResponseForMmsDownload(
+                        context,
+                        subId,
+                        notificationTransactionId,
+                        contentLocation,
+                        PduHeaders.STATUS_RETRIEVED);
             } else {
-                sendAcknowledgeForMmsDownload(context, subId, transactionIdBytes, contentLocation);
+                sendAcknowledgeForMmsDownload(
+                        context, subId, retrieveConf.getTransactionId(), contentLocation);
             }
 
             // Insert downloaded message into telephony
@@ -1955,8 +1960,12 @@
             // For a retry do nothing
         } else if (status == MMS_REQUEST_MANUAL_RETRY && autoDownload) {
             // Failure from autodownload - just treat like manual download
-            sendNotifyResponseForMmsDownload(context, subId, transactionIdBytes,
-                    contentLocation, PduHeaders.STATUS_DEFERRED);
+            sendNotifyResponseForMmsDownload(
+                    context,
+                    subId,
+                    notificationTransactionId,
+                    contentLocation,
+                    PduHeaders.STATUS_DEFERRED);
         }
         return new StatusPlusUri(status, retrieveStatus, messageUri);
     }
diff --git a/src/com/android/messaging/ui/appsettings/ApnPreference.java b/src/com/android/messaging/ui/appsettings/ApnPreference.java
index 74c6a08..c5cc85a 100644
--- a/src/com/android/messaging/ui/appsettings/ApnPreference.java
+++ b/src/com/android/messaging/ui/appsettings/ApnPreference.java
@@ -94,7 +94,7 @@
 
     public void setApnRadioButtonContentDescription(final CompoundButton buttonView) {
         final View widget = (View) buttonView.getParent();
-        final TextView tv = (TextView) widget.findViewById(android.R.id.title);
+        final TextView tv = (TextView) widget.findViewById(R.id.title);
         final String apnTitle = tv.getText().toString();
         buttonView.setContentDescription(apnTitle);
     }
diff --git a/src/com/android/messaging/ui/appsettings/PerSubscriptionSettingsActivity.java b/src/com/android/messaging/ui/appsettings/PerSubscriptionSettingsActivity.java
index 623bc91..7ab5dc7 100644
--- a/src/com/android/messaging/ui/appsettings/PerSubscriptionSettingsActivity.java
+++ b/src/com/android/messaging/ui/appsettings/PerSubscriptionSettingsActivity.java
@@ -134,7 +134,7 @@
             if (!MmsConfig.get(mSubId).getSMSDeliveryReportsEnabled()) {
                 final Preference deliveryReportsPref = findPreference(
                         getString(R.string.delivery_reports_pref_key));
-                mmsCategory.removePreference(deliveryReportsPref);
+                advancedCategory.removePreference(deliveryReportsPref);
             }
             final Preference wirelessAlertPref = findPreference(getString(
                     R.string.wireless_alerts_key));
diff --git a/src/com/android/messaging/util/EmailAddress.java b/src/com/android/messaging/util/EmailAddress.java
index 0c0dab9..c59170e 100644
--- a/src/com/android/messaging/util/EmailAddress.java
+++ b/src/com/android/messaging/util/EmailAddress.java
@@ -160,7 +160,7 @@
         // Host must not have any disallowed characters; allowI18n dictates whether
         // host must be ASCII.
         if (!EMAIL_ALLOWED_CHARS.matchesAllOf(host)
-                || (!allowI18n && !CharMatcher.ASCII.matchesAllOf(host))) {
+                || (!allowI18n && !CharMatcher.ascii().matchesAllOf(host))) {
             return false;
         }
 
@@ -182,7 +182,7 @@
             // User must not have any disallowed characters; allow I18n dictates whether
             // user must be ASCII.
             if (!EMAIL_ALLOWED_CHARS.matchesAllOf(user)
-                    || (!allowI18n && !CharMatcher.ASCII.matchesAllOf(user))) {
+                    || (!allowI18n && !CharMatcher.ascii().matchesAllOf(user))) {
                 return false;
             }
         }
diff --git a/tests/Android.mk b/tests/Android.mk
index dc1999b..aaff57a 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -24,9 +24,13 @@
 
 LOCAL_INSTRUMENTATION_FOR := messaging
 
+LOCAL_PROGUARD_ENABLED := disabled
+
 # Matching ../Android.mk
 LOCAL_SDK_VERSION := current
 
+LOCAL_COMPATIBILITY_SUITE := general-tests
+
 LOCAL_CERTIFICATE := platform
 
 LOCAL_STATIC_JAVA_LIBRARIES := \
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
index 3ad7d8e..07f0d17 100644
--- a/tests/AndroidManifest.xml
+++ b/tests/AndroidManifest.xml
@@ -17,7 +17,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.android.messaging.test" >
 
-    <uses-sdk android:minSdkVersion="16" android:targetSdkVersion="28"/>
+    <uses-sdk android:minSdkVersion="16" android:targetSdkVersion="24"/>
 
     <application android:label="Messaging Tests" >
         <uses-library android:name="android.test.runner" />
diff --git a/tests/AndroidTest.xml b/tests/AndroidTest.xml
new file mode 100644
index 0000000..601bc8e
--- /dev/null
+++ b/tests/AndroidTest.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 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.
+-->
+<configuration description="Runs Messaging Tests.">
+    <option name="test-suite-tag" value="apct" />
+    <option name="test-suite-tag" value="apct-instrumentation" />
+    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="messagingtests.apk" />
+        <option name="test-file-name" value="messaging.apk" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.InstrumentationTest" >
+        <option name="package" value="com.android.messaging.test" />
+        <option name="runner" value="android.test.InstrumentationTestRunner" />
+    </test>
+</configuration>
+
diff --git a/tests/src/com/android/messaging/datamodel/action/GetOrCreateConversationActionTest.java b/tests/src/com/android/messaging/datamodel/action/GetOrCreateConversationActionTest.java
index 1c0d0b5..f98d090 100644
--- a/tests/src/com/android/messaging/datamodel/action/GetOrCreateConversationActionTest.java
+++ b/tests/src/com/android/messaging/datamodel/action/GetOrCreateConversationActionTest.java
@@ -67,12 +67,6 @@
         final long threadId = MmsUtils.getOrCreateThreadId(mContext, recipients);
         assertEquals(TestDataFactory.SMS_MMS_THREAD_ID_CURSOR_VALUE, threadId);
 
-        // TestDataFactory creates NUM_TEST_CONVERSATIONS conversations. blank
-        // conversation would be the next conversation.
-        final String blankId = BugleDatabaseOperations.getExistingConversation(db, threadId, false);
-        // TODO(rtenneti): Investigate why blankId is 4 more than NUM_TEST_CONVERSATIONS.
-        assertEquals(TestDataFactory.NUM_TEST_CONVERSATIONS+4, Integer.parseInt((String)blankId));
-
         ArrayList<StubActionServiceCallLog> calls = mService.getCalls();
 
         GetOrCreateConversationActionMonitor monitor =
@@ -91,8 +85,7 @@
         assertTrue(result instanceof String);
 
         // Make sure that we created a new conversation
-        // TODO(rtenneti): Investigate why blankId is 4 more than NUM_TEST_CONVERSATIONS.
-        assertEquals(TestDataFactory.NUM_TEST_CONVERSATIONS+4, Integer.parseInt((String)result));
+        assertEquals(TestDataFactory.NUM_TEST_CONVERSATIONS, Integer.parseInt((String)result));
 
         // Now get the conversation that we just created again
         monitor = GetOrCreateConversationAction.getOrCreateConversation(participants, null,
@@ -110,8 +103,7 @@
         final String conversationId = (String) result;
 
         // Make sure that we found the same conversation id
-        // TODO(rtenneti): Investigate why blankId is 4 more than NUM_TEST_CONVERSATIONS.
-        assertEquals(TestDataFactory.NUM_TEST_CONVERSATIONS+4, Integer.parseInt((String)result));
+        assertEquals(TestDataFactory.NUM_TEST_CONVERSATIONS, Integer.parseInt((String)result));
 
         final ArrayList<ParticipantData> conversationParticipants =
                 BugleDatabaseOperations.getParticipantsForConversation(db, conversationId);