Merge "Remove UNIQUE constraint in Eab common table" into sc-dev
diff --git a/src/java/com/android/ims/rcs/uce/presence/pidfparser/PidfParser.java b/src/java/com/android/ims/rcs/uce/presence/pidfparser/PidfParser.java
index 2660f1d..dc2dc04 100644
--- a/src/java/com/android/ims/rcs/uce/presence/pidfparser/PidfParser.java
+++ b/src/java/com/android/ims/rcs/uce/presence/pidfparser/PidfParser.java
@@ -36,14 +36,13 @@
 import com.android.ims.rcs.uce.presence.pidfparser.pidf.Presence;
 import com.android.ims.rcs.uce.presence.pidfparser.pidf.Tuple;
 import com.android.ims.rcs.uce.util.UceUtils;
+import com.android.internal.annotations.VisibleForTesting;
 
 import java.io.IOException;
 import java.io.Reader;
 import java.io.StringReader;
 import java.io.StringWriter;
 import java.time.Instant;
-import java.time.format.DateTimeFormatter;
-import java.time.format.DateTimeParseException;
 import java.util.List;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -63,6 +62,29 @@
     private static final Pattern PIDF_PATTERN = Pattern.compile("\t|\r|\n");
 
     /**
+     * Testing interface used to get the timestamp.
+     */
+    @VisibleForTesting
+    public interface TimestampProxy {
+        Instant getTimestamp();
+    }
+
+    // The timestamp proxy to create the local timestamp.
+    private static final TimestampProxy sLocalTimestampProxy = () -> Instant.now();
+
+    // Override timestamp proxy for testing only.
+    private static TimestampProxy sOverrideTimestampProxy;
+
+    @VisibleForTesting
+    public static void setTimestampProxy(TimestampProxy proxy) {
+        sOverrideTimestampProxy = proxy;
+    }
+
+    private static TimestampProxy getTimestampProxy() {
+        return (sOverrideTimestampProxy != null) ? sOverrideTimestampProxy : sLocalTimestampProxy;
+    }
+
+    /**
      * Convert the RcsContactUceCapability to the string of pidf.
      */
     public static String convertToPidf(RcsContactUceCapability capabilities) {
@@ -214,17 +236,8 @@
             builder.setContactUri(Uri.parse(contact));
         }
 
