Merge "Add explicit handling for an unspecified gwpAsanMode manifest flag."
diff --git a/core/api/current.txt b/core/api/current.txt
index 4a8f048..0e92850 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -25917,6 +25917,7 @@
     method @Nullable public android.media.tv.TvInputService.RecordingSession onCreateRecordingSession(@NonNull String, @NonNull String);
     method @Nullable public abstract android.media.tv.TvInputService.Session onCreateSession(@NonNull String);
     method @Nullable public android.media.tv.TvInputService.Session onCreateSession(@NonNull String, @NonNull String);
+    method @Nullable public android.media.tv.TvInputService.Session onCreateSession(@NonNull String, @NonNull String, @NonNull android.content.AttributionSource);
     field public static final int PRIORITY_HINT_USE_CASE_TYPE_BACKGROUND = 100; // 0x64
     field public static final int PRIORITY_HINT_USE_CASE_TYPE_LIVE = 400; // 0x190
     field public static final int PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK = 300; // 0x12c
@@ -26077,6 +26078,7 @@
     method public String getSelectedTrack(int);
     method public java.util.List<android.media.tv.TvTrackInfo> getTracks(int);
     method public boolean onUnhandledInputEvent(android.view.InputEvent);
+    method public void overrideTvAppAttributionSource(@NonNull android.content.AttributionSource);
     method public void reset();
     method public void selectTrack(int, String);
     method public void sendAppPrivateCommand(@NonNull String, android.os.Bundle);
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 6eddc3c0..1d39931 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -760,10 +760,12 @@
 
   public class BroadcastOptions {
     method public void clearRequireCompatChange();
+    method public boolean isDeferUntilActive();
     method public boolean isPendingIntentBackgroundActivityLaunchAllowed();
     method public static android.app.BroadcastOptions makeBasic();
     method @RequiresPermission(android.Manifest.permission.ACCESS_BROADCAST_RESPONSE_STATS) public void recordResponseEventWhileInBackground(@IntRange(from=0) long);
     method @RequiresPermission(android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND) public void setBackgroundActivityStartsAllowed(boolean);
+    method @NonNull public android.app.BroadcastOptions setDeferUntilActive(boolean);
     method public void setDeliveryGroupMatchingFilter(@NonNull android.content.IntentFilter);
     method public void setDeliveryGroupMatchingKey(@NonNull String, @NonNull String);
     method public void setDeliveryGroupPolicy(int);
@@ -9120,14 +9122,20 @@
     method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean enable();
     method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean enableNdefPush();
     method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean enableSecureNfc(boolean);
+    method @NonNull @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public java.util.Map<java.lang.String,java.lang.Boolean> getTagIntentAppPreferenceForUser(int);
     method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public boolean isControllerAlwaysOn();
     method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public boolean isControllerAlwaysOnSupported();
+    method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean isTagIntentAppPreferenceSupported();
     method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public void registerControllerAlwaysOnListener(@NonNull java.util.concurrent.Executor, @NonNull android.nfc.NfcAdapter.ControllerAlwaysOnListener);
     method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean removeNfcUnlockHandler(android.nfc.NfcAdapter.NfcUnlockHandler);
     method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public boolean setControllerAlwaysOn(boolean);
     method public void setNdefPushMessage(android.nfc.NdefMessage, android.app.Activity, int);
+    method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int setTagIntentAppPreferenceForUser(int, @NonNull String, boolean);
     method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public void unregisterControllerAlwaysOnListener(@NonNull android.nfc.NfcAdapter.ControllerAlwaysOnListener);
     field public static final int FLAG_NDEF_PUSH_NO_CONFIRM = 1; // 0x1
+    field public static final int TAG_INTENT_APP_PREF_RESULT_PACKAGE_NOT_FOUND = -1; // 0xffffffff
+    field public static final int TAG_INTENT_APP_PREF_RESULT_SUCCESS = 0; // 0x0
+    field public static final int TAG_INTENT_APP_PREF_RESULT_UNAVAILABLE = -2; // 0xfffffffe
   }
 
   public static interface NfcAdapter.ControllerAlwaysOnListener {
@@ -14962,6 +14970,7 @@
     field public static final String SERVICE_ID_POST_CALL = "org.3gpp.urn:urn-7:3gpp-service.ims.icsi.gsma.callunanswered";
     field public static final String SERVICE_ID_SHARED_MAP = "org.3gpp.urn:urn-7:3gpp-service.ims.icsi.gsma.sharedmap";
     field public static final String SERVICE_ID_SHARED_SKETCH = "org.3gpp.urn:urn-7:3gpp-service.ims.icsi.gsma.sharedsketch";
+    field public static final String SERVICE_ID_SLM = "org.openmobilealliance:StandaloneMsg";
     field public static final String TUPLE_BASIC_STATUS_CLOSED = "closed";
     field public static final String TUPLE_BASIC_STATUS_OPEN = "open";
   }
diff --git a/core/java/android/app/BroadcastOptions.java b/core/java/android/app/BroadcastOptions.java
index 8b7b7eb..16c5b08 100644
--- a/core/java/android/app/BroadcastOptions.java
+++ b/core/java/android/app/BroadcastOptions.java
@@ -66,6 +66,7 @@
     private @DeliveryGroupPolicy int mDeliveryGroupPolicy;
     private @Nullable String mDeliveryGroupMatchingKey;
     private @Nullable IntentFilter mDeliveryGroupMatchingFilter;
+    private boolean mIsDeferUntilActive = false;
 
     /**
      * Change ID which is invalid.
@@ -688,6 +689,41 @@
     }
 
     /**
+     * Sets whether the broadcast should not run until the process is in an active process state
+     * (ie, a process exists for the app and the app is not in a cached process state).
+     *
+     * Whether an app's process state is considered active is independent of its standby bucket.
+     *
+     * A broadcast that is deferred until the process is active will not execute until the process
+     * is brought to an active state by some other action, like a job, alarm, or service binding. As
+     * a result, the broadcast may be delayed indefinitely. This deferral only applies to runtime
+     * registered receivers of a broadcast. Any manifest receivers will run immediately, similar to
+     * how a manifest receiver would start a new process in order to run a broadcast receiver.
+     *
+     * Ordered broadcasts, alarm broadcasts, interactive broadcasts, and manifest broadcasts are
+     * never deferred.
+     *
+     * Unordered broadcasts and unordered broadcasts with completion callbacks may be
+     * deferred. Completion callbacks for broadcasts deferred until active are
+     * best-effort. Completion callbacks will run when all eligible processes have finished
+     * executing the broadcast. Processes in inactive process states that defer the broadcast are
+     * not considered eligible and may not execute the broadcast prior to the completion callback.
+     *
+     * @hide
+     */
+    @SystemApi
+    public @NonNull BroadcastOptions setDeferUntilActive(boolean shouldDefer) {
+        mIsDeferUntilActive = shouldDefer;
+        return this;
+    }
+
+    /** @hide */
+    @SystemApi
+    public boolean isDeferUntilActive() {
+        return mIsDeferUntilActive;
+    }
+
+    /**
      * Returns the created options as a Bundle, which can be passed to
      * {@link android.content.Context#sendBroadcast(android.content.Intent)
      * Context.sendBroadcast(Intent)} and related methods.
diff --git a/core/java/android/hardware/soundtrigger/OWNERS b/core/java/android/hardware/soundtrigger/OWNERS
index e5d0370..01b2cb9 100644
--- a/core/java/android/hardware/soundtrigger/OWNERS
+++ b/core/java/android/hardware/soundtrigger/OWNERS
@@ -1,2 +1,2 @@
-ytai@google.com
+atneya@google.com
 elaurent@google.com
diff --git a/core/java/android/nfc/INfcAdapter.aidl b/core/java/android/nfc/INfcAdapter.aidl
index de107a2..8a30ef4 100644
--- a/core/java/android/nfc/INfcAdapter.aidl
+++ b/core/java/android/nfc/INfcAdapter.aidl
@@ -80,4 +80,10 @@
     boolean isControllerAlwaysOnSupported();
     void registerControllerAlwaysOnListener(in INfcControllerAlwaysOnListener listener);
     void unregisterControllerAlwaysOnListener(in INfcControllerAlwaysOnListener listener);
+    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)")
+    boolean isTagIntentAppPreferenceSupported();
+    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)")
+    Map getTagIntentAppPreferenceForUser(int userId);
+    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)")
+    int setTagIntentAppPreferenceForUser(int userId, String pkg, boolean allow);
 }
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
index 0c7f529..a980158 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -17,12 +17,14 @@
 package android.nfc;
 
 import android.annotation.CallbackExecutor;
+import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
 import android.annotation.SystemApi;
+import android.annotation.UserIdInt;
 import android.app.Activity;
 import android.app.ActivityThread;
 import android.app.OnActivityPausedListener;
@@ -46,9 +48,14 @@
 import android.util.Log;
 
 import java.io.IOException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
+import java.util.Objects;
 import java.util.concurrent.Executor;
 
 /**
@@ -371,6 +378,45 @@
     public static final String ACTION_REQUIRE_UNLOCK_FOR_NFC =
             "android.nfc.action.REQUIRE_UNLOCK_FOR_NFC";
 
+    /**
+     * The requested app is correctly added to the Tag intent app preference.
+     *
+     * @see #setTagIntentAppPreferenceForUser(int userId, String pkg, boolean allow)
+     * @hide
+     */
+    @SystemApi
+    public static final int TAG_INTENT_APP_PREF_RESULT_SUCCESS = 0;
+
+    /**
+     * The requested app is not installed on the device.
+     *
+     * @see #setTagIntentAppPreferenceForUser(int userId, String pkg, boolean allow)
+     * @hide
+     */
+    @SystemApi
+    public static final int TAG_INTENT_APP_PREF_RESULT_PACKAGE_NOT_FOUND = -1;
+
+    /**
+     * The NfcService is not available.
+     *
+     * @see #setTagIntentAppPreferenceForUser(int userId, String pkg, boolean allow)
+     * @hide
+     */
+    @SystemApi
+    public static final int TAG_INTENT_APP_PREF_RESULT_UNAVAILABLE = -2;
+
+    /**
+     * Possible response codes from {@link #setTagIntentAppPreferenceForUser}.
+     *
+     * @hide
+     */
+    @IntDef(prefix = { "TAG_INTENT_APP_PREF_RESULT" }, value = {
+            TAG_INTENT_APP_PREF_RESULT_SUCCESS,
+            TAG_INTENT_APP_PREF_RESULT_PACKAGE_NOT_FOUND,
+            TAG_INTENT_APP_PREF_RESULT_UNAVAILABLE})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface TagIntentAppPreferenceResult {}
+
     // Guarded by NfcAdapter.class
     static boolean sIsInitialized = false;
     static boolean sHasNfcFeature;
@@ -2408,4 +2454,133 @@
             @NonNull ControllerAlwaysOnListener listener) {
         mControllerAlwaysOnListener.unregister(listener);
     }
+
+
+    /**
+     * Sets whether we dispatch NFC Tag intents to the package.
+     *
+     * <p>{@link #ACTION_NDEF_DISCOVERED}, {@link #ACTION_TECH_DISCOVERED} or
+     * {@link #ACTION_TAG_DISCOVERED} will not be dispatched to an Activity if its package is
+     * disallowed.
+     * <p>An app is added to the preference list with the allowed flag set to {@code true}
+     * when a Tag intent is dispatched to the package for the first time. This API is called
+     * by settings to note that the user wants to change this default preference.
+     *
+     * @param userId the user to whom this package name will belong to
+     * @param pkg the full name (i.e. com.google.android.tag) of the package that will be added to
+     * the preference list
+     * @param allow {@code true} to allow dispatching Tag intents to the package's activity,
+     * {@code false} otherwise
+     * @return the {@link #TagIntentAppPreferenceResult} value
+     * @throws UnsupportedOperationException if {@link isTagIntentAppPreferenceSupported} returns
+     * {@code false}
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
+    @TagIntentAppPreferenceResult
+    public int setTagIntentAppPreferenceForUser(@UserIdInt int userId,
+                @NonNull String pkg, boolean allow) {
+        Objects.requireNonNull(pkg, "pkg cannot be null");
+        if (!isTagIntentAppPreferenceSupported()) {
+            Log.e(TAG, "TagIntentAppPreference is not supported");
+            throw new UnsupportedOperationException();
+        }
+        try {
+            return sService.setTagIntentAppPreferenceForUser(userId, pkg, allow);
+        } catch (RemoteException e) {
+            attemptDeadServiceRecovery(e);
+            // Try one more time
+            if (sService == null) {
+                Log.e(TAG, "Failed to recover NFC Service.");
+            }
+            try {
+                return sService.setTagIntentAppPreferenceForUser(userId, pkg, allow);
+            } catch (RemoteException ee) {
+                Log.e(TAG, "Failed to recover NFC Service.");
+            }
+            return TAG_INTENT_APP_PREF_RESULT_UNAVAILABLE;
+        }
+    }
+
+
+    /**
+     * Get the Tag dispatch preference list of the UserId.
+     *
+     * <p>This returns a mapping of package names for this user id to whether we dispatch Tag
+     * intents to the package. {@link #ACTION_NDEF_DISCOVERED}, {@link #ACTION_TECH_DISCOVERED} or
+    *  {@link #ACTION_TAG_DISCOVERED} will not be dispatched to an Activity if its package is
+    *  disallowed.
+     *
+     * @param userId the user to whom this preference list will belong to
+     * @return a map of the UserId which indicates the mapping from package name to
+     * boolean(allow status), otherwise return an empty map
+     * @throws UnsupportedOperationException if {@link isTagIntentAppPreferenceSupported} returns
+     * {@code false}
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
+    @NonNull
+    public Map<String, Boolean> getTagIntentAppPreferenceForUser(@UserIdInt int userId) {
+        if (!isTagIntentAppPreferenceSupported()) {
+            Log.e(TAG, "TagIntentAppPreference is not supported");
+            throw new UnsupportedOperationException();
+        }
+        try {
+            Map<String, Boolean> result = (Map<String, Boolean>) sService
+                     .getTagIntentAppPreferenceForUser(userId);
+            return result;
+        } catch (RemoteException e) {
+            attemptDeadServiceRecovery(e);
+            // Try one more time
+            if (sService == null) {
+                Log.e(TAG, "Failed to recover NFC Service.");
+                return Collections.emptyMap();
+            }
+            try {
+                Map<String, Boolean> result = (Map<String, Boolean>) sService
+                        .getTagIntentAppPreferenceForUser(userId);
+                return result;
+            } catch (RemoteException ee) {
+                Log.e(TAG, "Failed to recover NFC Service.");
+            }
+            return Collections.emptyMap();
+        }
+    }
+
+    /**
+     * Checks if the device supports Tag application preference.
+     *
+     * @return {@code true} if the device supports Tag application preference, {@code false}
+     * otherwise
+     * @throws UnsupportedOperationException if FEATURE_NFC is unavailable
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
+    public boolean isTagIntentAppPreferenceSupported() {
+        if (!sHasNfcFeature) {
+            throw new UnsupportedOperationException();
+        }
+        try {
+            return sService.isTagIntentAppPreferenceSupported();
+        } catch (RemoteException e) {
+            attemptDeadServiceRecovery(e);
+            // Try one more time
+            if (sService == null) {
+                Log.e(TAG, "Failed to recover NFC Service.");
+                return false;
+            }
+            try {
+                return sService.isTagIntentAppPreferenceSupported();
+            } catch (RemoteException ee) {
+                Log.e(TAG, "Failed to recover NFC Service.");
+            }
+            return false;
+        }
+    }
 }
diff --git a/core/java/android/nfc/OWNERS b/core/java/android/nfc/OWNERS
index 6aaf039..9a2e446 100644
--- a/core/java/android/nfc/OWNERS
+++ b/core/java/android/nfc/OWNERS
@@ -1,4 +1,5 @@
 # Bug component: 48448
 
-zachoverflow@google.com
+sattiraju@google.com
+henrichataing@google.com
 alisher@google.com
diff --git a/core/java/android/nfc/cardemulation/OWNERS b/core/java/android/nfc/cardemulation/OWNERS
index 6aaf039..9a2e446 100644
--- a/core/java/android/nfc/cardemulation/OWNERS
+++ b/core/java/android/nfc/cardemulation/OWNERS
@@ -1,4 +1,5 @@
 # Bug component: 48448
 
-zachoverflow@google.com
+sattiraju@google.com
+henrichataing@google.com
 alisher@google.com
diff --git a/core/java/android/nfc/dta/OWNERS b/core/java/android/nfc/dta/OWNERS
index 6aaf039..9a2e446 100644
--- a/core/java/android/nfc/dta/OWNERS
+++ b/core/java/android/nfc/dta/OWNERS
@@ -1,4 +1,5 @@
 # Bug component: 48448
 
-zachoverflow@google.com
+sattiraju@google.com
+henrichataing@google.com
 alisher@google.com
diff --git a/core/java/android/nfc/tech/OWNERS b/core/java/android/nfc/tech/OWNERS
index 6aaf039..9a2e446 100644
--- a/core/java/android/nfc/tech/OWNERS
+++ b/core/java/android/nfc/tech/OWNERS
@@ -1,4 +1,5 @@
 # Bug component: 48448
 
-zachoverflow@google.com
+sattiraju@google.com
+henrichataing@google.com
 alisher@google.com
diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java
index c731a80..2d16dc3 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -1006,12 +1006,15 @@
         // been replaced with an implementation that will suspendAll and
         // send VM_START.
         System.out.println("Waiting for debugger first packet");
+
+        mWaiting = true;
         while (!isDebuggerConnected()) {
             try {
                 Thread.sleep(100);
             } catch (InterruptedException ie) {
             }
         }
+        mWaiting = false;
 
         System.out.println("Debug.suspendAllAndSentVmStart");
         VMDebug.suspendAllAndSendVmStart();
diff --git a/core/java/com/android/internal/expresslog/Counter.java b/core/java/com/android/internal/expresslog/Counter.java
index 7571073..cc37c69 100644
--- a/core/java/com/android/internal/expresslog/Counter.java
+++ b/core/java/com/android/internal/expresslog/Counter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2023 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.
@@ -39,9 +39,7 @@
      * @hide
      */
     public static void logIncrement(@NonNull String metricId, long amount) {
-        final long metricIdHash = hashString(metricId);
+        final long metricIdHash = Utils.hashString(metricId);
         FrameworkStatsLog.write(FrameworkStatsLog.EXPRESS_EVENT_REPORTED, metricIdHash, amount);
     }
