diff --git a/packages/ScriptExecutor/Android.bp b/packages/ScriptExecutor/Android.bp
index 952a9b8..7ada5bf 100644
--- a/packages/ScriptExecutor/Android.bp
+++ b/packages/ScriptExecutor/Android.bp
@@ -88,6 +88,6 @@
         "src/**/*.java",
     ],
 
-    sdk_version: "current",
+    sdk_version: "test_current",
 }
 
diff --git a/packages/ScriptExecutor/src/com/android/car/scriptexecutor/ScriptExecutor.java b/packages/ScriptExecutor/src/com/android/car/scriptexecutor/ScriptExecutor.java
index abd4145..362005e 100644
--- a/packages/ScriptExecutor/src/com/android/car/scriptexecutor/ScriptExecutor.java
+++ b/packages/ScriptExecutor/src/com/android/car/scriptexecutor/ScriptExecutor.java
@@ -18,12 +18,15 @@
 
 import android.app.Service;
 import android.content.Intent;
+import android.os.Binder;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.IBinder;
 import android.os.ParcelFileDescriptor;
 import android.os.PersistableBundle;
+import android.os.Process;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.util.Log;
 
 import com.android.car.telemetry.scriptexecutorinterface.IScriptExecutor;
@@ -37,7 +40,6 @@
  * and input arguments.
  */
 public final class ScriptExecutor extends Service {
-
     static {
         System.loadLibrary("scriptexecutorjni");
     }
@@ -53,7 +55,8 @@
         @Override
         public void invokeScript(String scriptBody, String functionName,
                 PersistableBundle publishedData, PersistableBundle savedState,
-                IScriptExecutorListener listener) {
+                IScriptExecutorListener listener) throws SecurityException {
+            ensureCallerIsSystem();
             mNativeHandler.post(() ->
                     nativeInvokeScript(mLuaEnginePtr, scriptBody, functionName, publishedData,
                             savedState, listener));
@@ -62,7 +65,8 @@
         @Override
         public void invokeScriptForLargeInput(String scriptBody, String functionName,
                 ParcelFileDescriptor publishedDataFileDescriptor, PersistableBundle savedState,
-                IScriptExecutorListener listener) {
+                IScriptExecutorListener listener) throws SecurityException {
+            ensureCallerIsSystem();
             mNativeHandler.post(() -> {
                 PersistableBundle publishedData;
                 try (InputStream input = new ParcelFileDescriptor.AutoCloseInputStream(
@@ -117,6 +121,12 @@
         return mScriptExecutorBinder;
     }
 
+    private void ensureCallerIsSystem() throws SecurityException {
+        if (UserHandle.getAppId(Binder.getCallingUid()) != Process.SYSTEM_UID) {
+            throw new SecurityException("ScriptExecutor called from non-system user");
+        }
+    }
+
     /**
      * Initializes Lua Engine.
      *
diff --git a/packages/ScriptExecutor/tests/unit/README.md b/packages/ScriptExecutor/tests/README.md
similarity index 69%
rename from packages/ScriptExecutor/tests/unit/README.md
rename to packages/ScriptExecutor/tests/README.md
index 8c5a67a..fb2e52d 100644
--- a/packages/ScriptExecutor/tests/unit/README.md
+++ b/packages/ScriptExecutor/tests/README.md
@@ -14,7 +14,18 @@
   limitations under the License
   -->
 
-# How to run unit tests for ScriptExecutor
+# Test categories
+
+**1. Functional Tests
+
+ScriptExecutor functional tests that are run as system user - which is required by
+ScriptExecutor to invoke script processing.
+
+**2. Non-system-user Tests
+
+These are tests that does not need to be run as system user or tests running as non-system user.
+
+# How to run tests for ScriptExecutor
 
 **1. Navigate to the root of the repo and do full build:**
 
@@ -26,7 +37,7 @@
 
 **3. Run the tests. For example**
 
-`atest ScriptExecutorUnitTest:ScriptExecutorTest`
+`atest ScriptExecutorFunctionalTests:ScriptExecutorFunctionalTest`
 
 
 ## How to rerun the tests after changes
@@ -34,7 +45,7 @@
 device flash.
 
 **1. Navigate to ScriptExecutor unit test location and build its targets:**
-`cd packages/services/Car/packages/ScriptExecutor/tests/unit`
+`cd packages/services/Car/packages/ScriptExecutor/tests/functional`
 
 `mm -j`
 
@@ -48,5 +59,5 @@
 
 **3. At this point we are ready to run the tests again. For example:**
 
-`atest ScriptExecutorUnitTest:ScriptExecutorTest`
+`atest ScriptExecutorFunctionalTests:ScriptExecutorFunctionalTest`
 
diff --git a/packages/ScriptExecutor/tests/functional/Android.bp b/packages/ScriptExecutor/tests/functional/Android.bp
new file mode 100644
index 0000000..1e0ef38
--- /dev/null
+++ b/packages/ScriptExecutor/tests/functional/Android.bp
@@ -0,0 +1,41 @@
+// Copyright (C) 2021 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.
+//
+//
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+android_test {
+    name: "ScriptExecutorFunctionalTests",
+
+    srcs: ["src/**/*.java"],
+
+    platform_apis: true,
+
+    certificate: "platform",
+
+    instrumentation_for: "ScriptExecutor",
+
+    static_libs: [
+        "androidx.test.core",
+        "androidx.test.runner",
+        "junit",
+        "scriptexecutor-test-lib",
+        "truth-prebuilt",
+    ],
+
+    test_suites: ["general-tests"],
+}
diff --git a/packages/ScriptExecutor/tests/functional/AndroidManifest.xml b/packages/ScriptExecutor/tests/functional/AndroidManifest.xml
new file mode 100644
index 0000000..79e85d6
--- /dev/null
+++ b/packages/ScriptExecutor/tests/functional/AndroidManifest.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 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.
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="com.android.car.scriptexecutortest.functional"
+          android:sharedUserId="android.uid.system">
+
+    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
+
+    <queries>
+        <package android:name="com.android.car.scriptexecutor" />
+    </queries>
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="com.android.car.scriptexecutortest.functional"
+                     android:label="Tests for ScriptExecutor"/>
+</manifest>
diff --git a/packages/ScriptExecutor/tests/functional/src/com/android/car/scriptexecutortest/functional/ScriptExecutorFunctionalTest.java b/packages/ScriptExecutor/tests/functional/src/com/android/car/scriptexecutortest/functional/ScriptExecutorFunctionalTest.java
new file mode 100644
index 0000000..e9c8557
--- /dev/null
+++ b/packages/ScriptExecutor/tests/functional/src/com/android/car/scriptexecutortest/functional/ScriptExecutorFunctionalTest.java
@@ -0,0 +1,915 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package com.android.car.scriptexecutortest.functional;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.IBinder;
+import android.os.ParcelFileDescriptor;
+import android.os.PersistableBundle;
+import android.os.RemoteException;
+import android.os.UserHandle;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.car.scriptexecutor.ScriptExecutor;
+import com.android.car.telemetry.scriptexecutorinterface.IScriptExecutor;
+import com.android.car.telemetry.scriptexecutorinterface.IScriptExecutorListener;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.io.OutputStream;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+@RunWith(JUnit4.class)
+public final class ScriptExecutorFunctionalTest {
+
+    private IScriptExecutor mScriptExecutor;
+    private ScriptExecutor mInstance;
+    private Context mContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
+
+    private static final class ScriptExecutorListener extends IScriptExecutorListener.Stub {
+        private PersistableBundle mInterimResult;
+        private PersistableBundle mFinalResult;
+        private int mErrorType;
+        private String mMessage;
+        private String mStackTrace;
+        private final CountDownLatch mResponseLatch = new CountDownLatch(1);
+
+        @Override
+        public void onScriptFinished(PersistableBundle result) {
+            mFinalResult = result;
+            mResponseLatch.countDown();
+        }
+
+        @Override
+        public void onSuccess(PersistableBundle interimResult) {
+            mInterimResult = interimResult;
+            mResponseLatch.countDown();
+        }
+
+        @Override
+        public void onError(int errorType, String message, String stackTrace) {
+            mErrorType = errorType;
+            mMessage = message;
+            mStackTrace = stackTrace;
+            mResponseLatch.countDown();
+        }
+
+        private boolean awaitResponse(int waitTimeSec) throws InterruptedException {
+            return mResponseLatch.await(waitTimeSec, TimeUnit.SECONDS);
+        }
+    }
+
+    private final ScriptExecutorListener mListener = new ScriptExecutorListener();
+    private final PersistableBundle mEmptyPublishedData = new PersistableBundle();
+    private final PersistableBundle mEmptyIterimResult = new PersistableBundle();
+    private final CountDownLatch mBindLatch = new CountDownLatch(1);
+
+    private static final int BIND_SERVICE_TIMEOUT_SEC = 5;
+    private static final int SCRIPT_PROCESSING_TIMEOUT_SEC = 10;
+
+    private final ServiceConnection mScriptExecutorConnection =
+            new ServiceConnection() {
+                @Override
+                public void onServiceConnected(ComponentName className, IBinder service) {
+                    mScriptExecutor = IScriptExecutor.Stub.asInterface(service);
+                    mBindLatch.countDown();
+                }
+
+                @Override
+                public void onServiceDisconnected(ComponentName className) {
+                    assertWithMessage("Service unexpectedly disconnected").fail();
+                }
+            };
+
+    @Before
+    public void setUp() throws InterruptedException {
+        Intent intent = new Intent();
+        intent.setComponent(
+                new ComponentName(
+                        "com.android.car.scriptexecutor",
+                        "com.android.car.scriptexecutor.ScriptExecutor"));
+        mContext.bindServiceAsUser(
+                intent, mScriptExecutorConnection, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM);
+        if (!mBindLatch.await(BIND_SERVICE_TIMEOUT_SEC, TimeUnit.SECONDS)) {
+            assertWithMessage("Failed to bind to ScriptExecutor service").fail();
+        }
+    }
+
+    @Test
+    public void invokeScript_returnsResult() throws RemoteException, InterruptedException {
+        String returnResultScript =
+                "function hello(data, state)\n"
+                        + "    result = {hello=\"world\"}\n"
+                        + "    on_success(result)\n"
+                        + "end\n";
+
+        runScriptAndWaitForResponse(
+                returnResultScript, "hello", mEmptyPublishedData, mEmptyIterimResult);
+
+        // Expect to get back a bundle with a single string key: string value pair:
+        // {"hello": "world"}
+        assertThat(mListener.mInterimResult.size()).isEqualTo(1);
+        assertThat(mListener.mInterimResult.getString("hello")).isEqualTo("world");
+    }
+
+    @Test
+    public void invokeScript_allSupportedPrimitiveTypes()
+            throws RemoteException, InterruptedException {
+        String script =
+                "function knows(data, state)\n"
+                        + "    result = {string=\"hello\", boolean=true, integer=1, number=1.1}\n"
+                        + "    on_success(result)\n"
+                        + "end\n";
+
+        runScriptAndWaitForResponse(script, "knows", mEmptyPublishedData, mEmptyIterimResult);
+
+        // Expect to get back a bundle with 4 keys, each corresponding to a distinct supported type.
+        assertThat(mListener.mInterimResult.size()).isEqualTo(4);
+        assertThat(mListener.mInterimResult.getString("string")).isEqualTo("hello");
+        assertThat(mListener.mInterimResult.getBoolean("boolean")).isEqualTo(true);
+        assertThat(mListener.mInterimResult.getLong("integer")).isEqualTo(1);
+        assertThat(mListener.mInterimResult.getDouble("number")).isEqualTo(1.1);
+    }
+
+    @Test
+    public void invokeScript_skipsUnsupportedNestedTables()
+            throws RemoteException, InterruptedException {
+        String script =
+                "function nested(data, state)\n"
+                        + "    result = {string=\"hello\", boolean=true, integer=1, number=1.1}\n"
+                        + "    result.nested_table = {x=0, y=0}\n"
+                        + "    on_success(result)\n"
+                        + "end\n";
+
+        runScriptAndWaitForResponse(script, "nested", mEmptyPublishedData, mEmptyIterimResult);
+
+        // Verify that expected error is received.
+        assertThat(mListener.mErrorType)
+                .isEqualTo(IScriptExecutorListener.ERROR_TYPE_LUA_SCRIPT_ERROR);
+        assertThat(mListener.mMessage).contains("nested tables are not supported");
+    }
+
+    @Test
+    public void invokeScript_emptyBundle() throws RemoteException, InterruptedException {
+        String script =
+                "function empty(data, state)\n"
+                        + "    result = {}\n"
+                        + "    on_success(result)\n"
+                        + "end\n";
+
+        runScriptAndWaitForResponse(script, "empty", mEmptyPublishedData, mEmptyIterimResult);
+
+        // If a script returns empty table as the result, we get an empty bundle.
+        assertThat(mListener.mInterimResult).isNotNull();
+        assertThat(mListener.mInterimResult.size()).isEqualTo(0);
+    }
+
+    @Test
+    public void invokeScript_processPreviousStateAndReturnResult()
+            throws RemoteException, InterruptedException {
+        // Here we verify that the script actually processes provided state from a previous run
+        // and makes calculation based on that and returns the result.
+        String script =
+                "function update(data, state)\n"
+                        + "    result = {y = state.x+1}\n"
+                        + "    on_success(result)\n"
+                        + "end\n";
+        PersistableBundle previousState = new PersistableBundle();
+        previousState.putInt("x", 1);
+
+        runScriptAndWaitForResponse(script, "update", mEmptyPublishedData, previousState);
+
+        // Verify that y = 2, because y = x + 1 and x = 1.
+        assertThat(mListener.mInterimResult.size()).isEqualTo(1);
+        assertThat(mListener.mInterimResult.getLong("y")).isEqualTo(2);
+    }
+
+    @Test
+    public void invokeScript_allSupportedPrimitiveTypesWorkRoundTripWithKeyNamesPreserved()
+            throws RemoteException, InterruptedException {
+        // Here we verify that all supported primitive types in supplied previous state Bundle
+        // are interpreted by the script as expected.
+        String script =
+                "function update_all(data, state)\n"
+                        + "    result = {}\n"
+                        + "    result.integer = state.integer + 1\n"
+                        + "    result.number = state.number + 0.1\n"
+                        + "    result.boolean = not state.boolean\n"
+                        + "    result.string = state.string .. \"CADABRA\"\n"
+                        + "    on_success(result)\n"
+                        + "end\n";
+        PersistableBundle previousState = new PersistableBundle();
+        previousState.putInt("integer", 1);
+        previousState.putDouble("number", 0.1);
+        previousState.putBoolean("boolean", false);
+        previousState.putString("string", "ABRA");
+
+        runScriptAndWaitForResponse(script, "update_all", mEmptyPublishedData, previousState);
+
+        // Verify that keys are preserved but the values are modified as expected.
+        assertThat(mListener.mInterimResult.size()).isEqualTo(4);
+        assertThat(mListener.mInterimResult.getLong("integer")).isEqualTo(2);
+        assertThat(mListener.mInterimResult.getDouble("number")).isEqualTo(0.2);
+        assertThat(mListener.mInterimResult.getBoolean("boolean")).isEqualTo(true);
+        assertThat(mListener.mInterimResult.getString("string")).isEqualTo("ABRACADABRA");
+    }
+
+    @Test
+    public void invokeScript_allSupportedArrayTypesWorkRoundTripWithKeyNamesPreserved()
+            throws RemoteException, InterruptedException {
+        // Here we verify that all supported array types in supplied previous state Bundle are
+        // interpreted by the script as expected.
+        String script =
+                "function arrays(data, state)\n"
+                        + "    result = {}\n"
+                        + "    result.int_array = state.int_array\n"
+                        + "    result.long_array = state.long_array\n"
+                        + "    result.string_array = state.string_array\n"
+                        + "    on_success(result)\n"
+                        + "end\n";
+        PersistableBundle previousState = new PersistableBundle();
+        int[] int_array = new int[] {1, 2};
+        long[] int_array_in_long = new long[] {1, 2};
+        long[] long_array = new long[] {1, 2, 3};
+        String[] string_array = new String[] {"one", "two", "three"};
+        previousState.putIntArray("int_array", int_array);
+        previousState.putLongArray("long_array", long_array);
+        previousState.putStringArray("string_array", string_array);
+
+        runScriptAndWaitForResponse(script, "arrays", mEmptyPublishedData, previousState);
+
+        // Verify that keys are preserved but the values are modified as expected.
+        assertThat(mListener.mInterimResult.size()).isEqualTo(3);
+        // Lua has only one lua_Integer. Here Java long is used to represent it when data is
+        // transferred from Lua to CarTelemetryService.
+        assertThat(mListener.mInterimResult.getLongArray("int_array")).isEqualTo(int_array_in_long);
+        assertThat(mListener.mInterimResult.getLongArray("long_array")).isEqualTo(long_array);
+        assertThat(mListener.mInterimResult.getStringArray("string_array")).isEqualTo(string_array);
+    }
+
+    @Test
+    public void invokeScript_modifiesArray() throws RemoteException, InterruptedException {
+        // Verify that an array modified by a script is properly sent back by the callback.
+        String script =
+                "function modify_array(data, state)\n"
+                        + "    result = {}\n"
+                        + "    result.long_array = state.long_array\n"
+                        + "    result.long_array[2] = 100\n"
+                        + "    on_success(result)\n"
+                        + "end\n";
+        PersistableBundle previousState = new PersistableBundle();
+        long[] long_array = new long[] {1, 2, 3};
+        previousState.putLongArray("long_array", long_array);
+        long[] expected_array = new long[] {1, 100, 3};
+
+        runScriptAndWaitForResponse(script, "modify_array", mEmptyPublishedData, previousState);
+
+        // Verify that keys are preserved but the values are modified as expected.
+        assertThat(mListener.mInterimResult.size()).isEqualTo(1);
+        assertThat(mListener.mInterimResult.getLongArray("long_array")).isEqualTo(expected_array);
+    }
+
+    @Test
+    public void invokeScript_processesStringArray() throws RemoteException, InterruptedException {
+        // Verify that an array modified by a script is properly sent back by the callback.
+        String script =
+                "function process_string_array(data, state)\n"
+                        + "    result = {}\n"
+                        + "    result.answer = state.string_array[1] .. state.string_array[2]\n"
+                        + "    on_success(result)\n"
+                        + "end\n";
+        PersistableBundle previousState = new PersistableBundle();
+        String[] string_array = new String[] {"Hello ", "world!"};
+        previousState.putStringArray("string_array", string_array);
+
+        runScriptAndWaitForResponse(
+                script, "process_string_array", mEmptyPublishedData, previousState);
+
+        // Verify that keys are preserved but the values are modified as expected.
+        assertThat(mListener.mInterimResult.size()).isEqualTo(1);
+        assertThat(mListener.mInterimResult.getString("answer")).isEqualTo("Hello world!");
+    }
+
+    @Test
+    public void invokeScript_arraysWithLengthAboveLimitCauseError()
+            throws RemoteException, InterruptedException {
+        // Verifies that arrays pushed by Lua that have their size over the limit cause error.
+        String script =
+                "function size_limit(data, state)\n"
+                        + "    result = {}\n"
+                        + "    result.huge_array = {}\n"
+                        + "    for i=1, 10000 do\n"
+                        + "        result.huge_array[i]=i\n"
+                        + "    end\n"
+                        + "    on_success(result)\n"
+                        + "end\n";
+
+        runScriptAndWaitForResponse(
+                script, "size_limit", mEmptyPublishedData, mEmptyIterimResult);
+
+        // Verify that expected error is received.
+        assertThat(mListener.mErrorType)
+                .isEqualTo(IScriptExecutorListener.ERROR_TYPE_LUA_SCRIPT_ERROR);
+        assertThat(mListener.mMessage)
+                .isEqualTo(
+                        "Returned table huge_array exceeds maximum allowed size of 1000 elements."
+                                + " This key-value cannot be unpacked successfully. This error is"
+                                + " unrecoverable.");
+    }
+
+    @Test
+    public void invokeScript_arrayContainingVaryingTypesCausesError()
+            throws RemoteException, InterruptedException {
+        // Verifies that values in returned array must be the same integer type.
+        // For example string values in a Lua array are not allowed.
+        String script =
+                "function table_with_numbers_and_strings(data, state)\n"
+                        + "    result = {}\n"
+                        + "    result.mixed_array = state.long_array\n"
+                        + "    result.mixed_array[2] = 'a'\n"
+                        + "    on_success(result)\n"
+                        + "end\n";
+        PersistableBundle previousState = new PersistableBundle();
+        long[] long_array = new long[] {1, 2, 3};
+        previousState.putLongArray("long_array", long_array);
+
+        runScriptAndWaitForResponse(
+                script, "table_with_numbers_and_strings", mEmptyPublishedData, previousState);
+
+        // Verify that expected error is received.
+        assertThat(mListener.mErrorType)
+                .isEqualTo(IScriptExecutorListener.ERROR_TYPE_LUA_SCRIPT_ERROR);
+        assertThat(mListener.mMessage)
+                .contains("Returned Lua arrays must have elements of the same type.");
+    }
+
+    @Test
+    public void invokeScript_InTablesWithBothKeysAndIndicesCopiesOnlyIndexedData()
+            throws RemoteException, InterruptedException {
+        // Documents the current behavior that copies only indexed values in a Lua table that
+        // contains both keyed and indexed data.
+        String script =
+                "function keys_and_indices(data, state)\n"
+                        + "    result = {}\n"
+                        + "    result.mixed_array = state.long_array\n"
+                        + "    result.mixed_array['a'] = 130\n"
+                        + "    on_success(result)\n"
+                        + "end\n";
+        PersistableBundle previousState = new PersistableBundle();
+        long[] long_array = new long[] {1, 2, 3};
+        previousState.putLongArray("long_array", long_array);
+
+        runScriptAndWaitForResponse(
+                script, "keys_and_indices", mEmptyPublishedData, previousState);
+
+        // Verify that keys are preserved but the values are modified as expected.
+        assertThat(mListener.mInterimResult.size()).isEqualTo(1);
+        assertThat(mListener.mInterimResult.getLongArray("mixed_array")).isEqualTo(long_array);
+    }
+
+    @Test
+    public void invokeScript_noLuaBufferOverflowForLargeInputArrays()
+            throws RemoteException, InterruptedException {
+        // Tests that arrays with length that exceed internal Lua buffer size of 20 elements
+        // do not cause buffer overflow and are handled properly.
+        String script =
+                "function large_input_array(data, state)\n"
+                        + "    sum = 0\n"
+                        + "    for _, val in ipairs(state.long_array) do\n"
+                        + "        sum = sum + val\n"
+                        + "    end\n"
+                        + "    result = {total = sum}\n"
+                        + "    on_success(result)\n"
+                        + "end\n";
+
+        PersistableBundle previousState = new PersistableBundle();
+        int n = 10000;
+        long[] longArray = new long[n];
+        for (int i = 0; i < n; i++) {
+            longArray[i] = i;
+        }
+        previousState.putLongArray("long_array", longArray);
+        long expected_sum =
+                (longArray[0] + longArray[n - 1]) * n / 2; // sum of an arithmetic sequence.
+
+        runScriptAndWaitForResponse(
+                script, "large_input_array", mEmptyPublishedData, previousState);
+
+        // Verify that keys are preserved but the values are modified as expected.
+        assertThat(mListener.mInterimResult.size()).isEqualTo(1);
+        assertThat(mListener.mInterimResult.getLong("total")).isEqualTo(expected_sum);
+    }
+
+    @Test
+    public void invokeScript_scriptCallsOnError() throws RemoteException, InterruptedException {
+        String script =
+                "function calls_on_error()\n"
+                        + "    if 1 ~= 2 then\n"
+                        + "        on_error(\"one is not equal to two\")\n"
+                        + "        return\n"
+                        + "    end\n"
+                        + "end\n";
+
+        runScriptAndWaitForError(script, "calls_on_error");
+
+        assertThat(mListener.mErrorType)
+                .isEqualTo(IScriptExecutorListener.ERROR_TYPE_LUA_SCRIPT_ERROR);
+        assertThat(mListener.mMessage).isEqualTo("one is not equal to two");
+    }
+
+    @Test
+    public void invokeScript_tooManyParametersInOnError()
+            throws RemoteException, InterruptedException {
+        String script =
+                "function too_many_params_in_on_error()\n"
+                        + "    if 1 ~= 2 then\n"
+                        + "        on_error(\"param1\", \"param2\")\n"
+                        + "        return\n"
+                        + "    end\n"
+                        + "end\n";
+
+        runScriptAndWaitForError(script, "too_many_params_in_on_error");
+
+        assertThat(mListener.mErrorType)
+                .isEqualTo(IScriptExecutorListener.ERROR_TYPE_LUA_SCRIPT_ERROR);
+        assertThat(mListener.mMessage)
+                .isEqualTo("on_error can push only a single string parameter from Lua");
+    }
+
+    @Test
+    public void invokeScript_onErrorOnlyAcceptsString()
+            throws RemoteException, InterruptedException {
+        String script =
+                "function only_string()\n"
+                        + "    if 1 ~= 2 then\n"
+                        + "        on_error(false)\n"
+                        + "        return\n"
+                        + "    end\n"
+                        + "end\n";
+
+        runScriptAndWaitForError(script, "only_string");
+
+        assertThat(mListener.mErrorType)
+                .isEqualTo(IScriptExecutorListener.ERROR_TYPE_LUA_SCRIPT_ERROR);
+        assertThat(mListener.mMessage)
+                .isEqualTo("on_error can push only a single string parameter from Lua");
+    }
+
+    @Test
+    public void invokeScript_returnsFinalResult() throws RemoteException, InterruptedException {
+        String returnFinalResultScript =
+                "function script_finishes(data, state)\n"
+                        + "    result = {data = state.input + 1}\n"
+                        + "    on_script_finished(result)\n"
+                        + "end\n";
+        PersistableBundle previousState = new PersistableBundle();
+        previousState.putInt("input", 1);
+
+        runScriptAndWaitForResponse(
+                returnFinalResultScript, "script_finishes", mEmptyPublishedData, previousState);
+
+        // Expect to get back a bundle with a single key-value pair {"data": 2}
+        // because data = state.input + 1 as in the script body above.
+        assertThat(mListener.mFinalResult.size()).isEqualTo(1);
+        assertThat(mListener.mFinalResult.getLong("data")).isEqualTo(2);
+    }
+
+    @Test
+    public void invokeScript_emptyStringValueIsValidValue()
+            throws RemoteException, InterruptedException {
+        // Verify that an empty string value is a valid value to be returned from a script.
+        String returnFinalResultScript =
+                "function empty_string(data, state)\n"
+                        + "    result = {data = \"\"}\n"
+                        + "    on_script_finished(result)\n"
+                        + "end\n";
+
+        runScriptAndWaitForResponse(
+                returnFinalResultScript,
+                "empty_string",
+                mEmptyPublishedData,
+                new PersistableBundle());
+
+        // Expect to get back a bundle with a single key-value pair {"data": ""}
+        assertThat(mListener.mFinalResult.size()).isEqualTo(1);
+        assertThat(mListener.mFinalResult.getString("data")).isEqualTo("");
+    }
+
+    @Test
+    public void invokeScript_allPrimitiveSupportedTypesForReturningFinalResult()
+            throws RemoteException, InterruptedException {
+        // Here we verify that all supported primitive types are present in the returned final
+        // result bundle are present.
+        String script =
+                "function finalize_all(data, state)\n"
+                        + "    result = {}\n"
+                        + "    result.integer = state.integer + 1\n"
+                        + "    result.number = state.number + 0.1\n"
+                        + "    result.boolean = not state.boolean\n"
+                        + "    result.string = state.string .. \"CADABRA\"\n"
+                        + "    on_script_finished(result)\n"
+                        + "end\n";
+        PersistableBundle previousState = new PersistableBundle();
+        previousState.putInt("integer", 1);
+        previousState.putDouble("number", 0.1);
+        previousState.putBoolean("boolean", false);
+        previousState.putString("string", "ABRA");
+
+        runScriptAndWaitForResponse(script, "finalize_all", mEmptyPublishedData, previousState);
+
+        // Verify that keys are preserved but the values are modified as expected.
+        assertThat(mListener.mFinalResult.size()).isEqualTo(4);
+        assertThat(mListener.mFinalResult.getLong("integer")).isEqualTo(2);
+        assertThat(mListener.mFinalResult.getDouble("number")).isEqualTo(0.2);
+        assertThat(mListener.mFinalResult.getBoolean("boolean")).isEqualTo(true);
+        assertThat(mListener.mFinalResult.getString("string")).isEqualTo("ABRACADABRA");
+    }
+
+    @Test
+    public void invokeScript_emptyFinalResultBundle() throws RemoteException, InterruptedException {
+        String script =
+                "function empty_final_result(data, state)\n"
+                        + "    result = {}\n"
+                        + "    on_script_finished(result)\n"
+                        + "end\n";
+
+        runScriptAndWaitForResponse(
+                script, "empty_final_result", mEmptyPublishedData, mEmptyIterimResult);
+
+        // If a script returns empty table as the final result, we get an empty bundle.
+        assertThat(mListener.mFinalResult).isNotNull();
+        assertThat(mListener.mFinalResult.size()).isEqualTo(0);
+    }
+
+    @Test
+    public void invokeScript_wrongNumberOfCallbackInputsInOnScriptFinished()
+            throws RemoteException, InterruptedException {
+        String script =
+                "function wrong_number_of_outputs_in_on_script_finished(data, state)\n"
+                        + "    result = {}\n"
+                        + "    extra = 1\n"
+                        + "    on_script_finished(result, extra)\n"
+                        + "end\n";
+
+        runScriptAndWaitForResponse(
+                script,
+                "wrong_number_of_outputs_in_on_script_finished",
+                mEmptyPublishedData,
+                mEmptyIterimResult);
+
+        // We expect to get an error here because we expect only 1 input parameter in
+        // on_script_finished.
+        assertThat(mListener.mErrorType)
+                .isEqualTo(IScriptExecutorListener.ERROR_TYPE_LUA_SCRIPT_ERROR);
+        assertThat(mListener.mMessage)
+                .isEqualTo(
+                        "on_script_finished can push only a single parameter from Lua - a Lua"
+                                + " table");
+    }
+
+    @Test
+    public void invokeScript_wrongNumberOfCallbackInputsInOnSuccess()
+            throws RemoteException, InterruptedException {
+        String script =
+                "function wrong_number_of_outputs_in_on_success(data, state)\n"
+                        + "    result = {}\n"
+                        + "    extra = 1\n"
+                        + "    on_success(result, extra)\n"
+                        + "end\n";
+
+        runScriptAndWaitForResponse(
+                script,
+                "wrong_number_of_outputs_in_on_success",
+                mEmptyPublishedData,
+                mEmptyIterimResult);
+
+        // We expect to get an error here because we expect only 1 input parameter in on_success.
+        assertThat(mListener.mErrorType)
+                .isEqualTo(IScriptExecutorListener.ERROR_TYPE_LUA_SCRIPT_ERROR);
+        assertThat(mListener.mMessage)
+                .isEqualTo("on_success can push only a single parameter from Lua - a Lua table");
+    }
+
+    @Test
+    public void invokeScript_wrongTypeInOnSuccess() throws RemoteException, InterruptedException {
+        String script =
+                "function wrong_type_in_on_success(data, state)\n"
+                        + "    result = 1\n"
+                        + "    on_success(result)\n"
+                        + "end\n";
+
+        runScriptAndWaitForResponse(
+                script, "wrong_type_in_on_success", mEmptyPublishedData, mEmptyIterimResult);
+
+        // We expect to get an error here because the type of the input parameter for on_success
+        // must be a Lua table.
+        assertThat(mListener.mErrorType)
+                .isEqualTo(IScriptExecutorListener.ERROR_TYPE_LUA_SCRIPT_ERROR);
+        assertThat(mListener.mMessage)
+                .isEqualTo("on_success can push only a single parameter from Lua - a Lua table");
+    }
+
+    @Test
+    public void invokeScript_wrongTypeInOnScriptFinished()
+            throws RemoteException, InterruptedException {
+        String script =
+                "function wrong_type_in_on_script_finished(data, state)\n"
+                        + "    result = 1\n"
+                        + "    on_success(result)\n"
+                        + "end\n";
+
+        runScriptAndWaitForResponse(
+                script,
+                "wrong_type_in_on_script_finished",
+                mEmptyPublishedData,
+                mEmptyIterimResult);
+
+        // We expect to get an error here because the type of the input parameter for
+        // on_script_finished must be a Lua table.
+        assertThat(mListener.mErrorType)
+                .isEqualTo(IScriptExecutorListener.ERROR_TYPE_LUA_SCRIPT_ERROR);
+        assertThat(mListener.mMessage)
+                .isEqualTo("on_success can push only a single parameter from Lua - a Lua table");
+    }
+
+    @Test
+    public void invokeScriptLargeInput_largePublishedData() throws Exception {
+        // Verifies that large input does not overwhelm Binder's buffer because pipes are used
+        // instead.
+        String script =
+                "function large_published_data(data, state)\n"
+                        + "    sum = 0\n"
+                        + "    for _, val in ipairs(data.array) do\n"
+                        + "        sum = sum + val\n"
+                        + "    end\n"
+                        + "    result = {total = sum}\n"
+                        + "    on_script_finished(result)\n"
+                        + "end\n";
+
+        ParcelFileDescriptor[] fds = ParcelFileDescriptor.createPipe();
+        ParcelFileDescriptor writeFd = fds[1];
+        ParcelFileDescriptor readFd = fds[0];
+
+        PersistableBundle bundle = new PersistableBundle();
+        int n = 1 << 20; // 1024 * 1024 values, roughly 1 Million.
+        long[] array8Mb = new long[n];
+        for (int i = 0; i < n; i++) {
+            array8Mb[i] = i;
+        }
+        bundle.putLongArray("array", array8Mb);
+        long expectedSum =
+                (array8Mb[0] + array8Mb[n - 1]) * n / 2; // sum of an arithmetic sequence.
+
+        mScriptExecutor.invokeScriptForLargeInput(
+                script, "large_published_data", readFd, mEmptyIterimResult, mListener);
+
+        readFd.close();
+        try (OutputStream outputStream = new ParcelFileDescriptor.AutoCloseOutputStream(writeFd)) {
+            bundle.writeToStream(outputStream);
+        }
+
+        boolean gotResponse = mListener.awaitResponse(SCRIPT_PROCESSING_TIMEOUT_SEC);
+
+        assertWithMessage("Failed to get the callback method called by the script on time")
+                .that(gotResponse)
+                .isTrue();
+        assertThat(mListener.mFinalResult.size()).isEqualTo(1);
+        assertThat(mListener.mFinalResult.getLong("total")).isEqualTo(expectedSum);
+    }
+
+    @Test
+    public void invokeScript_bothPublishedDataAndPreviousStateAreProvided()
+            throws RemoteException, InterruptedException {
+        // Verifies that both published data and previous state PersistableBundles
+        // are piped into script.
+        String script =
+                "function data_and_state(data, state)\n"
+                        + "    result = {answer = data.a .. data.b .. state.c .. state.d}\n"
+                        + "    on_script_finished(result)\n"
+                        + "end\n";
+
+        PersistableBundle publishedData = new PersistableBundle();
+        publishedData.putString("a", "A");
+        publishedData.putString("b", "B");
+
+        PersistableBundle previousState = new PersistableBundle();
+        previousState.putString("c", "C");
+        previousState.putString("d", "D");
+
+        runScriptAndWaitForResponse(script, "data_and_state", publishedData, previousState);
+
+        // Lua script combines both input published data and previous state into a single result.
+        assertThat(mListener.mFinalResult).isNotNull();
+        assertThat(mListener.mFinalResult.size()).isEqualTo(1);
+        assertThat(mListener.mFinalResult.getString("answer")).isEqualTo("ABCD");
+    }
+
+    @Test
+    public void invokeScript_outputIntAndLongAreTreatedAsLong()
+            throws RemoteException, InterruptedException {
+        // Verifies that we treat output both integer and long as long integer type although we
+        // distinguish between int and long in the script input.
+        String script =
+                "function int_and_long_are_output_long(data, state)\n"
+                        + "    result = {int = data.int, long = state.long}\n"
+                        + "    on_script_finished(result)\n"
+                        + "end\n";
+
+        PersistableBundle publishedData = new PersistableBundle();
+        publishedData.putInt("int", 100);
+
+        PersistableBundle previousState = new PersistableBundle();
+        previousState.putLong("long", 200);
+
+        runScriptAndWaitForResponse(
+                script, "int_and_long_are_output_long", publishedData, previousState);
+
+        // If a script returns empty table as the final result, we get an empty bundle.
+        assertThat(mListener.mFinalResult).isNotNull();
+        assertThat(mListener.mFinalResult.size()).isEqualTo(2);
+        // getInt should always return "empty" value (zero) because all integer types are treated
+        // as Java long.
+        assertThat(mListener.mFinalResult.getInt("int")).isEqualTo(0);
+        assertThat(mListener.mFinalResult.getInt("long")).isEqualTo(0);
+        // Instead all expected integer values are successfully retrieved using getLong method
+        // from the output bundle.
+        assertThat(mListener.mFinalResult.getLong("int")).isEqualTo(100);
+        assertThat(mListener.mFinalResult.getLong("long")).isEqualTo(200);
+    }
+
+    @Test
+    public void invokeScript_nonUTFCharactersDoNotCauseErrors()
+            throws RemoteException, InterruptedException {
+        // Tries to create an output string value that does not conform to Modified UTF-8.
+        // JNI gracefully handles it by parsing on the string as is.
+        String script =
+                "function non_utf_key_string(data, state)\n"
+                        + "    result = {answer = \"i\0np\200\200ut\"}\n"
+                        + "    on_script_finished(result)\n"
+                        + "end\n";
+
+        runScriptAndWaitForResponse(
+                script, "non_utf_key_string", new PersistableBundle(), new PersistableBundle());
+
+        // The output will still have all characters, including those that do not conform to
+        // Modified UTF-8.
+        assertThat(mListener.mFinalResult).isNotNull();
+        assertThat(mListener.mFinalResult.size()).isEqualTo(1);
+        assertThat(mListener.mFinalResult.getString("answer")).isEqualTo("i\0np\200\200ut");
+    }
+
+    @Test
+    public void invokeScript_wrongFunctionNameProvided()
+            throws RemoteException, InterruptedException {
+        // Verifies that not specifying function name correctly is handled through error callback.
+        String script = "function correct_function(data, state)\n" + "end\n";
+
+        runScriptAndWaitForError(script, "wrong_function");
+
+        // Verify that the expected error is received.
+        assertThat(mListener.mErrorType)
+                .isEqualTo(IScriptExecutorListener.ERROR_TYPE_LUA_RUNTIME_ERROR);
+        assertThat(mListener.mMessage).contains("Wrong function name");
+    }
+
+    @Test
+    public void invokeScript_runtimeErrorDueToSyntax()
+            throws RemoteException, InterruptedException {
+        // Verifies that syntax errors during script loading are handled gracefully.
+        String script = "function wrong_syntax(data, state)\n" + "    x == 1\n" + "end\n";
+
+        runScriptAndWaitForError(script, "wrong_syntax");
+
+        // Verify that the expected error is received.
+        assertThat(mListener.mErrorType)
+                .isEqualTo(IScriptExecutorListener.ERROR_TYPE_LUA_RUNTIME_ERROR);
+        assertThat(mListener.mMessage).contains("Error encountered while loading the script");
+    }
+
+    @Test
+    public void invokeScript_runtimeErrorDueToUndefinedMethod()
+            throws RemoteException, InterruptedException {
+        // Verifies that runtime errors encountered during Lua script execution trigger an error
+        // returned via a callback.
+        String script =
+                "function runtime_error(data, state)\n" + "    on_problem(data, state)\n" + "end\n";
+
+        runScriptAndWaitForError(script, "runtime_error");
+
+        // Verify that the expected error is received.
+        assertThat(mListener.mErrorType)
+                .isEqualTo(IScriptExecutorListener.ERROR_TYPE_LUA_RUNTIME_ERROR);
+        assertThat(mListener.mMessage).contains("Error encountered while running the script");
+    }
+
+    @Test
+    public void invokeScript_returnedValuesOfUnsupportedTypesReturnError()
+            throws RemoteException, InterruptedException {
+        // Verifies that if we try to return a value of unsupported type, we get an error instead.
+        // In this case, the unsupported type is LUA_TFUNCTION type.
+        String script =
+                "function function_type(data, state)\n"
+                        + "    result = {fn = function_type}\n"
+                        + "    on_success(result)\n"
+                        + "end\n";
+
+        runScriptAndWaitForResponse(
+                script, "function_type", mEmptyPublishedData, mEmptyIterimResult);
+
+        // Verify that the expected error is received.
+        assertThat(mListener.mErrorType)
+                .isEqualTo(IScriptExecutorListener.ERROR_TYPE_LUA_SCRIPT_ERROR);
+        assertThat(mListener.mMessage)
+                .contains("has a Lua type=function, which is not supported yet");
+    }
+
+    @Test
+    public void invokeScript_returnedFloatingArraysNotSupported()
+            throws RemoteException, InterruptedException {
+        // Verifies that we do not support return values that contain floating number arrays.
+        String script =
+                "function floating_point_arrays(data, state)\n"
+                        + "    array = {}\n"
+                        + "    array[0] = 1.1\n"
+                        + "    array[1] = 1.2\n"
+                        + "    result = {data = array}\n"
+                        + "    on_success(result)\n"
+                        + "end\n";
+
+        runScriptAndWaitForResponse(
+                script, "floating_point_arrays", mEmptyPublishedData, mEmptyIterimResult);
+
+        // Verify that the expected error is received.
+        assertThat(mListener.mErrorType)
+                .isEqualTo(IScriptExecutorListener.ERROR_TYPE_LUA_SCRIPT_ERROR);
+        assertThat(mListener.mMessage)
+                .contains("a floating number array, which is not supported yet");
+    }
+
+    @Test
+    public void invokeScript_returnedBooleanArraysNotSupported()
+            throws RemoteException, InterruptedException {
+        // Verifies that we do not yet support return values that contain boolean arrays.
+        String script =
+                "function array_of_booleans(data, state)\n"
+                        + "    array = {}\n"
+                        + "    array[0] = false\n"
+                        + "    array[1] = true\n"
+                        + "    result = {data = array}\n"
+                        + "    on_success(result)\n"
+                        + "end\n";
+
+        runScriptAndWaitForResponse(
+                script, "array_of_booleans", mEmptyPublishedData, mEmptyIterimResult);
+
+        // Verify that the expected error is received.
+        assertThat(mListener.mErrorType)
+                .isEqualTo(IScriptExecutorListener.ERROR_TYPE_LUA_SCRIPT_ERROR);
+        assertThat(mListener.mMessage)
+                .contains("is an array with values of type=boolean, which is not supported yet");
+    }
+
+    // Helper method to invoke the script and wait for it to complete and return a response.
+    private void runScriptAndWaitForResponse(
+            String script,
+            String function,
+            PersistableBundle publishedData,
+            PersistableBundle previousState)
+            throws RemoteException, InterruptedException {
+        mScriptExecutor.invokeScript(script, function, publishedData, previousState, mListener);
+        assertWithMessage("Failed to get the callback method called by the script on time")
+                .that(mListener.awaitResponse(SCRIPT_PROCESSING_TIMEOUT_SEC))
+                .isTrue();
+    }
+
+    private void runScriptAndWaitForError(String script, String function)
+            throws RemoteException, InterruptedException {
+        runScriptAndWaitForResponse(
+                script, function, new PersistableBundle(), new PersistableBundle());
+    }
+}
diff --git a/packages/ScriptExecutor/tests/nonsystemuser/Android.bp b/packages/ScriptExecutor/tests/nonsystemuser/Android.bp
new file mode 100644
index 0000000..cc95fe3
--- /dev/null
+++ b/packages/ScriptExecutor/tests/nonsystemuser/Android.bp
@@ -0,0 +1,41 @@
+// Copyright (C) 2021 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.
+//
+//
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+android_test {
+    name: "ScriptExecutorNonSystemUserTests",
+
+    srcs: ["src/**/*.java"],
+
+    platform_apis: true,
+
+    certificate: "platform",
+
+    instrumentation_for: "ScriptExecutor",
+
+    static_libs: [
+        "androidx.test.core",
+        "androidx.test.runner",
+        "junit",
+        "scriptexecutor-test-lib",
+        "truth-prebuilt",
+    ],
+
+    test_suites: ["general-tests"],
+}
diff --git a/packages/ScriptExecutor/tests/nonsystemuser/AndroidManifest.xml b/packages/ScriptExecutor/tests/nonsystemuser/AndroidManifest.xml
new file mode 100644
index 0000000..9e20a43
--- /dev/null
+++ b/packages/ScriptExecutor/tests/nonsystemuser/AndroidManifest.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 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.
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="com.android.car.scriptexecutortest.nonsystemuser">
+
+    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
+
+    <queries>
+        <package android:name="com.android.car.scriptexecutor" />
+    </queries>
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="com.android.car.scriptexecutortest.nonsystemuser"
+                     android:label="Tests for ScriptExecutor"/>
+</manifest>
diff --git a/packages/ScriptExecutor/tests/nonsystemuser/src/com/android/car/scriptexecutortest/nonsystemuser/ScriptExecutorNonSystemUserTest.java b/packages/ScriptExecutor/tests/nonsystemuser/src/com/android/car/scriptexecutortest/nonsystemuser/ScriptExecutorNonSystemUserTest.java
new file mode 100644
index 0000000..6949e3e
--- /dev/null
+++ b/packages/ScriptExecutor/tests/nonsystemuser/src/com/android/car/scriptexecutortest/nonsystemuser/ScriptExecutorNonSystemUserTest.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package com.android.car.scriptexecutortest.nonsystemuser;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.IBinder;
+import android.os.ParcelFileDescriptor;
+import android.os.PersistableBundle;
+import android.os.UserHandle;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.car.scriptexecutor.ScriptExecutor;
+import com.android.car.telemetry.scriptexecutorinterface.IScriptExecutor;
+import com.android.car.telemetry.scriptexecutorinterface.IScriptExecutorListener;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+@RunWith(JUnit4.class)
+public final class ScriptExecutorNonSystemUserTest {
+
+    private IScriptExecutor mScriptExecutor;
+    private ScriptExecutor mInstance;
+    private Context mContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
+
+    private static final class ScriptExecutorListener extends IScriptExecutorListener.Stub {
+        public PersistableBundle mInterimResult;
+        public PersistableBundle mFinalResult;
+        public int mErrorType;
+        public String mMessage;
+        public String mStackTrace;
+        public final CountDownLatch mResponseLatch = new CountDownLatch(1);
+
+        @Override
+        public void onScriptFinished(PersistableBundle result) {
+            mFinalResult = result;
+            mResponseLatch.countDown();
+        }
+
+        @Override
+        public void onSuccess(PersistableBundle stateToPersist) {
+            mInterimResult = stateToPersist;
+            mResponseLatch.countDown();
+        }
+
+        @Override
+        public void onError(int errorType, String message, String stackTrace) {
+            mErrorType = errorType;
+            mMessage = message;
+            mStackTrace = stackTrace;
+            mResponseLatch.countDown();
+        }
+
+        private boolean awaitResponse(int waitTimeSec) throws InterruptedException {
+            return mResponseLatch.await(waitTimeSec, TimeUnit.SECONDS);
+        }
+    }
+
+    private final ScriptExecutorListener mListener = new ScriptExecutorListener();
+
+    private final PersistableBundle mPublishedData = new PersistableBundle();
+    private final PersistableBundle mSavedState = new PersistableBundle();
+
+    private final CountDownLatch mBindLatch = new CountDownLatch(1);
+
+    private static final int BIND_SERVICE_TIMEOUT_SEC = 5;
+    private static final int SCRIPT_PROCESSING_TIMEOUT_SEC = 10;
+
+    private final ServiceConnection mScriptExecutorConnection =
+            new ServiceConnection() {
+                @Override
+                public void onServiceConnected(ComponentName className, IBinder service) {
+                    mScriptExecutor = IScriptExecutor.Stub.asInterface(service);
+                    mBindLatch.countDown();
+                }
+
+                @Override
+                public void onServiceDisconnected(ComponentName className) {
+                    assertWithMessage("Service unexpectedly disconnected").fail();
+                }
+            };
+
+    @Before
+    public void setUp() throws InterruptedException {
+        Intent intent = new Intent();
+        intent.setComponent(
+                new ComponentName(
+                        "com.android.car.scriptexecutor",
+                        "com.android.car.scriptexecutor.ScriptExecutor"));
+        mContext.bindServiceAsUser(
+                intent, mScriptExecutorConnection, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM);
+        if (!mBindLatch.await(BIND_SERVICE_TIMEOUT_SEC, TimeUnit.SECONDS)) {
+            assertWithMessage("Failed to bind to ScriptExecutor service").fail();
+        }
+    }
+
+    @Test
+    public void invokeScript_FromNonSystemUser_isNotProcessed() throws Exception {
+        String script =
+                "function hello(data, state)\n"
+                        + "    result = {hello=\"world\"}\n"
+                        + "    on_success(result)\n"
+                        + "end\n";
+
+        mScriptExecutor.invokeScript(script, "hello", mPublishedData, mSavedState, mListener);
+
+        assertThat(mListener.awaitResponse(SCRIPT_PROCESSING_TIMEOUT_SEC)).isFalse();
+    }
+
+    @Test
+    public void invokeScriptForLargeInput_FromNonSystemUser_isNotProcessed() throws Exception {
+        String script =
+                "function hello(data, state)\n"
+                        + "    result = {hello=\"world\"}\n"
+                        + "    on_success(result)\n"
+                        + "end\n";
+
+        ParcelFileDescriptor[] fds = ParcelFileDescriptor.createPipe();
+        ParcelFileDescriptor writeFd = fds[1];
+        ParcelFileDescriptor readFd = fds[0];
+
+        mScriptExecutor.invokeScriptForLargeInput(
+                script, "large_published_data", readFd, mSavedState, mListener);
+
+        readFd.close();
+        writeFd.close();
+
+        assertThat(mListener.awaitResponse(SCRIPT_PROCESSING_TIMEOUT_SEC)).isFalse();
+    }
+}
diff --git a/packages/ScriptExecutor/tests/unit/Android.bp b/packages/ScriptExecutor/tests/unit/Android.bp
index 80ba55f..5f6213c 100644
--- a/packages/ScriptExecutor/tests/unit/Android.bp
+++ b/packages/ScriptExecutor/tests/unit/Android.bp
@@ -19,7 +19,7 @@
 }
 
 android_test {
-    name: "ScriptExecutorUnitTest",
+    name: "ScriptExecutorUnitTests",
 
     srcs: ["src/**/*.java"],
 
@@ -53,7 +53,7 @@
     ],
 
     srcs: [
-        "src/com/android/car/scriptexecutor/JniUtilsTestHelper.cpp",
+        "src/com/android/car/scriptexecutortest/unit/JniUtilsTestHelper.cpp",
     ],
 
     stl: "libc++_static",
diff --git a/packages/ScriptExecutor/tests/unit/AndroidManifest.xml b/packages/ScriptExecutor/tests/unit/AndroidManifest.xml
index f393408..9809a8a 100644
--- a/packages/ScriptExecutor/tests/unit/AndroidManifest.xml
+++ b/packages/ScriptExecutor/tests/unit/AndroidManifest.xml
@@ -16,7 +16,7 @@
   -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.car.scriptexecutor_test">
+          package="com.android.car.scriptexecutortest.unit">
 
     <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
 
@@ -29,6 +29,6 @@
     </application>
 
     <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.car.scriptexecutor_test"
+                     android:targetPackage="com.android.car.scriptexecutortest.unit"
                      android:label="Tests for ScriptExecutor"/>
 </manifest>
diff --git a/packages/ScriptExecutor/tests/unit/src/com/android/car/scriptexecutor/ScriptExecutorTest.java b/packages/ScriptExecutor/tests/unit/src/com/android/car/scriptexecutor/ScriptExecutorTest.java
deleted file mode 100644
index 1a4028a..0000000
--- a/packages/ScriptExecutor/tests/unit/src/com/android/car/scriptexecutor/ScriptExecutorTest.java
+++ /dev/null
@@ -1,907 +0,0 @@
-/*
- * Copyright (C) 2021 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.
- */
-
-package com.android.car.scriptexecutor;
-
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import static org.junit.Assert.fail;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.os.IBinder;
-import android.os.ParcelFileDescriptor;
-import android.os.PersistableBundle;
-import android.os.RemoteException;
-import android.os.UserHandle;
-
-import androidx.test.platform.app.InstrumentationRegistry;
-
-import com.android.car.telemetry.scriptexecutorinterface.IScriptExecutor;
-import com.android.car.telemetry.scriptexecutorinterface.IScriptExecutorListener;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-import java.io.OutputStream;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-@RunWith(JUnit4.class)
-public final class ScriptExecutorTest {
-
-    private IScriptExecutor mScriptExecutor;
-    private ScriptExecutor mInstance;
-    private Context mContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
-
-
-    private static final class ScriptExecutorListener extends IScriptExecutorListener.Stub {
-        public PersistableBundle mSavedBundle;
-        public PersistableBundle mFinalResult;
-        public int mErrorType;
-        public String mMessage;
-        public String mStackTrace;
-        public final CountDownLatch mResponseLatch = new CountDownLatch(1);
-
-        @Override
-        public void onScriptFinished(PersistableBundle result) {
-            mFinalResult = result;
-            mResponseLatch.countDown();
-        }
-
-        @Override
-        public void onSuccess(PersistableBundle stateToPersist) {
-            mSavedBundle = stateToPersist;
-            mResponseLatch.countDown();
-        }
-
-        @Override
-        public void onError(int errorType, String message, String stackTrace) {
-            mErrorType = errorType;
-            mMessage = message;
-            mStackTrace = stackTrace;
-            mResponseLatch.countDown();
-        }
-    }
-
-    private final ScriptExecutorListener mFakeScriptExecutorListener =
-            new ScriptExecutorListener();
-
-    private final PersistableBundle mPublishedData = new PersistableBundle();
-    private final PersistableBundle mSavedState = new PersistableBundle();
-
-    private final CountDownLatch mBindLatch = new CountDownLatch(1);
-
-    private static final int BIND_SERVICE_TIMEOUT_SEC = 5;
-    private static final int SCRIPT_PROCESSING_TIMEOUT_SEC = 10;
-
-
-    private final ServiceConnection mScriptExecutorConnection =
-            new ServiceConnection() {
-                @Override
-                public void onServiceConnected(ComponentName className, IBinder service) {
-                    mScriptExecutor = IScriptExecutor.Stub.asInterface(service);
-                    mBindLatch.countDown();
-                }
-
-                @Override
-                public void onServiceDisconnected(ComponentName className) {
-                    fail("Service unexpectedly disconnected");
-                }
-            };
-
-    // Helper method to invoke the script and wait for it to complete and return a response.
-    private void runScriptAndWaitForResponse(String script, String function,
-            PersistableBundle publishedData, PersistableBundle previousState)
-            throws RemoteException {
-        mScriptExecutor.invokeScript(script, function, publishedData, previousState,
-                mFakeScriptExecutorListener);
-        try {
-            if (!mFakeScriptExecutorListener.mResponseLatch.await(SCRIPT_PROCESSING_TIMEOUT_SEC,
-                    TimeUnit.SECONDS)) {
-                fail("Failed to get the callback method called by the script on time");
-            }
-        } catch (InterruptedException e) {
-            e.printStackTrace();
-            fail(e.getMessage());
-        }
-    }
-
-    private void runScriptAndWaitForError(String script, String function) throws RemoteException {
-        runScriptAndWaitForResponse(script, function, new PersistableBundle(),
-                new PersistableBundle());
-    }
-
-    @Before
-    public void setUp() throws InterruptedException {
-        Intent intent = new Intent();
-        intent.setComponent(new ComponentName("com.android.car.scriptexecutor",
-                "com.android.car.scriptexecutor.ScriptExecutor"));
-        mContext.bindServiceAsUser(intent, mScriptExecutorConnection, Context.BIND_AUTO_CREATE,
-                UserHandle.SYSTEM);
-        if (!mBindLatch.await(BIND_SERVICE_TIMEOUT_SEC, TimeUnit.SECONDS)) {
-            fail("Failed to bind to ScriptExecutor service");
-        }
-    }
-
-    @Test
-    public void invokeScript_returnsResult() throws RemoteException {
-        String returnResultScript =
-                "function hello(data, state)\n"
-                        + "    result = {hello=\"world\"}\n"
-                        + "    on_success(result)\n"
-                        + "end\n";
-
-        runScriptAndWaitForResponse(returnResultScript, "hello", mPublishedData, mSavedState);
-
-        // Expect to get back a bundle with a single string key: string value pair:
-        // {"hello": "world"}
-        assertThat(mFakeScriptExecutorListener.mSavedBundle.size()).isEqualTo(1);
-        assertThat(mFakeScriptExecutorListener.mSavedBundle.getString("hello")).isEqualTo(
-                "world");
-    }
-
-    @Test
-    public void invokeScript_allSupportedPrimitiveTypes() throws RemoteException {
-        String script =
-                "function knows(data, state)\n"
-                        + "    result = {string=\"hello\", boolean=true, integer=1, number=1.1}\n"
-                        + "    on_success(result)\n"
-                        + "end\n";
-
-        runScriptAndWaitForResponse(script, "knows", mPublishedData, mSavedState);
-
-        // Expect to get back a bundle with 4 keys, each corresponding to a distinct supported type.
-        assertThat(mFakeScriptExecutorListener.mSavedBundle.size()).isEqualTo(4);
-        assertThat(mFakeScriptExecutorListener.mSavedBundle.getString("string")).isEqualTo(
-                "hello");
-        assertThat(mFakeScriptExecutorListener.mSavedBundle.getBoolean("boolean")).isEqualTo(true);
-        assertThat(mFakeScriptExecutorListener.mSavedBundle.getLong("integer")).isEqualTo(1);
-        assertThat(mFakeScriptExecutorListener.mSavedBundle.getDouble("number")).isEqualTo(1.1);
-    }
-
-    @Test
-    public void invokeScript_skipsUnsupportedNestedTables() throws RemoteException {
-        String script =
-                "function nested(data, state)\n"
-                        + "    result = {string=\"hello\", boolean=true, integer=1, number=1.1}\n"
-                        + "    result.nested_table = {x=0, y=0}\n"
-                        + "    on_success(result)\n"
-                        + "end\n";
-
-        runScriptAndWaitForResponse(script, "nested", mPublishedData, mSavedState);
-
-        // Verify that expected error is received.
-        assertThat(mFakeScriptExecutorListener.mErrorType).isEqualTo(
-                IScriptExecutorListener.ERROR_TYPE_LUA_SCRIPT_ERROR);
-        assertThat(mFakeScriptExecutorListener.mMessage).contains(
-                "nested tables are not supported");
-    }
-
-    @Test
-    public void invokeScript_emptyBundle() throws RemoteException {
-        String script =
-                "function empty(data, state)\n"
-                        + "    result = {}\n"
-                        + "    on_success(result)\n"
-                        + "end\n";
-
-        runScriptAndWaitForResponse(script, "empty", mPublishedData, mSavedState);
-
-        // If a script returns empty table as the result, we get an empty bundle.
-        assertThat(mFakeScriptExecutorListener.mSavedBundle).isNotNull();
-        assertThat(mFakeScriptExecutorListener.mSavedBundle.size()).isEqualTo(0);
-    }
-
-    @Test
-    public void invokeScript_processPreviousStateAndReturnResult() throws RemoteException {
-        // Here we verify that the script actually processes provided state from a previous run
-        // and makes calculation based on that and returns the result.
-        String script =
-                "function update(data, state)\n"
-                        + "    result = {y = state.x+1}\n"
-                        + "    on_success(result)\n"
-                        + "end\n";
-        PersistableBundle previousState = new PersistableBundle();
-        previousState.putInt("x", 1);
-
-        runScriptAndWaitForResponse(script, "update", mPublishedData, previousState);
-
-        // Verify that y = 2, because y = x + 1 and x = 1.
-        assertThat(mFakeScriptExecutorListener.mSavedBundle.size()).isEqualTo(1);
-        assertThat(mFakeScriptExecutorListener.mSavedBundle.getLong("y")).isEqualTo(2);
-    }
-
-    @Test
-    public void invokeScript_allSupportedPrimitiveTypesWorkRoundTripWithKeyNamesPreserved()
-            throws RemoteException {
-        // Here we verify that all supported primitive types in supplied previous state Bundle
-        // are interpreted by the script as expected.
-        String script =
-                "function update_all(data, state)\n"
-                        + "    result = {}\n"
-                        + "    result.integer = state.integer + 1\n"
-                        + "    result.number = state.number + 0.1\n"
-                        + "    result.boolean = not state.boolean\n"
-                        + "    result.string = state.string .. \"CADABRA\"\n"
-                        + "    on_success(result)\n"
-                        + "end\n";
-        PersistableBundle previousState = new PersistableBundle();
-        previousState.putInt("integer", 1);
-        previousState.putDouble("number", 0.1);
-        previousState.putBoolean("boolean", false);
-        previousState.putString("string", "ABRA");
-
-        runScriptAndWaitForResponse(script, "update_all", mPublishedData, previousState);
-
-        // Verify that keys are preserved but the values are modified as expected.
-        assertThat(mFakeScriptExecutorListener.mSavedBundle.size()).isEqualTo(4);
-        assertThat(mFakeScriptExecutorListener.mSavedBundle.getLong("integer")).isEqualTo(2);
-        assertThat(mFakeScriptExecutorListener.mSavedBundle.getDouble("number")).isEqualTo(0.2);
-        assertThat(mFakeScriptExecutorListener.mSavedBundle.getBoolean("boolean")).isEqualTo(true);
-        assertThat(mFakeScriptExecutorListener.mSavedBundle.getString("string")).isEqualTo(
-                "ABRACADABRA");
-    }
-
-    @Test
-    public void invokeScript_allSupportedArrayTypesWorkRoundTripWithKeyNamesPreserved()
-            throws RemoteException {
-        // Here we verify that all supported array types in supplied previous state Bundle are
-        // interpreted by the script as expected.
-        String script =
-                "function arrays(data, state)\n"
-                        + "    result = {}\n"
-                        + "    result.int_array = state.int_array\n"
-                        + "    result.long_array = state.long_array\n"
-                        + "    result.string_array = state.string_array\n"
-                        + "    on_success(result)\n"
-                        + "end\n";
-        PersistableBundle previousState = new PersistableBundle();
-        int[] int_array = new int[]{1, 2};
-        long[] int_array_in_long = new long[]{1, 2};
-        long[] long_array = new long[]{1, 2, 3};
-        String[] string_array = new String[]{"one", "two", "three"};
-        previousState.putIntArray("int_array", int_array);
-        previousState.putLongArray("long_array", long_array);
-        previousState.putStringArray("string_array", string_array);
-
-        runScriptAndWaitForResponse(script, "arrays", mPublishedData, previousState);
-
-        // Verify that keys are preserved but the values are modified as expected.
-        assertThat(mFakeScriptExecutorListener.mSavedBundle.size()).isEqualTo(3);
-        // Lua has only one lua_Integer. Here Java long is used to represent it when data is
-        // transferred from Lua to CarTelemetryService.
-        assertThat(mFakeScriptExecutorListener.mSavedBundle.getLongArray("int_array")).isEqualTo(
-                int_array_in_long);
-        assertThat(mFakeScriptExecutorListener.mSavedBundle.getLongArray("long_array")).isEqualTo(
-                long_array);
-        assertThat(
-                mFakeScriptExecutorListener.mSavedBundle.getStringArray("string_array")).isEqualTo(
-                string_array);
-    }
-
-    @Test
-    public void invokeScript_modifiesArray()
-            throws RemoteException {
-        // Verify that an array modified by a script is properly sent back by the callback.
-        String script =
-                "function modify_array(data, state)\n"
-                        + "    result = {}\n"
-                        + "    result.long_array = state.long_array\n"
-                        + "    result.long_array[2] = 100\n"
-                        + "    on_success(result)\n"
-                        + "end\n";
-        PersistableBundle previousState = new PersistableBundle();
-        long[] long_array = new long[]{1, 2, 3};
-        previousState.putLongArray("long_array", long_array);
-        long[] expected_array = new long[]{1, 100, 3};
-
-        runScriptAndWaitForResponse(script, "modify_array", mPublishedData, previousState);
-
-        // Verify that keys are preserved but the values are modified as expected.
-        assertThat(mFakeScriptExecutorListener.mSavedBundle.size()).isEqualTo(1);
-        assertThat(mFakeScriptExecutorListener.mSavedBundle.getLongArray("long_array")).isEqualTo(
-                expected_array);
-    }
-
-    @Test
-    public void invokeScript_processesStringArray()
-            throws RemoteException {
-        // Verify that an array modified by a script is properly sent back by the callback.
-        String script =
-                "function process_string_array(data, state)\n"
-                        + "    result = {}\n"
-                        + "    result.answer = state.string_array[1] .. state.string_array[2]\n"
-                        + "    on_success(result)\n"
-                        + "end\n";
-        PersistableBundle previousState = new PersistableBundle();
-        String[] string_array = new String[]{"Hello ", "world!"};
-        previousState.putStringArray("string_array", string_array);
-
-        runScriptAndWaitForResponse(script, "process_string_array", mPublishedData, previousState);
-
-        // Verify that keys are preserved but the values are modified as expected.
-        assertThat(mFakeScriptExecutorListener.mSavedBundle.size()).isEqualTo(1);
-        assertThat(mFakeScriptExecutorListener.mSavedBundle.getString("answer")).isEqualTo(
-                "Hello world!");
-    }
-
-    @Test
-    public void invokeScript_arraysWithLengthAboveLimitCauseError()
-            throws RemoteException {
-        // Verifies that arrays pushed by Lua that have their size over the limit cause error.
-        String script =
-                "function size_limit(data, state)\n"
-                        + "    result = {}\n"
-                        + "    result.huge_array = {}\n"
-                        + "    for i=1, 10000 do\n"
-                        + "        result.huge_array[i]=i\n"
-                        + "    end\n"
-                        + "    on_success(result)\n"
-                        + "end\n";
-
-        runScriptAndWaitForResponse(script, "size_limit", mPublishedData, mSavedState);
-
-        // Verify that expected error is received.
-        assertThat(mFakeScriptExecutorListener.mErrorType).isEqualTo(
-                IScriptExecutorListener.ERROR_TYPE_LUA_SCRIPT_ERROR);
-        assertThat(mFakeScriptExecutorListener.mMessage).isEqualTo(
-                "Returned table huge_array exceeds maximum allowed size of 1000 "
-                        + "elements. This key-value cannot be unpacked successfully. This error "
-                        + "is unrecoverable.");
-    }
-
-    @Test
-    public void invokeScript_arrayContainingVaryingTypesCausesError()
-            throws RemoteException {
-        // Verifies that values in returned array must be the same integer type.
-        // For example string values in a Lua array are not allowed.
-        String script =
-                "function table_with_numbers_and_strings(data, state)\n"
-                        + "    result = {}\n"
-                        + "    result.mixed_array = state.long_array\n"
-                        + "    result.mixed_array[2] = 'a'\n"
-                        + "    on_success(result)\n"
-                        + "end\n";
-        PersistableBundle previousState = new PersistableBundle();
-        long[] long_array = new long[]{1, 2, 3};
-        previousState.putLongArray("long_array", long_array);
-
-        runScriptAndWaitForResponse(script, "table_with_numbers_and_strings", mPublishedData,
-                previousState);
-
-        // Verify that expected error is received.
-        assertThat(mFakeScriptExecutorListener.mErrorType).isEqualTo(
-                IScriptExecutorListener.ERROR_TYPE_LUA_SCRIPT_ERROR);
-        assertThat(mFakeScriptExecutorListener.mMessage).contains(
-                "Returned Lua arrays must have elements of the same type.");
-    }
-
-    @Test
-    public void invokeScript_InTablesWithBothKeysAndIndicesCopiesOnlyIndexedData()
-            throws RemoteException {
-        // Documents the current behavior that copies only indexed values in a Lua table that
-        // contains both keyed and indexed data.
-        String script =
-                "function keys_and_indices(data, state)\n"
-                        + "    result = {}\n"
-                        + "    result.mixed_array = state.long_array\n"
-                        + "    result.mixed_array['a'] = 130\n"
-                        + "    on_success(result)\n"
-                        + "end\n";
-        PersistableBundle previousState = new PersistableBundle();
-        long[] long_array = new long[]{1, 2, 3};
-        previousState.putLongArray("long_array", long_array);
-
-        runScriptAndWaitForResponse(script, "keys_and_indices", mPublishedData, previousState);
-
-        // Verify that keys are preserved but the values are modified as expected.
-        assertThat(mFakeScriptExecutorListener.mSavedBundle.size()).isEqualTo(1);
-        assertThat(mFakeScriptExecutorListener.mSavedBundle.getLongArray("mixed_array")).isEqualTo(
-                long_array);
-    }
-
-    @Test
-    public void invokeScript_noLuaBufferOverflowForLargeInputArrays() throws RemoteException {
-        // Tests that arrays with length that exceed internal Lua buffer size of 20 elements
-        // do not cause buffer overflow and are handled properly.
-        String script =
-                "function large_input_array(data, state)\n"
-                        + "    sum = 0\n"
-                        + "    for _, val in ipairs(state.long_array) do\n"
-                        + "        sum = sum + val\n"
-                        + "    end\n"
-                        + "    result = {total = sum}\n"
-                        + "    on_success(result)\n"
-                        + "end\n";
-
-        PersistableBundle previousState = new PersistableBundle();
-        int n = 10000;
-        long[] longArray = new long[n];
-        for (int i = 0; i < n; i++) {
-            longArray[i] = i;
-        }
-        previousState.putLongArray("long_array", longArray);
-        long expected_sum =
-                (longArray[0] + longArray[n - 1]) * n / 2; // sum of an arithmetic sequence.
-
-        runScriptAndWaitForResponse(script, "large_input_array", mPublishedData, previousState);
-
-        // Verify that keys are preserved but the values are modified as expected.
-        assertThat(mFakeScriptExecutorListener.mSavedBundle.size()).isEqualTo(1);
-        assertThat(mFakeScriptExecutorListener.mSavedBundle.getLong("total")).isEqualTo(
-                expected_sum);
-    }
-
-    @Test
-    public void invokeScript_scriptCallsOnError() throws RemoteException {
-        String script =
-                "function calls_on_error()\n"
-                        + "    if 1 ~= 2 then\n"
-                        + "        on_error(\"one is not equal to two\")\n"
-                        + "        return\n"
-                        + "    end\n"
-                        + "end\n";
-
-        runScriptAndWaitForError(script, "calls_on_error");
-
-        assertThat(mFakeScriptExecutorListener.mErrorType).isEqualTo(
-                IScriptExecutorListener.ERROR_TYPE_LUA_SCRIPT_ERROR);
-        assertThat(mFakeScriptExecutorListener.mMessage).isEqualTo("one is not equal to two");
-    }
-
-    @Test
-    public void invokeScript_tooManyParametersInOnError() throws RemoteException {
-        String script =
-                "function too_many_params_in_on_error()\n"
-                        + "    if 1 ~= 2 then\n"
-                        + "        on_error(\"param1\", \"param2\")\n"
-                        + "        return\n"
-                        + "    end\n"
-                        + "end\n";
-
-        runScriptAndWaitForError(script, "too_many_params_in_on_error");
-
-        assertThat(mFakeScriptExecutorListener.mErrorType).isEqualTo(
-                IScriptExecutorListener.ERROR_TYPE_LUA_SCRIPT_ERROR);
-        assertThat(mFakeScriptExecutorListener.mMessage).isEqualTo(
-                "on_error can push only a single string parameter from Lua");
-    }
-
-    @Test
-    public void invokeScript_onErrorOnlyAcceptsString() throws RemoteException {
-        String script =
-                "function only_string()\n"
-                        + "    if 1 ~= 2 then\n"
-                        + "        on_error(false)\n"
-                        + "        return\n"
-                        + "    end\n"
-                        + "end\n";
-
-        runScriptAndWaitForError(script, "only_string");
-
-        assertThat(mFakeScriptExecutorListener.mErrorType).isEqualTo(
-                IScriptExecutorListener.ERROR_TYPE_LUA_SCRIPT_ERROR);
-        assertThat(mFakeScriptExecutorListener.mMessage).isEqualTo(
-                "on_error can push only a single string parameter from Lua");
-    }
-
-    @Test
-    public void invokeScript_returnsFinalResult() throws RemoteException {
-        String returnFinalResultScript =
-                "function script_finishes(data, state)\n"
-                        + "    result = {data = state.input + 1}\n"
-                        + "    on_script_finished(result)\n"
-                        + "end\n";
-        PersistableBundle previousState = new PersistableBundle();
-        previousState.putInt("input", 1);
-
-        runScriptAndWaitForResponse(returnFinalResultScript, "script_finishes", mPublishedData,
-                previousState);
-
-        // Expect to get back a bundle with a single key-value pair {"data": 2}
-        // because data = state.input + 1 as in the script body above.
-        assertThat(mFakeScriptExecutorListener.mFinalResult.size()).isEqualTo(1);
-        assertThat(mFakeScriptExecutorListener.mFinalResult.getLong("data")).isEqualTo(2);
-    }
-
-    @Test
-    public void invokeScript_emptyStringValueIsValidValue() throws RemoteException {
-        // Verify that an empty string value is a valid value to be returned from a script.
-        String returnFinalResultScript =
-                "function empty_string(data, state)\n"
-                        + "    result = {data = \"\"}\n"
-                        + "    on_script_finished(result)\n"
-                        + "end\n";
-
-        runScriptAndWaitForResponse(returnFinalResultScript, "empty_string", mPublishedData,
-                new PersistableBundle());
-
-        // Expect to get back a bundle with a single key-value pair {"data": ""}
-        assertThat(mFakeScriptExecutorListener.mFinalResult.size()).isEqualTo(1);
-        assertThat(mFakeScriptExecutorListener.mFinalResult.getString("data")).isEqualTo("");
-    }
-
-    @Test
-    public void invokeScript_allPrimitiveSupportedTypesForReturningFinalResult()
-            throws RemoteException {
-        // Here we verify that all supported primitive types are present in the returned final
-        // result bundle are present.
-        String script =
-                "function finalize_all(data, state)\n"
-                        + "    result = {}\n"
-                        + "    result.integer = state.integer + 1\n"
-                        + "    result.number = state.number + 0.1\n"
-                        + "    result.boolean = not state.boolean\n"
-                        + "    result.string = state.string .. \"CADABRA\"\n"
-                        + "    on_script_finished(result)\n"
-                        + "end\n";
-        PersistableBundle previousState = new PersistableBundle();
-        previousState.putInt("integer", 1);
-        previousState.putDouble("number", 0.1);
-        previousState.putBoolean("boolean", false);
-        previousState.putString("string", "ABRA");
-
-        runScriptAndWaitForResponse(script, "finalize_all", mPublishedData, previousState);
-
-        // Verify that keys are preserved but the values are modified as expected.
-        assertThat(mFakeScriptExecutorListener.mFinalResult.size()).isEqualTo(4);
-        assertThat(mFakeScriptExecutorListener.mFinalResult.getLong("integer")).isEqualTo(2);
-        assertThat(mFakeScriptExecutorListener.mFinalResult.getDouble("number")).isEqualTo(0.2);
-        assertThat(mFakeScriptExecutorListener.mFinalResult.getBoolean("boolean")).isEqualTo(true);
-        assertThat(mFakeScriptExecutorListener.mFinalResult.getString("string")).isEqualTo(
-                "ABRACADABRA");
-    }
-
-    @Test
-    public void invokeScript_emptyFinalResultBundle() throws RemoteException {
-        String script =
-                "function empty_final_result(data, state)\n"
-                        + "    result = {}\n"
-                        + "    on_script_finished(result)\n"
-                        + "end\n";
-
-        runScriptAndWaitForResponse(script, "empty_final_result", mPublishedData, mSavedState);
-
-        // If a script returns empty table as the final result, we get an empty bundle.
-        assertThat(mFakeScriptExecutorListener.mFinalResult).isNotNull();
-        assertThat(mFakeScriptExecutorListener.mFinalResult.size()).isEqualTo(0);
-    }
-
-    @Test
-    public void invokeScript_wrongNumberOfCallbackInputsInOnScriptFinished()
-            throws RemoteException {
-        String script =
-                "function wrong_number_of_outputs_in_on_script_finished(data, state)\n"
-                        + "    result = {}\n"
-                        + "    extra = 1\n"
-                        + "    on_script_finished(result, extra)\n"
-                        + "end\n";
-
-        runScriptAndWaitForResponse(script, "wrong_number_of_outputs_in_on_script_finished",
-                mPublishedData, mSavedState);
-
-        // We expect to get an error here because we expect only 1 input parameter in
-        // on_script_finished.
-        assertThat(mFakeScriptExecutorListener.mErrorType).isEqualTo(
-                IScriptExecutorListener.ERROR_TYPE_LUA_SCRIPT_ERROR);
-        assertThat(mFakeScriptExecutorListener.mMessage).isEqualTo(
-                "on_script_finished can push only a single parameter from Lua - a Lua table");
-    }
-
-    @Test
-    public void invokeScript_wrongNumberOfCallbackInputsInOnSuccess() throws RemoteException {
-        String script =
-                "function wrong_number_of_outputs_in_on_success(data, state)\n"
-                        + "    result = {}\n"
-                        + "    extra = 1\n"
-                        + "    on_success(result, extra)\n"
-                        + "end\n";
-
-        runScriptAndWaitForResponse(script, "wrong_number_of_outputs_in_on_success",
-                mPublishedData, mSavedState);
-
-        // We expect to get an error here because we expect only 1 input parameter in on_success.
-        assertThat(mFakeScriptExecutorListener.mErrorType).isEqualTo(
-                IScriptExecutorListener.ERROR_TYPE_LUA_SCRIPT_ERROR);
-        assertThat(mFakeScriptExecutorListener.mMessage).isEqualTo(
-                "on_success can push only a single parameter from Lua - a Lua table");
-    }
-
-    @Test
-    public void invokeScript_wrongTypeInOnSuccess() throws RemoteException {
-        String script =
-                "function wrong_type_in_on_success(data, state)\n"
-                        + "    result = 1\n"
-                        + "    on_success(result)\n"
-                        + "end\n";
-
-        runScriptAndWaitForResponse(script, "wrong_type_in_on_success",
-                mPublishedData, mSavedState);
-
-        // We expect to get an error here because the type of the input parameter for on_success
-        // must be a Lua table.
-        assertThat(mFakeScriptExecutorListener.mErrorType).isEqualTo(
-                IScriptExecutorListener.ERROR_TYPE_LUA_SCRIPT_ERROR);
-        assertThat(mFakeScriptExecutorListener.mMessage).isEqualTo(
-                "on_success can push only a single parameter from Lua - a Lua table");
-    }
-
-    @Test
-    public void invokeScript_wrongTypeInOnScriptFinished() throws RemoteException {
-        String script =
-                "function wrong_type_in_on_script_finished(data, state)\n"
-                        + "    result = 1\n"
-                        + "    on_success(result)\n"
-                        + "end\n";
-
-        runScriptAndWaitForResponse(script, "wrong_type_in_on_script_finished",
-                mPublishedData, mSavedState);
-
-        // We expect to get an error here because the type of the input parameter for
-        // on_script_finished must be a Lua table.
-        assertThat(mFakeScriptExecutorListener.mErrorType).isEqualTo(
-                IScriptExecutorListener.ERROR_TYPE_LUA_SCRIPT_ERROR);
-        assertThat(mFakeScriptExecutorListener.mMessage).isEqualTo(
-                "on_success can push only a single parameter from Lua - a Lua table");
-    }
-
-    @Test
-    public void invokeScriptLargeInput_largePublishedData() throws Exception {
-        // Verifies that large input does not overwhelm Binder's buffer because pipes are used
-        // instead.
-        String script =
-                "function large_published_data(data, state)\n"
-                        + "    sum = 0\n"
-                        + "    for _, val in ipairs(data.array) do\n"
-                        + "        sum = sum + val\n"
-                        + "    end\n"
-                        + "    result = {total = sum}\n"
-                        + "    on_script_finished(result)\n"
-                        + "end\n";
-
-        ParcelFileDescriptor[] fds = ParcelFileDescriptor.createPipe();
-        ParcelFileDescriptor writeFd = fds[1];
-        ParcelFileDescriptor readFd = fds[0];
-
-        PersistableBundle bundle = new PersistableBundle();
-        int n = 1 << 20; // 1024 * 1024 values, roughly 1 Million.
-        long[] array8Mb = new long[n];
-        for (int i = 0; i < n; i++) {
-            array8Mb[i] = i;
-        }
-        bundle.putLongArray("array", array8Mb);
-        long expectedSum =
-                (array8Mb[0] + array8Mb[n - 1]) * n / 2; // sum of an arithmetic sequence.
-
-        mScriptExecutor.invokeScriptForLargeInput(script, "large_published_data", readFd,
-                mSavedState,
-                mFakeScriptExecutorListener);
-
-        readFd.close();
-        try (OutputStream outputStream = new ParcelFileDescriptor.AutoCloseOutputStream(writeFd)) {
-            bundle.writeToStream(outputStream);
-        }
-
-        boolean gotResponse = mFakeScriptExecutorListener.mResponseLatch.await(
-                SCRIPT_PROCESSING_TIMEOUT_SEC,
-                TimeUnit.SECONDS);
-
-        assertWithMessage("Failed to get the callback method called by the script on time")
-                .that(gotResponse).isTrue();
-        assertThat(mFakeScriptExecutorListener.mFinalResult.size()).isEqualTo(1);
-        assertThat(mFakeScriptExecutorListener.mFinalResult.getLong("total"))
-                .isEqualTo(expectedSum);
-    }
-
-    @Test
-    public void invokeScript_bothPublishedDataAndPreviousStateAreProvided() throws RemoteException {
-        // Verifies that both published data and previous state PersistableBundles
-        // are piped into script.
-        String script =
-                "function data_and_state(data, state)\n"
-                        + "    result = {answer = data.a .. data.b .. state.c .. state.d}\n"
-                        + "    on_script_finished(result)\n"
-                        + "end\n";
-
-        PersistableBundle publishedData = new PersistableBundle();
-        publishedData.putString("a", "A");
-        publishedData.putString("b", "B");
-
-        PersistableBundle previousState = new PersistableBundle();
-        previousState.putString("c", "C");
-        previousState.putString("d", "D");
-
-        runScriptAndWaitForResponse(script, "data_and_state", publishedData, previousState);
-
-        // Lua script combines both input published data and previous state into a single result.
-        assertThat(mFakeScriptExecutorListener.mFinalResult).isNotNull();
-        assertThat(mFakeScriptExecutorListener.mFinalResult.size()).isEqualTo(1);
-        assertThat(mFakeScriptExecutorListener.mFinalResult.getString("answer")).isEqualTo(
-                "ABCD");
-    }
-
-    @Test
-    public void invokeScript_outputIntAndLongAreTreatedAsLong() throws RemoteException {
-        // Verifies that we treat output both integer and long as long integer type although we
-        // distinguish between int and long in the script input.
-        String script =
-                "function int_and_long_are_output_long(data, state)\n"
-                        + "    result = {int = data.int, long = state.long}\n"
-                        + "    on_script_finished(result)\n"
-                        + "end\n";
-
-        PersistableBundle publishedData = new PersistableBundle();
-        publishedData.putInt("int", 100);
-
-        PersistableBundle previousState = new PersistableBundle();
-        previousState.putLong("long", 200);
-
-        runScriptAndWaitForResponse(script, "int_and_long_are_output_long",
-                publishedData, previousState);
-
-        // If a script returns empty table as the final result, we get an empty bundle.
-        assertThat(mFakeScriptExecutorListener.mFinalResult).isNotNull();
-        assertThat(mFakeScriptExecutorListener.mFinalResult.size()).isEqualTo(2);
-        // getInt should always return "empty" value (zero) because all integer types are treated
-        // as Java long.
-        assertThat(mFakeScriptExecutorListener.mFinalResult.getInt("int")).isEqualTo(0);
-        assertThat(mFakeScriptExecutorListener.mFinalResult.getInt("long")).isEqualTo(0);
-        // Instead all expected integer values are successfully retrieved using getLong method
-        // from the output bundle.
-        assertThat(mFakeScriptExecutorListener.mFinalResult.getLong("int")).isEqualTo(100);
-        assertThat(mFakeScriptExecutorListener.mFinalResult.getLong("long")).isEqualTo(200);
-    }
-
-    @Test
-    public void invokeScript_nonUTFCharactersDoNotCauseErrors() throws RemoteException {
-        // Tries to create an output string value that does not conform to Modified UTF-8.
-        // JNI gracefully handles it by parsing on the string as is.
-        String script =
-                "function non_utf_key_string(data, state)\n"
-                        + "    result = {answer = \"i\0np\200\200ut\"}\n"
-                        + "    on_script_finished(result)\n"
-                        + "end\n";
-
-        runScriptAndWaitForResponse(script, "non_utf_key_string", new PersistableBundle(),
-                new PersistableBundle());
-
-        // The output will still have all characters, including those that do not conform to
-        // Modified UTF-8.
-        assertThat(mFakeScriptExecutorListener.mFinalResult).isNotNull();
-        assertThat(mFakeScriptExecutorListener.mFinalResult.size()).isEqualTo(1);
-        assertThat(mFakeScriptExecutorListener.mFinalResult.getString("answer")).isEqualTo(
-                "i\0np\200\200ut");
-    }
-
-    @Test
-    public void invokeScript_wrongFunctionNameProvided() throws RemoteException {
-        // Verifies that not specifying function name correctly is handled through error callback.
-        String script =
-                "function correct_function(data, state)\n"
-                        + "end\n";
-
-        runScriptAndWaitForError(script, "wrong_function");
-
-        // Verify that the expected error is received.
-        assertThat(mFakeScriptExecutorListener.mErrorType).isEqualTo(
-                IScriptExecutorListener.ERROR_TYPE_LUA_RUNTIME_ERROR);
-        assertThat(mFakeScriptExecutorListener.mMessage).contains(
-                "Wrong function name");
-    }
-
-    @Test
-    public void invokeScript_runtimeErrorDueToSyntax() throws RemoteException {
-        // Verifies that syntax errors during script loading are handled gracefully.
-        String script =
-                "function wrong_syntax(data, state)\n"
-                        + "    x == 1\n"
-                        + "end\n";
-
-        runScriptAndWaitForError(script, "wrong_syntax");
-
-        // Verify that the expected error is received.
-        assertThat(mFakeScriptExecutorListener.mErrorType).isEqualTo(
-                IScriptExecutorListener.ERROR_TYPE_LUA_RUNTIME_ERROR);
-        assertThat(mFakeScriptExecutorListener.mMessage).contains(
-                "Error encountered while loading the script");
-    }
-
-    @Test
-    public void invokeScript_runtimeErrorDueToUndefinedMethod() throws RemoteException {
-        // Verifies that runtime errors encountered during Lua script execution trigger an error
-        // returned via a callback.
-        String script =
-                "function runtime_error(data, state)\n"
-                        + "    on_problem(data, state)\n"
-                        + "end\n";
-
-        runScriptAndWaitForError(script, "runtime_error");
-
-        // Verify that the expected error is received.
-        assertThat(mFakeScriptExecutorListener.mErrorType).isEqualTo(
-                IScriptExecutorListener.ERROR_TYPE_LUA_RUNTIME_ERROR);
-        assertThat(mFakeScriptExecutorListener.mMessage).contains(
-                "Error encountered while running the script");
-    }
-
-    @Test
-    public void invokeScript_returnedValuesOfUnsupportedTypesReturnError() throws RemoteException {
-        // Verifies that if we try to return a value of unsupported type, we get an error instead.
-        // In this case, the unsupported type is LUA_TFUNCTION type.
-        String script =
-                "function function_type(data, state)\n"
-                        + "    result = {fn = function_type}\n"
-                        + "    on_success(result)\n"
-                        + "end\n";
-
-        runScriptAndWaitForResponse(script, "function_type", mPublishedData, mSavedState);
-
-        // Verify that the expected error is received.
-        assertThat(mFakeScriptExecutorListener.mErrorType).isEqualTo(
-                IScriptExecutorListener.ERROR_TYPE_LUA_SCRIPT_ERROR);
-        assertThat(mFakeScriptExecutorListener.mMessage).contains(
-                "has a Lua type=function, which is not supported yet");
-    }
-
-    @Test
-    public void invokeScript_returnedFloatingArraysNotSupported() throws RemoteException {
-        // Verifies that we do not support return values that contain floating number arrays.
-        String script =
-                "function floating_point_arrays(data, state)\n"
-                        + "    array = {}\n"
-                        + "    array[0] = 1.1\n"
-                        + "    array[1] = 1.2\n"
-                        + "    result = {data = array}\n"
-                        + "    on_success(result)\n"
-                        + "end\n";
-
-        runScriptAndWaitForResponse(script, "floating_point_arrays", mPublishedData, mSavedState);
-
-        // Verify that the expected error is received.
-        assertThat(mFakeScriptExecutorListener.mErrorType).isEqualTo(
-                IScriptExecutorListener.ERROR_TYPE_LUA_SCRIPT_ERROR);
-        assertThat(mFakeScriptExecutorListener.mMessage).contains(
-                "a floating number array, which is not supported yet");
-    }
-
-    @Test
-    public void invokeScript_returnedBooleanArraysNotSupported() throws RemoteException {
-        // Verifies that we do not yet support return values that contain boolean arrays.
-        String script =
-                "function array_of_booleans(data, state)\n"
-                        + "    array = {}\n"
-                        + "    array[0] = false\n"
-                        + "    array[1] = true\n"
-                        + "    result = {data = array}\n"
-                        + "    on_success(result)\n"
-                        + "end\n";
-
-        runScriptAndWaitForResponse(script, "array_of_booleans", mPublishedData, mSavedState);
-
-        // Verify that the expected error is received.
-        assertThat(mFakeScriptExecutorListener.mErrorType).isEqualTo(
-                IScriptExecutorListener.ERROR_TYPE_LUA_SCRIPT_ERROR);
-        assertThat(mFakeScriptExecutorListener.mMessage).contains(
-                "is an array with values of type=boolean, which is not supported yet");
-    }
-}
-
diff --git a/packages/ScriptExecutor/tests/unit/src/com/android/car/scriptexecutor/JniUtilsTest.java b/packages/ScriptExecutor/tests/unit/src/com/android/car/scriptexecutortest/unit/JniUtilsTest.java
similarity index 98%
rename from packages/ScriptExecutor/tests/unit/src/com/android/car/scriptexecutor/JniUtilsTest.java
rename to packages/ScriptExecutor/tests/unit/src/com/android/car/scriptexecutortest/unit/JniUtilsTest.java
index 3292009..7cf8728 100644
--- a/packages/ScriptExecutor/tests/unit/src/com/android/car/scriptexecutor/JniUtilsTest.java
+++ b/packages/ScriptExecutor/tests/unit/src/com/android/car/scriptexecutortest/unit/JniUtilsTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.car.scriptexecutor;
+package com.android.car.scriptexecutortest.unit;
 
 import static com.google.common.truth.Truth.assertThat;
 
diff --git a/packages/ScriptExecutor/tests/unit/src/com/android/car/scriptexecutor/JniUtilsTestHelper.cpp b/packages/ScriptExecutor/tests/unit/src/com/android/car/scriptexecutortest/unit/JniUtilsTestHelper.cpp
similarity index 68%
rename from packages/ScriptExecutor/tests/unit/src/com/android/car/scriptexecutor/JniUtilsTestHelper.cpp
rename to packages/ScriptExecutor/tests/unit/src/com/android/car/scriptexecutortest/unit/JniUtilsTestHelper.cpp
index a205b32..57fea30 100644
--- a/packages/ScriptExecutor/tests/unit/src/com/android/car/scriptexecutor/JniUtilsTestHelper.cpp
+++ b/packages/ScriptExecutor/tests/unit/src/com/android/car/scriptexecutortest/unit/JniUtilsTestHelper.cpp
@@ -24,14 +24,16 @@
 namespace com {
 namespace android {
 namespace car {
-namespace scriptexecutor {
+namespace scriptexecutortest {
+namespace unit {
 namespace {
 
 template <typename T>
 bool hasIntegerArray(JNIEnv* env, jobject object, jlong luaEnginePtr, jstring key, T rawInputArray,
                      const int arrayLength) {
     const char* rawKey = env->GetStringUTFChars(key, nullptr);
-    LuaEngine* engine = reinterpret_cast<LuaEngine*>(static_cast<intptr_t>(luaEnginePtr));
+    scriptexecutor::LuaEngine* engine =
+            reinterpret_cast<scriptexecutor::LuaEngine*>(static_cast<intptr_t>(luaEnginePtr));
     // Assumes the table is on top of the stack.
     auto* luaState = engine->getLuaState();
     lua_pushstring(luaState, rawKey);
@@ -69,34 +71,43 @@
 
 #include "lua.h"
 
-JNIEXPORT jlong JNICALL Java_com_android_car_scriptexecutor_JniUtilsTest_nativeCreateLuaEngine(
-        JNIEnv* env, jobject object) {
+JNIEXPORT jlong JNICALL
+Java_com_android_car_scriptexecutortest_unit_JniUtilsTest_nativeCreateLuaEngine(JNIEnv* env,
+                                                                                jobject object) {
     // Cast first to intptr_t to ensure int can hold the pointer without loss.
-    return static_cast<jlong>(reinterpret_cast<intptr_t>(new LuaEngine()));
-}
-
-JNIEXPORT void JNICALL Java_com_android_car_scriptexecutor_JniUtilsTest_nativeDestroyLuaEngine(
-        JNIEnv* env, jobject object, jlong luaEnginePtr) {
-    delete reinterpret_cast<LuaEngine*>(static_cast<intptr_t>(luaEnginePtr));
+    return static_cast<jlong>(reinterpret_cast<intptr_t>(new scriptexecutor::LuaEngine()));
 }
 
 JNIEXPORT void JNICALL
-Java_com_android_car_scriptexecutor_JniUtilsTest_nativePushBundleToLuaTableCaller(
-        JNIEnv* env, jobject object, jlong luaEnginePtr, jobject bundle) {
-    LuaEngine* engine = reinterpret_cast<LuaEngine*>(static_cast<intptr_t>(luaEnginePtr));
-    pushBundleToLuaTable(env, engine->getLuaState(), bundle);
+Java_com_android_car_scriptexecutortest_unit_JniUtilsTest_nativeDestroyLuaEngine(
+        JNIEnv* env, jobject object, jlong luaEnginePtr) {
+    delete reinterpret_cast<scriptexecutor::LuaEngine*>(static_cast<intptr_t>(luaEnginePtr));
 }
 
-JNIEXPORT jint JNICALL Java_com_android_car_scriptexecutor_JniUtilsTest_nativeGetObjectSize(
-        JNIEnv* env, jobject object, jlong luaEnginePtr, jint index) {
-    LuaEngine* engine = reinterpret_cast<LuaEngine*>(static_cast<intptr_t>(luaEnginePtr));
+JNIEXPORT void JNICALL
+Java_com_android_car_scriptexecutortest_unit_JniUtilsTest_nativePushBundleToLuaTableCaller(
+        JNIEnv* env, jobject object, jlong luaEnginePtr, jobject bundle) {
+    scriptexecutor::LuaEngine* engine =
+            reinterpret_cast<scriptexecutor::LuaEngine*>(static_cast<intptr_t>(luaEnginePtr));
+    scriptexecutor::pushBundleToLuaTable(env, engine->getLuaState(), bundle);
+}
+
+JNIEXPORT jint JNICALL
+Java_com_android_car_scriptexecutortest_unit_JniUtilsTest_nativeGetObjectSize(JNIEnv* env,
+                                                                              jobject object,
+                                                                              jlong luaEnginePtr,
+                                                                              jint index) {
+    scriptexecutor::LuaEngine* engine =
+            reinterpret_cast<scriptexecutor::LuaEngine*>(static_cast<intptr_t>(luaEnginePtr));
     return lua_rawlen(engine->getLuaState(), static_cast<int>(index));
 }
 
-JNIEXPORT bool JNICALL Java_com_android_car_scriptexecutor_JniUtilsTest_nativeHasBooleanValue(
+JNIEXPORT bool JNICALL
+Java_com_android_car_scriptexecutortest_unit_JniUtilsTest_nativeHasBooleanValue(
         JNIEnv* env, jobject object, jlong luaEnginePtr, jstring key, jboolean value) {
     const char* rawKey = env->GetStringUTFChars(key, nullptr);
-    LuaEngine* engine = reinterpret_cast<LuaEngine*>(static_cast<intptr_t>(luaEnginePtr));
+    scriptexecutor::LuaEngine* engine =
+            reinterpret_cast<scriptexecutor::LuaEngine*>(static_cast<intptr_t>(luaEnginePtr));
     auto* luaState = engine->getLuaState();
     lua_pushstring(luaState, rawKey);
     env->ReleaseStringUTFChars(key, rawKey);
@@ -110,10 +121,11 @@
     return result;
 }
 
-JNIEXPORT bool JNICALL Java_com_android_car_scriptexecutor_JniUtilsTest_nativeHasIntValue(
+JNIEXPORT bool JNICALL Java_com_android_car_scriptexecutortest_unit_JniUtilsTest_nativeHasIntValue(
         JNIEnv* env, jobject object, jlong luaEnginePtr, jstring key, jint value) {
     const char* rawKey = env->GetStringUTFChars(key, nullptr);
-    LuaEngine* engine = reinterpret_cast<LuaEngine*>(static_cast<intptr_t>(luaEnginePtr));
+    scriptexecutor::LuaEngine* engine =
+            reinterpret_cast<scriptexecutor::LuaEngine*>(static_cast<intptr_t>(luaEnginePtr));
     // Assumes the table is on top of the stack.
     auto* luaState = engine->getLuaState();
     lua_pushstring(luaState, rawKey);
@@ -128,10 +140,12 @@
     return result;
 }
 
-JNIEXPORT bool JNICALL Java_com_android_car_scriptexecutor_JniUtilsTest_nativeHasDoubleValue(
+JNIEXPORT bool JNICALL
+Java_com_android_car_scriptexecutortest_unit_JniUtilsTest_nativeHasDoubleValue(
         JNIEnv* env, jobject object, jlong luaEnginePtr, jstring key, jdouble value) {
     const char* rawKey = env->GetStringUTFChars(key, nullptr);
-    LuaEngine* engine = reinterpret_cast<LuaEngine*>(static_cast<intptr_t>(luaEnginePtr));
+    scriptexecutor::LuaEngine* engine =
+            reinterpret_cast<scriptexecutor::LuaEngine*>(static_cast<intptr_t>(luaEnginePtr));
     // Assumes the table is on top of the stack.
     auto* luaState = engine->getLuaState();
     lua_pushstring(luaState, rawKey);
@@ -146,10 +160,12 @@
     return result;
 }
 
-JNIEXPORT bool JNICALL Java_com_android_car_scriptexecutor_JniUtilsTest_nativeHasStringValue(
+JNIEXPORT bool JNICALL
+Java_com_android_car_scriptexecutortest_unit_JniUtilsTest_nativeHasStringValue(
         JNIEnv* env, jobject object, jlong luaEnginePtr, jstring key, jstring value) {
     const char* rawKey = env->GetStringUTFChars(key, nullptr);
-    LuaEngine* engine = reinterpret_cast<LuaEngine*>(static_cast<intptr_t>(luaEnginePtr));
+    scriptexecutor::LuaEngine* engine =
+            reinterpret_cast<scriptexecutor::LuaEngine*>(static_cast<intptr_t>(luaEnginePtr));
     // Assumes the table is on top of the stack.
     auto* luaState = engine->getLuaState();
     lua_pushstring(luaState, rawKey);
@@ -168,7 +184,8 @@
     return result;
 }
 
-JNIEXPORT bool JNICALL Java_com_android_car_scriptexecutor_JniUtilsTest_nativeHasIntArrayValue(
+JNIEXPORT bool JNICALL
+Java_com_android_car_scriptexecutortest_unit_JniUtilsTest_nativeHasIntArrayValue(
         JNIEnv* env, jobject object, jlong luaEnginePtr, jstring key, jintArray value) {
     jint* rawInputArray = env->GetIntArrayElements(value, nullptr);
     const auto kInputLength = env->GetArrayLength(value);
@@ -177,7 +194,8 @@
     return result;
 }
 
-JNIEXPORT bool JNICALL Java_com_android_car_scriptexecutor_JniUtilsTest_nativeHasLongArrayValue(
+JNIEXPORT bool JNICALL
+Java_com_android_car_scriptexecutortest_unit_JniUtilsTest_nativeHasLongArrayValue(
         JNIEnv* env, jobject object, jlong luaEnginePtr, jstring key, jlongArray value) {
     jlong* rawInputArray = env->GetLongArrayElements(value, nullptr);
     const auto kInputLength = env->GetArrayLength(value);
@@ -189,7 +207,8 @@
 }  //  extern "C"
 
 }  // namespace
-}  // namespace scriptexecutor
+}  // namespace unit
+}  // namespace scriptexecutortest
 }  // namespace car
 }  // namespace android
 }  // namespace com
