Allow each RenderSession have its own time

Bug: 158750833
Test: all tests should pass
Change-Id: I4aa4d57bb929660af7cf4d5a1e0f33bfd3fa3e12
diff --git a/bridge/src/android/os/SystemClock_Delegate.java b/bridge/src/android/os/SystemClock_Delegate.java
index b6a85f8..fc939ae 100644
--- a/bridge/src/android/os/SystemClock_Delegate.java
+++ b/bridge/src/android/os/SystemClock_Delegate.java
@@ -16,9 +16,9 @@
 
 package android.os;
 
+import com.android.internal.lang.System_Delegate;
 import com.android.layoutlib.bridge.impl.DelegateManager;
 import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-import com.android.tools.layoutlib.java.System_Delegate;
 
 /**
  * Delegate implementing the native methods of android.os.SystemClock
diff --git a/create/src/com/android/tools/layoutlib/java/System_Delegate.java b/bridge/src/com/android/internal/lang/System_Delegate.java
similarity index 60%
rename from create/src/com/android/tools/layoutlib/java/System_Delegate.java
rename to bridge/src/com/android/internal/lang/System_Delegate.java
index 8260312..2558989 100644
--- a/create/src/com/android/tools/layoutlib/java/System_Delegate.java
+++ b/bridge/src/com/android/internal/lang/System_Delegate.java
@@ -13,13 +13,14 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package com.android.internal.lang;
 
-package com.android.tools.layoutlib.java;
+import com.android.layoutlib.bridge.android.BridgeContext;
 
-import com.android.tools.layoutlib.create.ReplaceMethodCallsAdapter;
-
+import java.util.WeakHashMap;
 import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicLong;
+
+import static com.android.layoutlib.bridge.impl.RenderAction.getCurrentContext;
 
 /**
  * Provides alternative implementations of methods that don't exist on the host VM.
@@ -29,11 +30,6 @@
  */
 @SuppressWarnings("unused")
 public class System_Delegate {
-    // Current system time
-    private static AtomicLong mNanosTime = new AtomicLong(System.nanoTime());
-    // Time that the system booted up in nanos
-    private static AtomicLong mBootNanosTime = new AtomicLong(System.nanoTime());
-
     public static void log(String message) {
         // ignore.
     }
@@ -43,27 +39,41 @@
     }
 
     public static void setNanosTime(long nanos) {
-        mNanosTime.set(nanos);
+        BridgeContext context = getCurrentContext();
+        if (context != null) {
+            context.getSessionInteractiveData().setNanosTime(nanos);
+        }
     }
 
     public static void setBootTimeNanos(long nanos) {
-        mBootNanosTime.set(nanos);
+        BridgeContext context = getCurrentContext();
+        if (context != null) {
+            context.getSessionInteractiveData().setBootNanosTime(nanos);
+        }
     }
 
     public static long nanoTime() {
-        return mNanosTime.get();
+        BridgeContext context = getCurrentContext();
+        if (context != null) {
+            return context.getSessionInteractiveData().getNanosTime();
+        }
+        return 0;
     }
 
     public static long currentTimeMillis() {
-        return TimeUnit.NANOSECONDS.toMillis(mNanosTime.get());
+        return TimeUnit.NANOSECONDS.toMillis(nanoTime());
     }
 
     public static long bootTime() {
-        return mBootNanosTime.get();
+        BridgeContext context = getCurrentContext();
+        if (context != null) {
+            return context.getSessionInteractiveData().getBootNanosTime();
+        }
+        return 0;
     }
 
     public static long bootTimeMillis() {
-        return TimeUnit.NANOSECONDS.toMillis(mBootNanosTime.get());
+        return TimeUnit.NANOSECONDS.toMillis(bootTime());
     }
 
     // This is no-op since layoutlib infrastructure loads all the native libraries.
diff --git a/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java b/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java
index 5f035b1..168d2db 100644
--- a/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java
+++ b/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java
@@ -23,9 +23,9 @@
 import com.android.ide.common.rendering.api.ResourceValue;
 import com.android.ide.common.rendering.api.Result;
 import com.android.ide.common.rendering.api.ViewInfo;
+import com.android.internal.lang.System_Delegate;
 import com.android.internal.util.ArrayUtils_Delegate;
 import com.android.layoutlib.bridge.impl.RenderSessionImpl;
-import com.android.tools.layoutlib.java.System_Delegate;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -129,12 +129,30 @@
 
     @Override
     public void setSystemTimeNanos(long nanos) {
-        System_Delegate.setNanosTime(nanos);
+        if (mSession != null) {
+            try {
+                Bridge.prepareThread();
+                mLastResult = mSession.acquire(RenderParams.DEFAULT_TIMEOUT);
+                System_Delegate.setNanosTime(nanos);
+            } finally {
+                mSession.release();
+                Bridge.cleanupThread();
+            }
+        }
     }
 
     @Override
     public void setSystemBootTimeNanos(long nanos) {
-        System_Delegate.setBootTimeNanos(nanos);
+        if (mSession != null) {
+            try {
+                Bridge.prepareThread();
+                mLastResult = mSession.acquire(RenderParams.DEFAULT_TIMEOUT);
+                System_Delegate.setBootTimeNanos(nanos);
+            } finally {
+                mSession.release();
+                Bridge.cleanupThread();
+            }
+        }
     }
 
     @Override