-
-    private static native long hashString(String stringToHash);
 }
diff --git a/core/java/com/android/internal/expresslog/Utils.java b/core/java/com/android/internal/expresslog/Utils.java
new file mode 100644
index 0000000..d82192f
--- /dev/null
+++ b/core/java/com/android/internal/expresslog/Utils.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2023 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.internal.expresslog;
+
+final class Utils {
+    static native long hashString(String stringToHash);
+}
diff --git a/core/java/com/android/internal/widget/ConversationLayout.java b/core/java/com/android/internal/widget/ConversationLayout.java
index 5f8acff..3fb2318 100644
--- a/core/java/com/android/internal/widget/ConversationLayout.java
+++ b/core/java/com/android/internal/widget/ConversationLayout.java
@@ -927,7 +927,8 @@
                 message = messages.get(i - histSize);
             }
             boolean isNewGroup = currentGroup == null;
-            Person sender = message.getMessage().getSenderPerson();
+            Person sender =
+                    message.getMessage() == null ? null : message.getMessage().getSenderPerson();
             CharSequence key = getKey(sender);
             isNewGroup |= !TextUtils.equals(key, currentSenderKey);
             if (isNewGroup) {
@@ -1190,7 +1191,8 @@
             return null;
         }
         final MessagingMessage messagingMessage = mMessages.get(mMessages.size() - 1);
-        final CharSequence text = messagingMessage.getMessage().getText();
+        final CharSequence text = messagingMessage.getMessage() == null ? null
+                : messagingMessage.getMessage().getText();
         if (text == null && messagingMessage instanceof MessagingImageMessage) {
             final String unformatted =
                     getResources().getString(R.string.conversation_single_line_image_placeholder);
diff --git a/core/java/com/android/internal/widget/MessagingGroup.java b/core/java/com/android/internal/widget/MessagingGroup.java
index 146cb3f..30e4099 100644
--- a/core/java/com/android/internal/widget/MessagingGroup.java
+++ b/core/java/com/android/internal/widget/MessagingGroup.java
@@ -492,7 +492,9 @@
             int color = mSendingSpinnerContainer.getVisibility() == View.VISIBLE
                     ? mSendingTextColor : mTextColor;
             for (MessagingMessage message : mMessages) {
-                message.setColor(message.getMessage().isRemoteInputHistory() ? color : mTextColor);
+                final boolean isRemoteInputHistory =
+                        message.getMessage() != null && message.getMessage().isRemoteInputHistory();
+                message.setColor(isRemoteInputHistory ? color : mTextColor);
             }
         }
     }
diff --git a/core/java/com/android/internal/widget/MessagingLayout.java b/core/java/com/android/internal/widget/MessagingLayout.java
index 9ac6ef7..a270b28 100644
--- a/core/java/com/android/internal/widget/MessagingLayout.java
+++ b/core/java/com/android/internal/widget/MessagingLayout.java
@@ -470,7 +470,8 @@
                 message = messages.get(i - histSize);
             }
             boolean isNewGroup = currentGroup == null;
-            Person sender = message.getMessage().getSenderPerson();
+            Person sender =
+                    message.getMessage() == null ? null : message.getMessage().getSenderPerson();
             CharSequence key = sender == null ? null
                     : sender.getKey() == null ? sender.getName() : sender.getKey();
             isNewGroup |= !TextUtils.equals(key, currentSenderKey);
diff --git a/core/java/com/android/internal/widget/MessagingMessage.java b/core/java/com/android/internal/widget/MessagingMessage.java
index 2cc0d23..5ecd3b8 100644
--- a/core/java/com/android/internal/widget/MessagingMessage.java
+++ b/core/java/com/android/internal/widget/MessagingMessage.java
@@ -68,6 +68,10 @@
 
     default boolean sameAs(Notification.MessagingStyle.Message message) {
         Notification.MessagingStyle.Message ownMessage = getMessage();
+        // We have to make sure both messages are not null to go further comparison
+        if (message == null || ownMessage == null) {
+            return message == ownMessage;
+        }
         if (!Objects.equals(message.getText(), ownMessage.getText())) {
             return false;
         }
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index 681f194..f7d1014 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -215,7 +215,7 @@
                 "android_content_res_Configuration.cpp",
                 "android_security_Scrypt.cpp",
                 "com_android_internal_content_om_OverlayConfig.cpp",
-                "com_android_internal_expresslog_Counter.cpp",
+                "com_android_internal_expresslog_Utils.cpp",
                 "com_android_internal_net_NetworkUtilsInternal.cpp",
                 "com_android_internal_os_ClassLoaderFactory.cpp",
                 "com_android_internal_os_FuseAppLoop.cpp",
@@ -260,7 +260,6 @@
                 "av-types-aidl-cpp",
                 "android.hardware.camera.device@3.2",
                 "libandroid_net",
-                "libandroidicu",
                 "libbattery",
                 "libnetdutils",
                 "libmemtrack",
@@ -280,6 +279,7 @@
                 "libpermission",
                 "libsensor",
                 "libinput",
+                "libicu",
                 "libcamera_client",
                 "libcamera_metadata",
                 "libprocinfo",
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 7dd46a6..9c7f0a8 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -196,7 +196,7 @@
 extern int register_com_android_internal_content_F2fsUtils(JNIEnv* env);
 extern int register_com_android_internal_content_NativeLibraryHelper(JNIEnv *env);
 extern int register_com_android_internal_content_om_OverlayConfig(JNIEnv *env);
-extern int register_com_android_internal_expresslog_Counter(JNIEnv* env);
+extern int register_com_android_internal_expresslog_Utils(JNIEnv* env);
 extern int register_com_android_internal_net_NetworkUtilsInternal(JNIEnv* env);
 extern int register_com_android_internal_os_ClassLoaderFactory(JNIEnv* env);
 extern int register_com_android_internal_os_FuseAppLoop(JNIEnv* env);
@@ -1591,7 +1591,7 @@
         REG_JNI(register_android_os_SharedMemory),
         REG_JNI(register_android_os_incremental_IncrementalManager),
         REG_JNI(register_com_android_internal_content_om_OverlayConfig),
-        REG_JNI(register_com_android_internal_expresslog_Counter),
+        REG_JNI(register_com_android_internal_expresslog_Utils),
         REG_JNI(register_com_android_internal_net_NetworkUtilsInternal),
         REG_JNI(register_com_android_internal_os_ClassLoaderFactory),
         REG_JNI(register_com_android_internal_os_LongArrayMultiStateCounter),
diff --git a/core/jni/OWNERS b/core/jni/OWNERS
index 53594e1..c99a27a 100644
--- a/core/jni/OWNERS
+++ b/core/jni/OWNERS
@@ -70,6 +70,7 @@
 per-file android_graphics_* = file:/graphics/java/android/graphics/OWNERS
 per-file *HardwareBuffer* = file:/graphics/java/android/graphics/OWNERS
 per-file android_hardware_SyncFence.cpp = file:/graphics/java/android/graphics/OWNERS
+per-file android_hardware_OverlayProperties.cpp = file:/graphics/java/android/graphics/OWNERS
 per-file android_os_GraphicsEnvironment.cpp = file:platform/frameworks/native:/opengl/OWNERS
 
 ### Text ###
diff --git a/core/jni/com_android_internal_expresslog_Counter.cpp b/core/jni/com_android_internal_expresslog_Utils.cpp
similarity index 83%
rename from core/jni/com_android_internal_expresslog_Counter.cpp
rename to core/jni/com_android_internal_expresslog_Utils.cpp
index d4a8c23..d33a7bd 100644
--- a/core/jni/com_android_internal_expresslog_Counter.cpp
+++ b/core/jni/com_android_internal_expresslog_Utils.cpp
@@ -26,7 +26,7 @@
 static jclass g_stringClass = nullptr;
 
 /**
- * Class:     com_android_internal_expresslog_Counter
+ * Class:     com_android_internal_expresslog_Utils
  * Method:    hashString
  * Signature: (Ljava/lang/String;)J
  */
@@ -43,15 +43,15 @@
         {"hashString", "(Ljava/lang/String;)J", (void*)hashString},
 };
 
