diff options
62 files changed, 555 insertions, 2066 deletions
diff --git a/core/api/current.txt b/core/api/current.txt index 4a8f0481cef2..46318ae6f7ef 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -20611,6 +20611,7 @@ package android.media { field public static final int DUAL_MONO_MODE_RR = 3; // 0x3 field public static final int ENCAPSULATION_METADATA_TYPE_DVB_AD_DESCRIPTOR = 2; // 0x2 field public static final int ENCAPSULATION_METADATA_TYPE_FRAMEWORK_TUNER = 1; // 0x1 + field public static final int ENCAPSULATION_METADATA_TYPE_SUPPLEMENTARY_AUDIO_PLACEMENT = 3; // 0x3 field public static final int ENCAPSULATION_MODE_ELEMENTARY_STREAM = 1; // 0x1 field public static final int ENCAPSULATION_MODE_NONE = 0; // 0x0 field public static final int ERROR = -1; // 0xffffffff @@ -20629,6 +20630,9 @@ package android.media { field public static final int STATE_NO_STATIC_DATA = 2; // 0x2 field public static final int STATE_UNINITIALIZED = 0; // 0x0 field public static final int SUCCESS = 0; // 0x0 + field public static final int SUPPLEMENTARY_AUDIO_PLACEMENT_LEFT = 1; // 0x1 + field public static final int SUPPLEMENTARY_AUDIO_PLACEMENT_NORMAL = 0; // 0x0 + field public static final int SUPPLEMENTARY_AUDIO_PLACEMENT_RIGHT = 2; // 0x2 field public static final int WRITE_BLOCKING = 0; // 0x0 field public static final int WRITE_NON_BLOCKING = 1; // 0x1 } @@ -25917,6 +25921,7 @@ package android.media.tv { 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 +26082,7 @@ package android.media.tv { 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 8a1d6f2c9fcf..1d3993106a8f 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -760,10 +760,12 @@ package android.app { 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); diff --git a/core/api/test-current.txt b/core/api/test-current.txt index c38c88749bdb..2d86051d074e 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -1696,7 +1696,10 @@ package android.os { public class Build { method public static boolean is64BitAbi(String); method public static boolean isDebuggable(); + field @Nullable public static final String BRAND_FOR_ATTESTATION; field public static final boolean IS_EMULATOR; + field @Nullable public static final String MODEL_FOR_ATTESTATION; + field @Nullable public static final String PRODUCT_FOR_ATTESTATION; } public static class Build.VERSION { diff --git a/core/java/android/app/BroadcastOptions.java b/core/java/android/app/BroadcastOptions.java index 8b7b7eb932ad..16c5b0845107 100644 --- a/core/java/android/app/BroadcastOptions.java +++ b/core/java/android/app/BroadcastOptions.java @@ -66,6 +66,7 @@ public class BroadcastOptions extends ComponentOptions { 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 @@ public class BroadcastOptions extends ComponentOptions { } /** + * 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/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index d83ad3d0850a..f1e37243003c 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -1530,6 +1530,14 @@ public abstract class PackageManager { */ public static final int INSTALL_DISABLE_ALLOWED_APEX_UPDATE_CHECK = 0x00400000; + /** + * Flag parameter for {@link #installPackage} to bypass the low target sdk version block + * for this install. + * + * @hide + */ + public static final int INSTALL_BYPASS_LOW_TARGET_SDK_BLOCK = 0x01000000; + /** @hide */ @IntDef(flag = true, value = { DONT_KILL_APP, diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java index 249f48608d40..832f23cdb3e2 100755 --- a/core/java/android/os/Build.java +++ b/core/java/android/os/Build.java @@ -61,6 +61,17 @@ public class Build { /** The name of the overall product. */ public static final String PRODUCT = getString("ro.product.name"); + /** + * The product name for attestation. In non-default builds (like the AOSP build) the value of + * the 'PRODUCT' system property may be different to the one provisioned to KeyMint, + * and Keymint attestation would still attest to the product name, it's running on. + * @hide + */ + @Nullable + @TestApi + public static final String PRODUCT_FOR_ATTESTATION = + getString("ro.product.name_for_attestation"); + /** The name of the industrial design. */ public static final String DEVICE = getString("ro.product.device"); @@ -89,9 +100,31 @@ public class Build { /** The consumer-visible brand with which the product/hardware will be associated, if any. */ public static final String BRAND = getString("ro.product.brand"); + /** + * The product brand for attestation. In non-default builds (like the AOSP build) the value of + * the 'BRAND' system property may be different to the one provisioned to KeyMint, + * and Keymint attestation would still attest to the product brand, it's running on. + * @hide + */ + @Nullable + @TestApi + public static final String BRAND_FOR_ATTESTATION = + getString("ro.product.brand_for_attestation"); + /** The end-user-visible name for the end product. */ public static final String MODEL = getString("ro.product.model"); + /** + * The product model for attestation. In non-default builds (like the AOSP build) the value of + * the 'MODEL' system property may be different to the one provisioned to KeyMint, + * and Keymint attestation would still attest to the product model, it's running on. + * @hide + */ + @Nullable + @TestApi + public static final String MODEL_FOR_ATTESTATION = + getString("ro.product.model_for_attestation"); + /** The manufacturer of the device's primary system-on-chip. */ @NonNull public static final String SOC_MANUFACTURER = SocProperties.soc_manufacturer().orElse(UNKNOWN); diff --git a/core/java/android/view/AccessibilityInteractionController.java b/core/java/android/view/AccessibilityInteractionController.java index 23e1505e1a4c..62211c42f397 100644 --- a/core/java/android/view/AccessibilityInteractionController.java +++ b/core/java/android/view/AccessibilityInteractionController.java @@ -1502,7 +1502,7 @@ public final class AccessibilityInteractionController { parent = provider.createAccessibilityNodeInfo(virtualDescendantId); if (parent == null) { // Going up the parent relation we found a null predecessor, - // so remove these disconnected nodes form the result. + // so remove these disconnected nodes from the result. final int currentResultSize = outInfos.size(); for (int i = currentResultSize - 1; i >= initialResultSize; i--) { outInfos.remove(i); diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index 0b0bfb1ddbe9..26b021490357 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -463,7 +463,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te AbsPositionScroller mPositionScroller; /** - * The offset in pixels form the top of the AdapterView to the top + * The offset in pixels from the top of the AdapterView to the top * of the currently selected view. Used to save and restore state. */ int mSelectedTop = 0; diff --git a/core/java/android/window/TaskFragmentTransaction.java b/core/java/android/window/TaskFragmentTransaction.java index a8216069bd53..2de3dfdd803c 100644 --- a/core/java/android/window/TaskFragmentTransaction.java +++ b/core/java/android/window/TaskFragmentTransaction.java @@ -126,7 +126,7 @@ public final class TaskFragmentTransaction implements Parcelable { /** Change type: the status of the TaskFragment is changed. */ public static final int TYPE_TASK_FRAGMENT_INFO_CHANGED = 2; - /** Change type: the TaskFragment is removed form the hierarchy. */ + /** Change type: the TaskFragment is removed from the hierarchy. */ public static final int TYPE_TASK_FRAGMENT_VANISHED = 3; /** Change type: the status of the parent leaf Task is changed. */ diff --git a/core/java/com/android/internal/app/OWNERS b/core/java/com/android/internal/app/OWNERS index 56da8e072cbb..69660ae7121d 100644 --- a/core/java/com/android/internal/app/OWNERS +++ b/core/java/com/android/internal/app/OWNERS @@ -11,6 +11,7 @@ per-file *BatteryStats* = file:/BATTERY_STATS_OWNERS per-file *Assist* = file:/core/java/android/service/voice/OWNERS per-file *Hotword* = file:/core/java/android/service/voice/OWNERS per-file *Voice* = file:/core/java/android/service/voice/OWNERS +per-file *VisualQuery* = file:/core/java/android/service/voice/OWNERS # System language settings per-file *Locale* = file:platform/packages/apps/Settings:/src/com/android/settings/localepicker/OWNERS diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java index deafd19e866f..05cad77ca9ab 100644 --- a/core/java/com/android/internal/os/Zygote.java +++ b/core/java/com/android/internal/os/Zygote.java @@ -178,7 +178,14 @@ public final class Zygote { * GWP-ASan is activated unconditionally (but still, only a small subset of * allocations is protected). */ - public static final int GWP_ASAN_LEVEL_ALWAYS = 1 << 22; + public static final int GWP_ASAN_LEVEL_ALWAYS = 2 << 21; + + /** + * GWP-ASan's `gwpAsanMode` manifest flag was unspecified. Currently, this + * means GWP_ASAN_LEVEL_LOTTERY for system apps, and GWP_ASAN_LEVEL_NONE for + * non-system apps. + */ + public static final int GWP_ASAN_LEVEL_DEFAULT = 3 << 21; /** Enable automatic zero-initialization of native heap memory allocations. */ public static final int NATIVE_HEAP_ZERO_INIT_ENABLED = 1 << 23; @@ -1347,15 +1354,13 @@ public final class Zygote { ? GWP_ASAN_LEVEL_ALWAYS : GWP_ASAN_LEVEL_NEVER; } - // If the app does not specify gwpAsanMode, the default behavior is lottery among the - // system apps, and disabled for user apps, unless overwritten by the compat feature. if (isCompatChangeEnabled(GWP_ASAN, info, platformCompat, 0)) { return GWP_ASAN_LEVEL_ALWAYS; } if ((info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { return GWP_ASAN_LEVEL_LOTTERY; } - return GWP_ASAN_LEVEL_NEVER; + return GWP_ASAN_LEVEL_DEFAULT; } private static boolean enableNativeHeapZeroInit( diff --git a/core/java/com/android/internal/util/TraceBuffer.java b/core/java/com/android/internal/util/TraceBuffer.java index fe8a59e160bd..bfcd65d4f277 100644 --- a/core/java/com/android/internal/util/TraceBuffer.java +++ b/core/java/com/android/internal/util/TraceBuffer.java @@ -193,7 +193,7 @@ public class TraceBuffer<P, S extends P, T extends P> { } /** - * Removes all elements form the buffer + * Removes all elements from the buffer */ public void resetBuffer() { synchronized (mBufferLock) { diff --git a/core/java/com/android/internal/widget/RecyclerView.java b/core/java/com/android/internal/widget/RecyclerView.java index e27557a0ef90..4a74d5fa53dc 100644 --- a/core/java/com/android/internal/widget/RecyclerView.java +++ b/core/java/com/android/internal/widget/RecyclerView.java @@ -10087,7 +10087,7 @@ public class RecyclerView extends ViewGroup implements ScrollingView, NestedScro static final int FLAG_IGNORE = 1 << 7; /** - * When the View is detached form the parent, we set this flag so that we can take correct + * When the View is detached from the parent, we set this flag so that we can take correct * action when we need to remove it or add it back. */ static final int FLAG_TMP_DETACHED = 1 << 8; diff --git a/core/jni/Android.bp b/core/jni/Android.bp index e4738fbd9a37..b5b7c0f38bb9 100644 --- a/core/jni/Android.bp +++ b/core/jni/Android.bp @@ -40,6 +40,12 @@ cc_library_shared { cppflags: ["-Wno-conversion-null"], + product_variables: { + eng: { + cflags: ["-DNO_RESET_STACK_PROTECTOR"], + }, + }, + cpp_std: "gnu++20", srcs: [ @@ -260,7 +266,6 @@ cc_library_shared { "av-types-aidl-cpp", "android.hardware.camera.device@3.2", "libandroid_net", - "libandroidicu", "libbattery", "libnetdutils", "libmemtrack", @@ -280,6 +285,7 @@ cc_library_shared { "libpermission", "libsensor", "libinput", + "libicu", "libcamera_client", "libcamera_metadata", "libprocinfo", diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp index d3a34923c5b9..963a83e5d3ee 100644 --- a/core/jni/com_android_internal_os_Zygote.cpp +++ b/core/jni/com_android_internal_os_Zygote.cpp @@ -353,6 +353,7 @@ enum RuntimeFlags : uint32_t { GWP_ASAN_LEVEL_NEVER = 0 << 21, GWP_ASAN_LEVEL_LOTTERY = 1 << 21, GWP_ASAN_LEVEL_ALWAYS = 2 << 21, + GWP_ASAN_LEVEL_DEFAULT = 3 << 21, NATIVE_HEAP_ZERO_INIT_ENABLED = 1 << 23, PROFILEABLE = 1 << 24, }; @@ -1926,6 +1927,13 @@ static void SpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray gids, gwp_asan_options.program_name = nice_name_ptr ?: process_name; switch (runtime_flags & RuntimeFlags::GWP_ASAN_LEVEL_MASK) { default: + case RuntimeFlags::GWP_ASAN_LEVEL_DEFAULT: + // TODO(b/247012630): Switch this to Action::TURN_ON_FOR_APP_SAMPLED_NON_CRASHING once + // performance and syshealth testing is completed, making the default for non-system + // apps that don't specify a `gwpAsanMode` in their manifest to be sampled-recoverable. + gwp_asan_options.desire = Action::DONT_TURN_ON_UNLESS_OVERRIDDEN; + android_mallopt(M_INITIALIZE_GWP_ASAN, &gwp_asan_options, sizeof(gwp_asan_options)); + break; case RuntimeFlags::GWP_ASAN_LEVEL_NEVER: gwp_asan_options.desire = Action::DONT_TURN_ON_UNLESS_OVERRIDDEN; android_mallopt(M_INITIALIZE_GWP_ASAN, &gwp_asan_options, sizeof(gwp_asan_options)); @@ -2288,7 +2296,7 @@ pid_t zygote::ForkCommon(JNIEnv* env, bool is_system_server, setpriority(PRIO_PROCESS, 0, PROCESS_PRIORITY_MIN); } -#if defined(__BIONIC__) +#if defined(__BIONIC__) && !defined(NO_RESET_STACK_PROTECTOR) // Reset the stack guard for the new process. android_reset_stack_guards(); #endif diff --git a/keystore/java/android/security/KeyStoreException.java b/keystore/java/android/security/KeyStoreException.java index 6536e43f67fd..cb757794a11d 100644 --- a/keystore/java/android/security/KeyStoreException.java +++ b/keystore/java/android/security/KeyStoreException.java @@ -265,7 +265,7 @@ public class KeyStoreException extends Exception { private static int initializeRkpStatusForRegularErrors(int errorCode) { // Check if the system code mistakenly called a constructor of KeyStoreException with // the OUT_OF_KEYS error code but without RKP status. - if (isRkpRelatedError(errorCode)) { + if (errorCode == ResponseCode.OUT_OF_KEYS) { Log.e(TAG, "RKP error code without RKP status"); // Set RKP status to RKP_SERVER_REFUSED_ISSUANCE so that the caller never retries. return RKP_SERVER_REFUSED_ISSUANCE; @@ -301,7 +301,7 @@ public class KeyStoreException extends Exception { super(message); mErrorCode = errorCode; mRkpStatus = rkpStatus; - if (!isRkpRelatedError(mErrorCode)) { + if (mErrorCode != ResponseCode.OUT_OF_KEYS) { Log.e(TAG, "Providing RKP status for error code " + errorCode + " has no effect."); } } @@ -338,7 +338,7 @@ public class KeyStoreException extends Exception { public boolean isTransientFailure() { PublicErrorInformation failureInfo = getErrorInformation(mErrorCode); // Special-case handling for RKP failures: - if (mRkpStatus != RKP_SUCCESS && isRkpRelatedError(mErrorCode)) { + if (mRkpStatus != RKP_SUCCESS && mErrorCode == ResponseCode.OUT_OF_KEYS) { switch (mRkpStatus) { case RKP_TEMPORARILY_UNAVAILABLE: case RKP_FETCHING_PENDING_CONNECTIVITY: @@ -376,11 +376,6 @@ public class KeyStoreException extends Exception { return (failureInfo.indicators & IS_SYSTEM_ERROR) != 0; } - private static boolean isRkpRelatedError(int errorCode) { - return errorCode == ResponseCode.OUT_OF_KEYS - || errorCode == ResponseCode.OUT_OF_KEYS_REQUIRES_UPGRADE; - } - /** * Returns the re-try policy for transient failures. Valid only if * {@link #isTransientFailure()} returns {@code True}. @@ -388,7 +383,7 @@ public class KeyStoreException extends Exception { @RetryPolicy public int getRetryPolicy() { PublicErrorInformation failureInfo = getErrorInformation(mErrorCode); - // Special-case handling for RKP failures: + // Special-case handling for RKP failures (To be removed in API 34) if (mRkpStatus != RKP_SUCCESS) { switch (mRkpStatus) { case RKP_TEMPORARILY_UNAVAILABLE: @@ -404,10 +399,14 @@ public class KeyStoreException extends Exception { ? RETRY_WITH_EXPONENTIAL_BACKOFF : RETRY_NEVER; } } - if ((failureInfo.indicators & IS_TRANSIENT_ERROR) != 0) { - return RETRY_WITH_EXPONENTIAL_BACKOFF; - } else { - return RETRY_NEVER; + switch (mErrorCode) { + case ResponseCode.OUT_OF_KEYS_REQUIRES_SYSTEM_UPGRADE: + return RETRY_AFTER_NEXT_REBOOT; + case ResponseCode.OUT_OF_KEYS_PENDING_INTERNET_CONNECTIVITY: + return RETRY_WHEN_CONNECTIVITY_AVAILABLE; + default: + return (failureInfo.indicators & IS_TRANSIENT_ERROR) != 0 + ? RETRY_WITH_EXPONENTIAL_BACKOFF : RETRY_NEVER; } } @@ -657,8 +656,16 @@ public class KeyStoreException extends Exception { new PublicErrorInformation(0, ERROR_KEY_DOES_NOT_EXIST)); sErrorCodeToFailureInfo.put(ResponseCode.OUT_OF_KEYS, new PublicErrorInformation(IS_SYSTEM_ERROR, ERROR_ATTESTATION_KEYS_UNAVAILABLE)); - sErrorCodeToFailureInfo.put(ResponseCode.OUT_OF_KEYS_REQUIRES_UPGRADE, + sErrorCodeToFailureInfo.put(ResponseCode.OUT_OF_KEYS_REQUIRES_SYSTEM_UPGRADE, new PublicErrorInformation(IS_SYSTEM_ERROR | IS_TRANSIENT_ERROR, ERROR_DEVICE_REQUIRES_UPGRADE_FOR_ATTESTATION)); + sErrorCodeToFailureInfo.put(ResponseCode.OUT_OF_KEYS_PENDING_INTERNET_CONNECTIVITY, + new PublicErrorInformation(IS_SYSTEM_ERROR | IS_TRANSIENT_ERROR, + ERROR_ATTESTATION_KEYS_UNAVAILABLE)); + sErrorCodeToFailureInfo.put(ResponseCode.OUT_OF_KEYS_TRANSIENT_ERROR, + new PublicErrorInformation(IS_SYSTEM_ERROR | IS_TRANSIENT_ERROR, + ERROR_ATTESTATION_KEYS_UNAVAILABLE)); + sErrorCodeToFailureInfo.put(ResponseCode.OUT_OF_KEYS_PERMANENT_ERROR, + new PublicErrorInformation(IS_SYSTEM_ERROR, ERROR_ATTESTATION_KEYS_UNAVAILABLE)); } } diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java index 2830d7effa99..471504588673 100644 --- a/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java +++ b/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java @@ -801,25 +801,32 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato )); if (mSpec.isDevicePropertiesAttestationIncluded()) { + final String platformReportedBrand = TextUtils.isEmpty(Build.BRAND_FOR_ATTESTATION) + ? Build.BRAND : Build.BRAND_FOR_ATTESTATION; params.add(KeyStore2ParameterUtils.makeBytes( KeymasterDefs.KM_TAG_ATTESTATION_ID_BRAND, - Build.BRAND.getBytes(StandardCharsets.UTF_8) + platformReportedBrand.getBytes(StandardCharsets.UTF_8) )); params.add(KeyStore2ParameterUtils.makeBytes( KeymasterDefs.KM_TAG_ATTESTATION_ID_DEVICE, Build.DEVICE.getBytes(StandardCharsets.UTF_8) )); + final String platformReportedProduct = + TextUtils.isEmpty(Build.PRODUCT_FOR_ATTESTATION) ? Build.PRODUCT : + Build.PRODUCT_FOR_ATTESTATION; params.add(KeyStore2ParameterUtils.makeBytes( KeymasterDefs.KM_TAG_ATTESTATION_ID_PRODUCT, - Build.PRODUCT.getBytes(StandardCharsets.UTF_8) + platformReportedProduct.getBytes(StandardCharsets.UTF_8) )); params.add(KeyStore2ParameterUtils.makeBytes( KeymasterDefs.KM_TAG_ATTESTATION_ID_MANUFACTURER, Build.MANUFACTURER.getBytes(StandardCharsets.UTF_8) )); + final String platformReportedModel = TextUtils.isEmpty(Build.MODEL_FOR_ATTESTATION) + ? Build.MODEL : Build.MODEL_FOR_ATTESTATION; params.add(KeyStore2ParameterUtils.makeBytes( KeymasterDefs.KM_TAG_ATTESTATION_ID_MODEL, - Build.MODEL.getBytes(StandardCharsets.UTF_8) + platformReportedModel.getBytes(StandardCharsets.UTF_8) )); } diff --git a/libs/hwui/jni/Paint.cpp b/libs/hwui/jni/Paint.cpp index f76863255153..293e28022e47 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/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java index d51f1e1327bd..f61c42760c9b 100644 --- a/media/java/android/media/AudioTrack.java +++ b/media/java/android/media/AudioTrack.java @@ -266,15 +266,19 @@ public class AudioTrack extends PlayerBase @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static final int ENCAPSULATION_MODE_HANDLE = 2; - /* Enumeration of metadata types permitted for use by + /** + * Enumeration of metadata types permitted for use by * encapsulation mode audio streams. + * @hide */ - /** @hide */ - @IntDef(prefix = { "ENCAPSULATION_METADATA_TYPE_" }, value = { - ENCAPSULATION_METADATA_TYPE_NONE, /* reserved */ - ENCAPSULATION_METADATA_TYPE_FRAMEWORK_TUNER, - ENCAPSULATION_METADATA_TYPE_DVB_AD_DESCRIPTOR, - }) + @IntDef(prefix = {"ENCAPSULATION_METADATA_TYPE_"}, + value = + { + ENCAPSULATION_METADATA_TYPE_NONE, /* reserved */ + ENCAPSULATION_METADATA_TYPE_FRAMEWORK_TUNER, + ENCAPSULATION_METADATA_TYPE_DVB_AD_DESCRIPTOR, + ENCAPSULATION_METADATA_TYPE_SUPPLEMENTARY_AUDIO_PLACEMENT, + }) @Retention(RetentionPolicy.SOURCE) public @interface EncapsulationMetadataType {} @@ -298,6 +302,45 @@ public class AudioTrack extends PlayerBase */ public static final int ENCAPSULATION_METADATA_TYPE_DVB_AD_DESCRIPTOR = 2; + /** + * Encapsulation metadata type for placement of supplementary audio. + * + * A 32 bit integer constant, one of {@link #SUPPLEMENTARY_AUDIO_PLACEMENT_NORMAL}, {@link + * #SUPPLEMENTARY_AUDIO_PLACEMENT_LEFT}, {@link #SUPPLEMENTARY_AUDIO_PLACEMENT_RIGHT}. + */ + public static final int ENCAPSULATION_METADATA_TYPE_SUPPLEMENTARY_AUDIO_PLACEMENT = 3; + + /** + * Enumeration of supplementary audio placement types. + * @hide + */ + @IntDef(prefix = {"SUPPLEMENTARY_AUDIO_PLACEMENT_"}, + value = + { + SUPPLEMENTARY_AUDIO_PLACEMENT_NORMAL, + SUPPLEMENTARY_AUDIO_PLACEMENT_LEFT, + SUPPLEMENTARY_AUDIO_PLACEMENT_RIGHT, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface SupplementaryAudioPlacement {} + // Important: The SUPPLEMENTARY_AUDIO_PLACEMENT values must be kept in sync with native header + // files. + + /** + * Supplementary audio placement normal. + */ + public static final int SUPPLEMENTARY_AUDIO_PLACEMENT_NORMAL = 0; + + /** + * Supplementary audio placement left. + */ + public static final int SUPPLEMENTARY_AUDIO_PLACEMENT_LEFT = 1; + + /** + * Supplementary audio placement right. + */ + public static final int SUPPLEMENTARY_AUDIO_PLACEMENT_RIGHT = 2; + /* Dual Mono handling is used when a stereo audio stream * contains separate audio content on the left and right channels. * Such information about the content of the stream may be found, for example, in diff --git a/media/java/android/media/ImageUtils.java b/media/java/android/media/ImageUtils.java index 4957300dd062..993155f81c60 100644 --- a/media/java/android/media/ImageUtils.java +++ b/media/java/android/media/ImageUtils.java @@ -84,6 +84,7 @@ class ImageUtils { 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/tv/ITvInputManager.aidl b/media/java/android/media/tv/ITvInputManager.aidl index 2a33ee6a6b4d..1d2198ee740f 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 @@ interface ITvInputManager { 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 64a23a2323f6..be73c0cdf43a 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 @@ interface ITvInputService { 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 8911f6c7d4be..6c1099082ef7 100644 --- a/media/java/android/media/tv/ITvInputSessionWrapper.java +++ b/media/java/android/media/tv/ITvInputSessionWrapper.java @@ -30,7 +30,6 @@ import android.view.InputChannel; 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 149c2f471a4c..819cd0c8c58c 100644 --- a/media/java/android/media/tv/TvInputManager.java +++ b/media/java/android/media/tv/TvInputManager.java @@ -25,6 +25,7 @@ import android.annotation.RequiresPermission; 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.InputEventSender; 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 @@ public final class TvInputManager { * 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 @@ public final class TvInputManager { * @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 final class TvInputManager { */ 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 @@ public final class TvInputManager { 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 @@ public final class TvInputManager { * @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 70acf25afc51..f3e5d14eec7a 100755 --- a/media/java/android/media/tv/TvInputService.java +++ b/media/java/android/media/tv/TvInputService.java @@ -26,6 +26,7 @@ import android.annotation.SystemApi; 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.ViewRootImpl; 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 @@ public abstract class TvInputService extends Service { @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 @@ public abstract class TvInputService extends Service { args.arg2 = cb; args.arg3 = inputId; args.arg4 = sessionId; + args.arg5 = tvAppAttributionSource; mServiceHandler.obtainMessage(ServiceHandler.DO_CREATE_SESSION, args).sendToTarget(); } @@ -370,6 +370,24 @@ public abstract class TvInputService extends Service { } /** + * 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 class TvInputService extends Service { 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 @@ public abstract class TvInputService extends Service { } /** - * called when broadcast info is removed. + * Called when broadcast info is removed. */ public void onRemoveBroadcastInfo(int requestId) { } @@ -2444,8 +2462,10 @@ public abstract class TvInputService extends Service { 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 @@ public abstract class TvInputService extends Service { 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 ff3d06c5bd69..de9acc3d797f 100644 --- a/media/java/android/media/tv/TvView.java +++ b/media/java/android/media/tv/TvView.java @@ -21,6 +21,7 @@ import android.annotation.NonNull; 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.SurfaceView; 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 @@ public class TvView extends ViewGroup { 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 @@ public class TvView extends ViewGroup { mDefStyleAttr = defStyleAttr; resetSurfaceView(); mTvInputManager = (TvInputManager) getContext().getSystemService(Context.TV_INPUT_SERVICE); + mTvAppAttributionSource = getContext().getAttributionSource(); } /** @@ -304,6 +306,22 @@ public class TvView extends ViewGroup { } /** + * 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 @@ public class TvView extends ViewGroup { // 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 @@ public class TvView extends ViewGroup { 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 681d76ab0dfe..b70818d1e1b0 100644 --- a/media/jni/android_media_MediaDrm.cpp +++ b/media/jni/android_media_MediaDrm.cpp @@ -1021,9 +1021,10 @@ DrmPlugin::SecurityLevel jintToSecurityLevel(jint jlevel) { 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/packages/SettingsLib/src/com/android/settingslib/media/OWNERS b/packages/SettingsLib/src/com/android/settingslib/media/OWNERS index d40f322042fe..3cae39f4ea40 100644 --- a/packages/SettingsLib/src/com/android/settingslib/media/OWNERS +++ b/packages/SettingsLib/src/com/android/settingslib/media/OWNERS @@ -1,2 +1,5 @@ # Default reviewers for this and subdirectories. shaoweishen@google.com + +#Android Media - For minor changes and renames only. +aquilescanta@google.com #{LAST_RESORT_SUGGESTION} diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java index 50a10bc0b15a..14d45d2db413 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java @@ -179,7 +179,7 @@ public class NavigationBar extends ViewController<NavigationBarView> implements private static final String EXTRA_TRANSIENT_STATE = "transient_state"; /** Allow some time inbetween the long press for back and recents. */ - private static final int LOCK_TO_APP_GESTURE_TOLERENCE = 200; + private static final int LOCK_TO_APP_GESTURE_TOLERANCE = 200; private static final long AUTODIM_TIMEOUT_MS = 2250; private final Context mContext; @@ -1327,7 +1327,7 @@ public class NavigationBar extends ViewController<NavigationBarView> implements // If we recently long-pressed the other button then they were // long-pressed 'together' - if ((time - mLastLockToAppLongPress) < LOCK_TO_APP_GESTURE_TOLERENCE) { + if ((time - mLastLockToAppLongPress) < LOCK_TO_APP_GESTURE_TOLERANCE) { stopLockTaskMode = true; return true; } else if (v.getId() == btnId1) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java index df81c0ed3a61..90313eb9b871 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java @@ -1042,7 +1042,7 @@ public class NotificationContentView extends FrameLayout implements Notification } /** - * @return one of the static enum types in this view, calculated form the current state + * @return one of the static enum types in this view, calculated from the current state */ public int calculateVisibleType() { if (mUserExpanding) { diff --git a/rs/jni/Android.bp b/rs/jni/Android.bp index 9a6fa8e8e423..8a6897c055c5 100644 --- a/rs/jni/Android.bp +++ b/rs/jni/Android.bp @@ -51,4 +51,10 @@ cc_library_shared { "-Wunreachable-code", "-Wno-deprecated-declarations", ], + + target: { + android_riscv64: { + enabled: false, + }, + }, } diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java index abc49372053e..f10f9303faad 100644 --- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java +++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java @@ -1094,7 +1094,7 @@ public class CompanionDeviceManagerService extends SystemService { } /** - * Remove the revoked association form the cache and also remove the uid form the map if + * Remove the revoked association from the cache and also remove the uid from the map if * there are other associations with the same package still pending for role holder removal. * * @see #mRevokedAssociationsPendingRoleHolderRemoval @@ -1113,7 +1113,7 @@ public class CompanionDeviceManagerService extends SystemService { final boolean shouldKeepUidForRemoval = any( getPendingRoleHolderRemovalAssociationsForUser(userId), ai -> packageName.equals(ai.getPackageName())); - // Do not remove the uid form the map since other associations with + // Do not remove the uid from the map since other associations with // the same packageName still pending for role holder removal. if (!shouldKeepUidForRemoval) { mUidsPendingRoleHolderRemoval.remove(uid); diff --git a/services/core/Android.bp b/services/core/Android.bp index 220782131376..821927d72428 100644 --- a/services/core/Android.bp +++ b/services/core/Android.bp @@ -143,9 +143,10 @@ java_library_static { static_libs: [ "android.hardware.authsecret-V1.0-java", - "android.hardware.boot-V1.0-java", - "android.hardware.boot-V1.1-java", - "android.hardware.boot-V1.2-java", + "android.hardware.boot-V1.0-java", // HIDL + "android.hardware.boot-V1.1-java", // HIDL + "android.hardware.boot-V1.2-java", // HIDL + "android.hardware.boot-V1-java", // AIDL "android.hardware.broadcastradio-V2.0-java", "android.hardware.health-V1.0-java", // HIDL "android.hardware.health-V2.0-java", // HIDL diff --git a/services/core/java/android/os/BatteryStatsInternal.java b/services/core/java/android/os/BatteryStatsInternal.java index d49cc116ab9b..4a2fc89ae7d5 100644 --- a/services/core/java/android/os/BatteryStatsInternal.java +++ b/services/core/java/android/os/BatteryStatsInternal.java @@ -16,6 +16,8 @@ package android.os; +import android.net.Network; + import com.android.internal.os.BinderCallsStats; import com.android.internal.os.SystemServerCpuThreadReader.SystemServiceCpuThreadTimes; @@ -63,6 +65,15 @@ public abstract class BatteryStatsInternal { public abstract void noteJobsDeferred(int uid, int numDeferred, long sinceLast); /** + * Informs battery stats of a data packet that woke up the CPU. + * + * @param network The network over which the packet arrived. + * @param elapsedMillis The time of the packet's arrival in elapsed timebase. + * @param uid The uid that received the packet. + */ + public abstract void noteCpuWakingNetworkPacket(Network network, long elapsedMillis, int uid); + + /** * Informs battery stats of binder stats for the given work source UID. */ public abstract void noteBinderCallStats(int workSourceUid, long incrementalBinderCallCount, diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java index 606a09cb1cac..b02dd5267726 100644 --- a/services/core/java/com/android/server/am/BatteryStatsService.java +++ b/services/core/java/com/android/server/am/BatteryStatsService.java @@ -441,6 +441,11 @@ public final class BatteryStatsService extends IBatteryStats.Stub } @Override + public void noteCpuWakingNetworkPacket(Network network, long elapsedMillis, int uid) { + Slog.d(TAG, "Wakeup due to incoming packet on network " + network + " to uid " + uid); + } + + @Override public void noteBinderCallStats(int workSourceUid, long incrementatCallCount, Collection<BinderCallsStats.CallStat> callStats) { synchronized (BatteryStatsService.this.mLock) { diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java index a840e6141e67..2f16a582ebf9 100644 --- a/services/core/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -2231,7 +2231,9 @@ public final class DisplayManagerService extends SystemService { } // 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/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java index 89719ce99ac9..958eb64b833b 100644 --- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java +++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java @@ -3184,6 +3184,10 @@ class PackageManagerShellCommand extends ShellCommand { case "--skip-verification": sessionParams.installFlags |= PackageManager.INSTALL_DISABLE_VERIFICATION; break; + case "--bypass-low-target-sdk-block": + sessionParams.installFlags |= + PackageManager.INSTALL_BYPASS_LOW_TARGET_SDK_BLOCK; + break; default: throw new IllegalArgumentException("Unknown option " + opt); } diff --git a/services/core/java/com/android/server/power/ShutdownThread.java b/services/core/java/com/android/server/power/ShutdownThread.java index a82d4eaa5b28..5096ad1faf73 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 @@ import java.nio.charset.StandardCharsets; 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 @@ public final class ShutdownThread extends Thread { // 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 @@ public final class ShutdownThread extends Thread { ? 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 @@ public final class ShutdownThread extends Thread { } 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/recoverysystem/RecoverySystemService.java b/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java index 13218731af70..9d5173a8da09 100644 --- a/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java +++ b/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java @@ -36,7 +36,7 @@ import android.content.Context; import android.content.IntentSender; import android.content.SharedPreferences; import android.content.pm.PackageManager; -import android.hardware.boot.V1_0.IBootControl; +import android.hardware.boot.IBootControl; import android.net.LocalSocket; import android.net.LocalSocketAddress; import android.os.Binder; @@ -48,6 +48,7 @@ import android.os.Process; import android.os.RecoverySystem; import android.os.RemoteException; import android.os.ResultReceiver; +import android.os.ServiceManager; import android.os.ShellCallback; import android.os.SystemProperties; import android.provider.DeviceConfig; @@ -66,6 +67,7 @@ import com.android.internal.widget.RebootEscrowListener; import com.android.server.LocalServices; import com.android.server.SystemService; import com.android.server.pm.ApexManager; +import com.android.server.recoverysystem.hal.BootControlHIDL; import libcore.io.IoUtils; @@ -155,18 +157,20 @@ public class RecoverySystemService extends IRecoverySystem.Stub implements Reboo /** * The action to perform upon new resume on reboot prepare request for a given client. */ - @IntDef({ ROR_NEED_PREPARATION, + @IntDef({ROR_NEED_PREPARATION, ROR_SKIP_PREPARATION_AND_NOTIFY, - ROR_SKIP_PREPARATION_NOT_NOTIFY }) - private @interface ResumeOnRebootActionsOnRequest {} + ROR_SKIP_PREPARATION_NOT_NOTIFY}) + private @interface ResumeOnRebootActionsOnRequest { + } /** * The action to perform upon resume on reboot clear request for a given client. */ - @IntDef({ ROR_NOT_REQUESTED, + @IntDef({ROR_NOT_REQUESTED, ROR_REQUESTED_NEED_CLEAR, - ROR_REQUESTED_SKIP_CLEAR }) - private @interface ResumeOnRebootActionsOnClear {} + ROR_REQUESTED_SKIP_CLEAR}) + private @interface ResumeOnRebootActionsOnClear { + } /** * Fatal arm escrow errors from lock settings that means the RoR is in a bad state. So clients @@ -306,19 +310,26 @@ public class RecoverySystemService extends IRecoverySystem.Stub implements Reboo * Throws remote exception if there's an error getting the boot control HAL. * Returns null if the boot control HAL's version is older than V1_2. */ - public android.hardware.boot.V1_2.IBootControl getBootControl() throws RemoteException { - IBootControl bootControlV10 = IBootControl.getService(true); - if (bootControlV10 == null) { - throw new RemoteException("Failed to get boot control HAL V1_0."); + public IBootControl getBootControl() throws RemoteException { + String serviceName = IBootControl.DESCRIPTOR + "/default"; + if (ServiceManager.isDeclared(serviceName)) { + Slog.i(TAG, + "AIDL version of BootControl HAL present, using instance " + serviceName); + return IBootControl.Stub.asInterface( + ServiceManager.waitForDeclaredService(serviceName)); } - android.hardware.boot.V1_2.IBootControl bootControlV12 = - android.hardware.boot.V1_2.IBootControl.castFrom(bootControlV10); - if (bootControlV12 == null) { + IBootControl bootcontrol = BootControlHIDL.getService(); + if (!BootControlHIDL.isServicePresent()) { + Slog.e(TAG, "Neither AIDL nor HIDL version of the BootControl HAL is present."); + return null; + } + + if (!BootControlHIDL.isV1_2ServicePresent()) { Slog.w(TAG, "Device doesn't implement boot control HAL V1_2."); return null; } - return bootControlV12; + return bootcontrol; } public void threadSleep(long millis) throws InterruptedException { @@ -526,7 +537,7 @@ public class RecoverySystemService extends IRecoverySystem.Stub implements Reboo if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.RECOVERY) != PackageManager.PERMISSION_GRANTED && mContext.checkCallingOrSelfPermission(android.Manifest.permission.REBOOT) - != PackageManager.PERMISSION_GRANTED) { + != PackageManager.PERMISSION_GRANTED) { throw new SecurityException("Caller must have " + android.Manifest.permission.RECOVERY + " or " + android.Manifest.permission.REBOOT + " for resume on reboot."); } @@ -738,7 +749,7 @@ public class RecoverySystemService extends IRecoverySystem.Stub implements Reboo return true; } - android.hardware.boot.V1_2.IBootControl bootControl; + IBootControl bootControl; try { bootControl = mInjector.getBootControl(); } catch (RemoteException e) { @@ -972,8 +983,8 @@ public class RecoverySystemService extends IRecoverySystem.Stub implements Reboo CompressedApexInfoList apexInfoList = getCompressedApexInfoList(packageFile); if (apexInfoList == null) { Log.i(TAG, "apex_info.pb not present in OTA package. " - + "Assuming device doesn't support compressed" - + "APEX, continueing without allocating space."); + + "Assuming device doesn't support compressed" + + "APEX, continueing without allocating space."); return true; } ApexManager apexManager = ApexManager.getInstance(); @@ -1160,6 +1171,7 @@ public class RecoverySystemService extends IRecoverySystem.Stub implements Reboo /** * Reads the status from the uncrypt service which is usually represented as a percentage. + * * @return an integer representing the percentage completed * @throws IOException if there was an error reading the socket */ @@ -1169,6 +1181,7 @@ public class RecoverySystemService extends IRecoverySystem.Stub implements Reboo /** * Sends a confirmation to the uncrypt service. + * * @throws IOException if there was an error writing to the socket */ public void sendAck() throws IOException { diff --git a/services/core/java/com/android/server/recoverysystem/hal/BootControlHIDL.java b/services/core/java/com/android/server/recoverysystem/hal/BootControlHIDL.java new file mode 100644 index 000000000000..65325c297719 --- /dev/null +++ b/services/core/java/com/android/server/recoverysystem/hal/BootControlHIDL.java @@ -0,0 +1,178 @@ +/* + * 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.server.recoverysystem.hal; + +import android.hardware.boot.IBootControl; +import android.hardware.boot.V1_0.CommandResult; +import android.os.IBinder; +import android.os.RemoteException; +import android.util.Slog; + +public class BootControlHIDL implements IBootControl { + private static final String TAG = "BootControlHIDL"; + + final android.hardware.boot.V1_0.IBootControl v1_hal; + final android.hardware.boot.V1_1.IBootControl v1_1_hal; + final android.hardware.boot.V1_2.IBootControl v1_2_hal; + + public static boolean isServicePresent() { + try { + android.hardware.boot.V1_0.IBootControl.getService(true); + } catch (RemoteException e) { + return false; + } + return true; + } + + public static boolean isV1_2ServicePresent() { + try { + android.hardware.boot.V1_2.IBootControl.getService(true); + } catch (RemoteException e) { + return false; + } + return true; + } + + public static BootControlHIDL getService() throws RemoteException { + android.hardware.boot.V1_0.IBootControl v1_hal = + android.hardware.boot.V1_0.IBootControl.getService(true); + android.hardware.boot.V1_1.IBootControl v1_1_hal = + android.hardware.boot.V1_1.IBootControl.castFrom(v1_hal); + android.hardware.boot.V1_2.IBootControl v1_2_hal = + android.hardware.boot.V1_2.IBootControl.castFrom(v1_hal); + return new BootControlHIDL(v1_hal, v1_1_hal, v1_2_hal); + } + + private BootControlHIDL(android.hardware.boot.V1_0.IBootControl v1_hal, + android.hardware.boot.V1_1.IBootControl v1_1_hal, + android.hardware.boot.V1_2.IBootControl v1_2_hal) throws RemoteException { + this.v1_hal = v1_hal; + this.v1_1_hal = v1_1_hal; + this.v1_2_hal = v1_2_hal; + if (v1_hal == null) { + throw new RemoteException("Failed to find V1.0 BootControl HIDL"); + } + if (v1_2_hal != null) { + Slog.i(TAG, "V1.2 version of BootControl HIDL HAL available, using V1.2"); + } else if (v1_1_hal != null) { + Slog.i(TAG, "V1.1 version of BootControl HIDL HAL available, using V1.1"); + } else { + Slog.i(TAG, "V1.0 version of BootControl HIDL HAL available, using V1.0"); + } + } + + @Override + public IBinder asBinder() { + return null; + } + + @Override + public int getActiveBootSlot() throws RemoteException { + if (v1_2_hal == null) { + throw new RemoteException("getActiveBootSlot() requires V1.2 BootControl HAL"); + } + return v1_2_hal.getActiveBootSlot(); + } + + @Override + public int getCurrentSlot() throws RemoteException { + return v1_hal.getCurrentSlot(); + } + + @Override + public int getNumberSlots() throws RemoteException { + return v1_hal.getNumberSlots(); + } + + @Override + public int getSnapshotMergeStatus() throws RemoteException { + if (v1_1_hal == null) { + throw new RemoteException("getSnapshotMergeStatus() requires V1.1 BootControl HAL"); + } + return v1_1_hal.getSnapshotMergeStatus(); + } + + @Override + public String getSuffix(int slot) throws RemoteException { + return v1_hal.getSuffix(slot); + } + + @Override + public boolean isSlotBootable(int slot) throws RemoteException { + int ret = v1_hal.isSlotBootable(slot); + if (ret == -1) { + throw new RemoteException( + "isSlotBootable() failed, Slot %d might be invalid.".formatted(slot)); + } + return ret != 0; + } + + @Override + public boolean isSlotMarkedSuccessful(int slot) throws RemoteException { + int ret = v1_hal.isSlotMarkedSuccessful(slot); + if (ret == -1) { + throw new RemoteException( + "isSlotMarkedSuccessful() failed, Slot %d might be invalid.".formatted(slot)); + } + return ret != 0; + } + + @Override + public void markBootSuccessful() throws RemoteException { + CommandResult res = v1_hal.markBootSuccessful(); + if (!res.success) { + throw new RemoteException("Error markBootSuccessful() " + res.errMsg); + } + } + + @Override + public void setActiveBootSlot(int slot) throws RemoteException { + CommandResult res = v1_hal.setActiveBootSlot(slot); + if (!res.success) { + throw new RemoteException("Error setActiveBootSlot(%d) %s".formatted(slot, res.errMsg)); + } + } + + @Override + public void setSlotAsUnbootable(int slot) throws RemoteException { + CommandResult res = v1_hal.setSlotAsUnbootable(slot); + if (!res.success) { + throw new RemoteException( + "Error setSlotAsUnbootable(%d) %s".formatted(slot, res.errMsg)); + } + } + + @Override + public void setSnapshotMergeStatus(int status) throws RemoteException { + if (v1_1_hal == null) { + throw new RemoteException("getSnapshotMergeStatus() requires V1.1 BootControl HAL"); + } + if (!v1_1_hal.setSnapshotMergeStatus(status)) { + throw new RemoteException("Error setSnapshotMergeStatus(%d)".formatted(status)); + } + } + + @Override + public int getInterfaceVersion() throws RemoteException { + return 1; + } + + @Override + public String getInterfaceHash() throws RemoteException { + return v1_hal.interfaceDescriptor(); + } +} diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java index b95d3726af07..8bc7bcce4958 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.NonNull; 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.Slog; 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.FrameworkStatsLog; 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 @@ public final class TvInputManagerService extends SystemService { @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 @@ public final class TvInputManagerService extends SystemService { 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 @@ public final class TvInputManagerService extends SystemService { @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 @@ public final class TvInputManagerService extends SystemService { if (serviceState.service != null) { if (!createSessionInternalLocked(serviceState.service, sessionToken, - resolvedUserId)) { + resolvedUserId, tvAppAttributionSource)) { removeSessionStateLocked(sessionToken, resolvedUserId); } } else { @@ -3113,7 +3112,8 @@ public final class TvInputManagerService extends SystemService { // 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/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java index 7f222423ec1c..efbd7a89bfc2 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -2278,7 +2278,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> } if (rootTask.getDisplayArea().isTopRootTask(rootTask) && topRunningActivity.isState(RESUMED)) { - // Kick off any lingering app transitions form the MoveTaskToFront + // Kick off any lingering app transitions from the MoveTaskToFront // operation, but only consider the top task and root-task on that // display. rootTask.executeAppTransition(targetOptions); diff --git a/services/tests/mockingservicestests/src/com/android/server/power/OWNERS b/services/tests/mockingservicestests/src/com/android/server/power/OWNERS index d68066bb8c40..fb62520ff57b 100644 --- a/services/tests/mockingservicestests/src/com/android/server/power/OWNERS +++ b/services/tests/mockingservicestests/src/com/android/server/power/OWNERS @@ -1 +1,3 @@ include /services/core/java/com/android/server/power/OWNERS + +per-file ThermalManagerServiceMockingTest.java=wvw@google.com,xwxw@google.com diff --git a/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTest.java b/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTest.java index 5234bb725a8f..63d676800512 100644 --- a/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTest.java @@ -46,7 +46,7 @@ import static org.mockito.Mockito.when; import android.content.Context; import android.content.IntentSender; import android.content.pm.PackageManager; -import android.hardware.boot.V1_2.IBootControl; +import android.hardware.boot.IBootControl; import android.os.Handler; import android.os.IPowerManager; import android.os.IRecoverySystemProgressListener; diff --git a/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTestable.java b/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTestable.java index 27e953f30fa0..f1cf48bc5f20 100644 --- a/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTestable.java +++ b/services/tests/servicestests/src/com/android/server/recoverysystem/RecoverySystemServiceTestable.java @@ -17,7 +17,7 @@ package com.android.server.recoverysystem; import android.content.Context; -import android.hardware.boot.V1_2.IBootControl; +import android.hardware.boot.IBootControl; import android.os.PowerManager; import com.android.internal.widget.LockSettingsInternal; diff --git a/tests/CanvasCompare/Android.bp b/tests/CanvasCompare/Android.bp deleted file mode 100644 index 98831154ddc2..000000000000 --- 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 2734e7f07f27..000000000000 --- 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 c88a9f82c347..000000000000 --- 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 Binary files differdeleted file mode 100644 index 3b4e056b70d0..000000000000 --- a/tests/CanvasCompare/res/drawable/sunset1.jpg +++ /dev/null diff --git a/tests/CanvasCompare/res/layout/automatic_layout.xml b/tests/CanvasCompare/res/layout/automatic_layout.xml deleted file mode 100644 index e049ec0a5000..000000000000 --- 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 1a9288ce1993..000000000000 --- 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 edd46103f4f5..000000000000 --- 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 f69378d34f65..000000000000 --- 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 8ccd4e2181ed..000000000000 --- 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 0dec1de79a46..000000000000 --- 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 4bcf5a4e30d5..000000000000 --- 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 d402699b0979..000000000000 --- 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 454fe7b50ad7..000000000000 --- 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 405ff65a34fd..000000000000 --- 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 d5224813c0bc..000000000000 --- 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 1ff153c003c1..000000000000 --- 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 0a1742ef3867..000000000000 --- 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); - } -} |