diff --git a/bridge/src/com/android/layoutlib/bridge/SessionInteractiveData.java b/bridge/src/com/android/layoutlib/bridge/SessionInteractiveData.java
index bdea6d0..c3669ee 100644
--- a/bridge/src/com/android/layoutlib/bridge/SessionInteractiveData.java
+++ b/bridge/src/com/android/layoutlib/bridge/SessionInteractiveData.java
@@ -3,14 +3,36 @@
 import com.android.layoutlib.bridge.util.HandlerMessageQueue;
 import com.android.tools.layoutlib.annotations.NotNull;
 
+import java.util.concurrent.atomic.AtomicLong;
+
 public class SessionInteractiveData {
     private final HandlerMessageQueue mHandlerMessageQueue = new HandlerMessageQueue();
+    // Current system time
+    private final AtomicLong mNanosTime = new AtomicLong(System.nanoTime());
+    // Time that the system booted up in nanos
+    private final AtomicLong mBootNanosTime = new AtomicLong(System.nanoTime());
 
     @NotNull
     public HandlerMessageQueue getHandlerMessageQueue() {
         return mHandlerMessageQueue;
     }
 
+    public void setNanosTime(long nanos) {
+        mNanosTime.set(nanos);
+    }
+
+    public long getNanosTime() {
+        return mNanosTime.get();
+    }
+
+    public void setBootNanosTime(long nanos) {
+        mBootNanosTime.set(nanos);
+    }
+
+    public long getBootNanosTime() {
+        return mBootNanosTime.get();
+    }
+
     public void dispose() {
         mHandlerMessageQueue.clear();
     }
diff --git a/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTestBase.java b/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTestBase.java
index 262e8eb..6d86d94 100644
--- a/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTestBase.java
+++ b/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTestBase.java
@@ -25,6 +25,7 @@
 import com.android.ide.common.resources.deprecated.ResourceItem;
 import com.android.ide.common.resources.deprecated.ResourceRepository;
 import com.android.ide.common.resources.deprecated.TestFolderWrapper;
+import com.android.internal.lang.System_Delegate;
 import com.android.layoutlib.bridge.Bridge;
 import com.android.layoutlib.bridge.android.RenderParamsFlags;
 import com.android.layoutlib.bridge.intensive.setup.ConfigGenerator;
@@ -34,7 +35,6 @@
 import com.android.layoutlib.bridge.intensive.util.ModuleClassLoader;
 import com.android.layoutlib.bridge.intensive.util.SessionParamsBuilder;
 import com.android.layoutlib.bridge.intensive.util.TestAssetRepository;
-import com.android.tools.layoutlib.java.System_Delegate;
 import com.android.utils.ILogger;
 
 import org.junit.AfterClass;
diff --git a/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTests.java b/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTests.java
index c39f9db..5eff409 100644
--- a/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTests.java
+++ b/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTests.java
@@ -26,6 +26,7 @@
 import com.android.ide.common.rendering.api.ViewInfo;
 import com.android.ide.common.rendering.api.XmlParserFactory;
 import com.android.internal.R;
+import com.android.internal.lang.System_Delegate;
 import com.android.layoutlib.bridge.android.BridgeContext;
 import com.android.layoutlib.bridge.android.RenderParamsFlags;
 import com.android.layoutlib.bridge.impl.ParserFactory;
@@ -39,7 +40,6 @@
 import com.android.resources.Density;
 import com.android.resources.Navigation;
 import com.android.resources.ResourceType;
-import com.android.tools.layoutlib.java.System_Delegate;
 
 import org.junit.After;
 import org.junit.Assert;
diff --git a/create/src/com/android/tools/layoutlib/create/CreateInfo.java b/create/src/com/android/tools/layoutlib/create/CreateInfo.java
index 6df0372..c9de939 100644
--- a/create/src/com/android/tools/layoutlib/create/CreateInfo.java
+++ b/create/src/com/android/tools/layoutlib/create/CreateInfo.java
@@ -19,7 +19,6 @@
 import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
 import com.android.tools.layoutlib.java.LinkedHashMap_Delegate;
 import com.android.tools.layoutlib.java.NioUtils_Delegate;
-import com.android.tools.layoutlib.java.System_Delegate;
 
 import org.objectweb.asm.Opcodes;
 import org.objectweb.asm.Type;
@@ -161,7 +160,6 @@
             InjectMethodRunnable.class,
             InjectMethodRunnables.class,
             /* Java package classes */
-            System_Delegate.class,
             LinkedHashMap_Delegate.class,
             NioUtils_Delegate.class,
         };
@@ -537,7 +535,7 @@
         @Override
         public void replace(MethodInformation mi) {
             mi.name = "currentTimeMillis";
-            mi.owner = Type.getInternalName(System_Delegate.class);
+            mi.owner = "com/android/internal/lang/System_Delegate";
         }
     }
 
@@ -550,7 +548,7 @@
         @Override
         public void replace(MethodInformation mi) {
             mi.name = "nanoTime";
-            mi.owner = Type.getInternalName(System_Delegate.class);
+            mi.owner = "com/android/internal/lang/System_Delegate";
         }
     }
 
@@ -566,7 +564,7 @@
             assert mi.desc.equals("(Ljava/lang/String;Ljava/lang/Throwable;)V")
                     || mi.desc.equals("(Ljava/lang/String;)V");
             mi.name = "log";
-            mi.owner = Type.getInternalName(System_Delegate.class);
+            mi.owner = "com/android/internal/lang/System_Delegate";
         }
     }
 
@@ -582,7 +580,7 @@
 
         @Override
         public void replace(MethodInformation mi) {
-            mi.owner = Type.getInternalName(System_Delegate.class);
+            mi.owner = "com/android/internal/lang/System_Delegate";
         }
     }