-static const char* const kCounterPathName = "com/android/internal/expresslog/Counter";
+static const char* const kUtilsPathName = "com/android/internal/expresslog/Utils";
 
 namespace android {
 
-int register_com_android_internal_expresslog_Counter(JNIEnv* env) {
+int register_com_android_internal_expresslog_Utils(JNIEnv* env) {
     jclass stringClass = FindClassOrDie(env, "java/lang/String");
     g_stringClass = MakeGlobalRefOrDie(env, stringClass);
 
-    return RegisterMethodsOrDie(env, kCounterPathName, g_methods, NELEM(g_methods));
+    return RegisterMethodsOrDie(env, kUtilsPathName, g_methods, NELEM(g_methods));
 }
 
 } // namespace android
diff --git a/libs/hwui/jni/Paint.cpp b/libs/hwui/jni/Paint.cpp
index f768632..293e280 100644
--- a/libs/hwui/jni/Paint.cpp
+++ b/libs/hwui/jni/Paint.cpp
@@ -35,7 +35,6 @@
 #include "SkShader.h"
 #include "SkBlendMode.h"
 #include "unicode/uloc.h"
-#include "unicode/ushape.h"
 #include "utils/Blur.h"
 
 #include <hwui/BlurDrawLooper.h>
diff --git a/media/aidl/android/media/soundtrigger_middleware/OWNERS b/media/aidl/android/media/soundtrigger_middleware/OWNERS
index e5d0370..01b2cb9 100644
--- a/media/aidl/android/media/soundtrigger_middleware/OWNERS
+++ b/media/aidl/android/media/soundtrigger_middleware/OWNERS
@@ -1,2 +1,2 @@
-ytai@google.com
+atneya@google.com
 elaurent@google.com
diff --git a/media/java/android/media/ImageUtils.java b/media/java/android/media/ImageUtils.java
index 4957300..993155f 100644
--- a/media/java/android/media/ImageUtils.java
+++ b/media/java/android/media/ImageUtils.java
@@ -84,6 +84,7 @@
     public static int getNumPlanesForHardwareBufferFormat(int hardwareBufferFormat) {
         switch(hardwareBufferFormat) {
             case HardwareBuffer.YCBCR_420_888:
+            case HardwareBuffer.YCBCR_P010:
                 return 3;
             case HardwareBuffer.RGBA_8888:
             case HardwareBuffer.RGBX_8888:
diff --git a/media/java/android/media/soundtrigger/OWNERS b/media/java/android/media/soundtrigger/OWNERS
index e5d0370..01b2cb9 100644
--- a/media/java/android/media/soundtrigger/OWNERS
+++ b/media/java/android/media/soundtrigger/OWNERS
@@ -1,2 +1,2 @@
-ytai@google.com
+atneya@google.com
 elaurent@google.com
diff --git a/media/java/android/media/tv/ITvInputManager.aidl b/media/java/android/media/tv/ITvInputManager.aidl
index 2a33ee6..1d2198e 100644
--- a/media/java/android/media/tv/ITvInputManager.aidl
+++ b/media/java/android/media/tv/ITvInputManager.aidl
@@ -16,6 +16,7 @@
 
 package android.media.tv;
 
+import android.content.AttributionSource;
 import android.content.ComponentName;
 import android.content.Intent;
 import android.graphics.Rect;
@@ -62,7 +63,7 @@
     void addBlockedRating(in String rating, int userId);
     void removeBlockedRating(in String rating, int userId);
 
-    void createSession(in ITvInputClient client, in String inputId, boolean isRecordingSession,
+    void createSession(in ITvInputClient client, in String inputId, in AttributionSource tvAppAttributionSource, boolean isRecordingSession,
             int seq, int userId);
     void releaseSession(in IBinder sessionToken, int userId);
     int getClientPid(in String sessionId);
diff --git a/media/java/android/media/tv/ITvInputService.aidl b/media/java/android/media/tv/ITvInputService.aidl
index 64a23a2..be73c0c 100755
--- a/media/java/android/media/tv/ITvInputService.aidl
+++ b/media/java/android/media/tv/ITvInputService.aidl
@@ -16,6 +16,7 @@
 
 package android.media.tv;
 
+import android.content.AttributionSource;
 import android.hardware.hdmi.HdmiDeviceInfo;
 import android.media.tv.ITvInputServiceCallback;
 import android.media.tv.ITvInputSessionCallback;
@@ -30,7 +31,7 @@
     oneway void registerCallback(in ITvInputServiceCallback callback);
     oneway void unregisterCallback(in ITvInputServiceCallback callback);
     oneway void createSession(in InputChannel channel, in ITvInputSessionCallback callback,
-            in String inputId, in String sessionId);
+            in String inputId, in String sessionId, in AttributionSource tvAppAttributionSource);
     oneway void createRecordingSession(in ITvInputSessionCallback callback, in String inputId,
             in String sessionId);
     List<String> getAvailableExtensionInterfaceNames();
diff --git a/media/java/android/media/tv/ITvInputSessionWrapper.java b/media/java/android/media/tv/ITvInputSessionWrapper.java
index 8911f6c..6c10990 100644
--- a/media/java/android/media/tv/ITvInputSessionWrapper.java
+++ b/media/java/android/media/tv/ITvInputSessionWrapper.java
@@ -30,7 +30,6 @@
 import android.view.InputEvent;
 import android.view.InputEventReceiver;
 import android.view.Surface;
-
 import com.android.internal.os.HandlerCaller;
 import com.android.internal.os.SomeArgs;
 
diff --git a/media/java/android/media/tv/TvInputManager.java b/media/java/android/media/tv/TvInputManager.java
index 149c2f4..819cd0c 100644
--- a/media/java/android/media/tv/TvInputManager.java
+++ b/media/java/android/media/tv/TvInputManager.java
@@ -25,6 +25,7 @@
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
 import android.annotation.TestApi;
+import android.content.AttributionSource;
 import android.content.Context;
 import android.content.Intent;
 import android.graphics.Rect;
@@ -53,9 +54,7 @@
 import android.view.KeyEvent;
 import android.view.Surface;
 import android.view.View;
-
 import com.android.internal.util.Preconditions;
-
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
@@ -1835,13 +1834,15 @@
      * of the given TV input.
      *
      * @param inputId The ID of the TV input.
+     * @param tvAppAttributionSource The Attribution Source of the TV App.
      * @param callback A callback used to receive the created session.
      * @param handler A {@link Handler} that the session creation will be delivered to.
      * @hide
      */
-    public void createSession(@NonNull String inputId, @NonNull final SessionCallback callback,
-            @NonNull Handler handler) {
-        createSessionInternal(inputId, false, callback, handler);
+    public void createSession(@NonNull String inputId,
+            @NonNull AttributionSource tvAppAttributionSource,
+            @NonNull final SessionCallback callback, @NonNull Handler handler) {
+        createSessionInternal(inputId, tvAppAttributionSource, false, callback, handler);
     }
 
     /**
@@ -1866,7 +1867,7 @@
      * @param useCase the use case type of the client.
      *        {@see TvInputService#PriorityHintUseCaseType}.
      * @param sessionId the unique id of the session owned by the client.
-     *        {@see TvInputService#onCreateSession(String, String)}.
+     *        {@see TvInputService#onCreateSession(String, String, AttributionSource)}.
      *
      * @return the use case priority value for the given use case type and the client's foreground
      *         or background status.
@@ -1917,11 +1918,11 @@
      */
     public void createRecordingSession(@NonNull String inputId,
             @NonNull final SessionCallback callback, @NonNull Handler handler) {
-        createSessionInternal(inputId, true, callback, handler);
+        createSessionInternal(inputId, null, true, callback, handler);
     }
 
-    private void createSessionInternal(String inputId, boolean isRecordingSession,
-            SessionCallback callback, Handler handler) {
+    private void createSessionInternal(String inputId, AttributionSource tvAppAttributionSource,
+            boolean isRecordingSession, SessionCallback callback, Handler handler) {
         Preconditions.checkNotNull(inputId);
         Preconditions.checkNotNull(callback);
         Preconditions.checkNotNull(handler);
@@ -1930,7 +1931,8 @@
             int seq = mNextSeq++;
             mSessionCallbackRecordMap.put(seq, record);
             try {
-                mService.createSession(mClient, inputId, isRecordingSession, seq, mUserId);
+                mService.createSession(
+                        mClient, inputId, tvAppAttributionSource, isRecordingSession, seq, mUserId);
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
@@ -2101,8 +2103,8 @@
      * @param deviceId The device ID to acquire Hardware for.
      * @param info The TV input which will use the acquired Hardware.
      * @param tvInputSessionId a String returned to TIS when the session was created.
-     *        {@see TvInputService#onCreateSession(String, String)}. If null, the client will be
-     *        treated as a background app.
+     *        {@see TvInputService#onCreateSession(String, String, AttributionSource)}. If null, the
+     *        client will be treated as a background app.
      * @param priorityHint The use case of the client. {@see TvInputService#PriorityHintUseCaseType}
      * @param executor the executor on which the listener would be invoked.
      * @param callback A callback to receive updates on Hardware.
diff --git a/media/java/android/media/tv/TvInputService.java b/media/java/android/media/tv/TvInputService.java
index 70acf25..f3e5d14 100755
--- a/media/java/android/media/tv/TvInputService.java
+++ b/media/java/android/media/tv/TvInputService.java
@@ -26,6 +26,7 @@
 import android.app.ActivityManager;
 import android.app.Service;
 import android.compat.annotation.UnsupportedAppUsage;
+import android.content.AttributionSource;
 import android.content.Context;
 import android.content.Intent;
 import android.graphics.PixelFormat;
@@ -57,10 +58,8 @@
 import android.view.WindowManager;
 import android.view.accessibility.CaptioningManager;
 import android.widget.FrameLayout;
-
 import com.android.internal.os.SomeArgs;
 import com.android.internal.util.Preconditions;
-
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
@@ -171,7 +170,7 @@
 
             @Override
             public void createSession(InputChannel channel, ITvInputSessionCallback cb,
-                    String inputId, String sessionId) {
+                    String inputId, String sessionId, AttributionSource tvAppAttributionSource) {
                 if (channel == null) {
                     Log.w(TAG, "Creating session without input channel");
                 }
@@ -183,6 +182,7 @@
                 args.arg2 = cb;
                 args.arg3 = inputId;
                 args.arg4 = sessionId;
+                args.arg5 = tvAppAttributionSource;
                 mServiceHandler.obtainMessage(ServiceHandler.DO_CREATE_SESSION,
                         args).sendToTarget();
             }
@@ -370,6 +370,24 @@
     }
 
     /**
+     * Returns a concrete implementation of {@link Session}.
+     *
+     * <p>For any apps that needs sessionId to request tuner resources from TunerResourceManager and
+     * needs to specify custom AttributionSource to AudioTrack, it needs to override this method to
+     * get the sessionId and AttrubutionSource passed. When no overriding, this method calls {@link
+     * #onCreateSession(String, String)} defaultly.
+     *
+     * @param inputId The ID of the TV input associated with the session.
+     * @param sessionId the unique sessionId created by TIF when session is created.
+     * @param tvAppAttributionSource The Attribution Source of the TV App.
+     */
+    @Nullable
+    public Session onCreateSession(@NonNull String inputId, @NonNull String sessionId,
+            @NonNull AttributionSource tvAppAttributionSource) {
+        return onCreateSession(inputId, sessionId);
+    }
+
+    /**
      * Returns a concrete implementation of {@link RecordingSession}.
      *
      * <p>For any apps that needs sessionId to request tuner resources from TunerResourceManager,
@@ -1107,7 +1125,7 @@
         public abstract void onSetStreamVolume(@FloatRange(from = 0.0, to = 1.0) float volume);
 
         /**
-         * called when broadcast info is requested.
+         * Called when broadcast info is requested.
          *
          * @param request broadcast info request
          */
@@ -1115,7 +1133,7 @@
         }
 
         /**
-         * called when broadcast info is removed.
+         * Called when broadcast info is removed.
          */
         public void onRemoveBroadcastInfo(int requestId) {
         }
@@ -2444,8 +2462,10 @@
                     ITvInputSessionCallback cb = (ITvInputSessionCallback) args.arg2;
                     String inputId = (String) args.arg3;
                     String sessionId = (String) args.arg4;
+                    AttributionSource tvAppAttributionSource = (AttributionSource) args.arg5;
                     args.recycle();
-                    Session sessionImpl = onCreateSession(inputId, sessionId);
+                    Session sessionImpl =
+                            onCreateSession(inputId, sessionId, tvAppAttributionSource);
                     if (sessionImpl == null) {
                         try {
                             // Failed to create a session.
@@ -2481,7 +2501,7 @@
                         proxySession.mServiceHandler = mServiceHandler;
                         TvInputManager manager = (TvInputManager) getSystemService(
                                 Context.TV_INPUT_SERVICE);
-                        manager.createSession(hardwareInputId,
+                        manager.createSession(hardwareInputId, tvAppAttributionSource,
                                 proxySession.mHardwareSessionCallback, mServiceHandler);
                     } else {
                         SomeArgs someArgs = SomeArgs.obtain();
diff --git a/media/java/android/media/tv/TvView.java b/media/java/android/media/tv/TvView.java
index ff3d06c..de9acc3 100644
--- a/media/java/android/media/tv/TvView.java
+++ b/media/java/android/media/tv/TvView.java
@@ -21,6 +21,7 @@
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
 import android.annotation.SystemApi;
+import android.content.AttributionSource;
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.content.res.Resources;
@@ -51,7 +52,6 @@
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewRootImpl;
-
 import java.lang.ref.WeakReference;
 import java.util.ArrayDeque;
 import java.util.List;
@@ -111,6 +111,7 @@
     private int mSurfaceViewTop;
     private int mSurfaceViewBottom;
     private TimeShiftPositionCallback mTimeShiftPositionCallback;
+    private AttributionSource mTvAppAttributionSource;
 
     private final SurfaceHolder.Callback mSurfaceHolderCallback = new SurfaceHolder.Callback() {
         @Override
@@ -185,6 +186,7 @@
         mDefStyleAttr = defStyleAttr;
         resetSurfaceView();
         mTvInputManager = (TvInputManager) getContext().getSystemService(Context.TV_INPUT_SERVICE);
+        mTvAppAttributionSource = getContext().getAttributionSource();
     }
 
     /**
@@ -304,6 +306,22 @@
     }
 
     /**
+     * Override default attribution source of TV App.
+     *
+     * <p>An attribution source of TV App is used to attribute work to TV Input Service.
+     * The default attribution source is created by {@link Context#getAttributionSource()}.
+     * Call this method before calling {@link #tune(String, Uri, Bundle)} or {@link
+     * #timeShiftPlay(String, Uri)} to override the default attribution source.
+     *
+     * @param tvAppAttributionSource The attribution source of the TV App.
+     */
+    public void overrideTvAppAttributionSource(@NonNull AttributionSource tvAppAttributionSource) {
+        if (tvAppAttributionSource != null) {
+            mTvAppAttributionSource = tvAppAttributionSource;
+        }
+    }
+
+    /**
      * Tunes to a given channel.
      *
      * @param inputId The ID of the TV input for the given channel.
@@ -355,7 +373,8 @@
             // is obsolete and should ignore it.
             mSessionCallback = new MySessionCallback(inputId, channelUri, params);
             if (mTvInputManager != null) {
-                mTvInputManager.createSession(inputId, mSessionCallback, mHandler);
+                mTvInputManager.createSession(
+                        inputId, mTvAppAttributionSource, mSessionCallback, mHandler);
             }
         }
     }
@@ -526,7 +545,8 @@
             resetInternal();
             mSessionCallback = new MySessionCallback(inputId, recordedProgramUri);
             if (mTvInputManager != null) {
-                mTvInputManager.createSession(inputId, mSessionCallback, mHandler);
+                mTvInputManager.createSession(
+                        inputId, mTvAppAttributionSource, mSessionCallback, mHandler);
             }
         }
     }
diff --git a/media/jni/android_media_MediaDrm.cpp b/media/jni/android_media_MediaDrm.cpp
index 681d76a..b70818d 100644
--- a/media/jni/android_media_MediaDrm.cpp
+++ b/media/jni/android_media_MediaDrm.cpp
@@ -1021,9 +1021,10 @@
 
 static jbyteArray android_media_MediaDrm_getSupportedCryptoSchemesNative(JNIEnv *env) {
     sp<IDrm> drm = android::DrmUtils::MakeDrm();
+    if (drm == NULL) return env->NewByteArray(0);
+
     std::vector<uint8_t> bv;
     drm->getSupportedSchemes(bv);
-
     jbyteArray jUuidBytes = env->NewByteArray(bv.size());
     env->SetByteArrayRegion(jUuidBytes, 0, bv.size(), reinterpret_cast<const jbyte *>(bv.data()));
     return jUuidBytes;
diff --git a/native/android/libandroid.map.txt b/native/android/libandroid.map.txt
index 4aa5bbf..a386923 100644
--- a/native/android/libandroid.map.txt
+++ b/native/android/libandroid.map.txt
@@ -1,9 +1,9 @@
 LIBANDROID {
   global:
-    AActivityManager_addUidImportanceListener; # apex # introduced=31
-    AActivityManager_removeUidImportanceListener; # apex # introduced=31
-    AActivityManager_isUidActive; # apex # introduced=31
-    AActivityManager_getUidImportance; # apex # introduced=31
+    AActivityManager_addUidImportanceListener; # systemapi # introduced=31
+    AActivityManager_removeUidImportanceListener; # systemapi # introduced=31
+    AActivityManager_isUidActive; # systemapi # introduced=31
+    AActivityManager_getUidImportance; # systemapi # introduced=31
     AAssetDir_close;
     AAssetDir_getNextFileName;
     AAssetDir_rewind;
diff --git a/omapi/OWNERS b/omapi/OWNERS
index 5682fd3..1dce1e0 100644
--- a/omapi/OWNERS
+++ b/omapi/OWNERS
@@ -1,5 +1,6 @@
 # Bug component: 456592
 
-zachoverflow@google.com
+sattiraju@google.com
+henrichataing@google.com
 alisher@google.com
 jackcwyu@google.com
diff --git a/omapi/java/android/se/OWNERS b/omapi/java/android/se/OWNERS
index 5682fd3..1dce1e0 100644
--- a/omapi/java/android/se/OWNERS
+++ b/omapi/java/android/se/OWNERS
@@ -1,5 +1,6 @@
 # Bug component: 456592
 
-zachoverflow@google.com
+sattiraju@google.com
+henrichataing@google.com
 alisher@google.com
 jackcwyu@google.com
diff --git a/omapi/java/android/se/omapi/OWNERS b/omapi/java/android/se/omapi/OWNERS
index 5682fd3..1dce1e0 100644
--- a/omapi/java/android/se/omapi/OWNERS
+++ b/omapi/java/android/se/omapi/OWNERS
@@ -1,5 +1,6 @@
 # Bug component: 456592
 
-zachoverflow@google.com
+sattiraju@google.com
+henrichataing@google.com
 alisher@google.com
 jackcwyu@google.com
diff --git a/rs/jni/Android.bp b/rs/jni/Android.bp
index 9a6fa8e..8a6897c 100644
--- a/rs/jni/Android.bp
+++ b/rs/jni/Android.bp
@@ -51,4 +51,10 @@
         "-Wunreachable-code",
         "-Wno-deprecated-declarations",
     ],
+
+    target: {
+        android_riscv64: {
+            enabled: false,
+        },
+    },
 }
diff --git a/services/core/Android.bp b/services/core/Android.bp
index bf71e6b..2207821 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -150,7 +150,7 @@
         "android.hardware.health-V1.0-java", // HIDL
         "android.hardware.health-V2.0-java", // HIDL
         "android.hardware.health-V2.1-java", // HIDL
-        "android.hardware.health-V1-java", // AIDL
+        "android.hardware.health-V2-java", // AIDL
         "android.hardware.health-translate-java",
         "android.hardware.light-V1-java",
         "android.hardware.tv.cec-V1.1-java",
diff --git a/services/core/java/com/android/server/VpnManagerService.java b/services/core/java/com/android/server/VpnManagerService.java
index ae50b23..2b43ef4 100644
--- a/services/core/java/com/android/server/VpnManagerService.java
+++ b/services/core/java/com/android/server/VpnManagerService.java
@@ -22,6 +22,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.UserIdInt;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -67,6 +68,7 @@
 import com.android.server.connectivity.Vpn;
 import com.android.server.connectivity.VpnProfileStore;
 import com.android.server.net.LockdownVpnTracker;
+import com.android.server.pm.UserManagerInternal;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -93,6 +95,7 @@
     private final INetworkManagementService mNMS;
     private final INetd mNetd;
     private final UserManager mUserManager;
+    private final int mMainUserId;
 
     @VisibleForTesting
     @GuardedBy("mVpns")
@@ -145,6 +148,12 @@
                 Vpn vpn, VpnProfile profile) {
             return new LockdownVpnTracker(context, handler, vpn,  profile);
         }
+
+        /** Get the main user on the device. */
+        public @UserIdInt int getMainUserId() {
+            // TODO(b/265785220): Change to use UserManager method instead.
+            return LocalServices.getService(UserManagerInternal.class).getMainUserId();
+        }
     }
 
     public VpnManagerService(Context context, Dependencies deps) {
@@ -159,6 +168,7 @@
         mNMS = mDeps.getINetworkManagementService();
         mNetd = mDeps.getNetd();
         mUserManager = mContext.getSystemService(UserManager.class);
+        mMainUserId = mDeps.getMainUserId();
         registerReceivers();
         log("VpnManagerService starting up");
     }
@@ -478,11 +488,12 @@
 
     @Override
     public boolean updateLockdownVpn() {
-        // Allow the system UID for the system server and for Settings.
+        // Allow the system UID for the system server and for Settings (from user 0 or main user).
         // Also, for unit tests, allow the process that ConnectivityService is running in.
         if (mDeps.getCallingUid() != Process.SYSTEM_UID
+                && mDeps.getCallingUid() != UserHandle.getUid(mMainUserId, Process.SYSTEM_UID)
                 && Binder.getCallingPid() != Process.myPid()) {
-            logw("Lockdown VPN only available to system process or AID_SYSTEM");
+            logw("Lockdown VPN only available to system process or AID_SYSTEM on main user");
             return false;
         }
 
@@ -697,7 +708,7 @@
                 intentFilter,
                 null /* broadcastPermission */,
                 mHandler);
-        mContext.createContextAsUser(UserHandle.SYSTEM, 0 /* flags */).registerReceiver(
+        mContext.createContextAsUser(UserHandle.of(mMainUserId), 0 /* flags */).registerReceiver(
                 mUserPresentReceiver,
                 new IntentFilter(Intent.ACTION_USER_PRESENT),
                 null /* broadcastPermission */,
@@ -735,6 +746,7 @@
 
             if (LockdownVpnTracker.ACTION_LOCKDOWN_RESET.equals(action)) {
                 onVpnLockdownReset();
+                return;
             }
 
             // UserId should be filled for below intents, check the existence.
@@ -795,7 +807,7 @@
             userVpn = mDeps.createVpn(mHandler.getLooper(), mContext, mNMS, mNetd, userId);
             mVpns.put(userId, userVpn);
 
-            if (user.isPrimary() && isLockdownVpnEnabled()) {
+            if (userId == mMainUserId && isLockdownVpnEnabled()) {
                 updateLockdownVpn();
             }
         }
@@ -910,15 +922,9 @@
     }
 
     private void onUserUnlocked(int userId) {
-        UserInfo user = mUserManager.getUserInfo(userId);
-        if (user == null) {
-            logw("Unlocked user doesn't exist. UserId: " + userId);
-            return;
-        }
-
         synchronized (mVpns) {
             // User present may be sent because of an unlock, which might mean an unlocked keystore.
-            if (user.isPrimary() && isLockdownVpnEnabled()) {
+            if (userId == mMainUserId && isLockdownVpnEnabled()) {
                 updateLockdownVpn();
             } else {
                 startAlwaysOnVpn(userId);
@@ -984,7 +990,7 @@
             }
 
             // Turn Always-on VPN off
-            if (mLockdownEnabled && userId == UserHandle.USER_SYSTEM) {
+            if (mLockdownEnabled && userId == mMainUserId) {
                 final long ident = Binder.clearCallingIdentity();
                 try {
                     mVpnProfileStore.remove(Credentials.LOCKDOWN_VPN);
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index b153c1b..2f16a58 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -845,6 +845,15 @@
                 for (int i = 0; i < userDisabledHdrTypeStrings.length; i++) {
                     mUserDisabledHdrTypes[i] = Integer.parseInt(userDisabledHdrTypeStrings[i]);
                 }
+
+                if (!mAreUserDisabledHdrTypesAllowed) {
+                    mLogicalDisplayMapper.forEachLocked(
+                            display -> {
+                                display.setUserDisabledHdrTypes(mUserDisabledHdrTypes);
+                                handleLogicalDisplayChangedLocked(display);
+                            });
+                }
+
             } catch (NumberFormatException e) {
                 Slog.e(TAG, "Failed to parse USER_DISABLED_HDR_FORMATS. "
                         + "Clearing the setting.", e);
@@ -872,6 +881,15 @@
                 Settings.Global.USER_PREFERRED_RESOLUTION_WIDTH, Display.INVALID_DISPLAY_WIDTH);
         Display.Mode mode = new Display.Mode(width, height, refreshRate);
         mUserPreferredMode = isResolutionAndRefreshRateValid(mode) ? mode : null;
+        if (mUserPreferredMode != null) {
+            mDisplayDeviceRepo.forEachLocked((DisplayDevice device) -> {
+                device.setUserPreferredDisplayModeLocked(mode);
+            });
+        } else {
+            mLogicalDisplayMapper.forEachLocked((LogicalDisplay display) -> {
+                configurePreferredDisplayModeLocked(display);
+            });
+        }
     }
 
     private DisplayInfo getDisplayInfoForFrameRateOverride(DisplayEventReceiver.FrameRateOverride[]
@@ -2213,7 +2231,9 @@
                 }
                 // fallthrough
             default:
-                Slog.w(TAG, "Display " + info + " does not support input device matching.");
+                if (DEBUG) {
+                    Slog.w(TAG, "Display " + info + " does not support input device matching.");
+                }
         }
         return Optional.empty();
     }
diff --git a/services/core/java/com/android/server/pm/UserManagerInternal.java b/services/core/java/com/android/server/pm/UserManagerInternal.java
index 8dc9428..cc58e5c 100644
--- a/services/core/java/com/android/server/pm/UserManagerInternal.java
+++ b/services/core/java/com/android/server/pm/UserManagerInternal.java
@@ -305,4 +305,10 @@
      * for users that already existed on-disk from an older version of Android.
      */
     public abstract boolean shouldIgnorePrepareStorageErrors(int userId);
+
+    /**
+     * Returns the user id of the main user, or {@link android.os.UserHandle#USER_NULL} if there is
+     * no main user.
+     */
+    public abstract @UserIdInt int getMainUserId();
 }
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index b3dcf72..0a465e9 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -6359,6 +6359,11 @@
                 return userData != null && userData.getIgnorePrepareStorageErrors();
             }
         }
+
+        @Override
+        public @UserIdInt int getMainUserId() {
+            return UserHandle.USER_SYSTEM;
+        }
     }
 
     /**
diff --git a/services/core/java/com/android/server/power/ShutdownThread.java b/services/core/java/com/android/server/power/ShutdownThread.java
index a82d4ea..5096ad1 100644
--- a/services/core/java/com/android/server/power/ShutdownThread.java
+++ b/services/core/java/com/android/server/power/ShutdownThread.java
@@ -61,6 +61,7 @@
 
 public final class ShutdownThread extends Thread {
     // constants
+    private static final boolean DEBUG = false;
     private static final String TAG = "ShutdownThread";
     private static final int ACTION_DONE_POLL_WAIT_MS = 500;
     private static final int RADIOS_STATE_POLL_SLEEP_MS = 100;
@@ -161,7 +162,9 @@
         // any additional calls are just returned
         synchronized (sIsStartedGuard) {
             if (sIsStarted) {
-                Log.d(TAG, "Request to shutdown already running, returning.");
+                if (DEBUG) {
+                    Log.d(TAG, "Request to shutdown already running, returning.");
+                }
                 return;
             }
         }
@@ -178,7 +181,9 @@
                         ? com.android.internal.R.string.shutdown_confirm_question
                         : com.android.internal.R.string.shutdown_confirm);
 
-        Log.d(TAG, "Notifying thread to start shutdown longPressBehavior=" + longPressBehavior);
+        if (DEBUG) {
+            Log.d(TAG, "Notifying thread to start shutdown longPressBehavior=" + longPressBehavior);
+        }
 
         if (confirm) {
             final CloseDialogReceiver closer = new CloseDialogReceiver(context);
@@ -348,26 +353,34 @@
     }
 
     private static boolean showSysuiReboot() {
-        Log.d(TAG, "Attempting to use SysUI shutdown UI");
+        if (DEBUG) {
+            Log.d(TAG, "Attempting to use SysUI shutdown UI");
+        }
         try {
             StatusBarManagerInternal service = LocalServices.getService(
                     StatusBarManagerInternal.class);
             if (service.showShutdownUi(mReboot, mReason)) {
                 // Sysui will handle shutdown UI.
-                Log.d(TAG, "SysUI handling shutdown UI");
+                if (DEBUG) {
+                    Log.d(TAG, "SysUI handling shutdown UI");
+                }
                 return true;
             }
         } catch (Exception e) {
             // If anything went wrong, ignore it and use fallback ui
         }
-        Log.d(TAG, "SysUI is unavailable");
+        if (DEBUG) {
+            Log.d(TAG, "SysUI is unavailable");
+        }
         return false;
     }
 
     private static void beginShutdownSequence(Context context) {
         synchronized (sIsStartedGuard) {
             if (sIsStarted) {
-                Log.d(TAG, "Shutdown sequence already running, returning.");
+                if (DEBUG) {
+                    Log.d(TAG, "Shutdown sequence already running, returning.");
+                }
                 return;
             }
             sIsStarted = true;
diff --git a/services/core/java/com/android/server/rollback/RollbackStore.java b/services/core/java/com/android/server/rollback/RollbackStore.java
index f973f5c..8068c6f 100644
--- a/services/core/java/com/android/server/rollback/RollbackStore.java
+++ b/services/core/java/com/android/server/rollback/RollbackStore.java
@@ -249,7 +249,7 @@
         targetDir.mkdirs();
         File targetFile = new File(targetDir, sourceFile.getName());
 
-        boolean fallbackToCopy = !isLinkPossible(sourceFile, targetFile);
+        boolean fallbackToCopy = !isLinkPossible(sourceFile, targetDir);
         if (!fallbackToCopy) {
             try {
                 // Create a hard link to avoid copy
diff --git a/services/core/java/com/android/server/soundtrigger_middleware/OWNERS b/services/core/java/com/android/server/soundtrigger_middleware/OWNERS
index e5d0370..01b2cb9 100644
--- a/services/core/java/com/android/server/soundtrigger_middleware/OWNERS
+++ b/services/core/java/com/android/server/soundtrigger_middleware/OWNERS
@@ -1,2 +1,2 @@
-ytai@google.com
+atneya@google.com
 elaurent@google.com
diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java
index b95d372..8bc7bcc 100755
--- a/services/core/java/com/android/server/tv/TvInputManagerService.java
+++ b/services/core/java/com/android/server/tv/TvInputManagerService.java
@@ -24,6 +24,7 @@
 import android.annotation.Nullable;
 import android.annotation.UserIdInt;
 import android.app.ActivityManager;
+import android.content.AttributionSource;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.ContentResolver;
@@ -90,7 +91,6 @@
 import android.util.SparseArray;
 import android.view.InputChannel;
 import android.view.Surface;
-
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.content.PackageMonitor;
@@ -101,9 +101,7 @@
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.IoThread;
 import com.android.server.SystemService;
-
 import dalvik.annotation.optimization.NeverCompile;
-
 import java.io.File;
 import java.io.FileDescriptor;
 import java.io.FileNotFoundException;
@@ -813,7 +811,7 @@
 
     @GuardedBy("mLock")
     private boolean createSessionInternalLocked(ITvInputService service, IBinder sessionToken,
-            int userId) {
+            int userId, AttributionSource tvAppAttributionSource) {
         UserState userState = getOrCreateUserStateLocked(userId);
         SessionState sessionState = userState.sessionStateMap.get(sessionToken);
         if (DEBUG) {
@@ -832,8 +830,8 @@
                 service.createRecordingSession(
                         callback, sessionState.inputId, sessionState.sessionId);
             } else {
-                service.createSession(
-                        channels[1], callback, sessionState.inputId, sessionState.sessionId);
+                service.createSession(channels[1], callback, sessionState.inputId,
+                        sessionState.sessionId, tvAppAttributionSource);
             }
         } catch (RemoteException e) {
             Slog.e(TAG, "error in createSession", e);
@@ -1485,7 +1483,8 @@
 
         @Override
         public void createSession(final ITvInputClient client, final String inputId,
-                boolean isRecordingSession, int seq, int userId) {
+                AttributionSource tvAppAttributionSource, boolean isRecordingSession, int seq,
+                int userId) {
             final int callingUid = Binder.getCallingUid();
             final int callingPid = Binder.getCallingPid();
             final int resolvedUserId = resolveCallingUserId(callingPid, callingUid,
@@ -1556,7 +1555,7 @@
 
                     if (serviceState.service != null) {
                         if (!createSessionInternalLocked(serviceState.service, sessionToken,
-                                resolvedUserId)) {
+                                    resolvedUserId, tvAppAttributionSource)) {
                             removeSessionStateLocked(sessionToken, resolvedUserId);
                         }
                     } else {
@@ -3113,7 +3112,8 @@
 
                 // And create sessions, if any.
                 for (IBinder sessionToken : serviceState.sessionTokens) {
-                    if (!createSessionInternalLocked(serviceState.service, sessionToken, mUserId)) {
+                    if (!createSessionInternalLocked(
+                                serviceState.service, sessionToken, mUserId, null)) {
                         tokensToBeRemoved.add(sessionToken);
                     }
                 }
diff --git a/services/incremental/TEST_MAPPING b/services/incremental/TEST_MAPPING
index 9fe090a..3976a70 100644
--- a/services/incremental/TEST_MAPPING
+++ b/services/incremental/TEST_MAPPING
@@ -36,5 +36,10 @@
         }
       ]
     }
+  ],
+  "kernel-presubmit": [
+    {
+      "name": "CtsIncrementalInstallHostTestCases"
+    }
   ]
 }
diff --git a/services/tests/mockingservicestests/OWNERS b/services/tests/mockingservicestests/OWNERS
index 4dda51f..0640d52 100644
--- a/services/tests/mockingservicestests/OWNERS
+++ b/services/tests/mockingservicestests/OWNERS
@@ -6,3 +6,6 @@
 per-file FakeServiceConnector.java = file:/GAME_MANAGER_OWNERS
 per-file Game* = file:/GAME_MANAGER_OWNERS
 per-file res/xml/game_manager* = file:/GAME_MANAGER_OWNERS
+
+# General utilities
+per-file services/tests/mockingservicestests/src/com/android/server/*.java=felipeal@google.com
diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/OWNERS b/services/voiceinteraction/java/com/android/server/soundtrigger/OWNERS
index e5d0370..01b2cb9 100644
--- a/services/voiceinteraction/java/com/android/server/soundtrigger/OWNERS
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger/OWNERS
@@ -1,2 +1,2 @@
-ytai@google.com
+atneya@google.com
 elaurent@google.com
diff --git a/telephony/java/android/telephony/ims/RcsContactPresenceTuple.java b/telephony/java/android/telephony/ims/RcsContactPresenceTuple.java
index 6a6c306..74bac22 100644
--- a/telephony/java/android/telephony/ims/RcsContactPresenceTuple.java
+++ b/telephony/java/android/telephony/ims/RcsContactPresenceTuple.java
@@ -147,7 +147,7 @@
             "org.3gpp.urn:urn-7:3gpp-application.ims.iari.rcs.chatbot";
 
     /**
-     * The service ID used to indicate that the Standalone Messaging is available.
+     * The service ID used to indicate that the Chatbot using Standalone Messaging is available.
      * <p>
      * See the GSMA RCC.07 specification for more information.
      */
@@ -161,6 +161,14 @@
      */
     public static final String SERVICE_ID_CHATBOT_ROLE = "org.gsma.rcs.isbot";
 
+    /**
+     * The service ID used to indicate that the Standalone Messaging is available.
+     * <p>
+     * See the GSMA RCC.07 RCS5_1_advanced_communications_specification_v4.0 specification
+     * for more information.
+     */
+    public static final String SERVICE_ID_SLM = "org.openmobilealliance:StandaloneMsg";
+
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
     @StringDef(prefix = "SERVICE_ID_", value = {
@@ -177,7 +185,8 @@
             SERVICE_ID_SHARED_SKETCH,
             SERVICE_ID_CHATBOT,
             SERVICE_ID_CHATBOT_STANDALONE,
-            SERVICE_ID_CHATBOT_ROLE
+            SERVICE_ID_CHATBOT_ROLE,
+            SERVICE_ID_SLM
     })
     public @interface ServiceId {}
 
diff --git a/tests/CanvasCompare/Android.bp b/tests/CanvasCompare/Android.bp
deleted file mode 100644
index 9883115..0000000
--- a/tests/CanvasCompare/Android.bp
+++ /dev/null
@@ -1,63 +0,0 @@
-//
-// Copyright (C) 2012 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 {
-    // See: http://go/android-license-faq
-    default_applicable_licenses: [
-        "frameworks_base_license",
-    ],
-}
-
-android_test {
-    name: "CanvasCompare",
-    srcs: [
-        "src/**/*.java",
-        ":CanvasCompare-rscript{CanvasCompare.srcjar}",
-    ],
-    resource_zips: [
-        ":CanvasCompare-rscript{CanvasCompare.res.zip}",
-    ],
-    platform_apis: true,
-    libs: [
-        "android.test.runner",
-        "android.test.base",
-    ],
-    static_libs: ["junit"],
-}
-
-genrule {
-    name: "CanvasCompare-rscript",
-    srcs: [
-        "src/**/*.rscript",
-        ":rs_script_api",
-        ":rs_clang_headers",
-    ],
-    tools: [
-        "llvm-rs-cc",
-        "soong_zip",
-    ],
-    out: [
-        "CanvasCompare.srcjar",
-        "CanvasCompare.res.zip",
-    ],
-    cmd: "for f in $(locations src/**/*.rscript); do " +
-        "  $(location llvm-rs-cc) -o $(genDir)/res/raw -p $(genDir)/src " +
-        "  -I $$(dirname $$(echo $(locations :rs_script_api) | awk '{ print $$1 }')) " +
-        "  -I $$(dirname $$(echo $(locations :rs_clang_headers) | awk '{ print $$1 }')) $${f}; " +
-        "done && " +
-        "$(location soong_zip) -srcjar -o $(location CanvasCompare.srcjar) -C $(genDir)/src -D $(genDir)/src &&" +
-        "$(location soong_zip) -o $(location CanvasCompare.res.zip) -C $(genDir)/res -D $(genDir)/res",
-}
diff --git a/tests/CanvasCompare/AndroidManifest.xml b/tests/CanvasCompare/AndroidManifest.xml
deleted file mode 100644
index 2734e7f..0000000
--- a/tests/CanvasCompare/AndroidManifest.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 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.test.hwuicompare">
-
-    <uses-permission android:name="android.permission.INTERNET"/>
-    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
-    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
-
-    <application android:label="@string/app_name"
-         android:theme="@android:style/Theme.Holo.Light.NoActionBar">
-        <activity android:name="AutomaticActivity"
-             android:label="CanvasAutoCompare"
-             android:exported="true">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN"/>
-                <category android:name="android.intent.category.LAUNCHER"/>
-            </intent-filter>
-        </activity>
-        <activity android:name="ManualActivity"
-             android:label="CanvasManualCompare"
-             android:exported="true">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN"/>
-                <category android:name="android.intent.category.LAUNCHER"/>
-            </intent-filter>
-        </activity>
-        <uses-library android:name="android.test.runner"/>
-    </application>
-    <instrumentation android:name="android.test.InstrumentationTestRunner"
-         android:targetPackage="com.android.test.hwuicompare"
-         android:label="HW/SW Canvas comparison tool."/>
-
-</manifest>
diff --git a/tests/CanvasCompare/OWNERS b/tests/CanvasCompare/OWNERS
deleted file mode 100644
index c88a9f8..0000000
--- a/tests/CanvasCompare/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-include /libs/hwui/OWNERS
diff --git a/tests/CanvasCompare/res/drawable/sunset1.jpg b/tests/CanvasCompare/res/drawable/sunset1.jpg
deleted file mode 100644
index 3b4e056..0000000
--- a/tests/CanvasCompare/res/drawable/sunset1.jpg
+++ /dev/null
Binary files differ
diff --git a/tests/CanvasCompare/res/layout/automatic_layout.xml b/tests/CanvasCompare/res/layout/automatic_layout.xml
deleted file mode 100644
index e049ec0..0000000
--- a/tests/CanvasCompare/res/layout/automatic_layout.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 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.
--->
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent" >
-
-    <com.android.test.hwuicompare.MainView
-        android:id="@+id/hardware_view"
-        android:layout_width="@dimen/layer_width"
-        android:layout_height="@dimen/layer_width" />
-
-    <ImageView
-        android:id="@+id/software_image_view"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentRight="true" />
-
-    <ImageView
-        android:id="@+id/hardware_image_view"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentBottom="true"
-        android:layout_alignParentRight="true" />
-
-</RelativeLayout>
diff --git a/tests/CanvasCompare/res/layout/manual_layout.xml b/tests/CanvasCompare/res/layout/manual_layout.xml
deleted file mode 100644
index 1a9288c..0000000
--- a/tests/CanvasCompare/res/layout/manual_layout.xml
+++ /dev/null
@@ -1,119 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 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.
--->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:gravity="center_horizontal"
-    android:orientation="vertical" >
-
-    <HorizontalScrollView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content" >
-
-        <LinearLayout
-            android:id="@+id/spinner_layout"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:orientation="horizontal" />
-    </HorizontalScrollView>
-
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="0dip"
-        android:layout_weight="1"
-        android:baselineAligned="true"
-        android:orientation="horizontal" >
-
-        <LinearLayout
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:gravity="center"
-            android:orientation="horizontal" >
-
-            <com.android.test.hwuicompare.MainView
-                android:id="@+id/hardware_view"
-                android:layout_width="@dimen/layer_width"
-                android:layout_height="@dimen/layer_width" />
-        </LinearLayout>
-
-        <LinearLayout
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:gravity="center"
-            android:orientation="horizontal" >
-
-            <com.android.test.hwuicompare.MainView
-                android:id="@+id/software_view"
-                android:layout_width="@dimen/layer_width"
-                android:layout_height="@dimen/layer_width" />
-        </LinearLayout>
-    </LinearLayout>
-
-    <ImageView
-        android:id="@+id/compare_image_view"
-        android:layout_width="@dimen/layer_width_double"
-        android:layout_height="@dimen/layer_height_double"
-        android:filter="false" />
-
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:gravity="center"
-        android:orientation="horizontal" >
-
-        <ImageButton
-            android:id="@+id/previous"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:contentDescription="@string/previous_combination"
-            android:src="@android:drawable/ic_media_previous" />
-
-        <ImageButton
-            android:id="@+id/next"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:contentDescription="@string/next_combination"
-            android:src="@android:drawable/ic_media_next" />
-
-        <TextView
-            android:id="@+id/current_error"
-            android:layout_width="100dp"
-            android:layout_height="wrap_content"
-            android:gravity="center"
-            android:textAppearance="?android:attr/textAppearanceLarge" />
-
-        <Button
-            android:id="@+id/show_hardware_version"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="@string/show_hardware_version" />
-
-        <Button
-            android:id="@+id/show_software_version"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="@string/show_software_version" />
-
-        <Button
-            android:id="@+id/show_error_heatmap"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="@string/show_error_heatmap" />
-    </LinearLayout>
-
-</LinearLayout>
diff --git a/tests/CanvasCompare/res/values/strings.xml b/tests/CanvasCompare/res/values/strings.xml
deleted file mode 100644
index edd4610..0000000
--- a/tests/CanvasCompare/res/values/strings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 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.
--->
-<resources>
-    <string name="app_name">Canvas Compare Test</string>
-
-    <!-- show hardware rendered version of the layer -->
-    <string name="show_hardware_version">Hardware</string>
-    <!-- show software rendered version of the layer -->
-    <string name="show_software_version">Software</string>
-    <!-- show layer error -->
-    <string name="show_error_values">Error</string>
-    <!-- show layer error heatmap -->
-    <string name="show_error_heatmap">Heatmap</string>
-    <!--  select and display the next combination of painting options-->
-    <string name="next_combination">Next Combination</string>
-    <!--  select and display the previous combination of painting options-->
-    <string name="previous_combination">Previous Combination</string>
-</resources>
diff --git a/tests/CanvasCompare/res/values/values.xml b/tests/CanvasCompare/res/values/values.xml
deleted file mode 100644
index f69378d..0000000
--- a/tests/CanvasCompare/res/values/values.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 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.
--->
-<resources>
-
-    <!-- NOTE: the below MUST be multiples of 64 -->
-    <dimen name="layer_height">320px</dimen>
-    <dimen name="layer_width">320px</dimen>
-
-    <dimen name="layer_height_double">640px</dimen>
-    <dimen name="layer_width_double">640px</dimen>
-
-</resources>
diff --git a/tests/CanvasCompare/src/com/android/test/hwuicompare/AutomaticActivity.java b/tests/CanvasCompare/src/com/android/test/hwuicompare/AutomaticActivity.java
deleted file mode 100644
index 8ccd4e2..0000000
--- a/tests/CanvasCompare/src/com/android/test/hwuicompare/AutomaticActivity.java
+++ /dev/null
@@ -1,310 +0,0 @@
-/*
- * Copyright (C) 2012 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.test.hwuicompare;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.TreeSet;
-
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import android.os.Bundle;
-import android.os.Environment;
-import android.os.Trace;
-import android.util.Log;
-import android.widget.ImageView;
-import android.widget.Toast;
-
-public class AutomaticActivity extends CompareActivity {
-    private static final String LOG_TAG = "AutomaticActivity";
-    private static final float ERROR_DISPLAY_THRESHOLD = 0.01f;
-    protected static final boolean DRAW_BITMAPS = false;
-
-    /**
-     * Threshold of error change required to consider a test regressed/improved
-     */
-    private static final float ERROR_CHANGE_THRESHOLD = 0.001f;
-
-    private static final float[] ERROR_CUTOFFS = {
-            0, 0.005f, 0.01f, 0.02f, 0.05f, 0.1f, 0.25f, 0.5f, 1f, 2f
-    };
-
-    private final float[] mErrorRates = new float[ERROR_CUTOFFS.length];
-    private float mTotalTests = 0;
-    private float mTotalError = 0;
-    private int mTestsRegressed = 0;
-    private int mTestsImproved = 0;
-
-    private ImageView mSoftwareImageView = null;
-    private ImageView mHardwareImageView = null;
-
-
-    public abstract static class FinalCallback {
-        abstract void report(String name, float value);
-        void complete() {};
-    }
-
-    private final ArrayList<FinalCallback> mFinalCallbacks = new ArrayList<FinalCallback>();
-
-    Runnable mRunnable = new Runnable() {
-        @Override
-        public void run() {
-            loadBitmaps();
-            if (mSoftwareBitmap == null || mHardwareBitmap == null) {
-                Log.e(LOG_TAG, "bitmap is null");
-                return;
-            }
-
-            if (DRAW_BITMAPS) {
-                mSoftwareImageView.setImageBitmap(mSoftwareBitmap);
-                mHardwareImageView.setImageBitmap(mHardwareBitmap);
-            }
-
-            Trace.traceBegin(Trace.TRACE_TAG_ALWAYS, "calculateError");
-            float error = mErrorCalculator.calcErrorRS(mSoftwareBitmap, mHardwareBitmap);
-            Trace.traceEnd(Trace.TRACE_TAG_ALWAYS);
-
-            final String[] modifierNames = DisplayModifier.getLastAppliedModifications();
-            handleError(modifierNames, error);
-
-            if (DisplayModifier.step()) {
-                finishTest();
-            } else {
-                mHardwareView.invalidate();
-                if (DRAW_BITMAPS) {
-                    mSoftwareImageView.invalidate();
-                    mHardwareImageView.invalidate();
-                }
-            }
-            mHandler.removeCallbacks(mRunnable);
-        }
-    };
-
-    @Override
-    protected void onPause() {
-        super.onPause();
-        mHandler.removeCallbacks(mRunnable);
-    };
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.automatic_layout);
-
-        mSoftwareImageView = findViewById(R.id.software_image_view);
-        mHardwareImageView = findViewById(R.id.hardware_image_view);
-
-        onCreateCommon(mRunnable);
-        beginTest();
-    }
-
-    private static class TestResult {
-        TestResult(String label, float error) {
-            mLabel = label;
-            mTotalError = error;
-            mCount = 1;
-        }
-        public void addInto(float error) {
-            mTotalError += error;
-            mCount++;
-        }
-        public float getAverage() {
-            return mTotalError / mCount;
-        }
-        final String mLabel;
-        float mTotalError;
-        int mCount;
-    }
-
-    JSONObject mOutputJson = null;
-    JSONObject mInputJson = null;
-    final HashMap<String, TestResult> mModifierResults = new HashMap<String, TestResult>();
-    final HashMap<String, TestResult> mIndividualResults = new HashMap<String, TestResult>();
-    final HashMap<String, TestResult> mModifierDiffResults = new HashMap<String, TestResult>();
-    final HashMap<String, TestResult> mIndividualDiffResults = new HashMap<String, TestResult>();
-    private void beginTest() {
-        mFinalCallbacks.add(new FinalCallback() {
-            @Override
-            void report(String name, float value) {
-                Log.d(LOG_TAG, name + " " + value);
-            };
-        });
-
-        File inputFile = new File(Environment.getExternalStorageDirectory(),
-                "CanvasCompareInput.json");
-        if (inputFile.exists() && inputFile.canRead() && inputFile.length() > 0) {
-            try {
-                FileInputStream inputStream = new FileInputStream(inputFile);
-                Log.d(LOG_TAG, "Parsing input file...");
-                StringBuffer content = new StringBuffer((int)inputFile.length());
-                byte[] buffer = new byte[1024];
-                while (inputStream.read(buffer) != -1) {
-                    content.append(new String(buffer));
-                }
-                mInputJson = new JSONObject(content.toString());
-                inputStream.close();
-                Log.d(LOG_TAG, "Parsed input file with " + mInputJson.length() + " entries");
-            } catch (JSONException e) {
-                Log.e(LOG_TAG, "error parsing input json", e);
-            } catch (IOException e) {
-                Log.e(LOG_TAG, "error reading input json from sd", e);
-            }
-        }
-
-        mOutputJson = new JSONObject();
-    }
-
-    private static void logTestResultHash(String label, HashMap<String, TestResult> map) {
-        Log.d(LOG_TAG, "---------------");
-        Log.d(LOG_TAG, label + ":");
-        Log.d(LOG_TAG, "---------------");
-        TreeSet<TestResult> set = new TreeSet<TestResult>(new Comparator<TestResult>() {
-            @Override
-            public int compare(TestResult lhs, TestResult rhs) {
-                if (lhs == rhs) return 0; // don't need to worry about complex equality
-
-                int cmp = Float.compare(lhs.getAverage(), rhs.getAverage());
-                if (cmp != 0) {
-                    return cmp;
-                }
-                return lhs.mLabel.compareTo(rhs.mLabel);
-            }
-        });
-
-        for (TestResult t : map.values()) {
-            set.add(t);
-        }
-
-        for (TestResult t : set.descendingSet()) {
-            if (Math.abs(t.getAverage()) > ERROR_DISPLAY_THRESHOLD) {
-                Log.d(LOG_TAG, String.format("%2.4f : %s", t.getAverage(), t.mLabel));
-            }
-        }
-        Log.d(LOG_TAG, "");
-    }
-
-    private void finishTest() {
-        for (FinalCallback c : mFinalCallbacks) {
-            c.report("averageError", (mTotalError / mTotalTests));
-            for (int i = 1; i < ERROR_CUTOFFS.length; i++) {
-                c.report(String.format("tests with error over %1.3f", ERROR_CUTOFFS[i]),
-                        mErrorRates[i]);
-            }
-            if (mInputJson != null) {
-                c.report("tests regressed", mTestsRegressed);
-                c.report("tests improved", mTestsImproved);
-            }
-            c.complete();
-        }
-
-        try {
-            if (mOutputJson != null) {
-                String outputString = mOutputJson.toString(4);
-                File outputFile = new File(Environment.getExternalStorageDirectory(),
-                        "CanvasCompareOutput.json");
-                FileOutputStream outputStream = new FileOutputStream(outputFile);
-                outputStream.write(outputString.getBytes());
-                outputStream.close();
-                Log.d(LOG_TAG, "Saved output file with " + mOutputJson.length() + " entries");
-            }
-        } catch (JSONException e) {
-            Log.e(LOG_TAG, "error during JSON stringify", e);
-        } catch (IOException e) {
-            Log.e(LOG_TAG, "error storing JSON output on sd", e);
-        }
-
-        logTestResultHash("Modifier change vs previous", mModifierDiffResults);
-        logTestResultHash("Invidual test change vs previous", mIndividualDiffResults);
-        logTestResultHash("Modifier average test results", mModifierResults);
-        logTestResultHash("Individual test results", mIndividualResults);
-
-        Toast.makeText(getApplicationContext(), "done!", Toast.LENGTH_SHORT).show();
-        finish();
-    }
-
-    /**
-     * Inserts the error value into all TestResult objects, associated with each of its modifiers
-     */
-    private static void addForAllModifiers(String fullName, float error, String[] modifierNames,
-            HashMap<String, TestResult> modifierResults) {
-        for (String modifierName : modifierNames) {
-            TestResult r = modifierResults.get(fullName);
-            if (r == null) {
-                modifierResults.put(modifierName, new TestResult(modifierName, error));
-            } else {
-                r.addInto(error);
-            }
-        }
-    }
-
-    private void handleError(final String[] modifierNames, final float error) {
-        String fullName = "";
-        for (String s : modifierNames) {
-            fullName = fullName.concat("." + s);
-        }
-        fullName = fullName.substring(1);
-
-        float deltaError = 0;
-        if (mInputJson != null) {
-            try {
-                deltaError = error - (float)mInputJson.getDouble(fullName);
-            } catch (JSONException e) {
-                Log.w(LOG_TAG, "Warning: unable to read from input json", e);
-            }
-            if (deltaError > ERROR_CHANGE_THRESHOLD) mTestsRegressed++;
-            if (deltaError < -ERROR_CHANGE_THRESHOLD) mTestsImproved++;
-            mIndividualDiffResults.put(fullName, new TestResult(fullName, deltaError));
-            addForAllModifiers(fullName, deltaError, modifierNames, mModifierDiffResults);
-        }
-
-        mIndividualResults.put(fullName, new TestResult(fullName, error));
-        addForAllModifiers(fullName, error, modifierNames, mModifierResults);
-
-        try {
-            if (mOutputJson != null) {
-                mOutputJson.put(fullName, error);
-            }
-        } catch (JSONException e) {
-            Log.e(LOG_TAG, "exception during JSON recording", e);
-            mOutputJson = null;
-        }
-
-        for (int i = 0; i < ERROR_CUTOFFS.length; i++) {
-            if (error <= ERROR_CUTOFFS[i]) break;
-            mErrorRates[i]++;
-        }
-        mTotalError += error;
-        mTotalTests++;
-    }
-
-    @Override
-    protected boolean forceRecreateBitmaps() {
-        // disable, unless needed for drawing into imageviews
-        return DRAW_BITMAPS;
-    }
-
-    // FOR TESTING
-    public void setFinalCallback(FinalCallback c) {
-        mFinalCallbacks.add(c);
-    }
-}
diff --git a/tests/CanvasCompare/src/com/android/test/hwuicompare/CompareActivity.java b/tests/CanvasCompare/src/com/android/test/hwuicompare/CompareActivity.java
deleted file mode 100644
index 0dec1de..0000000
--- a/tests/CanvasCompare/src/com/android/test/hwuicompare/CompareActivity.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2012 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.test.hwuicompare;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-import com.android.test.hwuicompare.R;
-
-import android.app.Activity;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.drawable.ColorDrawable;
-import android.os.Handler;
-import android.os.Trace;
-import android.util.Log;
-import android.view.View;
-
-abstract public class CompareActivity extends Activity {
-    private static final String LOG_TAG = "CompareActivity";
-
-    protected MainView mHardwareView = null;
-
-    protected Bitmap mSoftwareBitmap;
-    protected Bitmap mHardwareBitmap;
-
-    protected ErrorCalculator mErrorCalculator;
-
-    protected Handler mHandler;
-
-    Runnable mDrawCallback = null;
-    protected boolean mRedrewFlag = true;
-
-    protected void onCreateCommon(final Runnable postDrawCallback) {
-        mDrawCallback = new Runnable() {
-            @Override
-            public void run() {
-                mRedrewFlag = true;
-                mHandler.post(postDrawCallback);
-            };
-        };
-        getWindow().setBackgroundDrawable(new ColorDrawable(0xffefefef));
-        ResourceModifiers.init(getResources());
-
-        mHardwareView = findViewById(R.id.hardware_view);
-        mHardwareView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
-        mHardwareView.setBackgroundColor(Color.WHITE);
-        mHardwareView.addDrawCallback(mDrawCallback);
-
-        int width = getResources().getDimensionPixelSize(R.dimen.layer_width);
-        int height = getResources().getDimensionPixelSize(R.dimen.layer_height);
-        mSoftwareBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
-        mHardwareBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
-
-        mErrorCalculator = new ErrorCalculator(getApplicationContext(), getResources());
-
-        mHandler = new Handler();
-    }
-
-    protected abstract boolean forceRecreateBitmaps();
-
-    protected void loadBitmaps() {
-        Trace.traceBegin(Trace.TRACE_TAG_ALWAYS, "loadBitmaps");
-        if (forceRecreateBitmaps()) {
-            int width = mSoftwareBitmap.getWidth();
-            int height = mSoftwareBitmap.getHeight();
-
-            mSoftwareBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
-            mHardwareBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
-        }
-
-        Trace.traceBegin(Trace.TRACE_TAG_ALWAYS, "softwareDraw");
-        mHardwareView.draw(new Canvas(mSoftwareBitmap));
-        Trace.traceEnd(Trace.TRACE_TAG_ALWAYS);
-
-        try {
-            Method getHardwareLayer = View.class.getDeclaredMethod("getHardwareLayer");
-            if (!getHardwareLayer.isAccessible())
-                getHardwareLayer.setAccessible(true);
-            Object hardwareLayer = getHardwareLayer.invoke(mHardwareView);
-            if (hardwareLayer == null) {
-                Log.d(LOG_TAG, "failure to access hardware layer");
-                return;
-            }
-            Method copyInto = hardwareLayer.getClass()
-                    .getDeclaredMethod("copyInto", Bitmap.class);
-            if (!copyInto.isAccessible())
-                copyInto.setAccessible(true);
-
-            Trace.traceBegin(Trace.TRACE_TAG_ALWAYS, "copyInto");
-            boolean success = (Boolean) copyInto.invoke(hardwareLayer, mHardwareBitmap);
-            Trace.traceEnd(Trace.TRACE_TAG_ALWAYS);
-            if (!success) {
-                Log.d(LOG_TAG, "failure to copy hardware layer into bitmap");
-            }
-        } catch (NoSuchMethodException e) {
-            e.printStackTrace();
-        } catch (IllegalArgumentException e) {
-            e.printStackTrace();
-        } catch (IllegalAccessException e) {
-            e.printStackTrace();
-        } catch (InvocationTargetException e) {
-            e.printStackTrace();
-        }
-        Trace.traceEnd(Trace.TRACE_TAG_ALWAYS);
-    }
-}
diff --git a/tests/CanvasCompare/src/com/android/test/hwuicompare/DisplayModifier.java b/tests/CanvasCompare/src/com/android/test/hwuicompare/DisplayModifier.java
deleted file mode 100644
index 4bcf5a4..0000000
--- a/tests/CanvasCompare/src/com/android/test/hwuicompare/DisplayModifier.java
+++ /dev/null
@@ -1,503 +0,0 @@
-/*
- * Copyright (C) 2012 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.test.hwuicompare;
-
-import static java.util.Map.entry;
-
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.RectF;
-import android.util.Log;
-
-import java.util.Map;
-import java.util.Map.Entry;
-
-public abstract class DisplayModifier {
-
-    // automated tests ignore any combination of operations that don't together return TOTAL_MASK
-    protected final static int TOTAL_MASK = 0x1F;
-
-    // if we're filling, ensure we're not also sweeping over stroke parameters
-    protected final static int SWEEP_STROKE_WIDTH_BIT = 0x1 << 0;
-    protected final static int SWEEP_STROKE_CAP_BIT = 0x1 << 1;
-    protected final static int SWEEP_STROKE_JOIN_BIT = 0x1 << 2;
-
-    protected final static int SWEEP_SHADER_BIT = 0x1 << 3; // only allow non-simple shaders to use rectangle drawing
-    protected final static int SWEEP_TRANSFORM_BIT = 0x1 << 4; // only sweep over specified transforms
-
-    abstract public void modifyDrawing(Paint paint, Canvas canvas);
-    protected int mask() { return 0x0; };
-
-    private static final RectF gRect = new RectF(0, 0, 200, 175);
-    private static final float[] gPts = new float[] {
-            0, 100, 100, 0, 100, 200, 200, 100
-    };
-
-    private static final int NUM_PARALLEL_LINES = 24;
-    private static final float[] gTriPts = new float[] {
-        75, 0, 130, 130, 130, 130, 0, 130, 0, 130, 75, 0
-    };
-    private static final float[] gLinePts = new float[NUM_PARALLEL_LINES * 8 + gTriPts.length];
-    static {
-        int index;
-        for (index = 0; index < gTriPts.length; index++) {
-            gLinePts[index] = gTriPts[index];
-        }
-        float val = 0;
-        for (int i = 0; i < NUM_PARALLEL_LINES; i++) {
-            gLinePts[index + 0] = 150;
-            gLinePts[index + 1] = val;
-            gLinePts[index + 2] = 300;
-            gLinePts[index + 3] = val;
-            index += 4;
-            val += 8 + (2.0f/NUM_PARALLEL_LINES);
-        }
-        val = 0;
-        for (int i = 0; i < NUM_PARALLEL_LINES; i++) {
-            gLinePts[index + 0] = val;
-            gLinePts[index + 1] = 150;
-            gLinePts[index + 2] = val;
-            gLinePts[index + 3] = 300;
-            index += 4;
-            val += 8 + (2.0f/NUM_PARALLEL_LINES);
-        }
-    };
-
-    @SuppressWarnings("serial")
-    private static final Map<String, Map<String, DisplayModifier>> gMaps = Map.of(
-            "aa", Map.of(
-                    "true", new DisplayModifier() {
-                        @Override
-                        public void modifyDrawing(Paint paint, Canvas canvas) {
-                            paint.setAntiAlias(true);
-                        }
-                    },
-                    "false", new DisplayModifier() {
-                        @Override
-                        public void modifyDrawing(Paint paint, Canvas canvas) {
-                            paint.setAntiAlias(false);
-                        }
-                    }),
-            "style", Map.of(
-                    "fill", new DisplayModifier() {
-                        @Override
-                        public void modifyDrawing(Paint paint, Canvas canvas) {
-                            paint.setStyle(Paint.Style.FILL);
-                        }
-                    },
-                    "stroke", new DisplayModifier() {
-                        @Override
-                        public void modifyDrawing(Paint paint, Canvas canvas) {
-                            paint.setStyle(Paint.Style.STROKE);
-                        }
-                        @Override
-                        protected int mask() { return SWEEP_STROKE_WIDTH_BIT; }
-                    },
-                    "fillAndStroke", new DisplayModifier() {
-                        @Override
-                        public void modifyDrawing(Paint paint, Canvas canvas) {
-                            paint.setStyle(Paint.Style.FILL_AND_STROKE);
-                        }
-
-                        @Override
-                        protected int mask() { return SWEEP_STROKE_WIDTH_BIT; }
-                    }),
-            "strokeWidth", Map.of(
-                    "hair", new DisplayModifier() {
-                        @Override
-                        public void modifyDrawing(Paint paint, Canvas canvas) {
-                            paint.setStrokeWidth(0);
-                        }
-                        @Override
-                        protected int mask() { return SWEEP_STROKE_WIDTH_BIT; }
-                    },
-                    "0.3", new DisplayModifier() {
-                        @Override
-                        public void modifyDrawing(Paint paint, Canvas canvas) {
-                            paint.setStrokeWidth(0.3f);
-                        }
-                    },
-                    "1", new DisplayModifier() {
-                        @Override
-                        public void modifyDrawing(Paint paint, Canvas canvas) {
-                            paint.setStrokeWidth(1);
-                        }
-                    },
-                    "5", new DisplayModifier() {
-                        @Override
-                        public void modifyDrawing(Paint paint, Canvas canvas) {
-                            paint.setStrokeWidth(5);
-                        }
-                    },
-                    "30", new DisplayModifier() {
-                        @Override
-                        public void modifyDrawing(Paint paint, Canvas canvas) {
-                            paint.setStrokeWidth(30);
-                        }
-                    }),
-            "strokeCap", Map.of(
-                    "butt", new DisplayModifier() {
-                        @Override
-                        public void modifyDrawing(Paint paint, Canvas canvas) {
-                            paint.setStrokeCap(Paint.Cap.BUTT);
-                        }
-                        @Override
-                        protected int mask() { return SWEEP_STROKE_CAP_BIT; }
-                    },
-                    "round", new DisplayModifier() {
-                        @Override
-                        public void modifyDrawing(Paint paint, Canvas canvas) {
-                            paint.setStrokeCap(Paint.Cap.ROUND);
-                        }
-                    },
-                    "square", new DisplayModifier() {
-                        @Override
-                        public void modifyDrawing(Paint paint, Canvas canvas) {
-                            paint.setStrokeCap(Paint.Cap.SQUARE);
-                        }
-                    }),
-            "strokeJoin", Map.of(
-                    "bevel", new DisplayModifier() {
-                        @Override
-                        public void modifyDrawing(Paint paint, Canvas canvas) {
-                            paint.setStrokeJoin(Paint.Join.BEVEL);
-                        }
-                        @Override
-                        protected int mask() { return SWEEP_STROKE_JOIN_BIT; }
-                    },
-                    "round", new DisplayModifier() {
-                        @Override
-                        public void modifyDrawing(Paint paint, Canvas canvas) {
-                            paint.setStrokeJoin(Paint.Join.ROUND);
-                        }
-                    },
-                    "miter", new DisplayModifier() {
-                        @Override
-                        public void modifyDrawing(Paint paint, Canvas canvas) {
-                            paint.setStrokeJoin(Paint.Join.MITER);
-                        }
-                    }),
-                    // TODO: add miter0, miter1 etc to test miter distances
-            "transform", Map.of(
-                    "noTransform", new DisplayModifier() {
-                        @Override
-                        public void modifyDrawing(Paint paint, Canvas canvas) {}
-                        @Override
-                        protected int mask() { return SWEEP_TRANSFORM_BIT; };
-                    },
-                    "rotate5", new DisplayModifier() {
-                        @Override
-                        public void modifyDrawing(Paint paint, Canvas canvas) {
-                            canvas.rotate(5);
-                        }
-                    },
-                    "rotate45", new DisplayModifier() {
-                        @Override
-                        public void modifyDrawing(Paint paint, Canvas canvas) {
-                            canvas.rotate(45);
-                        }
-                    },
-                    "rotate90", new DisplayModifier() {
-                        @Override
-                        public void modifyDrawing(Paint paint, Canvas canvas) {
-                            canvas.rotate(90);
-                            canvas.translate(0, -200);
-                        }
-                    },
-                    "scale2x2", new DisplayModifier() {
-                        @Override
-                        public void modifyDrawing(Paint paint, Canvas canvas) {
-                            canvas.scale(2, 2);
-                        }
-                        @Override
-                        protected int mask() { return SWEEP_TRANSFORM_BIT; };
-                    },
-                    "rot20scl1x4", new DisplayModifier() {
-                        @Override
-                        public void modifyDrawing(Paint paint, Canvas canvas) {
-                            canvas.rotate(20);
-                            canvas.scale(1, 4);
-                        }
-                        @Override
-                        protected int mask() { return SWEEP_TRANSFORM_BIT; };
-                    }),
-            "shader", Map.ofEntries(
-                    entry("noShader", new DisplayModifier() {
-                        @Override
-                        public void modifyDrawing(Paint paint, Canvas canvas) {}
-                        @Override
-                        protected int mask() { return SWEEP_SHADER_BIT; };
-                    }),
-                    entry("repeatShader", new DisplayModifier() {
-                        @Override
-                        public void modifyDrawing(Paint paint, Canvas canvas) {
-                            paint.setShader(ResourceModifiers.instance().mRepeatShader);
-                        }
-                        @Override
-                        protected int mask() { return SWEEP_SHADER_BIT; };
-                    }),
-                    entry("translatedShader", new DisplayModifier() {
-                        @Override
-                        public void modifyDrawing(Paint paint, Canvas canvas) {
-                            paint.setShader(ResourceModifiers.instance().mTranslatedShader);
-                        }
-                    }),
-                    entry("scaledShader", new DisplayModifier() {
-                        @Override
-                        public void modifyDrawing(Paint paint, Canvas canvas) {
-                            paint.setShader(ResourceModifiers.instance().mScaledShader);
-                        }
-                    }),
-                    entry("horGradient", new DisplayModifier() {
-                        @Override
-                        public void modifyDrawing(Paint paint, Canvas canvas) {
-                            paint.setShader(ResourceModifiers.instance().mHorGradient);
-                        }
-                    }),
-                    entry("diagGradient", new DisplayModifier() {
-                        @Override
-                        public void modifyDrawing(Paint paint, Canvas canvas) {
-                            paint.setShader(ResourceModifiers.instance().mDiagGradient);
-                        }
-                        @Override
-                        protected int mask() { return SWEEP_SHADER_BIT; };
-                    }),
-                    entry("vertGradient", new DisplayModifier() {
-                        @Override
-                        public void modifyDrawing(Paint paint, Canvas canvas) {
-                            paint.setShader(ResourceModifiers.instance().mVertGradient);
-                        }
-                    }),
-                    entry("radGradient", new DisplayModifier() {
-                        @Override
-                        public void modifyDrawing(Paint paint, Canvas canvas) {
-                            paint.setShader(ResourceModifiers.instance().mRadGradient);
-                        }
-                    }),
-                    entry("sweepGradient", new DisplayModifier() {
-                        @Override
-                        public void modifyDrawing(Paint paint, Canvas canvas) {
-                            paint.setShader(ResourceModifiers.instance().mSweepGradient);
-                        }
-                    }),
-                    entry("composeShader", new DisplayModifier() {
-                        @Override
-                        public void modifyDrawing(Paint paint, Canvas canvas) {
-                            paint.setShader(ResourceModifiers.instance().mComposeShader);
-                        }
-                    }),
-                    entry("bad composeShader", new DisplayModifier() {
-                        @Override
-                        public void modifyDrawing(Paint paint, Canvas canvas) {
-                            paint.setShader(ResourceModifiers.instance().mBadComposeShader);
-                        }
-                    }),
-                    entry("bad composeShader 2", new DisplayModifier() {
-                        @Override
-                        public void modifyDrawing(Paint paint, Canvas canvas) {
-                            paint.setShader(ResourceModifiers.instance().mAnotherBadComposeShader);
-                        }
-                    })),
-            "drawing", Map.ofEntries(
-                    entry("roundRect", new DisplayModifier() {
-                        @Override
-                        public void modifyDrawing(Paint paint, Canvas canvas) {
-                            canvas.drawRoundRect(gRect, 20, 20, paint);
-                        }
-                    }),
-                    entry("rect", new DisplayModifier() {
-                        @Override
-                        public void modifyDrawing(Paint paint, Canvas canvas) {
-                            canvas.drawRect(gRect, paint);
-                        }
-                        @Override
-                        protected int mask() { return SWEEP_SHADER_BIT | SWEEP_STROKE_CAP_BIT; };
-                    }),
-                    entry("circle", new DisplayModifier() {
-                        @Override
-                        public void modifyDrawing(Paint paint, Canvas canvas) {
-                            canvas.drawCircle(100, 100, 75, paint);
-                        }
-                    }),
-                    entry("oval", new DisplayModifier() {
-                        @Override
-                        public void modifyDrawing(Paint paint, Canvas canvas) {
-                            canvas.drawOval(gRect, paint);
-                        }
-                    }),
-                    entry("lines", new DisplayModifier() {
-                        @Override
-                        public void modifyDrawing(Paint paint, Canvas canvas) {
-                            canvas.drawLines(gLinePts, paint);
-                        }
-                        @Override
-                        protected int mask() { return SWEEP_STROKE_CAP_BIT; };
-                    }),
-                    entry("plusPoints", new DisplayModifier() {
-                        @Override
-                        public void modifyDrawing(Paint paint, Canvas canvas) {
-                            canvas.drawPoints(gPts, paint);
-                        }
-                    }),
-                    entry("text", new DisplayModifier() {
-                        @Override
-                        public void modifyDrawing(Paint paint, Canvas canvas) {
-                            paint.setTextSize(36);
-                            canvas.drawText("TEXTTEST", 0, 50, paint);
-                        }
-                    }),
-                    entry("shadowtext", new DisplayModifier() {
-                        @Override
-                        public void modifyDrawing(Paint paint, Canvas canvas) {
-                            paint.setTextSize(36);
-                            paint.setShadowLayer(3.0f, 0.0f, 3.0f, 0xffff00ff);
-                            canvas.drawText("TEXTTEST", 0, 50, paint);
-                        }
-                    }),
-                    entry("bitmapMesh", new DisplayModifier() {
-                        @Override
-                        public void modifyDrawing(Paint paint, Canvas canvas) {
-                            canvas.drawBitmapMesh(ResourceModifiers.instance().mBitmap, 3, 3,
-                                    ResourceModifiers.instance().mBitmapVertices, 0, null, 0, null);
-                        }
-                    }),
-                    entry("arc", new DisplayModifier() {
-                        @Override
-                        public void modifyDrawing(Paint paint, Canvas canvas) {
-                            canvas.drawArc(gRect, 260, 285, false, paint);
-                        }
-                        @Override
-                        protected int mask() { return SWEEP_STROKE_CAP_BIT; };
-                    }),
-                    entry("arcFromCenter", new DisplayModifier() {
-                        @Override
-                        public void modifyDrawing(Paint paint, Canvas canvas) {
-                            canvas.drawArc(gRect, 260, 285, true, paint);
-                        }
-                        @Override
-                        protected int mask() { return SWEEP_STROKE_JOIN_BIT; };
-                    })));
-            // WARNING: DON'T PUT MORE MAPS BELOW THIS
-
-    private static Map<String, DisplayModifier> getMapAtIndex(int index) {
-        for (Map<String, DisplayModifier> map : gMaps.values()) {
-            if (index == 0) {
-                return map;
-            }
-            index--;
-        }
-        return null;
-    }
-
-    // indices instead of iterators for easier bidirectional traversal
-    private static final int mIndices[] = new int[gMaps.size()];
-    private static final String[] mLastAppliedModifications = new String[gMaps.size()];
-
-    private static boolean stepInternal(boolean forward) {
-        int modifierMapIndex = gMaps.size() - 1;
-        while (modifierMapIndex >= 0) {
-            Map<String, DisplayModifier> map = getMapAtIndex(modifierMapIndex);
-            mIndices[modifierMapIndex] += (forward ? 1 : -1);
-
-            if (mIndices[modifierMapIndex] >= 0 && mIndices[modifierMapIndex] < map.size()) {
-                break;
-            }
-
-            mIndices[modifierMapIndex] = (forward ? 0 : map.size() - 1);
-            modifierMapIndex--;
-        }
-        return modifierMapIndex < 0; // true if resetting
-    }
-
-    public static boolean step() {
-        boolean ret = false;
-        do {
-            ret |= stepInternal(true);
-        } while (!checkModificationStateMask());
-        return ret;
-    }
-
-    public static boolean stepBack() {
-        boolean ret = false;
-        do {
-            ret |= stepInternal(false);
-        } while (!checkModificationStateMask());
-        return ret;
-    }
-
-    private static boolean checkModificationStateMask() {
-        int operatorMask = 0x0;
-        int mapIndex = 0;
-        for (Map<String, DisplayModifier> map : gMaps.values()) {
-            int displayModifierIndex = mIndices[mapIndex];
-            for (Entry<String, DisplayModifier> modifierEntry : map.entrySet()) {
-                if (displayModifierIndex == 0) {
-                    mLastAppliedModifications[mapIndex] = modifierEntry.getKey();
-                    operatorMask |= modifierEntry.getValue().mask();
-                    break;
-                }
-                displayModifierIndex--;
-            }
-            mapIndex++;
-        }
-        return operatorMask == TOTAL_MASK;
-    }
-
-    public static void apply(Paint paint, Canvas canvas) {
-        int mapIndex = 0;
-        for (Map<String, DisplayModifier> map : gMaps.values()) {
-            int displayModifierIndex = mIndices[mapIndex];
-            for (Entry<String, DisplayModifier> modifierEntry : map.entrySet()) {
-                if (displayModifierIndex == 0) {
-                    mLastAppliedModifications[mapIndex] = modifierEntry.getKey();
-                    modifierEntry.getValue().modifyDrawing(paint, canvas);
-                    break;
-                }
-                displayModifierIndex--;
-            }
-            mapIndex++;
-        }
-    }
-
-    public static String[] getLastAppliedModifications() {
-        return mLastAppliedModifications.clone();
-    }
-
-    public static String[][] getStrings() {
-        String[][] keys = new String[gMaps.size()][];
-
-        int i = 0;
-        for (Map<String, DisplayModifier> map : gMaps.values()) {
-            keys[i] = new String[map.size()];
-            int j = 0;
-            for (String key : map.keySet()) {
-                keys[i][j++] = key;
-            }
-            i++;
-        }
-
-        return keys;
-    }
-
-    public static void setIndex(int mapIndex, int newIndexValue) {
-        mIndices[mapIndex] = newIndexValue;
-    }
-
-    public static int[] getIndices() {
-        return mIndices;
-    }
-}
diff --git a/tests/CanvasCompare/src/com/android/test/hwuicompare/ErrorCalculator.java b/tests/CanvasCompare/src/com/android/test/hwuicompare/ErrorCalculator.java
deleted file mode 100644
index d402699..0000000
--- a/tests/CanvasCompare/src/com/android/test/hwuicompare/ErrorCalculator.java
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Copyright (C) 2012 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.test.hwuicompare;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.Color;
-import android.renderscript.Allocation;
-import android.renderscript.Element;
-import android.renderscript.RenderScript;
-import android.util.Log;
-
-public class ErrorCalculator {
-    private static final String LOG_TAG = "ErrorCalculator";
-    private static final int REGION_SIZE = 8;
-
-    private static final boolean LOG_TIMING = false;
-    private static final boolean LOG_CALC = false;
-
-    private RenderScript mRS;
-    private Allocation mIdealPixelsAllocation;
-    private Allocation mGivenPixelsAllocation;
-    private Allocation mOutputPixelsAllocation;
-
-    private Allocation mInputRowsAllocation;
-    private Allocation mOutputRegionsAllocation;
-
-    private ScriptC_errorCalculator mScript;
-
-    private int[] mOutputRowRegions;
-
-    public ErrorCalculator(Context c, Resources resources) {
-        int width = resources.getDimensionPixelSize(R.dimen.layer_width);
-        int height = resources.getDimensionPixelSize(R.dimen.layer_height);
-        mOutputRowRegions = new int[height / REGION_SIZE];
-
-        mRS = RenderScript.create(c);
-        int[] rowIndices = new int[height / REGION_SIZE];
-        for (int i = 0; i < rowIndices.length; i++)
-            rowIndices[i] = i * REGION_SIZE;
-
-        mScript = new ScriptC_errorCalculator(mRS);
-        mScript.set_HEIGHT(height);
-        mScript.set_WIDTH(width);
-        mScript.set_REGION_SIZE(REGION_SIZE);
-
-        mInputRowsAllocation = Allocation.createSized(mRS, Element.I32(mRS), rowIndices.length,
-                Allocation.USAGE_SCRIPT);
-        mInputRowsAllocation.copyFrom(rowIndices);
-        mOutputRegionsAllocation = Allocation.createSized(mRS, Element.I32(mRS),
-                mOutputRowRegions.length, Allocation.USAGE_SCRIPT);
-    }
-
-
-    private static long startMillis, middleMillis;
-
-    public float calcErrorRS(Bitmap ideal, Bitmap given) {
-        if (LOG_TIMING) {
-            startMillis = System.currentTimeMillis();
-        }
-
-        mIdealPixelsAllocation = Allocation.createFromBitmap(mRS, ideal,
-                Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);
-        mGivenPixelsAllocation = Allocation.createFromBitmap(mRS, given,
-                Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);
-
-        mScript.set_ideal(mIdealPixelsAllocation);
-        mScript.set_given(mGivenPixelsAllocation);
-
-        mScript.forEach_countInterestingRegions(mInputRowsAllocation, mOutputRegionsAllocation);
-        mOutputRegionsAllocation.copyTo(mOutputRowRegions);
-
-        int regionCount = 0;
-        for (int region : mOutputRowRegions) {
-            regionCount += region;
-        }
-        int interestingPixels = Math.max(1, regionCount) * REGION_SIZE * REGION_SIZE;
-
-        if (LOG_TIMING) {
-            long startMillis2 = System.currentTimeMillis();
-        }
-
-        mScript.forEach_accumulateError(mInputRowsAllocation, mOutputRegionsAllocation);
-        mOutputRegionsAllocation.copyTo(mOutputRowRegions);
-        float totalError = 0;
-        for (int row : mOutputRowRegions) {
-            totalError += row;
-        }
-        totalError /= 1024.0f;
-
-        if (LOG_TIMING) {
-            long finalMillis = System.currentTimeMillis();
-            Log.d(LOG_TAG, "rs: first part took " + (middleMillis - startMillis) + "ms");
-            Log.d(LOG_TAG, "rs: last part took " + (finalMillis - middleMillis) + "ms");
-        }
-        if (LOG_CALC) {
-            Log.d(LOG_TAG, "rs: error " + totalError + ", pixels " + interestingPixels);
-        }
-        return totalError / interestingPixels;
-    }
-
-    public void calcErrorHeatmapRS(Bitmap ideal, Bitmap given, Bitmap output) {
-        mIdealPixelsAllocation = Allocation.createFromBitmap(mRS, ideal,
-                Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);
-        mGivenPixelsAllocation = Allocation.createFromBitmap(mRS, given,
-                Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);
-
-        mScript.set_ideal(mIdealPixelsAllocation);
-        mScript.set_given(mGivenPixelsAllocation);
-
-        mOutputPixelsAllocation = Allocation.createFromBitmap(mRS, output,
-                Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);
-        mScript.forEach_displayDifference(mOutputPixelsAllocation, mOutputPixelsAllocation);
-        mOutputPixelsAllocation.copyTo(output);
-    }
-
-    public static float calcError(Bitmap ideal, Bitmap given) {
-        if (LOG_TIMING) {
-            startMillis = System.currentTimeMillis();
-        }
-
-        int interestingRegions = 0;
-        for (int x = 0; x < ideal.getWidth(); x += REGION_SIZE) {
-            for (int y = 0; y < ideal.getWidth(); y += REGION_SIZE) {
-                if (inspectRegion(ideal, x, y)) {
-                    interestingRegions++;
-                }
-            }
-        }
-
-        int interestingPixels = Math.max(1, interestingRegions) * REGION_SIZE * REGION_SIZE;
-
-        if (LOG_TIMING) {
-            long startMillis2 = System.currentTimeMillis();
-        }
-
-        float totalError = 0;
-        for (int x = 0; x < ideal.getWidth(); x++) {
-            for (int y = 0; y < ideal.getHeight(); y++) {
-                int idealColor = ideal.getPixel(x, y);
-                int givenColor = given.getPixel(x, y);
-                if (idealColor == givenColor)
-                    continue;
-                totalError += Math.abs(Color.red(idealColor) - Color.red(givenColor));
-                totalError += Math.abs(Color.green(idealColor) - Color.green(givenColor));
-                totalError += Math.abs(Color.blue(idealColor) - Color.blue(givenColor));
-                totalError += Math.abs(Color.alpha(idealColor) - Color.alpha(givenColor));
-            }
-        }
-        totalError /= 1024.0f;
-        if (LOG_TIMING) {
-            long finalMillis = System.currentTimeMillis();
-            Log.d(LOG_TAG, "dvk: first part took " + (middleMillis - startMillis) + "ms");
-            Log.d(LOG_TAG, "dvk: last part took " + (finalMillis - middleMillis) + "ms");
-        }
-        if (LOG_CALC) {
-            Log.d(LOG_TAG, "dvk: error " + totalError + ", pixels " + interestingPixels);
-        }
-        return totalError / interestingPixels;
-    }
-
-    private static boolean inspectRegion(Bitmap ideal, int x, int y) {
-        int regionColor = ideal.getPixel(x, y);
-        for (int i = 0; i < REGION_SIZE; i++) {
-            for (int j = 0; j < REGION_SIZE; j++) {
-                if (ideal.getPixel(x + i, y + j) != regionColor)
-                    return true;
-            }
-        }
-        return false;
-    }
-}
diff --git a/tests/CanvasCompare/src/com/android/test/hwuicompare/MainView.java b/tests/CanvasCompare/src/com/android/test/hwuicompare/MainView.java
deleted file mode 100644
index 454fe7b..0000000
--- a/tests/CanvasCompare/src/com/android/test/hwuicompare/MainView.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2012 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.test.hwuicompare;
-
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.util.AttributeSet;
-import android.view.View;
-
-public class MainView extends View {
-    Paint mPaint = new Paint();
-
-    public MainView(Context context) {
-        super(context);
-    }
-
-    public MainView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public MainView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-    }
-
-    @Override
-    protected void onDraw(Canvas canvas) {
-        super.onDraw(canvas);
-
-        mPaint.reset();
-        DisplayModifier.apply(mPaint, canvas);
-
-        if (mDrawCallback != null) {
-            mDrawCallback.run();
-        }
-    }
-
-    private Runnable mDrawCallback;
-    public void addDrawCallback(Runnable drawCallback) {
-        mDrawCallback = drawCallback;
-    }
-}
diff --git a/tests/CanvasCompare/src/com/android/test/hwuicompare/ManualActivity.java b/tests/CanvasCompare/src/com/android/test/hwuicompare/ManualActivity.java
deleted file mode 100644
index 405ff65..0000000
--- a/tests/CanvasCompare/src/com/android/test/hwuicompare/ManualActivity.java
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * Copyright (C) 2012 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.test.hwuicompare;
-
-import com.android.test.hwuicompare.R;
-
-import android.graphics.Bitmap;
-import android.graphics.Color;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.widget.AdapterView;
-import android.widget.ArrayAdapter;
-import android.widget.Button;
-import android.widget.ImageButton;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.Spinner;
-import android.widget.TextView;
-
-public class ManualActivity extends CompareActivity {
-    private static final String LOG_TAG = "ManualActivity";
-    private ImageView mCompareImageView;
-    private Bitmap mCompareBitmap;
-    private TextView mErrorTextView;
-    private MainView mSoftwareView;
-
-    private static final int COMPARE_VIEW_UNINITIALIZED = -1;
-    private static final int COMPARE_VIEW_HARDWARE = 0;
-    private static final int COMPARE_VIEW_SOFTWARE = 1;
-    private static final int COMPARE_VIEW_HEATMAP = 2; // TODO: add more like this? any ideas?
-
-    private int mCompareImageViewState = COMPARE_VIEW_UNINITIALIZED;
-    private int mLastCompareImageViewState = COMPARE_VIEW_UNINITIALIZED;
-
-    Runnable mRunnable = new Runnable() {
-        @Override
-        public void run() {
-            Log.d(LOG_TAG, "mRunnable running, mRedrewFlag = " + mRedrewFlag);
-
-            if (mRedrewFlag) {
-                loadBitmaps();
-                // recalculate error
-                float error = mErrorCalculator.calcErrorRS(mSoftwareBitmap, mHardwareBitmap);
-                String modname = "";
-                for (String s : DisplayModifier.getLastAppliedModifications()) {
-                    modname = modname.concat(s + ".");
-                }
-
-                Log.d(LOG_TAG, "error for " + modname + " is " + error);
-                mErrorTextView.setText(String.format("%.4f", error));
-            }
-
-            if (mCompareImageViewState != mLastCompareImageViewState || mRedrewFlag) {
-                switch (mCompareImageViewState) {
-                    case COMPARE_VIEW_UNINITIALIZED:
-                        // set to hardware
-                    case COMPARE_VIEW_HARDWARE:
-                        mCompareImageView.setImageBitmap(mHardwareBitmap);
-                        break;
-                    case COMPARE_VIEW_SOFTWARE:
-                        mCompareImageView.setImageBitmap(mSoftwareBitmap);
-                        break;
-                    case COMPARE_VIEW_HEATMAP:
-                        mErrorCalculator.calcErrorHeatmapRS(mSoftwareBitmap, mHardwareBitmap,
-                                mCompareBitmap);
-                        mCompareImageView.setImageBitmap(mCompareBitmap);
-                        break;
-                }
-                mCompareImageView.getDrawable().setFilterBitmap(false);
-                mCompareImageView.invalidate();
-            }
-
-            mLastCompareImageViewState = mCompareImageViewState;
-            mRedrewFlag = false;
-            mHandler.removeCallbacks(mRunnable);
-        }
-    };
-
-    private void redrawViews() {
-        mHardwareView.invalidate();
-        mSoftwareView.invalidate();
-    }
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.manual_layout);
-        onCreateCommon(mRunnable);
-
-        mSoftwareView = (MainView) findViewById(R.id.software_view);
-        mSoftwareView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
-        mSoftwareView.setBackgroundColor(Color.WHITE);
-        mSoftwareView.addDrawCallback(mDrawCallback);
-
-        mCompareImageView = (ImageView) findViewById(R.id.compare_image_view);
-
-        int width = getResources().getDimensionPixelSize(R.dimen.layer_width);
-        int height = getResources().getDimensionPixelSize(R.dimen.layer_height);
-        mCompareBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
-
-        mErrorTextView = (TextView) findViewById(R.id.current_error);
-        ((ImageButton) findViewById(R.id.next)).setOnClickListener(new OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                DisplayModifier.step();
-                updateSpinners();
-                redrawViews();
-            }
-        });
-        ((ImageButton) findViewById(R.id.previous)).setOnClickListener(new OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                DisplayModifier.stepBack();
-                updateSpinners();
-                redrawViews();
-            }
-        });
-        ((Button) findViewById(R.id.show_hardware_version))
-                .setOnClickListener(new OnClickListener() {
-                    @Override
-                    public void onClick(View v) {
-                        mCompareImageViewState = COMPARE_VIEW_HARDWARE;
-                        mHandler.post(mRunnable);
-                    }
-                });
-        ((Button) findViewById(R.id.show_software_version))
-                .setOnClickListener(new OnClickListener() {
-                    @Override
-                    public void onClick(View v) {
-                        mCompareImageViewState = COMPARE_VIEW_SOFTWARE;
-                        mHandler.post(mRunnable);
-                    }
-                });
-        ((Button) findViewById(R.id.show_error_heatmap)).setOnClickListener(new OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                mCompareImageViewState = COMPARE_VIEW_HEATMAP;
-                mHandler.post(mRunnable);
-            }
-        });
-
-        buildSpinnerLayout();
-    }
-
-    private class DisplayModifierSpinner extends Spinner {
-        private final int mIndex;
-
-        public DisplayModifierSpinner(int index) {
-            super(ManualActivity.this);
-            mIndex = index;
-            setOnItemSelectedListener(new OnItemSelectedListener() {
-
-                @Override
-                public void onItemSelected(AdapterView<?> parentView, View selectedItem,
-                        int position, long id) {
-                    DisplayModifier.setIndex(mIndex, position);
-                    redrawViews();
-                }
-
-                @Override
-                public void onNothingSelected(AdapterView<?> parentView) {
-                }
-            });
-        }
-    }
-
-    private Spinner[] mSpinners;
-
-    private void buildSpinnerLayout() {
-        LinearLayout layout = (LinearLayout) findViewById(R.id.spinner_layout);
-        String[][] mapsStrings = DisplayModifier.getStrings();
-        mSpinners = new Spinner[mapsStrings.length];
-        int index = 0;
-        for (String[] spinnerValues : mapsStrings) {
-            mSpinners[index] = new DisplayModifierSpinner(index);
-            mSpinners[index].setAdapter(new ArrayAdapter<String>(this,
-                    android.R.layout.simple_spinner_dropdown_item, spinnerValues));
-            layout.addView(mSpinners[index]);
-            index++;
-        }
-        Log.d(LOG_TAG, "created " + index + " spinners");
-    }
-
-    private void updateSpinners() {
-        int[] indices = DisplayModifier.getIndices();
-        for (int i = 0; i < mSpinners.length; i++) {
-            mSpinners[i].setSelection(indices[i]);
-        }
-    }
-
-    @Override
-    protected boolean forceRecreateBitmaps() {
-        // continually recreate bitmaps to avoid modifying bitmaps currently being drawn
-        return true;
-    }
-}
diff --git a/tests/CanvasCompare/src/com/android/test/hwuicompare/ResourceModifiers.java b/tests/CanvasCompare/src/com/android/test/hwuicompare/ResourceModifiers.java
deleted file mode 100644
index d522481..0000000
--- a/tests/CanvasCompare/src/com/android/test/hwuicompare/ResourceModifiers.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2012 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.test.hwuicompare;
-
-import com.android.test.hwuicompare.R;
-
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.BitmapShader;
-import android.graphics.Color;
-import android.graphics.ComposeShader;
-import android.graphics.LinearGradient;
-import android.graphics.PorterDuff;
-import android.graphics.RadialGradient;
-import android.graphics.SweepGradient;
-import android.graphics.Matrix;
-import android.graphics.Shader;
-
-public class ResourceModifiers {
-        public final BitmapShader mRepeatShader;
-        public final BitmapShader mTranslatedShader;
-        public final BitmapShader mScaledShader;
-        private final int mTexWidth;
-        private final int mTexHeight;
-        private final float mDrawWidth;
-        private final float mDrawHeight;
-        public final LinearGradient mHorGradient;
-        public final LinearGradient mDiagGradient;
-        public final LinearGradient mVertGradient;
-        public final RadialGradient mRadGradient;
-        public final SweepGradient mSweepGradient;
-        public final ComposeShader mComposeShader;
-        public final ComposeShader mBadComposeShader;
-        public final ComposeShader mAnotherBadComposeShader;
-        public final Bitmap mBitmap;
-        private final Matrix mMtx1;
-        private final Matrix mMtx2;
-        private final Matrix mMtx3;
-
-        public final float[] mBitmapVertices;
-        public final int[] mBitmapColors;
-
-        private static ResourceModifiers sInstance = null;
-        public static ResourceModifiers instance() { return sInstance; }
-        public static void init(Resources resources) {
-            sInstance = new ResourceModifiers(resources);
-        }
-
-        public ResourceModifiers(Resources resources) {
-            mBitmap = BitmapFactory.decodeResource(resources, R.drawable.sunset1);
-            mTexWidth = mBitmap.getWidth();
-            mTexHeight = mBitmap.getHeight();
-
-            mDrawWidth = resources.getDimensionPixelSize(R.dimen.layer_width);
-            mDrawHeight = resources.getDimensionPixelSize(R.dimen.layer_height);
-
-            mRepeatShader = new BitmapShader(mBitmap, Shader.TileMode.REPEAT,
-                    Shader.TileMode.REPEAT);
-
-            mTranslatedShader = new BitmapShader(mBitmap, Shader.TileMode.REPEAT,
-                    Shader.TileMode.REPEAT);
-            mMtx1 = new Matrix();
-            mMtx1.setTranslate(mTexWidth / 2.0f, mTexHeight / 2.0f);
-            mMtx1.postRotate(45, 0, 0);
-            mTranslatedShader.setLocalMatrix(mMtx1);
-
-            mScaledShader = new BitmapShader(mBitmap, Shader.TileMode.MIRROR,
-                    Shader.TileMode.MIRROR);
-            mMtx2 = new Matrix();
-            mMtx2.setScale(0.5f, 0.5f);
-            mScaledShader.setLocalMatrix(mMtx2);
-
-            mHorGradient = new LinearGradient(0.0f, 0.0f, 1.0f, 0.0f,
-                    Color.RED, Color.GREEN, Shader.TileMode.CLAMP);
-            mMtx3 = new Matrix();
-            mMtx3.setScale(mDrawHeight, 1.0f);
-            mMtx3.postRotate(-90.0f);
-            mMtx3.postTranslate(0.0f, mDrawHeight);
-            mHorGradient.setLocalMatrix(mMtx3);
-
-            mDiagGradient = new LinearGradient(0.0f, 0.0f, mDrawWidth / 2.0f, mDrawHeight / 2.0f,
-                    Color.BLUE, Color.RED, Shader.TileMode.CLAMP);
-
-            mVertGradient = new LinearGradient(0.0f, 0.0f, 0.0f, mDrawHeight / 2.0f,
-                    Color.YELLOW, Color.MAGENTA, Shader.TileMode.MIRROR);
-
-            mSweepGradient = new SweepGradient(mDrawWidth / 2.0f, mDrawHeight / 2.0f,
-                    Color.YELLOW, Color.MAGENTA);
-
-            mComposeShader = new ComposeShader(mRepeatShader, mHorGradient,
-                    PorterDuff.Mode.MULTIPLY);
-
-            final float width = mBitmap.getWidth() / 8.0f;
-            final float height = mBitmap.getHeight() / 8.0f;
-
-            mBitmapVertices = new float[] {
-                0.0f, 0.0f, width, 0.0f, width * 2, 0.0f, width * 3, 0.0f,
-                0.0f, height, width, height, width * 2, height, width * 4, height,
-                0.0f, height * 2, width, height * 2, width * 2, height * 2, width * 3, height * 2,
-                0.0f, height * 4, width, height * 4, width * 2, height * 4, width * 4, height * 4,
-            };
-
-            mBitmapColors = new int[] {
-                0xffff0000, 0xff00ff00, 0xff0000ff, 0xffff0000,
-                0xff0000ff, 0xffff0000, 0xff00ff00, 0xff00ff00,
-                0xff00ff00, 0xff0000ff, 0xffff0000, 0xff00ff00,
-                0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ff0000,
-            };
-
-            // Use a repeating gradient with many colors to test the non simple case.
-            mRadGradient = new RadialGradient(mDrawWidth / 4.0f, mDrawHeight / 4.0f, 4.0f,
-                    mBitmapColors, null, Shader.TileMode.REPEAT);
-
-            mBadComposeShader = new ComposeShader(mRadGradient, mComposeShader,
-                    PorterDuff.Mode.MULTIPLY);
-
-            mAnotherBadComposeShader = new ComposeShader(mRadGradient, mVertGradient,
-                    PorterDuff.Mode.MULTIPLY);
-        }
-
-}
diff --git a/tests/CanvasCompare/src/com/android/test/hwuicompare/Test.java b/tests/CanvasCompare/src/com/android/test/hwuicompare/Test.java
deleted file mode 100644
index 1ff153c..0000000
--- a/tests/CanvasCompare/src/com/android/test/hwuicompare/Test.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package com.android.test.hwuicompare;
-
-import com.android.test.hwuicompare.AutomaticActivity.FinalCallback;
-
-import android.os.Bundle;
-import android.test.ActivityInstrumentationTestCase2;
-
-public class Test extends ActivityInstrumentationTestCase2<AutomaticActivity> {
-    AutomaticActivity mActivity;
-    private Bundle mBundle;
-
-    public Test() {
-        super(AutomaticActivity.class);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mBundle = new Bundle();
-        mActivity = getActivity();
-        mActivity.setFinalCallback(new FinalCallback() {
-
-            @Override
-            void report(String key, float value) {
-                mBundle.putFloat(key, value);
-            }
-            @Override
-            void complete() {
-                synchronized(mBundle) {
-                    mBundle.notify();
-                }
-            }
-        });
-    }
-
-    public void testCanvas() {
-        synchronized(mBundle) {
-            try {
-                mBundle.wait();
-            } catch (InterruptedException e) {
-                e.printStackTrace();
-            }
-        }
-        getInstrumentation().sendStatus(0, mBundle);
-    }
-}
diff --git a/tests/CanvasCompare/src/com/android/test/hwuicompare/errorCalculator.rscript b/tests/CanvasCompare/src/com/android/test/hwuicompare/errorCalculator.rscript
deleted file mode 100644
index 0a1742e..0000000
--- a/tests/CanvasCompare/src/com/android/test/hwuicompare/errorCalculator.rscript
+++ /dev/null
@@ -1,61 +0,0 @@
-#pragma version(1)
-#pragma rs java_package_name(com.android.test.hwuicompare)
-
-int REGION_SIZE;
-int WIDTH;
-int HEIGHT;
-
-rs_allocation ideal;
-rs_allocation given;
-
-void countInterestingRegions(const int32_t *v_in, int32_t *v_out) {
-    int y = v_in[0];
-    v_out[0] = 0;
-
-    for (int x = 0; x < HEIGHT; x += REGION_SIZE) {
-        bool interestingRegion = false;
-        uchar4 regionColor = rsGetElementAt_uchar4(ideal, x, y);
-        for (int i = 0; i < REGION_SIZE && !interestingRegion; i++) {
-            for (int j = 0; j < REGION_SIZE && !interestingRegion; j++) {
-                uchar4 testVal = rsGetElementAt_uchar4(ideal, x + j, y + i);
-                interestingRegion |= (testVal.r != regionColor.r);
-                interestingRegion |= (testVal.g != regionColor.g);
-                interestingRegion |= (testVal.b != regionColor.b);
-                interestingRegion |= (testVal.a != regionColor.a);
-            }
-        }
-        if (interestingRegion) {
-            v_out[0]++;
-        }
-    }
-}
-
-void accumulateError(const int32_t *v_in, int32_t *v_out) {
-    int startY = v_in[0];
-    int error = 0;
-    for (int y = startY; y < startY + REGION_SIZE; y++) {
-        for (int x = 0; x < HEIGHT; x++) {
-            uchar4 idealPixel = rsGetElementAt_uchar4(ideal, x, y);
-            uchar4 givenPixel = rsGetElementAt_uchar4(given, x, y);
-
-            error += abs(idealPixel.x - givenPixel.x);
-            error += abs(idealPixel.y - givenPixel.y);
-            error += abs(idealPixel.z - givenPixel.z);
-            error += abs(idealPixel.w - givenPixel.w);
-        }
-    }
-    v_out[0] = error;
-}
-
-void displayDifference(const uchar4 *v_in, uchar4 *v_out, uint32_t x, uint32_t y) {
-    float4 idealPixel = rsGetElementAt_float4(ideal, x, y);
-    float4 givenPixel = rsGetElementAt_float4(given, x, y);
-
-    float4 diff = idealPixel - givenPixel;
-    float totalDiff = diff.x + diff.y + diff.z + diff.w;
-    if (totalDiff < 0) {
-        v_out[0] = rsPackColorTo8888(0, 0, clamp(-totalDiff/2.f, 0.f, 1.f));
-    } else {
-        v_out[0] = rsPackColorTo8888(clamp(totalDiff/2.f, 0.f, 1.f), 0, 0);
-    }
-}