-        // Timestamp
-        String timestamp = PidfParserUtils.getTupleTimestamp(tuple);
-        if (!TextUtils.isEmpty(timestamp)) {
-            try {
-                Instant instant = DateTimeFormatter.ISO_OFFSET_DATE_TIME.parse(
-                        timestamp, Instant::from);
-                builder.setTime(instant);
-            } catch (DateTimeParseException e) {
-                Log.w(LOG_TAG, "getRcsContactPresenceTuple: Parse timestamp failed " + e);
-            }
-        }
+        // Use local time instead to prevent we receive the incorrect timestamp from the network.
+        builder.setTime(getTimestampProxy().getTimestamp());
 
         // Set service description
         if (!TextUtils.isEmpty(serviceDescription)) {
diff --git a/tests/src/com/android/ims/rcs/uce/presence/pidfparser/PidfParserTest.java b/tests/src/com/android/ims/rcs/uce/presence/pidfparser/PidfParserTest.java
index f8038be..be92ce3 100644
--- a/tests/src/com/android/ims/rcs/uce/presence/pidfparser/PidfParserTest.java
+++ b/tests/src/com/android/ims/rcs/uce/presence/pidfparser/PidfParserTest.java
@@ -47,14 +47,19 @@
 @RunWith(AndroidJUnit4.class)
 public class PidfParserTest extends ImsTestBase {
 
+    // The timestamp of the PIDF
+    private final Instant mPidfTimestamp = Instant.now().plusMillis(1);
+
     @Before
     public void setUp() throws Exception {
         super.setUp();
+        PidfParser.setTimestampProxy(() -> mPidfTimestamp);
     }
 
     @After
     public void tearDown() throws Exception {
         super.tearDown();
+        PidfParser.setTimestampProxy(null);
     }
 
     @Test
@@ -104,7 +109,7 @@
         assertEquals("1.0", presenceTuple1.getServiceVersion());
         assertEquals(serviceDescription, presenceTuple1.getServiceDescription());
         assertEquals(Uri.parse(contact), presenceTuple1.getContactUri());
-        assertEquals("2001-01-01T01:00:00Z", presenceTuple1.getTime().toString());
+        assertEquals(mPidfTimestamp.toString(), presenceTuple1.getTime().toString());
         assertTrue(presenceTuple1.getServiceCapabilities().isAudioCapable());
         assertFalse(presenceTuple1.getServiceCapabilities().isVideoCapable());
     }
@@ -184,7 +189,7 @@
             assertEquals(expectedTuple.getStatus(), tuple.getStatus());
             assertEquals(expectedTuple.getServiceVersion(), tuple.getServiceVersion());
             assertEquals(expectedTuple.getServiceDescription(), tuple.getServiceDescription());
-            assertEquals(expectedTuple.getTime(), tuple.getTime());
+            assertEquals(mPidfTimestamp, tuple.getTime());
             assertEquals(expectedTuple.getContactUri(), tuple.getContactUri());
 
             ServiceCapabilities expectedCap = expectedTuple.getServiceCapabilities();
@@ -243,7 +248,7 @@
         assertEquals("1.0", presenceTuple1.getServiceVersion());
         assertEquals(serviceDescription1, presenceTuple1.getServiceDescription());
         assertEquals(Uri.parse(contact), presenceTuple1.getContactUri());
-        assertEquals("2001-01-01T01:00:00Z", presenceTuple1.getTime().toString());
+        assertEquals(mPidfTimestamp.toString(), presenceTuple1.getTime().toString());
         assertNull(presenceTuple1.getServiceCapabilities());
 
         // Verify the second tuple information
@@ -254,7 +259,7 @@
         assertFalse(presenceTuple2.getServiceCapabilities().isVideoCapable());
         assertEquals(serviceDescription2, presenceTuple2.getServiceDescription());
         assertEquals(Uri.parse(contact), presenceTuple2.getContactUri());
-        assertEquals("2001-02-02T01:00:00Z", presenceTuple2.getTime().toString());
+        assertEquals(mPidfTimestamp.toString(), presenceTuple2.getTime().toString());
         assertNotNull(presenceTuple2.getServiceCapabilities());
         assertEquals(isAudioSupported, presenceTuple2.getServiceCapabilities().isAudioCapable());
         assertEquals(isVideoSupported, presenceTuple2.getServiceCapabilities().isVideoCapable());
@@ -341,7 +346,7 @@
                 .append("<caps:video>").append(isVideoSupported).append("</caps:video>")
                 .append("</caps:servcaps>")
                 .append("<contact>").append(contact).append("</contact>")
-                .append("<timestamp>2001-01-01T01:00:00.00Z</timestamp>")
+                .append("<timestamp>").append(mPidfTimestamp.toString()).append("</timestamp>")
                 .append("</tuple></presence>");
         return pidfBuilder.toString();
     }
@@ -444,7 +449,7 @@
                 + "<op:description>" + serviceDescription1 + "</op:description>"
                 + "</op:service-description>"
                 + "<contact>" + contact + "</contact>"
-                + "<timestamp>2001-01-01T01:00:00.00Z</timestamp>"
+                + "<timestamp>" + mPidfTimestamp.toString() + "</timestamp>"
                 + "</tuple>"
                 // tuple 2
                 + "<tuple id=\"a1\">"
@@ -462,7 +467,7 @@
                 + "<caps:video>" + videoSupported + "</caps:video>"
                 + "</caps:servcaps>"
                 + "<contact>" + contact + "</contact>"
-                + "<timestamp>2001-02-02T01:00:00.00Z</timestamp>"
+                + "<timestamp>" + mPidfTimestamp.toString() + "</timestamp>"
                 + "</tuple>"
                 + "</presence>";
     }
@@ -475,7 +480,6 @@
         final String basicStatus = RcsContactPresenceTuple.TUPLE_BASIC_STATUS_OPEN;
         final String version = "1.0";
         final String description = "description test";
-        final Instant nowTime = Instant.now();
 
         // init the capabilities
         ServiceCapabilities.Builder servCapsBuilder =
@@ -487,7 +491,7 @@
                 basicStatus, RcsContactPresenceTuple.SERVICE_ID_MMTEL, version);
         tupleBuilder.setContactUri(contact)
                 .setServiceDescription(description)
-                .setTime(nowTime)
+                .setTime(mPidfTimestamp)
                 .setServiceCapabilities(servCapsBuilder.build());
 
         PresenceBuilder presenceBuilder = new PresenceBuilder(contact,